CMS 3D CMS Logo

GsfElectronProducer.cc
Go to the documentation of this file.
27 
28 #include <array>
29 
30 using namespace reco;
31 
32 namespace {
33 
34  void setMVAOutputs(reco::GsfElectronCollection& electrons,
37  bool dnnPFidEnabled,
38  float extetaboundary,
39  const std::vector<tensorflow::Session*>& tfSessions) {
40  std::vector<GsfElectron::MvaOutput> mva_outputs(electrons.size());
41  size_t iele = 0;
42  for (auto& el : electrons) {
43  GsfElectron::MvaOutput mvaOutput;
44  mvaOutput.mva_e_pi = hoc->sElectronMVAEstimator->mva(el, vertices);
45  mvaOutput.mva_Isolated = hoc->iElectronMVAEstimator->mva(el, vertices.size());
46  if (dnnPFidEnabled) {
47  mva_outputs[iele] = mvaOutput;
48  } else {
49  el.setMvaOutput(mvaOutput);
50  }
51  iele++;
52  }
53  if (dnnPFidEnabled) {
54  // Here send the list of electrons to the ElectronDNNEstimator and get back the values for all the electrons in one go
55  LogDebug("GsfElectronProducer") << "Getting DNN PFId for ele";
56  const auto& dnn_ele_pfid = hoc->iElectronDNNEstimator->evaluate(electrons, tfSessions);
57  int jele = 0;
58  for (auto& el : electrons) {
59  const auto& values = dnn_ele_pfid[jele];
60  // get the previous values
61  auto& mvaOutput = mva_outputs[jele];
62 
63  if (abs(el.superCluster()->eta()) <= extetaboundary) {
64  mvaOutput.dnn_e_sigIsolated = values[0];
65  mvaOutput.dnn_e_sigNonIsolated = values[1];
66  mvaOutput.dnn_e_bkgNonIsolated = values[2];
67  mvaOutput.dnn_e_bkgTau = values[3];
68  mvaOutput.dnn_e_bkgPhoton = values[4];
69  } else {
70  mvaOutput.dnn_e_sigIsolated = values[0];
71  mvaOutput.dnn_e_sigNonIsolated = 0.0;
72  mvaOutput.dnn_e_bkgNonIsolated = values[1];
73  mvaOutput.dnn_e_bkgTau = 0.0;
74  mvaOutput.dnn_e_bkgPhoton = values[2];
75  }
76  el.setMvaOutput(mvaOutput);
77  jele++;
78  }
79  }
80  }
81 
82  // Something more clever has to be found. The collections are small, so the timing is not
83  // an issue here; but it is clearly suboptimal
84 
85  auto matchWithPFCandidates(std::vector<reco::PFCandidate> const& pfCandidates) {
86  std::map<reco::GsfTrackRef, reco::GsfElectron::MvaInput> gsfMVAInputs{};
87 
88  //Loop over the collection of PFFCandidates
89  for (auto const& pfCand : pfCandidates) {
91  // First check that the GsfTrack is non null
92  if (pfCand.gsfTrackRef().isNonnull()) {
94  input.earlyBrem = pfCand.egammaExtraRef()->mvaVariable(reco::PFCandidateEGammaExtra::MVA_FirstBrem);
95  input.lateBrem = pfCand.egammaExtraRef()->mvaVariable(reco::PFCandidateEGammaExtra::MVA_LateBrem);
96  input.deltaEta = pfCand.egammaExtraRef()->mvaVariable(reco::PFCandidateEGammaExtra::MVA_DeltaEtaTrackCluster);
97  input.sigmaEtaEta = pfCand.egammaExtraRef()->sigmaEtaEta();
98  input.hadEnergy = pfCand.egammaExtraRef()->hadEnergy();
99  gsfMVAInputs[pfCand.gsfTrackRef()] = input;
100  }
101  }
102  return gsfMVAInputs;
103  }
104 
105  void logElectrons(reco::GsfElectronCollection const& electrons, edm::Event const& event, const std::string& title) {
106  LogTrace("GsfElectronAlgo") << "========== " << title << " ==========";
107  LogTrace("GsfElectronAlgo") << "Event: " << event.id();
108  LogTrace("GsfElectronAlgo") << "Number of electrons: " << electrons.size();
109  for (auto const& ele : electrons) {
110  LogTrace("GsfElectronAlgo") << "Electron with charge, pt, eta, phi: " << ele.charge() << " , " << ele.pt()
111  << " , " << ele.eta() << " , " << ele.phi();
112  }
113  LogTrace("GsfElectronAlgo") << "=================================================";
114  }
115 
116 } // namespace
117 
118 class GsfElectronProducer : public edm::stream::EDProducer<edm::GlobalCache<GsfElectronAlgo::HeavyObjectCache>> {
119 public:
121 
123 
124  static std::unique_ptr<GsfElectronAlgo::HeavyObjectCache> initializeGlobalCache(const edm::ParameterSet& conf) {
125  return std::make_unique<GsfElectronAlgo::HeavyObjectCache>(conf);
126  }
127 
128  void endStream() override;
129 
131 
132  // ------------ method called to produce the data ------------
133  void produce(edm::Event& event, const edm::EventSetup& setup) override;
134 
135 private:
136  std::unique_ptr<GsfElectronAlgo> algo_;
137 
138  // configurables
143 
145 
146  bool isPreselected(reco::GsfElectron const& ele) const;
147  void setAmbiguityData(reco::GsfElectronCollection& electrons,
148  edm::Event const& event,
149  bool ignoreNotPreselected = true) const;
150 
151  // check expected configuration of previous modules
153  void checkEcalSeedingParameters(edm::ParameterSet const&);
154 
158 
159  const bool useGsfPfRecTracks_;
160 
162 
165 
166  std::vector<tensorflow::Session*> tfSessions_;
167 };
168 
171  // input collections
172  desc.add<edm::InputTag>("gsfElectronCoresTag", {"ecalDrivenGsfElectronCores"});
173  desc.add<edm::InputTag>("vtxTag", {"offlinePrimaryVertices"});
174  desc.add<edm::InputTag>("conversionsTag", {"allConversions"});
175  desc.add<edm::InputTag>("gsfPfRecTracksTag", {"pfTrackElec"});
176  desc.add<edm::InputTag>("barrelRecHitCollectionTag", {"ecalRecHit", "EcalRecHitsEB"});
177  desc.add<edm::InputTag>("endcapRecHitCollectionTag", {"ecalRecHit", "EcalRecHitsEE"});
178  desc.add<edm::InputTag>("seedsTag", {"ecalDrivenElectronSeeds"});
179  desc.add<edm::InputTag>("beamSpotTag", {"offlineBeamSpot"});
180  desc.add<edm::InputTag>("egmPFCandidatesTag", {"particleFlowEGamma"});
181 
182  // steering
183  desc.add<bool>("useDefaultEnergyCorrection", true);
184  desc.add<bool>("useCombinationRegression", false);
185  desc.add<bool>("ecalDrivenEcalEnergyFromClassBasedParameterization", true);
186  desc.add<bool>("ecalDrivenEcalErrorFromClassBasedParameterization", true);
187  desc.add<bool>("applyPreselection", false);
188  desc.add<bool>("useEcalRegression", false);
189  desc.add<bool>("applyAmbResolution", false);
190  desc.add<bool>("ignoreNotPreselected", true);
191  desc.add<bool>("useGsfPfRecTracks", true);
192  desc.add<bool>("pureTrackerDrivenEcalErrorFromSimpleParameterization", true);
193  desc.add<unsigned int>("ambSortingStrategy", 1);
194  desc.add<unsigned int>("ambClustersOverlapStrategy", 1);
195  desc.add<bool>("fillConvVtxFitProb", true);
196  desc.add<bool>("resetMvaValuesUsingPFCandidates", false);
197 
198  // Ecal rec hits configuration
199  desc.add<std::vector<std::string>>("recHitFlagsToBeExcludedBarrel");
200  desc.add<std::vector<std::string>>("recHitFlagsToBeExcludedEndcaps");
201  desc.add<std::vector<std::string>>("recHitSeverityToBeExcludedBarrel");
202  desc.add<std::vector<std::string>>("recHitSeverityToBeExcludedEndcaps");
203 
204  // Hcal rec hits configuration
205  desc.add<bool>("checkHcalStatus", true);
206  desc.add<edm::InputTag>("hbheRecHits", edm::InputTag("hbhereco"));
207  desc.add<std::vector<double>>("recHitEThresholdHB", {0., 0., 0., 0.});
208  desc.add<std::vector<double>>("recHitEThresholdHE", {0., 0., 0., 0., 0., 0., 0.});
209  desc.add<int>("maxHcalRecHitSeverity", 999999);
210  desc.add<bool>("hcalRun2EffDepth", false);
211 
212  // Isolation algos configuration
213  desc.add("trkIsol03Cfg", EleTkIsolFromCands::pSetDescript());
214  desc.add("trkIsol04Cfg", EleTkIsolFromCands::pSetDescript());
215  desc.add("trkIsolHEEP03Cfg", EleTkIsolFromCands::pSetDescript());
216  desc.add("trkIsolHEEP04Cfg", EleTkIsolFromCands::pSetDescript());
217  desc.add<bool>("useNumCrystals", true);
218  desc.add<double>("etMinBarrel", 0.0);
219  desc.add<double>("etMinEndcaps", 0.11);
220  desc.add<double>("etMinHcal", 0.0);
221  desc.add<double>("eMinBarrel", 0.095);
222  desc.add<double>("eMinEndcaps", 0.0);
223  desc.add<double>("intRadiusEcalBarrel", 3.0);
224  desc.add<double>("intRadiusEcalEndcaps", 3.0);
225  desc.add<double>("intRadiusHcal", 0.15);
226  desc.add<double>("jurassicWidth", 1.5);
227  desc.add<bool>("vetoClustered", false);
228 
229  // backward compatibility mechanism for ctf tracks
230  desc.add<bool>("ctfTracksCheck", true);
231  desc.add<edm::InputTag>("ctfTracksTag", {"generalTracks"});
232 
233  desc.add<double>("MaxElePtForOnlyMVA", 50.0);
234  desc.add<double>("PreSelectMVA", -0.1);
235 
236  {
238  psd0.add<double>("minSCEtBarrel", 4.0);
239  psd0.add<double>("minSCEtEndcaps", 4.0);
240  psd0.add<double>("minEOverPBarrel", 0.0);
241  psd0.add<double>("minEOverPEndcaps", 0.0);
242  psd0.add<double>("maxEOverPBarrel", 999999999.0);
243  psd0.add<double>("maxEOverPEndcaps", 999999999.0);
244  psd0.add<double>("maxDeltaEtaBarrel", 0.02);
245  psd0.add<double>("maxDeltaEtaEndcaps", 0.02);
246  psd0.add<double>("maxDeltaPhiBarrel", 0.15);
247  psd0.add<double>("maxDeltaPhiEndcaps", 0.15);
248  psd0.add<double>("hOverEConeSize", 0.15);
249  psd0.add<double>("maxHOverEBarrelCone", 0.15);
250  psd0.add<double>("maxHOverEEndcapsCone", 0.15);
251  psd0.add<double>("maxHBarrelCone", 0.0);
252  psd0.add<double>("maxHEndcapsCone", 0.0);
253  psd0.add<double>("maxHOverEBarrelBc", 0.15);
254  psd0.add<double>("maxHOverEEndcapsBc", 0.15);
255  psd0.add<double>("maxHBarrelBc", 0.0);
256  psd0.add<double>("maxHEndcapsBc", 0.0);
257  psd0.add<double>("maxSigmaIetaIetaBarrel", 999999999.0);
258  psd0.add<double>("maxSigmaIetaIetaEndcaps", 999999999.0);
259  psd0.add<double>("maxFbremBarrel", 999999999.0);
260  psd0.add<double>("maxFbremEndcaps", 999999999.0);
261  psd0.add<bool>("isBarrel", false);
262  psd0.add<bool>("isEndcaps", false);
263  psd0.add<bool>("isFiducial", false);
264  psd0.add<bool>("seedFromTEC", true);
265  psd0.add<double>("maxTIP", 999999999.0);
266  psd0.add<double>("multThresEB", EgammaLocalCovParamDefaults::kMultThresEB);
267  psd0.add<double>("multThresEE", EgammaLocalCovParamDefaults::kMultThresEE);
268  // preselection parameters
269  desc.add<edm::ParameterSetDescription>("preselection", psd0);
270  }
271 
272  // Corrections
273  desc.add<std::string>("crackCorrectionFunction", "EcalClusterCrackCorrection");
274 
275  desc.add<bool>("ecalWeightsFromDB", true);
276  desc.add<std::vector<std::string>>("ecalRefinedRegressionWeightFiles", {})
277  ->setComment("if not from DB. Otherwise, keep empty");
278  desc.add<bool>("combinationWeightsFromDB", true);
279  desc.add<std::vector<std::string>>("combinationRegressionWeightFile", {})
280  ->setComment("if not from DB. Otherwise, keep empty");
281 
282  // regression. The labels are needed in all cases.
283  desc.add<std::vector<std::string>>("ecalRefinedRegressionWeightLabels", {});
284  desc.add<std::vector<std::string>>("combinationRegressionWeightLabels", {});
285 
286  desc.add<std::vector<std::string>>(
287  "ElecMVAFilesString",
288  {
289  "RecoEgamma/ElectronIdentification/data/TMVA_Category_BDTSimpleCat_10_17Feb2011.weights.xml",
290  "RecoEgamma/ElectronIdentification/data/TMVA_Category_BDTSimpleCat_12_17Feb2011.weights.xml",
291  "RecoEgamma/ElectronIdentification/data/TMVA_Category_BDTSimpleCat_20_17Feb2011.weights.xml",
292  "RecoEgamma/ElectronIdentification/data/TMVA_Category_BDTSimpleCat_22_17Feb2011.weights.xml",
293  });
294  desc.add<std::vector<std::string>>(
295  "SoftElecMVAFilesString",
296  {
297  "RecoEgamma/ElectronIdentification/data/TMVA_BDTSoftElectrons_7Feb2014.weights.xml",
298  });
299 
300  {
302  psd1.add<bool>("enabled", false);
303  psd1.add<double>("extetaboundary", 2.65);
304  psd1.add<std::string>("inputTensorName", "FirstLayer_input");
305  psd1.add<std::string>("outputTensorName", "sequential/FinalLayer/Softmax");
306 
307  psd1.add<std::vector<std::string>>(
308  "modelsFiles",
309  {"RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/lowpT/lowpT_modelDNN.pb",
310  "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/highpTEB/highpTEB_modelDNN.pb",
311  "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/highpTEE/highpTEE_modelDNN.pb",
312  "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Winter22_122X/exteta1/modelDNN.pb",
313  "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Winter22_122X/exteta2/modelDNN.pb"});
314  psd1.add<std::vector<std::string>>(
315  "scalersFiles",
316  {"RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/lowpT/lowpT_scaler.txt",
317  "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/highpTEB/highpTEB_scaler.txt",
318  "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/highpTEE/highpTEE_scaler.txt",
319  "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Winter22_122X/exteta1/scaler.txt",
320  "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Winter22_122X/exteta2/scaler.txt"});
321  psd1.add<std::vector<unsigned int>>("outputDim", //Number of output nodes for the above models
322  {5, 5, 5, 5, 3});
323 
324  psd1.add<bool>("useEBModelInGap", true);
325  // preselection parameters
326  desc.add<edm::ParameterSetDescription>("EleDNNPFid", psd1);
327  }
328 
331  {
333  psd0.add<edm::InputTag>("pfClusterProducer", edm::InputTag("particleFlowClusterECAL"));
334  psd0.add<double>("drMax", 0.3);
335  psd0.add<double>("drVetoBarrel", 0.0);
336  psd0.add<double>("drVetoEndcap", 0.0);
337  psd0.add<double>("etaStripBarrel", 0.0);
338  psd0.add<double>("etaStripEndcap", 0.0);
339  psd0.add<double>("energyBarrel", 0.0);
340  psd0.add<double>("energyEndcap", 0.0);
341  desc.add<edm::ParameterSetDescription>("pfECALClusIsolCfg", psd0);
342  }
343 
345  {
347  psd0.add<edm::InputTag>("pfClusterProducerHCAL", edm::InputTag("particleFlowClusterHCAL"));
348  psd0.add<edm::InputTag>("pfClusterProducerHFEM", edm::InputTag(""));
349  psd0.add<edm::InputTag>("pfClusterProducerHFHAD", edm::InputTag(""));
350  psd0.add<bool>("useHF", false);
351  psd0.add<double>("drMax", 0.3);
352  psd0.add<double>("drVetoBarrel", 0.0);
353  psd0.add<double>("drVetoEndcap", 0.0);
354  psd0.add<double>("etaStripBarrel", 0.0);
355  psd0.add<double>("etaStripEndcap", 0.0);
356  psd0.add<double>("energyBarrel", 0.0);
357  psd0.add<double>("energyEndcap", 0.0);
358  psd0.add<bool>("useEt", true);
359  desc.add<edm::ParameterSetDescription>("pfHCALClusIsolCfg", psd0);
360  }
361 
362  descriptions.add("gsfElectronProducerDefault", desc);
363 }
364 
365 namespace {
366  GsfElectronAlgo::CutsConfiguration makeCutsConfiguration(edm::ParameterSet const& pset) {
368  .minSCEtBarrel = pset.getParameter<double>("minSCEtBarrel"),
369  .minSCEtEndcaps = pset.getParameter<double>("minSCEtEndcaps"),
370  .maxEOverPBarrel = pset.getParameter<double>("maxEOverPBarrel"),
371  .maxEOverPEndcaps = pset.getParameter<double>("maxEOverPEndcaps"),
372  .minEOverPBarrel = pset.getParameter<double>("minEOverPBarrel"),
373  .minEOverPEndcaps = pset.getParameter<double>("minEOverPEndcaps"),
374  .maxHOverEBarrelCone = pset.getParameter<double>("maxHOverEBarrelCone"),
375  .maxHOverEEndcapsCone = pset.getParameter<double>("maxHOverEEndcapsCone"),
376  .maxHBarrelCone = pset.getParameter<double>("maxHBarrelCone"),
377  .maxHEndcapsCone = pset.getParameter<double>("maxHEndcapsCone"),
378  .maxHOverEBarrelBc = pset.getParameter<double>("maxHOverEBarrelBc"),
379  .maxHOverEEndcapsBc = pset.getParameter<double>("maxHOverEEndcapsBc"),
380  .maxHBarrelBc = pset.getParameter<double>("maxHBarrelBc"),
381  .maxHEndcapsBc = pset.getParameter<double>("maxHEndcapsBc"),
382  .maxDeltaEtaBarrel = pset.getParameter<double>("maxDeltaEtaBarrel"),
383  .maxDeltaEtaEndcaps = pset.getParameter<double>("maxDeltaEtaEndcaps"),
384  .maxDeltaPhiBarrel = pset.getParameter<double>("maxDeltaPhiBarrel"),
385  .maxDeltaPhiEndcaps = pset.getParameter<double>("maxDeltaPhiEndcaps"),
386  .maxSigmaIetaIetaBarrel = pset.getParameter<double>("maxSigmaIetaIetaBarrel"),
387  .maxSigmaIetaIetaEndcaps = pset.getParameter<double>("maxSigmaIetaIetaEndcaps"),
388  .maxFbremBarrel = pset.getParameter<double>("maxFbremBarrel"),
389  .maxFbremEndcaps = pset.getParameter<double>("maxFbremEndcaps"),
390  .isBarrel = pset.getParameter<bool>("isBarrel"),
391  .isEndcaps = pset.getParameter<bool>("isEndcaps"),
392  .isFiducial = pset.getParameter<bool>("isFiducial"),
393  .maxTIP = pset.getParameter<double>("maxTIP"),
394  .seedFromTEC = pset.getParameter<bool>("seedFromTEC"),
395  .multThresEB = pset.getParameter<double>("multThresEB"),
396  .multThresEE = pset.getParameter<double>("multThresEE"),
397  };
398  }
399 }; // namespace
400 
402  : cutsCfg_{makeCutsConfiguration(cfg.getParameter<edm::ParameterSet>("preselection"))},
403  ecalSeedingParametersChecked_(false),
404  electronPutToken_(produces<GsfElectronCollection>()),
405  gsfPfRecTracksTag_(consumes(cfg.getParameter<edm::InputTag>("gsfPfRecTracksTag"))),
406  useGsfPfRecTracks_(cfg.getParameter<bool>("useGsfPfRecTracks")),
407  resetMvaValuesUsingPFCandidates_(cfg.getParameter<bool>("resetMvaValuesUsingPFCandidates")) {
408  if (resetMvaValuesUsingPFCandidates_) {
409  egmPFCandidateCollection_ = consumes(cfg.getParameter<edm::InputTag>("egmPFCandidatesTag"));
410  }
411 
412  inputCfg_.gsfElectronCores = consumes(cfg.getParameter<edm::InputTag>("gsfElectronCoresTag"));
413  inputCfg_.hbheRecHitsTag = consumes(cfg.getParameter<edm::InputTag>("hbheRecHits"));
414  inputCfg_.barrelRecHitCollection = consumes(cfg.getParameter<edm::InputTag>("barrelRecHitCollectionTag"));
415  inputCfg_.endcapRecHitCollection = consumes(cfg.getParameter<edm::InputTag>("endcapRecHitCollectionTag"));
416  inputCfg_.ctfTracks = consumes(cfg.getParameter<edm::InputTag>("ctfTracksTag"));
417  // used to check config consistency with seeding
418  inputCfg_.seedsTag = consumes(cfg.getParameter<edm::InputTag>("seedsTag"));
419  inputCfg_.beamSpotTag = consumes(cfg.getParameter<edm::InputTag>("beamSpotTag"));
420  inputCfg_.vtxCollectionTag = consumes(cfg.getParameter<edm::InputTag>("vtxTag"));
421  if (cfg.getParameter<bool>("fillConvVtxFitProb"))
422  inputCfg_.conversions = consumes(cfg.getParameter<edm::InputTag>("conversionsTag"));
423 
424  // inputs for PFCluster isolation
425  const edm::ParameterSet& pfECALClusIsolCfg = cfg.getParameter<edm::ParameterSet>("pfECALClusIsolCfg");
426  const edm::ParameterSet& pfHCALClusIsolCfg = cfg.getParameter<edm::ParameterSet>("pfHCALClusIsolCfg");
427  inputCfg_.pfClusterProducer =
428  consumes<reco::PFClusterCollection>(pfECALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducer"));
429  inputCfg_.pfClusterProducerHCAL = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHCAL"));
430  inputCfg_.pfClusterProducerHFEM = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFEM"));
431  inputCfg_.pfClusterProducerHFHAD = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFHAD"));
432 
433  // Config for PFID dnn
434  const auto& pset_dnn = cfg.getParameter<edm::ParameterSet>("EleDNNPFid");
435  dnnPFidEnabled_ = pset_dnn.getParameter<bool>("enabled");
436  extetaboundary_ = pset_dnn.getParameter<double>("extetaboundary");
437 
438  strategyCfg_.useDefaultEnergyCorrection = cfg.getParameter<bool>("useDefaultEnergyCorrection");
439 
440  strategyCfg_.applyPreselection = cfg.getParameter<bool>("applyPreselection");
441  strategyCfg_.ecalDrivenEcalEnergyFromClassBasedParameterization =
442  cfg.getParameter<bool>("ecalDrivenEcalEnergyFromClassBasedParameterization");
443  strategyCfg_.ecalDrivenEcalErrorFromClassBasedParameterization =
444  cfg.getParameter<bool>("ecalDrivenEcalErrorFromClassBasedParameterization");
445  strategyCfg_.pureTrackerDrivenEcalErrorFromSimpleParameterization =
446  cfg.getParameter<bool>("pureTrackerDrivenEcalErrorFromSimpleParameterization");
447  strategyCfg_.applyAmbResolution = cfg.getParameter<bool>("applyAmbResolution");
448  strategyCfg_.ignoreNotPreselected = cfg.getParameter<bool>("ignoreNotPreselected");
449  strategyCfg_.ambSortingStrategy = cfg.getParameter<unsigned>("ambSortingStrategy");
450  strategyCfg_.ambClustersOverlapStrategy = cfg.getParameter<unsigned>("ambClustersOverlapStrategy");
451  strategyCfg_.ctfTracksCheck = cfg.getParameter<bool>("ctfTracksCheck");
452  strategyCfg_.PreSelectMVA = cfg.getParameter<double>("PreSelectMVA");
453  strategyCfg_.MaxElePtForOnlyMVA = cfg.getParameter<double>("MaxElePtForOnlyMVA");
454  strategyCfg_.useEcalRegression = cfg.getParameter<bool>("useEcalRegression");
455  strategyCfg_.useCombinationRegression = cfg.getParameter<bool>("useCombinationRegression");
456  strategyCfg_.fillConvVtxFitProb = cfg.getParameter<bool>("fillConvVtxFitProb");
457  strategyCfg_.computePfClusterIso = dnnPFidEnabled_;
458 
459  // hcal helpers
460  auto const& psetPreselection = cfg.getParameter<edm::ParameterSet>("preselection");
461  hcalCfg_.hOverEConeSize = psetPreselection.getParameter<double>("hOverEConeSize");
462  if (hcalCfg_.hOverEConeSize > 0) {
463  hcalCfg_.onlyBehindCluster = false;
464  hcalCfg_.checkHcalStatus = cfg.getParameter<bool>("checkHcalStatus");
465 
466  //hcalCfg_.hbheRecHits = consumes<HBHERecHitCollection>(cfg.getParameter<edm::InputTag>("hbheRecHits"));
467  hcalCfg_.hbheRecHits = consumes<HBHERecHitCollection>(cfg.getParameter<edm::InputTag>("hbheRecHits"));
468 
469  hcalCfg_.eThresHB = cfg.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
470  hcalCfg_.maxSeverityHB = cfg.getParameter<int>("maxHcalRecHitSeverity");
471  hcalCfg_.eThresHE = cfg.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
472  hcalCfg_.maxSeverityHE = hcalCfg_.maxSeverityHB;
473  }
474 
475  hcalCfgBc_.hOverEConeSize = 0.;
476  hcalCfgBc_.onlyBehindCluster = true;
477  hcalCfgBc_.checkHcalStatus = cfg.getParameter<bool>("checkHcalStatus");
478 
479  //hcalCfgBc_.hbheRecHits = consumes<HBHERecHitCollection>(cfg.getParameter<edm::InputTag>("hbheRecHits"));
480  hcalCfgBc_.hbheRecHits = consumes<HBHERecHitCollection>(cfg.getParameter<edm::InputTag>("hbheRecHits"));
481 
482  hcalCfgBc_.eThresHB = cfg.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
483  hcalCfgBc_.maxSeverityHB = cfg.getParameter<int>("maxHcalRecHitSeverity");
484  hcalCfgBc_.eThresHE = cfg.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
485  hcalCfgBc_.maxSeverityHE = hcalCfgBc_.maxSeverityHB;
486 
487  hcalRun2EffDepth_ = cfg.getParameter<bool>("hcalRun2EffDepth");
488 
489  // Ecal rec hits configuration
491  auto const& flagnamesbarrel = cfg.getParameter<std::vector<std::string>>("recHitFlagsToBeExcludedBarrel");
492  recHitsCfg.recHitFlagsToBeExcludedBarrel = StringToEnumValue<EcalRecHit::Flags>(flagnamesbarrel);
493  auto const& flagnamesendcaps = cfg.getParameter<std::vector<std::string>>("recHitFlagsToBeExcludedEndcaps");
494  recHitsCfg.recHitFlagsToBeExcludedEndcaps = StringToEnumValue<EcalRecHit::Flags>(flagnamesendcaps);
495  auto const& severitynamesbarrel = cfg.getParameter<std::vector<std::string>>("recHitSeverityToBeExcludedBarrel");
496  recHitsCfg.recHitSeverityToBeExcludedBarrel =
497  StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesbarrel);
498  auto const& severitynamesendcaps = cfg.getParameter<std::vector<std::string>>("recHitSeverityToBeExcludedEndcaps");
499  recHitsCfg.recHitSeverityToBeExcludedEndcaps =
500  StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesendcaps);
501 
502  // isolation
504  .intRadiusHcal = cfg.getParameter<double>("intRadiusHcal"),
505  .etMinHcal = cfg.getParameter<double>("etMinHcal"),
506  .intRadiusEcalBarrel = cfg.getParameter<double>("intRadiusEcalBarrel"),
507  .intRadiusEcalEndcaps = cfg.getParameter<double>("intRadiusEcalEndcaps"),
508  .jurassicWidth = cfg.getParameter<double>("jurassicWidth"),
509  .etMinBarrel = cfg.getParameter<double>("etMinBarrel"),
510  .eMinBarrel = cfg.getParameter<double>("eMinBarrel"),
511  .etMinEndcaps = cfg.getParameter<double>("etMinEndcaps"),
512  .eMinEndcaps = cfg.getParameter<double>("eMinEndcaps"),
513  .vetoClustered = cfg.getParameter<bool>("vetoClustered"),
514  .useNumCrystals = cfg.getParameter<bool>("useNumCrystals")};
515 
516  // isolation
518  .ecaldrMax = pfECALClusIsolCfg.getParameter<double>("drMax"),
519  .ecaldrVetoBarrel = pfECALClusIsolCfg.getParameter<double>("drVetoBarrel"),
520  .ecaldrVetoEndcap = pfECALClusIsolCfg.getParameter<double>("drVetoEndcap"),
521  .ecaletaStripBarrel = pfECALClusIsolCfg.getParameter<double>("etaStripBarrel"),
522  .ecaletaStripEndcap = pfECALClusIsolCfg.getParameter<double>("etaStripEndcap"),
523  .ecalenergyBarrel = pfECALClusIsolCfg.getParameter<double>("energyBarrel"),
524  .ecalenergyEndcap = pfECALClusIsolCfg.getParameter<double>("energyEndcap"),
525  .useHF = pfHCALClusIsolCfg.getParameter<bool>("useHF"),
526  .hcaldrMax = pfHCALClusIsolCfg.getParameter<double>("drMax"),
527  .hcaldrVetoBarrel = pfHCALClusIsolCfg.getParameter<double>("drVetoBarrel"),
528  .hcaldrVetoEndcap = pfHCALClusIsolCfg.getParameter<double>("drVetoEndcap"),
529  .hcaletaStripBarrel = pfHCALClusIsolCfg.getParameter<double>("etaStripBarrel"),
530  .hcaletaStripEndcap = pfHCALClusIsolCfg.getParameter<double>("etaStripEndcap"),
531  .hcalenergyBarrel = pfHCALClusIsolCfg.getParameter<double>("energyBarrel"),
532  .hcalenergyEndcap = pfHCALClusIsolCfg.getParameter<double>("energyEndcap"),
533  .hcaluseEt = pfHCALClusIsolCfg.getParameter<bool>("useEt")};
534 
535  const RegressionHelper::Configuration regressionCfg{
536  .ecalRegressionWeightLabels = cfg.getParameter<std::vector<std::string>>("ecalRefinedRegressionWeightLabels"),
537  .ecalWeightsFromDB = cfg.getParameter<bool>("ecalWeightsFromDB"),
538  .ecalRegressionWeightFiles = cfg.getParameter<std::vector<std::string>>("ecalRefinedRegressionWeightFiles"),
540  cfg.getParameter<std::vector<std::string>>("combinationRegressionWeightLabels"),
541  .combinationWeightsFromDB = cfg.getParameter<bool>("combinationWeightsFromDB"),
542  .combinationRegressionWeightFiles =
543  cfg.getParameter<std::vector<std::string>>("combinationRegressionWeightFile")};
544 
545  // create algo
546  algo_ = std::make_unique<GsfElectronAlgo>(
547  inputCfg_,
548  strategyCfg_,
549  cutsCfg_,
550  hcalCfg_,
551  hcalCfgBc_,
552  isoCfg,
553  pfisoCfg,
554  recHitsCfg,
556  cfg.getParameter<std::string>("crackCorrectionFunction"), cfg, consumesCollector()),
557  regressionCfg,
558  cfg.getParameter<edm::ParameterSet>("trkIsol03Cfg"),
559  cfg.getParameter<edm::ParameterSet>("trkIsol04Cfg"),
560  cfg.getParameter<edm::ParameterSet>("trkIsolHEEP03Cfg"),
561  cfg.getParameter<edm::ParameterSet>("trkIsolHEEP04Cfg"),
562  consumesCollector());
563 
564  if (dnnPFidEnabled_) {
565  tfSessions_ = gcache->iElectronDNNEstimator->getSessions();
566  }
567 }
568 
570  for (auto session : tfSessions_) {
571  tensorflow::closeSession(session);
572  }
573 }
574 
576  if (!pset.exists("SeedConfiguration")) {
577  return;
578  }
579  edm::ParameterSet seedConfiguration = pset.getParameter<edm::ParameterSet>("SeedConfiguration");
580 
581  if (seedConfiguration.getParameter<bool>("applyHOverECut")) {
582  if ((hcalCfg_.hOverEConeSize != 0) &&
583  (hcalCfg_.hOverEConeSize != seedConfiguration.getParameter<double>("hOverEConeSize"))) {
584  edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
585  << "The H/E cone size (" << hcalCfg_.hOverEConeSize << ") is different from ecal seeding ("
586  << seedConfiguration.getParameter<double>("hOverEConeSize") << ").";
587  }
588  if (cutsCfg_.maxHOverEBarrelCone < seedConfiguration.getParameter<double>("maxHOverEBarrel")) {
589  edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
590  << "The max barrel cone H/E is lower than during ecal seeding.";
591  }
592  if (cutsCfg_.maxHOverEEndcapsCone < seedConfiguration.getParameter<double>("maxHOverEEndcaps")) {
593  edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
594  << "The max endcaps cone H/E is lower than during ecal seeding.";
595  }
596  }
597 
598  if (cutsCfg_.minSCEtBarrel < seedConfiguration.getParameter<double>("SCEtCut")) {
599  edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
600  << "The minimum super-cluster Et in barrel is lower than during ecal seeding.";
601  }
602  if (cutsCfg_.minSCEtEndcaps < seedConfiguration.getParameter<double>("SCEtCut")) {
603  edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
604  << "The minimum super-cluster Et in endcaps is lower than during ecal seeding.";
605  }
606 }
607 
608 //=======================================================================================
609 // Ambiguity solving
610 //=======================================================================================
611 
613  edm::Event const& event,
614  bool ignoreNotPreselected) const {
615  // Getting required event data
616  auto const& beamspot = event.get(inputCfg_.beamSpotTag);
617  auto gsfPfRecTracks =
619  auto const& barrelRecHits = event.get(inputCfg_.barrelRecHitCollection);
620  auto const& endcapRecHits = event.get(inputCfg_.endcapRecHitCollection);
621 
622  if (strategyCfg_.ambSortingStrategy == 0) {
624  } else if (strategyCfg_.ambSortingStrategy == 1) {
626  } else {
627  throw cms::Exception("GsfElectronAlgo|UnknownAmbiguitySortingStrategy")
628  << "value of strategyCfg_.ambSortingStrategy is : " << strategyCfg_.ambSortingStrategy;
629  }
630 
631  // init
632  for (auto& electron : electrons) {
633  electron.clearAmbiguousGsfTracks();
634  electron.setAmbiguous(false);
635  }
636 
637  // get ambiguous from GsfPfRecTracks
638  if (useGsfPfRecTracks_) {
639  for (auto& e1 : electrons) {
640  bool found = false;
641  for (auto const& gsfPfRecTrack : *gsfPfRecTracks) {
642  if (gsfPfRecTrack.gsfTrackRef() == e1.gsfTrack()) {
643  if (found) {
644  edm::LogWarning("GsfElectronAlgo") << "associated gsfPfRecTrack already found";
645  } else {
646  found = true;
647  for (auto const& duplicate : gsfPfRecTrack.convBremGsfPFRecTrackRef()) {
648  e1.addAmbiguousGsfTrack(duplicate->gsfTrackRef());
649  }
650  }
651  }
652  }
653  }
654  }
655  // or search overlapping clusters
656  else {
657  for (auto e1 = electrons.begin(); e1 != electrons.end(); ++e1) {
658  if (e1->ambiguous())
659  continue;
661  continue;
662 
663  SuperClusterRef scRef1 = e1->superCluster();
664  CaloClusterPtr eleClu1 = e1->electronCluster();
665  LogDebug("GsfElectronAlgo") << "Blessing electron with E/P " << e1->eSuperClusterOverP() << ", cluster "
666  << scRef1.get() << " & track " << e1->gsfTrack().get();
667 
668  for (auto e2 = e1 + 1; e2 != electrons.end(); ++e2) {
669  if (e2->ambiguous())
670  continue;
671  if (ignoreNotPreselected && !isPreselected(*e2))
672  continue;
673 
674  SuperClusterRef scRef2 = e2->superCluster();
675  CaloClusterPtr eleClu2 = e2->electronCluster();
676 
677  // search if same cluster
678  bool sameCluster = false;
680  sameCluster = (scRef1 == scRef2);
681  } else if (strategyCfg_.ambClustersOverlapStrategy == 1) {
682  float eMin = 1.;
683  float threshold = eMin * cosh(EleRelPoint(scRef1->position(), beamspot.position()).eta());
684  using egamma::sharedEnergy;
685  sameCluster = ((sharedEnergy(*eleClu1, *eleClu2, barrelRecHits, endcapRecHits) >= threshold) ||
686  (sharedEnergy(*scRef1->seed(), *eleClu2, barrelRecHits, endcapRecHits) >= threshold) ||
687  (sharedEnergy(*eleClu1, *scRef2->seed(), barrelRecHits, endcapRecHits) >= threshold) ||
688  (sharedEnergy(*scRef1->seed(), *scRef2->seed(), barrelRecHits, endcapRecHits) >= threshold));
689  } else {
690  throw cms::Exception("GsfElectronAlgo|UnknownAmbiguityClustersOverlapStrategy")
691  << "value of strategyCfg_.ambClustersOverlapStrategy is : " << strategyCfg_.ambClustersOverlapStrategy;
692  }
693 
694  // main instructions
695  if (sameCluster) {
696  LogDebug("GsfElectronAlgo") << "Discarding electron with E/P " << e2->eSuperClusterOverP() << ", cluster "
697  << scRef2.get() << " and track " << e2->gsfTrack().get();
698  e1->addAmbiguousGsfTrack(e2->gsfTrack());
699  e2->setAmbiguous(true);
700  } else if (e1->gsfTrack() == e2->gsfTrack()) {
701  edm::LogWarning("GsfElectronAlgo") << "Forgetting electron with E/P " << e2->eSuperClusterOverP()
702  << ", cluster " << scRef2.get() << " and track " << e2->gsfTrack().get();
703  e2->setAmbiguous(true);
704  }
705  }
706  }
707  }
708 }
709 
711  bool passCutBased = ele.passingCutBasedPreselection();
712  bool passPF = ele.passingPflowPreselection();
713  // it is worth nothing for gedGsfElectrons, this does nothing as its not set
714  // till GedGsfElectron finaliser, this is always false
715  bool passmva = ele.passingMvaPreselection();
716  if (!ele.ecalDrivenSeed()) {
717  if (ele.pt() > strategyCfg_.MaxElePtForOnlyMVA)
718  return passmva && passCutBased;
719  else
720  return passmva;
721  } else {
722  return passCutBased || passPF || passmva;
723  }
724 }
725 
726 // ------------ method called to produce the data ------------
728  // check configuration
731  auto seeds = event.getHandle(inputCfg_.seedsTag);
732  if (!seeds.isValid()) {
733  edm::LogWarning("GsfElectronAlgo|UnreachableSeedsProvenance")
734  << "Cannot check consistency of parameters with ecal seeding ones,"
735  << " because the original collection of seeds is not any more available.";
736  } else {
737  checkEcalSeedingParameters(edm::parameterSet(seeds.provenance()->stable(), event.processHistory()));
738  }
739  }
740 
741  auto electrons = algo_->completeElectrons(event, setup, globalCache());
743  const auto gsfMVAInputMap = matchWithPFCandidates(event.get(egmPFCandidateCollection_));
744  for (auto& el : electrons) {
745  el.setMvaInput(gsfMVAInputMap.find(el.gsfTrack())->second); // set Run2 MVA inputs
746  }
747  setMVAOutputs(
749  }
750 
751  // all electrons
752  logElectrons(electrons, event, "GsfElectronAlgo Info (before preselection)");
753  // preselection
755  electrons.erase(
756  std::remove_if(electrons.begin(), electrons.end(), [this](auto const& ele) { return !isPreselected(ele); }),
757  electrons.end());
758  logElectrons(electrons, event, "GsfElectronAlgo Info (after preselection)");
759  }
760  // ambiguity
763  electrons.erase(std::remove_if(electrons.begin(), electrons.end(), std::mem_fn(&reco::GsfElectron::ambiguous)),
764  electrons.end());
765  logElectrons(electrons, event, "GsfElectronAlgo Info (after amb. solving)");
766  }
767  // 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
768  if (hcalRun2EffDepth_) {
769  for (auto& ele : electrons)
770  ele.hcalToRun2EffDepth();
771  }
772  // final filling
773  event.emplace(electronPutToken_, std::move(electrons));
774 }
775 
void checkEcalSeedingParameters(edm::ParameterSet const &)
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
const edm::EDGetTokenT< reco::GsfPFRecTrackCollection > gsfPfRecTracksTag_
GsfElectronAlgo::Tokens inputCfg_
double pt() const final
transverse momentum
bool ecalDrivenSeed() const
Definition: GsfElectron.h:158
edm::EDGetTokenT< reco::PFCandidateCollection > egmPFCandidateCollection_
std::vector< std::string > ecalRegressionWeightLabels
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static void fillDescriptions(edm::ConfigurationDescriptions &)
const bool resetMvaValuesUsingPFCandidates_
bool passingPflowPreselection() const
Definition: GsfElectron.h:764
std::vector< Vertex > VertexCollection
collection of Vertex objects
Definition: VertexFwd.h:9
bool ambiguous() const
Definition: GsfElectron.h:765
edm::EDGetTokenT< reco::VertexCollection > vtxCollectionTag
edm::EDGetTokenT< EcalRecHitCollection > endcapRecHitCollection
ParameterSet const & parameterSet(StableProvenance const &provenance, ProcessHistory const &history)
Definition: Provenance.cc:11
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
ElectronHcalHelper::Configuration hcalCfg_
#define LogTrace(id)
static std::string const input
Definition: EdmProvDump.cc:47
std::unique_ptr< const ElectronMVAEstimator > iElectronMVAEstimator
U second(std::pair< T, U > const &p)
bool isBetterElectron(reco::GsfElectron const &, reco::GsfElectron const &)
bool isInnermostElectron(reco::GsfElectron const &, reco::GsfElectron const &)
GsfElectronProducer(const edm::ParameterSet &, const GsfElectronAlgo::HeavyObjectCache *)
static std::unique_ptr< GsfElectronAlgo::HeavyObjectCache > initializeGlobalCache(const edm::ParameterSet &conf)
const edm::EDPutTokenT< reco::GsfElectronCollection > electronPutToken_
edm::EDGetTokenT< reco::BeamSpot > beamSpotTag
bool closeSession(Session *&session)
Definition: TensorFlow.cc:198
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
std::vector< tensorflow::Session * > tfSessions_
static edm::ParameterSetDescription pSetDescript()
edm::EDGetTokenT< reco::ElectronSeedCollection > seedsTag
std::unique_ptr< const ElectronDNNEstimator > iElectronDNNEstimator
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isPreselected(reco::GsfElectron const &ele) const
void setAmbiguityData(reco::GsfElectronCollection &electrons, edm::Event const &event, bool ignoreNotPreselected=true) const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
const GsfElectronAlgo::CutsConfiguration cutsCfg_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
float sharedEnergy(reco::CaloCluster const &clu1, reco::CaloCluster const &clu2, EcalRecHitCollection const &barrelRecHits, EcalRecHitCollection const &endcapRecHits)
bool passingMvaPreselection() const
Definition: GsfElectron.h:778
fixed size matrix
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:232
edm::EDGetTokenT< EcalRecHitCollection > barrelRecHitCollection
std::unique_ptr< GsfElectronAlgo > algo_
ElectronHcalHelper::Configuration hcalCfgBc_
std::unique_ptr< const SoftElectronMVAEstimator > sElectronMVAEstimator
#define get
Log< level::Warning, false > LogWarning
std::array< double, 4 > arrayHB
static void globalEndJob(GsfElectronAlgo::HeavyObjectCache const *)
void produce(edm::Event &event, const edm::EventSetup &setup) override
def move(src, dest)
Definition: eostools.py:511
bool passingCutBasedPreselection() const
Definition: GsfElectron.h:763
GsfElectronAlgo::StrategyConfiguration strategyCfg_
Definition: event.py:1
#define LogDebug(id)
std::array< double, 7 > arrayHE