Exemplo n.º 1
0
    def prepareEvent(self, event):

        logging.debug('processing event %d' % event.event)

        ## met selection
        if event.met.pt < 50.0:
            return False

        ## muon selection
        event._allMuons = Collection(event, "Muon")
        event.muons = []
        for muon in event._allMuons:
            if muon.pt > 55 and abs(muon.eta) < 2.4 and muon.tightId and abs(
                    muon.dxy) < 0.2 and abs(muon.dz) < 0.5:
                if muon.miniPFRelIso_all < 0.10:
                    event.muons.append(muon)
        if len(event.muons) != 1:
            return False

        # #leptonic W pt cut
        event.mu = event.muons[0]
        event.leptonicW = event.mu.p4() + event.met.p4()
        if event.leptonicW.Pt() < 100.0:
            return False

        ## b-tag AK4 jet selection
        event.bjets = []
        for j in event._allJets:
            if not (j.pt > 25.0 and abs(j.eta) < 2.4 and (j.jetId & 2)):
                continue
            if j.btagDeepB > self.DeepCSV_WP_M and abs(
                    deltaPhi(j, event.muons[0])) < 2.0:
                event.bjets.append(j)

        if len(event.bjets) < 1:
            return False

        # # selection on AK8/AK15 jets
        event.fatjets = []
        for fj in event._allFatJets:
            if not (fj.pt > 150 and abs(fj.eta) < 2.4 and (fj.jetId & 2)):
                continue
            if abs(deltaPhi(fj, event.muons[0])) > 2.0:
                event.fatjets.append(fj)

        if len(event.fatjets) < 1:
            return False

        ## return True if passes selection
        return True
Exemplo n.º 2
0
    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""
        ## Getting objects
        jets = Collection(event, "Jet")
        #if self.isData == False:
        genjets = Collection(event, "GenJet")
        met = Object(event, self.metBranchName)

        jetNearMETInd, MMJetDPhi = -1, -1
        for iJ in range(1, len(jets)):
            if iJ > 2: continue
            dPhi = abs(deltaPhi(jets[iJ].phi, met.phi))
            if (MMJetDPhi < 0 or dPhi < MMJetDPhi):
                MMJetDPhi = dPhi
                jetNearMETInd = iJ

        if jetNearMETInd < 0: return True

        pJ = jets[jetNearMETInd]
        passFilter = len(jets) > jetNearMETInd
        pseudoGenPT = self.addFourVec(met, pJ).Pt()
        MMPseudoResp = pJ.pt / pseudoGenPT if pseudoGenPT > 0 else 999

        # True response info
        #print "isQCD: ", self.isQCD
        mmOut = []
        #if self.isQCD == True or self.isQCDOrig == True:
        #if isData ==False:
        mmOut = self.getQCDRespTailCorrector(jets, genjets, met)
        #else:
        #	mmOut = [-1, -1.0, -1]
        trueRespInd, trueResp = mmOut[0], mmOut[1]
        #print "trueResp: ", trueRespInd, trueResp
        trueRespFlv = 99
        trueRespGenPT = -1.0
        if trueRespInd >= 0:
            for iG in xrange(len(genjets)):
                gjet = genjets[iG]
                if iG != trueRespInd: continue
                trueRespGenPT = gjet.pt
                trueRespFlv = gjet.partonFlavour
                break

#if self.isQCDOrig:
        b = []
        for iB in xrange(self.nBootstraps):
            b.append(1)
        self.out.fillBranch("nBootstrapWeight", self.nBootstraps)
        self.out.fillBranch("bootstrapWeight", b)

        ### Store output
        self.out.fillBranch("pseudoResp", MMPseudoResp)
        self.out.fillBranch("pseudoRespCSV", pJ.btagDeepB)
        self.out.fillBranch("pseudoRespPseudoGenPT", pseudoGenPT)
        self.out.fillBranch("pseudoRespPassFilter", passFilter)
        self.out.fillBranch("trueResp", trueResp if trueRespInd >= 0 else -1)
        self.out.fillBranch("trueRespFlv", trueRespFlv)
        self.out.fillBranch("trueRespGenPT", trueRespGenPT)
        return True
    def prepareEvent(self, event):

        logging.debug('processing event %d' % event.event)

        ## select leading photon
        event._allPhotons = Collection(event, "Photon")
        event.photons = []
        for pho in event._allPhotons:
            if not (pho.pt > 200 and abs(pho.eta) < 2.4 and
                    (pho.cutBasedBitmap & 2)
                    and pho.electronVeto):  # medium ID
                continue
            event.photons.append(pho)

        if len(event.photons) < 1:
            return False

        ## selection on AK8 jets / drop if overlaps with a photon
        event.ak8jets = []
        for fj in event._allAK8jets:
            if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)):
                continue
            # require jet and photon to be back-to-back
            if deltaPhi(event.photons[0], fj) < 2:
                continue
#             if deltaR(event.photons[0], fj) < self._jetConeSize:
#                 continue
            event.ak8jets.append(fj)
        if len(event.ak8jets) < 1:
            return False

        ## ht
        event.ak4jets = []
        for j in event._allJets:
            if not (j.pt > 25 and abs(j.eta) < 2.4 and (j.jetId & 2)):
                continue
            event.ak4jets.append(j)
        event.ht = sum([j.pt for j in event.ak4jets])

        ## return True if passes selection
        return True
def transverseMass(obj, met):
    cos_dphi = np.cos(deltaPhi(obj, met))
    return np.sqrt(2 * obj.pt * met.pt * (1 - cos_dphi))
