Пример #1
0
def makeControlPlot(systhistos, syst, tag, seltag, opt):
    hists = tuple([systhistos[(tag, syst, c)] for c in COMBINATIONS.keys()])
    h_tot, h_cor, h_wro, h_unm = hists

    h_tot.Scale(1. / h_tot.Integral())

    ctrlplot = RatioPlot('ctrlplot_%s' % tag)
    ctrlplot.add(h_cor, 'Correct')
    ctrlplot.add(h_wro, 'Wrong')
    ctrlplot.add(h_unm, 'Unmatched')
    ctrlplot.reference = h_tot
    ctrlplot.tag = ''
    ctrlplot.subtag = seltag
    ctrlplot.ratiotitle = 'Ratio wrt Total'
    ctrlplot.ratiorange = (0., 3.0)
    ctrlplot.colors = [ROOT.kBlue - 3, ROOT.kRed - 4, ROOT.kOrange - 3]
    ctrlplot.show("control_%s_%s" % (syst, tag), opt.outDir)
    ctrlplot.reset()
Пример #2
0
def makeControlPlot(systhistos, syst, tag, seltag, opt):
	hists = tuple([systhistos[(tag, syst, c)] for c in COMBINATIONS.keys()])
	h_tot, h_cor, h_wro, h_unm = hists

	h_tot.Scale(1./h_tot.Integral())

	ctrlplot = RatioPlot('ctrlplot_%s'%tag)
	ctrlplot.add(h_cor, 'Correct')
	ctrlplot.add(h_wro, 'Wrong')
	ctrlplot.add(h_unm, 'Unmatched')
	ctrlplot.reference = h_tot
	ctrlplot.tag = ''
	ctrlplot.subtag = seltag
	ctrlplot.ratiotitle = 'Ratio wrt Total'
	ctrlplot.ratiorange = (0., 3.0)
	ctrlplot.colors = [ROOT.kBlue-3, ROOT.kRed-4, ROOT.kOrange-3]
	ctrlplot.show("control_%s_%s"%(syst,tag), os.path.join(opt.outDir, 'syst_plots'))
	ctrlplot.reset()
