Пример #1
0
 def __init__(self, name, dataType, **kwargs):
     
     year        = kwargs.get('year',  2017 )
     doZpt       = kwargs.get('doZpt', 'DY' in name )
     channel     = 'mumu'
     
     self.name   = name
     self.year   = year
     self.out    = TreeProducerMuMu(name)
     self.isData = dataType=='data'
     self.doZpt  = doZpt
     
     setYear(year)
     self.vlooseIso    = getVLooseTauIso(year)
     if year==2016:
       self.trigger    = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1 #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1
       self.muon1CutPt = 23
     else:
       self.trigger    = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27
       self.muon1CutPt = 25
     self.muon2CutPt   = 15
     
     if not self.isData:
       self.muSFs     = MuonSFs(year=year)
       self.puTool    = PileupWeightTool(year=year)
       self.btagTool      = BTagWeightTool('CSVv2','medium',channel='mutau',year=year)
       self.btagTool_deep = BTagWeightTool('DeepCSV','medium',channel='mutau',year=year)
       if self.doZpt:
         self.recoilTool  = RecoilCorrectionTool(year=year)
     self.csvv2_wp    = BTagWPs('CSVv2',year=year)
     self.deepcsv_wp  = BTagWPs('DeepCSV',year=year)
     
     self.Nocut = 0
     self.Trigger = 1
     self.GoodMuons = 2
     self.GoodSecondMuon = 3
     self.GoodDiLepton = 4
     self.TotalWeighted = 15
     self.TotalWeighted_no0PU = 16
     
     self.out.cutflow.GetXaxis().SetBinLabel(1+self.Nocut,               "no cut"                 )
     self.out.cutflow.GetXaxis().SetBinLabel(1+self.Trigger,             "trigger"                )
     self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodMuons,           "muon object"            )
     self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodSecondMuon,      "second muon object"     )
     self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodDiLepton,        "mumu pair"              )
     self.out.cutflow.GetXaxis().SetBinLabel(1+self.TotalWeighted,       "no cut, weighted"       )
     self.out.cutflow.GetXaxis().SetBinLabel(1+self.TotalWeighted_no0PU, "no cut, weighted, PU>0" )
     self.out.cutflow.GetXaxis().SetLabelSize(0.041)
    def __init__(self, name, DataType, filelist):

        self.name = name
        self.out = TreeProducer(name)
        self.sample = filelist

        if DataType == 'data':
            self.isData = True
            self.isMC = False
        else:
            self.isData = False
            self.isMC = True
        if not self.isData:
            self.puTool = PileupWeightTool(year=2017)
            self.btagTool = BTagWeightTool('CSVv2',
                                           'medium',
                                           channel='mutau',
                                           year=2017)
Пример #3
0
    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        self.out = wrappedOutputTree
        self.out.branch("isMC", "I")
        self.out.branch("is2016", "I")
        self.out.branch("is2017", "I")
        self.out.branch("is2018", "I")
        self.out.branch("is4m", "I")
        self.out.branch("is4e", "I")
        self.out.branch("is2e2m", "I")
        self.out.branch("isDoubleElectronTrigger", "I")
        self.out.branch("isDoubleMuonTrigger", "I")
        self.out.branch("isMuonElectronTrigger", "I")
        self.out.branch("passedMETFilters", "I")
        self.out.branch("nCleanElectron", "I")
        self.out.branch("nCleanMuon", "I")
        self.out.branch("nCleanTau", "I")
        self.out.branch("nCleanPhoton", "I")
        self.out.branch("nCleanJet", "I")
        self.out.branch("nCleanBTagJet", "I")
        self.out.branch("HT30", "F")
        self.out.branch("iLepton1", "I")
        self.out.branch("iLepton2", "I")
        self.out.branch("iLepton3", "I")
        self.out.branch("iLepton4", "I")
        self.out.branch("Z1_pt", "F")
        self.out.branch("Z1_eta", "F")
        self.out.branch("Z1_phi", "F")
        self.out.branch("Z1_mass", "F")
        self.out.branch("Z1_dEta", "F")
        self.out.branch("Z1_dPhi", "F")
        self.out.branch("Z1_dR", "F")
        self.out.branch("Z2_pt", "F")
        self.out.branch("Z2_eta", "F")
        self.out.branch("Z2_phi", "F")
        self.out.branch("Z2_mass", "F")
        self.out.branch("Z2_dEta", "F")
        self.out.branch("Z2_dPhi", "F")
        self.out.branch("Z2_dR", "F")
        self.out.branch("H_pt", "F")
        self.out.branch("H_eta", "F")
        self.out.branch("H_phi", "F")
        self.out.branch("H_mass", "F")
        self.out.branch("H_dEta", "F")
        self.out.branch("H_dPhi", "F")
        self.out.branch("H_dR", "F")
        self.out.branch("cosThetaStar", "F")
        self.out.branch("cosTheta1", "F")
        self.out.branch("cosTheta2", "F")
        self.out.branch("phi", "F")
        self.out.branch("phi1", "F")
        #self.out.branch("genCosThetaStar", "F")
        #self.out.branch("genCosTheta1", "F")
        #self.out.branch("genPhi1", "F")
        self.out.branch("lumiWeight", "F")
        self.out.branch("lheWeight", "F")
        self.out.branch("stitchWeight", "F")
        self.out.branch("puWeight", "F")
        self.out.branch("topWeight", "F")
        self.out.branch("qcdnloWeight", "F")
        self.out.branch("qcdnnloWeight", "F")
        self.out.branch("ewknloWeight", "F")
        self.out.branch("triggerWeight", "F")
        self.out.branch("leptonWeight", "F")
        self.out.branch("eventWeightLumi", "F")

        self.fileName = inputFile.GetName()
        self.sampleName = getNameFromFile(self.fileName)

        self.isMC = not "Run201" in self.fileName

        if self.verbose >= 0: print "+ Opening file", self.fileName

        # b-tagging working points for DeepCSV
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X
        if "Run2016" in self.fileName or "Summer16" in self.fileName:
            self.year = 2016
            self.lumi = 35920.
            self.btagLoose = 0.2217  #0.0614
            self.btagMedium = 0.6321  #0.3093
            self.btagTight = 0.8953  #0.7221
        elif "Run2017" in self.fileName or "Fall17" in self.fileName:
            self.year = 2017
            self.lumi = 41530.
            self.btagLoose = 0.1522  #0.0521
            self.btagMedium = 0.4941  #0.3033
            self.btagTight = 0.8001  #0.7489
        elif "Run2018" in self.fileName or "Autumn18" in self.fileName:
            self.year = 2018
            self.lumi = 59740.
            self.btagLoose = 0.1241  #0.0494
            self.btagMedium = 0.4184  #0.2770
            self.btagTight = 0.7527  #0.7264
        else:
            if self.verbose >= 0: print "- Unknown year, aborting module"
            import sys
            sys.exit()

        self.xs = XS[self.sampleName] if self.sampleName in XS else 0.
        self.nevents = EV[self.sampleName] if self.sampleName in EV else 0.
        self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1.
        self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1.
        self.isLO = abs(
            self.nevents % 1
        ) < 1.e-6  # if True, the event count is integer, so the weight should be normalized (+1)

        if self.verbose >= 1:
            print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb"
        if self.verbose >= 1:
            print "+ Sample", self.sampleName, ", XS", self.xs, ", events", self.nevents
        if self.verbose >= 1: print "+ Weight", self.lumiWeight
        if self.isMC and self.isLO and self.verbose >= 1:
            print "+ Sample is LO, gen weight will be set to 1"
        #        self.puTool = PileupWeightTool(year = year) if self.isMC else None

        self.DoubleElectronTriggers = [
            "HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL",
            "HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL_DZ",
            "HLT_DoubleEle33_CaloIdL_MW",
            "HLT_Ele16_Ele12_Ele8_CaloIdL_TrackIdL"
        ]
        self.DoubleMuonTriggers = [
            "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL",
            "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass3p8",
            "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass8",
            "HLT_TripleMu_12_10_5", "HLT_TripleMu_10_5_5_DZ"
        ]
        self.MuonElectronTriggers = [
            "HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL",
            "HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_DZ",
            "HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL",
            "HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_DZ",
            "HLT_Mu12_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_DZ",
            "HLT_Mu8_DiEle12_CaloIdL_TrackIdL",
            "HLT_Mu8_DiEle12_CaloIdL_TrackIdL_DZ",
            "HLT_DiMu9_Ele9_CaloIdL_TrackIdL",
            "HLT_DiMu9_Ele9_CaloIdL_TrackIdL_DZ"
        ]

        if self.isMC:
            self.muSFs = MuonSFs(year=self.year)
            self.elSFs = ElectronSFs(year=self.year)
            self.puTool = PileupWeightTool(year=self.year)
Пример #4
0
class HZZ4L(Module):
    def __init__(self):
        self.writeHistFile = True

    def beginJob(self, histFile=None, histDirName=None):
        Module.beginJob(self, histFile, histDirName)
        self.event = 0
        self.hists = {}
        self.hists["Nevents"] = ROOT.TH1F("Nevents", "Nevents", 1, 0, 1)
        #self.hists["Acceptance"] = ROOT.TH1F("Acceptance", "Acceptance", 5, -0.5, 4.5)
        #self.hists["genH_pt"] = ROOT.TH1F("genH_pt", ";generator H p_{T} (GeV)", 100, 0., 100.)
        #self.hists["genH_eta"] = ROOT.TH1F("genH_eta", ";generator H #eta", 100, -5., 5.)
        #self.hists["genH_phi"] = ROOT.TH1F("genH_phi", ";generator H #phi", 100, -3.15, 3.15)
        #self.hists["genH_mass"] = ROOT.TH1F("genH_mass", ";generator H mass", 300, 0., 150.)
        #self.hists["genJPsi_pt"] = ROOT.TH1F("genJPsi_pt", ";generator J/#Psi p_{T} (GeV)", 100, 0., 100.)
        #self.hists["genJPsi_eta"] = ROOT.TH1F("genJPsi_eta", ";generator J/#Psi #eta", 100, -5., 5.)
        #self.hists["genJPsi_phi"] = ROOT.TH1F("genJPsi_phi", ";generator J/#Psi #phi", 100, -3.15, 3.15)
        #self.hists["genJPsi_mass"] = ROOT.TH1F("genJPsi_mass", ";generator J/#Psi mass", 200, 0., 4.)
        #self.hists["genPhoton_pt"] = ROOT.TH1F("genPhoton_pt", ";generator #gamma p_{T} (GeV)", 100, 0., 100.)
        #self.hists["genPhoton_eta"] = ROOT.TH1F("genPhoton_eta", ";generator #gamma #eta", 100, -5., 5.)
        #self.hists["genMuon1_pt"] = ROOT.TH1F("genMuon1_pt", ";generator #mu^{-} p_{T} (GeV)", 100, 0., 100.)
        #self.hists["genMuon1_eta"] = ROOT.TH1F("genMuon1_eta", ";generator #mu^{-} #eta", 100, -5., 5.)
        #self.hists["genMuon2_pt"] = ROOT.TH1F("genMuon2_pt", ";generator #mu^{+} p_{T} (GeV)", 100, 0., 100.)
        #self.hists["genMuon2_eta"] = ROOT.TH1F("genMuon2_eta", ";generator #mu^{+} #eta", 100, -5., 5.)

        #self.hists["genCosThetaStar"] = ROOT.TH1F("genCosThetaStar", ";cos #theta^{*}", 100, -1., 1.)
        #self.hists["genCosTheta1"] = ROOT.TH1F("genCosTheta1", ";cos #theta_{1}", 100, -1., 1.)
        #self.hists["genPhi1"] = ROOT.TH1F("genPhi1", ";#Phi_{1}", 100, -3.1415, 3.1415)
        #self.hists["genCosThetaStarZtoMM"] = ROOT.TH1F("genCosThetaStarZtoMM", ";cos #theta^{*}", 100, -1., 1.)

        self.hists["Cutflow"] = ROOT.TH1F("Cutflow", "Cutflow", 10, -0.5, 9.5)
        self.hists["Cutflow"].GetXaxis().SetBinLabel(1, "All events")
        self.hists["Cutflow"].GetXaxis().SetBinLabel(2, "Acceptance")
        #        self.addObject(self.h_events)
        #        self.h_events.SetDirectory
        self.verbose = -1

    def endJob(self):
        Module.endJob(self)
        print "+ Module ended successfully,"  #, self.h_events.GetEntries(), "events analyzed"
        pass

    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        self.out = wrappedOutputTree
        self.out.branch("isMC", "I")
        self.out.branch("is2016", "I")
        self.out.branch("is2017", "I")
        self.out.branch("is2018", "I")
        self.out.branch("is4m", "I")
        self.out.branch("is4e", "I")
        self.out.branch("is2e2m", "I")
        self.out.branch("isDoubleElectronTrigger", "I")
        self.out.branch("isDoubleMuonTrigger", "I")
        self.out.branch("isMuonElectronTrigger", "I")
        self.out.branch("passedMETFilters", "I")
        self.out.branch("nCleanElectron", "I")
        self.out.branch("nCleanMuon", "I")
        self.out.branch("nCleanTau", "I")
        self.out.branch("nCleanPhoton", "I")
        self.out.branch("nCleanJet", "I")
        self.out.branch("nCleanBTagJet", "I")
        self.out.branch("HT30", "F")
        self.out.branch("iLepton1", "I")
        self.out.branch("iLepton2", "I")
        self.out.branch("iLepton3", "I")
        self.out.branch("iLepton4", "I")
        self.out.branch("Z1_pt", "F")
        self.out.branch("Z1_eta", "F")
        self.out.branch("Z1_phi", "F")
        self.out.branch("Z1_mass", "F")
        self.out.branch("Z1_dEta", "F")
        self.out.branch("Z1_dPhi", "F")
        self.out.branch("Z1_dR", "F")
        self.out.branch("Z2_pt", "F")
        self.out.branch("Z2_eta", "F")
        self.out.branch("Z2_phi", "F")
        self.out.branch("Z2_mass", "F")
        self.out.branch("Z2_dEta", "F")
        self.out.branch("Z2_dPhi", "F")
        self.out.branch("Z2_dR", "F")
        self.out.branch("H_pt", "F")
        self.out.branch("H_eta", "F")
        self.out.branch("H_phi", "F")
        self.out.branch("H_mass", "F")
        self.out.branch("H_dEta", "F")
        self.out.branch("H_dPhi", "F")
        self.out.branch("H_dR", "F")
        self.out.branch("cosThetaStar", "F")
        self.out.branch("cosTheta1", "F")
        self.out.branch("cosTheta2", "F")
        self.out.branch("phi", "F")
        self.out.branch("phi1", "F")
        #self.out.branch("genCosThetaStar", "F")
        #self.out.branch("genCosTheta1", "F")
        #self.out.branch("genPhi1", "F")
        self.out.branch("lumiWeight", "F")
        self.out.branch("lheWeight", "F")
        self.out.branch("stitchWeight", "F")
        self.out.branch("puWeight", "F")
        self.out.branch("topWeight", "F")
        self.out.branch("qcdnloWeight", "F")
        self.out.branch("qcdnnloWeight", "F")
        self.out.branch("ewknloWeight", "F")
        self.out.branch("triggerWeight", "F")
        self.out.branch("leptonWeight", "F")
        self.out.branch("eventWeightLumi", "F")

        self.fileName = inputFile.GetName()
        self.sampleName = getNameFromFile(self.fileName)

        self.isMC = not "Run201" in self.fileName

        if self.verbose >= 0: print "+ Opening file", self.fileName

        # b-tagging working points for DeepCSV
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X
        if "Run2016" in self.fileName or "Summer16" in self.fileName:
            self.year = 2016
            self.lumi = 35920.
            self.btagLoose = 0.2217  #0.0614
            self.btagMedium = 0.6321  #0.3093
            self.btagTight = 0.8953  #0.7221
        elif "Run2017" in self.fileName or "Fall17" in self.fileName:
            self.year = 2017
            self.lumi = 41530.
            self.btagLoose = 0.1522  #0.0521
            self.btagMedium = 0.4941  #0.3033
            self.btagTight = 0.8001  #0.7489
        elif "Run2018" in self.fileName or "Autumn18" in self.fileName:
            self.year = 2018
            self.lumi = 59740.
            self.btagLoose = 0.1241  #0.0494
            self.btagMedium = 0.4184  #0.2770
            self.btagTight = 0.7527  #0.7264
        else:
            if self.verbose >= 0: print "- Unknown year, aborting module"
            import sys
            sys.exit()

        self.xs = XS[self.sampleName] if self.sampleName in XS else 0.
        self.nevents = EV[self.sampleName] if self.sampleName in EV else 0.
        self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1.
        self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1.
        self.isLO = abs(
            self.nevents % 1
        ) < 1.e-6  # if True, the event count is integer, so the weight should be normalized (+1)

        if self.verbose >= 1:
            print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb"
        if self.verbose >= 1:
            print "+ Sample", self.sampleName, ", XS", self.xs, ", events", self.nevents
        if self.verbose >= 1: print "+ Weight", self.lumiWeight
        if self.isMC and self.isLO and self.verbose >= 1:
            print "+ Sample is LO, gen weight will be set to 1"
        #        self.puTool = PileupWeightTool(year = year) if self.isMC else None

        self.DoubleElectronTriggers = [
            "HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL",
            "HLT_Ele23_Ele12_CaloIdL_TrackIdL_IsoVL_DZ",
            "HLT_DoubleEle33_CaloIdL_MW",
            "HLT_Ele16_Ele12_Ele8_CaloIdL_TrackIdL"
        ]
        self.DoubleMuonTriggers = [
            "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL",
            "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass3p8",
            "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass8",
            "HLT_TripleMu_12_10_5", "HLT_TripleMu_10_5_5_DZ"
        ]
        self.MuonElectronTriggers = [
            "HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL",
            "HLT_Mu8_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_DZ",
            "HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL",
            "HLT_Mu23_TrkIsoVVL_Ele12_CaloIdL_TrackIdL_IsoVL_DZ",
            "HLT_Mu12_TrkIsoVVL_Ele23_CaloIdL_TrackIdL_IsoVL_DZ",
            "HLT_Mu8_DiEle12_CaloIdL_TrackIdL",
            "HLT_Mu8_DiEle12_CaloIdL_TrackIdL_DZ",
            "HLT_DiMu9_Ele9_CaloIdL_TrackIdL",
            "HLT_DiMu9_Ele9_CaloIdL_TrackIdL_DZ"
        ]

        if self.isMC:
            self.muSFs = MuonSFs(year=self.year)
            self.elSFs = ElectronSFs(year=self.year)
            self.puTool = PileupWeightTool(year=self.year)

    def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        outputFile.mkdir("Hists")
        outputFile.cd("Hists")
        for histname, hist in self.hists.iteritems():
            hist.Write()
        outputFile.cd("..")
        if self.verbose >= 0: print "+ File closed successfully"
        pass

    def analyze(self, event):
        eventWeightLumi, lheWeight, stitchWeight, puWeight, qcdnloWeight, qcdnnloWeight, ewknloWeight, topWeight = 1., 1., 1., 1., 1., 1., 1., 1.
        triggerWeight, leptonWeight = 1., 1.
        isDoubleElectronTrigger, isDoubleMuonTrigger, isMuonElectronTrigger = False, False, False
        nCleanElectron, nCleanMuon, nCleanTau, nCleanPhoton, nCleanJet, nCleanBTagJet, HT30 = 0, 0, 0, 0, 0, 0, 0
        cosThetaStar, cosTheta1, cosTheta2, phi, phi1 = -2., -2., -2., -4., -4.
        is4e, is4m, is2e2m = False, False, False

        for t in self.DoubleElectronTriggers:
            if hasattr(event, t) and getattr(event, t):
                isDoubleElectronTrigger = True
        for t in self.DoubleMuonTriggers:
            if hasattr(event, t) and getattr(event, t):
                isDoubleMuonTrigger = True
        for t in self.MuonElectronTriggers:
            if hasattr(event, t) and getattr(event, t):
                isMuonElectronTrigger = True

        lheWeight = 1.

        if self.isMC:
            # Event weight
            if not self.isLO and hasattr(event, "LHEWeight_originalXWGTUP"):
                lheWeight = event.LHEWeight_originalXWGTUP

            # PU weight
            puWeight = self.puTool.getWeight(event.Pileup_nTrueInt)

        self.hists["Cutflow"].Fill(1, lheWeight)

        cleanElectrons, cleanMuons = [], []

        # Electrons
        for i in range(event.nElectron):
            if event.Electron_pt[i] > 7. and abs(
                    event.Electron_eta[i]
            ) < 2.5 and event.Electron_mvaFall17V2Iso_WP90[i] and abs(
                    event.Electron_dxy[i]) < 0.5 and abs(
                        event.Electron_dz[i]
                    ) < 1.0 and event.Electron_sip3d[i] < 4.:
                cleanElectrons += [i]

        # Muons
        for i in range(event.nMuon):
            if event.Muon_pt[i] > 5. and abs(event.Muon_eta[i]) < 2.4 and abs(
                    event.Muon_dxy[i]) < 0.5 and abs(
                        event.Muon_dz[i]) < 1.0 and event.Muon_looseId[
                            i] and event.Muon_pfRelIso03_all[
                                i] < 0.35 and event.Muon_sip3d[i] < 4.:
                cleanMuons += [i]

        il1, il2, il3, il4 = -1, -1, -1, -1
        l1, l2, l3, l4, z1, z2 = TLorentzVector(), TLorentzVector(
        ), TLorentzVector(), TLorentzVector(), TLorentzVector(
        ), TLorentzVector()
        lm1, lp1, lm2, lp2 = TLorentzVector(), TLorentzVector(
        ), TLorentzVector(), TLorentzVector()

        # ZZ -> 4mu
        if len(cleanMuons) >= 4:

            # Try to reconstruct Z1
            for i in range(len(cleanMuons)):
                for j in range(len(cleanMuons)):
                    if i == j or (il1 >= 0 and il2 >= 0): continue
                    if event.Muon_charge[i] * event.Muon_charge[j] > 0:
                        continue
                    l1.SetPtEtaPhiM(event.Muon_pt[i], event.Muon_eta[i],
                                    event.Muon_phi[i], event.Muon_mass[i])
                    l2.SetPtEtaPhiM(event.Muon_pt[j], event.Muon_eta[j],
                                    event.Muon_phi[j], event.Muon_mass[j])
                    if 40 < (l1 + l2).M() < 120.:
                        z1, il1, il2 = (l1 + l2), i, j
                        lm1, lp1 = (l1,
                                    l2) if event.Muon_charge[i] < 0 else (l2,
                                                                          l1)

            # Look for Z2
            for i in range(len(cleanMuons)):
                for j in range(len(cleanMuons)):
                    if i == j or i == il1 or j == il1 or i == il2 or j == il2 or (
                            il3 >= 0 and il4 >= 0):
                        continue
                    if event.Muon_charge[i] * event.Muon_charge[j] > 0:
                        continue
                    l3.SetPtEtaPhiM(event.Muon_pt[i], event.Muon_eta[i],
                                    event.Muon_phi[i], event.Muon_mass[i])
                    l4.SetPtEtaPhiM(event.Muon_pt[j], event.Muon_eta[j],
                                    event.Muon_phi[j], event.Muon_mass[j])
                    if (l3 + l4).M() > 4.:
                        z2, il3, il4 = (l3 + l4), i, j
                        lm2, lp2 = (l3,
                                    l4) if event.Muon_charge[i] < 0 else (l4,
                                                                          l3)

            if il1 >= 0 and il2 >= 0 and il3 >= 0 and il4 >= 0 and isDoubleMuonTrigger:
                is4m = True

        # ZZ -> 4e
        elif len(cleanElectrons) >= 4:

            # Try to reconstruct Z1
            for i in range(len(cleanElectrons)):
                for j in range(len(cleanElectrons)):
                    if i == j or (il1 >= 0 and il2 >= 0): continue
                    if event.Electron_charge[i] * event.Electron_charge[j] > 0:
                        continue
                    l1.SetPtEtaPhiM(event.Electron_pt[i],
                                    event.Electron_eta[i],
                                    event.Electron_phi[i],
                                    event.Electron_mass[i])
                    l2.SetPtEtaPhiM(event.Electron_pt[j],
                                    event.Electron_eta[j],
                                    event.Electron_phi[j],
                                    event.Electron_mass[j])
                    if 40 < (l1 + l2).M() < 120.:
                        z1, il1, il2 = (l1 + l2), i, j
                        lm1, lp1 = (l1,
                                    l2) if event.Muon_charge[i] < 0 else (l2,
                                                                          l1)

            # Look for Z2
            for i in range(len(cleanElectrons)):
                for j in range(len(cleanElectrons)):
                    if i == j or i == il1 or j == il1 or i == il2 or j == il2 or (
                            il3 >= 0 and il4 >= 0):
                        continue
                    if event.Electron_charge[i] * event.Electron_charge[j] > 0:
                        continue
                    l3.SetPtEtaPhiM(event.Electron_pt[i],
                                    event.Electron_eta[i],
                                    event.Electron_phi[i],
                                    event.Electron_mass[i])
                    l4.SetPtEtaPhiM(event.Electron_pt[j],
                                    event.Electron_eta[j],
                                    event.Electron_phi[j],
                                    event.Electron_mass[j])
                    if (l3 + l4).M() > 4.:
                        z2, il3, il4 = (l3 + l4), i, j
                        lm2, lp2 = (l3,
                                    l4) if event.Muon_charge[i] < 0 else (l4,
                                                                          l3)

            if il1 >= 0 and il2 >= 0 and il3 >= 0 and il4 >= 0 and isDoubleElectronTrigger:
                is4e = True

        # ZZ -> 2e2mu
        elif len(cleanMuons) >= 2 and len(cleanElectrons) >= 2:

            # Try to reconstruct Z1 (mumu)
            for i in range(len(cleanMuons)):
                for j in range(len(cleanMuons)):
                    if i == j or (il1 >= 0 and il2 >= 0): continue
                    if event.Muon_charge[i] * event.Muon_charge[j] > 0:
                        continue
                    l1.SetPtEtaPhiM(event.Muon_pt[i], event.Muon_eta[i],
                                    event.Muon_phi[i], event.Muon_mass[i])
                    l2.SetPtEtaPhiM(event.Muon_pt[j], event.Muon_eta[j],
                                    event.Muon_phi[j], event.Muon_mass[j])
                    if (l1 + l2).M() > 4.:
                        z1, il1, il2 = (l1 + l2), i, j
                        lm1, lp1 = (l1,
                                    l2) if event.Muon_charge[i] < 0 else (l2,
                                                                          l1)

            # Look for Z2 (ee)
            for i in range(len(cleanElectrons)):
                for j in range(len(cleanElectrons)):
                    if i == j or (il3 >= 0 and il3 >= 0): continue
                    if event.Electron_charge[i] * event.Electron_charge[j] > 0:
                        continue
                    l3.SetPtEtaPhiM(event.Electron_pt[i],
                                    event.Electron_eta[i],
                                    event.Electron_phi[i],
                                    event.Electron_mass[i])
                    l4.SetPtEtaPhiM(event.Electron_pt[j],
                                    event.Electron_eta[j],
                                    event.Electron_phi[j],
                                    event.Electron_mass[j])
                    if (l3 + l4).M() > 4.:
                        z2, il3, il4 = (l3 + l4), i, j
                        lm2, lp2 = (l3,
                                    l4) if event.Muon_charge[i] < 0 else (l4,
                                                                          l3)

            # Swap Z1 and Z2 if needed
            if z2.M() > z1.M():
                z1, z2 = z2, z1
                l1, l2, l3, l4 = l3, l4, l1, l2
                lm1, lp1, lm2, lp2 = lm2, lp2, lm1, lp1
                il1, il2, il3, il4 = il3, il4, il1, il2

            if il1 >= 0 and il2 >= 0 and il3 >= 0 and il4 >= 0 and (
                    40. < z1.M() < 120.) and z2.M() > 4. and (
                        isDoubleElectronTrigger or isDoubleMuonTrigger
                        or isMuonElectronTrigger):
                is2e2m = True

        if not is4m and not is4e and not is2e2m:
            if self.verbose >= 2: print "- No ZZ candidate reconstructed"
            return False

        self.hists["Cutflow"].Fill(2, lheWeight)

        h = z1 + z2

        z1_pt = z1.Pt()
        z1_eta = z1.Eta()
        z1_phi = z1.Phi()
        z1_mass = z1.M()
        z1_dEta = abs(l1.Eta() - l2.Eta())
        z1_dPhi = abs(l1.DeltaPhi(l2))
        z1_dR = l1.DeltaR(l2)

        z2_pt = z2.Pt()
        z2_eta = z2.Eta()
        z2_phi = z2.Phi()
        z2_mass = z2.M()
        z2_dEta = abs(l3.Eta() - l4.Eta())
        z2_dPhi = abs(l3.DeltaPhi(l4))
        z2_dR = l3.DeltaR(l4)

        h_pt = h.Pt()
        h_eta = h.Eta()
        h_phi = h.Phi()
        h_mass = h.M()
        h_dEta = abs(z1.Eta() - z2.Eta())
        h_dPhi = abs(z1.DeltaPhi(z2))
        h_dR = z1.DeltaR(z2)

        cosThetaStar = self.returnCosThetaStar(h, z1)
        cosTheta1 = self.returnCosTheta1(z1, lp1, lm1, z2)
        cosTheta2 = self.returnCosTheta1(z2, lp2, lm2, z1)
        phi = self.returnPhi(h, lp1, lm1, lp2, lm2)
        phi1 = self.returnPhi1(h, lp1, lm1)

        # Weights
        if self.isMC:
            if is4e: triggerWeight = 0.982 / 0.991
            elif is4m: triggerWeight = 1.000 / 0.997
            elif is2e2m: triggerWeight = 0.983 / 0.995
