def cleanFromLepton(objs, leptonCollection): cleanStuffs = [] dicts = matchObjectCollectionMultiple(objs, leptonCollection, 0.4) for key, value in dicts.iteritems(): #print "key : ", key , " ; value : ", value if (value is not None and len(value) != 0) or (value is not None): continue cleanStuffs.append(key) return cleanStuffs
def genRecoFinder(obj1s, obj2s): dicts = matchObjectCollectionMultiple(obj1s, obj2s, 0.4, lambda x, y: x.pdgId == y.pdgId) genRecoflatten = [] for key, value in dicts.iteritems(): if value is None: continue # None means genparts list is empty. if len(value) == 0: continue # empty list mean unsuccessful deltaR matching from GEN to Reco genRecoflatten.append([key, value[0]]) return genRecoflatten
def recoFinder(obj1s, obj2s): dicts = matchObjectCollectionMultiple(obj1s, obj2s, 0.4, lambda x, y: x.pdgId == y.pdgId) #else: # dicts=matchObjectCollectionMultiple(obj1s,obj2s,0.4,lambda x,y : x.partonFlavour==y.pdgId) #print "dicts = ", dicts recoflatten = [] for key, value in dicts.iteritems(): if value is None: continue # None means genparts list is empty. if len(value) == 0: continue # empty list mean unsuccessful deltaR matching from GEN to Reco #print "key = ", key #print "value[0].pdgId = ", value[0].pdgId recoflatten.append(key) return recoflatten
def matchLeptons(self, event): def plausible(rec, gen): if abs(rec.pdgId) == 11 and abs(gen.pdgId) != 11: return False if abs(rec.pdgId) == 13 and abs(gen.pdgId) != 13: return False dr = deltaR(rec.etc, rec.phi, gen.eta, gen.phi) if dr < 0.3: return True if rec.pt < 10 and abs(rec.pdgId) == 13 and gen.pdgId != rec.pdgId: return False if dr < 0.7: return True if min(rec.pt, gen.pt) / max(rec.pt, gen.pt) < 0.3: return False return True leps = event.selectedLeptons match = matchObjectCollectionMultiple(leps, event.genleps + event.gentauleps, dRmax=1.2, presel=lambda plausible: True) for lep in leps: gen = match[lep] lep.mcMatchId = (gen.sourceId if gen != None else 0) lep.mcMatchTau = (gen in event.gentauleps if gen else -99) lep.mcLep = gen
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" jets = Collection(event, self.jetBranchName) if not self.isData: genJets = Collection(event, self.genJetBranchName) if self.doGroomed: subJets = Collection(event, self.subJetBranchName) if not self.isData: genSubJets = Collection(event, self.genSubJetBranchName) genSubJetMatcher = matchObjectCollectionMultiple(genJets, genSubJets, dRmax=0.8) if not self.isData: self.jetSmearer.setSeed(event) jets_pt_raw = [] jets_pt_nom = [] jets_mass_raw = [] jets_mass_nom = [] jets_corr_JEC = [] jets_corr_JER = [] jets_corr_JMS = [] jets_corr_JMR = [] jets_pt_jerUp = {} jets_pt_jerDown = {} jets_pt_jesUp = {} jets_pt_jesDown = {} jets_mass_jerUp = {} jets_mass_jerDown = {} jets_mass_jmrUp = [] jets_mass_jmrDown = [] jets_mass_jesUp = {} jets_mass_jesDown = {} jets_mass_jmsUp = [] jets_mass_jmsDown = [] for jerID in self.splitJERIDs: jets_pt_jerUp[jerID] = [] jets_pt_jerDown[jerID] = [] jets_mass_jerUp[jerID] = [] jets_mass_jerDown[jerID] = [] for jesUncertainty in self.jesUncertainties: jets_pt_jesUp[jesUncertainty] = [] jets_pt_jesDown[jesUncertainty] = [] jets_mass_jesUp[jesUncertainty] = [] jets_mass_jesDown[jesUncertainty] = [] if self.doGroomed: jets_msdcorr_raw = [] jets_msdcorr_nom = [] jets_msdcorr_corr_JMR = [] jets_msdcorr_corr_JMS = [] jets_msdcorr_corr_PUPPI = [] jets_msdcorr_jerUp = {} jets_msdcorr_jerDown = {} jets_msdcorr_jmrUp = [] jets_msdcorr_jmrDown = [] jets_msdcorr_jesUp = {} jets_msdcorr_jesDown = {} jets_msdcorr_jmsUp = [] jets_msdcorr_jmsDown = [] jets_msdcorr_tau21DDT_nom = [] jets_msdcorr_tau21DDT_jerUp = {} jets_msdcorr_tau21DDT_jerDown = {} jets_msdcorr_tau21DDT_jmrUp = [] jets_msdcorr_tau21DDT_jmrDown = [] jets_msdcorr_tau21DDT_jmsUp = [] jets_msdcorr_tau21DDT_jmsDown = [] for jerID in self.splitJERIDs: jets_msdcorr_jerUp[jerID] = [] jets_msdcorr_jerDown[jerID] = [] jets_msdcorr_tau21DDT_jerUp[jerID] = [] jets_msdcorr_tau21DDT_jerDown[jerID] = [] for jesUncertainty in self.jesUncertainties: jets_msdcorr_jesUp[jesUncertainty] = [] jets_msdcorr_jesDown[jesUncertainty] = [] rho = getattr(event, self.rhoBranchName) # match reconstructed jets to generator level ones # (needed to evaluate JER scale factors and uncertainties) if not self.isData: pairs = matchObjectCollection(jets, genJets) for jet in jets: # jet pt and mass corrections jet_pt = jet.pt jet_mass = jet.mass if hasattr(jet, "rawFactor"): jet_rawpt = jet_pt * (1 - jet.rawFactor) jet_rawmass = jet_mass * (1 - jet.rawFactor) else: jet_rawpt = -1.0 * jet_pt # If factor not present factor will be saved as -1 jet_rawmass = -1.0 * jet_mass # If factor not present factor will be saved as -1 (jet_pt, jet_mass) = self.jetReCalibrator.correct(jet, rho) jet.pt = jet_pt jet.mass = jet_mass jets_pt_raw.append(jet_rawpt) jets_mass_raw.append(jet_rawmass) jets_corr_JEC.append(jet_pt / jet_rawpt) if not self.isData: genJet = pairs[jet] # evaluate JER scale factors and uncertainties # (cf. https://twiki.cern.ch/twiki/bin/view/CMS/JetResolution and https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookJetEnergyResolution ) if not self.isData: (jet_pt_jerNomVal, jet_pt_jerUpVal, jet_pt_jerDownVal) = self.jetSmearer.getSmearValsPt( jet, genJet, rho) else: # set values to 1 for data so that jet_pt_nom is not smeared (jet_pt_jerNomVal, jet_pt_jerUpVal, jet_pt_jerDownVal) = (1, 1, 1) jets_corr_JER.append(jet_pt_jerNomVal) jet_pt_nom = jet_pt_jerNomVal * jet_pt if self.applySmearing else jet_pt if jet_pt_nom < 0.0: jet_pt_nom *= -1.0 jets_pt_nom.append(jet_pt_nom) # Evaluate JMS and JMR scale factors and uncertainties jmsNomVal, jmsDownVal, jmsUpVal = self.jmsVals if not self.isData else ( 1, 1, 1) if not self.isData: (jet_mass_jmrNomVal, jet_mass_jmrUpVal, jet_mass_jmrDownVal) = self.jetSmearer.getSmearValsM( jet, genJet) else: # set values to 1 for data so that jet_mass_nom is not smeared (jet_mass_jmrNomVal, jet_mass_jmrUpVal, jet_mass_jmrDownVal) = (1, 1, 1) jets_corr_JMS.append(jmsNomVal) jets_corr_JMR.append(jet_mass_jmrNomVal) jet_mass_nom = jet_pt_jerNomVal * jet_mass_jmrNomVal * \ jmsNomVal * jet_mass if self.applySmearing else jet_mass if jet_mass_nom < 0.0: jet_mass_nom *= -1.0 jets_mass_nom.append(jet_mass_nom) if not self.isData: jet_pt_jerUp = { jerID: jet_pt_nom for jerID in self.splitJERIDs } jet_pt_jerDown = { jerID: jet_pt_nom for jerID in self.splitJERIDs } jet_mass_jerUp = { jerID: jet_mass_nom for jerID in self.splitJERIDs } jet_mass_jerDown = { jerID: jet_mass_nom for jerID in self.splitJERIDs } thisJERID = self.getJERsplitID(jet_pt_nom, jet.eta) jet_pt_jerUp[thisJERID] = jet_pt_jerUpVal * jet_pt jet_pt_jerDown[thisJERID] = jet_pt_jerDownVal * jet_pt jet_mass_jerUp[thisJERID] = jet_pt_jerUpVal * \ jet_mass_jmrNomVal * jmsNomVal * jet_mass jet_mass_jerDown[thisJERID] = jet_pt_jerDownVal * \ jet_mass_jmrNomVal * jmsNomVal * jet_mass for jerID in self.splitJERIDs: jets_pt_jerUp[jerID].append(jet_pt_jerUp[jerID]) jets_pt_jerDown[jerID].append(jet_pt_jerDown[jerID]) jets_mass_jerUp[jerID].append(jet_mass_jerUp[jerID]) jets_mass_jerDown[jerID].append(jet_mass_jerDown[jerID]) jets_mass_jmrUp.append(jet_pt_jerNomVal * jet_mass_jmrUpVal * jmsNomVal * jet_mass) jets_mass_jmrDown.append(jet_pt_jerNomVal * jet_mass_jmrDownVal * jmsNomVal * jet_mass) jets_mass_jmsUp.append(jet_pt_jerNomVal * jet_mass_jmrNomVal * jmsUpVal * jet_mass) jets_mass_jmsDown.append(jet_pt_jerNomVal * jet_mass_jmrNomVal * jmsDownVal * jet_mass) if self.doGroomed: if not self.isData: genGroomedSubJets = genSubJetMatcher[ genJet] if genJet is not None else None genGroomedJet = genGroomedSubJets[0].p4( ) + genGroomedSubJets[1].p4( ) if genGroomedSubJets is not None and len( genGroomedSubJets) >= 2 else None else: genGroomedSubJets = None genGroomedJet = None if jet.subJetIdx1 >= 0 and jet.subJetIdx2 >= 0: groomedP4 = subJets[jet.subJetIdx1].p4() + subJets[ jet.subJetIdx2].p4() # check subjet jecs else: groomedP4 = None jet_msdcorr_raw = groomedP4.M( ) if groomedP4 is not None else 0.0 # raw value always stored withoud mass correction jets_msdcorr_raw.append(jet_msdcorr_raw) # LC: Apply PUPPI SD mass correction https://github.com/cms-jet/PuppiSoftdropMassCorr/ puppisd_genCorr = self.puppisd_corrGEN.Eval(jet.pt) if abs(jet.eta) <= 1.3: puppisd_recoCorr = self.puppisd_corrRECO_cen.Eval(jet.pt) else: puppisd_recoCorr = self.puppisd_corrRECO_for.Eval(jet.pt) puppisd_total = puppisd_genCorr * puppisd_recoCorr jets_msdcorr_corr_PUPPI.append(puppisd_total) if groomedP4 is not None: groomedP4.SetPtEtaPhiM(groomedP4.Perp(), groomedP4.Eta(), groomedP4.Phi(), groomedP4.M() * puppisd_total) # now apply the mass correction to the raw value jet_msdcorr_raw = groomedP4.M( ) if groomedP4 is not None else 0.0 if jet_msdcorr_raw < 0.0: jet_msdcorr_raw *= -1.0 # Evaluate JMS and JMR scale factors and uncertainties if not self.isData: (jet_msdcorr_jmrNomVal, jet_msdcorr_jmrUpVal, jet_msdcorr_jmrDownVal) = \ (self.jetSmearer.getSmearValsM(groomedP4, genGroomedJet) if groomedP4 is not None and genGroomedJet is not None else (0., 0., 0.)) else: (jet_msdcorr_jmrNomVal, jet_msdcorr_jmrUpVal, jet_msdcorr_jmrDownVal) = (1, 1, 1) jets_msdcorr_corr_JMS.append(jmsNomVal) jets_msdcorr_corr_JMR.append(jet_msdcorr_jmrNomVal) jet_msdcorr_nom = jet_pt_jerNomVal * \ jet_msdcorr_jmrNomVal * jmsNomVal * jet_msdcorr_raw # store the nominal mass value jets_msdcorr_nom.append(jet_msdcorr_nom) if not self.isData: jet_msdcorr_jerUp = { jerID: jet_msdcorr_nom for jerID in self.splitJERIDs } jet_msdcorr_jerDown = { jerID: jet_msdcorr_nom for jerID in self.splitJERIDs } thisJERID = self.getJERsplitID(jet_pt_nom, jet.eta) jet_msdcorr_jerUp[thisJERID] = jet_pt_jerUpVal * \ jet_msdcorr_jmrNomVal * jmsNomVal * jet_msdcorr_raw jet_msdcorr_jerDown[thisJERID] = jet_pt_jerDownVal * \ jet_msdcorr_jmrNomVal * jmsNomVal * jet_msdcorr_raw for jerID in self.splitJERIDs: jets_msdcorr_jerUp[jerID].append( jet_msdcorr_jerUp[jerID]) jets_msdcorr_jerDown[jerID].append( jet_msdcorr_jerDown[jerID]) jets_msdcorr_jmrUp.append( jet_pt_jerNomVal * jet_msdcorr_jmrUpVal * jmsNomVal * jet_msdcorr_raw) jets_msdcorr_jmrDown.append( jet_pt_jerNomVal * jet_msdcorr_jmrDownVal * jmsNomVal * jet_msdcorr_raw) jets_msdcorr_jmsUp.append( jet_pt_jerNomVal * jet_msdcorr_jmrNomVal * jmsUpVal * jet_msdcorr_raw) jets_msdcorr_jmsDown.append( jet_pt_jerNomVal * jet_msdcorr_jmrNomVal * jmsDownVal * jet_msdcorr_raw) # Also evaluated JMS&JMR SD corr in tau21DDT region: https://twiki.cern.ch/twiki/bin/viewauth/CMS/JetWtagging#tau21DDT_0_43 if self.era in ["2016"]: jmstau21DDTNomVal = 1.014 jmstau21DDTDownVal = 1.007 jmstau21DDTUpVal = 1.021 self.jetSmearer.jmr_vals = [1.086, 1.176, 0.996] elif self.era in ["2017"]: jmstau21DDTNomVal = 0.983 jmstau21DDTDownVal = 0.976 jmstau21DDTUpVal = 0.99 self.jetSmearer.jmr_vals = [1.080, 1.161, 0.999] elif self.era in ["2018"]: jmstau21DDTNomVal = 1.000 # tau21DDT < 0.43 WP jmstau21DDTDownVal = 0.990 jmstau21DDTUpVal = 1.010 self.jetSmearer.jmr_vals = [1.124, 1.208, 1.040] ( jet_msdcorr_tau21DDT_jmrNomVal, jet_msdcorr_tau21DDT_jmrUpVal, jet_msdcorr_tau21DDT_jmrDownVal ) = self.jetSmearer.getSmearValsM( groomedP4, genGroomedJet ) if groomedP4 is not None and genGroomedJet is not None else ( 0., 0., 0.) jet_msdcorr_tau21DDT_nom = jet_pt_jerNomVal * \ jet_msdcorr_tau21DDT_jmrNomVal * jmstau21DDTNomVal * jet_msdcorr_raw jets_msdcorr_tau21DDT_nom.append(jet_msdcorr_tau21DDT_nom) jet_msdcorr_tau21DDT_jerUp = { jerID: jet_msdcorr_tau21DDT_nom for jerID in self.splitJERIDs } jet_msdcorr_tau21DDT_jerDown = { jerID: jet_msdcorr_tau21DDT_nom for jerID in self.splitJERIDs } jet_msdcorr_tau21DDT_jerUp[thisJERID] = jet_pt_jerUpVal * \ jet_msdcorr_tau21DDT_jmrNomVal * jmstau21DDTNomVal * jet_msdcorr_raw jet_msdcorr_tau21DDT_jerDown[thisJERID] = jet_pt_jerDownVal * \ jet_msdcorr_tau21DDT_jmrNomVal * jmstau21DDTNomVal * jet_msdcorr_raw for jerID in self.splitJERIDs: jets_msdcorr_tau21DDT_jerUp[jerID].append( jet_msdcorr_tau21DDT_jerUp[jerID]) jets_msdcorr_tau21DDT_jerDown[jerID].append( jet_msdcorr_tau21DDT_jerDown[jerID]) jets_msdcorr_tau21DDT_jmrUp.append( jet_pt_jerNomVal * jet_msdcorr_tau21DDT_jmrUpVal * jmstau21DDTNomVal * jet_msdcorr_raw) jets_msdcorr_tau21DDT_jmrDown.append( jet_pt_jerNomVal * jet_msdcorr_tau21DDT_jmrDownVal * jmstau21DDTNomVal * jet_msdcorr_raw) jets_msdcorr_tau21DDT_jmsUp.append( jet_pt_jerNomVal * jet_msdcorr_tau21DDT_jmrNomVal * jmstau21DDTUpVal * jet_msdcorr_raw) jets_msdcorr_tau21DDT_jmsDown.append( jet_pt_jerNomVal * jet_msdcorr_tau21DDT_jmrNomVal * jmstau21DDTDownVal * jet_msdcorr_raw) # Restore original jmr_vals in jetSmearer self.jetSmearer.jmr_vals = self.jmrVals if not self.isData: # evaluate JES uncertainties jet_pt_jesUp = {} jet_pt_jesDown = {} jet_mass_jesUp = {} jet_mass_jesDown = {} jet_msdcorr_jesUp = {} jet_msdcorr_jesDown = {} for jesUncertainty in self.jesUncertainties: # (cf. https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookJetEnergyCorrections#JetCorUncertainties) # cf. https://hypernews.cern.ch/HyperNews/CMS/get/JetMET/2000.html if jesUncertainty == "HEMIssue": delta = 1. if jet_pt_nom > 15 and jet.jetId & 2 and jet.phi > -1.57 and jet.phi < -0.87: if jet.eta > -2.5 and jet.eta < -1.3: delta = 0.8 elif jet.eta <= -2.5 and jet.eta > -3: delta = 0.65 jet_pt_jesUp[jesUncertainty] = jet_pt_nom jet_pt_jesDown[jesUncertainty] = delta * jet_pt_nom jet_mass_jesUp[jesUncertainty] = jet_mass_nom jet_mass_jesDown[jesUncertainty] = delta * jet_mass_nom if self.doGroomed: jet_msdcorr_jesUp[jesUncertainty] = jet_msdcorr_nom jet_msdcorr_jesDown[jesUncertainty] = delta * \ jet_msdcorr_nom else: self.jesUncertainty[jesUncertainty].setJetPt( jet_pt_nom) self.jesUncertainty[jesUncertainty].setJetEta(jet.eta) delta = self.jesUncertainty[ jesUncertainty].getUncertainty(True) jet_pt_jesUp[jesUncertainty] = jet_pt_nom * \ (1. + delta) jet_pt_jesDown[jesUncertainty] = jet_pt_nom * \ (1. - delta) jet_mass_jesUp[jesUncertainty] = jet_mass_nom * \ (1. + delta) jet_mass_jesDown[jesUncertainty] = jet_mass_nom * \ (1. - delta) if self.doGroomed: jet_msdcorr_jesUp[jesUncertainty] = jet_msdcorr_nom * \ (1. + delta) jet_msdcorr_jesDown[ jesUncertainty] = jet_msdcorr_nom * (1. - delta) jets_pt_jesUp[jesUncertainty].append( jet_pt_jesUp[jesUncertainty]) jets_pt_jesDown[jesUncertainty].append( jet_pt_jesDown[jesUncertainty]) jets_mass_jesUp[jesUncertainty].append( jet_mass_jesUp[jesUncertainty]) jets_mass_jesDown[jesUncertainty].append( jet_mass_jesDown[jesUncertainty]) if self.doGroomed: jets_msdcorr_jesUp[jesUncertainty].append( jet_msdcorr_jesUp[jesUncertainty]) jets_msdcorr_jesDown[jesUncertainty].append( jet_msdcorr_jesDown[jesUncertainty]) self.out.fillBranch("%s_pt_raw" % self.jetBranchName, jets_pt_raw) self.out.fillBranch("%s_pt_nom" % self.jetBranchName, jets_pt_nom) self.out.fillBranch("%s_corr_JEC" % self.jetBranchName, jets_corr_JEC) self.out.fillBranch("%s_mass_raw" % self.jetBranchName, jets_mass_raw) self.out.fillBranch("%s_mass_nom" % self.jetBranchName, jets_mass_nom) if not self.isData: self.out.fillBranch("%s_corr_JER" % self.jetBranchName, jets_corr_JER) self.out.fillBranch("%s_corr_JMS" % self.jetBranchName, jets_corr_JMS) self.out.fillBranch("%s_corr_JMR" % self.jetBranchName, jets_corr_JMR) for jerID in self.splitJERIDs: self.out.fillBranch( "%s_pt_jer%sUp" % (self.jetBranchName, jerID), jets_pt_jerUp[jerID]) self.out.fillBranch( "%s_pt_jer%sDown" % (self.jetBranchName, jerID), jets_pt_jerDown[jerID]) self.out.fillBranch( "%s_mass_jer%sUp" % (self.jetBranchName, jerID), jets_mass_jerUp[jerID]) self.out.fillBranch( "%s_mass_jer%sDown" % (self.jetBranchName, jerID), jets_mass_jerDown[jerID]) self.out.fillBranch("%s_mass_jmrUp" % self.jetBranchName, jets_mass_jmrUp) self.out.fillBranch("%s_mass_jmrDown" % self.jetBranchName, jets_mass_jmrDown) self.out.fillBranch("%s_mass_jmsUp" % self.jetBranchName, jets_mass_jmsUp) self.out.fillBranch("%s_mass_jmsDown" % self.jetBranchName, jets_mass_jmsDown) if self.doGroomed: self.out.fillBranch("%s_msoftdrop_raw" % self.jetBranchName, jets_msdcorr_raw) self.out.fillBranch("%s_msoftdrop_nom" % self.jetBranchName, jets_msdcorr_nom) self.out.fillBranch("%s_msoftdrop_corr_JMS" % self.jetBranchName, jets_msdcorr_corr_JMS) self.out.fillBranch("%s_msoftdrop_corr_JMR" % self.jetBranchName, jets_msdcorr_corr_JMR) self.out.fillBranch("%s_msoftdrop_corr_PUPPI" % self.jetBranchName, jets_msdcorr_corr_PUPPI) if not self.isData: self.out.fillBranch( "%s_msoftdrop_tau21DDT_nom" % self.jetBranchName, jets_msdcorr_tau21DDT_nom) for jerID in self.splitJERIDs: self.out.fillBranch( "%s_msoftdrop_jer%sUp" % (self.jetBranchName, jerID), jets_msdcorr_jerUp[jerID]) self.out.fillBranch( "%s_msoftdrop_jer%sDown" % (self.jetBranchName, jerID), jets_msdcorr_jerDown[jerID]) self.out.fillBranch( "%s_msoftdrop_tau21DDT_jer%sUp" % (self.jetBranchName, jerID), jets_msdcorr_tau21DDT_jerUp[jerID]) self.out.fillBranch( "%s_msoftdrop_tau21DDT_jer%sDown" % (self.jetBranchName, jerID), jets_msdcorr_tau21DDT_jerDown[jerID]) self.out.fillBranch("%s_msoftdrop_jmrUp" % self.jetBranchName, jets_msdcorr_jmrUp) self.out.fillBranch( "%s_msoftdrop_jmrDown" % self.jetBranchName, jets_msdcorr_jmrDown) self.out.fillBranch("%s_msoftdrop_jmsUp" % self.jetBranchName, jets_msdcorr_jmsUp) self.out.fillBranch( "%s_msoftdrop_jmsDown" % self.jetBranchName, jets_msdcorr_jmsDown) self.out.fillBranch( "%s_msoftdrop_tau21DDT_jmrUp" % self.jetBranchName, jets_msdcorr_tau21DDT_jmrUp) self.out.fillBranch( "%s_msoftdrop_tau21DDT_jmrDown" % self.jetBranchName, jets_msdcorr_tau21DDT_jmrDown) self.out.fillBranch( "%s_msoftdrop_tau21DDT_jmsUp" % self.jetBranchName, jets_msdcorr_tau21DDT_jmsUp) self.out.fillBranch( "%s_msoftdrop_tau21DDT_jmsDown" % self.jetBranchName, jets_msdcorr_tau21DDT_jmsDown) if not self.isData: for jesUncertainty in self.jesUncertainties: self.out.fillBranch( "%s_pt_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_pt_jesUp[jesUncertainty]) self.out.fillBranch( "%s_pt_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_pt_jesDown[jesUncertainty]) self.out.fillBranch( "%s_mass_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_mass_jesUp[jesUncertainty]) self.out.fillBranch( "%s_mass_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_mass_jesDown[jesUncertainty]) if self.doGroomed: self.out.fillBranch( "%s_msoftdrop_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_msdcorr_jesUp[jesUncertainty]) self.out.fillBranch( "%s_msoftdrop_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_msdcorr_jesDown[jesUncertainty]) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" jets = Collection(event, self.jetBranchName) genJets = Collection(event, self.genJetBranchName) if self.doGroomed: subJets = Collection(event, self.subJetBranchName) genSubJets = Collection(event, self.genSubJetBranchName) genSubJetMatcher = matchObjectCollectionMultiple(genJets, genSubJets, dRmax=0.8) jets_pt_nom = [] jets_pt_jerUp = [] jets_pt_jerDown = [] jets_pt_jesUp = {} jets_pt_jesDown = {} jets_mass_nom = [] jets_mass_jerUp = [] jets_mass_jerDown = [] jets_mass_jmrUp = [] jets_mass_jmrDown = [] jets_mass_jesUp = {} jets_mass_jesDown = {} jets_mass_jmsUp = [] jets_mass_jmsDown = [] for jesUncertainty in self.jesUncertainties: jets_pt_jesUp[jesUncertainty] = [] jets_pt_jesDown[jesUncertainty] = [] jets_mass_jesUp[jesUncertainty] = [] jets_mass_jesDown[jesUncertainty] = [] if self.corrMET: met = Object(event, self.metBranchName) (met_px, met_py) = (met.pt * math.cos(met.phi), met.pt * math.sin(met.phi)) (met_px_nom, met_py_nom) = (met_px, met_py) (met_px_jerUp, met_py_jerUp) = (met_px, met_py) (met_px_jerDown, met_py_jerDown) = (met_px, met_py) (met_px_jesUp, met_py_jesUp) = ({}, {}) (met_px_jesDown, met_py_jesDown) = ({}, {}) for jesUncertainty in self.jesUncertainties: met_px_jesUp[jesUncertainty] = met_px met_py_jesUp[jesUncertainty] = met_py met_px_jesDown[jesUncertainty] = met_px met_py_jesDown[jesUncertainty] = met_py if self.doGroomed: jets_msdcorr_nom = [] jets_msdcorr_jerUp = [] jets_msdcorr_jerDown = [] jets_msdcorr_jmrUp = [] jets_msdcorr_jmrDown = [] jets_msdcorr_jesUp = {} jets_msdcorr_jesDown = {} jets_msdcorr_jmsUp = [] jets_msdcorr_jmsDown = [] for jesUncertainty in self.jesUncertainties: jets_msdcorr_jesUp[jesUncertainty] = [] jets_msdcorr_jesDown[jesUncertainty] = [] rho = getattr(event, self.rhoBranchName) # match reconstructed jets to generator level ones # (needed to evaluate JER scale factors and uncertainties) pairs = matchObjectCollection(jets, genJets) for jet in jets: genJet = pairs[jet] if self.doGroomed: genGroomedSubJets = genSubJetMatcher[ genJet] if genJet != None else None genGroomedJet = genGroomedSubJets[0].p4() + genGroomedSubJets[ 1].p4() if genGroomedSubJets != None and len( genGroomedSubJets) >= 2 else None if jet.subJetIdx1 >= 0 and jet.subJetIdx2 >= 0: groomedP4 = subJets[jet.subJetIdx1].p4() + subJets[ jet.subJetIdx2].p4() else: groomedP4 = None # evaluate JER scale factors and uncertainties # (cf. https://twiki.cern.ch/twiki/bin/view/CMS/JetResolution and https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookJetEnergyResolution ) (jet_pt_jerNomVal, jet_pt_jerUpVal, jet_pt_jerDownVal) = self.jetSmearer.getSmearValsPt( jet, genJet, rho) jet_pt = jet.pt if self.redoJEC: jet_pt = self.jetReCalibrator.correct(jet, rho) jet_pt_nom = jet_pt_jerNomVal * jet_pt if jet_pt_nom < 0.0: jet_pt_nom *= -1.0 jet_pt_jerUp = jet_pt_jerUpVal * jet_pt jet_pt_jerDown = jet_pt_jerDownVal * jet_pt jets_pt_nom.append(jet_pt_nom) jets_pt_jerUp.append(jet_pt_jerUpVal * jet_pt) jets_pt_jerDown.append(jet_pt_jerDownVal * jet_pt) # evaluate JES uncertainties jet_pt_jesUp = {} jet_pt_jesDown = {} jet_mass_jesUp = {} jet_mass_jesDown = {} jet_mass_jmsUp = [] jet_mass_jmsDown = [] # Evaluate JMS and JMR scale factors and uncertainties jmsNomVal = self.jmsVals[0] jmsDownVal = self.jmsVals[1] jmsUpVal = self.jmsVals[2] (jet_mass_jmrNomVal, jet_mass_jmrUpVal, jet_mass_jmrDownVal) = self.jetSmearer.getSmearValsM(jet, genJet) jet_mass_nom = jet_pt_jerNomVal * jet_mass_jmrNomVal * jmsNomVal * jet.mass if jet_mass_nom < 0.0: jet_mass_nom *= -1.0 jets_mass_nom.append(jet_mass_nom) jets_mass_jerUp.append(jet_pt_jerUpVal * jet_mass_jmrNomVal * jmsNomVal * jet.mass) jets_mass_jerDown.append(jet_pt_jerDownVal * jet_mass_jmrNomVal * jmsNomVal * jet.mass) jets_mass_jmrUp.append(jet_pt_jerNomVal * jet_mass_jmrUpVal * jmsNomVal * jet.mass) jets_mass_jmrDown.append(jet_pt_jerNomVal * jet_mass_jmrDownVal * jmsNomVal * jet.mass) jets_mass_jmsUp.append(jet_pt_jerNomVal * jet_mass_jmrNomVal * jmsUpVal * jet.mass) jets_mass_jmsDown.append(jet_pt_jerNomVal * jet_mass_jmrNomVal * jmsDownVal * jet.mass) if self.doGroomed: # to evaluate JES uncertainties jet_msdcorr_jmsUp = [] jet_msdcorr_jmsDown = [] jet_msdcorr_jesUp = {} jet_msdcorr_jesDown = {} (jet_msdcorr_jmrNomVal, jet_msdcorr_jmrUpVal, jet_msdcorr_jmrDownVal) = self.jetSmearer.getSmearValsM( groomedP4, genGroomedJet ) if groomedP4 != None and genGroomedJet != None else (0., 0., 0.) jet_msdcorr_raw = groomedP4.M() if groomedP4 != None else 0.0 if jet_msdcorr_raw < 0.0: jet_msdcorr_raw *= -1.0 jet_msdcorr_nom = jet_pt_jerNomVal * jet_msdcorr_jmrNomVal * jet_msdcorr_raw jets_msdcorr_nom.append(jet_msdcorr_nom) jets_msdcorr_jerUp.append(jet_pt_jerUpVal * jet_msdcorr_jmrNomVal * jmsNomVal * jet_msdcorr_raw) jets_msdcorr_jerDown.append(jet_pt_jerDownVal * jet_msdcorr_jmrNomVal * jmsNomVal * jet_msdcorr_raw) jets_msdcorr_jmrUp.append(jet_pt_jerNomVal * jet_msdcorr_jmrUpVal * jmsNomVal * jet_msdcorr_raw) jets_msdcorr_jmrDown.append( jet_pt_jerNomVal * jet_msdcorr_jmrDownVal * jmsNomVal * jet_msdcorr_raw) jets_msdcorr_jmsUp.append(jet_pt_jerNomVal * jet_msdcorr_jmrNomVal * jmsUpVal * jet_msdcorr_raw) jets_msdcorr_jmsDown.append( jet_pt_jerNomVal * jet_msdcorr_jmrNomVal * jmsDownVal * jet_msdcorr_raw) for jesUncertainty in self.jesUncertainties: # (cf. https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookJetEnergyCorrections#JetCorUncertainties ) self.jesUncertainty[jesUncertainty].setJetPt(jet_pt_nom) self.jesUncertainty[jesUncertainty].setJetEta(jet.eta) delta = self.jesUncertainty[jesUncertainty].getUncertainty( True) jet_pt_jesUp[jesUncertainty] = jet_pt_nom * (1. + delta) jet_pt_jesDown[jesUncertainty] = jet_pt_nom * (1. - delta) jets_pt_jesUp[jesUncertainty].append( jet_pt_jesUp[jesUncertainty]) jets_pt_jesDown[jesUncertainty].append( jet_pt_jesDown[jesUncertainty]) jet_mass_jesUp[jesUncertainty] = jet_mass_nom * (1. + delta) jet_mass_jesDown[jesUncertainty] = jet_mass_nom * (1. - delta) jets_mass_jesUp[jesUncertainty].append( jet_mass_jesUp[jesUncertainty]) jets_mass_jesDown[jesUncertainty].append( jet_mass_jesDown[jesUncertainty]) if self.doGroomed: jet_msdcorr_jesUp[jesUncertainty] = jet_msdcorr_nom * ( 1. + delta) jet_msdcorr_jesDown[jesUncertainty] = jet_msdcorr_nom * ( 1. - delta) jets_msdcorr_jesUp[jesUncertainty].append( jet_msdcorr_jesUp[jesUncertainty]) jets_msdcorr_jesDown[jesUncertainty].append( jet_msdcorr_jesDown[jesUncertainty]) # progate JER and JES corrections and uncertainties to MET if self.corrMET and jet_pt_nom > self.unclEnThreshold: jet_cosPhi = math.cos(jet.phi) jet_sinPhi = math.sin(jet.phi) met_px_nom = met_px_nom - (jet_pt_nom - jet_pt) * jet_cosPhi met_py_nom = met_py_nom - (jet_pt_nom - jet_pt) * jet_sinPhi met_px_jerUp = met_px_jerUp - (jet_pt_jerUp - jet_pt_nom) * jet_cosPhi met_py_jerUp = met_py_jerUp - (jet_pt_jerUp - jet_pt_nom) * jet_sinPhi met_px_jerDown = met_px_jerDown - (jet_pt_jerDown - jet_pt_nom) * jet_cosPhi met_py_jerDown = met_py_jerDown - (jet_pt_jerDown - jet_pt_nom) * jet_sinPhi for jesUncertainty in self.jesUncertainties: met_px_jesUp[jesUncertainty] = met_px_jesUp[ jesUncertainty] - (jet_pt_jesUp[jesUncertainty] - jet_pt_nom) * jet_cosPhi met_py_jesUp[jesUncertainty] = met_py_jesUp[ jesUncertainty] - (jet_pt_jesUp[jesUncertainty] - jet_pt_nom) * jet_sinPhi met_px_jesDown[jesUncertainty] = met_px_jesDown[ jesUncertainty] - (jet_pt_jesDown[jesUncertainty] - jet_pt_nom) * jet_cosPhi met_py_jesDown[jesUncertainty] = met_py_jesDown[ jesUncertainty] - (jet_pt_jesDown[jesUncertainty] - jet_pt_nom) * jet_sinPhi # propagate "unclustered energy" uncertainty to MET if self.corrMET: (met_px_unclEnUp, met_py_unclEnUp) = (met_px, met_py) (met_px_unclEnDown, met_py_unclEnDown) = (met_px, met_py) met_deltaPx_unclEn = getattr( event, self.metBranchName + "_MetUnclustEnUpDeltaX") met_deltaPy_unclEn = getattr( event, self.metBranchName + "_MetUnclustEnUpDeltaY") met_px_unclEnUp = met_px_unclEnUp + met_deltaPx_unclEn met_py_unclEnUp = met_py_unclEnUp + met_deltaPy_unclEn met_px_unclEnDown = met_px_unclEnDown - met_deltaPx_unclEn met_py_unclEnDown = met_py_unclEnDown - met_deltaPy_unclEn # propagate effect of jet energy smearing to MET met_px_jerUp = met_px_jerUp + (met_px_nom - met_px) met_py_jerUp = met_py_jerUp + (met_py_nom - met_py) met_px_jerDown = met_px_jerDown + (met_px_nom - met_px) met_py_jerDown = met_py_jerDown + (met_py_nom - met_py) for jesUncertainty in self.jesUncertainties: met_px_jesUp[jesUncertainty] = met_px_jesUp[jesUncertainty] + ( met_px_nom - met_px) met_py_jesUp[jesUncertainty] = met_py_jesUp[jesUncertainty] + ( met_py_nom - met_py) met_px_jesDown[jesUncertainty] = met_px_jesDown[ jesUncertainty] + (met_px_nom - met_px) met_py_jesDown[jesUncertainty] = met_py_jesDown[ jesUncertainty] + (met_py_nom - met_py) met_px_unclEnUp = met_px_unclEnUp + (met_px_nom - met_px) met_py_unclEnUp = met_py_unclEnUp + (met_py_nom - met_py) met_px_unclEnDown = met_px_unclEnDown + (met_px_nom - met_px) met_py_unclEnDown = met_py_unclEnDown + (met_py_nom - met_py) self.out.fillBranch("%s_pt_nom" % self.jetBranchName, jets_pt_nom) self.out.fillBranch("%s_pt_jerUp" % self.jetBranchName, jets_pt_jerUp) self.out.fillBranch("%s_pt_jerDown" % self.jetBranchName, jets_pt_jerDown) self.out.fillBranch("%s_mass_nom" % self.jetBranchName, jets_mass_nom) self.out.fillBranch("%s_mass_jerUp" % self.jetBranchName, jets_mass_jerUp) self.out.fillBranch("%s_mass_jerDown" % self.jetBranchName, jets_mass_jerDown) self.out.fillBranch("%s_mass_jmrUp" % self.jetBranchName, jets_mass_jmrUp) self.out.fillBranch("%s_mass_jmrDown" % self.jetBranchName, jets_mass_jmrDown) self.out.fillBranch("%s_mass_jmsUp" % self.jetBranchName, jets_mass_jmsUp) self.out.fillBranch("%s_mass_jmsDown" % self.jetBranchName, jets_mass_jmsDown) if self.doGroomed: self.out.fillBranch("%s_msoftdrop_nom" % self.jetBranchName, jets_msdcorr_nom) self.out.fillBranch("%s_msoftdrop_jerUp" % self.jetBranchName, jets_msdcorr_jerUp) self.out.fillBranch("%s_msoftdrop_jerDown" % self.jetBranchName, jets_msdcorr_jerDown) self.out.fillBranch("%s_msoftdrop_jmrUp" % self.jetBranchName, jets_msdcorr_jmrUp) self.out.fillBranch("%s_msoftdrop_jmrDown" % self.jetBranchName, jets_msdcorr_jmrDown) self.out.fillBranch("%s_msoftdrop_jmsUp" % self.jetBranchName, jets_msdcorr_jmsUp) self.out.fillBranch("%s_msoftdrop_jmsDown" % self.jetBranchName, jets_msdcorr_jmsDown) if self.corrMET: self.out.fillBranch("%s_pt_nom" % self.metBranchName, math.sqrt(met_px_nom**2 + met_py_nom**2)) self.out.fillBranch("%s_phi_nom" % self.metBranchName, math.atan2(met_py_nom, met_px_nom)) self.out.fillBranch("%s_pt_jerUp" % self.metBranchName, math.sqrt(met_px_jerUp**2 + met_py_jerUp**2)) self.out.fillBranch("%s_phi_jerUp" % self.metBranchName, math.atan2(met_py_jerUp, met_px_jerUp)) self.out.fillBranch( "%s_pt_jerDown" % self.metBranchName, math.sqrt(met_px_jerDown**2 + met_py_jerDown**2)) self.out.fillBranch("%s_phi_jerDown" % self.metBranchName, math.atan2(met_py_jerDown, met_px_jerDown)) for jesUncertainty in self.jesUncertainties: self.out.fillBranch( "%s_pt_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_pt_jesUp[jesUncertainty]) self.out.fillBranch( "%s_pt_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_pt_jesDown[jesUncertainty]) self.out.fillBranch( "%s_mass_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_mass_jesUp[jesUncertainty]) self.out.fillBranch( "%s_mass_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_mass_jesDown[jesUncertainty]) if self.doGroomed: self.out.fillBranch( "%s_msoftdrop_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_msdcorr_jesUp[jesUncertainty]) self.out.fillBranch( "%s_msoftdrop_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_msdcorr_jesDown[jesUncertainty]) if self.corrMET: self.out.fillBranch( "%s_pt_jes%sUp" % (self.metBranchName, jesUncertainty), math.sqrt(met_px_jesUp[jesUncertainty]**2 + met_py_jesUp[jesUncertainty]**2)) self.out.fillBranch( "%s_phi_jes%sUp" % (self.metBranchName, jesUncertainty), math.atan2(met_py_jesUp[jesUncertainty], met_px_jesUp[jesUncertainty])) self.out.fillBranch( "%s_pt_jes%sDown" % (self.metBranchName, jesUncertainty), math.sqrt(met_px_jesDown[jesUncertainty]**2 + met_py_jesDown[jesUncertainty]**2)) self.out.fillBranch( "%s_phi_jes%sDown" % (self.metBranchName, jesUncertainty), math.atan2(met_py_jesDown[jesUncertainty], met_px_jesDown[jesUncertainty])) if self.corrMET: self.out.fillBranch( "%s_pt_unclustEnUp" % self.metBranchName, math.sqrt(met_px_unclEnUp**2 + met_py_unclEnUp**2)) self.out.fillBranch("%s_phi_unclustEnUp" % self.metBranchName, math.atan2(met_py_unclEnUp, met_px_unclEnUp)) self.out.fillBranch( "%s_pt_unclustEnDown" % self.metBranchName, math.sqrt(met_px_unclEnDown**2 + met_py_unclEnDown**2)) self.out.fillBranch( "%s_phi_unclustEnDown" % self.metBranchName, math.atan2(met_py_unclEnDown, met_px_unclEnDown)) return True
def analyze(self, event): """process event, return True (go to next module) or False (fail, go to next event)""" jets = Collection(event, self.jetBranchName ) genJets = Collection(event, self.genJetBranchName ) if self.doGroomed : subJets = Collection(event, self.subJetBranchName ) genSubJets = Collection(event, self.genSubJetBranchName ) genSubJetMatcher = matchObjectCollectionMultiple( genJets, genSubJets, dRmax=0.8 ) self.jetSmearer.setSeed(event) jet_L1 = [] jet_L2L3 = [] jet_LRes = [] jets_pt_raw = [] jets_pt_nom = [] jets_mass_raw = [] jets_mass_nom = [] jets_corr_JEC = [] jets_corr_JER = [] jets_corr_JMS = [] jets_corr_JMR = [] jets_pt_jerUp = [] jets_pt_jerDown = [] jets_pt_jesUp = {} jets_pt_jesDown = {} jets_mass_jerUp = [] jets_mass_jerDown = [] jets_mass_jmrUp = [] jets_mass_jmrDown = [] jets_mass_jesUp = {} jets_mass_jesDown = {} jets_mass_jmsUp = [] jets_mass_jmsDown = [] for jesUncertainty in self.jesUncertainties: jets_pt_jesUp[jesUncertainty] = [] jets_pt_jesDown[jesUncertainty] = [] jets_mass_jesUp[jesUncertainty] = [] jets_mass_jesDown[jesUncertainty] = [] if self.corrMET : met = Object(event, self.metBranchName) ( met_px, met_py ) = ( met.pt*math.cos(met.phi), met.pt*math.sin(met.phi) ) ( met_px_nom, met_py_nom ) = ( met_px, met_py ) ( met_px_jerUp, met_py_jerUp ) = ( met_px, met_py ) ( met_px_jerDown, met_py_jerDown ) = ( met_px, met_py ) ( met_px_jesUp, met_py_jesUp ) = ( {}, {} ) ( met_px_jesDown, met_py_jesDown ) = ( {}, {} ) for jesUncertainty in self.jesUncertainties: met_px_jesUp[jesUncertainty] = met_px met_py_jesUp[jesUncertainty] = met_py met_px_jesDown[jesUncertainty] = met_px met_py_jesDown[jesUncertainty] = met_py if self.doGroomed: jets_msdcorr_raw = [] jets_msdcorr_nom = [] jets_msdcorr_corr_JMR = [] jets_msdcorr_corr_JMS = [] jets_msdcorr_corr_PUPPI = [] jets_msdcorr_jerUp = [] jets_msdcorr_jerDown = [] jets_msdcorr_jmrUp = [] jets_msdcorr_jmrDown = [] jets_msdcorr_jesUp = {} jets_msdcorr_jesDown = {} jets_msdcorr_jmsUp = [] jets_msdcorr_jmsDown = [] jets_msdcorr_tau21DDT_nom = [] jets_msdcorr_tau21DDT_jerUp = [] jets_msdcorr_tau21DDT_jerDown = [] jets_msdcorr_tau21DDT_jmrUp = [] jets_msdcorr_tau21DDT_jmrDown = [] jets_msdcorr_tau21DDT_jmsUp = [] jets_msdcorr_tau21DDT_jmsDown = [] for jesUncertainty in self.jesUncertainties: jets_msdcorr_jesUp[jesUncertainty] = [] jets_msdcorr_jesDown[jesUncertainty] = [] rho = getattr(event, self.rhoBranchName) # match reconstructed jets to generator level ones # (needed to evaluate JER scale factors and uncertainties) pairs = matchObjectCollection(jets, genJets) for jet in jets: #jet pt and mass corrections jet_pt=jet.pt jet_mass=jet.mass jet_L1.append(self.jetReCalibrator.getCorrection(jet,rho, corrector=self.jetReCalibrator.separateJetCorrectors["myL1"])) jet_L2L3.append(self.jetReCalibrator.getCorrection(jet,rho, corrector=self.jetReCalibrator.separateJetCorrectors["myL2L3"])) jet_LRes.append(self.jetReCalibrator.getCorrection(jet,rho, corrector=self.jetReCalibrator.separateJetCorrectors["myRes"])) #redo JECs if desired if hasattr(jet, "rawFactor"): jet_rawpt = jet_pt * (1 - jet.rawFactor) jet_rawmass = jet_mass * (1 - jet.rawFactor) else: jet_rawpt = -1.0 * jet_pt #If factor not present factor will be saved as -1 jet_rawmass = -1.0 * jet_mass #If factor not present factor will be saved as -1 if self.redoJEC : (jet_pt, jet_mass) = self.jetReCalibrator.correct(jet,rho) jet.pt = jet_pt jet.mass = jet_mass jets_pt_raw.append(jet_rawpt) jets_mass_raw.append(jet_rawmass) jets_corr_JEC.append(jet_pt/jet_rawpt) genJet = pairs[jet] if self.doGroomed: genGroomedSubJets = genSubJetMatcher[genJet] if genJet != None else None genGroomedJet = genGroomedSubJets[0].p4() + genGroomedSubJets[1].p4() if genGroomedSubJets != None and len(genGroomedSubJets) >= 2 else None if jet.subJetIdx1 >= 0 and jet.subJetIdx2 >= 0 : groomedP4 = subJets[ jet.subJetIdx1 ].p4() + subJets[ jet.subJetIdx2].p4() #check subjet jecs else : groomedP4 = None # LC: Apply PUPPI SD mass correction https://github.com/cms-jet/PuppiSoftdropMassCorr/ puppisd_genCorr = self.puppisd_corrGEN.Eval(jet.pt) if abs(jet.eta) <= 1.3: puppisd_recoCorr = self.puppisd_corrRECO_cen.Eval(jet.pt) else: puppisd_recoCorr = self.puppisd_corrRECO_for.Eval(jet.pt) puppisd_total = puppisd_genCorr * puppisd_recoCorr jets_msdcorr_corr_PUPPI.append(puppisd_total) if groomedP4 != None: groomedP4.SetPtEtaPhiM(groomedP4.Perp(), groomedP4.Eta(), groomedP4.Phi(), groomedP4.M()*puppisd_total) # evaluate JER scale factors and uncertainties # (cf. https://twiki.cern.ch/twiki/bin/view/CMS/JetResolution and https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookJetEnergyResolution ) ( jet_pt_jerNomVal, jet_pt_jerUpVal, jet_pt_jerDownVal ) = self.jetSmearer.getSmearValsPt(jet, genJet, rho) jets_corr_JER.append(jet_pt_jerNomVal) jet_pt_nom = jet_pt_jerNomVal *jet_pt if jet_pt_nom < 0.0: jet_pt_nom *= -1.0 jet_pt_jerUp = jet_pt_jerUpVal *jet_pt jet_pt_jerDown = jet_pt_jerDownVal*jet_pt jets_pt_nom .append(jet_pt_nom) jets_pt_jerUp .append(jet_pt_jerUpVal*jet_pt) jets_pt_jerDown.append(jet_pt_jerDownVal*jet_pt) # evaluate JES uncertainties jet_pt_jesUp = {} jet_pt_jesDown = {} jet_mass_jesUp = {} jet_mass_jesDown = {} jet_mass_jmsUp = [] jet_mass_jmsDown = [] # Evaluate JMS and JMR scale factors and uncertainties jmsNomVal = self.jmsVals[0] jmsDownVal = self.jmsVals[1] jmsUpVal = self.jmsVals[2] ( jet_mass_jmrNomVal, jet_mass_jmrUpVal, jet_mass_jmrDownVal ) = self.jetSmearer.getSmearValsM(jet, genJet) jets_corr_JMS .append(jmsNomVal) jets_corr_JMR .append(jet_mass_jmrNomVal) jet_mass_nom = jet_pt_jerNomVal*jet_mass_jmrNomVal*jmsNomVal*jet_mass if jet_mass_nom < 0.0: jet_mass_nom *= -1.0 jets_mass_nom .append(jet_mass_nom) jets_mass_jerUp .append(jet_pt_jerUpVal *jet_mass_jmrNomVal *jmsNomVal *jet_mass) jets_mass_jerDown.append(jet_pt_jerDownVal*jet_mass_jmrNomVal *jmsNomVal *jet_mass) jets_mass_jmrUp .append(jet_pt_jerNomVal *jet_mass_jmrUpVal *jmsNomVal *jet_mass) jets_mass_jmrDown.append(jet_pt_jerNomVal *jet_mass_jmrDownVal*jmsNomVal *jet_mass) jets_mass_jmsUp .append(jet_pt_jerNomVal *jet_mass_jmrNomVal *jmsUpVal *jet_mass) jets_mass_jmsDown.append(jet_pt_jerNomVal *jet_mass_jmrNomVal *jmsDownVal *jet_mass) if self.doGroomed : # evaluate JES uncertainties jet_msdcorr_jesUp = {} jet_msdcorr_jesDown = {} # Evaluate JMS and JMR scale factors and uncertainties ( jet_msdcorr_jmrNomVal, jet_msdcorr_jmrUpVal, jet_msdcorr_jmrDownVal ) = self.jetSmearer.getSmearValsM(groomedP4, genGroomedJet) if groomedP4 != None and genGroomedJet != None else (0.,0.,0.) jet_msdcorr_raw = groomedP4.M() if groomedP4 != None else 0.0 jets_msdcorr_corr_JMS.append(jmsNomVal) jets_msdcorr_corr_JMR.append(jet_msdcorr_jmrNomVal) if jet_msdcorr_raw < 0.0: jet_msdcorr_raw *= -1.0 jet_msdcorr_nom = jet_pt_jerNomVal*jet_msdcorr_jmrNomVal*jmsNomVal*jet_msdcorr_raw jets_msdcorr_raw .append(jet_msdcorr_raw) #fix later so jec's not applied - LC: Current PUPPI SD mass correction implementation needs the JECs applied before looking up the correction so make sure that's accounted for if this is changed. jets_msdcorr_nom .append(jet_msdcorr_nom) jets_msdcorr_jerUp .append(jet_pt_jerUpVal *jet_msdcorr_jmrNomVal *jmsNomVal *jet_msdcorr_raw) jets_msdcorr_jerDown.append(jet_pt_jerDownVal*jet_msdcorr_jmrNomVal *jmsNomVal *jet_msdcorr_raw) jets_msdcorr_jmrUp .append(jet_pt_jerNomVal *jet_msdcorr_jmrUpVal *jmsNomVal *jet_msdcorr_raw) jets_msdcorr_jmrDown.append(jet_pt_jerNomVal *jet_msdcorr_jmrDownVal*jmsNomVal *jet_msdcorr_raw) jets_msdcorr_jmsUp .append(jet_pt_jerNomVal *jet_msdcorr_jmrNomVal *jmsUpVal *jet_msdcorr_raw) jets_msdcorr_jmsDown.append(jet_pt_jerNomVal *jet_msdcorr_jmrNomVal *jmsDownVal *jet_msdcorr_raw) #Also evaluated JMS&JMR SD corr in tau21DDT region: https://twiki.cern.ch/twiki/bin/viewauth/CMS/JetWtagging#tau21DDT_0_43 if self.era in ["2016"]: jmstau21DDTNomVal = 1.014 jmstau21DDTDownVal = 1.007 jmstau21DDTUpVal = 1.021 self.jetSmearer.jmr_vals = [1.086,1.176,0.996] elif self.era in ["2017","2018"]: jmstau21DDTNomVal = 0.983 jmstau21DDTDownVal = 0.976 jmstau21DDTUpVal = 0.99 self.jetSmearer.jmr_vals = [1.080,1.161,0.999] ( jet_msdcorr_tau21DDT_jmrNomVal, jet_msdcorr_tau21DDT_jmrUpVal, jet_msdcorr_tau21DDT_jmrDownVal ) = self.jetSmearer.getSmearValsM(groomedP4, genGroomedJet) if groomedP4 != None and genGroomedJet != None else (0.,0.,0.) jet_msdcorr_tau21DDT_nom = jet_pt_jerNomVal*jet_msdcorr_tau21DDT_jmrNomVal*jmstau21DDTNomVal*jet_msdcorr_raw jets_msdcorr_tau21DDT_nom .append(jet_msdcorr_tau21DDT_nom) jets_msdcorr_tau21DDT_jerUp .append(jet_pt_jerUpVal *jet_msdcorr_tau21DDT_jmrNomVal *jmstau21DDTNomVal *jet_msdcorr_raw) jets_msdcorr_tau21DDT_jerDown.append(jet_pt_jerDownVal*jet_msdcorr_tau21DDT_jmrNomVal *jmstau21DDTNomVal *jet_msdcorr_raw) jets_msdcorr_tau21DDT_jmrUp .append(jet_pt_jerNomVal *jet_msdcorr_tau21DDT_jmrUpVal *jmstau21DDTNomVal *jet_msdcorr_raw) jets_msdcorr_tau21DDT_jmrDown.append(jet_pt_jerNomVal *jet_msdcorr_tau21DDT_jmrDownVal*jmstau21DDTNomVal *jet_msdcorr_raw) jets_msdcorr_tau21DDT_jmsUp .append(jet_pt_jerNomVal *jet_msdcorr_tau21DDT_jmrNomVal *jmstau21DDTUpVal *jet_msdcorr_raw) jets_msdcorr_tau21DDT_jmsDown.append(jet_pt_jerNomVal *jet_msdcorr_tau21DDT_jmrNomVal *jmstau21DDTDownVal *jet_msdcorr_raw) #Restore original jmr_vals in jetSmearer self.jetSmearer.jmr_vals = self.jmrVals for jesUncertainty in self.jesUncertainties: # (cf. https://twiki.cern.ch/twiki/bin/view/CMSPublic/WorkBookJetEnergyCorrections#JetCorUncertainties ) self.jesUncertainty[jesUncertainty].setJetPt(jet_pt_nom) self.jesUncertainty[jesUncertainty].setJetEta(jet.eta) delta = self.jesUncertainty[jesUncertainty].getUncertainty(True) jet_pt_jesUp[jesUncertainty] = jet_pt_nom*(1. + delta) jet_pt_jesDown[jesUncertainty] = jet_pt_nom*(1. - delta) jets_pt_jesUp[jesUncertainty].append(jet_pt_jesUp[jesUncertainty]) jets_pt_jesDown[jesUncertainty].append(jet_pt_jesDown[jesUncertainty]) jet_mass_jesUp [jesUncertainty] = jet_mass_nom*(1. + delta) jet_mass_jesDown [jesUncertainty] = jet_mass_nom*(1. - delta) jets_mass_jesUp [jesUncertainty].append(jet_mass_jesUp[jesUncertainty]) jets_mass_jesDown[jesUncertainty].append(jet_mass_jesDown[jesUncertainty]) if self.doGroomed : jet_msdcorr_jesUp [jesUncertainty] = jet_msdcorr_nom*(1. + delta) jet_msdcorr_jesDown [jesUncertainty] = jet_msdcorr_nom*(1. - delta) jets_msdcorr_jesUp [jesUncertainty].append(jet_msdcorr_jesUp[jesUncertainty]) jets_msdcorr_jesDown[jesUncertainty].append(jet_msdcorr_jesDown[jesUncertainty]) # propagate JER and JES corrections and uncertainties to MET if self.corrMET and jet_pt_nom > self.unclEnThreshold: jet_cosPhi = math.cos(jet.phi) jet_sinPhi = math.sin(jet.phi) met_px_nom = met_px_nom - (jet_pt_nom - jet_pt)*jet_cosPhi met_py_nom = met_py_nom - (jet_pt_nom - jet_pt)*jet_sinPhi met_px_jerUp = met_px_jerUp - (jet_pt_jerUp - jet_pt_nom)*jet_cosPhi met_py_jerUp = met_py_jerUp - (jet_pt_jerUp - jet_pt_nom)*jet_sinPhi met_px_jerDown = met_px_jerDown - (jet_pt_jerDown - jet_pt_nom)*jet_cosPhi met_py_jerDown = met_py_jerDown - (jet_pt_jerDown - jet_pt_nom)*jet_sinPhi for jesUncertainty in self.jesUncertainties: met_px_jesUp[jesUncertainty] = met_px_jesUp[jesUncertainty] - (jet_pt_jesUp[jesUncertainty] - jet_pt_nom)*jet_cosPhi met_py_jesUp[jesUncertainty] = met_py_jesUp[jesUncertainty] - (jet_pt_jesUp[jesUncertainty] - jet_pt_nom)*jet_sinPhi met_px_jesDown[jesUncertainty] = met_px_jesDown[jesUncertainty] - (jet_pt_jesDown[jesUncertainty] - jet_pt_nom)*jet_cosPhi met_py_jesDown[jesUncertainty] = met_py_jesDown[jesUncertainty] - (jet_pt_jesDown[jesUncertainty] - jet_pt_nom)*jet_sinPhi # propagate "unclustered energy" uncertainty to MET if self.corrMET : ( met_px_unclEnUp, met_py_unclEnUp ) = ( met_px, met_py ) ( met_px_unclEnDown, met_py_unclEnDown ) = ( met_px, met_py ) met_deltaPx_unclEn = getattr(event, self.metBranchName + "_MetUnclustEnUpDeltaX") met_deltaPy_unclEn = getattr(event, self.metBranchName + "_MetUnclustEnUpDeltaY") met_px_unclEnUp = met_px_unclEnUp + met_deltaPx_unclEn met_py_unclEnUp = met_py_unclEnUp + met_deltaPy_unclEn met_px_unclEnDown = met_px_unclEnDown - met_deltaPx_unclEn met_py_unclEnDown = met_py_unclEnDown - met_deltaPy_unclEn # propagate effect of jet energy smearing to MET met_px_jerUp = met_px_jerUp + (met_px_nom - met_px) met_py_jerUp = met_py_jerUp + (met_py_nom - met_py) met_px_jerDown = met_px_jerDown + (met_px_nom - met_px) met_py_jerDown = met_py_jerDown + (met_py_nom - met_py) for jesUncertainty in self.jesUncertainties: met_px_jesUp[jesUncertainty] = met_px_jesUp[jesUncertainty] + (met_px_nom - met_px) met_py_jesUp[jesUncertainty] = met_py_jesUp[jesUncertainty] + (met_py_nom - met_py) met_px_jesDown[jesUncertainty] = met_px_jesDown[jesUncertainty] + (met_px_nom - met_px) met_py_jesDown[jesUncertainty] = met_py_jesDown[jesUncertainty] + (met_py_nom - met_py) met_px_unclEnUp = met_px_unclEnUp + (met_px_nom - met_px) met_py_unclEnUp = met_py_unclEnUp + (met_py_nom - met_py) met_px_unclEnDown = met_px_unclEnDown + (met_px_nom - met_px) met_py_unclEnDown = met_py_unclEnDown + (met_py_nom - met_py) self.out.fillBranch("%s_pt_raw" % self.jetBranchName, jets_pt_raw) self.out.fillBranch("%s_pt_nom" % self.jetBranchName, jets_pt_nom) self.out.fillBranch("%s_corr_JEC" % self.jetBranchName, jets_corr_JEC) self.out.fillBranch("%s_corr_JER" % self.jetBranchName, jets_corr_JER) self.out.fillBranch("%s_pt_jerUp" % self.jetBranchName, jets_pt_jerUp) self.out.fillBranch("%s_pt_jerDown" % self.jetBranchName, jets_pt_jerDown) self.out.fillBranch("%s_mass_raw" % self.jetBranchName, jets_mass_raw) self.out.fillBranch("%s_mass_nom" % self.jetBranchName, jets_mass_nom) self.out.fillBranch("%s_corr_JMS" % self.jetBranchName, jets_corr_JMS) self.out.fillBranch("%s_corr_JMR" % self.jetBranchName, jets_corr_JMR) self.out.fillBranch("%s_mass_jerUp" % self.jetBranchName, jets_mass_jerUp) self.out.fillBranch("%s_mass_jerDown" % self.jetBranchName, jets_mass_jerDown) self.out.fillBranch("%s_mass_jmrUp" % self.jetBranchName, jets_mass_jmrUp) self.out.fillBranch("%s_mass_jmrDown" % self.jetBranchName, jets_mass_jmrDown) self.out.fillBranch("%s_mass_jmsUp" % self.jetBranchName, jets_mass_jmsUp) self.out.fillBranch("%s_mass_jmsDown" % self.jetBranchName, jets_mass_jmsDown) self.out.fillBranch("%s_L1" % self.jetBranchName, jet_L1) self.out.fillBranch("%s_L2L3" % self.jetBranchName, jet_L2L3) self.out.fillBranch("%s_LRes" % self.jetBranchName, jet_LRes) if self.doGroomed : self.out.fillBranch("%s_msoftdrop_raw" % self.jetBranchName, jets_msdcorr_raw) self.out.fillBranch("%s_msoftdrop_nom" % self.jetBranchName, jets_msdcorr_nom) self.out.fillBranch("%s_msoftdrop_corr_JMS" % self.jetBranchName, jets_msdcorr_corr_JMS) self.out.fillBranch("%s_msoftdrop_corr_JMR" % self.jetBranchName, jets_msdcorr_corr_JMR) self.out.fillBranch("%s_msoftdrop_jerUp" % self.jetBranchName, jets_msdcorr_jerUp) self.out.fillBranch("%s_msoftdrop_jerDown" % self.jetBranchName, jets_msdcorr_jerDown) self.out.fillBranch("%s_msoftdrop_corr_PUPPI" % self.jetBranchName, jets_msdcorr_corr_PUPPI) self.out.fillBranch("%s_msoftdrop_jmrUp" % self.jetBranchName, jets_msdcorr_jmrUp) self.out.fillBranch("%s_msoftdrop_jmrDown" % self.jetBranchName, jets_msdcorr_jmrDown) self.out.fillBranch("%s_msoftdrop_jmsUp" % self.jetBranchName, jets_msdcorr_jmsUp) self.out.fillBranch("%s_msoftdrop_jmsDown" % self.jetBranchName, jets_msdcorr_jmsDown) self.out.fillBranch("%s_msoftdrop_tau21DDT_nom" % self.jetBranchName, jets_msdcorr_tau21DDT_nom) self.out.fillBranch("%s_msoftdrop_tau21DDT_jerUp" % self.jetBranchName, jets_msdcorr_tau21DDT_jerUp) self.out.fillBranch("%s_msoftdrop_tau21DDT_jerDown" % self.jetBranchName, jets_msdcorr_tau21DDT_jerDown) self.out.fillBranch("%s_msoftdrop_tau21DDT_jmrUp" % self.jetBranchName, jets_msdcorr_tau21DDT_jmrUp) self.out.fillBranch("%s_msoftdrop_tau21DDT_jmrDown" % self.jetBranchName, jets_msdcorr_tau21DDT_jmrDown) self.out.fillBranch("%s_msoftdrop_tau21DDT_jmsUp" % self.jetBranchName, jets_msdcorr_tau21DDT_jmsUp) self.out.fillBranch("%s_msoftdrop_tau21DDT_jmsDown" % self.jetBranchName, jets_msdcorr_tau21DDT_jmsDown) if self.corrMET : self.out.fillBranch("%s_pt_nom" % self.metBranchName, math.sqrt(met_px_nom**2 + met_py_nom**2)) self.out.fillBranch("%s_phi_nom" % self.metBranchName, math.atan2(met_py_nom, met_px_nom)) self.out.fillBranch("%s_pt_jerUp" % self.metBranchName, math.sqrt(met_px_jerUp**2 + met_py_jerUp**2)) self.out.fillBranch("%s_phi_jerUp" % self.metBranchName, math.atan2(met_py_jerUp, met_px_jerUp)) self.out.fillBranch("%s_pt_jerDown" % self.metBranchName, math.sqrt(met_px_jerDown**2 + met_py_jerDown**2)) self.out.fillBranch("%s_phi_jerDown" % self.metBranchName, math.atan2(met_py_jerDown, met_px_jerDown)) for jesUncertainty in self.jesUncertainties: self.out.fillBranch("%s_pt_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_pt_jesUp[jesUncertainty]) self.out.fillBranch("%s_pt_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_pt_jesDown[jesUncertainty]) self.out.fillBranch("%s_mass_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_mass_jesUp[jesUncertainty]) self.out.fillBranch("%s_mass_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_mass_jesDown[jesUncertainty]) if self.doGroomed : self.out.fillBranch("%s_msoftdrop_jes%sUp" % (self.jetBranchName, jesUncertainty), jets_msdcorr_jesUp[jesUncertainty]) self.out.fillBranch("%s_msoftdrop_jes%sDown" % (self.jetBranchName, jesUncertainty), jets_msdcorr_jesDown[jesUncertainty]) if self.corrMET: self.out.fillBranch("%s_pt_jes%sUp" % (self.metBranchName, jesUncertainty), math.sqrt(met_px_jesUp[jesUncertainty]**2 + met_py_jesUp[jesUncertainty]**2)) self.out.fillBranch("%s_phi_jes%sUp" % (self.metBranchName, jesUncertainty), math.atan2(met_py_jesUp[jesUncertainty], met_px_jesUp[jesUncertainty])) self.out.fillBranch("%s_pt_jes%sDown" % (self.metBranchName, jesUncertainty), math.sqrt(met_px_jesDown[jesUncertainty]**2 + met_py_jesDown[jesUncertainty]**2)) self.out.fillBranch("%s_phi_jes%sDown" % (self.metBranchName, jesUncertainty), math.atan2(met_py_jesDown[jesUncertainty], met_px_jesDown[jesUncertainty])) if self.corrMET: self.out.fillBranch("%s_pt_unclustEnUp" % self.metBranchName, math.sqrt(met_px_unclEnUp**2 + met_py_unclEnUp**2)) self.out.fillBranch("%s_phi_unclustEnUp" % self.metBranchName, math.atan2(met_py_unclEnUp, met_px_unclEnUp)) self.out.fillBranch("%s_pt_unclustEnDown" % self.metBranchName, math.sqrt(met_px_unclEnDown**2 + met_py_unclEnDown**2)) self.out.fillBranch("%s_phi_unclustEnDown" % self.metBranchName, math.atan2(met_py_unclEnDown, met_px_unclEnDown)) return True