Пример #3
0
def main(args, opt):
	os.system('mkdir -p %s'%opt.outDir)
	systfiles = {} # procname -> filename
	try:
		for fname in os.listdir(os.path.join(args[0],'syst')):
			if not os.path.splitext(fname)[1] == '.root': continue
			for syst,_,systfile,_ in SYSTSFROMFILES:
				if fname in systfile:
					systfiles[syst] = [os.path.join(args[0], 'syst', fname)]

		# Get the split nominal files
		systfiles['nominal'] = []
		for fname in os.listdir(os.path.join(args[0],'Chunks')):
			if not os.path.splitext(fname)[1] == '.root': continue
			isdata,procname,splitno = resolveFilename(fname)
			if not procname == 'TTJets_MSDecays_172v5': continue
			if not splitno: continue # file is split

			systfiles['nominal'].append(os.path.join(args[0],'Chunks',fname))
		if len(systfiles['nominal']) < 20:
			print "ERROR >>> Missing files for split nominal sample?"
			return -1

	except IndexError:
		print "Please provide a valid input directory"
		exit(-1)

	hname_to_keys = {} # hname -> (tag, syst, comb)
	tasklist = {} # treefile -> tasklist

	for fsyst in systfiles.keys():
		if not fsyst in tasklist: tasklist[fsyst] = []
		for tag,sel,_ in SELECTIONS:
			if fsyst == 'nominal':
				for syst,_,weight,combs in SYSTSFROMWEIGHTS:
					tasks = makeSystTask(tag, sel, syst,
						                 hname_to_keys, weight=weight,
						                 combs=combs)
					tasklist[fsyst] += tasks

				tasks = []
				for comb,combsel in COMBINATIONS.iteritems():
					for var,nbins,xmin,xmax,titlex in CONTROLVARS:
						hname = "%s_%s_%s" % (var, comb, tag)
						finalsel = "%s*(%s&&%s)"%(COMMONWEIGHT, sel, combsel)
						tasks.append((hname, var, finalsel,
							                 nbins, xmin, xmax, titlex))
						hname_to_keys[hname] = (tag, var, comb)

				tasklist[fsyst] += tasks

				tasks = []
				for name, nus in [('nu', 1), ('nonu', 0), ('nuunm', -1)]:
					hname = "SVLMass_%s_%s_%s" % ('tot', tag, name)
					finalsel = "%s*(%s&&BHadNeutrino==%d)"%(
						                 COMMONWEIGHT, sel, nus)
					tasks.append((hname, 'SVLMass', finalsel,
						          NBINS, XMIN, XMAX, MASSXAXISTITLE))
					hname_to_keys[hname] = (tag, name, 'tot')

				tasklist[fsyst] += tasks


			else:
				tasks = makeSystTask(tag, sel, fsyst, hname_to_keys)
				tasklist[fsyst] += tasks

	if not opt.cache:
		# print '  Will process the following tasks:'
		# for filename,tasks in sorted(tasklist.iteritems()):
		# 	print filename
		# 	for task in tasks:
		# 		print task
		# raw_input("Press any key to continue...")
		runTasks(systfiles, tasklist, opt, 'syst_histos')

		systhistos = {} # (tag, syst, comb) -> histo
		systhistos = gatherHistosFromFiles(tasklist, systfiles,
			                           os.path.join(opt.outDir, 'syst_histos'),
			                           hname_to_keys)


		cachefile = open(".svlsysthistos.pck", 'w')
		pickle.dump(systhistos, cachefile, pickle.HIGHEST_PROTOCOL)
		cachefile.close()


		# print "Wrote syst histos to cache file"
		# raw_input("press key")

	cachefile = open(".svlsysthistos.pck", 'r')
	systhistos = pickle.load(cachefile)
	print '>>> Read syst histos from cache (.svlsysthistos.pck)'
	cachefile.close()

	ROOT.gStyle.SetOptTitle(0)
	ROOT.gStyle.SetOptStat(0)
	ROOT.gROOT.SetBatch(1)


	for var,_,_,_,_ in CONTROLVARS:
		for sel,tag in [
			#('inclusive', 'Fully Inclusive'),
			#('inclusive_mrank1', 'Mass ranked, leading p_{T}'),
			#('inclusive_mrank1dr', 'Mass ranked, #DeltaR<2, leading p_{T}'),
			#('inclusive_drrank1dr', '#DeltaR ranked, #DeltaR<2, leading p_{T}'),
			('inclusive_optmrank', 'Optimized mass rank')]:
			try: makeControlPlot(systhistos, var, sel, tag, opt)
			except KeyError:
				print 'control plots for %s selection not found' % sel

	for tag,_,_ in SELECTIONS:
		if not 'inclusive' in tag : continue
		print "... processing %s"%tag

		# Make plot of mass with and without neutrino:
		# for comb in COMBINATIONS.keys():
		# plot = RatioPlot('neutrino_%s'%tag)
		# plot.rebin = 2
		# plot.add(systhistos[(tag,'nonu', 'tot')], 'Without neutrino')
		# plot.add(systhistos[(tag,'nu',   'tot')], 'With neutrino')
		# plot.add(systhistos[(tag,'nuunm','tot')], 'Unmatched')
		# plot.reference = systhistos[(tag,'nominal','tot')]
		# plot.tag = "Mass shape with and without neutrinos"
		# plot.subtag = SELNAMES[tag] + COMBNAMES['tot']
		# plot.ratiotitle = 'Ratio wrt Total'
		# plot.ratiorange = (0.7, 1.3)
		# plot.colors = [ROOT.kBlue-3, ROOT.kRed-4, ROOT.kOrange-3]
		# plot.show("neutrino_%s_%s"%(tag,'tot'),
		# 	      os.path.join(opt.outDir, 'syst_plots'))
		# plot.reset()

		for name, title, systs, colors, comb in SYSTPLOTS:
			print name, title, systs, colors, comb
			plot = RatioPlot('%s_%s'%(name,comb))
			plot.rebin = 2

			for syst in systs:
				try:
					plot.add(systhistos[(tag,syst,comb)], SYSTNAMES[syst])
				except:
					print 'failed to add',(tag,syst,comb),syst

			plot.tag = title
			subtag = SELNAMES[tag] + COMBNAMES[comb]
			plot.subtag = subtag
			plot.ratiotitle = 'Ratio wrt %s' % SYSTNAMES[systs[0]]
			plot.ratiorange = (0.85, 1.15)
			plot.colors = colors
			filename = "%s_%s"%(name,tag)
			if comb != 'tot': filename += '_%s'%comb
			plot.show(filename, os.path.join(opt.outDir,'syst_plots'))
			plot.reset()

		# Make top pt plot with both correct and wrong
		plot = RatioPlot('toppt_paper_cor_wro')
		plot.canvassize = (600,600)
		plot.tag = 'Top p_{T} mis-modeling'
		plot.rebin = 2
		plot.subtag = 'Inclusive channels'
		plot.ratiotitle = '1 / Nominal'
		plot.ratiorange = (0.85, 1.15)
		plot.legpos = (0.55, 0.30)
		plot.colors = [ROOT.kGreen+2, ROOT.kGreen-6, ROOT.kRed+2, ROOT.kRed-6]
		plot.add(systhistos[(tag,'nominal','cor')], 'Nominal (correct)',      includeInRatio=False)
		plot.add(systhistos[(tag,'toppt','cor')], 'p_{T} weighted (correct)', includeInRatio=True)
		plot.add(systhistos[(tag,'nominal','wro')], 'Nominal (wrong)',        includeInRatio=False)
		plot.add(systhistos[(tag,'toppt','wro')], 'p_{T} weighted (wrong)',   includeInRatio=True)
		plot.reference = [systhistos[(tag,'nominal','cor')], systhistos[(tag,'nominal','wro')]]

		plot.show('toppt_cor_wro_forpaper_%s'%tag, os.path.join(opt.outDir,'syst_plots'))
		plot.reset()

		# Make b fragmentation plot for paper
		plot = RatioPlot('bfrag_paper')
		plot.canvassize = (600,600)
		plot.tag = 'b fragmentation'
		plot.rebin = 2
		plot.subtag = 'Inclusive channels'
		plot.ratiotitle = '1 / Z2* rb LEP'
		plot.ratiorange = (0.85, 1.15)
		plot.legpos = (0.65, 0.15)
		plot.colors = [ROOT.kMagenta, ROOT.kMagenta+2, ROOT.kMagenta-9, ROOT.kAzure+7]
		plot.add(systhistos[(tag,'nominal', 'tot')], 'Z2* rb LEP', includeInRatio=False)
		plot.add(systhistos[(tag,'bfragdn', 'tot')], 'Z2* rb LEP soft')
		plot.add(systhistos[(tag,'bfragup', 'tot')], 'Z2* rb LEP hard')
		plot.add(systhistos[(tag,'bfragz2s','tot')], 'Z2* nominal')
		plot.reference = [systhistos[(tag,'nominal','tot')]]
		plot.show('bfrag_paper_%s'%tag, os.path.join(opt.outDir,'syst_plots'))
		plot.reset()


	# for tag,sel,seltag in SELECTIONS:
	# 	print 70*'-'
	# 	print '%-10s: %s' % (tag, sel)
	# 	fcor, fwro, funm = {}, {}, {}
	# 	for mass in sorted(massfiles.keys()):
	# 	# mass = 172.5
	# 		hists = masshistos[(tag, mass)]
	# 		n_tot, n_cor, n_wro, n_unm = (x.GetEntries() for x in hists)
	# 		fcor[mass] = 100.*(n_cor/float(n_tot))
	# 		fwro[mass] = 100.*(n_wro/float(n_tot))
	# 		funm[mass] = 100.*(n_unm/float(n_tot))
	# 		print ('  %5.1f GeV: %7d entries \t'
	# 			   '(%4.1f%% corr, %4.1f%% wrong, %4.1f%% unmatched)' %
	# 			   (mass, n_tot, fcor[mass], fwro[mass], funm[mass]))

	# 	oname = os.path.join(opt.outDir, 'fracvsmt_%s'%tag)
	# 	plotFracVsTopMass(fcor, fwro, funm, tag, seltag, oname)

	# print 112*'-'
	# print 'Estimated systematics (from a crude chi2 fit)'
	# print '%20s | %-15s | %-15s | %-15s | %-15s | %-15s' % (
	# 									 'selection', 'bfrag', 'scale',
	# 									 'toppt', 'matching', 'uecr')
	# for tag,_,_ in SELECTIONS:
	# 		sys.stdout.write("%20s | " % tag)
	# 		for syst in ['bfrag', 'scale', 'toppt', 'matching', 'uecr']:
	# 			err, chi2 = systematics[(tag,syst)]
	# 			sys.stdout.write('%4.1f (%4.1f GeV)' % (chi2*1e5, err))
	# 			# sys.stdout.write('%4.1f (%4.1f GeV)' % (chi2, err))
	# 			sys.stdout.write(' | ')
	# 		sys.stdout.write('\n')
	# print 112*'-'

	return 0
