def Plot2d(dataType, outputDir, datasets, mcsets, histlist): # # this function is basically the 2d analogon to Plot1d: create 2d plots according to the histograms in the list # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # this function takes the following parameters: # dataType....type of the lepton ('mu', 'el') # outputDir...basic output directory # datasets....list of data samples [datasample1, datasample2, ..] # mcsets......list of mc samples [mcsample1, mcsample2, ..] # histlist....list of 1d histogram names ['h_Loose_LepIso', 'h_Loose_LepPhi', ..] # define canvas and pads canv = helper.makeCanvas(900, 675, 'c2d') pad_plot = helper.makePad('tot') pad_plot.cd() pad_plot.SetTicks(1,1) # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in datasets[0].hists: # get index of the histogram i = datasets[0].hists.index(hist) # only histograms in the parameter histlist are plotted if not hist.GetName() in histlist: continue # pre- and postpends prepend = '' postpend = '' if '_Loose_' in hist.GetName(): prepend = 'Loose_' if '_Tight_' in hist.GetName(): prepend = 'Tight_' # we stack both data and mc samples (i.e. one may use several data and several mc samples) data = ROOT.THStack() mc = ROOT.THStack() for dataset in datasets: data.Add(dataset.hists[i]) for mcset in mcsets: mc .Add(mcset .hists[i]) # call make2dPlot to make plots for data, total MC, each mc sample make2dPlot(dataType, canv, pad_plot, outputDir, data.GetStack().Last(), 'data', prepend + helper.getSaveName(hist) + postpend) make2dPlot(dataType, canv, pad_plot, outputDir, mc .GetStack().Last(), 'MC' , prepend + helper.getSaveName(hist) + postpend) for mcset in mcsets: make2dPlot(dataType, canv, pad_plot, outputDir, mcset.hists[i], mcset.GetName(), prepend + helper.getSaveName(hist) + postpend)
import ROOT, copy, array import lib as helper ROOT.gROOT.SetBatch(1) ROOT.gStyle.SetOptStat(0) ROOT.gStyle.SetPaintTextFormat("4.3f") ROOT.TGaxis.SetMaxDigits(3) file = ROOT.TFile('stufffortalk/ssFR_data_ewkcor_sync16Apr2014f.root', 'read') canv = helper.makeCanvas(900, 675) pad_plot = helper.makePad('tot') pad_plot.cd() pad_plot.SetTicks(1,1) hold = file.Get('h_mufr40c') etabin = array.array('d', [0.0, 0.5, 1.0, 1.5, 2.0, 2.5]) ptbins = array.array('d', [10., 15., 20., 25., 30., 35., 45., 50.]) hist = ROOT.TH2F('hist', 'hist', len(ptbins)-1, ptbins, len(etabin)-1, etabin) print hold.GetNbinsX() print hold.GetNbinsY() print hist.GetNbinsX() print hist.GetNbinsY() for y in range(1, hold.GetNbinsY()+1): for x in range(1, hold.GetNbinsX()+1): hist.SetBinContent(y,x,hold.GetBinContent(x,y)) print 'x=' + str(x) + ', y=' + str(y) + ', value=' + str(hold.GetBinContent(x,y))
def Plot2dFRMapClosureTest(dataType, outputDir, module, datasets, mcsets, mcsetsplot = [], mcsubtract = [], mcsubtractplot = []): # # basically the same function as Plot2dFRMap but only for closure test samples # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # this function takes the following paramters: # dataType..........type of the lepton ('mu', 'el') # outputDir.........basic output directory # module............module (the 1d projections on lepton eta and lepton pt are only created for the module 'all') # datasets..........list of data samples [datasample1, datasample2, ..] # mcsets............list of mc samples [mcsample1, mcsample2, ..] to enter bg stack # histlist..........list of 1d histogram names ['h_Loose_LepIso', 'h_Loose_LepPhi', ..] # mcsetsplot........list of mc samples [mcsample1, mcsample2, ..] to be drawn seperately # mcsubtract........list of mc samples [mcsample1, mcsample2, ..] to enter ewk subtraction # mcsubtractplot....list of mc samples [mcsample1, mcsample2, ..] to be drawn in comparison with ewk subtraction # default for ewk scales (central1 is ewk scale according to ETH method with lower and upper limit, central2 is scale according to UCSx) central1 = 1.0 lower = 1.0 upper = 1.0 central2 = 1.0 # compute the scales according to ETH and UCSx method # this part needs improvement scfirst = fit.getMCScaleFactorSimultaneouslyWithErrors(datasets, mcsubtractplot, mcsubtract) central1 = scfirst[0][1] lower = scfirst[1][1] upper = scfirst[2][1] scsecond = fit.getMCScaleFactorMutually(mcsubtract, 'h_Tight_MTMET30', datasets, mcsubtractplot, 60, 100) central2 = scsecond[0] print "------**------" print "qcd = " + str(scfirst[0][0]) print "central 1 = " + str(central1) print "lower 1 = " + str(lower) print "upper 1 = " + str(upper) print "central 2 = " + str(central2) print "------++------" # define canvas canv = helper.makeCanvas(900, 675, 'c2dFR') index_numerator = 0 index_denominator = 0 title_indeces = [0, 0] origins = 6 # we add data and mc in stacks for both numerator and denominator FR_ttbar = [{} for i in range(origins)] FR_qcd = [{} for i in range(origins)] ttbar_numerator = [ROOT.THStack() for i in range(origins)] qcd_numerator = [ROOT.THStack() for i in range(origins)] ttbar_denominator = [ROOT.THStack() for i in range(origins)] qcd_denominator = [ROOT.THStack() for i in range(origins)] # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in datasets[0].hists: # get index of the histogram i = datasets[0].hists.index(hist) # get indeces of histograms which carry title for X axis (0) and Y axis (1) if hist.GetName() == 'h_Loose_LepEta': title_indeces[1] = i if hist.GetName() == 'h_Loose_LepPt': title_indeces[0] = i # get numerator histograms if hist.GetName()[-8:] == 'h_FTight': index_numerator = i data_numerator = ROOT.THStack() mc_numerator = ROOT.THStack() mcsub_numerator = ROOT.THStack() for data in datasets: data_numerator .Add(copy.deepcopy(data.hists[index_numerator])) for mc in mcsets: mc_numerator .Add(copy.deepcopy(mc .hists[index_numerator])) for mc in mcsubtractplot: mcsub_numerator.Add(copy.deepcopy(mc .hists[index_numerator])) # get numerator histograms if hist.GetName()[-8:] == 'h_PTight': mc_numerator_p = ROOT.THStack() for mc in mcsets: if 'dyjets50' in mc.GetName(): mc_numerator_p .Add(copy.deepcopy(mc .hists[i])) # get denominator histograms if hist.GetName()[-8:] == 'h_FLoose': index_denominator = i data_denominator = ROOT.THStack() mc_denominator = ROOT.THStack() mcsub_denominator = ROOT.THStack() for data in datasets: data_denominator .Add(copy.deepcopy(data.hists[index_denominator])) for mc in mcsets: mc_denominator .Add(copy.deepcopy(mc .hists[index_denominator])) for mc in mcsubtractplot: mcsub_denominator.Add(copy.deepcopy(mc .hists[index_denominator])) # get denominator histograms if hist.GetName()[-8:] == 'h_PLoose': mc_denominator_p = ROOT.THStack() for mc in mcsets: if 'dyjets50' in mc.GetName(): mc_denominator_p .Add(copy.deepcopy(mc .hists[i])) # we stack the closure test histograms (i.e. with provenance info) seperately # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in mcsetsplot[0].hists: # get index of the histogram i = mcsetsplot[0].hists.index(hist) # get numerator histogram if hist.GetName()[-10:-1] == 'h_FTight_': origin = int(hist.GetName()[-1:]) for mc in mcsetsplot: if 'qcd' in mc.GetName(): qcd_numerator [origin].Add(copy.deepcopy(mc.hists[i])) if 'ttbar' in mc.GetName(): ttbar_numerator[origin].Add(copy.deepcopy(mc.hists[i])) # get denominator histogram if hist.GetName()[-10:-1] == 'h_FLoose_': origin = int(hist.GetName()[-1:]) for mc in mcsetsplot: if 'qcd' in mc.GetName(): qcd_denominator [origin].Add(copy.deepcopy(mc.hists[i])) if 'ttbar' in mc.GetName(): ttbar_denominator[origin].Add(copy.deepcopy(mc.hists[i])) # get numerator histograms from stack FR_data = copy.deepcopy(data_numerator .GetStack().Last()) FR_mc = copy.deepcopy(mc_numerator .GetStack().Last()) PR_mc = copy.deepcopy(mc_numerator_p .GetStack().Last()) FR_mcsub = copy.deepcopy(mcsub_numerator.GetStack().Last()) FR_data_mcsub_c1 = copy.deepcopy(FR_data) for j in range(origins): FR_ttbar[j] = copy.deepcopy(ttbar_numerator[j].GetStack().Last()) FR_qcd [j] = copy.deepcopy(qcd_numerator [j].GetStack().Last()) data_denominator_mcsub_c1 = copy.deepcopy(data_denominator.GetStack().Last()) # perform ewk subtraction only for ETH method if len(mcsubtract)>0: for mc in mcsubtract: # numerator mc.hists[index_numerator].Scale(central1) FR_data_mcsub_c1.Add(mc.hists[index_numerator], -1) mc.hists[index_numerator].Scale(1.0/central1) # denominator mc.hists[index_denominator].Scale(central1) data_denominator_mcsub_c1.Add(mc.hists[index_denominator],-1) mc.hists[index_denominator].Scale(1.0/central1) # fake rates FR_data .Divide(FR_data , copy.deepcopy(data_denominator .GetStack().Last()), 1, 1, 'B') FR_mc .Divide(FR_mc , copy.deepcopy(mc_denominator .GetStack().Last()), 1, 1, 'B') PR_mc .Divide(PR_mc , copy.deepcopy(mc_denominator_p .GetStack().Last()), 1, 1, 'B') FR_mcsub .Divide(FR_mcsub , copy.deepcopy(mcsub_denominator.GetStack().Last()), 1, 1, 'B') FR_data_mcsub_c1.Divide(FR_data_mcsub_c1, data_denominator_mcsub_c1 , 1, 1, '' ) for j in range(origins): FR_ttbar[j].Divide(FR_ttbar[j], copy.deepcopy(ttbar_denominator[j].GetStack().Last()), 1, 1, 'B') FR_qcd [j].Divide(FR_qcd [j], copy.deepcopy(qcd_denominator [j].GetStack().Last()), 1, 1, 'B') # plot 2d maps make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data , title_indeces, 'data' , True, 'fakerates_2dct/') make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_mc , title_indeces, 'mc' , True, 'fakerates_2dct/') make2dFRPlot(dataType, canv, outputDir, datasets[0], PR_mc , title_indeces, 'mc' , True, 'fakerates_2dct/', True) make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_mcsub , title_indeces, 'qcd' , True, 'fakerates_2dct/') make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data_mcsub_c1, title_indeces, 'datamcsub_central1', True, 'fakerates_2dct/') for j in range(origins): make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_ttbar[j], title_indeces, 'ttbar_g_' + str(j), True, 'fakerates_2dct/') make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_qcd[j] , title_indeces, 'qcd_g_' + str(j) , True, 'fakerates_2dct/')
def Plot2dFRMap(dataType, outputDir, module, datasets, mcsets, mcsetsplot = [], mcsubtract = [], mcsubtractplot = [], doProjection = False, mcsubtractscales = False): # # produce the fake rate 2d maps (incl. ewk subtraction) for given samples # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # this function takes the following paramters: # dataType..........type of the lepton ('mu', 'el') # outputDir.........basic output directory # module............module (the 1d projections on lepton eta and lepton pt are only created for the module 'all') # datasets..........list of data samples [datasample1, datasample2, ..] # mcsets............list of mc samples [mcsample1, mcsample2, ..] to enter bg stack # histlist..........list of 1d histogram names ['h_Loose_LepIso', 'h_Loose_LepPhi', ..] # mcsetsplot........list of mc samples [mcsample1, mcsample2, ..] to be drawn seperately # mcsubtract........list of mc samples [mcsample1, mcsample2, ..] to enter ewk subtraction # mcsubtractplot....list of mc samples [mcsample1, mcsample2, ..] to be drawn in comparison with ewk subtraction # doProjection......True if the 1d projections on lepton eta and lepton pt bins shall be produced as well # mcsubtractscales..True if we first want to scale ewk according to ETH/UCSx methods # default for ewk scales (central1 is ewk scale according to ETH method with lower and upper limit, central2 is scale according to UCSx) central1 = 1.0 lower = 1.0 upper = 1.0 central2 = 1.0 # compute the scales according to ETH and UCSx method # this part needs improvement if mcsubtractscales: scfirst = fit.getMCScaleFactorSimultaneouslyWithErrors(datasets, mcsubtractplot, mcsubtract) central1 = scfirst[0][1] lower = scfirst[1][1] upper = scfirst[2][1] scsecond = fit.getMCScaleFactorMutually(mcsubtract, 'h_Tight_MTMET30', datasets, mcsubtractplot, 60, 100) central2 = scsecond[0] print "------**------" print "qcd = " + str(scfirst[0][0]) print "central 1 = " + str(central1) print "lower 1 = " + str(lower) print "upper 1 = " + str(upper) print "central 2 = " + str(central2) print "------++------" # define canvas canv = helper.makeCanvas(900, 675, 'c2dFR') # we add data and mc in stacks for both numerator and denominator index_numerator = 0 index_denominator = 0 FR_mcplot = [{} for i in range(len(mcsetsplot))] FR_mcplot_copy = [{} for i in range(len(mcsetsplot))] mcplot_denominator = [{} for i in range(len(mcsetsplot))] title_indeces = [0, 0] # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in datasets[0].hists: # get index of histogram i = datasets[0].hists.index(hist) # get indeces of histograms which carry title for X axis (0) and Y axis (1) if hist.GetName() == 'h_Loose_LepEta': title_indeces[1] = i if hist.GetName() == 'h_Loose_LepPt': title_indeces[0] = i # get numerator histograms if hist.GetName()[-8:] == 'h_FTight': index_numerator = i data_numerator = ROOT.THStack() mc_numerator = ROOT.THStack() mcsub_numerator = ROOT.THStack() for data in datasets: data_numerator .Add(copy.deepcopy(data.hists[index_numerator])) for mc in mcsets: mc_numerator .Add(copy.deepcopy(mc .hists[index_numerator])) for j, mc in enumerate(mcsetsplot): FR_mcplot[j] = copy.deepcopy(mc .hists[index_numerator]) for mc in mcsubtractplot: mcsub_numerator .Add(copy.deepcopy(mc .hists[index_numerator])) # get denominator histograms if hist.GetName()[-8:] == 'h_PTight': mc_numerator_p = ROOT.THStack() for mc in mcsets: if 'dyjets50' in mc.GetName(): mc_numerator_p .Add(copy.deepcopy(mc .hists[i])) # get denominator histograms if hist.GetName()[-8:] == 'h_FLoose': index_denominator = i data_denominator = ROOT.THStack() mc_denominator = ROOT.THStack() mcsub_denominator = ROOT.THStack() for data in datasets: data_denominator .Add(copy.deepcopy(data.hists[index_denominator])) for mc in mcsets: mc_denominator .Add(copy.deepcopy(mc .hists[index_denominator])) for j, mc in enumerate(mcsetsplot): mcplot_denominator[j] = copy.deepcopy(mc .hists[index_denominator]) for mc in mcsubtractplot: mcsub_denominator .Add(copy.deepcopy(mc .hists[index_denominator])) # get denominator histograms if hist.GetName()[-8:] == 'h_PLoose': mc_denominator_p = ROOT.THStack() for mc in mcsets: if 'dyjets50' in mc.GetName(): mc_denominator_p .Add(copy.deepcopy(mc .hists[i])) # Get Numerator CERN Histogram if hist.GetName()[-19:] == 'h_FTight_CERN_small': data_numerator_CERN_small = ROOT.THStack() for data in datasets: data_numerator_CERN_small .Add(copy.deepcopy(data.hists[i])) # Get Numerator CERN Histogram if hist.GetName()[-19:] == 'h_FTight_CERN_large': data_numerator_CERN_large = ROOT.THStack() for data in datasets: data_numerator_CERN_large .Add(copy.deepcopy(data.hists[i])) # Get Numerator CERN Histogram if hist.GetName()[-19:] == 'h_FLoose_CERN_small': data_denominator_CERN_small = ROOT.THStack() for data in datasets: data_denominator_CERN_small .Add(copy.deepcopy(data.hists[i])) # Get Numerator CERN Histogram if hist.GetName()[-19:] == 'h_FLoose_CERN_small': data_denominator_CERN_large = ROOT.THStack() for data in datasets: data_denominator_CERN_large .Add(copy.deepcopy(data.hists[i])) # get numerator histograms from stack FR_data = copy.deepcopy(data_numerator .GetStack().Last()) FR_mc = copy.deepcopy(mc_numerator .GetStack().Last()) PR_mc = copy.deepcopy(mc_numerator_p .GetStack().Last()) FR_mcsub = copy.deepcopy(mcsub_numerator .GetStack().Last()) # we copy the numerators for the projections FR_data_copy = copy.deepcopy(FR_data) FR_mc_copy = copy.deepcopy(FR_mc) PR_mc_copy = copy.deepcopy(PR_mc) FR_mcsub_copy = copy.deepcopy(FR_mcsub) for j in range(len(mcsetsplot)): FR_mcplot_copy[j] = copy.deepcopy(FR_mcplot[j]) # ewk numerators FR_data_mcsub = copy.deepcopy(FR_data) FR_data_mcsub_c1 = copy.deepcopy(FR_data) FR_data_mcsub_l1 = copy.deepcopy(FR_data) FR_data_mcsub_u1 = copy.deepcopy(FR_data) FR_data_mcsub_c2 = copy.deepcopy(FR_data) # CERN method (not working yet) FR_data_CERN_small = copy.deepcopy(data_numerator_CERN_small.GetStack().Last()) FR_data_CERN_large = copy.deepcopy(data_numerator_CERN_large.GetStack().Last()) FR_data_CERN_small.Divide(FR_data_CERN_small, copy.deepcopy(data_denominator_CERN_small.GetStack().Last()), 1, 1, 'B') FR_data_CERN_large.Divide(FR_data_CERN_large, copy.deepcopy(data_denominator_CERN_large.GetStack().Last()), 1, 1, 'B') FR_data_mcsub_c3 = copy.deepcopy(FR_data) FR_data_mcsub_c3.Divide(FR_data_mcsub_c3, copy.deepcopy(data_denominator.GetStack().Last()), 1, 1, 'B') FR_data_mcsub_c3 = DoMCSubCERN(FR_data_mcsub_c3, FR_data_CERN_small, FR_data_CERN_large, 447731, 517016, 23680, 10089) # numbers from loose MET #FR_data_mcsub_c3 = DoMCSubCERN(FR_data_mcsub_c3, FR_data_CERN_small, FR_data_CERN_large, 108963, 27751, 847, 270) # numbers from tight MET # you gotta fill in the numbers by hand (i know, not very nice indeed) from the counters fCounter_CERN_small/-large from Fakerates.cc # ewk denominators data_denominator_mcsub = copy.deepcopy(data_denominator.GetStack().Last()) data_denominator_mcsub_c1 = copy.deepcopy(data_denominator.GetStack().Last()) data_denominator_mcsub_l1 = copy.deepcopy(data_denominator.GetStack().Last()) data_denominator_mcsub_u1 = copy.deepcopy(data_denominator.GetStack().Last()) data_denominator_mcsub_c2 = copy.deepcopy(data_denominator.GetStack().Last()) # create 2d PLOT # we subtract every mc set in mcsubtract from the data 5 times (unscaled, ETH, lower, upper, UCSx) # both for numerator and denominator (WATCH OUT FOR THE SCALING!) if len(mcsubtract)>0: for mc in mcsets: # numerator unscaled FR_data_mcsub.Add(mc.hists[index_numerator], -1) # numerator ETH central mc.hists[index_numerator].Scale(central1) FR_data_mcsub_c1.Add(mc.hists[index_numerator], -1) # numerator ETH lower bound mc.hists[index_numerator].Scale(lower/central1) FR_data_mcsub_l1.Add(mc.hists[index_numerator], -1) # numerator ETH upper bound mc.hists[index_numerator].Scale(upper/lower) FR_data_mcsub_u1.Add(mc.hists[index_numerator], -1) # numerator UCSx central mc.hists[index_numerator].Scale(central2/upper) FR_data_mcsub_c2.Add(mc.hists[index_numerator], -1) # rescale it to 1 again mc.hists[index_numerator].Scale(1/central2) # denominator unscaled data_denominator_mcsub.Add(mc.hists[index_denominator], -1) # denominator ETH central mc.hists[index_denominator].Scale(central1) data_denominator_mcsub_c1.Add(mc.hists[index_denominator],-1) # denominator ETH lower bound mc.hists[index_denominator].Scale(lower/central1) data_denominator_mcsub_l1.Add(mc.hists[index_denominator],-1) # denominator ETH upper bound mc.hists[index_denominator].Scale(upper/lower) data_denominator_mcsub_u1.Add(mc.hists[index_denominator],-1) # denominator UCSx central mc.hists[index_denominator].Scale(central2/upper) data_denominator_mcsub_c2.Add(mc.hists[index_denominator],-1) # rescale it to 1 again mc.hists[index_denominator].Scale(1/central2) # ewk subtracted numerators data_numerator_mcsub = copy.deepcopy(FR_data_mcsub ) data_numerator_mcsub_c1 = copy.deepcopy(FR_data_mcsub_c1) data_numerator_mcsub_l1 = copy.deepcopy(FR_data_mcsub_l1) data_numerator_mcsub_u1 = copy.deepcopy(FR_data_mcsub_u1) data_numerator_mcsub_c2 = copy.deepcopy(FR_data_mcsub_c2) # ewk subtracted fake rates FR_data_mcsub .Divide(FR_data_mcsub , data_denominator_mcsub , 1, 1, '') FR_data_mcsub_c1.Divide(FR_data_mcsub_c1, data_denominator_mcsub_c1, 1, 1, '') FR_data_mcsub_l1.Divide(FR_data_mcsub_l1, data_denominator_mcsub_l1, 1, 1, '') FR_data_mcsub_u1.Divide(FR_data_mcsub_u1, data_denominator_mcsub_u1, 1, 1, '') FR_data_mcsub_c2.Divide(FR_data_mcsub_c2, data_denominator_mcsub_c2, 1, 1, '') data_den = data_denominator .GetStack().Last() #make2dFRPlot(dataType, canv, outputDir, datasets[0], data_den , title_indeces, 'data_den', True) # fake rates for pure data, total mc and every single mc sample FR_data .Divide(FR_data , copy.deepcopy(data_denominator .GetStack().Last()), 1, 1, 'B') FR_mc .Divide(FR_mc , copy.deepcopy(mc_denominator .GetStack().Last()), 1, 1, 'B') PR_mc .Divide(PR_mc , copy.deepcopy(mc_denominator_p .GetStack().Last()), 1, 1, 'B') FR_mcsub .Divide(FR_mcsub , copy.deepcopy(mcsub_denominator .GetStack().Last()), 1, 1, 'B') for j in range(len(mcsetsplot)): FR_mcplot[j].Divide(FR_mcplot[j], copy.deepcopy(mcplot_denominator[j]), 1, 1, 'B') # call make2dFRPlot to produce fake rate maps # pure data make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data , title_indeces, 'data') # total mc make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_mc , title_indeces, 'mc' ) # total mc (prompt ratio) make2dFRPlot(dataType, canv, outputDir, datasets[0], PR_mc , title_indeces, 'mc' , False, 'fakerates_2d/', True) # mcsubtractplot (i.e. qcd) make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_mcsub , title_indeces, mcsubtractplot[0].GetName()) # every single mc sample if len(mcsetsplot)>0: for j in range(len(mcsetsplot)): make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_mcplot[j], title_indeces, mcsetsplot[j].GetName()) # ewk subtracted unscaled if len(mcsubtract)>0: make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data_mcsub, title_indeces, 'datamcsub') # ewk subtracted ETH, lower, upper, UCSx, CERN if mcsubtractscales: make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data_mcsub_c1, title_indeces, 'datamcsub_central1') make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data_mcsub_l1, title_indeces, 'datamcsub_lower1' ) make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data_mcsub_u1, title_indeces, 'datamcsub_upper1' ) make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data_mcsub_c2, title_indeces, 'datamcsub_central2') make2dFRPlot(dataType, canv, outputDir, datasets[0], FR_data_mcsub_c3, title_indeces, 'datamcsub_central3') # do make the lepton eta and lepton pt projections if module == 'all' if doProjection == True and module == 'all': # re-adjust the canvas margin and create some pads as we're goin 1d now, bro! canv.SetRightMargin(0.0) pad_plot = helper.makePad('plot') pad_ratio = helper.makePad('ratio') # projection on lepton pt goes first # ewk subtracted numerators FR_data_px_mcsub = copy.deepcopy(data_numerator_mcsub .ProjectionX()) FR_data_px_mcsub_c1 = copy.deepcopy(data_numerator_mcsub_c1.ProjectionX()) FR_data_px_mcsub_l1 = copy.deepcopy(data_numerator_mcsub_l1.ProjectionX()) FR_data_px_mcsub_u1 = copy.deepcopy(data_numerator_mcsub_u1.ProjectionX()) FR_data_px_mcsub_c2 = copy.deepcopy(data_numerator_mcsub_c2.ProjectionX()) # ewk subtracted fake rates FR_data_px_mcsub .Divide(FR_data_px_mcsub , data_denominator_mcsub .ProjectionX(), 1, 1, '') FR_data_px_mcsub_c1.Divide(FR_data_px_mcsub_c1, data_denominator_mcsub_c1.ProjectionX(), 1, 1, '') FR_data_px_mcsub_l1.Divide(FR_data_px_mcsub_l1, data_denominator_mcsub_l1.ProjectionX(), 1, 1, '') FR_data_px_mcsub_u1.Divide(FR_data_px_mcsub_u1, data_denominator_mcsub_u1.ProjectionX(), 1, 1, '') FR_data_px_mcsub_c2.Divide(FR_data_px_mcsub_c2, data_denominator_mcsub_c2.ProjectionX(), 1, 1, '') # normal numerators FR_data_px = copy.deepcopy(FR_data_copy .ProjectionX()) FR_mc_px = copy.deepcopy(FR_mc_copy .ProjectionX()) PR_mc_px = copy.deepcopy(PR_mc_copy .ProjectionX()) FR_mcsub_px = copy.deepcopy(FR_mcsub_copy .ProjectionX()) # normal fake rates FR_data_px .Divide(FR_data_px , copy.deepcopy(data_denominator .GetStack().Last().ProjectionX()), 1, 1, 'B') FR_mc_px .Divide(FR_mc_px , copy.deepcopy(mc_denominator .GetStack().Last().ProjectionX()), 1, 1, 'B') PR_mc_px .Divide(PR_mc_px , copy.deepcopy(mc_denominator_p .GetStack().Last().ProjectionX()), 1, 1, 'B') FR_mcsub_px .Divide(FR_mcsub_px , copy.deepcopy(mcsub_denominator .GetStack().Last().ProjectionX()), 1, 1, 'B') for j in range(len(mcsetsplot)): FR_mcplot_px[j] = copy.deepcopy(FR_mcplot_copy[j].ProjectionX()) FR_mcplot_px[j].Divide(FR_mcplot_px[j], copy.deepcopy(mcplot_denominator[j].ProjectionX()), 1, 1, 'B') # here comes the lepton eta projection # ewk subtracted numerators FR_data_py_mcsub = copy.deepcopy(data_numerator_mcsub .ProjectionY()) FR_data_py_mcsub_c1 = copy.deepcopy(data_numerator_mcsub_c1.ProjectionY()) FR_data_py_mcsub_l1 = copy.deepcopy(data_numerator_mcsub_l1.ProjectionY()) FR_data_py_mcsub_u1 = copy.deepcopy(data_numerator_mcsub_u1.ProjectionY()) FR_data_py_mcsub_c2 = copy.deepcopy(data_numerator_mcsub_c2.ProjectionY()) # ewk subtracted fake rates FR_data_py_mcsub .Divide(FR_data_py_mcsub , data_denominator_mcsub .ProjectionY(), 1, 1, '') FR_data_py_mcsub_c1.Divide(FR_data_py_mcsub_c1, data_denominator_mcsub_c1.ProjectionY(), 1, 1, '') FR_data_py_mcsub_l1.Divide(FR_data_py_mcsub_l1, data_denominator_mcsub_l1.ProjectionY(), 1, 1, '') FR_data_py_mcsub_u1.Divide(FR_data_py_mcsub_u1, data_denominator_mcsub_u1.ProjectionY(), 1, 1, '') FR_data_py_mcsub_c2.Divide(FR_data_py_mcsub_c2, data_denominator_mcsub_c2.ProjectionY(), 1, 1, '') # normal numerators FR_data_py = copy.deepcopy(FR_data_copy .ProjectionY()) FR_mc_py = copy.deepcopy(FR_mc_copy .ProjectionY()) PR_mc_py = copy.deepcopy(PR_mc_copy .ProjectionY()) FR_mcsub_py = copy.deepcopy(FR_mcsub_copy .ProjectionY()) # normal fake rates FR_data_py .Divide(FR_data_py , copy.deepcopy(data_denominator .GetStack().Last().ProjectionY()), 1, 1, 'B') FR_mc_py .Divide(FR_mc_py , copy.deepcopy(mc_denominator .GetStack().Last().ProjectionY()), 1, 1, 'B') PR_mc_py .Divide(PR_mc_py , copy.deepcopy(mc_denominator_p .GetStack().Last().ProjectionY()), 1, 1, 'B') FR_mcsub_py .Divide(FR_mcsub_py , copy.deepcopy(mcsub_denominator .GetStack().Last().ProjectionY()), 1, 1, 'B') for j in range(len(mcsetsplot)): FR_mcplot_py[j] = copy.deepcopy(FR_mcplot_copy[j].ProjectionY()) FR_mcplot_py[j].Divide(FR_mcplot_py[j], copy.deepcopy(mcplot_denominator[j].ProjectionY()), 1, 1, 'B') # plottin some nice plots, man! hell yeah! # define the list of histograms which shall be plotted # i.e. one has to take the histogram of the stack, not the stack itself # projections on lepton pt # data vs. total mc histstoplot = [] histstoplot.append([FR_data_px, 'data']) histstoplot.append([FR_mc_px, 'totbg']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[0]], 'FR_proj_Pt_data') histstoplot = [] histstoplot.append([FR_data_px, 'data']) histstoplot.append([PR_mc_px, 'totbg']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[0]], 'PR_proj_Pt_dyjets50') # data vs. every mc sample if len(mcsetsplot)>0: for j in range(len(mcsetsplot)): histstoplot = [] histstoplot.append([FR_data_px, 'data']) histstoplot.append([FR_mcplot_px[j], mcsetsplot[j].GetName()]) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[0]], 'FR_proj_Pt_data-' + mcsetsplot[j].GetName().lstrip(dataType + '_')) # ewk subtracted unscaled vs. mcsubtractplot (i.e. qcd) # THIS PART WANTS TO BE IMPROVED: we treat all mcsubplot samples as qcd! if len(mcsubtract)>0: histstoplot = [] histstoplot.append([FR_data_px_mcsub, 'datamcsub']) if len(mcsubtractplot)>0: histstoplot.append([FR_mcsub_px, 'mu_qcdmuenr']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[0]], 'FR_proj_Pt_data-ew') # ewk subtraction methods vs. other methods if mcsubtractscales: # data vs. ETH histstoplot = [] histstoplot.append([FR_data_px, 'data']) histstoplot.append([FR_data_px_mcsub_c1, 'datamcsub_central1']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[0]], 'FR_proj_Pt_data-ew_data-eth', True, 'Data/ETH') # ETH vs. UCSx histstoplot = [] histstoplot.append([FR_data_px_mcsub_c1, 'datamcsub_central1']) histstoplot.append([FR_data_px_mcsub_c2, 'datamcsub_central2']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[0]], 'FR_proj_Pt_data-ew_eth-ucsx', True, 'ETH/UCSx', 1.01, 0.99) # ETH vs. mcsubtractplot (i.e. qcd) # THIS PART WANTS TO BE IMPROVED: we treat all mcsubplot samples as qcd! histstoplot = [] histstoplot.append([FR_data_px_mcsub_c1, 'datamcsub_central1']) if len(mcsubtractplot)>0: histstoplot.append([FR_mcsub_px, 'mu_qcdmuenr']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[0]], 'FR_proj_Pt_data-ew_data-eth-qcd', True, 'ETH/QCD') # projections on lepton eta # data vs. total mc histstoplot = [] histstoplot.append([FR_data_py, 'data']) histstoplot.append([FR_mc_py, 'totbg']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[1]], 'FR_proj_Eta_data') histstoplot = [] histstoplot.append([FR_data_py, 'data']) histstoplot.append([PR_mc_py, 'totbg']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[1]], 'PR_proj_Eta_dyjets50') # data vs. every single mc if len(mcsetsplot)>0: for j in range(len(mcsetsplot)): histstoplot = [] histstoplot.append([FR_data_py, 'data']) histstoplot.append([FR_mcplot_py[j], mcsetsplot[j].GetName()]) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[1]], 'FR_proj_Pt_data-' + mcsetsplot[j].GetName().lstrip(dataType + '_')) # ewk subtraction unscaled vs. mcsubtractplot (i.e. qcd) vs. data # THIS PART WANTS TO BE IMPROVED: we treat all mcsubplot samples as qcd! if len(mcsubtract)>0: histstoplot = [] histstoplot.append([FR_data_py, 'data']) histstoplot.append([FR_data_py_mcsub, 'datamcsub']) if len(mcsubtractplot)>0: histstoplot.append([FR_mcsub_py, 'mu_qcdmuenr']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[1]], 'FR_proj_Eta_data-ew') # ewk subtraction methods compared if mcsubtractscales: # data vs. ETH histstoplot = [] histstoplot.append([FR_data_py, 'data']) histstoplot.append([FR_data_py_mcsub_c1, 'datamcsub_central1']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[1]], 'FR_proj_Eta_data-ew_data-eth', True, 'Data/ETH') # ETH vs. UCSx histstoplot = [] histstoplot.append([FR_data_py_mcsub_c1, 'datamcsub_central1']) histstoplot.append([FR_data_py_mcsub_c2, 'datamcsub_central2']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[1]], 'FR_proj_Eta_data-ew_eth-ucsx', True, 'ETH/UCSx', 1.01, 0.99) # ETH vs. mcsubtractplot (i.e. qcd) vs. data # THIS PART WANTS TO BE IMPROVED: we treat all mcsubplot samples as qcd! histstoplot = [] histstoplot.append([FR_data_py_mcsub_c1, 'datamcsub_central1']) if len(mcsubtractplot)>0: histstoplot.append([FR_mcsub_py, 'mu_qcdmuenr']) histstoplot.append([FR_data_py, 'data']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, datasets[0].hists[title_indeces[1]], 'FR_proj_Eta_data-ew_data-eth-qcd', True, 'ETH/QCD') return True
def PlotFR(dataType, outputDir, datasets, mcsets, histlist, mcsetsplot = [], mcsubtract = [], mcsubtractplot = [], mcsubtractscales = False, bgestimation = False): # # produce the fake rate plots (incl. ewk subtraction) for given histograms and given samples # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # this function takes the following paramters: # dataType..........type of the lepton ('mu', 'el') # outputDir.........basic output directory # datasets..........list of data samples [datasample1, datasample2, ..] # mcsets............list of mc samples [mcsample1, mcsample2, ..] to enter bg stack # histlist..........list of 1d histogram names ['h_Loose_LepIso', 'h_Loose_LepPhi', ..] # mcsetsplot........list of mc samples [mcsample1, mcsample2, ..] to be drawn seperately # mcsubtract........list of mc samples [mcsample1, mcsample2, ..] to enter ewk subtraction # mcsubtractplot....list of mc samples [mcsample1, mcsample2, ..] to be drawn in comparison with ewk subtraction # mcsubtractscales..True if we first want to scale ewk according to ETH/UCSx methods # produce canvas and pads canv = helper.makeCanvas(900, 675, 'c1dFR') pad_plot = helper.makePad('plot') pad_ratio = helper.makePad('ratio') pad_plot.SetTicks(1,1) pad_ratio.SetTicks(1,1) # default for ewk scales (central1 is ewk scale according to ETH method with lower and upper limit, central2 is scale according to UCSx) central1 = 1.0 lower = 1.0 upper = 1.0 central2 = 1.0 # compute the scales according to ETH and UCSx method # this part needs improvement if mcsubtractscales: scfirst = fit.getMCScaleFactorSimultaneouslyWithErrors(datasets, mcsubtractplot, mcsubtract, 50, 120, 'h_Tight_MTMET30') qcd2 = scfirst[0][0] central12= scfirst[0][1] lower2 = scfirst[1][1] upper2 = scfirst[2][1] scfirst = fit.getMCScaleFactorSimultaneouslyWithErrors(datasets, mcsubtractplot, mcsubtract) central1 = scfirst[0][1] lower = scfirst[1][1] upper = scfirst[2][1] scsecond = fit.getMCScaleFactorMutually(mcsubtract, 'h_Tight_MTMET30', datasets, mcsubtractplot, 60, 100) central2 = scsecond[0] scsecond = fit.getMCScaleFactorMutually(mcsubtract, 'h_Tight_MTMET20', datasets, mcsubtractplot, 60, 100) central22= scsecond[0] print "------**------" print "MET30:" print "qcd = " + str(qcd2) print "central 1 = " + str(central12) print "lower 1 = " + str(lower2) print "upper 1 = " + str(upper2) print "central 2 = " + str(central2) print "------**------" print "MET20:" print "qcd = " + str(scfirst[0][0]) print "central 1 = " + str(central1) print "lower 1 = " + str(lower) print "upper 1 = " + str(upper) print "central 2 = " + str(central22) print "------++------" # we add data and mc in stacks for both numerator and denominator m = -1 n = -1 index_numerators = [] index_denominators = [] data_numerators = [] data_denominators = [] mc_numerators = [] mc_denominators = [] FRs_mcplot = [] mcplot_denominators = [] mcsub_numerators = [] mcsub_denominators = [] # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in datasets[0].hists: # get index of the histogram i = datasets[0].hists.index(hist) # only histograms in the parameter histlist are plotted if not hist.GetName() in histlist: continue # there are two NVertices plots in the list with different binning # we only plot the NVertices, but not the NVertices1 (this we use for the fake rate plots, see lib_FakeRate.py) if hist.GetName()[-9:] == "NVertices": continue # we take "NVertices1" histograms for Fakerate Plots # get numerator stacks if 'h_Tight_' in hist.GetName(): index_numerators .append(i) data_numerators .append(ROOT.THStack()) mc_numerators .append(ROOT.THStack()) FRs_mcplot .append([]) mcsub_numerators .append(ROOT.THStack()) m += 1 for data in datasets: data_numerators[m] .Add(copy.deepcopy(data.hists[index_numerators[m]])) for mc in mcsets: mc_numerators[m] .Add(copy.deepcopy(mc.hists [index_numerators[m]])) for j, mc in enumerate(mcsetsplot): FRs_mcplot[m][j] = copy.deepcopy(mc.hists [index_numerators[m]]) for mc in mcsubtractplot: mcsub_numerators[m] .Add(copy.deepcopy(mc.hists [index_numerators[m]])) # get denominator stacks if 'h_Loose_' in hist.GetName(): index_denominators .append(i) data_denominators .append(ROOT.THStack()) mc_denominators .append(ROOT.THStack()) mcplot_denominators.append([]) mcsub_denominators .append(ROOT.THStack()) n += 1 for data in datasets: data_denominators[n] .Add(copy.deepcopy(data.hists[index_denominators[n]])) for mc in mcsets: mc_denominators[n] .Add(copy.deepcopy(mc.hists [index_denominators[n]])) for j, mc in enumerate(mcsetsplot): mcplot_denominators[n][j] = copy.deepcopy(mc.hists [index_denominators[n]]) for mc in mcsubtractplot: mcsub_denominators[n] .Add(copy.deepcopy(mc.hists [index_denominators[n]])) # get numerators from stack for data, mc and mcsubtract FRs_data = [copy.deepcopy(data_numerator .GetStack().Last()) for data_numerator in data_numerators ] FRs_mc = [copy.deepcopy(mc_numerator .GetStack().Last()) for mc_numerator in mc_numerators ] FRs_mcsub = [copy.deepcopy(mcsub_numerator .GetStack().Last()) for mcsub_numerator in mcsub_numerators ] # perform ewk subtraction, once unscaled, once ETH method (central1, lower, upper) and once UCSx method for i in range(len(FRs_data)): FR_data_mcsub = copy.deepcopy(FRs_data[i]) FR_data_mcsub_c1 = copy.deepcopy(FRs_data[i]) FR_data_mcsub_l1 = copy.deepcopy(FRs_data[i]) FR_data_mcsub_u1 = copy.deepcopy(FRs_data[i]) FR_data_mcsub_c2 = copy.deepcopy(FRs_data[i]) data_denominator_mcsub = copy.deepcopy(data_denominators[i].GetStack().Last()) data_denominator_mcsub_c1 = copy.deepcopy(data_denominators[i].GetStack().Last()) data_denominator_mcsub_l1 = copy.deepcopy(data_denominators[i].GetStack().Last()) data_denominator_mcsub_u1 = copy.deepcopy(data_denominators[i].GetStack().Last()) data_denominator_mcsub_c2 = copy.deepcopy(data_denominators[i].GetStack().Last()) # we subtract every mc set in mcsubtract from the data 5 times (unscaled, ETH, lower, upper, UCSx) # both for numerator and denominator (WATCH OUT FOR THE SCALING!) if len(mcsubtract)>0: for mc in mcsubtract: # numerator unscaled FR_data_mcsub.Add(mc.hists[index_numerators[i]], -1) # numerator ETH central mc.hists[index_numerators[i]].Scale(central1) FR_data_mcsub_c1.Add(mc.hists[index_numerators[i]], -1) # numerator ETH lower bound mc.hists[index_numerators[i]].Scale(lower/central1) FR_data_mcsub_l1.Add(mc.hists[index_numerators[i]], -1) # numerator ETH upper bound mc.hists[index_numerators[i]].Scale(upper/lower) FR_data_mcsub_u1.Add(mc.hists[index_numerators[i]], -1) # numerator UCSx central mc.hists[index_numerators[i]].Scale(central2/upper) FR_data_mcsub_c2.Add(mc.hists[index_numerators[i]], -1) # rescale it to 1 again mc.hists[index_numerators[i]].Scale(1/central2) # denominator unscaled data_denominator_mcsub.Add(mc.hists[index_denominators[i]],-1) # denominator ETH central mc.hists[index_denominators[i]].Scale(central1) data_denominator_mcsub_c1.Add(mc.hists[index_denominators[i]],-1) # denominator ETH lower bound mc.hists[index_denominators[i]].Scale(lower/central1) data_denominator_mcsub_l1.Add(mc.hists[index_denominators[i]],-1) # denominator ETH upper bound mc.hists[index_denominators[i]].Scale(upper/lower) data_denominator_mcsub_u1.Add(mc.hists[index_denominators[i]],-1) # denomiantor UCSx central mc.hists[index_denominators[i]].Scale(central2/upper) data_denominator_mcsub_c2.Add(mc.hists[index_denominators[i]],-1) # rescale it to 1 again mc.hists[index_denominators[i]].Scale(1/central2) # ewk subtracted fake rates (non-correlated error propagation) FR_data_mcsub .Divide(FR_data_mcsub , data_denominator_mcsub , 1, 1, '') FR_data_mcsub_c1.Divide(FR_data_mcsub_c1, data_denominator_mcsub_c1, 1, 1, '') FR_data_mcsub_l1.Divide(FR_data_mcsub_l1, data_denominator_mcsub_l1, 1, 1, '') FR_data_mcsub_u1.Divide(FR_data_mcsub_u1, data_denominator_mcsub_u1, 1, 1, '') FR_data_mcsub_c2.Divide(FR_data_mcsub_c2, data_denominator_mcsub_c2, 1, 1, '') # fake rates for pure data, total mc, single mc (correlated error propagation) FRs_data[i] .Divide(FRs_data[i] , data_denominators[i] .GetStack().Last(), 1, 1, 'B') FRs_mc[i] .Divide(FRs_mc[i] , mc_denominators[i] .GetStack().Last(), 1, 1, 'B') FRs_mcsub[i] .Divide(FRs_mcsub[i] , mcsub_denominators[i] .GetStack().Last(), 1, 1, 'B') if len(mcsetsplot)>0: for j in range(len(mcsetsplot)): FRs_mcplot[i][j].Divide(FRs_mcplot[i][j], mcplot_denominators[i][j], 1, 1, 'B') # define the list of histograms which shall be plotted # i.e. one has to take the histogram of the stack, not the stack itself # data vs. total mc histstoplot = [] histstoplot.append([FRs_data[i], 'data']) histstoplot.append([FRs_mc[i], 'totbg']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, FRs_data[i], 'FR_' + FRs_data[i].GetName().lstrip('h_Tight_') + '_data') # fake rate for every single mc if len(mcsetsplot)>0: for j in range(len(mcsetsplot)): histstoplot = [] histstoplot.append([FRs_data[i], 'data']) histstoplot.append([FRs_mcplot[i][j], mcsetsplot[j].GetName()]) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, FRs_data[i], 'FR_' + FRs_data[i].GetName().lstrip('h_Tight_') + '_data-' + mcsetsplot[j].GetName().lstrip(dataType + '_')) # ewk subtracted vs. mcsubtractplot # THIS PART WANTS TO BE IMPROVED: we treat all mcsubplot samples as qcd! if len(mcsubtract)>0: histstoplot = [] histstoplot.append([FR_data_mcsub, 'datamcsub']) if len(mcsubtractplot)>0: histstoplot.append([FRs_mcsub[i], 'mu_qcdmuenr']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, FRs_data[i], 'FR_' + FRs_data[i].GetName().lstrip('h_Tight_') + '_data-ew') # ewk subtracted one method vs. the other if len(mcsubtract)>0 and mcsubtractscales: # data vs. ETH histstoplot = [] histstoplot.append([FRs_data[i], 'data']) histstoplot.append([FR_data_mcsub_c1, 'datamcsub_central1']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, FRs_data[i], 'FR_' + FRs_data[i].GetName().lstrip('h_Tight_') + '_data-ew_data-eth', True, 'Data/ETH') # ETH vs. UCSx histstoplot = [] histstoplot.append([FR_data_mcsub_c1, 'datamcsub_central1']) histstoplot.append([FR_data_mcsub_c2, 'datamcsub_central2']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, FRs_data[i], 'FR_' + FRs_data[i].GetName().lstrip('h_Tight_') + '_data-ew_eth-ucsx', True, 'ETH/UCSx', 1.01, 0.99) # ETH vs. mcsubtractplot vs. data # THIS PART WANTS TO BE IMPROVED: we treat all mcsubplot samples as qcd! histstoplot = [] histstoplot.append([FR_data_mcsub_c1, 'datamcsub_central1']) if len(mcsubtractplot)>0: histstoplot.append([FRs_mcsub[i], 'mu_qcdmuenr']) histstoplot.append([FRs_data[i], 'data']) make1dFRPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, FRs_data[i], 'FR_' + FRs_data[i].GetName().lstrip('h_Tight_') + '_data-ew_data-eth-qcd', True, 'ETH/QCD') return True
def PlotProvenance(dataType, outputDir, mcsets, binstoplot = []): # # produce and plot the provenance plot from a list of bins # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # this function takes the following parameters: # dataType....type of the lepton ('mu', 'el') # outputDir...basic output directory # mcsets......list of mc samples [mcsample1, mcsample2, ..] # binstoplot..list of bin numbers (matching origins from Fakerates.cc) we want to plot # define canvas and pads canv = helper.makeCanvas(900, 675, 'c1dZ') pad_plot = helper.makePad('tot') pad_plot.SetTicks(1,1) pad_plot.cd() # define some numbers and lists nbins = len(binstoplot) index_loose = 0 index_tight = 0 index_lnt = 0 labels = ['all', 'W', 'B', 'C', 'U/D/S', 'unm.'] hist_plot = [] mcgroups_loose = [] mcgroups_loose_lnt = [] mcgroups_loose_aes = [] mcgroups_tight = [] mcgroups_tight_aes = [] mcnames = [] # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in mcsets[0].hists: # get index of the histogram i = mcsets[0].hists.index(hist) # only consider plots with 'Provenance' in their names if not 'Provenance' in hist.GetName(): continue # h_Loose_Provenance is the denominator after lepton selection only # h_Loose_ProvenanceLNT is the numerator-subtracted denominator after lepton selection only # h_Loose_ProvenanceAES is the denominator after event and lepton selection # h_Tight_Provenance is the numerator after lepton selection only # h_Tight_ProvenanceAES is the numerator after event and lepton selection if hist.GetName() == 'h_Loose_Provenance' : index_loose = i if hist.GetName() == 'h_Loose_ProvenanceLNT': index_loose_lnt = i if hist.GetName() == 'h_Loose_ProvenanceAES': index_loose_aes = i if hist.GetName() == 'h_Tight_Provenance' : index_tight = i if hist.GetName() == 'h_Tight_ProvenanceAES': index_tight_aes = i # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for mcset in mcsets: # strip off the digits from the sample name label = ''.join([j for j in mcset.GetName() if not j.isdigit()]) foundat = -1 for j, mcname in enumerate(mcnames): if label == mcname: foundat = j # we group all provenance plots from samples which have the same label (e.g. dyjets10 and dyjets50) if foundat == -1: mcgroups_loose .append(ROOT.THStack()) mcgroups_loose_lnt.append(ROOT.THStack()) mcgroups_loose_aes.append(ROOT.THStack()) mcgroups_tight .append(ROOT.THStack()) mcgroups_tight_aes.append(ROOT.THStack()) mcgroups_loose [len(mcgroups_loose) -1].Add(mcset.hists[index_loose] ) mcgroups_loose_lnt[len(mcgroups_loose_lnt)-1].Add(mcset.hists[index_loose_lnt]) mcgroups_loose_aes[len(mcgroups_loose_aes)-1].Add(mcset.hists[index_loose_aes]) mcgroups_tight [len(mcgroups_tight) -1].Add(mcset.hists[index_tight] ) mcgroups_tight_aes[len(mcgroups_tight_aes)-1].Add(mcset.hists[index_tight_aes]) mcnames.append(label) else: mcgroups_loose [foundat].Add(mcset.hists[index_loose] ) mcgroups_loose_lnt[foundat].Add(mcset.hists[index_loose_lnt]) mcgroups_loose_aes[foundat].Add(mcset.hists[index_loose_aes]) mcgroups_tight [foundat].Add(mcset.hists[index_tight] ) mcgroups_tight_aes[foundat].Add(mcset.hists[index_tight_aes]) # fake rate provenance are created with and without event selection hist_den = [{} for j in range(len(mcnames))] hist_den_aes = [{} for j in range(len(mcnames))] hist_num = [{} for j in range(len(mcnames))] hist_num_aes = [{} for j in range(len(mcnames))] # create the histograms for each provenance plot (loose, lnt, loose_aes, tight, tight_aes) for i, plotgroup in enumerate([mcgroups_loose, mcgroups_loose_lnt, mcgroups_loose_aes, mcgroups_tight, mcgroups_tight_aes]): hist_plot.append([]) for j, group in enumerate(plotgroup): group.Draw('hist') histogram = group.GetStack().Last() if nbins == 0: nbins = histogram.GetNbinsX() if histogram.GetName() == 'h_Loose_Provenance' : postpend = 'loose' if histogram.GetName() == 'h_Loose_ProvenanceLNT': postpend = 'loose_lnt' if histogram.GetName() == 'h_Loose_ProvenanceAES': postpend = 'loose_aes' if histogram.GetName() == 'h_Tight_Provenance' : postpend = 'tight' if histogram.GetName() == 'h_Tight_ProvenanceAES': postpend = 'tight_aes' # we create as many histograms as we want to plot origins and we store them all in hist_plot hist_plot[i].append(ROOT.TH1F(histogram.GetName() + '_plot' + str(j), histogram.GetName(), nbins, 0, nbins)) # each of these histograms we fill in such a way that only one bin is non-zero n = 1 for k in range(1, histogram.GetNbinsX()+1): if binstoplot == [] or k in binstoplot: hist_plot[i][j].SetBinContent(n, histogram.GetBinContent(k)) n +=1 # copy numerators and denominators for subsequent fake rate production if hist_plot[i][j].GetName() == 'h_Loose_Provenance_plot' + str(j) : hist_den[j] = copy.deepcopy(hist_plot[i][j]) if hist_plot[i][j].GetName() == 'h_Loose_ProvenanceAES_plot' + str(j): hist_den_aes[j] = copy.deepcopy(hist_plot[i][j]) if hist_plot[i][j].GetName() == 'h_Tight_Provenance_plot' + str(j) : hist_num[j] = copy.deepcopy(hist_plot[i][j]) if hist_plot[i][j].GetName() == 'h_Tight_ProvenanceAES_plot' + str(j): hist_num_aes[j] = copy.deepcopy(hist_plot[i][j]) # produce nice lits of histograms and plot them hist_plots = makeProvenancePlots(hist_plot[i][j], labels, binstoplot) hist_plots[0].Draw('hist text') for k in range(1,len(hist_plots)): hist_plots[k].Draw('hist text same') helper.saveCanvas(canv, pad_plot, outputDir + "closure/", mcnames[j] + '_' + postpend) # we create the fake rate provenances with and without event selection for j in range(len(mcnames)): hist_num[j].Divide(hist_num[j], hist_den[j], 1, 1, 'B') hist_nums = makeProvenancePlots(hist_num[j], labels, binstoplot, False) hist_nums[0].Draw('hist text') for k in range(1, len(hist_nums)): hist_nums[k].Draw('hist text same') helper.saveCanvas(canv, pad_plot, outputDir + "closure/", mcnames[j] + '_rate') hist_num_aes[j].Divide(hist_num_aes[j], hist_den_aes[j], 1, 1, 'B') hist_nums = makeProvenancePlots(hist_num_aes[j], labels, binstoplot, False) hist_nums[0].Draw('hist text') for k in range(1, len(hist_nums)): hist_nums[k].Draw('hist text same') helper.saveCanvas(canv, pad_plot, outputDir + "closure/", mcnames[j] + '_rate_aes')
def PlotCompare(dataType, outputDir, mcsets, histname, leg, cutoff = -1, precise = False): # # plot a set of histograms defined by histname and comparing mc samples # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # this function takes the following parameters: # dataType....type of the lepton ('mu', 'el') # outputDir...basic output directory # mcsets......list of mc samples [mcsample1, mcsample2, ..] # leg.........legend to be plotted # cutoff......cutoff for the histogram name (see function getSaveName() in lib.py) # precise.....True if only the histogram with the name matching histname exactly shall be plotted # define canvas and pads canv = helper.makeCanvas(900, 675) pad_plot = helper.makePad('plot') pad_ratio = helper.makePad('ratio') pad_ratio.cd() # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in mcsets[0].hists: # get index of histogram i = mcsets[0].hists.index(hist) pad_plot.cd() # if precise is True, we only plot the histogram with the name matching histname exactly # else, we plot all histograms which have histname in their name (useful for several versions or bins of a histogram) if precise and not histname == hist.GetName(): continue if not precise and not histname in hist.GetName(): continue # pre- and postpends prepend = '' postpend = '_compare' if '_Loose_' in hist.GetName(): prepend = 'Loose_' if '_Tight_' in hist.GetName(): prepend = 'Tight_' # draw first histogram hist.Draw('hist') hist.SetFillStyle(0) hist.Scale(1.0/hist.Integral()) max = hist.GetMaximum() for j in range(1,len(mcsets)): mcsets[j].hists[i].Draw('hist same') mcsets[j].hists[i].SetFillStyle(0) mcsets[j].hists[i].SetLineStyle(2) mcsets[j].hists[i].Scale(1.0/mcsets[j].hists[i].Integral()) if max < mcsets[j].hists[i].GetMaximum(): max = mcsets[j].hists[i].GetMaximum() # do some cosmetics hist.SetMinimum(0.0001) hist.SetMaximum(1.5 * max) hist = helper.set1dPlotStyle(dataType, hist, helper.getColor(mcsets[0].GetName()), '', hist, '1/Integral') # draw legend leg.Draw() # draw ratio plot pad_ratio.cd() hist_ratio = copy.deepcopy(hist) hist_ratio.Divide(copy.deepcopy(mcsets[1].hists[i])) hist_ratio.Draw("p e1") hist_ratio = helper.setRatioStyle(dataType, hist_ratio, hist) line = helper.makeLine(hist_ratio.GetXaxis().GetXmin(), 1.00, hist_ratio.GetXaxis().GetXmax(), 1.00) line.Draw() # make plot helper.saveCanvas(canv, pad_plot, outputDir + "compare/", prepend + helper.getSaveName(hist, cutoff) + postpend)
def PlotJPtZooms(dataType, outputDir, dataset, mcsets, leg): # # plotting JetPt and JetRawPt distributions in bins of lepton eta and lepton pt (binning according to fake rate maps) # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # this function takes the following parameters: # dataType....type of the lepton ('mu', 'el') # outputDir...basic output directory # datasets....list of data samples [datasample1, datasample2, ..] # mcsets......list of mc samples [mcsample1, mcsample2, ..] # leg.........legend to be plotted # define canvas and pads canv = helper.makeCanvas(900, 675, 'c1dZ') pad_plot = helper.makePad('tot') pad_plot.SetTicks(1,1) pad_plot.cd() # text for eta binning t_eta = ROOT.TLatex() t_eta.SetNDC() t_eta.SetTextSize(0.05) t_eta.SetTextAlign(11) t_eta.SetTextColor(ROOT.kBlack) # text for pt binning t_pt = ROOT.TLatex() t_pt.SetNDC() t_pt.SetTextSize(0.05) t_pt.SetTextAlign(11) t_pt.SetTextColor(ROOT.kBlack) # bins in eta and pt, with total number of bins bins_eta = [0.0, 1.0, 2.4] #bins_pt = [10.0, 20.0, 30.0, 35.0, 37.5, 40.0, 42.5, 45.0, 47.5, 50.0, 55.0, 60.0, 70.0] # old bins_pt = [10.0, 20.0, 22.5, 25.0, 27.5, 30.0, 32.5, 35.0, 40.0, 50.0, 60.0, 70.0] # new bins_tot = (len(bins_eta)-1)*(len(bins_pt)-1) # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in dataset.hists: # get index of the histogram i = dataset.hists.index(hist) # only histograms in the parameter histlist are plotted if not "JPtZoom" in hist.GetName(): continue # pre- and postpends prepend = '' postpend = '' if '_Loose_' in hist.GetName(): prepend = 'Loose_' if '_Tight_' in hist.GetName(): prepend = 'Tight_' # get the id of the plot, i.e. the last number in the name (e.g. '0' in h_Loose_DJPtZoomC_0) id = hist.GetName().split('_')[-1] # draw data hist.Scale(1.0/hist.Integral()) hist.SetFillStyle(0) hist.SetLineStyle(2) hist.Draw("HIST") max = hist.GetMaximum() # draw mc samples for mc in mcsets: mc.hists[i].Scale(1.0/mc.hists[i].Integral()) mc.hists[i].SetFillStyle(0) mc.hists[i].Draw("HIST SAME") if mc.hists[i].GetMaximum()>max: max = mc.hists[i].GetMaximum() # do some cosmetics hist.SetMaximum(1.5*max) hist.GetXaxis().SetTitle(helper.getXTitle(dataType, hist)) hist.GetYaxis().SetTitle("1/Integral") hist.SetTitle("") hist.GetXaxis().SetTitleSize(0.07) hist.GetXaxis().SetLabelSize(0.07) hist.GetYaxis().SetTitleSize(0.07) hist.GetYaxis().SetLabelSize(0.07) hist.GetXaxis().SetNdivisions(505) hist.GetYaxis().SetNdivisions(505) # draw legend leg.Draw() # write bin texts m = int(id)//(len(bins_pt)-1) n = int(id)%(len(bins_pt)-1) if "ZoomC" in hist.GetName(): write = "corr." else: write = "raw" text_eta = str(bins_eta[m]) + " #leq jet-|#eta| < " + str(bins_eta[m+1]) text_pt = str(bins_pt[n]) + " #leq jet-p_{T} (" + write + ") < " + str(bins_pt[n+1]) t_eta.DrawLatex(0.22, 0.8, text_eta) t_pt.DrawLatex(0.22, 0.73, text_pt) # draw plots helper.saveCanvas(canv, pad_plot, outputDir + "zoom_jpt/", prepend + helper.getSaveName(hist, '-2:') + postpend, False)
def PlotMETZooms(dataType, outputDir, datasets, mcsets, leg, grouping = False): # # plotting MET distribution in bins of lepton eta and lepton pt (binning according to fake rate maps) # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # dataType....type of the lepton ('mu', 'el') # outputDir...basic output directory # datasets....list of data samples [datasample1, datasample2, ..] # mcsets......list of mc samples [mcsample1, mcsample2, ..] # leg.........legend to be plotted # grouping....True if mc samples should be grouped before stacking (useful in case of e.g. several QCD files) # define canvas and pads canv = helper.makeCanvas(900, 675, 'c1dM') pad_plot = helper.makePad('plot') pad_ratio = helper.makePad('ratio') pad_plot.SetTicks(1,1) pad_ratio.SetTicks(1,1) # text for eta binning t_eta = ROOT.TLatex() t_eta.SetNDC() t_eta.SetTextSize(0.05) t_eta.SetTextAlign(11) t_eta.SetTextColor(ROOT.kBlack) # text for pt binning t_pt = ROOT.TLatex() t_pt.SetNDC() t_pt.SetTextSize(0.05) t_pt.SetTextAlign(11) t_pt.SetTextColor(ROOT.kBlack) # bins in eta and pt, with total number of bins bins_eta = [0.0, 0.5, 1.0, 1.5, 2.0, 2.5] bins_pt = [20.0, 25.0, 30.0, 35.0, 40.0, 45.0, 50.0] bins_tot = (len(bins_eta)-1)*(len(bins_pt)-1) # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in datasets[0].hists: # get index of the histogram i = datasets[0].hists.index(hist) pad_plot.cd() # only histograms in the parameter histlist are plotted if not "METZoom" in hist.GetName(): continue # pre- and postpends prepend = '' postpend = '' if '_Loose_' in hist.GetName(): prepend = 'Loose_' if '_Tight_' in hist.GetName(): prepend = 'Tight_' # get the id of the plot, i.e. the last number in the name (e.g. '0' in h_Loose_FRMETZoom_0) id = hist.GetName().split('_')[-1] # we stack both data and mc samples (i.e. one may use several data and several mc samples) data = ROOT.THStack() mc = ROOT.THStack() for dataset in datasets: data.Add(dataset.hists[i]) # if grouping is enabled, we first sum all 'similar' mc samples before adding them to the stack # similar means, that we sum all samples which have the same name up to a few digits at the end # in this way, e.g., the samples dyjets50 and dyjets10 are stacked together # if grouping is not enabled, we just stack all mc samples in one stack if grouping: mcgroups = [] mcnames = [] for mcset in mcsets: label = ''.join([j for j in mcset.GetName() if not j.isdigit()]) foundat = -1 for j, mcname in enumerate(mcnames): if label == mcname: foundat = j if foundat == -1: mcgroups.append(ROOT.THStack()) mcgroups[len(mcgroups)-1].Add(mcset.hists[i]) mcnames.append(label) else: mcgroups[foundat].Add(mcset.hists[i]) for j, group in enumerate(mcgroups): group.Draw('hist') histogram = group.GetStack().Last() mc.Add(histogram) else: for mcset in mcsets: mc.Add(mcset.hists[i]) # draw histogram mc.Draw('hist') # define the list of histograms which shall be plotted # i.e. one has to take the histogram of the stack, not the stack itself hists = [] hists.append([data.GetStack().Last(), 'data' ]) hists.append([mc , 'totbg']) # plot pad_plot first, then we add the texts and plot ratio afterwards make1dPlot_plot(dataType, pad_plot, hists, hists[0][0], leg) # write bin texts m = int(id)//(len(bins_pt)-1) n = int(id)%(len(bins_pt)-1) if dataType == 'el': lepton = 'e' else : lepton = '#mu' text_eta = str(bins_eta[m]) + " #leq " + lepton + "-|#eta| < " + str(bins_eta[m+1]) text_pt = str(bins_pt[n]) + " #leq " + lepton + "-p_{T} < " + str(bins_pt[n+1]) t_eta.DrawLatex(0.22, 0.8, text_eta) t_pt.DrawLatex(0.22, 0.73, text_pt) # plot ratio #make1dPlot_ratio(dataType, pad_ratio, hists, hists[0][0]) # calling the function to produce the ratio plot results in a malfunction i do not understand properly # so we copy the lines from make1dPlot_ratio() while we still keep that function for other purposes pad_ratio.cd() data_bg_ratio = copy.deepcopy(hists[0][0]) data_bg_ratio.Divide(copy.deepcopy(hists[1][0].GetStack().Last())) data_bg_ratio.Draw("p e") data_bg_ratio = helper.setRatioStyle(dataType, data_bg_ratio, hists[0][0]) line = helper.makeLine(data_bg_ratio.GetXaxis().GetXmin(), 1.00, data_bg_ratio.GetXaxis().GetXmax(), 1.00) line.Draw() # save plot ROOT.gPad.RedrawAxis() helper.saveCanvas(canv, pad_plot, outputDir + "zoom_met/", prepend + helper.getSaveName(hist, '-2:') + postpend)
def Plot1d(dataType, outputDir, datasets, mcsets, histlist, leg, grouping = False): # # given data and mc samples, all histograms in histlist are produced with mc samples stacked # NOTE: ALL SAMPLES MUST CONTAIN THE EXACT SAME LIST OF HISTOGRAMS, OTHERWISE THIS FUNCTION WILL NOT WORK # # this function takes the following parameters: # dataType....type of the lepton ('mu', 'el') # outputDir...basic output directory # datasets....list of data samples [datasample1, datasample2, ..] # mcsets......list of mc samples [mcsample1, mcsample2, ..] # histlist....list of 1d histogram names ['h_Loose_LepIso', 'h_Loose_LepPhi', ..] # leg.........legend to be drawn # grouping....True if mc samples should be grouped before stacking (useful in case of e.g. several QCD files) # define canvas and pads canv = helper.makeCanvas(900, 675, 'c1d') pad_plot = helper.makePad('plot') pad_ratio = helper.makePad('ratio') pad_plot.SetTicks(1,1) pad_ratio.SetTicks(1,1) # iterate over all histograms in root files # it does not matter which sample we iterate on, as all samples contain the same list of histograms for hist in datasets[0].hists: # get index of the histogram i = datasets[0].hists.index(hist) pad_plot.cd() # only histograms in the parameter histlist are plotted if not hist.GetName() in histlist: continue # there are two NVertices plots in the list with different binning # we only plot the NVertices, but not the NVertices1 (this we use for the fake rate plots, see lib_FakeRate.py) if hist.GetName()[-10:] == "NVertices1": continue # pre- and postpends prepend = '' postpend = '' if '_Loose_' in hist.GetName(): prepend = 'Loose_' if '_Tight_' in hist.GetName(): prepend = 'Tight_' # we stack both data and mc samples (i.e. one may use several data and several mc samples) data = ROOT.THStack() mc = ROOT.THStack() for dataset in datasets: data.Add(dataset.hists[i]) # if grouping is enabled, we first sum all 'similar' mc samples before adding them to the stack # similar means, that we sum all samples which have the same name up to a few digits at the end # in this way, e.g., the samples dyjets50 and dyjets10 are stacked together # if grouping is not enabled, we just stack all mc samples in one stack if grouping: mcgroups = [] mcnames = [] for mcset in mcsets: label = ''.join([j for j in mcset.GetName() if not j.isdigit()]) foundat = -1 for j, mcname in enumerate(mcnames): if label == mcname: foundat = j if foundat == -1: mcgroups.append(ROOT.THStack()) mcgroups[len(mcgroups)-1].Add(mcset.hists[i]) mcnames.append(label) else: mcgroups[foundat].Add(mcset.hists[i]) for j, group in enumerate(mcgroups): group.Draw('hist') histogram = group.GetStack().Last() mc.Add(histogram) else: for mc in mcsets: mc.Add(mc.hists[i]) # define the list of histograms which shall be plotted # i.e. one has to take the histogram of the stack, not the stack itself histstoplot = [] histstoplot.append([data.GetStack().Last(), 'data' ]) histstoplot.append([mc , 'totbg']) # call make1dPlot to create the plot make1dPlot(dataType, canv, pad_plot, pad_ratio, outputDir, histstoplot, hist, prepend + helper.getSaveName(hist) + postpend, leg)