Example #1
0
def plotHists(args):

    print '\n******************************************'
    print 'plot histograms together'

    #------------------------------------------
    #input parameters
    print '\ninput parameters:'
    argsdict = vars(args)
    for ii in xrange(len(argsdict)):
        print '  %s = %s'%(argsdict.keys()[ii], argsdict.values()[ii],)
    
    #------------------------------------------
    #define useful variables
    lumi = float(args.lumi) #fb^-1
    colors = plotTools.getColors()

    #------------------------------------------
    #get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))
	
    #------------------------------------------
    #set error sum and overflow
    ROOT.TH1.SetDefaultSumw2()
    ROOT.TH1.StatOverflows()

    #------------------------------------------
    #check inputs
    if len(args.inputFileNames) == 0:
        raise SystemExit('\n***EXIT*** no files given')

    if len(args.inputHistNames) == 0:
        raise SystemExit('\n***EXIT*** no histograms given')
  
    if len(args.inputHistNames) != len(args.inputFileNames):
        raise SystemExit('\n***EXIT*** number of files and histograms is different: %s files and %s histograms'%(len(args.inputFileNames), len(args.inputHistNames)))

    print '\ninput files and histograms (%s):'%len(args.inputFileNames)
    for fileName, histName in zip(args.inputFileNames, args.inputHistNames):
        print '  %s\t%s'%(fileName,histName)

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #open files and get histograms
    files = []
    hists = []

    for ii in xrange( len(args.inputFileNames)):
        
        #open input file
        if not os.path.isfile(args.inputFileNames[ii]):
            raise SystemExit('\n***ERROR*** couldn\'t find input file: %s'%args.inputFileNames[ii])
        files.append(ROOT.TFile(args.inputFileNames[ii]))
    
        #get input histogram
        if not files[ii].Get(args.inputHistNames[ii]):
            raise SystemExit('\n***ERROR*** couldn\'t find input histogram %s in file %s'%(args.inputHistNames[ii],args.inputHistNames[ii]))
        hists.append(files[ii].Get(args.inputHistNames[ii]))

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #labels and legends
    ax = 0.65
    ay = 0.85
    size=20
    a = plotTools.getATLAS()
    p = plotTools.getInternal()
    n = plotTools.getNote(size)
    l = plotTools.getLegend(ax,ay,size)
    #line = plotTools.getLine()
    
    #------------------------------------------
    #canvas
    '''
    c = ROOT.TCanvas('c', 'c', 60, 50, 800, 600)
    c.cd()
    c.SetLogx(args.logx)
    c.SetLogy(args.logy)
    c.SetRightMargin(0.05)
    c.Draw()
    '''
    
    c   = ROOT.TCanvas('c', 'c', 50, 50, 800, 600)
    #cp  = ROOT.TPad("cp",  "cp",  0., 0.,   1., 1.)
    cp1 = ROOT.TPad("cp1", "cp1", 0., 0.33, 1., 1.)
    cp2 = ROOT.TPad("cp2", "cp2", 0., 0.,   1., 0.33)

    c.SetRightMargin(0.15)
    c.Draw()

    cp1.SetLogx(args.logx)
    cp1.SetLogy(args.logy)
    cp2.SetLogx(args.logx)
    cp2.SetLogy(False)
    cp1.SetBottomMargin(0.)
    cp1.SetBorderMode(0)
    cp2.SetTopMargin(0.)
    cp2.SetBottomMargin(0.3)
    cp2.SetBorderMode(0)
    cp1.Draw()
    cp2.Draw()

    #cp.SetFillStyle(4000)#transparent
    #cp.Draw()
    
    #------------------------------------------
    #plot distributions
    cp1.Clear()
    cp1.cd()

    #set histograms
    hs = ROOT.THStack('hs','hs')
    hs.Clear()

    for ii,hist in enumerate(hists):
        hist.SetMarkerColor( colors[ ii%len(colors) ] )
        hist.SetLineColor( colors[ ii%len(colors) ] )
        hist.SetMarkerStyle(20)
        hs.Add(hist)
        
    hs.Draw('nostack hist')

    if len(args.xlabel) != 0:        
        hs.GetXaxis().SetTitle(args.xlabel)
    else:
        hs.GetXaxis().SetTitle(args.inputHistNames[0])
    hs.GetXaxis().SetTitleFont(43)
    hs.GetXaxis().SetTitleSize(size)
    hs.GetXaxis().SetTitleOffset(1.5)
    hs.GetXaxis().SetLabelFont(43)
    hs.GetXaxis().SetLabelSize(size)
    #hs.GetXaxis().SetRange(firstBin,lastBin)

    hs.GetYaxis().SetTitle(args.ylabel)
    hs.GetYaxis().SetTitleFont(43)
    hs.GetYaxis().SetTitleSize(size)
    hs.GetYaxis().SetTitleOffset(1.5)
    hs.GetYaxis().SetLabelFont(43)
    hs.GetYaxis().SetLabelSize(size)
    #hs.GetYaxis().SetRangeUser(0.5,hs.GetMaximum()*10.)
    c.Update()

    #------------------------------------------
    #plot ratios
    cp2.Clear()
    cp2.cd()

    rs=[]

    #clone
    for ii in range(len(hists)):
        rs.append(hists[ii].Clone(hists[ii].GetName()+'_ratio'))

    #divide
    for ii in range(len(hists)):
        rs[ii].Divide(hists[0])

    #stack of ratio histograms
    hsr = ROOT.THStack('hsr','hsr')
    #NOTE set y axis range before drawing
    #hsr.SetMinimum(0.)#0.
    #hsr.SetMaximum(2.)#2.

    #set properties
    for ii in range(len(rs)):
        rs[ii].SetMarkerStyle(20)
        rs[ii].SetMarkerColor(colors[ii%len(colors)])
        rs[ii].SetLineColor(colors[ii%len(colors)])
        #if ii!=0: #NOTE skip the first ratio plot
        hsr.Add(rs[ii])

    hsr.Draw('nostack')
    
    #line
    #lowx = rs[0].GetBinLowEdge(1)
    #highx = rs[0].GetBinLowEdge(rs[0].GetNbinsX()+1)
    #print '\ndrawing the line in the range %s - %s'%(lowx,highx)
    #line.DrawLine(lowx,1.0,highx,1.0)
    
    hsr.GetYaxis().SetTitle('ratio')
    hsr.GetYaxis().SetTitleFont(43)
    hsr.GetYaxis().SetTitleSize(size)
    hsr.GetYaxis().SetTitleOffset(1.5)
    hsr.GetYaxis().SetLabelFont(43)
    hsr.GetYaxis().SetLabelSize(size)
        
    hsr.GetXaxis().SetTitle(args.xlabel)
    hsr.GetXaxis().SetTitleFont(43)
    hsr.GetXaxis().SetTitleSize(size)
    hsr.GetXaxis().SetTitleOffset(3.0)
    hsr.GetXaxis().SetLabelFont(43)
    hsr.GetXaxis().SetLabelSize(size)

    hsr.Draw('nostack hist')
    c.Update()

    #------------------------------------------
    #labels
    cp1.cd()

    ax = 0.20#0.65
    ay = 0.32#0.88
    spacing = 0.05#0.04
    a.DrawLatex(ax,ay,'ATLAS')
    p.DrawLatex(ax+0.13,ay,'simulation internal')#internal, simualtion internal
    c.Update()
        
    #notes
    print '\nnotes:'
    notes = []
    notes.append('#sqrt{s} = 13 TeV')
    if float(lumi) > 0.:
        notes.append('L_{int} = %s fb^{-1}'%lumi)
    notes+=args.notes
    for ii, note in enumerate(notes):
        n.DrawLatex(ax,ay-spacing*(ii+1),note)
        print '  %s'%note
    c.Update()
    
    #legend
    l.Clear()
    l.SetTextSize(20)
    for ii,hist in enumerate(hists):
        if len(args.labels) == len(hists):
            l.AddEntry(hists[ii], args.labels[ii], 'pl')
        else:
            l.AddEntry(hists[ii], os.path.basename(hists[ii].GetDirectory().GetFile().GetName()), 'pl')
    l.SetX1(ax)
    l.SetY1(ay-spacing*(len(notes)+1)-spacing*l.GetNRows())
    l.SetX2(ax+0.15)
    l.SetY2(ay-spacing*(len(notes)+1))
    l.Draw()
    c.Update()

    if args.wait:
        c.WaitPrimitive()
    if args.save:
        c.SaveAs(localdir+'/figures/histograms.%s.pdf'%args.tag)
Example #2
0
def injectDataLikeSignal(args):
    #---Get dir of the script
    localdir = os.path.dirname(os.path.realpath(__file__))

    #---setting the correct error for MC
    ROOT.TH1.SetDefaultSumw2()
    ROOT.TH1.StatOverflows()
    ROOT.TH2.SetDefaultSumw2()
    ROOT.TH2.StatOverflows()
    #---Opening json file
    try:
        json_data = open(args.config)
        config = json.load(json_data)
    except:
        print "Cannot open json config file: ", args.config

        print "---Aborting---"
        raise RuntimeError

    #---debug
    if args.debug:
        printConfig(config)
#--Test if RootFiles exist
#bkg
    doesRootFileExist(localdir + "/" + config["QCDFileDir"] +
                      config["QCDFile"])
    #signal
    signalFileList = makeSignalFileList(config)
    if args.debug:
        print("the signal file list being injected is ", signalFileList)
    for signalFile in signalFileList:
        doesRootFileExist(signalFile)
    #TODO test if signal inputfile exist
#create outputFile
    outFileName = makeOutputFileName(config, args)
    outFile = r.TFile(outFileName, "RECREATE")

    #---debug
    if args.debug:
        print("output file name : ", outFile)