Пример #4
0
def main(args, opt):
    os.system('mkdir -p %s' % opt.outDir)
    masstrees, massfiles = getMassTrees(args[0], verbose=True)
    masspoints = sorted(list(set([mass for mass, _ in masstrees.keys()])))

    hname_to_keys = {}  # hname -> (tag, chan, mass, comb, [ntk1])

    tasklist = {}  ## (mass,chan) -> tasks
    for (mass, chan) in masstrees.keys():
        tasks = []
        for tag, sel, _ in SELECTIONS:

            #htag = ("%s_%5.1f_tt"%(tag,mass)).replace('.','')
            #if not chan == 'tt':
            htag = ("%s_%5.1f_%s" % (tag, mass, chan)).replace('.', '')

            for comb, combsel in COMBINATIONS.iteritems():
                hname = "SVLMass_%s_%s" % (comb, htag)
                finalsel = "%s*(%s&&%s)" % (COMMONWEIGHT, sel, combsel)
                tasks.append((hname, 'SVLMass', finalsel, NBINS, XMIN, XMAX,
                              MASSXAXISTITLE))
                hname_to_keys[hname] = (tag, chan, mass, comb)

                for ntk1, ntk2 in NTRKBINS:
                    tksel = "(SVNtrk>=%d && SVNtrk<%d)" % (ntk1, ntk2)
                    finalsel = "%s*(%s&&%s&&%s)" % (COMMONWEIGHT, sel, combsel,
                                                    tksel)
                    hname = "SVLMass_%s_%s_%d" % (comb, htag, ntk1)
                    tasks.append((hname, 'SVLMass', finalsel, NBINS, XMIN,
                                  XMAX, MASSXAXISTITLE))
                    hname_to_keys[hname] = (tag, chan, mass, comb, ntk1)

        tasklist[(mass, chan)] = tasks

    if not opt.cache:
        runTasks(massfiles, tasklist, opt, 'mass_histos')

        ## Retrieve the histograms from the individual files
        # (tag, chan, mass, comb)      -> histo
        # (tag, chan, mass, comb, ntk) -> histo
        masshistos = gatherHistosFromFiles(
            tasklist, massfiles, os.path.join(opt.outDir, 'mass_histos'),
            hname_to_keys)

        cachefile = open(".svlmasshistos.pck", 'w')
        pickle.dump(masshistos, cachefile, pickle.HIGHEST_PROTOCOL)
        cachefile.close()
        print 'Wrote .svlmasshistos.pck with all the mass histos'

    else:
        ## Read mass scan histos:
        cachefile = open(".svlmasshistos.pck", 'r')
        masshistos = pickle.load(cachefile)
        print '>>> Read mass scan histograms from cache (.svlmasshistos.pck)'
        cachefile.close()

    # ofi = ROOT.TFile(os.path.join(opt.outDir,'masshistos.root'),
    # 													   'recreate')
    # ofi.cd()

    # for key in masshistos.keys():
    # 	tag, chan, mass = key[0],key[1],key[2]
    # 	if not ofi.cd(tag):
    # 		outDir = ofi.mkdir(tag)
    # 		outDir.cd()

    # 	for comb in COMBINATIONS.keys():
    # 		masshistos[(tag,chan,mass,comb)].Write()
    # 		for ntk,_ in NTRKBINS:
    # 			masshistos[(tag,chan,mass,comb,ntk)].Write()
    # ofi.Write()
    # ofi.Close()

    ROOT.gStyle.SetOptTitle(0)
    ROOT.gStyle.SetOptStat(0)
    ROOT.gROOT.SetBatch(1)

    cachefile = open(".xsecweights.pck", 'r')
    xsecweights = pickle.load(cachefile)
    cachefile.close()
    print '>>> Read xsec weights from cache (.xsecweights.pck)'

    ## Scale all the histograms for the plotting:
    for key, hist in masshistos.iteritems():
        hist.Scale(LUMI * xsecweights[CHANMASSTOPROCNAME[(key[1], key[2])]])

    errorGetters = {}  # tag -> function(chi2) -> error
    systematics = {}  # (seltag, systname) -> error
    mass_scan_dir = os.path.join(opt.outDir, 'mass_scans')
    for tag, sel, seltag in SELECTIONS:
        print "... processing %s" % tag
        pairing = 'inclusive'
        try:
            pairing = tag.split('_', 1)[1]
        except IndexError:
            pass

        for chan in ['tt', 't', 'tbar', 'tW', 'tbarW']:
            # print "   %s channel" % chan
            ## Skip some useless combinations:
            chanTitle = chan
            if chanTitle == 'tt': chanTitle = 'ttbar'
            chanTitle = chanTitle.replace('tbar', '#bar{t}')
            if chan in ['t', 'tbar'] and ('ee' in tag or 'mm' in tag
                                          or 'em' in tag):
                continue
            if chan in ['tW', 'tbarW'] and tag in [
                    'e', 'm', 'eplus', 'eminus', 'mplus', 'mminus',
                    'e_optmrank', 'm_optmrank', 'eplus_optmrank',
                    'eminus_optmrank', 'mplus_optmrank', 'mminus_optmrank'
            ]:
                continue

            ratplot = RatioPlot('ratioplot')
            ratplot.normalized = False
            ratplot.ratiotitle = "Ratio wrt 172.5 GeV"
            ratplot.ratiorange = (0.5, 1.5)
            ratplot.rebin = 2

            reference = masshistos[(tag, chan, 172.5, 'tot')]
            ratplot.reference = reference

            for mass in masspoints:
                legentry = 'm_{t} = %5.1f GeV' % mass
                try:
                    histo = masshistos[(tag, chan, mass, 'tot')]
                    ratplot.add(histo, legentry)
                except KeyError:
                    pass
                # print "Can't find ", (tag,chan,mass,'tot')

            ratplot.tag = 'All combinations'
            ratplot.subtag = '%s %s' % (seltag, chanTitle)
            ratplot.show("massscan_%s_%s_tot" % (tag, chan), mass_scan_dir)

            # chi2s = ratplot.getChiSquares(rangex=FITRANGE)
            # chi2stofit = []
            # for legentry in sorted(chi2s.keys()):
            # 	chi2stofit.append((float(legentry[8:-4]), chi2s[legentry]))
            # errorGetters[tag] = fitChi2(chi2stofit,
            # 							tag=seltag,
            # 							oname=os.path.join(mass_scan_dir,
            # 						    "chi2_simple_fit_%s.pdf"%tag),
            # 							drawfit=False)
            ratplot.reset()

            ratplot.reference = masshistos[(tag, chan, 172.5, 'cor')]
            for mass in masspoints:
                legentry = 'm_{t} = %5.1f GeV' % mass
                try:
                    ratplot.add(masshistos[(tag, chan, mass, 'cor')], legentry)
                except KeyError:
                    pass
            ratplot.tag = 'Correct combinations'
            ratplot.subtag = '%s %s' % (seltag, chanTitle)
            ratplot.show("massscan_%s_%s_cor" % (tag, chan), mass_scan_dir)
            ratplot.reset()

            ratplot.reference = masshistos[(tag, chan, 172.5, 'wro')]
            for mass in masspoints:
                legentry = 'm_{t} = %5.1f GeV' % mass
                try:
                    ratplot.add(masshistos[(tag, chan, mass, 'wro')], legentry)
                except KeyError:
                    pass
            ratplot.tag = 'Wrong combinations'
            ratplot.subtag = '%s %s' % (seltag, chanTitle)
            ratplot.show("massscan_%s_%s_wro" % (tag, chan), mass_scan_dir)
            ratplot.reset()

            ratplot.reference = masshistos[(tag, chan, 172.5, 'unm')]
            for mass in masspoints:
                legentry = 'm_{t} = %5.1f GeV' % mass
                try:
                    ratplot.add(masshistos[(tag, chan, mass, 'unm')], legentry)
                except KeyError:
                    pass
            ratplot.tag = 'Unmatched combinations'
            ratplot.subtag = '%s %s' % (seltag, chanTitle)
            ratplot.show("massscan_%s_%s_unm" % (tag, chan), mass_scan_dir)
            ratplot.reset()

        ## ntkscan plot
        if 'inclusive' in tag:
            ntkmassplot = RatioPlot('ntkmassplot_%s' % tag)
            ntkmassplot.rebin = 2
            ntkmassplot.reference = [masshistos[(tag, 'tt', 172.5, 'tot')]]
            ntkmassplot.add(masshistos[(tag, 'tt', 172.5, 'tot')],
                            'Sum',
                            includeInRatio=False)
            for ntk1, ntk2 in NTRKBINS:
                title = "%d #leq N_{trk.} < %d" % (ntk1, ntk2)
                if ntk2 > 100:
                    title = "%d #leq N_{trk.}" % (ntk1)
                ntkmassplot.add(masshistos[(tag, 'tt', 172.5, 'tot', ntk1)],
                                title)
            ntkmassplot.colors = [
                ROOT.kOrange + 8, ROOT.kGreen + 3, ROOT.kGreen + 1,
                ROOT.kGreen, ROOT.kGreen - 10, ROOT.kYellow - 3,
                ROOT.kYellow - 5
            ]
            ntkmassplot.ratiorange = (0, 3.0)
            ntkmassplot.ratiotitle = "Ratio wrt Sum"
            ntkmassplot.tag = 'm_{t} = 172.5 GeV'
            ntkmassplot.subtag = '%s, %s' % (pairing, seltag)
            ntkmassplot.show("ntkscan_%s" % tag, opt.outDir)
            ntkmassplot.reset()

    #fractions
    for tag, sel, seltag in SELECTIONS:
        print 70 * '-'
        print '%-10s: %s %s' % (tag, sel, seltag)
        if not ('inclusive' in tag): continue
        fcor, fwro, funm = {}, {}, {}
        for mass, proc in sorted(massfiles.keys()):
            # mass = 172.5
            ncount = {}
            for comb in ['tot', 'cor', 'wro', 'unm']:
                hist = masshistos[(tag, proc, mass, comb)]
                ncount[comb] = hist.Integral()
            fcor[mass] = 100. * (ncount['cor'] / float(ncount['tot']))
            fwro[mass] = 100. * (ncount['wro'] / float(ncount['tot']))
            funm[mass] = 100. * (ncount['unm'] / float(ncount['tot']))
            print(
                '  %-6s %5.1f GeV: %7d entries \t'
                '(%4.1f%% corr, %4.1f%% wrong, %4.1f%% unmatched)' %
                (proc, mass, ncount['tot'], fcor[mass], fwro[mass],
                 funm[mass]))
        oname = os.path.join(opt.outDir, 'fracvsmt_%s' % tag)
        plotFracVsTopMass(fcor, fwro, funm, tag, seltag, oname)

    return 0
