Esempio n. 1
0
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)
Esempio n. 2
0
def make2dFRPlot(dataType, canv, outputDir, dataset, hist, title_indeces, name='', exportinroot = False, folder = 'fakerates_2d/', isprompt = False):
	#
	# produces all 2d fake rate maps
	#
	# this function takes the following paramters:
	# dataType..........type of the lepton ('mu', 'el')
	# canv..............canvas to be plotted
	# outputDir.........basic output directory
	# dataset...........dataset (only to take the title of the X and Y axis from)
	# hist..............histogram to be plotted
	# title_indeces.....list of two elements which are the indeces of the histograms that carry the X anc Y axis titles in their X axis title
	# name..............name of the output file
	# exportinroot......True if we want to export the canvas in a root file
	# folder............one may change the last outputfolder to something else than fakerates_2d
	# isprompt..........temporary solution to plot prompt ratio

	# define pad

	pad_plot = helper.makePad('tot')
	pad_plot.cd()
	pad_plot.SetTicks(1,1)

	# draw histogram

	hist.Draw("text colz e")

	# cosmetics

	hist.SetMarkerColor(ROOT.kBlack)
	hist.SetMarkerSize(1.8)
	hist.GetXaxis().SetTitle(helper.getXTitle(dataType, dataset.hists[title_indeces[0]]))
	hist.GetYaxis().SetTitle(helper.getXTitle(dataType, dataset.hists[title_indeces[1]]))
	hist.GetXaxis().SetTitleSize(0.07)
	hist.GetXaxis().SetLabelSize(0.07)
	hist.GetYaxis().SetTitleSize(0.07)
	hist.GetYaxis().SetLabelSize(0.07)
	hist.SetMinimum(0.0)

	if dataType == 'el': hist.SetMaximum(0.6)
	else               : hist.SetMaximum(0.4)
	if isprompt == True: prepend = 'PR'
	else               : prepend = 'FR' 

	hist.SetTitle(prepend + " 2d Map (" + helper.getLegendName(name) + ")")

	# save plot

	helper.saveCanvas(canv, pad_plot, outputDir + folder, prepend + "_2dmap_" + name.lower().replace(" ", "_"), False, exportinroot)
	pad_plot.Close()
Esempio n. 3
0
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))
Esempio n. 4
0
def canvasWithRatio(stack, histo, legend):
	c1 = ROOT.TCanvas('canvas', 'canvas', 675, 675)
	pad_plot  = lib.makePad('plot')
	pad_ratio = lib.makePad('ratio')
	pad_plot.SetTicks(1,1)
	pad_ratio.SetTicks(1,1)

	stackcp = copy.deepcopy(stack)
	stackhisto = copy.deepcopy(stackcp.GetStack().Last())
	hlist = stackcp.GetHists()
	newstack = ROOT.THStack('st', 'st')
	for i in hlist:
		i.Scale(1./stackhisto.Integral())
		newstack.Add(copy.deepcopy(i))
	
	pad_plot.cd()
	stackcp.Draw('hist')
	stackcp.GetYaxis().SetLabelSize(0.05)

	histoerr = copy.deepcopy(stackhisto)
	histoerr.SetFillColor(ROOT.kGray+3)
	histoerr.SetLineColor(ROOT.kGray+3)
	histoerr.SetFillStyle(3004)
	histoerr.Draw('same e2')

	#newstack.Draw('hist')
	histo.SetMarkerStyle(20)
	histo.SetMarkerSize(0.9)
	histo.SetMarkerColor(ROOT.kBlack)
	histo.SetLineColor(ROOT.kBlack)
	histonorm = copy.deepcopy(histo)
	#histonorm.Scale(1./histonorm.Integral())
	histonorm.Draw('same pe')

	stackmax = stackcp.GetMaximum()
	histomax = histo.GetMaximum()
	stackcp.SetMaximum(1.15* max(stackmax, histomax) )

	legend.Draw('same')
	
	pad_ratio.cd()
	#stackhisto.Scale(1./stackhisto.Integral())
	histocp = copy.deepcopy(histo)
	histocp.SetName('ratio')
	histocp.SetStats(0)
	#histocp.Scale(1./histocp.Integral())
	histocp.Divide(stackhisto)
	histocp.GetYaxis().SetRangeUser(0.00, 2.0)
	histocp.Draw('pe')
	histocp.GetYaxis().SetNdivisions(505)
	histocp.GetYaxis().SetLabelSize(0.08)
	histocp.GetXaxis().SetLabelSize(0.12)
	histocp.GetXaxis().SetTitle(histocp.GetName().split('_')[0])
	histocp.GetXaxis().SetTitleOffset(1.15)
	histocp.GetXaxis().SetTitleSize(0.15)
	histocp.SetTitle('')

	fl = ROOT.TF1("fl","[0]*x+[1]",0.,1.)
	histocp.Fit(fl)
	fl.Draw('same')

	line = lib.makeLine(histocp.GetXaxis().GetXmin(), 1., histocp.GetXaxis().GetXmax(), 1.)
	line.Draw('same')
	pad_ratio.Draw()
	pad_ratio.Update()
	c1.Update()
	return c1, stackhisto, histocp, stackcp, newstack, histonorm, line, histoerr
Esempio n. 5
0
if module == 'fakerates_2dct' or module == 'all':
	FR.Plot2dFRMapClosureTest(dataType, outputDir, module, data_samples, mc_samples, closure_samples, [wjets, dyjets50, dyjets10], qcd_samples)


if module == 'closure' or module == 'all':
	Plot.PlotProvenance(dataType, outputDir, closure_samples, [3,4,5,6])




# hard-coded to produce FR vs LepEta and LepPt plots for different jet cuts and different Jet Pts

if module == 'fakerates_1d' or module == 'all':

	canv = helper.makeCanvas(900, 675)
	pad_plot = helper.makePad('plot')
	pad_ratio = helper.makePad('ratio')


	for hist in data.hists:

		i = data.hists.index(hist)
			
		# Get Numerator Plots
		if hist.GetName() == 'h_Tight_LepEta_30':
			histindex_eta = i
			data_numerator_eta30 = copy.deepcopy(hist)
		if hist.GetName() == 'h_Tight_LepEta_40':
			data_numerator_eta40 = copy.deepcopy(hist)
		if hist.GetName() == 'h_Tight_LepEta_50':
			data_numerator_eta50 = copy.deepcopy(hist)
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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')
Esempio n. 9
0
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)
Esempio n. 10
0
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)
Esempio n. 11
0
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)
Esempio n. 12
0
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)