예제 #1
0
def getPlotsIn(inF, dirname, LPdirname, rebin=True, var=None, bins=[]):
    """gets the data and mc sums in a given directory"""

    data, dataLP = None, None
    if not inF.Get(LPdirname): return None, None
    LPKeys = inF.Get(LPdirname).GetListOfKeys()
    Keys = inF.Get(dirname).GetListOfKeys()
    for key, LPkey in product(Keys, LPKeys):
        name = key.GetName()
        nameLP = LPkey.GetName()
        if ('Graph' in name): continue
        if ('Graph' in nameLP): continue
        if (not name == dirname) and (not nameLP == LPdirname): continue
        #data histogram
        data_ = key.ReadObj()
        dataLP_ = LPkey.ReadObj()
        # if data_.InheritsFrom(ROOT.TH2.Class()): continue
        # if dataLP_.InheritsFrom(ROOT.TH2.Class()): continue

        if rebin:
            data_.Rebin()
            dataLP_.Rebin()
        if ((not bins == []) and (var in name)):
            data = rebinUnequalBinSize(data_, bins)
            dataLP = rebinUnequalBinSize(dataLP_, bins)
        else:
            data = data_.Clone()
            data.SetDirectory(0)
            fixExtremities(data)
            dataLP = dataLP_.Clone()
            dataLP.SetDirectory(0)
            fixExtremities(dataLP)

    return data, dataLP
예제 #2
0
def customizeSignalShapes(binName, sigName, sigF, baseSigF, outDir):
    """ 
    takes specific signal and scales the base signal simulation + systematics by the ratio sig/orig_signal
    the result is stored in {0}_{1}.shapes.root {0}=signal name {1}=binName
    """

    #get signal
    fIn = ROOT.TFile.Open(sigF)
    sigH = fIn.Get('{0}_mlb'.format(binName))
    sigH.SetDirectory(0)
    fixExtremities(
        sigH
    )  # this needs to be done as the signal is the raw output of TOP-17-010.cc
    fIn.Close()

    #get original signal
    fIn = ROOT.TFile.Open(baseSigF)
    origSigH = fIn.Get('{0}_mlb/central'.format(binName))
    origSigH.SetDirectory(0)

    #force the integral to be the same as this is a shape analysis
    sf = origSigH.Integral() / sigH.Integral()
    sigH.Scale(sf)

    #transfer factor
    tfH = sigH.Clone('tf')
    tfH.Divide(origSigH)
    tfH.SetDirectory(0)

    #prepare the output applying the transfer factor to each histogram found
    fOut = ROOT.TFile.Open(
        os.path.join(outDir, '{0}.shapes.root'.format(sigName)), 'RECREATE')
    fdir = fOut.mkdir('{0}_mlb'.format(binName))
    for k in fIn.Get('{0}_mlb'.format(binName)).GetListOfKeys():
        h = k.ReadObj()
        h.SetDirectory(fdir)
        for xbin in range(h.GetNbinsX()):
            h.SetBinContent(
                xbin + 1,
                h.GetBinContent(xbin + 1) * tfH.GetBinContent(xbin + 1))
        fdir.cd()
        h.Write()
    fOut.Close()

    #free mem
    tfH.Delete()
    fIn.Close()
예제 #3
0
def getPassGenDistributions(pName, gName, plotter, ci, fill=0, marker=20):
    """reads the distributions from the plotter"""

    passH = plotter.Get(pName)
    fixExtremities(passH)
    passH.SetDirectory(0)
    passH.SetFillStyle(fill)
    passH.SetLineColor(ci)
    passH.SetMarkerColor(ci)
    passH.SetLineWidth(2)
    passH.SetMarkerStyle(marker)

    genH = plotter.Get(gName)
    fixExtremities(genH)
    genH.SetDirectory(0)
    genH.SetFillStyle(fill)
    genH.SetLineColor(ci)
    genH.SetMarkerColor(ci)
    genH.SetLineWidth(2)
    genH.SetMarkerStyle(marker)

    return passH, genH
예제 #4
0
def getPlotsIn(inF,dirname,specList=[],rebin=True,bins=[]):

    """gets the data and mc sums in a given directory"""

    data,mcTotal,h=None,None,None
    mcSpecList=[None]*len(specList)
    for key in inF.Get(dirname).GetListOfKeys():
        name=key.GetName()
        if 'Graph' in name : continue        

        #data histogram
        if name==dirname:
            data_=key.ReadObj()
            if rebin : 
                data_.Rebin(rebin)
            if len(bins)>0: 
                data = rebinUnequalBinSize(data_,bins)
            else:
                data = data_.Clone()
            data.SetDirectory(0)
            fixExtremities(data)

        #predictions
        else:
            h_=key.ReadObj()
            if rebin: 
                h_.Rebin(rebin)
            if len(bins)>0: 
                h = rebinUnequalBinSize(h_,bins)
            else:
                h = h_.Clone();
            proc=name.split('_')[-1]
            
            #check if this specific process should be stored
            try:                
                idx=specList.index(proc)
                mcSpecList[idx]=h.Clone()
                mcSpecList[idx].SetDirectory(0)
                fixExtremities(mcSpecList[idx])
            except:
                pass

            #add to the total
            if not mcTotal:
                mcTotal=h.Clone(dirname+'_mctot')
                mcTotal.SetDirectory(0)
                mcTotal.Reset('ICE')
            mcTotal.Add(h)

    if mcTotal : fixExtremities(mcTotal)

    return data,mcTotal,mcSpecList