#            IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0], event.Muon_eta[0], 2)
#            IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0], event.Muon_eta[0])
#            IdSF2 = self.muSFs.getIdSF(event.Muon_pt[1], event.Muon_eta[1], 2)
#            IsoSF2 = self.muSFs.getIsoSF(event.Muon_pt[1], event.Muon_eta[1])
#            IdIsoSF3 = self.elSFs.getIdIsoSF(event.Electron_pt[0], event.Electron_eta[0])
#            leptonWeight = IdSF1 * IsoSF1 * IdSF2 * IsoSF2 * IdIsoSF3

        passedMETFilters = True
        filters = [
            "Flag_goodVertices", "Flag_globalSuperTightHalo2016Filter",
            "Flag_BadPFMuonFilter", "Flag_EcalDeadCellTriggerPrimitiveFilter",
            "Flag_HBHENoiseFilter", "Flag_HBHENoiseIsoFilter",
            "Flag_ecalBadCalibFilter", "Flag_ecalBadCalibFilterV2"
        ]
        if not self.isMC: filters += ["Flag_eeBadScFilter"]
        for f in filters:
            if hasattr(event, f) and getattr(event, f) == False:
                passedMETFilters = False

        ### Event variables ###

        # Muons
        nCleanMuon = len(cleanMuons)

        # Electrons
        nCleanElectron = len(cleanElectrons)

        # Taus
        for i in range(event.nTau):
            if event.Tau_pt[i] > 20. and abs(
                    event.Tau_eta[i]) < 2.5 and event.Tau_idDeepTau2017v2p1VSe[
                        i] >= 16 and event.Tau_idDeepTau2017v2p1VSmu[
                            i] >= 8 and event.Tau_idDeepTau2017v2p1VSjet[
                                i] >= 16 and event.Tau_rawIsodR03[i] < 0.15:
                nCleanTau += 1

        # Photons
        for i in range(event.nPhoton):
            if event.Photon_pt[i] > 15. and abs(
                    event.Photon_eta[i]) < 2.5 and event.Photon_pfRelIso03_all[
                        i] < 0.15 and event.Photon_mvaID_WP90[i]:
                nCleanPhoton += 1

        # Jets and Event variables
        for i in range(event.nJet):
            if event.Jet_jetId[i] >= 6 and abs(event.Jet_eta[i]) < 2.5:
                HT30 += event.Jet_pt[i]
                nCleanJet += 1
                if event.Jet_btagDeepB[i] >= self.btagMedium:
                    nCleanBTagJet += 1

        if self.isMC:
            eventWeightLumi = self.lumiWeight * lheWeight * puWeight * topWeight * qcdnloWeight * qcdnnloWeight * ewknloWeight * triggerWeight * leptonWeight

        self.out.fillBranch("isMC", self.isMC)
        self.out.fillBranch("is2016", (self.year == 2016))
        self.out.fillBranch("is2017", (self.year == 2017))
        self.out.fillBranch("is2018", (self.year == 2018))
        self.out.fillBranch("is4m", is4m)
        self.out.fillBranch("is4e", is4e)
        self.out.fillBranch("is2e2m", is2e2m)
        self.out.fillBranch("isDoubleElectronTrigger", isDoubleElectronTrigger)
        self.out.fillBranch("isDoubleMuonTrigger", isDoubleMuonTrigger)
        self.out.fillBranch("isMuonElectronTrigger", isMuonElectronTrigger)
        self.out.fillBranch("passedMETFilters", passedMETFilters)
        self.out.fillBranch("nCleanElectron", nCleanElectron)
        self.out.fillBranch("nCleanMuon", nCleanMuon)
        self.out.fillBranch("nCleanTau", nCleanTau)
        self.out.fillBranch("nCleanPhoton", nCleanPhoton)
        self.out.fillBranch("nCleanJet", nCleanJet)
        self.out.fillBranch("nCleanBTagJet", nCleanBTagJet)
        self.out.fillBranch("HT30", HT30)
        self.out.fillBranch("iLepton1", il1)
        self.out.fillBranch("iLepton2", il2)
        self.out.fillBranch("iLepton3", il3)
        self.out.fillBranch("iLepton4", il4)
        self.out.fillBranch("Z1_pt", z1_pt)
        self.out.fillBranch("Z1_eta", z1_eta)
        self.out.fillBranch("Z1_phi", z1_phi)
        self.out.fillBranch("Z1_mass", z1_mass)
        self.out.fillBranch("Z1_dEta", z1_dEta)
        self.out.fillBranch("Z1_dPhi", z1_dPhi)
        self.out.fillBranch("Z1_dR", z1_dR)
        self.out.fillBranch("Z2_pt", z2_pt)
        self.out.fillBranch("Z2_eta", z2_eta)
        self.out.fillBranch("Z2_phi", z2_phi)
        self.out.fillBranch("Z2_mass", z2_mass)
        self.out.fillBranch("Z2_dEta", z2_dEta)
        self.out.fillBranch("Z2_dPhi", z2_dPhi)
        self.out.fillBranch("Z2_dR", z2_dR)
        self.out.fillBranch("H_pt", h_pt)
        self.out.fillBranch("H_eta", h_eta)
        self.out.fillBranch("H_phi", h_phi)
        self.out.fillBranch("H_mass", h_mass)
        self.out.fillBranch("H_dEta", h_dEta)
        self.out.fillBranch("H_dPhi", h_dPhi)
        self.out.fillBranch("H_dR", h_dR)
        self.out.fillBranch("cosThetaStar", cosThetaStar)
        self.out.fillBranch("cosTheta1", cosTheta1)
        self.out.fillBranch("cosTheta2", cosTheta2)
        self.out.fillBranch("phi", phi)
        self.out.fillBranch("phi1", phi1)
        #self.out.fillBranch("genCosThetaStar", genCosThetaStar)
        #self.out.fillBranch("genCosTheta1", genCosTheta1)
        #self.out.fillBranch("genPhi1", genPhi1)
        self.out.fillBranch("lumiWeight", self.lumiWeight)
        self.out.fillBranch("lheWeight", lheWeight)
        self.out.fillBranch("stitchWeight", stitchWeight)
        self.out.fillBranch("puWeight", puWeight)
        self.out.fillBranch("topWeight", topWeight)
        self.out.fillBranch("qcdnloWeight", qcdnloWeight)
        self.out.fillBranch("qcdnnloWeight", qcdnnloWeight)
        self.out.fillBranch("ewknloWeight", ewknloWeight)
        self.out.fillBranch("triggerWeight", triggerWeight)
        self.out.fillBranch("leptonWeight", leptonWeight)
        self.out.fillBranch("eventWeightLumi", eventWeightLumi)

        if self.verbose >= 2: print "+ Tree filled"

        return True

    def returnCosThetaStar(self, theH, theJPsi):
        h, j = TLorentzVector(theH), TLorentzVector(theJPsi)
        # Boost the Z to the A rest frame
        j.Boost(-h.BoostVector())
        value = j.CosTheta()
        if value != value or math.isinf(value): return -2.
        return value

    def returnCosTheta1(self, theJPsi, theL1, theL2, thePhoton):
        j, l1, l2, g = TLorentzVector(theJPsi), TLorentzVector(
            theL1), TLorentzVector(theL2), TLorentzVector(thePhoton)
        # Boost objects to the JPsi rest frame
        l1.Boost(-j.BoostVector())
        l2.Boost(-j.BoostVector())
        g.Boost(-j.BoostVector())
        # cos theta = Gamma dot L1 / (|Gamma|*|L1|)
        value = g.Vect().Dot(l1.Vect()) / (
            (g.Vect().Mag()) * (l1.Vect().Mag())
        ) if g.Vect().Mag() > 0. and l1.Vect().Mag() > 0. else -2
        if value != value or math.isinf(value): return -2.
        return value

    def returnPhi1(self, theH, theL1, theL2):
        h, l1, l2 = TLorentzVector(theH), TLorentzVector(
            theL1), TLorentzVector(theL2)
        beamAxis = TVector3(0., 0., 1.)
        # Boost objects to the A rest frame
        l1.Boost(-h.BoostVector())
        l2.Boost(-h.BoostVector())
        # Reconstruct JPsi in H rest frame
        j = l1 + l2
        # Build unit vectors orthogonal to the decay planes
        Zplane = TVector3(l1.Vect().Cross(l2.Vect()))  # L1 x L2
        Bplane = TVector3(beamAxis.Cross(
            j.Vect()))  # Beam x JPsi, beam/JPsi plane
        if Zplane.Mag() == 0. or Bplane.Mag() == 0.: return -4.
        Zplane.SetMag(1.)
        Bplane.SetMag(1.)
        # Sign of Phi1
        sgn = j.Vect().Dot(Zplane.Cross(Bplane))
        sgn /= abs(sgn)
        if abs(Zplane.Dot(Bplane)) > 1.: return -5.
        value = sgn * math.acos(Zplane.Dot(Bplane))
        if value != value or math.isinf(value): return -5.
        return value

    def returnPhi(self, theH, theL1, theL2, theL3, theL4):
        h, l1, l2, l3, l4 = TLorentzVector(theH), TLorentzVector(
            theL1), TLorentzVector(theL2), TLorentzVector(
                theL3), TLorentzVector(theL4)
        # Boost objects to the A rest frame
        l1.Boost(-h.BoostVector())
        l2.Boost(-h.BoostVector())
        l3.Boost(-h.BoostVector())
        l4.Boost(-h.BoostVector())
        # Build unit vectors orthogonal to the decay planes
        Zplane = l1.Vect().Cross(l2.Vect())  # L1 x L2
        Hplane = l3.Vect().Cross(l4.Vect())  # B1 x B2
        Zplane.SetMag(1.)
        Hplane.SetMag(1.)
        # Sign of Phi
        z1 = l1 + l2
        sgn = 1 if z1.Vect().Dot(Zplane.Cross(Hplane)) > 0 else -1
        value = sgn * math.acos(Zplane.Dot(Hplane))
        if value != value or math.isinf(value): return -5.
        return value
Пример #5
0
    def __init__(self, name, dataType, **kwargs):

        year = kwargs.get('year', 2017)
        tes = kwargs.get('tes', 1.0)
        channel = 'eletau'

        self.name = name
        self.year = year
        self.tes = tes
        self.out = TreeProducerEleTau(name)
        self.isData = dataType == 'data'
        self.doZpt = 'DY' in self.name

        setYear(year)
        self.vlooseIso = getVLooseTauIso(year)
        if year == 2016:
            self.trigger = lambda e: e.HLT_Ele25_eta2p1_WPTight_Gsf or e.HLT_Ele45_WPLoose_Gsf_L1JetTauSeeded  #or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20_SingleL1 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau30
            self.electronCutPt = 26
        else:
            # HLT_Ele32_WPTight_Gsf_L1DoubleEG
            # HLT_Ele32_WPTight_Gsf
            self.trigger = lambda e: e.HLT_Ele35_WPTight_Gsf or e.HLT_Ele32_WPTight_Gsf
            self.electronCutPt = 36
        self.tauCutPt = 20

        if not self.isData:
            self.eleSFs = ElectronSFs(year=year)
            self.puTool = PileupWeightTool(year=year)
            self.ltfSFs = LeptonTauFakeSFs('loose', 'tight', year=year)
            self.btagTool = BTagWeightTool('CSVv2',
                                           'medium',
                                           channel=channel,
                                           year=year)
            self.btagTool_deep = BTagWeightTool('DeepCSV',
                                                'medium',
                                                channel=channel,
                                                year=year)
            if self.doZpt:
                self.recoilTool = RecoilCorrectionTool(year=year)
        self.csvv2_wp = BTagWPs('CSVv2', year=year)
        self.deepcsv_wp = BTagWPs('DeepCSV', year=year)

        self.Nocut = 0
        self.Trigger = 1
        self.GoodElectrons = 2
        self.GoodTaus = 3
        self.GoodDiLepton = 4
        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16

        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodElectrons,
                                                "electron object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus,
                                                "tau object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton,
                                                "eletau pair")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted,
                                                "no cut, weighted")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU,
                                                "no cut, weighted, PU>0")
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)
Пример #6
0
class EleTauProducer(Module):
    def __init__(self, name, dataType, **kwargs):

        year = kwargs.get('year', 2017)
        tes = kwargs.get('tes', 1.0)
        channel = 'eletau'

        self.name = name
        self.year = year
        self.tes = tes
        self.out = TreeProducerEleTau(name)
        self.isData = dataType == 'data'
        self.doZpt = 'DY' in self.name

        setYear(year)
        self.vlooseIso = getVLooseTauIso(year)
        if year == 2016:
            self.trigger = lambda e: e.HLT_Ele25_eta2p1_WPTight_Gsf or e.HLT_Ele45_WPLoose_Gsf_L1JetTauSeeded  #or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20_SingleL1 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau30
            self.electronCutPt = 26
        else:
            # HLT_Ele32_WPTight_Gsf_L1DoubleEG
            # HLT_Ele32_WPTight_Gsf
            self.trigger = lambda e: e.HLT_Ele35_WPTight_Gsf or e.HLT_Ele32_WPTight_Gsf
            self.electronCutPt = 36
        self.tauCutPt = 20

        if not self.isData:
            self.eleSFs = ElectronSFs(year=year)
            self.puTool = PileupWeightTool(year=year)
            self.ltfSFs = LeptonTauFakeSFs('loose', 'tight', year=year)
            self.btagTool = BTagWeightTool('CSVv2',
                                           'medium',
                                           channel=channel,
                                           year=year)
            self.btagTool_deep = BTagWeightTool('DeepCSV',
                                                'medium',
                                                channel=channel,
                                                year=year)
            if self.doZpt:
                self.recoilTool = RecoilCorrectionTool(year=year)
        self.csvv2_wp = BTagWPs('CSVv2', year=year)
        self.deepcsv_wp = BTagWPs('DeepCSV', year=year)

        self.Nocut = 0
        self.Trigger = 1
        self.GoodElectrons = 2
        self.GoodTaus = 3
        self.GoodDiLepton = 4
        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16

        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodElectrons,
                                                "electron object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus,
                                                "tau object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton,
                                                "eletau pair")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted,
                                                "no cut, weighted")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU,
                                                "no cut, weighted, PU>0")
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)

    def beginJob(self):
        pass

    def endJob(self):
        if not self.isData:
            self.btagTool.setDirectory(self.out.outputfile, 'btag')
            self.btagTool_deep.setDirectory(self.out.outputfile, 'btag')
        self.out.outputfile.Write()
        self.out.outputfile.Close()

    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        pass

    def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        pass

    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""

        #electrons = Collection(event, "Electron")

        #####################################
        self.out.cutflow.Fill(self.Nocut)
        if self.isData:
            self.out.cutflow.Fill(self.TotalWeighted, 1.)
            if event.PV_npvs > 0:
                self.out.cutflow.Fill(self.TotalWeighted_no0PU, 1.)
            else:
                return False
        else:
            self.out.cutflow.Fill(self.TotalWeighted, event.genWeight)
            if event.Pileup_nTrueInt > 0:
                self.out.cutflow.Fill(self.TotalWeighted_no0PU,
                                      event.genWeight)
            else:
                return False
        #####################################

        if not self.trigger(event):
            return False

        #####################################
        self.out.cutflow.Fill(self.Trigger)
        #####################################

        idx_goodelectrons = []
        for ielectron in range(event.nElectron):
            if event.Electron_pt[ielectron] < self.electronCutPt: continue
            if abs(event.Electron_eta[ielectron]) > 2.1: continue
            if abs(event.Electron_dz[ielectron]) > 0.2: continue
            if abs(event.Electron_dxy[ielectron]) > 0.045: continue
            if event.Electron_convVeto[ielectron] != 1: continue
            if ord(event.Electron_lostHits[ielectron]) > 1: continue
            if getvar(event, 'Electron_mvaFall17Iso_WP80')[ielectron] < 0.5:
                continue
            idx_goodelectrons.append(ielectron)

        if len(idx_goodelectrons) == 0:
            return False

        #####################################
        self.out.cutflow.Fill(self.GoodElectrons)
        #####################################

        idx_goodtaus = []
        for itau in range(event.nTau):
            if event.Tau_pt[itau] < self.tauCutPt: continue
            if abs(event.Tau_eta[itau]) > 2.3: continue
            if abs(event.Tau_dz[itau]) > 0.2: continue
            if event.Tau_decayMode[itau] not in [0, 1, 10]: continue
            if abs(event.Tau_charge[itau]) != 1: continue
            #if ord(event.Tau_idAntiEle[itau])<1: continue
            #if ord(event.Tau_idAntiMu[itau])<1: continue
            if not self.vlooseIso(event, itau): continue
            idx_goodtaus.append(itau)

        if len(idx_goodtaus) == 0:
            return False

        #####################################
        self.out.cutflow.Fill(self.GoodTaus)
        #####################################

        electrons = Collection(event, 'Electron')
        taus = Collection(event, 'Tau')
        ltaus = []
        for idx1 in idx_goodelectrons:
            for idx2 in idx_goodtaus:
                dR = taus[idx2].p4().DeltaR(electrons[idx1].p4())
                if dR < 0.5: continue
                ltau = LeptonTauPair(idx1, event.Electron_pt[idx1],
                                     event.Electron_pfRelIso03_all[idx1], idx2,
                                     event.Tau_pt[idx2],
                                     event.Tau_rawMVAoldDM2017v2[idx2])
                ltaus.append(ltau)

        if len(ltaus) == 0:
            return False

        ltau = bestDiLepton(ltaus)
        electron = electrons[ltau.id1].p4()
        tau = taus[ltau.id2].p4()
        #print 'chosen tau1 (idx, pt) = ', ltau.id1, ltau.tau1_pt, 'check', electron.p4().Pt()
        #print 'chosen tau2 (idx, pt) = ', ltau.id2, ltau.tau2_pt, 'check', tau.p4().Pt()

        #####################################
        self.out.cutflow.Fill(self.GoodDiLepton)
        #####################################

        jetIds = []
        bjetIds = []
        jets = Collection(event, 'Jet')
        nfjets = 0
        ncjets = 0
        nbtag = 0
        for ijet in range(event.nJet):
            if event.Jet_pt[ijet] < 30: continue
            if abs(event.Jet_eta[ijet]) > 4.7: continue
            if electron.DeltaR(jets[ijet].p4()) < 0.5: continue
            if tau.DeltaR(jets[ijet].p4()) < 0.5: continue
            jetIds.append(ijet)

            if abs(event.Jet_eta[ijet]) > 2.4:
                nfjets += 1
            else:
                ncjets += 1

            if event.Jet_btagDeepB[ijet] > self.deepcsv_wp.medium:
                nbtag += 1
                bjetIds.append(ijet)

        if not self.isData and self.vlooseIso(
                event,
                ltau.id2) and event.Electron_pfRelIso03_all[ltau.id1] < 0.50:
            self.btagTool.fillEfficiencies(event, jetIds)
            self.btagTool_deep.fillEfficiencies(event, jetIds)

        #eventSum = ROOT.TLorentzVector()
        #
        #for lep in electrons :
        #    eventSum += lep.p4()
        #for lep in electrons :
        #    eventSum += lep.p4()
        #for j in filter(self.jetSel,jets):
        #    eventSum += j.p4()

        # ELECTRON
        self.out.pt_1[0] = event.Electron_pt[ltau.id1]
        self.out.eta_1[0] = event.Electron_eta[ltau.id1]
        self.out.phi_1[0] = event.Electron_phi[ltau.id1]
        self.out.m_1[0] = event.Electron_mass[ltau.id1]
        self.out.dxy_1[0] = event.Electron_dxy[ltau.id1]
        self.out.dz_1[0] = event.Electron_dz[ltau.id1]
        self.out.q_1[0] = event.Electron_charge[ltau.id1]
        self.out.pfRelIso03_all_1[0] = event.Electron_pfRelIso03_all[ltau.id1]
        self.out.cutBased_1[0] = event.Electron_cutBased[ltau.id1]
        self.out.mvaFall17Iso_1[0] = getvar(event,
                                            'Electron_mvaFall17Iso')[ltau.id1]
        self.out.mvaFall17Iso_WP80_1[0] = getvar(
            event, 'Electron_mvaFall17Iso_WP80')[ltau.id1]
        self.out.mvaFall17Iso_WP90_1[0] = getvar(
            event, 'Electron_mvaFall17Iso_WP90')[ltau.id1]
        self.out.mvaFall17Iso_WPL_1[0] = getvar(
            event, 'Electron_mvaFall17Iso_WPL')[ltau.id1]

        # TAU
        self.out.pt_2[0] = event.Tau_pt[ltau.id2]
        self.out.eta_2[0] = event.Tau_eta[ltau.id2]
        self.out.phi_2[0] = event.Tau_phi[ltau.id2]
        self.out.m_2[0] = event.Tau_mass[ltau.id2]
        self.out.dxy_2[0] = event.Tau_dxy[ltau.id2]
        self.out.dz_2[0] = event.Tau_dz[ltau.id2]
        self.out.leadTkPtOverTauPt_2[0] = event.Tau_leadTkPtOverTauPt[ltau.id2]
        self.out.chargedIso_2[0] = event.Tau_chargedIso[ltau.id2]
        self.out.neutralIso_2[0] = event.Tau_neutralIso[ltau.id2]
        self.out.photonsOutsideSignalCone_2[
            0] = event.Tau_photonsOutsideSignalCone[ltau.id2]
        self.out.puCorr_2[0] = event.Tau_puCorr[ltau.id2]
        self.out.rawAntiEle_2[0] = event.Tau_rawAntiEle[ltau.id2]
        self.out.rawIso_2[0] = event.Tau_rawIso[ltau.id2]
        self.out.q_2[0] = event.Tau_charge[ltau.id2]
        self.out.decayMode_2[0] = event.Tau_decayMode[ltau.id2]
        ###self.out.rawAntiEleCat_2[0]            = event.Tau_rawAntiEleCat[ltau.id2]
        self.out.idAntiEle_2[0] = ord(event.Tau_idAntiEle[ltau.id2])
        self.out.idAntiMu_2[0] = ord(event.Tau_idAntiMu[ltau.id2])
        self.out.idDecayMode_2[0] = event.Tau_idDecayMode[ltau.id2]
        self.out.idDecayModeNewDMs_2[0] = event.Tau_idDecayModeNewDMs[ltau.id2]
        self.out.rawMVAoldDM_2[0] = event.Tau_rawMVAoldDM[ltau.id2]
        self.out.rawMVAnewDM2017v2_2[0] = event.Tau_rawMVAnewDM2017v2[ltau.id2]
        self.out.rawMVAoldDM2017v1_2[0] = event.Tau_rawMVAoldDM2017v1[ltau.id2]
        self.out.rawMVAoldDM2017v2_2[0] = event.Tau_rawMVAoldDM2017v2[ltau.id2]
        self.out.idMVAoldDM_2[0] = ord(event.Tau_idMVAoldDM[ltau.id2])
        self.out.idMVAoldDM2017v1_2[0] = ord(
            event.Tau_idMVAoldDM2017v1[ltau.id2])
        self.out.idMVAoldDM2017v2_2[0] = ord(
            event.Tau_idMVAoldDM2017v2[ltau.id2])
        self.out.idMVAnewDM2017v2_2[0] = ord(
            event.Tau_idMVAnewDM2017v2[ltau.id2])

        # GENERATOR
        #print type(event.Tau_genPartFlav[ltau.id2])
        if not self.isData:
            self.out.genPartFlav_1[0] = ord(
                event.Electron_genPartFlav[ltau.id1])
            self.out.genPartFlav_2[0] = ord(event.Tau_genPartFlav[ltau.id2])

            genvistau = Collection(event, 'GenVisTau')
            dRmax = 1000
            gendm = -1
            genpt = -1
            geneta = -1
            genphi = -1
            for igvt in range(event.nGenVisTau):
                dR = genvistau[igvt].p4().DeltaR(tau)
                if dR < 0.5 and dR < dRmax:
                    dRmax = dR
                    gendm = event.GenVisTau_status[igvt]
                    genpt = event.GenVisTau_pt[igvt]
                    geneta = event.GenVisTau_eta[igvt]
                    genphi = event.GenVisTau_phi[igvt]

            self.out.gendecayMode_2[0] = gendm
            self.out.genvistaupt_2[0] = genpt
            self.out.genvistaueta_2[0] = geneta
            self.out.genvistauphi_2[0] = genphi

        # EVENT
        self.out.isData[0] = self.isData
        self.out.run[0] = event.run
        self.out.luminosityBlock[0] = event.luminosityBlock
        self.out.event[0] = event.event & 0xffffffffffffffff
        self.out.met[0] = event.MET_pt
        self.out.metphi[0] = event.MET_phi
        ###self.out.puppimet[0]                  = event.PuppiMET_pt
        ###self.out.puppimetphi[0]               = event.PuppiMET_phi
        ###self.out.metsignificance[0]           = event.MET_significance
        ###self.out.metcovXX[0]                  = event.MET_covXX
        ###self.out.metcovXY[0]                  = event.MET_covXY
        ###self.out.metcovYY[0]                  = event.MET_covYY
        ###self.out.fixedGridRhoFastjetAll[0]    = event.fixedGridRhoFastjetAll
        self.out.npvs[0] = event.PV_npvs
        self.out.npvsGood[0] = event.PV_npvsGood

        if not self.isData:
            self.out.genmet[0] = event.GenMET_pt
            self.out.genmetphi[0] = event.GenMET_phi
            self.out.nPU[0] = event.Pileup_nPU
            self.out.nTrueInt[0] = event.Pileup_nTrueInt
            self.out.genWeight[0] = event.genWeight
            try:
                self.out.LHE_Njets[0] = event.LHE_Njets
            except RuntimeError:
                self.out.LHE_Njets[0] = -1

        # JETS
        self.out.njets[0] = len(jetIds)
        self.out.njets50[0] = len([j for j in jetIds if event.Jet_pt[j] > 50])
        self.out.nfjets[0] = nfjets
        self.out.ncjets[0] = ncjets
        self.out.nbtag[0] = nbtag

        if len(jetIds) > 0:
            self.out.jpt_1[0] = event.Jet_pt[jetIds[0]]
            self.out.jeta_1[0] = event.Jet_eta[jetIds[0]]
            self.out.jphi_1[0] = event.Jet_phi[jetIds[0]]
            self.out.jcsvv2_1[0] = event.Jet_btagCSVV2[jetIds[0]]
            self.out.jdeepb_1[0] = event.Jet_btagDeepB[jetIds[0]]
        else:
            self.out.jpt_1[0] = -9.
            self.out.jeta_1[0] = -9.
            self.out.jphi_1[0] = -9.
            self.out.jcsvv2_1[0] = -9.
            self.out.jdeepb_1[0] = -9.

        if len(jetIds) > 1:
            self.out.jpt_2[0] = event.Jet_pt[jetIds[1]]
            self.out.jeta_2[0] = event.Jet_eta[jetIds[1]]
            self.out.jphi_2[0] = event.Jet_phi[jetIds[1]]
            self.out.jcsvv2_2[0] = event.Jet_btagCSVV2[jetIds[1]]
            self.out.jdeepb_2[0] = event.Jet_btagDeepB[jetIds[1]]
        else:
            self.out.jpt_2[0] = -9.
            self.out.jeta_2[0] = -9.
            self.out.jphi_2[0] = -9.
            self.out.jcsvv2_2[0] = -9.
            self.out.jdeepb_2[0] = -9.

        if len(bjetIds) > 0:
            self.out.bpt_1[0] = event.Jet_pt[bjetIds[0]]
            self.out.beta_1[0] = event.Jet_eta[bjetIds[0]]
        else:
            self.out.bpt_1[0] = -9.
            self.out.beta_1[0] = -9.

        if len(bjetIds) > 1:
            self.out.bpt_2[0] = event.Jet_pt[bjetIds[1]]
            self.out.beta_2[0] = event.Jet_eta[bjetIds[1]]
        else:
            self.out.bpt_2[0] = -9.
            self.out.beta_2[0] = -9.

        self.out.pfmt_1[0] = math.sqrt(
            2 * self.out.pt_1[0] * self.out.met[0] *
            (1 - math.cos(deltaPhi(self.out.phi_1[0], self.out.metphi[0]))))
        self.out.pfmt_2[0] = math.sqrt(
            2 * self.out.pt_2[0] * self.out.met[0] *
            (1 - math.cos(deltaPhi(self.out.phi_2[0], self.out.metphi[0]))))

        self.out.m_vis[0] = (electron + tau).M()
        self.out.pt_ll[0] = (electron + tau).Pt()
        self.out.dR_ll[0] = electron.DeltaR(tau)
        self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0])

        # PZETA
        leg1 = ROOT.TVector3(electron.Px(), electron.Py(), 0.)
        leg2 = ROOT.TVector3(tau.Px(), tau.Py(), 0.)
        met_tlv = ROOT.TLorentzVector()
        met_tlv = ROOT.TLorentzVector()
        met_tlv.SetPxPyPzE(self.out.met[0] * math.cos(self.out.metphi[0]),
                           self.out.met[0] * math.cos(self.out.metphi[0]), 0,
                           self.out.met[0])
        metleg = met_tlv.Vect()
        zetaAxis = ROOT.TVector3(leg1.Unit() + leg2.Unit()).Unit()
        pzetaVis = leg1 * zetaAxis + leg2 * zetaAxis
        pzetaMET = metleg * zetaAxis
        self.out.pzetamiss[0] = pzetaMET
        self.out.pzetavis[0] = pzetaVis
        self.out.dzeta[0] = pzetaMET - 0.85 * pzetaVis

        # VETOS
        self.out.extramuon_veto[0], self.out.extraelec_veto[
            0], self.out.dilepton_veto[0] = extraLeptonVetos(
                event, [-1], [ltau.id1], self.name)

        # WEIGHTS
        if not self.isData:
            if self.doZpt:
                zboson = getZPTMass(event)
                self.out.m_genboson[0] = zboson.M()
                self.out.pt_genboson[0] = zboson.Pt()
                self.out.zptweight[0] = self.recoilTool.getZptWeight(
                    zboson.Pt(), zboson.M())
            self.out.genweight[0] = event.genWeight
            self.out.puweight[0] = self.puTool.getWeight(event.Pileup_nTrueInt)
            self.out.trigweight[0] = self.eleSFs.getTriggerSF(
                self.out.pt_1[0], self.out.eta_1[0])
            self.out.idisoweight_1[0] = self.eleSFs.getIdIsoSF(
                self.out.pt_1[0], self.out.eta_1[0])
            self.out.idisoweight_2[0] = self.ltfSFs.getSF(
                self.out.genPartFlav_2[0], self.out.eta_2[0])
            self.out.btagweight[0] = self.btagTool.getWeight(event, jetIds)
            self.out.btagweight_deep[0] = self.btagTool_deep.getWeight(
                event, jetIds)
            self.out.weight[0] = self.out.genWeight[0] * self.out.puweight[
                0] * self.out.trigweight[0] * self.out.idisoweight_1[
                    0] * self.out.idisoweight_2[0]

        self.out.tree.Fill()
        return True
