CMS 3D CMS Logo

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