Пример #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)
Пример #2
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)
Пример #3
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
Пример #4
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)
Пример #5
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
Пример #6
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
Пример #7
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)
Пример #8
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
Пример #9
0
class MuTauProducer(Module):
    def __init__(self, name, dataType, **kwargs):

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

        self.name = name
        self.year = year
        self.tes = tes
        self.out = TreeProducerMuTau(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_IsoMu22 or e.HLT_IsoMu22_eta2p1 or e.HLT_IsoTkMu22 or e.HLT_IsoTkMu22_eta2p1  #or e.HLT_IsoMu19_eta2p1_LooseIsoPFTau20_SingleL1
            self.muonCutPt = 23
        else:
            self.trigger = lambda e: e.HLT_IsoMu24 or e.HLT_IsoMu27
            self.muonCutPt = 25
        self.tauCutPt = 20

        if not self.isData:
            self.muSFs = MuonSFs(year=year)
            self.puTool = PileupWeightTool(year=year)
            self.ltfSFs = LeptonTauFakeSFs('tight', 'vloose', 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.GoodMuons = 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.GoodMuons,
                                                "muon object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodTaus,
                                                "tau object")
        self.out.cutflow.GetXaxis().SetBinLabel(1 + self.GoodDiLepton,
                                                "mutau 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)"""

        #####################################
        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.muonCutPt: continue
            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 not event.Muon_mediumId[imuon]: continue
            #if event.Muon_pfRelIso04_all[imuon]>0.50: continue
            idx_goodmuons.append(imuon)

        if len(idx_goodmuons) == 0:
            return False

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

        idx_goodtaus = []
        for itau in range(event.nTau):
            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
            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)
        #####################################

        muons = Collection(event, 'Muon')
        taus = Collection(event, 'Tau')
        ltaus = []
        for idx1 in idx_goodmuons:
            for idx2 in idx_goodtaus:
                if taus[idx2].p4().DeltaR(muons[idx1].p4()) < 0.5: continue
                ltau = LeptonTauPair(idx1, event.Muon_pt[idx1],
                                     event.Muon_pfRelIso04_all[idx1], idx2,
                                     event.Tau_pt[idx2],
                                     event.Tau_rawMVAoldDM2017v2[idx2])
                ltaus.append(ltau)

        if len(ltaus) == 0:
            return False

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

        #####################################
        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] < 30: continue
            if abs(event.Jet_eta[ijet]) > 4.7: continue
            if muon.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.Muon_pfRelIso04_all[ltau.id1] < 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()

        # MUON
        self.out.pt_1[0] = event.Muon_pt[ltau.id1]
        self.out.eta_1[0] = event.Muon_eta[ltau.id1]
        self.out.phi_1[0] = event.Muon_phi[ltau.id1]
        self.out.m_1[0] = event.Muon_mass[ltau.id1]
        self.out.dxy_1[0] = event.Muon_dxy[ltau.id1]
        self.out.dz_1[0] = event.Muon_dz[ltau.id1]
        self.out.q_1[0] = event.Muon_charge[ltau.id1]
        self.out.pfRelIso04_all_1[0] = event.Muon_pfRelIso04_all[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.rawMVAoldDM2017v1_2[0] = event.Tau_rawMVAoldDM2017v1[ltau.id2]
        self.out.rawMVAoldDM2017v2_2[0] = event.Tau_rawMVAoldDM2017v2[ltau.id2]
        self.out.rawMVAnewDM2017v2_2[0] = event.Tau_rawMVAnewDM2017v2[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.Muon_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
            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] = (muon + tau).M()
        self.out.pt_ll[0] = (muon + tau).Pt()
        self.out.dR_ll[0] = muon.DeltaR(tau)
        self.out.dphi_ll[0] = deltaPhi(self.out.phi_1[0], self.out.phi_2[0])

        # PZETA
        leg1 = ROOT.TVector3(muon.Px(), muon.Py(), 0.)
        leg2 = ROOT.TVector3(tau.Px(), tau.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, [ltau.id1], [-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.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