CMS 3D CMS Logo

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