Пример #5
0
def main(args, opt):
	os.system('mkdir -p %s'%opt.outDir)
	masstrees, massfiles = getMassTrees(args[0], verbose=True)
	masspoints = sorted(list(set([mass for mass,_ in masstrees.keys()])))

	hname_to_keys = {} # hname -> (tag, chan, mass, comb, [ntk1])

	tasklist = {} ## (mass,chan) -> tasks
	for (mass,chan) in masstrees.keys():
		tasks = []
		for tag,sel,_ in SELECTIONS:

			#htag = ("%s_%5.1f_tt"%(tag,mass)).replace('.','')
			#if not chan == 'tt':
			htag = ("%s_%5.1f_%s"%(tag,mass,chan)).replace('.','')

			for comb,combsel in COMBINATIONS.iteritems():
				hname = "SVLMass_%s_%s" % (comb, htag)
				finalsel = "%s*(%s&&%s)"%(COMMONWEIGHT,sel,combsel)
				tasks.append((hname, 'SVLMass', finalsel,
							  NBINS, XMIN, XMAX, MASSXAXISTITLE))
				hname_to_keys[hname] = (tag, chan, mass, comb)

				for ntk1,ntk2 in NTRKBINS:
					tksel = "(SVNtrk>=%d && SVNtrk<%d)"%(ntk1,ntk2)
					finalsel = "%s*(%s&&%s&&%s)"%(COMMONWEIGHT, sel,
												  combsel,tksel)
					hname = "SVLMass_%s_%s_%d" % (comb, htag, ntk1)
					tasks.append((hname, 'SVLMass', finalsel,
								  NBINS, XMIN, XMAX, MASSXAXISTITLE))
					hname_to_keys[hname] = (tag, chan, mass, comb, ntk1)

		tasklist[(mass,chan)] = tasks

	if not opt.cache:
		runTasks(massfiles, tasklist, opt, 'mass_histos')

		## Retrieve the histograms from the individual files
		# (tag, chan, mass, comb)      -> histo
		# (tag, chan, mass, comb, ntk) -> histo
		masshistos = gatherHistosFromFiles(tasklist, massfiles,
						   os.path.join(opt.outDir,
								'mass_histos'),
						   hname_to_keys)

		cachefile = open(".svlmasshistos.pck", 'w')
		pickle.dump(masshistos, cachefile, pickle.HIGHEST_PROTOCOL)
		cachefile.close()
		print 'Wrote .svlmasshistos.pck with all the mass histos'

	else:
		## Read mass scan histos:
		cachefile = open(".svlmasshistos.pck", 'r')
		masshistos = pickle.load(cachefile)
		print '>>> Read mass scan histograms from cache (.svlmasshistos.pck)'
		cachefile.close()

	# ofi = ROOT.TFile(os.path.join(opt.outDir,'masshistos.root'),
	# 													   'recreate')
	# ofi.cd()

	# for key in masshistos.keys():
	# 	tag, chan, mass = key[0],key[1],key[2]
	# 	if not ofi.cd(tag):
	# 		outDir = ofi.mkdir(tag)
	# 		outDir.cd()

	# 	for comb in COMBINATIONS.keys():
	# 		masshistos[(tag,chan,mass,comb)].Write()
	# 		for ntk,_ in NTRKBINS:
	# 			masshistos[(tag,chan,mass,comb,ntk)].Write()
	# ofi.Write()
	# ofi.Close()

	ROOT.gStyle.SetOptTitle(0)
	ROOT.gStyle.SetOptStat(0)
	ROOT.gROOT.SetBatch(1)


	cachefile = open(".xsecweights.pck", 'r')
	xsecweights = pickle.load(cachefile)
	cachefile.close()
	print '>>> Read xsec weights from cache (.xsecweights.pck)'

	## Scale all the histograms for the plotting:
	for key, hist in masshistos.iteritems():
		hist.Scale(LUMI*xsecweights[CHANMASSTOPROCNAME[(key[1], key[2])]])


	errorGetters = {} # tag -> function(chi2) -> error
	systematics = {} # (seltag, systname) -> error
	mass_scan_dir = os.path.join(opt.outDir, 'mass_scans')
	for tag,sel,seltag in SELECTIONS:
		print "... processing %s"%tag
		pairing = 'inclusive'
		try: pairing = tag.split('_',1)[1]
		except IndexError: pass

		for chan in ['tt', 't', 'tbar', 'tW', 'tbarW']:
			# print "   %s channel" % chan
			## Skip some useless combinations:
			chanTitle=chan
			if chanTitle=='tt' : chanTitle='ttbar'
			chanTitle=chanTitle.replace('tbar','#bar{t}')
			if chan in ['t','tbar'] and ('ee' in tag or 'mm' in tag or 'em' in tag):
				continue
			if chan in ['tW','tbarW'] and tag in ['e', 'm',
							      'eplus','eminus', 'mplus','mminus',
							      'e_optmrank', 'm_optmrank',
							      'eplus_optmrank','eminus_optmrank', 'mplus_optmrank','mminus_optmrank']:
				continue

			ratplot = RatioPlot('ratioplot')
			ratplot.normalized = False
			ratplot.ratiotitle = "Ratio wrt 172.5 GeV"
			ratplot.ratiorange = (0.5, 1.5)
			ratplot.rebin = 2

			reference = masshistos[(tag,chan,172.5,'tot')]
			ratplot.reference = reference

			for mass in masspoints:
				legentry = 'm_{t} = %5.1f GeV' % mass
				try:
					histo = masshistos[(tag,chan,mass,'tot')]
					ratplot.add(histo, legentry)
				except KeyError: pass
					# print "Can't find ", (tag,chan,mass,'tot')


			ratplot.tag = 'All combinations'
			ratplot.subtag = '%s %s' % (seltag, chanTitle)
			ratplot.show("massscan_%s_%s_tot"%(tag,chan), mass_scan_dir)

			# chi2s = ratplot.getChiSquares(rangex=FITRANGE)
			# chi2stofit = []
			# for legentry in sorted(chi2s.keys()):
			# 	chi2stofit.append((float(legentry[8:-4]), chi2s[legentry]))
			# errorGetters[tag] = fitChi2(chi2stofit,
			# 							tag=seltag,
			# 							oname=os.path.join(mass_scan_dir,
			# 						    "chi2_simple_fit_%s.pdf"%tag),
			# 							drawfit=False)
			ratplot.reset()

			ratplot.reference = masshistos[(tag,chan,172.5,'cor')]
			for mass in masspoints:
				legentry = 'm_{t} = %5.1f GeV' % mass
				try: ratplot.add(masshistos[(tag,chan,mass,'cor')], legentry)
				except KeyError: pass
			ratplot.tag = 'Correct combinations'
			ratplot.subtag = '%s %s' % (seltag, chanTitle)
			ratplot.show("massscan_%s_%s_cor"%(tag,chan), mass_scan_dir)
			ratplot.reset()

			ratplot.reference = masshistos[(tag,chan,172.5,'wro')]
			for mass in masspoints:
				legentry = 'm_{t} = %5.1f GeV' % mass
				try: ratplot.add(masshistos[(tag,chan,mass,'wro')], legentry)
				except KeyError: pass
			ratplot.tag = 'Wrong combinations'
			ratplot.subtag = '%s %s' % (seltag, chanTitle)
			ratplot.show("massscan_%s_%s_wro"%(tag,chan), mass_scan_dir)
			ratplot.reset()

			ratplot.reference = masshistos[(tag,chan,172.5,'unm')]
			for mass in masspoints:
				legentry = 'm_{t} = %5.1f GeV' % mass
				try: ratplot.add(masshistos[(tag,chan,mass,'unm')], legentry)
				except KeyError: pass
			ratplot.tag = 'Unmatched combinations'
			ratplot.subtag = '%s %s' % (seltag, chanTitle)
			ratplot.show("massscan_%s_%s_unm"%(tag,chan), mass_scan_dir)
			ratplot.reset()


		## ntkscan plot
		if 'inclusive' in tag:
			ntkmassplot = RatioPlot('ntkmassplot_%s'%tag)
			ntkmassplot.rebin = 2
			ntkmassplot.reference = [masshistos[(tag, 'tt', 172.5, 'tot')]]
			ntkmassplot.add(masshistos[(tag, 'tt', 172.5, 'tot')], 'Sum', includeInRatio=False)
			for ntk1,ntk2 in NTRKBINS:
				title = "%d #leq N_{trk.} < %d" %(ntk1, ntk2)
				if ntk2 > 100:
					title = "%d #leq N_{trk.}" %(ntk1)
				ntkmassplot.add(masshistos[(tag, 'tt', 172.5, 'tot', ntk1)],
					            title)
			ntkmassplot.colors = [ROOT.kOrange+8,
			                      ROOT.kGreen+3, ROOT.kGreen+1,
								  ROOT.kGreen, ROOT.kGreen-10,
								  ROOT.kYellow-3, ROOT.kYellow-5]
			ntkmassplot.ratiorange = (0,3.0)
			ntkmassplot.ratiotitle = "Ratio wrt Sum"
			ntkmassplot.tag = 'm_{t} = 172.5 GeV'
			ntkmassplot.subtag = '%s, %s' %(pairing, seltag)
			ntkmassplot.show("ntkscan_%s"%tag, opt.outDir)
			ntkmassplot.reset()

	#fractions
	for tag,sel,seltag in SELECTIONS:
		print 70*'-'
	 	print '%-10s: %s %s' % (tag, sel,seltag)
		if not('inclusive' in tag): continue
	 	fcor, fwro, funm = {}, {}, {}
	 	for mass,proc in sorted(massfiles.keys()):
			# mass = 172.5
			ncount={}
			for comb in ['tot','cor','wro','unm']:
				hist = masshistos[(tag,proc, mass,comb)]
				ncount[comb]=hist.Integral()
			fcor[mass] = 100.*(ncount['cor']/float(ncount['tot']))
	 		fwro[mass] = 100.*(ncount['wro']/float(ncount['tot']))
	 		funm[mass] = 100.*(ncount['unm']/float(ncount['tot']))
	 		print ('  %-6s %5.1f GeV: %7d entries \t'
	 			   '(%4.1f%% corr, %4.1f%% wrong, %4.1f%% unmatched)' %
	 			   (proc, mass, ncount['tot'],
	 			   	fcor[mass], fwro[mass], funm[mass]))
		oname = os.path.join(opt.outDir, 'fracvsmt_%s'%tag)
		plotFracVsTopMass(fcor, fwro, funm, tag, seltag, oname)


	return 0
