CMS 3D CMS Logo

NoPileUpPFMEtDataProducer.cc
Go to the documentation of this file.
2 
5 
6 #include <algorithm>
7 #include <cmath>
8 
9 const int flag_isWithinFakeJet = 1;
12 
13 const double dR2Min = 0.001 * 0.001;
14 
16  : moduleLabel_(cfg.getParameter<std::string>("@module_label")),
17  looseJetIdAlgo_(nullptr),
18  pfMEtSignInterface_(nullptr) {
19  srcJets_ = consumes<reco::PFJetCollection>(cfg.getParameter<edm::InputTag>("srcJets"));
20  srcJetIds_ = consumes<edm::ValueMap<int> >(cfg.getParameter<edm::InputTag>("srcJetIds"));
21  minJetPt_ = cfg.getParameter<double>("minJetPt");
22  std::string jetIdSelection_string = cfg.getParameter<std::string>("jetIdSelection");
23  if (jetIdSelection_string == "loose")
25  else if (jetIdSelection_string == "medium")
27  else if (jetIdSelection_string == "tight")
29  else
30  throw cms::Exception("NoPileUpPFMEtDataProducer")
31  << "Invalid Configuration Parameter 'jetIdSelection' = " << jetIdSelection_string << " !!\n";
32  jetEnOffsetCorrLabel_ = cfg.getParameter<std::string>("jetEnOffsetCorrLabel");
33 
34  srcPFCandidates_ = consumes<reco::PFCandidateCollection>(cfg.getParameter<edm::InputTag>("srcPFCandidates"));
35  srcPFCandidatesView_ = consumes<edm::View<reco::PFCandidate> >(cfg.getParameter<edm::InputTag>("srcPFCandidates"));
37  consumes<PFCandToVertexAssMap>(cfg.getParameter<edm::InputTag>("srcPFCandToVertexAssociations"));
38  srcJetsForMEtCov_ = mayConsume<reco::PFJetCollection>(cfg.getParameter<edm::InputTag>("srcJetsForMEtCov"));
39  minJetPtForMEtCov_ = cfg.getParameter<double>("minJetPtForMEtCov");
40  srcHardScatterVertex_ = consumes<reco::VertexCollection>(cfg.getParameter<edm::InputTag>("srcHardScatterVertex"));
41  dZcut_ = cfg.getParameter<double>("dZcut");
42 
43  edm::ParameterSet cfgPFJetIdAlgo;
44  cfgPFJetIdAlgo.addParameter<std::string>("version", "FIRSTDATA");
45  cfgPFJetIdAlgo.addParameter<std::string>("quality", "LOOSE");
46  looseJetIdAlgo_ = new PFJetIDSelectionFunctor(cfgPFJetIdAlgo);
47 
48  pfMEtSignInterface_ = new PFMEtSignInterfaceBase(cfg.getParameter<edm::ParameterSet>("resolution"));
49 
50  maxWarnings_ = (cfg.exists("maxWarnings")) ? cfg.getParameter<int>("maxWarnings") : 1;
51  numWarnings_ = 0;
52 
53  verbosity_ = (cfg.exists("verbosity")) ? cfg.getParameter<int>("verbosity") : 0;
54 
55  produces<reco::PUSubMETCandInfoCollection>("jetInfos");
56  produces<reco::PUSubMETCandInfoCollection>("pfCandInfos");
57 }
58 
60  delete looseJetIdAlgo_;
61  delete pfMEtSignInterface_;
62 }
63 
64 namespace {
65  void setPFCandidateFlag(const reco::PFJet& pfJet,
67  std::vector<int>& flags,
68  int value,
69  int& numWarnings,
70  int maxWarnings,
71  std::vector<const reco::PFJet*>* pfCandidateToJetAssociations = nullptr) {
72  edm::ProductID viewProductID;
73  if (!pfCandidateCollection.empty()) {
74  viewProductID = pfCandidateCollection.ptrAt(0).id();
75  }
76 
77  std::vector<reco::PFCandidatePtr> pfConsts = pfJet.getPFConstituents();
78  for (std::vector<reco::PFCandidatePtr>::const_iterator pfJetConstituent = pfConsts.begin();
79  pfJetConstituent != pfConsts.end();
80  ++pfJetConstituent) {
81  std::vector<int> idxs;
82  if (!pfCandidateCollection.empty() && pfJetConstituent->id() == viewProductID) {
83  idxs.push_back(pfJetConstituent->key());
84  } else {
85  bool isMatched_fast = false;
86  if (pfJetConstituent->key() < pfCandidateCollection.size()) {
87  edm::Ptr<reco::PFCandidate> pfCandidatePtr = pfCandidateCollection.ptrAt(pfJetConstituent->key());
88  double dR2 = deltaR2((*pfJetConstituent)->p4(), pfCandidatePtr->p4());
89  if (dR2 < dR2Min) {
90  idxs.push_back(pfCandidatePtr.key());
91  isMatched_fast = true;
92  }
93  }
94 
95  if (!isMatched_fast) {
96  size_t numPFCandidates = pfCandidateCollection.size();
97  for (size_t iPFCandidate = 0; iPFCandidate < numPFCandidates; ++iPFCandidate) {
98  edm::Ptr<reco::PFCandidate> pfCandidatePtr = pfCandidateCollection.ptrAt(iPFCandidate);
99  double dR2 = deltaR2((*pfJetConstituent)->p4(), pfCandidatePtr->p4());
100  if (dR2 < dR2Min) {
101  idxs.push_back(pfCandidatePtr.key());
102  }
103  }
104  if (numWarnings < maxWarnings) {
105  edm::LogWarning("setPFCandidateFlag")
106  << " The productIDs of PFJetConstituent and PFCandidateCollection passed as function arguments don't "
107  "match.\n"
108  << "NOTE: The return value will be unaffected, but the code will run MUCH slower !!";
109  ++numWarnings;
110  }
111  }
112  }
113  if (!idxs.empty()) {
114  for (std::vector<int>::const_iterator idx = idxs.begin(); idx != idxs.end(); ++idx) {
115  if ((*idx) >= (int)flags.size())
116  flags.resize(2 * flags.size());
117  flags[*idx] |= value;
118  if (pfCandidateToJetAssociations != nullptr)
119  (*pfCandidateToJetAssociations)[*idx] = &pfJet;
120  }
121  } else {
122  edm::LogError("setPFCandidateFlag")
123  << " Failed to associated PFJetConstituent with index = " << pfJetConstituent->key()
124  << " to any PFCandidate !!";
125  }
126  }
127  }
128 } // namespace
129 
131  LogDebug("produce") << "<NoPileUpPFMEtDataProducer::produce>:\n"
132  << " moduleLabel = " << moduleLabel_ << std::endl;
133 
134  // get jets
136  evt.getByToken(srcJets_, jets);
137 
138  typedef edm::ValueMap<int> jetIdMap;
139  edm::Handle<jetIdMap> jetIds;
140  evt.getByToken(srcJetIds_, jetIds);
141 
142  // get jets for computing contributions to PFMEt significance matrix
145  evt.getByToken(srcJetsForMEtCov_, jetsForMEtCov);
146 
147  // get PFCandidates
150 
151  std::vector<int> pfCandidateFlags(pfCandidates->size());
152  std::vector<const reco::PFJet*> pfCandidateToJetAssociations(pfCandidates->size());
153 
155  evt.getByToken(srcPFCandidates_, pfCandidateHandle);
156 
157  // get PFCandidate-to-vertex associations and "the" hard-scatter vertex
158  edm::Handle<PFCandToVertexAssMap> pfCandToVertexAssociations;
159  evt.getByToken(srcPFCandToVertexAssociations_, pfCandToVertexAssociations);
160 
161  noPuUtils::reversedPFCandToVertexAssMap pfCandToVertexAssociations_reversed =
162  noPuUtils::reversePFCandToVertexAssociation(*pfCandToVertexAssociations);
163 
164  edm::Handle<reco::VertexCollection> hardScatterVertex;
165  evt.getByToken(srcHardScatterVertex_, hardScatterVertex);
166 
167  auto jetInfos = std::make_unique<reco::PUSubMETCandInfoCollection>();
168  auto pfCandInfos = std::make_unique<reco::PUSubMETCandInfoCollection>();
169 
170  // const JetCorrector* jetEnOffsetCorrector = nullptr;
171  if (!jetEnOffsetCorrLabel_.empty()) {
172  throw cms::Exception("NoPileUpPFMEtDataProducer::produce")
173  << "Failed to access Jet corrections for = " << jetEnOffsetCorrLabel_ << " !!\n"
174  << "During the migration from the deprecated ::JetCorrector to the\n"
175  << "new reco::JetCorrector class, this module was never completely migrated.\n"
176  << "The usage of the deprecated class was removed and replaced by this exception.\n"
177  << "To use the new reco::JetCorrector class, someone must do the work\n"
178  << "to implement and test usage of reco::JetCollector in this class.\n";
179  }
180 
181  size_t numJets = jets->size();
182  for (size_t iJet = 0; iJet < numJets; ++iJet) {
183  reco::PFJetRef jet(jets, iJet);
184  if (!(jet->pt() > minJetPt_))
185  continue;
186 
187  bool passesLooseJetId = (*looseJetIdAlgo_)(*jet);
188  if (!passesLooseJetId) {
189  setPFCandidateFlag(*jet, *pfCandidates, pfCandidateFlags, flag_isWithinFakeJet, numWarnings_, maxWarnings_);
190  }
191  setPFCandidateFlag(*jet, *pfCandidates, pfCandidateFlags, flag_isWithinSelectedJet, numWarnings_, maxWarnings_);
192 
193  reco::PUSubMETCandInfo jetInfo;
194  jetInfo.setP4(jet->p4());
195  int jetId = (*jetIds)[jet];
196  bool jetIdSelection_passed = PileupJetIdentifier::passJetId(jetId, jetIdSelection_);
197  jetInfo.setType((jetIdSelection_passed) ? reco::PUSubMETCandInfo::kHS : reco::PUSubMETCandInfo::kPU);
198  jetInfo.setPassesLooseJetId(passesLooseJetId);
199  double jetEnergy_uncorrected = jet->chargedHadronEnergy() + jet->neutralHadronEnergy() + jet->photonEnergy() +
200  jet->electronEnergy() + jet->muonEnergy() + jet->HFHadronEnergy() +
201  jet->HFEMEnergy();
202  double jetPx_uncorrected = cos(jet->phi()) * sin(jet->theta()) * jetEnergy_uncorrected;
203  double jetPy_uncorrected = sin(jet->phi()) * sin(jet->theta()) * jetEnergy_uncorrected;
204  double jetPz_uncorrected = cos(jet->theta()) * jetEnergy_uncorrected;
206  jetPx_uncorrected, jetPy_uncorrected, jetPz_uncorrected, jetEnergy_uncorrected);
207  reco::PFJet rawJet(*jet);
208  rawJet.setP4(rawJetP4);
209  double jetNeutralEnFrac = (jetEnergy_uncorrected > 0.)
210  ? (jet->neutralEmEnergy() + jet->neutralHadronEnergy()) / jetEnergy_uncorrected
211  : -1.;
212  jetInfo.setChargedEnFrac((1 - jetNeutralEnFrac));
213  // jetInfo.setOffsetEnCorr(
214  // (jetEnOffsetCorrector) ? rawJet.energy() * (1. - jetEnOffsetCorrector->correction(rawJet, evt, es)) : 0.);
215  jetInfo.setOffsetEnCorr(0.);
216 
218 
219  jetInfos->push_back(jetInfo);
220  }
221  LogDebug("produce") << "#jetInfos = " << jetInfos->size() << std::endl;
222 
223  for (reco::PFJetCollection::const_iterator jet = jets->begin(); jet != jets->end(); ++jet) {
224  if (jet->pt() > minJetPtForMEtCov_) {
225  setPFCandidateFlag(*jet,
226  *pfCandidates,
227  pfCandidateFlags,
229  numWarnings_,
230  maxWarnings_,
231  &pfCandidateToJetAssociations);
232  }
233  }
234 
235  size_t numPFCandidates = pfCandidates->size();
236  for (size_t iPFCandidate = 0; iPFCandidate < numPFCandidates; ++iPFCandidate) {
237  reco::PFCandidatePtr pfCandidatePtr = pfCandidates->ptrAt(iPFCandidate);
238 
239  int idx = pfCandidatePtr.key();
240  reco::PUSubMETCandInfo pfCandInfo;
241  pfCandInfo.setP4(pfCandidatePtr->p4());
242  pfCandInfo.setCharge(pfCandidatePtr->charge());
243  pfCandInfo.setType(-1);
244  // CV: need to call isVertexAssociated_fast instead of isVertexAssociated function
245  // (makes run-time of MVAPFMEtDataProducer::produce decrease from ~1s per event to ~0.35s per event)
246  //int vtxAssociationType = isVertexAssociated(*pfCandidatePtr, *pfCandToVertexAssociations, *hardScatterVertex, dZcut_);
247  reco::PFCandidateRef pfCandidateRef(pfCandidateHandle, iPFCandidate);
248  int vtxAssociationType = noPuUtils::isVertexAssociated_fast(
249  pfCandidateRef, pfCandToVertexAssociations_reversed, *hardScatterVertex, dZcut_, numWarnings_, maxWarnings_);
250  bool isHardScatterVertex_associated = (vtxAssociationType == noPuUtils::kChHSAssoc);
251  if (pfCandidatePtr->charge() == 0)
253  else if (isHardScatterVertex_associated)
255  else
257  pfCandInfo.setIsWithinJet((pfCandidateFlags[idx] & flag_isWithinSelectedJet));
258  if (pfCandInfo.isWithinJet())
259  pfCandInfo.setPassesLooseJetId((pfCandidateFlags[idx] & flag_isWithinFakeJet));
260  else
261  pfCandInfo.setPassesLooseJetId(true);
262 
263  // CV: for PFCandidates that are within PFJets (of Pt between 'minJetPtForMEtCov' and 'minJetPt'),
264  // take contribution to PFMEt significance matrix from associated PFJet.
265  // (energy uncertainty scaled by ratio of PFCandidate/PFJet energy)
266  const reco::PFJet* jet_matched = pfCandidateToJetAssociations[idx];
267  if (jet_matched) {
268  metsig::SigInputObj pfCandResolution = pfMEtSignInterface_->compResolution(pfCandidatePtr.get());
269  metsig::SigInputObj jetResolution = pfMEtSignInterface_->compResolution(jet_matched);
270 
271  metsig::SigInputObj metSign;
272  metSign.set(pfCandResolution.get_type(),
273  pfCandResolution.get_energy(),
274  pfCandResolution.get_phi(),
275  jetResolution.get_sigma_e() * (pfCandidatePtr->energy() / jet_matched->energy()),
276  jetResolution.get_sigma_tan());
277  pfCandInfo.setMEtSignObj(metSign);
278  } else {
279  pfCandInfo.setMEtSignObj(pfMEtSignInterface_->compResolution(pfCandidatePtr.get()));
280  }
281 
282  pfCandInfos->push_back(pfCandInfo);
283  }
284 
285  LogDebug("produce") << "#pfCandInfos = " << pfCandInfos->size() << std::endl;
286 
287  evt.put(std::move(jetInfos), "jetInfos");
288  evt.put(std::move(pfCandInfos), "pfCandInfos");
289 }
290 
292 
bool isWithinJet() const
Definition: PUSubMETData.h:37
double get_phi() const
Definition: SigInputObj.h:38
edm::EDGetTokenT< PFCandToVertexAssMap > srcPFCandToVertexAssociations_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
const int flag_isWithinSelectedJet
void produce(edm::Event &, const edm::EventSetup &) override
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
double get_sigma_e() const
Definition: SigInputObj.h:39
constexpr bool isUninitialized() const noexcept
Definition: EDGetToken.h:104
void setP4(const reco::Candidate::LorentzVector p4)
Definition: PUSubMETData.h:46
edm::EDGetTokenT< reco::PFJetCollection > srcJetsForMEtCov_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:540
const int flag_isWithinFakeJet
noPuUtils::reversedPFCandToVertexAssMap reversePFCandToVertexAssociation(const PFCandToVertexAssMap &)
edm::EDGetTokenT< reco::VertexCollection > srcHardScatterVertex_
Log< level::Error, false > LogError
Jets made from PFObjects.
Definition: PFJet.h:20
const LorentzVector & p4() const final
four-momentum Lorentz vector
void set(const std::string &m_type, const double &m_energy, const double &m_phi, const double &m_sigma_e, const double &m_sigma_tan)
Definition: SigInputObj.h:42
edm::EDGetTokenT< edm::View< reco::PFCandidate > > srcPFCandidatesView_
virtual std::vector< reco::PFCandidatePtr > getPFConstituents() const
get all constituents
Definition: PFJet.cc:41
static bool passJetId(int flag, Id level)
const int flag_isWithinJetForMEtCov
edm::EDGetTokenT< reco::PFCandidateCollection > srcPFCandidates_
void addParameter(std::string const &name, T const &value)
Definition: ParameterSet.h:135
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
void setIsWithinJet(bool isWJ)
Definition: PUSubMETData.h:53
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
edm::EDGetTokenT< reco::PFJetCollection > srcJets_
NoPileUpPFMEtDataProducer(const edm::ParameterSet &)
Definition: value.py:1
PFJetIDSelectionFunctor * looseJetIdAlgo_
PFMEtSignInterfaceBase * pfMEtSignInterface_
PF Jet selector for pat::Jets.
void setPassesLooseJetId(float jetId)
Definition: PUSubMETData.h:54
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:139
void setCharge(int charge)
Definition: PUSubMETData.h:50
edm::EDGetTokenT< edm::ValueMap< int > > srcJetIds_
void setChargedEnFrac(float chEnF)
Definition: PUSubMETData.h:57
const double dR2Min
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Candidate.h:36
double get_energy() const
Definition: SigInputObj.h:37
double get_sigma_tan() const
Definition: SigInputObj.h:40
void setType(int type)
Definition: PUSubMETData.h:49
key_type key() const
Definition: Ptr.h:163
int isVertexAssociated_fast(const reco::PFCandidateRef &, const noPuUtils::reversedPFCandToVertexAssMap &, const reco::VertexCollection &, double, int &, int)
metsig::SigInputObj compResolution(const T *particle) const
PileupJetIdentifier::Id jetIdSelection_
std::string get_type() const
Definition: SigInputObj.h:36
Log< level::Warning, false > LogWarning
void setMEtSignObj(metsig::SigInputObj msig)
Definition: PUSubMETData.h:59
void setOffsetEnCorr(float offset)
Definition: PUSubMETData.h:55
void setP4(const LorentzVector &p4) final
set 4-momentum
def move(src, dest)
Definition: eostools.py:511
#define LogDebug(id)
double energy() const final
energy