Exemplo n.º 5
0
    def analyze(self, event):
        """
        process event, return True (go to next module)
        or False (fail, go to next event)
        """
        electrons = list(Collection(event, "Electron"))
        muons = list(Collection(event, "Muon"))
        jets = list(Collection(event, "Jet"))
        taus = list(Collection(event, "Tau"))
        flag = Object(event, "Flag")
        met = Object(event, "MET")

        # in case of systematic take the shifted values are default
        # For the central values, need to include jetMetTool all the time
        # Jet systematics
        if self.syst_var == "":
            syst_var = "nom"
        else:
            syst_var = self.syst_var

        ##############################
        ## corrections and MET
        ##############################
        
        try:
            var_jet_pts = getattr(event,  "Jet_pt_{}".format(syst_var), None)
            if var_jet_pts:
                for i,jet in enumerate(jets):
                    jet.pt = var_jet_pts[i]
            else:
                print 'WARNING: jet pts with variation {}'
                'not available, using the nominal value'.format(syst_var)
        except:
            var_jet_pts = getattr(event,  "Jet_pt_nom", None)
            for i,jet in enumerate(jets):
                jet.pt = var_jet_pts[i]

        try:
            var_met_pt  = getattr(event,  "MET_pt_{}".format(syst_var), None)
            var_met_phi = getattr(event, "MET_phi_{}".format(syst_var), None)
            if var_met_pt:
                met.pt = var_met_pt
            else:
                print 'WARNING: MET pt with variation '
                '{} not available, using the nominal value'.format(syst_var)
            if var_met_phi:
                met.phi = var_met_phi
            else:
                print 'WARNING: MET phi with variation {}'
                'not available, using the nominal value'.format(syst_var)
        except:
            var_met_pt  = getattr(event,  "MET_pt_nom", None)
            var_met_phi = getattr(event, "MET_phi_nom", None)
            if var_met_pt:
                met.pt = var_met_pt
            if var_met_phi:
                met.phi = var_met_phi

        met_p4 = ROOT.TLorentzVector()
        met_p4.SetPtEtaPhiM(met.pt,0.0,met.phi, 0.0)

        # Electrons Energy
        if "ElectronEn" in self.syst_var:
            (met_px, met_py) = ( met.pt*np.cos(met.phi), met.pt*np.sin(met.phi) )
            if "Up" in self.syst_var:
                for i, elec in enumerate(electrons):
                    met_px = met_px + (elec.energyErr)*np.cos(elec.phi)/math.cosh(elec.eta)
                    met_py = met_py + (elec.energyErr)*np.sin(elec.phi)/math.cosh(elec.eta)
                    elec.pt = elec.pt + elec.energyErr/math.cosh(elec.eta)
            else:
                for i, elec in enumerate(electrons):
                    met_px = met_px - (elec.energyErr)*np.cos(elec.phi)/math.cosh(elec.eta)
                    met_py = met_py - (elec.energyErr)*np.sin(elec.phi)/math.cosh(elec.eta)
                    elec.pt = elec.pt - elec.energyErr/math.cosh(elec.eta)
            met.pt  = math.sqrt(met_px**2 + met_py**2)
            met.phi = math.atan2(met_py, met_px)

        # Muons Energy
        if self.isMC:
            muons_pts = getattr(event, "Muon_corrected_pt")
            for i, muon in enumerate(muons):
                muon.pt = muons_pts[i]

        if "MuonEn" in self.syst_var:
            (met_px, met_py) = ( met.pt*np.cos(met.phi), met.pt*np.sin(met.phi) )
            if "Up" in self.syst_var:
                muons_pts = getattr(event, "Muon_correctedUp_pt")
                for i, muon in enumerate(muons):
                    met_px = met_px - (muons_pts[i] - muon.pt)*np.cos(muon.phi)
                    met_py = met_py - (muons_pts[i] - muon.pt)*np.sin(muon.phi)
                    muon.pt = muons_pts[i]
            else:
                muons_pts = getattr(event, "Muon_correctedDown_pt")
                for i, muon in enumerate(muons):
                    met_px =met_px - (muons_pts[i] - muon.pt)*np.cos(muon.phi)
                    met_py =met_py - (muons_pts[i] - muon.pt)*np.sin(muon.phi)
                    muon.pt = muons_pts[i]
            met.pt  = math.sqrt(met_px**2 + met_py**2)
            met.phi = math.atan2(met_py, met_px)
            
        pass_met_filter = self.met_filter(flag, True)

        # filling and contructing the event categorisation
        self.out.fillBranch("met_pt{}".format(self.syst_suffix), met.pt)
        self.out.fillBranch("met_phi{}".format(self.syst_suffix), met.phi)
        self.out.fillBranch("met_filter{}".format(self.syst_suffix), pass_met_filter)

        ##############################
        ## process leptons 
        ##############################

        muons.sort(key=lambda muon: muon.pt, reverse=True)
        electrons.sort(key=lambda el: el.pt, reverse=True)

        # Choose tight-quality e/mu for event categorization
        good_muons = []
        for idx,mu in enumerate(muons):
            isoLep   = mu.pfRelIso04_all
            pass_ips = abs(mu.dxy) < 0.02 and abs(mu.dz) < 0.1
            pass_fid = abs(mu.eta) < 2.4 and mu.pt >= (25 if idx==0 else 20)
            pass_ids = mu.tightId and isoLep <= 0.15
            if pass_fid and pass_ids and pass_ips:
                good_muons.append(mu)
                
        good_electrons = []
        for idy,el in enumerate(electrons):
            id_CB = el.cutBased
            # changing to MVA based ID :
            if el.pt >= (25 if idy==0 else 20) and abs(el.eta) <= 2.5 and self.electron_id(el, "90"):
                good_electrons.append(el)

        # let sort the muons in pt
        good_muons.sort(key=lambda x: x.pt, reverse=True)
        good_electrons.sort(key=lambda x: x.pt, reverse=True)

        # Find any remaining e/mu that pass looser selection
        extra_leptons = []
        for mu in muons:
            isoLep   = mu.pfRelIso04_all
            pass_ids = mu.softId and isoLep <= 0.25
            pass_fid = abs(mu.eta) < 2.4 and mu.pt >= 7
            if tk.closest(mu, good_muons)[1] < 0.01:
                continue
            if pass_fid and pass_ids:
                extra_leptons.append(mu)

        for el in electrons:
            pass_fid = abs(el.eta) < 2.5 and el.pt >= 7
            if tk.closest(el, good_electrons)[1] < 0.01:
                continue
            if pass_fid and self.electron_id(el, "WPL"):
                extra_leptons.append(el)

        good_leptons = good_electrons + good_muons
        good_leptons.sort(key=lambda x: x.pt, reverse=True)
        extra_leptons.sort(key=lambda x: x.pt, reverse=True)

        ngood_leptons = len(good_leptons)
        nextra_leptons = len(extra_leptons)
        
        _leading_lep_flavor = 0
        if len(good_muons) and len(good_electrons): 
            if good_muons[0].pt > good_electrons[0].pt: _leading_lep_flavor = 1

        _leading_lep_pt = good_leptons[0].pt if ngood_leptons else 0.0
        _leading_lep_eta = good_leptons[0].eta if ngood_leptons else -99.
        _leading_lep_phi = good_leptons[0].phi if ngood_leptons else -99.
        _trailing_lep_pt = good_leptons[1].pt if ngood_leptons >= 2 else 0.0
        _trailing_lep_eta = good_leptons[1].eta if ngood_leptons >= 2 else -99.
        _trailing_lep_phi = good_leptons[1].phi if ngood_leptons >= 2 else -99.

        self.out.fillBranch("ngood_leptons{}".format(self.syst_suffix), ngood_leptons)
        self.out.fillBranch("nextra_leptons{}".format(self.syst_suffix), nextra_leptons)
        self.out.fillBranch("leading_lep_flavor{}".format(self.syst_suffix), _leading_lep_flavor)
        self.out.fillBranch("leading_lep_pt{}".format(self.syst_suffix), _leading_lep_pt)
        self.out.fillBranch("leading_lep_eta{}".format(self.syst_suffix), _leading_lep_eta)
        self.out.fillBranch("leading_lep_phi{}".format(self.syst_suffix), _leading_lep_phi)
        self.out.fillBranch("trailing_lep_pt{}".format(self.syst_suffix), _trailing_lep_pt)
        self.out.fillBranch("trailing_lep_eta{}".format(self.syst_suffix), _trailing_lep_eta)
        self.out.fillBranch("trailing_lep_phi{}".format(self.syst_suffix), _trailing_lep_phi)

        if False:
            print "number of leptons [all, good, extra]: ", ngood_leptons, " : ", nextra_leptons
            print "        CBId electrons : ", [e.cutBased for e in good_electrons]
            print "        WP90 electrons : ", [e.mvaFall17Iso_WP90 for e in good_electrons]
            print "             muons     : ", [e.tightId for e in good_muons]
            print "        lepton pts     : ", [e.pt for e in good_leptons]

        # Leptons efficiency/Trigger/Isolation Scale factors
        # These are applied only of the first 2 leading leptons
        if self.isMC:
            w_muon_SF     = w_electron_SF     = 1.0
            w_muon_SFUp   = w_electron_SFUp   = 1.0
            w_muon_SFDown = w_electron_SFDown = 1.0

            if ngood_leptons >= 2:
                if abs(good_leptons[0].pdgId) == 11:
                    w_electron_SF     *=  good_leptons[0].SF
                    w_electron_SFUp   *= (good_leptons[0].SF + good_leptons[0].SFErr)
                    w_electron_SFDown *= (good_leptons[0].SF - good_leptons[0].SFErr)
                if abs(good_leptons[0].pdgId) == 11:
                    w_electron_SF     *=  good_leptons[1].SF
                    w_electron_SFUp   *= (good_leptons[1].SF + good_leptons[1].SFErr)
                    w_electron_SFDown *= (good_leptons[1].SF - good_leptons[1].SFErr)
                if abs(good_leptons[0].pdgId) == 13:
                    w_muon_SF     *=  good_leptons[0].SF
                    w_muon_SFUp   *= (good_leptons[0].SF + good_leptons[0].SFErr)
                    w_muon_SFDown *= (good_leptons[0].SF - good_leptons[0].SFErr)
                if abs(good_leptons[1].pdgId) == 13:
                    w_muon_SF     *=  good_leptons[1].SF
                    w_muon_SFUp   *= (good_leptons[1].SF + good_leptons[1].SFErr)
                    w_muon_SFDown *= (good_leptons[1].SF - good_leptons[1].SFErr)

            self.out.fillBranch("w_muon_SF"        , w_muon_SF        )
            self.out.fillBranch("w_muon_SFUp"      , w_muon_SFUp      )
            self.out.fillBranch("w_muon_SFDown"    , w_muon_SFDown    )
            self.out.fillBranch("w_electron_SF"    , w_electron_SF    )
            self.out.fillBranch("w_electron_SFUp"  , w_electron_SFUp  )
            self.out.fillBranch("w_electron_SFDown", w_electron_SFDown)

        # process taus
        had_taus = []
        for tau in taus:
            if tk.closest(tau, good_leptons)[1] < 0.4:
                continue
            # only hadronic tau decay
            if tau.decayMode != 5:
                continue
            if tau.pt > 18 and abs(tau.eta) <= 2.3:
                had_taus.append(tau)
        _nhad_taus = len(had_taus)

        self.out.fillBranch("nhad_taus{}".format(self.syst_suffix), _nhad_taus)
        self.out.fillBranch("lead_tau_pt{}".format(self.syst_suffix), had_taus[0].pt if _nhad_taus else 0)

        ##############################
        ## process jet 
        ##############################

        z_candidate = []
        zcand_p4 = ROOT.TLorentzVector()
        emulated_met = ROOT.TLorentzVector()
        all_lepton_p4 = ROOT.TLorentzVector()
        rem_lepton_p4 = ROOT.TLorentzVector()

        good_jets  = []
        good_bjets = []
        for jet in jets:
            if jet.pt < 30.0 or abs(jet.eta) > 4.7:
                continue
            if not jet.jetId:
                continue
            if tk.closest(jet, good_leptons)[1] < 0.4:
                continue
            good_jets.append(jet)
            # Count b-tag with medium WP DeepJet
            # ref : https://twiki.cern.ch/twiki/bin/view/CMS/BtagRecommendation
            if abs(jet.eta) <= 2.4 and jet.btagDeepFlavB > self.btag_id("loose"):
                good_bjets.append(jet)

        _ngood_jets = len(good_jets)
        _ngood_bjets = len(good_bjets)
        good_jets.sort(key=lambda jet: jet.pt, reverse=True)
        good_bjets.sort(key=lambda jet: jet.pt, reverse=True)

        _lead_jet_pt = good_jets[0].pt if _ngood_jets >= 1 else 0.
        _lead_jet_eta = good_jets[0].eta if _ngood_jets >= 1 else -99.
        _lead_jet_phi = good_jets[0].phi if _ngood_jets >= 1 else -99.
        _lead_jet_mass = good_jets[0].mass if _ngood_jets >= 1 else -99.
        _trail_jet_pt = good_jets[1].pt if _ngood_jets >= 2 else 0.
        _trail_jet_eta = good_jets[1].eta if _ngood_jets >= 2 else -99.
        _trail_jet_phi = good_jets[1].phi if _ngood_jets >= 2 else -99.
        _trail_jet_mass = good_jets[1].mass if _ngood_jets >= 2 else -99.
        _third_jet_pt = good_jets[2].pt if _ngood_jets >= 3 else 0.
        _third_jet_eta = good_jets[2].eta if _ngood_jets >= 3 else -99.
        _third_jet_phi = good_jets[2].phi if _ngood_jets >= 3 else -99.
        _third_jet_mass = good_jets[2].mass if _ngood_jets >= 3 else -99.
        _H_T = sum([jet.pt for jet in good_jets])
        _dphi_j_met = tk.deltaPhi(good_jets[0], met.phi) if _ngood_jets >= 1 else -99.
        _lead_bjet_pt = good_bjets[0].pt if _ngood_bjets else 0.

        self.out.fillBranch("ngood_jets{}".format(self.syst_suffix), _ngood_jets)
        self.out.fillBranch("ngood_bjets{}".format(self.syst_suffix), _ngood_bjets)
        self.out.fillBranch("lead_jet_pt{}".format(self.syst_suffix), _lead_jet_pt)
        self.out.fillBranch("lead_jet_eta{}".format(self.syst_suffix), _lead_jet_eta)
        self.out.fillBranch("lead_jet_phi{}".format(self.syst_suffix), _lead_jet_phi)
        self.out.fillBranch("lead_jet_mass{}".format(self.syst_suffix), _lead_jet_mass)
        self.out.fillBranch("trail_jet_pt{}".format(self.syst_suffix), _trail_jet_pt)
        self.out.fillBranch("trail_jet_eta{}".format(self.syst_suffix), _trail_jet_eta)
        self.out.fillBranch("trail_jet_phi{}".format(self.syst_suffix), _trail_jet_phi)
        self.out.fillBranch("trail_jet_mass{}".format(self.syst_suffix), _trail_jet_mass)
        self.out.fillBranch("third_jet_pt{}".format(self.syst_suffix), _third_jet_pt)
        self.out.fillBranch("third_jet_eta{}".format(self.syst_suffix), _third_jet_eta)
        self.out.fillBranch("third_jet_phi{}".format(self.syst_suffix), _third_jet_phi)
        self.out.fillBranch("third_jet_mass{}".format(self.syst_suffix), _third_jet_mass)
        self.out.fillBranch("H_T{}".format(self.syst_suffix), _H_T)
        self.out.fillBranch("delta_phi_j_met{}".format(self.syst_suffix), _dphi_j_met)
        self.out.fillBranch("lead_bjet_pt{}".format(self.syst_suffix), _lead_bjet_pt)

        ##############################
        ## construct Z and category
        ##############################

        lep_category = 0
        if ngood_leptons < 2:
            lep_category = -1

        if ngood_leptons == 2 and nextra_leptons==0:
            # constructing the signal region
            if (good_leptons[0].pdgId * good_leptons[1].pdgId) == -11*11:
                lep_category = 1 # EE category
            if (good_leptons[0].pdgId * good_leptons[1].pdgId) == -11*13:
                lep_category = 2 # EM category
            if (good_leptons[0].pdgId * good_leptons[1].pdgId) == -13*13:
                lep_category = 3 # MM category
            z_candidate = [good_leptons[0], good_leptons[1]]
            zcand_p4 = good_leptons[0].p4() + good_leptons[1].p4()
            all_lepton_p4 = zcand_p4

        elif ngood_leptons == 3 and nextra_leptons==0:
            # constructing the 3 leptons CR
            for pair in itertools.combinations(good_leptons, 2):
                if pair[0].pdgId == -pair[1].pdgId:
                    zcand_ = pair[0].p4() + pair[1].p4()
                    if abs(zcand_.M()-self.zmass) < abs(zcand_p4.M()-self.zmass):
                        zcand_p4 = zcand_
                        z_candidate = list(pair)
                        lep3_idx_ = 3 - good_leptons.index(pair[0]) - good_leptons.index(pair[1])
                        emulated_met = good_leptons[lep3_idx_].p4() + met_p4
                        all_lepton_p4 = zcand_ + good_leptons[lep3_idx_].p4()
                        rem_lepton_p4 = good_leptons[lep3_idx_].p4()
                        if abs(pair[0].pdgId) == 11:
                            lep_category = 4 # EEL category
                        if abs(pair[0].pdgId) == 13:
                            lep_category = 5 # MML category

        elif ngood_leptons>=2 and (ngood_leptons + nextra_leptons) == 4:
            # constructing the 4 leptons CR
            for pair in itertools.combinations(good_leptons, 2):
                # checking if OSSF pair
                rem_pair = [x for x in good_leptons + extra_leptons if x not in pair]
                if (pair[0].pdgId == -pair[1].pdgId) and (rem_pair[0].pdgId == -rem_pair[1].pdgId):
                    zcand_0 = pair[0].p4() + pair[1].p4()
                    zcand_1 = rem_pair[0].p4() + rem_pair[1].p4()
                    if abs(zcand_0.M()-self.zmass) < abs(zcand_p4.M()-self.zmass):
                        zcand_p4 = zcand_0
                        z_candidate = pair
                        emulated_met =  zcand_1 + met_p4
                        all_lepton_p4 = zcand_p4 + zcand_1
                        rem_lepton_p4 = zcand_1
                        if abs(pair[0].pdgId) == 11:
                            lep_category = 6 # EELL category
                        if abs(pair[0].pdgId) == 13:
                            lep_category = 7 # MMLL category

        else:
            # too many bad leptons, with no obvious meaning ?
            if ngood_leptons==1 and (ngood_leptons + nextra_leptons)>=1:
                lep_category = -2
            elif ngood_leptons>=2 and (ngood_leptons + nextra_leptons)>=2:
                lep_category = -3
            else:
                lep_category = -4

        # filling MonoZ type of variables
        self.out.fillBranch("lep_category{}".format(self.syst_suffix), lep_category)
        self.out.fillBranch("Z_pt{}".format(self.syst_suffix), zcand_p4.Pt())
        self.out.fillBranch("Z_eta{}".format(self.syst_suffix), zcand_p4.Eta())
        self.out.fillBranch("Z_phi{}".format(self.syst_suffix), zcand_p4.Phi())
        self.out.fillBranch("Z_mass{}".format(self.syst_suffix), zcand_p4.M())
        self.out.fillBranch("Z_mt{}".format(self.syst_suffix), zcand_p4.Mt())
        
        ##############################
        ## high level info
        ##############################

        _delta_zphi = tk.deltaPhi(z_candidate[0].phi, z_candidate[1].phi) if lep_category > 0 else -99
        _delta_zdR  = tk.deltaR(z_candidate[0].eta, z_candidate[0].phi,
                                z_candidate[1].eta, z_candidate[1].phi,) if lep_category > 0 else -99
        _delta_zeta     = abs(z_candidate[0].eta - z_candidate[1].eta) if lep_category > 0 else -99
        _delta_phi_zmet = tk.deltaPhi(zcand_p4.Phi(), met.phi)
        _vec_delta_balance  = (met_p4 - zcand_p4).Pt()/zcand_p4.Pt() if zcand_p4.Pt() != 0 else -1
        _sca_delta_balance  = met.pt/zcand_p4.Pt() if zcand_p4.Pt() != 0 else -1

        # hadronic recoil
        had_recoil_p4 = ROOT.TLorentzVector()
        had_recoil_p4 += met_p4
        for lep in good_leptons + extra_leptons:
            had_recoil_p4 += lep.p4()
        had_recoil_p4 = -had_recoil_p4
        _delta_met_rec = tk.deltaPhi(met.phi, had_recoil_p4.Phi()) if lep_category > 0 else -99

        _MT = np.sqrt(2 * zcand_p4.Pt() * var_met_pt * (1 - np.cos(_delta_phi_zmet)))
        # defined as from https://arxiv.org/pdf/1808.09054.pdf
        _Ell = np.sqrt(zcand_p4.Mag2() + zcand_p4.M2())
        _altMT = np.sqrt(np.power(_Ell + met_p4.Pt(),2) + (met_p4 + zcand_p4).Mag2())
        # checking the transverse mass
        _rem_p4 = ROOT.TLorentzVector()
        _rem_p4.SetPtEtaPhiM(rem_lepton_p4.Pt(), 0, rem_lepton_p4.Phi(), 0)

        self.out.fillBranch("delta_phi_ll{}".format(self.syst_suffix), _delta_zphi)
        self.out.fillBranch("delta_eta_ll{}".format(self.syst_suffix), _delta_zeta)
        self.out.fillBranch("delta_R_ll{}".format(self.syst_suffix), _delta_zdR)
        self.out.fillBranch("delta_phi_ZMet{}".format(self.syst_suffix), _delta_phi_zmet)
        self.out.fillBranch("vec_balance{}".format(self.syst_suffix), _vec_delta_balance)
        self.out.fillBranch("sca_balance{}".format(self.syst_suffix), _sca_delta_balance)
        self.out.fillBranch("hadronic_recoil{}".format(self.syst_suffix), had_recoil_p4.Pt())
        self.out.fillBranch("delta_met_rec{}".format(self.syst_suffix), _delta_met_rec)
        self.out.fillBranch("emulatedMET{}".format(self.syst_suffix), emulated_met.Pt())
        self.out.fillBranch("emulatedMET_phi{}".format(self.syst_suffix), emulated_met.Phi())
        self.out.fillBranch("mass_alllep{}".format(self.syst_suffix), all_lepton_p4.M())
        self.out.fillBranch("pt_alllep{}".format(self.syst_suffix), all_lepton_p4.Pt())
        self.out.fillBranch("remll_mass{}".format(self.syst_suffix), rem_lepton_p4.M())
        self.out.fillBranch("MT{}".format(self.syst_suffix), _MT)
        self.out.fillBranch("altMT{}".format(self.syst_suffix), _altMT)
        self.out.fillBranch("trans_mass{}".format(self.syst_suffix), (_rem_p4 + met_p4).M())

        # Let remove the negative categories with no obvious meaning meaning
        # This will reduce the size of most of the bacground and data
        if (lep_category > 0 and zcand_p4.Pt()>60 and zcand_p4.M() > 55 and zcand_p4.M() < 127):
            return True
        else:
            return False
    def _prepareEvent(self, event):

        logging.debug('processing event %d' % event.event)

	## met selection
	if event.MET_pt < 50.0:
	    return False
	metLV = ROOT.TLorentzVector()
	metLV.SetPtEtaPhiM( event.MET_pt, 0.0, event.MET_phi, 0.0)
	      

	## muon selection
	event._allMuons = Collection(event, "Muon")	
	event.muons = []
	for muon in event._allMuons:
	   if abs(muon.eta) < 2.4 and\
	      abs(muon.dxy) < 0.2 and\
	      abs(muon.dz) < 0.5:# and\
	      #muon.pfRelIso03_all < 0.15:
		  drMuJet = deltaR(muon, event._allJets[muon.jetIdx]) if muon.jetIdx >= 0 else -999
		  ptRel = muon.pt
		  if drMuJet > -999:
			jetforPtRel = event._allJets[muon.jetIdx]
		  	jetLV = ROOT.TLorentzVector()
		  	jetLV.SetPtEtaPhiM(jetforPtRel.pt, jetforPtRel.eta, jetforPtRel.phi, jetforPtRel.mass) 
		  	thismuonLV = ROOT.TLorentzVector()
		  	thismuonLV.SetPtEtaPhiM(muon.pt, muon.eta, muon.phi, muon.mass)
		  	ptRel = muon.pt * math.cos(thismuonLV.Angle(jetLV.Vect()))
		  if ptRel > 55.0 or drMuJet > 0.4:
		  	event.muons.append(muon)
			event.muonpTrel = ptRel
			event.drMuJet = drMuJet


	if (len(event.muons) != 1):
		return False
	
	muonLV = ROOT.TLorentzVector()
	muonLV.SetPtEtaPhiM( event.muons[0].pt, event.muons[0].eta, event.muons[0].phi, event.muons[0].mass )


	## b-tag AK4 jet selection
        event.ak4jets = []
        for j in event._allJets:
            if not (j.pt > 25.0 and abs(j.eta) < 2.4 and (j.jetId & 2)):
                continue
	    if j.btagCSVV2 > 0.8484 and\
	       abs(deltaPhi(j,event.muons[0])) < 2.0:
		event.ak4jets.append(j)

        if (len(event.ak4jets) < 1):
		return False 



	

	## selection on AK8 jets / drop if overlaps with a photon
        event.ak8jets = []
        for fj in event._allAK8jets:
            if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)):
                continue
            if abs(deltaPhi(fj, event.muons[0])) > 2.0:
		event.ak8jets.append(fj)

        if (len(event.ak8jets)<1):
            return False

        ## selection on CA15 jets / drop if overlaps with a photon
        event.ca15jets = []
        for fj in event._allCA15jets:
            if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)):
                continue
            if abs(deltaPhi(fj, event.muons[0])) > 2.0:
            	event.ca15jets.append(fj)
   
        if (len(event.ca15jets)<1):
            return False


        ## require the leading ak8 & ca15 jets overlap
        if deltaR(event.ak8jets[0],event.ca15jets[0])>0.8:
            return False

	##leptonic W pt cut
	WLV = ROOT.TLorentzVector()
	WLV = muonLV + metLV
	if WLV.Pt() < 250.0:
	    return False 

	##Find gen top and compute top size (-999. if unmatched)
	if self.isMC:
		event.genTops = []
		index = -1
		matchIndex = []
		for p in event.genParticles:
			index += 1
			if not (abs(p.pdgId) == 6):
				continue
			pLV = ROOT.TLorentzVector()
			pLV.SetPtEtaPhiM(p.pt, p.eta, p.phi, p.mass)
			#if deltaR(event.ak8jets[0], p) < 1.0:
			event.genTops.append(p)
			matchIndex.append(index)
		#print "Found gen tops", len(event.genTops)

		event.topDecayParts = []
		if matchIndex > -1:

			index = -1
			event.genWs = []
			genWindx = []
			for p in event.genParticles:
				index += 1
				#if not (p.genPartIdxMother in matchIndex):
				#	continue
				pLV = ROOT.TLorentzVector()
				pLV.SetPtEtaPhiM(p.pt, p.eta, p.phi, p.mass)
				if abs(p.pdgId) == 5 and (p.genPartIdxMother in matchIndex):
					event.topDecayParts.append(p)
				if abs(p.pdgId) == 24 and (abs(event.genParticles[p.genPartIdxMother].pdgId) == 24):
					event.genWs.append(p)
					genWindx.append(index)
		#print "Found gen Ws", len(event.genWs)		
		#print event.genWs
		for q in event.genParticles:
			if (q.genPartIdxMother in genWindx):
				qLV = ROOT.TLorentzVector()
        			qLV.SetPtEtaPhiM(q.pt, q.eta, q.phi, q.mass)
				event.topDecayParts.append(q)
	
		#print "Top decay parts", len(event.topDecayParts)
		event.maxDR = -999.
		nMerged = 0
		for d in event.topDecayParts:
			thisDR = deltaR(d,event.topDecayParts[-1])
			if deltaR(d,event.ak8jets[0]) < 0.8:
				nMerged += 1
			if thisDR > event.maxDR:
				event.maxDR = thisDR
	
		#print nMerged
		if nMerged >= 3:
			#print "full"
			event.isFullyMerged = 1
		elif nMerged == 2:
			#print "semi"
			event.isSemiMerged = 1
		elif nMerged <= 1:
			#print "un"
			event.isUnMerged = 1
				
		






	

	



    
        ## return True if passes selection
        return True