예제 #5
0
def getUncertaintiesFromProjection(opt,fIn,d,proc_systs,hnom):

    """projects the _exp and _th 2D histograms to build the corresponding Up/Down uncertainty templates"""

    histos=[]
    errors=[]
    warns=[]

    #map all systematics available for projection
    allSysts={}
    for hname in ['{0}_exp'.format(d),'{0}_th'.format(d)]:
        h2d=fIn.Get('{0}/{0}_{1}'.format(hname,proc_systs['title']))
        try:
            for ybin in range(h2d.GetNbinsY()):
                allSysts[h2d.GetYaxis().GetBinLabel(ybin+1)]=(h2d,ybin+1)
        except:
            pass

    #project systematics
    for s in proc_systs['proj']:
        slist,norm,doEnvelope,smooth=proc_systs['proj'][s]
     
        try:            
            h2d,ybin=allSysts[ slist[0] ]
            varUp=h2d.ProjectionX('varup',ybin,ybin)
            fixExtremities(varUp) #add the overflow as for the main plot
            if smooth: applySmoothing(varUp)
        except:            
            errors.append('Failed to prepare %s'%slist[0])
            continue

        varDn=None

        #project down variation if available
        if not doEnvelope:
            try:
                h2d,ybin=allSysts[ slist[1] ]
                varDn=h2d.ProjectionX('vardn',ybin,ybin)
                fixExtremities(varDn) #add the overflow as for the main plot
                if smooth: applySmoothing(varDn)
            except:
                errors.append('Failed to prepare %s'%slist[1])
                continue

        #make an envelope if several are available
        elif len(slist)>2:

            try:
                varUp.Reset('ICE')
                varUp.Add(hnom) 
                varDn=hnom.Clone('vardn')
                for s_i in slist:

                    h2d,ybin=allSysts[ s_i ]
                    vartemp=h2d.ProjectionX('vartemp',ybin,ybin)
                    fixExtremities(vartemp) #add the overflow as for the main plot
                    if smooth: applySmoothing(vartemp)

                    #do max(var_i-nom,var_j-nom) per bin
                    for xbin in range(hnom.GetNbinsX()):
                        val         = vartemp.GetBinContent(xbin+1)
                        deltaVal    = val-hnom.GetBinContent(xbin+1)
                        if deltaVal>0:
                            curDeltaVal = varUp.GetBinContent(xbin+1)-hnom.GetBinContent(xbin+1)                 
                            if curDeltaVal<deltaVal:
                                varUp.SetBinContent(xbin+1,val)
                        else:
                            curDeltaVal = varDn.GetBinContent(xbin+1)-hnom.GetBinContent(xbin+1)                 
                            if curDeltaVal>deltaVal:
                                varDn.SetBinContent(xbin+1,val)
                            
                    #delete as no longer used
                    vartemp.Delete()

            except:
                errors.append('Failed to prepare %s'%s_i)
                continue


        #mirror the shape if down variation is not available yet
        if not varDn:
            varDn=getMirrored(varUp,hnom,'vardn')
            
        #check, format and add to the list if variation is to keep
        keep,checkReport=doFinalTemplateCheck(hnom,varUp,varDn)
        if len(checkReport):
            pfix='Keep but' if keep else 'Discard as'
            warns.append('%s %s for %s'%(pfix,checkReport.replace('\n',','),s))

        formatTemplate(varUp,s+'Up',norm=hnom.Integral() if norm else None)
        formatTemplate(varDn,s+'Down',norm=hnom.Integral() if norm else None)
        if keep:            
            histos.append(varUp)
            histos.append(varDn)

        #show plot with warnings found
        if opt.debug: 
            showVariation(hnom,
                          [varUp,varDn],
                          checkReport.split('\n'),
                          os.path.join(opt.output,'{0}_{1}_{2}'.format(hnom.GetTitle(),d,s)))

    #print errors/warnings found
    if len(errors) or len(warns):
        print '-'*50
        print 'Some errors/warnings found projecting syst templates for',proc_systs['title']
        print 'Please check the list below'
        for e in errors : print e
        for w in warns  : print w
        print '-'*50
            
    return histos
