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()
예제 #2
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)
예제 #3
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')
예제 #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)
def plotSearchPhase(dataHist,
                    fitHist,
                    significanceHist,
                    xLab,
                    yLab,
                    sigLab,
                    name,
                    luminosity,
                    CME,
                    chi2ndf,
                    BHpval,
                    nPar,
                    userFirstBin=-1,
                    userLastBin=-1,
                    bumpLow=0,
                    bumpHigh=0,
                    bumpFound=False,
                    logx=False,
                    notes=[],
                    wait=False):

    print '\n******************************************'
    print 'plot search phase results'

    #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()

    #canvas
    c = ROOT.TCanvas('c', 'c', 100, 50, 800, 600)
    c.SetLogx(logx)
    c.SetLogy(1)

    textSize = 20

    #pads
    outpad = ROOT.TPad("extpad", "extpad", 0., 0., 1., 1.)
    pad1 = ROOT.TPad("pad1", "pad1", 0., 0.33, 1., 1.)
    pad2 = ROOT.TPad("pad2", "pad2", 0., 0., 1., 0.33)

    #setup drawing options
    outpad.SetFillStyle(4000)  #transparent
    pad1.SetBottomMargin(0.00001)
    pad1.SetBorderMode(0)
    pad1.SetLogy(1)
    pad1.SetLogx(logx)
    pad2.SetTopMargin(0.00001)
    pad2.SetBottomMargin(0.3)
    pad2.SetBorderMode(0)
    pad2.SetLogx(logx)
    pad1.Draw()
    pad2.Draw()
    outpad.Draw()

    #------------------------------------------
    #draw data and fit histograms
    pad1.cd()

    #use bin range within which bkg plot has entries,
    #plus one empty on either side if available
    #print 'userFirstBin, userLastBin = %s, %s'%(userFirstBin,userLastBin)
    firstBin, lastBin = getAxisRangeFromHist(dataHist)
    #print 'firstBin, lastBin = %s, %s'%(firstBin,lastBin)
    if (userFirstBin > 0):
        firstBin = userFirstBin
        #print 'first bin = %s'%firstBin
    if (userLastBin > 0 and userLastBin >= firstBin):
        lastBin = userLastBin
        #print 'last bin  = %s'%LastBin

    #draw fit histogram
    fitHist.SetLineColor(ROOT.kRed)
    fitHist.SetFillStyle(0)
    fitHist.SetLineWidth(2)

    fitHist.GetXaxis().SetRange(firstBin, lastBin)

    fitHist.GetYaxis().SetTitle(yLab)
    fitHist.GetYaxis().SetTitleFont(43)
    fitHist.GetYaxis().SetTitleSize(textSize)
    #fitHist.GetYaxis().SetTitleOffset(1.0)
    fitHist.GetYaxis().SetLabelFont(43)
    fitHist.GetYaxis().SetLabelSize(textSize)
    #fitHist.GetYaxis().SetRangeUser(0.5,fitHist.GetMaximum()*10.)

    fitHist.Draw('hist ][')
    c.Update()

    #draw data histogram
    dataHist.SetMarkerStyle(textSize)
    dataHist.SetMarkerColor(ROOT.kBlack)
    dataHist.SetLineColor(ROOT.kBlack)
    dataHist.GetXaxis().SetRange(firstBin, lastBin)

    dataHist.Draw("E same")
    c.Update()

    #set y axis range
    if dataHist.GetBinContent(lastBin) <= fitHist.GetBinContent(lastBin):
        ymin = dataHist.GetBinContent(lastBin)
        if ymin == 0.:
            ymin = 0.5
        fitHist.SetMinimum(ymin * 0.5)
        c.Update()

    #------------------------------------------
    #draw significance histogram
    pad2.cd()

    significanceHist.GetXaxis().SetTitle(xLab)
    significanceHist.GetXaxis().SetTitleFont(43)
    significanceHist.GetXaxis().SetTitleSize(textSize)
    significanceHist.GetXaxis().SetTitleOffset(3.0)
    significanceHist.GetXaxis().SetLabelFont(43)
    significanceHist.GetXaxis().SetLabelSize(textSize)
    significanceHist.GetXaxis().SetRange(firstBin, lastBin)

    significanceHist.GetYaxis().SetTitle(sigLab)
    significanceHist.GetYaxis().SetTitleFont(43)
    significanceHist.GetYaxis().SetTitleSize(textSize)
    #significanceHist.GetYaxis().SetTitleOffset(1.0)
    significanceHist.GetYaxis().SetLabelFont(43)
    significanceHist.GetYaxis().SetLabelSize(textSize)
    #significanceHist.GetYaxis().SetRangeUser(-5.,fitHist.GetMaximum*1.1)

    significanceHist.SetLineColor(ROOT.kBlack)
    significanceHist.SetLineWidth(2)
    significanceHist.SetFillColor(ROOT.kRed)
    significanceHist.SetFillStyle(1001)

    significanceHist.Draw("HIST")
    c.Update()

    #------------------------------------------
    #labels
    pad1.cd()

    ax = 0.60
    ay = 0.85
    a = plotTools.getATLAS()
    p = plotTools.getInternal()
    n = plotTools.getNote(textSize)

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

    #notes
    allNotes = []
    allNotes.append('#sqrt{s} = %s TeV' % CME)
    if float(luminosity) > 0.:
        if float(luminosity) < 0.1:
            allNotes.append('L_{int} = %.0f pb^{-1}' % float(luminosity) * 1e3)
        else:
            allNotes.append('L_{int} = %.1f fb^{-1}' % float(luminosity))
    allNotes.append('#chi^{2}/ndf = %.3f' % float(chi2ndf))
    allNotes.append('bump range = %.0f - %.0f GeV' %
                    (float(bumpLow), float(bumpHigh)))
    allNotes.append('BH p-value = %.4f' % float(BHpval))
    if bumpFound:
        allNotes.append('bump range excluded')
    else:
        allNotes.append('bump range not excluded')
    allNotes.append('%s par. fit func.' % nPar)
    allNotes += notes

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

    c.Update()

    #------------------------------------------
    #draw bump lines
    line = ROOT.TLine()
    if bumpFound:
        line.SetLineColor(ROOT.kGreen + 1)
    else:
        line.SetLineColor(ROOT.kBlue)
    line.SetLineWidth(1)
    pad1.cd()
    line.DrawLine(bumpLow,
                  dataHist.GetYaxis().GetXmin(), bumpLow,
                  dataHist.GetBinContent(dataHist.FindBin(bumpLow)))
    line.DrawLine(bumpHigh,
                  dataHist.GetYaxis().GetXmin(), bumpHigh,
                  dataHist.GetBinContent(dataHist.FindBin(bumpHigh) - 1))
    pad2.cd()
    line.DrawLine(bumpLow, significanceHist.GetMinimum(), bumpLow,
                  2 * significanceHist.GetMaximum())
    line.DrawLine(bumpHigh, significanceHist.GetMinimum(), bumpHigh,
                  2 * significanceHist.GetMaximum())
    c.Update()

    #------------------------------------------
    #save
    c.Update()
    if wait:
        c.WaitPrimitive()
    localdir = os.path.dirname(os.path.realpath(__file__))
    c.SaveAs(localdir + '/figures/bumphunt.' + name + '.pdf')