Exemplo n.º 7
0
    def analyze(self, event):
        """
        process event, return True (go to next module)
        or False (fail, go to next event)
        """
        jets = list(Collection(event, "Jet"))
        fatjets = list(Collection(event, "FatJet"))
        taus = list(Collection(event, "Tau"))
        PFCands = list(Collection(event, "PFCands"))
        flag = Object(event, "Flag")
        met = Object(event, "MET")
        genpart = list(Collection(event, "GenPart"))

        met_p4 = ROOT.TLorentzVector()
        met_p4.SetPtEtaPhiM(met.pt, 0.0, met.phi, 0.0)

        # filling and contructing the event categorisation
        self.out.fillBranch("met_pt{}".format(self.syst_suffix), met.pt)
        self.out.fillBranch("met_phi{}".format(self.syst_suffix), met.phi)

        pass_met_filter = self.met_filter(flag, True)
        self.out.fillBranch("met_filter{}".format(self.syst_suffix),
                            pass_met_filter)

        #look through all the PFCands. See here (https://github.com/SUEPPhysics/SUEPNano/blob/autumn18/python/addPFCands_cff.py)
        good_cands = []
        fastjet_list = []
        sum_cand_pt = 0.0
        for cand in PFCands:
            if cand.trkPt < 1 or cand.fromPV < 2 or cand.trkEta > 2.5:
                continue
            good_cands.append(cand)
            sum_cand_pt += cand.trkPt
            fastjet_prep = (cand.trkPt, cand.trkEta, cand.trkPhi, cand.mass)
            fastjet_list.append(fastjet_prep)
        nCands = len(good_cands)
        ave_cand_pt = sum_cand_pt / nCands if nCands >= 1 else 0.0

        #fill out the basics
        self.out.fillBranch("nCleaned_Cands{}".format(self.syst_suffix),
                            nCands)
        self.out.fillBranch("HTTot{}".format(self.syst_suffix), sum_cand_pt)
        self.out.fillBranch("ave_cand_pt{}".format(self.syst_suffix),
                            ave_cand_pt)

        #make new jet collection based on fastjet
        fastjet_in = np.array(fastjet_list[:],
                              dtype=[('pT', 'f8'), ('eta', 'f8'),
                                     ('phi', 'f8'), ('mass', 'f8')])
        sequence = pyjet.cluster(
            fastjet_in, R=1.5,
            p=-1)  #p=-1,0,1 for anti-kt, aachen, and kt respectively
        fastjets = sequence.inclusive_jets(ptmin=3)
        self.out.fillBranch("ngood_fastjets".format(self.syst_suffix),
                            len(fastjets))

        #remove the 10 hardest tracks for SUEP_isr
        #fastjets.sort(key=lambda fastjet: len(fastjet), reverse=True)
        spher_tmp = ROOT.TLorentzVector()
        if len(fastjets) > 1:
            SUEP_cand = fastjets[0]
            ISR_cand = fastjets[1]
            if len(fastjets[1]) > len(fastjets[0]):
                SUEP_cand = fastjets[1]
                ISR_cand = fastjets[0]

            SUEP_pt = ROOT.TLorentzVector()
            SUEP_pt.SetPtEtaPhiM(SUEP_cand.pt, SUEP_cand.eta, SUEP_cand.phi,
                                 SUEP_cand.mass)
            boost_pt = SUEP_pt.BoostVector()
            boosted_cands = []
            for cands in good_cands:
                spher_tmp.SetPtEtaPhiM(cands.trkPt, cands.trkEta, cands.trkPhi,
                                       cands.mass)
                spher_tmp.Boost(-boost_pt)
                if abs(tk.deltaPhi(spher_tmp.Phi(), ISR_cand.phi)) < 1.6:
                    continue
                boosted_cands.append(
                    [spher_tmp.Px(),
                     spher_tmp.Py(),
                     spher_tmp.Pz()])
            try:
                sorted_evals = self.sphericity(boosted_cands, 2.0)
            except:
                sorted_evals = [0.0, 0.0, 0.0]
            SUEP_ch_spher = 1.5 * (sorted_evals[1] + sorted_evals[0])
            SUEP_ch_aplan = 1.5 * sorted_evals[0]
            SUEP_ch_FW2M = 1.0 - 3.0 * (sorted_evals[2] * sorted_evals[1] +
                                        sorted_evals[2] * sorted_evals[0] +
                                        sorted_evals[1] * sorted_evals[0])
            SUEP_ch_D = 27.0 * sorted_evals[2] * sorted_evals[
                1] * sorted_evals[0]
            self.out.fillBranch("SUEP_ch_nconst{}".format(self.syst_suffix),
                                len(boosted_cands))
            self.out.fillBranch("SUEP_ch_spher{}".format(self.syst_suffix),
                                SUEP_ch_spher)
            self.out.fillBranch("SUEP_ch_aplan{}".format(self.syst_suffix),
                                SUEP_ch_aplan)
            self.out.fillBranch("SUEP_ch_FW2M{}".format(self.syst_suffix),
                                SUEP_ch_FW2M)
            self.out.fillBranch("SUEP_ch_D{}".format(self.syst_suffix),
                                SUEP_ch_D)

        if len(fastjets) > 0:
            #looking at the highest pT fastjet for SUEP_pt
            self.out.fillBranch("SUEP_pt_pt{}".format(self.syst_suffix),
                                fastjets[0].pt)
            self.out.fillBranch("SUEP_pt_m{}".format(self.syst_suffix),
                                fastjets[0].mass)
            self.out.fillBranch("SUEP_pt_eta{}".format(self.syst_suffix),
                                fastjets[0].eta)
            self.out.fillBranch("SUEP_pt_phi{}".format(self.syst_suffix),
                                fastjets[0].phi)
            self.out.fillBranch("SUEP_pt_nconst{}".format(self.syst_suffix),
                                len(fastjets[0]))
            sum_SUEP_pt = 0.0
            girth_pt = 0.0
            SUEP_pt = ROOT.TLorentzVector()
            SUEP_pt.SetPtEtaPhiM(fastjets[0].pt, fastjets[0].eta,
                                 fastjets[0].phi, fastjets[0].mass)
            boost_pt = SUEP_pt.BoostVector()
            spher_pt = []
            for const in fastjets[0]:
                sum_SUEP_pt += const.pt
                dR = abs(
                    tk.deltaR(
                        const.eta,
                        const.phi,
                        fastjets[0].eta,
                        fastjets[0].phi,
                    ))
                girth_pt += dR * const.pt / fastjets[0].pt
                spher_tmp.SetPtEtaPhiM(const.pt, const.eta, const.phi,
                                       const.mass)
                spher_tmp.Boost(-boost_pt)
                spher_pt.append(
                    [spher_tmp.Px(),
                     spher_tmp.Py(),
                     spher_tmp.Pz()])
            try:
                sorted_evals = self.sphericity(spher_pt, 2.0)
            except:
                sorted_evals = [0.0, 0.0, 0.0]
            SUEP_pt_spher = 1.5 * (sorted_evals[1] + sorted_evals[0])
            SUEP_pt_aplan = 1.5 * sorted_evals[0]
            SUEP_pt_FW2M = 1.0 - 3.0 * (sorted_evals[2] * sorted_evals[1] +
                                        sorted_evals[2] * sorted_evals[0] +
                                        sorted_evals[1] * sorted_evals[0])
            SUEP_pt_D = 27.0 * sorted_evals[2] * sorted_evals[
                1] * sorted_evals[0]
            self.out.fillBranch("SUEP_pt_pt_ave{}".format(self.syst_suffix),
                                sum_SUEP_pt / len(fastjets[0]))
            self.out.fillBranch("SUEP_pt_girth{}".format(self.syst_suffix),
                                girth_pt)
            self.out.fillBranch("SUEP_pt_spher{}".format(self.syst_suffix),
                                SUEP_pt_spher)
            self.out.fillBranch("SUEP_pt_aplan{}".format(self.syst_suffix),
                                SUEP_pt_aplan)
            self.out.fillBranch("SUEP_pt_FW2M{}".format(self.syst_suffix),
                                SUEP_pt_FW2M)
            self.out.fillBranch("SUEP_pt_D{}".format(self.syst_suffix),
                                SUEP_pt_D)

            nconst_dphi1 = nconst_dphi3 = nconst_dphi5 = nconst_dphi7 = 0
            if len(fastjets) > 1:
                if len(fastjets[0]) > len(fastjets[1]):
                    SUEP_dphi_cand = fastjets[0]
                    ISR_dphi_cand = fastjets[1]
                else:
                    SUEP_dphi_cand = fastjets[1]
                    ISR_dphi_cand = fastjets[0]

                SUEP_dphi_vector = ROOT.TLorentzVector()
                SUEP_dphi_vector.SetPtEtaPhiM(SUEP_dphi_cand.pt,
                                              SUEP_dphi_cand.eta,
                                              SUEP_dphi_cand.phi,
                                              SUEP_dphi_cand.mass)
                boost_dphi = SUEP_dphi_vector.BoostVector()
                spher_dphi1 = []
                spher_dphi3 = []
                spher_dphi5 = []
                spher_dphi7 = []
                for const in SUEP_dphi_cand:
                    #dphi = abs(tk.deltaPhi(const.phi, ISR_dphi_cand.phi))
                    spher_tmp.SetPtEtaPhiM(const.pt, const.eta, const.phi,
                                           const.mass)
                    spher_tmp.Boost(-boost_dphi)
                    dphi = abs(tk.deltaPhi(spher_tmp.Phi(), ISR_dphi_cand.phi))
                    if dphi < 0.1:
                        continue
                    nconst_dphi1 += 1
                    spher_dphi1.append(
                        [spher_tmp.Px(),
                         spher_tmp.Py(),
                         spher_tmp.Pz()])
                    if dphi < 0.3:
                        continue
                    nconst_dphi3 += 1
                    spher_dphi3.append(
                        [spher_tmp.Px(),
                         spher_tmp.Py(),
                         spher_tmp.Pz()])
                    if dphi < 0.5:
                        continue
                    nconst_dphi5 += 1
                    spher_dphi5.append(
                        [spher_tmp.Px(),
                         spher_tmp.Py(),
                         spher_tmp.Pz()])
                    if dphi < 0.7:
                        continue
                    nconst_dphi7 += 1
                    spher_dphi7.append(
                        [spher_tmp.Px(),
                         spher_tmp.Py(),
                         spher_tmp.Pz()])
            try:
                sorted_dphi1 = self.sphericity(spher_dphi1, 2.0)
                sorted_dphi3 = self.sphericity(spher_dphi3, 2.0)
                sorted_dphi5 = self.sphericity(spher_dphi5, 2.0)
                sorted_dphi7 = self.sphericity(spher_dphi7, 2.0)
            except:
                sorted_dphi1 = [0.0, 0.0, 0.0]
                sorted_dphi3 = [0.0, 0.0, 0.0]
                sorted_dphi5 = [0.0, 0.0, 0.0]
                sorted_dphi7 = [0.0, 0.0, 0.0]
            SUEP_dphi1_spher = 1.5 * (sorted_dphi1[1] + sorted_dphi1[0])
            SUEP_dphi3_spher = 1.5 * (sorted_dphi3[1] + sorted_dphi3[0])
            SUEP_dphi5_spher = 1.5 * (sorted_dphi5[1] + sorted_dphi5[0])
            SUEP_dphi7_spher = 1.5 * (sorted_dphi7[1] + sorted_dphi7[0])

            self.out.fillBranch("SUEP_dphi1_nconst{}".format(self.syst_suffix),
                                nconst_dphi1)
            self.out.fillBranch("SUEP_dphi1_spher{}".format(self.syst_suffix),
                                SUEP_dphi1_spher)
            self.out.fillBranch("SUEP_dphi3_nconst{}".format(self.syst_suffix),
                                nconst_dphi3)
            self.out.fillBranch("SUEP_dphi3_spher{}".format(self.syst_suffix),
                                SUEP_dphi3_spher)
            self.out.fillBranch("SUEP_dphi5_nconst{}".format(self.syst_suffix),
                                nconst_dphi5)
            self.out.fillBranch("SUEP_dphi5_spher{}".format(self.syst_suffix),
                                SUEP_dphi5_spher)
            self.out.fillBranch("SUEP_dphi7_nconst{}".format(self.syst_suffix),
                                nconst_dphi7)
            self.out.fillBranch("SUEP_dphi7_spher{}".format(self.syst_suffix),
                                SUEP_dphi7_spher)

            #look at the fastjet with the most constituents for SUEP_mult
            fastjets.sort(key=lambda fastjet: len(fastjet), reverse=True)
            self.out.fillBranch("SUEP_mult_pt{}".format(self.syst_suffix),
                                fastjets[0].pt)
            self.out.fillBranch("SUEP_mult_m{}".format(self.syst_suffix),
                                fastjets[0].mass)
            self.out.fillBranch("SUEP_mult_eta{}".format(self.syst_suffix),
                                fastjets[0].eta)
            self.out.fillBranch("SUEP_mult_phi{}".format(self.syst_suffix),
                                fastjets[0].phi)
            self.out.fillBranch("SUEP_mult_nconst{}".format(self.syst_suffix),
                                len(fastjets[0]))
            sum_SUEP_mult = 0.0
            girth_mult = 0.0
            SUEP_mult = ROOT.TLorentzVector()
            SUEP_mult.SetPtEtaPhiM(fastjets[0].pt, fastjets[0].eta,
                                   fastjets[0].phi, fastjets[0].mass)
            boost_mult = SUEP_mult.BoostVector()
            spher_mult = []
            unboost = []
            #for const in fastjets[0]:
            #    print(const.eta, const.phi, const.pt)
            #print("now for boosted")
            for const in fastjets[0]:
                sum_SUEP_mult += const.pt
                dR = abs(
                    tk.deltaR(
                        const.eta,
                        const.phi,
                        fastjets[0].eta,
                        fastjets[0].phi,
                    ))
                girth_mult += dR * const.pt / fastjets[0].pt
                spher_tmp.SetPtEtaPhiM(const.pt, const.eta, const.phi,
                                       const.mass)
                unboost.append(
                    [spher_tmp.Px(),
                     spher_tmp.Py(),
                     spher_tmp.Pz()])
                spher_tmp.Boost(-boost_mult)
                #print(spher_tmp.Eta(), spher_tmp.Phi(), spher_tmp.Pt())
                spher_mult.append(
                    [spher_tmp.Px(),
                     spher_tmp.Py(),
                     spher_tmp.Pz()])
            try:
                sorted_evals = self.sphericity(unboost, 2.0)
            except:
                sorted_evals = [0.0, 0.0, 0.0]
            #print(sorted_evals)
            try:
                sorted_evals = self.sphericity(spher_mult, 2.0)
            except:
                sorted_evals = [0.0, 0.0, 0.0]
            #print(sorted_evals)
            SUEP_mult_spher = 1.5 * (sorted_evals[1] + sorted_evals[0])
            SUEP_mult_aplan = 1.5 * sorted_evals[0]
            SUEP_mult_FW2M = 1.0 - 3.0 * (sorted_evals[2] * sorted_evals[1] +
                                          sorted_evals[2] * sorted_evals[0] +
                                          sorted_evals[1] * sorted_evals[0])
            SUEP_mult_D = 27.0 * sorted_evals[2] * sorted_evals[
                1] * sorted_evals[0]
            self.out.fillBranch("SUEP_mult_pt_ave{}".format(self.syst_suffix),
                                sum_SUEP_mult / len(fastjets[0]))
            self.out.fillBranch("SUEP_mult_girth{}".format(self.syst_suffix),
                                girth_mult)
            self.out.fillBranch("SUEP_mult_spher{}".format(self.syst_suffix),
                                SUEP_mult_spher)
            self.out.fillBranch("SUEP_mult_aplan{}".format(self.syst_suffix),
                                SUEP_mult_aplan)
            self.out.fillBranch("SUEP_mult_FW2M{}".format(self.syst_suffix),
                                SUEP_mult_FW2M)
            self.out.fillBranch("SUEP_mult_D{}".format(self.syst_suffix),
                                SUEP_mult_D)

        good_jets = []
        good_bjets = []
        HT = 0.0
        for jet in jets:
            if jet.pt < 30.0 or abs(jet.eta) > 4.7:
                continue
            if not jet.jetId:
                continue
            #if tk.closest(jet, good_leptons)[1] < 0.4:
            #    continue
            good_jets.append(jet)
            HT += jet.pt
            # Count b-tag with medium WP DeepCSV
            # ref : https://twiki.cern.ch/twiki/bin/viewauth/CMS/BtagRecommendation94X
            if abs(jet.eta) <= 2.4 and jet.btagDeepB > self.btag_id("medium"):
                good_bjets.append(jet)

        good_jets.sort(key=lambda jet: jet.pt, reverse=True)
        good_bjets.sort(key=lambda jet: jet.pt, reverse=True)

        _dphi_j_met = tk.deltaPhi(good_jets[0],
                                  met.phi) if len(good_jets) else -99.0
        _lead_jet_pt = good_jets[0].pt if len(good_jets) else 0.0
        _lead_bjet_pt = good_bjets[0].pt if len(good_bjets) else 0.0

        self.out.fillBranch("HT{}".format(self.syst_suffix), HT)
        self.out.fillBranch("ngood_jets{}".format(self.syst_suffix),
                            len(good_jets))
        self.out.fillBranch("ngood_bjets{}".format(self.syst_suffix),
                            len(good_bjets))
        self.out.fillBranch("lead_jet_pt{}".format(self.syst_suffix),
                            _lead_jet_pt)
        self.out.fillBranch("lead_bjet_pt{}".format(self.syst_suffix),
                            _lead_bjet_pt)
        self.out.fillBranch("delta_phi_j_met{}".format(self.syst_suffix),
                            _dphi_j_met)

        # process taus
        had_taus = []
        for tau in taus:
            #if tk.closest(tau, good_leptons)[1] < 0.4:
            #    continue
            # only hadronic tau decay
            if tau.decayMode != 5:
                continue
            if tau.pt > 18 and abs(tau.eta) <= 2.3:
                had_taus.append(tau)
        self.out.fillBranch("nhad_taus{}".format(self.syst_suffix),
                            len(had_taus))
        self.out.fillBranch("lead_tau_pt{}".format(self.syst_suffix),
                            had_taus[0].pt if len(had_taus) else 0)

        # This will reduce the size of most of the background and data
        if (len(fastjets) > 0):
            return True
        else:
            return False
    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""

        self.correctJetsAndMET(event)
        self.selectLeptons(event)

        if self.prepareEvent(event) is False:
            return False

        self.loadGenHistory(event)

        ## event variables
        htfwd_ = 0.
        htveryfwd_ = 0.
        for j in event._allJets:
            #if not (j.pt > 20 and abs(j.eta) < 2.4 and (j.jetId & 2)):
            if not (j.pt > 25 and (j.jetId & 2)):
                continue
            if (abs(j.eta) > 2.4):
                htfwd_ += j.pt
            if (abs(j.eta) > 3.5):
                htveryfwd_ += j.pt

        self.out.fillBranch("ht", event.ht)
        self.out.fillBranch("htfwd", htfwd_)
        self.out.fillBranch("htveryfwd", htveryfwd_)
        self.out.fillBranch("nlep", len(event.looseLeptons))
        self.out.fillBranch("met", event.met.pt)

        ## count bjets away from fatjet
        nlb_fj_pihalf_ = 0
        nmb_fj_pihalf_ = 0
        ntb_fj_pihalf_ = 0
        nb_fj_pi_ = 0
        for j in event.bljets:
            if abs(deltaPhi(j, event.fatjets[0])) > 3.14:
                nb_fj_pi_ += 1
            if abs(deltaPhi(j, event.fatjets[0])) > 3.14 / 2.:
                nlb_fj_pihalf_ += 1
        for j in event.bmjets:
            if abs(deltaPhi(j, event.fatjets[0])) > 3.14 / 2.:
                nmb_fj_pihalf_ += 1
        for j in event.btjets:
            if abs(deltaPhi(j, event.fatjets[0])) > 3.14 / 2.:
                ntb_fj_pihalf_ += 1

        nb_away_fj_ = 0
        for j in event.bljets:
            if deltaR(j, event.fatjets[0]) > 1.:
                nb_away_fj_ += 1

        self.out.fillBranch("nlb_fj_pihalf", nlb_fj_pihalf_)
        self.out.fillBranch("nmb_fj_pihalf", nmb_fj_pihalf_)
        self.out.fillBranch("ntb_fj_pihalf", ntb_fj_pihalf_)
        self.out.fillBranch("nb_fj_pi", nb_fj_pi_)
        self.out.fillBranch("nb_away_fj", nb_away_fj_)

        self.fillBaseEventInfo(event)
        self.fillFatJetInfo(event)

        return True