Пример #7
0
    def __init__(self, name, dataType, **kwargs):

        self.name = name
        self.out = TreeProducerEleTau(name)
        self.isData = dataType == 'data'
        self.year = kwargs.get('year', 2017)
        self.tes = kwargs.get('tes', 1.0)
        self.ltf = kwargs.get('ltf', 1.0)
        self.jtf = kwargs.get('jtf', 1.0)
        self.doZpt = kwargs.get('doZpt', 'DY' in name)
        self.doRecoil = kwargs.get(
            'doRecoil', ('DY' in name or re.search(r"W\d?Jets", name))
            and self.year > 2016)
        self.doTTpt = kwargs.get('doTTpt', 'TT' in name)
        self.doTight = kwargs.get('doTight', self.tes != 1 or self.ltf != 1)
        self.channel = 'eletau'
        year, channel = self.year, self.channel

        self.vlooseIso = getVLooseTauIso(year)
        if year == 2016:
            self.trigger = lambda e: e.HLT_Ele25_eta2p1_WPTight_Gsf or e.HLT_Ele27_WPTight_Gsf  #or e.HLT_Ele45_WPLoose_Gsf_L1JetTauSeeded #or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20_SingleL1 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau30
            self.eleCutPt = 26
        elif year == 2017:
            self.trigger = lambda e: e.HLT_Ele35_WPTight_Gsf or e.HLT_Ele32_WPTight_Gsf_L1DoubleEG or e.HLT_Ele32_WPTight_Gsf
            self.eleCutPt = 36
        else:
            self.trigger = lambda e: e.HLT_Ele32_WPTight_Gsf or e.HLT_Ele35_WPTight_Gsf
            self.eleCutPt = 33
        self.tauCutPt = 20

        if not self.isData:
            self.eleSFs = ElectronSFs(year=year)
            self.puTool = PileupWeightTool(year=year)
            self.ltfSFs = LeptonTauFakeSFs('loose', 'tight', year=year)
            self.btagTool = BTagWeightTool('DeepCSV',
                                           'medium',
                                           channel='mutau',
                                           year=year)
            if self.doZpt:
                self.zptTool = ZptCorrectionTool(year=year)
            if self.doRecoil:
                self.recoilTool = RecoilCorrectionTool(year=year)
        self.deepcsv_wp = BTagWPs('DeepCSV', year=year)

        self.Nocut = 0
        self.Trigger = 1
        self.GoodElectrons = 2
        self.GoodTaus = 3
        self.GoodDiLepton = 4
        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16

        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodElectrons,
                                                "electron object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus,
                                                "tau object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton,
                                                "eletau pair")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted,
                                                "no cut, weighted")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU,
                                                "no cut, weighted, PU>0")
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)
Пример #8
0
class EleTauProducer(Module):
    def __init__(self, name, dataType, **kwargs):

        self.name = name
        self.out = TreeProducerEleTau(name)
        self.isData = dataType == 'data'
        self.year = kwargs.get('year', 2017)
        self.tes = kwargs.get('tes', 1.0)
        self.ltf = kwargs.get('ltf', 1.0)
        self.jtf = kwargs.get('jtf', 1.0)
        self.doZpt = kwargs.get('doZpt', 'DY' in name)
        self.doRecoil = kwargs.get(
            'doRecoil', ('DY' in name or re.search(r"W\d?Jets", name))
            and self.year > 2016)
        self.doTTpt = kwargs.get('doTTpt', 'TT' in name)
        self.doTight = kwargs.get('doTight', self.tes != 1 or self.ltf != 1)
        self.channel = 'eletau'
        year, channel = self.year, self.channel

        self.vlooseIso = getVLooseTauIso(year)
        if year == 2016:
            self.trigger = lambda e: e.HLT_Ele25_eta2p1_WPTight_Gsf or e.HLT_Ele27_WPTight_Gsf  #or e.HLT_Ele45_WPLoose_Gsf_L1JetTauSeeded #or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20_SingleL1 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau20 or e.HLT_Ele24_eta2p1_WPLoose_Gsf_LooseIsoPFTau30
            self.eleCutPt = 26
        elif year == 2017:
            self.trigger = lambda e: e.HLT_Ele35_WPTight_Gsf or e.HLT_Ele32_WPTight_Gsf_L1DoubleEG or e.HLT_Ele32_WPTight_Gsf
            self.eleCutPt = 36
        else:
            self.trigger = lambda e: e.HLT_Ele32_WPTight_Gsf or e.HLT_Ele35_WPTight_Gsf
            self.eleCutPt = 33
        self.tauCutPt = 20

        if not self.isData:
            self.eleSFs = ElectronSFs(year=year)
            self.puTool = PileupWeightTool(year=year)
            self.ltfSFs = LeptonTauFakeSFs('loose', 'tight', year=year)
            self.btagTool = BTagWeightTool('DeepCSV',
                                           'medium',
                                           channel='mutau',
                                           year=year)
            if self.doZpt:
                self.zptTool = ZptCorrectionTool(year=year)
            if self.doRecoil:
                self.recoilTool = RecoilCorrectionTool(year=year)
        self.deepcsv_wp = BTagWPs('DeepCSV', year=year)

        self.Nocut = 0
        self.Trigger = 1
        self.GoodElectrons = 2
        self.GoodTaus = 3
        self.GoodDiLepton = 4
        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16

        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodElectrons,
                                                "electron object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus,
                                                "tau object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton,
                                                "eletau pair")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted,
                                                "no cut, weighted")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU,
                                                "no cut, weighted, PU>0")
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)

    def beginJob(self):
        pass

    def endJob(self):
        if not self.isData:
            self.btagTool.setDirectory(self.out.outputfile, 'btag')
        self.out.endJob()

    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        sys.stdout.flush()
        checkBranches(inputTree)

    def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        pass

    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""
        sys.stdout.flush()

        #####################################
        self.out.cutflow.Fill(self.Nocut)
        if self.isData:
            self.out.cutflow.Fill(self.TotalWeighted, 1.)
            if event.PV_npvs > 0:
                self.out.cutflow.Fill(self.TotalWeighted_no0PU, 1.)
            else:
                return False
        else:
            self.out.cutflow.Fill(self.TotalWeighted, event.genWeight)
            if event.Pileup_nTrueInt > 0:
                self.out.cutflow.Fill(self.TotalWeighted_no0PU,
                                      event.genWeight)
            else:
                return False
        #####################################

        if not self.trigger(event):
            return False

        #####################################
        self.out.cutflow.Fill(self.Trigger)
        #####################################

        idx_goodelectrons = []
        for ielectron in range(event.nElectron):
            if event.Electron_pt[ielectron] < self.eleCutPt: continue
            if abs(event.Electron_eta[ielectron]) > 2.1: continue
            if abs(event.Electron_dz[ielectron]) > 0.2: continue
            if abs(event.Electron_dxy[ielectron]) > 0.045: continue
            if event.Electron_convVeto[ielectron] != 1: continue
            if ord(event.Electron_lostHits[ielectron]) > 1: continue
            if event.Electron_mvaFall17V2Iso_WP80[ielectron] < 0.5: continue
            idx_goodelectrons.append(ielectron)

        if len(idx_goodelectrons) == 0:
            return False

        #####################################
        self.out.cutflow.Fill(self.GoodElectrons)
        #####################################

        Tau_genmatch = {}  # bug in Tau_genPartFlav
        idx_goodtaus = []
        for itau in range(event.nTau):
            if not self.vlooseIso(event, itau): continue
            if abs(event.Tau_eta[itau]) > 2.3: continue
            if abs(event.Tau_dz[itau]) > 0.2: continue
            if event.Tau_decayMode[itau] not in [0, 1, 10]: continue
            if abs(event.Tau_charge[itau]) != 1: continue
            if not self.isData:
                Tau_genmatch[itau] = genmatch(event, itau)
                #if self.tes!=1.0 and Tau_genmatch[itau]==5:
                #  event.Tau_pt[itau]   *= self.tes
                #  event.Tau_mass[itau] *= self.tes
                #elif self.ltf!=1.0 and 0<Tau_genmatch[itau]<5:
                #  event.Tau_pt[itau]   *= self.ltf
                #  event.Tau_mass[itau] *= self.ltf
                #elif self.jtf!=1.0 and Tau_genmatch[itau]==0:
                #  event.Tau_pt[itau]   *= self.jtf
                #  event.Tau_mass[itau] *= self.jtf
            if event.Tau_pt[itau] < self.tauCutPt: continue
            ###if ord(event.Tau_idAntiEle[itau])<1: continue
            ###if ord(event.Tau_idAntiMu[itau])<1: continue
            idx_goodtaus.append(itau)

        if len(idx_goodtaus) == 0:
            return False

        #####################################
        self.out.cutflow.Fill(self.GoodTaus)
        #####################################

        electrons = Collection(event, 'Electron')
        taus = Collection(event, 'Tau')
        ltaus = []
        for idx1 in idx_goodelectrons:
            for idx2 in idx_goodtaus:
                dR = taus[idx2].p4().DeltaR(electrons[idx1].p4())
                if dR < 0.5: continue
                ltau = LeptonTauPair(idx1, event.Electron_pt[idx1],
                                     event.Electron_pfRelIso03_all[idx1], idx2,
                                     event.Tau_pt[idx2],
                                     event.Tau_rawMVAoldDM2017v2[idx2])
                ltaus.append(ltau)

        if len(ltaus) == 0:
            return False

        ltau = bestDiLepton(ltaus)
        electron = electrons[ltau.id1].p4()
        tau = taus[ltau.id2].p4()
        #print 'chosen tau1 (idx, pt) = ', ltau.id1, ltau.tau1_pt, 'check', electron.p4().Pt()
        #print 'chosen tau2 (idx, pt) = ', ltau.id2, ltau.tau2_pt, 'check', tau.p4().Pt()

        #####################################
        self.out.cutflow.Fill(self.GoodDiLepton)
        #####################################

        # VETOS
        self.out.extramuon_veto[0], self.out.extraelec_veto[
            0], self.out.dilepton_veto[0] = extraLeptonVetos(
                event, [-1], [ltau.id1], self.channel)
        self.out.lepton_vetos[0] = self.out.extramuon_veto[
            0] or self.out.extraelec_veto[0] or self.out.dilepton_veto[0]
        ###if self.doTight and (self.out.lepton_vetos[0] or event.Electron_pfRelIso03_all[ltau.id1]>0.10 or\
        ###                     ord(event.Tau_idAntiMu[ltau.id2]<1 or ord(event.Tau_idAntiEle[ltau.id2]<8):
        ###  return False

        # JETS
        jetIds = []
        bjetIds = []
        jets = Collection(event, 'Jet')
        nfjets = 0
        ncjets = 0
        nbtag = 0
        for ijet in range(event.nJet):
            if event.Jet_pt[ijet] < 30: continue
            if abs(event.Jet_eta[ijet]) > 4.7: continue
            if electron.DeltaR(jets[ijet].p4()) < 0.5: continue
            if tau.DeltaR(jets[ijet].p4()) < 0.5: continue
            jetIds.append(ijet)

            if abs(event.Jet_eta[ijet]) > 2.4:
                nfjets += 1
            else:
                ncjets += 1

            if event.Jet_btagDeepB[ijet] > self.deepcsv_wp.medium:
                nbtag += 1
                bjetIds.append(ijet)

        if not self.isData and self.vlooseIso(
                event,
                ltau.id2) and event.Electron_pfRelIso03_all[ltau.id1] < 0.50:
            self.btagTool.fillEfficiencies(event, jetIds)

        # EVENT
        self.out.isData[0] = self.isData
        self.out.run[0] = event.run
        self.out.lumi[0] = event.luminosityBlock
        self.out.event[0] = event.event & 0xffffffffffffffff
        ###self.out.puppimet[0]                  = event.PuppiMET_pt
        ###self.out.puppimetphi[0]               = event.PuppiMET_phi
        ###self.out.metsignificance[0]           = event.MET_significance
        ###self.out.metcovXX[0]                  = event.MET_covXX
        ###self.out.metcovXY[0]                  = event.MET_covXY
        ###self.out.metcovYY[0]                  = event.MET_covYY
        self.out.npvs[0] = event.PV_npvs
        self.out.npvsGood[0] = event.PV_npvsGood

        if not self.isData:
            self.out.genmet[0] = event.GenMET_pt
            self.out.genmetphi[0] = event.GenMET_phi
            self.out.nPU[0] = event.Pileup_nPU
            self.out.nTrueInt[0] = event.Pileup_nTrueInt
            try:
                self.out.LHE_Njets[0] = event.LHE_Njets
            except RuntimeError:
                self.out.LHE_Njets[0] = -1

        # ELECTRON
        self.out.pt_1[0] = event.Electron_pt[ltau.id1]
        self.out.eta_1[0] = event.Electron_eta[ltau.id1]
        self.out.phi_1[0] = event.Electron_phi[ltau.id1]
        self.out.m_1[0] = event.Electron_mass[ltau.id1]
        self.out.dxy_1[0] = event.Electron_dxy[ltau.id1]
        self.out.dz_1[0] = event.Electron_dz[ltau.id1]
        self.out.q_1[0] = event.Electron_charge[ltau.id1]
        self.out.pfRelIso03_all_1[0] = event.Electron_pfRelIso03_all[ltau.id1]
        self.out.cutBased_1[0] = event.Electron_cutBased[ltau.id1]
        self.out.mvaFall17Iso_1[0] = event.Electron_mvaFall17V2Iso[ltau.id1]
        self.out.mvaFall17Iso_WPL_1[0] = event.Electron_mvaFall17V2Iso_WPL[
            ltau.id1]
        self.out.mvaFall17Iso_WP80_1[0] = event.Electron_mvaFall17V2Iso_WP80[
            ltau.id1]
        self.out.mvaFall17Iso_WP90_1[0] = event.Electron_mvaFall17V2Iso_WP90[
            ltau.id1]

        # TAU
        self.out.pt_2[0] = event.Tau_pt[ltau.id2]
        self.out.eta_2[0] = event.Tau_eta[ltau.id2]
        self.out.phi_2[0] = event.Tau_phi[ltau.id2]
        self.out.m_2[0] = event.Tau_mass[ltau.id2]
        self.out.dxy_2[0] = event.Tau_dxy[ltau.id2]
        self.out.dz_2[0] = event.Tau_dz[ltau.id2]
        self.out.leadTkPtOverTauPt_2[0] = event.Tau_leadTkPtOverTauPt[ltau.id2]
        self.out.chargedIso_2[0] = event.Tau_chargedIso[ltau.id2]
        self.out.neutralIso_2[0] = event.Tau_neutralIso[ltau.id2]
        self.out.photonsOutsideSignalCone_2[
            0] = event.Tau_photonsOutsideSignalCone[ltau.id2]
        self.out.puCorr_2[0] = event.Tau_puCorr[ltau.id2]
        self.out.rawAntiEle_2[0] = event.Tau_rawAntiEle[ltau.id2]
        self.out.rawIso_2[0] = event.Tau_rawIso[ltau.id2]
        self.out.q_2[0] = event.Tau_charge[ltau.id2]
        self.out.decayMode_2[0] = event.Tau_decayMode[ltau.id2]
        ###self.out.rawAntiEleCat_2[0]            = event.Tau_rawAntiEleCat[ltau.id2]
        self.out.idAntiEle_2[0] = ord(event.Tau_idAntiEle[ltau.id2])
        self.out.idAntiMu_2[0] = ord(event.Tau_idAntiMu[ltau.id2])
        self.out.idDecayMode_2[0] = event.Tau_idDecayMode[ltau.id2]
        self.out.idDecayModeNewDMs_2[0] = event.Tau_idDecayModeNewDMs[ltau.id2]
        self.out.rawMVAoldDM_2[0] = event.Tau_rawMVAoldDM[ltau.id2]
        self.out.rawMVAnewDM2017v2_2[0] = event.Tau_rawMVAnewDM2017v2[ltau.id2]
        self.out.rawMVAoldDM2017v1_2[0] = event.Tau_rawMVAoldDM2017v1[ltau.id2]
        self.out.rawMVAoldDM2017v2_2[0] = event.Tau_rawMVAoldDM2017v2[ltau.id2]
        self.out.idMVAoldDM_2[0] = ord(event.Tau_idMVAoldDM[ltau.id2])
        self.out.idMVAoldDM2017v1_2[0] = ord(
            event.Tau_idMVAoldDM2017v1[ltau.id2])
        self.out.idMVAoldDM2017v2_2[0] = ord(
            event.Tau_idMVAoldDM2017v2[ltau.id2])
        self.out.idMVAnewDM2017v2_2[0] = ord(
            event.Tau_idMVAnewDM2017v2[ltau.id2])

        # GENERATOR
        if not self.isData:
            self.out.genPartFlav_1[0] = ord(
                event.Electron_genPartFlav[ltau.id1])
            self.out.genPartFlav_2[0] = Tau_genmatch[
                ltau.id2]  # ord(event.Tau_genPartFlav[ltau.id2])

            genvistau = Collection(event, 'GenVisTau')
            dRmax = 1000
            gendm = -1
            genpt = -1
            geneta = -1
            genphi = -1
            for igvt in range(event.nGenVisTau):
                dR = genvistau[igvt].p4().DeltaR(tau)
                if dR < 0.5 and dR < dRmax:
                    dRmax = dR
                    gendm = event.GenVisTau_status[igvt]
                    genpt = event.GenVisTau_pt[igvt]
                    geneta = event.GenVisTau_eta[igvt]
                    genphi = event.GenVisTau_phi[igvt]

            self.out.gendecayMode_2[0] = gendm
            self.out.genvistaupt_2[0] = genpt
            self.out.genvistaueta_2[0] = geneta
            self.out.genvistauphi_2[0] = genphi

        # WEIGHTS
        met = TLorentzVector()
        met.SetPxPyPzE(event.MET_pt * cos(event.MET_phi),
                       event.MET_pt * sin(event.MET_phi), 0, event.MET_pt)
        if not self.isData:
            if self.doRecoil:
                boson, boson_vis = getBoson(event)
                self.recoilTool.CorrectPFMETByMeanResolution(
                    met, boson, boson_vis, len(jetIds))
                event.MET_pt = met.Pt()
                event.MET_phi = met.Phi()
                self.out.m_genboson[0] = boson.M()
                self.out.pt_genboson[0] = boson.Pt()
                if self.doZpt:
                    self.out.zptweight[0] = self.zptTool.getZptWeight(
                        boson.Pt(), boson.M())
            elif self.doZpt:
                zboson = getZBoson(event)
                self.out.m_genboson[0] = zboson.M()
                self.out.pt_genboson[0] = zboson.Pt()
                self.out.zptweight[0] = self.zptTool.getZptWeight(
                    zboson.Pt(), zboson.M())
            elif self.doTTpt:
                toppt1, toppt2 = getTTPt(event)
                self.out.ttptweight[0] = getTTptWeight(toppt1, toppt2)
            self.out.genweight[0] = event.genWeight
            self.out.puweight[0] = self.puTool.getWeight(event.Pileup_nTrueInt)
            self.out.trigweight[0] = self.eleSFs.getTriggerSF(
                self.out.pt_1[0], self.out.eta_1[0])
            self.out.idisoweight_1[0] = self.eleSFs.getIdIsoSF(
                self.out.pt_1[0], self.out.eta_1[0])
            self.out.idisoweight_2[0] = self.ltfSFs.getSF(
                self.out.genPartFlav_2[0], self.out.eta_2[0])
            self.out.btagweight[0] = self.btagTool.getWeight(event, jetIds)
            self.out.weight[0] = self.out.genweight[0] * self.out.puweight[
                0] * self.out.trigweight[0] * self.out.idisoweight_1[
                    0] * self.out.idisoweight_2[0]

        # JETS
        self.out.njets[0] = len(jetIds)
        self.out.njets50[0] = len([j for j in jetIds if event.Jet_pt[j] > 50])
        self.out.nfjets[0] = nfjets
        self.out.ncjets[0] = ncjets
        self.out.nbtag[0] = nbtag

        if len(jetIds) > 0:
            self.out.jpt_1[0] = event.Jet_pt[jetIds[0]]
            self.out.jeta_1[0] = event.Jet_eta[jetIds[0]]
            self.out.jphi_1[0] = event.Jet_phi[jetIds[0]]
            self.out.jdeepb_1[0] = event.Jet_btagDeepB[jetIds[0]]
        else:
            self.out.jpt_1[0] = -9.
            self.out.jeta_1[0] = -9.
            self.out.jphi_1[0] = -9.
            self.out.jdeepb_1[0] = -9.

        if len(jetIds) > 1:
            self.out.jpt_2[0] = event.Jet_pt[jetIds[1]]
            self.out.jeta_2[0] = event.Jet_eta[jetIds[1]]
            self.out.jphi_2[0] = event.Jet_phi[jetIds[1]]
            self.out.jdeepb_2[0] = event.Jet_btagDeepB[jetIds[1]]
        else:
            self.out.jpt_2[0] = -9.
            self.out.jeta_2[0] = -9.
            self.out.jphi_2[0] = -9.
            self.out.jdeepb_2[0] = -9.

        if len(bjetIds) > 0:
            self.out.bpt_1[0] = event.Jet_pt[bjetIds[0]]
            self.out.beta_1[0] = event.Jet_eta[bjetIds[0]]
        else:
            self.out.bpt_1[0] = -9.
            self.out.beta_1[0] = -9.

        if len(bjetIds) > 1:
            self.out.bpt_2[0] = event.Jet_pt[bjetIds[1]]
            self.out.beta_2[0] = event.Jet_eta[bjetIds[1]]
        else:
            self.out.bpt_2[0] = -9.
            self.out.beta_2[0] = -9.

        self.out.met[0] = event.MET_pt
        self.out.metphi[0] = event.MET_phi
        self.out.pfmt_1[0] = sqrt(
            2 * self.out.pt_1[0] * self.out.met[0] *
            (1 - cos(deltaPhi(self.out.phi_1[0], self.out.metphi[0]))))
        self.out.pfmt_2[0] = sqrt(
            2 * self.out.pt_2[0] * self.out.met[0] *
            (1 - cos(deltaPhi(self.out.phi_2[0], self.out.metphi[0]))))

        self.out.m_vis[0] = (electron + tau).M()
        self.out.pt_ll[0] = (electron + tau).Pt()
        self.out.dR_ll[0] = electron.DeltaR(tau)
        self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0])
        self.out.deta_ll[0] = abs(self.out.eta_1[0] - self.out.eta_2[0])

        # PZETA
        leg1 = TVector3(electron.Px(), electron.Py(), 0.)
        leg2 = TVector3(tau.Px(), tau.Py(), 0.)
        zetaAxis = TVector3(leg1.Unit() + leg2.Unit()).Unit()
        pzeta_vis = leg1 * zetaAxis + leg2 * zetaAxis
        pzeta_miss = met.Vect() * zetaAxis
        self.out.pzetamiss[0] = pzeta_miss
        self.out.pzetavis[0] = pzeta_vis
        self.out.dzeta[0] = pzeta_miss - 0.85 * pzeta_vis

        self.out.tree.Fill()
        return True
Пример #9
0
class MuMuProducer(Module):
    
    def __init__(self, name, dataType, **kwargs):
        
        year        = kwargs.get('year',  2017 )
        doZpt       = kwargs.get('doZpt', 'DY' in name )
        channel     = 'mumu'
        
        self.name   = name
        self.year   = year
        self.out    = TreeProducerMuMu(name)
        self.isData = dataType=='data'
        self.doZpt  = doZpt
        
        setYear(year)
        self.vlooseIso    = getVLooseTauIso(year)
        if year==2016:
          self.trigger    = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1 #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1
          self.muon1CutPt = 23
        else:
          self.trigger    = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27
          self.muon1CutPt = 25
        self.muon2CutPt   = 15
        
        if not self.isData:
          self.muSFs     = MuonSFs(year=year)
          self.puTool    = PileupWeightTool(year=year)
          self.btagTool      = BTagWeightTool('CSVv2','medium',channel='mutau',year=year)
          self.btagTool_deep = BTagWeightTool('DeepCSV','medium',channel='mutau',year=year)
          if self.doZpt:
            self.recoilTool  = RecoilCorrectionTool(year=year)
        self.csvv2_wp    = BTagWPs('CSVv2',year=year)
        self.deepcsv_wp  = BTagWPs('DeepCSV',year=year)
        
        self.Nocut = 0
        self.Trigger = 1
        self.GoodMuons = 2
        self.GoodSecondMuon = 3
        self.GoodDiLepton = 4
        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16
        
        self.out.cutflow.GetXaxis().SetBinLabel(1+self.Nocut,               "no cut"                 )
        self.out.cutflow.GetXaxis().SetBinLabel(1+self.Trigger,             "trigger"                )
        self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodMuons,           "muon object"            )
        self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodSecondMuon,      "second muon object"     )
        self.out.cutflow.GetXaxis().SetBinLabel(1+self.GoodDiLepton,        "mumu pair"              )
        self.out.cutflow.GetXaxis().SetBinLabel(1+self.TotalWeighted,       "no cut, weighted"       )
        self.out.cutflow.GetXaxis().SetBinLabel(1+self.TotalWeighted_no0PU, "no cut, weighted, PU>0" )
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)
        
    def beginJob(self):
        pass
    
    def endJob(self):
        self.out.outputfile.Write()
        self.out.outputfile.Close()
    
    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        pass


    def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):        
        pass
        
    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""
        
        #####################################
        self.out.cutflow.Fill(self.Nocut)
        if self.isData:
          self.out.cutflow.Fill(self.TotalWeighted, 1.)
          if event.PV_npvs>0:
            self.out.cutflow.Fill(self.TotalWeighted_no0PU, 1.)
          else:
            return False
        else:
          self.out.cutflow.Fill(self.TotalWeighted, event.genWeight)
          self.out.pileup.Fill(event.Pileup_nTrueInt)
          if event.Pileup_nTrueInt>0:
            self.out.cutflow.Fill(self.TotalWeighted_no0PU, event.genWeight)
          else:
            return False
        #####################################
        
        
        if not self.trigger(event):
            return False
        
        #####################################
        self.out.cutflow.Fill(self.Trigger)
        #####################################
        
        
        idx_goodmuons = [ ]
        for imuon in range(event.nMuon):
            if event.Muon_pt[imuon] < self.muon2CutPt: continue # lower pT cut
            if abs(event.Muon_eta[imuon]) > 2.4: continue
            if abs(event.Muon_dz[imuon]) > 0.2: continue
            if abs(event.Muon_dxy[imuon]) > 0.045: continue
            if event.Muon_pfRelIso04_all[imuon] > 0.15: continue
            if not event.Muon_mediumId[imuon]: continue
            idx_goodmuons.append(imuon)
        
        if len(idx_goodmuons) < 1:
            return False
        
        #####################################
        self.out.cutflow.Fill(self.GoodMuons)
        #####################################
        
        
        if not any(event.Muon_pt[i]>self.muon1CutPt for i in idx_goodmuons) or len(idx_goodmuons)<2: # higher pT cut
            return False
        
        #####################################
        self.out.cutflow.Fill(self.GoodSecondMuon)
        #####################################
        
        
        muons = Collection(event, 'Muon')
        dileptons = [ ]
        for idx1 in idx_goodmuons:
          for idx2 in idx_goodmuons:
              if idx1 >= idx2: continue
              muon1 = muons[idx1].p4()
              muon2 = muons[idx2].p4()
              if muon1.DeltaR(muon2) < 0.5: continue
              if not (70<(muon1+muon2).M()<110): continue # Z mass
              dilepton = DiLeptonBasicClass(idx1, event.Muon_pt[idx1], event.Muon_pfRelIso04_all[idx1], 
                                            idx2, event.Muon_pt[idx2], event.Muon_pfRelIso04_all[idx2])
              dileptons.append(dilepton)
        
        if len(dileptons)==0:
            return False
        
        dilepton = bestDiLepton(dileptons)
        muon1    = muons[dilepton.id1].p4()
        muon2    = muons[dilepton.id2].p4()
        
        #####################################
        self.out.cutflow.Fill(self.GoodDiLepton)
        #####################################
        
        
        # JETS
        jetIds  = [ ]
        bjetIds = [ ]
        jets    = Collection(event, 'Jet')
        nfjets  = 0
        ncjets  = 0
        nbtag   = 0
        for ijet in range(event.nJet):
            if event.Jet_pt[ijet] < 20: continue # 20 for tau -> j fake measurement
            if abs(event.Jet_eta[ijet]) > 4.7: continue
            if muon1.DeltaR(jets[ijet].p4()) < 0.5: continue
            if muon2.DeltaR(jets[ijet].p4()) < 0.5: continue
            jetIds.append(ijet)
            
            if abs(event.Jet_eta[ijet]) > 2.4:
                nfjets += 1
            else:
                ncjets += 1
            
            if event.Jet_btagDeepB[ijet] > self.deepcsv_wp.medium:
              nbtag += 1
              bjetIds.append(ijet)
        
        if not self.isData and event.Muon_pfRelIso04_all[dilepton.id1]<0.50 and event.Muon_pfRelIso04_all[dilepton.id2]<0.50:
          self.btagTool.fillEfficiencies(event,jetIds)
          self.btagTool_deep.fillEfficiencies(event,jetIds)
        
        #eventSum = ROOT.TLorentzVector()
        #
        #for lep in muons :
        #    eventSum += lep.p4()
        #for lep in electrons :
        #    eventSum += lep.p4()
        #for j in filter(self.jetSel,jets):
        #    eventSum += j.p4()
        
        
        # MUONS
        self.out.pt_1[0]                       = event.Muon_pt[dilepton.id1]
        self.out.eta_1[0]                      = event.Muon_eta[dilepton.id1]
        self.out.phi_1[0]                      = event.Muon_phi[dilepton.id1]
        self.out.m_1[0]                        = event.Muon_mass[dilepton.id1]
        self.out.dxy_1[0]                      = event.Muon_dxy[dilepton.id1]
        self.out.dz_1[0]                       = event.Muon_dz[dilepton.id1]         
        self.out.q_1[0]                        = event.Muon_charge[dilepton.id1]
        self.out.pfRelIso04_all_1[0]           = event.Muon_pfRelIso04_all[dilepton.id1]
        
        self.out.pt_2[0]                       = event.Muon_pt[dilepton.id2]
        self.out.eta_2[0]                      = event.Muon_eta[dilepton.id2]
        self.out.phi_2[0]                      = event.Muon_phi[dilepton.id2]
        self.out.m_2[0]                        = event.Muon_mass[dilepton.id2]
        self.out.dxy_2[0]                      = event.Muon_dxy[dilepton.id2]
        self.out.dz_2[0]                       = event.Muon_dz[dilepton.id2]         
        self.out.q_2[0]                        = event.Muon_charge[dilepton.id2]
        self.out.pfRelIso04_all_2[0]           = event.Muon_pfRelIso04_all[dilepton.id2]
        
        if not self.isData:
            self.out.genPartFlav_1[0]          = ord(event.Muon_genPartFlav[dilepton.id1])
            self.out.genPartFlav_2[0]          = ord(event.Muon_genPartFlav[dilepton.id2])
        
        
        # TAU
        maxId = -1
        maxPt = 20
        taus  = Collection(event, 'Tau')
        for itau in range(event.nTau):
          if event.Tau_pt[itau] < maxPt: continue
          if muon1.DeltaR(taus[itau].p4())<0.5: continue
          if muon2.DeltaR(taus[itau].p4())<0.5: continue
          if abs(event.Tau_eta[itau])>2.3: continue
          if abs(event.Tau_dz[itau])>0.2: continue
          if event.Tau_decayMode[itau] not in [0,1,10,11]: continue
          if abs(event.Tau_charge[itau])!=1: continue
          if ord(event.Tau_idAntiEle[itau])<1: continue # VLoose
          if ord(event.Tau_idAntiMu[itau])<1: continue # Loose
          #if not self.vlooseIso(event,itau): continue
          maxId = itau
          maxPt = event.Tau_pt[itau]
        if maxId>-1:
          self.out.pt_3[0]                     = event.Tau_pt[maxId]
          self.out.eta_3[0]                    = event.Tau_eta[maxId]
          self.out.m_3[0]                      = event.Tau_mass[maxId]
          self.out.decayMode_3[0]              = event.Tau_decayMode[maxId]
          self.out.idAntiEle_3[0]              = ord(event.Tau_idAntiEle[maxId])
          self.out.idAntiMu_3[0]               = ord(event.Tau_idAntiMu[maxId])
          self.out.idMVAoldDM_3[0]             = ord(event.Tau_idMVAoldDM[maxId])
          self.out.idMVAoldDM2017v1_3[0]       = ord(event.Tau_idMVAoldDM2017v1[maxId])
          self.out.idMVAoldDM2017v2_3[0]       = ord(event.Tau_idMVAoldDM2017v2[maxId])
          self.out.idMVAnewDM2017v2_3[0]       = ord(event.Tau_idMVAnewDM2017v2[maxId])
          self.out.idIso_3[0]                  = Tau_idIso(event,maxId)
          if not self.isData:
            self.out.genPartFlav_3[0]          = ord(event.Tau_genPartFlav[maxId])
        else:
          self.out.pt_3[0]                     = -1
          self.out.eta_3[0]                    = -9
          self.out.m_3[0]                      = -1
          self.out.decayMode_3[0]              = -1
          self.out.idAntiEle_3[0]              = -1
          self.out.idAntiMu_3[0]               = -1
          self.out.idMVAoldDM_3[0]             = -1
          self.out.idMVAoldDM2017v1_3[0]       = -1
          self.out.idMVAoldDM2017v2_3[0]       = -1
          self.out.idMVAnewDM2017v2_3[0]       = -1
          self.out.idIso_3[0]                  = -1
          self.out.genPartFlav_3[0]            = -1
        
        
        # EVENT
        self.out.isData[0]                     = self.isData
        self.out.run[0]                        = event.run
        self.out.luminosityBlock[0]            = event.luminosityBlock
        self.out.event[0]                      = event.event & 0xffffffffffffffff
        self.out.met[0]                        = event.MET_pt
        self.out.metphi[0]                     = event.MET_phi
        ###self.out.puppimet[0]                  = event.PuppiMET_pt
        ###self.out.puppimetphi[0]               = event.PuppiMET_phi
        ###self.out.metsignificance[0]           = event.MET_significance
        ###self.out.metcovXX[0]                  = event.MET_covXX
        ###self.out.metcovXY[0]                  = event.MET_covXY
        ###self.out.metcovYY[0]                  = event.MET_covYY
        ###self.out.fixedGridRhoFastjetAll[0]    = event.fixedGridRhoFastjetAll
        self.out.npvs[0]                       = event.PV_npvs
        self.out.npvsGood[0]                   = event.PV_npvsGood
        
        if not self.isData:
          self.out.genmet[0]                   = event.GenMET_pt
          self.out.genmetphi[0]                = event.GenMET_phi
          self.out.nPU[0]                      = event.Pileup_nPU
          self.out.nTrueInt[0]                 = event.Pileup_nTrueInt
          try:
            self.out.LHE_Njets[0]              = event.LHE_Njets
          except RuntimeError:
            self.out.LHE_Njets[0]              = -1
        
        
        # JETS
        self.out.njets[0]                      = len(jetIds)
        self.out.njets50[0]                    = len([j for j in jetIds if event.Jet_pt[j]>50])
        self.out.nfjets[0]                     = nfjets
        self.out.ncjets[0]                     = ncjets
        self.out.nbtag[0]                      = nbtag
        
        if len(jetIds)>0:
          self.out.jpt_1[0]                    = event.Jet_pt[jetIds[0]]
          self.out.jeta_1[0]                   = event.Jet_eta[jetIds[0]]
          self.out.jphi_1[0]                   = event.Jet_phi[jetIds[0]]
          self.out.jcsvv2_1[0]                 = event.Jet_btagCSVV2[jetIds[0]]
          self.out.jdeepb_1[0]                 = event.Jet_btagDeepB[jetIds[0]]
        else:
          self.out.jpt_1[0]                    = -9.
          self.out.jeta_1[0]                   = -9.
          self.out.jphi_1[0]                   = -9.
          self.out.jcsvv2_1[0]                 = -9.
          self.out.jdeepb_1[0]                 = -9.
        
        if len(jetIds)>1:  
          self.out.jpt_2[0]                    = event.Jet_pt[jetIds[1]]
          self.out.jeta_2[0]                   = event.Jet_eta[jetIds[1]]
          self.out.jphi_2[0]                   = event.Jet_phi[jetIds[1]]
          self.out.jcsvv2_2[0]                 = event.Jet_btagCSVV2[jetIds[1]]
          self.out.jdeepb_2[0]                 = event.Jet_btagDeepB[jetIds[1]]
        else:
          self.out.jpt_2[0]                    = -9.
          self.out.jeta_2[0]                   = -9.
          self.out.jphi_2[0]                   = -9.
          self.out.jcsvv2_2[0]                 = -9.
          self.out.jdeepb_2[0]                 = -9.
        
        if len(bjetIds)>0:
          self.out.bpt_1[0]                    = event.Jet_pt[bjetIds[0]]
          self.out.beta_1[0]                   = event.Jet_eta[bjetIds[0]]
        else:
          self.out.bpt_1[0]                    = -9.
          self.out.beta_1[0]                   = -9.
        
        if len(bjetIds)>1:
          self.out.bpt_2[0]                    = event.Jet_pt[bjetIds[1]]
          self.out.beta_2[0]                   = event.Jet_eta[bjetIds[1]]
        else:
          self.out.bpt_2[0]                    = -9.
          self.out.beta_2[0]                   = -9.
        
        
        self.out.njets[0]                      = len(jetIds)
        self.out.nfjets[0]                     = nfjets
        self.out.ncjets[0]                     = ncjets
        self.out.nbtag[0]                      = nbtag
        
        self.out.pfmt_1[0]                     = math.sqrt( 2 * self.out.pt_1[0] * self.out.met[0] * ( 1 - math.cos(deltaPhi(self.out.phi_1[0], self.out.metphi[0])) ) );
        self.out.pfmt_2[0]                     = math.sqrt( 2 * self.out.pt_2[0] * self.out.met[0] * ( 1 - math.cos(deltaPhi(self.out.phi_2[0], self.out.metphi[0])) ) );
        
        self.out.m_vis[0]                      = (muon1 + muon2).M()
        self.out.pt_ll[0]                      = (muon1 + muon2).Pt()
        self.out.dR_ll[0]                      = muon1.DeltaR(muon2)
        self.out.dphi_ll[0]                    = deltaPhi(self.out.phi_1[0], self.out.phi_2[0])
        
        
        # PZETA
        leg1     = ROOT.TVector3(muon1.Px(), muon1.Py(), 0.)
        leg2     = ROOT.TVector3(muon2.Px(), muon2.Py(), 0.)
        met_tlv  = ROOT.TLorentzVector()
        met_tlv.SetPxPyPzE(self.out.met[0]*math.cos(self.out.metphi[0]), self.out.met[0]*math.cos(self.out.metphi[0]), 0, self.out.met[0])
        metleg   = met_tlv.Vect()
        zetaAxis = ROOT.TVector3(leg1.Unit() + leg2.Unit()).Unit()
        pzetaVis = leg1*zetaAxis + leg2*zetaAxis
        pzetaMET = metleg*zetaAxis
        self.out.pzetamiss[0]  = pzetaMET
        self.out.pzetavis[0]   = pzetaVis
        self.out.dzeta[0]      = pzetaMET - 0.85*pzetaVis
        
        
        # VETOS
        self.out.extramuon_veto[0], self.out.extraelec_veto[0], self.out.dilepton_veto[0]  = extraLeptonVetos(event, [dilepton.id1, dilepton.id2], [-1], self.name)
        
        
        # WEIGHTS
        if not self.isData:
          if self.doZpt:
            zboson = getZPTMass(event)
            self.out.m_genboson[0]    = zboson.M()
            self.out.pt_genboson[0]   = zboson.Pt()
            self.out.zptweight[0]     = self.recoilTool.getZptWeight(zboson.Pt(),zboson.M())
          self.out.genweight[0]       = event.genWeight
          self.out.puweight[0]        = self.puTool.getWeight(event.Pileup_nTrueInt)
          self.out.trigweight[0]      = self.muSFs.getTriggerSF(self.out.pt_1[0],self.out.eta_1[0])
          self.out.idisoweight_1[0]   = self.muSFs.getIdIsoSF(self.out.pt_1[0],self.out.eta_1[0])
          self.out.idisoweight_2[0]   = self.muSFs.getIdIsoSF(self.out.pt_2[0],self.out.eta_2[0])
          self.out.btagweight[0]      = self.btagTool.getWeight(event,jetIds)
          self.out.btagweight_deep[0] = self.btagTool_deep.getWeight(event,jetIds)
          self.out.weight[0]          = self.out.genweight[0]*self.out.puweight[0]*self.out.trigweight[0]*self.out.idisoweight_1[0]*self.out.idisoweight_2[0]
        
        
        self.out.tree.Fill() 
        return True