예제 #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
def plotTomography(tomographyHist,
                   xLab,
                   yLab,
                   name,
                   luminosity,
                   CME,
                   BHpval,
                   nPar,
                   bumpLow=0,
                   bumpHigh=0,
                   bumpFound=False,
                   logx=False,
                   notes=[],
                   wait=False):

    print '\n******************************************'
    print 'plot search phase tomography'

    #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()

    #------------------------------------------
    #canvas
    c = ROOT.TCanvas('c', 'c', 100, 50, 800, 600)
    c.SetLogx(logx)
    c.SetLogy(1)

    #------------------------------------------
    #draw
    textSize = 20

    tomographyHist.SetLineColor(ROOT.kRed)
    tomographyHist.SetTitle("")

    tomographyHist.GetXaxis().SetTitle(xLab)
    tomographyHist.GetXaxis().SetTitleFont(43)
    tomographyHist.GetXaxis().SetTitleSize(textSize)
    #tomographyHist.GetXaxis().SetTitleOffset(3.0)
    tomographyHist.GetXaxis().SetLabelFont(43)
    tomographyHist.GetXaxis().SetLabelSize(textSize)
    #tomographyHist.GetXaxis().SetNdivisions(805,ROOT.kTRUE)
    #tomographyHist.GetXaxis().SetMoreLogLabels()

    tomographyHist.GetYaxis().SetTitle("Poisson p-value")
    tomographyHist.GetYaxis().SetTitleFont(43)
    tomographyHist.GetYaxis().SetTitleSize(textSize)
    #tomographyHist.GetYaxis().SetTitleOffset(1.2)
    tomographyHist.GetYaxis().SetLabelFont(43)
    tomographyHist.GetYaxis().SetLabelSize(textSize)
    #tomographyHist.GetYaxis().SetRangeUser(-5.,fitHist.GetMaximum*1.1)
    #tomographyHist.GetYaxis().SetMoreLogLabels()

    tomographyHist.SetMarkerColor(ROOT.kRed)
    tomographyHist.SetMarkerSize(0.2)
    tomographyHist.Draw("AP")

    #------------------------------------------
    #labels
    c.cd()

    ax = 0.60
    ay = 0.85
    a = plotTools.getATLAS()
    p = plotTools.getInternal()
    n = plotTools.getNote(textSize)

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

    #notes
    allNotes = []
    allNotes.append('#sqrt{s} = %s TeV' % CME)
    if float(luminosity) > 0.:
        if float(luminosity) < 0.1:
            allNotes.append('L_{int} = %.0f pb^{-1}' % float(luminosity) * 1e3)
        else:
            allNotes.append('L_{int} = %.1f fb^{-1}' % float(luminosity))
    allNotes.append('#chi^{2}/ndf = %.3f' % float(chi2ndf))
    allNotes.append('bump range = %.0f - %.0f GeV' %
                    (float(bumpLow), float(bumpHigh)))
    allNotes.append('BH p-value = %.4f' % float(BHpval))
    if bumpFound:
        allNotes.append('bump range excluded')
    else:
        allNotes.append('bump range not excluded')
    allNotes.append('%s par. fit func.' % nPar)
    allNotes += notes

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

    c.Update()

    #------------------------------------------
    #save
    c.Update()
    if wait:
        c.WaitPrimitive()
    localdir = os.path.dirname(os.path.realpath(__file__))
    c.SaveAs(localdir + '/figures/tomography.' + name + '.pdf')