Exemplo n.º 9
0
    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""
        electrons = Collection(event, "Electron")
        muons = Collection(event, "Muon")
        jets = Collection(event, "Jet")
        photons = Collection(event, "Photon")

        try:

            genparts = Collection(event, "GenPart")
        except:
            pass

        tight_muons = []

        loose_but_not_tight_muons = []

        tight_electrons = []

        loose_but_not_tight_electrons = []

        tight_photons = []

        tight_jets = []

        for i in range(0, len(muons)):

            if muons[i].pt < 20:
                continue

            if abs(muons[i].eta) > 2.4:
                continue

            if muons[i].tightId and muons[i].pfRelIso04_all < 0.15:
                tight_muons.append(i)
            elif muons[i].pfRelIso04_all < 0.4:
                loose_but_not_tight_muons.append(i)

        for i in range(0, len(electrons)):

            if electrons[i].pt / electrons[i].eCorr < 20:
                continue

            if abs(electrons[i].eta + electrons[i].deltaEtaSC) > 2.5:
                continue

            if (abs(electrons[i].eta + electrons[i].deltaEtaSC) < 1.479
                    and abs(electrons[i].dz) < 0.1
                    and abs(electrons[i].dxy) < 0.05) or (
                        abs(electrons[i].eta + electrons[i].deltaEtaSC) > 1.479
                        and abs(electrons[i].dz) < 0.2
                        and abs(electrons[i].dxy) < 0.1):
                if electrons[i].cutBased >= 3:
                    tight_electrons.append(i)

                elif electrons[i].cutBased >= 1:
                    loose_but_not_tight_electrons.append(i)

        for i in range(0, len(photons)):

            if photons[i].pt / photons[i].eCorr < 20:
                continue

            #if not ((abs(photons[i].eta) < 1.4442) or (1.566 < abs(photons[i].eta) and abs(photons[i].eta) < 2.5) ):
            if not (
                (abs(photons[i].eta) < 1.4442) or
                (1.566 < abs(photons[i].eta) and abs(photons[i].eta) < 2.5)):
                continue

            mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11) | (1 << 13)
            mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11)
            mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 13)
            mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | (
                1 << 13)
            mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | (
                1 << 13
            )  #invert the medium photon ID with the sigma_ietaieta cut removed

            bitmap = photons[i].vidNestedWPBitmap & mask1

            #first add the photons that pass the full ID
            if not (bitmap == mask1):
                continue

            if not ((bitmap == mask1) or (bitmap == mask2) or
                    (bitmap == mask3) or (bitmap == mask4) or
                    (bitmap == mask5)):
                continue

            #if photons[i].cutBased == 0 or photons[i].cutBased == 1:
            #    continue

