def __init__(self,
                 globalTag,
                 jesUncertainties=["Total"],
                 jetType="AK4PFchs"):

        #--------------------------------------------------------------------------------------------
        # CV: globalTag and jetType not yet used, as there is no consistent set of txt files for
        #     JES uncertainties and JER scale factors and uncertainties yet
        #--------------------------------------------------------------------------------------------

        self.jesUncertainties = jesUncertainties

        # smear jet pT to account for measured difference in JER between data and simulation.
        self.applyJERCorr = True
        self.jerInputFileName = "Spring16_25nsV10_MC_PtResolution_AK4PFchs.txt"
        self.jerUncertaintyInputFileName = "Spring16_25nsV10_MC_SF_AK4PFchs.txt"
        self.jetSmearer = jetSmearer(globalTag, jetType, self.jerInputFileName,
                                     self.jerUncertaintyInputFileName)

        self.jetBranchName = "Jet"
        self.genJetBranchName = "GenJet"
        self.metBranchName = "MET"
        self.rhoBranchName = "fixedGridRhoFastjetAll"

        # read jet energy scale (JES) uncertainties
        self.jesInputFilePath = os.environ[
            'CMSSW_BASE'] + "/src/PhysicsTools/NanoAODTools/data/jme/"
        if len(jesUncertainties) == 1 and jesUncertainties[0] == "Total":
            self.jesUncertaintyInputFileName = "Summer16_23Sep2016V4_MC_Uncertainty_AK4PFchs.txt"
        else:
            self.jesUncertaintyInputFileName = "Summer16_23Sep2016V4_MC_UncertaintySources_AK4PFchs.txt"

        # define energy threshold below which jets are considered as "unclustered energy"
        # (cf. JetMETCorrections/Type1MET/python/correctionTermsPfMetType1Type2_cff.py )
        self.unclEnThreshold = 15.

        # load libraries for accessing JES scale factors and uncertainties from txt files
        for library in [
                "libCondFormatsJetMETObjects", "libPhysicsToolsNanoAODTools"
        ]:
            if library not in ROOT.gSystem.GetLibraries():
                print("Load Library '%s'" % library.replace("lib", ""))
                ROOT.gSystem.Load(library)
