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,
126  reco::PhotonCollection& outputCollection,
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,
136  reco::PhotonCollection& outputCollection,
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<PhotonMIPHaloTagger> photonMIPHaloTagger_ = nullptr;
205  //MVA based Halo tagger for the EE photons
206  std::unique_ptr<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  photonIsoCalculator_ = std::make_unique<PhotonIsolationCalculator>();
430  edm::ParameterSet isolationSumsCalculatorSet = config.getParameter<edm::ParameterSet>("isolationSumsCalculatorSet");
431  photonIsoCalculator_->setup(isolationSumsCalculatorSet,
432  flagsexclEB_,
433  flagsexclEE_,
434  severitiesexclEB_,
435  severitiesexclEE_,
436  consumesCollector());
437  photonMIPHaloTagger_ = std::make_unique<PhotonMIPHaloTagger>();
438  edm::ParameterSet mipVariableSet = config.getParameter<edm::ParameterSet>("mipVariableSet");
439  photonMIPHaloTagger_->setup(mipVariableSet, consumesCollector());
440  }
441 
442  if (recoStep_.isFinal() && runMVABasedHaloTagger_) {
443  edm::ParameterSet mvaBasedHaloVariableSet = config.getParameter<edm::ParameterSet>("mvaBasedHaloVariableSet");
444  photonMVABasedHaloTagger_ =
445  std::make_unique<PhotonMVABasedHaloTagger>(mvaBasedHaloVariableSet, consumesCollector());
446  }
447 
449  const edm::ParameterSet& pfECALClusIsolCfg = config.getParameter<edm::ParameterSet>("pfECALClusIsolCfg");
450  pfClusterProducer_ =
451  consumes<reco::PFClusterCollection>(pfECALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducer"));
452  ecaldrMax_ = pfECALClusIsolCfg.getParameter<double>("drMax");
453  ecaldrVetoBarrel_ = pfECALClusIsolCfg.getParameter<double>("drVetoBarrel");
454  ecaldrVetoEndcap_ = pfECALClusIsolCfg.getParameter<double>("drVetoEndcap");
455  ecaletaStripBarrel_ = pfECALClusIsolCfg.getParameter<double>("etaStripBarrel");
456  ecaletaStripEndcap_ = pfECALClusIsolCfg.getParameter<double>("etaStripEndcap");
457  ecalenergyBarrel_ = pfECALClusIsolCfg.getParameter<double>("energyBarrel");
458  ecalenergyEndcap_ = pfECALClusIsolCfg.getParameter<double>("energyEndcap");
459 
460  const edm::ParameterSet& pfHCALClusIsolCfg = config.getParameter<edm::ParameterSet>("pfHCALClusIsolCfg");
461  pfClusterProducerHCAL_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHCAL"));
462  pfClusterProducerHFEM_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFEM"));
463  pfClusterProducerHFHAD_ = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFHAD"));
464  useHF_ = pfHCALClusIsolCfg.getParameter<bool>("useHF");
465  hcaldrMax_ = pfHCALClusIsolCfg.getParameter<double>("drMax");
466  hcaldrVetoBarrel_ = pfHCALClusIsolCfg.getParameter<double>("drVetoBarrel");
467  hcaldrVetoEndcap_ = pfHCALClusIsolCfg.getParameter<double>("drVetoEndcap");
468  hcaletaStripBarrel_ = pfHCALClusIsolCfg.getParameter<double>("etaStripBarrel");
469  hcaletaStripEndcap_ = pfHCALClusIsolCfg.getParameter<double>("etaStripEndcap");
470  hcalenergyBarrel_ = pfHCALClusIsolCfg.getParameter<double>("energyBarrel");
471  hcalenergyEndcap_ = pfHCALClusIsolCfg.getParameter<double>("energyEndcap");
472  hcaluseEt_ = pfHCALClusIsolCfg.getParameter<bool>("useEt");
473 
474  // Register the product
475  produces<reco::PhotonCollection>(photonCollection_);
476  if (not pfEgammaCandidates_.isUninitialized()) {
477  produces<edm::ValueMap<reco::PhotonRef>>(valueMapPFCandPhoton_);
478  }
479 
480  const auto& pset_dnn = config.getParameter<edm::ParameterSet>("PhotonDNNPFid");
481  dnnPFidEnabled_ = pset_dnn.getParameter<bool>("enabled");
482  if (dnnPFidEnabled_) {
483  tfSessions_ = gcache->photonDNNEstimator->getSessions();
484  }
485 }
486 
488  // this method is supposed to create, initialize and return a CacheData instance
489  return std::make_unique<CacheData>(config);
490 }
491 
493  for (auto session : tfSessions_) {
494  tensorflow::closeSession(session);
495  }
496 }
497 
499  using namespace edm;
500 
501  if (cutsFromDB_) {
502  hcalCuts_ = &eventSetup.getData(hcalCutsToken_);
503  }
504 
505  auto outputPhotonCollection_p = std::make_unique<reco::PhotonCollection>();
506  edm::ValueMap<reco::PhotonRef> pfEGCandToPhotonMap;
507 
508  // Get the PhotonCore collection
509  bool validPhotonCoreHandle = false;
510  Handle<reco::PhotonCoreCollection> photonCoreHandle;
511  bool validPhotonHandle = false;
512  Handle<reco::PhotonCollection> photonHandle;
513  //value maps for isolation
514  edm::Handle<edm::ValueMap<float>> phoChargedIsolationMap;
515  edm::Handle<edm::ValueMap<float>> phoNeutralHadronIsolationMap;
516  edm::Handle<edm::ValueMap<float>> phoPhotonIsolationMap;
517  edm::Handle<edm::ValueMap<float>> phoChargedWorstVtxIsoMap;
518  edm::Handle<edm::ValueMap<float>> phoChargedWorstVtxGeomVetoIsoMap;
519  edm::Handle<edm::ValueMap<float>> phoChargedPFPVIsoMap;
520 
521  edm::Handle<edm::ValueMap<float>> phoPFECALClusIsolationMap;
522  edm::Handle<edm::ValueMap<float>> phoPFHCALClusIsolationMap;
523 
524  if (recoStep_.isFinal()) {
525  theEvent.getByToken(photonProducerT_, photonHandle);
526  //get isolation objects
527  theEvent.getByToken(phoChargedIsolationToken_, phoChargedIsolationMap);
528  theEvent.getByToken(phoNeutralHadronIsolationToken_, phoNeutralHadronIsolationMap);
529  theEvent.getByToken(phoPhotonIsolationToken_, phoPhotonIsolationMap);
530  theEvent.getByToken(phoChargedWorstVtxIsoToken_, phoChargedWorstVtxIsoMap);
531  theEvent.getByToken(phoChargedWorstVtxGeomVetoIsoToken_, phoChargedWorstVtxGeomVetoIsoMap);
532  theEvent.getByToken(phoChargedPFPVIsoToken_, phoChargedPFPVIsoMap);
533 
534  //OOT photons in legacy 80X re-miniAOD workflow dont have cluster isolation embed in them
536  theEvent.getByToken(phoPFECALClusIsolationToken_, phoPFECALClusIsolationMap);
537  }
539  theEvent.getByToken(phoPFHCALClusIsolationToken_, phoPFHCALClusIsolationMap);
540  }
541 
542  if (photonHandle.isValid()) {
543  validPhotonHandle = true;
544  } else {
545  throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the product " << photonProducer_.label() << "\n";
546  }
547  } else {
548  theEvent.getByToken(photonCoreProducerT_, photonCoreHandle);
549  if (photonCoreHandle.isValid()) {
550  validPhotonCoreHandle = true;
551  } else {
552  throw cms::Exception("GEDPhotonProducer")
553  << "Error! Can't get the photonCoreProducer " << photonProducer_.label() << "\n";
554  }
555  }
556 
557  // Get EcalRecHits
558  auto const& barrelRecHits = theEvent.get(barrelEcalHits_);
559  auto const& endcapRecHits = theEvent.get(endcapEcalHits_);
560  auto const& preshowerRecHits = theEvent.get(preshowerHits_);
561 
562  Handle<reco::PFCandidateCollection> pfEGCandidateHandle;
563  // Get the PF refined cluster collection
565  theEvent.getByToken(pfEgammaCandidates_, pfEGCandidateHandle);
566  if (!pfEGCandidateHandle.isValid()) {
567  throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the pfEgammaCandidates";
568  }
569  }
570 
571  Handle<reco::PFCandidateCollection> pfCandidateHandle;
572 
573  if (recoStep_.isFinal()) {
574  // Get the PF candidates collection
575  theEvent.getByToken(pfCandidates_, pfCandidateHandle);
576  //OOT photons have no PF candidates so its not an error in this case
577  if (!pfCandidateHandle.isValid() && !recoStep_.isOOT()) {
578  throw cms::Exception("GEDPhotonProducer") << "Error! Can't get the pfCandidates";
579  }
580  }
581 
582  // get the geometry from the event setup:
584 
585  // prepare access to hcal data
586  if (hcalHelperCone_ != nullptr and hcalHelperBc_ != nullptr) {
587  hcalHelperCone_->beginEvent(theEvent, eventSetup);
588  hcalHelperBc_->beginEvent(theEvent, eventSetup);
589  }
590 
591  auto const& topology = eventSetup.getData(caloTopologyToken_);
592  auto const& thresholds = eventSetup.getData(ecalPFRechitThresholdsToken_);
593 
594  // Get the primary event vertex
595  const reco::VertexCollection dummyVC;
596  auto const& vertexCollection{usePrimaryVertex_ ? theEvent.get(vertexProducer_) : dummyVC};
597 
598  // math::XYZPoint vtx(0.,0.,0.);
599  //if (vertexCollection.size()>0) vtx = vertexCollection.begin()->position();
600 
601  // get the regression calculator ready
603  if (photonEnergyCorrector_->gedRegression()) {
604  photonEnergyCorrector_->gedRegression()->setEvent(theEvent);
605  photonEnergyCorrector_->gedRegression()->setEventContent(eventSetup);
606  }
607 
609  ecalisoAlgo = std::make_unique<PhotonEcalPFClusterIsolation>(ecaldrMax_,
616 
617  hcalisoAlgo = std::make_unique<PhotonHcalPFClusterIsolation>(hcaldrMax_,
624  hcaluseEt_);
625 
626  int iSC = 0; // index in photon collection
627  // Loop over barrel and endcap SC collections and fill the photon collection
628  if (validPhotonCoreHandle)
629  fillPhotonCollection(theEvent,
630  eventSetup,
631  photonCoreHandle,
632  &topology,
633  &barrelRecHits,
634  &endcapRecHits,
635  &preshowerRecHits,
636  hcalHelperCone_.get(),
637  hcalHelperBc_.get(),
638  //vtx,
640  *outputPhotonCollection_p,
641  iSC,
642  thresholds);
643 
644  iSC = 0;
645  if (validPhotonHandle && recoStep_.isFinal())
646  fillPhotonCollection(theEvent,
647  eventSetup,
648  photonHandle,
649  pfCandidateHandle,
650  pfEGCandidateHandle,
651  theEvent.get(vertexProducer_),
652  *outputPhotonCollection_p,
653  iSC,
654  phoChargedIsolationMap,
655  phoNeutralHadronIsolationMap,
656  phoPhotonIsolationMap,
657  phoChargedWorstVtxIsoMap,
658  phoChargedWorstVtxGeomVetoIsoMap,
659  phoChargedPFPVIsoMap,
660  phoPFECALClusIsolationMap,
661  phoPFHCALClusIsolationMap);
662 
663  // put the product in the event
664  edm::LogInfo("GEDPhotonProducer") << " Put in the event " << iSC << " Photon Candidates \n";
665 
666  // 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
667  if (hcalRun2EffDepth_) {
668  for (auto& pho : *outputPhotonCollection_p)
669  pho.hcalToRun2EffDepth();
670  }
671  const auto photonOrphHandle = theEvent.put(std::move(outputPhotonCollection_p), photonCollection_);
672 
675  auto pfEGCandToPhotonMap_p = std::make_unique<edm::ValueMap<reco::PhotonRef>>();
676  edm::ValueMap<reco::PhotonRef>::Filler filler(*pfEGCandToPhotonMap_p);
677  unsigned nObj = pfEGCandidateHandle->size();
678  std::vector<reco::PhotonRef> values(nObj);
680  for (unsigned int lCand = 0; lCand < nObj; lCand++) {
681  reco::PFCandidateRef pfCandRef(reco::PFCandidateRef(pfEGCandidateHandle, lCand));
682  reco::SuperClusterRef pfScRef = pfCandRef->superClusterRef();
683 
684  for (unsigned int lSC = 0; lSC < photonOrphHandle->size(); lSC++) {
685  reco::PhotonRef photonRef(reco::PhotonRef(photonOrphHandle, lSC));
686  reco::SuperClusterRef scRef = photonRef->superCluster();
687  if (pfScRef != scRef)
688  continue;
689  values[lCand] = photonRef;
690  }
691  }
692 
693  filler.insert(pfEGCandidateHandle, values.begin(), values.end());
694  filler.fill();
695  theEvent.put(std::move(pfEGCandToPhotonMap_p), valueMapPFCandPhoton_);
696  }
697 }
698 
700  edm::EventSetup const& es,
701  const edm::Handle<reco::PhotonCoreCollection>& photonCoreHandle,
702  const CaloTopology* topology,
703  const EcalRecHitCollection* ecalBarrelHits,
704  const EcalRecHitCollection* ecalEndcapHits,
706  const ElectronHcalHelper* hcalHelperCone,
707  const ElectronHcalHelper* hcalHelperBc,
710  int& iSC,
712  const EcalRecHitCollection* hits = nullptr;
713  std::vector<double> preselCutValues;
714  std::vector<int> flags_, severitiesexcl_;
715 
716  for (unsigned int lSC = 0; lSC < photonCoreHandle->size(); lSC++) {
717  reco::PhotonCoreRef coreRef(reco::PhotonCoreRef(photonCoreHandle, lSC));
718  reco::SuperClusterRef parentSCRef = coreRef->parentSuperCluster();
719  reco::SuperClusterRef scRef = coreRef->superCluster();
720 
721  // const reco::SuperCluster* pClus=&(*scRef);
722  iSC++;
723 
724  DetId::Detector thedet = scRef->seed()->hitsAndFractions()[0].first.det();
725  int subdet = scRef->seed()->hitsAndFractions()[0].first.subdetId();
726  if (subdet == EcalBarrel) {
727  preselCutValues = preselCutValuesBarrel_;
728  hits = ecalBarrelHits;
729  flags_ = flagsexclEB_;
730  severitiesexcl_ = severitiesexclEB_;
731  } else if (subdet == EcalEndcap) {
732  preselCutValues = preselCutValuesEndcap_;
733  hits = ecalEndcapHits;
734  flags_ = flagsexclEE_;
735  severitiesexcl_ = severitiesexclEE_;
736  } else if (EcalTools::isHGCalDet(thedet)) {
737  preselCutValues = preselCutValuesEndcap_;
738  hits = nullptr;
739  flags_ = flagsexclEE_;
740  severitiesexcl_ = severitiesexclEE_;
741  } else {
742  edm::LogWarning("") << "GEDPhotonProducer: do not know if it is a barrel or endcap SuperCluster: " << thedet
743  << ' ' << subdet;
744  }
745 
746  // SC energy preselection
747  if (parentSCRef.isNonnull() &&
748  ptFast(parentSCRef->energy(), parentSCRef->position(), {0, 0, 0}) <= preselCutValues[0])
749  continue;
750 
751  float maxXtal = (hits != nullptr ? EcalClusterTools::eMax(*(scRef->seed()), hits) : 0.f);
752 
753  //AA
754  //Change these to consider severity level of hits
755  float e1x5 = (hits != nullptr ? EcalClusterTools::e1x5(*(scRef->seed()), hits, topology) : 0.f);
756  float e2x5 = (hits != nullptr ? EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
757  float e3x3 = (hits != nullptr ? EcalClusterTools::e3x3(*(scRef->seed()), hits, topology) : 0.f);
758  float e5x5 = (hits != nullptr ? EcalClusterTools::e5x5(*(scRef->seed()), hits, topology) : 0.f);
759  const auto& cov = (hits != nullptr ? EcalClusterTools::covariances(*(scRef->seed()), hits, topology, caloGeom_)
760  : std::array<float, 3>({{0.f, 0.f, 0.f}}));
761  // fractional local covariances
762  const auto& locCov = (hits != nullptr ? EcalClusterTools::localCovariances(*(scRef->seed()), hits, topology)
763  : std::array<float, 3>({{0.f, 0.f, 0.f}}));
764 
765  float sigmaEtaEta = std::sqrt(cov[0]);
766  float sigmaIetaIeta = std::sqrt(locCov[0]);
767 
768  float full5x5_maxXtal = (hits != nullptr ? noZS::EcalClusterTools::eMax(*(scRef->seed()), hits) : 0.f);
769  //AA
770  //Change these to consider severity level of hits
771  float full5x5_e1x5 = (hits != nullptr ? noZS::EcalClusterTools::e1x5(*(scRef->seed()), hits, topology) : 0.f);
772  float full5x5_e2x5 = (hits != nullptr ? noZS::EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
773  float full5x5_e3x3 = (hits != nullptr ? noZS::EcalClusterTools::e3x3(*(scRef->seed()), hits, topology) : 0.f);
774  float full5x5_e5x5 = (hits != nullptr ? noZS::EcalClusterTools::e5x5(*(scRef->seed()), hits, topology) : 0.f);
775  const auto& full5x5_cov =
776  (hits != nullptr ? noZS::EcalClusterTools::covariances(*(scRef->seed()), hits, topology, caloGeom_)
777  : std::array<float, 3>({{0.f, 0.f, 0.f}}));
778  // for full5x5 local covariances, do noise-cleaning
779  // by passing per crystal PF recHit thresholds and mult values.
780  // mult values for EB and EE were obtained by dedicated studies.
781  const auto& full5x5_locCov =
782  (hits != nullptr ? noZS::EcalClusterTools::localCovariances(*(scRef->seed()),
783  hits,
784  topology,
786  &thresholds,
787  multThresEB_,
788  multThresEE_)
789  : std::array<float, 3>({{0.f, 0.f, 0.f}}));
790 
791  float full5x5_sigmaEtaEta = sqrt(full5x5_cov[0]);
792  float full5x5_sigmaIetaIeta = sqrt(full5x5_locCov[0]);
793  float full5x5_sigmaIetaIphi = full5x5_locCov[1];
794 
795  // compute position of ECAL shower
796  math::XYZPoint caloPosition = scRef->position();
797 
799  double photonEnergy = 1.;
800  math::XYZPoint vtx(0., 0., 0.);
801  if (!vertexCollection.empty())
802  vtx = vertexCollection.begin()->position();
803  // compute momentum vector of photon from primary vertex and cluster position
804  math::XYZVector direction = caloPosition - vtx;
805  //math::XYZVector momentum = direction.unit() * photonEnergy ;
806  math::XYZVector momentum = direction.unit();
807 
808  // Create dummy candidate with unit momentum and zero energy to allow setting of all variables. The energy is set for last.
809  math::XYZTLorentzVectorD p4(momentum.x(), momentum.y(), momentum.z(), photonEnergy);
810  reco::Photon newCandidate(p4, caloPosition, coreRef, vtx);
811 
812  //std::cout << " standard p4 before " << newCandidate.p4() << " energy " << newCandidate.energy() << std::endl;
813  //std::cout << " type " <<newCandidate.getCandidateP4type() << " standard p4 after " << newCandidate.p4() << " energy " << newCandidate.energy() << std::endl;
814 
815  // Calculate fiducial flags and isolation variable. Blocked are filled from the isolationCalculator
816  reco::Photon::FiducialFlags fiducialFlags;
817  reco::Photon::IsolationVariables isolVarR03, isolVarR04;
818  if (!EcalTools::isHGCalDet(thedet)) {
819  photonIsoCalculator_->calculate(&newCandidate, evt, es, fiducialFlags, isolVarR04, isolVarR03, hcalCuts_);
820  }
821  newCandidate.setFiducialVolumeFlags(fiducialFlags);
822  newCandidate.setIsolationVariables(isolVarR04, isolVarR03);
823 
825  reco::Photon::ShowerShape showerShape;
826  showerShape.e1x5 = e1x5;
827  showerShape.e2x5 = e2x5;
828  showerShape.e3x3 = e3x3;
829  showerShape.e5x5 = e5x5;
830  showerShape.maxEnergyXtal = maxXtal;
831  showerShape.sigmaEtaEta = sigmaEtaEta;
832  showerShape.sigmaIetaIeta = sigmaIetaIeta;
833  for (uint id = 0; id < showerShape.hcalOverEcal.size(); ++id) {
834  showerShape.hcalOverEcal[id] =
835  (hcalHelperCone != nullptr) ? hcalHelperCone->hcalESum(*scRef, id + 1, hcalCuts_) / scRef->energy() : 0.f;
836 
837  showerShape.hcalOverEcalBc[id] =
838  (hcalHelperBc != nullptr) ? hcalHelperBc->hcalESum(*scRef, id + 1, hcalCuts_) / scRef->energy() : 0.f;
839  }
840  showerShape.invalidHcal = (hcalHelperBc != nullptr) ? !hcalHelperBc->hasActiveHcal(*scRef) : false;
841  if (hcalHelperBc != nullptr)
842  showerShape.hcalTowersBehindClusters = hcalHelperBc->hcalTowersBehindClusters(*scRef);
843  showerShape.pre7DepthHcal = false;
844 
846  const float spp = (!edm::isFinite(locCov[2]) ? 0. : sqrt(locCov[2]));
847  const float sep = locCov[1];
848  showerShape.sigmaIetaIphi = sep;
849  showerShape.sigmaIphiIphi = spp;
850  showerShape.e2nd = (hits != nullptr ? EcalClusterTools::e2nd(*(scRef->seed()), hits) : 0.f);
851  showerShape.eTop = (hits != nullptr ? EcalClusterTools::eTop(*(scRef->seed()), hits, topology) : 0.f);
852  showerShape.eLeft = (hits != nullptr ? EcalClusterTools::eLeft(*(scRef->seed()), hits, topology) : 0.f);
853  showerShape.eRight = (hits != nullptr ? EcalClusterTools::eRight(*(scRef->seed()), hits, topology) : 0.f);
854  showerShape.eBottom = (hits != nullptr ? EcalClusterTools::eBottom(*(scRef->seed()), hits, topology) : 0.f);
855  showerShape.e1x3 = (hits != nullptr ? EcalClusterTools::e1x3(*(scRef->seed()), hits, topology) : 0.f);
856  showerShape.e2x2 = (hits != nullptr ? EcalClusterTools::e2x2(*(scRef->seed()), hits, topology) : 0.f);
857  showerShape.e2x5Max = (hits != nullptr ? EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
858  showerShape.e2x5Left = (hits != nullptr ? EcalClusterTools::e2x5Left(*(scRef->seed()), hits, topology) : 0.f);
859  showerShape.e2x5Right = (hits != nullptr ? EcalClusterTools::e2x5Right(*(scRef->seed()), hits, topology) : 0.f);
860  showerShape.e2x5Top = (hits != nullptr ? EcalClusterTools::e2x5Top(*(scRef->seed()), hits, topology) : 0.f);
861  showerShape.e2x5Bottom = (hits != nullptr ? EcalClusterTools::e2x5Bottom(*(scRef->seed()), hits, topology) : 0.f);
862  if (hits) {
863  Cluster2ndMoments clus2ndMoments = EcalClusterTools::cluster2ndMoments(*(scRef->seed()), *hits);
864  showerShape.smMajor = clus2ndMoments.sMaj;
865  showerShape.smMinor = clus2ndMoments.sMin;
866  showerShape.smAlpha = clus2ndMoments.alpha;
867  } else {
868  showerShape.smMajor = 0.f;
869  showerShape.smMinor = 0.f;
870  showerShape.smAlpha = 0.f;
871  }
872 
873  // fill preshower shapes
874  EcalClusterLazyTools toolsforES(
876  const float sigmaRR = toolsforES.eseffsirir(*scRef);
877  showerShape.effSigmaRR = sigmaRR;
878  newCandidate.setShowerShapeVariables(showerShape);
879 
880  const reco::CaloCluster& seedCluster = *(scRef->seed());
881  DetId seedXtalId = seedCluster.seed();
882  int nSaturatedXtals = 0;
883  bool isSeedSaturated = false;
884  if (hits != nullptr) {
885  const auto hitsAndFractions = scRef->hitsAndFractions();
886  for (auto const& hitFractionPair : hitsAndFractions) {
887  auto&& ecalRecHit = hits->find(hitFractionPair.first);
888  if (ecalRecHit == hits->end())
889  continue;
890  if (ecalRecHit->checkFlag(EcalRecHit::Flags::kSaturated)) {
891  nSaturatedXtals++;
892  if (seedXtalId == ecalRecHit->detid())
893  isSeedSaturated = true;
894  }
895  }
896  }
897  reco::Photon::SaturationInfo saturationInfo;
898  saturationInfo.nSaturatedXtals = nSaturatedXtals;
899  saturationInfo.isSeedSaturated = isSeedSaturated;
900  newCandidate.setSaturationInfo(saturationInfo);
901 
903  reco::Photon::ShowerShape full5x5_showerShape;
904  full5x5_showerShape.e1x5 = full5x5_e1x5;
905  full5x5_showerShape.e2x5 = full5x5_e2x5;
906  full5x5_showerShape.e3x3 = full5x5_e3x3;
907  full5x5_showerShape.e5x5 = full5x5_e5x5;
908  full5x5_showerShape.maxEnergyXtal = full5x5_maxXtal;
909  full5x5_showerShape.sigmaEtaEta = full5x5_sigmaEtaEta;
910  full5x5_showerShape.sigmaIetaIeta = full5x5_sigmaIetaIeta;
912  const float full5x5_spp = (!edm::isFinite(full5x5_locCov[2]) ? 0. : std::sqrt(full5x5_locCov[2]));
913  const float full5x5_sep = full5x5_sigmaIetaIphi;
914  full5x5_showerShape.sigmaIetaIphi = full5x5_sep;
915  full5x5_showerShape.sigmaIphiIphi = full5x5_spp;
916  full5x5_showerShape.e2nd = (hits != nullptr ? noZS::EcalClusterTools::e2nd(*(scRef->seed()), hits) : 0.f);
917  full5x5_showerShape.eTop = (hits != nullptr ? noZS::EcalClusterTools::eTop(*(scRef->seed()), hits, topology) : 0.f);
918  full5x5_showerShape.eLeft =
919  (hits != nullptr ? noZS::EcalClusterTools::eLeft(*(scRef->seed()), hits, topology) : 0.f);
920  full5x5_showerShape.eRight =
921  (hits != nullptr ? noZS::EcalClusterTools::eRight(*(scRef->seed()), hits, topology) : 0.f);
922  full5x5_showerShape.eBottom =
923  (hits != nullptr ? noZS::EcalClusterTools::eBottom(*(scRef->seed()), hits, topology) : 0.f);
924  full5x5_showerShape.e1x3 = (hits != nullptr ? noZS::EcalClusterTools::e1x3(*(scRef->seed()), hits, topology) : 0.f);
925  full5x5_showerShape.e2x2 = (hits != nullptr ? noZS::EcalClusterTools::e2x2(*(scRef->seed()), hits, topology) : 0.f);
926  full5x5_showerShape.e2x5Max =
927  (hits != nullptr ? noZS::EcalClusterTools::e2x5Max(*(scRef->seed()), hits, topology) : 0.f);
928  full5x5_showerShape.e2x5Left =
929  (hits != nullptr ? noZS::EcalClusterTools::e2x5Left(*(scRef->seed()), hits, topology) : 0.f);
930  full5x5_showerShape.e2x5Right =
931  (hits != nullptr ? noZS::EcalClusterTools::e2x5Right(*(scRef->seed()), hits, topology) : 0.f);
932  full5x5_showerShape.e2x5Top =
933  (hits != nullptr ? noZS::EcalClusterTools::e2x5Top(*(scRef->seed()), hits, topology) : 0.f);
934  full5x5_showerShape.e2x5Bottom =
935  (hits != nullptr ? noZS::EcalClusterTools::e2x5Bottom(*(scRef->seed()), hits, topology) : 0.f);
936  if (hits) {
937  Cluster2ndMoments clus2ndMoments = noZS::EcalClusterTools::cluster2ndMoments(*(scRef->seed()), *hits);
938  full5x5_showerShape.smMajor = clus2ndMoments.sMaj;
939  full5x5_showerShape.smMinor = clus2ndMoments.sMin;
940  full5x5_showerShape.smAlpha = clus2ndMoments.alpha;
941  } else {
942  full5x5_showerShape.smMajor = 0.f;
943  full5x5_showerShape.smMinor = 0.f;
944  full5x5_showerShape.smAlpha = 0.f;
945  }
946  // fill preshower shapes
947  full5x5_showerShape.effSigmaRR = sigmaRR;
948  for (uint id = 0; id < full5x5_showerShape.hcalOverEcal.size(); ++id) {
949  full5x5_showerShape.hcalOverEcal[id] =
950  (hcalHelperCone != nullptr) ? hcalHelperCone->hcalESum(*scRef, id + 1, hcalCuts_) / full5x5_e5x5 : 0.f;
951  full5x5_showerShape.hcalOverEcalBc[id] =
952  (hcalHelperBc != nullptr) ? hcalHelperBc->hcalESum(*scRef, id + 1, hcalCuts_) / full5x5_e5x5 : 0.f;
953  }
954  full5x5_showerShape.pre7DepthHcal = false;
955  newCandidate.full5x5_setShowerShapeVariables(full5x5_showerShape);
956 
957  //get the pointer for the photon object
958  edm::Ptr<reco::PhotonCore> photonPtr(photonCoreHandle, lSC);
959 
960  // New in CMSSW_12_1_0 for PFID with DNNs
961  // The PFIso values are computed in the first loop on gedPhotonsTmp to make them available as DNN inputs.
962  // They are computed with the same inputs and algo as the final PFiso variables computed in the second loop after PF.
963  // Get PFClusters for PFID only if the PFID DNN evaluation is enabled
964  if (dnnPFidEnabled_) {
965  auto clusterHandle = evt.getHandle(pfClusterProducer_);
966  std::vector<edm::Handle<reco::PFClusterCollection>> clusterHandles{evt.getHandle(pfClusterProducerHCAL_)};
967  if (useHF_) {
968  clusterHandles.push_back(evt.getHandle(pfClusterProducerHFEM_));
969  clusterHandles.push_back(evt.getHandle(pfClusterProducerHFHAD_));
970  }
972  pfIso.sumEcalClusterEt = ecalisoAlgo->getSum(newCandidate, clusterHandle);
973  pfIso.sumHcalClusterEt = hcalisoAlgo->getSum(newCandidate, clusterHandles);
974 
975  newCandidate.setPflowIsolationVariables(pfIso);
976  }
977 
980  // Photon candidate takes by default (set in photons_cfi.py)
981  // a 4-momentum derived from the ecal photon-specific corrections.
982  if (!EcalTools::isHGCalDet(thedet)) {
983  photonEnergyCorrector_->calculate(evt, newCandidate, subdet, vertexCollection, es);
984  if (candidateP4type_ == "fromEcalEnergy") {
985  newCandidate.setP4(newCandidate.p4(reco::Photon::ecal_photons));
986  newCandidate.setCandidateP4type(reco::Photon::ecal_photons);
987  newCandidate.setMass(0.0);
988  } else if (candidateP4type_ == "fromRegression1") {
989  newCandidate.setP4(newCandidate.p4(reco::Photon::regression1));
990  newCandidate.setCandidateP4type(reco::Photon::regression1);
991  newCandidate.setMass(0.0);
992  } else if (candidateP4type_ == "fromRegression2") {
993  newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
994  newCandidate.setCandidateP4type(reco::Photon::regression2);
995  newCandidate.setMass(0.0);
996  } else if (candidateP4type_ == "fromRefinedSCRegression") {
997  newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
998  newCandidate.setCandidateP4type(reco::Photon::regression2);
999  newCandidate.setMass(0.0);
1000  }
1001  } else {
1002  math::XYZVector gamma_momentum = direction.unit() * scRef->energy();
1003  math::PtEtaPhiMLorentzVector p4(gamma_momentum.rho(), gamma_momentum.eta(), gamma_momentum.phi(), 0.0);
1004  newCandidate.setP4(p4);
1005  newCandidate.setCandidateP4type(reco::Photon::ecal_photons);
1006  // Make it an EE photon
1007  reco::Photon::FiducialFlags fiducialFlags;
1008  fiducialFlags.isEE = true;
1009  newCandidate.setFiducialVolumeFlags(fiducialFlags);
1010  }
1011 
1012  // fill MIP Vairables for Halo: Block for MIP are filled from PhotonMIPHaloTagger
1014  if (subdet == EcalBarrel && runMIPTagger_) {
1015  photonMIPHaloTagger_->MIPcalculate(&newCandidate, evt, es, mipVar);
1016  newCandidate.setMIPVariables(mipVar);
1017  }
1018 
1020  bool isLooseEM = true;
1021  if (newCandidate.pt() < highEt_) {
1022  if (newCandidate.hadronicOverEm() >= preselCutValues[1])
1023  isLooseEM = false;
1024  if (newCandidate.ecalRecHitSumEtConeDR04() > preselCutValues[2] + preselCutValues[3] * newCandidate.pt())
1025  isLooseEM = false;
1026  if (newCandidate.hcalTowerSumEtConeDR04() > preselCutValues[4] + preselCutValues[5] * newCandidate.pt())
1027  isLooseEM = false;
1028  if (newCandidate.nTrkSolidConeDR04() > int(preselCutValues[6]))
1029  isLooseEM = false;
1030  if (newCandidate.nTrkHollowConeDR04() > int(preselCutValues[7]))
1031  isLooseEM = false;
1032  if (newCandidate.trkSumPtSolidConeDR04() > preselCutValues[8])
1033  isLooseEM = false;
1034  if (newCandidate.trkSumPtHollowConeDR04() > preselCutValues[9])
1035  isLooseEM = false;
1036  if (newCandidate.sigmaIetaIeta() > preselCutValues[10])
1037  isLooseEM = false;
1038  }
1039 
1040  if (isLooseEM)
1041  outputPhotonCollection.push_back(newCandidate);
1042  }
1043 
1044  if (dnnPFidEnabled_) {
1045  // Here send the list of photons to the PhotonDNNEstimator and get back the values for all the photons in one go
1046  LogDebug("GEDPhotonProducer") << "Getting DNN PFId for photons";
1047  const auto& dnn_photon_pfid = globalCache()->photonDNNEstimator->evaluate(outputPhotonCollection, tfSessions_);
1048  size_t ipho = 0;
1049  for (auto& photon : outputPhotonCollection) {
1050  const auto& [iModel, values] = dnn_photon_pfid[ipho];
1052  // The model index it is not useful for the moment
1053  pfID.dnn = values[0];
1054  photon.setPflowIDVariables(pfID);
1055  ipho++;
1056  }
1057  }
1058 }
1059 
1061  edm::EventSetup const& es,
1062  const edm::Handle<reco::PhotonCollection>& photonHandle,
1063  const edm::Handle<reco::PFCandidateCollection> pfCandidateHandle,
1064  const edm::Handle<reco::PFCandidateCollection> pfEGCandidateHandle,
1067  int& iSC,
1068  const edm::Handle<edm::ValueMap<float>>& chargedHadrons,
1069  const edm::Handle<edm::ValueMap<float>>& neutralHadrons,
1071  const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtx,
1072  const edm::Handle<edm::ValueMap<float>>& chargedHadronsWorstVtxGeomVeto,
1073  const edm::Handle<edm::ValueMap<float>>& chargedHadronsPFPV,
1074  const edm::Handle<edm::ValueMap<float>>& pfEcalClusters,
1075  const edm::Handle<edm::ValueMap<float>>& pfHcalClusters) {
1076  std::vector<double> preselCutValues;
1077 
1078  for (unsigned int lSC = 0; lSC < photonHandle->size(); lSC++) {
1079  reco::PhotonRef phoRef(reco::PhotonRef(photonHandle, lSC));
1080  reco::SuperClusterRef parentSCRef = phoRef->parentSuperCluster();
1081  reco::SuperClusterRef scRef = phoRef->superCluster();
1082  DetId::Detector thedet = scRef->seed()->hitsAndFractions()[0].first.det();
1083  int subdet = scRef->seed()->hitsAndFractions()[0].first.subdetId();
1084  if (subdet == EcalBarrel) {
1085  preselCutValues = preselCutValuesBarrel_;
1086  } else if (subdet == EcalEndcap) {
1087  preselCutValues = preselCutValuesEndcap_;
1088  } else if (EcalTools::isHGCalDet(thedet)) {
1089  preselCutValues = preselCutValuesEndcap_;
1090  } else {
1091  edm::LogWarning("") << "GEDPhotonProducer: do not know if it is a barrel or endcap SuperCluster" << thedet << ' '
1092  << subdet;
1093  }
1094 
1095  // SC energy preselection
1096  if (parentSCRef.isNonnull() &&
1097  ptFast(parentSCRef->energy(), parentSCRef->position(), {0, 0, 0}) <= preselCutValues[0])
1098  continue;
1099 
1100  reco::Photon newCandidate(*phoRef);
1101  iSC++;
1102 
1103  if (runMVABasedHaloTagger_) {
1104  float BHmva = photonMVABasedHaloTagger_->calculateMVA(&newCandidate, globalCache()->haloTaggerGBR.get(), evt, es);
1105  newCandidate.setHaloTaggerMVAVal(BHmva);
1106  }
1107 
1108  // Calculate the PF isolation
1110  // The PFID are not recomputed since they have been already computed in the first loop with the DNN
1111 
1112  //get the pointer for the photon object
1113  edm::Ptr<reco::Photon> photonPtr(photonHandle, lSC);
1114 
1115  if (!recoStep_.isOOT()) { //out of time photons do not have PF info so skip in this case
1116  pfIso.chargedHadronIso = (*chargedHadrons)[photonPtr];
1117  pfIso.neutralHadronIso = (*neutralHadrons)[photonPtr];
1118  pfIso.photonIso = (*photons)[photonPtr];
1119  pfIso.chargedHadronWorstVtxIso = (*chargedHadronsWorstVtx)[photonPtr];
1120  pfIso.chargedHadronWorstVtxGeomVetoIso = (*chargedHadronsWorstVtxGeomVeto)[photonPtr];
1121  pfIso.chargedHadronPFPVIso = (*chargedHadronsPFPV)[photonPtr];
1122  }
1123 
1124  //OOT photons in legacy 80X reminiAOD workflow dont have pf cluster isolation embeded into them at this stage
1125  // They have been already computed in the first loop on gedPhotonsTmp but better to compute them again here.
1126  pfIso.sumEcalClusterEt = !phoPFECALClusIsolationToken_.isUninitialized() ? (*pfEcalClusters)[photonPtr] : 0.;
1127  pfIso.sumHcalClusterEt = !phoPFHCALClusIsolationToken_.isUninitialized() ? (*pfHcalClusters)[photonPtr] : 0.;
1128  newCandidate.setPflowIsolationVariables(pfIso);
1129 
1130  // do the regression
1131  photonEnergyCorrector_->calculate(evt, newCandidate, subdet, vertexCollection, es);
1132  if (candidateP4type_ == "fromEcalEnergy") {
1133  newCandidate.setP4(newCandidate.p4(reco::Photon::ecal_photons));
1135  newCandidate.setMass(0.0);
1136  } else if (candidateP4type_ == "fromRegression1") {
1137  newCandidate.setP4(newCandidate.p4(reco::Photon::regression1));
1139  newCandidate.setMass(0.0);
1140  } else if (candidateP4type_ == "fromRegression2") {
1141  newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
1143  newCandidate.setMass(0.0);
1144  } else if (candidateP4type_ == "fromRefinedSCRegression") {
1145  newCandidate.setP4(newCandidate.p4(reco::Photon::regression2));
1147  newCandidate.setMass(0.0);
1148  }
1149 
1150  outputPhotonCollection.push_back(newCandidate);
1151  }
1152 }
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
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:218
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:528
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: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:243
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:552
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
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
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