#            if not photons[i].electronVeto:
#                continue

            if photons[i].pixelSeed:
                continue

            pass_lepton_dr_cut = True

            for j in range(0, len(tight_muons)):
                if deltaR(muons[tight_muons[j]].eta, muons[tight_muons[j]].phi,
                          photons[i].eta, photons[i].phi) < 0.5:
                    pass_lepton_dr_cut = False

            for j in range(0, len(tight_electrons)):

                if deltaR(electrons[tight_electrons[j]].eta,
                          electrons[tight_electrons[j]].phi, photons[i].eta,
                          photons[i].phi) < 0.5:
                    pass_lepton_dr_cut = False

            if not pass_lepton_dr_cut:
                continue

            tight_photons.append(i)

        for i in range(0, len(photons)):

            if photons[i].pt / photons[i].eCorr < 20:
                continue

            #if not ((abs(photons[i].eta) < 1.4442) or (1.566 < abs(photons[i].eta) and abs(photons[i].eta) < 2.5) ):
            if not (
                (abs(photons[i].eta) < 1.4442) or
                (1.566 < abs(photons[i].eta) and abs(photons[i].eta) < 2.5)):
                continue

            mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11) | (1 << 13)
            mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11)
            mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 13)
            mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | (
                1 << 13)
            mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | (
                1 << 13
            )  #invert the medium photon ID with the sigma_ietaieta cut removed

            bitmap = photons[i].vidNestedWPBitmap & mask1

            #after adding the photons that pass the full ID, add the photons that pass the inverted ID
            if (bitmap == mask1):
                continue

            if not ((bitmap == mask1) or (bitmap == mask2) or
                    (bitmap == mask3) or (bitmap == mask4) or
                    (bitmap == mask5)):
                continue

            #if photons[i].cutBased == 0 or photons[i].cutBased == 1:
            #    continue

#            if not photons[i].electronVeto:
#                continue

            if photons[i].pixelSeed:
                continue

            pass_lepton_dr_cut = True

            for j in range(0, len(tight_muons)):
                if deltaR(muons[tight_muons[j]].eta, muons[tight_muons[j]].phi,
                          photons[i].eta, photons[i].phi) < 0.5:
                    pass_lepton_dr_cut = False

            for j in range(0, len(tight_electrons)):
                if deltaR(electrons[tight_electrons[j]].eta,
                          electrons[tight_electrons[j]].phi, photons[i].eta,
                          photons[i].phi) < 0.5:
                    pass_lepton_dr_cut = False

            if not pass_lepton_dr_cut:
                continue

            tight_photons.append(i)

        if len(tight_photons) == 0:
            return False

        njets = 0

        for i in range(0, len(jets)):

            if jets[i].pt < 30:
                continue

            if abs(jets[i].eta) > 4.7:
                continue

            if not jets[i].jetId & (1 << 0):
                continue

            njets += 1

        for i in range(0, len(jets)):

            if jets[i].pt < 30:
                continue

            if abs(jets[i].eta) > 4.7:
                continue

            if not jets[i].jetId & (1 << 0):
                continue

            #pass_photon_dr_cut = True

            #for j in range(0,len(tight_photons)):

            #    print "deltaR(photons[tight_photons[j]].eta,photons[tight_photons[j]].phi,jets[i].eta,jets[i].phi) = " + str(deltaR(photons[tight_photons[j]].eta,photons[tight_photons[j]].phi,jets[i].eta,jets[i].phi))

            #    if deltaR(photons[tight_photons[j]].eta,photons[tight_photons[j]].phi,jets[i].eta,jets[i].phi) < 0.5:
            #        pass_photon_dr_cut = False

            #if not pass_photon_dr_cut:
            #    continue

            if deltaR(photons[tight_photons[0]].eta,
                      photons[tight_photons[0]].phi, jets[i].eta,
                      jets[i].phi) < 0.5:
                continue

            pass_lepton_dr_cut = True

            for j in range(0, len(tight_muons)):

                if deltaR(muons[tight_muons[j]].eta, muons[tight_muons[j]].phi,
                          jets[i].eta, jets[i].phi) < 0.5:
                    pass_lepton_dr_cut = False

            for j in range(0, len(tight_electrons)):

                if deltaR(electrons[tight_electrons[j]].eta,
                          electrons[tight_electrons[j]].phi, jets[i].eta,
                          jets[i].phi) < 0.5:

                    pass_lepton_dr_cut = False

            for j in range(0, len(loose_but_not_tight_muons)):

                if deltaR(muons[loose_but_not_tight_muons[j]].eta,
                          muons[loose_but_not_tight_muons[j]].phi, jets[i].eta,
                          jets[i].phi) < 0.5:

                    pass_lepton_dr_cut = False

            for j in range(0, len(loose_but_not_tight_electrons)):

                if deltaR(electrons[loose_but_not_tight_electrons[j]].eta,
                          electrons[loose_but_not_tight_electrons[j]].phi,
                          jets[i].eta, jets[i].phi) < 0.5:

                    pass_lepton_dr_cut = False

            if not pass_lepton_dr_cut:
                continue

            tight_jets.append(i)

        if len(tight_jets) < 2:
            return False

        if jets[tight_jets[0]].btagCSVV2 < 0.8484 and jets[
                tight_jets[1]].btagCSVV2 < 0.8484:
            self.out.fillBranch("btagging_selection", 1)
        else:
            self.out.fillBranch("btagging_selection", 0)

        if jets[tight_jets[0]].pt < 40:
            return False

        if jets[tight_jets[1]].pt < 30:
            return False

        if abs(jets[tight_jets[0]].eta) > 4.7:
            return False

        if abs(jets[tight_jets[1]].eta) > 4.7:
            return False

        if (jets[tight_jets[0]].p4() + jets[tight_jets[1]].p4()).M() < 200:
            return False

        #if abs(jets[0].p4().Eta() - jets[1].p4().Eta()) < 2.5:
        #    return False

        if photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr < 20:
            return False

        #if not (abs(photons[tight_photons[0]].eta) < 1.4442):
        #if not (abs(photons[tight_photons[0]].eta) < 1.4442):
        #    return False

        if not ((abs(photons[tight_photons[0]].eta) < 1.4442) or
                (1.566 < abs(photons[tight_photons[0]].eta)
                 and abs(photons[tight_photons[0]].eta) < 2.5)):
            return False

        if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi,
                  jets[tight_jets[0]].eta, jets[tight_jets[0]].phi) < 0.5:
            return False

        if deltaR(photons[tight_photons[0]].eta, photons[tight_photons[0]].phi,
                  jets[tight_jets[1]].eta, jets[tight_jets[1]].phi) < 0.5:
            return False

        if deltaR(jets[tight_jets[0]].eta, jets[tight_jets[0]].phi,
                  jets[tight_jets[1]].eta, jets[tight_jets[1]].phi) < 0.5:
            return False

        #if photons[tight_photons[0]].cutBased == 0 or photons[tight_photons[0]].cutBased == 1:
        #    return False


