CMS 3D CMS Logo

PhotonIDValueMapProducer.cc
Go to the documentation of this file.
3 
6 
8 
11 
14 
17 
19 
21 
22 #include <memory>
23 #include <vector>
24 
25 // Introduce these two types for brevity of casting
28 
29 // This template function finds whether theCandidate is in thefootprint
30 // collection. It is templated to be able to handle both reco and pat
31 // photons (from AOD and miniAOD, respectively).
32 template <class T, class U>
33 bool isInFootprint(const T& thefootprint, const U& theCandidate) {
34  for ( auto itr = thefootprint.begin(); itr != thefootprint.end(); ++itr ) {
35  if( itr->key() == theCandidate.key() ) return true;
36  }
37  return false;
38 }
39 
41 
42  public:
43 
45  ~PhotonIDValueMapProducer() override;
46 
47  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
48 
49  private:
50 
51  void produce(edm::Event&, const edm::EventSetup&) override;
52 
55  const std::vector<float> & values,
56  const std::string & label) const ;
57 
58  // This function computes charged hadron isolation
59  // with respect to multiple PVs and returns the worst
60  // of the found isolation values.
61  // The function implements the computation method taken directly
62  // from Run 1 code of H->gamma gamma, specifically from
63  // the class CiCPhotonID of the HiggsTo2photons anaysis code.
64  // Template is introduced to handle reco/pat photons and aod/miniAOD
65  // PF candidates collections
66  template <class T, class U>
68  const U& pfCandidates,
70  bool isAOD, bool isPVConstraint,const reco::Vertex& pv,
71  float dRmax, float dxyMax, float dzMax,
72  float dRvetoBarrel, float dRvetoEndcap, float ptMin);
73 
74  // Some helper functions that are needed to access info in
75  // AOD vs miniAOD
77  candidatePdgId(const edm::Ptr<reco::Candidate> candidate, bool isAOD);
78 
79  const reco::Track* getTrackPointer(const edm::Ptr<reco::Candidate> candidate, bool isAOD);
80  void getImpactParameters(const edm::Ptr<reco::Candidate>& candidate,
81  bool isAOD, const reco::Vertex& pv, float &dxy, float &dz);
82 
83 
84 
85  // The object that will compute 5x5 quantities
86  std::unique_ptr<noZS::EcalClusterLazyTools> lazyToolnoZS;
87 
88  // for AOD case
96 
97  // for miniAOD case
105 
106  // check whether a non-null preshower is there
107  bool usesES_;
108 
109  // Cluster shapes
110  constexpr static char phoFull5x5SigmaIEtaIEta_[] = "phoFull5x5SigmaIEtaIEta";
111  constexpr static char phoFull5x5SigmaIEtaIPhi_[] = "phoFull5x5SigmaIEtaIPhi";
112  constexpr static char phoFull5x5E1x3_[] = "phoFull5x5E1x3";
113  constexpr static char phoFull5x5E2x2_[] = "phoFull5x5E2x2";
114  constexpr static char phoFull5x5E2x5Max_[] = "phoFull5x5E2x5Max";
115  constexpr static char phoFull5x5E5x5_[] = "phoFull5x5E5x5";
116  constexpr static char phoESEffSigmaRR_[] = "phoESEffSigmaRR";
117  // Cluster shape ratios
118  constexpr static char phoFull5x5E1x3byE5x5_[] = "phoFull5x5E1x3byE5x5";
119  constexpr static char phoFull5x5E2x2byE5x5_[] = "phoFull5x5E2x2byE5x5";
120  constexpr static char phoFull5x5E2x5byE5x5_[] = "phoFull5x5E2x5byE5x5";
121  // Isolations
122  constexpr static char phoChargedIsolation_[] = "phoChargedIsolation";
123  constexpr static char phoNeutralHadronIsolation_[] = "phoNeutralHadronIsolation";
124  constexpr static char phoPhotonIsolation_[] = "phoPhotonIsolation";
125  constexpr static char phoWorstChargedIsolation_[] = "phoWorstChargedIsolation";
126  constexpr static char phoWorstChargedIsolationWithConeVeto_[] = "phoWorstChargedIsolationWithConeVeto";
127  constexpr static char phoWorstChargedIsolationWithPVConstraint_[] = "phoWorstChargedIsolationWithPVConstraint";
128  constexpr static char phoWorstChargedIsolationWithConeVetoWithPVConstraint_[] = "phoWorstChargedIsolationWithConeVetoWithPVConstraint";
129 
130  //PFCluster Isolation
131  constexpr static char phoTrkIsolation_[] = "phoTrkIsolation";
132  constexpr static char phoHcalPFClIsolation_[] = "phoHcalPFClIsolation";
133  constexpr static char phoEcalPFClIsolation_[] = "phoEcalPFClIsolation";
134 
135 };
136 
137 // Cluster shapes
145 // Cluster shape ratios
149 // Isolations
157 
158 //PFCluster Isolation
162 
163 
165 
166  //
167  // Declare consummables, handle both AOD and miniAOD case
168  //
169  ebReducedRecHitCollection_ = mayConsume<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>
170  ("ebReducedRecHitCollection"));
171  ebReducedRecHitCollectionMiniAOD_ = mayConsume<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>
172  ("ebReducedRecHitCollectionMiniAOD"));
173 
174  eeReducedRecHitCollection_ = mayConsume<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>
175  ("eeReducedRecHitCollection"));
176  eeReducedRecHitCollectionMiniAOD_ = mayConsume<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>
177  ("eeReducedRecHitCollectionMiniAOD"));
178 
179  if (!iConfig.getParameter<edm::InputTag>("esReducedRecHitCollection").label().empty() ||
180  !iConfig.getParameter<edm::InputTag>("esReducedRecHitCollectionMiniAOD").label().empty()) {
181  usesES_ = true;
182  esReducedRecHitCollection_ = mayConsume<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>
183  ("esReducedRecHitCollection"));
184  esReducedRecHitCollectionMiniAOD_ = mayConsume<EcalRecHitCollection>(iConfig.getParameter<edm::InputTag>
185  ("esReducedRecHitCollectionMiniAOD"));
186 
187  } else {
188  usesES_ = false;
189  }
190 
191  vtxToken_ = mayConsume<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("vertices"));
192  vtxTokenMiniAOD_ = mayConsume<reco::VertexCollection>(iConfig.getParameter<edm::InputTag>("verticesMiniAOD"));
193 
194  // reco photons are castable into pat photons, so no need to handle reco/pat seprately
195  src_ = mayConsume<edm::View<reco::Photon> >(iConfig.getParameter<edm::InputTag>("src"));
196  srcMiniAOD_ = mayConsume<edm::View<reco::Photon> >(iConfig.getParameter<edm::InputTag>("srcMiniAOD"));
197 
198  // The particleBasedIsolation object is relevant only for AOD, RECO format
199  particleBasedIsolationToken_ = mayConsume<edm::ValueMap<std::vector<reco::PFCandidateRef > > >
200  (iConfig.getParameter<edm::InputTag>("particleBasedIsolation"));
201 
202  // AOD has reco::PFCandidate vector, and miniAOD has pat::PackedCandidate vector.
203  // Both inherit from reco::Candidate, so we go to the base class. We can cast into
204  // the full type later if needed. Since the collection names are different, we
205  // introduce both collections
206  pfCandidatesToken_ = mayConsume< edm::View<reco::Candidate> >(iConfig.getParameter<edm::InputTag>("pfCandidates"));
207  pfCandidatesTokenMiniAOD_ = mayConsume< edm::View<reco::Candidate> >(iConfig.getParameter<edm::InputTag>("pfCandidatesMiniAOD"));
208 
209  //
210  // Declare producibles
211  //
212  // Cluster shapes
213  produces<edm::ValueMap<float> >(phoFull5x5SigmaIEtaIEta_);
214  produces<edm::ValueMap<float> >(phoFull5x5SigmaIEtaIPhi_);
215  produces<edm::ValueMap<float> >(phoFull5x5E1x3_);
216  produces<edm::ValueMap<float> >(phoFull5x5E2x2_);
217  produces<edm::ValueMap<float> >(phoFull5x5E2x5Max_);
218  produces<edm::ValueMap<float> >(phoFull5x5E5x5_);
219  produces<edm::ValueMap<float> >(phoESEffSigmaRR_);
220  // Cluster shape ratios
221  produces<edm::ValueMap<float> >(phoFull5x5E1x3byE5x5_);
222  produces<edm::ValueMap<float> >(phoFull5x5E2x2byE5x5_);
223  produces<edm::ValueMap<float> >(phoFull5x5E2x5byE5x5_);
224  // Isolations
225  produces<edm::ValueMap<float> >(phoChargedIsolation_);
226  produces<edm::ValueMap<float> >(phoNeutralHadronIsolation_);
227  produces<edm::ValueMap<float> >(phoPhotonIsolation_);
228  produces<edm::ValueMap<float> >(phoWorstChargedIsolation_);
229  produces<edm::ValueMap<float> >(phoWorstChargedIsolationWithConeVeto_);
230  produces<edm::ValueMap<float> >(phoWorstChargedIsolationWithPVConstraint_);
231  produces<edm::ValueMap<float> >(phoWorstChargedIsolationWithConeVetoWithPVConstraint_);
232 
233  //PFCluster Isolations
234  produces<edm::ValueMap<float> >(phoTrkIsolation_);
235  produces<edm::ValueMap<float> >(phoHcalPFClIsolation_);
236  produces<edm::ValueMap<float> >(phoEcalPFClIsolation_);
237 
238 
239 }
240 
242 }
243 
245 
246  using namespace edm;
247 
248  // Constants
249  const float coneSizeDR = 0.3;
250  const float dxyMax = 0.1;
251  const float dzMax = 0.2;
252 
254 
255  bool isAOD = true;
256  iEvent.getByToken(src_, src);
257  if( !src.isValid() ){
258  isAOD = false;
259  iEvent.getByToken(srcMiniAOD_,src);
260  }
261  if( !src.isValid() ) {
262  throw cms::Exception("IllDefinedDataTier")
263  << "DataFormat does not contain a photon source!";
264  }
265 
266  // Configure Lazy Tools
267  if (usesES_) {
268  if( isAOD )
269  lazyToolnoZS = std::make_unique<noZS::EcalClusterLazyTools>(iEvent, iSetup,
273  else
274  lazyToolnoZS = std::make_unique<noZS::EcalClusterLazyTools>(iEvent, iSetup,
278  } else {
279  if( isAOD )
280  lazyToolnoZS = std::make_unique<noZS::EcalClusterLazyTools>(iEvent, iSetup,
283  else
284  lazyToolnoZS = std::make_unique<noZS::EcalClusterLazyTools>(iEvent, iSetup,
287 
288  }
289 
290  // Get PV
292  iEvent.getByToken(vtxToken_, vertices);
293  if( !vertices.isValid() )
294  iEvent.getByToken(vtxTokenMiniAOD_, vertices);
295  if (vertices->empty()) return; // skip the event if no PV found
296  const reco::Vertex &pv = vertices->front();
297 
299  if( isAOD ){
300  // this exists only in AOD
301  iEvent.getByToken(particleBasedIsolationToken_, particleBasedIsolationMap);
302  }
303 
304  edm::Handle< edm::View<reco::Candidate> > pfCandidatesHandle;
305 
306  iEvent.getByToken(pfCandidatesToken_, pfCandidatesHandle);
307  if( !pfCandidatesHandle.isValid() )
308  iEvent.getByToken(pfCandidatesTokenMiniAOD_, pfCandidatesHandle);
309 
310  if( !isAOD && !src->empty() ) {
311  edm::Ptr<pat::Photon> test(src->ptrAt(0));
312  if( test.isNull() || !test.isAvailable() ) {
313  throw cms::Exception("InvalidConfiguration")
314  <<"DataFormat is detected as miniAOD but cannot cast to pat::Photon!";
315  }
316  }
317 
318  // size_t n = src->size();
319  // Cluster shapes
320  std::vector<float> phoFull5x5SigmaIEtaIEta;
321  std::vector<float> phoFull5x5SigmaIEtaIPhi;
322  std::vector<float> phoFull5x5E1x3;
323  std::vector<float> phoFull5x5E2x2;
324  std::vector<float> phoFull5x5E2x5Max;
325  std::vector<float> phoFull5x5E5x5;
326  std::vector<float> phoESEffSigmaRR;
327  // Cluster shape ratios
328  std::vector<float> phoFull5x5E1x3byE5x5;
329  std::vector<float> phoFull5x5E2x2byE5x5;
330  std::vector<float> phoFull5x5E2x5byE5x5;
331  // Isolations
332  std::vector<float> phoChargedIsolation;
333  std::vector<float> phoNeutralHadronIsolation;
334  std::vector<float> phoPhotonIsolation;
335  std::vector<float> phoWorstChargedIsolation;
336  std::vector<float> phoWorstChargedIsolationWithConeVeto;
337  std::vector<float> phoWorstChargedIsolationWithPVConstraint;
338  std::vector<float> phoWorstChargedIsolationWithConeVetoWithPVConstraint;
339 
340  //PFCluster Isolations
341  std::vector<float> phoTrkIsolation;
342  std::vector<float> phoHcalPFClIsolation;
343  std::vector<float> phoEcalPFClIsolation;
344 
345  // reco::Photon::superCluster() is virtual so we can exploit polymorphism
346  for (unsigned idxpho = 0; idxpho < src->size(); ++idxpho) {
347  const auto& iPho = src->ptrAt(idxpho);
348 
349  //
350  // Compute full 5x5 quantities
351  //
352  const auto& theseed = *(iPho->superCluster()->seed());
353 
354  // For full5x5_sigmaIetaIeta, for 720 we use: lazy tools for AOD,
355  // and userFloats or lazy tools for miniAOD. From some point in 72X and on, one can
356  // retrieve the full5x5 directly from the object with ->full5x5_sigmaIetaIeta()
357  // for both formats.
358  float see = -999;
359  std::vector<float> vCov = lazyToolnoZS->localCovariances( theseed );
360  see = (isnan(vCov[0]) ? 0. : sqrt(vCov[0]));
361  float sep = vCov[1];
362  phoFull5x5SigmaIEtaIEta.push_back(see);
363  phoFull5x5SigmaIEtaIPhi.push_back(sep);
364 
365  phoFull5x5E1x3 .push_back(lazyToolnoZS-> e1x3 (theseed) );
366  phoFull5x5E2x2 .push_back(lazyToolnoZS-> e2x2 (theseed) );
367  phoFull5x5E2x5Max.push_back(lazyToolnoZS-> e2x5Max(theseed) );
368  phoFull5x5E5x5 .push_back(lazyToolnoZS-> e5x5 (theseed) );
369 
370  phoFull5x5E1x3byE5x5.push_back(phoFull5x5E1x3[idxpho]/phoFull5x5E5x5[idxpho]);
371  phoFull5x5E2x2byE5x5.push_back(phoFull5x5E2x2[idxpho]/phoFull5x5E5x5[idxpho]);
372  phoFull5x5E2x5byE5x5.push_back(phoFull5x5E2x5Max[idxpho]/phoFull5x5E5x5[idxpho]);
373 
374  phoESEffSigmaRR .push_back(lazyToolnoZS->eseffsirir( *(iPho->superCluster()) ) );
375 
376  //
377  // Compute absolute uncorrected isolations with footprint removal
378  //
379 
380  // First, find photon direction with respect to the good PV
381  math::XYZVector photon_directionWrtVtx(iPho->superCluster()->x() - pv.x(),
382  iPho->superCluster()->y() - pv.y(),
383  iPho->superCluster()->z() - pv.z());
384 
385  //PFCluster Isolations
386  phoTrkIsolation .push_back( iPho->trkSumPtSolidConeDR04());
387  if (isAOD)
388  {
389  phoHcalPFClIsolation .push_back(0.f);
390  phoEcalPFClIsolation .push_back(0.f);
391  }
392  else
393  {
394  edm::Ptr<pat::Photon> patPhotonPtr(src->ptrAt(idxpho));
395  phoHcalPFClIsolation .push_back(patPhotonPtr->hcalPFClusterIso());
396  phoEcalPFClIsolation .push_back(patPhotonPtr->ecalPFClusterIso());
397  }
398 
399 
400  // Zero the isolation sums
401  float chargedIsoSum = 0;
402  float neutralHadronIsoSum = 0;
403  float photonIsoSum = 0;
404 
405  // Loop over all PF candidates
406  for (unsigned idxcand = 0; idxcand < pfCandidatesHandle->size(); ++idxcand ){
407 
408  // Here, the type will be a simple reco::Candidate. We cast it
409  // for full PFCandidate or PackedCandidate below as necessary
410  const auto& iCand = pfCandidatesHandle->ptrAt(idxcand);
411 
412  // One would think that we should check that this iCand from
413  // the generic PF collection is not identical to the iPho photon
414  // for which we are computing the isolations. However, it turns out
415  // to be unnecessary. Below, in the function isInFootprint(), we drop
416  // this iCand if it is in the footprint, and this always removes
417  // the iCand if it matches the iPho.
418  // The explicit check at this point is not totally trivial because
419  // of non-triviality of implementation of this check for miniAOD (PackedCandidates
420  // of the PF collection do not contain the supercluser link, so can't use that).
421  // if( isAOD ){
422  // if( ((const recoCandPtr)iCand)->superClusterRef() == iPho->superCluster() ) continue;
423  // }
424 
425 
426  // Check if this candidate is within the isolation cone
427  float dR2 = deltaR2(photon_directionWrtVtx.Eta(),photon_directionWrtVtx.Phi(),
428  iCand->eta(), iCand->phi());
429  if( dR2 > coneSizeDR*coneSizeDR ) continue;
430 
431  // Check if this candidate is not in the footprint
432  bool inFootprint = false;
433  if(isAOD) {
434  inFootprint = isInFootprint( (*particleBasedIsolationMap)[iPho], iCand );
435  } else {
436  edm::Ptr<pat::Photon> patPhotonPtr(src->ptrAt(idxpho));
437  inFootprint = isInFootprint(patPhotonPtr->associatedPackedPFCandidates(), iCand);
438  }
439 
440  if( inFootprint ) continue;
441 
442  // Find candidate type
443  reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(iCand, isAOD);
444 
445  // Increment the appropriate isolation sum
446  if( thisCandidateType == reco::PFCandidate::h ){
447  // for charged hadrons, additionally check consistency
448  // with the PV
449  float dxy = -999, dz=-999;
450  getImpactParameters(iCand, isAOD, pv, dxy, dz);
451 
452 
453  if(fabs(dxy) > dxyMax) continue;
454  if (fabs(dz) > dzMax) continue;
455 
456  // The candidate is eligible, increment the isolaiton
457  chargedIsoSum += iCand->pt();
458  }
459 
460  if( thisCandidateType == reco::PFCandidate::h0 )
461  neutralHadronIsoSum += iCand->pt();
462 
463  if( thisCandidateType == reco::PFCandidate::gamma )
464  photonIsoSum += iCand->pt();
465  }
466 
467  phoChargedIsolation .push_back( chargedIsoSum );
468  phoNeutralHadronIsolation.push_back( neutralHadronIsoSum );
469  phoPhotonIsolation .push_back( photonIsoSum );
470 
471  // Worst isolation computed with no vetos or ptMin cut, as in
472  // Run 1 Hgg code.
473  float dRvetoBarrel = 0.0;
474  float dRvetoEndcap = 0.0;
475  float ptMin = 0.0;
476  bool isPVConstraint=false;
477  float worstChargedIso =
478  computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices,
479  isAOD, isPVConstraint,pv,coneSizeDR, dxyMax, dzMax,
480  dRvetoBarrel, dRvetoEndcap, ptMin);
481  phoWorstChargedIsolation .push_back( worstChargedIso );
482 
483  // Worst isolation computed with cone vetos and a ptMin cut, as in
484  // Run 2 Hgg code.
485  dRvetoBarrel = 0.02;
486  dRvetoEndcap = 0.02;
487  ptMin = 0.1;
488  float worstChargedIsoWithConeVeto =
489  computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices,
490  isAOD, isPVConstraint,pv, coneSizeDR, dxyMax, dzMax,
491  dRvetoBarrel, dRvetoEndcap, ptMin);
492  phoWorstChargedIsolationWithConeVeto .push_back( worstChargedIsoWithConeVeto );
493 
494  isPVConstraint=true;
495  float worstChargedIsoWithPVConstraint =
496  computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices,
497  isAOD, isPVConstraint,pv,coneSizeDR, dxyMax, dzMax,
498  dRvetoBarrel, dRvetoEndcap, ptMin);
499  phoWorstChargedIsolationWithPVConstraint .push_back( worstChargedIsoWithPVConstraint );
500 
501  // Worst isolation computed with cone vetos and a ptMin cut, as in
502  // Run 2 Hgg code.
503  dRvetoBarrel = 0.02;
504  dRvetoEndcap = 0.02;
505  ptMin = 0.1;
506  float worstChargedIsoWithConeVetoWithPVConstraint =
507  computeWorstPFChargedIsolation(iPho, pfCandidatesHandle, vertices,
508  isAOD,isPVConstraint, pv, coneSizeDR, dxyMax, dzMax,
509  dRvetoBarrel, dRvetoEndcap, ptMin);
510  phoWorstChargedIsolationWithConeVetoWithPVConstraint .push_back( worstChargedIsoWithConeVetoWithPVConstraint );
511 
512 
513 
514  }
515 
516  // Cluster shapes
517  writeValueMap(iEvent, src, phoFull5x5SigmaIEtaIEta, phoFull5x5SigmaIEtaIEta_);
518  writeValueMap(iEvent, src, phoFull5x5SigmaIEtaIPhi, phoFull5x5SigmaIEtaIPhi_);
519  writeValueMap(iEvent, src, phoFull5x5E1x3 , phoFull5x5E1x3_);
520  writeValueMap(iEvent, src, phoFull5x5E2x2 , phoFull5x5E2x2_);
521  writeValueMap(iEvent, src, phoFull5x5E2x5Max, phoFull5x5E2x5Max_);
522  writeValueMap(iEvent, src, phoFull5x5E5x5 , phoFull5x5E5x5_);
523  writeValueMap(iEvent, src, phoESEffSigmaRR , phoESEffSigmaRR_);
524  // Cluster shape ratios
525  writeValueMap(iEvent, src, phoFull5x5E1x3byE5x5 , phoFull5x5E1x3byE5x5_);
526  writeValueMap(iEvent, src, phoFull5x5E2x2byE5x5 , phoFull5x5E2x2byE5x5_);
527  writeValueMap(iEvent, src, phoFull5x5E2x5byE5x5 , phoFull5x5E2x5byE5x5_);
528  // Isolation
529  writeValueMap(iEvent, src, phoChargedIsolation, phoChargedIsolation_);
530  writeValueMap(iEvent, src, phoNeutralHadronIsolation, phoNeutralHadronIsolation_);
531  writeValueMap(iEvent, src, phoPhotonIsolation, phoPhotonIsolation_);
532  writeValueMap(iEvent, src, phoWorstChargedIsolation, phoWorstChargedIsolation_);
533  writeValueMap(iEvent, src, phoWorstChargedIsolationWithConeVeto, phoWorstChargedIsolationWithConeVeto_);
534  writeValueMap(iEvent, src, phoWorstChargedIsolationWithPVConstraint, phoWorstChargedIsolationWithPVConstraint_);
535  writeValueMap(iEvent, src, phoWorstChargedIsolationWithConeVetoWithPVConstraint, phoWorstChargedIsolationWithConeVetoWithPVConstraint_);
536  //PFCluster Isolation
537  writeValueMap(iEvent, src, phoTrkIsolation, phoTrkIsolation_);
538  writeValueMap(iEvent, src, phoHcalPFClIsolation, phoHcalPFClIsolation_);
539  writeValueMap(iEvent, src, phoEcalPFClIsolation, phoEcalPFClIsolation_);
540 
541 }
542 
545  const std::vector<float> & values,
546  const std::string & label) const
547 {
548  using namespace edm;
549  using namespace std;
550  auto valMap = std::make_unique<ValueMap<float>>();
552  filler.insert(handle, values.begin(), values.end());
553  filler.fill();
554  iEvent.put(std::move(valMap), label);
555 }
556 
558  //The following says we do not know what parameters are allowed so do no validation
559  // Please change this to state exactly what you do use, even if it is no parameters
561  desc.setUnknown();
562  descriptions.addDefault(desc);
563 }
564 
565 // Charged isolation with respect to the worst vertex. See more
566 // comments above at the function declaration.
567 template <class T, class U>
571  bool isAOD, bool isPVConstraint,const reco::Vertex& pv,
572  float dRmax, float dxyMax, float dzMax,
573  float dRvetoBarrel, float dRvetoEndcap, float ptMin){
574 
575 
576  float worstIsolation = 999;
577  std::vector<float> allIsolations;
578 
579  float dRveto;
580  if (photon->isEB())
581  dRveto = dRvetoBarrel;
582  else
583  dRveto = dRvetoEndcap;
584 
585  //Calculate isolation sum separately for each vertex
586  for(unsigned int ivtx=0; ivtx<vertices->size(); ++ivtx) {
587 
588  // Shift the photon according to the vertex
589  reco::VertexRef vtx(vertices, ivtx);
590  math::XYZVector photon_directionWrtVtx(photon->superCluster()->x() - vtx->x(),
591  photon->superCluster()->y() - vtx->y(),
592  photon->superCluster()->z() - vtx->z());
593 
594  float sum = 0;
595  // Loop over the PFCandidates
596  for(unsigned i=0; i<pfCandidates->size(); i++) {
597 
598  const auto& iCand = pfCandidates->ptrAt(i);
599 
600  //require that PFCandidate is a charged hadron
601  reco::PFCandidate::ParticleType thisCandidateType = candidatePdgId(iCand, isAOD);
602  if (thisCandidateType != reco::PFCandidate::h)
603  continue;
604 
605  if (iCand->pt() < ptMin)
606  continue;
607 
608  float dxy=-999, dz=-999;
609  if(isPVConstraint) getImpactParameters(iCand, isAOD, pv, dxy, dz);
610  else getImpactParameters(iCand, isAOD, *vtx, dxy, dz);
611 
612 
613 
614  if( fabs(dxy) > dxyMax) continue;
615  if ( fabs(dz) > dzMax) continue;
616 
617  float dR2 = deltaR2(photon_directionWrtVtx.Eta(), photon_directionWrtVtx.Phi(),
618  iCand->eta(), iCand->phi());
619  if(dR2 > dRmax*dRmax || dR2 < dRveto*dRveto) continue;
620 
621  sum += iCand->pt();
622  }
623 
624  allIsolations.push_back(sum);
625  }
626 
627  if( !allIsolations.empty() )
628  worstIsolation = * std::max_element( allIsolations.begin(), allIsolations.end() );
629 
630  return worstIsolation;
631 }
632 
633 
636  bool isAOD){
637 
639  if( isAOD )
640  thisCandidateType = ( (const recoCandPtr)candidate)->particleId();
641  else {
642  // the neutral hadrons and charged hadrons can be of pdgId types
643  // only 130 (K0L) and +-211 (pi+-) in packed candidates
644  const int pdgId = ( (const patCandPtr)candidate)->pdgId();
645  if( pdgId == 22 )
646  thisCandidateType = reco::PFCandidate::gamma;
647  else if( abs(pdgId) == 130) // PDG ID for K0L
648  thisCandidateType = reco::PFCandidate::h0;
649  else if( abs(pdgId) == 211) // PDG ID for pi+-
650  thisCandidateType = reco::PFCandidate::h;
651  }
652  return thisCandidateType;
653 }
654 
655 const reco::Track*
657 
658  const reco::Track* theTrack = nullptr;
659  if( isAOD )
660  theTrack = &*( ((const recoCandPtr) candidate)->trackRef());
661  else
662  theTrack = &( ((const patCandPtr) candidate)->pseudoTrack());
663 
664  return theTrack;
665 }
666 
668  bool isAOD, const reco::Vertex& pv,
669  float &dxy, float &dz){
670 
671  dxy=-999;
672  dz=-999;
673  if( isAOD ) {
674  const reco::Track *theTrack = &*( ((const recoCandPtr) candidate)->trackRef());
675  dxy = theTrack->dxy(pv.position());
676  dz = theTrack->dz(pv.position());
677  } else {
678  const pat::PackedCandidate & aCand = *(patCandPtr(candidate));
679  dxy = aCand.dxy(pv.position());
680  dz = aCand.dz(pv.position());
681 
682  }
683 
684 }
685 
virtual float dz(size_t ipv=0) const
dz with respect to the PV[ipv]
void writeValueMap(edm::Event &iEvent, const edm::Handle< edm::View< reco::Photon > > &handle, const std::vector< float > &values, const std::string &label) const
T getParameter(std::string const &) const
edm::EDGetTokenT< EcalRecHitCollection > esReducedRecHitCollectionMiniAOD_
const reco::Track * getTrackPointer(const edm::Ptr< reco::Candidate > candidate, bool isAOD)
edm::EDGetTokenT< reco::VertexCollection > vtxToken_
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:137
ParticleType
particle types
Definition: PFCandidate.h:45
edm::EDGetTokenT< reco::VertexCollection > vtxTokenMiniAOD_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:579
std::unique_ptr< noZS::EcalClusterLazyTools > lazyToolnoZS
edm::EDGetTokenT< EcalRecHitCollection > eeReducedRecHitCollectionMiniAOD_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
double y() const
y coordinate
Definition: Vertex.h:113
reco::PFCandidate::ParticleType candidatePdgId(const edm::Ptr< reco::Candidate > candidate, bool isAOD)
edm::EDGetTokenT< EcalRecHitCollection > ebReducedRecHitCollection_
PhotonIDValueMapProducer(const edm::ParameterSet &)
edm::EDGetTokenT< edm::ValueMap< std::vector< reco::PFCandidateRef > > > particleBasedIsolationToken_
edm::EDGetTokenT< edm::ValueMap< std::vector< reco::PFCandidateRef > > > particleBasedIsolationTokenMiniAOD_
edm::EDGetTokenT< EcalRecHitCollection > ebReducedRecHitCollectionMiniAOD_
const Point & position() const
position
Definition: Vertex.h:109
#define constexpr
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
int iEvent
Definition: GenABIO.cc:230
edm::EDGetTokenT< edm::View< reco::Candidate > > pfCandidatesTokenMiniAOD_
void addDefault(ParameterSetDescription const &psetDescription)
edm::EDGetTokenT< EcalRecHitCollection > eeReducedRecHitCollection_
bool isnan(float x)
Definition: math.h:13
T sqrt(T t)
Definition: SSEVec.h:18
bool isInFootprint(const T &thefootprint, const U &theCandidate)
edm::Ptr< pat::PackedCandidate > patCandPtr
def pv(vc)
Definition: MetAnalyzer.py:6
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
double z() const
z coordinate
Definition: Vertex.h:115
edm::EDGetTokenT< edm::View< reco::Candidate > > pfCandidatesToken_
void produce(edm::Event &, const edm::EventSetup &) override
double f[11][100]
bool isValid() const
Definition: HandleBase.h:74
double dz() const
dz parameter (= dsz/cos(lambda)). This is the track z0 w.r.t (0,0,0) only if the refPoint is close to...
Definition: TrackBase.h:609
double x() const
x coordinate
Definition: Vertex.h:111
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
edm::EDGetTokenT< EcalRecHitCollection > esReducedRecHitCollection_
static char phoWorstChargedIsolationWithConeVetoWithPVConstraint_[]
float computeWorstPFChargedIsolation(const T &photon, const U &pfCandidates, const edm::Handle< reco::VertexCollection > vertices, bool isAOD, bool isPVConstraint, const reco::Vertex &pv, float dRmax, float dxyMax, float dzMax, float dRvetoBarrel, float dRvetoEndcap, float ptMin)
std::string const & label() const
Definition: InputTag.h:36
edm::Ptr< pat::Photon > patPhotonPtr
static char phoWorstChargedIsolationWithPVConstraint_[]
HLT enums.
virtual float dxy() const
dxy with respect to the PV ref
void getImpactParameters(const edm::Ptr< reco::Candidate > &candidate, bool isAOD, const reco::Vertex &pv, float &dxy, float &dz)
double dxy() const
dxy parameter. (This is the transverse impact parameter w.r.t. to (0,0,0) ONLY if refPoint is close t...
Definition: TrackBase.h:591
long double T
edm::Ptr< reco::PFCandidate > recoCandPtr
static char phoWorstChargedIsolationWithConeVeto_[]
def move(src, dest)
Definition: eostools.py:510