예제 #6
0
def customizeData(binName, dataDef, bkgList, templDir, outDir):
    """ customizes data to use as observation """
    dataDef = dataDef.replace("\"", "")
    tkns = dataDef.split(',')
    dataType, dataF, dataHisto = tkns[0:3]

    #get the data
    inF = ROOT.TFile.Open(dataF)
    dataH = inF.Get(dataHisto)
    dataH.SetDirectory(0)
    inF.Close()

    #use a scenario as pseudo-data
    if len(tkns) == 5:

        #reset current histogram
        ndata = dataH.Integral()
        dataH.Reset('ICE')

        #scale scenario to the current number of entries
        scenario, scenarioHisto = tkns[3:5]
        scenarioF = os.path.dirname(os.path.dirname(dataF))
        scenarioF = os.path.join(scenarioF, scenario)
        print 'Using a scenario as pseudo-data', scenarioF, scenarioHisto
        inF = ROOT.TFile.Open(scenarioF)
        hscen = inF.Get(scenarioHisto)
        fixExtremities(
            hscen
        )  # this needs to be done as the signal is the raw output of TOP-17-010.cc
        hscen.Scale(ndata / hscen.Integral())
        dataH.Add(hscen)
        inF.Close()
        dataH.SetTitle(dataH.GetTitle() + os.path.dirname(scenario))
        print 'Scaled', scenario, 'to', ndata, 'new title=', dataH.GetTitle()

    #specific for pseudo-data
    #sum up signal to background expectations when dataType is 'sig' type
    #round each bin to an integer
    if dataType == 'sig':
        for proc in bkgList:
            inF = ROOT.TFile.Open('{0}/templates_{1}.root'.format(
                templDir, proc))
            h = inF.Get('{0}_mlb/central'.format(binName))
            dataH.Add(h)
            inF.Close()

        for xbin in range(dataH.GetNbinsX()):
            dataH.SetBinContent(xbin + 1, int(dataH.GetBinContent(xbin + 1)))

        dataType = dataH.GetTitle()
        for tkn in [' ', '#', '_', '^', '{', '}', ',', ':', '+', '-']:
            dataType = dataType.replace(tkn, '')
        dataType = dataType.replace('.', 'p')
        dataType = 'pseudodata.%s' % dataType

    #save to file
    dataShapesURL = os.path.join(outDir, '%s.shapes.root' % dataType)
    fOut = ROOT.TFile.Open(dataShapesURL, 'RECREATE')
    fdir = fOut.mkdir('{0}_mlb'.format(binName))
    fdir.cd()
    dataH.SetTitle('')
    dataH.SetDirectory(fdir)
    dataH.Write('data_obs')
    fOut.Close()

    return dataShapesURL
예제 #7
0
def computeVBFTriggerEff(f, distsOfInterest):
    """computes ratios to evaluate VBF trigger efficiency and fits an erf function"""

    ratios = {}
    inF = ROOT.TFile.Open(f)
    for key in inF.GetListOfKeys():
        name = key.GetName()
        if not 'HighPtVBFA' in name: continue
        dist = '_'.join(name.split('_')[1:])
        if not dist in distsOfInterest: continue

        dataNum, mcNum, _ = getPlotsIn(inF, name, rebin=False)
        dataDen, mcDen, _ = getPlotsIn(inF,
                                       name.replace('HighPtVBFA',
                                                    'HighPtOfflineVBFA'),
                                       rebin=False)
        for h in [dataNum, mcNum, dataDen, mcDen]:
            fixExtremities(h)
            scaleTo(h, 1.0)

        dataNum.Divide(dataDen)
        dataNum.GetYaxis().SetTitle(
            'High p_{T} VBF #gamma / High p_{T} #gamma')
        dataNum.SetTitle('Data')
        dataNum.SetMarkerStyle(20)

        mcNum.Divide(mcDen)
        mcNum.GetYaxis().SetTitle('High p_{T} VBF #gamma / High p_{T} #gamma')
        mcNum.SetTitle('MC')
        mcNum.SetMarkerStyle(24)
        mcNum.SetMarkerColor(ROOT.kGray)
        mcNum.SetLineColor(ROOT.kGray)
        mcNum.SetFillStyle(1001)
        mcNum.SetFillColor(ROOT.kGray)

        data2mc = dataNum.Clone('{0}_data2mc'.format(dist))
        data2mc.Divide(mcNum)
        data2mc.SetDirectory(0)
        data2mc.GetYaxis().SetTitle('Data/MC')

        turnOn = None
        if dist in ['mjj', 'subleadpt']:
            turnOn = ROOT.TF1('turnon', '[0]+[1]/(1.+TMath::Exp([2]*(x-[3])))',
                              dataNum.GetXaxis().GetXmin(),
                              dataNum.GetXaxis().GetXmax())
            turnOn.SetParLimits(0, 0., 0.8)
            turnOn.SetParLimits(1, 0.5, 1.2)
            turnOn.SetParLimits(2, -2, 2)
            turnOn.SetParLimits(3, 500, 2000)
            if dist == 'subleadpt': turnOn.SetParLimits(3, 20, 50)
        #else:
        #    turnOn=ROOT.TF1('turnon',
        #                    '[0]',
        #                    dataNum.GetXaxis().GetXmin(),
        #                    dataNum.GetXaxis().GetXmax())
        data2mcParam = parametrizeTurnOn(dataNum, mcNum, turnOn)
        ratios[name] = (dataNum, mcNum, data2mc, data2mcParam)

    inF.Close()

    return ratios