Пример #10
0
class TauTauProducer(Module):
    def __init__(self, name, dataType, **kwargs):

        self.name = name
        self.out = TreeProducerTauTau(name)
        self.isData = dataType == 'data'
        self.year = kwargs.get('year', 2017)
        self.tes = kwargs.get('tes', 1.0)
        self.ltf = kwargs.get('ltf', 1.0)
        self.jtf = kwargs.get('jtf', 1.0)
        self.doZpt = kwargs.get('doZpt', 'DY' in name)
        self.doRecoil = kwargs.get(
            'doRecoil', ('DY' in name or re.search(r"W\d?Jets", name))
            and self.year > 2016)
        self.doTTpt = kwargs.get('doTTpt', 'TT' in name)
        self.doTight = kwargs.get('doTight', self.tes != 1 or self.ltf != 1)
        self.channel = 'tautau'
        year, channel = self.year, self.channel

        self.vlooseIso = getVLooseTauIso(year)
        if year == 2016:
            if self.isData:
                self.trigger    = lambda e: e.HLT_DoubleMediumIsoPFTau35_Trk1_eta2p1_Reg \
                                  if e.run<280919 else e.HLT_DoubleMediumCombinedIsoPFTau35_Trk1_eta2p1_Reg
            else:
                self.trigger = lambda e: e.HLT_DoubleMediumIsoPFTau35_Trk1_eta2p1_Reg or e.HLT_DoubleMediumCombinedIsoPFTau35_Trk1_eta2p1_Reg
        elif year == 2017:
            self.trigger = lambda e: e.HLT_DoubleTightChargedIsoPFTau35_Trk1_TightID_eta2p1_Reg or e.HLT_DoubleTightChargedIsoPFTau40_Trk1_eta2p1_Reg or e.HLT_DoubleMediumChargedIsoPFTau40_Trk1_TightID_eta2p1_Reg
        else:
            if self.isData:
                self.trigger    = lambda e: e.HLT_DoubleTightChargedIsoPFTau35_Trk1_TightID_eta2p1_Reg or e.HLT_DoubleTightChargedIsoPFTau40_Trk1_eta2p1_Reg or e.HLT_DoubleMediumChargedIsoPFTau40_Trk1_TightID_eta2p1_Reg \
                                  if e.run<317509 else e.HLT_DoubleMediumChargedIsoPFTauHPS35_Trk1_eta2p1_Reg
            else:
                self.trigger = lambda e: e.HLT_DoubleMediumChargedIsoPFTauHPS35_Trk1_eta2p1_Reg
        self.tauCutPt = 40

        if not self.isData:
            self.tauSFs = TauTriggerSFs('tautau', 'tight', year=year)
            self.tauSFsVT = TauTriggerSFs('tautau', 'vtight', year=year)
            self.ltfSFs = LeptonTauFakeSFs('loose', 'vloose', year=year)
            self.puTool = PileupWeightTool(year=year)
            self.btagTool = BTagWeightTool('DeepCSV',
                                           'medium',
                                           channel='mutau',
                                           year=year)
            if self.doZpt:
                self.zptTool = ZptCorrectionTool(year=year)
            if self.doRecoil:
                self.recoilTool = RecoilCorrectionTool(year=year)
        self.deepcsv_wp = BTagWPs('DeepCSV', year=year)

        self.Nocut = 0
        self.Trigger = 1
        self.GoodTaus = 2
        self.GoodDiTau = 3

        self.Nocut_GT = 20
        self.Trigger_GT = 21
        self.GoodTaus_GT = 22
        self.GoodDiTau_GT = 23

        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16

        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus,
                                                "tau objects")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiTau,
                                                "ditau pair")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut_GT,
                                                "no cut, GM")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger_GT,
                                                "trigger, GM")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus_GT,
                                                "tau objects, GM")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiTau_GT,
                                                "ditau pair, GM")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted,
                                                "no cut, weighted")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU,
                                                "no cut, weighted, PU>0")
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)

    def beginJob(self):
        pass

    def endJob(self):
        if not self.isData:
            self.btagTool.setDirectory(self.out.outputfile, 'btag')
        self.out.endJob()

    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        sys.stdout.flush()
        checkBranches(inputTree)

    def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        pass

    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""
        sys.stdout.flush()

        ##print '-'*80
        ngentauhads = 0
        ngentaus = 0
        #if not self.isData:
        #    for igp in range(event.nGenPart):
        #        if abs(event.GenPart_pdgId[igp])==15 and event.GenPart_status[igp]==2:
        #            genflag = event.GenPart_statusFlags[igp]
        #            binary = format(genflag,'b').zfill(15)
        #            # 0 : isPrompt
        #            # 1 : isDecayedLeptonHadron
        #            # 2 : isTauDecayProduct
        #            # 3 : isPromptTauDecayProduct
        #            # 4 : isDirectTauDecayProduct
        #            # 5 : isDirectPromptTauDecayProduct
        #            # 6 : isDirectHadronDecayProduct
        #            # 7 : isHardProcess
        #            # 8 : fromHardProcess
        #            # 9 : isHardProcessTauDecayProduct
        #            # 10 : isDirectHardProcessTauDecayProduct
        #            # 11 : fromHardProcessBeforeFSR
        #            # 12 : isFirstCopy
        #            # 13 : isLastCopy
        #            # 14 : isLastCopyBeforeFSR
        #
        #            if int(binary[14])==0: continue
        #            if int(binary[6])==0: continue
        #            #print 'Tau found with status = 2 (pt, eta) = ', event.GenPart_pt[igp], event.GenPart_eta[igp], event.GenPart_statusFlags[igp]
        #
        #            ngentaus += 1
        #            _pdg_ = -1
        #            _idx_ = event.GenPart_genPartIdxMother[igp]
        #            #_status_ = -1
        #            flag_resonance = False
        #
        #            while abs(_pdg_) not in [9000002, 9000006]:
        #                if _idx_==-1: break
        #                _pdg_ = event.GenPart_pdgId[_idx_]
        #                # _status_ = event.GenPart_status[_idx_]
        #                _idx_ = event.GenPart_genPartIdxMother[_idx_]
        #                if abs(_pdg_) > 30 and abs(_pdg_) not in [9000002, 9000006]:
        #                    flag_resonance = True
        #                #print '\t (pdg, mother id) = ', _pdg_, _status_, _idx_
        #            if flag_resonance: continue
        #            _dr_ = 100.
        #            for igvt in range(event.nGenVisTau):
        #                dr = deltaR(event.GenPart_eta[igp], event.GenPart_phi[igp], event.GenVisTau_eta[igvt], event.GenVisTau_phi[igvt])
        #                #print dr, _dr_, event.GenPart_eta[igp], event.GenPart_phi[igp], event.GenVisTau_eta[igvt], event.GenVisTau_phi[igvt]
        #                if _dr_ > dr:
        #                    _dr_ = dr
        #            #print 'match !',_pdg_, event.nGenVisTau,  _dr_
        #            if _dr_ < 0.1:
        #                ngentauhads += 1
        #
        #    #for igvt in range(event.nGenVisTau):
        #    #    print 'status = ', event.GenVisTau_status[igvt], 'mother ID = ', event.GenVisTau_genPartIdxMother[igvt], 'pt = ', event.GenVisTau_pt[igvt], ', eta = ', event.GenVisTau_eta[igvt]
        #    #    ngentauhads += 1
        #
        #    if ngentaus != 2:
        #       print 'WOW!!! ngentaus = %d != 2'%(ngentaus)

        #####################################
        self.out.cutflow.Fill(self.Nocut)
        #if ngentauhads == 2:
        #   self.out.cutflow.Fill(self.Nocut_GT)
        if self.isData:
            self.out.cutflow.Fill(self.TotalWeighted, 1.)
            if event.PV_npvs > 0:
                self.out.cutflow.Fill(self.TotalWeighted_no0PU, 1.)
            else:
                return False
        else:
            self.out.cutflow.Fill(self.TotalWeighted, event.genWeight)
            self.out.pileup.Fill(event.Pileup_nTrueInt)
            if event.Pileup_nTrueInt > 0:
                self.out.cutflow.Fill(self.TotalWeighted_no0PU,
                                      event.genWeight)
            else:
                return False
        #####################################

        if not self.trigger(event):
            return False

        #####################################
        self.out.cutflow.Fill(self.Trigger)
        #if ngentauhads == 2:
        #    self.out.cutflow.Fill(self.Trigger_GT)
        #####################################

        Tau_genmatch = {}  # bug in Tau_genPartFlav
        idx_goodtaus = []
        for itau in range(event.nTau):
            if abs(event.Tau_eta[itau]) > 2.1: continue
            if abs(event.Tau_dz[itau]) > 0.2: continue
            if event.Tau_decayMode[itau] not in [0, 1, 10]: continue
            if abs(event.Tau_charge[itau]) != 1: continue
            if not self.vlooseIso(event, itau): continue
            if not self.isData:
                Tau_genmatch[itau] = genmatch(event, itau)
                #if self.tes!=1.0:
                #  event.Tau_pt[itau]   *= self.tes
                #  event.Tau_mass[itau] *= self.tes
            if event.Tau_pt[itau] < self.tauCutPt: continue
            idx_goodtaus.append(itau)

        if len(idx_goodtaus) < 2:
            return False

        #####################################
        self.out.cutflow.Fill(self.GoodTaus)
        #if ngentauhads == 2:
        #    self.out.cutflow.Fill(self.GoodTaus_GT)
        #####################################

        taus = Collection(event, 'Tau')
        ditaus = []
        for idx1 in idx_goodtaus:
            for idx2 in idx_goodtaus:
                if idx1 >= idx2: continue
                dR = taus[idx1].p4().DeltaR(taus[idx2].p4())
                if dR < 0.5: continue
                ditau = DiTauPair(idx1, event.Tau_pt[idx1],
                                  event.Tau_rawMVAoldDM[idx1], idx2,
                                  event.Tau_pt[idx2],
                                  event.Tau_rawMVAoldDM[idx2])
                ditaus.append(ditau)

        if len(ditaus) == 0:
            return False

        ditau = bestDiLepton(ditaus)
        tau1 = taus[ditau.id1].p4()
        tau2 = taus[ditau.id2].p4()
        #print 'chosen tau1 (idx, pt) = ', ditau.id1, ditau.tau1_pt, 'check', tau1.p4().Pt()
        #print 'chosen tau2 (idx, pt) = ', ditau.id2, ditau.tau2_pt, 'check', tau2.p4().Pt()

        #####################################
        self.out.cutflow.Fill(self.GoodDiTau)
        #if ngentauhads == 2:
        #    self.out.cutflow.Fill(self.GoodDiTau_GT)
        #####################################

        # VETOS
        self.out.extramuon_veto[0], self.out.extraelec_veto[
            0], self.out.dilepton_veto[0] = extraLeptonVetos(
                event, [-1], [-1], self.name)
        self.out.lepton_vetos[0] = self.out.extramuon_veto[
            0] or self.out.extraelec_veto[0] or self.out.dilepton_veto[0]

        jetIds = []
        bjetIds = []
        jets = Collection(event, 'Jet')
        #jets = filter(self.jetSel,jets):
        nfjets = 0
        ncjets = 0
        nbtag = 0
        for ijet in range(event.nJet):
            if event.Jet_pt[ijet] < 30: continue
            if abs(event.Jet_eta[ijet]) > 4.7: continue
            if tau1.DeltaR(jets[ijet].p4()) < 0.5: continue
            if tau2.DeltaR(jets[ijet].p4()) < 0.5: continue
            jetIds.append(ijet)

            if abs(event.Jet_eta[ijet]) > 2.4:
                nfjets += 1
            else:
                ncjets += 1

            if event.Jet_btagDeepB[ijet] > self.deepcsv_wp.medium:
                nbtag += 1
                bjetIds.append(ijet)

        if not self.isData and self.vlooseIso(
                event, ditau.id1) and self.vlooseIso(event, ditau.id2):
            self.btagTool.fillEfficiencies(event, jetIds)

        #eventSum = TLorentzVector()
        #
        #for lep in muons :
        #    eventSum += lep.p4()
        #for lep in electrons :
        #    eventSum += lep.p4()
        #for j in filter(self.jetSel,jets):
        #    eventSum += j.p4()

        # EVENT
        self.out.isData[0] = self.isData
        self.out.run[0] = event.run
        self.out.lumi[0] = event.luminosityBlock
        #print 'event =', event.event & 0xffffffffffffffff, 'original = ', event.event
        self.out.event[0] = event.event & 0xffffffffffffffff
        ###self.out.puppimetpt[0]                = event.PuppiMET_pt
        ###self.out.puppimetphi[0]               = event.PuppiMET_phi
        ###self.out.metsignificance[0]           = event.MET_significance
        ###self.out.metcovXX[0]                  = event.MET_covXX
        ###self.out.metcovXY[0]                  = event.MET_covXY
        ###self.out.metcovYY[0]                  = event.MET_covYY
        ###self.out.fixedGridRhoFastjetAll[0]    = event.fixedGridRhoFastjetAll
        self.out.npvs[0] = event.PV_npvs
        self.out.npvsGood[0] = event.PV_npvsGood

        if not self.isData:
            self.out.ngentauhads[0] = ngentauhads
            self.out.ngentaus[0] = ngentaus
            self.out.genmet[0] = event.GenMET_pt
            self.out.genmetphi[0] = event.GenMET_phi
            self.out.nPU[0] = event.Pileup_nPU
            self.out.nTrueInt[0] = event.Pileup_nTrueInt
            try:
                self.out.LHE_Njets[0] = event.LHE_Njets
            except RuntimeError:
                self.out.LHE_Njets[0] = -1
        #print 'check (LO)', event.LHE_NpLO, type(event.LHE_NpLO)
        #print 'check (NLO)', event.LHE_NpNLO, type(event.LHE_NpNLO)
        #self.out.LHE_NpLO[0]                   = event.LHE_NpLO
        #self.out.LHE_NpNLO[0]                  = event.LHE_NpNLO
        #print self.out.LHE_Njets[0], event.LHE_Njets
        #print self.out.event[0], event.event, (event.event & 0xffffffffffffffff)
        #print self.out.LHE_Njets[0], event.LHE_Njets, int(event.LHE_Njets)
        #print event.LHE_NpNLO
        #print self.out.Pileup_nPU, event.Pileup_nPU

        # TAU 1
        self.out.pt_1[0] = event.Tau_pt[ditau.id1]
        self.out.eta_1[0] = event.Tau_eta[ditau.id1]
        self.out.phi_1[0] = event.Tau_phi[ditau.id1]
        self.out.m_1[0] = event.Tau_mass[ditau.id1]
        self.out.dxy_1[0] = event.Tau_dxy[ditau.id1]
        self.out.dz_1[0] = event.Tau_dz[ditau.id1]
        self.out.leadTkPtOverTauPt_1[0] = event.Tau_leadTkPtOverTauPt[
            ditau.id1]
        self.out.chargedIso_1[0] = event.Tau_chargedIso[ditau.id1]
        self.out.neutralIso_1[0] = event.Tau_neutralIso[ditau.id1]
        self.out.photonsOutsideSignalCone_1[
            0] = event.Tau_photonsOutsideSignalCone[ditau.id1]
        self.out.puCorr_1[0] = event.Tau_puCorr[ditau.id1]
        self.out.rawAntiEle_1[0] = event.Tau_rawAntiEle[ditau.id1]
        self.out.rawIso_1[0] = event.Tau_rawIso[ditau.id1]
        self.out.rawMVAnewDM2017v2_1[0] = event.Tau_rawMVAnewDM2017v2[
            ditau.id1]
        self.out.rawMVAoldDM_1[0] = event.Tau_rawMVAoldDM[ditau.id1]
        self.out.rawMVAoldDM2017v1_1[0] = event.Tau_rawMVAoldDM2017v1[
            ditau.id1]
        self.out.rawMVAoldDM2017v2_1[0] = event.Tau_rawMVAoldDM2017v2[
            ditau.id1]
        self.out.q_1[0] = event.Tau_charge[ditau.id1]
        self.out.decayMode_1[0] = event.Tau_decayMode[ditau.id1]
        ###self.out.rawAntiEleCat_1[0]            = event.Tau_rawAntiEleCat[ditau.id1]
        self.out.idAntiEle_1[0] = ord(event.Tau_idAntiEle[ditau.id1])
        self.out.idAntiMu_1[0] = ord(event.Tau_idAntiMu[ditau.id1])
        self.out.idDecayMode_1[0] = event.Tau_idDecayMode[ditau.id1]
        self.out.idDecayModeNewDMs_1[0] = event.Tau_idDecayModeNewDMs[
            ditau.id1]
        self.out.idMVAnewDM2017v2_1[0] = ord(
            event.Tau_idMVAnewDM2017v2[ditau.id1])
        self.out.idMVAoldDM_1[0] = ord(event.Tau_idMVAoldDM[ditau.id1])
        self.out.idMVAoldDM2017v1_1[0] = ord(
            event.Tau_idMVAoldDM2017v1[ditau.id1])
        self.out.idMVAoldDM2017v2_1[0] = ord(
            event.Tau_idMVAoldDM2017v2[ditau.id1])

        # TAU 2
        self.out.pt_2[0] = event.Tau_pt[ditau.id2]
        self.out.eta_2[0] = event.Tau_eta[ditau.id2]
        self.out.phi_2[0] = event.Tau_phi[ditau.id2]
        self.out.m_2[0] = event.Tau_mass[ditau.id2]
        self.out.dxy_2[0] = event.Tau_dxy[ditau.id2]
        self.out.dz_2[0] = event.Tau_dz[ditau.id2]
        self.out.leadTkPtOverTauPt_2[0] = event.Tau_leadTkPtOverTauPt[
            ditau.id2]
        self.out.chargedIso_2[0] = event.Tau_chargedIso[ditau.id2]
        self.out.neutralIso_2[0] = event.Tau_neutralIso[ditau.id2]
        self.out.photonsOutsideSignalCone_2[
            0] = event.Tau_photonsOutsideSignalCone[ditau.id2]
        self.out.puCorr_2[0] = event.Tau_puCorr[ditau.id2]
        self.out.rawAntiEle_2[0] = event.Tau_rawAntiEle[ditau.id2]
        self.out.rawIso_2[0] = event.Tau_rawIso[ditau.id2]
        self.out.q_2[0] = event.Tau_charge[ditau.id2]
        self.out.decayMode_2[0] = event.Tau_decayMode[ditau.id2]
        ###self.out.rawAntiEleCat_2[0]            = event.Tau_rawAntiEleCat[ditau.id2]
        self.out.idAntiEle_2[0] = ord(event.Tau_idAntiEle[ditau.id2])
        self.out.idAntiMu_2[0] = ord(event.Tau_idAntiMu[ditau.id2])
        self.out.idDecayMode_2[0] = event.Tau_idDecayMode[ditau.id2]
        self.out.idDecayModeNewDMs_2[0] = event.Tau_idDecayModeNewDMs[
            ditau.id2]
        self.out.rawMVAoldDM_2[0] = event.Tau_rawMVAoldDM[ditau.id2]
        self.out.rawMVAoldDM2017v1_2[0] = event.Tau_rawMVAoldDM2017v1[
            ditau.id2]
        self.out.rawMVAoldDM2017v2_2[0] = event.Tau_rawMVAoldDM2017v2[
            ditau.id2]
        self.out.rawMVAnewDM2017v2_2[0] = event.Tau_rawMVAnewDM2017v2[
            ditau.id2]
        self.out.idMVAoldDM_2[0] = ord(event.Tau_idMVAoldDM[ditau.id2])
        self.out.idMVAoldDM2017v1_2[0] = ord(
            event.Tau_idMVAoldDM2017v1[ditau.id2])
        self.out.idMVAoldDM2017v2_2[0] = ord(
            event.Tau_idMVAoldDM2017v2[ditau.id2])
        self.out.idMVAnewDM2017v2_2[0] = ord(
            event.Tau_idMVAnewDM2017v2[ditau.id2])

        # GENERATOR
        if not self.isData:
            self.out.genPartFlav_1[0] = Tau_genmatch[ditau.id1]
            self.out.genPartFlav_2[0] = Tau_genmatch[ditau.id2]

            genvistau = Collection(event, 'GenVisTau')
            dRmax1, dRmax2 = .5, .5
            gendm1, gendm2 = -1, -1
            genpt1, genpt2 = -1, -1
            geneta1, geneta2 = -9, -9
            genphi1, genphi2 = -9, -9
            for igvt in range(event.nGenVisTau):
                dR = genvistau[igvt].p4().DeltaR(tau1)
                if dR < dRmax1:
                    dRmax1 = dR
                    gendm1 = event.GenVisTau_status[igvt]
                    genpt1 = event.GenVisTau_pt[igvt]
                    geneta1 = event.GenVisTau_eta[igvt]
                    genphi1 = event.GenVisTau_phi[igvt]
                dR = genvistau[igvt].p4().DeltaR(tau2)
                if dR < dRmax2:
                    dRmax2 = dR
                    gendm2 = event.GenVisTau_status[igvt]
                    genpt2 = event.GenVisTau_pt[igvt]
                    geneta2 = event.GenVisTau_eta[igvt]
                    genphi2 = event.GenVisTau_phi[igvt]

            self.out.gendecayMode_1[0] = gendm1
            self.out.genvistaupt_1[0] = genpt1
            self.out.genvistaueta_1[0] = geneta1
            self.out.genvistauphi_1[0] = genphi1

            self.out.gendecayMode_2[0] = gendm2
            self.out.genvistaupt_2[0] = genpt2
            self.out.genvistaueta_2[0] = geneta2
            self.out.genvistauphi_2[0] = genphi2

        # WEIGHTS
        met = TLorentzVector()
        met.SetPxPyPzE(event.MET_pt * cos(event.MET_phi),
                       event.MET_pt * sin(event.MET_phi), 0, event.MET_pt)
        if not self.isData:
            if self.doRecoil:
                boson, boson_vis = getBoson(event)
                self.recoilTool.CorrectPFMETByMeanResolution(
                    met, boson, boson_vis, len(jetIds))
                event.MET_pt = met.Pt()
                event.MET_phi = met.Phi()
                self.out.m_genboson[0] = boson.M()
                self.out.pt_genboson[0] = boson.Pt()
                if self.doZpt:
                    self.out.zptweight[0] = self.zptTool.getZptWeight(
                        boson.Pt(), boson.M())
            elif self.doZpt:
                zboson = getZBoson(event)
                self.out.m_genboson[0] = zboson.M()
                self.out.pt_genboson[0] = zboson.Pt()
                self.out.zptweight[0] = self.zptTool.getZptWeight(
                    zboson.Pt(), zboson.M())
            elif self.doTTpt:
                toppt1, toppt2 = getTTPt(event)
                self.out.ttptweight[0] = getTTptWeight(toppt1, toppt2)
            diTauLeg1SF = self.tauSFs.getTriggerSF(self.out.pt_1[0],
                                                   self.out.eta_1[0],
                                                   self.out.phi_1[0],
                                                   self.out.decayMode_1[0],
                                                   self.out.genPartFlav_1[0])
            diTauLeg2SF = self.tauSFs.getTriggerSF(self.out.pt_2[0],
                                                   self.out.eta_2[0],
                                                   self.out.phi_2[0],
                                                   self.out.decayMode_2[0],
                                                   self.out.genPartFlav_2[0])
            diTauLeg1SFVT = self.tauSFsVT.getTriggerSF(
                self.out.pt_1[0], self.out.eta_1[0], self.out.phi_1[0],
                self.out.decayMode_1[0], self.out.genPartFlav_1[0])
            diTauLeg2SFVT = self.tauSFsVT.getTriggerSF(
                self.out.pt_2[0], self.out.eta_2[0], self.out.phi_2[0],
                self.out.decayMode_2[0], self.out.genPartFlav_2[0])
            self.out.genweight[0] = event.genWeight
            self.out.trigweight[0] = diTauLeg1SF * diTauLeg2SF
            self.out.trigweightVT[0] = diTauLeg1SFVT * diTauLeg2SFVT
            self.out.puweight[0] = self.puTool.getWeight(event.Pileup_nTrueInt)
            self.out.idisoweight_1[0] = self.ltfSFs.getSF(
                self.out.genPartFlav_1[0], self.out.eta_1[0])
            self.out.idisoweight_2[0] = self.ltfSFs.getSF(
                self.out.genPartFlav_2[0], self.out.eta_2[0])
            self.out.btagweight[0] = self.btagTool.getWeight(event, jetIds)
            self.out.weight[0] = self.out.genweight[0] * self.out.puweight[
                0] * self.out.trigweight[0] * self.out.idisoweight_1[
                    0] * self.out.idisoweight_2[0]

        # JETS
        self.out.njets[0] = len(jetIds)
        self.out.njets50[0] = len([j for j in jetIds if event.Jet_pt[j] > 50])
        self.out.nfjets[0] = nfjets
        self.out.ncjets[0] = ncjets
        self.out.nbtag[0] = nbtag

        if len(jetIds) > 0:
            self.out.jpt_1[0] = event.Jet_pt[jetIds[0]]
            self.out.jeta_1[0] = event.Jet_eta[jetIds[0]]
            self.out.jphi_1[0] = event.Jet_phi[jetIds[0]]
            self.out.jdeepb_1[0] = event.Jet_btagDeepB[jetIds[0]]
        else:
            self.out.jpt_1[0] = -9.
            self.out.jeta_1[0] = -9.
            self.out.jphi_1[0] = -9.
            self.out.jdeepb_1[0] = -9.

        if len(jetIds) > 1:
            self.out.jpt_2[0] = event.Jet_pt[jetIds[1]]
            self.out.jeta_2[0] = event.Jet_eta[jetIds[1]]
            self.out.jphi_2[0] = event.Jet_phi[jetIds[1]]
            self.out.jdeepb_2[0] = event.Jet_btagDeepB[jetIds[1]]
        else:
            self.out.jpt_2[0] = -9.
            self.out.jeta_2[0] = -9.
            self.out.jphi_2[0] = -9.
            self.out.jdeepb_2[0] = -9.

        if len(bjetIds) > 0:
            self.out.bpt_1[0] = event.Jet_pt[bjetIds[0]]
            self.out.beta_1[0] = event.Jet_eta[bjetIds[0]]
        else:
            self.out.bpt_1[0] = -9.
            self.out.beta_1[0] = -9.

        if len(bjetIds) > 1:
            self.out.bpt_2[0] = event.Jet_pt[bjetIds[1]]
            self.out.beta_2[0] = event.Jet_eta[bjetIds[1]]
        else:
            self.out.bpt_2[0] = -9.
            self.out.beta_2[0] = -9.

        self.out.met[0] = event.MET_pt
        self.out.metphi[0] = event.MET_phi
        self.out.pfmt_1[0] = sqrt(
            2 * self.out.pt_1[0] * self.out.met[0] *
            (1 - cos(deltaPhi(self.out.phi_1[0], self.out.metphi[0]))))
        self.out.pfmt_2[0] = sqrt(
            2 * self.out.pt_2[0] * self.out.met[0] *
            (1 - cos(deltaPhi(self.out.phi_2[0], self.out.metphi[0]))))

        self.out.m_vis[0] = (tau1 + tau2).M()
        self.out.pt_ll[0] = (tau1 + tau2).Pt()
        self.out.dR_ll[0] = tau1.DeltaR(tau2)
        self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0])
        self.out.deta_ll[0] = abs(self.out.eta_1[0] - self.out.eta_2[0])

        # PZETA
        leg1 = TVector3(tau1.Px(), tau1.Py(), 0.)
        leg2 = TVector3(tau2.Px(), tau2.Py(), 0.)
        zetaAxis = TVector3(leg1.Unit() + leg2.Unit()).Unit()
        pzeta_vis = leg1 * zetaAxis + leg2 * zetaAxis
        pzeta_miss = met.Vect() * zetaAxis
        self.out.pzetamiss[0] = pzeta_miss
        self.out.pzetavis[0] = pzeta_vis
        self.out.dzeta[0] = pzeta_miss - 0.85 * pzeta_vis

        self.out.tree.Fill()
        return True