#---Get bkg histogram and writing it
# skip if bkg histogram already exist

    bkgFile = ROOT.TFile(
        "/lustre/SCRATCH/atlas/ywng/WorkSpace/r21/r21SwiftNew/SensitivityStudies/source/scripts//../input_dijetISR2018/bkg//Fluctuated_SwiftFittrijet_HLT_j380_inclusiveAprRewdo.root",
        'READ')
    bkgHist = bkgFile.Get("basicBkgFrom4ParamFit_fluctuated").Clone()
    #bkgFile = ROOT.TFile(localdir+"/"+config["QCDFileDir"]+"/"+config["QCDFile"], 'READ')
    #print(bkgFile)
    #print(localdir+"/"+config["QCDFileDir"]+"/"+config["QCDFile"])
    #print(config["histBaseNameBkg"])
    #bkgHist = bkgFile.Get(config["histBaseNameBkg"]).Clone()

    bkgHist.SetTitle(config["histBaseNameBkg"] + "_QCD")

    outFile.cd()
    bkgHist.Write()

    histNameFromInput = config["histBasedNameSig"].format("")

    sigHist = {}
    for signalFile in signalFileList:
        mass = sensitivityTools.getSignalMass(signalFile)
        sigFile = ROOT.TFile(signalFile)
        print(sigFile)
        # getting the original size histogram
        print("chekc5 in loop")
        histNameSigUpdated = config["histBasedNameSig"].format(str(mass))
        histNameSigUpdated = histNameSigUpdated.encode("ascii")
        sigHist["ori"] = sigFile.Get(histNameSigUpdated)
        print(sigHist)
        sigHist["ori"].SetName(histNameSigUpdated + "_sig")
        sigHist["ori"].SetTitle(histNameSigUpdated + "_sig")
        # Scaling the signal histograms up
        sigHist["scaled"] = sigHist["ori"].Clone()
        # the scaling is actually a bit off....
        sigHist["scaled"].Scale(args.sigScale / sigHist["scaled"].Integral())
        sigHist["eff"] = plotTools.getEffectiveEntriesHistogram(
            sigHist["ori"], config["histBasedNameSig"].format("") + '_eff')
        #fluctuating the scaled histogram
        sigHist["dataLike"] = plotTools.getDataLikeHistYvonneVersion(
            sigHist["eff"], sigHist["scaled"], histNameSigUpdated + "_sig", 1,
            config["thresholdMass"])
        # I am skippig the smoothing part
        totHist = bkgHist.Clone()
        totHist.Add(sigHist["dataLike"])
        histNameToHist = histNameSigUpdated + "injectedToBkg"
        totHist.SetName(histNameToHist)
        totHist.SetTitle(histNameToHist)
        if args.debug:
            print("background hist entries: ", bkgHist.Integral())
            print("scale: ", args.sigScale)
            print("signalHistEntries: ", sigHist["dataLike"].Integral())
            print("total his entries: ", totHist.Integral())
        outFile.cd()
        totHist.Write()
        if args.plot:
            totHist.SetLineColor(r.kGreen)
            scaledSigHist = sigHist["dataLike"].Clone()
            scaledSigHist.Scale(totHist.Integral() /
                                sigHist["dataLike"].Integral())
            scaledSigHist.SetLineColor(r.kRed)
            c1 = r.TCanvas(1)
            c1.SetLogy()
            bkgHist.Draw()
            scaledSigHist.Draw("same")
            totHist.Draw("same")

            l = plotTools.getLegend(0.65, 0.85, 2)
            l.AddEntry(bkgHist, "QCDBkgnd", "l")
            l.AddEntry(scaledSigHist, "signal scaled up", "l")
            l.AddEntry(totHist, "total", "l")
            l.Draw()
            c1.SaveAs("../figures/step02Result." + model + "." + mass + "." +
                      args.sigScale + ".pdf")

    outFile.Write()
    outFile.Close()
def injectDataLikeSignal(args):

    print '\n******************************************'
    print 'inject data-like signal'

    #******************************************
    #set ATLAS style
    #Yvonne hacking this
    #using the python version