예제 #8
0
def plotLumiScanResults(args):

    print '\n******************************************'
    print 'plot lumi scan results'

    #******************************************
    #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 SystemExit('***ERROR*** 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
    
    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

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

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

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

    #------------------------------------------
    #set variables
    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 input file
    if not os.path.isdir(args.path):
        raise SystemExit('\n***ERROR*** not a valid path: %s'%args.path)
    
    #------------------------------------------
    #get list of available mass and lumi points
    massValuesAvailable = []
    lumiValues = []
    searchphaseFileList=os.listdir(args.path)

    for searchphaseFileName in sorted(searchphaseFileList):
        if '.%s.'%model in searchphaseFileName and '.%i.par.'%nPar in searchphaseFileName and '.%i.seed.'%seed in searchphaseFileName and args.tag in searchphaseFileName:

            fields = searchphaseFileName.split('.')
            for ii,field in enumerate(fields):
                if field == 'GeV':
                    massValuesAvailable.append( int(fields[ii-1]))
                if field == 'ifb':
                    lumiValues.append( float(fields[ii-1].replace('p','.')))


    massValues = list( set(massValuesConfig) & set(massValuesAvailable) )
    massValues.sort(key=float)
    lumiValues = list( set(lumiValues))
    lumiValues.sort(key=float)
    
    #------------------------------------------
    #NOTE remove higher lumi values
    #lumiValues = [lumiValue for lumiValue in lumiValues if lumiValue<40.]
    #------------------------------------------

    print '\nmass values [GeV]: %s'%massValues
    print 'luminosity values [fb^-1]: %s'%lumiValues

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

    #------------------------------------------
    #loop over mass points
    for mass in massValues:

        #------------------------------------------
        #NOTE use just one mass value
        #if float(mass) != 1250:
        #    continue
        #------------------------------------------

        print '\n******************************************'
        print '%s m = %s GeV'%(modelLabel, mass)
        print '******************************************'
        glumi = []
        gpval = []
        gpvalerr = []
        glowedge = []
        ghighedge = []

        #------------------------------------------
        #p-values histogram
        hpval = ROOT.TH1D('pvalues','pvalues',20,0.,1.)
        hpval.SetDefaultSumw2(ROOT.kTRUE)
        hpval.SetDirectory(0)
        
        #------------------------------------------
        #loop over luminosity values
        for lumi in lumiValues:

            #luminosity
            print '\nluminosity = %.1f fb^-1'%lumi
            slumi = ('%.1f'% float( str(lumi).replace('p','.'))).replace('.','p')
            discoverlumi = ''
            
            #get SearchPhase result file
            spFileName = ''
            for searchphaseFileName in sorted(searchphaseFileList):
                if '.%s.'%model in searchphaseFileName and '.%i.par.'%nPar in searchphaseFileName and '.%i.seed.'%seed in searchphaseFileName and args.tag in searchphaseFileName and '.%s.GeV.'%int(mass) in searchphaseFileName and '.%s.ifb.'%slumi in searchphaseFileName and '.%s'%histBaseName in searchphaseFileName and '%s'%bTaggingWP in searchphaseFileName:
                    spFileName = searchphaseFileName

            if spFileName != '':
                print spFileName
            else:
                continue
                    
            #------------------------------------------
            #TEST
            #raise SystemExit('\n***TEST*** exit')
            #------------------------------------------
            
            if os.path.isfile(args.path+'/'+spFileName):
                spFile = ROOT.TFile(args.path+'/'+spFileName,'READ')

                bumpHunterStatOfFitToData = spFile.Get("bumpHunterStatOfFitToData")
                bumpHunterStatValue = bumpHunterStatOfFitToData[0]
                bumpHunterPValue    = bumpHunterStatOfFitToData[1]
                bumpHunterPValueErr = bumpHunterStatOfFitToData[2]

                bumpHunterPLowHigh = spFile.Get('bumpHunterPLowHigh')
                #bumpHunterStatValue = bumpHunterPLowHigh[0]
                bumpLowEdge         = bumpHunterPLowHigh[1]
                bumpHighEdge        = bumpHunterPLowHigh[2]

                print "bump range: %s GeV - %s GeV"%(bumpLowEdge,bumpHighEdge)
                print "BumpHunter stat = %s"%bumpHunterStatValue
                print "BumpHunter p-value = %s +/- %s"%(bumpHunterPValue, bumpHunterPValueErr)

                bumpHunterSigmas = ROOT.Math.normal_quantile(1.-bumpHunterPValue, 1.)
                print "BumpHunter sigmas = %s"%bumpHunterSigmas
                                
                gpval.append(bumpHunterPValue)
                gpvalerr.append(bumpHunterPValueErr)

                glowedge.append(bumpLowEdge)
                ghighedge.append(bumpHighEdge)

                glumi.append(float(lumi))

                highestlumi = lumi

                hpval.Fill(float(bumpHunterPValue))
                
        print '\nhighest luminosity tested = %s pb^-1'%highestlumi
    
        #------------------------------------------
        #TEST
        #raise SystemExit('\n***TEST*** exit')
        #------------------------------------------        
        
        #------------------------------------------
        #plot luminosity scan for given mass value
        glumi = np.array(glumi)#/1e3
        glumierr = np.zeros_like(glumi)#/1e3
        gpval = np.array(gpval)
        gpvalerr = np.array(gpvalerr)
        glowedge = np.array(glowedge)#/1e3
        ghighedge = np.array(ghighedge)#/1e3
        #ROOT.gStyle.SetPadTickY(0)
        #ROOT.gStyle.SetPadRightMargin(0.15)

        #------------------------------------------
        #canvas and pads
        c = ROOT.TCanvas('c', 'c', 100, 50, 800, 600)
        yd = 0.5 #bottom pad height (pad2)
        pad1 = ROOT.TPad("pad1","pad1",0, yd, 1, 1)#top
        pad2 = ROOT.TPad("pad2","pad2",0, 0, 1, yd)#bottom

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

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

        #------------------------------------------
        #pad 1
        #------------------------------------------
        pad1.cd()
        pad1.Clear()
        pad1.SetLogx(1)
        pad1.SetLogy(0)
        
        #..........................................
        #bump band
        gr = ROOT.TGraphAsymmErrors(len(glumi), glumi, (ghighedge+glowedge)/2, np.zeros_like(glumi), np.zeros_like(glumi), (ghighedge-glowedge)/2, (ghighedge-glowedge)/2) #n,x,y,exl,exh,eyl,eyh
        gr.SetTitle('range')
        #gr.GetXaxis().SetTitle('luminosity [fb^{-1}]')
        gr.GetYaxis().SetTitle(axisLabel)
        gr.GetYaxis().SetLabelFont(43)
        gr.GetYaxis().SetLabelSize(textSize)
        gr.GetYaxis().SetTitleFont(43)
        gr.GetYaxis().SetTitleSize(textSize)
        gr.GetYaxis().SetDecimals(True)

        gr.SetMarkerColor(ROOT.kRed)
        gr.SetLineColor(ROOT.kRed)
        gr.SetFillColor(ROOT.kRed)
        gr.SetFillStyle(3003)

        #..........................................
        #draw
        gr.Draw("ape") #draw points
        grb = gr.Clone() 
        grb.Draw("same3") #draw band
        
        c.cd()
        c.Update()

        #------------------------------------------
        #pad 2
        #------------------------------------------
        pad2.cd()
        pad2.Clear()
        pad2.SetLogx(1)
        pad2.SetLogy(1)
        
        #p-value graph
        gpv = ROOT.TGraphErrors(int(len(glumi)), glumi, gpval, glumierr, gpvalerr)
        gpv.SetTitle('p-value')
        gpv.GetXaxis().SetTitle('luminosity [fb^{-1}]')
        gpv.GetXaxis().SetLabelFont(43)
        gpv.GetXaxis().SetLabelSize(textSize)
        gpv.GetXaxis().SetTitleFont(43)
        gpv.GetXaxis().SetTitleSize(textSize)
        gpv.GetYaxis().SetTitle('BumpHunter p-value')
        gpv.GetYaxis().SetLabelFont(43)
        gpv.GetYaxis().SetLabelSize(textSize)
        gpv.GetYaxis().SetTitleFont(43)
        gpv.GetYaxis().SetTitleSize(textSize)
        gpv.GetXaxis().SetTitleOffset(2.5)#this needs to be adjusted depending on yd
        
        gpv.SetFillColor(ROOT.kBlack)
        gpv.SetFillStyle(3002)
        gpv.SetMaximum(2.)
        gpv.SetMinimum(1e-10)

        gpv.SetMinimum(1e-7)
        gpv.Draw("apel") #HERE after SetMinimum()
        #gpv.Draw("same 3") #draw band #NOTE clashes with the line

        #draw sigma reference lines
        s = ROOT.TLatex()
        s.SetNDC(False)
        s.SetTextFont(43)
        s.SetTextColor(ROOT.kRed)
        s.SetTextSize(textSize)
        lxs = ROOT.TLine()
        lxs.SetLineColor(ROOT.kRed)
        lxs.SetLineWidth(2)

        for i in range(6):
            if i<1: continue
            pvalxs = 1. - ROOT.Math.normal_cdf(i)
            lxs.DrawLine(gpv.GetXaxis().GetXmin(), pvalxs, gpv.GetXaxis().GetXmax(), pvalxs)
            s.DrawLatex(gpv.GetXaxis().GetXmax()*1.05,pvalxs,'%0.f#sigma'%i)

        #draw graph (again) on top
        gpv.Draw("same pel") #HERE after SetMinimum()
        #gpv.Draw("same 3") #draw band #NOTE clashes with the line

        #..........................................
        #labels
        #NOTE notes and labels are written from bottom to top
        ax = 0.20
        ay = 0.24
        a = plotTools.getATLAS()
        p = plotTools.getInternal()
        n = plotTools.getNote(textSize)
        spacing = 0.06

        #notes: 13 TeV, model mass, n. par
        allNotes = []
        allNotes.append('#sqrt{s} = 13 TeV')
        if modelLabel != '':
            allNotes.append('m_{%s} = %0.f GeV'%(modelLabel,float(mass)))
        else:
            allNotes.append('m_{%s} = %0.f GeV'%(model,float(mass)))
        allNotes.append('%s par. fit func.'%nPar)
        allNotes+=notes
        allNotes=allNotes[::-1] #reverse the order
        
        for ii, note in enumerate(allNotes):
            n.DrawLatex(ax,ay+spacing*(ii),note)

        #ATLAS internal
        a.DrawLatex(ax,ay+spacing*len(allNotes),'ATLAS')
        p.DrawLatex(ax+0.13,ay+spacing*len(allNotes),'internal')
                
        #..........................................
        c.Update()
        if args.wait:
            c.WaitPrimitive()
        c.SaveAs(localdir+'/../figures/lumiscan.'+model+'.%s'%int(mass)+'.GeV.'+histName+'.%i'%nPar+'.par.%i'%seed+'.seed.'+args.tag+'.pdf')
