CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
GEDPhotonProducer.cc
Go to the documentation of this file.
1 
53 
54 class CacheData {
55 public:
57  // Here we will have to load the DNN PFID if present in the config
59  const auto& pset_dnn = conf.getParameter<edm::ParameterSet>("PhotonDNNPFid");
60  const auto dnnEnabled = pset_dnn.getParameter<bool>("enabled");
61  if (dnnEnabled) {
62  config.inputTensorName = pset_dnn.getParameter<std::string>("inputTensorName");
63  config.outputTensorName = pset_dnn.getParameter<std::string>("outputTensorName");
64  config.modelsFiles = pset_dnn.getParameter<std::vector<std::string>>("modelsFiles");
65  config.scalersFiles = pset_dnn.getParameter<std::vector<std::string>>("scalersFiles");
66  config.outputDim = pset_dnn.getParameter<uint>("outputDim");
67  const auto useEBModelInGap = pset_dnn.getParameter<bool>("useEBModelInGap");
68  photonDNNEstimator = std::make_unique<PhotonDNNEstimator>(config, useEBModelInGap);
69  }
70  }
71  std::unique_ptr<const PhotonDNNEstimator> photonDNNEstimator;
72 };
73 
74 class GEDPhotonProducer : public edm::stream::EDProducer<edm::GlobalCache<CacheData>> {
75 public:
76  GEDPhotonProducer(const edm::ParameterSet& ps, const CacheData* gcache);
77 
78  void produce(edm::Event& evt, const edm::EventSetup& es) override;
79 
80  static std::unique_ptr<CacheData> initializeGlobalCache(const edm::ParameterSet&);
81  static void globalEndJob(const CacheData*){};
82 
83  void endStream() override;
84 
85 private:
86  class RecoStepInfo {
87  public:
88  enum FlagBits { kOOT = 0x1, kFinal = 0x2 };
89  explicit RecoStepInfo(const std::string& recoStep);
90 
91  bool isOOT() const { return flags_ & kOOT; }
92  bool isFinal() const { return flags_ & kFinal; }
93 
94  private:
95  unsigned int flags_;
96  };
97 
99  edm::EventSetup const& es,
100  const edm::Handle<reco::PhotonCoreCollection>& photonCoreHandle,
101  const CaloTopology* topology,
102  const EcalRecHitCollection* ecalBarrelHits,
103  const EcalRecHitCollection* ecalEndcapHits,
105  const ElectronHcalHelper* hcalHelperCone,
106  const ElectronHcalHelper* hcalHelperBc,
107  const reco::VertexCollection& pvVertices,
108  reco::PhotonCollection& outputCollection,
109  int& iSC,
111 
113  edm::EventSetup const& es,
114  const edm::Handle<reco::PhotonCollection>& photonHandle,
115  const edm::Handle<reco::PFCandidateCollection> pfCandidateHandle,
116  const edm::Handle<reco::PFCandidateCollection> pfEGCandidateHandle,
117  reco::VertexCollection const& pvVertices,
118  reco::PhotonCollection& outputCollection,
119  int& iSC,
120  const edm::Handle<edm::ValueMap<float>>& chargedHadrons,
121  const edm::Handle<edm::ValueMap<float>>& neutralHadrons,
123  const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtx,
124  const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtxGeomVeto,
125  const edm::Handle<edm::ValueMap<float>>& chargedHadronsPFPV,
126  const edm::Handle<edm::ValueMap<float>>& pfEcalClusters,
127  const edm::Handle<edm::ValueMap<float>>& pfHcalClusters);
128 
129  // std::string PhotonCoreCollection_;
132 
142  //for isolation with map-based veto
144  //photon isolation sums
151 
154 
156 
158 
159  std::unique_ptr<PhotonIsolationCalculator> photonIsoCalculator_ = nullptr;
160 
161  //AA
162  //Flags and severities to be excluded from calculations
163 
164  std::vector<int> flagsexclEB_;
165  std::vector<int> flagsexclEE_;
166  std::vector<int> severitiesexclEB_;
167  std::vector<int> severitiesexclEE_;
168 
169  double multThresEB_;
170  double multThresEE_;
173  double highEt_;
174  double minR9Barrel_;
175  double minR9Endcap_;
177 
179 
181 
182  CaloGeometry const* caloGeom_ = nullptr;
183 
184  //MIP
185  std::unique_ptr<PhotonMIPHaloTagger> photonMIPHaloTagger_ = nullptr;
186 
187  std::vector<double> preselCutValuesBarrel_;
188  std::vector<double> preselCutValuesEndcap_;
189 
190  std::unique_ptr<PhotonEnergyCorrector> photonEnergyCorrector_ = nullptr;
192 
196 
197  // additional configuration and helpers
198  std::unique_ptr<ElectronHcalHelper> hcalHelperCone_;
199  std::unique_ptr<ElectronHcalHelper> hcalHelperBc_;
201 
202  // DNN for PFID photon enabled
204  std::vector<tensorflow::Session*> tfSessions_;
205 
206  double ecaldrMax_;
214  std::unique_ptr<PhotonEcalPFClusterIsolation> ecalisoAlgo = nullptr;
216 
217  bool useHF_;
218  double hcaldrMax_;
225  double hcaluseEt_;
226 
230 
232  std::unique_ptr<PhotonHcalPFClusterIsolation> hcalisoAlgo = nullptr;
233 };
234 
237 
238 namespace {
239  inline double ptFast(const double energy, const math::XYZPoint& position, const math::XYZPoint& origin) {
240  const auto v = position - origin;
241  return energy * std::sqrt(v.perp2() / v.mag2());
242  }
243 } // namespace
244 
246  if (step == "final")
247  flags_ = kFinal;
248  else if (step == "oot")
249  flags_ = kOOT;
250  else if (step == "ootfinal")
251  flags_ = (kOOT | kFinal);
252  else if (step == "tmp")
253  flags_ = 0;
254  else {
255  throw cms::Exception("InvalidConfig")
256  << " reconstructStep " << step << " is invalid, the options are: tmp, final,oot or ootfinal" << std::endl;
257  }
258 }
259 
261  : photonProducer_{config.getParameter<edm::InputTag>("photonProducer")},
262  ecalClusterESGetTokens_{consumesCollector()},
263  recoStep_(config.getParameter<std::string>("reconstructionStep")),
267  hcalHelperCone_(nullptr),
268  hcalHelperBc_(nullptr) {
269  if (recoStep_.isFinal()) {
270  photonProducerT_ = consumes(photonProducer_);
271  pfCandidates_ = consumes(config.getParameter<edm::InputTag>("pfCandidates"));
272 
273  const edm::ParameterSet& pfIsolCfg = config.getParameter<edm::ParameterSet>("pfIsolCfg");
274  auto getVMToken = [&pfIsolCfg, this](const std::string& name) {
275  return consumes(pfIsolCfg.getParameter<edm::InputTag>(name));
276  };
277  phoChargedIsolationToken_ = getVMToken("chargedHadronIso");
278  phoNeutralHadronIsolationToken_ = getVMToken("neutralHadronIso");
279  phoPhotonIsolationToken_ = getVMToken("photonIso");
280  phoChargedWorstVtxIsoToken_ = getVMToken("chargedHadronWorstVtxIso");
281  phoChargedWorstVtxGeomVetoIsoToken_ = getVMToken("chargedHadronWorstVtxGeomVetoIso");
282  phoChargedPFPVIsoToken_ = getVMToken("chargedHadronPFPVIso");
283 
284  //OOT photons in legacy 80X re-miniAOD do not have PF cluster embeded into the reco object
285  //to preserve 80X behaviour
286  if (config.exists("pfECALClusIsolation")) {
287  phoPFECALClusIsolationToken_ = consumes(config.getParameter<edm::InputTag>("pfECALClusIsolation"));
288  }
289  if (config.exists("pfHCALClusIsolation")) {
290  phoPFHCALClusIsolationToken_ = consumes(config.getParameter<edm::InputTag>("pfHCALClusIsolation"));
291  }
292 
293  } else {
295  }
296 
297  auto pfEg = config.getParameter<edm::InputTag>("pfEgammaCandidates");
298  if (not pfEg.label().empty()) {
299  pfEgammaCandidates_ = consumes(pfEg);
300  }
301  barrelEcalHits_ = consumes(config.getParameter<edm::InputTag>("barrelEcalHits"));
302  endcapEcalHits_ = consumes(config.getParameter<edm::InputTag>("endcapEcalHits"));
303  preshowerHits_ = consumes(config.getParameter<edm::InputTag>("preshowerHits"));
304  vertexProducer_ = consumes(config.getParameter<edm::InputTag>("primaryVertexProducer"));
305 
306  auto hbhetag = config.getParameter<edm::InputTag>("hbheRecHits");
307  if (not hbhetag.label().empty())
308  hbheRecHits_ = consumes<HBHERecHitCollection>(hbhetag);
309 
310  //
311  photonCollection_ = config.getParameter<std::string>("outputPhotonCollection");
312  multThresEB_ = config.getParameter<double>("multThresEB");
313  multThresEE_ = config.getParameter<double>("multThresEE");
314  hOverEConeSize_ = config.getParameter<double>("hOverEConeSize");
315  highEt_ = config.getParameter<double>("highEt");
316  // R9 value to decide converted/unconverted
317  minR9Barrel_ = config.getParameter<double>("minR9Barrel");
318  minR9Endcap_ = config.getParameter<double>("minR9Endcap");
319  usePrimaryVertex_ = config.getParameter<bool>("usePrimaryVertex");
320  runMIPTagger_ = config.getParameter<bool>("runMIPTagger");
321 
322  candidateP4type_ = config.getParameter<std::string>("candidateP4type");
323  valueMapPFCandPhoton_ = config.getParameter<std::string>("valueMapPhotons");
324 
325  //AA
326  //Flags and Severities to be excluded from photon calculations
327  auto const& flagnamesEB = config.getParameter<std::vector<std::string>>("RecHitFlagToBeExcludedEB");
328  auto const& flagnamesEE = config.getParameter<std::vector<std::string>>("RecHitFlagToBeExcludedEE");
329 
330  flagsexclEB_ = StringToEnumValue<EcalRecHit::Flags>(flagnamesEB);
331  flagsexclEE_ = StringToEnumValue<EcalRecHit::Flags>(flagnamesEE);
332 
333  auto const& severitynamesEB = config.getParameter<std::vector<std::string>>("RecHitSeverityToBeExcludedEB");
334  auto const& severitynamesEE = config.getParameter<std::vector<std::string>>("RecHitSeverityToBeExcludedEE");
335 
336  severitiesexclEB_ = StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesEB);
337  severitiesexclEE_ = StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesEE);
338 
339  photonEnergyCorrector_ = std::make_unique<PhotonEnergyCorrector>(config, consumesCollector());
340 
341  checkHcalStatus_ = config.getParameter<bool>("checkHcalStatus");
342  if (not hbheRecHits_.isUninitialized()) {
343  ElectronHcalHelper::Configuration cfgCone, cfgBc;
345  if (cfgCone.hOverEConeSize > 0) {
346  cfgCone.onlyBehindCluster = false;
348 
349  cfgCone.hbheRecHits = hbheRecHits_;
350 
351  cfgCone.eThresHB = config.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
352  cfgCone.maxSeverityHB = config.getParameter<int>("maxHcalRecHitSeverity");
353  cfgCone.eThresHE = config.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
354  cfgCone.maxSeverityHE = cfgCone.maxSeverityHB;
355  }
356  cfgBc.hOverEConeSize = 0.;
357  cfgBc.onlyBehindCluster = true;
359 
360  cfgBc.hbheRecHits = hbheRecHits_;
361 
362  cfgBc.eThresHB = config.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
363  cfgBc.maxSeverityHB = config.getParameter<int>("maxHcalRecHitSeverity");
364  cfgBc.eThresHE = config.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
365  cfgBc.maxSeverityHE = cfgBc.maxSeverityHB;
366 
367  hcalHelperCone_ = std::make_unique<ElectronHcalHelper>(cfgCone, consumesCollector());
368  hcalHelperBc_ = std::make_unique<ElectronHcalHelper>(cfgBc, consumesCollector());
369  }
370 
371  hcalRun2EffDepth_ = config.getParameter<bool>("hcalRun2EffDepth");
372 
373  // cut values for pre-selection
374  preselCutValuesBarrel_ = {config.getParameter<double>("minSCEtBarrel"),
375  config.getParameter<double>("maxHoverEBarrel"),
376  config.getParameter<double>("ecalRecHitSumEtOffsetBarrel"),
377  config.getParameter<double>("ecalRecHitSumEtSlopeBarrel"),
378  config.getParameter<double>("hcalRecHitSumEtOffsetBarrel"),
379  config.getParameter<double>("hcalRecHitSumEtSlopeBarrel"),
380  config.getParameter<double>("nTrackSolidConeBarrel"),
381  config.getParameter<double>("nTrackHollowConeBarrel"),
382  config.getParameter<double>("trackPtSumSolidConeBarrel"),
383  config.getParameter<double>("trackPtSumHollowConeBarrel"),
384  config.getParameter<double>("sigmaIetaIetaCutBarrel")};
385  //
386  preselCutValuesEndcap_ = {config.getParameter<double>("minSCEtEndcap"),
387  config.getParameter<double>("maxHoverEEndcap"),
388  config.getParameter<double>("ecalRecHitSumEtOffsetEndcap"),
389  config.getParameter<double>("ecalRecHitSumEtSlopeEndcap"),
390  config.getParameter<double>("hcalRecHitSumEtOffsetEndcap"),
391  config.getParameter<double>("hcalRecHitSumEtSlopeEndcap"),
392  config.getParameter<double>("nTrackSolidConeEndcap"),
393  config.getParameter<double>("nTrackHollowConeEndcap"),
394  config.getParameter<double>("trackPtSumSolidConeEndcap"),
395  config.getParameter<double>("trackPtSumHollowConeEndcap"),
396  config.getParameter<double>("sigmaIetaIetaCutEndcap")};
397  //
398 
399  //moved from beginRun to here, I dont see how this could cause harm as its just reading in the exactly same parameters each run
400  if (!recoStep_.isFinal()) {
401  photonIsoCalculator_ = std::make_unique<PhotonIsolationCalculator>();
402  edm::ParameterSet isolationSumsCalculatorSet = config.getParameter<edm::ParameterSet>("isolationSumsCalculatorSet");
403  photonIsoCalculator_->setup(isolationSumsCalculatorSet,
404  flagsexclEB_,
405  flagsexclEE_,
406  severitiesexclEB_,
407  severitiesexclEE_,
408  consumesCollector());
409  photonMIPHaloTagger_ = std::make_unique<PhotonMIPHaloTagger>();
410  edm::ParameterSet mipVariableSet = config.getParameter<edm::ParameterSet>("mipVariableSet");
411  photonMIPHaloTagger_->setup(mipVariableSet, consumesCollector());
412  }
413 
415  const edm::ParameterSet& pfECALClusIsolCfg = config.getParameter<edm::ParameterSet>("pfECALClusIsolCfg");
417  consumes<reco::PFClusterCollection>(pfECALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducer"));
418  ecaldrMax_ = pfECALClusIsolCfg.getParameter<double>("drMax");
419  ecaldrVetoBarrel_ = pfECALClusIsolCfg.getParameter<double>("drVetoBarrel");
420  ecaldrVetoEndcap_ = pfECALClusIsolCfg.getParameter<double>("drVetoEndcap");
421  ecaletaStripBarrel_ = pfECALClusIsolCfg.getParameter<double>("etaStripBarrel");
422  ecaletaStripEndcap_ = pfECALClusIsolCfg.getParameter<double>("etaStripEndcap");
423  ecalenergyBarrel_ = pfECALClusIsolCfg.getParameter<double>("energyBarrel");
424  ecalenergyEndcap_ = pfECALClusIsolCfg.getParameter<double>("energyEndcap");
425 
426  const edm::ParameterSet& pfHCALClusIsolCfg = config.getParameter<edm::ParameterSet>("pfHCALClusIsolCfg");
427  pfClusterProducerHCAL_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHCAL"));
428  pfClusterProducerHFEM_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFEM"));
429  pfClusterProducerHFHAD_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFHAD"));
430  useHF_ = pfHCALClusIsolCfg.getParameter<bool>("useHF");
431  hcaldrMax_ = pfHCALClusIsolCfg.getParameter<double>("drMax");
432  hcaldrVetoBarrel_ = pfHCALClusIsolCfg.getParameter<double>("drVetoBarrel");
433  hcaldrVetoEndcap_ = pfHCALClusIsolCfg.getParameter<double>("drVetoEndcap");
434  hcaletaStripBarrel_ = pfHCALClusIsolCfg.getParameter<double>("etaStripBarrel");
435  hcaletaStripEndcap_ = pfHCALClusIsolCfg.getParameter<double>("etaStripEndcap");
436  hcalenergyBarrel_ = pfHCALClusIsolCfg.getParameter<double>("energyBarrel");
437  hcalenergyEndcap_ = pfHCALClusIsolCfg.getParameter<double>("energyEndcap");
438  hcaluseEt_ = pfHCALClusIsolCfg.getParameter<bool>("useEt");
439 
440  // Register the product
441  produces<reco::PhotonCollection>(photonCollection_);
443  produces<edm::ValueMap<reco::PhotonRef>>(valueMapPFCandPhoton_);
444  }
445 
446  const auto& pset_dnn = config.getParameter<edm::ParameterSet>("PhotonDNNPFid");
447  dnnPFidEnabled_ = pset_dnn.getParameter<bool>("enabled");
448  if (dnnPFidEnabled_) {
449  tfSessions_ = gcache->photonDNNEstimator->getSessions();
450  }
451 }
452 
453 std::unique_ptr<CacheData> GEDPhotonProducer::initializeGlobalCache(const edm::ParameterSet& config) {
454  // this method is supposed to create, initialize and return a CacheData instance
455  return std::make_unique<CacheData>(config);
456 }
457 
459  for (auto session : tfSessions_) {
461  }
462 }
463 
464 void GEDPhotonProducer::produce(edm::Event& theEvent, const edm::EventSetup& eventSetup) {
465  using namespace edm;
466 
467  auto outputPhotonCollection_p = std::make_unique<reco::PhotonCollection>();
468  edm::ValueMap<reco::PhotonRef> pfEGCandToPhotonMap;
469 
470  // Get the PhotonCore collection
471  bool validPhotonCoreHandle = false;
472  Handle<reco::PhotonCoreCollection> photonCoreHandle;
473  bool validPhotonHandle = false;
474  Handle<reco::PhotonCollection> photonHandle;
475  //value maps for isolation
476  edm::Handle<edm::ValueMap<float>> phoChargedIsolationMap;
477  edm::Handle<edm::ValueMap<float>> phoNeutralHadronIsolationMap;
478  edm::Handle<edm::ValueMap<float>> phoPhotonIsolationMap;
479  edm::Handle<edm::ValueMap<float>> phoChargedWorstVtxIsoMap;
480  edm::Handle<edm::ValueMap<float>> phoChargedWorstVtxGeomVetoIsoMap;
481  edm::Handle<edm::ValueMap<float>> phoChargedPFPVIsoMap;
482 
483  edm::Handle<edm::ValueMap<float>> phoPFECALClusIsolationMap;
484  edm::Handle<edm::ValueMap<float>> phoPFHCALClusIsolationMap;
485 
486  if (recoStep_.isFinal()) {
487  theEvent.getByToken(photonProducerT_, photonHandle);
488  //get isolation objects
489  theEvent.getByToken(phoChargedIsolationToken_, phoChargedIsolationMap);
490  theEvent.getByToken(phoNeutralHadronIsolationToken_, phoNeutralHadronIsolationMap);
491  theEvent.getByToken(phoPhotonIsolationToken_, phoPhotonIsolationMap);
492  theEvent.getByToken(phoChargedWorstVtxIsoToken_, phoChargedWorstVtxIsoMap);
493  theEvent.getByToken(phoChargedWorstVtxGeomVetoIsoToken_, phoChargedWorstVtxGeomVetoIsoMap);
494  theEvent.getByToken(phoChargedPFPVIsoToken_, phoChargedPFPVIsoMap);
495 
496  //OOT photons in legacy 80X re-miniAOD workflow dont have cluster isolation embed in them
498  theEvent.getByToken(phoPFECALClusIsolationToken_, phoPFECALClusIsolationMap);
499  }
501  theEvent.getByToken(phoPFHCALClusIsolationToken_, phoPFHCALClusIsolationMap);
502  }
503 
504  if (photonHandle.isValid()) {
505  validPhotonHandle = true;
506  } else {
507  throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the product " << photonProducer_.label() << "\n";
508  }
509  } else {
510  theEvent.getByToken(photonCoreProducerT_, photonCoreHandle);
511  if (photonCoreHandle.isValid()) {
512  validPhotonCoreHandle = true;
513  } else {
514  throw cms::Exception("GEDPhotonProducer")
515  << "Error! Can't get the photonCoreProducer " << photonProducer_.label() << "\n";
516  }
517  }
518 
519  // Get EcalRecHits
520  auto const& barrelRecHits = theEvent.get(barrelEcalHits_);
521  auto const& endcapRecHits = theEvent.get(endcapEcalHits_);
522  auto const& preshowerRecHits = theEvent.get(preshowerHits_);
523 
524  Handle<reco::PFCandidateCollection> pfEGCandidateHandle;
525  // Get the PF refined cluster collection
527  theEvent.getByToken(pfEgammaCandidates_, pfEGCandidateHandle);
528  if (!pfEGCandidateHandle.isValid()) {
529  throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the pfEgammaCandidates";
530  }
531  }
532 
533  Handle<reco::PFCandidateCollection> pfCandidateHandle;
534 
535  if (recoStep_.isFinal()) {
536  // Get the PF candidates collection
537  theEvent.getByToken(pfCandidates_, pfCandidateHandle);
538  //OOT photons have no PF candidates so its not an error in this case
539  if (!pfCandidateHandle.isValid() && !recoStep_.isOOT()) {
540  throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the pfCandidates";
541  }
542  }
543 
544  // get the geometry from the event setup:
545  caloGeom_ = &eventSetup.getData(caloGeometryToken_);
546 
547  // prepare access to hcal data
548  if (hcalHelperCone_ != nullptr and hcalHelperBc_ != nullptr) {
549  hcalHelperCone_->beginEvent(theEvent, eventSetup);
550  hcalHelperBc_->beginEvent(theEvent, eventSetup);
551  }
552 
553  auto const& topology = eventSetup.getData(caloTopologyToken_);
554  auto const& thresholds = eventSetup.getData(ecalPFRechitThresholdsToken_);
555 
556  // Get the primary event vertex
557  const reco::VertexCollection dummyVC;
558  auto const& vertexCollection{usePrimaryVertex_ ? theEvent.get(vertexProducer_) : dummyVC};
559 
560  // math::XYZPoint vtx(0.,0.,0.);
561  //if (vertexCollection.size()>0) vtx = vertexCollection.begin()->position();
562 
563  // get the regression calculator ready
564  photonEnergyCorrector_->init(eventSetup);
565  if (photonEnergyCorrector_->gedRegression()) {
566  photonEnergyCorrector_->gedRegression()->setEvent(theEvent);
567  photonEnergyCorrector_->gedRegression()->setEventContent(eventSetup);
568  }
569 
571  ecalisoAlgo = std::make_unique<PhotonEcalPFClusterIsolation>(ecaldrMax_,
578 
579  hcalisoAlgo = std::make_unique<PhotonHcalPFClusterIsolation>(hcaldrMax_,
586  hcaluseEt_);
587 
588  int iSC = 0; // index in photon collection
589  // Loop over barrel and endcap SC collections and fill the photon collection
590  if (validPhotonCoreHandle)
591  fillPhotonCollection(theEvent,
592  eventSetup,
593  photonCoreHandle,
594  &topology,
595  &barrelRecHits,
596  &endcapRecHits,
597  &preshowerRecHits,
598  hcalHelperCone_.get(),
599  hcalHelperBc_.get(),
600  //vtx,
602  *outputPhotonCollection_p,
603  iSC,
604  thresholds);
605 
606  iSC = 0;
607  if (validPhotonHandle && recoStep_.isFinal())
608  fillPhotonCollection(theEvent,
609  eventSetup,
610  photonHandle,
611  pfCandidateHandle,
612  pfEGCandidateHandle,
613  theEvent.get(vertexProducer_),
614  *outputPhotonCollection_p,
615  iSC,
616  phoChargedIsolationMap,
617  phoNeutralHadronIsolationMap,
618  phoPhotonIsolationMap,
619  phoChargedWorstVtxIsoMap,
620  phoChargedWorstVtxGeomVetoIsoMap,
621  phoChargedPFPVIsoMap,
622  phoPFECALClusIsolationMap,
623  phoPFHCALClusIsolationMap);
624 
625  // put the product in the event
626  edm::LogInfo("GEDPhotonProducer") << " Put in the event " << iSC << " Photon Candidates \n";
627 
628  // go back to run2-like 2 effective depths if desired - depth 1 is the normal depth 1, depth 2 is the sum over the rest
629  if (hcalRun2EffDepth_) {
630  for (auto& pho : *outputPhotonCollection_p)
631  pho.hcalToRun2EffDepth();
632  }
633  const auto photonOrphHandle = theEvent.put(std::move(outputPhotonCollection_p), photonCollection_);
634 
637  auto pfEGCandToPhotonMap_p = std::make_unique<edm::ValueMap<reco::PhotonRef>>();
638  edm::ValueMap<reco::PhotonRef>::Filler filler(*pfEGCandToPhotonMap_p);
639  unsigned nObj = pfEGCandidateHandle->size();
640  std::vector<reco::PhotonRef> values(nObj);
642  for (unsigned int lCand = 0; lCand < nObj; lCand++) {
643  reco::PFCandidateRef pfCandRef(reco::PFCandidateRef(pfEGCandidateHandle, lCand));
644  reco::SuperClusterRef pfScRef = pfCandRef->superClusterRef();
645 
646  for (unsigned int lSC = 0; lSC < photonOrphHandle->size(); lSC++) {
647  reco::PhotonRef photonRef(reco::PhotonRef(photonOrphHandle, lSC));
648  reco::SuperClusterRef scRef = photonRef->superCluster();
649  if (pfScRef != scRef)
650  continue;
651  values[lCand] = photonRef;
652  }
653  }
654 
655  filler.insert(pfEGCandidateHandle, values.begin(), values.end());
656  filler.fill();
657  theEvent.put(std::move(pfEGCandToPhotonMap_p), valueMapPFCandPhoton_);
658  }
659 }
660 
662  edm::EventSetup const& es,
663  const edm::Handle<reco::PhotonCoreCollection>& photonCoreHandle,
664  const CaloTopology* topology,
665  const EcalRecHitCollection* ecalBarrelHits,
666  const EcalRecHitCollection* ecalEndcapHits,
668  const ElectronHcalHelper* hcalHelperCone,
669  const ElectronHcalHelper* hcalHelperBc,
671  reco::PhotonCollection& outputPhotonCollection,
672  int& iSC,
674  const EcalRecHitCollection* hits = nullptr;
675  std::vector<double> preselCutValues;
676  std::vector<int> flags_, severitiesexcl_;
677 
678  for (unsigned int lSC = 0; lSC < photonCoreHandle->size(); lSC++) {
679  reco::PhotonCoreRef coreRef(reco::PhotonCoreRef(photonCoreHandle, lSC));
680  reco::SuperClusterRef parentSCRef = coreRef->parentSuperCluster();
681  reco::SuperClusterRef scRef = coreRef->superCluster();
682 
683  // const reco::SuperCluster* pClus=&(*scRef);
684  iSC++;
685 
686  DetId::Detector thedet = scRef->seed()->hitsAndFractions()[0].first.det();
687  int subdet = scRef->seed()->hitsAndFractions()[0].first.subdetId();
688  if (subdet == EcalBarrel) {
689  preselCutValues = preselCutValuesBarrel_;
690  hits = ecalBarrelHits;
691  flags_ = flagsexclEB_;
692  severitiesexcl_ = severitiesexclEB_;
693  } else if (subdet == EcalEndcap) {
694  preselCutValues = preselCutValuesEndcap_;
695  hits = ecalEndcapHits;
696  flags_ = flagsexclEE_;
697  severitiesexcl_ = severitiesexclEE_;
698  } else if (EcalTools::isHGCalDet(thedet)) {
699  preselCutValues = preselCutValuesEndcap_;
700  hits = nullptr;
701  flags_ = flagsexclEE_;
702  severitiesexcl_ = severitiesexclEE_;
703  } else {
704  edm::LogWarning("") << "GEDPhotonProducer: do not know if it is a barrel or endcap SuperCluster: " << thedet
705  << ' ' << subdet;
706  }
707 
708  // SC energy preselection
709  if (parentSCRef.isNonnull() &&
710  ptFast(parentSCRef->energy(), parentSCRef->position(), {0, 0, 0}) <= preselCutValues[0])
711  continue;
712 
713  float maxXtal = (hits != nullptr ? EcalClusterTools::eMax(*(scRef->seed()), hits) : 0.f);
714 
715  //AA
716  //Change these to consider severity level of hits
717  float e1x5 = (hits != nullptr ? EcalClusterTools::e1x5(*(scRef->seed()), hits, topology) : 0.f);
718  float e2x5 = (hits != nullptr ? EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
719  float e3x3 = (hits != nullptr ? EcalClusterTools::e3x3(*(scRef->seed()), hits, topology) : 0.f);
720  float e5x5 = (hits != nullptr ? EcalClusterTools::e5x5(*(scRef->seed()), hits, topology) : 0.f);
721  const auto& cov = (hits != nullptr ? EcalClusterTools::covariances(*(scRef->seed()), hits, topology, caloGeom_)
722  : std::array<float, 3>({{0.f, 0.f, 0.f}}));
723  // fractional local covariances
724  const auto& locCov = (hits != nullptr ? EcalClusterTools::localCovariances(*(scRef->seed()), hits, topology)
725  : std::array<float, 3>({{0.f, 0.f, 0.f}}));
726 
727  float sigmaEtaEta = std::sqrt(cov[0]);
728  float sigmaIetaIeta = std::sqrt(locCov[0]);
729 
730  float full5x5_maxXtal = (hits != nullptr ? noZS::EcalClusterTools::eMax(*(scRef->seed()), hits) : 0.f);
731  //AA
732  //Change these to consider severity level of hits
733  float full5x5_e1x5 = (hits != nullptr ? noZS::EcalClusterTools::e1x5(*(scRef->seed()), hits, topology) : 0.f);
734  float full5x5_e2x5 = (hits != nullptr ? noZS::EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
735  float full5x5_e3x3 = (hits != nullptr ? noZS::EcalClusterTools::e3x3(*(scRef->seed()), hits, topology) : 0.f);
736  float full5x5_e5x5 = (hits != nullptr ? noZS::EcalClusterTools::e5x5(*(scRef->seed()), hits, topology) : 0.f);
737  const auto& full5x5_cov =
738  (hits != nullptr ? noZS::EcalClusterTools::covariances(*(scRef->seed()), hits, topology, caloGeom_)
739  : std::array<float, 3>({{0.f, 0.f, 0.f}}));
740  // for full5x5 local covariances, do noise-cleaning
741  // by passing per crystal PF recHit thresholds and mult values.
742  // mult values for EB and EE were obtained by dedicated studies.
743  const auto& full5x5_locCov =
744  (hits != nullptr ? noZS::EcalClusterTools::localCovariances(*(scRef->seed()),
745  hits,
746  topology,
748  &thresholds,
749  multThresEB_,
750  multThresEE_)
751  : std::array<float, 3>({{0.f, 0.f, 0.f}}));
752 
753  float full5x5_sigmaEtaEta = sqrt(full5x5_cov[0]);
754  float full5x5_sigmaIetaIeta = sqrt(full5x5_locCov[0]);
755  float full5x5_sigmaIetaIphi = full5x5_locCov[1];
756 
757  // compute position of ECAL shower
758  math::XYZPoint caloPosition = scRef->position();
759 
761  double photonEnergy = 1.;
762  math::XYZPoint vtx(0., 0., 0.);
763  if (!vertexCollection.empty())
764  vtx = vertexCollection.begin()->position();
765  // compute momentum vector of photon from primary vertex and cluster position
766  math::XYZVector direction = caloPosition - vtx;
767  //math::XYZVector momentum = direction.unit() * photonEnergy ;
768  math::XYZVector momentum = direction.unit();
769 
770  // Create dummy candidate with unit momentum and zero energy to allow setting of all variables. The energy is set for last.
771  math::XYZTLorentzVectorD p4(momentum.x(), momentum.y(), momentum.z(), photonEnergy);
772  reco::Photon newCandidate(p4, caloPosition, coreRef, vtx);
773 
774  //std::cout << " standard p4 before " << newCandidate.p4() << " energy " << newCandidate.energy() << std::endl;
775  //std::cout << " type " <<newCandidate.getCandidateP4type() << " standard p4 after " << newCandidate.p4() << " energy " << newCandidate.energy() << std::endl;
776 
777  // Calculate fiducial flags and isolation variable. Blocked are filled from the isolationCalculator
778  reco::Photon::FiducialFlags fiducialFlags;
779  reco::Photon::IsolationVariables isolVarR03, isolVarR04;
780  if (!EcalTools::isHGCalDet(thedet)) {
781  photonIsoCalculator_->calculate(&newCandidate, evt, es, fiducialFlags, isolVarR04, isolVarR03);
782  }
783  newCandidate.setFiducialVolumeFlags(fiducialFlags);
784  newCandidate.setIsolationVariables(isolVarR04, isolVarR03);
785 
787  reco::Photon::ShowerShape showerShape;
788  showerShape.e1x5 = e1x5;
789  showerShape.e2x5 = e2x5;
790  showerShape.e3x3 = e3x3;
791  showerShape.e5x5 = e5x5;
792  showerShape.maxEnergyXtal = maxXtal;
793  showerShape.sigmaEtaEta = sigmaEtaEta;
794  showerShape.sigmaIetaIeta = sigmaIetaIeta;
795  for (uint id = 0; id < showerShape.hcalOverEcal.size(); ++id) {
796  showerShape.hcalOverEcal[id] =
797  (hcalHelperCone != nullptr) ? hcalHelperCone->hcalESum(*scRef, id + 1) / scRef->energy() : 0.f;
798 
799  showerShape.hcalOverEcalBc[id] =
800  (hcalHelperBc != nullptr) ? hcalHelperBc->hcalESum(*scRef, id + 1) / scRef->energy() : 0.f;
801  }
802  showerShape.invalidHcal = (hcalHelperBc != nullptr) ? !hcalHelperBc->hasActiveHcal(*scRef) : false;
803  if (hcalHelperBc != nullptr)
804  showerShape.hcalTowersBehindClusters = hcalHelperBc->hcalTowersBehindClusters(*scRef);
805  showerShape.pre7DepthHcal = false;
806 
808  const float spp = (!edm::isFinite(locCov[2]) ? 0. : sqrt(locCov[2]));
809  const float sep = locCov[1];
810  showerShape.sigmaIetaIphi = sep;
811  showerShape.sigmaIphiIphi = spp;
812  showerShape.e2nd = (hits != nullptr ? EcalClusterTools::e2nd(*(scRef->seed()), hits) : 0.f);
813  showerShape.eTop = (hits != nullptr ? EcalClusterTools::eTop(*(scRef->seed()), hits, topology) : 0.f);
814  showerShape.eLeft = (hits != nullptr ? EcalClusterTools::eLeft(*(scRef->seed()), hits, topology) : 0.f);
815  showerShape.eRight = (hits != nullptr ? EcalClusterTools::eRight(*(scRef->seed()), hits, topology) : 0.f);
816  showerShape.eBottom = (hits != nullptr ? EcalClusterTools::eBottom(*(scRef->seed()), hits, topology) : 0.f);
817  showerShape.e1x3 = (hits != nullptr ? EcalClusterTools::e1x3(*(scRef->seed()), hits, topology) : 0.f);
818  showerShape.e2x2 = (hits != nullptr ? EcalClusterTools::e2x2(*(scRef->seed()), hits, topology) : 0.f);
819  showerShape.e2x5Max = (hits != nullptr ? EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
820  showerShape.e2x5Left = (hits != nullptr ? EcalClusterTools::e2x5Left(*(scRef->seed()), hits, topology) : 0.f);
821  showerShape.e2x5Right = (hits != nullptr ? EcalClusterTools::e2x5Right(*(scRef->seed()), hits, topology) : 0.f);
822  showerShape.e2x5Top = (hits != nullptr ? EcalClusterTools::e2x5Top(*(scRef->seed()), hits, topology) : 0.f);
823  showerShape.e2x5Bottom = (hits != nullptr ? EcalClusterTools::e2x5Bottom(*(scRef->seed()), hits, topology) : 0.f);
824  if (hits) {
825  Cluster2ndMoments clus2ndMoments = EcalClusterTools::cluster2ndMoments(*(scRef->seed()), *hits);
826  showerShape.smMajor = clus2ndMoments.sMaj;
827  showerShape.smMinor = clus2ndMoments.sMin;
828  showerShape.smAlpha = clus2ndMoments.alpha;
829  } else {
830  showerShape.smMajor = 0.f;
831  showerShape.smMinor = 0.f;
832  showerShape.smAlpha = 0.f;
833  }
834 
835  // fill preshower shapes
836  EcalClusterLazyTools toolsforES(
838  const float sigmaRR = toolsforES.eseffsirir(*scRef);
839  showerShape.effSigmaRR = sigmaRR;
840  newCandidate.setShowerShapeVariables(showerShape);
841 
842  const reco::CaloCluster& seedCluster = *(scRef->seed());
843  DetId seedXtalId = seedCluster.seed();
844  int nSaturatedXtals = 0;
845  bool isSeedSaturated = false;
846  if (hits != nullptr) {
847  const auto hitsAndFractions = scRef->hitsAndFractions();
848  for (auto const& hitFractionPair : hitsAndFractions) {
849  auto&& ecalRecHit = hits->find(hitFractionPair.first);
850  if (ecalRecHit == hits->end())
851  continue;
852  if (ecalRecHit->checkFlag(EcalRecHit::Flags::kSaturated)) {
853  nSaturatedXtals++;
854  if (seedXtalId == ecalRecHit->detid())
855  isSeedSaturated = true;
856  }
857  }
858  }
859  reco::Photon::SaturationInfo saturationInfo;
860  saturationInfo.nSaturatedXtals = nSaturatedXtals;
861  saturationInfo.isSeedSaturated = isSeedSaturated;
862  newCandidate.setSaturationInfo(saturationInfo);
863 
865  reco::Photon::ShowerShape full5x5_showerShape;
866  full5x5_showerShape.e1x5 = full5x5_e1x5;
867  full5x5_showerShape.e2x5 = full5x5_e2x5;
868  full5x5_showerShape.e3x3 = full5x5_e3x3;
869  full5x5_showerShape.e5x5 = full5x5_e5x5;
870  full5x5_showerShape.maxEnergyXtal = full5x5_maxXtal;
871  full5x5_showerShape.sigmaEtaEta = full5x5_sigmaEtaEta;
872  full5x5_showerShape.sigmaIetaIeta = full5x5_sigmaIetaIeta;
874  const float full5x5_spp = (!edm::isFinite(full5x5_locCov[2]) ? 0. : std::sqrt(full5x5_locCov[2]));
875  const float full5x5_sep = full5x5_sigmaIetaIphi;
876  full5x5_showerShape.sigmaIetaIphi = full5x5_sep;
877  full5x5_showerShape.sigmaIphiIphi = full5x5_spp;
878  full5x5_showerShape.e2nd = (hits != nullptr ? noZS::EcalClusterTools::e2nd(*(scRef->seed()), hits) : 0.f);
879  full5x5_showerShape.eTop = (hits != nullptr ? noZS::EcalClusterTools::eTop(*(scRef->seed()), hits, topology) : 0.f);
880  full5x5_showerShape.eLeft =
881  (hits != nullptr ? noZS::EcalClusterTools::eLeft(*(scRef->seed()), hits, topology) : 0.f);
882  full5x5_showerShape.eRight =
883  (hits != nullptr ? noZS::EcalClusterTools::eRight(*(scRef->seed()), hits, topology) : 0.f);
884  full5x5_showerShape.eBottom =
885  (hits != nullptr ? noZS::EcalClusterTools::eBottom(*(scRef->seed()), hits, topology) : 0.f);
886  full5x5_showerShape.e1x3 = (hits != nullptr ? noZS::EcalClusterTools::e1x3(*(scRef->seed()), hits, topology) : 0.f);
887  full5x5_showerShape.e2x2 = (hits != nullptr ? noZS::EcalClusterTools::e2x2(*(scRef->seed()), hits, topology) : 0.f);
888  full5x5_showerShape.e2x5Max =
889  (hits != nullptr ? noZS::EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
890  full5x5_showerShape.e2x5Left =
891  (hits != nullptr ? noZS::EcalClusterTools::e2x5Left(*(scRef->seed()), hits, topology) : 0.f);
892  full5x5_showerShape.e2x5Right =
893  (hits != nullptr ? noZS::EcalClusterTools::e2x5Right(*(scRef->seed()), hits, topology) : 0.f);
894  full5x5_showerShape.e2x5Top =
895  (hits != nullptr ? noZS::EcalClusterTools::e2x5Top(*(scRef->seed()), hits, topology) : 0.f);
896  full5x5_showerShape.e2x5Bottom =
897  (hits != nullptr ? noZS::EcalClusterTools::e2x5Bottom(*(scRef->seed()), hits, topology) : 0.f);
898  if (hits) {
899  Cluster2ndMoments clus2ndMoments = noZS::EcalClusterTools::cluster2ndMoments(*(scRef->seed()), *hits);
900  full5x5_showerShape.smMajor = clus2ndMoments.sMaj;
901  full5x5_showerShape.smMinor = clus2ndMoments.sMin;
902  full5x5_showerShape.smAlpha = clus2ndMoments.alpha;
903  } else {
904  full5x5_showerShape.smMajor = 0.f;
905  full5x5_showerShape.smMinor = 0.f;
906  full5x5_showerShape.smAlpha = 0.f;
907  }
908  // fill preshower shapes
909  full5x5_showerShape.effSigmaRR = sigmaRR;
910  for (uint id = 0; id < full5x5_showerShape.hcalOverEcal.size(); ++id) {
911  full5x5_showerShape.hcalOverEcal[id] =
912  (hcalHelperCone != nullptr) ? hcalHelperCone->hcalESum(*scRef, id + 1) / full5x5_e5x5 : 0.f;
913  full5x5_showerShape.hcalOverEcalBc[id] =
914  (hcalHelperBc != nullptr) ? hcalHelperBc->hcalESum(*scRef, id + 1) / full5x5_e5x5 : 0.f;
915  }
916  full5x5_showerShape.pre7DepthHcal = false;
917  newCandidate.full5x5_setShowerShapeVariables(full5x5_showerShape);
918 
919  //get the pointer for the photon object
920  edm::Ptr<reco::PhotonCore> photonPtr(photonCoreHandle, lSC);
921 
922  // New in CMSSW_12_1_0 for PFID with DNNs
923  // The PFIso values are computed in the first loop on gedPhotonsTmp to make them available as DNN inputs.
924  // They are computed with the same inputs and algo as the final PFiso variables computed in the second loop after PF.
925  // Get PFClusters for PFID only if the PFID DNN evaluation is enabled
926  if (dnnPFidEnabled_) {
927  auto clusterHandle = evt.getHandle(pfClusterProducer_);
928  std::vector<edm::Handle<reco::PFClusterCollection>> clusterHandles{evt.getHandle(pfClusterProducerHCAL_)};
929  if (useHF_) {
930  clusterHandles.push_back(evt.getHandle(pfClusterProducerHFEM_));
931  clusterHandles.push_back(evt.getHandle(pfClusterProducerHFHAD_));
932  }
934  pfIso.sumEcalClusterEt = ecalisoAlgo->getSum(newCandidate, clusterHandle);
935  pfIso.sumHcalClusterEt = hcalisoAlgo->getSum(newCandidate, clusterHandles);
936 
937  newCandidate.setPflowIsolationVariables(pfIso);
938  }
939 
942  // Photon candidate takes by default (set in photons_cfi.py)
943  // a 4-momentum derived from the ecal photon-specific corrections.
944  if (!EcalTools::isHGCalDet(thedet)) {
945  photonEnergyCorrector_->calculate(evt, newCandidate, subdet, vertexCollection, es);
946  if (candidateP4type_ == "fromEcalEnergy") {
947  newCandidate.setP4(newCandidate.p4(reco::Photon::ecal_photons));
948  newCandidate.setCandidateP4type(reco::Photon::ecal_photons);
949  } else if (candidateP4type_ == "fromRegression1") {
950  newCandidate.setP4(newCandidate.p4(reco::Photon::regression1));
951  newCandidate.setCandidateP4type(reco::Photon::regression1);
952  } else if (candidateP4type_ == "fromRegression2") {
953  newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
954  newCandidate.setCandidateP4type(reco::Photon::regression2);
955  } else if (candidateP4type_ == "fromRefinedSCRegression") {
956  newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
957  newCandidate.setCandidateP4type(reco::Photon::regression2);
958  }
959  } else {
960  math::XYZVector gamma_momentum = direction.unit() * scRef->energy();
961  math::XYZTLorentzVectorD p4(gamma_momentum.x(), gamma_momentum.y(), gamma_momentum.z(), scRef->energy());
962  newCandidate.setP4(p4);
963  newCandidate.setCandidateP4type(reco::Photon::ecal_photons);
964  // Make it an EE photon
965  reco::Photon::FiducialFlags fiducialFlags;
966  fiducialFlags.isEE = true;
967  newCandidate.setFiducialVolumeFlags(fiducialFlags);
968  }
969 
970  // fill MIP Vairables for Halo: Block for MIP are filled from PhotonMIPHaloTagger
972  if (subdet == EcalBarrel && runMIPTagger_) {
973  photonMIPHaloTagger_->MIPcalculate(&newCandidate, evt, es, mipVar);
974  newCandidate.setMIPVariables(mipVar);
975  }
976 
978  bool isLooseEM = true;
979  if (newCandidate.pt() < highEt_) {
980  if (newCandidate.hadronicOverEm() >= preselCutValues[1])
981  isLooseEM = false;
982  if (newCandidate.ecalRecHitSumEtConeDR04() > preselCutValues[2] + preselCutValues[3] * newCandidate.pt())
983  isLooseEM = false;
984  if (newCandidate.hcalTowerSumEtConeDR04() > preselCutValues[4] + preselCutValues[5] * newCandidate.pt())
985  isLooseEM = false;
986  if (newCandidate.nTrkSolidConeDR04() > int(preselCutValues[6]))
987  isLooseEM = false;
988  if (newCandidate.nTrkHollowConeDR04() > int(preselCutValues[7]))
989  isLooseEM = false;
990  if (newCandidate.trkSumPtSolidConeDR04() > preselCutValues[8])
991  isLooseEM = false;
992  if (newCandidate.trkSumPtHollowConeDR04() > preselCutValues[9])
993  isLooseEM = false;
994  if (newCandidate.sigmaIetaIeta() > preselCutValues[10])
995  isLooseEM = false;
996  }
997 
998  if (isLooseEM)
999  outputPhotonCollection.push_back(newCandidate);
1000  }
1001 
1002  if (dnnPFidEnabled_) {
1003  // Here send the list of photons to the PhotonDNNEstimator and get back the values for all the photons in one go
1004  LogDebug("GEDPhotonProducer") << "Getting DNN PFId for photons";
1005  const auto& dnn_photon_pfid = globalCache()->photonDNNEstimator->evaluate(outputPhotonCollection, tfSessions_);
1006  size_t ipho = 0;
1007  for (auto& photon : outputPhotonCollection) {
1008  const auto& values = dnn_photon_pfid[ipho];
1010  pfID.dnn = values[0];
1011  photon.setPflowIDVariables(pfID);
1012  ipho++;
1013  }
1014  }
1015 }
1016 
1018  edm::EventSetup const& es,
1019  const edm::Handle<reco::PhotonCollection>& photonHandle,
1020  const edm::Handle<reco::PFCandidateCollection> pfCandidateHandle,
1021  const edm::Handle<reco::PFCandidateCollection> pfEGCandidateHandle,
1023  reco::PhotonCollection& outputPhotonCollection,
1024  int& iSC,
1025  const edm::Handle<edm::ValueMap<float>>& chargedHadrons,
1026  const edm::Handle<edm::ValueMap<float>>& neutralHadrons,
1028  const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtx,
1029  const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtxGeomVeto,
1030  const edm::Handle<edm::ValueMap<float>>& chargedHadronsPFPV,
1031  const edm::Handle<edm::ValueMap<float>>& pfEcalClusters,
1032  const edm::Handle<edm::ValueMap<float>>& pfHcalClusters) {
1033  std::vector<double> preselCutValues;
1034 
1035  for (unsigned int lSC = 0; lSC < photonHandle->size(); lSC++) {
1036  reco::PhotonRef phoRef(reco::PhotonRef(photonHandle, lSC));
1037  reco::SuperClusterRef parentSCRef = phoRef->parentSuperCluster();
1038  reco::SuperClusterRef scRef = phoRef->superCluster();
1039  DetId::Detector thedet = scRef->seed()->hitsAndFractions()[0].first.det();
1040  int subdet = scRef->seed()->hitsAndFractions()[0].first.subdetId();
1041  if (subdet == EcalBarrel) {
1042  preselCutValues = preselCutValuesBarrel_;
1043  } else if (subdet == EcalEndcap) {
1044  preselCutValues = preselCutValuesEndcap_;
1045  } else if (EcalTools::isHGCalDet(thedet)) {
1046  preselCutValues = preselCutValuesEndcap_;
1047  } else {
1048  edm::LogWarning("") << "GEDPhotonProducer: do not know if it is a barrel or endcap SuperCluster" << thedet << ' '
1049  << subdet;
1050  }
1051 
1052  // SC energy preselection
1053  if (parentSCRef.isNonnull() &&
1054  ptFast(parentSCRef->energy(), parentSCRef->position(), {0, 0, 0}) <= preselCutValues[0])
1055  continue;
1056 
1057  reco::Photon newCandidate(*phoRef);
1058  iSC++;
1059 
1060  // Calculate the PF isolation
1062  // The PFID are not recomputed since they have been already computed in the first loop with the DNN
1063 
1064  //get the pointer for the photon object
1065  edm::Ptr<reco::Photon> photonPtr(photonHandle, lSC);
1066 
1067  if (!recoStep_.isOOT()) { //out of time photons do not have PF info so skip in this case
1068  pfIso.chargedHadronIso = (*chargedHadrons)[photonPtr];
1069  pfIso.neutralHadronIso = (*neutralHadrons)[photonPtr];
1070  pfIso.photonIso = (*photons)[photonPtr];
1071  pfIso.chargedHadronWorstVtxIso = (*chargedHadronsWorstVtx)[photonPtr];
1072  pfIso.chargedHadronWorstVtxGeomVetoIso = (*chargedHadronsWorstVtxGeomVeto)[photonPtr];
1073  pfIso.chargedHadronPFPVIso = (*chargedHadronsPFPV)[photonPtr];
1074  }
1075 
1076  //OOT photons in legacy 80X reminiAOD workflow dont have pf cluster isolation embeded into them at this stage
1077  // They have been already computed in the first loop on gedPhotonsTmp but better to compute them again here.
1078  pfIso.sumEcalClusterEt = !phoPFECALClusIsolationToken_.isUninitialized() ? (*pfEcalClusters)[photonPtr] : 0.;
1079  pfIso.sumHcalClusterEt = !phoPFHCALClusIsolationToken_.isUninitialized() ? (*pfHcalClusters)[photonPtr] : 0.;
1080  newCandidate.setPflowIsolationVariables(pfIso);
1081 
1082  // do the regression
1083  photonEnergyCorrector_->calculate(evt, newCandidate, subdet, vertexCollection, es);
1084  if (candidateP4type_ == "fromEcalEnergy") {
1085  newCandidate.setP4(newCandidate.p4(reco::Photon::ecal_photons));
1087  } else if (candidateP4type_ == "fromRegression1") {
1088  newCandidate.setP4(newCandidate.p4(reco::Photon::regression1));
1090  } else if (candidateP4type_ == "fromRegression2") {
1091  newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
1093  } else if (candidateP4type_ == "fromRefinedSCRegression") {
1094  newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
1096  }
1097 
1098  outputPhotonCollection.push_back(newCandidate);
1099  }
1100 }
void setPflowIsolationVariables(const PflowIsolationVariables &pfisol)
Set Particle Flow Isolation variables.
Definition: Photon.h:557
static bool isHGCalDet(DetId::Detector thedet)
identify HGCal cells
Definition: EcalTools.h:49
GEDPhotonProducer(const edm::ParameterSet &ps, const CacheData *gcache)
std::unique_ptr< PhotonHcalPFClusterIsolation > hcalisoAlgo
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:133
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
edm::EDGetTokenT< reco::PFCandidateCollection > pfCandidates_
void fillPhotonCollection(edm::Event &evt, edm::EventSetup const &es, const edm::Handle< reco::PhotonCoreCollection > &photonCoreHandle, const CaloTopology *topology, const EcalRecHitCollection *ecalBarrelHits, const EcalRecHitCollection *ecalEndcapHits, const EcalRecHitCollection *preshowerHits, const ElectronHcalHelper *hcalHelperCone, const ElectronHcalHelper *hcalHelperBc, const reco::VertexCollection &pvVertices, reco::PhotonCollection &outputCollection, int &iSC, EcalPFRecHitThresholds const &thresholds)
double hcalESum(const reco::SuperCluster &, int depth) const
static float e2x5Bottom(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
HcalPFClusterIsolation< reco::Photon > PhotonHcalPFClusterIsolation
std::vector< CaloTowerDetId > hcalTowersBehindClusters
Definition: Photon.h:153
ROOT::Math::LorentzVector< ROOT::Math::PxPyPzE4D< double > > XYZTLorentzVectorD
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:14
void setCandidateP4type(const P4type type)
Definition: Photon.h:353
uint16_t *__restrict__ id
const edm::ESGetToken< EcalPFRecHitThresholds, EcalPFRecHitThresholdsRcd > ecalPFRechitThresholdsToken_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:539
static float eMax(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits)
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void produce(edm::Event &evt, const edm::EventSetup &es) override
std::unique_ptr< PhotonEnergyCorrector > photonEnergyCorrector_
constexpr bool isUninitialized() const noexcept
Definition: EDGetToken.h:99
CaloGeometry const * caloGeom_
std::unique_ptr< PhotonEcalPFClusterIsolation > ecalisoAlgo
bool exists(std::string const &parameterName) const
checks if a parameter exists
edm::EDGetTokenT< reco::PFClusterCollection > pfClusterProducerHFEM_
std::vector< int > flagsexclEB_
void endStream() override
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
const edm::ESGetToken< CaloTopology, CaloTopologyRecord > caloTopologyToken_
edm::EDGetTokenT< EcalRecHitCollection > endcapEcalHits_
std::array< float, 7 > hcalOverEcalBc
Definition: Photon.h:152
std::vector< std::string > modelsFiles
constexpr bool isFinite(T x)
std::vector< int > severitiesexclEE_
tuple vertexCollection
edm::EDGetTokenT< HBHERecHitCollection > hbheRecHits
double ptFast(const double energy, const math::XYZPoint &position, const math::XYZPoint &origin)
std::string photonCollection_
static float e2x5Top(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
RecoStepInfo(const std::string &recoStep)
bool getData(T &iHolder) const
Definition: EventSetup.h:128
static std::array< float, 3 > covariances(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology, const CaloGeometry *geometry, float w0=4.7)
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:563
edm::EDGetTokenT< edm::ValueMap< float > > phoChargedPFPVIsoToken_
static std::array< float, 3 > localCovariances(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology, float w0=EgammaLocalCovParamDefaults::kRelEnCut, const EcalPFRecHitThresholds *thresholds=nullptr, float multEB=0.0, float multEE=0.0)
edm::EDGetTokenT< EcalRecHitCollection > barrelEcalHits_
static std::unique_ptr< CacheData > initializeGlobalCache(const edm::ParameterSet &)
edm::EDGetTokenT< edm::ValueMap< float > > phoChargedWorstVtxGeomVetoIsoToken_
std::unique_ptr< ElectronHcalHelper > hcalHelperCone_
static float e2x2(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
edm::EDGetTokenT< edm::ValueMap< float > > phoChargedIsolationToken_
T sqrt(T t)
Definition: SSEVec.h:19
std::unique_ptr< PhotonIsolationCalculator > photonIsoCalculator_
edm::EDGetTokenT< edm::ValueMap< std::vector< reco::PFCandidateRef > > > particleBasedIsolationToken
def move
Definition: eostools.py:511
static float e2nd(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits)
bool closeSession(Session *&session)
Definition: TensorFlow.cc:198
std::vector< int > flagsexclEE_
std::unique_ptr< const PhotonDNNEstimator > photonDNNEstimator
auto hcalTowersBehindClusters(const reco::SuperCluster &sc) const
bool get(ProductID const &oid, Handle< PROD > &result) const
Definition: Event.h:346
edm::EDGetTokenT< reco::PhotonCoreCollection > photonCoreProducerT_
static float e2x5Max(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
static float eBottom(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
std::vector< tensorflow::Session * > tfSessions_
static float e2x5Right(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
string preshowerHits
edm::EDGetTokenT< edm::ValueMap< float > > phoPFHCALClusIsolationToken_
edm::EDGetTokenT< reco::PFCandidateCollection > pfEgammaCandidates_
std::vector< int > severitiesexclEB_
edm::EDGetTokenT< reco::PFClusterCollection > pfClusterProducerHFHAD_
CacheData(const edm::ParameterSet &conf)
const_iterator end() const
static Cluster2ndMoments cluster2ndMoments(const reco::BasicCluster &basicCluster, const EcalRecHitCollection &recHits, double phiCorrectionFactor=0.8, double w0=4.7, bool useLogWeights=true)
Log< level::Info, false > LogInfo
edm::EDGetTokenT< HBHERecHitCollection > hbheRecHits_
static float eTop(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
Definition: DetId.h:17
ESData get(edm::EventSetup const &eventSetup) const
edm::EDGetTokenT< edm::ValueMap< float > > phoNeutralHadronIsolationToken_
DetId seed() const
return DetId of seed
Definition: CaloCluster.h:219
edm::EDGetTokenT< edm::ValueMap< float > > phoChargedWorstVtxIsoToken_
bool hasActiveHcal(const reco::SuperCluster &sc) const
std::vector< double > preselCutValuesBarrel_
edm::EDGetTokenT< reco::PhotonCollection > photonProducerT_
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:31
EcalPFClusterIsolation< reco::Photon > PhotonEcalPFClusterIsolation
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:12
std::array< float, 7 > hcalOverEcal
Definition: Photon.h:150
Detector
Definition: DetId.h:24
std::vector< Photon > PhotonCollection
collectin of Photon objects
Definition: PhotonFwd.h:9
std::vector< double > preselCutValuesEndcap_
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
const EcalClusterLazyTools::ESGetTokens ecalClusterESGetTokens_
const edm::InputTag photonProducer_
static float e2x5Left(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
const LorentzVector & p4(P4type type) const
std::unique_ptr< ElectronHcalHelper > hcalHelperBc_
static void globalEndJob(const CacheData *)
std::string candidateP4type_
edm::EDGetTokenT< edm::ValueMap< float > > phoPhotonIsolationToken_
const edm::ESGetToken< CaloGeometry, CaloGeometryRecord > caloGeometryToken_
std::string const & label() const
Definition: InputTag.h:36
tuple config
parse the configuration file
iterator find(key_type k)
static int position[264][3]
Definition: ReadPGInfo.cc:289
edm::EDGetTokenT< reco::PFClusterCollection > pfClusterProducer_
edm::EDGetTokenT< edm::ValueMap< float > > phoPFECALClusIsolationToken_
static float eRight(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
EgammaHcalIsolation::arrayHB eThresHB
std::vector< std::string > scalersFiles
static float e3x3(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
step
Definition: StallMonitor.cc:94
EgammaHcalIsolation::arrayHE eThresHE
static float e1x3(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
edm::EDGetTokenT< reco::VertexCollection > vertexProducer_
Log< level::Warning, false > LogWarning
std::array< double, 4 > arrayHB
std::unique_ptr< PhotonMIPHaloTagger > photonMIPHaloTagger_
static float eLeft(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
ESGetTokenH3DDVariant esConsumes(std::string const &Reccord, edm::ConsumesCollector &)
Definition: DeDxTools.cc:283
edm::EDGetTokenT< EcalRecHitCollection > preshowerHits_
edm::EDGetTokenT< reco::PFClusterCollection > pfClusterProducerHCAL_
static float e1x5(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
void setP4(P4type type, const LorentzVector &p4, float p4Error, bool setToRecoCandidate)
std::string valueMapPFCandPhoton_
#define LogDebug(id)
static float e5x5(const reco::BasicCluster &cluster, const EcalRecHitCollection *recHits, const CaloTopology *topology)
std::array< double, 7 > arrayHE