Пример #11
0
    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        self.out = wrappedOutputTree
        self.out.branch("iSkim", "I")
        self.out.branch("isMC", "I")
        self.out.branch("isSingleMuIsoTrigger", "I")
        self.out.branch("isSingleMuTrigger", "I")
        self.out.branch("isDoubleMuonTrigger", "I")
        self.out.branch("isSingleEleIsoTrigger", "I")
        self.out.branch("isSingleEleTrigger", "I")
        self.out.branch("passedMETFilters", "I")
        self.out.branch("nCleanElectron", "I")
        self.out.branch("nCleanMuon", "I")
        self.out.branch("nCleanJet", "I")
        self.out.branch("Z_mass", "F")
        self.out.branch("Z_pt", "F")
        self.out.branch("W_mass", "F")
        self.out.branch("W_tmass", "F")
        self.out.branch("W_pt", "F")
        self.out.branch("ll_dEta", "F")
        self.out.branch("ll_dPhi", "F")
        self.out.branch("ll_dR", "F")
        self.out.branch("Wqq_mass", "F")
        self.out.branch("Tlvb1_mass", "F")
        self.out.branch("Tlvb2_mass", "F")
        self.out.branch("Tqqb1_mass", "F")
        self.out.branch("Tqqb2_mass", "F")
        self.out.branch("jj_mass", "F")
        self.out.branch("jj_pt", "F")
        self.out.branch("jj_dEta", "F")
        self.out.branch("jj_dPhi", "F")
        self.out.branch("jj_dR", "F")
        self.out.branch("nj_mass", "F")
        self.out.branch("vis_mass", "F")
        self.out.branch("lljj_mass", "F")
        self.out.branch("minMuonIso", "F")
        self.out.branch("maxMuonIso", "F")
        self.out.branch("minMuonMetDPhi", "F")
        self.out.branch("maxMuonMetDPhi", "F")
        self.out.branch("minMuonJetDR", "F")
        self.out.branch("HT30", "F")
        self.out.branch("nj20", "I")
        self.out.branch("nj30", "I")
        self.out.branch("nj40", "I")
        self.out.branch("nBJet", "I")
        self.out.branch("CSV1", "F")
        self.out.branch("CSV2", "F")
        self.out.branch("CSV3", "F")
        self.out.branch("CSV4", "F")
        self.out.branch("iCSV1", "I")
        self.out.branch("iCSV2", "I")
        self.out.branch("iCSV3", "I")
        self.out.branch("iCSV4", "I")
        self.out.branch("lumiWeight", "F")
        self.out.branch("lheWeight", "F")
        self.out.branch("stitchWeight", "F")
        self.out.branch("puWeight", "F")
        self.out.branch("topWeight", "F")
        self.out.branch("qcdnloWeight", "F")
        self.out.branch("qcdnnloWeight", "F")
        self.out.branch("ewknloWeight", "F")
        self.out.branch("triggerWeight", "F")
        self.out.branch("leptonWeight", "F")
        self.out.branch("eventWeightLumi", "F")

        self.fileName = inputFile.GetName()
        self.sampleName = getNameFromFile(self.fileName)

        self.isMC = not "Run201" in self.fileName

        print "+ Opening file", self.fileName

        # b-tagging working points for DeepCSV
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X
        if "Run2016" in self.fileName or "Summer16" in self.fileName:
            self.year = 2016
            self.lumi = 35920.
            self.btagLoose = 0.2217  #0.0614
            self.btagMedium = 0.6321  #0.3093
            self.btagTight = 0.8953  #0.7221
        elif "Run2017" in self.fileName or "Fall17" in self.fileName:
            self.year = 2017
            self.lumi = 41530.
            self.btagLoose = 0.1522  #0.0521
            self.btagMedium = 0.4941  #0.3033
            self.btagTight = 0.8001  #0.7489
        elif "Run2018" in self.fileName or "Autumn18" in self.fileName:
            self.year = 2018
            self.lumi = 59740.
            self.btagLoose = 0.1241  #0.0494
            self.btagMedium = 0.4184  #0.2770
            self.btagTight = 0.7527  #0.7264
        else:
            print "- Unknown year, aborting module"
            import sys
            sys.exit()

        self.xs = XS[self.sampleName] if self.sampleName in XS else 0.
        self.nevents = EV[self.sampleName] if self.sampleName in EV else 0.
        self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1.
        self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1.
        self.isLO = abs(
            self.nevents % 1
        ) < 1.e-6  # if True, the event count is integer, so the weight should be normalized (+1)

        print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb"
        print "+ Sample", self.sampleName, (
            "is LO" if self.isLO else
            "is not LO"), ", XS", self.xs, ", events", self.nevents
        print "+ Weight", self.lumiWeight
        if self.isMC and self.isLO:
            print "+ Sample is LO, gen weight will be set to 1"
        #        self.puTool = PileupWeightTool(year = year) if self.isMC else None

        self.SingleMuIsoTriggers = [
            "HLT_IsoMu24", "HLT_IsoTkMu24", "HLT_IsoMu27", "HLT_IsoTkMu27"
        ]
        self.SingleMuTriggers = [
            "HLT_Mu50", "HLT_TkMu50", "HLT_Mu100", "HLT_TkMu100"
        ]
        self.DoubleMuonTriggers = [
            "HLT_Mu17_Mu8", "HLT_Mu17_Mu8_DZ", "HLT_Mu17_TkMu8_DZ"
        ]
        self.SingleEleIsoTriggers = [
            "HLT_Ele27_WPTight_Gsf", "HLT_Ele27_WPLoose_Gsf",
            "HLT_Ele32_WPTight_Gsf", "HLT_Ele35_WPTight_Gsf"
        ]
        self.SingleEleTriggers = [
            "HLT_Ele105_CaloIdVT_GsfTrkIdT", "HLT_Ele115_CaloIdVT_GsfTrkIdT",
            "HLT_Photon175", "HLT_Photon200"
        ]

        if self.isMC:
            self.muSFs = MuonSFs(year=self.year)
            self.elSFs = ElectronSFs(year=self.year)
            self.puTool = PileupWeightTool(year=self.year)
            #            self.btagToolAK8 = BTagWeightTool('CSVv2','AK8','loose',sigma='central',channel='ll',year=year)
            #            self.btagToolAK4 = BTagWeightTool('CSVv2','AK4','loose',sigma='central',channel='ll',year=year)
            #            self.btagToolAK8_deep = BTagWeightTool('DeepCSV','AK8','loose',sigma='central',channel='ll',year=year)
            #            self.btagToolAK8_deep_up = BTagWeightTool('DeepCSV','AK8','loose',sigma='up',channel='ll',year=year)
            #            self.btagToolAK8_deep_down = BTagWeightTool('DeepCSV','AK8','loose',sigma='down',channel='ll',year=year)
            #            self.btagToolAK4_deep = BTagWeightTool('DeepCSV','AK4','loose',sigma='central',channel='ll',year=year)
            #            self.btagToolAK4_deep_up = BTagWeightTool('DeepCSV','AK4','loose',sigma='up',channel='ll',year=year)
            #            self.btagToolAK4_deep_down = BTagWeightTool('DeepCSV','AK4','loose',sigma='down',channel='ll',year=year)
            if 'DYJetsToLL_M-50' in self.fileName:
                self.VptCorr = DYCorrection('DYJetsToLL')
            elif 'ZJetsToNuNu' in self.fileName:
                self.VptCorr = DYCorrection('ZJetsToNuNu')
            elif 'WJetsToLNu' in self.fileName:
                self.VptCorr = DYCorrection('WJetsToLNu')
            else:
                self.VptCorr = None
Пример #12
0
class SameSign(Module):
    def __init__(self):
        self.writeHistFile = True

    def beginJob(self, histFile=None, histDirName=None):
        Module.beginJob(self, histFile, histDirName)
        self.event = 0
        self.hists = {}
        self.hists["Events"] = ROOT.TH1F("Events", "Events", 1, 0, 1)
#        self.addObject(self.h_events)
#        self.h_events.SetDirectory

    def endJob(self):
        Module.endJob(self)
        print "+ Module ended successfully,"  #, self.h_events.GetEntries(), "events analyzed"
        pass

    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        self.out = wrappedOutputTree
        self.out.branch("iSkim", "I")
        self.out.branch("isMC", "I")
        self.out.branch("isSingleMuIsoTrigger", "I")
        self.out.branch("isSingleMuTrigger", "I")
        self.out.branch("isDoubleMuonTrigger", "I")
        self.out.branch("isSingleEleIsoTrigger", "I")
        self.out.branch("isSingleEleTrigger", "I")
        self.out.branch("passedMETFilters", "I")
        self.out.branch("nCleanElectron", "I")
        self.out.branch("nCleanMuon", "I")
        self.out.branch("nCleanJet", "I")
        self.out.branch("Z_mass", "F")
        self.out.branch("Z_pt", "F")
        self.out.branch("W_mass", "F")
        self.out.branch("W_tmass", "F")
        self.out.branch("W_pt", "F")
        self.out.branch("ll_dEta", "F")
        self.out.branch("ll_dPhi", "F")
        self.out.branch("ll_dR", "F")
        self.out.branch("Wqq_mass", "F")
        self.out.branch("Tlvb1_mass", "F")
        self.out.branch("Tlvb2_mass", "F")
        self.out.branch("Tqqb1_mass", "F")
        self.out.branch("Tqqb2_mass", "F")
        self.out.branch("jj_mass", "F")
        self.out.branch("jj_pt", "F")
        self.out.branch("jj_dEta", "F")
        self.out.branch("jj_dPhi", "F")
        self.out.branch("jj_dR", "F")
        self.out.branch("nj_mass", "F")
        self.out.branch("vis_mass", "F")
        self.out.branch("lljj_mass", "F")
        self.out.branch("minMuonIso", "F")
        self.out.branch("maxMuonIso", "F")
        self.out.branch("minMuonMetDPhi", "F")
        self.out.branch("maxMuonMetDPhi", "F")
        self.out.branch("minMuonJetDR", "F")
        self.out.branch("HT30", "F")
        self.out.branch("nj20", "I")
        self.out.branch("nj30", "I")
        self.out.branch("nj40", "I")
        self.out.branch("nBJet", "I")
        self.out.branch("CSV1", "F")
        self.out.branch("CSV2", "F")
        self.out.branch("CSV3", "F")
        self.out.branch("CSV4", "F")
        self.out.branch("iCSV1", "I")
        self.out.branch("iCSV2", "I")
        self.out.branch("iCSV3", "I")
        self.out.branch("iCSV4", "I")
        self.out.branch("lumiWeight", "F")
        self.out.branch("lheWeight", "F")
        self.out.branch("stitchWeight", "F")
        self.out.branch("puWeight", "F")
        self.out.branch("topWeight", "F")
        self.out.branch("qcdnloWeight", "F")
        self.out.branch("qcdnnloWeight", "F")
        self.out.branch("ewknloWeight", "F")
        self.out.branch("triggerWeight", "F")
        self.out.branch("leptonWeight", "F")
        self.out.branch("eventWeightLumi", "F")

        self.fileName = inputFile.GetName()
        self.sampleName = getNameFromFile(self.fileName)

        self.isMC = not "Run201" in self.fileName

        print "+ Opening file", self.fileName

        # b-tagging working points for DeepCSV
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X
        if "Run2016" in self.fileName or "Summer16" in self.fileName:
            self.year = 2016
            self.lumi = 35920.
            self.btagLoose = 0.2217  #0.0614
            self.btagMedium = 0.6321  #0.3093
            self.btagTight = 0.8953  #0.7221
        elif "Run2017" in self.fileName or "Fall17" in self.fileName:
            self.year = 2017
            self.lumi = 41530.
            self.btagLoose = 0.1522  #0.0521
            self.btagMedium = 0.4941  #0.3033
            self.btagTight = 0.8001  #0.7489
        elif "Run2018" in self.fileName or "Autumn18" in self.fileName:
            self.year = 2018
            self.lumi = 59740.
            self.btagLoose = 0.1241  #0.0494
            self.btagMedium = 0.4184  #0.2770
            self.btagTight = 0.7527  #0.7264
        else:
            print "- Unknown year, aborting module"
            import sys
            sys.exit()

        self.xs = XS[self.sampleName] if self.sampleName in XS else 0.
        self.nevents = EV[self.sampleName] if self.sampleName in EV else 0.
        self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1.
        self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1.
        self.isLO = abs(
            self.nevents % 1
        ) < 1.e-6  # if True, the event count is integer, so the weight should be normalized (+1)

        print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb"
        print "+ Sample", self.sampleName, (
            "is LO" if self.isLO else
            "is not LO"), ", XS", self.xs, ", events", self.nevents
        print "+ Weight", self.lumiWeight
        if self.isMC and self.isLO:
            print "+ Sample is LO, gen weight will be set to 1"
        #        self.puTool = PileupWeightTool(year = year) if self.isMC else None

        self.SingleMuIsoTriggers = [
            "HLT_IsoMu24", "HLT_IsoTkMu24", "HLT_IsoMu27", "HLT_IsoTkMu27"
        ]
        self.SingleMuTriggers = [
            "HLT_Mu50", "HLT_TkMu50", "HLT_Mu100", "HLT_TkMu100"
        ]
        self.DoubleMuonTriggers = [
            "HLT_Mu17_Mu8", "HLT_Mu17_Mu8_DZ", "HLT_Mu17_TkMu8_DZ"
        ]
        self.SingleEleIsoTriggers = [
            "HLT_Ele27_WPTight_Gsf", "HLT_Ele27_WPLoose_Gsf",
            "HLT_Ele32_WPTight_Gsf", "HLT_Ele35_WPTight_Gsf"
        ]
        self.SingleEleTriggers = [
            "HLT_Ele105_CaloIdVT_GsfTrkIdT", "HLT_Ele115_CaloIdVT_GsfTrkIdT",
            "HLT_Photon175", "HLT_Photon200"
        ]

        if self.isMC:
            self.muSFs = MuonSFs(year=self.year)
            self.elSFs = ElectronSFs(year=self.year)
            self.puTool = PileupWeightTool(year=self.year)
            #            self.btagToolAK8 = BTagWeightTool('CSVv2','AK8','loose',sigma='central',channel='ll',year=year)
            #            self.btagToolAK4 = BTagWeightTool('CSVv2','AK4','loose',sigma='central',channel='ll',year=year)
            #            self.btagToolAK8_deep = BTagWeightTool('DeepCSV','AK8','loose',sigma='central',channel='ll',year=year)
            #            self.btagToolAK8_deep_up = BTagWeightTool('DeepCSV','AK8','loose',sigma='up',channel='ll',year=year)
            #            self.btagToolAK8_deep_down = BTagWeightTool('DeepCSV','AK8','loose',sigma='down',channel='ll',year=year)
            #            self.btagToolAK4_deep = BTagWeightTool('DeepCSV','AK4','loose',sigma='central',channel='ll',year=year)
            #            self.btagToolAK4_deep_up = BTagWeightTool('DeepCSV','AK4','loose',sigma='up',channel='ll',year=year)
            #            self.btagToolAK4_deep_down = BTagWeightTool('DeepCSV','AK4','loose',sigma='down',channel='ll',year=year)
            if 'DYJetsToLL_M-50' in self.fileName:
                self.VptCorr = DYCorrection('DYJetsToLL')
            elif 'ZJetsToNuNu' in self.fileName:
                self.VptCorr = DYCorrection('ZJetsToNuNu')
            elif 'WJetsToLNu' in self.fileName:
                self.VptCorr = DYCorrection('WJetsToLNu')
            else:
                self.VptCorr = None

    def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        outputFile.mkdir("Hists")
        outputFile.cd("Hists")
        for histname, hist in self.hists.iteritems():
            hist.Write()
        outputFile.cd("..")
        print "+ File closed successfully"
        pass

    def analyze(self, event):
        iSkim = 0
        eventWeightLumi, lheWeight, stitchWeight, puWeight, qcdnloWeight, qcdnnloWeight, ewknloWeight, topWeight = 1., 1., 1., 1., 1., 1., 1., 1.
        triggerWeight, leptonWeight = 1., 1.
        MinMuonIso, MaxMuonIso, MinMuonMetDPhi, MaxMuonMetDPhi, MinMuonJetDR = -1., -1., -1., -1., -1.
        mZ, mW, mT, ptZ, ptW = -1., -1., -1., -1., -1.
        dEtaLL, dPhiLL, dRLL = -1., -1., -1.
        mJJ, ptJJ, dEtaJJ, dPhiJJ, dRJJ = -1., -1., -1., -1., -1.
        mLLJJ, mNJ = -1., -1.
        mHadW, mLepTop1, mLepTop2, mHadTop1, mHadTop2 = -1., -1., -1., -1., -1.
        isSingleMuIsoTrigger, isSingleMuTrigger, isDoubleMuonTrigger, isSingleEleIsoTrigger, isSingleEleTrigger = False, False, False, False, False
        for t in self.SingleMuIsoTriggers:
            if hasattr(event, t) and getattr(event, t):
                isSingleMuIsoTrigger = True
        for t in self.SingleMuTriggers:
            if hasattr(event, t) and getattr(event, t):
                isSingleMuTrigger = True
        for t in self.DoubleMuonTriggers:
            if hasattr(event, t) and getattr(event, t):
                isDoubleMuonTrigger = True
        for t in self.SingleEleIsoTriggers:
            if hasattr(event, t) and getattr(event, t):
                isSingleEleIsoTrigger = True
        for t in self.SingleEleTriggers:
            if hasattr(event, t) and getattr(event, t):
                isSingleEleTrigger = True

        lheWeight = 1.

        if self.isMC:
            # Event weight
            if not self.isLO and hasattr(event, "LHEWeight_originalXWGTUP"):
                lheWeight = event.LHEWeight_originalXWGTUP

            GenVpt = self.VptCorr.getGenVpt(
                event) if not self.VptCorr is None else 0.

            # MC stitching weight

            # W+jets inclusive and exclusive
            if 'WJetsToLNu_TuneCUETP8M1_13TeV-amcatnloFXFX-pythia8' in self.fileName and 'Summer16' in self.fileName:
                if event.LHE_Vpt > 100.: stitchWeight = 0.

            # Z+jets and Z+gamma
            if self.fileName.startswith(
                    'ZGTo2LG_TuneCUETP8M1') or self.fileName.startswith(
                        'ZGToLLG_01J_5f_TuneCP5') or self.fileName.startswith(
                            'DYJetsToLL_M-50_Tune'):
                nGenPhotons = 0
                photonPtTh = 15. if self.fileName.startswith(
                    'ZGTo2LG_TuneCUETP8M1') or self.fileName.startswith(
                        'DYJetsToLL_M-50_TuneCUETP8M1') else 20.
                for i in range(event.nGenPart):
                    if GenPart_pdgId[i] == 22 and TMath.Odd(
                            GenPart_statusFlags[i]
                    ) and GenPart_pt > photonPtTh:
                        nGenPhotons += 1
                if self.fileName.startswith('ZG') and nGenPhotons <= 0:
                    stitchWeight = 0.
                if self.fileName.startswith(
                        'DYJetsToLL_M-50') and nGenPhotons >= 1:
                    stitchWeight = 0.

            # PU weight
            puWeight = self.puTool.getWeight(event.Pileup_nTrueInt)

            # Higher order correction weights
            if not self.VptCorr is None:
                if not 'amcatnlo' in self.fileName:
                    qcdnloWeight = self.VptCorr.getWeightQCDNLO(GenVpt)
                qcdnnloWeight = self.VptCorr.getWeightQCDNNLO(GenVpt)
                ewknloWeight = self.VptCorr.getWeightEWKNLO(GenVpt)

            if 'TTTo' in self.fileName:
                Top1_pt, Top2_pt = getTTPt(event)
                topWeight = getTTptWeight(Top1_pt, Top2_pt)

        self.hists["Events"].Fill(0, lheWeight)

        #        electrons = Collection(event, "Electron")
        #        muons = Collection(event, "Muon")
        #        jets = Collection(event, "Jet")
        #        eventSum = ROOT.TLorentzVector()

        #        #select events with at least 2 muons
        #        if len(muons) >=2 :
        #          for lep in muons :     #loop on muons
        #                  eventSum += lep.p4()
        #          for lep in electrons : #loop on electrons
        #            eventSum += lep.p4()
        #          for j in jets :       #loop on jets
        #            eventSum += j.p4()

        # Clean collections

        # Electrons
        cleanElectron = []
        for i in range(event.nElectron):
            if event.Electron_pt[i] > 10. and event.Electron_cutBased[i] >= 2:
                p4 = TLorentzVector()
                p4.SetPtEtaPhiM(event.Electron_pt[i], event.Electron_eta[i],
                                event.Electron_phi[i], event.Electron_mass[i])
                cleanElectron.append(p4)

        # Muons
        cleanMuon = []
        for i in range(event.nMuon):
            if event.Muon_pt[i] > 10. and event.Muon_mediumId[
                    i] and event.Muon_pfRelIso03_all[i] < 0.15:
                p4 = TLorentzVector()
                p4.SetPtEtaPhiM(event.Muon_pt[i], event.Muon_eta[i],
                                event.Muon_phi[i], event.Muon_mass[i])
                cleanMuon.append(p4)

        # Jets and Event variables
        cleanJet, cleanBJet, cleanNonBJet = [], [], []
        HT30, Nj20, Nj30, Nj40, nBJet = 0., 0, 0, 0, 0
        CSVs = []
        twoJets, allJets = TLorentzVector(), TLorentzVector()
        for i in range(event.nJet):
            if event.Jet_jetId[i] >= 6 and abs(event.Jet_eta[i]) < 2.5:
                p4 = TLorentzVector()
                p4.SetPtEtaPhiM(event.Jet_pt[i], event.Jet_eta[i],
                                event.Jet_phi[i], event.Jet_mass[i])
                # remove overlaps with electrons and muons
                cleanFromLeptons = True
                for e in range(len(cleanElectron)):
                    if cleanElectron[e].DeltaR(p4) < 0.4:
                        cleanFromLeptons = False
                for m in range(len(cleanMuon)):
                    if cleanMuon[m].DeltaR(p4) < 0.4: cleanFromLeptons = False
                # fill variables
                if cleanFromLeptons:
                    if event.Jet_pt[i] > 20.:
                        Nj20 += 1
                    if event.Jet_pt[i] > 30.:
                        HT30 += event.Jet_pt[i]
                        Nj30 += 1
                        cleanJet.append(p4)
                        if event.Jet_btagDeepB[i] >= self.btagMedium:
                            cleanBJet.append(p4)
                        else:
                            cleanNonBJet.append(p4)
                        CSVs.append([i, event.Jet_btagDeepB[i]])
                        if len(cleanJet) < 2: twoJets += p4
                        allJets += p4
                    if event.Jet_pt[i] > 40.:
                        Nj40 += 1

        # b-tag ranking
        nBJet = len(cleanBJet)
        CSV1, CSV2, CSV3, CSV4, iCSV1, iCSV2, iCSV3, iCSV4 = 0., 0., 0., 0., -1, -1, -1, -1

        CSVs.sort(key=lambda x: x[1], reverse=True)
        if len(CSVs) > 0: iCSV1, CSV1 = CSVs[0][0], CSVs[0][1]
        if len(CSVs) > 1: iCSV2, CSV2 = CSVs[1][0], CSVs[1][1]
        if len(CSVs) > 2: iCSV3, CSV3 = CSVs[2][0], CSVs[2][1]
        if len(CSVs) > 3: iCSV4, CSV4 = CSVs[3][0], CSVs[3][1]

        if len(cleanJet) >= 2:
            mJJ = (cleanJet[0] + cleanJet[1]).M()
            ptJJ = (cleanJet[0] + cleanJet[1]).Pt()
            dEtaJJ = abs(cleanJet[0].Eta() - cleanJet[1].Eta())
            dPhiJJ = abs(cleanJet[0].DeltaPhi(cleanJet[1]))
            dRJJ = cleanJet[0].DeltaR(cleanJet[1])
        mNJ = allJets.M()

        Lepton1, Lepton2, Lepton3, Neutrino, MET, LLJJ, Vis = TLorentzVector(
        ), TLorentzVector(), TLorentzVector(), TLorentzVector(
        ), TLorentzVector(), TLorentzVector(), TLorentzVector()
        MET.SetPtEtaPhiM(event.MET_pt, 0., event.MET_phi, 0.)

        # Categorization:
        # iSkim = 1: 2 muons (OS or SS)
        # iSkim = 2: 1 muon and 1 electron (no OS requirement)
        # iSkim = 3: 3 muons (assumed that they are not 3 same-sign)
        # iSkim = 4: 2 muons (OS) and 1 electron
        # iSkim = 5: 1 muons, 3 jets, >= 1 btag
        # iSkim = 6: 2 electrons

        # case 3a: 3 lepton CR (3mu)
        if iSkim == 0 and event.nMuon >= 3:
            if (isSingleMuIsoTrigger or isSingleMuTrigger) and event.Muon_pt[
                    0] > 27. and event.Muon_pt[1] > 15. and event.Muon_pt[
                        2] > 15. and event.Muon_mediumId[
                            0] and event.Muon_mediumId[
                                1] and event.Muon_mediumId[2]:
                Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0],
                                     event.Muon_phi[0], event.Muon_mass[0])
                Lepton2.SetPtEtaPhiM(event.Muon_pt[1], event.Muon_eta[1],
                                     event.Muon_phi[1], event.Muon_mass[1])
                Lepton3.SetPtEtaPhiM(event.Muon_pt[2], event.Muon_eta[2],
                                     event.Muon_phi[2], event.Muon_mass[2])
                if event.Muon_charge[0] * event.Muon_charge[1] < 0:
                    mll = (Lepton1 + Lepton2).M()
                    ptll = (Lepton1 + Lepton2).Pt()
                    detall = abs(Lepton1.Eta() - Lepton2.Eta())
                    dphill = abs(Lepton1.DeltaPhi(Lepton2))
                    drll = Lepton1.DeltaR(Lepton2)
                else:
                    mll = (Lepton1 + Lepton3).M()
                    ptll = (Lepton1 + Lepton3).Pt()
                    detall = abs(Lepton1.Eta() - Lepton3.Eta())
                    dphill = abs(Lepton1.DeltaPhi(Lepton3))
                    drll = Lepton1.DeltaR(Lepton3)
                if mll > 15.:
                    iSkim = 3
                    # Variables
                    mZ, ptZ = mll, ptll
                    dEtaLL, dPhiLL, dRLL = detall, dphill, drll
                    MinMuonIso = min(
                        min(event.Muon_pfRelIso03_all[0],
                            event.Muon_pfRelIso03_all[1]),
                        event.Muon_pfRelIso03_all[2])
                    MaxMuonIso = max(
                        max(event.Muon_pfRelIso03_all[0],
                            event.Muon_pfRelIso03_all[1]),
                        event.Muon_pfRelIso03_all[2])
                    MinMuonMetDPhi = min(
                        min(abs(Lepton1.DeltaPhi(MET)),
                            abs(Lepton2.DeltaPhi(MET))),
                        abs(Lepton3.DeltaPhi(MET)))
                    MaxMuonMetDPhi = max(
                        max(abs(Lepton1.DeltaPhi(MET)),
                            abs(Lepton2.DeltaPhi(MET))),
                        abs(Lepton3.DeltaPhi(MET)))
                    MinMuonJetDR = min(
                        min(getMinMuonJetDR(cleanJet, Lepton1),
                            getMinMuonJetDR(cleanJet, Lepton2)),
                        getMinMuonJetDR(cleanJet, Lepton3))
                    LLJJ = twoJets + Lepton1 + Lepton2
                    Vis = allJets + Lepton1 + Lepton2 + Lepton3
                    # Weights
                    if self.isMC:
                        triggerWeight = self.muSFs.getTriggerSF(
                            event.Muon_pt[0], event.Muon_eta[0])
                        IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0],
                                                   event.Muon_eta[0], 2)
                        IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0],
                                                     event.Muon_eta[0])
                        IdSF2 = self.muSFs.getIdSF(event.Muon_pt[1],
                                                   event.Muon_eta[1], 2)
                        IsoSF2 = self.muSFs.getIsoSF(event.Muon_pt[1],
                                                     event.Muon_eta[1])
                        IdSF3 = self.muSFs.getIdSF(event.Muon_pt[2],
                                                   event.Muon_eta[2], 2)
                        IsoSF3 = self.muSFs.getIsoSF(event.Muon_pt[2],
                                                     event.Muon_eta[2])
                        leptonWeight = IdSF1 * IsoSF1 * IdSF2 * IsoSF2 * IdSF3 * IsoSF3

        # case 3b: 3 lepton CR (2mu 1e)
        if iSkim == 0 and event.nMuon >= 2 and event.nElectron >= 1:
            if (isSingleMuIsoTrigger or isSingleMuTrigger) and event.Muon_pt[
                    0] > 27. and event.Muon_pt[1] > 15. and event.Electron_pt[
                        0] > 15. and event.Muon_mediumId[
                            0] and event.Muon_mediumId[
                                1] and event.Electron_cutBased[
                                    0] >= 2 and event.Muon_charge[
                                        0] * event.Muon_charge[1] < 0:
                Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0],
                                     event.Muon_phi[0], event.Muon_mass[0])
                Lepton2.SetPtEtaPhiM(event.Muon_pt[1], event.Muon_eta[1],
                                     event.Muon_phi[1], event.Muon_mass[1])
                Lepton3.SetPtEtaPhiM(event.Electron_pt[0],
                                     event.Electron_eta[0],
                                     event.Electron_phi[0],
                                     event.Electron_mass[0])
                mll = (Lepton1 + Lepton2).M()
                ptll = (Lepton1 + Lepton2).Pt()
                if mll > 15.:
                    iSkim = 4
                    # Variables
                    mZ, ptZ = mll, ptll
                    dEtaLL = abs(Lepton1.Eta() - Lepton2.Eta())
                    dPhiLL = abs(Lepton1.DeltaPhi(Lepton2))
                    dRLL = Lepton1.DeltaR(Lepton2)
                    MinMuonIso = min(event.Muon_pfRelIso03_all[0],
                                     event.Muon_pfRelIso03_all[1])
                    MaxMuonIso = max(event.Muon_pfRelIso03_all[0],
                                     event.Muon_pfRelIso03_all[1])
                    MinMuonMetDPhi = min(
                        min(abs(Lepton1.DeltaPhi(MET)),
                            abs(Lepton2.DeltaPhi(MET))),
                        abs(Lepton3.DeltaPhi(MET)))
                    MaxMuonMetDPhi = max(
                        max(abs(Lepton1.DeltaPhi(MET)),
                            abs(Lepton2.DeltaPhi(MET))),
                        abs(Lepton3.DeltaPhi(MET)))
                    MinMuonJetDR = min(getMinMuonJetDR(cleanJet, Lepton1),
                                       getMinMuonJetDR(cleanJet, Lepton2))
                    LLJJ = twoJets + Lepton1 + Lepton2
                    Vis = allJets + Lepton1 + Lepton2 + Lepton3
                    # Weights
                    if self.isMC:
                        triggerWeight = self.muSFs.getTriggerSF(
                            event.Muon_pt[0], event.Muon_eta[0])
                        IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0],
                                                   event.Muon_eta[0], 2)
                        IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0],
                                                     event.Muon_eta[0])
                        IdSF2 = self.muSFs.getIdSF(event.Muon_pt[1],
                                                   event.Muon_eta[1], 2)
                        IsoSF2 = self.muSFs.getIsoSF(event.Muon_pt[1],
                                                     event.Muon_eta[1])
                        IdIsoSF3 = self.elSFs.getIdIsoSF(
                            event.Electron_pt[0], event.Electron_eta[0])
                        leptonWeight = IdSF1 * IsoSF1 * IdSF2 * IsoSF2 * IdIsoSF3

        # case 1: Z->mumu CR (2 mu)
        if iSkim == 0 and event.nMuon >= 2:
            if (isSingleMuIsoTrigger or isSingleMuTrigger) and event.Muon_pt[
                    0] > 27. and event.Muon_pt[1] > 7. and event.Muon_mediumId[
                        0] and event.Muon_mediumId[1]:
                Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0],
                                     event.Muon_phi[0], event.Muon_mass[0])
                Lepton2.SetPtEtaPhiM(event.Muon_pt[1], event.Muon_eta[1],
                                     event.Muon_phi[1], event.Muon_mass[1])
                mll = (Lepton1 + Lepton2).M()
                ptll = (Lepton1 + Lepton2).Pt()
                if mll > 15.:
                    iSkim = 1
                    # Variables
                    mZ, ptZ = mll, ptll
                    dEtaLL = abs(Lepton1.Eta() - Lepton2.Eta())
                    dPhiLL = abs(Lepton1.DeltaPhi(Lepton2))
                    dRLL = Lepton1.DeltaR(Lepton2)
                    MinMuonIso = min(event.Muon_pfRelIso03_all[0],
                                     event.Muon_pfRelIso03_all[1])
                    MaxMuonIso = max(event.Muon_pfRelIso03_all[0],
                                     event.Muon_pfRelIso03_all[1])
                    MinMuonMetDPhi = min(abs(Lepton1.DeltaPhi(MET)),
                                         abs(Lepton2.DeltaPhi(MET)))
                    MaxMuonMetDPhi = max(abs(Lepton1.DeltaPhi(MET)),
                                         abs(Lepton2.DeltaPhi(MET)))
                    MinMuonJetDR = min(getMinMuonJetDR(cleanJet, Lepton1),
                                       getMinMuonJetDR(cleanJet, Lepton2))
                    LLJJ = twoJets + Lepton1 + Lepton2
                    Vis = allJets + Lepton1 + Lepton2
                    # Weights
                    if self.isMC:
                        triggerWeight = self.muSFs.getTriggerSF(
                            event.Muon_pt[0], event.Muon_eta[0])
                        IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0],
                                                   event.Muon_eta[0], 2)
                        IdSF2 = self.muSFs.getIdSF(event.Muon_pt[1],
                                                   event.Muon_eta[1], 2)
                        IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0],
                                                     event.Muon_eta[0])
                        IsoSF2 = self.muSFs.getIsoSF(event.Muon_pt[1],
                                                     event.Muon_eta[1])
                        leptonWeight = IdSF1 * IdSF2 * IsoSF1 * IsoSF2

        # case 4: Z->ee CR (2 electrons)
        if iSkim == 0 and event.nElectron >= 2:
            if isSingleEleIsoTrigger and event.Electron_pt[
                    0] > 35. and event.Electron_pt[
                        1] > 10. and event.Electron_cutBased[
                            0] > 0 and event.Electron_cutBased[1] > 0:
                Lepton1.SetPtEtaPhiM(event.Electron_pt[0],
                                     event.Electron_eta[0],
                                     event.Electron_phi[0],
                                     event.Electron_mass[0])
                Lepton2.SetPtEtaPhiM(event.Electron_pt[1],
                                     event.Electron_eta[1],
                                     event.Electron_phi[1],
                                     event.Electron_mass[1])
                mll = (Lepton1 + Lepton2).M()
                ptll = (Lepton1 + Lepton2).Pt()
                if mll > 15.:
                    iSkim = 6
                    # Variables
                    mZ, ptZ = mll, ptll
                    dEtaLL = abs(Lepton1.Eta() - Lepton2.Eta())
                    dPhiLL = abs(Lepton1.DeltaPhi(Lepton2))
                    dRLL = Lepton1.DeltaR(Lepton2)
                    MinMuonIso = event.Electron_pfRelIso03_all[0]
                    MaxMuonIso = event.Electron_pfRelIso03_all[0]
                    MinMuonMetDPhi = min(abs(Lepton1.DeltaPhi(MET)),
                                         abs(Lepton2.DeltaPhi(MET)))
                    MaxMuonMetDPhi = max(abs(Lepton1.DeltaPhi(MET)),
                                         abs(Lepton2.DeltaPhi(MET)))
                    MinMuonJetDR = min(getMinMuonJetDR(cleanJet, Lepton1),
                                       getMinMuonJetDR(cleanJet, Lepton2))
                    LLJJ = twoJets + Lepton1 + Lepton2
                    Vis = allJets + Lepton1 + Lepton2
                    # Weights
                    if self.isMC:
                        triggerWeight = self.elSFs.getTriggerSF(
                            event.Electron_pt[0], event.Electron_eta[0])
                        leptonWeight = self.elSFs.getIdIsoSF(
                            event.Electron_pt[0],
                            event.Electron_eta[0]) * self.elSFs.getIdIsoSF(
                                event.Electron_pt[1], event.Electron_eta[1])

        # case 2: ttbar and Z OF CR (1 muon and 1 electron)
        if iSkim == 0 and event.nMuon >= 1 and event.nElectron >= 1:
            if (isSingleMuIsoTrigger or isSingleMuTrigger
                ) and event.Muon_pt[0] > 27. and event.Electron_pt[
                    0] > 20. and event.Muon_mediumId[
                        0] and event.Electron_cutBased[0] >= 2:
                Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0],
                                     event.Muon_phi[0], event.Muon_mass[0])
                Lepton2.SetPtEtaPhiM(event.Electron_pt[0],
                                     event.Electron_eta[0],
                                     event.Electron_phi[0],
                                     event.Electron_mass[0])
                mll = (Lepton1 + Lepton2).M()
                ptll = (Lepton1 + Lepton2).Pt()
                if mll > 15.:
                    iSkim = 2
                    # Variables
                    mZ, ptZ = mll, ptll
                    dEtaLL = abs(Lepton1.Eta() - Lepton2.Eta())
                    dPhiLL = abs(Lepton1.DeltaPhi(Lepton2))
                    dRLL = Lepton1.DeltaR(Lepton2)
                    MinMuonIso = event.Muon_pfRelIso03_all[0]
                    MaxMuonIso = event.Muon_pfRelIso03_all[0]
                    MinMuonMetDPhi = abs(Lepton1.DeltaPhi(MET))
                    MaxMuonMetDPhi = abs(Lepton1.DeltaPhi(MET))
                    MinMuonJetDR = min(getMinMuonJetDR(cleanJet, Lepton1),
                                       getMinMuonJetDR(cleanJet, Lepton2))
                    LLJJ = twoJets + Lepton1 + Lepton2
                    Vis = allJets + Lepton1 + Lepton2
                    # Weights
                    if self.isMC:
                        triggerWeight = self.muSFs.getTriggerSF(
                            Lepton1.Pt(), Lepton1.Eta())
                        IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0],
                                                   event.Muon_eta[0], 2)
                        IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0],
                                                     event.Muon_eta[0])
                        IdIsoSF2 = self.elSFs.getIdIsoSF(
                            event.Electron_pt[0], event.Electron_eta[0])
                        leptonWeight = IdSF1 * IsoSF1 * IdIsoSF2

        # case 4: ttbar CR (1 muon and >= 3 jets)
        if iSkim == 0 and event.nMuon >= 1:
            if (isSingleMuIsoTrigger or isSingleMuTrigger
                ) and event.Muon_pt[0] > 27. and event.Muon_mediumId[
                    0] and event.Muon_pfRelIso03_all[0] < 0.15:
                Lepton1.SetPtEtaPhiM(event.Muon_pt[0], event.Muon_eta[0],
                                     event.Muon_phi[0], event.Muon_mass[0])
                pzN = recoverNeutrinoPz(Lepton1, MET)
                Neutrino.SetPxPyPzE(MET.Px(), MET.Py(), pzN, MET.Pt())
                mW = (Lepton1 + Neutrino).M()
                ptW = (Lepton1 + Neutrino).Pt()
                mT = math.sqrt(2. * Lepton1.Pt() * MET.Pt() *
                               (1. - math.cos(Lepton1.DeltaPhi(MET))))
                if Nj30 >= 3:  # and nBJet >= 1:
                    iSkim = 5
                    # Variables
                    MinMuonIso = event.Muon_pfRelIso03_all[0]
                    MaxMuonIso = event.Muon_pfRelIso03_all[0]
                    MinMuonMetDPhi = abs(Lepton1.DeltaPhi(MET))
                    MaxMuonMetDPhi = abs(Lepton1.DeltaPhi(MET))
                    MinMuonJetDR = getMinMuonJetDR(cleanJet, Lepton1)
                    LLJJ = twoJets + Lepton1
                    Vis = allJets + Lepton1
                    # W and Top reconstruction
                    if len(cleanBJet) >= 2:
                        mLepTop1 = (Lepton1 + Neutrino + cleanBJet[0]).M()
                        mLepTop2 = (Lepton1 + Neutrino + cleanBJet[1]).M()
                    elif len(cleanBJet) >= 1:
                        mLepTop1 = (Lepton1 + Neutrino + cleanBJet[0]).M()
                        mHadTop2 = mHadTop1
                    if len(cleanNonBJet) >= 2:
                        mHadW = (cleanNonBJet[0] + cleanNonBJet[1]).M()
                        if len(cleanBJet) >= 2:
                            mHadTop1 = (cleanNonBJet[0] + cleanNonBJet[1] +
                                        cleanBJet[0]).M()
                            mHadTop2 = (cleanNonBJet[0] + cleanNonBJet[1] +
                                        cleanBJet[1]).M()
                        elif len(cleanBJet) >= 1:
                            mHadTop1 = (cleanNonBJet[0] + cleanNonBJet[1] +
                                        cleanBJet[0]).M()
                            mHadTop2 = mHadTop1
                    # Weights
                    if self.isMC:
                        triggerWeight = self.muSFs.getTriggerSF(
                            Lepton1.Pt(), Lepton1.Eta())
                        IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0],
                                                   event.Muon_eta[0], 2)
                        IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0],
                                                     event.Muon_eta[0])
                        leptonWeight = IdSF1 * IsoSF1

        passedMETFilters = True
        filters = [
            "Flag_goodVertices", "Flag_globalSuperTightHalo2016Filter",
            "Flag_BadPFMuonFilter", "Flag_EcalDeadCellTriggerPrimitiveFilter",
            "Flag_HBHENoiseFilter", "Flag_HBHENoiseIsoFilter",
            "Flag_ecalBadCalibFilter", "Flag_ecalBadCalibFilterV2"
        ]
        if not self.isMC: filters += ["Flag_eeBadScFilter"]
        for f in filters:
            if hasattr(event, f) and getattr(event, f) == False:
                passedMETFilters = False