#        if not photons[tight_photons[0]].electronVeto:
#            return False

        if photons[tight_photons[0]].pixelSeed:
            return False

        #if event.MET_pt < 35:
        #    return False

        if abs(deltaPhi(event.MET_phi, jets[tight_jets[0]].phi)) < 0.4:
            return False

        if abs(deltaPhi(event.MET_phi, jets[tight_jets[1]].phi)) < 0.4:
            return False

        if len(tight_muons) + len(loose_but_not_tight_muons) + len(
                tight_electrons) + len(loose_but_not_tight_electrons) > 1:
            return False

        isprompt_mask = (1 << 0)  #isPrompt
        isprompttaudecayproduct_mask = (1 << 4)  #isPromptTauDecayProduct

        is_lepton_real = 0

        if len(tight_muons) == 1:

            try:

                for i in range(0, len(genparts)):
                    if genparts[i].pt > 5 and abs(
                            genparts[i].pdgId) == 13 and (
                                (genparts[i].statusFlags & isprompt_mask
                                 == isprompt_mask) or
                                (genparts[i].statusFlags
                                 & isprompttaudecayproduct_mask
                                 == isprompttaudecayproduct_mask)) and deltaR(
                                     muons[tight_muons[0]].eta,
                                     muons[tight_muons[0]].phi,
                                     genparts[i].eta, genparts[i].phi) < 0.3:
                        is_lepton_real = 1

            except:
                pass

            if not (event.HLT_IsoMu24 or event.HLT_IsoTkMu24):
                return False

            if deltaR(photons[tight_photons[0]].eta,
                      photons[tight_photons[0]].phi, muons[tight_muons[0]].eta,
                      muons[tight_muons[0]].phi) < 0.5:
                return False

            if muons[tight_muons[0]].pt < 25:
                return False

            if abs(muons[tight_muons[0]].eta) > 2.4:
                return False

            if muons[tight_muons[0]].pfRelIso04_all > 0.15:
                return False

            if not muons[tight_muons[0]].tightId:
                return False

            #if sqrt(2*muons[tight_muons[0]].pt*event.MET_pt*(1 - cos(event.MET_phi - muons[tight_muons[0]].phi))) < 30:
            #    return False

            self.out.fillBranch(
                "mt",
                sqrt(2 * muons[tight_muons[0]].pt * event.MET_pt *
                     (1 - cos(event.MET_phi - muons[tight_muons[0]].phi))))

            print "selected muon event: " + str(event.event) + " " + str(
                event.luminosityBlock) + " " + str(event.run)

            mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11) | (1 << 13)
            mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11)
            mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 13)
            mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | (
                1 << 13)
            mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | (
                1 << 13
            )  #invert the medium photon ID with the sigma_ietaieta cut removed

            bitmap = photons[tight_photons[0]].vidNestedWPBitmap & mask1

            if (bitmap == mask1):
                self.out.fillBranch("photon_selection", 2)
            elif (bitmap == mask5):
                self.out.fillBranch("photon_selection", 1)
            elif (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4):
                self.out.fillBranch("photon_selection", 0)
            else:
                assert (0)

            self.out.fillBranch("is_lepton_real", is_lepton_real)
            self.out.fillBranch("lepton_pdg_id", 13)
            self.out.fillBranch("lepton_pt", muons[tight_muons[0]].pt)
            self.out.fillBranch("lepton_eta", muons[tight_muons[0]].eta)
            self.out.fillBranch("lepton_phi", muons[tight_muons[0]].phi)
            self.out.fillBranch("met", event.MET_pt)
            self.out.fillBranch(
                "photon_pt",
                photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr)
            self.out.fillBranch("photon_eta", photons[tight_photons[0]].eta)
            self.out.fillBranch("photon_phi", photons[tight_photons[0]].phi)
            self.out.fillBranch("mjj", (jets[tight_jets[0]].p4() +
                                        jets[tight_jets[1]].p4()).M())
            self.out.fillBranch("mlg", (muons[tight_muons[0]].p4() +
                                        photons[tight_photons[0]].p4()).M())
            self.out.fillBranch("is_lepton_tight", 1)

        elif len(loose_but_not_tight_muons) == 1:

            try:

                for i in range(0, len(genparts)):
                    if genparts[i].pt > 5 and abs(
                            genparts[i].pdgId) == 13 and (
                                (genparts[i].statusFlags & isprompt_mask
                                 == isprompt_mask) or
                                (genparts[i].statusFlags
                                 & isprompttaudecayproduct_mask
                                 == isprompttaudecayproduct_mask)) and deltaR(
                                     muons[loose_but_not_tight_muons[0]].eta,
                                     muons[loose_but_not_tight_muons[0]].phi,
                                     genparts[i].eta, genparts[i].phi) < 0.3:
                        is_lepton_real = 1
            except:
                pass

            if not (event.HLT_IsoMu24 or event.HLT_IsoTkMu24):
                return False

            if deltaR(photons[tight_photons[0]].eta,
                      photons[tight_photons[0]].phi,
                      muons[loose_but_not_tight_muons[0]].eta,
                      muons[loose_but_not_tight_muons[0]].phi) < 0.5:
                return False

            if muons[loose_but_not_tight_muons[0]].pt < 25:
                return False

            if abs(muons[loose_but_not_tight_muons[0]].eta) > 2.4:
                return False

            #if sqrt(2*muons[loose_but_not_tight_muons[0]].pt*event.MET_pt*(1 - cos(event.MET_phi - muons[loose_but_not_tight_muons[0]].phi))) < 30:
            #    return False

            self.out.fillBranch(
                "mt",
                sqrt(2 * muons[loose_but_not_tight_muons[0]].pt *
                     event.MET_pt *
                     (1 - cos(event.MET_phi -
                              muons[loose_but_not_tight_muons[0]].phi))))

            mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11) | (1 << 13)
            mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11)
            mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 13)
            mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | (
                1 << 13)
            mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | (
                1 << 13
            )  #invert the medium photon ID with the sigma_ietaieta cut removed

            bitmap = photons[tight_photons[0]].vidNestedWPBitmap & mask1

            if (bitmap == mask1):
                self.out.fillBranch("photon_selection", 2)
            elif (bitmap == mask5):
                self.out.fillBranch("photon_selection", 1)
            elif (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4):
                self.out.fillBranch("photon_selection", 0)
            else:
                assert (0)

            self.out.fillBranch("is_lepton_real", is_lepton_real)
            self.out.fillBranch("lepton_pdg_id", 13)
            self.out.fillBranch("lepton_pt",
                                muons[loose_but_not_tight_muons[0]].pt)
            self.out.fillBranch("lepton_eta",
                                muons[loose_but_not_tight_muons[0]].eta)
            self.out.fillBranch("lepton_phi",
                                muons[loose_but_not_tight_muons[0]].phi)
            self.out.fillBranch("met", event.MET_pt)
            self.out.fillBranch(
                "photon_pt",
                photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr)
            self.out.fillBranch("photon_eta", photons[tight_photons[0]].eta)
            self.out.fillBranch("photon_phi", photons[tight_photons[0]].phi)
            self.out.fillBranch("mjj", (jets[tight_jets[0]].p4() +
                                        jets[tight_jets[1]].p4()).M())
            self.out.fillBranch("mlg",
                                (muons[loose_but_not_tight_muons[0]].p4() +
                                 photons[tight_photons[0]].p4()).M())
            self.out.fillBranch("is_lepton_tight", 0)

        elif len(tight_electrons) == 1:

            try:

                for i in range(0, len(genparts)):
                    if genparts[i].pt > 5 and abs(
                            genparts[i].pdgId) == 11 and (
                                (genparts[i].statusFlags & isprompt_mask
                                 == isprompt_mask) or
                                (genparts[i].statusFlags
                                 & isprompttaudecayproduct_mask
                                 == isprompttaudecayproduct_mask)) and deltaR(
                                     electrons[tight_electrons[0]].eta,
                                     electrons[tight_electrons[0]].phi,
                                     genparts[i].eta, genparts[i].phi) < 0.3:
                        is_lepton_real = 1
            except:
                pass

            if not event.HLT_Ele27_WPTight_Gsf:
                return False

            if electrons[tight_electrons[0]].cutBased == 0 or electrons[
                    tight_electrons[0]].cutBased == 1:
                return False

            if deltaR(photons[tight_photons[0]].eta,
                      photons[tight_photons[0]].phi,
                      electrons[tight_electrons[0]].eta,
                      electrons[tight_electrons[0]].phi) < 0.5:
                return False

            if electrons[tight_electrons[0]].pt / electrons[
                    tight_electrons[0]].eCorr < 30:
                return False

            if abs(electrons[tight_electrons[0]].eta) > 2.5:
                return False

            ele_p4 = electrons[tight_electrons[0]].p4()

            pho_p4 = photons[tight_photons[0]].p4()

            ele_p4.SetPtEtaPhiM(
                ele_p4.Pt() / electrons[tight_electrons[0]].eCorr,
                ele_p4.Eta(), ele_p4.Phi(), ele_p4.M())

            pho_p4.SetPtEtaPhiM(pho_p4.Pt() / photons[tight_photons[0]].eCorr,
                                pho_p4.Eta(), pho_p4.Phi(), pho_p4.M())

            #            if (ele_p4 + pho_p4).M() > 81.2 and (ele_p4 + pho_p4).M() < 101.2:
            #            if (ele_p4 + pho_p4).M() > 76.2 and (ele_p4 + pho_p4).M() < 106.2:
            #                return False

            #if sqrt(2*electrons[tight_electrons[0]].pt/electrons[tight_electrons[0]].eCorr*event.MET_pt*(1 - cos(event.MET_phi - electrons[tight_electrons[0]].phi))) < 30:
            #    return False

            self.out.fillBranch(
                "mt",
                sqrt(2 * electrons[tight_electrons[0]].pt /
                     electrons[tight_electrons[0]].eCorr * event.MET_pt *
                     (1 -
                      cos(event.MET_phi - electrons[tight_electrons[0]].phi))))

            mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11) | (1 << 13)
            mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11)
            mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 13)
            mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | (
                1 << 13)
            mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | (
                1 << 13
            )  #invert the medium photon ID with the sigma_ietaieta cut removed

            bitmap = photons[tight_photons[0]].vidNestedWPBitmap & mask1

            if (bitmap == mask1):
                self.out.fillBranch("photon_selection", 2)
            elif (bitmap == mask5):
                self.out.fillBranch("photon_selection", 1)
            elif (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4):
                self.out.fillBranch("photon_selection", 0)
            else:
                assert (0)

            self.out.fillBranch("is_lepton_real", is_lepton_real)
            self.out.fillBranch("lepton_pdg_id", 11)
            self.out.fillBranch("lepton_pt", electrons[tight_electrons[0]].pt)
            self.out.fillBranch("lepton_eta",
                                electrons[tight_electrons[0]].eta)
            self.out.fillBranch("lepton_phi",
                                electrons[tight_electrons[0]].phi)
            self.out.fillBranch("met", event.MET_pt)
            self.out.fillBranch(
                "photon_pt",
                photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr)
            self.out.fillBranch("photon_eta", photons[tight_photons[0]].eta)
            self.out.fillBranch("photon_phi", photons[tight_photons[0]].phi)
            self.out.fillBranch("mjj", (jets[tight_jets[0]].p4() +
                                        jets[tight_jets[1]].p4()).M())
            self.out.fillBranch("mlg", (ele_p4 + pho_p4).M())
            self.out.fillBranch("is_lepton_tight", 1)

            print "selected electron event: " + str(event.event) + " " + str(
                event.luminosityBlock) + " " + str(event.run)

        elif len(loose_but_not_tight_electrons) == 1:

            try:

                for i in range(0, len(genparts)):
                    if genparts[i].pt > 5 and abs(
                            genparts[i].pdgId
                    ) == 11 and (
                        (genparts[i].statusFlags & isprompt_mask
                         == isprompt_mask) or
                        (genparts[i].statusFlags & isprompttaudecayproduct_mask
                         == isprompttaudecayproduct_mask)) and deltaR(
                             electrons[loose_but_not_tight_electrons[0]].eta,
                             electrons[loose_but_not_tight_electrons[0]].phi,
                             genparts[i].eta, genparts[i].phi) < 0.3:
                        is_lepton_real = 1

            except:

                pass

            if not event.HLT_Ele27_WPTight_Gsf:
                return False

            if deltaR(photons[tight_photons[0]].eta,
                      photons[tight_photons[0]].phi,
                      electrons[loose_but_not_tight_electrons[0]].eta,
                      electrons[loose_but_not_tight_electrons[0]].phi) < 0.5:
                return False

            if electrons[loose_but_not_tight_electrons[0]].pt / electrons[
                    loose_but_not_tight_electrons[0]].eCorr < 30:
                return False

            if abs(electrons[loose_but_not_tight_electrons[0]].eta) > 2.5:
                return False

            ele_p4 = electrons[loose_but_not_tight_electrons[0]].p4()

            pho_p4 = photons[tight_photons[0]].p4()

            ele_p4.SetPtEtaPhiM(
                ele_p4.Pt() /
                electrons[loose_but_not_tight_electrons[0]].eCorr,
                ele_p4.Eta(), ele_p4.Phi(), ele_p4.M())

            pho_p4.SetPtEtaPhiM(pho_p4.Pt() / photons[tight_photons[0]].eCorr,
                                pho_p4.Eta(), pho_p4.Phi(), pho_p4.M())

            #            if (ele_p4 + pho_p4).M() > 81.2 and (ele_p4 + pho_p4).M() < 101.2:
            #            if (ele_p4 + pho_p4).M() > 76.2 and (ele_p4 + pho_p4).M() < 106.2:
            #                return False

            #if sqrt(2*electrons[loose_but_not_tight_electrons[0]].pt/electrons[loose_but_not_tight_electrons[0]].eCorr*event.MET_pt*(1 - cos(event.MET_phi - electrons[loose_but_not_tight_electrons[0]].phi))) < 30:
            #    return False

            self.out.fillBranch(
                "mt",
                sqrt(2 * electrons[loose_but_not_tight_electrons[0]].pt /
                     electrons[loose_but_not_tight_electrons[0]].eCorr *
                     event.MET_pt *
                     (1 -
                      cos(event.MET_phi -
                          electrons[loose_but_not_tight_electrons[0]].phi))))

            mask1 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11) | (1 << 13)
            mask2 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 11)
            mask3 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 9) | (
                1 << 13)
            mask4 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 7) | (1 << 11) | (
                1 << 13)
            mask5 = (1 << 1) | (1 << 3) | (1 << 5) | (1 << 9) | (1 << 11) | (
                1 << 13
            )  #invert the medium photon ID with the sigma_ietaieta cut removed

            bitmap = photons[tight_photons[0]].vidNestedWPBitmap & mask1

            if (bitmap == mask1):
                self.out.fillBranch("photon_selection", 2)
            elif (bitmap == mask5):
                self.out.fillBranch("photon_selection", 1)
            elif (bitmap == mask2) or (bitmap == mask3) or (bitmap == mask4):
                self.out.fillBranch("photon_selection", 0)
            else:
                assert (0)

            self.out.fillBranch("is_lepton_real", is_lepton_real)
            self.out.fillBranch("lepton_pdg_id", 11)
            self.out.fillBranch("lepton_pt",
                                electrons[loose_but_not_tight_electrons[0]].pt)
            self.out.fillBranch(
                "lepton_eta", electrons[loose_but_not_tight_electrons[0]].eta)
            self.out.fillBranch(
                "lepton_phi", electrons[loose_but_not_tight_electrons[0]].phi)
            self.out.fillBranch("met", event.MET_pt)
            self.out.fillBranch(
                "photon_pt",
                photons[tight_photons[0]].pt / photons[tight_photons[0]].eCorr)
            self.out.fillBranch("photon_eta", photons[tight_photons[0]].eta)
            self.out.fillBranch("photon_phi", photons[tight_photons[0]].phi)
            self.out.fillBranch("mjj", (jets[tight_jets[0]].p4() +
                                        jets[tight_jets[1]].p4()).M())
            self.out.fillBranch("mlg", (ele_p4 + pho_p4).M())
            self.out.fillBranch("is_lepton_tight", 0)

        else:
            return False

        #print event.event

        #self.out.fillBranch("EventMass",eventSum.M())
        #if eventSum.M() < 2000:
        #    return False
        #else:
        #    return True

        photon_gen_matching = 0

        try:

            for i in range(0, len(genparts)):
                if genparts[i].pt > 5 and abs(
                        genparts[i].pdgId
                ) == 13 and genparts[i].status == 1 and (
                    (genparts[i].statusFlags & isprompt_mask == isprompt_mask)
                        or
                    (genparts[i].statusFlags & isprompttaudecayproduct_mask
                     == isprompttaudecayproduct_mask)) and deltaR(
                         photons[tight_photons[0]].eta,
                         photons[tight_photons[0]].phi, genparts[i].eta,
                         genparts[i].phi) < 0.3:
                    photon_gen_matching += 1
                    break

            for i in range(0, len(genparts)):
                if genparts[i].pt > 5 and abs(
                        genparts[i].pdgId
                ) == 11 and genparts[i].status == 1 and (
                    (genparts[i].statusFlags & isprompt_mask == isprompt_mask)
                        or
                    (genparts[i].statusFlags & isprompttaudecayproduct_mask
                     == isprompttaudecayproduct_mask)) and deltaR(
                         photons[tight_photons[0]].eta,
                         photons[tight_photons[0]].phi, genparts[i].eta,
                         genparts[i].phi) < 0.3:
                    photon_gen_matching += 2
                    break

            for i in range(0, len(genparts)):
                if genparts[i].pt > 5 and genparts[i].pdgId == 22 and genparts[
                        i].status == 1 and (
                            (genparts[i].statusFlags & isprompt_mask
                             == isprompt_mask) or
                            (genparts[i].statusFlags
                             & isprompttaudecayproduct_mask
                             == isprompttaudecayproduct_mask)) and deltaR(
                                 photons[tight_photons[0]].eta,
                                 photons[tight_photons[0]].phi,
                                 genparts[i].eta, genparts[i].phi) < 0.3:

                    if genparts[i].genPartIdxMother >= 0 and (
                            abs(genparts[genparts[i].genPartIdxMother].pdgId)
                            == 11 or abs(
                                genparts[genparts[i].genPartIdxMother].pdgId)
                            == 13 or abs(
                                genparts[genparts[i].genPartIdxMother].pdgId)
                            == 15):
                        photon_gen_matching += 8
                    else:
                        photon_gen_matching += 4
                    break

        except:
            pass

        self.out.fillBranch("photon_gen_matching", photon_gen_matching)

        try:

            self.out.fillBranch("gen_weight", event.Generator_weight)

        except:
            pass

        try:

            self.out.fillBranch("npu", event.Pileup_nPU)
            self.out.fillBranch("ntruepu", event.Pileup_nTrueInt)

        except:
            pass

        self.out.fillBranch("njets", njets)
        self.out.fillBranch("npvs", event.PV_npvs)
        self.out.fillBranch("event", event.event)
        self.out.fillBranch("lumi", event.luminosityBlock)
        self.out.fillBranch("run", event.run)

        return True
