def plothist(xtitle,hists,ratio=False,logy=False,norm=False): # SETTING outdir = ensuredir("plots/") fname = outdir+"testPlot" if ratio: fname += "_ratio" if logy: fname += "_logy" if norm: fname += "_norm" # normalize each histogram rrange = 0.5 width = 0.2 # legend width position = 'topright' # legend position header = "Gaussians" # legend header text = "#mu#tau_{h}" # corner text grid = True #and False staterr = True and False # add uncertainty band to first histogram lstyle = 1 # solid lines # PLOT LOG.header(fname) plot = Plot(xtitle,hists,norm=norm) plot.draw(ratio=ratio,logy=logy,ratiorange=rrange,lstyle=lstyle,grid=grid,staterr=staterr) plot.drawlegend(position,header=header,width=width) plot.drawtext(text) plot.saveas(fname+".png") plot.saveas(fname+".pdf") #plot.saveas(fname+".C") #plot.saveas(fname+".png",fname+".C") #plot.saveas(fname,ext=['png','pdf']) plot.close() print
def checklatex(texts, tag=""): """Check legend entries: colors, titles, ...""" # https://root.cern.ch/doc/master/classTPaveText.html LOG.header("checklegend" + tag.replace('_', ' ')) output = ensuredir('plots') fname = "%s/testLatex%s" % (output, tag) xdim = 500 ydim = 50 * (len(texts) + 2.5) print ">>> Canvas: %sx%s (nlines=%d)" % (xdim, ydim, len(texts)) canvas = TCanvas('canvas', 'canvas', xdim, int(ydim)) #pave1 = TPaveText(0.0,0,0.5,1,'ARC') #,'BR') pave2 = TPaveText(0.04, 0.04, 0.96, 0.96) #'ARC') #,'BR') #pave1.SetBorderSize(0) pave2.SetBorderSize(0) #pave1.SetTextAlign(12) pave2.SetTextAlign(12) #pave1.SetTextFont(42) pave2.SetTextFont(42) #pave1.SetFillColor(0) pave2.SetFillColor(0) #pave1.SetCornerRadius(0.05) #pave2.SetCornerRadius(0.05) #pave1.SetMargin(0.12) #pave1.SetTextSize(tsize) #pave2.Copy(pave1) for line in texts: latex = makelatex(line) print ">>> %r -> %r" % (line, latex) #pave1.AddText(line) pave2.AddText(latex) #pave1.Draw() pave2.Draw() canvas.SaveAs(fname + ".png") #canvas.SaveAs(fname+".pdf") canvas.Close()
def plothist(xtitle,hists,ratio=False,logy=False,norm=False,**kwargs): # SETTING outdir = ensuredir("plots/") fname = outdir+"testLegend" rrange = 0.5 header = "Gaussians" # legend header text = "#mu#tau_{h}" # corner text grid = True and False staterr = True and False # add uncertainty band to first histogram lstyle = 1 # solid lines panel = 1 # 1 = main (top) panel, 2 = ratio (bottom) panel hists = [h.Clone("%s_clone%d"%(h.GetName(),i)) for i, h in enumerate(hists)] if kwargs.get('pos',False): fname += "_"+kwargs['pos'].replace(';','') header = kwargs['pos'] if ratio: fname += "_ratio" # PLOT LOG.header(fname) plot = Plot(xtitle,hists,norm=norm) plot.draw(ratio=ratio,logy=logy,ratiorange=rrange,lstyle=lstyle,grid=grid,staterr=staterr) plot.drawlegend(border=True,header=header,panel=panel,**kwargs) plot.drawtext(text) plot.saveas(fname+".png") #plot.saveas(fname+".pdf") plot.close() print
def plotstack(xname,xtitle,datahist,exphists,ratio=False,logy=False): """Plot Stack objects for a given data hisogram and list of MC histograms.""" # SETTING outdir = ensuredir("plots") fname = "%s/testStack_%s"%(outdir,xname) if ratio: fname += "_ratio" if logy: fname += "_logy" rrange = 0.5 text = "#mu#tau_{h} baseline" grid = True and False position = 'topright' if logy else 'right' # PLOT LOG.header(fname) plot = Stack(xtitle,datahist,exphists) plot.draw(ratio=ratio,logy=logy,ratiorange=rrange,grid=grid) plot.drawlegend(position=position) plot.drawtext(text) plot.saveas(fname+".png") plot.saveas(fname+".pdf") #plot.saveas(fname+".C") #plot.saveas(fname+".png",fname+".C") #plot.saveas(fname,ext=['png','pdf']) plot.close() print
def main(): #### Test several initializations of Variable object. #### Note that key-word arguments starting with 'c' are used for context-dependent attributes ###mvisbins = [0,30,40,50,60,70,75,80,90,100,120,200] ###variables = [ ### Variable('m_vis', "m_{vis} [GeV]", 40, 0,200), ### Variable('njets', "Number of jets", 8, 0, 8), ### Variable('m_vis', 40, 0,200), ### Variable('njets', 8, 0, 8), ### Variable('njets', 8, 0, 8, veto='njets'), ### Variable('st', 20, 0,800, title="S_{T}",only="njets",blind="st>600"), ### Variable('m_vis', 40, 0,200, cbins={'njets':mvisbins},blind=(70,90)), ### Variable('m_vis', mvisbins, cbins={"njets[^&]*2":(40,0,200)},), ### Variable('pt_1+pt_2', 20, 0,800, title="S_{T}^{tautau}",ctitle={"njets":"S_{T}"}), ###] selections = [ Selection(""), Selection("baseline", "pt_1>50 && pt_2>50"), Selection("njets>=1", "pt_1>50 && pt_2>50 && njets>=1"), Selection("1 b tags", "pt_1>50 && pt_2>50 && njets>=2 && nbtags>=1", weight="btagweight"), ] for selection in selections: LOG.header(selection.name) print ">>> name='%s', filename='%s', title='%s', cut='%s'" % (color( selection.name), color(selection.filename), color( selection.title), color(selection.selection)) print ">>> weight=%r, drawcmd=%r" % (selection.weight, selection.drawcmd()) sum1 = selection + "dzeta>-40" print '>>> sum1 = selection + "dzeta>-40"' print ">>> name=%r, filename=%r, title=%r" % ( sum1.name, sum1.filename, sum1.title) print ">>> cut=%r" % (sum1.selection) sum2 = selection + Selection("dzeta", "dzeta>-40") print '>>> sum2 = selection + Selection("dzeta","dzeta>-40")' print ">>> name=%r, filename=%r, title=%r" % ( sum2.name, sum2.filename, sum2.title) print ">>> cut=%r" % (sum2.selection)
def compare(fnames, variables, **kwargs): # SETTING tnames = kwargs.get('tree', []) entries = kwargs.get('entries', []) # entries of files outdir = kwargs.get('outdir', "compare") tag = kwargs.get('tag', "") cut = kwargs.get('cut', "") norm = kwargs.get('norm', False) ensuredir(outdir) if isinstance(tnames, str): tnames = [tnames] * len(fnames) else: while len(tnames) < len(fnames): tnames.append(tnames[-1]) if norm: tag += "_norm" # normalize each histogram # GET FILES & TREES files = [] trees = [] for fname, tname in zip(fnames, tnames): file = TFile.Open(fname, 'READ') tree = file.Get(tname) files.append(file) trees.append(tree) for variable in variables[:]: if not hasattr(tree, variable.name): LOG.warning( "compare: tree %s:%s does not contain branch %r! Skipping..." % (fname, tname, variable.name)) variables.remove(variable) while len(entries) < len(trees): i = len(entries) entry = "%s %d" % (tnames[i], i + 1) entries.append(entry) # PLOT for variable in variables: fname = "%s/%s%s.png" % (outdir, variable, tag) rrange = 0.5 header = "Compare" # legend header text = "" # corner text ratio = True #and False logy = True and False grid = True #and False staterr = True #and False # add uncertainty band to first histogram lstyle = 1 # solid lines LOG.header(fname) # GET HISOGRAMS hists = [] for i, (tree, htitle) in enumerate(zip(trees, entries)): hname = "%s_%d" % (variable.filename, i) #hist = variable.gethist(hname,htitle) #dcmd = variable.drawcmd(hname) hist = variable.draw( tree, cut, name=hname, title=htitle) # create and fill hist from tree evts = hist.GetEntries() hist.SetTitle("%s (%d)" % (htitle, evts)) hists.append(hist) print ">>> %r: entries=%d, integral=%s, mean=%#.6g, s.d.=%#.6g" % ( htitle, evts, hist.Integral(), hist.GetMean(), hist.GetStdDev()) # DRAW PLOT plot = Plot(variable, hists, norm=norm) plot.draw(ratio=True, logy=logy, ratiorange=rrange, lstyle=lstyle, grid=grid, staterr=staterr) plot.drawlegend(header=header) plot.drawtext(text) plot.saveas(fname) plot.close() print
def compare(fnames, varsets, **kwargs): # SETTING tname = kwargs.get('tree', 'Events') entries = kwargs.get('entries', []) # entries of files outdir = kwargs.get('outdir', "compare") tag = kwargs.get('tag', "") cut = kwargs.get('cut', "") norm = kwargs.get('norm', False) ensuredir(outdir) if norm: tag += "_norm" # normalize each histogram tree = TChain(tname) # GET FILES & TREES for fname in fnames: tree.Add(fname) # PLOT for varset in varsets: fname = "%s/%s%s.png" % (outdir, '-'.join(v.filename for v in varset), tag) rrange = 0.5 header = "Compare" # legend header text = "" # corner text ratio = True #and False logy = True and False grid = True #and False staterr = True #and False # add uncertainty band to first histogram lstyle = 1 # solid lines xvar = varset[0] LOG.header(fname) # GET HISOGRAMS hists = [] for i, variable in enumerate(varset): hname = "%s_%d" % (variable.filename, i) htitle = variable.name #hist = variable.gethist(hname,htitle) #dcmd = variable.drawcmd(hname) hist = variable.draw( tree, cut, name=hname, title=htitle) # create and fill hist from tree evts = hist.GetEntries() hist.SetTitle(htitle) #"%s (%d)"%(htitle,evts) hists.append(hist) print ">>> %r: entries=%d, integral=%s, mean=%#.6g, s.d.=%#.6g" % ( htitle, evts, hist.Integral(), hist.GetMean(), hist.GetStdDev()) # DRAW PLOT plot = Plot(xvar, hists, norm=norm) plot.draw(ratio=True, logy=logy, ratiorange=rrange, lstyle=lstyle, grid=grid, staterr=staterr) plot.drawlegend(header=header, latex=False) plot.drawtext(text) plot.saveas(fname) plot.close() print
def main(args): channels = args.channels eras = args.eras parallel = args.parallel verbosity = args.verbosity obsset = args.observables plot = True analysis = 'ztt_tid' # $PROCESS_$ANALYSIS tag = "" fileexp = "$OUTDIR/$ANALYSIS_$OBS_$CHANNEL-$ERA$TAG.inputs.root" outdir = ensuredir("input") plotdir = "input/plots/$ERA" for era in eras: for channel in channels: for obs in obsset: PLOG.header("%s, %s, %s"%(obs,channel,era)) splitbydm = 'mtau' in obs and 'mumu' not in channel ############### # SAMPLES # ############### # sample set and their systematic variations # GET SAMPLESET join = ['VV','TT','ST'] sname = "$PICODIR/$SAMPLE_$CHANNEL$TAG.root" sampleset = getsampleset(channel,era,fname=sname,join=join,split=None,table=False,verb=1) if channel=='mumu': # RENAME (HTT convention) sampleset.rename('DY_M50','ZLL') sampleset.rename('WJ','W') sampleset.datasample.name = 'data_obs' # SYSTEMATIC VARIATIONS varprocs = { # processes to be varied 'Nom': ['ZLL','W','VV','ST','TT','QCD','data_obs'], } samplesets = { # sets of samples per variation 'Nom': sampleset, # nominal } samplesets['Nom'].printtable(merged=True,split=True) if verbosity>=2: samplesets['Nom'].printobjs(file=True) else: # SPLIT & RENAME (HTT convention) GMR = "genmatch_2==5" GML = "genmatch_2>0 && genmatch_2<5" GMJ = "genmatch_2==0" GMF = "genmatch_2<5" if splitbydm: idweights = getdmsf(era) # DM-dependent SF, pT > 20 GeV print idweights sampleset.split('DY',[('ZTT_DM0', GMR+" && dm_2==0"), ('ZTT_DM1', GMR+" && dm_2==1"), ('ZTT_DM10',GMR+" && dm_2==10"),('ZTT_DM11',GMR+" && dm_2==11"), ('ZL',GML),('ZJ',GMJ)]) sampleset.get('DY',unique=True).replaceweight('idweight_2',idweights[0],verb=2) # replace tau ID SF else: idweights = ('idweight_2', 'idweightUp_2', 'idweightDown_2') # pT-dependent SF sampleset.split('DY',[('ZTT',GMR),('ZL',GML),('ZJ',GMJ),]) sampleset.split('TT',[('TTT',GMR),('TTL',GML),('TTJ',GMJ)]) #sampleset.split('ST',[('STT',GMR),('STJ',GMF),]) # small background sampleset.rename('WJ','W') sampleset.datasample.name = 'data_obs' # SYSTEMATIC VARIATIONS systs = preparesysts( # prepare systematic variations: syskey, systag, procs ('Nom',"", ['ZTT','ZL','ZJ','W','VV','ST','TTT','TTL','TTJ','QCD','data_obs']), #,'STT','STJ' ('TES',"_shape_tes",['ZTT','TTT']), # tau energy scale ('LTF',"_shape_ltf",['ZL', 'TTL']), # l -> tau energy scale ('JTF',"_shape_jtf",['ZJ', 'TTJ','QCD','W']), # j -> tau energy scale ('tid',"_shape_tid",['ZTT','TTT'], idweights), # replace 'idweight_2' with up/down variations ('zpt',"_shape_dy", ['ZTT','ZL','ZJ'], ('zptweight','(1.1*zptweight-0.1)','(0.9*zptweight+0.1)')), # replace 'zptweight' ERA=era,CHANNEL=channel) # keys to replace in systag if splitbydm: for syskey, syst in systs.iteritems(): if 'ZTT' in syst.procs: # split all ZTT shapes syst.procs = ['ZTT_DM0','ZTT_DM1','ZTT_DM10','ZTT_DM11']+syst.procs[1:] samplesets = { # sets of samples per variation 'Nom': sampleset, # nominal 'TESUp': sampleset.shift(systs['TES'].procs,"_TES1p030",systs['TES'].up," +3% TES", split=True,filter=False,share=True), 'TESDown': sampleset.shift(systs['TES'].procs,"_TES0p970",systs['TES'].dn," -3% TES", split=True,filter=False,share=True), #'TESUp': sampleset.shift(systs['TES'].procs,"_TESUp", systs['TES'].up," +3% TES", split=True,filter=False,share=True), #'TESDown': sampleset.shift(systs['TES'].procs,"_TESDown",systs['TES'].dn," -3% TES", split=True,filter=False,share=True), 'LTFUp': sampleset.shift(systs['LTF'].procs,"_LTF1p030",systs['LTF'].up," +3% LTF", split=True,filter=False,share=True), 'LTFDown': sampleset.shift(systs['LTF'].procs,"_LTF0p970",systs['LTF'].dn," -3% LTF", split=True,filter=False,share=True), 'JTFUp': sampleset.shift(systs['JTF'].procs,"_JTF1p100",systs['JTF'].up," +10% JTF",split=True,filter=False,share=True), 'JTFDown': sampleset.shift(systs['JTF'].procs,"_JTF0p900",systs['JTF'].dn," -10% JTF",split=True,filter=False,share=True), } keys = samplesets.keys() if verbosity>=1 else ['Nom','TESUp','TESDown'] for shift in keys: # print table if not shift in samplesets: continue samplesets[shift].printtable(merged=True,split=True) if verbosity>=2: samplesets[shift].printobjs(file=True) ################### # OBSERVABLES # ################### # observable/variables to be fitted in combine if channel=='mumu': observables = [ Var('m_vis', 1, 60, 120, fname='mvis', ymargin=1.6, rrange=0.08), ] elif splitbydm: observables = [ Var('dm_2==0?0.1396:m_2', "m_tau", 18, 0, 1.8, fname='mtau'), ] else: mvis = Var('m_vis', 30, 50, 200, fname='mvis') observables = [ #Var('m_vis', 30, 50, 200, fname='mvis'), Var('m_vis', 38, 10, 200, fname='mvis'), # broad range #Var('m_vis', 15, 50, 200, tag="_10"), # coarser binning ] ############ # BINS # ############ # selection categories if channel=='mumu': baseline = "q_1*q_2<0 && iso_1<0.15 && iso_2<0.15 && !lepton_vetoes && metfilter" bins = [ Sel('ZMM', baseline), ] else: tauwps = ['VVVLoose','VVLoose','VLoose','Loose','Medium','Tight','VTight','VVTight'] tauwpbits = { wp: 2**i for i, wp in enumerate(tauwps)} tauwps = ['Tight'] # only do Tight iso_1 = "iso_1<0.15" iso_2 = "idDecayModeNewDMs_2 && idDeepTau2017v2p1VSjet_2>=$WP && idDeepTau2017v2p1VSe_2>=2 && idDeepTau2017v2p1VSmu_2>=8" baseline = "q_1*q_2<0 && %s && %s && !lepton_vetoes_notau && metfilter"%(iso_1,iso_2) zttregion = "%s && mt_1<60 && dzeta>-25 && abs(deta_ll)<1.5"%(baseline) bins = [ #Sel('baseline', repkey(baseline,WP=16)), #Sel('zttregion',repkey(zttregion,WP=16)), ] for wpname in tauwps: # loop over tau ID WPs wpbit = tauwpbits[wpname] bins.append(Sel(wpname,repkey(zttregion,WP=wpbit))) ####################### # DATACARD INPUTS # ####################### # histogram inputs for the datacards # https://twiki.cern.ch/twiki/bin/viewauth/CMS/SMTauTau2016 chshort = channel.replace('tau','t').replace('mu','m') # abbreviation of channel fname = repkey(fileexp,OUTDIR=outdir,ANALYSIS=analysis,CHANNEL=chshort,ERA=era,TAG=tag) createinputs(fname,samplesets['Nom'],observables,bins,recreate=True) if channel in ['mutau']: createinputs(fname,samplesets['TESUp'], observables,bins,systs['TES'].up,filter=systs['TES'].procs) createinputs(fname,samplesets['TESDown'],observables,bins,systs['TES'].dn,filter=systs['TES'].procs) createinputs(fname,samplesets['LTFUp'], observables,bins,systs['LTF'].up,filter=systs['LTF'].procs) createinputs(fname,samplesets['LTFDown'],observables,bins,systs['LTF'].dn,filter=systs['LTF'].procs) createinputs(fname,samplesets['JTFUp'], observables,bins,systs['JTF'].up,filter=systs['JTF'].procs) createinputs(fname,samplesets['JTFDown'],observables,bins,systs['JTF'].dn,filter=systs['JTF'].procs) createinputs(fname,samplesets['Nom'],observables,bins,systs['tid'].up,filter=systs['tid'].procs,replaceweight=systs['tid'].wgtup) createinputs(fname,samplesets['Nom'],observables,bins,systs['tid'].dn,filter=systs['tid'].procs,replaceweight=systs['tid'].wgtdn) createinputs(fname,samplesets['Nom'],observables,bins,systs['zpt'].up,filter=systs['zpt'].procs,replaceweight=systs['zpt'].wgtup) createinputs(fname,samplesets['Nom'],observables,bins,systs['zpt'].dn,filter=systs['zpt'].procs,replaceweight=systs['zpt'].wgtdn) ############ # PLOT # ############ # control plots of the histogram inputs if plot: plotdir_ = ensuredir(repkey(plotdir,ERA=era,CHANNEL=channel)) pname = repkey(fileexp,OUTDIR=plotdir_,ANALYSIS=analysis,CHANNEL=chshort+"-$BIN",ERA=era,TAG='$TAG'+tag).replace('.root','.png') text = "%s: $BIN"%(channel.replace("mu","#mu").replace("tau","#tau_{h}")) groups = [ ] #(['^TT','ST'],'Top'),] plotinputs(fname,systs,observables,bins,text=text, pname=pname,tag=tag,group=groups)
def main(): mvisbins = [0, 30, 40, 50, 60, 70, 75, 80, 90, 100, 120, 200] # Test several initializations of Variable object. # Note that key-word arguments starting with 'c' are used for context-dependent attributes variables = [ Variable('m_vis', "m_{vis} [GeV]", 40, 0, 200), Variable('njets', "Number of jets", 8, 0, 8), Variable('m_vis', 40, 0, 200), Variable('njets', 8, 0, 8), Variable('njets', 8, 0, 8, veto='njets'), Variable('st', 20, 0, 800, title="S_{T}", only="njets", blind="st>600"), Variable('m_vis', 40, 0, 200, cbins={'njets': mvisbins}, blind=(70, 90)), Variable( 'm_vis', mvisbins, cbins={"njets[^&]*2": (40, 0, 200)}, ), Variable('pt_1+pt_2', 20, 0, 800, title="S_{T}^{tautau}", ctitle={"njets": "S_{T}"}), ] selections = [ "pt_1>50 && pt_2>50", "pt_1>50 && pt_2>50 && njets>=1", "pt_1>50 && pt_2>50 && njets>=2 && nbtags>=1", "pt_1>50 && pt_2>50 && njets==0", "pt_1>50 && pt_2>50 && dzeta>-40", ] for var in variables: LOG.header(var.name) print ">>> string=%s, repr=%r" % (var, var) print ">>> name='%s', filename='%s', title='%s'" % (color( var.name), color(var.filename), color(var.title)) print ">>> (nbins,xmin,xmax)=(%s,%s,%s), bins=%s" % ( var.nbins, var.xmin, var.xmax, var.bins) print ">>> hasintbins=%s, hasvariablebins=%s" % (var.hasintbins(), var.hasvariablebins()) print ">>> cut=%r, blindcuts=%r, blind(50,60)=%r" % ( var.cut, var.blindcuts, var.blind(50, 60)) hist = var.gethist() print ">>> hist=%s, (nbins,xmin,xmax)=(%s,%s,%s), variable=%s" % ( hist, hist.GetXaxis().GetNbins(), hist.GetXaxis().GetXmin(), hist.GetXaxis().GetXmax(), hist.GetXaxis().IsVariableBinSize()) gDirectory.Delete(hist.GetName()) for sel in selections: # context-dependent attributes var.changecontext(sel) print ">>> context: '%s'" % color(sel, 'grey') print ">>> plotfor=%s, name='%s', title='%s'" % ( var.plotfor(sel), color(var.name), color(var.title)) print ">>> (nbins,xmin,xmax)=(%s,%s,%s), bins=%s" % ( var.nbins, var.xmin, var.xmax, var.bins) print