#        try:
##            if event.Flag_goodVertices: print "Flag_goodVertices"
##            if event.Flag_globalSuperTightHalo2016Filter: print "Flag_globalSuperTightHalo2016Filter"
##            if event.Flag_BadPFMuonFilter: print "Flag_BadPFMuonFilter"
##            if event.Flag_EcalDeadCellTriggerPrimitiveFilter: print "Flag_EcalDeadCellTriggerPrimitiveFilter"
##            if event.Flag_HBHENoiseFilter: print "Flag_HBHENoiseFilter"
##            if event.Flag_HBHENoiseIsoFilter: print "Flag_HBHENoiseIsoFilter"
###            if (self.isMC or event.Flag_eeBadScFilter): print "Flag_eeBadScFilter"
##            if event.Flag_ecalBadCalibFilter: print "Flag_ecalBadCalibFilterV2"
#            if event.Flag_goodVertices and event.Flag_globalSuperTightHalo2016Filter and event.Flag_BadPFMuonFilter and event.Flag_EcalDeadCellTriggerPrimitiveFilter and event.Flag_HBHENoiseFilter and event.Flag_HBHENoiseIsoFilter: # and event.Flag_ecalBadCalibFilter: #and (self.isMC or event.Flag_eeBadScFilter): FIXME
#                passedMETFilters = True
##            if not self.isMC:
##                if not event.Flag_eeBadScFilter:
##                    passedMETFilters = False
#        except:
#            passedMETFilters = False

        if iSkim == 0: return False

        if self.isMC:
            eventWeightLumi = self.lumiWeight * lheWeight * puWeight * topWeight * qcdnloWeight * qcdnnloWeight * ewknloWeight * triggerWeight * leptonWeight

        self.out.fillBranch("iSkim", iSkim)
        self.out.fillBranch("isMC", self.isMC)
        self.out.fillBranch("isSingleMuIsoTrigger", isSingleMuIsoTrigger)
        self.out.fillBranch("isSingleMuTrigger", isSingleMuTrigger)
        self.out.fillBranch("isDoubleMuonTrigger", isDoubleMuonTrigger)
        self.out.fillBranch("isSingleEleIsoTrigger", isSingleEleIsoTrigger)
        self.out.fillBranch("isSingleEleTrigger", isSingleEleTrigger)
        self.out.fillBranch("passedMETFilters", passedMETFilters)
        self.out.fillBranch("nCleanElectron", len(cleanElectron))
        self.out.fillBranch("nCleanMuon", len(cleanMuon))
        self.out.fillBranch("nCleanJet", len(cleanJet))
        self.out.fillBranch("Z_mass", mZ)
        self.out.fillBranch("Z_pt", ptZ)
        self.out.fillBranch("W_mass", mW)
        self.out.fillBranch("W_tmass", mT)
        self.out.fillBranch("W_pt", ptW)
        self.out.fillBranch("ll_dEta", dEtaLL)
        self.out.fillBranch("ll_dPhi", dPhiLL)
        self.out.fillBranch("ll_dR", dRLL)
        self.out.fillBranch("Wqq_mass", mHadW)
        self.out.fillBranch("Tlvb1_mass", mLepTop1)
        self.out.fillBranch("Tlvb2_mass", mLepTop2)
        self.out.fillBranch("Tqqb1_mass", mHadTop1)
        self.out.fillBranch("Tqqb2_mass", mHadTop2)
        self.out.fillBranch("jj_mass", mJJ)
        self.out.fillBranch("jj_pt", ptJJ)
        self.out.fillBranch("jj_dEta", dEtaJJ)
        self.out.fillBranch("jj_dPhi", dPhiJJ)
        self.out.fillBranch("jj_dR", dRJJ)
        self.out.fillBranch("nj_mass", mNJ)
        self.out.fillBranch("vis_mass", Vis.M())
        self.out.fillBranch("lljj_mass", LLJJ.M())
        self.out.fillBranch("minMuonIso", MinMuonIso)
        self.out.fillBranch("maxMuonIso", MaxMuonIso)
        self.out.fillBranch("minMuonMetDPhi", MinMuonMetDPhi)
        self.out.fillBranch("maxMuonMetDPhi", MaxMuonMetDPhi)
        self.out.fillBranch("minMuonJetDR", MinMuonJetDR)
        self.out.fillBranch("HT30", HT30)
        self.out.fillBranch("nj20", Nj20)
        self.out.fillBranch("nj30", Nj30)
        self.out.fillBranch("nj40", Nj40)
        self.out.fillBranch("nBJet", nBJet)
        self.out.fillBranch("CSV1", CSV1)
        self.out.fillBranch("CSV2", CSV2)
        self.out.fillBranch("CSV3", CSV3)
        self.out.fillBranch("CSV4", CSV4)
        self.out.fillBranch("iCSV1", iCSV1)
        self.out.fillBranch("iCSV2", iCSV2)
        self.out.fillBranch("iCSV3", iCSV3)
        self.out.fillBranch("iCSV4", iCSV4)
        self.out.fillBranch("lumiWeight", self.lumiWeight)
        self.out.fillBranch("lheWeight", lheWeight)
        self.out.fillBranch("stitchWeight", stitchWeight)
        self.out.fillBranch("puWeight", puWeight)
        self.out.fillBranch("topWeight", topWeight)
        self.out.fillBranch("qcdnloWeight", qcdnloWeight)
        self.out.fillBranch("qcdnnloWeight", qcdnnloWeight)
        self.out.fillBranch("ewknloWeight", ewknloWeight)
        self.out.fillBranch("triggerWeight", triggerWeight)
        self.out.fillBranch("leptonWeight", leptonWeight)
        self.out.fillBranch("eventWeightLumi", eventWeightLumi)

        return True
Пример #13
0
    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        self.out = wrappedOutputTree
        self.out.branch("isMC", "I")
        self.out.branch("is2016", "I")
        self.out.branch("is2017", "I")
        self.out.branch("is2018", "I")
        self.out.branch("isSingleMuonTrigger", "I")
        self.out.branch("isSingleMuonPhotonTrigger", "I")
        self.out.branch("isSingleMuonNoFiltersPhotonTrigger", "I")
        self.out.branch("isDoubleMuonTrigger", "I")
        self.out.branch("isDoubleMuonPhotonTrigger", "I")
        self.out.branch("isJPsiTrigger", "I")
        self.out.branch("isDisplacedTrigger", "I")
        self.out.branch("passedMETFilters", "I")
        self.out.branch("nCleanElectron", "I")
        self.out.branch("nCleanMuon", "I")
        self.out.branch("nCleanTau", "I")
        self.out.branch("nCleanPhoton", "I")
        self.out.branch("nCleanJet", "I")
        self.out.branch("nCleanBTagJet", "I")
        self.out.branch("HT30", "F")
        self.out.branch("iPhoton", "I")
        self.out.branch("iMuon1", "I")
        self.out.branch("iMuon2", "I")
        
        self.out.branch("Muon1_pt", "F")
        self.out.branch("Muon1_eta", "F")
        self.out.branch("Muon2_pt", "F")
        self.out.branch("Muon2_eta", "F")
        self.out.branch("Muon1_pfRelIso03_all", "F")
        self.out.branch("Muon2_pfRelIso03_all", "F")
        self.out.branch("Muon1_mediumId", "I")
        self.out.branch("Muon2_mediumId", "I")
        self.out.branch("Muon1_ip3d", "F")
        self.out.branch("Muon2_ip3d", "F")
        self.out.branch("minMuonIso", "F")
        self.out.branch("maxMuonIso", "F")
        self.out.branch("minMuonTrkIso", "F")
        self.out.branch("maxMuonTrkIso", "F")
        self.out.branch("Muon12_diffdxy", "F")
        self.out.branch("Muon12_diffdz", "F")
        self.out.branch("Muon12_signdxy", "F")
        self.out.branch("Muon12_signdz", "F")
        self.out.branch("Photon1_pt", "F")
        self.out.branch("Photon1_eta", "F")
        self.out.branch("Photon1_mvaID_WP80", "I")
        self.out.branch("Photon1_pfRelIso03_all", "F")
        
        self.out.branch("JPsi_pt", "F")
        self.out.branch("JPsi_eta", "F")
        self.out.branch("JPsi_phi", "F")
        self.out.branch("JPsi_mass", "F")
        self.out.branch("JPsi_dEta", "F")
        self.out.branch("JPsi_dPhi", "F")
        self.out.branch("JPsi_dR", "F")
        self.out.branch("H_pt", "F")
        self.out.branch("H_eta", "F")
        self.out.branch("H_phi", "F")
        self.out.branch("H_mass", "F")
        self.out.branch("H_dEta", "F")
        self.out.branch("H_dPhi", "F")
        self.out.branch("H_dR", "F")
        self.out.branch("minMuonMetDPhi", "F")
        self.out.branch("maxMuonMetDPhi", "F")
        self.out.branch("photonMetDPhi", "F")
        self.out.branch("metPlusPhotonDPhi", "F")
        self.out.branch("cosThetaStar", "F")
        self.out.branch("cosTheta1", "F")
        self.out.branch("phi1", "F")
        self.out.branch("genCosThetaStar", "F")
        self.out.branch("genCosTheta1", "F")
        self.out.branch("genPhi1", "F")
        self.out.branch("lumiWeight", "F")
        self.out.branch("lheWeight", "F")
        self.out.branch("stitchWeight", "F")
        self.out.branch("puWeight", "F")
        self.out.branch("topWeight", "F")
        self.out.branch("qcdnloWeight", "F")
        self.out.branch("qcdnnloWeight", "F")
        self.out.branch("ewknloWeight", "F")
        self.out.branch("triggerWeight", "F")
        self.out.branch("leptonWeight", "F")
        self.out.branch("eventWeightLumi", "F")
        
        
        self.fileName = inputFile.GetName()
        self.sampleName = getNameFromFile(self.fileName)
        
        self.isMC = not "Run201" in self.fileName
        
        if self.verbose >= 0: print "+ Opening file", self.fileName
        
        self.thMuons = [10., 3.]
        self.thPhoton = [10.]
        
        # b-tagging working points for DeepCSV
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X
        if "Run2016" in self.fileName or "UL16" in self.fileName or "Summer16" in self.fileName:
            self.year = 2016
            self.lumi = 35920.
            self.btagLoose = 0.2217 #0.0614
            self.btagMedium = 0.6321 #0.3093
            self.btagTight = 0.8953 #0.7221
        elif "Run2017" in self.fileName or "UL17" in self.fileName or "Fall17" in self.fileName:
            self.year = 2017
            self.lumi = 41530.
            self.btagLoose = 0.1522 #0.0521
            self.btagMedium = 0.4941 #0.3033
            self.btagTight = 0.8001 #0.7489
        elif "Run2018" in self.fileName or "UL18" in self.fileName or "Autumn18" in self.fileName:
            self.year = 2018
            self.lumi = 59740.
            self.btagLoose = 0.1241 #0.0494
            self.btagMedium = 0.4184 #0.2770
            self.btagTight = 0.7527 #0.7264
        else:
            if self.verbose >= 0: print "- Unknown year, aborting module"
            import sys
            sys.exit()
        
        self.xs = XS[self.sampleName] if self.sampleName in XS else 0.
        self.nevents = EV[self.sampleName] if self.sampleName in EV else 0.
        self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1.
        self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1.
        self.isLO = abs(self.nevents % 1) < 1.e-6 # if True, the event count is integer, so the weight should be normalized (+1)
        self.isSignal = ('JPsiG' in self.sampleName)
        
        if self.verbose >= 1: print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb"
        if self.verbose >= 1: print "+ Sample", self.sampleName, ", XS", self.xs, ", events", self.nevents
        if self.verbose >= 1: print "+ Weight", self.lumiWeight
        if self.isMC and self.isLO and self.verbose >= 1: print "+ Sample is LO, gen weight will be set to 1"
#        self.puTool = PileupWeightTool(year = year) if self.isMC else None

        self.SingleMuonTriggers = ["HLT_IsoMu27"]
        self.SingleMuonPhotonTriggers = ["HLT_Mu17_Photon30_CaloIdL_L1ISO", "HLT_Mu17_Photon30_IsoCaloId", "HLT_Mu17_Photon30_CaloIdL"] # 27.13 in 2017
        self.SingleMuonNoFiltersPhotonTriggers = ["HLT_Mu38NoFiltersNoVtxDisplaced_Photon38_CaloIdL", "HLT_Mu38NoFiltersNoVtx_Photon38_CaloIdL", "HLT_Mu43NoFiltersNoVtx_Photon43_CaloIdL"]
        self.DoubleMuonTriggers = ["HLT_Mu17_Mu8", "HLT_Mu17_Mu8_DZ", "HLT_Mu17_TkMu8_DZ", "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass", "HLT_Mu37_TkMu27", ] #, "HLT_DoubleMu33NoFiltersNoVtxDisplaced"]
        self.DoubleMuonPhotonTriggers = ["HLT_DoubleMu20_7_Mass0to30_Photon23"]
        self.JPsiTriggers = ["HLT_Dimuon16_Jpsi", "HLT_Dimuon18_PsiPrime", "HLT_Dimuon18_PsiPrime_noCorrL1", "HLT_Dimuon25_Jpsi", "HLT_Dimuon25_Jpsi_noCorrL1", "HLT_Dimuon20_Jpsi", ]
        self.DisplacedTriggers = ["HLT_DoubleMu4_JpsiTrk_Displaced", "HLT_DoubleMu4_PsiPrimeTrk_Displaced"]
        
        if self.isMC:
            self.muSFs  = MuonSFs(year = self.year)
            self.elSFs  = ElectronSFs(year = self.year)
            self.puTool = PileupWeightTool(year = self.year)
Пример #14
0
class Higgs(Module):
    def __init__(self):
        self.writeHistFile=True
        


    def beginJob(self,histFile=None,histDirName=None):
        Module.beginJob(self,histFile,histDirName)
        self.event = 0
        self.hists = {}
        self.hists["Nevents"] = ROOT.TH1F("Nevents", "Nevents", 1, 0, 1)
        self.hists["Acceptance"] = ROOT.TH1F("Acceptance", "Acceptance", 5, -0.5, 4.5)
        self.hists["genH_pt"] = ROOT.TH1F("genH_pt", ";generator H p_{T} (GeV)", 100, 0., 100.)
        self.hists["genH_eta"] = ROOT.TH1F("genH_eta", ";generator H #eta", 100, -5., 5.)
        self.hists["genH_phi"] = ROOT.TH1F("genH_phi", ";generator H #phi", 100, -3.15, 3.15)
        self.hists["genH_mass"] = ROOT.TH1F("genH_mass", ";generator H mass", 300, 0., 150.)
        self.hists["genJPsi_pt"] = ROOT.TH1F("genJPsi_pt", ";generator J/#Psi p_{T} (GeV)", 100, 0., 100.)
        self.hists["genJPsi_eta"] = ROOT.TH1F("genJPsi_eta", ";generator J/#Psi #eta", 100, -5., 5.)
        self.hists["genJPsi_phi"] = ROOT.TH1F("genJPsi_phi", ";generator J/#Psi #phi", 100, -3.15, 3.15)
        self.hists["genJPsi_mass"] = ROOT.TH1F("genJPsi_mass", ";generator J/#Psi mass", 200, 0., 4.)
        self.hists["genPhoton_pt"] = ROOT.TH1F("genPhoton_pt", ";generator #gamma p_{T} (GeV)", 100, 0., 100.)
        self.hists["genPhoton_eta"] = ROOT.TH1F("genPhoton_eta", ";generator #gamma #eta", 100, -5., 5.)
        self.hists["genMuon1_pt"] = ROOT.TH1F("genMuon1_pt", ";generator #mu^{-} p_{T} (GeV)", 100, 0., 100.)
        self.hists["genMuon1_eta"] = ROOT.TH1F("genMuon1_eta", ";generator #mu^{-} #eta", 100, -5., 5.)
        self.hists["genMuon2_pt"] = ROOT.TH1F("genMuon2_pt", ";generator #mu^{+} p_{T} (GeV)", 100, 0., 100.)
        self.hists["genMuon2_eta"] = ROOT.TH1F("genMuon2_eta", ";generator #mu^{+} #eta", 100, -5., 5.)
        
        self.hists["genCosThetaStar"] = ROOT.TH1F("genCosThetaStar", ";cos #theta^{*}", 100, -1., 1.)
        self.hists["genCosTheta1"] = ROOT.TH1F("genCosTheta1", ";cos #theta_{1}", 100, -1., 1.)
        self.hists["genPhi1"] = ROOT.TH1F("genPhi1", ";#Phi_{1}", 100, -3.1415, 3.1415)
        self.hists["genCosThetaStarZtoMM"] = ROOT.TH1F("genCosThetaStarZtoMM", ";cos #theta^{*}", 100, -1., 1.)
        
        self.hists["Cutflow"] = ROOT.TH1F("Cutflow", "Cutflow", 10, -0.5, 9.5)
        self.hists["Cutflow"].GetXaxis().SetBinLabel(1, "All events")
        self.hists["Cutflow"].GetXaxis().SetBinLabel(2, "Acceptance")
        self.hists["Cutflow"].GetXaxis().SetBinLabel(3, "2 reco muons")
        self.hists["Cutflow"].GetXaxis().SetBinLabel(4, "J/#Psi cand")
        self.hists["Cutflow"].GetXaxis().SetBinLabel(5, "reco #gamma")