Example #2
0
    def __init__(
            self, isMC, isSig, era, muonSelectionTag, electronSelectionTag,
            CorrMET
    ):  #, HTFilter, LTFilter):#, muonSelection, electronSelection):
        self.isMC = isMC
        self.isSig = isSig
        self.era = era
        self.muonSelectionTag = muonSelectionTag
        self.electronSelectionTag = electronSelectionTag
        self.CorrMET = CorrMET

        #self.HTFilt = HTFilter
        #self.LTFilt = LTFilter
        # smear jet pT to account for measured difference in JER between data and simulation.
        self.jerInputFileName = "Spring16_25nsV10_MC_PtResolution_AK4PFchs.txt"
        self.jerUncertaintyInputFileName = "Spring16_25nsV10_MC_SF_AK4PFchs.txt"
        ###################### LepSF, JECSFs and JERSF for 2017 era ###############################################################
        if self.era == "2016":
            self.btag_LooseWP = 0.5426
            self.btag_MediumWP = 0.8484
            self.btag_TightWP = 0.9535
            #https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation80XReReco
            self.btag_DeepLooseWP = 0.2219
            self.btag_DeepMediumWP = 0.6324
            self.btag_DeepTightWP = 0.8958
            if self.isMC:
                if self.muonSelectionTag == "LooseWP_2016":
                    mu_f = ["Mu_Trg.root", "Mu_ID.root", "Mu_Iso.root"]
                    mu_h = [
                        "IsoMu24_OR_IsoTkMu24_PtEtaBins/pt_abseta_ratio",
                        "MC_NUM_LooseID_DEN_genTracks_PAR_pt_eta/pt_abseta_ratio",
                        "LooseISO_LooseID_pt_eta/pt_abseta_ratio"
                    ]
                if self.electronSelectionTag == "GPMVA90_2016":
                    el_f = ["EGM2D_eleGSF.root", "EGM2D_eleMVA90.root"]
                    el_h = ["EGamma_SF2D", "EGamma_SF2D"]
                if self.muonSelectionTag == "MediumWP_2016":
                    mu_f = ["Mu_Trg.root", "Mu_ID.root", "Mu_Iso.root"]
                    mu_h = [
                        "IsoMu24_OR_IsoTkMu24_PtEtaBins/pt_abseta_ratio",
                        "MC_NUM_MediumID_DEN_genTracks_PAR_pt_eta/pt_abseta_ratio",
                        "LooseISO_MediumID_pt_eta/pt_abseta_ratio"
                    ]
                if self.electronSelectionTag == "Tight_2016":
                    el_f = ["EGM2D_eleGSF.root", "EGM2D_eleMVA90.root"]
                    el_h = ["EGamma_SF2D", "EGamma_SF2D"]
            #self.jerUncertaintyInputFileName = "Spring16_25nsV10_MC_SF_AK4PFchs.txt"
            self.jetSmearer = jetSmearer("Summer16_23Sep2016V4_MC", "AK4PFchs",
                                         self.jerInputFileName,
                                         self.jerUncertaintyInputFileName)
        ###################### LepSF, JECSFs and JERSF for 2017 era ###############################################################
        elif self.era == "2017":
            self.btag_LooseWP = 0.5803
            self.btag_MediumWP = 0.8838
            self.btag_TightWP = 0.9693
            # DeepCSV (new Deep Flavour tagger)
            #https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X
            self.btag_DeepLooseWP = 0.1522
            self.btag_DeepMediumWP = 0.4941
            self.btag_DeepTightWP = 0.8001
            if self.isMC:
                if self.muonSelectionTag == "LooseWP_2017":
                    mu_f = ["Mu_Trg17.root", "Mu_ID17.root", "Mu_Iso17.root"]
                    mu_h = [
                        "IsoMu27_PtEtaBins/pt_abseta_ratio",
                        "NUM_LooseID_DEN_genTracks_pt_abseta",
                        "NUM_LooseRelIso_DEN_LooseID_pt_abseta"
                    ]
                if self.electronSelectionTag == "GPMVA90_2017":
                    el_f = ["EGM2D_eleGSF17.root", "EGM2D_eleMVA90_17.root"]
                    el_h = ["EGamma_SF2D", "EGamma_SF2D"]
                if self.muonSelectionTag == "MediumWP_2017":
                    mu_f = ["Mu_Trg17.root", "Mu_ID17.root", "Mu_Iso17.root"]
                    mu_h = [
                        "IsoMu27_PtEtaBins/pt_abseta_ratio",
                        "NUM_MediumID_DEN_genTracks_pt_abseta",
                        "NUM_LooseRelIso_DEN_MediumID_pt_abseta"
                    ]
                if self.electronSelectionTag == "Tight_2017":
                    el_f = ["EGM2D_eleGSF17.root", "EGM2D_eleMVA90_17.root"]
                    el_h = ["EGamma_SF2D", "EGamma_SF2D"]
            # Temporarly use the jetmet uncertainty for 2016
            #self.jerUncertaintyInputFileName = "Spring16_25nsV10_MC_SF_AK4PFchs.txt"
            #self.jetSmearer = jetSmearer("Summer16_23Sep2016V4_MC", "AK4PFchs", self.jerInputFileName, self.jerUncertaintyInputFileName)
            #self.jerUncertaintyInputFileName = "Fall17_17Nov2017_V6_MC_Uncertainty_AK4PFchs.txt"
            self.jetSmearer = jetSmearer("Fall17_17Nov2017_V6_MC", "AK4PFchs",
                                         self.jerInputFileName,
                                         self.jerUncertaintyInputFileName)
        else:
            raise ValueError("ERROR: Invalid era = '%s'!" % self.era)
        if self.isMC:
            mu_f = [
                "%s/src/PhysicsTools/NanoAODTools/python/postprocessing/data/leptonSF/"
                % os.environ['CMSSW_BASE'] + f for f in mu_f
            ]
            el_f = [
                "%s/src/PhysicsTools/NanoAODTools/python/postprocessing/data/leptonSF/"
                % os.environ['CMSSW_BASE'] + f for f in el_f
            ]
            self.mu_f = ROOT.std.vector(str)(len(mu_f))
            self.mu_h = ROOT.std.vector(str)(len(mu_f))
            for i in range(len(mu_f)):
                self.mu_f[i] = mu_f[i]
                self.mu_h[i] = mu_h[i]
            self.el_f = ROOT.std.vector(str)(len(el_f))
            self.el_h = ROOT.std.vector(str)(len(el_f))
            for i in range(len(el_f)):
                self.el_f[i] = el_f[i]
                self.el_h[i] = el_h[i]
            self.jetReCalibrator = JetReCalibrator(
                "Fall17_17Nov2017_V6_MC",
                "AK4PFchs",
                True,
                os.environ['CMSSW_BASE'] +
                "/src/PhysicsTools/NanoAODTools/data/jme/",
                calculateSeparateCorrections=False,
                calculateType1METCorrection=False)
            self.unclEnThreshold = 15.

        if "/LeptonEfficiencyCorrector_cc.so" not in ROOT.gSystem.GetLibraries(
        ):
            print "Load C++ Worker"
            ROOT.gROOT.ProcessLine(
                ".L %s/src/PhysicsTools/NanoAODTools/python/postprocessing/helpers/LeptonEfficiencyCorrector.cc+"
                % os.environ['CMSSW_BASE'])
        pass
    def __init__(self,
                 era,
                 globalTag,
                 jesUncertainties=["Total"],
                 archive=None,
                 jetType="AK8PFPuppi",
                 noGroom=False,
                 jerTag="",
                 jmrVals=[],
                 jmsVals=[],
                 isData=False,
                 applySmearing=True,
                 applyHEMfix=False,
                 splitJER=False):
        self.era = era
        self.noGroom = noGroom
        self.isData = isData
        self.applySmearing = applySmearing if not isData else False  # don't smear for data
        # ---------------------------------------------------------------------
        # CV: globalTag and jetType not yet used in the jet smearer, as there
        # is no consistent set of txt files for JES uncertainties and JER scale
        # factors and uncertainties yet
        # ---------------------------------------------------------------------
        self.splitJER = splitJER
        if self.splitJER:
            self.splitJERIDs = list(range(6))
        else:
            self.splitJERIDs = [""]  # "empty" ID for the overall JER

        self.jesUncertainties = jesUncertainties
        # smear jet pT to account for measured difference in JER between data
        # and simulation.
        if jerTag != "":
            self.jerInputFileName = jerTag + "_PtResolution_" + jetType + ".txt"
            self.jerUncertaintyInputFileName = jerTag + "_SF_" + jetType + ".txt"
        else:
            print("WARNING: jerTag is empty!!! This module will soon be "
                  "deprecated! Please use jetmetHelperRun2 in the future.")
            if era == "2016":
                self.jerInputFileName = ''.join(
                    ["Summer16_25nsV1_MC_PtResolution_", jetType, ".txt"])
                self.jerUncertaintyInputFileName = ''.join(
                    ["Summer16_25nsV1_MC_SF_", jetType, ".txt"])
            elif era == "2017" or era == "2018":
                # use Fall17 as temporary placeholder until
                # post-Moriond 2019 JERs are out
                self.jerInputFileName = ''.join(
                    ["Fall17_V3_MC_PtResolution_", jetType, ".txt"])
                self.jerUncertaintyInputFileName = ''.join(
                    ["Fall17_V3_MC_SF_", jetType, ".txt"])

        # jet mass resolution: https://twiki.cern.ch/twiki/bin/view/CMS/JetWtagging
        self.jmrVals = jmrVals
        if not self.jmrVals:
            print("WARNING: jmrVals is empty!!! Using default values. This "
                  "module will soon be deprecated! Please use "
                  "jetmetHelperRun2 in the future.")
            self.jmrVals = [1.0, 1.2, 0.8]  # nominal, up, down
            # Use 2017 values for 2018 until 2018 are released
            if self.era in ["2017", "2018"]:
                self.jmrVals = [1.09, 1.14, 1.04]

        self.jetSmearer = jetSmearer(globalTag, jetType, self.jerInputFileName,
                                     self.jerUncertaintyInputFileName,
                                     self.jmrVals)

        if "AK4" in jetType:
            self.jetBranchName = "Jet"
            self.genJetBranchName = "GenJet"
            self.genSubJetBranchName = None
            self.doGroomed = False
        elif "AK8" in jetType:
            self.jetBranchName = "FatJet"
            self.subJetBranchName = "SubJet"
            self.genJetBranchName = "GenJetAK8"
            self.genSubJetBranchName = "SubGenJetAK8"
            if not self.noGroom:
                self.doGroomed = True
                self.puppiCorrFile = ROOT.TFile.Open(
                    os.environ['CMSSW_BASE'] +
                    "/src/PhysicsTools/NanoAODTools/data/jme/puppiCorr.root")
                self.puppisd_corrGEN = self.puppiCorrFile.Get(
                    "puppiJECcorr_gen")
                self.puppisd_corrRECO_cen = self.puppiCorrFile.Get(
                    "puppiJECcorr_reco_0eta1v3")
                self.puppisd_corrRECO_for = self.puppiCorrFile.Get(
                    "puppiJECcorr_reco_1v3eta2v5")
            else:
                self.doGroomed = False
        else:
            raise ValueError("ERROR: Invalid jet type = '%s'!" % jetType)
        self.rhoBranchName = "fixedGridRhoFastjetAll"
        self.lenVar = "n" + self.jetBranchName

        # jet mass scale
        self.jmsVals = jmsVals
        if not self.jmsVals:
            print("WARNING: jmsVals is empty!!! Using default values! This " +
                  "module will soon be deprecated! Please use " +
                  "jetmetHelperRun2 in the future.")
            # 2016 values
            self.jmsVals = [1.00, 0.9906, 1.0094]  # nominal, down, up
            # Use 2017 values for 2018 until 2018 are released
            if self.era in ["2017", "2018"]:
                self.jmsVals = [0.982, 0.978, 0.986]

        # read jet energy scale (JES) uncertainties
        # (downloaded from https://twiki.cern.ch/twiki/bin/view/CMS/JECDataMC )
        self.jesInputArchivePath = os.environ['CMSSW_BASE'] + \
            "/src/PhysicsTools/NanoAODTools/data/jme/"

        # Text files are now tarred so must extract first into temporary
        # directory (gets deleted during python memory management at script exit)
        self.jesArchive = tarfile.open(
            self.jesInputArchivePath + globalTag +
            ".tgz", "r:gz") if not archive else tarfile.open(
                self.jesInputArchivePath + archive + ".tgz", "r:gz")
        self.jesInputFilePath = tempfile.mkdtemp()
        self.jesArchive.extractall(self.jesInputFilePath)

        if len(jesUncertainties) == 1 and jesUncertainties[0] == "Total":
            self.jesUncertaintyInputFileName = globalTag + "_Uncertainty_" + jetType + ".txt"
        elif jesUncertainties[0] == "Merged" and not self.isData:
            self.jesUncertaintyInputFileName = "Regrouped_" + \
                globalTag + "_UncertaintySources_" + jetType + ".txt"
        else:
            self.jesGroupedFilePath = os.environ[
                'CMSSW_BASE'] + "/src/PhysicsTools/NanoAODTools/data/jme/regrouped/"
            self.jesGroupedUncertaintyFileName = "RegroupedV2_" + globalTag + "_UncertaintySources_" + jetType + ".txt"
            self.jesGroupedUncertaintyFilePath = pjoin(
                self.jesGroupedFilePath, self.jesGroupedUncertaintyFileName)
            # Copy the uncertainty source file to the tmp directory
            shutil.copy(
                self.jesGroupedUncertaintyFilePath,
                pjoin(self.jesInputFilePath,
                      self.jesGroupedUncertaintyFileName))
            self.jesUncertaintyInputFileName = self.jesGroupedUncertaintyFileName
            #self.jesUncertaintyInputFileName = "RegroupedV2_" + globalTag + "_UncertaintySources_" + jetType + ".txt"

        # read all uncertainty source names from the loaded file
        if jesUncertainties[0] in ["All", "Merged"]:
            with open(self.jesInputFilePath + '/' +
                      self.jesUncertaintyInputFileName) as f:
                lines = f.read().split("\n")
                sources = [
                    x for x in lines if x.startswith("[") and x.endswith("]")
                ]
                sources = [x[1:-1] for x in sources]
                self.jesUncertainties = sources
        if applyHEMfix:
            self.jesUncertainties.append("HEMIssue")

        self.jetReCalibrator = JetReCalibrator(
            globalTag,
            jetType,
            True,
            self.jesInputFilePath,
            calculateSeparateCorrections=False,
            calculateType1METCorrection=False)

        # load libraries for accessing JES scale factors and uncertainties
        # from txt files
        for library in [
                "libCondFormatsJetMETObjects", "libPhysicsToolsNanoAODTools"
        ]:
            if library not in ROOT.gSystem.GetLibraries():
                print("Load Library '%s'" % library.replace("lib", ""))
                ROOT.gSystem.Load(library)
