From 307bb39ad77330087e1caf7aa37a46f36cc03bba Mon Sep 17 00:00:00 2001 From: Sebastien Wertz Date: Thu, 28 Jul 2022 09:03:11 +0200 Subject: [PATCH 1/2] new colour scheme --- config/analysis.yml | 91 +++++++-------------------------------------- 1 file changed, 14 insertions(+), 77 deletions(-) diff --git a/config/analysis.yml b/config/analysis.yml index 3a0cedd..aea3f78 100644 --- a/config/analysis.yml +++ b/config/analysis.yml @@ -33,134 +33,68 @@ plotIt: groups: data: legend: Data - - ttbb: - legend: 't#bar{t}b#bar{b}' - fill-color: "#912200" - line-width: 1 - line-color: 1 - line-style: 1 ttB: legend: 't#bar{t}+B' mpl_legend: '$\mathrm{t}\overline{\mathrm{t}}+B$' - fill-color: "#FFFF00" + fill-color: "#00A0B0" line-width: 1 line-color: 1 line-style: 1 ttB_OOA: legend: 't#bar{t}+B OOA' mpl_legend: '$\mathrm{t}\overline{\mathrm{t}}+B$ OOA' - fill-color: "#ffb29c" - line-width: 1 - line-color: 1 - line-style: 1 - ttb: - legend: 't#bar{t}b' - fill-color: "#B93A13" + fill-color: "#496f73" line-width: 1 line-color: 1 line-style: 1 ttcc: legend: 't#bar{t}+C' mpl_legend: '$\mathrm{t}\overline{\mathrm{t}}+C$' - #fill-color: "#f55d2f" - fill-color: "#FF6600" + fill-color: "#eb6841" line-width: 1 line-color: 1 line-style: 1 ttjj: legend: 't#bar{t}+light' mpl_legend: '$\mathrm{t}\overline{\mathrm{t}}$+light' - #fill-color: "#F09175" - fill-color: "#CC3300" - line-width: 1 - line-color: 1 - line-style: 1 - TT_other: - legend: 't#bar{t} other' - fill-color: "#ffb29c" + fill-color: "#edc951" line-width: 1 line-color: 1 line-style: 1 - - ttbb_4fs: - legend: 't#bar{t}b#bar{b} 4FS' - line-color: "#912200" - tt_5fs: - legend: 't#bar{t} 5FS' - line-color: "#F09175" - - #TT1L: - # legend: 't#bar{t} semileptonic' - # fill-color: "#EB6841" - #TT2L: - # legend: 't#bar{t} dileptonic' - # fill-color: "#F09175" - #TT0L: - # legend: 't#bar{t} hadronic' - # fill-color: "#B93A13" - VJets: legend: 'V+jets' - fill-color: "#FFFFFF" + fill-color: "#EEEEEE" line-width: 1 line-color: 1 line-style: 1 - #ZJets: - # legend: 'Z+jets' - # fill-color: "#FFFFFF" - # line-width: 1 - # line-color: 1 - # line-style: 1 - #WJets: - # legend: 'W+jets' - # fill-color: "#ECD078" - # line-width: 1 - # line-color: 1 - # line-style: 1 ttX: legend: 't#bar{t}X' mpl_legend: '$\mathrm{t}\overline{\mathrm{t}}+X$' - fill-color: "#FF3333" - #fill-color: "#53777A" + fill-color: "#296a00" line-width: 1 line-color: 1 line-style: 1 ttV: legend: 't#bar{t}V' mpl_legend: '$\mathrm{t}\overline{\mathrm{t}}\mathrm{V}$' - fill-color: "#296a00" + fill-color: "#A8DBA8" line-width: 1 line-color: 1 line-style: 1 ttH: legend: 't#bar{t}H' mpl_legend: '$\mathrm{t}\overline{\mathrm{t}}\mathrm{H}$' - fill-color: "#45b101" - #fill-color: "#A8DBA8" + fill-color: "#296a00" line-width: 1 line-color: 1 line-style: 1 - #ttW: - # legend: 't#bar{t}W' - # fill-color: "#53777A" - # line-width: 1 - # line-color: 1 - # line-style: 1 - #ttZ: - # legend: 't#bar{t}Z' - # fill-color: "#C02942" - # line-width: 1 - # line-color: 1 - # line-style: 1 ST: legend: 'Single t' mpl_legend: 'Single $\mathrm{t}$' - fill-color: "#FF6666" + fill-color: "#ffb29c" line-width: 1 line-color: 1 line-style: 1 - #fill-color: "#C02942" systematics: # this list is only used for control plots - muon_ID @@ -207,18 +141,21 @@ plotIt: - btagSF_deepjet_fixWP_qcdscale - btagSF_deepjet_fixWP_topmass - btagSF_deepjet_fixWP_type3 + - btagSF_deepjet_fixWP_jes - btagSF_deepjet_fixWP_statistic_2016ULpreVFP - btagSF_deepjet_fixWP_statistic_2016ULpostVFP - btagSF_deepjet_fixWP_statistic_2017UL - btagSF_deepjet_fixWP_statistic_2018UL - #- jer + - jer - jer0 - jer1 #- jer2 #- jer3 #- jer4 #- jer5 - #- jesTotal + # in principle there is no double counting in the plots because + # we never produce the total and the Merged scheme simultaneously + - jesTotal - jesFlavorQCD - jesEC2 - jesHF -- GitLab From 837e6191e8c994b2617ee061ee63daf33201d07a Mon Sep 17 00:00:00 2001 From: Sebastien Wertz Date: Thu, 28 Jul 2022 09:05:17 +0200 Subject: [PATCH 2/2] support fully split JEC uncertainty scheme, add flag to use single JER nuisance --- python/baseTtbbPlotter.py | 4 ++-- python/definitions.py | 40 ++++++++++++++++++++++++++++------- python/recoBaseTtbbPlotter.py | 6 ++++-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/python/baseTtbbPlotter.py b/python/baseTtbbPlotter.py index b5b45d4..0b5e336 100644 --- a/python/baseTtbbPlotter.py +++ b/python/baseTtbbPlotter.py @@ -42,7 +42,7 @@ class baseTtbbModule(NanoAODModule): parser.add_argument("-r", "--reduce-split", type=int, default=0, help="Reduce number of jobs by factor X") parser.add_argument("--samples", nargs='*', required=True, help="Sample template YML file") parser.add_argument("--roc-corr", action="store_true", help="Enable muon Rochester correction") - parser.add_argument("--pdf-mode", choices=["simple", "full"], default="simple", help="Full PDF uncertainties (100 histogram variations) or simple (event-based envelope) (only if systematics enabled)") + parser.add_argument("--pdf-mode", choices=["simple", "full"], default="simple", help="Full PDF uncertainties (100 histogram variations) or simple (event-based envelope) (only if systematics enabled) (default: %(default)s)") def _loadSampleLists(self, analysisCfg): # fill sample template using JSON files @@ -175,7 +175,7 @@ class baseTtbbPlotter(baseTtbbModule, HistogramsModule): def addArgs(self, parser): super().addArgs(parser) - parser.add_argument("--main-signal", default="powheg_4FS", help="Main signal sample, used for control plots") + parser.add_argument("--main-signal", default="powheg_4FS", help="Main signal sample, used for control plots (default: %(default)s)") def postProcess(self, taskList, config=None, workdir=None, resultsdir=None, makeBU=True, removeBatch=True, createEnvelope=True, moveSystHists=True, removeSignalOverlap=True, diff --git a/python/definitions.py b/python/definitions.py index 88a4146..4db9007 100644 --- a/python/definitions.py +++ b/python/definitions.py @@ -14,11 +14,13 @@ from bamboo.analysisutils import configureRochesterCorrection, configureJets, co from bamboo.scalefactors import get_correction import utils - + + def getYearFromEra(era): """ Go from '2017'/'2018UL'/'2016ULpreVFP' to '17'/'18'/'16' """ return re.search(r"20([0-9]+).*", era).group(1) + #### Configure NanoAOD decoration def getNanoAODDescription(era, isMC, doRocCor=True): @@ -39,6 +41,7 @@ def getNanoAODDescription(era, isMC, doRocCor=True): else: return td.NanoAODDescription(groups=groups, collections=collections, systVariations=varReaders) + JECTagDatabase = { "2016ULpreVFP": "Summer19UL16APV_V7_MC", "2016ULpostVFP": "Summer19UL16_V7_MC", @@ -52,26 +55,47 @@ JERTagDatabase = { "2018UL": "Summer19UL18_JRV2_MC" } -def configureJetMETCorrections(tree, era, isNotWorker, isMC, backend, sampleName, configMET=False): +def configureJetMETCorrections(tree, era, isNotWorker, isMC, backend, sampleName, splitJER=True, jesScheme="Merged", configMET=False): if isMC: # NOTE: not including variations that would only affect MET since we're not using it... but this could change - exclJetSysts = ["jesTotal"] + [f"jer{x}" for x in range(2, 6) ] - exclJetSysts += [ f"jesHF_{e}" for e in ["2016", "2017", "2018"] ] - exclJetSysts += [ f"jesEC2_{e}" for e in ["2016", "2017", "2018"] ] - exclJetSysts.append("jesHF") + exclJetSysts = [] + if splitJER: + exclJetSysts += [f"jer{x}" for x in range(2, 6) ] + if jesScheme == "Merged": + sources = "Merged" + exclJetSysts += ["jesTotal"] + exclJetSysts += [ f"jesHF_{e}" for e in ["2016", "2017", "2018"] ] + exclJetSysts += [ f"jesEC2_{e}" for e in ["2016", "2017", "2018"] ] + exclJetSysts.append("jesHF") + elif jesScheme == "All": + # here we specify explicitly the sources we use, to avoid having the jetMet + # calculator pre-compute all the sources we won't use use in the end + sources = ["AbsoluteStat", "AbsoluteScale", "AbsoluteMPFBias", + "Fragmentation", "SinglePionECAL", "SinglePionHCAL", + "FlavorQCD", + "FlavorPureGluon", "FlavorPureQuark", "FlavorPureCharm", "FlavorPureBottom", + "TimePtEta", "RelativeJEREC1", "RelativePtBB", "RelativePtEC1", + "RelativeBal", "RelativeSample", "RelativeFSR", "RelativeStatFSR", "RelativeStatEC", + "PileUpDataMC", "PileUpPtRef", "PileUpPtBB", "PileUpPtEC1"] + else: + sources = ["Total"] exclJetSysts += list(chain.from_iterable([ (f"{j}up", f"{j}down") for j in exclJetSysts ])) + configureJets(tree._Jet, "AK4PFchs", jec=JECTagDatabase[era], smear=JERTagDatabase[era], jecLevels=[], # NOTE: not re-applying the JEC, only computing uncertainties! - jesUncertaintySources="Merged", regroupTag="V2", enableSystematics=lambda v: v not in exclJetSysts, - splitJER=True, addHEM2018Issue=(era == "2018UL"), mayWriteCache=isNotWorker, + jesUncertaintySources=sources, regroupTag="V2", enableSystematics=lambda v: v not in exclJetSysts, + splitJER=splitJER, addHEM2018Issue=(era == "2018UL"), mayWriteCache=isNotWorker, isMC=isMC, backend=backend, uName=sampleName) + if configMET: configureType1MET(tree._MET, jec=JECTagDatabase[era], smear=JERTagDatabase[era], jesUncertaintySources="Merged", regroupTag="V2", splitJER=True, addHEM2018Issue=(era == "2018UL"), mayWriteCache=isNotWorker, isMC=isMC, backend=backend, uName=sampleName) + #### Reco-level object definitions + def flagDef(flags, era, isMC): # from https://twiki.cern.ch/twiki/bin/view/CMS/MissingETOptionalFiltersRun2 cuts = [ diff --git a/python/recoBaseTtbbPlotter.py b/python/recoBaseTtbbPlotter.py index db9cdb6..d118ab8 100644 --- a/python/recoBaseTtbbPlotter.py +++ b/python/recoBaseTtbbPlotter.py @@ -17,9 +17,11 @@ class recoBaseTtbbPlotter(baseTtbbPlotter): def addArgs(self, parser): super().addArgs(parser) - parser.add_argument("--btag-sf", choices=['none', 'fixWPMT', 'itFit'], default='fixWPMT', help="Choose b-tag SFs to use") + parser.add_argument("--btag-sf", choices=['none', 'fixWPMT', 'itFit'], default='fixWPMT', help="Choose b-tag SFs to use (default: %(default)s)") parser.add_argument("--decorr-btag", action="store_true", help="Decorrelate b-tagging uncertainties for different working points") parser.add_argument("--btag-fix", action="store_true", help="Fix: use preVFP mistag SFs in postVFP") + parser.add_argument("--no-split-jer", action="store_true", help="Do not produce the split JER variations") + parser.add_argument("--jes-scheme", choices=["All", "Merged", "Total"], default="Merged", help="JEC uncertainty scheme (default: %(default)s)") def prepareTree(self, tree, sample=None, sampleCfg=None, **kwargs): tree,noSel,be,lumiArgs = super().prepareTree(tree, sample=sample, sampleCfg=sampleCfg, **kwargs) @@ -32,7 +34,7 @@ class recoBaseTtbbPlotter(baseTtbbPlotter): # configure Jet/Met corrections isNotWorker = (self.args.distributed != "worker") - defs.configureJetMETCorrections(tree, era, isNotWorker, self.isMC(sample), be, sample) + defs.configureJetMETCorrections(tree, era, isNotWorker, self.isMC(sample), be, sample, splitJER=not self.args.no_split_jer, jesScheme=self.args.jes_scheme) return tree,noSel,be,lumiArgs -- GitLab