#        self.addObject(self.h_events)
#        self.h_events.SetDirectory
        self.verbose = -1
    
    def endJob(self):
        Module.endJob(self)
        print "+ Module ended successfully,"#, self.h_events.GetEntries(), "events analyzed"
        pass
        
    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        self.out = wrappedOutputTree
        self.out.branch("isMC", "I")
        self.out.branch("is2016", "I")
        self.out.branch("is2017", "I")
        self.out.branch("is2018", "I")
        self.out.branch("isSingleMuonTrigger", "I")
        self.out.branch("isSingleMuonPhotonTrigger", "I")
        self.out.branch("isSingleMuonNoFiltersPhotonTrigger", "I")
        self.out.branch("isDoubleMuonTrigger", "I")
        self.out.branch("isDoubleMuonPhotonTrigger", "I")
        self.out.branch("isJPsiTrigger", "I")
        self.out.branch("isDisplacedTrigger", "I")
        self.out.branch("passedMETFilters", "I")
        self.out.branch("nCleanElectron", "I")
        self.out.branch("nCleanMuon", "I")
        self.out.branch("nCleanTau", "I")
        self.out.branch("nCleanPhoton", "I")
        self.out.branch("nCleanJet", "I")
        self.out.branch("nCleanBTagJet", "I")
        self.out.branch("HT30", "F")
        self.out.branch("iPhoton", "I")
        self.out.branch("iMuon1", "I")
        self.out.branch("iMuon2", "I")
        
        self.out.branch("Muon1_pt", "F")
        self.out.branch("Muon1_eta", "F")
        self.out.branch("Muon2_pt", "F")
        self.out.branch("Muon2_eta", "F")
        self.out.branch("Muon1_pfRelIso03_all", "F")
        self.out.branch("Muon2_pfRelIso03_all", "F")
        self.out.branch("Muon1_mediumId", "I")
        self.out.branch("Muon2_mediumId", "I")
        self.out.branch("Muon1_ip3d", "F")
        self.out.branch("Muon2_ip3d", "F")
        self.out.branch("minMuonIso", "F")
        self.out.branch("maxMuonIso", "F")
        self.out.branch("minMuonTrkIso", "F")
        self.out.branch("maxMuonTrkIso", "F")
        self.out.branch("Muon12_diffdxy", "F")
        self.out.branch("Muon12_diffdz", "F")
        self.out.branch("Muon12_signdxy", "F")
        self.out.branch("Muon12_signdz", "F")
        self.out.branch("Photon1_pt", "F")
        self.out.branch("Photon1_eta", "F")
        self.out.branch("Photon1_mvaID_WP80", "I")
        self.out.branch("Photon1_pfRelIso03_all", "F")
        
        self.out.branch("JPsi_pt", "F")
        self.out.branch("JPsi_eta", "F")
        self.out.branch("JPsi_phi", "F")
        self.out.branch("JPsi_mass", "F")
        self.out.branch("JPsi_dEta", "F")
        self.out.branch("JPsi_dPhi", "F")
        self.out.branch("JPsi_dR", "F")
        self.out.branch("H_pt", "F")
        self.out.branch("H_eta", "F")
        self.out.branch("H_phi", "F")
        self.out.branch("H_mass", "F")
        self.out.branch("H_dEta", "F")
        self.out.branch("H_dPhi", "F")
        self.out.branch("H_dR", "F")
        self.out.branch("minMuonMetDPhi", "F")
        self.out.branch("maxMuonMetDPhi", "F")
        self.out.branch("photonMetDPhi", "F")
        self.out.branch("metPlusPhotonDPhi", "F")
        self.out.branch("cosThetaStar", "F")
        self.out.branch("cosTheta1", "F")
        self.out.branch("phi1", "F")
        self.out.branch("genCosThetaStar", "F")
        self.out.branch("genCosTheta1", "F")
        self.out.branch("genPhi1", "F")
        self.out.branch("lumiWeight", "F")
        self.out.branch("lheWeight", "F")
        self.out.branch("stitchWeight", "F")
        self.out.branch("puWeight", "F")
        self.out.branch("topWeight", "F")
        self.out.branch("qcdnloWeight", "F")
        self.out.branch("qcdnnloWeight", "F")
        self.out.branch("ewknloWeight", "F")
        self.out.branch("triggerWeight", "F")
        self.out.branch("leptonWeight", "F")
        self.out.branch("eventWeightLumi", "F")
        
        
        self.fileName = inputFile.GetName()
        self.sampleName = getNameFromFile(self.fileName)
        
        self.isMC = not "Run201" in self.fileName
        
        if self.verbose >= 0: print "+ Opening file", self.fileName
        
        self.thMuons = [10., 3.]
        self.thPhoton = [10.]
        
        # b-tagging working points for DeepCSV
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation2016Legacy
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X
        # https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation102X
        if "Run2016" in self.fileName or "UL16" in self.fileName or "Summer16" in self.fileName:
            self.year = 2016
            self.lumi = 35920.
            self.btagLoose = 0.2217 #0.0614
            self.btagMedium = 0.6321 #0.3093
            self.btagTight = 0.8953 #0.7221
        elif "Run2017" in self.fileName or "UL17" in self.fileName or "Fall17" in self.fileName:
            self.year = 2017
            self.lumi = 41530.
            self.btagLoose = 0.1522 #0.0521
            self.btagMedium = 0.4941 #0.3033
            self.btagTight = 0.8001 #0.7489
        elif "Run2018" in self.fileName or "UL18" in self.fileName or "Autumn18" in self.fileName:
            self.year = 2018
            self.lumi = 59740.
            self.btagLoose = 0.1241 #0.0494
            self.btagMedium = 0.4184 #0.2770
            self.btagTight = 0.7527 #0.7264
        else:
            if self.verbose >= 0: print "- Unknown year, aborting module"
            import sys
            sys.exit()
        
        self.xs = XS[self.sampleName] if self.sampleName in XS else 0.
        self.nevents = EV[self.sampleName] if self.sampleName in EV else 0.
        self.xsWeight = self.xs / self.nevents if self.nevents > 0 else 1.
        self.lumiWeight = self.xsWeight * self.lumi if self.isMC else 1.
        self.isLO = abs(self.nevents % 1) < 1.e-6 # if True, the event count is integer, so the weight should be normalized (+1)
        self.isSignal = ('JPsiG' in self.sampleName)
        
        if self.verbose >= 1: print "+ Module parameters: isMC", self.isMC, ", year", self.year, ", lumi", self.lumi, "pb"
        if self.verbose >= 1: print "+ Sample", self.sampleName, ", XS", self.xs, ", events", self.nevents
        if self.verbose >= 1: print "+ Weight", self.lumiWeight
        if self.isMC and self.isLO and self.verbose >= 1: print "+ Sample is LO, gen weight will be set to 1"
#        self.puTool = PileupWeightTool(year = year) if self.isMC else None

        self.SingleMuonTriggers = ["HLT_IsoMu27"]
        self.SingleMuonPhotonTriggers = ["HLT_Mu17_Photon30_CaloIdL_L1ISO", "HLT_Mu17_Photon30_IsoCaloId", "HLT_Mu17_Photon30_CaloIdL"] # 27.13 in 2017
        self.SingleMuonNoFiltersPhotonTriggers = ["HLT_Mu38NoFiltersNoVtxDisplaced_Photon38_CaloIdL", "HLT_Mu38NoFiltersNoVtx_Photon38_CaloIdL", "HLT_Mu43NoFiltersNoVtx_Photon43_CaloIdL"]
        self.DoubleMuonTriggers = ["HLT_Mu17_Mu8", "HLT_Mu17_Mu8_DZ", "HLT_Mu17_TkMu8_DZ", "HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ_Mass", "HLT_Mu37_TkMu27", ] #, "HLT_DoubleMu33NoFiltersNoVtxDisplaced"]
        self.DoubleMuonPhotonTriggers = ["HLT_DoubleMu20_7_Mass0to30_Photon23"]
        self.JPsiTriggers = ["HLT_Dimuon16_Jpsi", "HLT_Dimuon18_PsiPrime", "HLT_Dimuon18_PsiPrime_noCorrL1", "HLT_Dimuon25_Jpsi", "HLT_Dimuon25_Jpsi_noCorrL1", "HLT_Dimuon20_Jpsi", ]
        self.DisplacedTriggers = ["HLT_DoubleMu4_JpsiTrk_Displaced", "HLT_DoubleMu4_PsiPrimeTrk_Displaced"]
        
        if self.isMC:
            self.muSFs  = MuonSFs(year = self.year)
            self.elSFs  = ElectronSFs(year = self.year)
            self.puTool = PileupWeightTool(year = self.year)
    
    def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        outputFile.mkdir("Hists")
        outputFile.cd("Hists")
        for histname, hist in self.hists.iteritems():
            hist.Write()
        outputFile.cd("..")
        if self.verbose >= 0: print "+ File closed successfully"
        pass
        
    
    def analyze(self, event):
        eventWeightLumi, lheWeight, stitchWeight, puWeight, qcdnloWeight, qcdnnloWeight, ewknloWeight, topWeight = 1., 1., 1., 1., 1., 1., 1., 1.
        triggerWeight, leptonWeight = 1., 1.
        isSingleMuonTrigger, isSingleMuonPhotonTrigger, isSingleMuonNoFiltersPhotonTrigger, isDoubleMuonTrigger, isDoubleMuonPhotonTrigger, isJPsiTrigger, isDisplacedTrigger = False, False, False, False, False, False, False
        nCleanElectron, nCleanMuon, nCleanTau, nCleanPhoton, nCleanJet, nCleanBTagJet, HT30 = 0, 0, 0, 0, 0, 0, 0
        cosThetaStar, cosTheta1, phi1 = -2., -2., -4.
        genCosThetaStar, genCosTheta1, genPhi1 = -2., -2., -4.

        for t in self.SingleMuonTriggers:
            if hasattr(event, t) and getattr(event, t): isSingleMuonTrigger = True
        for t in self.SingleMuonPhotonTriggers:
            if hasattr(event, t) and getattr(event, t): isSingleMuonPhotonTrigger = True
        for t in self.SingleMuonNoFiltersPhotonTriggers:
            if hasattr(event, t) and getattr(event, t): isSingleMuonNoFiltersPhotonTrigger = True
        for t in self.DoubleMuonTriggers:
            if hasattr(event, t) and getattr(event, t): isDoubleMuonTrigger = True
        for t in self.DoubleMuonPhotonTriggers:
            if hasattr(event, t) and getattr(event, t): isDoubleMuonPhotonTrigger = True
        for t in self.JPsiTriggers:
            if hasattr(event, t) and getattr(event, t): isJPsiTrigger = True
        for t in self.DisplacedTriggers:
            if hasattr(event, t) and getattr(event, t): isDisplacedTrigger = True
        
        lheWeight = 1.
        
        if self.isMC: 
            # Event weight
            if not self.isLO and hasattr(event, "LHEWeight_originalXWGTUP"): lheWeight = event.LHEWeight_originalXWGTUP
            
            # PU weight
            puWeight = self.puTool.getWeight(event.Pileup_nTrueInt)
        
        self.hists["Nevents"].Fill(0, lheWeight)
        self.hists["Acceptance"].Fill(0, lheWeight)
        self.hists["Cutflow"].Fill(0, lheWeight)
        

        # Gen studies
        if self.isMC and self.isSignal:
            genHIdx, genJPsiIdx, genMuon1Idx, genMuon2Idx, genPhotonIdx = -1, -1, -1, -1, -1
#            print "-"*40
            for i in range(event.nGenPart):
#                print i, "\t", event.GenPart_pdgId[i], "\t", event.GenPart_status[i], "\t", event.GenPart_statusFlags[i], "\t", event.GenPart_pt[i]
                if event.GenPart_pdgId[i] == 25 or event.GenPart_pdgId[i] == 23: genHIdx = i
                if event.GenPart_pdgId[i] == 443 and event.GenPart_genPartIdxMother[i] >= 0 and event.GenPart_pdgId[event.GenPart_genPartIdxMother[i]] == 25: genJPsiIdx = i
                if event.GenPart_pdgId[i] == 22 and event.GenPart_status[i] in [1, 23] and event.GenPart_genPartIdxMother[i] >= 0 and event.GenPart_pdgId[event.GenPart_genPartIdxMother[i]] == 25: genPhotonIdx = i #and (genPhotonIdx < 0 or event.GenPart_pt[i] > event.GenPart_pt[genPhotonIdx])
                if event.GenPart_pdgId[i] == -13 and event.GenPart_status[i] == 1 and event.GenPart_genPartIdxMother[i] >= 0 and event.GenPart_pdgId[event.GenPart_genPartIdxMother[i]] != 22 and (genMuon1Idx < 0 or event.GenPart_pt[i] > event.GenPart_pt[genMuon1Idx]): genMuon1Idx = i
                if event.GenPart_pdgId[i] == +13 and event.GenPart_status[i] == 1 and event.GenPart_genPartIdxMother[i] >= 0 and event.GenPart_pdgId[event.GenPart_genPartIdxMother[i]] != 22 and (genMuon2Idx < 0 or event.GenPart_pt[i] > event.GenPart_pt[genMuon2Idx]): genMuon2Idx = i
            
            if genHIdx >= 0 and genJPsiIdx >= 0 and genPhotonIdx >= 0 and genMuon1Idx >= 0 and genMuon2Idx >= 0:
                genH, genJPsi, genMuon1, genMuon2, genPhoton = TLorentzVector(), TLorentzVector(), TLorentzVector(), TLorentzVector(), TLorentzVector()
                if genHIdx >= 0: genH.SetPtEtaPhiM(event.GenPart_pt[genHIdx], event.GenPart_eta[genHIdx], event.GenPart_phi[genHIdx], event.GenPart_mass[genHIdx])
                if genJPsiIdx >= 0: genJPsi.SetPtEtaPhiM(event.GenPart_pt[genJPsiIdx], event.GenPart_eta[genJPsiIdx], event.GenPart_phi[genJPsiIdx], event.GenPart_mass[genJPsiIdx])
                if genPhotonIdx >= 0: genPhoton.SetPtEtaPhiM(event.GenPart_pt[genPhotonIdx], event.GenPart_eta[genPhotonIdx], event.GenPart_phi[genPhotonIdx], event.GenPart_mass[genPhotonIdx])
                if genMuon1Idx >= 0: genMuon1.SetPtEtaPhiM(event.GenPart_pt[genMuon1Idx], event.GenPart_eta[genMuon1Idx], event.GenPart_phi[genMuon1Idx], event.GenPart_mass[genMuon1Idx])
                if genMuon2Idx >= 0: genMuon2.SetPtEtaPhiM(event.GenPart_pt[genMuon2Idx], event.GenPart_eta[genMuon2Idx], event.GenPart_phi[genMuon2Idx], event.GenPart_mass[genMuon2Idx])
                
                # Recalculate candidate 4-vectors for consistent calculation of angular variables
                genJPsi = genMuon1 + genMuon2
                genH = genJPsi + genPhoton
                
                genCosThetaStar, genCosTheta1, genPhi1 = self.returnCosThetaStar(genH, genJPsi), self.returnCosTheta1(genJPsi, genMuon1, genMuon2, genPhoton), self.returnPhi1(genH, genMuon1, genMuon2)
                
                self.hists["genH_pt"].Fill(genH.Pt(), lheWeight)
                self.hists["genH_eta"].Fill(genH.Eta(), lheWeight)
                self.hists["genH_phi"].Fill(genH.Phi(), lheWeight)
                self.hists["genH_mass"].Fill(genH.M(), lheWeight)
                self.hists["genJPsi_pt"].Fill(genJPsi.Pt(), lheWeight)
                self.hists["genJPsi_eta"].Fill(genJPsi.Eta(), lheWeight)
                self.hists["genJPsi_phi"].Fill(genJPsi.Phi(), lheWeight)
                self.hists["genJPsi_mass"].Fill(genJPsi.M(), lheWeight)
                self.hists["genPhoton_pt"].Fill(genPhoton.Pt(), lheWeight)
                self.hists["genPhoton_eta"].Fill(genPhoton.Eta(), lheWeight)
                self.hists["genMuon1_pt"].Fill(max(genMuon1.Pt(), genMuon2.Pt()), lheWeight)
                self.hists["genMuon1_eta"].Fill(genMuon1.Eta(), lheWeight)
                self.hists["genMuon2_pt"].Fill(min(genMuon1.Pt(), genMuon2.Pt()), lheWeight)
                self.hists["genMuon2_eta"].Fill(genMuon2.Eta(), lheWeight)
                self.hists["genCosThetaStar"].Fill(genCosThetaStar, lheWeight)
                self.hists["genCosTheta1"].Fill(genCosTheta1, lheWeight)
                self.hists["genPhi1"].Fill(genPhi1, lheWeight)
                self.hists["genCosThetaStarZtoMM"].Fill(self.returnCosThetaStar(genH, genMuon1), lheWeight)
                
                # Reweight
                topWeight = 3./4. * (1. + genCosTheta1**2) # Transverse polarization (H, Z)
                if 'ZToJPsiG' in self.sampleName:
                    stitchWeight = 3./2. * (1. - genCosTheta1**2) # Longitudinal polarization (Z)
                
                # Acceptance
                if abs(genPhoton.Eta()) < 2.5:
                    self.hists["Acceptance"].Fill(1, lheWeight)
                    if abs(genMuon1.Eta()) < 2.4:
                        self.hists["Acceptance"].Fill(2, lheWeight)
                        if abs(genMuon2.Eta()) < 2.4:
                            self.hists["Acceptance"].Fill(3, lheWeight)
                            self.hists["Cutflow"].Fill(1, lheWeight)
                            if genPhoton.Pt() > 15. and genMuon1.Pt() > 5. and genMuon2.Pt() > 5.:
                                self.hists["Acceptance"].Fill(4, lheWeight)

        # Muons
        m1, m2 = -1, -1
        for i in range(event.nMuon):
            if event.Muon_pt[i] > self.thMuons[0 if m1 < 0 else 1] and abs(event.Muon_eta[i]) < 2.4 and event.Muon_looseId[i]:
                if m1 < 0: m1 = i
                if m2 < 0 and m1 >= 0 and event.Muon_charge[m1] != event.Muon_charge[i]: m2 = i
            
        if m1 < 0 or m2 < 0:
            if self.verbose >= 2: print "- No OS loose muons in acceptance"
            return False
            
        self.hists["Cutflow"].Fill(2, lheWeight)
        
        muon1, muon2 = TLorentzVector(), TLorentzVector()
        muon1.SetPtEtaPhiM(event.Muon_pt[m1], event.Muon_eta[m1], event.Muon_phi[m1], event.Muon_mass[m1])
        muon2.SetPtEtaPhiM(event.Muon_pt[m2], event.Muon_eta[m2], event.Muon_phi[m2], event.Muon_mass[m2])
        muonP = muon1 if event.Muon_charge[m1] > event.Muon_charge[m2] else muon2
        muonM = muon1 if event.Muon_charge[m1] < event.Muon_charge[m2] else muon2
        muon1v2, muon2v2 = TVector2(muon1.Px(), muon1.Py()), TVector2(muon2.Px(), muon2.Py())
        
        jpsi = muon1 + muon2
        
        if jpsi.M() < 2. or jpsi.M() > 12.:
            if self.verbose >= 2: print "- Dimuon invariant mass < 2 or > 12 GeV"
            return False
        
        self.hists["Cutflow"].Fill(3, lheWeight)
        
        # Photons
        p0 = -1
        for i in range(event.nPhoton):
            if event.Photon_pt[i] > self.thPhoton[0] and abs(event.Photon_eta[i]) < 2.5 and event.Photon_pfRelIso03_all[i] < 0.25: # and event.Photon_mvaID_WP80[i]:
                if p0 < 0: p0 = i
        
        if p0 < 0:
            if self.verbose >= 2: print "- No isolated photons in acceptance"
            return False
        
        self.hists["Cutflow"].Fill(4, lheWeight)
        
        photon = TLorentzVector()
        photon.SetPtEtaPhiM(event.Photon_pt[p0], event.Photon_eta[p0], event.Photon_phi[p0], event.Photon_mass[p0])
        photonv2 = TVector2(photon.Px(), photon.Py())
        
        met, metPlusPhoton = TVector2(), TVector2()
        met.SetMagPhi(event.MET_pt, event.MET_phi)
        metPlusPhoton.Set(met.Px() + photon.Px(), met.Py() + photon.Py())
        
        h = jpsi + photon

        jpsi_pt = jpsi.Pt()
        jpsi_eta = jpsi.Eta()
        jpsi_phi = jpsi.Phi()
        jpsi_mass = jpsi.M()
        jpsi_dEta = abs(muon1.Eta() - muon2.Eta())
        jpsi_dPhi = abs(muon1.DeltaPhi(muon2))
        jpsi_dR = muon1.DeltaR(muon2)
        
        h_pt = h.Pt()
        h_eta = h.Eta()
        h_phi = h.Phi()
        h_mass = h.M()
        h_dEta = abs(jpsi.Eta() - photon.Eta())
        h_dPhi = abs(jpsi.DeltaPhi(photon))
        h_dR = jpsi.DeltaR(photon)
        
        Muon1TrkIso, Muon2TrkIso = event.Muon_tkRelIso[m1], event.Muon_tkRelIso[m2]
        if jpsi_dR < 0.3:
            Muon1TrkIso = max(0., (Muon1TrkIso * event.Muon_pt[m1] * event.Muon_tunepRelPt[m1] - event.Muon_pt[m2] * event.Muon_tunepRelPt[m2])) / (event.Muon_pt[m1] * event.Muon_tunepRelPt[m1])
            Muon2TrkIso = max(0., (Muon2TrkIso * event.Muon_pt[m2] * event.Muon_tunepRelPt[m2] - event.Muon_pt[m1] * event.Muon_tunepRelPt[m1])) / (event.Muon_pt[m2] * event.Muon_tunepRelPt[m2])
        minMuonTrkIso = min(Muon1TrkIso, Muon2TrkIso)
        maxMuonTrkIso = max(Muon1TrkIso, Muon2TrkIso)
        minMuonIso = min(event.Muon_pfRelIso03_all[m1], event.Muon_pfRelIso03_all[m2])
        maxMuonIso = max(event.Muon_pfRelIso03_all[m1], event.Muon_pfRelIso03_all[m2])
        minMuonMetDPhi = min(abs(muon1v2.DeltaPhi(met)), abs(muon2v2.DeltaPhi(met)))
        maxMuonMetDPhi = max(abs(muon1v2.DeltaPhi(met)), abs(muon2v2.DeltaPhi(met)))
        photonMetDPhi = abs(photonv2.DeltaPhi(met))
        metPlusPhotonDPhi = abs(met.DeltaPhi(metPlusPhoton))
        
        cosThetaStar = self.returnCosThetaStar(h, jpsi)
        cosTheta1 = self.returnCosTheta1(jpsi, muonP, muonM, photon)
        phi1 = self.returnPhi1(h, muonP, muonM)

        # Weights
#        if self.isMC:
#            triggerWeight = self.muSFs.getTriggerSF(event.Muon_pt[m1], event.Muon_eta[m1])
#            IdSF1 = self.muSFs.getIdSF(event.Muon_pt[0], event.Muon_eta[0], 2)
#            IsoSF1 = self.muSFs.getIsoSF(event.Muon_pt[0], event.Muon_eta[0])
#            IdSF2 = self.muSFs.getIdSF(event.Muon_pt[1], event.Muon_eta[1], 2)
#            IsoSF2 = self.muSFs.getIsoSF(event.Muon_pt[1], event.Muon_eta[1])
#            IdIsoSF3 = self.elSFs.getIdIsoSF(event.Electron_pt[0], event.Electron_eta[0])
#            leptonWeight = IdSF1 * IsoSF1 * IdSF2 * IsoSF2 * IdIsoSF3
        
        passedMETFilters = True
        filters = ["Flag_goodVertices", "Flag_globalSuperTightHalo2016Filter", "Flag_BadPFMuonFilter", "Flag_EcalDeadCellTriggerPrimitiveFilter", "Flag_HBHENoiseFilter", "Flag_HBHENoiseIsoFilter", "Flag_ecalBadCalibFilter", "Flag_ecalBadCalibFilterV2"]
        if not self.isMC: filters += ["Flag_eeBadScFilter"]
        for f in filters:
            if hasattr(event, f) and getattr(event, f) == False: passedMETFilters = False
#        try:
##            if event.Flag_goodVertices: print "Flag_goodVertices"
##            if event.Flag_globalSuperTightHalo2016Filter: print "Flag_globalSuperTightHalo2016Filter"
##            if event.Flag_BadPFMuonFilter: print "Flag_BadPFMuonFilter"
##            if event.Flag_EcalDeadCellTriggerPrimitiveFilter: print "Flag_EcalDeadCellTriggerPrimitiveFilter"
##            if event.Flag_HBHENoiseFilter: print "Flag_HBHENoiseFilter"
##            if event.Flag_HBHENoiseIsoFilter: print "Flag_HBHENoiseIsoFilter"
###            if (self.isMC or event.Flag_eeBadScFilter): print "Flag_eeBadScFilter"
##            if event.Flag_ecalBadCalibFilter: print "Flag_ecalBadCalibFilterV2"
#            if event.Flag_goodVertices and event.Flag_globalSuperTightHalo2016Filter and event.Flag_BadPFMuonFilter and event.Flag_EcalDeadCellTriggerPrimitiveFilter and event.Flag_HBHENoiseFilter and event.Flag_HBHENoiseIsoFilter: # and event.Flag_ecalBadCalibFilter: #and (self.isMC or event.Flag_eeBadScFilter): FIXME
#                passedMETFilters = True
##            if not self.isMC:
##                if not event.Flag_eeBadScFilter:
##                    passedMETFilters = False
#        except:
#            passedMETFilters = False
        
        
        
        ### Event variables ###
        
        # Muons
        for i in range(event.nMuon):
            if i != m1 and i != m2 and event.Muon_pt[i] > 10. and abs(event.Muon_eta[i]) < 2.4 and event.Muon_looseId[i] and event.Muon_pfRelIso03_all[i] < 0.15:
                nCleanMuon += 1
        
        # Electrons
        for i in range(event.nElectron):
            if event.Electron_pt[i] > 10. and abs(event.Electron_eta[i]) < 2.5 and event.Electron_cutBased[i] >= 2:
                nCleanElectron += 1
        
        # Taus
        for i in range(event.nTau):
            if event.Tau_pt[i] > 20. and abs(event.Tau_eta[i]) < 2.5 and event.Tau_idDeepTau2017v2p1VSe[i] >= 16 and event.Tau_idDeepTau2017v2p1VSmu[i] >= 8 and event.Tau_idDeepTau2017v2p1VSjet[i] >= 16 and event.Tau_rawIsodR03[i] < 0.15:
                nCleanTau += 1
        
        # Photons
        for i in range(event.nPhoton):
            if i != p0 and event.Photon_pt[i] > 15. and abs(event.Photon_eta[i]) < 2.5 and event.Photon_pfRelIso03_all[i] < 0.15 and event.Photon_mvaID_WP90[i]:
                nCleanPhoton += 1
        
        # Jets and Event variables
        for i in range(event.nJet):
            if event.Jet_jetId[i] >= 6 and abs(event.Jet_eta[i]) < 2.5:
                HT30 += event.Jet_pt[i]
                nCleanJet += 1
                if event.Jet_btagDeepB[i] >= self.btagMedium: nCleanBTagJet += 1
        
        
        if self.isMC: eventWeightLumi = self.lumiWeight * lheWeight * puWeight * topWeight * qcdnloWeight * qcdnnloWeight * ewknloWeight * triggerWeight * leptonWeight
        
        self.out.fillBranch("isMC", self.isMC)
        self.out.fillBranch("is2016", (self.year == 2016))
        self.out.fillBranch("is2017", (self.year == 2017))
        self.out.fillBranch("is2018", (self.year == 2018))
        self.out.fillBranch("isSingleMuonTrigger", isSingleMuonTrigger)
        self.out.fillBranch("isSingleMuonPhotonTrigger", isSingleMuonPhotonTrigger)
        self.out.fillBranch("isSingleMuonNoFiltersPhotonTrigger", isSingleMuonNoFiltersPhotonTrigger)
        self.out.fillBranch("isDoubleMuonTrigger", isDoubleMuonTrigger)
        self.out.fillBranch("isDoubleMuonPhotonTrigger", isDoubleMuonPhotonTrigger)
        self.out.fillBranch("isJPsiTrigger", isJPsiTrigger)
        self.out.fillBranch("passedMETFilters", passedMETFilters)
        self.out.fillBranch("nCleanElectron", nCleanElectron)
        self.out.fillBranch("nCleanMuon", nCleanMuon)
        self.out.fillBranch("nCleanTau", nCleanTau)
        self.out.fillBranch("nCleanPhoton", nCleanPhoton)
        self.out.fillBranch("nCleanJet", nCleanJet)
        self.out.fillBranch("nCleanBTagJet", nCleanBTagJet)
        self.out.fillBranch("HT30", HT30)
        self.out.fillBranch("iPhoton", p0)
        self.out.fillBranch("iMuon1", m1)
        self.out.fillBranch("iMuon2", m2)
        #
        self.out.fillBranch("Muon1_pt", event.Muon_pt[m1])
        self.out.fillBranch("Muon1_eta", event.Muon_eta[m1])
        self.out.fillBranch("Muon2_pt", event.Muon_pt[m2])
        self.out.fillBranch("Muon2_eta", event.Muon_eta[m2])
        self.out.fillBranch("Muon1_pfRelIso03_all", event.Muon_pfRelIso03_all[m1])
        self.out.fillBranch("Muon2_pfRelIso03_all", event.Muon_pfRelIso03_all[m2])
        self.out.fillBranch("Muon1_mediumId", event.Muon_mediumId[m1])
        self.out.fillBranch("Muon2_mediumId", event.Muon_mediumId[m2])
        self.out.fillBranch("Muon1_ip3d", event.Muon_ip3d[m1])
        self.out.fillBranch("Muon2_ip3d", event.Muon_ip3d[m2])
        self.out.fillBranch("minMuonIso", minMuonIso)
        self.out.fillBranch("maxMuonIso", maxMuonIso)
        self.out.fillBranch("minMuonTrkIso", minMuonTrkIso)
        self.out.fillBranch("maxMuonTrkIso", maxMuonTrkIso)
        self.out.fillBranch("Muon12_diffdxy", abs(event.Muon_dxy[m1]-event.Muon_dxy[m2]))
        self.out.fillBranch("Muon12_diffdz", abs(event.Muon_dz[m1]-event.Muon_dz[m2]))
        self.out.fillBranch("Muon12_signdxy", abs(event.Muon_dxy[m1]-event.Muon_dxy[m2]) / math.sqrt(event.Muon_dxyErr[m1]**2 + event.Muon_dxyErr[m2]**2))
        self.out.fillBranch("Muon12_signdz", abs(event.Muon_dz[m1]-event.Muon_dz[m2]) / math.sqrt(event.Muon_dzErr[m1]**2 + event.Muon_dzErr[m2]**2))
        self.out.fillBranch("Photon1_pt", event.Photon_pt[p0])
        self.out.fillBranch("Photon1_eta", event.Photon_eta[p0])
        self.out.fillBranch("Photon1_mvaID_WP80", event.Photon_mvaID_WP80[p0])
        self.out.fillBranch("Photon1_pfRelIso03_all", event.Photon_pfRelIso03_all[p0])
        #
        self.out.fillBranch("JPsi_pt", jpsi_pt)
        self.out.fillBranch("JPsi_eta", jpsi_eta)
        self.out.fillBranch("JPsi_phi", jpsi_phi)
        self.out.fillBranch("JPsi_mass", jpsi_mass)
        self.out.fillBranch("JPsi_dEta", jpsi_dEta)
        self.out.fillBranch("JPsi_dPhi", jpsi_dPhi)
        self.out.fillBranch("JPsi_dR", jpsi_dR)
        self.out.fillBranch("H_pt", h_pt)
        self.out.fillBranch("H_eta", h_eta)
        self.out.fillBranch("H_phi", h_phi)
        self.out.fillBranch("H_mass", h_mass)
        self.out.fillBranch("H_dEta", h_dEta)
        self.out.fillBranch("H_dPhi", h_dPhi)
        self.out.fillBranch("H_dR", h_dR)
        self.out.fillBranch("minMuonMetDPhi", minMuonMetDPhi)
        self.out.fillBranch("maxMuonMetDPhi", maxMuonMetDPhi)
        self.out.fillBranch("photonMetDPhi", photonMetDPhi)
        self.out.fillBranch("metPlusPhotonDPhi", metPlusPhotonDPhi)
        self.out.fillBranch("cosThetaStar", cosThetaStar)
        self.out.fillBranch("cosTheta1", cosTheta1)
        self.out.fillBranch("phi1", phi1)
        self.out.fillBranch("genCosThetaStar", genCosThetaStar)
        self.out.fillBranch("genCosTheta1", genCosTheta1)
        self.out.fillBranch("genPhi1", genPhi1)
        self.out.fillBranch("lumiWeight", self.lumiWeight)
        self.out.fillBranch("lheWeight", lheWeight)
        self.out.fillBranch("stitchWeight", stitchWeight)
        self.out.fillBranch("puWeight", puWeight)
        self.out.fillBranch("topWeight", topWeight)
        self.out.fillBranch("qcdnloWeight", qcdnloWeight)
        self.out.fillBranch("qcdnnloWeight", qcdnnloWeight)
        self.out.fillBranch("ewknloWeight", ewknloWeight)
        self.out.fillBranch("triggerWeight", triggerWeight)
        self.out.fillBranch("leptonWeight", leptonWeight)
        self.out.fillBranch("eventWeightLumi", eventWeightLumi)
        
        if self.verbose >= 2: print "+ Tree filled"
        
        return True





    def returnCosThetaStar(self, theH, theJPsi):
        h, j = TLorentzVector(theH), TLorentzVector(theJPsi)
        # Boost the Z to the A rest frame
        j.Boost( -h.BoostVector() )
        value = j.CosTheta()
        if value != value or math.isinf(value): return -2.
        return value

    def returnCosTheta1(self, theJPsi, theL1, theL2, thePhoton):
        j, l1, l2, g = TLorentzVector(theJPsi), TLorentzVector(theL1), TLorentzVector(theL2), TLorentzVector(thePhoton)
        # Boost objects to the JPsi rest frame
        l1.Boost( -j.BoostVector() )
        l2.Boost( -j.BoostVector() )
        g.Boost( -j.BoostVector() )
        # cos theta = Gamma dot L1 / (|Gamma|*|L1|)
        value = g.Vect().Dot( l1.Vect() ) / ( (g.Vect().Mag())*(l1.Vect().Mag()) ) if g.Vect().Mag() > 0. and l1.Vect().Mag() > 0. else -2
        if value != value or math.isinf(value): return -2.
        return value