Пример #6
0
def main(args, options):
	os.system('mkdir -p %s'%options.outDir)
	try:
		treefiles = {} # procname -> filename
		for filename in os.listdir(args[0]):
			if not os.path.splitext(filename)[1] == '.root': continue
			procname = filename.split('_',1)[1][:-5]
			treefiles[procname] = os.path.join(args[0],filename)

	except OSError:
		print "Not a valid input directory: %s" % args[0]
		return -1

	except IndexError:
		print "Need to provide an input directory"
		return -1

	## Collect all the trees
	svltrees = {} # proc -> tree
	for proc in treefiles.keys():
		tfile = ROOT.TFile.Open(treefiles[proc], 'READ')
		if not filterUseless(treefiles[proc]): continue
		svltrees[proc] = tfile.Get(TREENAME)

	## Produce all the relevant histograms
	if not options.cached:
		masshistos = {}     # (selection tag, process) -> histo
		methistos  = {}     # (selection tag, process) -> histo
		fittertkhistos = {} # (selection tag, process) -> [h_ntk1, h_ntk2, ...]
		for tag,sel,_ in SELECTIONS:
			for proc, tree in svltrees.iteritems():
				if not filterUseless(treefiles[proc], sel): continue

				htag = ("%s_%s"%(tag, proc)).replace('.','')
				print ' ... processing %-30s %s htag=%s' % (proc, sel, htag)
				masshistos[(tag, proc)] = getHistoFromTree(tree, sel=sel,
					                               var='SVLMass',
		                                           hname="SVLMass_%s"%(htag),
		                                           titlex=MASSXAXISTITLE)

				methistos[(tag, proc)] =  getHistoFromTree(tree, sel=sel,
					                               var='MET',
		                                           hname="MET_%s"%(htag),
		                                           xmin=0,xmax=200,
		                                           titlex="Missing E_{T} [GeV]")

				fittertkhistos[(tag,proc)] = getNTrkHistos(tree, sel=sel,
									   tag=htag,
									   var='SVLMass',
									   titlex=MASSXAXISTITLE)

		cachefile = open(".svlqcdmasshistos.pck", 'w')
		pickle.dump(masshistos,     cachefile, pickle.HIGHEST_PROTOCOL)
		pickle.dump(methistos,      cachefile, pickle.HIGHEST_PROTOCOL)
		pickle.dump(fittertkhistos, cachefile, pickle.HIGHEST_PROTOCOL)
		cachefile.close()
	else:
		cachefile = open(".svlqcdmasshistos.pck", 'r')
		masshistos     = pickle.load(cachefile)
		methistos      = pickle.load(cachefile)
		fittertkhistos = pickle.load(cachefile)
		cachefile.close()


	#########################################################
	## Write out the histograms, make data/mc plots
	outputFileName = os.path.join(options.outDir,'qcd_DataMCHists.root')
	ofi = ROOT.TFile(outputFileName, 'recreate')
	ofi.cd()
	for hist in [h for h in masshistos.values() + methistos.values()]:
		hist.Write(hist.GetName())
	for hist in [h for hists in fittertkhistos.values() for h in hists]:
		hist.Write(hist.GetName())
	ofi.Write()
	ofi.Close()

	## Run the plotter to get scaled MET plots
	## Can then use those to subtract non-QCD backgrounds from data template
	## Overwrite some of the options
	options.filter = 'SVLMass,MET' ## only run SVLMass and MET plots
	# options.excludeProcesses = 'QCD'
	options.outFile = 'scaled_met_inputs.root'
	options.cutUnderOverFlow = True
	os.system('rm %s' % os.path.join(options.outDir, options.outFile))
	runPlotter(outputFileName, options)

	#########################################################
	## Build the actual templates from the single histograms
	templates = {} # selection tag -> template histo
	inputfile = openTFile(os.path.join(options.outDir, options.outFile))

	for tag,sel,_ in SELECTIONS:
		categories = ['MET', 'SVLMass']
		for x,_ in NTRKBINS:
			categories.append('SVLMass_tot_%d'%int(x))

		for category in categories:
			plotdirname = '%s_%s'%(category,tag)
			plotdir = inputfile.Get(plotdirname)
			h_bg = None
			h_data = None
			for tkey in plotdir.GetListOfKeys():
				key = tkey.GetName()
				if key.startswith('Graph_from'): continue
				if key.startswith('MC8TeV_QCD'): continue

				hist = inputfile.Get('%s/%s'%(plotdirname,key))
				if key.startswith('MC8TeV'):
					if not h_bg:
						h_bg = hist.Clone("%s_BGs" % tag)
					else:
						h_bg.Add(hist)

				if key.startswith('Data8TeV'):
					h_data = hist.Clone("%s_Data" % tag)

			## Determine a suitable output name
			histname = '%s_template'%tag
			if category == 'MET': histname = "%s_%s" % ('met',histname)
			if 'tot' in category:
				tkbin = int(category.split('_')[2])
				histname = "%s_%d" % (histname, tkbin)
			h_data_subtr = h_data.Clone(histname)

			## Now subtract the combined MC from the data
			h_data_subtr.Add(h_bg, -1)

			dicttag = tag
			if category == 'MET':
				dicttag = 'met_%s'%tag
			if '_tot_' in category:
				dicttag = '%s_%d' % (tag, tkbin)
			templates[dicttag] = h_data_subtr

	ofi = ROOT.TFile(os.path.join(options.outDir,'qcd_templates.root'),
		             'recreate')
	ofi.cd()
	for hist in templates.values(): hist.Write(hist.GetName())
	ofi.Write()
	ofi.Close()

	for key,hist in sorted(templates.iteritems()):
		print key


	#########################################################
	## Make a plot comparing the templates
	for tag,_,seltag in SELECTIONS:
		if not tag.endswith('_qcd'): continue
		templateplot = RatioPlot('qcdtemplates_%s'%tag)
		for key,hist in sorted(templates.iteritems()):
			if not tag in key: continue
			if key.startswith('met'): continue

			if key == tag:
				templateplot.add(hist, 'Inclusive')
				templateplot.reference = hist
			else:
				ntrkbin = int(key.rsplit('_',1)[1])
				templateplot.add(hist, 'N_{track} = %d'%ntrkbin)

		templateplot.tag = 'QCD templates'
		templateplot.subtag = seltag
		templateplot.tagpos    = (0.90, 0.85)
		templateplot.subtagpos = (0.90, 0.78)
		templateplot.legpos = (0.75, 0.25)
		templateplot.ratiotitle = 'Ratio wrt Inclusive'
		templateplot.extratext = '' #Work in Progress'
		templateplot.ratiorange = (0.2, 2.2)
		templateplot.colors = [ROOT.kBlack, ROOT.kBlue-8, ROOT.kAzure-2,
		                       ROOT.kCyan-3]
		templateplot.show("qcdtemplates_%s"%tag, options.outDir)
		templateplot.reset()


	return 0