Exemplo n.º 10
0
    def prepareEvent(self, event):

        logging.debug('processing event %d' % event.event)

        ## met selection
        if event.met.pt < 50.0:
            return False

        ## muon selection
        muSubJets = []
        for j in Collection(event, "CustomAK4CHS"):
            if j.pt > 30 and abs(j.eta) < 2.4:
                muSubJets.append(j)

        event._allMuons = Collection(event, "Muon")
        event.muons = []
        for muon in event._allMuons:
            if muon.pt > 55 and abs(muon.eta) < 2.4 and muon.tightId and abs(
                    muon.dxy) < 0.2 and abs(muon.dz) < 0.5:
                j, muon.drjet = closest(muon, muSubJets)
                muon.ptrel = muon.p4().Perp(j.p4().Vect()) if j else 0
                #                 if muon.pfRelIso04_all < 0.15:
                if muon.drjet > 0.4 or muon.ptrel > 25:
                    event.muons.append(muon)
        if len(event.muons) != 1:
            return False

        # #leptonic W pt cut
        event.mu = event.muons[0]
        event.leptonicW = event.mu.p4() + event.met.p4()
        if event.leptonicW.Pt() < 250.0:
            return False

        ## b-tag AK4 jet selection
        event.ak4jets = []
        for j in event._allJets:
            if not (j.pt > 25.0 and abs(j.eta) < 2.4 and (j.jetId & 2)):
                continue
            if j.btagCSVV2 > 0.8484 and\
               abs(deltaPhi(j, event.muons[0])) < 2.0:
                event.ak4jets.append(j)

        if len(event.ak4jets) < 1:
            return False

        # # selection on AK8 jets
        event.ak8jets = []
        for fj in event._allAK8jets:
            if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)):
                continue
            if abs(deltaPhi(fj, event.muons[0])) > 2.0:
                event.ak8jets.append(fj)

        if len(event.ak8jets) < 1:
            return False

        # # selection on CA15 jets
        event.ca15jets = []
        for fj in event._allCA15jets:
            if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)):
                continue
            if abs(deltaPhi(fj, event.muons[0])) > 2.0:
                event.ca15jets.append(fj)

        if len(event.ca15jets) < 1:
            return False

        ## require the leading ak8 & ca15 jets overlap
        if deltaR(event.ak8jets[0], event.ca15jets[0]) > 0.8:
            return False

        # # selection on HOTVR jets
        event.hotvrjets = []
        for fj in event._allHOTVRjets:
            if not (fj.pt > 200 and abs(fj.eta) < 2.4):
                continue
            if abs(deltaPhi(fj, event.muons[0])) > 2.0:
                event.hotvrjets.append(fj)

        ## return True if passes selection
        return True
    def prepareEvent(self, event):

        logging.debug('processing event %d' % event.event)

        ## select leading photon
        event._allPhotons = Collection(event, "Photon")
        event.photons = []
        for pho in event._allPhotons:
            if not (pho.pt > 200 and abs(pho.eta) < 2.4 and (pho.cutBasedBitmap & 2) and pho.electronVeto):  # medium ID
                continue
            event.photons.append(pho)

        if len(event.photons) < 1:
            return False

        ## selection on AK8 jets / drop if overlaps with a photon
        event.fatjets = []
        for fj in event._allFatJets:
            if not (fj.pt > 200 and abs(fj.eta) < 2.4 and (fj.jetId & 2)):
                continue
            # require jet and photon to be back-to-back
            if deltaPhi(event.photons[0], fj) < 2:
                continue
#             if deltaR(event.photons[0], fj) < self._jetConeSize:
#                 continue
            event.fatjets.append(fj)
        if len(event.fatjets) < 1:
            return False

        ## selection on SV
        event._allSV = Collection(event, "SV")
        event.secondary_vertices = []
        for sv in event._allSV:
#             if sv.ntracks > 2 and abs(sv.dxy) < 3. and sv.dlenSig > 4:
#             if sv.dlenSig > 4:
            if True:
                event.secondary_vertices.append(sv)
        if len(event.secondary_vertices) < 2:
            return False
        event.secondary_vertices = sorted(event.secondary_vertices, key=lambda x: x.pt, reverse=True)  # sort by pt
#         event.secondary_vertices = sorted(event.secondary_vertices, key=lambda x : x.dxySig, reverse=True)  # sort by dxysig

        # selection on the probe jet (sub-leading in pT)
        probe_fj = event.fatjets[0]
        if not (probe_fj.pt > 200 and probe_fj.msoftdrop > 50 and probe_fj.msoftdrop < 200):
            return False
        # require at least 1 SV matched to each subjet
        self.matchSVToSubjets(event, probe_fj)
        if len(probe_fj.subjets[0].sv_list) == 0 or len(probe_fj.subjets[1].sv_list) == 0:
            return False

        ## ht
        event.ak4jets = []
        for j in event._allJets:
            if not (j.pt > 25 and abs(j.eta) < 2.4 and (j.jetId & 2)):
                continue
            event.ak4jets.append(j)
        event.ht = sum([j.pt for j in event.ak4jets])

        ## return True if passes selection
        return True
Exemplo n.º 12
0
def transverseMass(lepPt, lepPhi, met, metPhi):
    cosDPhi = cos(deltaPhi(lepPhi, metPhi))
    return sqrt(2 * lepPt * met * (1 - cosDPhi))
Exemplo n.º 13
0
    def analyze(self, event):
        """process event, return True (go to next module) or False (fail, go to next event)"""
        if not (event.HLT_Mu17_TrkIsoVVL_Mu8_TrkIsoVVL_DZ or event.HLT_Mu17_TrkIsoVVL_TkMu8_TrkIsoVVL_DZ or event.HLT_IsoTkMu24 or event.HLT_IsoMu24):
	    self.out.fillBranch("pass_selection",0)
            return True
	
	electrons = Collection(event, "Electron")
        muons = Collection(event, "Muon")
        jets = Collection(event, "Jet")
        Z = ROOT.TLorentzVector()

	tight_muons = []
	
	if (len(muons)<=1):
		self.out.fillBranch("pass_selection",0)
                return True
	for i in range(0,len(muons)):
            if (muons[i].eta) < 2.4 and (muons[i].mediumId) and (muons[i].pfIsoId)>=3:
	        if (muons[i].pt) <= 25:
                    continue
		for j in range(i+1,len(muons)):
  		    if (muons[j].eta) < 2.4 and (muons[j].mediumId) and (muons[j].pfIsoId)>=3:
	                if (muons[j].pt) <= 20:
			    continue
		        if (muons[i].charge + muons[j].charge == 0):
			    Z = muons[i].p4() + muons[j].p4()
			    if (Z.M() > 76 and Z.M() < 106):
				self.out.fillBranch("pass_selection",1)
	            		self.out.fillBranch("z_pt",Z.Pt())
				self.out.fillBranch("z_mass",Z.M())
				self.out.fillBranch("z_phi",Z.Phi())
				tight_muons.append(i)            
				tight_muons.append(j)
				#return True
	
        #print(2)
	if len(tight_muons) < 2:
	    self.out.fillBranch("pass_selection",0)
	    return True
	#print(3)
	njet = 0
	for k in range(0,len(jets)):
            #print(4)
	    if abs(jets[k].eta) > 2.4:
                jets[k].pt = -1000
                jets[k].phi = -1000
                jets[k].jetId = -1000
                continue
            #print(5) 
	    if jets[k].pt < 30:
                jets[k].pt = -1000
                jets[k].phi = -1000
                jets[k].jetId = -1000
		continue
	    #print(6)
	    if not (jets[k].jetId & 1):
                jets[k].pt = -1000
                jets[k].phi = -1000
                jets[k].jetId = -1000
		continue
	    #print(7)
	    pass_lepton_dr_cut = True

	    for i in range(0,len(tight_muons)):
		if deltaR(muons[tight_muons[i]].eta,muons[tight_muons[i]].phi,jets[k].eta,jets[k].phi) < 0.4:
	            pass_lepton_dr_cut = False

	    if not pass_lepton_dr_cut:
                jets[k].pt = -1000
                jets[k].phi = -1000
                jets[k].jetId = -1000
		continue
            njet += 1
	    
	    self.out.fillBranch("jet_pt",jets[k].pt)
	    self.out.fillBranch("jet_id",jets[k].jetId)
	    self.out.fillBranch("jet_phi",jets[k].phi)
	    self.out.fillBranch("dphi_zjet",deltaPhi(Z.Phi(),jets[k].phi))
	
	self.out.fillBranch("njet",njet)
	'''
	if(njet!=0):
	    print(njet)
        '''
	return True