예제 #9
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))
예제 #10
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
예제 #11
0
def plotSensitivityScanResults(args):

    print '\n******************************************'
    print 'plot sensitivity scan results'

    #******************************************
    #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 SystemExit(
            '***ERROR*** 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

    lumiMin = float(settings.GetValue('luminosityMin', '0.1'))
    if lumiMin < 0.1:  #fb^-1
        lumiMin = 0.1  #fb^-1
    print '  minimum luminosity = %s' % lumiMin

    lumiMax = float(settings.GetValue('luminosityMax', '10.'))
    print '  maximum luminosity = %s' % lumiMax
    if lumiMax > 100.:  #fb^-1
        lumiMax = 100.  #fb^-1

    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

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

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

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

    #------------------------------------------
    #set variables
    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__))

    #------------------------------------------
    #get list of available mass and lumi points
    massValuesAvailable = []
    lumiValues = []
    searchphaseFileList = os.listdir(args.path)

    for searchphaseFileName in sorted(searchphaseFileList):
        if '.%s.' % model in searchphaseFileName and '.%i.par.' % nPar in searchphaseFileName and '.%i.seed.' % seed in searchphaseFileName and args.tag in searchphaseFileName:

            fields = searchphaseFileName.split('.')
            for ii, field in enumerate(fields):
                if field == 'GeV':
                    massValuesAvailable.append(int(fields[ii - 1]))
                if field == 'ifb':
                    lumiValues.append(float(fields[ii - 1].replace('p', '.')))

    massValues = list(set(massValuesConfig) & set(massValuesAvailable))
    massValues.sort(key=float)
    lumiValues = list(set(lumiValues))
    lumiValues.sort(key=float)
    print '\navailable values'
    print '  mass [GeV]: %s' % massValues
    print '  luminosity [fb^-1]: %s' % lumiValues

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

    #------------------------------------------
    #arrays for sensitivity scan graphs
    gmass = np.array(massValues, dtype=np.float64)
    glumi = np.zeros_like(gmass, dtype=np.float64)
    glowedge = np.zeros_like(gmass, dtype=np.float64)
    ghighedge = np.zeros_like(gmass, dtype=np.float64)

    #------------------------------------------
    #loop over luminosity values
    for lumi in lumiValues:

        #------------------------------------------
        if args.debug:
            print '\n\n******************************************'
            print '******************************************'
            print 'luminosity = %s ^pb-1' % lumi
            print 'available mass values [GeV]: %s' % massValues
            print '******************************************'
            print '******************************************\n'

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

        #------------------------------------------
        #loop over signal mass values
        removeMassValues = []
        for mass in massValues:

            #------------------------------------------
            #check SearchPhase results
            if args.debug:
                print '******************************************\nSearchPhase results\n'
                print '%s mass = %s GeV' % (model, mass)
                print 'lumi = %s fb^-1' % lumi

            #get SearchPhase result file
            spFileName = ''
            for searchphaseFileName in sorted(searchphaseFileList):
                #if '.%s.'%model in searchphaseFileName and '.%i.par.'%nPar in searchphaseFileName and '.%i.seed.'%seed in searchphaseFileName and args.tag in searchphaseFileName and '.%s.GeV.'%int(mass) in searchphaseFileName and '.%s.ifb.'%slumi in searchphaseFileName:
                if '.%s.' % model in searchphaseFileName and '.%i.par.' % nPar in searchphaseFileName and '.%i.seed.' % seed in searchphaseFileName and args.tag in searchphaseFileName and '.%s.GeV.' % int(
                        mass
                ) in searchphaseFileName and '.%s.ifb.' % slumi in searchphaseFileName and '.%s' % histBaseName in searchphaseFileName and '%s' % bTaggingWP in searchphaseFileName:
                    spFileName = searchphaseFileName

            spFileName = args.path + '/' + spFileName

            if spFileName != '':
                if args.debug:
                    print 'file = %s' % spFileName
            else:
                continue

            if os.path.isfile(spFileName):
                spFile = ROOT.TFile(spFileName, 'READ')
                if not spFile:
                    raise SystemExit(
                        '\n***ERROR*** couldn\'t open search pahse output file: %s'
                        % spFileName)

                #------------------------------------------
                #fill sensitivity scan graph and remove discovered signal mass values from the list
                bumpHunterStatOfFitToData = spFile.Get(
                    "bumpHunterStatOfFitToData")
                bumpHunterStatValue = bumpHunterStatOfFitToData[0]
                bumpHunterPValue = bumpHunterStatOfFitToData[1]
                bumpHunterPValueErr = bumpHunterStatOfFitToData[2]

                bumpHunterPLowHigh = spFile.Get('bumpHunterPLowHigh')
                #bumpHunterStatValue = bumpHunterPLowHigh[0]
                bumpLowEdge = bumpHunterPLowHigh[1]
                bumpHighEdge = bumpHunterPLowHigh[2]

                if args.debug:
                    print "bump range: %s GeV - %s GeV" % (bumpLowEdge,
                                                           bumpHighEdge)
                    print "BumpHunter stat = %s" % bumpHunterStatValue
                    print "BumpHunter p-value = %s +/- %s" % (
                        bumpHunterPValue, bumpHunterPValueErr)

                bumpHunterSigmas = ROOT.Math.normal_quantile(
                    1. - bumpHunterPValue, 1.)
                if args.debug:
                    print "BumpHunter sigmas = %s" % bumpHunterSigmas

                if bumpHunterSigmas > 5.:
                    massIndex = np.where(gmass == mass)

                    #------------------------------------------
                    #NOTE remove some points
                    #if float(mass) <= 6000. or float(mass) >= 11000.:
                    #    glumi[massIndex] = 0.
                    #else:
                    glumi[massIndex] = lumi  #NOTE always keep this uncommented
                    glowedge[
                        massIndex] = bumpLowEdge  #NOTE always keep this uncommented
                    ghighedge[
                        massIndex] = bumpHighEdge  #NOTE always keep this uncommented
                    #------------------------------------------

                    removeMassValues.append(mass)

                #------------------------------------------

            else:
                print 'BumpHunter results not available for %s GeV %s: %s' % (
                    mass, model, spFileName)

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

        #------------------------------------------
        #remove mass points discovered
        for removeMass in removeMassValues:
            massValues.remove(removeMass)
        if args.debug:
            print '\n******************************************'
            print 'available mass values [GeV]: %s' % massValues
            print '******************************************'

    #------------------------------------------
    #print sensitivity scan results
    print '\nsensitivity scan results'
    print '  mass [GeV] = %s' % gmass
    print '  luminosity [fb^-1] = %s' % glumi

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

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

    #------------------------------------------
    #canvas and pads
    c = ROOT.TCanvas('c', 'c', 100, 50, 800, 600)
    yd = 0.5  #bottom pad height (pad2)
    pad1 = ROOT.TPad("pad1", "pad1", 0, yd, 1, 1)  #top
    pad2 = ROOT.TPad("pad2", "pad2", 0, 0, 1, yd)  #bottom

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

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

    #..........................................
    #labels
    ax = 0.65  #0.20
    ay = 0.80  #0.88
    a = plotTools.getATLAS()
    p = plotTools.getInternal()
    n = plotTools.getNote(textSize)
    spacing = 0.06  #0.04
    textSize = 20

    #------------------------------------------
    #pad 1
    #------------------------------------------
    pad1.cd()
    pad1.Clear()
    pad1.SetLogx(0)
    pad1.SetLogy(1)

    #..........................................
    #graph
    g = ROOT.TGraph(len(gmass), gmass, glumi)
    g.SetTitle('sensitivity studies')

    g.GetXaxis().SetTitle('m_{%s} [GeV]' % modelLabel)
    g.GetXaxis().SetLabelFont(43)
    g.GetXaxis().SetLabelSize(textSize)
    g.GetXaxis().SetTitleFont(43)
    g.GetXaxis().SetTitleSize(textSize)
    dx = gmass[0] * 0.1
    g.GetXaxis().SetLimits(gmass[0] - dx, gmass[-1] + dx)

    g.GetYaxis().SetTitle('discovery luminosity [fb^{-1}]')
    g.GetYaxis().SetLabelFont(43)
    g.GetYaxis().SetLabelSize(textSize)
    g.GetYaxis().SetTitleFont(43)
    g.GetYaxis().SetTitleSize(textSize)

    glumiMin = max(glumi[0], glumi.min())  #NOTE can not use 0. in log scale
    g.SetMinimum(glumiMin * 0.5)  #HERE before Draw()
    g.SetMaximum(glumi.max() * 2.)  #HERE before Draw()

    g.Draw("ap")

    #..........................................
    #luminosity lines
    llumi = ROOT.TLine()
    llumi.SetLineColor(ROOT.kRed)
    llumi.SetLineWidth(2)
    #llumi.DrawLine(g.GetXaxis().GetXmin(), 1., g.GetXaxis().GetXmax(), 1.)

    #draw graph (again but) on top of the lines
    g.Draw("same p")

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

    #notes
    allNotes = []
    allNotes.append('#sqrt{s} = 13 TeV')
    allNotes.append('%s sensitivity scan' % modelLabel)
    allNotes.append('%s parameter fit' % nPar)
    allNotes += notes

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

    #..........................................
    c.cd()
    c.Update()

    #------------------------------------------
    #pad 2
    #------------------------------------------
    pad2.cd()
    pad2.Clear()
    pad2.SetLogx(0)
    pad2.SetLogy(0)
    pad2.SetGridx(1)
    pad2.SetGridy(1)

    #..........................................
    #bump band
    gb = ROOT.TGraphAsymmErrors(
        len(glumi), gmass, (ghighedge + glowedge) / 2, np.zeros_like(glumi),
        np.zeros_like(glumi), (ghighedge - glowedge) / 2,
        (ghighedge - glowedge) / 2)  #n,x,y,exl,exh,eyl,eyh
    gb.SetTitle('bump range')

    gb.GetXaxis().SetTitle('m_{%s} Q[GeV]' % modelLabel)
    gb.GetXaxis().SetLabelFont(43)
    gb.GetXaxis().SetLabelSize(textSize)
    gb.GetXaxis().SetTitleFont(43)
    gb.GetXaxis().SetTitleSize(textSize)
    gb.GetXaxis().SetLimits(gmass[0] - dx, gmass[-1] + dx)
    gb.GetXaxis().SetTitleOffset(
        2.5)  #this needs to be adjusted depending on yd

    gb.GetYaxis().SetTitle('m_{%s} Q[GeV]' % modelLabel)
    gb.GetYaxis().SetTitle(axisLabel)
    gb.GetYaxis().SetLabelFont(43)
    gb.GetYaxis().SetLabelSize(textSize)
    gb.GetYaxis().SetTitleFont(43)
    gb.GetYaxis().SetTitleSize(textSize)
    gb.GetYaxis().SetDecimals(True)

    gb.SetMarkerColor(ROOT.kRed)
    gb.SetLineColor(ROOT.kRed)
    gb.SetFillColor(ROOT.kRed)
    gb.SetFillStyle(3003)

    #..........................................
    #draw
    gb.Draw("ape")  #draw points
    #gbb = gb.Clone()
    #gbb.Draw("same3") #draw band

    #..........................................
    c.cd()
    c.Update()

    #..........................................
    c.Update()
    if args.wait:
        c.WaitPrimitive()
    c.SaveAs(localdir + '/../figures/sensitivityscan.' + model + '.' +
             histName + '.%i' % nPar + '.par.%i' % seed + '.seed.' + args.tag +
             '.pdf')