Пример #7
0
def main(args, options):
    os.system('mkdir -p %s' % options.outDir)
    try:
        treefiles = {}  # procname -> filename
        for filename in os.listdir(args[0]):
            if not os.path.splitext(filename)[1] == '.root': continue
            procname = filename.split('_', 1)[1][:-5]
            treefiles[procname] = os.path.join(args[0], filename)

    except OSError:
        print "Not a valid input directory: %s" % args[0]
        return -1

    except IndexError:
        print "Need to provide an input directory"
        return -1

    ## Collect all the trees
    svltrees = {}  # proc -> tree
    for proc in treefiles.keys():
        tfile = ROOT.TFile.Open(treefiles[proc], 'READ')
        if not filterUseless(treefiles[proc]): continue
        svltrees[proc] = tfile.Get(TREENAME)

    ## Produce all the relevant histograms
    if not options.cached:
        masshistos = {}  # (selection tag, process) -> histo
        methistos = {}  # (selection tag, process) -> histo
        fittertkhistos = {
        }  # (selection tag, process) -> [h_ntk1, h_ntk2, ...]
        for tag, sel, _ in SELECTIONS:
            for proc, tree in svltrees.iteritems():
                if not filterUseless(treefiles[proc], sel): continue

                htag = ("%s_%s" % (tag, proc)).replace('.', '')
                print ' ... processing %-30s %s htag=%s' % (proc, sel, htag)
                masshistos[(tag, proc)] = getHistoFromTree(
                    tree,
                    sel=sel,
                    var='SVLMass',
                    hname="SVLMass_%s" % (htag),
                    titlex=MASSXAXISTITLE)

                methistos[(tag, proc)] = getHistoFromTree(
                    tree,
                    sel=sel,
                    var='MET',
                    hname="MET_%s" % (htag),
                    xmin=0,
                    xmax=200,
                    titlex="Missing E_{T} [GeV]")

                fittertkhistos[(tag,
                                proc)] = getNTrkHistos(tree,
                                                       sel=sel,
                                                       tag=htag,
                                                       var='SVLMass',
                                                       titlex=MASSXAXISTITLE)

        cachefile = open(".svlqcdmasshistos.pck", 'w')
        pickle.dump(masshistos, cachefile, pickle.HIGHEST_PROTOCOL)
        pickle.dump(methistos, cachefile, pickle.HIGHEST_PROTOCOL)
        pickle.dump(fittertkhistos, cachefile, pickle.HIGHEST_PROTOCOL)
        cachefile.close()
    else:
        cachefile = open(".svlqcdmasshistos.pck", 'r')
        masshistos = pickle.load(cachefile)
        methistos = pickle.load(cachefile)
        fittertkhistos = pickle.load(cachefile)
        cachefile.close()

    #########################################################
    ## Write out the histograms, make data/mc plots
    outputFileName = os.path.join(options.outDir, 'qcd_DataMCHists.root')
    ofi = ROOT.TFile(outputFileName, 'recreate')
    ofi.cd()
    for hist in [h for h in masshistos.values() + methistos.values()]:
        hist.Write(hist.GetName())
    for hist in [h for hists in fittertkhistos.values() for h in hists]:
        hist.Write(hist.GetName())
    ofi.Write()
    ofi.Close()

    ## Run the plotter to get scaled MET plots
    ## Can then use those to subtract non-QCD backgrounds from data template
    ## Overwrite some of the options
    options.filter = 'SVLMass,MET'  ## only run SVLMass and MET plots
    # options.excludeProcesses = 'QCD'
    options.outFile = 'scaled_met_inputs.root'
    options.cutUnderOverFlow = True
    os.system('rm %s' % os.path.join(options.outDir, options.outFile))
    runPlotter(outputFileName, options)

    #########################################################
    ## Build the actual templates from the single histograms
    templates = {}  # selection tag -> template histo
    inputfile = openTFile(os.path.join(options.outDir, options.outFile))

    for tag, sel, _ in SELECTIONS:
        categories = ['MET', 'SVLMass']
        for x, _ in NTRKBINS:
            categories.append('SVLMass_tot_%d' % int(x))

        for category in categories:
            plotdirname = '%s_%s' % (category, tag)
            plotdir = inputfile.Get(plotdirname)
            h_bg = None
            h_data = None
            for tkey in plotdir.GetListOfKeys():
                key = tkey.GetName()
                if key.startswith('Graph_from'): continue
                if key.startswith('MC8TeV_QCD'): continue

                hist = inputfile.Get('%s/%s' % (plotdirname, key))
                if key.startswith('MC8TeV'):
                    if not h_bg:
                        h_bg = hist.Clone("%s_BGs" % tag)
                    else:
                        h_bg.Add(hist)

                if key.startswith('Data8TeV'):
                    h_data = hist.Clone("%s_Data" % tag)

            ## Determine a suitable output name
            histname = '%s_template' % tag
            if category == 'MET': histname = "%s_%s" % ('met', histname)
            if 'tot' in category:
                tkbin = int(category.split('_')[2])
                histname = "%s_%d" % (histname, tkbin)
            h_data_subtr = h_data.Clone(histname)

            ## Now subtract the combined MC from the data
            h_data_subtr.Add(h_bg, -1)

            dicttag = tag
            if category == 'MET':
                dicttag = 'met_%s' % tag
            if '_tot_' in category:
                dicttag = '%s_%d' % (tag, tkbin)
            templates[dicttag] = h_data_subtr

    ofi = ROOT.TFile(os.path.join(options.outDir, 'qcd_templates.root'),
                     'recreate')
    ofi.cd()
    for hist in templates.values():
        hist.Write(hist.GetName())
    ofi.Write()
    ofi.Close()

    for key, hist in sorted(templates.iteritems()):
        print key

    #########################################################
    ## Make a plot comparing the templates
    for tag, _, seltag in SELECTIONS:
        if not tag.endswith('_qcd'): continue
        templateplot = RatioPlot('qcdtemplates_%s' % tag)
        for key, hist in sorted(templates.iteritems()):
            if not tag in key: continue
            if key.startswith('met'): continue

            if key == tag:
                templateplot.add(hist, 'Inclusive')
                templateplot.reference = hist
            else:
                ntrkbin = int(key.rsplit('_', 1)[1])
                templateplot.add(hist, 'N_{track} = %d' % ntrkbin)

        templateplot.tag = 'QCD templates'
        templateplot.subtag = seltag
        templateplot.tagpos = (0.90, 0.85)
        templateplot.subtagpos = (0.90, 0.78)
        templateplot.legpos = (0.75, 0.25)
        templateplot.ratiotitle = 'Ratio wrt Inclusive'
        templateplot.extratext = ''  #Work in Progress'
        templateplot.ratiorange = (0.2, 2.2)
        templateplot.colors = [
            ROOT.kBlack, ROOT.kBlue - 8, ROOT.kAzure - 2, ROOT.kCyan - 3
        ]
        templateplot.show("qcdtemplates_%s" % tag, options.outDir)
        templateplot.reset()

    return 0