Exemplo n.º 14
0
    def analyze(self, event):
        """
        process event, return True (go to next module)
        or False (fail, go to next event)
        """

        # skip useless events
        if event.lep_category <= 0:
            return False

        # Get collection from event tree
        electrons = list(Collection(event, "Electron"))
        muons = list(Collection(event, "Muon"))
        jets = list(Collection(event, "Jet"))

        # in case of systematic take the shifted values are default
        # For the central values, need to include jetMetTool all the time
        # Jet systematics
        if self.syst_var == "":
            syst_var = "nom"
        else:
            syst_var = self.syst_var
        # checking something
        try:
            var_jet_pts = getattr(event, "Jet_pt_{}".format(syst_var), None)
            if var_jet_pts:
                for i, jet in enumerate(jets):
                    jet.pt = var_jet_pts[i]
            else:
                print 'WARNING: jet pts with variation {}'
                'not available, using the nominal value'.format(syst_var)
        except:
            var_jet_pts = getattr(event, "Jet_pt_nom", None)
            for i, jet in enumerate(jets):
                jet.pt = var_jet_pts[i]

        # Get variables from event tree
        Z_pt = event.Z_pt
        Z_eta = event.Z_eta
        Z_phi = event.Z_phi
        Z_mass = event.Z_mass
        Z_p4 = ROOT.TLorentzVector()
        Z_p4.SetPtEtaPhiM(Z_pt, Z_eta, Z_phi, Z_mass)
        Z_p4_bst = ROOT.TLorentzVector(Z_p4)

        met_pt = event.met_pt
        met_phi = event.met_phi
        met_p4 = ROOT.TLorentzVector()
        met_p4.SetPtEtaPhiM(met_pt, 0., met_phi, 0.)
        met_p4_bst = ROOT.TLorentzVector(met_p4)

        emulatedMET_pt_bst = event.emulatedMET
        emulatedMET_phi = event.emulatedMET_phi
        emulatedMET_p4 = ROOT.TLorentzVector()
        emulatedMET_p4.SetPtEtaPhiM(emulatedMET_pt_bst, 0., emulatedMET_phi,
                                    0.)
        emulatedMET_p4_bst = ROOT.TLorentzVector(emulatedMET_p4)

        # process leptons
        good_leptons = []
        good_muons = []
        good_electrons = []
        # Choose tight-quality e/mu for event categorization
        for idx, mu in enumerate(muons):
            isoLep = mu.pfRelIso04_all
            pass_ips = abs(mu.dxy) < 0.02 and abs(mu.dz) < 0.1
            pass_fid = abs(mu.eta) < 2.4 and mu.pt >= (25 if idx == 0 else 20)
            pass_ids = mu.tightId and isoLep <= 0.15
            if pass_fid and pass_ids and pass_ips:
                good_muons.append(mu)
        for idy, el in enumerate(electrons):
            if el.pt >= (25 if idy == 0 else 20) and abs(
                    el.eta) <= 2.5 and self.electron_id(el, "90"):
                good_electrons.append(el)

        # Find any remaining e/mu that pass looser selection
        extra_leptons = []
        for mu in muons:
            isoLep = mu.pfRelIso04_all
            pass_ids = mu.softId and isoLep <= 0.25
            pass_fid = abs(mu.eta) < 2.4 and mu.pt >= 10
            if tk.closest(mu, good_muons)[1] < 0.01:
                continue
            if pass_fid and pass_ids:
                extra_leptons.append(mu)

        for el in electrons:
            pass_fid = abs(el.eta) < 2.5 and el.pt >= 10
            if tk.closest(el, good_electrons)[1] < 0.01:
                continue
            if pass_fid and self.electron_id(el, "WPL"):
                extra_leptons.append(el)

        # sort the leptons in pt
        good_muons.sort(key=lambda x: x.pt, reverse=True)
        good_electrons.sort(key=lambda x: x.pt, reverse=True)
        good_leptons = good_electrons + good_muons
        good_leptons.sort(key=lambda x: x.pt, reverse=True)
        extra_leptons.sort(key=lambda x: x.pt, reverse=True)
        ngood_leptons = len(good_leptons)
        nextra_leptons = len(extra_leptons)
        if ngood_leptons != event.ngood_leptons or nextra_leptons != event.nextra_leptons:
            print(
                'n good (extra) leptons: {} ({}) in VBSProducer, {} ({}) in MonoZProducer.'
                .format(ngood_leptons, nextra_leptons, event.ngood_leptons,
                        event.nextra_leptons))
        lead_lep_p4 = good_leptons[0].p4(
        ) if ngood_leptons else ROOT.TLorentzVector(0., 0., 0., 0.)
        lead_lep_p4_bst = ROOT.TLorentzVector(lead_lep_p4)
        lead_lep_pt = good_leptons[0].pt if ngood_leptons else 0.
        trail_lep_p4 = good_leptons[1].p4(
        ) if ngood_leptons >= 2 else ROOT.TLorentzVector(0., 0., 0., 0.)
        trail_lep_p4_bst = ROOT.TLorentzVector(trail_lep_p4)
        trail_lep_pt = good_leptons[1].pt if ngood_leptons >= 2 else 0.

        # process jet
        good_jets = []
        good_jets_p4 = ROOT.TLorentzVector(0., 0., 0., 0.)
        et_jets20 = 0.
        et_jets30 = 0.
        for jet in jets:
            if not jet.jetId:
                continue
            if tk.closest(jet, good_leptons)[1] < 0.4:
                continue
            if jet.pt <= 20 or abs(jet.eta) > 4.7:
                continue
            et_jets20 += jet.p4().Et()
            if jet.pt < 30.:
                continue
            et_jets30 += jet.p4().Et()
            good_jets.append(jet)
            good_jets_p4 += jet.p4()
        # sort the jets by pt
        good_jets.sort(key=lambda jet: jet.pt, reverse=True)
        ngood_jets = len(good_jets)
        if ngood_jets != event.ngood_jets:
            print 'ngood_jets: {} in VBSProducer, {} in MonoZProducer'.format(
                ngood_jets, event.ngood_jets)
        lead_jet_p4 = good_jets[0].p4() if ngood_jets else ROOT.TLorentzVector(
            0., 0., 0., 0.)
        lead_jet_pt = good_jets[0].pt if ngood_jets else 0.
        lead_jet_phi = good_jets[0].phi if ngood_jets else 0.
        lead_jet_eta = good_jets[0].eta if ngood_jets else -99.
        trail_jet_p4 = good_jets[1].p4(
        ) if ngood_jets > 1 else ROOT.TLorentzVector(0., 0., 0., 0.)
        trail_jet_pt = good_jets[1].pt if ngood_jets > 1 else 0.
        trail_jet_phi = good_jets[1].phi if ngood_jets > 1 else 0.
        trail_jet_eta = good_jets[1].eta if ngood_jets > 1 else -99.

        # boosting 4 vectors
        boost_vet = good_jets_p4.BoostVector()
        lead_lep_p4_bst.Boost(boost_vet)
        trail_lep_p4_bst.Boost(boost_vet)
        Z_p4_bst.Boost(boost_vet)
        met_p4_bst.Boost(boost_vet)
        emulatedMET_p4_bst.Boost(boost_vet)

        # variables in bossted frame
        delta_eta_ll_bst = abs(lead_lep_p4_bst.Eta() - trail_lep_p4_bst.Eta())
        delta_phi_ll_bst = tk.deltaPhi(lead_lep_p4_bst.Phi(),
                                       trail_lep_p4_bst.Phi())
        delta_phi_ZMet_bst = tk.deltaPhi(Z_p4_bst.Phi(), met_p4_bst.Phi())

        # more variables
        x_denom20 = (et_jets20 + met_pt + Z_pt)
        x_denom30 = (et_jets30 + met_pt + Z_pt)
        x_Z = Z_pt / x_denom30 if x_denom30 > 0. else -99.
        x_jet20 = et_jets20 / x_denom20 if x_denom20 > 0. else -99.
        x_jet30 = et_jets30 / x_denom30 if x_denom30 > 0. else -99.
        x_MET = met_pt / x_denom30 if x_denom30 > 0. else -99.
        H_T = sum([jet.pt for jet in good_jets])
        HT_F = (lead_jet_pt + trail_jet_pt) / H_T if H_T > 0. else 0.
        Jet_etas_multiplied = lead_jet_eta * trail_jet_eta

        # more variables
        if ngood_jets >= 2:
            S_T_jets = (lead_jet_p4 + trail_jet_p4).Pt() / (lead_jet_pt +
                                                            trail_jet_pt)
            S_T_hard = (lead_jet_p4 + trail_jet_p4 +
                        Z_p4).Pt() / (lead_jet_pt + trail_jet_pt + Z_pt)
            S_T_all = (lead_jet_p4 + trail_jet_p4 + Z_p4 + met_p4).Pt() / (
                lead_jet_pt + trail_jet_pt + Z_pt + met_pt)
            Jet_pt_Ratio = trail_jet_pt / lead_jet_pt
            R_pt = lead_lep_pt * trail_lep_pt / (lead_jet_pt * trail_jet_pt)
            dijet_abs_dEta = abs(lead_jet_eta - trail_jet_eta)
            dijet_Mjj = (lead_jet_p4 + trail_jet_p4).M()
            dijet_Zep = Z_eta - 0.5 * (lead_jet_eta + trail_jet_eta)
            dijet_centrality = np.exp(-4 * (dijet_Zep / dijet_abs_dEta)**
                                      2) if dijet_abs_dEta > 0 else -99.
            # study jets between leading and trailing jets
            eta_range = sorted([lead_jet_eta, trail_jet_eta])
            pT_mid_Jets = [
                jet.pt for jet in good_jets[2:]
                if eta_range[0] < jet.eta < eta_range[1]
            ]
            CJV_Pt = pT_mid_Jets[0] if len(pT_mid_Jets) else 0.
            CJV_Pt_Sum = sum(pT_mid_Jets) if len(pT_mid_Jets) else 0.
        else:
            S_T_jets = -99.
            S_T_hard = -99.
            S_T_all = -99.
            Jet_pt_Ratio = -99.
            R_pt = -99.
            dijet_abs_dEta = -99.
            dijet_Mjj = -99.
            dijet_Zep = -99.
            dijet_centrality = -99.
            CJV_Pt = 0.
            CJV_Pt_Sum = 0.

        # more variables
        dPT_OZ = (lead_jet_pt + trail_jet_pt) / Z_pt if Z_pt > 0. else -99.
        etaThirdJet = good_jets[2].eta if ngood_jets >= 3 else -99.
        deltaPhiClosestJetMet = 99.
        deltaPhiFarthestJetMet = -99.
        for jet in good_jets:
            if deltaPhiClosestJetMet > abs(tk.deltaPhi(jet.phi, met_phi)):
                deltaPhiClosestJetMet = abs(tk.deltaPhi(jet.phi, met_phi))
            if deltaPhiFarthestJetMet < abs(tk.deltaPhi(jet.phi, met_phi)):
                deltaPhiFarthestJetMet = abs(tk.deltaPhi(jet.phi, met_phi))

        self.out.fillBranch("lead_jet_eta{}".format(self.syst_suffix),
                            lead_jet_eta)
        self.out.fillBranch("lead_jet_phi{}".format(self.syst_suffix),
                            lead_jet_phi)
        self.out.fillBranch("trail_jet_pt{}".format(self.syst_suffix),
                            trail_jet_pt)
        self.out.fillBranch("trail_jet_eta{}".format(self.syst_suffix),
                            trail_jet_eta)
        self.out.fillBranch("trail_jet_phi{}".format(self.syst_suffix),
                            trail_jet_phi)
        self.out.fillBranch("dijet_abs_dEta{}".format(self.syst_suffix),
                            dijet_abs_dEta)
        self.out.fillBranch("dijet_Mjj{}".format(self.syst_suffix), dijet_Mjj)
        self.out.fillBranch("dijet_Zep{}".format(self.syst_suffix), dijet_Zep)
        self.out.fillBranch("dijet_centrality{}".format(self.syst_suffix),
                            dijet_centrality)
        self.out.fillBranch("S_T_hard{}".format(self.syst_suffix), S_T_hard)
        self.out.fillBranch("S_T_jets{}".format(self.syst_suffix), S_T_jets)
        self.out.fillBranch("S_T_all{}".format(self.syst_suffix), S_T_all)

        self.out.fillBranch("x_Z{}".format(self.syst_suffix), x_Z)
        self.out.fillBranch("x_jet20{}".format(self.syst_suffix), x_jet20)
        self.out.fillBranch("x_jet30{}".format(self.syst_suffix), x_jet30)
        self.out.fillBranch("x_MET{}".format(self.syst_suffix), x_MET)
        self.out.fillBranch("H_T{}".format(self.syst_suffix), H_T)
        self.out.fillBranch("HT_F{}".format(self.syst_suffix), HT_F)
        self.out.fillBranch("Jet_pt_Ratio{}".format(self.syst_suffix),
                            Jet_pt_Ratio)
        self.out.fillBranch("R_pt{}".format(self.syst_suffix), R_pt)
        self.out.fillBranch("Jet_etas_multiplied{}".format(self.syst_suffix),
                            Jet_etas_multiplied)
        self.out.fillBranch("dPT_OZ{}".format(self.syst_suffix), dPT_OZ)
        self.out.fillBranch("CJV_Pt{}".format(self.syst_suffix), CJV_Pt)
        self.out.fillBranch("CJV_Pt_Sum{}".format(self.syst_suffix),
                            CJV_Pt_Sum)
        self.out.fillBranch("deltaPhiClosestJetMet{}".format(self.syst_suffix),
                            deltaPhiClosestJetMet)
        self.out.fillBranch(
            "deltaPhiFarthestJetMet{}".format(self.syst_suffix),
            deltaPhiFarthestJetMet)
        self.out.fillBranch("etaThirdJet{}".format(self.syst_suffix),
                            etaThirdJet)

        self.out.fillBranch("Z_pt_bst{}".format(self.syst_suffix),
                            Z_p4_bst.Pt())
        self.out.fillBranch("Z_phi_bst{}".format(self.syst_suffix),
                            Z_p4_bst.Phi())
        self.out.fillBranch("met_pt_bst{}".format(self.syst_suffix),
                            met_p4_bst.Pt())
        self.out.fillBranch("met_phi_bst{}".format(self.syst_suffix),
                            met_p4_bst.Phi())
        self.out.fillBranch("emulatedMET_pt_bst{}".format(self.syst_suffix),
                            emulatedMET_p4_bst.Pt())
        self.out.fillBranch("emulatedMET_phi_bst{}".format(self.syst_suffix),
                            emulatedMET_p4_bst.Phi())
        self.out.fillBranch("delta_phi_ll_bst{}".format(self.syst_suffix),
                            delta_phi_ll_bst)
        self.out.fillBranch("delta_eta_ll_bst{}".format(self.syst_suffix),
                            delta_eta_ll_bst)
        self.out.fillBranch("delta_phi_ZMet_bst{}".format(self.syst_suffix),
                            delta_phi_ZMet_bst)

        return True