Example #4
0
    def __init__(self,
                 era,
                 globalTag,
                 jesUncertainties=["Total"],
                 jetType="AK4PFchs",
                 redoJEC=False,
                 noGroom=False):

        self.era = era
        self.redoJEC = redoJEC
        self.noGroom = noGroom
        #--------------------------------------------------------------------------------------------
        # CV: globalTag and jetType not yet used, as there is no consistent set of txt files for
        #     JES uncertainties and JER scale factors and uncertainties yet
        #--------------------------------------------------------------------------------------------

        self.jesUncertainties = jesUncertainties

        # smear jet pT to account for measured difference in JER between data and simulation.
        self.jerInputFileName = "Spring16_25nsV10_MC_PtResolution_" + jetType + ".txt"
        self.jerUncertaintyInputFileName = "Spring16_25nsV10_MC_SF_" + jetType + ".txt"
        self.jetSmearer = jetSmearer(globalTag, jetType, self.jerInputFileName,
                                     self.jerUncertaintyInputFileName)

        if "AK4" in jetType:
            self.jetBranchName = "Jet"
            self.genJetBranchName = "GenJet"
            self.genSubJetBranchName = None
            self.doGroomed = False
            self.corrMET = True
        elif "AK8" in jetType:
            self.jetBranchName = "FatJet"
            self.subJetBranchName = "SubJet"
            self.genJetBranchName = "GenJetAK8"
            self.genSubJetBranchName = "SubGenJetAK8"
            if not self.noGroom:
                self.doGroomed = True
            else:
                self.doGroomed = False
            self.corrMET = False
        else:
            raise ValueError("ERROR: Invalid jet type = '%s'!" % jetType)
        self.metBranchName = "MET"
        self.rhoBranchName = "fixedGridRhoFastjetAll"
        self.lenVar = "n" + self.jetBranchName
        # To do : change to real values
        self.jmsVals = [1.00, 0.99, 1.01]

        # read jet energy scale (JES) uncertainties
        # (downloaded from https://twiki.cern.ch/twiki/bin/view/CMS/JECDataMC )
        self.jesInputFilePath = os.environ[
            'CMSSW_BASE'] + "/src/PhysicsTools/NanoAODTools/data/jme/"
        if len(jesUncertainties) == 1 and jesUncertainties[0] == "Total":
            if self.era == "2016":
                self.jesUncertaintyInputFileName = "Summer16_23Sep2016V4_MC_Uncertainty_" + jetType + ".txt"
            elif self.era == "2017":
                self.jesUncertaintyInputFileName = "Fall17_17Nov2017_V6_MC_Uncertainty_" + jetType + ".txt"
            else:
                raise ValueError("ERROR: Invalid era = '%s'!" % self.era)
        else:
            if self.era == "2016":
                self.jesUncertaintyInputFileName = "Summer16_23Sep2016V4_MC_UncertaintySources_" + jetType + ".txt"
            elif self.era == "2017":
                self.jesUncertaintyInputFileName = "Fall17_17Nov2017_V6_MC_UncertaintySources_" + jetType + ".txt"
            else:
                raise ValueError("ERROR: Invalid era = '%s'!" % self.era)

        # read all uncertainty source names from the loaded file
        if jesUncertainties[0] == "All":
            with open(self.jesInputFilePath +
                      self.jesUncertaintyInputFileName) as f:
                lines = f.read().split("\n")
                sources = filter(
                    lambda x: x.startswith("[") and x.endswith("]"), lines)
                sources = map(lambda x: x[1:-1], sources)
                self.jesUncertainties = sources

        if self.redoJEC:
            self.jetReCalibrator = JetReCalibrator(
                globalTag,
                jetType,
                True,
                self.jesInputFilePath,
                calculateSeparateCorrections=False,
                calculateType1METCorrection=False)

        # define energy threshold below which jets are considered as "unclustered energy"
        # (cf. JetMETCorrections/Type1MET/python/correctionTermsPfMetType1Type2_cff.py )
        self.unclEnThreshold = 15.

        # load libraries for accessing JES scale factors and uncertainties from txt files
        for library in [
                "libCondFormatsJetMETObjects", "libPhysicsToolsNanoAODTools"
        ]:
            if library not in ROOT.gSystem.GetLibraries():
                print("Load Library '%s'" % library.replace("lib", ""))
                ROOT.gSystem.Load(library)
    def __init__(self, era, globalTag, jesUncertainties = [ "Total" ], jetType = "AK4PFchs", redoJEC=False, noGroom=False, jerTag="", jmrVals = [], jmsVals = []):

        self.era = era
        self.redoJEC = redoJEC
        self.noGroom = noGroom
        #--------------------------------------------------------------------------------------------
        # CV: globalTag and jetType not yet used in the jet smearer, as there is no consistent set of 
        #     txt files for JES uncertainties and JER scale factors and uncertainties yet
        #--------------------------------------------------------------------------------------------

        self.jesUncertainties = jesUncertainties
        # smear jet pT to account for measured difference in JER between data and simulation.
        if jerTag != "":
            self.jerInputFileName = jerTag + "_PtResolution_" + jetType + ".txt"
            self.jerUncertaintyInputFileName = jerTag + "_SF_"  + jetType + ".txt"
        else:
            print "WARNING: jerTag is empty!!! This module will soon be deprecated! Please use jetmetHelperRun2 in the future."
            if era == "2016":
                self.jerInputFileName = "Summer16_25nsV1_MC_PtResolution_" + jetType + ".txt"
                self.jerUncertaintyInputFileName = "Summer16_25nsV1_MC_SF_" + jetType + ".txt"
            elif era == "2017" or era == "2018": # use Fall17 as temporary placeholder until post-Moriond 2019 JERs are out
                self.jerInputFileName = "Fall17_V3_MC_PtResolution_" + jetType + ".txt"
                self.jerUncertaintyInputFileName = "Fall17_V3_MC_SF_" + jetType + ".txt"

        #jet mass resolution: https://twiki.cern.ch/twiki/bin/view/CMS/JetWtagging
        self.jmrVals = jmrVals
        if not self.jmrVals:
            print "WARNING: jmrVals is empty!!! Using default values. This module will soon be deprecated! Please use jetmetHelperRun2 in the future."
            self.jmrVals = [1.0, 1.2, 0.8] #nominal, up, down
            # Use 2017 values for 2018 until 2018 are released
            if self.era in ["2017","2018"]:
                self.jmrVals = [1.09, 1.14, 1.04] 

        self.jetSmearer = jetSmearer(globalTag, jetType, self.jerInputFileName, self.jerUncertaintyInputFileName, self.jmrVals)

        if "AK4" in jetType : 
            self.jetBranchName = "Jet"
            self.genJetBranchName = "GenJet"
            self.genSubJetBranchName = None
            self.doGroomed = False
            self.corrMET = True
        elif "AK8" in jetType :
            self.jetBranchName = "FatJet"
            self.subJetBranchName = "SubJet"
            self.genJetBranchName = "GenJetAK8"
            self.genSubJetBranchName = "SubGenJetAK8"
            if not self.noGroom:
                self.doGroomed = True
                self.puppiCorrFile = ROOT.TFile.Open(os.environ['CMSSW_BASE'] + "/src/PhysicsTools/NanoAODTools/data/jme/puppiCorr.root")
                self.puppisd_corrGEN = self.puppiCorrFile.Get("puppiJECcorr_gen")
                self.puppisd_corrRECO_cen = self.puppiCorrFile.Get("puppiJECcorr_reco_0eta1v3")
                self.puppisd_corrRECO_for = self.puppiCorrFile.Get("puppiJECcorr_reco_1v3eta2v5")
            else:
                self.doGroomed = False
            self.corrMET = False
        else:
            raise ValueError("ERROR: Invalid jet type = '%s'!" % jetType)
        self.metBranchName = "MET"
        self.rhoBranchName = "fixedGridRhoFastjetAll"
        self.lenVar = "n" + self.jetBranchName

        #jet mass scale
        self.jmsVals = jmsVals
        if not self.jmsVals:
            print "WARNING: jmsVals is empty!!! Using default values! This module will soon be deprecated! Please use jetmetHelperRun2 in the future."
            #2016 values 
            self.jmsVals = [1.00, 0.9906, 1.0094] #nominal, down, up
            # Use 2017 values for 2018 until 2018 are released
            if self.era in ["2017","2018"]:
                self.jmsVals = [0.982, 0.978, 0.986]

        # read jet energy scale (JES) uncertainties
        # (downloaded from https://twiki.cern.ch/twiki/bin/view/CMS/JECDataMC )
        self.jesInputArchivePath = os.environ['CMSSW_BASE'] + "/src/PhysicsTools/NanoAODTools/data/jme/"
        # Text files are now tarred so must extract first into temporary directory (gets deleted during python memory management at script exit)
        self.jesArchive = tarfile.open(self.jesInputArchivePath+globalTag+".tgz", "r:gz")
        self.jesInputFilePath = tempfile.mkdtemp()
        self.jesArchive.extractall(self.jesInputFilePath)
        
        
        if len(jesUncertainties) == 1 and jesUncertainties[0] == "Total":
            self.jesUncertaintyInputFileName = globalTag + "_Uncertainty_" + jetType + ".txt"
        else:
            self.jesUncertaintyInputFileName = globalTag + "_UncertaintySources_" + jetType + ".txt"

        # read all uncertainty source names from the loaded file
        if jesUncertainties[0] == "All":
            with open(self.jesInputFilePath+'/'+self.jesUncertaintyInputFileName) as f:
                lines = f.read().split("\n")
                sources = filter(lambda x: x.startswith("[") and x.endswith("]"), lines)
                sources = map(lambda x: x[1:-1], sources)
                self.jesUncertainties = sources
            
        if self.redoJEC :
            self.jetReCalibrator = JetReCalibrator(globalTag, jetType , True, self.jesInputFilePath, calculateSeparateCorrections = False, calculateType1METCorrection  = False)
        

        # define energy threshold below which jets are considered as "unclustered energy"
        # (cf. JetMETCorrections/Type1MET/python/correctionTermsPfMetType1Type2_cff.py )
        self.unclEnThreshold = 15.

        # load libraries for accessing JES scale factors and uncertainties from txt files
        for library in [ "libCondFormatsJetMETObjects", "libPhysicsToolsNanoAODTools" ]:
            if library not in ROOT.gSystem.GetLibraries():
                print("Load Library '%s'" % library.replace("lib", ""))
                ROOT.gSystem.Load(library)
