def initCache(self, cacheDir="systematics"): logger.info("Initializing cache for %s in directory %s"%(self.name, cacheDir)) if cacheDir: self.cacheDir = os.path.join(cache_directory, cacheDir) try: os.makedirs(cacheDir) except: pass cacheDirName = os.path.join(cacheDir, self.name) self.cache = MergingDirDB(cacheDirName) if not self.cache: raise Exeption("Cache not initiated!") if self.name.count("DD"): helperCacheDirName = os.path.join(cacheDir, self.name+"_helper") self.helperCache = MergingDirDB(helperCacheDirName) if not self.helperCache: raise histoHelperCacheDirName = os.path.join(cacheDir, self.name+"_histo") self.histoHelperCache = MergingDirDB(histoHelperCacheDirName) if not self.histoHelperCache: raise tfCacheDirName = os.path.join(cacheDir, self.name+"_tf") self.tfCache = MergingDirDB(tfCacheDirName) if not self.tfCache: raise elif self.name.count("had"): helperCacheDirName = os.path.join(cacheDir, "had_helper") self.helperCache = MergingDirDB(helperCacheDirName) if not self.helperCache: raise else: self.helperCache=None self.tfCache=None else: self.cache=None self.helperCache=None self.tfCache=None
def initCache(self, cacheDir="dataObs"): if cacheDir: self.cacheDir = os.path.join(cache_directory, cacheDir) try: os.makedirs(cacheDir) except: pass cacheDirName = os.path.join(cacheDir, self.name) self.cache = MergingDirDB(cacheDirName) if not self.cache: raise else: self.cache = None
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "True" #always false for QCD estimate if args.year == 2016: from TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import * mc = all_noQCD #all_mc data_sample = Run2016 elif args.year == 2017: from TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import * mc = all_noQCD #all_mc data_sample = Run2017 elif args.year == 2018:
# Text on the plots def drawObjects( lumi_scale ): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [ (0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line ] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", "all", args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"]="False" #always false for QCD estimat from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import * data2016 = Run2016 from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import * data2017 = Run2017 from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import * data2018 = Run2018 lumi_scale = (data2016.lumi + data2017.lumi + data2018.lumi) * 0.001 filterCutData = getFilterCut( 2016, isData=True, skipBadChargedCandidate=True ) data2016.setSelectionString( [filterCutData, "reweightHEM>0", cutInterpreter.cutString( args.mode )] )
if args.binning[0] > 1: xRange = np.linspace( args.binning[1], args.binning[2], int(args.binning[0]), endpoint=False) else: xRange = [ 0.5 * ( args.binning[2] - args.binning[1] ) ] # Samples from TTXPheno.samples.hepmc_samples_11_06 import * hepSample = ttbarZ if args.sample == "ttZ" else ttbar hepSample.root_samples_dict = { name:sample for name, sample in hepSample.root_samples_dict.iteritems() if name.startswith(args.pdf+"_") or name == "PP"} baseDir = os.path.join( cache_directory, "hepmc", "limits" ) if not os.path.exists( baseDir ): os.makedirs( baseDir ) cacheFileName = os.path.join( baseDir, "calculatedLimits" ) limitCache = MergingDirDB( cacheFileName ) sample_directory = hepSample.name if args.small: sample_directory += "_small" addon = [] #save data file filename = '_'.join( ['hepMCnll', args.sample ] + map( str, args.binning ) + [ args.selection ] + addon ) + '.data' def getHiggsWeight( c ): sigmaC = (1-c)**2*hepSample.samples_dict['PP'].xSection + \ (1-c)*c*hepSample.samples_dict[args.pdf+'_GH'].xSection + \ (1-c)*c*hepSample.samples_dict[args.pdf+'_HG'].xSection + \ c**2*hepSample.samples_dict[args.pdf+'_HH'].xSection return sigmaC
from TTGammaEFT.Samples.genTuples_TTGamma_EFT_postProcessed import * eftSample = eval(args.sample) #settings for eft reweighting w = WeightInfo(eftSample.reweight_pkl) w.set_order(args.order) variables = w.variables def get_weight_string(parameters): return w.get_weight_string(**parameters) baseDir = os.path.join(cache_directory, "analysis", "eft") cacheFileName = os.path.join(baseDir, eftSample.name) cache = MergingDirDB(cacheFileName) parameters = allRegions[args.controlRegion]["parameters"] channels = allRegions[args.controlRegion]["channels"] photonSelection = not allRegions[args.controlRegion]["noPhotonCR"] allPhotonRegions = allRegions[args.controlRegion]["inclRegion"] + allRegions[ args.controlRegion]["regions"] if photonSelection else allRegions[ args.controlRegion]["regions"] setup = Setup(year=2016, checkOnly=args.checkOnly) setup = setup.sysClone(parameters=parameters) def wrapper(arg): r, channel, setup, (ctZ, ctZI, ctW, ctWI) = arg EFTparams = ["ctZ", str(ctZ), "ctZI", str(ctZI)] #, "ctW", str(ctW), "ctWI", str(ctWI) ]
selection = signalRegions[args.recoSelection]["lambda"] setup = Setup( year=args.year, photonSelection=False, checkOnly=True, runOnLxPlus=False) #photonselection always false for qcd estimate setup = setup.sysClone(parameters=allRegions[args.recoSelection]["parameters"]) recoselection = setup.selection("MC", channel="all", **setup.defaultParameters()) recoSelection = recoselection["prefix"] nGen, xminGen, xmaxGen = args.genBinning nReco, xminReco, xmaxReco = args.recoBinning cache_dir = os.path.join(cache_directory, "unfolding", str(args.year), "matrix") dirDB = MergingDirDB(cache_dir) if args.year == 2016: lumi_scale = 35.92 elif args.year == 2017: lumi_scale = 41.53 elif args.year == 2018: lumi_scale = 59.74 elif args.year == "RunII": lumi_scale = 35.92 + 41.53 + 59.74 if args.normalize: lumi_scale = 1. plot_directory_ = os.path.join(plot_directory, "unfolding", str(args.year), args.plot_directory, args.genSelection, args.recoSelection, args.mode) reconstructionBinning = [50, 0.6, 2] dresMatrix = {
def plotRegions(sorted=True): # get region histograms if args.year == "combined": hists_tmp = Results.getRegionHistos(postFit=args.postFit, plotBins=plotBins, nuisances=plotNuisances, addStatOnlyHistos=True, bkgSubstracted=args.bkgSubstracted, labelFormater=labelFormater) for i, dir in enumerate(Results.channels): if i == 0: hists = { key: hist.Clone(str(i) + dir + key) for key, hist in hists_tmp[dir].iteritems() if not args.plotNuisances or key not in plotNuisances } #copy.deepcopy(hists_tmp) if args.plotNuisances: for n in plotNuisances: hists.update({ n: { "up": hists_tmp[dir][n]["up"].Clone( str(i) + dir + n + "up"), "down": copy.deepcopy(hists_tmp[dir][n]["down"].Clone( str(i) + dir + n + "down")) } }) hists[n]["up"].legendText = hists_tmp[dir][n][ "up"].legendText hists[n]["up"].style = hists_tmp[dir][n]["up"].style hists[n]["down"].legendText = hists_tmp[dir][n][ "down"].legendText hists[n]["down"].style = hists_tmp[dir][n][ "down"].style else: for key, hist in hists_tmp[dir].iteritems(): if args.plotNuisances and key in plotNuisances: hists[key]["up"].Add( hist["up"].Clone(str(i) + dir + key + "up")) hists[key]["down"].Add( hist["down"].Clone(str(i) + dir + key + "down")) else: hists[key].Add(hist.Clone(str(i) + dir + key)) else: hists = Results.getRegionHistos(postFit=args.postFit, plotBins=plotBins, nuisances=plotNuisances, addStatOnlyHistos=True, bkgSubstracted=args.bkgSubstracted, labelFormater=labelFormater)["Bin0"] if args.plotNuisances and args.plotNuisances[0] == "total": hists["totalUnc"] = Results.sumNuisanceHistos(hists, addStatUnc=True, postFit=args.postFit) for i_n, ni in enumerate(plotNuisances): del hists[ni] error = [] for i in range(hists["totalUnc"]["up"].GetNbinsX()): print i + 1, hists["totalUnc"]["relUp"].GetBinContent( i + 1) - hists["total"].GetBinError(i + 1) > 0, abs( hists["totalUnc"]["relUp"].GetBinContent(i + 1) - hists["total"].GetBinError(i + 1) ), abs(hists["totalUnc"]["relUp"].GetBinContent(i + 1) - hists["total"].GetBinError(i + 1) ) / hists["total"].GetBinError(i + 1) error.append( abs(hists["totalUnc"]["relUp"].GetBinContent(i + 1) - hists["total"].GetBinError(i + 1)) / hists["total"].GetBinError(i + 1)) global max print "Max difference: %f, Mean difference: %f" % (max(error), np.mean(error)) differential = False ch = "all" xLabel = "" if args.substituteCard: subCard = args.substituteCard.split("_") if args.bkgSubstracted and args.substituteCard: hists = replaceHistoBinning(hists) differential = True ch = subCard[-1] minMax = 0.29 #0.19 if args.postFit else 0.9 if args.bkgSubstracted: minMax = 0.29 #0.19 if args.postFit else 0.9 ratioCenter = None boxes, ratio_boxes = getErrorBoxes(copy.copy(hists["signal"]), minMax, lineColor=ROOT.kOrange - 2, fillColor=ROOT.kOrange - 2, hashcode=1001, ratioCenter=ratioCenter) boxes_stat, ratio_boxes_stat = getErrorBoxes(copy.copy( hists["signal_stat"]), minMax, lineColor=ROOT.kAzure - 3, fillColor=ROOT.kAzure - 3, hashcode=1001, ratioCenter=ratioCenter) else: boxes, ratio_boxes = getUncertaintyBoxes( copy.copy(hists["total"]), minMax, lineColor=ROOT.kGray + 3, fillColor=ROOT.kGray + 3, hashcode=formatSettings(nBins)["hashcode"]) if args.postFit: boxes_stat, ratio_boxes_stat = getUncertaintyBoxes( copy.copy(hists["total_stat"]), minMax, lineColor=ROOT.kAzure - 3, fillColor=ROOT.kAzure - 3, hashcode=1001) hists["data"].style = styles.errorStyle(ROOT.kBlack) hists[ "data"].legendText = "data" if not args.bkgSubstracted else "bkg-sub. data (#color[61]{stat}, #color[92]{total} error, %s)" % ( ch.replace("mu", "#mu") if ch != "all" else "e+#mu") hists["data"].legendOption = "p" if args.bkgSubstracted else "p" if args.bkgSubstracted: hists["signal"].style = styles.lineStyle(ROOT.kOrange + 7, width=2, errors=False) hists[ "signal"].legendText = "tt#gamma SM prediction" # (detector level)" else: for h_key, h in hists.iteritems(): if "total" in h_key or h_key not in processes: continue hists[h_key].legendText = default_processes[h_key]["texName"] hists[h_key].style = styles.fillStyle( default_processes[h_key]["color"], errors=False) hists[h_key].LabelsOption("v", "X") # some settings and things like e.g. uncertainty boxes drawObjects_ = drawObjects( nBins=nBins, isData=(not args.expected), lumi_scale=lumi_scale, postFit=args.postFit, cardfile=args.substituteCard if args.substituteCard else args.cardfile, preliminary=args.preliminary) drawObjects_ += boxes if args.postFit: drawObjects_ += boxes_stat # if args.bkgSubstracted: drawObjects_ += boxes_stat drawObjects_ += drawDivisions(crLabel, misIDPOI=("misIDPOI" in args.cardfile)) drawObjects_ += drawPTDivisions(crLabel, ptLabels) histModifications = [] if not differential: histModifications += [ lambda h: h.GetYaxis().SetTitleSize( formatSettings(nBins)["textsize"]) ] histModifications += [ lambda h: h.GetYaxis().SetLabelSize( formatSettings(nBins)["ylabelsize"]) ] histModifications += [ lambda h: h.GetYaxis().SetTitleOffset( formatSettings(nBins)["textoffset"]) ] histModifications += [ setPTBinLabels(ptLabels, crName, fac=formatSettings(nBins)["offsetfactor"] * hists["total"].GetMaximum()) ] ratioHistModifications = [] if not differential: ratioHistModifications += [ lambda h: h.GetYaxis().SetTitleSize( formatSettings(nBins)["textsize"]) ] ratioHistModifications += [ lambda h: h.GetYaxis().SetLabelSize( formatSettings(nBins)["ylabelsize"]) ] ratioHistModifications += [ lambda h: h.GetYaxis().SetTitleOffset( formatSettings(nBins)["textoffset"]) ] ratioHistModifications += [ lambda h: h.GetXaxis().SetTitleSize( formatSettings(nBins)["textsize"]) ] ratioHistModifications += [ lambda h: h.GetXaxis().SetLabelSize( formatSettings(nBins)["xlabelsize"]) ] ratioHistModifications += [ lambda h: h.GetXaxis().SetLabelOffset(0.035) ] addon = [] if args.bkgSubstracted: addon += ["bkgSub"] if args.substituteCard: addon += ["rebinned"] + [cr for cr in subCard ] #if cr not in args.cardfile.split("_") ] if args.plotNuisances: addon += args.plotNuisances # plot name if args.plotRegions and args.plotChannels: plotName = "_".join( ["regions"] + addon + args.plotRegions + [ch for ch in args.plotChannels if not "tight" in ch]) elif args.plotRegions: plotName = "_".join(["regions"] + addon + args.plotRegions) elif args.plotChannels: plotName = "_".join( ["regions"] + addon + [ch for ch in args.plotChannels if not "tight" in ch]) else: plotName = "_".join(["regions"] + addon) if args.cacheHistogram: from Analysis.Tools.MergingDirDB import MergingDirDB from TTGammaEFT.Tools.user import cache_directory cache_dir = os.path.join(cache_directory, "unfolding", str(args.year), "bkgSubstracted", "expected" if args.expected else "observed") dirDB = MergingDirDB(cache_dir) if not dirDB: raise addon = [] if args.plotRegions: addon += args.plotRegions if args.plotChannels: addon += args.plotChannels systematics = [ sys for sys in Results.getPulls(postFit=True).keys() if not "prop" in sys ] # data histogram name = ["bkgSubtracted", args.substituteCard, args.cardfile, "data"] print "_".join(name + addon) dirDB.add("_".join(name + addon), hists["data"], overwrite=True) # bkg substracted total histogram (signal) with total error name = ["bkgSubtracted", args.substituteCard, args.cardfile, "signal"] print "_".join(name + addon) dirDB.add("_".join(name + addon), hists["signal"], overwrite=True) # bkg substracted total histogram (signal) with stat error name = [ "bkgSubtracted", args.substituteCard, args.cardfile, "signal_stat" ] print "_".join(name + addon) dirDB.add("_".join(name + addon), hists["signal_stat"], overwrite=True) # get histo list plots, ratioHistos = Results.getRegionHistoList( hists, processes=processes, noData=False, sorted=sorted and not args.bkgSubstracted, bkgSubstracted=args.bkgSubstracted, directory="dc_2016" if args.year == "combined" else "Bin0") if args.plotRegionPlot: plotting.draw( Plot.fromHisto( plotName, plots, texX="" if not differential else xLabel, texY="Observed - Background" if args.bkgSubstracted else "Number of Events", ), logX=False, logY=True, sorting=False, plot_directory=plotDirectory, legend=[(0.2, 0.86 if args.bkgSubstracted else formatSettings(nBins)["legylower"], 0.9, 0.9), formatSettings(nBins)["legcolumns"]] if not differential else (0.15, 0.80, 0.9, 0.9), widths={ "x_width": formatSettings(nBins)["padwidth"], "y_width": formatSettings(nBins)["padheight"], "y_ratio_width": formatSettings(nBins)["padratio"] } if not differential else {}, yRange=(0.7, hists["total"].GetMaximum() * formatSettings(nBins)["heightFactor"]) if not differential else "auto", ratio={ "yRange": (1 - minMax, 1 + minMax), "texY": "Data/Pred." if args.bkgSubstracted else "Data/MC", "histos": ratioHistos, "drawObjects": ratio_boxes + ratio_boxes_stat if args.postFit else ratio_boxes, "histModifications": ratioHistModifications }, drawObjects=drawObjects_ if not differential else drawObjectsDiff(lumi_scale) + boxes + boxes_stat, histModifications=histModifications, copyIndexPHP=True, extensions=["png", "pdf", "root"] if args.bkgSubstracted else ["png"], # pdfs are quite large for sorted histograms (disco plot) redrawHistos=args.bkgSubstracted, ) del hists
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "True" if args.year == 2016: import TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import Run2016 as data_sample elif args.year == 2017: import TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import Run2017 as data_sample elif args.year == 2018: import TTGammaEFT.Samples.nanoTuples_Autumn18_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import Run2018 as data_sample elif args.year == "RunII": import TTGammaEFT.Samples.nanoTuples_RunII_postProcessed as mc_samples
# Text on the plots def drawObjects( lumi_scale ): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [ (0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line ] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", "all", args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"]="False" #always false for QCD estimate from TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import * mc16 = all_noQCD_16 data16 = Run2016 from TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import * mc17 = all_noQCD_17 data17 = Run2017 from TTGammaEFT.Samples.nanoTuples_Autumn18_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import * mc18 = all_noQCD_18
args = argParser.parse_args() lumi_scale = 136.6 # Samples from TTXPheno.samples.hepmc_samples_11_06 import * hepSample = ttbarZ if args.sample == "ttZ" else ttbar hepSample.root_samples_dict = { name: sample for name, sample in hepSample.root_samples_dict.iteritems() if "HG" in name } baseDir = os.path.join(cache_directory, "hepmc", "limits") cacheFileName = os.path.join(baseDir, "calculatedLimits") limitCache = MergingDirDB(cacheFileName) res = {} res[68] = {} res[95] = {} for i, (pdf, val) in enumerate(hepSample.root_samples_dict.iteritems()): pdf = pdf.split("_")[0] pdfVal = float(pdf.split("-")[1]) print pdfVal if pdf.endswith("35"): continue if pdf.endswith("42"): continue if pdf.endswith("45"): continue sConfig = "_".join([args.sample, args.selection, pdf]) if not limitCache.contains(sConfig): continue
#cache_directory = "/scratch-cbe/users/lukas.lechner/TTGammaEFT/cache/" cache_directory = "/scratch-cbe/users/lukas.lechner/TTGammaEFT/cache_read/" hists = [ "SR3pPtUnfold", "SR3pAbsEtaUnfold", "SR3pdRUnfold", ] #year = 2016 year = "combined" cache_dir = os.path.join(cache_directory, "unfolding", str(year), "bkgSubstracted", "expected" if expected else "observed", "postFit", "noFreeze") dirDB = MergingDirDB(cache_dir) if year == "combined": years = [2016, 2017, 2018] else: years = [year] for h in hists: for y in years: if year == "combined": data_key = "bkgSubtracted_%s_addDYSF_addPtBinnedUnc_%s_%s_VG3_VG4p_misDY3_misDY4p_addDYSF_addPtBinnedUnc_data_%i" % ( h, h.replace("3p", "3"), h.replace("3p", "4p"), y) signal_key = "bkgSubtracted_%s_addDYSF_addPtBinnedUnc_%s_%s_VG3_VG4p_misDY3_misDY4p_addDYSF_addPtBinnedUnc_signal_%i" % ( h, h.replace("3p", "3"), h.replace("3p", "4p"), y) signal_stat_key = "bkgSubtracted_%s_addDYSF_addPtBinnedUnc_%s_%s_VG3_VG4p_misDY3_misDY4p_addDYSF_addPtBinnedUnc_signal_stat_%i" % ( h, h.replace("3p", "3"), h.replace("3p", "4p"), y) else:
"abs(PSWeight[%i])*LHEWeight_originalXWGTUP/Generator_weight" % i for i in ps_indices ] scale_variations = ["abs(LHEScaleWeight[%i])" % i for i in scale_indices] PDF_variations = ["abs(LHEPdfWeight[%i])" % i for i in pdf_indices] variations = PDF_variations + scale_variations + PS_variations + aS_variations results = {} scale_systematics = {} # Results DB for scale and PDF uncertainties cacheDir = os.path.join(cache_directory, "modelling", str(args.year), "inclusive" if args.notNormalized else "normalized") PDF_cache = MergingDirDB(os.path.join(cacheDir, "PDF")) scale_cache = MergingDirDB(os.path.join(cacheDir, "Scale")) PS_cache = MergingDirDB(os.path.join(cacheDir, "PS")) ISR_cache = MergingDirDB(os.path.join(cacheDir, "ISR")) FSR_cache = MergingDirDB(os.path.join(cacheDir, "FSR")) if not PDF_cache: raise if not scale_cache: raise if not PS_cache: raise if not ISR_cache: raise if not FSR_cache: raise def wrapper(arg): r, c, s, inclusive = arg print r, c, s.sys["reweight"], inclusive logger.debug("Calculating estimate for %s in region %s and channel %s" %
# Text on the plots def drawObjects( lumi_scale ): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [ (0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line ] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"]="False" #always false for QCD estimate if args.year == 2016: from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import * data_sample = Run2016 elif args.year == 2017: from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import * data_sample = Run2017 elif args.year == 2018: from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import * data_sample = Run2018 lumi_scale = data_sample.lumi * 0.001
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "False" #always false for QCD estimate if args.year == 2016: from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import * data_sample = Run2016 elif args.year == 2017: from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import * data_sample = Run2017 elif args.year == 2018: from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import * data_sample = Run2018 lumi_scale = data_sample.lumi * 0.001
line = (0.8, 0.95, "(13 TeV)") lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] if args.small: args.plot_directory += "_small" import TTGammaEFT.unfolding.settings as settings_module logger.info("Unfolding settings: %s", args.settings) settings = getattr(settings_module, args.settings) # database year_str = "_".join( settings.years) + ('_' + args.prefix if args.prefix is not None else '') cache_dir = os.path.join(cache_directory, "unfolding", year_str, "matrix") dirDB = MergingDirDB(cache_dir) # specifics from the arguments plot_directory_ = os.path.join(plot_directory, "unfolding", args.settings, year_str, args.plot_directory) cfg_key = (args.small, year_str, args.settings) read_variables = [ "weight/F", "year/I", "nPhotonGood/I", "nJetGood/I", "nBTagGood/I", "nLeptonTight/I", "nLeptonVetoIsoCorr/I", "nPhotonNoChgIsoNoSieie/I", "PhotonGood0_pt/F", "triggered/I", "overlapRemoval/I", "pTStitching/I", "GenPhotonATLASUnfold0_pt/F", "GenPhotonCMSUnfold0_pt/F", "nGenLeptonATLASUnfold/I", "nGenPhotonATLASUnfold/I", "nGenBJetATLASUnfold/I", "nGenJetsATLASUnfold/I", "nGenLeptonCMSUnfold/I", "nGenPhotonCMSUnfold/I", "nGenBJetCMSUnfold/I", "nGenJetsCMSUnfold/I", "reweightHEM/F", "reweightTrigger/F", "reweightL1Prefire/F",
class DataObservation(): def __init__(self, name, process, cacheDir=None): self.name = name self.process = process self.initCache(cacheDir) def initCache(self, cacheDir="dataObs"): if cacheDir: self.cacheDir = os.path.join(cache_directory, cacheDir) try: os.makedirs(cacheDir) except: pass cacheDirName = os.path.join(cacheDir, self.name) self.cache = MergingDirDB(cacheDirName) if not self.cache: raise else: self.cache = None def uniqueKey(self, region, channel, setup): ## this is used in MCBasedEstimate if hasattr(setup, "blinding"): return str(region), channel, json.dumps( setup.sys, sort_keys=True), json.dumps( setup.parameters, sort_keys=True), json.dumps(setup.lumi, sort_keys=True), setup.blinding else: return str(region), channel, json.dumps( setup.sys, sort_keys=True), json.dumps( setup.parameters, sort_keys=True), json.dumps(setup.lumi, sort_keys=True) # alias for cachedObservation to make it easier to call the same function as for the mc"s def cachedEstimate(self, region, channel, setup, signalAddon=None, save=True, overwrite=False, checkOnly=False): return self.cachedObservation(region, channel, setup, overwrite=overwrite, checkOnly=checkOnly) def cachedObservation(self, region, channel, setup, save=True, overwrite=False, checkOnly=False): key = self.uniqueKey(region, channel, setup) if (self.cache and self.cache.contains(key)) and not overwrite: res = self.cache.get(key) logger.debug("Loading cached %s result for %r : %r" % (self.name, key, res)) elif self.cache and not checkOnly: res = self.observation(region, channel, setup, overwrite) _res = self.cache.add(key, res, overwrite=True) logger.debug("Adding cached %s result for %r" % (self.name, key)) elif not checkOnly: res = self.observation(region, channel, setup, overwrite) else: res = u_float(-1, 0) return res if res >= 0 or checkOnly else u_float(0, 0) def writeToCache(self, region, channel, setup, value, signalAddon=None, save=True, overwrite=False, checkOnly=False): key = self.uniqueKey(region, channel, setup) if (self.cache and self.cache.contains(key)) and not overwrite: res = self.cache.get(key) if res.val != value.val: print "Warning, caches estimate not equal to input value: have %s, got %s" % ( res, value) logger.debug("Loading cached %s result for %r : %r" % (self.name, key, res)) elif self.cache and not checkOnly: _res = self.cache.add(key, value, overwrite=True) res = value logger.debug("Adding cached %s result for %r" % (self.name, key)) else: res = u_float(-1, 0) return res if res >= 0 or checkOnly else u_float(0, 0) def observation(self, region, channel, setup, overwrite): if setup.nJet == "3p": setup4p = setup.sysClone(parameters={"nJet": (4, -1)}) setup3 = setup.sysClone(parameters={"nJet": (3, 3)}) return sum([ self.cachedEstimate(region, channel, s, overwrite=overwrite) for s in [setup3, setup4p] ]) if channel == "all": return sum([ self.cachedEstimate(region, c, setup, overwrite=overwrite) for c in lepChannels ]) elif channel == "SFtight": return sum([ self.cachedEstimate(region, c, setup, overwrite=overwrite) for c in dilepChannels ]) else: preSelection = setup.preselection("Data", channel=channel) # cut = "&&".join([region.cutString(setup.sys['selectionModifier']), preSelection['cut']]) cut = "&&".join([region.cutString(), preSelection['cut']]) logger.debug("Using cut %s" % cut) weight = preSelection['weightStr'] if hasattr(setup, "blinding") and setup.blinding: weight += "*" + setup.blinding return u_float(**self.process.getYieldFromDraw( selectionString=cut, weightString=weight))
# "nLeptonVetoIsoCorr": "nLeptonVetoNoIso", "nLeptonTight": "nLeptonTightInvIso", "nMuonTight": "nMuonTightInvIso", "nElectronTight": "nElectronTightInvIso", "mLtight0Gamma": "mLinvtight0Gamma", "nPhotonGood": "nPhotonGoodInvLepIso", "nJetGood": "nJetGoodInvLepIso", "nBTagGood": "nBTagGoodInvLepIso", "mT": "mTinv", "m3": "m3inv", # "ht": "htinv", "LeptonTight0": "LeptonTightInvIso0", } cache_dir = os.path.join(cache_directory, "qcdTFHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise binning = [ 20, 0, 200 ] # Sample definition os.environ["gammaSkim"]="False" #always false for QCD estimate if args.year == 2016: import TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import Run2016 as data_sample elif args.year == 2017: import TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import Run2017 as data_sample elif args.year == 2018: import TTGammaEFT.Samples.nanoTuples_Autumn18_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import Run2018 as data_sample
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "False" #always false for QCD estimate if args.year == 2016: import TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import Run2016 as data_sample elif args.year == 2017: import TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import Run2017 as data_sample elif args.year == 2018: import TTGammaEFT.Samples.nanoTuples_Autumn18_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import Run2018 as data_sample elif args.year == "RunII": import TTGammaEFT.Samples.nanoTuples_RunII_postProcessed as mc_samples
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "False" #always false for QCD estimate if args.year == 2016: import TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed as mc_samples elif args.year == 2017: import TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed as mc_samples elif args.year == 2018: import TTGammaEFT.Samples.nanoTuples_Autumn18_private_semilep_postProcessed as mc_samples elif args.year == "RunII": import TTGammaEFT.Samples.nanoTuples_RunII_postProcessed as mc_samples all = mc_samples.all_noQCD
class SystematicEstimator: __metaclass__ = abc.ABCMeta def __init__(self, name, cacheDir=None): logger.info("Initializing Systematic Estimator for %s"%name) self.name = name self.initCache(cacheDir) self.processCut = None if "_gen" in name: self.processCut = "cat0" #"photoncat0" elif "_misID" in name: self.processCut = "cat2" #"photoncat2" elif "_had" in name: self.processCut = "cat134" #"photoncat134" elif "_prompt" in name: self.processCut = "cat02" #"photoncat02" elif "_np" in name: self.processCut = "cat134" #"photoncat134" elif "_hp" in name: self.processCut = "cat1" #"photoncat1" elif "_fake" in name: self.processCut = "cat3" #"photoncat3" elif "_PU" in name: self.processCut = "cat4" #"photoncat4" def initCache(self, cacheDir="systematics"): logger.info("Initializing cache for %s in directory %s"%(self.name, cacheDir)) if cacheDir: self.cacheDir = os.path.join(cache_directory, cacheDir) try: os.makedirs(cacheDir) except: pass cacheDirName = os.path.join(cacheDir, self.name) self.cache = MergingDirDB(cacheDirName) if not self.cache: raise Exeption("Cache not initiated!") if self.name.count("DD"): helperCacheDirName = os.path.join(cacheDir, self.name+"_helper") self.helperCache = MergingDirDB(helperCacheDirName) if not self.helperCache: raise histoHelperCacheDirName = os.path.join(cacheDir, self.name+"_histo") self.histoHelperCache = MergingDirDB(histoHelperCacheDirName) if not self.histoHelperCache: raise tfCacheDirName = os.path.join(cacheDir, self.name+"_tf") self.tfCache = MergingDirDB(tfCacheDirName) if not self.tfCache: raise elif self.name.count("had"): helperCacheDirName = os.path.join(cacheDir, "had_helper") self.helperCache = MergingDirDB(helperCacheDirName) if not self.helperCache: raise else: self.helperCache=None self.tfCache=None else: self.cache=None self.helperCache=None self.tfCache=None # For the datadriven subclasses which often need the same getYieldFromDraw we write those yields to a cache def yieldFromCache(self, setup, process, c, selectionString, weightString, overwrite=False): s = (process, c, selectionString, weightString) if self.helperCache and self.helperCache.contains(s) and not overwrite: return self.helperCache.get(s) else: yieldFromDraw = u_float(**setup.processes[process].getYieldFromDraw(selectionString, weightString)) if self.helperCache: self.helperCache.add(s, yieldFromDraw, overwrite=True) return yieldFromDraw # For the datadriven subclasses which often need the same mT histos we write those yields to a cache def histoFromCache(self, var, binning, setup, process, c, selectionString, weightString, overwrite=False): s = (var, "_".join(map(str,binning)), process, c, selectionString, weightString) if self.histoHelperCache and self.histoHelperCache.contains(s) and not overwrite: return self.histoHelperCache.get(s).Clone(process+c+var) else: histo = setup.processes[process].get1DHistoFromDraw( var, binning=binning, selectionString=selectionString, weightString=weightString, addOverFlowBin="upper" ) if self.histoHelperCache: self.histoHelperCache.add(s, histo.Clone(process+c+var), overwrite=True) return histo.Clone(process+c+var) def uniqueKey(self, region, channel, setup, signalAddon=None, qcdUpdates={}): sysForKey = setup.sys.copy() sysForKey["reweight"] = "TEMP" reweightKey = '["' + '", "'.join(sorted([i for i in setup.sys['reweight']])) + '"]' # little hack to preserve order of list when being dumped into json key = region, channel, json.dumps(sysForKey, sort_keys=True).replace('"TEMP"',reweightKey), json.dumps(setup.parameters, sort_keys=True), json.dumps(setup.lumi, sort_keys=True) if qcdUpdates: key += tuple(json.dumps(qcdUpdates, sort_keys=True)) if signalAddon: key += tuple(signalAddon) return key def replace(self, i, r): try: if i.count("reweight"): return i.replace(r[0], r[1]) else: return i except: return i def cachedEstimate(self, region, channel, setup, signalAddon=None, save=True, overwrite=False, checkOnly=False): key = self.uniqueKey(region, channel, setup, signalAddon=signalAddon) if (self.cache and self.cache.contains(key)) and not overwrite: res = self.cache.get(key) logger.debug( "Loading cached %s result for %r : %r"%(self.name, key, res) ) elif self.cache and not checkOnly: logger.debug( "Calculating %s result for %r"%(self.name, key) ) res = self._estimate( region, channel, setup, signalAddon=signalAddon, overwrite=overwrite ) _res = self.cache.add( key, res, overwrite=True ) logger.debug( "Adding cached %s result for %r : %r" %(self.name, key, res) ) elif not checkOnly: res = self._estimate( region, channel, setup, signalAddon=signalAddon, overwrite=overwrite) else: res = u_float(-1,0) return res if res >= 0 or checkOnly else u_float(0,0) def writeToCache(self, region, channel, setup, value, signalAddon=None, save=True, overwrite=False, checkOnly=False): key = self.uniqueKey(region, channel, setup, signalAddon=signalAddon) if (self.cache and self.cache.contains(key)) and not overwrite: res = self.cache.get(key) # if res.val != value.val: print "Warning, caches estimate not equal to input value: have %s, got %s"%(res, value) # logger.debug( "Loading cached %s result for %r : %r"%(self.name, key, res) ) elif self.cache and not checkOnly: _res = self.cache.add( key, value, overwrite=True ) res = value logger.debug( "Adding cached %s result for %r : %r" %(self.name, key, res) ) else: res = u_float(-1,0) return res if res >= 0 or checkOnly else u_float(0,0) def cachedTransferFactor(self, channel, setup, qcdUpdates=None, save=True, overwrite=False, checkOnly=False): key = self.uniqueKey("region", channel, setup, qcdUpdates=qcdUpdates) if (self.tfCache and self.tfCache.contains(key)) and not overwrite: res = self.tfCache.get(key) logger.debug( "Loading cached %s result for %r : %r"%(self.name, key, res) ) elif self.tfCache and not checkOnly: logger.debug( "Calculating %s result for %r"%(self.name, key) ) # res = self._dataDrivenTransferFactor( channel, setup, qcdUpdates=qcdUpdates, overwrite=overwrite ) res = self._fittedTransferFactor( channel, setup, qcdUpdates=qcdUpdates, overwrite=overwrite ) _res = self.tfCache.add( key, res, overwrite=True ) logger.debug( "Adding cached transfer factor for %r : %r" %(key, res) ) elif not checkOnly: # res = self._dataDrivenTransferFactor( channel, setup, qcdUpdates=qcdUpdates, overwrite=overwrite ) res = self._fittedTransferFactor( channel, setup, qcdUpdates=qcdUpdates, overwrite=overwrite ) else: res = u_float(-1,0) return res if res > 0 or checkOnly else u_float(0,0) def cachedQCDMCTransferFactor(self, channel, setup, qcdUpdates=None, save=True, overwrite=False, checkOnly=False): key = self.uniqueKey("regionQCDMC", channel, setup, qcdUpdates=qcdUpdates) if (self.tfCache and self.tfCache.contains(key)) and not overwrite: res = self.tfCache.get(key) logger.debug( "Loading cached %s result for %r : %r"%(self.name, key, res) ) elif self.tfCache and not checkOnly: logger.debug( "Calculating %s result for %r"%(self.name, key) ) # res = self._dataDrivenTransferFactor( channel, setup, qcdUpdates=qcdUpdates, overwrite=overwrite ) res = self._transferFactor( channel, setup, qcdUpdates=qcdUpdates, overwrite=overwrite ) _res = self.tfCache.add( key, res, overwrite=True ) logger.debug( "Adding cached transfer factor for %r : %r" %(key, res) ) elif not checkOnly: # res = self._dataDrivenTransferFactor( channel, setup, qcdUpdates=qcdUpdates, overwrite=overwrite ) res = self._transferFactor( channel, setup, qcdUpdates=qcdUpdates, overwrite=overwrite ) else: res = u_float(-1,0) return res if res > 0 or checkOnly else u_float(0,0) def cachedFakeFactor(self, region, channel, setup, overwrite=False, checkOnly=False): key = self.uniqueKey(region, channel, setup) if (self.helperCache and self.helperCache.contains(key)) and not overwrite: res = self.helperCache.get(key) logger.debug( "Loading cached %s result for %r : %r"%(self.name, key, res) ) elif self.helperCache and not checkOnly: logger.debug( "Calculating %s result for %r"%(self.name, key) ) res = self._dataDrivenFakeCorrectionFactor( region, channel, setup, overwrite=overwrite ) _res = self.helperCache.add( key, res, overwrite=True ) logger.debug( "Adding cached transfer factor for %r : %r" %(key, res) ) elif not checkOnly: res = self._dataDrivenFakeCorrectionFactor( region, channel, setup, overwrite=overwrite ) else: res = u_float(-1,0) return res if res > 0 or checkOnly else u_float(0,0) @abc.abstractmethod def _estimate(self, region, channel, setup, signalAddon=None, overwrite=False): """Estimate yield in "region" using setup""" return def _transferFactor(self, channel, setup, overwrite=False): """Estimate transfer factor for QCD in "region" using setup""" return def _dataDrivenTransferFactor(self, channel, setup, qcdUpdates=None, overwrite=False): """Estimate transfer factor for QCD in "region" using setup""" return def _fittedTransferFactor(self, channel, setup, qcdUpdates=None, overwrite=False): """Estimate transfer factor for QCD in "region" using setup""" return def _dataDrivenFakeCorrectionFactor(self, region, channel, setup, overwrite=False): """Estimate fake factor for hadronic fakes in "region" using setup""" return def TransferFactorStatistic(self, region, channel, setup): ref = self.cachedTransferFactor(channel, setup) up = u_float(ref.val + ref.sigma) down = u_float(ref.val - ref.sigma) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def TuneSystematic(self, region, channel, setup): up = self.cachedEstimate(region, channel, setup, signalAddon="TuneUp") down = self.cachedEstimate(region, channel, setup, signalAddon="TuneDown") ref = self.cachedEstimate(region, channel, setup) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def topPtSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightTopPt"]})) return abs((up-ref)/ref) if ref > 0 else up def ErdOnSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup, signalAddon="erdOn") return abs((up-ref)/ref) if ref > 0 else up def QCDbasedSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup, signalAddon="QCDbased") return abs((up-ref)/ref) if ref > 0 else up def GluonMoveSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup, signalAddon="GluonMove") return abs((up-ref)/ref) if ref > 0 else up def PUSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightPUUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightPUDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def EERSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"eResUp"})) down = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"eResDown"})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def EESSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"eScaleUp"})) down = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"eScaleDown"})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) # def MERSystematic(self, region, channel, setup): # ref = self.cachedEstimate(region, channel, setup) # up = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"muTotalUp"})) # down = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"muTotalDown"})) # return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def JERSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"jerUp"})) down = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"jerDown"})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def JECSystematic(self, region, channel, setup, jes="Total"): ref = self.cachedEstimate(region, channel, setup) if ref == 0: return u_float(0,0) up = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"jes%sUp"%jes})) down = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"jes%sDown"%jes})) unc = abs(0.5*(up-down)/ref) if unc.val == 0: uncUp = abs((ref-up)/ref) uncDown = abs((ref-down)/ref) unc = uncUp if uncUp.val >= uncDown.val else uncDown if unc.val == 0: return u_float(0,0) return unc def unclusteredSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"unclustEnUp"})) down = self.cachedEstimate(region, channel, setup.sysClone({"selectionModifier":"unclustEnDown"})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def L1PrefireSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightL1PrefireUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightL1PrefireDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def btaggingSFbSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightBTag_SF_b_Up"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightBTag_SF_b_Down"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def btaggingSFlSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightBTag_SF_l_Up"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightBTag_SF_l_Down"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def leptonSFSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def leptonSFStatSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFStatUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFStatDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def leptonSFSystSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFSystUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFSystDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def leptonTrackingSFSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightLeptonTrackingTightSFUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightLeptonTrackingTightSFDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def photonSFSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightPhotonSFUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightPhotonSFDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def photonSFAltSigSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightPhotonSFAltSigUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightPhotonSFAltSigDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def photonElectronVetoSFSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightPhotonElectronVetoSFUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightPhotonElectronVetoSFDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def triggerSystematic(self, region, channel, setup): ref = self.cachedEstimate(region, channel, setup) up = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightTriggerUp"]})) down = self.cachedEstimate(region, channel, setup.sysClone({"reweight":["reweightTriggerDown"]})) return abs(0.5*(up-down)/ref) if ref > 0 else u_float(0,0) def getBkgSysJobs(self, region, channel, setup): l = [ (region, channel, setup.sysClone({"reweight":["reweightTopPt"]}), None), (region, channel, setup.sysClone({"reweight":["reweightPUUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightPUDown"]}), None), (region, channel, setup.sysClone({"selectionModifier":"eScaleUp"}), None), (region, channel, setup.sysClone({"selectionModifier":"eScaleDown"}), None), (region, channel, setup.sysClone({"selectionModifier":"eResUp"}), None), (region, channel, setup.sysClone({"selectionModifier":"eResDown"}), None), # (region, channel, setup.sysClone({"selectionModifier":"muTotalUp"}), None), # (region, channel, setup.sysClone({"selectionModifier":"muTotalDown"}), None), (region, channel, setup.sysClone({"selectionModifier":"jerUp"}), None), (region, channel, setup.sysClone({"selectionModifier":"jerDown"}), None), # (region, channel, setup.sysClone({"selectionModifier":"jesTotalUp"}), None), # (region, channel, setup.sysClone({"selectionModifier":"jesTotalDown"}), None), # (region, channel, setup.sysClone({"selectionModifier":"unclustEnUp"}), None), # (region, channel, setup.sysClone({"selectionModifier":"unclustEnDown"}), None), (region, channel, setup.sysClone({"reweight":["reweightL1PrefireUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightL1PrefireDown"]}), None), (region, channel, setup.sysClone({"reweight":["reweightBTag_SF_b_Up"]}), None), (region, channel, setup.sysClone({"reweight":["reweightBTag_SF_b_Down"]}), None), (region, channel, setup.sysClone({"reweight":["reweightBTag_SF_l_Up"]}), None), (region, channel, setup.sysClone({"reweight":["reweightBTag_SF_l_Down"]}), None), (region, channel, setup.sysClone({"reweight":["reweightLeptonTrackingTightSFUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightLeptonTrackingTightSFDown"]}), None), (region, channel, setup.sysClone({"reweight":["reweightPhotonSFUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightPhotonSFDown"]}), None), (region, channel, setup.sysClone({"reweight":["reweightPhotonSFAltSigUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightPhotonSFAltSigDown"]}), None), (region, channel, setup.sysClone({"reweight":["reweightPhotonElectronVetoSFUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightPhotonElectronVetoSFDown"]}), None), (region, channel, setup.sysClone({"reweight":["reweightTriggerUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightTriggerDown"]}), None), (region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFStatUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFStatDown"]}), None), (region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFSystUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFSystDown"]}), None), (region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFUp"]}), None), (region, channel, setup.sysClone({"reweight":["reweightLeptonTightSFDown"]}), None), ] # JEC Tags, (standard is "Total") jesTags = ['FlavorQCD', 'RelativeBal', 'HF', 'BBEC1', 'EC2', 'Absolute', 'Absolute_%i'%setup.year, 'HF_%i'%setup.year, 'EC2_%i'%setup.year, 'RelativeSample_%i'%setup.year, 'BBEC1_%i'%setup.year] for jes in jesTags: l += [ (region, channel, setup.sysClone({"selectionModifier":"jes%sUp"%jes}), None), (region, channel, setup.sysClone({"selectionModifier":"jes%sDown"%jes}), None), ] return l def getSigSysJobs(self, region, channel, setup): # in case there is a difference, enter it here (originally for fastSim) l = self.getBkgSysJobs(region = region, channel = channel, setup = setup) l += [ (region, channel, setup, "TuneUp"), (region, channel, setup, "TuneDown"), (region, channel, setup, "erdOn"), (region, channel, setup, "QCDbased"), (region, channel, setup, "GluonMove"), ] return l def getTexName(self, channel, rootTex=True): try: name = self.texName except: try: name = self.process[channel].texName except: try: texNames = [self.process[c].texName for c in allChannels] # If all, only take texName if it is the same for all lepChannels if texNames.count(texNames[0]) == len(texNames): name = texNames[0] else: name = self.name except: name = self.name if not rootTex: name = "$" + name.replace("#","\\") + "$" # Make it tex format return name
if args.inclRegion: regionNames.append("incl") if args.misIDPOI: regionNames.append("misIDPOI") if args.dyPOI: regionNames.append("dyPOI") if args.wJetsPOI: regionNames.append("wJetsPOI") if args.ttPOI: regionNames.append("ttPOI") if args.useChannels: regionNames.append("_".join( [ch for ch in args.useChannels if not "tight" in ch])) baseDir = os.path.join(cache_directory, "analysis", str(args.year), "limits") limitDir = os.path.join(baseDir, "cardFiles", args.label, "expected" if args.expected else "observed") if not os.path.exists(limitDir): os.makedirs(limitDir) cacheFileName = os.path.join(baseDir, "calculatednll") nllCache = MergingDirDB(cacheFileName) print cacheFileName cacheFileName = os.path.join(baseDir, "calculatedLimits") limitCache = MergingDirDB(cacheFileName) cacheFileName = os.path.join(baseDir, "calculatedSignifs") signifCache = MergingDirDB(cacheFileName) cacheDir = os.path.join(cache_directory, "modelling", str(args.year)) cacheFileName = os.path.join(cacheDir, "Scale") scaleUncCache = MergingDirDB(cacheFileName) cacheFileName = os.path.join(cacheDir, "PDF") pdfUncCache = MergingDirDB(cacheFileName)
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "False" #always false for QCD estimate if args.year == 2016: from TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import * mc = [all_noQCD_16] data_sample = Run2016 elif args.year == 2017: from TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import * mc = [all_noQCD_17] data_sample = Run2017 elif args.year == 2018:
if args.uncorrVG: regionNames.append("uncorrVG") if args.splitScale: regionNames.append("splitScale") if args.noSystematics: regionNames.append("noSyst") if args.splitMisIDExt: regionNames.append("splitMisIDExt") if args.rSR: regionNames.append("rSR" + args.rSR) if args.parameters: # load and define the EFT sample from TTGammaEFT.Samples.genTuples_TTGamma_EFT_postProcessed import * eftSample = TTG_2WC_ref baseDir = os.path.join(cache_directory, "analysis", "COMBINED", "limits") baseDir = os.path.join(baseDir, "withbkg" if args.withbkg else "withoutbkg") cacheFileName = os.path.join(baseDir, "calculatednll") nllCache = MergingDirDB(cacheFileName) baseDir = os.path.join(cache_directory, "analysis", "eft") cacheFileName = os.path.join(baseDir, eftSample.name) yieldCache = MergingDirDB(cacheFileName) configlist = regionNames + EFTparams configlist.append("incl" if args.inclRegion else "diff") configlist.append("expected" if args.expected else "observed") sEFTConfig = "_".join(configlist) # if not args.overwrite and nllCache.contains( sEFTConfig ) and abs(nllCache.get(sEFTConfig)["nll0"])>0.1: sys.exit(0) years = [2016, 2017, 2018]
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "False" #always false for QCD estimate if args.year == 2016: from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import Run2016 as data_sample elif args.year == 2017: from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import Run2017 as data_sample elif args.year == 2018: from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import Run2018 as data_sample elif args.year == "RunII": from TTGammaEFT.Samples.nanoTuples_RunII_postProcessed import RunII as data_sample filterCutData = getFilterCut(args.year, isData=True,
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "False" #always false for QCD estimate if args.year == 2016: from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import * data_sample = Run2016 elif args.year == 2017: from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import * data_sample = Run2017 dataB = Run2017B dataC = Run2017C dataD = Run2017D dataE = Run2017E dataF = Run2017F
import RootTools.core.logger as logger_rt logger = logger.get_logger(args.logLevel, logFile=None) logger_rt = logger_rt.get_logger(args.logLevel, logFile=None) args.preliminary = True from Analysis.Tools.MergingDirDB import MergingDirDB from TTGammaEFT.Tools.user import cache_directory year = str(args.year) if args.plotYear: year += "_" + str(args.plotYear) cache_dir = os.path.join(cache_directory, "unfoldingTest", str(args.year), "bkgSubstracted" if args.bkgSubstracted else "total", "expected" if args.expected else "observed", "postFit" if args.postFit else "preFit") print cache_dir dirDB = MergingDirDB(cache_dir) if not dirDB: raise addons = [] if args.plotRegions: addons += args.plotRegions if args.plotChannels: addons += args.plotChannels if args.year == "combined" and not args.plotYear: years = ["2016", "2017", "2018"] elif args.year == "combined" and args.plotYear: years = [args.plotYear] else: years = [None] for i, year in enumerate(years): if year: addon = addons + [year]
import Analysis.Tools.logger as logger import RootTools.core.logger as logger_rt logger = logger.get_logger( args.logLevel, logFile = None ) logger_rt = logger_rt.get_logger( args.logLevel, logFile = None ) args.preliminary = True from Analysis.Tools.MergingDirDB import MergingDirDB from TTGammaEFT.Tools.user import cache_directory year = str(args.year) if args.plotYear: year += "_" + str(args.plotYear) cache_dir = os.path.join(cache_directory, "unfolding", str(args.year), "bkgSubstracted" if args.bkgSubstracted else "total", "expected" if args.expected else "observed", "postFit" if args.postFit else "preFit") print cache_dir dirDB = MergingDirDB(cache_dir) if not dirDB: raise addons = [] if args.plotRegions: addons += args.plotRegions if args.plotChannels: addons += args.plotChannels if args.year == "combined" and not args.plotYear: years = ["2016","2017","2018"] elif args.year == "combined" and args.plotYear: years = [args.plotYear] else: years = [None] for i, year in enumerate(years): if year: addon = addons + [year]
# Text on the plots def drawObjects(lumi_scale): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%3.1f fb^{-1} (13 TeV)" % lumi_scale) lines = [(0.15, 0.95, "CMS #bf{#it{Preliminary}}"), line] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"] = "False" #always false for QCD estimate if args.year == 2016: from TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import * mc = all_noQCD_16 data_sample = Run2016 elif args.year == 2017: from TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed import * from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import * mc = all_noQCD_17 data_sample = Run2017 elif args.year == 2018:
# Text on the plots def drawObjects( lumi_scale ): tex = ROOT.TLatex() tex.SetNDC() tex.SetTextSize(0.04) tex.SetTextAlign(11) # align right line = (0.68, 0.95, "%i fb^{-1} (13 TeV)" % lumi_scale) lines = [ # (0.15, 0.95, "CMS #bf{#it{Preliminary}} (%s)"%args.selection), (0.15, 0.95, "Private Work"), line ] return [tex.DrawLatex(*l) for l in lines] cache_dir = os.path.join(cache_directory, "drawHistos", str(args.year), args.selection, args.mode) dirDB = MergingDirDB(cache_dir) if not dirDB: raise # Sample definition os.environ["gammaSkim"]="False" #always false for QCD estimate if args.year == 2016: import TTGammaEFT.Samples.nanoTuples_Summer16_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2016_14Dec2018_semilep_postProcessed import Run2016 as data_sample elif args.year == 2017: import TTGammaEFT.Samples.nanoTuples_Fall17_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2017_14Dec2018_semilep_postProcessed import Run2017 as data_sample elif args.year == 2018: import TTGammaEFT.Samples.nanoTuples_Autumn18_private_semilep_postProcessed as mc_samples from TTGammaEFT.Samples.nanoTuples_Run2018_14Dec2018_semilep_postProcessed import Run2018 as data_sample elif args.year == "RunII": import TTGammaEFT.Samples.nanoTuples_RunII_postProcessed as mc_samples