#just import the python one later
    if os.path.isfile(os.path.expanduser("/lustre/SCRATCH/atlas/ywng/WorkSpace/signalInjection/20171122_SensitivityScan/PlotSensitivity/RootStyle/AtlasStyle.C")):
        ROOT.gROOT.LoadMacro('/lustre/SCRATCH/atlas/ywng/WorkSpace/signalInjection/20171122_SensitivityScan/PlotSensitivity/RootStyle/AtlasStyle.C')
        #ROOT.set_color_env()

    #if os.path.isfile(os.path.expanduser('~/RootUtils/AtlasStyle.C')):
    #    ROOT.gROOT.LoadMacro('~/RootUtils/AtlasStyle.C')
    #    ROOT.SetAtlasStyle()
    #    #ROOT.set_color_env()
    else:
        print '\n***WARNING*** couldn\'t find ATLAS Style'
        #import AtlasStyle
        #AtlasStyle.SetAtlasStyle()

    #------------------------------------------
    #set error sum and overflow
    ROOT.TH1.SetDefaultSumw2()
    ROOT.TH1.StatOverflows()
    ROOT.TH2.SetDefaultSumw2()
    ROOT.TH2.StatOverflows()

    #------------------------------------------
    #input parameters
    print '\ninput parameters:'
    argsdict = vars(args)
    for ii in xrange(len(argsdict)):
        print '  %s = %s'%(argsdict.keys()[ii], argsdict.values()[ii],)

    slumi = ('%.1f'% float( str(args.lumi).replace('p','.'))).replace('.','p')

    #------------------------------------------
    #get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))

    #------------------------------------------
    #get settings
    print '\nconfig settings:'
    settings = ROOT.TEnv()
    if settings.ReadFile(args.configFileName,ROOT.EEnvLevel(0)) != 0:
        raise IOError('could not find sensitivity scan config file: %s'%args.configFileName)

    model = settings.GetValue('signalModel','')
    print '  signal model = %s'%model

    modelLabel = settings.GetValue('signalModelLabel','').replace('"','')
    print '  signal model label = %s'%modelLabel

    massValuesConfig = settings.GetValue('signalMasses','2000,3000,4000').split(',')
    massValuesConfig = [float(m) for m in massValuesConfig]
    print '  signal masses [GeV] = %s'%massValuesConfig

    histBaseNameBkg = settings.GetValue('histBaseNameBkg','mjj')
    print '  hist base name = %s'%histBaseNameBkg

    histBaseNameSig = settings.GetValue('histBaseNameSig','mjj')
    print '  hist base name = %s'%histBaseNameSig

    bTaggingWP = settings.GetValue('bTaggingWP','') #fix_8585
    print '  b-tagging WP = %s'%bTaggingWP

    axisLabel = settings.GetValue('axisLabel','m [GeV]')
    print '  hist x-axis label = %s'%axisLabel

    nPar = int(settings.GetValue('nFitParameters','3'))
    print '  n fit parameters = %s'%nPar

    thresholdMass = float(settings.GetValue('thresholdMass','1100.'))
    print '  threshold mass = %s'%thresholdMass

    seed = float(settings.GetValue('randomSeed','0'))
    print '  random seed = %s'%seed

    configNotes = settings.GetValue('notes','').split(',')
    print '  notes = %s'%configNotes

	#------------------------------------------
    #set variables
    slumi = ('%.1f'% float( str(args.lumi).replace('p','.'))).replace('.','p')

    histNameSig = histBaseNameSig

    histNameBkg = histBaseNameBkg
    print("Step2 histNameBkg: ", histNameBkg)

    if bTaggingWP != '':
        histNameBkg+='_'+bTaggingWP
    if args.debug:
        print '\nhist name = %s'%histNameBkg

    textSize=20

	#------------------------------------------
    #get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))

    #------------------------------------------
    #check data-like QCD file
    if not os.path.isfile(args.dataLikeQCDFileName):
        raise SystemExit('\n***ERROR*** couldn\'t find data-like QCD file: %s'%args.dataLikeQCDFileName)

    #------------------------------------------
    #check luminosity
    #if not slumi+'.ifb.' in args.dataLikeQCDFileName: #HANNO: commented out
    #    raise SystemExit('\n***ERROR*** is the lumi value right?')

    #------------------------------------------
    #check output file
    #outFileName = localdir+'/../results/signalplusbackground/signalplusbackground.'+model+'.'+slumi+'.ifb.'+histNameSig+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root'
    histNameFromInput=histNameSig.format("")
    outFileName = localdir+'/../results2/signalplusbackground/signalplusbackground.'+model+"."+slumi+'.ifb.'+histNameFromInput+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.root'
    #if os.path.isfile(outFileName):
    #    raise SystemExit('\n***WARNING*** output file exists already: %s'%outFileName)
    outFile = ROOT.TFile(outFileName, 'RECREATE')

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #data-like QCD hist
    dataLikeQCDFile = ROOT.TFile(args.dataLikeQCDFileName, 'READ')
    if not dataLikeQCDFile:
        raise SystemExit('\n***ERROR*** couldn\'t open data-like QCD input file: %s'%args.dataLikeQCDFileName)

    #QCDHist = dataLikeQCDFile.Get(histName+'_DL')
    QCDHist = dataLikeQCDFile.Get(histNameBkg)
    if not QCDHist:
        raise SystemExit('\n***ERROR*** couldn\'t find data-like QCD input histogram: %s'%histNameBkg)

    QCDHist.SetName(histNameBkg+'_QCD')
    print ("histNameBkg: ",histNameBkg)
    QCDHist.SetTitle(histNameBkg+'_QCD')
    outFile.cd()
    QCDHist.Write()

    #------------------------------------------
    #define canvas before entering loop over input signals
    if args.plot:
        c1 = ROOT.TCanvas('c1', 'c1', 100, 50, 800, 600)
        c1.SetLogx(1)
        c1.SetLogy(1)

    #------------------------------------------
    #get signal samples
    #fileList = os.listdir(localdir+'/../inputs/'+model+'/')
    fileList = os.listdir(localdir+'/../inputs/'+'Gauss_width3'+'/')
    print("sigFiles: ", fileList)
    for sigFileName in sorted(fileList):

        #------------------------------------------
        #check that it is a valid signal file
        if not '.root' in sigFileName:
            continue

        #------------------------------------------
        #get signal mass value from file name
        mass = sensitivityTools.getSignalMass(sigFileName)
        print '\n%s: %s GeV'%(model,mass)

        #check that the signal mass value is contained in the input list of signal masses (config file)
        #if float(mass) not in massValuesConfig:
        #    print '  skip'
        #    continue

        #------------------------------------------
        #TEST
        #if float(mass) != 3000.:
        #    continue

        #------------------------------------------
        #get signal hist
        sigFile = ROOT.TFile(localdir+'/../inputs/'+model+'/'+sigFileName)
        print("path: ", localdir+'/../inputs/'+model+'/'+sigFileName)
        print("histNameSig: ", histNameSig)

        histNameSigUpdated=histNameSig.format(str(mass))

        print("histNameSigUpdated: ", histNameSigUpdated)

        sigHist = sigFile.Get(histNameSigUpdated)

        print("sigHistIntegral: ", sigHist.Integral())

        print(sigHist, sigHist)

        print("histNameSig: ", histNameSigUpdated)

        sigHist.SetName(histNameSigUpdated+'_sig')

        sigHist.SetTitle(histNameSigUpdated+'_sig')

        if sigHist is not None and args.debug:
            print '\n  signal events:           ', sigHist.GetEntries()
            print '  effective signal events: ', sigHist.GetEffectiveEntries()
            print '  sum of signal weights:   ', sigHist.GetSumOfWeights()

        #------------------------------------------
        #scaled signal hist
        scaleFactor = float(args.lumi)*1000
        #NOTE cross sections are included already
        '''
        if args.fixCS:
            ZprimebbCrossSection = sensitivityTools.getZprimebbCrossSection(mass)
            print '\n  Z\'->bb cross section applied: %s fb'%ZprimebbCrossSection
            scaleFactor*=ZprimebbCrossSection
        '''
        if args.debug:
            print '\n  scale factor: %s'%scaleFactor

        #scale histogram by factor
        scaledSigHist = sigHist.Clone()
        scaledSigHist.Scale(scaleFactor)
        scaledSigHist.SetName(histNameSig+'_scaledSig')

        if scaledSigHist is not None and args.debug:
            print '\n  events after scaling:            ', scaledSigHist.GetEntries()
            print '  effective entries after scaling: ', scaledSigHist.GetEffectiveEntries()
            print '  sum of weights after scaling:    ', scaledSigHist.GetSumOfWeights()
            print '  first bin above 0 after scaline: ', scaledSigHist.FindFirstBinAbove(0,1)

        #------------------------------------------
        #effective entries signal hist
        effEntSigHist = plotTools.getEffectiveEntriesHistogram(sigHist, histNameSig+'_eff')
        if args.debug:
            print '\n  entries in effective entries:           ', effEntSigHist.GetEntries()
            print '  effective entries in effective entries: ', effEntSigHist.GetEffectiveEntries()
            print '  sum of weights in effective entries:    ', effEntSigHist.GetSumOfWeights()

        #------------------------------------------
        #data-like signal hist
        histNameSig2=histNameSig.format(str(int(mass)))
        dataLikeSigHist = plotTools.getDataLikeHist(effEntSigHist, scaledSigHist, histNameSig2+'_sig', seed, thresholdMass)
        firstBin = -1
        for ii in xrange(dataLikeSigHist.GetNbinsX()):
            if dataLikeSigHist.GetBinContent(ii)>0.:
                firstBin=ii
                break

        if firstBin > 0.:
            print '  data-like signal histogram starts at %s GeV'%dataLikeSigHist.GetBinLowEdge(firstBin)
        else:
            print '  data-like signal histogram is empty: n. entries = %s'%dataLikeSigHist.GetEntries()

        #------------------------------------------
        #smooth signal hist
        histNameSigSmooth=histNameSig.format(str(int(mass)))
        smoothSigHist = plotTools.getSmoothHistogram(scaledSigHist, histNameSigSmooth+'_sig_smooth')

        #------------------------------------------
        #remove any signal entry if there are no QCD entries (low mass region)
        if dataLikeSigHist is not None:
            for ii in xrange(QCDHist.GetNbinsX()):
                if QCDHist.GetBinContent(ii) == 0:
                    dataLikeSigHist.SetBinContent(ii,0)
                    dataLikeSigHist.SetBinError(ii,0)
                    smoothSigHist.SetBinContent(ii,0)
                    smoothSigHist.SetBinError(ii,0)
                else:
                    break

        #------------------------------------------
        #signal+QCD hist
        if QCDHist is not None and args.debug:
            print '\n  QCD events:           ', QCDHist.GetEntries()
            print '  QCD effective events: ', QCDHist.GetEffectiveEntries()
            print '  QCD sum of weights:   ', QCDHist.GetSumOfWeights()

        totHist = QCDHist.Clone()

        #..........................................
        #ORIGINAL
        #if dataLikeSigHist is not None:
        #    totHist.Add(dataLikeSigHist)

        #..........................................
        #NEW
        if dataLikeSigHist.GetBinContent(ii)>0.:
            print '  injecting data-like signal'
            totHist.Add(dataLikeSigHist)
        else:
            print '  not enough effective entries: injecting smoooth signal'
            totHist.Add(smoothSigHist)
        #END NEW
        #..........................................
        histNameToHist=histNameSig.format(str( int(mass)))

        histNameToHist=histNameToHist+"injectedToBkg"
        totHist.SetName(histNameToHist)
        totHist.SetTitle(histNameToHist)

        if totHist is not None and args.debug:
            print '\n  tot events:           ', totHist.GetEntries()
            print '  tot effective events: ', totHist.GetEffectiveEntries()
            print '  tot sum of weights:   ', totHist.GetSumOfWeights()

        #------------------------------------------
        #write to output file
        outFile.cd()
        dataLikeSigHist.Write()
        totHist.Write()

        #------------------------------------------
        #plot
        if args.plot:

            QCDHist.SetMarkerStyle(24)

            totHist.SetMarkerStyle(20)

            effEntSigHist.SetMarkerStyle(20)
            effEntSigHist.SetMarkerColor(ROOT.kGreen+1)
            effEntSigHist.SetLineColor(ROOT.kGreen+1)

            sigHist.SetMarkerStyle(25)
            sigHist.SetMarkerColor(ROOT.kAzure+1)
            sigHist.SetLineColor(ROOT.kAzure+1)

            scaledSigHist.SetMarkerStyle(26)
            scaledSigHist.SetMarkerColor(ROOT.kOrange+1)
            scaledSigHist.SetLineColor(ROOT.kOrange+1)

            dataLikeSigHist.SetMarkerStyle(24)
            dataLikeSigHist.SetMarkerColor(ROOT.kRed+1)
            dataLikeSigHist.SetLineColor(ROOT.kRed+1)

            smoothSigHist.SetMarkerStyle(32)
            smoothSigHist.SetMarkerColor(ROOT.kMagenta+1)
            smoothSigHist.SetLineColor(ROOT.kMagenta+1)

            hs = ROOT.THStack('hs','hs')
            hs.Add(QCDHist)
            hs.Add(totHist)
            hs.Add(effEntSigHist)
            hs.Add(sigHist)
            hs.Add(scaledSigHist)
            hs.Add(dataLikeSigHist)
            hs.Add(smoothSigHist)
            hs.Draw('nostack')

            hs.GetXaxis().SetTitle(axisLabel)
            hs.GetXaxis().SetTitleFont(43)
            hs.GetXaxis().SetTitleSize(textSize)
            #hs.GetXaxis().SetTitleOffset(1.5)
            hs.GetXaxis().SetLabelFont(43)
            hs.GetXaxis().SetLabelSize(textSize)

            hs.GetYaxis().SetTitle('entries')
            hs.GetYaxis().SetTitleFont(43)
            hs.GetYaxis().SetTitleSize(textSize)
            #hs.GetYaxis().SetTitleOffset(1.5)
            hs.GetYaxis().SetLabelFont(43)
            hs.GetYaxis().SetLabelSize(textSize)

            #------------------------------------------
            #labels and legends
            ax = 0.65
            ay = 0.88 #0.85
            a = plotTools.getATLAS()
            p = plotTools.getInternal()
            n = plotTools.getNote(textSize)
            l = plotTools.getLegend(ax,ay,textSize)

            #ATLAS internal
            a.DrawLatex(ax,ay,'ATLAS')
            p.DrawLatex(ax+0.13,ay,'internal')

            #notes
            notes=[]
            notes.append('#sqrt{s} = 13 TeV')
            if float(args.lumi) < -0.1:
                notes.append('L_{int} = %.0f pb^{-1}'%float(args.lumi)*1e3)
            else:
                notes.append('L_{int} = %.1f fb^{-1}'%float(args.lumi))
            if modelLabel != '':
                notes.append('m_{%s} = %0.f GeV'%(modelLabel,float(mass)))
            else:
                notes.append('m_{%s} = %0.f GeV'%(model,float(mass)))
            #notes.append('%s par. fit func.'%nPar)
            notes+=configNotes

            for ii, note in enumerate(notes):
                n.DrawLatex(ax,ay-0.04*(ii+1),note)

            #legend
            l.Clear()
            l.SetTextSize(textSize)
            l.AddEntry(QCDHist,"QCD background","pl")
            l.AddEntry(totHist,"signal plus backgournd","pl")
            l.AddEntry(sigHist,"non-scaled signal","pl")
            l.AddEntry(scaledSigHist,"scaled signal","pl")
            l.AddEntry(effEntSigHist,"effective signal","pl")
            l.AddEntry(dataLikeSigHist,"data-like signal","pl")
            l.AddEntry(smoothSigHist,"smooth signal","pl")
            l.SetX1(ax)
            l.SetY1(ay - 0.04*(len(notes)+1) - 0.04*l.GetNRows())
            l.SetX2(ax+0.15)
            l.SetY2(ay - 0.04*(len(notes)+1))
            l.Draw()

            c1.Update()
            if args.wait:
                c1.WaitPrimitive()
            c1.SaveAs('../figures/signalplusbackground.'+model+'.'+mass+'.GeV.'+slumi+'.ifb.'+histNameSig+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.pdf')

    outFile.Write()
    outFile.Close()
Example #4
0
def plotHists(args):

    print '\n******************************************'
    print 'plot histograms together'

    #------------------------------------------
    #input parameters
    print '\ninput parameters:'
    argsdict = vars(args)
    for ii in xrange(len(argsdict)):
        print '  %s = %s' % (
            argsdict.keys()[ii],
            argsdict.values()[ii],
        )

    #------------------------------------------
    #define useful variables
    lumi = float(args.lumi)  #fb^-1
    colors = plotTools.getColors()

    #------------------------------------------
    #get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))

    #------------------------------------------
    #set error sum and overflow
    ROOT.TH1.SetDefaultSumw2()
    ROOT.TH1.StatOverflows()

    #------------------------------------------
    #check inputs
    if len(args.inputFileNames) == 0:
        raise SystemExit('\n***EXIT*** no files given')

    if len(args.inputHistNames) == 0:
        raise SystemExit('\n***EXIT*** no histograms given')

    if len(args.inputHistNames) != len(args.inputFileNames):
        raise SystemExit(
            '\n***EXIT*** number of files and histograms is different: %s files and %s histograms'
            % (len(args.inputFileNames), len(args.inputHistNames)))

    print '\ninput files and histograms (%s):' % len(args.inputFileNames)
    for fileName, histName in zip(args.inputFileNames, args.inputHistNames):
        print '  %s\t%s' % (fileName, histName)

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #open files and get histograms
    files = []
    hists = []

    for ii in xrange(len(args.inputFileNames)):

        #open input file
        if not os.path.isfile(args.inputFileNames[ii]):
            raise SystemExit('\n***ERROR*** couldn\'t find input file: %s' %
                             args.inputFileNames[ii])
        files.append(ROOT.TFile(args.inputFileNames[ii]))

        #get input histogram
        if not files[ii].Get(args.inputHistNames[ii]):
            raise SystemExit(
                '\n***ERROR*** couldn\'t find input histogram %s in file %s' %
                (args.inputHistNames[ii], args.inputHistNames[ii]))
        hists.append(files[ii].Get(args.inputHistNames[ii]))

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #labels and legends
    ax = 0.65
    ay = 0.85
    size = 20
    a = plotTools.getATLAS()
    p = plotTools.getInternal()
    n = plotTools.getNote(size)
    l = plotTools.getLegend(ax, ay, size)
    #line = plotTools.getLine()

    #------------------------------------------
    #canvas
    '''
    c = ROOT.TCanvas('c', 'c', 60, 50, 800, 600)
    c.cd()
    c.SetLogx(args.logx)
    c.SetLogy(args.logy)
    c.SetRightMargin(0.05)
    c.Draw()
    '''

    c = ROOT.TCanvas('c', 'c', 50, 50, 800, 600)
    #cp  = ROOT.TPad("cp",  "cp",  0., 0.,   1., 1.)
    cp1 = ROOT.TPad("cp1", "cp1", 0., 0.33, 1., 1.)
    cp2 = ROOT.TPad("cp2", "cp2", 0., 0., 1., 0.33)

    c.SetRightMargin(0.15)
    c.Draw()

    cp1.SetLogx(args.logx)
    cp1.SetLogy(args.logy)
    cp2.SetLogx(args.logx)
    cp2.SetLogy(False)
    cp1.SetBottomMargin(0.)
    cp1.SetBorderMode(0)
    cp2.SetTopMargin(0.)
    cp2.SetBottomMargin(0.3)
    cp2.SetBorderMode(0)
    cp1.Draw()
    cp2.Draw()

    #cp.SetFillStyle(4000)#transparent
    #cp.Draw()

    #------------------------------------------
    #plot distributions
    cp1.Clear()
    cp1.cd()

    #set histograms
    hs = ROOT.THStack('hs', 'hs')
    hs.Clear()

    for ii, hist in enumerate(hists):
        hist.SetMarkerColor(colors[ii % len(colors)])
        hist.SetLineColor(colors[ii % len(colors)])
        hist.SetMarkerStyle(20)
        hs.Add(hist)

    hs.Draw('nostack hist')

    if len(args.xlabel) != 0:
        hs.GetXaxis().SetTitle(args.xlabel)
    else:
        hs.GetXaxis().SetTitle(args.inputHistNames[0])
    hs.GetXaxis().SetTitleFont(43)
    hs.GetXaxis().SetTitleSize(size)
    hs.GetXaxis().SetTitleOffset(1.5)
    hs.GetXaxis().SetLabelFont(43)
    hs.GetXaxis().SetLabelSize(size)
    #hs.GetXaxis().SetRange(firstBin,lastBin)

    hs.GetYaxis().SetTitle(args.ylabel)
    hs.GetYaxis().SetTitleFont(43)
    hs.GetYaxis().SetTitleSize(size)
    hs.GetYaxis().SetTitleOffset(1.5)
    hs.GetYaxis().SetLabelFont(43)
    hs.GetYaxis().SetLabelSize(size)
    #hs.GetYaxis().SetRangeUser(0.5,hs.GetMaximum()*10.)
    c.Update()

    #------------------------------------------
    #plot ratios
    cp2.Clear()
    cp2.cd()

    rs = []

    #clone
    for ii in range(len(hists)):
        rs.append(hists[ii].Clone(hists[ii].GetName() + '_ratio'))

    #divide
    for ii in range(len(hists)):
        rs[ii].Divide(hists[0])

    #stack of ratio histograms
    hsr = ROOT.THStack('hsr', 'hsr')
    #NOTE set y axis range before drawing
    #hsr.SetMinimum(0.)#0.
    #hsr.SetMaximum(2.)#2.

    #set properties
    for ii in range(len(rs)):
        rs[ii].SetMarkerStyle(20)
        rs[ii].SetMarkerColor(colors[ii % len(colors)])
        rs[ii].SetLineColor(colors[ii % len(colors)])
        #if ii!=0: #NOTE skip the first ratio plot
        hsr.Add(rs[ii])

    hsr.Draw('nostack')

    #line
    #lowx = rs[0].GetBinLowEdge(1)
    #highx = rs[0].GetBinLowEdge(rs[0].GetNbinsX()+1)
    #print '\ndrawing the line in the range %s - %s'%(lowx,highx)
    #line.DrawLine(lowx,1.0,highx,1.0)

    hsr.GetYaxis().SetTitle('ratio')
    hsr.GetYaxis().SetTitleFont(43)
    hsr.GetYaxis().SetTitleSize(size)
    hsr.GetYaxis().SetTitleOffset(1.5)
    hsr.GetYaxis().SetLabelFont(43)
    hsr.GetYaxis().SetLabelSize(size)

    hsr.GetXaxis().SetTitle(args.xlabel)
    hsr.GetXaxis().SetTitleFont(43)
    hsr.GetXaxis().SetTitleSize(size)
    hsr.GetXaxis().SetTitleOffset(3.0)
    hsr.GetXaxis().SetLabelFont(43)
    hsr.GetXaxis().SetLabelSize(size)

    hsr.Draw('nostack hist')
    c.Update()

    #------------------------------------------
    #labels
    cp1.cd()

    ax = 0.20  #0.65
    ay = 0.32  #0.88
    spacing = 0.05  #0.04
    a.DrawLatex(ax, ay, 'ATLAS')
    p.DrawLatex(ax + 0.13, ay,
                'simulation internal')  #internal, simualtion internal
    c.Update()

    #notes
    print '\nnotes:'
    notes = []
    notes.append('#sqrt{s} = 13 TeV')
    if float(lumi) > 0.:
        notes.append('L_{int} = %s fb^{-1}' % lumi)
    notes += args.notes
    for ii, note in enumerate(notes):
        n.DrawLatex(ax, ay - spacing * (ii + 1), note)
        print '  %s' % note
    c.Update()

    #legend
    l.Clear()
    l.SetTextSize(20)
    for ii, hist in enumerate(hists):
        if len(args.labels) == len(hists):
            l.AddEntry(hists[ii], args.labels[ii], 'pl')
        else:
            l.AddEntry(
                hists[ii],
                os.path.basename(hists[ii].GetDirectory().GetFile().GetName()),
                'pl')
    l.SetX1(ax)
    l.SetY1(ay - spacing * (len(notes) + 1) - spacing * l.GetNRows())
    l.SetX2(ax + 0.15)
    l.SetY2(ay - spacing * (len(notes) + 1))
    l.Draw()
    c.Update()

    if args.wait:
        c.WaitPrimitive()
    if args.save:
        c.SaveAs(localdir + '/figures/histograms.%s.pdf' % args.tag)
Example #5
0
def getDataLikeQCD(args):

    print '\n******************************************'
    print 'get data-like QCD'

    #******************************************
    #set ATLAS style
    if os.path.isfile(os.path.expanduser('~/RootUtils/AtlasStyle.C')):
        ROOT.gROOT.LoadMacro('~/RootUtils/AtlasStyle.C')
        ROOT.SetAtlasStyle()
        ROOT.set_color_env()
    else:
        print '\n***WARNING*** couldn\'t find ATLAS Style'
        #import AtlasStyle
        #AtlasStyle.SetAtlasStyle()

    #------------------------------------------
    #set error sum and overflow
    ROOT.TH1.SetDefaultSumw2()
    ROOT.TH1.StatOverflows()
    ROOT.TH2.SetDefaultSumw2()
    ROOT.TH2.StatOverflows()

    #------------------------------------------
    #input parameters
    print '\ninput parameters:'
    argsdict = vars(args)
    for ii in xrange(len(argsdict)):
        print '  %s = %s' % (
            argsdict.keys()[ii],
            argsdict.values()[ii],
        )

    #------------------------------------------
    #get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))

    #------------------------------------------
    #get settings
    print '\nconfig settings:'
    settings = ROOT.TEnv()
    if settings.ReadFile(args.configFileName, ROOT.EEnvLevel(0)) != 0:
        raise IOError('could not find sensitivity scan config file: %s' %
                      args.configFileName)

    QCDFileName = settings.GetValue(
        'QCDFile', '../inputs/QCD/histograms.mc.dijet.1p0.ifb.root')
    print '  QCD input file = %s' % QCDFileName

    patchFileName = settings.GetValue('patchFile', '')
    print '  patch file = %s' % patchFileName

    histBaseName = settings.GetValue('histBaseName', 'mjj')
    print '  hist base name = %s' % histBaseName

    bTaggingWP = settings.GetValue('bTaggingWP', '')  #fix_8585
    print '  b-tagging WP = %s' % bTaggingWP

    axisLabel = settings.GetValue('axisLabel', 'm [GeV]')
    print '  hist x-axis label = %s' % axisLabel

    nPar = int(settings.GetValue('nFitParameters', '3'))
    print '  n fit parameters = %s' % nPar

    thresholdMass = float(settings.GetValue('thresholdMass', '1100.'))
    print '  threshold mass = %s' % thresholdMass

    seed = float(settings.GetValue('randomSeed', '0'))
    print '  random seed = %s' % seed

    configNotes = settings.GetValue('notes', '').split(',')
    print '  notes = %s' % configNotes

    #------------------------------------------
    #set variables
    slumi = ('%.1f' % float(str(args.lumi).replace('p', '.'))).replace(
        '.', 'p')

    histName = histBaseName
    if bTaggingWP != '':
        histName += '_' + bTaggingWP
    if args.debug:
        print '\nhist name = %s' % histName

    textSize = 20

    #------------------------------------------
    #get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))

    #------------------------------------------
    #check QCD file
    if not os.path.isfile(QCDFileName):
        raise SystemExit('\n***ERROR*** couldn\'t find QCD file: %s' %
                         QCDFileName)

#------------------------------------------
#check output file
    outFileName = localdir + '/../results/datalikeQCD/datalikeQCD.' + slumi + '.ifb.' + histName + '.%i' % nPar + '.par.%i' % seed + '.seed.' + args.tag + '.root'
    if not (args.overwrite):
        if os.path.isfile(outFileName):
            raise SystemExit('\n***WARNING*** output file exists already: %s' %
                             outFileName)

#------------------------------------------
#QCD hist
    QCDFile = ROOT.TFile(QCDFileName, 'READ')
    if not QCDFile:
        raise SystemExit('\n***ERROR*** couldn\'t open QCD input file: %s' %
                         QCDFilename)

    QCDHist = QCDFile.Get(histName)
    if not QCDHist:
        raise SystemExit(
            '\n***ERROR*** couldn\'t find QCD input histogram: %s' % histName)

    QCDHist.SetName(histName + '_input')

    #------------------------------------------
    #scaled QCD hist
    scaledHist = QCDHist.Clone()
    scaledHist.SetName(histName + '_scaled')
    scaledHist.SetTitle(histName + '_scaled')
    scaleFactor = float(args.lumi)
    if args.debug:
        print 'scale factor = %s' % scaleFactor
    scaledHist.Scale(scaleFactor)

    #------------------------------------------
    #effective entries QCD hist
    effEntHist = plotTools.getEffectiveEntriesHistogram(
        QCDHist, histName + '_eff')

    #------------------------------------------
    #data-like QCD hist
    pureDataLikeHist = plotTools.getDataLikeHist(effEntHist, scaledHist,
                                                 histName + '_pureDL', seed,
                                                 thresholdMass)
    firstBin = -1
    for ii in xrange(pureDataLikeHist.GetNbinsX()):
        if pureDataLikeHist.GetBinContent(ii) > 0.:
            firstBin = ii
            break

    if firstBin > 0.:
        print '\ndata-like histogram starts at %s GeV' % pureDataLikeHist.GetBinLowEdge(
            firstBin)
    else:
        raise SystemExit('\n***ERROR*** data-like histogram has no entries')

    #------------------------------------------
    #smooth QCD hist
    smoothHist = plotTools.getSmoothHistogram(scaledHist, histName + '_smooth')

    #------------------------------------------
    #OPTION 1 PATCH: patch from smooth hist
    #NOTE this introduces features in the background, use option 2 instead
    '''
    #patch data-like hist with smooth hist + Poisson noise to extend low mass region when there are not enough effective entries
    dataLikeHist = pureDataLikeHist.Clone()
    dataLikeHist.SetName(histName+'_DL')
    dataLikeHist.SetTitle(histName+'_DL')

    patchHist = ROOT.TH1D(histName+'_patch', histName+'_patch', QCDHist.GetXaxis().GetNbins(), QCDHist.GetXaxis().GetXbins().GetArray())
    if args.patch:
        for ii in xrange( int( round(pureDataLikeHist.GetNbinsX()))):
            if ii > firstBin:
                break
            if pureDataLikeHist.GetXaxis().GetBinUpEdge(ii) > thresholdMass and dataLikeHist.GetBinContent(ii) == 0.:

                #bincontent
                bincontent = int( round(scaledHist.GetBinContent(ii)))

                #random number generator
                #NOTE the seed for each bin must be always the same
                binSeed = int( round( patchHist.GetBinCenter(ii) + seed*1e5))
                rand3 = ROOT.TRandom3(binSeed)

                #add Poisson noise
                bincontent = int( round( rand3.PoissonD(bincontent)))

                #fill
                for jj in xrange(bincontent):
                    patchHist.Fill(patchHist.GetBinCenter(ii))

        #patch data-like histogram
        dataLikeHist.Add(patchHist)
    '''
    #------------------------------------------
    #END OPTION 1 PATCH

    #------------------------------------------
    #OPTION 2 PATCH: patch from smooth fit
    #patch data-like hist with fit of smooth hist; then apply Poisson noise
    dataLikeHist = pureDataLikeHist.Clone()
    dataLikeHist.SetName(histName + '_DL')
    dataLikeHist.SetTitle(histName + '_DL')

    #..........................................
    #mjj or mbj or mbb? 85% or 77%? fixed or flat? 3 or 4 parameter fit?
    #this is setting the output file name TODO Yvonne: fix this
    if len(patchFileName) == 0:
        if 'mbb' in histName:
            if nPar == 3:
                if 'fix_8585' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbb_fix_8585_smooth.0.seed.3.par.root'
                elif 'flt_8585' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbb_flt_8585_smooth.0.seed.3.par.root'
                elif 'fix_7777' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbb_fix_7777_smooth.0.seed.3.par.root'
                elif 'flt_7777' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbb_flt_7777_smooth.0.seed.3.par.root'
                else:
                    args.patch = False
            elif nPar == 4:
                if 'fix_8585' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbb_fix_8585_smooth.0.seed.4.par.root'
                elif 'flt_8585' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbb_flt_8585_smooth.0.seed.4.par.root'
                elif 'fix_7777' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbb_fix_7777_smooth.0.seed.4.par.root'
                elif 'flt_7777' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbb_flt_7777_smooth.0.seed.4.par.root'
                else:
                    args.patch = False
            else:
                args.patch = False
        elif 'mbj' in histName:
            if nPar == 3:
                if 'fix_8585' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbj_fix_8585_smooth.0.seed.3.par.root'
                elif 'flt_8585' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbj_flt_8585_smooth.0.seed.3.par.root'
                elif 'fix_7777' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbj_fix_7777_smooth.0.seed.3.par.root'
                elif 'flt_7777' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbj_flt_7777_smooth.0.seed.3.par.root'
                else:
                    args.patch = False
            elif nPar == 4:
                if 'fix_8585' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbj_fix_8585_smooth.0.seed.4.par.root'
                elif 'flt_8585' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbj_flt_8585_smooth.0.seed.4.par.root'
                elif 'fix_7777' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbj_fix_7777_smooth.0.seed.4.par.root'
                elif 'flt_7777' in histName:
                    patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mbj_flt_7777_smooth.0.seed.4.par.root'
                else:
                    args.patch = False
            else:
                args.patch = False
        else:
            if nPar == 3:
                patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mjj_smooth.0.seed.3.par.root'
            elif nPar == 4:
                patchFileName = localdir + '/../data/searchPhase.patch.QCD.20p0.ifb.mjj_smooth.0.seed.4.par.root'
            else:
                args.patch = False

    #..........................................
    #open patch file
    if not os.path.isfile(patchFileName):
        raise SystemExit('\n***ERROR*** couldn\'t find patch file: %s' %
                         patchFileName)
    patchFile = ROOT.TFile(patchFileName, 'READ')
    if not patchFile:
        raise SystemExit('\n***ERROR*** couldn\'t open patch file: %s' %
                         patchFileName)

    #..........................................
    #get patch hist
    fullPatchHist = patchFile.Get("basicBkgFrom4ParamFit")

    #check the binninng of the patch and the nominal hist are the same
    #if QCDHist.GetXaxis().GetXbins().GetArray() != fullPatchHist.GetXaxis().GetXbins().GetArray():
    if QCDHist.GetNbinsX() != fullPatchHist.GetNbinsX(
    ) or QCDHist.GetBinLowEdge(1) != fullPatchHist.GetBinLowEdge(
            1) or QCDHist.GetBinLowEdge(
                QCDHist.GetNbinsX()) != fullPatchHist.GetBinLowEdge(
                    fullPatchHist.GetNbinsX()):
        raise SystemExit(
            '\n***ERROR*** QCD hist and patch hist have different binning')

    #..........................................
    #scale patch to right luminosity
    #NOTE the patch are obtained from 20/fb fits
    patchScaleFactor = float(args.lumi) / 20.
    print '\npatch scale factor = %s' % patchScaleFactor
    fullPatchHist.Scale(patchScaleFactor)

    #..........................................
    #apply patch
    patchHist = ROOT.TH1D(histName + '_patch', histName + '_patch',
                          QCDHist.GetXaxis().GetNbins(),
                          QCDHist.GetXaxis().GetXbins().GetArray())
    if args.patch:
        for ii in xrange(int(round(pureDataLikeHist.GetNbinsX()))):
            if ii > firstBin:
                break
            if pureDataLikeHist.GetXaxis().GetBinUpEdge(
                    ii) > thresholdMass and dataLikeHist.GetBinContent(
                        ii) == 0.:

                #bincontent
                bincontent = int(round(fullPatchHist.GetBinContent(ii)))

                #random number generator
                #NOTE the seed for each bin must be always the same
                binSeed = int(round(patchHist.GetBinCenter(ii) + seed * 1e5))
                rand3 = ROOT.TRandom3(binSeed)

                #add Poisson noise
                bincontent = int(round(rand3.PoissonD(bincontent)))

                #fill
                for jj in xrange(bincontent):
                    patchHist.Fill(patchHist.GetBinCenter(ii))

        #patch data-like histogram
        dataLikeHist.Add(patchHist)
    else:
        print 'patch not applied'
    #END OPTION 2 PATCH
    #------------------------------------------

    #------------------------------------------
    #check entries and weights of the data-like QCD background
    if args.debug:
        print '\nevents:		   ', pureDataLikeHist.GetEntries()
        print 'effective events: ', pureDataLikeHist.GetEffectiveEntries()
        print 'sum of weights:   ', pureDataLikeHist.GetSumOfWeights()

    #------------------------------------------
    #write data-like hist to output file
    outFile = ROOT.TFile(outFileName, 'RECREATE')
    outFile.cd()
    scaledHist.Write()
    effEntHist.Write()
    pureDataLikeHist.Write()
    smoothHist.Write()
    patchHist.Write()
    dataLikeHist.Write()
    outFile.Write()

    #------------------------------------------
    #plot
    if args.plot:
        c1 = ROOT.TCanvas('c1', 'c1', 100, 50, 800, 600)
        c1.SetLogx(not args.linx)
        c1.SetLogy(1)

        effEntHist.SetMarkerColor(ROOT.kGreen + 1)
        effEntHist.SetMarkerStyle(20)
        effEntHist.SetLineColor(ROOT.kGreen + 1)

        QCDHist.SetMarkerColor(ROOT.kAzure + 1)
        QCDHist.SetMarkerStyle(25)
        QCDHist.SetLineColor(ROOT.kAzure + 1)

        scaledHist.SetMarkerColor(ROOT.kOrange + 1)
        scaledHist.SetMarkerStyle(26)
        scaledHist.SetLineColor(ROOT.kOrange + 1)

        patchHist.SetMarkerColor(ROOT.kMagenta + 1)
        patchHist.SetMarkerStyle(32)
        patchHist.SetLineColor(ROOT.kMagenta + 1)

        pureDataLikeHist.SetMarkerColor(ROOT.kRed + 1)
        pureDataLikeHist.SetMarkerStyle(24)
        pureDataLikeHist.SetLineColor(ROOT.kRed + 1)

        hs = ROOT.THStack('hs', 'hs')
        hs.Add(effEntHist)
        hs.Add(QCDHist)
        hs.Add(scaledHist)
        hs.Add(patchHist)
        hs.Add(pureDataLikeHist)
        hs.Draw('nostack')

        hs.GetXaxis().SetTitle(axisLabel)
        hs.GetXaxis().SetTitleFont(43)
        hs.GetXaxis().SetTitleSize(textSize)
        #hs.GetXaxis().SetTitleOffset(1.5)
        hs.GetXaxis().SetLabelFont(43)
        hs.GetXaxis().SetLabelSize(textSize)

        hs.GetYaxis().SetTitle('entries')
        hs.GetYaxis().SetTitleFont(43)
        hs.GetYaxis().SetTitleSize(textSize)
        #hs.GetYaxis().SetTitleOffset(1.5)
        hs.GetYaxis().SetLabelFont(43)
        hs.GetYaxis().SetLabelSize(textSize)

        #use new axis in TeV instead of GeV
        #NOTE this is over-complicated and will be used only if requested
        #NOTE when the x-axis is logarithmic, GetUxm* will return the exponent only
        '''
        #remove the current axis
        hs.GetXaxis().SetLabelOffset(999)
        hs.GetXaxis().SetTickLength(0)

        #map the axis values to -x
        func = ROOT.TF1('func', 'x/1000.', ROOT.gPad.GetUxmin()/1000., ROOT.gPad.GetUxmax()/1000.)
        newaxis = ROOT.TGaxis(  ROOT.gPad.GetUxmin(),
                                ROOT.gPad.GetUymin(),
                                ROOT.gPad.GetUxmax(),
                                ROOT.gPad.GetUymin(),
                                'func',510,'+')

        newaxis.SetLabelOffset(0.005)
        newaxis.SetLabelFont(43)
        newaxis.SetLabelSize(textSize)
        newaxis.Draw()
        '''

        #------------------------------------------
        #labels and legends
        ax = 0.65
        ay = 0.88  #0.85
        a = plotTools.getATLAS()
        p = plotTools.getInternal()
        n = plotTools.getNote(textSize)
        l = plotTools.getLegend(ax, ay, textSize)

        #ATLAS internal
        a.DrawLatex(ax, ay, 'ATLAS')
        p.DrawLatex(ax + 0.13, ay, 'internal')

        #notes
        notes = []
        notes.append('#sqrt{s} = 13 TeV')
        if float(args.lumi) < 0.1:
            notes.append('L_{int} = %.0f pb^{-1}' % float(args.lumi) * 1e3)
        else:
            notes.append('L_{int} = %.1f fb^{-1}' % float(args.lumi))
        #notes.append('%s par. fit func.'%nPar)
        notes += configNotes

        for ii, note in enumerate(notes):
            n.DrawLatex(ax, ay - 0.04 * (ii + 1), note)

#legend
        l.Clear()
        l.SetTextSize(textSize)
        l.AddEntry(QCDHist, 'non-scaled', 'pl')
        l.AddEntry(scaledHist, 'scaled', 'pl')
        l.AddEntry(effEntHist, 'effective', 'pl')
        l.AddEntry(pureDataLikeHist, 'data-like', 'pl')
        l.AddEntry(patchHist, 'patch', 'pl')
        l.SetX1(ax)
        l.SetY1(ay - 0.04 * (len(notes) + 1) - 0.04 * l.GetNRows())
        l.SetX2(ax + 0.15)
        l.SetY2(ay - 0.04 * (len(notes) + 1))
        l.Draw()

        c1.Update()
        if args.wait:
            c1.WaitPrimitive()
        c1.SaveAs('../figures/datalikeQCD.' + slumi + '.ifb.' + histName +
                  '.%i' % nPar + '.par.%i' % seed + '.seed.' + args.tag +
                  '.pdf')
Example #6
0
def plotDataMC(args):

    print "\n******************************************"
    print "plotting data and MC distributions together"

    # ------------------------------------------
    # input parameters
    print "\ninput parameters:"
    argsdict = vars(args)
    for ii in xrange(len(argsdict)):
        print "  %s = %s" % (argsdict.keys()[ii], argsdict.values()[ii])

    # ------------------------------------------
    # define useful variables
    lumi = float(args.lumi)  # fb^-1
    # colors = plotTools.getColors()
    colors = []
    colors.append(ROOT.kRed + 1)
    colors.append(ROOT.kBlue + 1)
    colors.append(ROOT.kGreen + 1)

    # ------------------------------------------
    # get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))

    # ------------------------------------------
    # first things first
    ROOT.TH1.SetDefaultSumw2()
    ROOT.TH1.StatOverflows()
    ROOT.TH2.SetDefaultSumw2()
    ROOT.TH2.StatOverflows()

    # ------------------------------------------
    # check inputs
    if args.dataFileName == "":
        raise SystemExit("\n***EXIT*** no data file given")

    if len(args.MCFileNames) == 0:
        raise SystemExit("\n***EXIT*** no MC files given")

    if len(args.histName) == 0:
        raise SystemExit("\n***EXIT*** no histogram name given")

    inputFileNames = []
    inputFileNames.append(args.dataFileName)
    inputFileNames += args.MCFileNames
    # print inputFileNames#DEBUG

    if len(inputFileNames) != len(args.labels):
        raise SystemExit(
            "\n***EXIT*** number of files and labels is different: %s files and %s labels"
            % (len(inputFileNames), len(args.labels))
        )

    # ------------------------------------------
    # open files and get histograms
    files = []
    hists = []

    for ii in xrange(len(inputFileNames)):

        # open input file
        if not os.path.isfile(inputFileNames[ii]):
            raise SystemExit("\n***ERROR*** couldn't find input file: %s" % inputFileNames[ii])
        files.append(ROOT.TFile(inputFileNames[ii]))

        # get input histogram
        if not files[ii].Get(args.histName):
            raise SystemExit(
                "\n***ERROR*** couldn't find input histogram %s in file %s" % (args.histName, args.histName)
            )
        hists.append(files[ii].Get(args.histName))

    # ------------------------------------------
    # TEST
    # raise SystemExit('\n***TEST*** exit')
    # ------------------------------------------

    # ------------------------------------------
    # scale MC to data
    print "\nscaling MC distributions to data integral"

    print "before"
    for ii, hist in enumerate(hists):
        print "  %s\t%s\t%s\t%s" % (ii, hist.Integral(), hist.Integral("width"), hist.GetEntries())

    for ii in xrange(len(hists)):
        if ii == 0:
            continue  # skip data file
        hists[ii].Scale(hists[0].Integral() / hists[ii].Integral())

    print "after"
    for ii, hist in enumerate(hists):
        print "  %s\t%s\t%s\t%s" % (ii, hist.Integral(), hist.Integral("width"), hist.GetEntries())

    # ------------------------------------------
    # TEST
    # raise SystemExit('\n***TEST*** exit')
    # ------------------------------------------

    # ------------------------------------------
    # labels and legends
    ax = 0.65
    ay = 0.85
    size = 20
    a = plotTools.getATLAS()
    p = plotTools.getInternal()
    n = plotTools.getNote(size)
    l = plotTools.getLegend(ax, ay, size)
    line = plotTools.getLine()

    # ------------------------------------------
    # canvas and pads
    c = ROOT.TCanvas("c", "c", 400, 50, 800, 600)
    pad1 = ROOT.TPad("pad1", "pad1", 0, 0.5, 1, 1.0)  # top
    pad2 = ROOT.TPad("pad2", "pad2", 0, 0.3, 1, 0.5)  # central
    pad3 = ROOT.TPad("pad3", "pad3", 0, 0.0, 1, 0.3)  # bottom

    pad1.SetTopMargin(0.08)
    pad1.SetBottomMargin(0.0)
    pad1.SetBorderMode(0)
    pad1.Draw()

    pad2.SetTopMargin(0.0)
    pad2.SetBottomMargin(0.0)
    pad2.SetBorderMode(0)
    pad2.Draw()

    pad3.SetTopMargin(0.0)
    pad3.SetBottomMargin(1.0 / 3.0)
    pad3.SetBorderMode(0)
    pad3.Draw()

    # ------------------------------------------
    # draw histograms
    pad1.cd()
    pad1.SetLogx(args.logx)
    pad1.SetLogy(1)
    pad1.SetGrid(1, 1)

    # data histogram
    hists[0].SetMarkerStyle(20)
    hists[0].SetMarkerColor(ROOT.kBlack)
    hists[0].SetLineColor(ROOT.kBlack)
    hists[0].SetFillStyle(0)
    hists[0].SetLineWidth(2)
    ymax = ROOT.gPad.GetFrame().GetY2()

    # MC histograms
    for ii in xrange(len(hists)):
        if ii == 0:
            continue
        hists[ii].SetMarkerStyle(0)
        hists[ii].SetMarkerColor(colors[(ii - 1) % len(colors)])
        hists[ii].SetLineColor(colors[(ii - 1) % len(colors)])
        hists[ii].SetFillStyle(0)
        hists[ii].SetLineWidth(2)
        hists[ii].GetYaxis().SetRangeUser(0.1, ymax)

    hs = ROOT.THStack("hs", "hs")
    for ii in xrange(len(hists)):
        hs.Add(hists[ii])
    hs.Draw("nostack")

    hs.GetYaxis().SetTitle("events/bin")
    hs.GetYaxis().SetTitleFont(43)
    hs.GetYaxis().SetTitleSize(size)
    hs.GetYaxis().SetLabelFont(43)
    hs.GetYaxis().SetLabelSize(size)

    hs.GetXaxis().SetTitle(args.xlabel)
    hs.GetXaxis().SetLabelFont(43)
    hs.GetXaxis().SetLabelSize(size)
    hs.GetXaxis().SetLabelFont(43)
    hs.GetXaxis().SetLabelSize(size)

    hs.Draw("nostack")
    c.Update()

    # ------------------------------------------
    # draw ratios
    pad2.cd()
    pad2.SetLogx(args.logx)
    pad2.SetLogy(0)
    pad2.SetGrid(1, 1)

    ratios = []

    for ii in xrange(len(hists)):
        if ii == 0:
            continue
        ratio = hists[0].Clone()
        ratio.Divide(hists[ii])
        ratio.SetName("ratio_%s" % str(ii))
        ratio.SetTitle("ratio_%s" % str(ii))

        ratio.SetMarkerStyle(0)
        ratio.SetMarkerColor(colors[(ii - 1) % len(colors)])
        ratio.SetLineColor(colors[(ii - 1) % len(colors)])
        ratio.SetFillStyle(0)
        ratio.SetLineWidth(2)

        ratio.GetYaxis().SetRangeUser(0.0, 2.0)  # TEST

        ratios.append(ratio)

    hsr = ROOT.THStack("hsr", "hsr")
    for ii in xrange(len(ratios)):
        hsr.Add(ratios[ii])
    hsr.Draw("nostack")

    hsr.GetYaxis().SetTitle("data/MC")
    hsr.GetYaxis().SetTitleFont(43)
    hsr.GetYaxis().SetTitleSize(size)
    hsr.GetYaxis().SetLabelFont(43)
    hsr.GetYaxis().SetLabelSize(size)

    hsr.GetXaxis().SetTitle(args.xlabel)
    hsr.GetXaxis().SetTitleFont(43)
    hsr.GetXaxis().SetTitleSize(size)
    hsr.GetXaxis().SetTitleOffset(4.0)
    hsr.GetXaxis().SetLabelFont(43)
    hsr.GetXaxis().SetLabelSize(size)
    hsr.GetYaxis().SetMoreLogLabels(1)

    # lowx = ratios[0].GetBinLowEdge(1)
    # highx = ratios[0].GetBinLowEdge(ratios[0].GetNbinsX()+1)
    # line.DrawLine(lowx,1.,highx,1.)

    hsr.Draw("nostack")
    c.Update()

    # ------------------------------------------
    # draw differences
    pad3.cd()
    pad3.SetLogx(args.logx)
    pad3.SetLogy(0)
    pad3.SetGrid(1, 1)

    diffs = []

    for ii in xrange(len(hists)):
        if ii == 0:
            continue
        diff = hists[0].Clone()
        diff.Add(hists[ii], -1)
        diff.SetName("diff_%s" % str(ii))
        diff.SetTitle("diff_%s" % str(ii))

        diff.SetMarkerStyle(0)
        diff.SetMarkerColor(colors[(ii - 1) % len(colors)])
        diff.SetLineColor(colors[(ii - 1) % len(colors)])
        diff.SetFillStyle(0)
        diff.SetLineWidth(2)

        diff.GetYaxis().SetRangeUser(-1e3, 1e3)  # TEST

        diffs.append(diff)

    hsd = ROOT.THStack("hsd", "hsd")
    for ii in xrange(len(diffs)):
        hsd.Add(diffs[ii])
    hsd.Draw("nostack")

    hsd.GetYaxis().SetTitle("data-MC")
    hsd.GetYaxis().SetTitleFont(43)
    hsd.GetYaxis().SetTitleSize(size)
    hsd.GetYaxis().SetLabelFont(43)
    hsd.GetYaxis().SetLabelSize(size)

    hsd.GetXaxis().SetTitle(args.xlabel)
    hsd.GetXaxis().SetTitleFont(43)
    hsd.GetXaxis().SetTitleSize(size)
    hsd.GetXaxis().SetTitleOffset(4.0)
    hsd.GetXaxis().SetLabelFont(43)
    hsd.GetXaxis().SetLabelSize(size)
    hsd.GetYaxis().SetMoreLogLabels(1)

    # lowx = diffs[0].GetBinLowEdge(1)
    # highx = diffs[0].GetBinLowEdge(diffs[0].GetNbinsX()+1)
    # line.DrawLine(lowx,1.,highx,1.)

    hsd.Draw("nostack")
    c.Update()

    # ------------------------------------------
    # draw labels and legend
    pad1.cd()

    ax = 0.65
    ay = 0.80
    spacing = 0.08
    a.DrawLatex(ax, ay, "ATLAS")
    p.DrawLatex(ax + 0.13, ay, "internal")  # internal, simualtion internal
    c.Update()

    # notes
    print "\nnotes:"
    notes = []
    notes.append("#sqrt{s} = 13 TeV")
    if float(lumi) > 0.0:
        notes.append("L_{int} = %s fb^{-1}" % lumi)
    notes += args.notes
    for ii, note in enumerate(notes):
        n.DrawLatex(ax, ay - spacing * (ii + 1), note)
        print "  %s" % note
    c.Update()

    # legend
    l.Clear()
    l.SetTextSize(20)
    for ii, hist in enumerate(hists):
        if len(args.labels) == len(hists):
            l.AddEntry(hists[ii], args.labels[ii], "pl")
        else:
            l.AddEntry(hists[ii], os.path.basename(hists[ii].GetDirectory().GetFile().GetName()), "pl")
    l.SetX1(ax)
    l.SetY1(ay - spacing * (len(notes) + 1) - spacing * l.GetNRows())
    l.SetX2(ax + 0.15)
    l.SetY2(ay - spacing * (len(notes) + 1))
    l.Draw()
    c.Update()

    if args.wait:
        c.WaitPrimitive()
    if args.save:
        c.SaveAs(localdir + "/figures/dataMC.%s.pdf" % args.tag)
    del c
Example #7
0
def plotSlices(args):

    print '\n******************************************'
    print 'plot slices'

    #------------------------------------------
    #input parameters
    print '\ninput parameters:'
    argsdict = vars(args)
    for ii in xrange(len(argsdict)):
        print '  %s = %s'%(argsdict.keys()[ii], argsdict.values()[ii],)
    
    #------------------------------------------
    #define useful variables
    lumi = float(args.lumi) #fb^-1
    colors = plotTools.getColors()
    #colors = []
    ##colors.append(ROOT.kBlack)
    #colors.append(ROOT.kGreen+1)
    #colors.append(ROOT.kCyan+1)
    #colors.append(ROOT.kBlue+1)
    #colors.append(ROOT.kMagenta+1)
    #colors.append(ROOT.kRed+1)
    #colors.append(ROOT.kYellow+1)
    #colors.append(ROOT.kSpring+1)
    #colors.append(ROOT.kTeal+1)
    #colors.append(ROOT.kAzure+1) 
    #colors.append(ROOT.kViolet+1)
    #colors.append(ROOT.kPink+1)
    #colors.append(ROOT.kOrange+1)

    #------------------------------------------
    #get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))
	
    #------------------------------------------
    #set error sum and overflow
    ROOT.TH1.SetDefaultSumw2()
    ROOT.TH1.StatOverflows()

    #------------------------------------------
    #get input files
    inputFileNames = [inputFileName for inputFileName in args.inputFileNames if (all(tag in inputFileName for tag in args.inputFileTags) and '.root' in inputFileName)]
    inputFileNames = list( set(inputFileNames))
    inputFileNames.sort()
    
    #make sure we have found some files
    if len(inputFileNames) == 0:
        raise SystemExit('\n***EXIT*** no files found for tags: %s'%' '.join(args.inputFileTags))
  
    print '\ninput files (%s):'%str(len(inputFileNames)+len([args.reference]))
    if len(args.reference) != 0:
        print '  %s\t(reference)'%args.reference
    
    for fileName in inputFileNames:
        print '  %s'%fileName

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #open files and get histograms
    if len(args.reference) != 0:

        #open reference input file
        if not os.path.isfile(args.reference):
            raise SystemExit('\n***ERROR*** couldn\'t find reference input file')
        rf = ROOT.TFile(args.reference)
    
        #get input histograms
        if len(args.inputHistName) == 0:
            raise SystemExit('\n***ERROR*** no input histogram name')
        if not rf.Get(args.inputHistName):
            raise SystemExit('\n***ERROR*** couldn\'t find reference input histogram: %s'%args.inputHistName)
        rh = rf.Get(args.inputHistName)
    
    files = []
    hists = []

    for ii,inputFileName in enumerate(inputFileNames):
        
        #open input file
        if len(inputFileName) == 0:
            raise SystemExit('\n***ERROR*** no input file name')
        if not os.path.isfile(inputFileName):
            raise SystemExit('\n***ERROR*** couldn\'t find input file')
        files.append(ROOT.TFile(inputFileName))
    
        #get input histograms
        if len(args.inputHistName) == 0:
            raise SystemExit('\n***ERROR*** no input histogram name')
        if not files[ii].Get(args.inputHistName):
            raise SystemExit('\n***ERROR*** couldn\'t find input histogram: %s'%args.inputHistName)
        hists.append(files[ii].Get(args.inputHistName))

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #labels and legends
    ax = 0.65
    ay = 0.85
    size=20
    a = plotTools.getATLAS()
    p = plotTools.getInternal()
    n = plotTools.getNote(size)
    l = plotTools.getLegend(ax,ay,size)

    #------------------------------------------
    #canvase
    c = ROOT.TCanvas('c', 'c', 60, 50, 800, 600)
    c.cd()
    c.SetLogx(args.logx)
    c.SetLogy(args.logy)
    c.SetRightMargin(0.05)
    c.Draw()

    #------------------------------------------
    #plot

    #set histograms
    hs = ROOT.THStack('hs','hs')
    hs.Clear()

    if len(args.reference) != 0:
        if rh is not None:
            rh.SetMarkerColor(ROOT.kBlack)
            rh.SetLineColor(ROOT.kBlack)
            rh.SetMarkerStyle(20)
            hs.Add(rh)
    
    for ii,hist in enumerate(hists):
        hist.SetMarkerColor( colors[ ii%len(colors) ] )
        hist.SetLineColor( colors[ ii%len(colors) ] )
        hist.SetMarkerStyle(20)
        hs.Add(hist)
        
    hs.Draw('nostack')

    if len(args.xlabel) != 0:        
        hs.GetXaxis().SetTitle(args.xlabel)
    else:
        hs.GetXaxis().SetTitle(args.inputHistName)
    hs.GetXaxis().SetTitleFont(43)
    hs.GetXaxis().SetTitleSize(20)
    hs.GetXaxis().SetTitleOffset(1.5)
    hs.GetXaxis().SetLabelFont(43)
    hs.GetXaxis().SetLabelSize(20)
    #hs.GetXaxis().SetRange(firstBin,lastBin)

    hs.GetYaxis().SetTitle(args.ylabel)
    hs.GetYaxis().SetTitleFont(43)
    hs.GetYaxis().SetTitleSize(20)
    hs.GetYaxis().SetTitleOffset(1.5)
    hs.GetYaxis().SetLabelFont(43)
    hs.GetYaxis().SetLabelSize(size)
    #hs.GetYaxis().SetRangeUser(0.5,hs.GetMaximum()*10.)
    c.Update()

    #labels
    ax = 0.65
    ay = 0.88
    a.DrawLatex(ax,ay,'ATLAS')
    p.DrawLatex(ax+0.13,ay,'internal')
    c.Update()
        
    #notes
    print '\nnotes:'
    notes = []
    notes.append('#sqrt{s} = 13 TeV')
    if float(lumi) > 0.:
        notes.append('L_{int} = %s fb^{-1}'%lumi)
    notes+=args.notes
    for ii, note in enumerate(notes):
        n.DrawLatex(ax,ay-0.04*(ii+1),note)
        print '  %s'%note
    c.Update()
    
    #legend
    l.Clear()
    l.SetTextSize(20)
    if len(args.reference) != 0:
        if rh is not None:
            l.AddEntry(rh, 'total', 'pl')

    for ii,hist in enumerate(hists):
        if len(args.labels) == len(hists):
            l.AddEntry(hists[ii], args.labels[ii], 'pl')
        else:
            l.AddEntry(hists[ii], os.path.basename(hists[ii].GetDirectory().GetFile().GetName()), 'pl')
    l.SetX1(ax)
    l.SetY1(ay-0.04*(len(notes)+1)-0.03*l.GetNRows())
    l.SetX2(ax+0.15)
    l.SetY2(ay-0.04*(len(notes)+1))
    l.Draw()
    c.Update()

    if args.wait:
        c.WaitPrimitive()
    if args.save:
        c.SaveAs(localdir+'/figures/MCSlices.%s.%s.pdf'%(args.inputHistName,args.tag))
Example #8
0
def plotDataMC(args):

    print '\n******************************************'
    print 'plotting data and MC distributions together'

    #------------------------------------------
    #input parameters
    print '\ninput parameters:'
    argsdict = vars(args)
    for ii in xrange(len(argsdict)):
        print '  %s = %s' % (
            argsdict.keys()[ii],
            argsdict.values()[ii],
        )

    #------------------------------------------
    #define useful variables
    lumi = float(args.lumi)  #fb^-1
    #colors = plotTools.getColors()
    colors = []
    colors.append(ROOT.kRed + 1)
    colors.append(ROOT.kBlue + 1)
    colors.append(ROOT.kGreen + 1)

    #------------------------------------------
    #get directory of this script
    localdir = os.path.dirname(os.path.realpath(__file__))

    #------------------------------------------
    #first things first
    ROOT.TH1.SetDefaultSumw2()
    ROOT.TH1.StatOverflows()
    ROOT.TH2.SetDefaultSumw2()
    ROOT.TH2.StatOverflows()

    #------------------------------------------
    #check inputs
    if args.dataFileName == '':
        raise SystemExit('\n***EXIT*** no data file given')

    if len(args.MCFileNames) == 0:
        raise SystemExit('\n***EXIT*** no MC files given')

    if len(args.histName) == 0:
        raise SystemExit('\n***EXIT*** no histogram name given')

    inputFileNames = []
    inputFileNames.append(args.dataFileName)
    inputFileNames += args.MCFileNames
    #print inputFileNames#DEBUG

    if len(inputFileNames) != len(args.labels):
        raise SystemExit(
            '\n***EXIT*** number of files and labels is different: %s files and %s labels'
            % (len(inputFileNames), len(args.labels)))

    #------------------------------------------
    #open files and get histograms
    files = []
    hists = []

    for ii in xrange(len(inputFileNames)):

        #open input file
        if not os.path.isfile(inputFileNames[ii]):
            raise SystemExit('\n***ERROR*** couldn\'t find input file: %s' %
                             inputFileNames[ii])
        files.append(ROOT.TFile(inputFileNames[ii]))

        #get input histogram
        if not files[ii].Get(args.histName):
            raise SystemExit(
                '\n***ERROR*** couldn\'t find input histogram %s in file %s' %
                (args.histName, args.histName))
        hists.append(files[ii].Get(args.histName))

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #scale MC to data
    print '\nscaling MC distributions to data integral'

    print 'before'
    for ii, hist in enumerate(hists):
        print '  %s\t%s\t%s\t%s' % (ii, hist.Integral(),
                                    hist.Integral('width'), hist.GetEntries())

    for ii in xrange(len(hists)):
        if ii == 0: continue  #skip data file
        hists[ii].Scale(hists[0].Integral() / hists[ii].Integral())

    print 'after'
    for ii, hist in enumerate(hists):
        print '  %s\t%s\t%s\t%s' % (ii, hist.Integral(),
                                    hist.Integral('width'), hist.GetEntries())

    #------------------------------------------
    #TEST
    #raise SystemExit('\n***TEST*** exit')
    #------------------------------------------

    #------------------------------------------
    #labels and legends
    ax = 0.65
    ay = 0.85
    size = 20
    a = plotTools.getATLAS()
    p = plotTools.getInternal()
    n = plotTools.getNote(size)
    l = plotTools.getLegend(ax, ay, size)
    line = plotTools.getLine()

    #------------------------------------------
    #canvas and pads
    c = ROOT.TCanvas('c', 'c', 400, 50, 800, 600)
    pad1 = ROOT.TPad("pad1", "pad1", 0, 0.5, 1, 1.0)  #top
    pad2 = ROOT.TPad("pad2", "pad2", 0, 0.3, 1, 0.5)  #central
    pad3 = ROOT.TPad("pad3", "pad3", 0, 0.0, 1, 0.3)  #bottom

    pad1.SetTopMargin(0.08)
    pad1.SetBottomMargin(0.0)
    pad1.SetBorderMode(0)
    pad1.Draw()

    pad2.SetTopMargin(0.0)
    pad2.SetBottomMargin(0.0)
    pad2.SetBorderMode(0)
    pad2.Draw()

    pad3.SetTopMargin(0.0)
    pad3.SetBottomMargin(1. / 3.)
    pad3.SetBorderMode(0)
    pad3.Draw()

    #------------------------------------------
    #draw histograms
    pad1.cd()
    pad1.SetLogx(args.logx)
    pad1.SetLogy(1)
    pad1.SetGrid(1, 1)

    #data histogram
    hists[0].SetMarkerStyle(20)
    hists[0].SetMarkerColor(ROOT.kBlack)
    hists[0].SetLineColor(ROOT.kBlack)
    hists[0].SetFillStyle(0)
    hists[0].SetLineWidth(2)
    ymax = ROOT.gPad.GetFrame().GetY2()

    #MC histograms
    for ii in xrange(len(hists)):
        if ii == 0: continue
        hists[ii].SetMarkerStyle(0)
        hists[ii].SetMarkerColor(colors[(ii - 1) % len(colors)])
        hists[ii].SetLineColor(colors[(ii - 1) % len(colors)])
        hists[ii].SetFillStyle(0)
        hists[ii].SetLineWidth(2)
        hists[ii].GetYaxis().SetRangeUser(0.1, ymax)

    hs = ROOT.THStack('hs', 'hs')
    for ii in xrange(len(hists)):
        hs.Add(hists[ii])
    hs.Draw('nostack')

    hs.GetYaxis().SetTitle("events/bin")
    hs.GetYaxis().SetTitleFont(43)
    hs.GetYaxis().SetTitleSize(size)
    hs.GetYaxis().SetLabelFont(43)
    hs.GetYaxis().SetLabelSize(size)

    hs.GetXaxis().SetTitle(args.xlabel)
    hs.GetXaxis().SetLabelFont(43)
    hs.GetXaxis().SetLabelSize(size)
    hs.GetXaxis().SetLabelFont(43)
    hs.GetXaxis().SetLabelSize(size)

    hs.Draw('nostack')
    c.Update()

    #------------------------------------------
    #draw ratios
    pad2.cd()
    pad2.SetLogx(args.logx)
    pad2.SetLogy(0)
    pad2.SetGrid(1, 1)

    ratios = []

    for ii in xrange(len(hists)):
        if ii == 0: continue
        ratio = hists[0].Clone()
        ratio.Divide(hists[ii])
        ratio.SetName('ratio_%s' % str(ii))
        ratio.SetTitle('ratio_%s' % str(ii))

        ratio.SetMarkerStyle(0)
        ratio.SetMarkerColor(colors[(ii - 1) % len(colors)])
        ratio.SetLineColor(colors[(ii - 1) % len(colors)])
        ratio.SetFillStyle(0)
        ratio.SetLineWidth(2)

        ratio.GetYaxis().SetRangeUser(0., 2.)  #TEST

        ratios.append(ratio)

    hsr = ROOT.THStack('hsr', 'hsr')
    for ii in xrange(len(ratios)):
        hsr.Add(ratios[ii])
    hsr.Draw('nostack')

    hsr.GetYaxis().SetTitle('data/MC')
    hsr.GetYaxis().SetTitleFont(43)
    hsr.GetYaxis().SetTitleSize(size)
    hsr.GetYaxis().SetLabelFont(43)
    hsr.GetYaxis().SetLabelSize(size)

    hsr.GetXaxis().SetTitle(args.xlabel)
    hsr.GetXaxis().SetTitleFont(43)
    hsr.GetXaxis().SetTitleSize(size)
    hsr.GetXaxis().SetTitleOffset(4.0)
    hsr.GetXaxis().SetLabelFont(43)
    hsr.GetXaxis().SetLabelSize(size)
    hsr.GetYaxis().SetMoreLogLabels(1)

    #lowx = ratios[0].GetBinLowEdge(1)
    #highx = ratios[0].GetBinLowEdge(ratios[0].GetNbinsX()+1)
    #line.DrawLine(lowx,1.,highx,1.)

    hsr.Draw('nostack')
    c.Update()

    #------------------------------------------
    #draw differences
    pad3.cd()
    pad3.SetLogx(args.logx)
    pad3.SetLogy(0)
    pad3.SetGrid(1, 1)

    diffs = []

    for ii in xrange(len(hists)):
        if ii == 0: continue
        diff = hists[0].Clone()
        diff.Add(hists[ii], -1)
        diff.SetName('diff_%s' % str(ii))
        diff.SetTitle('diff_%s' % str(ii))

        diff.SetMarkerStyle(0)
        diff.SetMarkerColor(colors[(ii - 1) % len(colors)])
        diff.SetLineColor(colors[(ii - 1) % len(colors)])
        diff.SetFillStyle(0)
        diff.SetLineWidth(2)

        diff.GetYaxis().SetRangeUser(-1e3, 1e3)  #TEST

        diffs.append(diff)

    hsd = ROOT.THStack('hsd', 'hsd')
    for ii in xrange(len(diffs)):
        hsd.Add(diffs[ii])
    hsd.Draw('nostack')

    hsd.GetYaxis().SetTitle('data-MC')
    hsd.GetYaxis().SetTitleFont(43)
    hsd.GetYaxis().SetTitleSize(size)
    hsd.GetYaxis().SetLabelFont(43)
    hsd.GetYaxis().SetLabelSize(size)

    hsd.GetXaxis().SetTitle(args.xlabel)
    hsd.GetXaxis().SetTitleFont(43)
    hsd.GetXaxis().SetTitleSize(size)
    hsd.GetXaxis().SetTitleOffset(4.0)
    hsd.GetXaxis().SetLabelFont(43)
    hsd.GetXaxis().SetLabelSize(size)
    hsd.GetYaxis().SetMoreLogLabels(1)

    #lowx = diffs[0].GetBinLowEdge(1)
    #highx = diffs[0].GetBinLowEdge(diffs[0].GetNbinsX()+1)
    #line.DrawLine(lowx,1.,highx,1.)

    hsd.Draw('nostack')
    c.Update()

    #------------------------------------------
    #draw labels and legend
    pad1.cd()

    ax = 0.65
    ay = 0.80
    spacing = 0.08
    a.DrawLatex(ax, ay, 'ATLAS')
    p.DrawLatex(ax + 0.13, ay, 'internal')  #internal, simualtion internal
    c.Update()

    #notes
    print '\nnotes:'
    notes = []
    notes.append('#sqrt{s} = 13 TeV')
    if float(lumi) > 0.:
        notes.append('L_{int} = %s fb^{-1}' % lumi)
    notes += args.notes
    for ii, note in enumerate(notes):
        n.DrawLatex(ax, ay - spacing * (ii + 1), note)
        print '  %s' % note
    c.Update()

    #legend
    l.Clear()
    l.SetTextSize(20)
    for ii, hist in enumerate(hists):
        if len(args.labels) == len(hists):
            l.AddEntry(hists[ii], args.labels[ii], 'pl')
        else:
            l.AddEntry(
                hists[ii],
                os.path.basename(hists[ii].GetDirectory().GetFile().GetName()),
                'pl')
    l.SetX1(ax)
    l.SetY1(ay - spacing * (len(notes) + 1) - spacing * l.GetNRows())
    l.SetX2(ax + 0.15)
    l.SetY2(ay - spacing * (len(notes) + 1))
    l.Draw()
    c.Update()

    if args.wait:
        c.WaitPrimitive()
    if args.save:
        c.SaveAs(localdir + '/figures/dataMC.%s.pdf' % args.tag)
    del c