Example #6
0
    def __init__(self,
                 era,
                 globalTag,
                 jesUncertainties=["Total"],
                 archive=None,
                 globalTagProd=None,
                 jetType="AK4PFchs",
                 metBranchName="MET",
                 jerTag="",
                 isData=False,
                 applySmearing=True):

        # globalTagProd only needs to be defined if METFixEE2017 is to be recorrected, and should be the GT that was used for the production of the nanoAOD files
        self.era = era
        self.isData = isData
        self.applySmearing = applySmearing if not isData else False  # if set to true, Jet_pt_nom will have JER applied. not to be switched on for data.

        self.metBranchName = metBranchName
        self.rhoBranchName = "fixedGridRhoFastjetAll"
        #--------------------------------------------------------------------------------------------
        # CV: globalTag and jetType not yet used in the jet smearer, as there is no consistent set of
        #     txt files for JES uncertainties and JER scale factors and uncertainties yet
        #--------------------------------------------------------------------------------------------

        self.jesUncertainties = jesUncertainties

        # smear jet pT to account for measured difference in JER between data and simulation.
        if jerTag != "":
            self.jerInputFileName = jerTag + "_PtResolution_" + jetType + ".txt"
            self.jerUncertaintyInputFileName = jerTag + "_SF_" + jetType + ".txt"
        else:
            print "WARNING: jerTag is empty!!! This module will soon be deprecated! Please use jetmetHelperRun2 in the future."
            if era == "2016":
                self.jerInputFileName = "Summer16_25nsV1_MC_PtResolution_" + jetType + ".txt"
                self.jerUncertaintyInputFileName = "Summer16_25nsV1_MC_SF_" + jetType + ".txt"
            elif era == "2017" or era == "2018":  ## use 2017 JER for 2018 for the time being
                self.jerInputFileName = "Fall17_V3_MC_PtResolution_" + jetType + ".txt"
                self.jerUncertaintyInputFileName = "Fall17_V3_MC_SF_" + jetType + ".txt"
            elif era == "2018" and False:  ## jetSmearer not working with 2018 JERs yet
                self.jerInputFileName = "Autumn18_V7_MC_PtResolution_" + jetType + ".txt"
                self.jerUncertaintyInputFileName = "Autumn18_V7_MC_SF_" + jetType + ".txt"

        self.jetSmearer = jetSmearer(globalTag, jetType, self.jerInputFileName,
                                     self.jerUncertaintyInputFileName)

        if "AK4" in jetType:
            self.jetBranchName = "Jet"
            self.genJetBranchName = "GenJet"
            self.genSubJetBranchName = None
        else:
            raise ValueError("ERROR: Invalid jet type = '%s'!" % jetType)
        self.lenVar = "n" + self.jetBranchName

        # read jet energy scale (JES) uncertainties
        # (downloaded from https://twiki.cern.ch/twiki/bin/view/CMS/JECDataMC )
        self.jesInputArchivePath = os.environ[
            'CMSSW_BASE'] + "/src/PhysicsTools/NanoAODTools/data/jme/"
        # Text files are now tarred so must extract first into temporary directory (gets deleted during python memory management at script exit)
        self.jesArchive = tarfile.open(
            self.jesInputArchivePath + globalTag +
            ".tgz", "r:gz") if not archive else tarfile.open(
                self.jesInputArchivePath + archive + ".tgz", "r:gz")
        self.jesInputFilePath = tempfile.mkdtemp()
        self.jesArchive.extractall(self.jesInputFilePath)

        # to fully re-calculate type-1 MET the JEC that are currently applied are also needed. IS THAT EVEN CORRECT?

        if len(jesUncertainties) == 1 and jesUncertainties[0] == "Total":
            self.jesUncertaintyInputFileName = globalTag + "_Uncertainty_" + jetType + ".txt"
        else:
            self.jesUncertaintyInputFileName = globalTag + "_UncertaintySources_" + jetType + ".txt"

        # read all uncertainty source names from the loaded file
        if jesUncertainties[0] == "All":
            with open(self.jesInputFilePath + '/' +
                      self.jesUncertaintyInputFileName) as f:
                lines = f.read().split("\n")
                sources = filter(
                    lambda x: x.startswith("[") and x.endswith("]"), lines)
                sources = map(lambda x: x[1:-1], sources)
                self.jesUncertainties = sources

        # Define the jet recalibrator
        self.jetReCalibrator = JetReCalibrator(
            globalTag,
            jetType,
            True,
            self.jesInputFilePath,
            calculateSeparateCorrections=False,
            calculateType1METCorrection=False)

        # Define the recalibrator for level 1 corrections only
        self.jetReCalibratorL1 = JetReCalibrator(
            globalTag,
            jetType,
            False,
            self.jesInputFilePath,
            calculateSeparateCorrections=True,
            calculateType1METCorrection=False,
            upToLevel=1)

        # Define the recalibrators for GT used in nanoAOD production (only needed to reproduce 2017 v2 MET)
        if globalTagProd:
            self.jetReCalibratorProd = JetReCalibrator(
                globalTagProd,
                jetType,
                True,
                self.jesInputFilePath,
                calculateSeparateCorrections=False,
                calculateType1METCorrection=False)
            self.jetReCalibratorProdL1 = JetReCalibrator(
                globalTagProd,
                jetType,
                False,
                self.jesInputFilePath,
                calculateSeparateCorrections=True,
                calculateType1METCorrection=False,
                upToLevel=1)
        else:
            self.jetReCalibratorProd = False
            self.jetReCalibratorProdL1 = False

        # define energy threshold below which jets are considered as "unclustered energy"
        # (cf. JetMETCorrections/Type1MET/python/correctionTermsPfMetType1Type2_cff.py )
        self.unclEnThreshold = 15.

        # load libraries for accessing JES scale factors and uncertainties from txt files
        for library in [
                "libCondFormatsJetMETObjects", "libPhysicsToolsNanoAODTools"
        ]:
            if library not in ROOT.gSystem.GetLibraries():
                print("Load Library '%s'" % library.replace("lib", ""))
                ROOT.gSystem.Load(library)