Пример #8
0
def main(args, opt):
    os.system('mkdir -p %s' % opt.outDir)
    systfiles = {}  # procname -> filename
    try:
        for fname in os.listdir(os.path.join(args[0], 'syst')):
            if not os.path.splitext(fname)[1] == '.root': continue
            for syst, _, systfile, _ in SYSTSFROMFILES:
                if fname in systfile:
                    systfiles[syst] = [os.path.join(args[0], 'syst', fname)]

        # Get the split nominal files
        systfiles['nominal'] = []
        for fname in os.listdir(os.path.join(args[0], 'Chunks')):
            if not os.path.splitext(fname)[1] == '.root': continue
            isdata, procname, splitno = resolveFilename(fname)
            if not procname == 'TTJets_MSDecays_172v5': continue
            if not splitno: continue  # file is split

            systfiles['nominal'].append(os.path.join(args[0], 'Chunks', fname))
        if len(systfiles['nominal']) < 20:
            print "ERROR >>> Missing files for split nominal sample?"
            return -1

    except IndexError:
        print "Please provide a valid input directory"
        exit(-1)

    hname_to_keys = {}  # hname -> (tag, syst, comb)
    tasklist = {}  # treefile -> tasklist

    for fsyst in systfiles.keys():
        if not fsyst in tasklist: tasklist[fsyst] = []
        for tag, sel, _ in SELECTIONS:
            if fsyst == 'nominal':
                for syst, _, weight, combs in SYSTSFROMWEIGHTS:
                    tasks = makeSystTask(tag,
                                         sel,
                                         syst,
                                         hname_to_keys,
                                         weight=weight,
                                         combs=combs)
                    tasklist[fsyst] += tasks

                tasks = []
                for comb, combsel in COMBINATIONS.iteritems():
                    for var, nbins, xmin, xmax, titlex in CONTROLVARS:
                        hname = "%s_%s_%s" % (var, comb, tag)
                        finalsel = "%s*(%s&&%s)" % (COMMONWEIGHT, sel, combsel)
                        tasks.append(
                            (hname, var, finalsel, nbins, xmin, xmax, titlex))
                        hname_to_keys[hname] = (tag, var, comb)

                tasklist[fsyst] += tasks

                tasks = []
                for name, nus in [('nu', 1), ('nonu', 0), ('nuunm', -1)]:
                    hname = "SVLMass_%s_%s_%s" % ('tot', tag, name)
                    finalsel = "%s*(%s&&BHadNeutrino==%d)" % (COMMONWEIGHT,
                                                              sel, nus)
                    tasks.append((hname, 'SVLMass', finalsel, NBINS, XMIN,
                                  XMAX, MASSXAXISTITLE))
                    hname_to_keys[hname] = (tag, name, 'tot')

                tasklist[fsyst] += tasks

            else:
                tasks = makeSystTask(tag, sel, fsyst, hname_to_keys)
                tasklist[fsyst] += tasks

    if not opt.cache:
        # print '  Will process the following tasks:'
        # for filename,tasks in sorted(tasklist.iteritems()):
        # 	print filename
        # 	for task in tasks:
        # 		print task
        # raw_input("Press any key to continue...")
        runTasks(systfiles, tasklist, opt, 'syst_histos')

        systhistos = {}  # (tag, syst, comb) -> histo
        systhistos = gatherHistosFromFiles(
            tasklist, systfiles, os.path.join(opt.outDir, 'syst_histos'),
            hname_to_keys)

        cachefile = open(".svlsysthistos.pck", 'w')
        pickle.dump(systhistos, cachefile, pickle.HIGHEST_PROTOCOL)
        cachefile.close()

        # print "Wrote syst histos to cache file"
        # raw_input("press key")

    cachefile = open(".svlsysthistos.pck", 'r')
    systhistos = pickle.load(cachefile)
    print '>>> Read syst histos from cache (.svlsysthistos.pck)'
    cachefile.close()

    ROOT.gStyle.SetOptTitle(0)
    ROOT.gStyle.SetOptStat(0)
    ROOT.gROOT.SetBatch(1)

    for var, _, _, _, _ in CONTROLVARS:
        for sel, tag in [
                #('inclusive', 'Fully Inclusive'),
                #('inclusive_mrank1', 'Mass ranked, leading p_{T}'),
                #('inclusive_mrank1dr', 'Mass ranked, #DeltaR<2, leading p_{T}'),
                #('inclusive_drrank1dr', '#DeltaR ranked, #DeltaR<2, leading p_{T}'),
            ('inclusive_optmrank', 'Optimized mass rank')
        ]:
            try:
                makeControlPlot(systhistos, var, sel, tag, opt)
            except KeyError:
                print 'control plots for %s selection not found' % sel

    for tag, _, _ in SELECTIONS:
        if not 'inclusive' in tag: continue
        print "... processing %s" % tag

        # Make plot of mass with and without neutrino:
        # for comb in COMBINATIONS.keys():
        # plot = RatioPlot('neutrino_%s'%tag)
        # plot.rebin = 2
        # plot.add(systhistos[(tag,'nonu', 'tot')], 'Without neutrino')
        # plot.add(systhistos[(tag,'nu',   'tot')], 'With neutrino')
        # plot.add(systhistos[(tag,'nuunm','tot')], 'Unmatched')
        # plot.reference = systhistos[(tag,'nominal','tot')]
        # plot.tag = "Mass shape with and without neutrinos"
        # plot.subtag = SELNAMES[tag] + COMBNAMES['tot']
        # plot.ratiotitle = 'Ratio wrt Total'
        # plot.ratiorange = (0.7, 1.3)
        # plot.colors = [ROOT.kBlue-3, ROOT.kRed-4, ROOT.kOrange-3]
        # plot.show("neutrino_%s_%s"%(tag,'tot'),
        # 	      os.path.join(opt.outDir, 'syst_plots'))
        # plot.reset()

        for name, title, systs, colors, comb in SYSTPLOTS:
            print name, title, systs, colors, comb
            plot = RatioPlot('%s_%s' % (name, comb))
            plot.rebin = 2

            for syst in systs:
                try:
                    plot.add(systhistos[(tag, syst, comb)], SYSTNAMES[syst])
                except:
                    print 'failed to add', (tag, syst, comb), syst

            plot.tag = title
            subtag = SELNAMES[tag] + COMBNAMES[comb]
            plot.subtag = subtag
            plot.ratiotitle = 'Ratio wrt %s' % SYSTNAMES[systs[0]]
            plot.ratiorange = (0.85, 1.15)
            plot.colors = colors
            filename = "%s_%s" % (name, tag)
            if comb != 'tot': filename += '_%s' % comb
            plot.show(filename, os.path.join(opt.outDir, 'syst_plots'))
            plot.reset()

        # Make top pt plot with both correct and wrong
        plot = RatioPlot('toppt_paper_cor_wro')
        plot.canvassize = (600, 600)
        plot.tag = 'Top quark p_{T} mismodeling'
        plot.rebin = 2
        plot.subtag = 'Inclusive channels'
        plot.tagpos = (0.92, 0.85)
        plot.subtagpos = (0.92, 0.78)
        plot.titlex = 'm_{svl} [GeV]'
        plot.ratiotitle = '1 / Nominal'
        # plot.ratiorange = (0.85, 1.15)
        plot.ratiorange = (0.92, 1.08)
        plot.legpos = (0.55, 0.38)
        plot.ratioydivisions = 405
        plot.colors = [
            ROOT.kGreen + 2, ROOT.kGreen - 6, ROOT.kRed + 2, ROOT.kRed - 6
        ]
        plot.add(systhistos[(tag, 'nominal', 'cor')],
                 'Nominal (correct)',
                 includeInRatio=False)
        plot.add(systhistos[(tag, 'toppt', 'cor')],
                 'p_{T} weighted (correct)',
                 includeInRatio=True)
        plot.add(systhistos[(tag, 'nominal', 'wro')],
                 'Nominal (wrong)',
                 includeInRatio=False)
        plot.add(systhistos[(tag, 'toppt', 'wro')],
                 'p_{T} weighted (wrong)',
                 includeInRatio=True)
        plot.reference = [
            systhistos[(tag, 'nominal', 'cor')],
            systhistos[(tag, 'nominal', 'wro')]
        ]

        plot.show('toppt_cor_wro_forpaper_%s' % tag,
                  os.path.join(opt.outDir, 'syst_plots'))
        plot.reset()

        # Make b fragmentation plot for paper
        plot = RatioPlot('bfrag_paper')
        plot.canvassize = (600, 600)
        plot.tag = 'b fragmentation'
        plot.titlex = 'm_{svl} [GeV]'
        plot.rebin = 2
        plot.subtag = 'Inclusive channels'
        plot.tagpos = (0.92, 0.85)
        plot.subtagpos = (0.92, 0.78)
        plot.ratiotitle = '1 / Z2* #it{r}_{b} LEP'
        # plot.ratiorange = (0.85, 1.15)
        plot.ratiorange = (0.92, 1.08)
        plot.legpos = (0.65, 0.20)
        plot.ratioydivisions = 405
        plot.colors = [
            ROOT.kMagenta, ROOT.kMagenta + 2, ROOT.kMagenta - 9,
            ROOT.kAzure + 7
        ]
        plot.add(systhistos[(tag, 'nominal', 'tot')],
                 'Z2* #it{r}_{b} LEP',
                 includeInRatio=False)
        plot.add(systhistos[(tag, 'bfragdn', 'tot')],
                 'Z2* #it{r}_{b} LEP soft')
        plot.add(systhistos[(tag, 'bfragup', 'tot')],
                 'Z2* #it{r}_{b} LEP hard')
        plot.add(systhistos[(tag, 'bfragz2s', 'tot')], 'Z2* nominal')
        plot.reference = [systhistos[(tag, 'nominal', 'tot')]]
        plot.show('bfrag_paper_%s' % tag, os.path.join(opt.outDir,
                                                       'syst_plots'))
        plot.reset()

    # for tag,sel,seltag in SELECTIONS:
    # 	print 70*'-'
    # 	print '%-10s: %s' % (tag, sel)
    # 	fcor, fwro, funm = {}, {}, {}
    # 	for mass in sorted(massfiles.keys()):
    # 	# mass = 172.5
    # 		hists = masshistos[(tag, mass)]
    # 		n_tot, n_cor, n_wro, n_unm = (x.GetEntries() for x in hists)
    # 		fcor[mass] = 100.*(n_cor/float(n_tot))
    # 		fwro[mass] = 100.*(n_wro/float(n_tot))
    # 		funm[mass] = 100.*(n_unm/float(n_tot))
    # 		print ('  %5.1f GeV: %7d entries \t'
    # 			   '(%4.1f%% corr, %4.1f%% wrong, %4.1f%% unmatched)' %
    # 			   (mass, n_tot, fcor[mass], fwro[mass], funm[mass]))

    # 	oname = os.path.join(opt.outDir, 'fracvsmt_%s'%tag)
    # 	plotFracVsTopMass(fcor, fwro, funm, tag, seltag, oname)

    # print 112*'-'
    # print 'Estimated systematics (from a crude chi2 fit)'
    # print '%20s | %-15s | %-15s | %-15s | %-15s | %-15s' % (
    # 									 'selection', 'bfrag', 'scale',
    # 									 'toppt', 'matching', 'uecr')
    # for tag,_,_ in SELECTIONS:
    # 		sys.stdout.write("%20s | " % tag)
    # 		for syst in ['bfrag', 'scale', 'toppt', 'matching', 'uecr']:
    # 			err, chi2 = systematics[(tag,syst)]
    # 			sys.stdout.write('%4.1f (%4.1f GeV)' % (chi2*1e5, err))
    # 			# sys.stdout.write('%4.1f (%4.1f GeV)' % (chi2, err))
    # 			sys.stdout.write(' | ')
    # 		sys.stdout.write('\n')
    # print 112*'-'

    return 0