#  TLorentzVector pA(theV);
#  TLorentzVector pL1(theL1);
#  TLorentzVector pL2(theL2);
#  TLorentzVector pB1(theB1);
#  TLorentzVector pB2(theB2);
#  // Boost objects to the A rest frame
#  pL1.Boost( -pA.BoostVector() );
#  pL2.Boost( -pA.BoostVector() );
#  pB1.Boost( -pA.BoostVector() );
#  pB2.Boost( -pA.BoostVector() );
#  // Reconstruct H in A rest frame
#  TLorentzVector pHr = pB1 + pB2;
#  // cos theta = H dot L1 / (|H|*|L1|)
#  float value=pHr.Vect().Dot( pL1.Vect() ) / ( pHr.Vect().Mag()*pL1.Vect().Mag() );
#  if(value!=value || isinf(value)) return -2.;
#  return value;


    def returnPhi1(self, theH, theL1, theL2):
        h, l1, l2 = TLorentzVector(theH), TLorentzVector(theL1), TLorentzVector(theL2)
        beamAxis = TVector3(0., 0., 1.)
        # Boost objects to the A rest frame
        l1.Boost( -h.BoostVector() )
        l2.Boost( -h.BoostVector() )
        # Reconstruct JPsi in H rest frame
        j = l1 + l2
        # Build unit vectors orthogonal to the decay planes
        Zplane = TVector3(l1.Vect().Cross( l2.Vect() )) # L1 x L2
        Bplane = TVector3(beamAxis.Cross( j.Vect() )) # Beam x JPsi, beam/JPsi plane
        if Zplane.Mag() == 0. or Bplane.Mag() == 0.: return -4.
        Zplane.SetMag(1.)
        Bplane.SetMag(1.)
        # Sign of Phi1
        sgn = j.Vect().Dot( Zplane.Cross(Bplane) )
        sgn /= abs(sgn)
        if abs(Zplane.Dot(Bplane)) > 1.: return -5.
        value = sgn * math.acos( Zplane.Dot(Bplane) )
        if value != value or math.isinf(value): return -5.
        return value
Пример #15
0
class MuMuProducer(Module):
    def __init__(self, name, dataType, **kwargs):

        self.name = name
        self.out = TreeProducerMuMu(name)
        self.isData = dataType == 'data'
        self.year = kwargs.get('year', 2017)
        self.tes = kwargs.get('tes', 1.0)
        self.ltf = kwargs.get('ltf', 1.0)
        self.inZmassWindow = kwargs.get('ZmassWindow', True)
        self.doZpt = kwargs.get('doZpt', 'DY' in name)
        self.doRecoil = kwargs.get(
            'doRecoil', ('DY' in name or re.search(r"W\d?Jets", name))
            and self.year > 2016)
        self.doTTpt = kwargs.get('doTTpt', 'TT' in name)
        self.doTight = kwargs.get('doTight', self.tes != 1 or self.ltf != 1)
        self.channel = 'mumu'
        year, channel = self.year, self.channel

        self.vlooseIso = getVLooseTauIso(year)
        self.filter = getMETFilters(year, self.isData)
        if year == 2016:
            self.trigger = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1  #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1
            self.muon1CutPt = lambda e: 23
        elif year == 2017:
            self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27  #or e.HLT_IsoMu20_eta2p1_LooseChargedIsoPFTau27_eta2p1_CrossL1
            self.muon1CutPt = lambda e: 25 if e.HLT_IsoMu24 else 28
        else:
            self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27  #or e.HLT_IsoMu20_eta2p1_LooseChargedIsoPFTau27_eta2p1_CrossL1
            self.muon1CutPt = lambda e: 25
        self.muon2CutPt = 15

        if not self.isData:
            self.muSFs = MuonSFs(year=year)
            self.puTool = PileupWeightTool(year=year)
            self.btagTool = BTagWeightTool('DeepCSV',
                                           'medium',
                                           channel='mutau',
                                           year=year)
            if self.doZpt:
                self.zptTool = ZptCorrectionTool(year=year)
            if self.doRecoil:
                self.recoilTool = RecoilCorrectionTool(year=year)
        self.deepcsv_wp = BTagWPs('DeepCSV', year=year)

        self.Nocut = 0
        self.Trigger = 1
        self.GoodMuons = 2
        self.GoodSecondMuon = 3
        self.GoodDiLepton = 4
        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16

        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodMuons,
                                                "muon object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodSecondMuon,
                                                "second muon object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton,
                                                "mumu pair")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted,
                                                "no cut, weighted")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU,
                                                "no cut, weighted, PU>0")
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)

    def beginJob(self):
        pass

    def endJob(self):
        if not self.isData:
            self.btagTool.setDirectory(self.out.outputfile, 'btag')
        self.out.endJob()

    def beginFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        sys.stdout.flush()
        checkBranches(inputTree)

    def endFile(self, inputFile, outputFile, inputTree, wrappedOutputTree):
        pass

    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""
        sys.stdout.flush()

        #####################################
        self.out.cutflow.Fill(self.Nocut)
        if self.isData:
            self.out.cutflow.Fill(self.TotalWeighted, 1.)
            if event.PV_npvs > 0:
                self.out.cutflow.Fill(self.TotalWeighted_no0PU, 1.)
            else:
                return False
        else:
            self.out.cutflow.Fill(self.TotalWeighted, event.genWeight)
            self.out.pileup.Fill(event.Pileup_nTrueInt)
            if event.Pileup_nTrueInt > 0:
                self.out.cutflow.Fill(self.TotalWeighted_no0PU,
                                      event.genWeight)
            else:
                return False
        #####################################

        if not self.trigger(event):
            return False

        #####################################
        self.out.cutflow.Fill(self.Trigger)
        #####################################

        idx_goodmuons = []
        for imuon in range(event.nMuon):
            if event.Muon_pt[imuon] < self.muon2CutPt: continue  # lower pT cut
            if abs(event.Muon_eta[imuon]) > 2.4: continue
            if abs(event.Muon_dz[imuon]) > 0.2: continue
            if abs(event.Muon_dxy[imuon]) > 0.045: continue
            if event.Muon_pfRelIso04_all[imuon] > 0.15: continue
            if not event.Muon_mediumId[imuon]: continue
            idx_goodmuons.append(imuon)

        if len(idx_goodmuons) < 1:
            return False

        #####################################
        self.out.cutflow.Fill(self.GoodMuons)
        #####################################

        if not any(event.Muon_pt[i] > self.muon1CutPt(event) for i in
                   idx_goodmuons) or len(idx_goodmuons) < 2:  # higher pT cut
            return False

        #####################################
        self.out.cutflow.Fill(self.GoodSecondMuon)
        #####################################

        muons = Collection(event, 'Muon')
        dileptons = []
        for idx1 in idx_goodmuons:
            for idx2 in idx_goodmuons:
                if idx1 >= idx2: continue
                muon1 = muons[idx1].p4()
                muon2 = muons[idx2].p4()
                if muon1.DeltaR(muon2) < 0.5: continue
                if self.inZmassWindow and not (70 < (muon1 + muon2).M() < 110):
                    continue  # Z mass
                dilepton = DiLeptonBasicClass(idx1, event.Muon_pt[idx1],
                                              event.Muon_pfRelIso04_all[idx1],
                                              idx2, event.Muon_pt[idx2],
                                              event.Muon_pfRelIso04_all[idx2])
                dileptons.append(dilepton)

        if len(dileptons) == 0:
            return False

        dilepton = bestDiLepton(dileptons)
        muon1 = muons[dilepton.id1].p4()
        muon2 = muons[dilepton.id2].p4()

        #####################################
        self.out.cutflow.Fill(self.GoodDiLepton)
        #####################################

        # JETS
        jetIds = []
        bjetIds = []
        jets = Collection(event, 'Jet')
        nfjets = 0
        ncjets = 0
        nbtag = 0
        for ijet in range(event.nJet):
            if event.Jet_pt[ijet] < 20:
                continue  # 20 for tau -> j fake measurement
            if abs(event.Jet_eta[ijet]) > 4.7: continue
            if muon1.DeltaR(jets[ijet].p4()) < 0.5: continue
            if muon2.DeltaR(jets[ijet].p4()) < 0.5: continue
            jetIds.append(ijet)

            if abs(event.Jet_eta[ijet]) > 2.4:
                nfjets += 1
            else:
                ncjets += 1

            if event.Jet_btagDeepB[ijet] > self.deepcsv_wp.medium:
                nbtag += 1
                bjetIds.append(ijet)

        if not self.isData and event.Muon_pfRelIso04_all[
                dilepton.id1] < 0.50 and event.Muon_pfRelIso04_all[
                    dilepton.id2] < 0.50:
            self.btagTool.fillEfficiencies(event, jetIds)

        # VETOS
        self.out.extramuon_veto[0], self.out.extraelec_veto[
            0], self.out.dilepton_veto[0] = extraLeptonVetos(
                event, [dilepton.id1, dilepton.id2], [-1], self.channel)
        self.out.lepton_vetos[0] = self.out.extramuon_veto[
            0] or self.out.extraelec_veto[0] or self.out.dilepton_veto[0]

        # EVENT
        self.out.isData[0] = self.isData
        self.out.run[0] = event.run
        self.out.lumi[0] = event.luminosityBlock
        self.out.event[0] = event.event & 0xffffffffffffffff
        ###self.out.puppimet[0]                  = event.PuppiMET_pt
        ###self.out.puppimetphi[0]               = event.PuppiMET_phi
        ###self.out.metsignificance[0]           = event.MET_significance
        ###self.out.metcovXX[0]                  = event.MET_covXX
        ###self.out.metcovXY[0]                  = event.MET_covXY
        ###self.out.metcovYY[0]                  = event.MET_covYY
        self.out.npvs[0] = event.PV_npvs
        self.out.npvsGood[0] = event.PV_npvsGood
        self.out.metfilter[0] = self.filter(event)

        if not self.isData:
            self.out.genPartFlav_1[0] = ord(
                event.Muon_genPartFlav[dilepton.id1])
            self.out.genPartFlav_2[0] = ord(
                event.Muon_genPartFlav[dilepton.id2])
            self.out.genmet[0] = event.GenMET_pt
            self.out.genmetphi[0] = event.GenMET_phi
            self.out.nPU[0] = event.Pileup_nPU
            self.out.nTrueInt[0] = event.Pileup_nTrueInt
            try:
                self.out.LHE_Njets[0] = event.LHE_Njets
            except RuntimeError:
                self.out.LHE_Njets[0] = -1

        # MUON 1
        self.out.pt_1[0] = event.Muon_pt[dilepton.id1]
        self.out.eta_1[0] = event.Muon_eta[dilepton.id1]
        self.out.phi_1[0] = event.Muon_phi[dilepton.id1]
        self.out.m_1[0] = event.Muon_mass[dilepton.id1]
        self.out.dxy_1[0] = event.Muon_dxy[dilepton.id1]
        self.out.dz_1[0] = event.Muon_dz[dilepton.id1]
        self.out.q_1[0] = event.Muon_charge[dilepton.id1]
        self.out.pfRelIso04_all_1[0] = event.Muon_pfRelIso04_all[dilepton.id1]

        # MUON 2
        self.out.pt_2[0] = event.Muon_pt[dilepton.id2]
        self.out.eta_2[0] = event.Muon_eta[dilepton.id2]
        self.out.phi_2[0] = event.Muon_phi[dilepton.id2]
        self.out.m_2[0] = event.Muon_mass[dilepton.id2]
        self.out.dxy_2[0] = event.Muon_dxy[dilepton.id2]
        self.out.dz_2[0] = event.Muon_dz[dilepton.id2]
        self.out.q_2[0] = event.Muon_charge[dilepton.id2]
        self.out.pfRelIso04_all_2[0] = event.Muon_pfRelIso04_all[dilepton.id2]

        # TAU for jet -> tau fake rate measurement
        maxId = -1
        maxPt = 20
        taus = Collection(event, 'Tau')
        for itau in range(event.nTau):
            if event.Tau_pt[itau] < maxPt: continue
            if muon1.DeltaR(taus[itau].p4()) < 0.5: continue
            if muon2.DeltaR(taus[itau].p4()) < 0.5: continue
            if abs(event.Tau_eta[itau]) > 2.3: continue
            if abs(event.Tau_dz[itau]) > 0.2: continue
            if event.Tau_decayMode[itau] not in [0, 1, 10, 11]: continue
            if abs(event.Tau_charge[itau]) != 1: continue
            if ord(event.Tau_idAntiEle[itau]) < 1: continue  # VLoose
            if ord(event.Tau_idAntiMu[itau]) < 1: continue  # Loose
            #if not self.vlooseIso(event,itau): continue
            maxId = itau
            maxPt = event.Tau_pt[itau]
        if maxId > -1:
            self.out.pt_3[0] = event.Tau_pt[maxId]
            self.out.eta_3[0] = event.Tau_eta[maxId]
            self.out.m_3[0] = event.Tau_mass[maxId]
            self.out.decayMode_3[0] = event.Tau_decayMode[maxId]
            self.out.idAntiEle_3[0] = ord(event.Tau_idAntiEle[maxId])
            self.out.idAntiMu_3[0] = ord(event.Tau_idAntiMu[maxId])
            self.out.idMVAoldDM_3[0] = ord(event.Tau_idMVAoldDM[maxId])
            self.out.idMVAoldDM2017v1_3[0] = ord(
                event.Tau_idMVAoldDM2017v1[maxId])
            self.out.idMVAoldDM2017v2_3[0] = ord(
                event.Tau_idMVAoldDM2017v2[maxId])
            self.out.idMVAnewDM2017v2_3[0] = ord(
                event.Tau_idMVAnewDM2017v2[maxId])
            self.out.idIso_3[0] = Tau_idIso(event, maxId)
            if not self.isData:
                self.out.genPartFlav_3[0] = genmatch(
                    event, maxId)  #ord(event.Tau_genPartFlav[maxId])
        else:
            self.out.pt_3[0] = -1
            self.out.eta_3[0] = -9
            self.out.m_3[0] = -1
            self.out.decayMode_3[0] = -1
            self.out.idAntiEle_3[0] = -1
            self.out.idAntiMu_3[0] = -1
            self.out.idMVAoldDM_3[0] = -1
            self.out.idMVAoldDM2017v1_3[0] = -1
            self.out.idMVAoldDM2017v2_3[0] = -1
            self.out.idMVAnewDM2017v2_3[0] = -1
            self.out.idIso_3[0] = -1
            self.out.genPartFlav_3[0] = -1

        # WEIGHTS
        met = TLorentzVector()
        met.SetPxPyPzE(event.MET_pt * cos(event.MET_phi),
                       event.MET_pt * sin(event.MET_phi), 0, event.MET_pt)
        if not self.isData:
            if self.doRecoil:
                boson, boson_vis = getBoson(event)
                self.recoilTool.CorrectTByMeanResolution(
                    met, boson, boson_vis, len(jetIds))
                event.MET_pt = met.Pt()
                event.MET_phi = met.Phi()
                self.out.m_genboson[0] = boson.M()
                self.out.pt_genboson[0] = boson.Pt()
                if self.doZpt:
                    self.out.zptweight[0] = self.zptTool.getZptWeight(
                        boson.Pt(), boson.M())
            elif self.doZpt:
                zboson = getZBoson(event)
                self.out.m_genboson[0] = zboson.M()
                self.out.pt_genboson[0] = zboson.Pt()
                self.out.zptweight[0] = self.zptTool.getZptWeight(
                    zboson.Pt(), zboson.M())
            elif self.doTTpt:
                toppt1, toppt2 = getTTPt(event)
                self.out.ttptweight[0] = getTTptWeight(toppt1, toppt2)
            self.out.genweight[0] = event.genWeight
            self.out.puweight[0] = self.puTool.getWeight(event.Pileup_nTrueInt)
            self.out.trigweight[0] = self.muSFs.getTriggerSF(
                self.out.pt_1[0], self.out.eta_1[0])
            self.out.idisoweight_1[0] = self.muSFs.getIdIsoSF(
                self.out.pt_1[0], self.out.eta_1[0])
            self.out.idisoweight_2[0] = self.muSFs.getIdIsoSF(
                self.out.pt_2[0], self.out.eta_2[0])
            self.out.btagweight[0] = self.btagTool.getWeight(event, jetIds)
            self.out.weight[0] = self.out.genweight[0] * self.out.puweight[
                0] * self.out.trigweight[0] * self.out.idisoweight_1[
                    0] * self.out.idisoweight_2[0]

        # JETS
        self.out.njets[0] = len(jetIds)
        self.out.njets50[0] = len([j for j in jetIds if event.Jet_pt[j] > 50])
        self.out.nfjets[0] = nfjets
        self.out.ncjets[0] = ncjets
        self.out.nbtag[0] = nbtag

        if len(jetIds) > 0:
            self.out.jpt_1[0] = event.Jet_pt[jetIds[0]]
            self.out.jeta_1[0] = event.Jet_eta[jetIds[0]]
            self.out.jphi_1[0] = event.Jet_phi[jetIds[0]]
            self.out.jdeepb_1[0] = event.Jet_btagDeepB[jetIds[0]]
        else:
            self.out.jpt_1[0] = -9.
            self.out.jeta_1[0] = -9.
            self.out.jphi_1[0] = -9.
            self.out.jdeepb_1[0] = -9.

        if len(jetIds) > 1:
            self.out.jpt_2[0] = event.Jet_pt[jetIds[1]]
            self.out.jeta_2[0] = event.Jet_eta[jetIds[1]]
            self.out.jphi_2[0] = event.Jet_phi[jetIds[1]]
            self.out.jdeepb_2[0] = event.Jet_btagDeepB[jetIds[1]]
        else:
            self.out.jpt_2[0] = -9.
            self.out.jeta_2[0] = -9.
            self.out.jphi_2[0] = -9.
            self.out.jdeepb_2[0] = -9.

        if len(bjetIds) > 0:
            self.out.bpt_1[0] = event.Jet_pt[bjetIds[0]]
            self.out.beta_1[0] = event.Jet_eta[bjetIds[0]]
        else:
            self.out.bpt_1[0] = -9.
            self.out.beta_1[0] = -9.

        if len(bjetIds) > 1:
            self.out.bpt_2[0] = event.Jet_pt[bjetIds[1]]
            self.out.beta_2[0] = event.Jet_eta[bjetIds[1]]
        else:
            self.out.bpt_2[0] = -9.
            self.out.beta_2[0] = -9.

        self.out.met[0] = event.MET_pt
        self.out.metphi[0] = event.MET_phi
        self.out.pfmt_1[0] = sqrt(
            2 * self.out.pt_1[0] * event.MET_pt *
            (1 - cos(deltaPhi(self.out.phi_1[0], event.MET_phi))))
        self.out.pfmt_2[0] = sqrt(
            2 * self.out.pt_2[0] * event.MET_pt *
            (1 - cos(deltaPhi(self.out.phi_2[0], event.MET_phi))))

        self.out.m_vis[0] = (muon1 + muon2).M()
        self.out.pt_ll[0] = (muon1 + muon2).Pt()
        self.out.dR_ll[0] = muon1.DeltaR(muon2)
        self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0])
        self.out.deta_ll[0] = abs(self.out.eta_1[0] - self.out.eta_2[0])

        # PZETA
        leg1 = TVector3(muon1.Px(), muon1.Py(), 0.)
        leg2 = TVector3(muon2.Px(), muon2.Py(), 0.)
        zetaAxis = TVector3(leg1.Unit() + leg2.Unit()).Unit()
        pzeta_vis = leg1 * zetaAxis + leg2 * zetaAxis
        pzeta_miss = met.Vect() * zetaAxis
        self.out.pzetamiss[0] = pzeta_miss
        self.out.pzetavis[0] = pzeta_vis
        self.out.dzeta[0] = pzeta_miss - 0.85 * pzeta_vis

        self.out.tree.Fill()
        return True
Пример #16
0
    def __init__(self, name, dataType, **kwargs):

        self.name = name
        self.out = TreeProducerMuMu(name)
        self.isData = dataType == 'data'
        self.year = kwargs.get('year', 2017)
        self.tes = kwargs.get('tes', 1.0)
        self.ltf = kwargs.get('ltf', 1.0)
        self.inZmassWindow = kwargs.get('ZmassWindow', True)
        self.doZpt = kwargs.get('doZpt', 'DY' in name)
        self.doRecoil = kwargs.get(
            'doRecoil', ('DY' in name or re.search(r"W\d?Jets", name))
            and self.year > 2016)
        self.doTTpt = kwargs.get('doTTpt', 'TT' in name)
        self.doTight = kwargs.get('doTight', self.tes != 1 or self.ltf != 1)
        self.channel = 'mumu'
        year, channel = self.year, self.channel

        self.vlooseIso = getVLooseTauIso(year)
        self.filter = getMETFilters(year, self.isData)
        if year == 2016:
            self.trigger = lambda e: e.HLT_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1  #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1
            self.muon1CutPt = lambda e: 23
        elif year == 2017:
            self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27  #or e.HLT_IsoMu20_eta2p1_LooseChargedIsoPFTau27_eta2p1_CrossL1
            self.muon1CutPt = lambda e: 25 if e.HLT_IsoMu24 else 28
        else:
            self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27  #or e.HLT_IsoMu20_eta2p1_LooseChargedIsoPFTau27_eta2p1_CrossL1
            self.muon1CutPt = lambda e: 25
        self.muon2CutPt = 15

        if not self.isData:
            self.muSFs = MuonSFs(year=year)
            self.puTool = PileupWeightTool(year=year)
            self.btagTool = BTagWeightTool('DeepCSV',
                                           'medium',
                                           channel='mutau',
                                           year=year)
            if self.doZpt:
                self.zptTool = ZptCorrectionTool(year=year)
            if self.doRecoil:
                self.recoilTool = RecoilCorrectionTool(year=year)
        self.deepcsv_wp = BTagWPs('DeepCSV', year=year)

        self.Nocut = 0
        self.Trigger = 1
        self.GoodMuons = 2
        self.GoodSecondMuon = 3
        self.GoodDiLepton = 4
        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16

        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodMuons,
                                                "muon object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodSecondMuon,
                                                "second muon object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton,
                                                "mumu pair")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted,
                                                "no cut, weighted")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU,
                                                "no cut, weighted, PU>0")
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)
Пример #17
0
    def __init__(self, name, dataType, **kwargs):

        self.name = name
        self.out = TreeProducerTauTau(name)
        self.isData = dataType == 'data'
        self.year = kwargs.get('year', 2017)
        self.tes = kwargs.get('tes', 1.0)
        self.ltf = kwargs.get('ltf', 1.0)
        self.jtf = kwargs.get('jtf', 1.0)
        self.doZpt = kwargs.get('doZpt', 'DY' in name)
        self.doRecoil = kwargs.get(
            'doRecoil', ('DY' in name or re.search(r"W\d?Jets", name))
            and self.year > 2016)
        self.doTTpt = kwargs.get('doTTpt', 'TT' in name)
        self.doTight = kwargs.get('doTight', self.tes != 1 or self.ltf != 1)
        self.channel = 'tautau'
        year, channel = self.year, self.channel

        self.vlooseIso = getVLooseTauIso(year)
        if year == 2016:
            if self.isData:
                self.trigger    = lambda e: e.HLT_DoubleMediumIsoPFTau35_Trk1_eta2p1_Reg \
                                  if e.run<280919 else e.HLT_DoubleMediumCombinedIsoPFTau35_Trk1_eta2p1_Reg
            else:
                self.trigger = lambda e: e.HLT_DoubleMediumIsoPFTau35_Trk1_eta2p1_Reg or e.HLT_DoubleMediumCombinedIsoPFTau35_Trk1_eta2p1_Reg
        elif year == 2017:
            self.trigger = lambda e: e.HLT_DoubleTightChargedIsoPFTau35_Trk1_TightID_eta2p1_Reg or e.HLT_DoubleTightChargedIsoPFTau40_Trk1_eta2p1_Reg or e.HLT_DoubleMediumChargedIsoPFTau40_Trk1_TightID_eta2p1_Reg
        else:
            if self.isData:
                self.trigger    = lambda e: e.HLT_DoubleTightChargedIsoPFTau35_Trk1_TightID_eta2p1_Reg or e.HLT_DoubleTightChargedIsoPFTau40_Trk1_eta2p1_Reg or e.HLT_DoubleMediumChargedIsoPFTau40_Trk1_TightID_eta2p1_Reg \
                                  if e.run<317509 else e.HLT_DoubleMediumChargedIsoPFTauHPS35_Trk1_eta2p1_Reg
            else:
                self.trigger = lambda e: e.HLT_DoubleMediumChargedIsoPFTauHPS35_Trk1_eta2p1_Reg
        self.tauCutPt = 40

        if not self.isData:
            self.tauSFs = TauTriggerSFs('tautau', 'tight', year=year)
            self.tauSFsVT = TauTriggerSFs('tautau', 'vtight', year=year)
            self.ltfSFs = LeptonTauFakeSFs('loose', 'vloose', year=year)
            self.puTool = PileupWeightTool(year=year)
            self.btagTool = BTagWeightTool('DeepCSV',
                                           'medium',
                                           channel='mutau',
                                           year=year)
            if self.doZpt:
                self.zptTool = ZptCorrectionTool(year=year)
            if self.doRecoil:
                self.recoilTool = RecoilCorrectionTool(year=year)
        self.deepcsv_wp = BTagWPs('DeepCSV', year=year)

        self.Nocut = 0
        self.Trigger = 1
        self.GoodTaus = 2
        self.GoodDiTau = 3

        self.Nocut_GT = 20
        self.Trigger_GT = 21
        self.GoodTaus_GT = 22
        self.GoodDiTau_GT = 23

        self.TotalWeighted = 15
        self.TotalWeighted_no0PU = 16

        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut, "no cut")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger, "trigger")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus,
                                                "tau objects")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiTau,
                                                "ditau pair")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Nocut_GT,
                                                "no cut, GM")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.Trigger_GT,
                                                "trigger, GM")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus_GT,
                                                "tau objects, GM")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiTau_GT,
                                                "ditau pair, GM")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted,
                                                "no cut, weighted")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.TotalWeighted_no0PU,
                                                "no cut, weighted, PU>0")
        self.out.cutflow.GetXaxis().SetLabelSize(0.041)