Example #7
0
    def __init__(self,
                 era,
                 globalTag,
                 jesUncertainties=["Total"],
                 jetType="AK4PFchs",
                 redoJEC=False,
                 noGroom=False,
                 reducedJECsystematics=False):

        self.era = era
        self.redoJEC = redoJEC
        self.noGroom = noGroom
        #--------------------------------------------------------------------------------------------
        # CV: globalTag and jetType not yet used in the jet smearer, as there is no consistent set of
        #     txt files for JES uncertainties and JER scale factors and uncertainties yet
        #--------------------------------------------------------------------------------------------

        self.jesUncertainties = jesUncertainties

        # smear jet pT to account for measured difference in JER between data and simulation.
        if era == "2016":
            self.jerInputFileName = "Summer16_25nsV1b_MC/Summer16_25nsV1b_MC_PtResolution_" + jetType + ".txt"
            self.jerUncertaintyInputFileName = "Summer16_25nsV1b_MC/Summer16_25nsV1b_MC_SF_" + jetType + ".txt"
        elif era == "2017":  # use Fall17 as temporary placeholder until post-Moriond 2019 JERs are out
            self.jerInputFileName = "Fall17_V3b_MC/Fall17_V3b_MC_PtResolution_" + jetType + ".txt"
            self.jerUncertaintyInputFileName = "Fall17_V3b_MC/Fall17_V3b_MC_SF_" + jetType + ".txt"
        elif era == "2018":  ## (see https://hypernews.cern.ch/HyperNews/CMS/get/JetMET/1994.html)
            self.jerInputFileName = "Autumn18_V7b_MC/Autumn18_V7b_MC_PtResolution_" + jetType + ".txt"
            self.jerUncertaintyInputFileName = "Autumn18_V7b_MC/Autumn18_V7b_MC_SF_" + jetType + ".txt"

        #jet mass resolution: https://twiki.cern.ch/twiki/bin/view/CMS/JetWtagging
        if self.era == "2016" or self.era == "2018":  #update when 2018 values available
            self.jmrVals = [1.0, 1.2, 0.8]  #nominal, up, down
        else:
            self.jmrVals = [1.09, 1.14, 1.04]

        self.jetSmearer = jetSmearer(globalTag, jetType, self.jerInputFileName,
                                     self.jerUncertaintyInputFileName,
                                     self.jmrVals)

        if "AK4" in jetType:
            self.jetBranchName = "Jet"
            self.genJetBranchName = "GenJet"
            self.genSubJetBranchName = None
            self.doGroomed = False
            self.corrMET = True
        elif "AK8" in jetType:
            self.jetBranchName = "FatJet"
            self.subJetBranchName = "SubJet"
            self.genJetBranchName = "GenJetAK8"
            self.genSubJetBranchName = "SubGenJetAK8"
            if not self.noGroom:
                self.doGroomed = True
            else:
                self.doGroomed = False
            self.corrMET = False
        else:
            raise ValueError("ERROR: Invalid jet type = '%s'!" % jetType)
        self.metBranchName = "MET"
        self.rhoBranchName = "fixedGridRhoFastjetAll"
        self.lenVar = "n" + self.jetBranchName

        #jet mass scale
        #W-tagging PUPPI softdrop JMS values: https://twiki.cern.ch/twiki/bin/view/CMS/JetWtagging
        #2016 values - use for 2018 until new values available
        self.jmsVals = [1.00, 0.9906, 1.0094]  #nominal, down, up
        if self.era == "2017":
            self.jmsVals = [0.982, 0.978, 0.986]

        # read jet energy scale (JES) uncertainties
        # (downloaded from https://twiki.cern.ch/twiki/bin/view/CMS/JECDataMC )
        self.jesInputArchivePath = os.environ[
            'CMSSW_BASE'] + "/src/PhysicsTools/NanoAODTools/data/jme/"
        # Text files are now tarred so must extract first into temporary directory (gets deleted during python memory management at script exit)
        self.jesArchive = tarfile.open(
            self.jesInputArchivePath + globalTag + ".tgz", "r:gz")
        self.jesInputFilePath = tempfile.mkdtemp()
        self.jesArchive.extractall(self.jesInputFilePath)

        if len(jesUncertainties) == 1 and jesUncertainties[0] == "Total":
            if self.era == "2016":
                self.jesUncertaintyInputFileName = "Summer16_07Aug2017_V11_MC_Uncertainty_" + jetType + ".txt"
            elif self.era == "2017":
                self.jesUncertaintyInputFileName = "Fall17_17Nov2017_V32_MC_Uncertainty_" + jetType + ".txt"
            elif self.era == "2018":
                self.jesUncertaintyInputFileName = "Autumn18_V19_MC_Uncertainty_" + jetType + ".txt"
            else:
                raise ValueError("ERROR: Invalid era = '%s'!" % self.era)
        else:
            if self.era == "2016":
                self.jesUncertaintyInputFileName = "Summer16_07Aug2017_V11_MC_UncertaintySources_" + jetType + ".txt"
            elif self.era == "2017":
                self.jesUncertaintyInputFileName = "Fall17_17Nov2017_V32_MC_UncertaintySources_" + jetType + ".txt"
            elif self.era == "2018":
                self.jesUncertaintyInputFileName = "Autumn18_V19_MC_UncertaintySources_" + jetType + ".txt"
            else:
                raise ValueError("ERROR: Invalid era = '%s'!" % self.era)
            if reducedJECsystematics:
                ## Use https://twiki.cern.ch/twiki/bin/viewauth/CMS/JECUncertaintySources#Run_2_reduced_set_of_uncertainty ##
                self.jesUncertaintyInputFileName = "Regrouped_" + self.jesUncertaintyInputFileName

        # read all uncertainty source names from the loaded file
        if jesUncertainties[0] == "All":
            with open(self.jesInputFilePath + '/' +
                      self.jesUncertaintyInputFileName) as f:
                lines = f.read().split("\n")
                sources = filter(
                    lambda x: x.startswith("[") and x.endswith("]"), lines)
                sources = map(lambda x: x[1:-1], sources)
                self.jesUncertainties = sources

        if self.redoJEC:
            self.jetReCalibrator = JetReCalibrator(
                globalTag,
                jetType,
                True,
                self.jesInputFilePath,
                calculateSeparateCorrections=False,
                calculateType1METCorrection=False)

        # define energy threshold below which jets are considered as "unclustered energy"
        # (cf. JetMETCorrections/Type1MET/python/correctionTermsPfMetType1Type2_cff.py )
        self.unclEnThreshold = 15.

        # load libraries for accessing JES scale factors and uncertainties from txt files
        for library in [
                "libCondFormatsJetMETObjects", "libPhysicsToolsNanoAODTools"
        ]:
            if library not in ROOT.gSystem.GetLibraries():
                print("Load Library '%s'" % library.replace("lib", ""))
                ROOT.gSystem.Load(library)