CMS 3D CMS Logo

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