def GetYield2(path, files, ch='eee', level='sr', inc=None, histopref='', filepref='', var='', isdata=False): t = TopHistoReader(path, files) t.SetLevel(level) t.SetChan(ch) t.SetHistoNamePrefix(histopref) #t.SetLumi(GetLumi(2018)*1000) #t.SetLumi(GetLumi(year)*1000) #t.SetLumi(1) t.SetFileNamePrefix(filepref) t.SetIsData(isdata) if var != '': pref = histopref + '_' if histopref != '' else '' if inc == None: h = t.GetNamedHisto(pref + var + '_' + ch) else: h = t.GetNamedHisto(pref + var + '_' + ch + '_' + inc) y = h.GetBinContent(9) else: y = t.GetYield() return y
def __init__(self, path, outpath='./temp/', chan='ElMu', level='2jets', DYsamples='DYJetsToLL_M_10to50,DYJetsToLL_MLL50', DataSamples='HighEGJet,SingleMuon, DoubleMuon', lumi=304.32, massRange=[91 - 15, 91 + 15], mode='', histonameprefix='H', hname='DY_InvMass'): self.SetPath(path) self.SetOutPath(outpath) self.t = TopHistoReader(path) self.t.SetHistoNamePrefix(histonameprefix) self.SetLumi(lumi) self.SetChanAndLevel(chan, level) self.SetDYsamples(DYsamples) self.SetDataSamples(DataSamples) self.SetMassRange(massRange[0], massRange[1]) self.SetHistoNameOF() self.SetHistoNameSF() if chan == 'ElMu': if hname != '': self.SetHistoNameOF(hname) self.SetMode('OF') else: if hname != '': self.SetHistoNameSF(hname) self.SetMode('SF') if mode != '': self.SetMode(mode)
def __init__(self, path, outpath='./temp/', chan='ElMu', level='2jets', process={}, prompt=[], nonprompt=[], lumi=304.32, histonameprefix='H', yieldsSSname='SSYields'): self.SetPath(path) self.t = TopHistoReader(self.GetPath()) self.t.SetHistoNamePrefix(histonameprefix) self.t.SetYieldsSSname(yieldsSSname) self.SetLumi(lumi) self.SetOutPath(outpath) self.SetChanAndLevel(chan, level) self.process = process self.nonpromptProcess = [] self.promptProcess = [] if prompt == [] or nonprompt == []: for pr in process.keys(): if pr in ['data', 'Data', 'DATA']: continue elif pr in [ 'fake', 'nonprompt', 'Nonprompt', 'NonPrompt', 'Fake', 'fakes', 'Fakes' ]: self.nonpromptProcess.append(pr) else: self.promptProcess.append(pr) else: self.promptProcess = prompt self.nonpromptProcess = nonprompt
def SavePlots(s, var='mt2', sampName='tt', tag='PDF uncertainty'): tr = TopHistoReader(outpath + s) a = HistoUnc(out + '/PDF%s/' % sampName, var + sampName + s, tag=tag, xtit=titdic[var] if var in titdic.keys() else '') a.SetLumi(GetLumi(year)) a.AddHistoNom(tr.GetNamedHisto(sampName, var)) a.AddHistoUp(tr.GetNamedHisto(sampName + '_' + s + 'Up', var)) a.AddHistoDown(tr.GetNamedHisto(sampName + '_' + s + 'Down', var)) a.Draw()
def __init__(self, path, hname='', outpath='./temp/', outname='', rebin=1): self.t = TopHistoReader(path) self.SetPath(path) self.SetRebin(rebin) self.SetHistoName(hname) self.SetOutputDir(outpath) self.SetOutName(outname) self.histos = [] self.syst = [] self.dpr = {} self.AddData()
#gr.GetXaxis().SetLimits(165,180); c.SetRightMargin(0.03) c.Update() for form in ['png', 'pdf']: c.Print(outpath + outname + '_' + mode + '.' + form) ch = 'ElMu' lev = '2jets' level = {'dilepton': 1, 'ZVeto': 2, 'MET': 3, '2jets': 4, '1btag': 5} # Get acceptance numbers from plotter.TopHistoReader import TopHistoReader thr = TopHistoReader(path) dic = {'tt': 'TT', 'up': 'TT_mtop178p5', 'down': 'TT_mtop166p5'} GetAcc = lambda samp, ch, lev: thr.GetNamedHisto('Lep0Eta_%s_%s' % (ch, lev), dic[samp]).Integral() GetUnc = lambda samp, ch, lev: thr.GetNamedHisto('Yields_%s' % (ch), dic[samp] ).GetBinError(level[lev]) nom = GetAcc('tt', ch, lev) up = GetAcc('up', ch, lev) do = GetAcc('down', ch, lev) mass = [166.5, 172.5, 178.5] xsec = [xsecnom * (nom / do), xsecnom, xsecnom * (nom / up)] #= [xsecunc*(nom/do), xsecunc, xsecunc*(nom/up)] xsecerr = [GetUnc(x, ch, lev) for x in ['down', 'tt', 'up']] DrawTopMassFit(mass, xsec, xsecerr, 'lin')
class DYDD: ### Set methods def SetPath(self, p): if not p.endswith('/'): p += '/' self.path = p def SetOutPath(self, p): self.outpath = p def SetMode(self, mode='OF', hname=''): self.doOF = True if mode in ['SF', 'Elec', 'ElEl', 'Muon', 'MuMu']: self.doOF = False if self.doOF: if hname != '': self.SetHistoNameOF(hname) self.SetZhistoName(self.hnameOF) else: if hname != '': self.SetHistoNameSF(hname) self.SetZhistoName(self.hnameSF) def SetLumi(self, l): self.lumi = l self.t.SetLumi(self.lumi) def SetHistoNameOF(self, h='DY_InvMass'): self.hnameOF = h def SetHistoNameSF(self, h='DY_SF_InvMass'): self.hnameSF = h def SetDYsamples(self, f): self.DYfiles = f def SetDataSamples(self, f): self.datafiles = f def SetChannel(self, c): self.chan = c def SetLevel(self, l): self.level = l def SetZhistoName(self, h): self.zhname = h def SetMassRange(self, minM=91 - 15, maxM=91 + 15): self.minMZ = minM self.maxMZ = maxM def SetChanAndLevel(self, chan='', level=''): ''' Manages to set chan and leve to the class and the TopHistoReader ''' if chan != '': self.SetChannel(chan) if level != '': self.SetLevel(level) self.t.SetChan(self.GetChan()) self.t.SetLevel(self.GetLevel()) return self.GetChan(), self.GetLevel() ### Get methods def GetPath(self): return self.path def GetOutPath(self): return self.outpath def GetZhistoName(self): return self.zhname def GetDYfiles(self): return self.DYfiles def GetDataFiles(self): return self.datafiles def GetLevel(self): return self.level def GetChan(self): return self.chan ### Calculate quantities... def GetDYhisto(self, chan='', level='', isData=True): # ARREGLAR PARA QUE COJA EL ADECUADO DEPENDIENDO DEL CANAL!! O HACER FUNCION PARA INDICAR CANAL EMU chan, level = self.SetChanAndLevel(chan, level) if isData: self.t.SetIsData(True) pr = self.GetDataFiles() else: self.t.SetIsData(False) pr = self.GetDYfiles() zname = self.GetZhistoName() if level == 'dilepton' and zname[-4:] == 'ElMu': zname = zname[:-4] h = self.t.GetHisto(pr, zname, chan, level) h.SetDirectory(0) return h def GetHdata(self, chan, level): return self.GetDYhisto(chan, level, True) def GetHMC(self, chan, level): return self.GetDYhisto(chan, level, False) def DYyield(self, direc='in', isData=True, chan='', level=''): h = self.GetDYhisto(chan, level, isData) b0 = h.FindBin(self.minMZ) bN = h.FindBin(self.maxMZ) nbins = h.GetNbinsX() integral = h.Integral() y = 0 err = 0 if direc == 'in' or direc == 'In' or direc == 'IN': y += h.Integral(b0, bN) else: y += h.Integral(0, b0 - 1) y += h.Integral(bN + 1, nbins + 1) if isData: err = sqrt(y) else: entries = h.GetEntries() err = sqrt((y * integral) / entries) if y < 0: # Avoid wierd numbers due to negative weights... y = 0 err = 0 return y, err def GetDataIn(self, chan='', level=''): return self.DYyield('in', True, chan, level) def GetDataOut(self, chan='', level=''): return self.DYyield('out', True, chan, level) def GetMCin(self, chan='', level=''): return self.DYyield('in', False, chan, level) def GetMCout(self, chan='', level=''): return self.DYyield('out', False, chan, level) def GetRoutin(self, chan='', level=''): ''' Returns ratio Rout/in from MC ''' rin, errin = self.GetMCin(chan, level) out, errout = self.GetMCout(chan, level) r = out / rin if rin != 0 else 0 err = r * SumSquare( [errout / out if out != 0 else 0, errin / rin if rin != 0 else 0]) return r, err def GetKfactor(self, chan='', level=''): ''' Calculate the k factor k_ee, k_mumu ''' chan, level = self.SetChanAndLevel(chan, level) rinElec, errElec = self.GetDataIn(elname, level) rinMuon, errMuon = self.GetDataIn(muname, level) k = (rinElec / rinMuon if rinMuon != 0 else 0) if chan == elname else ( rinMuon / rinElec if rinElec != 0 else 0) k = sqrt(k) kerr = k * SumSquare([ errElec / (2 * rinElec) if rinElec != 0 else 0, errMuon / (2 * rinMuon) if rinMuon != 0 else 0 ]) return k, kerr def GetDYDD(self, chan='', level='', mode=''): ''' Returns the DY estimate from data ''' chan, level = self.SetChanAndLevel(chan, level) if chan == 'ElMu': self.SetMode('ElMu') if mode != '': self.SetMode(mode) routin, routin_err = self.GetRoutin(chan, level) NemuIn, NemuIn_err = self.GetDataIn('ElMu', level) kee, keerr = self.GetKfactor(elname, level) NeeIn, NeeInerr = self.GetDataIn(elname, level) kmm, kmmrr = self.GetKfactor(muname, level) NmmIn, NmmInerr = self.GetDataIn(muname, level) est = lambda r, Nin, Nemu, k: r * (Nin - Nemu * k / 2) esterr = lambda r, Nin, Nemu, k, er, eNin, eNemu, ek: SumSquare([ est(r, Nin, Nemu, k) * (er / r if r != 0 else 0), r * eNin, r * k / 2 * eNemu, r * Nemu / 2 * ek ]) N = 0 Nerr = 0 if chan == elname: N = est(routin, NeeIn, NemuIn, kee) Nerr = esterr(routin, NeeIn, NemuIn, kee, routin_err, NeeInerr, NemuIn_err, keerr) elif chan == muname: N = est(routin, NmmIn, NemuIn, kmm) Nerr = esterr(routin, NmmIn, NemuIn, kmm, routin_err, NmmInerr, NemuIn_err, kmmrr) else: # ElMu self.t.SetIsData(False) yDY = self.t.GetYield(self.GetDYfiles(), 'ElMu') yDYe = self.t.GetYieldStatUnc(self.GetDYfiles(), 'ElMu') SF, err = self.GetScaleFactor('ElMu') N = yDY * SF Nerr = N * SumSquare([ err / SF if SF != 0 else err, yDYe / yDY if yDY != 0 else yDYe ]) if N < 0: N = 0 Nerr = 0 if not Nerr == Nerr: Nerr = 0 return N, Nerr def GetScaleFactor(self, chan='', level='', mode=''): ''' Returns the data/MC ratio for the DY estimate ''' chan, level = self.SetChanAndLevel(chan, level) if chan == 'ElMu': self.SetMode('ElMu') if mode != '': self.SetMode(mode) SF = 1 err = 0 if chan == muname or chan == elname: dd, dde = self.GetDYDD(chan) mo, moe = self.GetMCout(chan) SF = dd / mo if mo != 0 else 0 err = SF * SumSquare( [dde / dd if dd != 0 else 0, moe / mo if mo != 0 else 0]) elif chan == 'ElMu': e, er = self.GetScaleFactor(elname) m, mr = self.GetScaleFactor(muname) SF = sqrt(e * m) err = SF * SumSquare( [er / e if e != 0 else 0, mr / m if m != 0 else 0]) return SF, err def DrawHisto(self, doSF=False, name='', chan='', level='', rebin=1, log=True): self.SetChanAndLevel('', level) self.SetMode('SF' if doSF else 'OF') if name == '': name = 'DYDD_%s_%s' % ('SF' if doSF else 'OF', self.GetLevel()) hData = self.GetDYhisto(chan, level, True) hMC = self.GetDYhisto(chan, level, False) hemu = self.GetDYhisto('ElMu', level, True) hData.SetMarkerStyle(20) hData.SetMarkerColor(1) hData.SetLineColor(1) hData.SetMarkerSize(1.3) hMC.SetFillStyle(1000) hMC.SetLineColor(kAzure - 8) hMC.SetFillColor(kAzure - 8) hemu.SetFillStyle(1000) hemu.SetLineColor(kGray) hemu.SetFillColor(kGray) hData.Rebin(rebin) hemu.Rebin(rebin) hMC.Rebin(rebin) ke, kee = self.GetKfactor(elname) km, kme = self.GetKfactor(muname) hemu.Scale(0.5 * (ke if chan == 'ElE' else km)) hs = THStack() hs.Add(hemu) hs.Add(hMC) lab = 'e^{#pm}e^{#mp}' if chan == 'ElEl' else '#mu^{#pm}#mu^{#mp}' rlab = 'ee' if chan == 'ElEl' else '#mu#mu' processes = [ 'Z/#gamma*#rightarrow %s' % (lab), '0.5 k_{%s} #times Data(e#mu)' % rlab ] colors = {processes[0]: kAzure - 9, processes[1]: kGray} s = Stack(doRatio=False) s.SetXtitle(size=0.06, offset=0.8, nDiv=510, labSize=0.05) s.SetTextCMS(cmstex='CMS', x=0.13, y=0.88, s=0.06) s.SetTextCMSmode(texcmsMode='Preliminary', x=0.225, y=0.875, s=0.052) s.SetLumi(304.32) s.SetTextLumi(texlumi='%2.1f pb^{-1} (5.02 TeV)', texlumiX=0.68, texlumiY=0.95, texlumiS=0.045) s.SetDataHisto(hData) s.SetColors(colors) s.SetStack(hs) s.SetOutName('DYestimate_%s%s' % (chan, level) + ('_log' if log else '')) s.SetOutPath(self.outpath) plotMinimum = 0.5 if log else 0 plotMaxScale = 10 if log else 1.3 s.SetLogY(log) s.SetPlotMaxScale(plotMaxScale) s.SetPlotMinimum(plotMinimum) maximum = hData.GetMaximum() * (5 if log else 1.2) s.AddLine(76, 0.5, 76, maximum) s.AddLine(106, 0.5, 106, maximum) s.processes = processes s.SetLegendPos(x0=0.60, y0=0.55, x1=0.93, y1=0.91, size=0.042, ncol=1) s.DrawStack('m_{%s} (GeV)' % rlab) def DrawClosureMCeff(self, level='dilepton', outpath='~/www/temp/', ratio=[0.9, 1.1]): self.SetMode('OF') self.SetChanAndLevel('', level) ke, kee = self.GetKfactor(elname) km, kme = self.GetKfactor(muname) print 'ke = %1.2f +/- %1.2f' % (ke, kee) print 'km = %1.2f +/- %1.2f' % (km, kme) hdata = TH1F('d1', 'd1', 2, 0, 2) hpred = TH1F('h1', 'h1', 2, 0, 2) err = lambda l: sqrt(sum([x * x for x in l])) ''' hee1 = self.GetDYhisto(elname, level, False) hmm1 = self.GetDYhisto(muname, level, False) ee1 = hee1.Integral(); mm1 = hmm1.Integral() hdata.SetBinContent(1, ee1); hdata.SetBinError(1, sqrt(ee1)); hdata.SetBinContent(2, mm1); hdata.SetBinError(2, sqrt(mm1)); hpred.SetBinContent(1, mm1*ke1); hpred.SetBinError(1, mm1*ke1*( err([sqrt(mm1)/mm1, kee1/ke1]) )) hpred.SetBinContent(2, ee1*km1); hpred.SetBinError(2, ee1*km1*( err([sqrt(ee1)/ee1, kme1/km1]) )) ''' sampName = 'TT' hname = 'Lep0Eta' h_emu = self.t.GetNamedHisto('%s_%s_%s' % (hname, 'ElMu', level), sampName) h_ee = self.t.GetNamedHisto( '%s_%s_%s' % (hname, 'ElEl', '2jetsnomet' if level == '2jets' else level), sampName) h_mu = self.t.GetNamedHisto( '%s_%s_%s' % (hname, 'MuMu', '2jetsnomet' if level == '2jets' else level), sampName) y_emu = h_emu.Integral() * 304.32 y_mu = h_mu.Integral() * 304.32 y_ee = h_ee.Integral() * 304.32 d_ee = 0.5 * y_emu * ke d_ee_err = d_ee * (kee / ke) d_mu = 0.5 * y_emu * km d_mu_err = d_mu * (kme / km) hdata.SetBinContent(1, y_ee) hdata.SetBinError(1, y_ee / sqrt(h_ee.GetEntries())) hdata.SetBinContent(2, y_mu) hdata.SetBinError(2, y_mu / sqrt(h_mu.GetEntries())) hpred.SetBinContent(1, d_ee) hpred.SetBinError(1, d_ee_err) hpred.SetBinContent(2, d_mu) hpred.SetBinError(2, d_mu_err) p = HistoComp(outpath, doRatio=True, doNorm=False) hdata.SetLineWidth(1) hdata.SetMarkerSize(1.2) hdata.SetMarkerColor(1) hdata.SetMarkerStyle(20) hdata.SetFillColor(0) hdata.SetFillStyle(0) hpred.SetFillStyle(3144) hpred.SetFillColor(kAzure - 8) p.SetPlotMaxScale(1.5) p.SetLumi(304.32) p.AddHisto(hpred, 'l', 'e2', '0.5 x k_{ll} x t#bar{t} e#mu MC', kAzure + 2, 2) p.AddHisto(hdata, 'pe', '', 'Same-flavor t#bar{t} MC', 1) p.SetBinLabels(['ee', '#mu#mu']) p.SetYratioTitle('Ratio') p.SetYtitle('t#bar{t} events') rmin, rmax = ratio p.SetLegendPos(0.15, 0.6, 0.5, 0.8, ncol=1) p.SetRatioMin(rmin) p.SetRatioMax(rmax) p.SetOutName('DYDDeffClosure_' + level) p.autoRatio = True p.PlotWithData = True p.Draw(0) def PrintDYestimate(self, doSF=False, name='', level=''): hee = self.GetDYhisto(elname, level, False) hmm = self.GetDYhisto(muname, level, False) self.SetChanAndLevel('', level) self.SetMode('SF' if doSF else 'OF') if name == '': name = 'DYDD_%s_%s' % ('SF' if doSF else 'OF', self.GetLevel()) t = OutText(self.GetOutPath(), name, textformat='tex') t.SetTexAlign("l c c c") t.SetSeparatorLength(20 + (3 + 22) * 3) t.SetDefaultFixOption(False) t.line('%' + 'Drell-Yan estimate for %s and level \'%s\'' % ('SF channels' if doSF else 'all channels (no MET cut) ', self.GetLevel())) t.bar() s = lambda tit, vee, vmm, vem: t.line( t.fix(tit, 20) + t.vsep() + t.fix(vee, 22, 'c') + t.vsep() + t.fix( vmm, 22, 'c') + t.vsep() + t.fix(vem, 22, 'c')) v = lambda val, err: '%1.2f' % val + t.pm() + '%1.2f' % err d = lambda val, err: '%1.0f' % val + t.pm() + '%1.2f' % err s('', 'ee', '$\mu\mu$', 'e$\mu$') t.sep() mie, miee = self.GetMCin(elname) moe, moee = self.GetMCout(elname) mim, mime = self.GetMCin(muname) mom, mome = self.GetMCout(muname) s(' $N_{in}$ (MC)', v(mie, miee), v(mim, mime), '') s(' $N_{out}$ (MC)', v(moe, moee), v(mom, mome), '') re, ree = self.GetRoutin(elname) rm, rme = self.GetRoutin(muname) s(' $R_{out/in}$ (MC)', v(re, ree), v(rm, rme), '') ke, kee = self.GetKfactor(elname) km, kme = self.GetKfactor(muname) s(' $k_{ll}$ ', v(ke, kee), v(km, kme), '') ie, ier = self.GetDataIn(elname) im, imr = self.GetDataIn(muname) iem, iemr = self.GetDataIn('ElMu') s(' $N_{in}$ (Data)', d(ie, ier), d(im, imr), d(iem, iemr)) t.sep() dde, ddee = self.GetDYDD(elname) ddm, ddme = self.GetDYDD(muname) tmc = ' DY estimate out (MC) ' if doSF else ' DY estimate (MC)' tdata = ' DY estimate out (DD) ' if doSF else ' DY estimate (DD)' if doSF: s(' DY estimate (MC)', v(moe, moee), v(mom, mome), '') s(' DY estimate (DD)', v(dde, ddee), v(ddm, ddme), '') else: ddem, ddeme = self.GetDYDD('ElMu') yDY = self.t.GetYield(self.GetDYfiles(), 'ElMu') yDYe = self.t.GetYieldStatUnc(self.GetDYfiles(), 'ElMu') s(' DY estimate (MC)', v(moe, moee), v(mom, mome), v(yDY, yDYe)) s(' DY estimate (DD)', v(dde, ddee), v(ddm, ddme), v(ddem, ddeme)) t.sep() sfee, sfeee = self.GetScaleFactor(elname) sfmm, sfmme = self.GetScaleFactor(muname) if doSF: s(' DD/MC ratio ', v(sfee, sfeee), v(sfmm, sfmme), '') else: sfem, sfeme = self.GetScaleFactor('ElMu') s(' DD/MC ratio ', v(sfee, sfeee), v(sfmm, sfmme), v(sfem, sfeme)) t.bar() t.write() def PrintDYSFnjets(self): t = OutText(self.GetOutPath(), 'DYSF_njets') t.SetSeparatorLength(22 + (3 + 16) * 3) t.SetDefaultFixOption(False) t.line( 'Drell-Yan data/MC scale factors for different jet multiplicities') t.bar() s = lambda tit, vee, vmm, vem: t.line( t.fix(tit, 22) + t.vsep() + t.fix(vee, 16, 'c') + t.vsep() + t.fix( vmm, 16, 'c') + t.vsep() + t.fix(vem, 16, 'c')) v = lambda val, err: '%1.2f' % val + t.pm() + '%1.2f' % err s('', elname, muname, 'ElMu') t.sep() #labels = ['Inclusive','== 1 jet', '== 2 jets', '>= 3 jets','>= 2 jets, >= 1 btag', '>= 2 btag'] #levels = ['dilepton', 'eq1jet', 'eq2jet', 'geq3jet','1btag', '2btag'] labels = ['Inclusive', '>= 2 jets', ' >= 1 btag'] levels = ['dilepton', '2jets', '1btag'] for i in range(len(labels)): if i == 4: t.sep() lab = labels[i] lev = levels[i] sfe, sfee = self.GetScaleFactor(elname, lev, 'SF') sfm, sfme = self.GetScaleFactor(muname, lev, 'SF') sfo, sfoe = self.GetScaleFactor('ElMu', lev, 'OF') s(' ' + lab, v(sfe, sfee) if sfe > 0 else '-', v(sfm, sfme) if sfm > 0 else '-', v(sfo, sfoe) if sfo > 0 else '-') t.bar() t.write() def __init__(self, path, outpath='./temp/', chan='ElMu', level='2jets', DYsamples='DYJetsToLL_M_10to50,DYJetsToLL_MLL50', DataSamples='HighEGJet,SingleMuon, DoubleMuon', lumi=304.32, massRange=[91 - 15, 91 + 15], mode='', histonameprefix='H', hname='DY_InvMass'): self.SetPath(path) self.SetOutPath(outpath) self.t = TopHistoReader(path) self.t.SetHistoNamePrefix(histonameprefix) self.SetLumi(lumi) self.SetChanAndLevel(chan, level) self.SetDYsamples(DYsamples) self.SetDataSamples(DataSamples) self.SetMassRange(massRange[0], massRange[1]) self.SetHistoNameOF() self.SetHistoNameSF() if chan == 'ElMu': if hname != '': self.SetHistoNameOF(hname) self.SetMode('OF') else: if hname != '': self.SetHistoNameSF(hname) self.SetMode('SF') if mode != '': self.SetMode(mode)
class DYDD: ### Set methods def SetPath(self, p): if not p.endswith('/'): p += '/' self.path = p def SetOutPath(self, p): self.outpath = p def SetMode(self, mode='OF', hname=''): self.doOF = True if mode in ['SF', 'Elec', 'ElEl', 'Muon', 'MuMu']: self.doOF = False if self.doOF: if hname != '': self.SetHistoNameOF(hname) self.SetZhistoName(self.hnameOF) else: if hname != '': self.SetHistoNameSF(hname) self.SetZhistoName(self.hnameSF) def SetLumi(self, l): self.lumi = l self.t.SetLumi(self.lumi) def SetHistoNameOF(self, h='DY_InvMass'): self.hnameOF = h def SetHistoNameSF(self, h='DY_SF_InvMass'): self.hnameSF = h def SetDYsamples(self, f): self.DYfiles = f def SetDataSamples(self, f): self.datafiles = f def SetChannel(self, c): self.chan = c def SetLevel(self, l): self.level = l def SetZhistoName(self, h): self.zhname = h def SetMassRange(self, minM=91 - 15, maxM=91 + 15): self.minMZ = minM self.maxMZ = maxM def SetChanAndLevel(self, chan='', level=''): ''' Manages to set chan and leve to the class and the TopHistoReader ''' if chan != '': self.SetChannel(chan) if level != '': self.SetLevel(level) self.t.SetChan(self.GetChan()) self.t.SetLevel(self.GetLevel()) return self.GetChan(), self.GetLevel() ### Get methods def GetPath(self): return self.path def GetOutPath(self): return self.outpath def GetZhistoName(self): return self.zhname def GetDYfiles(self): return self.DYfiles def GetDataFiles(self): return self.datafiles def GetLevel(self): return self.level def GetChan(self): return self.chan ### Calculate quantities... def GetDYhisto(self, chan='', level='', isData=True): # ARREGLAR PARA QUE COJA EL ADECUADO DEPENDIENDO DEL CANAL!! O HACER FUNCION PARA INDICAR CANAL EMU chan, level = self.SetChanAndLevel(chan, level) if isData: self.t.SetIsData(True) pr = self.GetDataFiles() else: self.t.SetIsData(False) pr = self.GetDYfiles() zname = self.GetZhistoName() if level == 'dilepton' and zname[-4:] == 'ElMu': zname = zname[:-4] h = self.t.GetHisto(pr, zname, chan, level) h.SetDirectory(0) return h def GetHdata(self, chan, level): return self.GetDYhisto(chan, level, True) def GetHMC(self, chan, level): return self.GetDYhisto(chan, level, False) def DYyield(self, direc='in', isData=True, chan='', level=''): h = self.GetDYhisto(chan, level, isData) b0 = h.FindBin(self.minMZ) bN = h.FindBin(self.maxMZ) nbins = h.GetNbinsX() integral = h.Integral() y = 0 err = 0 if direc == 'in' or direc == 'In' or direc == 'IN': y += h.Integral(b0, bN) else: y += h.Integral(0, b0 - 1) y += h.Integral(bN + 1, nbins + 1) if isData: err = sqrt(y) else: entries = h.GetEntries() err = sqrt((y * integral) / entries) if y < 0: # Avoid wierd numbers due to negative weights... y = 0 err = 0 return y, err def GetDataIn(self, chan='', level=''): return self.DYyield('in', True, chan, level) def GetDataOut(self, chan='', level=''): return self.DYyield('out', True, chan, level) def GetMCin(self, chan='', level=''): return self.DYyield('in', False, chan, level) def GetMCout(self, chan='', level=''): return self.DYyield('out', False, chan, level) def GetRoutin(self, chan='', level=''): ''' Returns ratio Rout/in from MC ''' rin, errin = self.GetMCin(chan, level) out, errout = self.GetMCout(chan, level) r = out / rin if rin != 0 else 0 err = r * SumSquare( [errout / out if out != 0 else 0, errin / rin if rin != 0 else 0]) return r, err def GetKfactor(self, chan='', level=''): ''' Calculate the k factor k_ee, k_mumu ''' chan, level = self.SetChanAndLevel(chan, level) rinElec, errElec = self.GetDataIn(elname, level) rinMuon, errMuon = self.GetDataIn(muname, level) k = (rinElec / rinMuon if rinMuon != 0 else 0) if chan == elname else ( rinMuon / rinElec if rinElec != 0 else 0) kerr = k * SumSquare([ errElec / (2 * rinElec) if rinElec != 0 else 0, errMuon / (2 * rinMuon) if rinMuon != 0 else 0 ]) return k, kerr def GetDYDD(self, chan='', level='', mode=''): ''' Returns the DY estimate from data ''' chan, level = self.SetChanAndLevel(chan, level) if chan == 'ElMu': self.SetMode('ElMu') if mode != '': self.SetMode(mode) routin, routin_err = self.GetRoutin(chan, level) NemuIn, NemuIn_err = self.GetDataIn('ElMu', level) kee, keerr = self.GetKfactor(elname, level) NeeIn, NeeInerr = self.GetDataIn(elname, level) kmm, kmmrr = self.GetKfactor(muname, level) NmmIn, NmmInerr = self.GetDataIn(muname, level) est = lambda r, Nin, Nemu, k: r * (Nin - Nemu * k / 2) esterr = lambda r, Nin, Nemu, k, er, eNin, eNemu, ek: SumSquare([ est(r, Nin, Nemu, k) * (er / r if r != 0 else 0), r * eNin, r * k / 2 * eNemu, r * Nemu / 2 * ek ]) N = 0 Nerr = 0 if chan == elname: N = est(routin, NeeIn, NemuIn, kee) Nerr = esterr(routin, NeeIn, NemuIn, kee, routin_err, NeeInerr, NemuIn_err, keerr) elif chan == muname: N = est(routin, NmmIn, NemuIn, kmm) Nerr = esterr(routin, NmmIn, NemuIn, kmm, routin_err, NmmInerr, NemuIn_err, kmmrr) else: # ElMu self.t.SetIsData(False) yDY = self.t.GetYield(self.GetDYfiles(), 'ElMu') yDYe = self.t.GetYieldStatUnc(self.GetDYfiles(), 'ElMu') SF, err = self.GetScaleFactor('ElMu') N = yDY * SF Nerr = N * SumSquare([ err / SF if SF != 0 else err, yDYe / yDY if yDY != 0 else yDYe ]) if N < 0: N = 0 Nerr = 0 if not Nerr == Nerr: Nerr = 0 return N, Nerr def GetScaleFactor(self, chan='', level='', mode=''): ''' Returns the data/MC ratio for the DY estimate ''' chan, level = self.SetChanAndLevel(chan, level) if chan == 'ElMu': self.SetMode('ElMu') if mode != '': self.SetMode(mode) SF = 1 err = 0 if chan == muname or chan == elname: dd, dde = self.GetDYDD(chan) mo, moe = self.GetMCout(chan) SF = dd / mo if mo != 0 else 0 err = SF * SumSquare( [dde / dd if dd != 0 else 0, moe / mo if mo != 0 else 0]) elif chan == 'ElMu': e, er = self.GetScaleFactor(elname) m, mr = self.GetScaleFactor(muname) SF = sqrt(e * m) err = SF * SumSquare( [er / e if e != 0 else 0, mr / m if m != 0 else 0]) return SF, err def PrintDYestimate(self, doSF=False, name='', level=''): self.SetChanAndLevel('', level) self.SetMode('SF' if doSF else 'OF') if name == '': name = 'DYDD_%s_%s' % ('SF' if doSF else 'OF', self.GetLevel()) t = OutText(self.GetOutPath(), name) t.SetSeparatorLength(20 + (3 + 22) * 3) t.SetDefaultFixOption(False) t.line('Drell-Yan estimate for %s and level \'%s\'' % ('SF channels' if doSF else 'all channels (no MET cut) ', self.GetLevel())) t.bar() s = lambda tit, vee, vmm, vem: t.line( t.fix(tit, 20) + t.vsep() + t.fix(vee, 22, 'c') + t.vsep() + t.fix( vmm, 22, 'c') + t.vsep() + t.fix(vem, 22, 'c')) v = lambda val, err: '%1.3f' % val + t.pm() + '%1.3f' % err d = lambda val, err: '%1.0f' % val + t.pm() + '%1.2f' % err s('', elname, muname, 'ElMu') t.sep() mie, miee = self.GetMCin(elname) moe, moee = self.GetMCout(elname) mim, mime = self.GetMCin(muname) mom, mome = self.GetMCout(muname) s(' N_in (MC)', v(mie, miee), v(mim, mime), '') s(' N_out (MC)', v(moe, moee), v(mom, mome), '') re, ree = self.GetRoutin(elname) rm, rme = self.GetRoutin(muname) s(' R_(out/in) (MC)', v(re, ree), v(rm, rme), '') ke, kee = self.GetKfactor(elname) km, kme = self.GetKfactor(muname) s(' k_ll ', v(ke, kee), v(km, kme), '') ie, ier = self.GetDataIn(elname) im, imr = self.GetDataIn(muname) iem, iemr = self.GetDataIn('ElMu') s(' N_in (Data)', d(ie, ier), d(im, imr), d(iem, iemr)) t.sep() dde, ddee = self.GetDYDD(elname) ddm, ddme = self.GetDYDD(muname) tmc = ' DY estimate out (MC) ' if doSF else ' DY estimate (MC)' tdata = ' DY estimate out (DD) ' if doSF else ' DY estimate (DD)' if doSF: s(' DY estimate (MC)', v(moe, moee), v(mom, mome), '') s(' DY estimate (DD)', v(dde, ddee), v(ddm, ddme), '') else: ddem, ddeme = self.GetDYDD('ElMu') yDY = self.t.GetYield(self.GetDYfiles(), 'ElMu') yDYe = self.t.GetYieldStatUnc(self.GetDYfiles(), 'ElMu') s(' DY estimate (MC)', v(moe, moee), v(mom, mome), v(yDY, yDYe)) s(' DY estimate (DD)', v(dde, ddee), v(ddm, ddme), v(ddem, ddeme)) t.sep() sfee, sfeee = self.GetScaleFactor(elname) sfmm, sfmme = self.GetScaleFactor(muname) if doSF: s(' DD/MC ratio ', v(sfee, sfeee), v(sfmm, sfmme), '') else: sfem, sfeme = self.GetScaleFactor('ElMu') s(' DD/MC ratio ', v(sfee, sfeee), v(sfmm, sfmme), v(sfem, sfeme)) t.bar() t.write() def PrintDYSFnjets(self): t = OutText(self.GetOutPath(), 'DYSF_njets') t.SetSeparatorLength(22 + (3 + 16) * 3) t.SetDefaultFixOption(False) t.line( 'Drell-Yan data/MC scale factors for different jet multiplicities') t.bar() s = lambda tit, vee, vmm, vem: t.line( t.fix(tit, 22) + t.vsep() + t.fix(vee, 16, 'c') + t.vsep() + t.fix( vmm, 16, 'c') + t.vsep() + t.fix(vem, 16, 'c')) v = lambda val, err: '%1.2f' % val + t.pm() + '%1.2f' % err s('', elname, muname, 'ElMu') t.sep() #labels = ['Inclusive','== 1 jet', '== 2 jets', '>= 3 jets','>= 2 jets, >= 1 btag', '>= 2 btag'] #levels = ['dilepton', 'eq1jet', 'eq2jet', 'geq3jet','1btag', '2btag'] labels = ['Inclusive', '>= 2 jets', ' >= 1 btag'] levels = ['dilepton', '2jets', '1btag'] for i in range(len(labels)): if i == 4: t.sep() lab = labels[i] lev = levels[i] sfe, sfee = self.GetScaleFactor(elname, lev, 'SF') sfm, sfme = self.GetScaleFactor(muname, lev, 'SF') sfo, sfoe = self.GetScaleFactor('ElMu', lev, 'OF') s(' ' + lab, v(sfe, sfee) if sfe > 0 else '-', v(sfm, sfme) if sfm > 0 else '-', v(sfo, sfoe) if sfo > 0 else '-') t.bar() t.write() def __init__(self, path, outpath='./temp/', chan='ElMu', level='2jets', DYsamples='DYJetsToLL_M_10to50,DYJetsToLL_MLL50', DataSamples='HighEGJet,SingleMuon, DoubleMuon', lumi=308.54, massRange=[91 - 15, 91 + 15], mode='', histonameprefix='H', hname='DY_InvMass'): self.SetPath(path) self.SetOutPath(outpath) self.t = TopHistoReader(path) self.t.SetHistoNamePrefix(histonameprefix) self.SetLumi(lumi) self.SetChanAndLevel(chan, level) self.SetDYsamples(DYsamples) self.SetDataSamples(DataSamples) self.SetMassRange(massRange[0], massRange[1]) self.SetHistoNameOF() self.SetHistoNameSF() if chan == 'ElMu': if hname != '': self.SetHistoNameOF(hname) self.SetMode('OF') else: if hname != '': self.SetHistoNameSF(hname) self.SetMode('SF') if mode != '': self.SetMode(mode)
if inc == None: h = t.GetNamedHisto(pref + var + '_' + ch) else: h = t.GetNamedHisto(pref + var + '_' + ch + '_' + inc) y = h.GetBinContent(9) else: y = t.GetYield() return y from wzanalysis.wzanalysis import lev, level, ch, chan #path = '/pool/ciencias/nanoAODv4/5TeV/5TeV_21nov2019/' path = '/nfs/fanae/user/joanrs/xuAnalysis/tempWZ8/' #process = ['WZTo3LNU_NNPDF30_TuneCP5_5p20TeV','DYJetsToLL_MLL_50_TuneCP5_5020GeV_amcatnloFXFX','DYJetsToLL_M_10to50_TuneCP5_5020GeV_amcatnloFXFX','ZZTo2L2Nu_5p02TeV','ZZTo4L_5p02TeV','WWTo2L2Nu_NNPDF31_TuneCP5_5p02TeV', 'tW_5f_noFullHad_TuneCP5_PSweights_5p02TeV_py, tW_5f_noFullHad_TuneCP5_5p02TeV', 'tbarW_5f_noFullHad_TuneCP5_PSweights_5p02TeV_powhe, tbarW_5f_noFullHad_TuneCP5_5p02TeV', 'TT_TuneCP5_PSweights_5p02TeV' ] t = TopHistoReader(path) t.SetLumi(Lumi) PR = [] TT = [] DY = [] VV = [] WZ = [] Da = [] ZZ = [] WW = [] #process = ['WZTo3LNU'] process = [ 'WZTo3LNU', 'DYJetsToLL_MLL50', 'DYJetsToLL_M_10to50', 'ZZTo2L2Nu', 'ZZTo4L', 'WWTo2L2Nu', 'tW_noFullHad', 'tbarW_noFullHad', 'TT', 'HighEGJet', 'SingleMuon' ]
def ReadHistos(self, path, chan='ElMu', level='2jets', lumi=Lumi, lumiunc=0.04, bkg=[], signal=[], data='', expUnc=[], modUnc=[], histoPrefix=''): ''' Set the xsec from histos ''' if isinstance(expUnc, str): expUnc = expUnc.replace(' ', '').split(',') if isinstance(modUnc, str): modUnc = modUnc.replace(' ', '').split(',') self.SetChan(chan) self.SetLevel(level) self.t = TopHistoReader(path) self.t.SetHistoNamePrefix(histoPrefix) self.t.SetLumi(lumi) self.t.SetChan(chan) self.t.SetLevel(level) self.ss = SampleSums(self.pathToTrees, self.motherfname, 'Runs') signalName = signal[0] signalSample = signal[1] # GetFiduEvents hfiduname = 'FiduEvents' #_%s'%chan fiduEvents = self.t.GetNamedHisto( hfiduname, signalSample).GetBinContent(invlevel[level]) nGenEvents = self.ss.GetCount( 'Count') #self.GetNGenEvents(signalSample) self.SetLumiUnc(lumiunc) self.SetFiduEvents(fiduEvents) self.SetGenEvents(nGenEvents) for l in bkg: if len(l) == 3: name, pr, unc = l expunc = expUnc elif len(l) == 4: name, pr, unc, expunc = l self.AddBkg(name, self.t.GetYield(pr), unc, self.t.GetUnc(pr, chan, level, expUnc), self.t.GetYieldStatUnc(pr)) self.SetSignal(signalName, self.t.GetYield(signalSample), self.t.GetYieldStatUnc(signalSample)) self.t.SetIsData(True) self.SetData(self.t.GetYield(data)) self.t.SetIsData(False) for e in expUnc: self.AddExpUnc(e, self.t.GetUnc(signal[1], chan, level, e)) # Modeling uncertainties if 'pdf' in modUnc or 'PDF' in modUnc or 'Scale' in modUnc or 'ME' in modUnc or 'scale' in modUnc: pathToTrees = self.pathToTrees #'/pool/ciencias/userstorage/juanr/nanoAODv4/5TeV/5TeV_5sept/' motherfname = self.motherfname #'TT_TuneCP5_PSweights_5p02TeV' w = WeightReader(path, '', chan, level, sampleName='TT', pathToTrees=pathToTrees, motherfname=motherfname, PDFname='PDFweights', ScaleName='ScaleWeights', lumi=Lumi, histoprefix=histoPrefix) #w.SetSampleName(signalName) if 'pdf' in modUnc or 'PDF' in modUnc: self.AddModUnc('PDF', w.GetPDFandAlphaSunc()) if 'scale' in modUnc or 'ME' in modUnc: self.AddModUnc('Scale ME', w.GetMaxRelUncScale()) if 'ISR' in modUnc or 'isr' in modUnc: self.AddModUnc('ISR', self.t.GetUnc(signalSample, chan, level, 'ISR')) if 'FSR' in modUnc or 'fsr' in modUnc: self.AddModUnc('FSR', self.t.GetUnc(signalSample, chan, level, 'FSR'))
class CrossSection: ### Add background, signal and data numbers def AddBkg(self, name, val, normunc=0, systunc=0, statunc=0, samples=''): ''' Add a bkg process (must include yield, name, uncertainties...) ''' self.bkg.append( Process(name, Yield=val, NormUnc=normunc, SystUnc=systunc, StatUnc=statunc, samples=samples)) def SetSignal(self, name, val, statunc=0, samples=''): ''' Set the signal process (must include yield, name, uncertainties...) ''' self.signal = Process(name, Yield=val, StatUnc=statunc, samples=samples) def SetData(self, n): ''' Number of observed events ''' self.data = n self.dataunc = sqrt(n) ### Add uncertainties... experimental and modeling def AddExpUnc(self, name, val): ''' Add the uncertainty 'name' with value 'val' to the experimental uncertainties ''' self.effUnc[name] = val def AddModUnc(self, name, val=0., do=''): ''' Add the uncertainty 'name' with value 'val' to the modeling uncertainties (on acceptance) if sample names are given (up/down) the uncertainty is read from the histos in that samples ''' if isinstance(val, float): self.accUnc[name] = val else: nom = self.GetSignalYield() up = self.t.GetYield(val) do = self.t.GetYield(do) var = max(abs(up - nom), abs(do - nom)) / nom self.AddModUnc(name, var) ### Setting methods def SetTextFormat(self, textformat): ''' Set the format of the output tables (txt, tex) ''' self.textformat = textformat def SetChan(self, ch): ''' Set the channel ''' self.chan = ch def SetLevel(self, lev): ''' Set level ''' self.lev = lev def SetThXsec(self, t): ''' Set the theoretical cross section using to normalize signal events ''' self.thxsec = t def SetDoFiducial(self, val=True): ''' Boolean to activate printing the fiducial cross section ''' self.doFiducial = val def SetLumi(self, l): ''' Set the luminosity ''' self.lumi = l def SetLumiUnc(self, l): ''' Set relative lumi unc ''' self.lumiunc = l def SetFiduEvents(self, f): ''' Number of fiducual (unweighted) events ''' self.nfidu = f def SetGenEvents(self, g): ''' Number of generated events in the sample ''' self.ngen = g def SetBR(self, b): # Use relative unc ''' The branching ratio to what we consider signal ''' self.BR = b def SetOutPath(self, p): ''' Set the output path ''' self.outpath = p ### Get parameters... def GetThXsec(self): return self.thxsec def GetLumi(self): return self.lumi def GetLumiUnc(self): return self.lumiunc def GetFiduEvents(self, sys=''): return self.nfidu def GetGenEvents(self): return self.ngen def GetBR(self): return self.BR def GetLevel(self): return self.lev def GetChan(self): return self.chan def GetBkg(self, name): for b in self.bkg: if b.GetName() == name: return b print 'WARNING: not found background ' + name def GetBkgTotRelUnc(self, name): return self.GetBkg(name).GetTotRelUnc() def GetBkgTotAbsUnc(self, name): return self.GetBkgYield(name) * self.GetBkgTotRelUnc(name) def GetBkgYield(self, name, sys=''): pr = self.GetBkg(name) if sys == '': return pr.GetYield() elif IsUpSyst(sys): return pr.GetYield() * (1 + pr.GetTotRelUnc()) elif IsDownSyst(sys): return pr.GetYield() * (1 - pr.GetTotRelUnc()) else: return pr.GetYield() * (1 + pr.GetTotRelUnc()) def GetData(self): return self.data def GetDataUnc(self): return self.dataunc def GetSignal(self): return self.signal def GetSignalYield(self, sys='', d=''): y = self.signal.GetYield() if sys == '': return y u = self.GetUnc(sys) if IsDownSyst(d): return y * (1 - u) return y * (1 + u) def GetExpUnc(self, name=''): if name == '': return self.effUnc else: return self.effUnc[name] def GetModUnc(self, name=''): if name == '': return self.accUnc else: return self.accUnc[name] def GetUnc(self, name): if name in self.modUnc.keys(): return self.GetModUnc(name) elif name in self.effUnc.keys(): return self.GetEffUnc(name) else: print 'WARNING: not found uncertainty \'%d\'' % name return 0 def GetTotBkg(self, sys='', d=''): ''' Returns the total expected bkg ''' if sys != '' and sys in [x.GetName() for x in self.bkg]: y = self.GetTotBkg() var = self.GetBkgTotAbsUnc(sys) y = y - var if IsDownSyst(sys + d) else y + var else: y = sum([x.GetYield() for x in self.bkg]) return y def GetTotBkgStatUnc(self): ''' Returns the total stat unc on bkg ''' b = 0 for pr in self.bkg: b += pr.GetStatUnc() * pr.GetStatUnc() return sqrt(b) def GetTotBkgSystUnc(self): ''' Returns the total syst unc on bkg ''' b = 0 for pr in self.bkg: b += pr.GetSystAbsUnc() * pr.GetSystAbsUnc() return sqrt(b) def GetXsec(self, sys='', d=''): ''' Returns the measured cross section ''' data = self.GetData() bkg = self.GetTotBkg(sys, d) if sys in [x.GetName() for x in self.bkg ] else self.GetTotBkg() y = self.GetSignalYield(sys, d) thxsec = self.GetThXsec() return self.ComputeXsec(data, bkg, y) def GetFiduXsec(self): ''' Returns the fiducial cross section ''' # fidu = inclusive*(A) return self.ComputeXsec() * self.GetAcc() def GetAcc(self, sys=''): ''' Returns the measured acceptance ''' return self.GetFiduEvents(sys) / (self.GetGenEvents() * self.GetBR()) def GetAccUnc(self): ''' Return the syst unc on acceptance ''' err = 0 for a in self.accUnc.values(): err += a * a return sqrt(err) def GetEff(self, sys=''): ''' Returns the measured efficiency ''' y = self.GetSignalYield(sys) A = self.GetAcc() BR = self.GetBR() lum = self.GetLumi() xth = self.GetThXsec() return (y) / (A * lum * xth * BR) def GetEffUnc(self): ''' Return the syst unc on efficiency ''' err = 0 for a in self.effUnc.values(): err += a * a return sqrt(err) def GetXsecSystUnc(self): ''' Returns the xsec syst unc on cross section ''' effunc = self.GetEffUnc() accunc = self.GetAccUnc() bkgunc2 = 0 for b in [x.GetName() for x in self.bkg]: bkgunc2 += self.GetXsecBkgRelUnc(b) * self.GetXsecBkgRelUnc(b) return sqrt(effunc * effunc + accunc * accunc + bkgunc2) def GetXsecLumiUnc(self): ''' Returns the xsec lumi uncertainty on cross section ''' #return self.GetXsec()*(1/self.GetLumi() - 1/(self.GetLumi() * (1+self.GetLumiUnc()) )) r = self.GetLumiUnc() return (abs(r / (1 - r)) + abs(r / (1 + r))) / 2 def GetXsecStatUnc(self): ''' Returns the stat unc on cross section ''' xsec = self.ComputeXsec() varUp = self.ComputeXsec(self.GetData() + self.GetDataUnc(), self.GetTotBkg(), self.GetSignalYield()) varDo = self.ComputeXsec(self.GetData() - self.GetDataUnc(), self.GetTotBkg(), self.GetSignalYield()) return max([abs(xsec - varDo) / xsec, abs(xsec - varUp) / xsec]) def GetXsecBkgRelUnc(self, bkgname): ''' Returns the relative unc on the xsec due to the total unc on a bkg estimation ''' nom = self.ComputeXsec() varUp = self.ComputeXsec(self.GetData(), self.GetTotBkg(bkgname, 'Up'), self.GetSignalYield()) varDo = self.ComputeXsec(self.GetData(), self.GetTotBkg(bkgname, 'Down'), self.GetSignalYield()) return max([abs(nom - varUp) / nom, abs(nom - varDo) / nom]) ### Several printing methods! def PrintYields(self, name='yields', doStat=True, doSyst=True): t = OutText(self.outpath, name, "new", textformat=self.textformat) t.SetTexAlign("l c") nsem = 16 + 3 + 8 + (5 + 8 if doStat else 0) + (5 + 8 if doSyst else 0) t.SetSeparatorLength(nsem) t.line('%' + 'Yields for channel \'%s\' and level \'%s\'' % (self.GetChan(), self.GetLevel())) t.bar() for pr in self.bkg: name = t.fix(" %s" % pr.GetName(), 16, 'l', 0) y = t.fix("%1.2f" % pr.GetYield(), 8, 0) stat = t.fix("%1.2f" % pr.GetStatUnc(), 8, 0) syst = t.fix("%1.2f" % pr.GetSystAbsUnc(), 8, 0) t.line(name + t.vsep() + y + ((t.pm() + stat) if doStat else '') + ((t.pm() + syst) if doSyst else '')) t.sep() totbkg = t.fix("%1.2f" % self.GetTotBkg(), 8, 0) totbkgstat = t.fix("%1.2f" % self.GetTotBkgStatUnc(), 8, 0) totbkgsyst = t.fix("%1.2f" % self.GetTotBkgSystUnc(), 8, 0) t.line( t.fix(" Total bkg", 16, 'l', 0) + t.vsep() + totbkg + ((t.pm() + totbkgstat) if doStat else '') + ((t.pm() + totbkgsyst) if doSyst else '')) t.sep() y = self.GetSignalYield() signal = t.fix(" %s" % (self.GetSignal().GetName()), 16, 'l', 0) ysig = t.fix("%1.2f" % y, 8, 0) sigunc = t.fix("%1.2f" % (self.GetXsecSystUnc() * y), 8, 0) sigsta = t.fix("%1.2f" % self.GetSignal().GetStatUnc(), 8, 0) t.line(signal + t.vsep() + ysig + ((t.pm() + sigsta) if doStat else '') + ((t.pm() + sigunc) if doSyst else '')) t.sep() t.line( t.fix(" Data", 16, 'l', 0) + t.vsep() + t.fix("%i" % self.GetData(), 8, 0)) t.bar() t.write() def PrintXsec(self, name='xsec'): t = OutText(self.outpath, name, "new", textformat=self.textformat) t.SetTexAlign("l c") t.SetSeparatorLength(26 + 3 + 20 + 5) t.SetDefaultFixOption(False) t.line('%' + 'tt cross section for channel \'%s\' and level \'%s\'' % (self.GetChan(), self.GetLevel())) acc = self.GetAcc() eff = self.GetEff() t.bar() t.line( t.fix(' Acceptance', 16, 'r') + t.vsep() + t.fix("%1.4f" % acc, 6) + t.pm() + t.fix("%1.2f" % (acc * self.GetAccUnc()), 8)) t.line( t.fix(' Efficiency', 16, 'r') + t.vsep() + t.fix("%1.4f" % eff, 6) + t.pm() + t.fix("%1.2f" % (eff * self.GetEffUnc()), 8)) t.sep() t.line( t.fix(' Branching ratio', 16, 'r') + t.vsep() + t.fix("%1.4f" % self.GetBR(), 6)) t.line( t.fix(' Gen events', 16, 'r') + t.vsep() + t.fix("%d" % self.GetGenEvents(), 9)) t.line( t.fix(' Fiducial events', 16, 'r') + t.vsep() + t.fix("%d" % self.GetFiduEvents(), 9)) if self.doFiducial: t.sep() xsec = self.GetFiduXsec() stat = self.GetXsecStatUnc() syst = self.GetEffUnc() lumi = self.GetXsecLumiUnc() #t.line(t.fix(' Fiducial cross section', 26, 'r') + t.vsep() + t.fix("%1.2f"%xsec,6)) #t.line(t.fix(' +\- ', 26, 'r') + ' ' + t.fix('%1.2f (%1.2f'%(stat*xsec,stat*100) + ' %) (stat)',20, 'l')) #t.line(t.fix(' +\- ', 26, 'r') + ' ' + t.fix('%1.2f (%1.2f'%(syst*xsec,syst*100) + ' %) (syst)',20, 'l')) #t.line(t.fix(' +\- ', 26, 'r') + ' ' + t.fix('%1.2f (%1.2f'%(lumi*xsec,lumi*100) + ' %) (lumi)',20, 'l')) t.sep() xsec = self.GetXsec() stat = self.GetXsecStatUnc() syst = self.GetXsecSystUnc() lumi = self.GetXsecLumiUnc() t.line( t.fix(' Inclusive cross section', 26, 'r') + t.vsep() + t.fix("%1.2f" % xsec, 6)) t.line( t.fix(' $\pm$ ', 26, 'r') + ' ' + t.fix('%1.2f (%1.2f' % (stat * xsec, stat * 100) + ' \%) (stat)', 20, 'l') + t.vsep()) t.line( t.fix(' $\pm$ ', 26, 'r') + ' ' + t.fix('%1.2f (%1.2f' % (syst * xsec, syst * 100) + ' \%) (syst)', 20, 'l') + t.vsep()) t.line( t.fix(' $\pm$ ', 26, 'r') + ' ' + t.fix('%1.2f (%1.2f' % (lumi * xsec, lumi * 100) + ' \%) (lumi)', 20, 'l') + t.vsep()) t.bar() t.write() def AddToTxt(self, name='xsec', lab='e#mu'): t = OutText(self.outpath, name, "new", textformat=self.textformat) text = t.GetTextFromOutFile(form='txt') xsec = self.GetXsec() stat = self.GetXsecStatUnc() * xsec syst = self.GetXsecSystUnc() * xsec lum = self.GetXsecLumiUnc() * xsec isthere = False for l in text.splitlines(): if l == '' or l.replace(' ', '') == '': continue if l.startswith(lab): isthere = True t.line('%s %1.2f %1.2f %1.2f %1.2f' % (lab, xsec, stat, syst, lum)) else: t.line(l) if not isthere: t.line('%s %1.2f %1.2f %1.2f %1.2f' % (lab, xsec, stat, syst, lum)) t.write() def PrintSystTable(self, name='uncertainties'): t = OutText(self.outpath, name, "new", textformat=self.textformat) t.SetTexAlign("l c") t.SetSeparatorLength(30) t.SetDefaultFixOption(False) t.line('%Uncertainties on tt inclusive cross section \n% ' + 'for channel \'%s\' and level \'%s\'' % (self.GetChan(), self.GetLevel())) exp = self.GetExpUnc() mod = self.GetModUnc() stat = self.GetXsecStatUnc() lum = self.GetXsecLumiUnc() syst = self.GetXsecSystUnc() xsec = self.GetXsec() t.bar() t.line(t.fix(' Source', 18, 'l') + t.vsep() + fix("value (\%)", 6)) t.sep() for b in [x.GetName() for x in self.bkg]: t.line( fix(' ' + b, 18, 'r') + t.vsep() + fix('%1.2f' % (self.GetXsecBkgRelUnc(b) * 100), 6)) t.sep() for e in exp.keys(): t.line( fix(' ' + e, 18, 'l') + t.vsep() + fix('%1.2f' % (exp[e] * 100), 6)) t.sep() for e in mod.keys(): t.line( fix(' ' + e, 18, 'l') + t.vsep() + fix('%1.2f' % (mod[e] * 100), 6)) t.sep() t.line( fix(' Total systematic', 18, 'l') + t.vsep() + fix('%1.2f' % (syst * 100), 6)) t.sep() t.line( fix(' Statistics', 18, 'l') + t.vsep() + fix('%1.2f' % (stat * 100), 6)) t.sep() t.line( fix(' Luminosity', 18, 'l') + t.vsep() + fix('%1.2f' % (lum * 100), 6)) t.bar() t.write() ### Other def ComputeXsec(self, data='', bkg='', y=''): ''' Computes the xsec from data, bkg and expected yield ''' if data == '': data = self.data if bkg == '': bkg = self.GetTotBkg() if y == '': y = self.GetSignalYield() return (data - bkg) / y * self.GetThXsec() def SetPathToTrees(self, ptt): self.pathToTrees = ptt def SetMotherName(self, mn): self.motherfname = mn def GetNGenEvents(self): self.treesow = TChain('Runs', 'Runs') files = GetFiles(self.pathToTrees, self.motherfname) for f in files: self.treesow.Add(f) def ReadHistos(self, path, chan='ElMu', level='2jets', lumi=Lumi, lumiunc=0.04, bkg=[], signal=[], data='', expUnc=[], modUnc=[], histoPrefix=''): ''' Set the xsec from histos ''' if isinstance(expUnc, str): expUnc = expUnc.replace(' ', '').split(',') if isinstance(modUnc, str): modUnc = modUnc.replace(' ', '').split(',') self.SetChan(chan) self.SetLevel(level) self.t = TopHistoReader(path) self.t.SetHistoNamePrefix(histoPrefix) self.t.SetLumi(lumi) self.t.SetChan(chan) self.t.SetLevel(level) self.ss = SampleSums(self.pathToTrees, self.motherfname, 'Runs') signalName = signal[0] signalSample = signal[1] # GetFiduEvents hfiduname = 'FiduEvents' #_%s'%chan fiduEvents = self.t.GetNamedHisto( hfiduname, signalSample).GetBinContent(invlevel[level]) nGenEvents = self.ss.GetCount( 'Count') #self.GetNGenEvents(signalSample) self.SetLumiUnc(lumiunc) self.SetFiduEvents(fiduEvents) self.SetGenEvents(nGenEvents) for l in bkg: if len(l) == 3: name, pr, unc = l expunc = expUnc elif len(l) == 4: name, pr, unc, expunc = l self.AddBkg(name, self.t.GetYield(pr), unc, self.t.GetUnc(pr, chan, level, expUnc), self.t.GetYieldStatUnc(pr)) self.SetSignal(signalName, self.t.GetYield(signalSample), self.t.GetYieldStatUnc(signalSample)) self.t.SetIsData(True) self.SetData(self.t.GetYield(data)) self.t.SetIsData(False) for e in expUnc: self.AddExpUnc(e, self.t.GetUnc(signal[1], chan, level, e)) # Modeling uncertainties if 'pdf' in modUnc or 'PDF' in modUnc or 'Scale' in modUnc or 'ME' in modUnc or 'scale' in modUnc: pathToTrees = self.pathToTrees #'/pool/ciencias/userstorage/juanr/nanoAODv4/5TeV/5TeV_5sept/' motherfname = self.motherfname #'TT_TuneCP5_PSweights_5p02TeV' w = WeightReader(path, '', chan, level, sampleName='TT', pathToTrees=pathToTrees, motherfname=motherfname, PDFname='PDFweights', ScaleName='ScaleWeights', lumi=Lumi, histoprefix=histoPrefix) #w.SetSampleName(signalName) if 'pdf' in modUnc or 'PDF' in modUnc: self.AddModUnc('PDF', w.GetPDFandAlphaSunc()) if 'scale' in modUnc or 'ME' in modUnc: self.AddModUnc('Scale ME', w.GetMaxRelUncScale()) if 'ISR' in modUnc or 'isr' in modUnc: self.AddModUnc('ISR', self.t.GetUnc(signalSample, chan, level, 'ISR')) if 'FSR' in modUnc or 'fsr' in modUnc: self.AddModUnc('FSR', self.t.GetUnc(signalSample, chan, level, 'FSR')) def __init__(self, outpath='./temp/', lev='', chan='', genEvents=1, fiduEvents=1, textformat="txt"): self.SetTextFormat(textformat) self.SetThXsec(68.9) self.SetLumi(Lumi) self.SetLumiUnc(0.035) # Relative self.SetChan(chan) self.SetLevel(lev) self.SetGenEvents(genEvents) self.SetFiduEvents(fiduEvents) self.SetBR((0.108 * 3) * (0.108 * 3)) # By default, tt dilepton self.bkg = [] # List of 'Process' self.data = 0 # This is just an integer self.signal = '' # Process self.accUnc = {} # 'Name' : value self.effUnc = {} # 'Name' : value self.SetOutPath(outpath) self.doFiducial = True self.SetMotherName("TT_TuneCP5_5p02TeV") self.SetPathToTrees("")
3.5, weight='TWeight_%s%i' % (tag, i), cut='') histos = [ 'mt2', 'met', 'mll', 'dnn', 'dileppt', 'deltaphi', 'deltaeta', 'ht', 'lep0pt', 'lep1pt', 'lep0eta', 'lep1eta', 'njets', 'nbtags', 'jet0pt', 'jet1pt', 'jet0eta', 'jet1eta' ] histos += ['dnn_5bins', 'dnn_10bins', 'dnn_30bins', 'dnn_40bins'] out = l.Run() if sendJobs: exit() t = TopHistoReader(outpath + 'tempfiles/') print "Creating outputs in %s ..." % outpath for var in histos: PDFhistosNom = t.GetNamedHisto(var + '_PDF0', 'tt') PDFhistos = [ t.GetNamedHisto(var + '_PDF%i' % i, 'tt') for i in range(1, nPDFweights - 2 if year != 2016 else nPDFweights) ] AlphaShistos = [ t.GetNamedHisto(var + '_PDF%i' % (nPDFweights - 2), 'tt'), t.GetNamedHisto(var + '_PDF%i' % (nPDFweights - 1), 'tt') ] if year != 2016 else [] pdfNom, pdfUp, pdfDown = GetPDFuncHisto(PDFhistosNom, PDFhistos, AlphaShistos, prName='tt',
class NonpromptDD: ### Set methods def SetPath(self, p): if not p.endswith('/'): p += '/' self.path = p def SetOutPath(self, p): self.outpath = p def SetLumi(self, l): self.lumi = l self.t.SetLumi(self.lumi) def SetChannel(self, c): self.chan = c def SetLevel(self, l): self.level = l def SetChanAndLevel(self, chan='', level=''): ''' Manages to set chan and leve to the class and the TopHistoReader ''' if chan != '': self.SetChannel(chan) if level != '': self.SetLevel(level) self.t.SetChan(self.GetChan()) self.t.SetLevel(self.GetLevel()) return self.GetChan(), self.GetLevel() ### Get methods def GetPath(self): return self.path def GetOutPath(self): return self.outpath def GetLevel(self): return self.level def GetChan(self): return self.chan ### Calculate quantities... def GetYield(self, process, chan='', level='', SS=False): if process == 'Data' or process == 'data': self.t.SetIsData(True) if process in self.process.keys(): process = self.process[process] chan, lev = self.SetChanAndLevel(chan, level) y = self.t.GetYield(process, chan, level, SS=SS) err = self.t.GetYieldStatUnc(process, chan, level, SS=SS) self.t.SetIsData(False) if y < 0: # Negative weights... y = 0 err = 0 return y, err def GetSS(self, process, chan='', level=''): return self.GetYield(process, chan, level, True) def GetROSSS(self, process, chan='', level=''): ''' Returns the OS to SS ratio for process ''' OS, OSe = self.GetYield(process, chan, level) SS, SSe = self.GetSS(process, chan, level) R = OS / SS if SS != 0 else 1 e = R * SumSquare( [OSe / OS if OS != 0 else 0, SSe / SS if SS != 0 else 0]) return R, e def GetNonpromptDD(self, chan='', level=''): chan, lev = self.SetChanAndLevel(chan, level) R, Re = self.GetROSSS( [self.process[lab] for lab in self.nonpromptProcess]) BkgSS, BkgSSe = self.GetSS( [self.process[lab] for lab in self.promptProcess]) DataSS, DataSSe = self.GetSS('data') y = R * (DataSS - BkgSS) e = y * SumSquare([ Re / R if R != 0 else 0, (DataSSe + BkgSSe) / (DataSS - BkgSS) if (DataSS - BkgSS != 0) else 0 ]) return y, e ## Print tables def PrintSSyields(self, name='', level=''): self.SetChanAndLevel('', level) if name == '': name = 'SameSign_%s' % (self.GetLevel()) t = OutText(self.GetOutPath(), name) t.SetSeparatorLength(12 + (3 + 16) * 3) t.SetDefaultFixOption(False) t.line('Same-sign yields for level of selection \'%s\'' % (self.GetLevel())) t.bar() s = lambda tit, vee, vmm, vem: t.line( t.fix(tit, 10) + t.vsep() + t.fix(vee, 16, 'c') + t.vsep() + t.fix( vmm, 16, 'c') + t.vsep() + t.fix(vem, 16, 'c')) v = lambda L: '%1.2f' % L[0] + t.pm() + '%1.2f' % L[1] d = lambda L: '%1.0f' % L[0] + t.pm() + '%1.2f' % L[1] S = lambda tit, pr: s(tit, v(self.GetSS(pr, elecName)), v(self.GetSS(pr, muName)), v(self.GetSS(pr, 'ElMu'))) D = lambda tit, pr: s(tit, d(self.GetSS(pr, elecName)), d(self.GetSS(pr, muName)), d(self.GetSS(pr, 'ElMu'))) s('', elecName, muName, 'ElMu') t.sep() for pr in self.promptProcess: S(pr, pr) #S('tt signal', 'tt') #S('tW','tW') #S('Drell-Yan','DY') #S('Dibosons','VV') t.sep() for pr in self.nonpromptProcess: S(pr, pr) #S('W+Jets', 'WJets') #S('tt semilep', 'ttsemilep') t.sep() S('Total MC', [ self.process[lab] for lab in self.promptProcess + self.nonpromptProcess ]) t.sep() D('Data', 'data') t.bar() t.write() def PrintNonpromptEstimate(self, name='', chan='', level=''): chan, lev = self.SetChanAndLevel(chan, level) if name == '': name = 'NonpromptDD_%s_%s' % (self.GetChan(), self.GetLevel()) t = OutText(self.GetOutPath(), name) t.SetSeparatorLength(55 + 20) t.SetDefaultFixOption(False) t.line( ' Nonpromt estimate from a same-sign control retion\nfor channel \'%s\' and level of selection \'%s\'' % (chan, lev)) t.bar() s = lambda tit, vee, vmm, vem: t.line( t.fix(tit, 10) + t.vsep() + t.fix(vee, 16, 'c') + t.vsep() + t.fix( vmm, 16, 'c') + t.vsep() + t.fix(vem, 16, 'c')) v = lambda L: '%1.2f' % L[0] + t.pm() + '%1.2f' % L[1] d = lambda L: '%1.0f' % L[0] + t.pm() + '%1.2f' % L[1] pr = [self.process[p] for p in self.nonpromptProcess] sr = [self.process[p] for p in self.promptProcess] t.line( t.fix(' MC nonprompt estimate (OS W+Jets and semilpetonic tt)', 55) + t.vsep() + v(self.GetYield(pr))) t.sep() t.line( t.fix(' MC nonprompt SS (W+Jets and semilpetonic tt)', 55) + t.vsep() + v(self.GetSS(pr))) t.line( t.fix(' R = nonpromt(OS)/nonprompt(SS)', 55) + t.vsep() + v(self.GetROSSS(pr))) t.line( t.fix(' BkgSS = MC prompt SS (other sources)', 55) + t.vsep() + v(self.GetSS(sr))) t.line( t.fix(' DataSS = Obseved data SS', 55) + t.vsep() + v(self.GetSS('data'))) t.sep() t.line( t.fix(' Nonprompt data-driven estimate = R(DataSS-BkgSS)', 55) + t.vsep() + v(self.GetNonpromptDD())) t.bar() t.write() ### Init def __init__(self, path, outpath='./temp/', chan='ElMu', level='2jets', process={}, prompt=[], nonprompt=[], lumi=304.32, histonameprefix='H', yieldsSSname='SSYields'): self.SetPath(path) self.t = TopHistoReader(self.GetPath()) self.t.SetHistoNamePrefix(histonameprefix) self.t.SetYieldsSSname(yieldsSSname) self.SetLumi(lumi) self.SetOutPath(outpath) self.SetChanAndLevel(chan, level) self.process = process self.nonpromptProcess = [] self.promptProcess = [] if prompt == [] or nonprompt == []: for pr in process.keys(): if pr in ['data', 'Data', 'DATA']: continue elif pr in [ 'fake', 'nonprompt', 'Nonprompt', 'NonPrompt', 'Fake', 'fakes', 'Fakes' ]: self.nonpromptProcess.append(pr) else: self.promptProcess.append(pr) else: self.promptProcess = prompt self.nonpromptProcess = nonprompt
def DrawPostFit(ms=235, ml=60, htype='fit_s', var='dnn', ch='', year=''): getdir = lambda dirtype, ch: 'shapes_%s/%s/' % (dirtype, ch) getfname = lambda ms, ml: 'postfit_%s_%s_%s' % (var, str(ms), str(ml)) # Get channels if not isinstance(ch, list): if ch == '': ch = ['ee', 'mumu', 'emu'] elif ',' in ch: ch = ch.replace(' ', '').split(',') else: ch = [ch] if not isinstance(year, list): if year == '': year = [2016, 2017, 2018] elif isinstance(year, str) and ',' in year: year = year.replace(' ', '').split(',') else: year = [year] pch = [] for y in year: for c in ch: pch.append(chdic[y][c]) if len(year) == 3: yearname = 'comb' else: yearname = str(year[0]) if len(ch) == 3: chname = 'all' else: chname = ch[0] # test or not depending on var ttname = 'tt' if not 'dnn' in var else 'tt_test' pr = bkg + [ttname] sig = ('stop' if not 'dnn' in var else 'stop_test') if htype != 'fit_b' else [] hm = HistoManager(pr, '', path=pathToPostFit, signalList=sig) pathInTree = [getdir(htype, x) for x in pch] hm.SetPathInTree(pathInTree) hm.ReadHistosFromFile(getfname(ms, ml), dataname='data', rebin=1) hm.ReArrangeDic({ 'Others': ['ttW', 'ttZ', 'Nonprompt', 'VV'], 't#bar{t}+tW': ['tW', ttname], 'Drell-Yan': ['DY'] }) hm.GetDataHisto() #hm.indic['data_obs']['data_obs'] = hm.GetSumBkg() outdir = GetOutpath(region, year, ms, ml, ch) fprocess = ['Others', 'Drell-Yan', 't#bar{t}+tW'] s = Stack(outpath=outdir + '/postfit/') colors['Others'] = kTeal + 2 colors['t#bar{t}+tW'] = colors['tt'] colors['Drell-Yan'] = colors['DY'] s.SetColors(colors) s.SetProcesses(fprocess) s.SetLumi( GetLumi(year[0]) if len(year) == 1 else (GetLumi(2016) + GetLumi(2017) + GetLumi(2018))) outname = htype + '_' + var + '%s_%s_%i_%i' % (yearname, chname, ms, ml) s.SetOutName(outname) s.SetHistosFromMH(hm) #s.Set t = TopHistoReader(pathToPostFit) t.ReComputeStatUnc = False t.SetPathInTree(pathInTree) hbkg = t.GetNamedHisto('total_background', getfname(ms, ml)) hbkg.SetLineStyle(0) hbkg.SetLineWidth(0) hbkg.SetMarkerSize(0) s.SetTotMC(hbkg) s.SetMCunc(hbkg) s.SetMCstatUnc(None) s.SetMCnormUnc(None) s.SetRatioStatUnc(None) s.SetRatioNormUnc(None) s.SetRatioUnc(GetRatioHistoUncFromHisto(hbkg)) s.SetRatioUncStyle() s.SetUncStyle() if sig != []: s.AddSignalHisto(hm.indic[sig][sig], color=kViolet + 2, mode='ontop', ratioBkg=True, name='stop') s.SetTextChan('SR: BS + p_{T}^{miss} #geq 50, m_{T2} #geq 80') s.SetRatioMin(0.5) s.SetRatioMax(1.5) s.SetPlotMaxScale(1.8) xtit = 'DNN score (%i, %i)' % (ms, ml) chlab = '' if chname == 'ee': chlab = 'ee' elif chname == 'mumu': chlab = '#mu#mu' elif chname == 'emu': chlab = 'e#mu' flab = 'Prefit' if htype == 'fit_b': flab = 'Fit background only' elif htype == 'fit_s': flab = 'Fit S+B' mlab = '#splitline{m_{#tilde{t}_{1}} = %1.0f GeV}{m_{#tilde{#chi}_{1}^{0}} = %1.0f GeV}' % ( ms, ml) s.AddTex(flab, x=0.15, y=0.77, s=0.05) s.AddTex(mlab, x=0.15, y=0.62, s=0.04) s.AddTex(chlab, x=0.15, y=0.84, s=0.04) s.DrawStack(xtit, 'Events') s.SetLogY() s.SetZoom(False) if var == 'dnn' and region == 'SR': s.SetZoom(True) s.SetOutName('log_' + outname) s.SetPlotMinimum(1) s.SetPlotMaxScale(1200) s.SetYratioTitle('Ratio')
def loadHistos(self): ''' Load the PDF and Scale histos and norm histos ''' t = TopHistoReader(self.path) t.SetHistoNamePrefix(self.histoprefix) t.SetIsData(1) n = self.GetSampleName() t.SetProcess(n) t.SetChan(self.GetChan()) t.SetLevel(self.GetLevel()) #if self.GetNgenEvents() <= 0 : self.SetNgenEvents(t.GetNGenEvents()) self.SetYield(t.GetYield() * self.GetLumi()) self.hpdf = t.GetHisto(n, self.PDFhistoName) self.hscale = t.GetHisto(n, self.scaleHistoName) #self.hPS = t.GetHisto(n,self.PShistoName) if self.pathToTrees != '' and self.motherfname != '': self.LoadTreeSumOfWeights(self.pathToTrees, self.motherfname) self.hsumpdf = t.GetNamedHisto( self.normPDFhistoName ) if self.normPDFhistoName != '' else self.GetSumPDFhistoFromSumWTree( ) self.hsumscale = t.GetNamedHisto( self.normScaleHitstoName ) if self.normScaleHitstoName != '' else self.GetSumScaleHistoFromSumWTree( ) self.SetNgenEvents(self.count) self.nPDFweights = self.hsumpdf.GetNbinsX() self.nScaleWeighs = self.hsumscale.GetNbinsX() print '>> Count : ', self.count print '>> SumOfWeights : ', self.sow
import os, sys from conf import * basepath = os.path.abspath(__file__).rsplit('/xuAnalysis/', 1)[0] + '/xuAnalysis/' sys.path.append(basepath) from plotter.TopHistoReader import TopHistoReader, HistoManager from plotter.Plotter import Stack, HistoComp from ROOT.TMath import Sqrt as sqrt from ROOT import kRed, kOrange, kBlue, kTeal, kGreen, kGray, kAzure, kPink, kCyan, kBlack, kSpring, kViolet, kYellow from ROOT import TCanvas, gROOT gROOT.SetBatch(1) tr1 = TopHistoReader(path=path[2016]) tr2 = TopHistoReader( path=path[2018] ) #'/pool/ciencias/userstorage/juanr/top/2016/nov15/') # TOP-17-001 s = HistoComp(outpath='./temp/', doNorm=True, doRatio=True) s.autoRatio = True s.SetTextLumi('Normalized distributions', texlumiX=0.12) hname = 'H_NJets_ElMu_dilepton' s.AddHisto(tr1.GetNamedHisto(hname, 'TT'), 'hist', 'hist', '2016', color=kAzure + 2) s.AddHisto(tr2.GetNamedHisto(hname, 'TTTo2L2Nu'), 'hist', 'hist', '2018',