1 from __future__
import print_function
8 def __init__(self,globalTag,jetFlavour,doResidualJECs,jecPath,upToLevel=3,
9 calculateSeparateCorrections=
False,
10 calculateType1METCorrection=
False, type1METParams={
'jetPtThreshold':15.,
'skipEMfractionThreshold':0.9,
'skipMuons':
True} ):
11 """Create a corrector object that reads the payloads from the text dumps of a global tag under 12 CMGTools/RootTools/data/jec (see the getJec.py there to make the dumps). 13 It will apply the L1,L2,L3 and possibly the residual corrections to the jets. 14 If configured to do so, it will also compute the type1 MET corrections.""" 23 path = os.path.expandvars(jecPath)
24 self.
L1JetPar = ROOT.JetCorrectorParameters(
"%s/%s_L1FastJet_%s.txt" % (path,globalTag,jetFlavour),
"");
25 self.
L2JetPar = ROOT.JetCorrectorParameters(
"%s/%s_L2Relative_%s.txt" % (path,globalTag,jetFlavour),
"");
26 self.
L3JetPar = ROOT.JetCorrectorParameters(
"%s/%s_L3Absolute_%s.txt" % (path,globalTag,jetFlavour),
"");
27 self.
vPar = ROOT.vector(ROOT.JetCorrectorParameters)()
29 if upToLevel >= 2: self.vPar.push_back(self.
L2JetPar);
30 if upToLevel >= 3: self.vPar.push_back(self.
L3JetPar);
33 self.
ResJetPar = ROOT.JetCorrectorParameters(
"%s/%s_L2L3Residual_%s.txt" % (path,globalTag,jetFlavour))
37 if os.path.exists(
"%s/%s_Uncertainty_%s.txt" % (path,globalTag,jetFlavour)):
38 self.
JetUncertainty = ROOT.JetCorrectionUncertainty(
"%s/%s_Uncertainty_%s.txt" % (path,globalTag,jetFlavour));
39 elif os.path.exists(
"%s/Uncertainty_FAKE.txt" % path):
40 self.
JetUncertainty = ROOT.JetCorrectionUncertainty(
"%s/Uncertainty_FAKE.txt" % path);
42 print(
'Missing JEC uncertainty file "%s/%s_Uncertainty_%s.txt", so jet energy uncertainties will not be available' % (path,globalTag,jetFlavour))
45 if calculateSeparateCorrections
or calculateType1METCorrection:
46 self.
vParL1 = ROOT.vector(ROOT.JetCorrectorParameters)()
49 if upToLevel >= 2
and calculateSeparateCorrections:
50 self.
vParL2 = ROOT.vector(ROOT.JetCorrectorParameters)()
53 if upToLevel >= 3
and calculateSeparateCorrections:
54 self.
vParL3 = ROOT.vector(ROOT.JetCorrectorParameters)()
57 if doResidualJECs
and calculateSeparateCorrections:
58 self.
vParL3Res = ROOT.vector(ROOT.JetCorrectorParameters)()
64 if corrector != self.
JetCorrector and delta!=0:
raise RuntimeError(
'Configuration not supported')
65 corrector.setJetEta(jet.eta())
66 corrector.setJetPt(jet.pt()*jet.rawFactor())
67 corrector.setJetA(jet.jetArea())
69 corr = corrector.getCorrection()
71 if not self.
JetUncertainty:
raise RuntimeError(
"Jet energy scale uncertainty shifts requested, but not available")
72 self.JetUncertainty.setJetEta(jet.eta())
73 self.JetUncertainty.setJetPt(corr * jet.pt() * jet.rawFactor())
75 jet.jetEnergyCorrUncertainty = self.JetUncertainty.getUncertainty(
True)
76 except RuntimeError
as r:
77 print(
"Caught %s when getting uncertainty for jet of pt %.1f, eta %.2f\n" % (r,corr * jet.pt() * jet.rawFactor(),jet.eta()))
78 jet.jetEnergyCorrUncertainty = 0.5
80 corr *=
max(0, 1+delta*jet.jetEnergyCorrUncertainty)
84 """Return the raw 4-vector, after subtracting the muons (if requested), 85 or None if the jet fails the EMF cut.""" 86 p4 = jet.p4() * jet.rawFactor()
87 emf = ( jet.physObj.neutralEmEnergy() + jet.physObj.chargedEmEnergy() )/p4.E()
91 for idau
in xrange(jet.numberOfDaughters()):
92 pfcand = jet.daughter(idau)
93 if pfcand.isGlobalMuon()
or pfcand.isStandAloneMuon():
97 def correct(self,jet,rho,delta=0,addCorr=False,addShifts=False, metShift=[0,0],type1METCorr=[0,0,0]):
98 """Corrects a jet energy (optionally shifting it also by delta times the JEC uncertainty) 100 If addCorr, set jet.corr to the correction. 101 If addShifts, set also the +1 and -1 jet shifts 103 The metShift vector will accumulate the x and y changes to the MET from the JEC, i.e. the 104 negative difference between the new and old jet momentum, for jets eligible for type1 MET 105 corrections, and after subtracting muons. The pt cut is applied to the new corrected pt. 106 This shift can be applied on top of the *OLD TYPE1 MET*, but only if there was no change 107 in the L1 corrections nor in the definition of the type1 MET (e.g. jet pt cuts). 109 The type1METCorr vector, will accumulate the x, y, sumEt type1 MET corrections, to be 110 applied to the *RAW MET* (if the feature was turned on in the constructor of the class). 112 raw = jet.rawFactor()
116 for sepcorr
in self.separateJetCorrectors.keys():
119 for cdelta,shift
in [(1.0,
"JECUp"), (-1.0,
"JECDown")]:
121 setattr(jet,
"corr"+shift, cshift)
124 newpt = jet.pt()*raw*corr
127 if rawP4forT1
and rawP4forT1.Pt()*corr > self.
type1METParams[
'jetPtThreshold']:
128 metShift[0] -= rawP4forT1.Px() * (corr - 1.0/raw)
129 metShift[1] -= rawP4forT1.Py() * (corr - 1.0/raw)
136 type1METCorr[0] -= rawP4forT1.Px() * (corr - l1corr)
137 type1METCorr[1] -= rawP4forT1.Py() * (corr - l1corr)
138 type1METCorr[2] += rawP4forT1.Et() * (corr - l1corr)
139 jet.setCorrP4(jet.p4() * (corr * raw))
142 def correctAll(self,jets,rho,delta=0, addCorr=False, addShifts=False, metShift=[0.,0.], type1METCorr=[0.,0.,0.]):
143 """Applies 'correct' to all the jets, discard the ones that have bad corrections (corrected pt <= 0)""" 145 if metShift != [0.,0. ]:
raise RuntimeError(
"input metShift tuple is not initialized to zeros")
146 if type1METCorr != [0.,0.,0.]:
raise RuntimeError(
"input type1METCorr tuple is not initialized to zeros")
148 ok = self.
correct(j,rho,delta,addCorr=addCorr,addShifts=addShifts,metShift=metShift,type1METCorr=type1METCorr)
149 if not ok: badJets.append(j)
151 print(
"Warning: %d out of %d jets flagged bad by JEC." % (len(badJets), len(jets)))
157 """Object to apply type1 corrections computed by the JetReCalibrator to the MET. 158 old74XMiniAODs should be True if using inputs produced with CMSSW_7_4_11 or earlier.""" 161 oldpx, oldpy = met.px(), met.py()
164 raw = met.shiftedP2_74x(12,0);
165 rawsumet = met.shiftedSumEt_74x(12,0);
168 rawsumet = met.uncorSumEt();
169 rawpx, rawpy = raw.px, raw.py
171 corrpx = rawpx + type1METCorrections[0]
172 corrpy = rawpy + type1METCorrections[1]
173 corrsumet = rawsumet + type1METCorrections[2]
175 met.setP4(ROOT.reco.Particle.LorentzVector(corrpx,corrpy,0,hypot(corrpx,corrpy)))
177 met._sumEt = corrsumet
178 met.sumEt = types.MethodType(
lambda myself : myself._sumEt, met, met.__class__)
180 met.setCorShift(rawpx, rawpy, rawsumet, met.Raw)
186 met._rawSumEt = rawsumet
187 met._rawP4 = ROOT.reco.Particle.LorentzVector(rawpx,rawpy,0,hypot(rawpx,rawpy))
188 met.uncorPt = types.MethodType(
lambda myself : myself._rawP4.Pt(), met, met.__class__)
189 met.uncorPx = types.MethodType(
lambda myself : myself._rawP4.Px(), met, met.__class__)
190 met.uncorPy = types.MethodType(
lambda myself : myself._rawP4.Py(), met, met.__class__)
191 met.uncorPhi = types.MethodType(
lambda myself : myself._rawP4.Phi(), met, met.__class__)
192 met.uncorP4 = types.MethodType(
lambda myself : myself._rawP4, met, met.__class__)
193 met.uncorSumEt = types.MethodType(
lambda myself : myself._rawSumEt, met, met.__class__)
195 met.uncorP2 = types.MethodType(
lambda myself :
None, met, met.__class__)
196 met.uncorP3 = types.MethodType(
lambda myself :
None, met, met.__class__)
def correctAll(self, jets, rho, delta=0, addCorr=False, addShifts=False, metShift=[0., type1METCorr=[0.)
def correct(self, jet, rho, delta=0, addCorr=False, addShifts=False, metShift=[0, type1METCorr=[0)
S & print(S &os, JobReport::InputFile const &f)
def getCorrection(self, jet, rho, delta=0, corrector=None)
def correct(self, met, type1METCorrections)
def __init__(self, old74XMiniAODs)
def rawP4forType1MET_(self, jet)
def setFakeRawMETOnOldMiniAODs(met, rawpx, rawpy, rawsumet)