Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-11-25 02:29:54

0001 #include "CommonTools/Utils/interface/StringToEnumValue.h"
0002 #include "DataFormats/Common/interface/Handle.h"
0003 #include "DataFormats/EcalRecHit/interface/EcalSeverityLevel.h"
0004 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
0005 #include "DataFormats/EgammaReco/interface/ElectronSeed.h"
0006 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0007 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0008 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateEGammaExtra.h"
0009 #include "DataFormats/ParticleFlowReco/interface/GsfPFRecTrack.h"
0010 #include "DataFormats/TrackCandidate/interface/TrackCandidateCollection.h"
0011 #include "FWCore/Common/interface/Provenance.h"
0012 #include "FWCore/Framework/interface/Event.h"
0013 #include "FWCore/Framework/interface/EventSetup.h"
0014 #include "FWCore/Framework/interface/stream/EDProducer.h"
0015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0016 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0017 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0018 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0019 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterFunctionFactory.h"
0020 #include "RecoEgamma/EgammaIsolationAlgos/interface/EleTkIsolFromCands.h"
0021 #include "RecoEgamma/EgammaElectronAlgos/interface/EgAmbiguityTools.h"
0022 #include "RecoEgamma/EgammaElectronAlgos/interface/ElectronUtilities.h"
0023 #include "RecoEgamma/EgammaElectronAlgos/interface/GsfElectronAlgo.h"
0024 #include "RecoEcal/EgammaCoreTools/interface/EgammaLocalCovParamDefaults.h"
0025 #include "RecoEgamma/EgammaIsolationAlgos/interface/EcalPFClusterIsolation.h"
0026 #include "RecoEgamma/EgammaIsolationAlgos/interface/HcalPFClusterIsolation.h"
0027 
0028 #include <array>
0029 
0030 using namespace reco;
0031 
0032 namespace {
0033 
0034   void setMVAOutputs(reco::GsfElectronCollection& electrons,
0035                      const GsfElectronAlgo::HeavyObjectCache* hoc,
0036                      reco::VertexCollection const& vertices,
0037                      bool dnnPFidEnabled,
0038                      float extetaboundary) {
0039     std::vector<GsfElectron::MvaOutput> mva_outputs(electrons.size());
0040     size_t iele = 0;
0041     for (auto& el : electrons) {
0042       GsfElectron::MvaOutput mvaOutput;
0043       mvaOutput.mva_e_pi = hoc->sElectronMVAEstimator->mva(el, vertices);
0044       mvaOutput.mva_Isolated = hoc->iElectronMVAEstimator->mva(el, vertices.size());
0045       if (dnnPFidEnabled) {
0046         mva_outputs[iele] = mvaOutput;
0047       } else {
0048         el.setMvaOutput(mvaOutput);
0049       }
0050       iele++;
0051     }
0052     if (dnnPFidEnabled) {
0053       // Here send the list of electrons to the ElectronDNNEstimator and get back the values for all the electrons in one go
0054       LogDebug("GsfElectronProducer") << "Getting DNN PFId for ele";
0055       const auto& dnn_ele_pfid = hoc->iElectronDNNEstimator->evaluate(electrons);
0056       int jele = 0;
0057       for (auto& el : electrons) {
0058         const auto& [iModel, values] = dnn_ele_pfid[jele];
0059         // get the previous values
0060         auto& mvaOutput = mva_outputs[jele];
0061 
0062         if (iModel <= 3) {  // models 0,1,2,3 have 5 outputs in this version
0063           assert(values.size() == 5);
0064           mvaOutput.dnn_e_sigIsolated = values[0];
0065           mvaOutput.dnn_e_sigNonIsolated = values[1];
0066           mvaOutput.dnn_e_bkgNonIsolated = values[2];
0067           mvaOutput.dnn_e_bkgTau = values[3];
0068           mvaOutput.dnn_e_bkgPhoton = values[4];
0069         } else if (iModel == 4) {  //etaExtended model has 3 outputs
0070           assert(values.size() == 3);
0071           mvaOutput.dnn_e_sigIsolated = values[0];
0072           mvaOutput.dnn_e_sigNonIsolated = 0.0;
0073           mvaOutput.dnn_e_bkgNonIsolated = values[1];
0074           mvaOutput.dnn_e_bkgTau = 0.0;
0075           mvaOutput.dnn_e_bkgPhoton = values[2];
0076         }
0077         el.setMvaOutput(mvaOutput);
0078         jele++;
0079       }
0080     }
0081   }
0082 
0083   // Something more clever has to be found. The collections are small, so the timing is not
0084   // an issue here; but it is clearly suboptimal
0085 
0086   auto matchWithPFCandidates(std::vector<reco::PFCandidate> const& pfCandidates) {
0087     std::map<reco::GsfTrackRef, reco::GsfElectron::MvaInput> gsfMVAInputs{};
0088 
0089     //Loop over the collection of PFFCandidates
0090     for (auto const& pfCand : pfCandidates) {
0091       reco::GsfElectronRef myRef;
0092       // First check that the GsfTrack is non null
0093       if (pfCand.gsfTrackRef().isNonnull()) {
0094         reco::GsfElectron::MvaInput input;
0095         input.earlyBrem = pfCand.egammaExtraRef()->mvaVariable(reco::PFCandidateEGammaExtra::MVA_FirstBrem);
0096         input.lateBrem = pfCand.egammaExtraRef()->mvaVariable(reco::PFCandidateEGammaExtra::MVA_LateBrem);
0097         input.deltaEta = pfCand.egammaExtraRef()->mvaVariable(reco::PFCandidateEGammaExtra::MVA_DeltaEtaTrackCluster);
0098         input.sigmaEtaEta = pfCand.egammaExtraRef()->sigmaEtaEta();
0099         input.hadEnergy = pfCand.egammaExtraRef()->hadEnergy();
0100         gsfMVAInputs[pfCand.gsfTrackRef()] = input;
0101       }
0102     }
0103     return gsfMVAInputs;
0104   }
0105 
0106   void logElectrons(reco::GsfElectronCollection const& electrons, edm::Event const& event, const std::string& title) {
0107     LogTrace("GsfElectronAlgo") << "========== " << title << " ==========";
0108     LogTrace("GsfElectronAlgo") << "Event: " << event.id();
0109     LogTrace("GsfElectronAlgo") << "Number of electrons: " << electrons.size();
0110     for (auto const& ele : electrons) {
0111       LogTrace("GsfElectronAlgo") << "Electron with charge, pt, eta, phi: " << ele.charge() << " , " << ele.pt()
0112                                   << " , " << ele.eta() << " , " << ele.phi();
0113     }
0114     LogTrace("GsfElectronAlgo") << "=================================================";
0115   }
0116 
0117 }  // namespace
0118 
0119 class GsfElectronProducer : public edm::stream::EDProducer<edm::GlobalCache<GsfElectronAlgo::HeavyObjectCache>> {
0120 public:
0121   static void fillDescriptions(edm::ConfigurationDescriptions&);
0122 
0123   explicit GsfElectronProducer(const edm::ParameterSet&, const GsfElectronAlgo::HeavyObjectCache*);
0124 
0125   static std::unique_ptr<GsfElectronAlgo::HeavyObjectCache> initializeGlobalCache(const edm::ParameterSet& conf) {
0126     return std::make_unique<GsfElectronAlgo::HeavyObjectCache>(conf);
0127   }
0128 
0129   void endStream() override;
0130 
0131   static void globalEndJob(GsfElectronAlgo::HeavyObjectCache const*) {}
0132 
0133   // ------------ method called to produce the data  ------------
0134   void produce(edm::Event& event, const edm::EventSetup& setup) override;
0135 
0136 private:
0137   std::unique_ptr<GsfElectronAlgo> algo_;
0138 
0139   // configurables
0140   GsfElectronAlgo::Tokens inputCfg_;
0141   GsfElectronAlgo::StrategyConfiguration strategyCfg_;
0142   const GsfElectronAlgo::CutsConfiguration cutsCfg_;
0143   ElectronHcalHelper::Configuration hcalCfg_, hcalCfgBc_;
0144 
0145   bool hcalRun2EffDepth_;
0146 
0147   bool isPreselected(reco::GsfElectron const& ele) const;
0148   void setAmbiguityData(reco::GsfElectronCollection& electrons,
0149                         edm::Event const& event,
0150                         bool ignoreNotPreselected = true) const;
0151 
0152   // check expected configuration of previous modules
0153   bool ecalSeedingParametersChecked_;
0154   void checkEcalSeedingParameters(edm::ParameterSet const&);
0155 
0156   const edm::EDPutTokenT<reco::GsfElectronCollection> electronPutToken_;
0157   const edm::EDGetTokenT<reco::GsfPFRecTrackCollection> gsfPfRecTracksTag_;
0158   edm::EDGetTokenT<reco::PFCandidateCollection> egmPFCandidateCollection_;
0159 
0160   const bool useGsfPfRecTracks_;
0161 
0162   const bool resetMvaValuesUsingPFCandidates_;
0163 
0164   bool dnnPFidEnabled_;
0165   float extetaboundary_;
0166 
0167   edm::ESGetToken<HcalPFCuts, HcalPFCutsRcd> hcalCutsToken_;
0168   bool cutsFromDB_;
0169 };
0170 
0171 void GsfElectronProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0172   edm::ParameterSetDescription desc;
0173   // input collections
0174   desc.add<edm::InputTag>("gsfElectronCoresTag", {"ecalDrivenGsfElectronCores"});
0175   desc.add<edm::InputTag>("vtxTag", {"offlinePrimaryVertices"});
0176   desc.add<edm::InputTag>("conversionsTag", {"allConversions"});
0177   desc.add<edm::InputTag>("gsfPfRecTracksTag", {"pfTrackElec"});
0178   desc.add<edm::InputTag>("barrelRecHitCollectionTag", {"ecalRecHit", "EcalRecHitsEB"});
0179   desc.add<edm::InputTag>("endcapRecHitCollectionTag", {"ecalRecHit", "EcalRecHitsEE"});
0180   desc.add<edm::InputTag>("seedsTag", {"ecalDrivenElectronSeeds"});
0181   desc.add<edm::InputTag>("beamSpotTag", {"offlineBeamSpot"});
0182   desc.add<edm::InputTag>("egmPFCandidatesTag", {"particleFlowEGamma"});
0183 
0184   // steering
0185   desc.add<bool>("useDefaultEnergyCorrection", true);
0186   desc.add<bool>("useCombinationRegression", false);
0187   desc.add<bool>("ecalDrivenEcalEnergyFromClassBasedParameterization", true);
0188   desc.add<bool>("ecalDrivenEcalErrorFromClassBasedParameterization", true);
0189   desc.add<bool>("applyPreselection", false);
0190   desc.add<bool>("useEcalRegression", false);
0191   desc.add<bool>("applyAmbResolution", false);
0192   desc.add<bool>("ignoreNotPreselected", true);
0193   desc.add<bool>("useGsfPfRecTracks", true);
0194   desc.add<bool>("pureTrackerDrivenEcalErrorFromSimpleParameterization", true);
0195   desc.add<unsigned int>("ambSortingStrategy", 1);
0196   desc.add<unsigned int>("ambClustersOverlapStrategy", 1);
0197   desc.add<bool>("fillConvVtxFitProb", true);
0198   desc.add<bool>("resetMvaValuesUsingPFCandidates", false);
0199 
0200   // Ecal rec hits configuration
0201   desc.add<std::vector<std::string>>("recHitFlagsToBeExcludedBarrel");
0202   desc.add<std::vector<std::string>>("recHitFlagsToBeExcludedEndcaps");
0203   desc.add<std::vector<std::string>>("recHitSeverityToBeExcludedBarrel");
0204   desc.add<std::vector<std::string>>("recHitSeverityToBeExcludedEndcaps");
0205 
0206   // Hcal rec hits configuration
0207   desc.add<bool>("checkHcalStatus", true);
0208   desc.add<edm::InputTag>("hbheRecHits", edm::InputTag("hbhereco"));
0209   desc.add<std::vector<double>>("recHitEThresholdHB", {0., 0., 0., 0.});
0210   desc.add<std::vector<double>>("recHitEThresholdHE", {0., 0., 0., 0., 0., 0., 0.});
0211   desc.add<int>("maxHcalRecHitSeverity", 999999);
0212   desc.add<bool>("hcalRun2EffDepth", false);
0213   desc.add<bool>("usePFThresholdsFromDB", false);
0214 
0215   // Isolation algos configuration
0216   desc.add("trkIsol03Cfg", EleTkIsolFromCands::pSetDescript());
0217   desc.add("trkIsol04Cfg", EleTkIsolFromCands::pSetDescript());
0218   desc.add("trkIsolHEEP03Cfg", EleTkIsolFromCands::pSetDescript());
0219   desc.add("trkIsolHEEP04Cfg", EleTkIsolFromCands::pSetDescript());
0220   desc.add<bool>("useNumCrystals", true);
0221   desc.add<double>("etMinBarrel", 0.0);
0222   desc.add<double>("etMinEndcaps", 0.11);
0223   desc.add<double>("etMinHcal", 0.0);
0224   desc.add<double>("eMinBarrel", 0.095);
0225   desc.add<double>("eMinEndcaps", 0.0);
0226   desc.add<double>("intRadiusEcalBarrel", 3.0);
0227   desc.add<double>("intRadiusEcalEndcaps", 3.0);
0228   desc.add<double>("intRadiusHcal", 0.15);
0229   desc.add<double>("jurassicWidth", 1.5);
0230   desc.add<bool>("vetoClustered", false);
0231 
0232   // backward compatibility mechanism for ctf tracks
0233   desc.add<bool>("ctfTracksCheck", true);
0234   desc.add<edm::InputTag>("ctfTracksTag", {"generalTracks"});
0235 
0236   desc.add<double>("MaxElePtForOnlyMVA", 50.0);
0237   desc.add<double>("PreSelectMVA", -0.1);
0238 
0239   {
0240     edm::ParameterSetDescription psd0;
0241     psd0.add<double>("minSCEtBarrel", 4.0);
0242     psd0.add<double>("minSCEtEndcaps", 4.0);
0243     psd0.add<double>("minEOverPBarrel", 0.0);
0244     psd0.add<double>("minEOverPEndcaps", 0.0);
0245     psd0.add<double>("maxEOverPBarrel", 999999999.0);
0246     psd0.add<double>("maxEOverPEndcaps", 999999999.0);
0247     psd0.add<double>("maxDeltaEtaBarrel", 0.02);
0248     psd0.add<double>("maxDeltaEtaEndcaps", 0.02);
0249     psd0.add<double>("maxDeltaPhiBarrel", 0.15);
0250     psd0.add<double>("maxDeltaPhiEndcaps", 0.15);
0251     psd0.add<double>("hOverEConeSize", 0.15);
0252     psd0.add<double>("maxHOverEBarrelCone", 0.15);
0253     psd0.add<double>("maxHOverEEndcapsCone", 0.15);
0254     psd0.add<double>("maxHBarrelCone", 0.0);
0255     psd0.add<double>("maxHEndcapsCone", 0.0);
0256     psd0.add<double>("maxHOverEBarrelBc", 0.15);
0257     psd0.add<double>("maxHOverEEndcapsBc", 0.15);
0258     psd0.add<double>("maxHBarrelBc", 0.0);
0259     psd0.add<double>("maxHEndcapsBc", 0.0);
0260     psd0.add<double>("maxSigmaIetaIetaBarrel", 999999999.0);
0261     psd0.add<double>("maxSigmaIetaIetaEndcaps", 999999999.0);
0262     psd0.add<double>("maxFbremBarrel", 999999999.0);
0263     psd0.add<double>("maxFbremEndcaps", 999999999.0);
0264     psd0.add<bool>("isBarrel", false);
0265     psd0.add<bool>("isEndcaps", false);
0266     psd0.add<bool>("isFiducial", false);
0267     psd0.add<bool>("seedFromTEC", true);
0268     psd0.add<double>("maxTIP", 999999999.0);
0269     psd0.add<double>("multThresEB", EgammaLocalCovParamDefaults::kMultThresEB);
0270     psd0.add<double>("multThresEE", EgammaLocalCovParamDefaults::kMultThresEE);
0271     // preselection parameters
0272     desc.add<edm::ParameterSetDescription>("preselection", psd0);
0273   }
0274 
0275   // Corrections
0276   desc.add<std::string>("crackCorrectionFunction", "EcalClusterCrackCorrection");
0277 
0278   desc.add<bool>("ecalWeightsFromDB", true);
0279   desc.add<std::vector<std::string>>("ecalRefinedRegressionWeightFiles", {})
0280       ->setComment("if not from DB. Otherwise, keep empty");
0281   desc.add<bool>("combinationWeightsFromDB", true);
0282   desc.add<std::vector<std::string>>("combinationRegressionWeightFile", {})
0283       ->setComment("if not from DB. Otherwise, keep empty");
0284 
0285   // regression. The labels are needed in all cases.
0286   desc.add<std::vector<std::string>>("ecalRefinedRegressionWeightLabels", {});
0287   desc.add<std::vector<std::string>>("combinationRegressionWeightLabels", {});
0288 
0289   desc.add<std::vector<std::string>>(
0290       "ElecMVAFilesString",
0291       {
0292           "RecoEgamma/ElectronIdentification/data/TMVA_Category_BDTSimpleCat_10_17Feb2011.weights.xml",
0293           "RecoEgamma/ElectronIdentification/data/TMVA_Category_BDTSimpleCat_12_17Feb2011.weights.xml",
0294           "RecoEgamma/ElectronIdentification/data/TMVA_Category_BDTSimpleCat_20_17Feb2011.weights.xml",
0295           "RecoEgamma/ElectronIdentification/data/TMVA_Category_BDTSimpleCat_22_17Feb2011.weights.xml",
0296       });
0297   desc.add<std::vector<std::string>>(
0298       "SoftElecMVAFilesString",
0299       {
0300           "RecoEgamma/ElectronIdentification/data/TMVA_BDTSoftElectrons_7Feb2014.weights.xml",
0301       });
0302 
0303   {
0304     edm::ParameterSetDescription psd1;
0305     psd1.add<bool>("enabled", false);
0306     psd1.add<double>("extetaboundary", 2.65);
0307     psd1.add<std::string>("inputTensorName", "FirstLayer_input");
0308     psd1.add<std::string>("outputTensorName", "sequential/FinalLayer/Softmax");
0309 
0310     psd1.add<std::vector<std::string>>(
0311         "modelsFiles",
0312         {"RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/lowpT/lowpT_modelDNN.pb",
0313          "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/highpTEB/highpTEB_modelDNN.pb",
0314          "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/highpTEE/highpTEE_modelDNN.pb",
0315          "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Winter22_122X/exteta1/modelDNN.pb",
0316          "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Winter22_122X/exteta2/modelDNN.pb"});
0317     psd1.add<std::vector<std::string>>(
0318         "scalersFiles",
0319         {"RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/lowpT/lowpT_scaler.txt",
0320          "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/highpTEB/highpTEB_scaler.txt",
0321          "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Summer21_120X/highpTEE/highpTEE_scaler.txt",
0322          "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Winter22_122X/exteta1/scaler.txt",
0323          "RecoEgamma/ElectronIdentification/data/Ele_PFID_dnn/Run3Winter22_122X/exteta2/scaler.txt"});
0324     psd1.add<std::vector<unsigned int>>("outputDim",  //Number of output nodes for the above models
0325                                         {5, 5, 5, 5, 3});
0326 
0327     psd1.add<bool>("useEBModelInGap", true);
0328     // preselection parameters
0329     desc.add<edm::ParameterSetDescription>("EleDNNPFid", psd1);
0330   }
0331 
0332   ///For PF cluster isolations
0333   ///ECAL
0334   {
0335     edm::ParameterSetDescription psd0;
0336     psd0.add<edm::InputTag>("pfClusterProducer", edm::InputTag("particleFlowClusterECAL"));
0337     psd0.add<double>("drMax", 0.3);
0338     psd0.add<double>("drVetoBarrel", 0.0);
0339     psd0.add<double>("drVetoEndcap", 0.0);
0340     psd0.add<double>("etaStripBarrel", 0.0);
0341     psd0.add<double>("etaStripEndcap", 0.0);
0342     psd0.add<double>("energyBarrel", 0.0);
0343     psd0.add<double>("energyEndcap", 0.0);
0344     desc.add<edm::ParameterSetDescription>("pfECALClusIsolCfg", psd0);
0345   }
0346 
0347   ///HCAL
0348   {
0349     edm::ParameterSetDescription psd0;
0350     psd0.add<edm::InputTag>("pfClusterProducerHCAL", edm::InputTag("particleFlowClusterHCAL"));
0351     psd0.add<edm::InputTag>("pfClusterProducerHFEM", edm::InputTag(""));
0352     psd0.add<edm::InputTag>("pfClusterProducerHFHAD", edm::InputTag(""));
0353     psd0.add<bool>("useHF", false);
0354     psd0.add<double>("drMax", 0.3);
0355     psd0.add<double>("drVetoBarrel", 0.0);
0356     psd0.add<double>("drVetoEndcap", 0.0);
0357     psd0.add<double>("etaStripBarrel", 0.0);
0358     psd0.add<double>("etaStripEndcap", 0.0);
0359     psd0.add<double>("energyBarrel", 0.0);
0360     psd0.add<double>("energyEndcap", 0.0);
0361     psd0.add<bool>("useEt", true);
0362     desc.add<edm::ParameterSetDescription>("pfHCALClusIsolCfg", psd0);
0363   }
0364 
0365   descriptions.add("gsfElectronProducerDefault", desc);
0366 }
0367 
0368 namespace {
0369   GsfElectronAlgo::CutsConfiguration makeCutsConfiguration(edm::ParameterSet const& pset) {
0370     return GsfElectronAlgo::CutsConfiguration{
0371         .minSCEtBarrel = pset.getParameter<double>("minSCEtBarrel"),
0372         .minSCEtEndcaps = pset.getParameter<double>("minSCEtEndcaps"),
0373         .maxEOverPBarrel = pset.getParameter<double>("maxEOverPBarrel"),
0374         .maxEOverPEndcaps = pset.getParameter<double>("maxEOverPEndcaps"),
0375         .minEOverPBarrel = pset.getParameter<double>("minEOverPBarrel"),
0376         .minEOverPEndcaps = pset.getParameter<double>("minEOverPEndcaps"),
0377         .maxHOverEBarrelCone = pset.getParameter<double>("maxHOverEBarrelCone"),
0378         .maxHOverEEndcapsCone = pset.getParameter<double>("maxHOverEEndcapsCone"),
0379         .maxHBarrelCone = pset.getParameter<double>("maxHBarrelCone"),
0380         .maxHEndcapsCone = pset.getParameter<double>("maxHEndcapsCone"),
0381         .maxHOverEBarrelBc = pset.getParameter<double>("maxHOverEBarrelBc"),
0382         .maxHOverEEndcapsBc = pset.getParameter<double>("maxHOverEEndcapsBc"),
0383         .maxHBarrelBc = pset.getParameter<double>("maxHBarrelBc"),
0384         .maxHEndcapsBc = pset.getParameter<double>("maxHEndcapsBc"),
0385         .maxDeltaEtaBarrel = pset.getParameter<double>("maxDeltaEtaBarrel"),
0386         .maxDeltaEtaEndcaps = pset.getParameter<double>("maxDeltaEtaEndcaps"),
0387         .maxDeltaPhiBarrel = pset.getParameter<double>("maxDeltaPhiBarrel"),
0388         .maxDeltaPhiEndcaps = pset.getParameter<double>("maxDeltaPhiEndcaps"),
0389         .maxSigmaIetaIetaBarrel = pset.getParameter<double>("maxSigmaIetaIetaBarrel"),
0390         .maxSigmaIetaIetaEndcaps = pset.getParameter<double>("maxSigmaIetaIetaEndcaps"),
0391         .maxFbremBarrel = pset.getParameter<double>("maxFbremBarrel"),
0392         .maxFbremEndcaps = pset.getParameter<double>("maxFbremEndcaps"),
0393         .isBarrel = pset.getParameter<bool>("isBarrel"),
0394         .isEndcaps = pset.getParameter<bool>("isEndcaps"),
0395         .isFiducial = pset.getParameter<bool>("isFiducial"),
0396         .maxTIP = pset.getParameter<double>("maxTIP"),
0397         .seedFromTEC = pset.getParameter<bool>("seedFromTEC"),
0398         .multThresEB = pset.getParameter<double>("multThresEB"),
0399         .multThresEE = pset.getParameter<double>("multThresEE"),
0400     };
0401   }
0402 };  // namespace
0403 
0404 GsfElectronProducer::GsfElectronProducer(const edm::ParameterSet& cfg, const GsfElectronAlgo::HeavyObjectCache* gcache)
0405     : cutsCfg_{makeCutsConfiguration(cfg.getParameter<edm::ParameterSet>("preselection"))},
0406       ecalSeedingParametersChecked_(false),
0407       electronPutToken_(produces<GsfElectronCollection>()),
0408       gsfPfRecTracksTag_(consumes(cfg.getParameter<edm::InputTag>("gsfPfRecTracksTag"))),
0409       useGsfPfRecTracks_(cfg.getParameter<bool>("useGsfPfRecTracks")),
0410       resetMvaValuesUsingPFCandidates_(cfg.getParameter<bool>("resetMvaValuesUsingPFCandidates")) {
0411   if (resetMvaValuesUsingPFCandidates_) {
0412     egmPFCandidateCollection_ = consumes(cfg.getParameter<edm::InputTag>("egmPFCandidatesTag"));
0413   }
0414 
0415   //Retrieve HCAL PF thresholds - from config or from DB
0416   cutsFromDB_ = cfg.getParameter<bool>("usePFThresholdsFromDB");
0417   if (cutsFromDB_) {
0418     hcalCutsToken_ = esConsumes<HcalPFCuts, HcalPFCutsRcd>(edm::ESInputTag("", "withTopo"));
0419   }
0420 
0421   inputCfg_.gsfElectronCores = consumes(cfg.getParameter<edm::InputTag>("gsfElectronCoresTag"));
0422   inputCfg_.hbheRecHitsTag = consumes(cfg.getParameter<edm::InputTag>("hbheRecHits"));
0423   inputCfg_.barrelRecHitCollection = consumes(cfg.getParameter<edm::InputTag>("barrelRecHitCollectionTag"));
0424   inputCfg_.endcapRecHitCollection = consumes(cfg.getParameter<edm::InputTag>("endcapRecHitCollectionTag"));
0425   inputCfg_.ctfTracks = consumes(cfg.getParameter<edm::InputTag>("ctfTracksTag"));
0426   // used to check config consistency with seeding
0427   inputCfg_.seedsTag = consumes(cfg.getParameter<edm::InputTag>("seedsTag"));
0428   inputCfg_.beamSpotTag = consumes(cfg.getParameter<edm::InputTag>("beamSpotTag"));
0429   inputCfg_.vtxCollectionTag = consumes(cfg.getParameter<edm::InputTag>("vtxTag"));
0430   if (cfg.getParameter<bool>("fillConvVtxFitProb"))
0431     inputCfg_.conversions = consumes(cfg.getParameter<edm::InputTag>("conversionsTag"));
0432 
0433   // inputs for PFCluster isolation
0434   const edm::ParameterSet& pfECALClusIsolCfg = cfg.getParameter<edm::ParameterSet>("pfECALClusIsolCfg");
0435   const edm::ParameterSet& pfHCALClusIsolCfg = cfg.getParameter<edm::ParameterSet>("pfHCALClusIsolCfg");
0436   inputCfg_.pfClusterProducer =
0437       consumes<reco::PFClusterCollection>(pfECALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducer"));
0438   inputCfg_.pfClusterProducerHCAL = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHCAL"));
0439   inputCfg_.pfClusterProducerHFEM = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFEM"));
0440   inputCfg_.pfClusterProducerHFHAD = consumes(pfHCALClusIsolCfg.getParameter<edm::InputTag>("pfClusterProducerHFHAD"));
0441 
0442   // Config for PFID dnn
0443   const auto& pset_dnn = cfg.getParameter<edm::ParameterSet>("EleDNNPFid");
0444   dnnPFidEnabled_ = pset_dnn.getParameter<bool>("enabled");
0445   extetaboundary_ = pset_dnn.getParameter<double>("extetaboundary");
0446 
0447   strategyCfg_.useDefaultEnergyCorrection = cfg.getParameter<bool>("useDefaultEnergyCorrection");
0448 
0449   strategyCfg_.applyPreselection = cfg.getParameter<bool>("applyPreselection");
0450   strategyCfg_.ecalDrivenEcalEnergyFromClassBasedParameterization =
0451       cfg.getParameter<bool>("ecalDrivenEcalEnergyFromClassBasedParameterization");
0452   strategyCfg_.ecalDrivenEcalErrorFromClassBasedParameterization =
0453       cfg.getParameter<bool>("ecalDrivenEcalErrorFromClassBasedParameterization");
0454   strategyCfg_.pureTrackerDrivenEcalErrorFromSimpleParameterization =
0455       cfg.getParameter<bool>("pureTrackerDrivenEcalErrorFromSimpleParameterization");
0456   strategyCfg_.applyAmbResolution = cfg.getParameter<bool>("applyAmbResolution");
0457   strategyCfg_.ignoreNotPreselected = cfg.getParameter<bool>("ignoreNotPreselected");
0458   strategyCfg_.ambSortingStrategy = cfg.getParameter<unsigned>("ambSortingStrategy");
0459   strategyCfg_.ambClustersOverlapStrategy = cfg.getParameter<unsigned>("ambClustersOverlapStrategy");
0460   strategyCfg_.ctfTracksCheck = cfg.getParameter<bool>("ctfTracksCheck");
0461   strategyCfg_.PreSelectMVA = cfg.getParameter<double>("PreSelectMVA");
0462   strategyCfg_.MaxElePtForOnlyMVA = cfg.getParameter<double>("MaxElePtForOnlyMVA");
0463   strategyCfg_.useEcalRegression = cfg.getParameter<bool>("useEcalRegression");
0464   strategyCfg_.useCombinationRegression = cfg.getParameter<bool>("useCombinationRegression");
0465   strategyCfg_.fillConvVtxFitProb = cfg.getParameter<bool>("fillConvVtxFitProb");
0466   strategyCfg_.computePfClusterIso = dnnPFidEnabled_;
0467 
0468   // hcal helpers
0469   auto const& psetPreselection = cfg.getParameter<edm::ParameterSet>("preselection");
0470   hcalCfg_.hOverEConeSize = psetPreselection.getParameter<double>("hOverEConeSize");
0471   if (hcalCfg_.hOverEConeSize > 0) {
0472     hcalCfg_.onlyBehindCluster = false;
0473     hcalCfg_.checkHcalStatus = cfg.getParameter<bool>("checkHcalStatus");
0474 
0475     //hcalCfg_.hbheRecHits = consumes<HBHERecHitCollection>(cfg.getParameter<edm::InputTag>("hbheRecHits"));
0476     hcalCfg_.hbheRecHits = consumes<HBHERecHitCollection>(cfg.getParameter<edm::InputTag>("hbheRecHits"));
0477 
0478     hcalCfg_.eThresHB = cfg.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
0479     hcalCfg_.maxSeverityHB = cfg.getParameter<int>("maxHcalRecHitSeverity");
0480     hcalCfg_.eThresHE = cfg.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
0481     hcalCfg_.maxSeverityHE = hcalCfg_.maxSeverityHB;
0482   }
0483 
0484   hcalCfgBc_.hOverEConeSize = 0.;
0485   hcalCfgBc_.onlyBehindCluster = true;
0486   hcalCfgBc_.checkHcalStatus = cfg.getParameter<bool>("checkHcalStatus");
0487 
0488   //hcalCfgBc_.hbheRecHits = consumes<HBHERecHitCollection>(cfg.getParameter<edm::InputTag>("hbheRecHits"));
0489   hcalCfgBc_.hbheRecHits = consumes<HBHERecHitCollection>(cfg.getParameter<edm::InputTag>("hbheRecHits"));
0490 
0491   hcalCfgBc_.eThresHB = cfg.getParameter<EgammaHcalIsolation::arrayHB>("recHitEThresholdHB");
0492   hcalCfgBc_.maxSeverityHB = cfg.getParameter<int>("maxHcalRecHitSeverity");
0493   hcalCfgBc_.eThresHE = cfg.getParameter<EgammaHcalIsolation::arrayHE>("recHitEThresholdHE");
0494   hcalCfgBc_.maxSeverityHE = hcalCfgBc_.maxSeverityHB;
0495 
0496   hcalRun2EffDepth_ = cfg.getParameter<bool>("hcalRun2EffDepth");
0497 
0498   // Ecal rec hits configuration
0499   GsfElectronAlgo::EcalRecHitsConfiguration recHitsCfg;
0500   auto const& flagnamesbarrel = cfg.getParameter<std::vector<std::string>>("recHitFlagsToBeExcludedBarrel");
0501   recHitsCfg.recHitFlagsToBeExcludedBarrel = StringToEnumValue<EcalRecHit::Flags>(flagnamesbarrel);
0502   auto const& flagnamesendcaps = cfg.getParameter<std::vector<std::string>>("recHitFlagsToBeExcludedEndcaps");
0503   recHitsCfg.recHitFlagsToBeExcludedEndcaps = StringToEnumValue<EcalRecHit::Flags>(flagnamesendcaps);
0504   auto const& severitynamesbarrel = cfg.getParameter<std::vector<std::string>>("recHitSeverityToBeExcludedBarrel");
0505   recHitsCfg.recHitSeverityToBeExcludedBarrel =
0506       StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesbarrel);
0507   auto const& severitynamesendcaps = cfg.getParameter<std::vector<std::string>>("recHitSeverityToBeExcludedEndcaps");
0508   recHitsCfg.recHitSeverityToBeExcludedEndcaps =
0509       StringToEnumValue<EcalSeverityLevel::SeverityLevel>(severitynamesendcaps);
0510 
0511   // isolation
0512   const GsfElectronAlgo::IsolationConfiguration isoCfg{
0513       .intRadiusHcal = cfg.getParameter<double>("intRadiusHcal"),
0514       .etMinHcal = cfg.getParameter<double>("etMinHcal"),
0515       .intRadiusEcalBarrel = cfg.getParameter<double>("intRadiusEcalBarrel"),
0516       .intRadiusEcalEndcaps = cfg.getParameter<double>("intRadiusEcalEndcaps"),
0517       .jurassicWidth = cfg.getParameter<double>("jurassicWidth"),
0518       .etMinBarrel = cfg.getParameter<double>("etMinBarrel"),
0519       .eMinBarrel = cfg.getParameter<double>("eMinBarrel"),
0520       .etMinEndcaps = cfg.getParameter<double>("etMinEndcaps"),
0521       .eMinEndcaps = cfg.getParameter<double>("eMinEndcaps"),
0522       .vetoClustered = cfg.getParameter<bool>("vetoClustered"),
0523       .useNumCrystals = cfg.getParameter<bool>("useNumCrystals")};
0524 
0525   // isolation
0526   const GsfElectronAlgo::PFClusterIsolationConfiguration pfisoCfg{
0527       .ecaldrMax = pfECALClusIsolCfg.getParameter<double>("drMax"),
0528       .ecaldrVetoBarrel = pfECALClusIsolCfg.getParameter<double>("drVetoBarrel"),
0529       .ecaldrVetoEndcap = pfECALClusIsolCfg.getParameter<double>("drVetoEndcap"),
0530       .ecaletaStripBarrel = pfECALClusIsolCfg.getParameter<double>("etaStripBarrel"),
0531       .ecaletaStripEndcap = pfECALClusIsolCfg.getParameter<double>("etaStripEndcap"),
0532       .ecalenergyBarrel = pfECALClusIsolCfg.getParameter<double>("energyBarrel"),
0533       .ecalenergyEndcap = pfECALClusIsolCfg.getParameter<double>("energyEndcap"),
0534       .useHF = pfHCALClusIsolCfg.getParameter<bool>("useHF"),
0535       .hcaldrMax = pfHCALClusIsolCfg.getParameter<double>("drMax"),
0536       .hcaldrVetoBarrel = pfHCALClusIsolCfg.getParameter<double>("drVetoBarrel"),
0537       .hcaldrVetoEndcap = pfHCALClusIsolCfg.getParameter<double>("drVetoEndcap"),
0538       .hcaletaStripBarrel = pfHCALClusIsolCfg.getParameter<double>("etaStripBarrel"),
0539       .hcaletaStripEndcap = pfHCALClusIsolCfg.getParameter<double>("etaStripEndcap"),
0540       .hcalenergyBarrel = pfHCALClusIsolCfg.getParameter<double>("energyBarrel"),
0541       .hcalenergyEndcap = pfHCALClusIsolCfg.getParameter<double>("energyEndcap"),
0542       .hcaluseEt = pfHCALClusIsolCfg.getParameter<bool>("useEt")};
0543 
0544   const RegressionHelper::Configuration regressionCfg{
0545       .ecalRegressionWeightLabels = cfg.getParameter<std::vector<std::string>>("ecalRefinedRegressionWeightLabels"),
0546       .ecalWeightsFromDB = cfg.getParameter<bool>("ecalWeightsFromDB"),
0547       .ecalRegressionWeightFiles = cfg.getParameter<std::vector<std::string>>("ecalRefinedRegressionWeightFiles"),
0548       .combinationRegressionWeightLabels =
0549           cfg.getParameter<std::vector<std::string>>("combinationRegressionWeightLabels"),
0550       .combinationWeightsFromDB = cfg.getParameter<bool>("combinationWeightsFromDB"),
0551       .combinationRegressionWeightFiles =
0552           cfg.getParameter<std::vector<std::string>>("combinationRegressionWeightFile")};
0553 
0554   // create algo
0555   algo_ = std::make_unique<GsfElectronAlgo>(
0556       inputCfg_,
0557       strategyCfg_,
0558       cutsCfg_,
0559       hcalCfg_,
0560       hcalCfgBc_,
0561       isoCfg,
0562       pfisoCfg,
0563       recHitsCfg,
0564       EcalClusterFunctionFactory::get()->create(
0565           cfg.getParameter<std::string>("crackCorrectionFunction"), cfg, consumesCollector()),
0566       regressionCfg,
0567       cfg.getParameter<edm::ParameterSet>("trkIsol03Cfg"),
0568       cfg.getParameter<edm::ParameterSet>("trkIsol04Cfg"),
0569       cfg.getParameter<edm::ParameterSet>("trkIsolHEEP03Cfg"),
0570       cfg.getParameter<edm::ParameterSet>("trkIsolHEEP04Cfg"),
0571       consumesCollector());
0572 }
0573 
0574 void GsfElectronProducer::endStream() {}
0575 
0576 void GsfElectronProducer::checkEcalSeedingParameters(edm::ParameterSet const& pset) {
0577   if (!pset.exists("SeedConfiguration")) {
0578     return;
0579   }
0580   edm::ParameterSet seedConfiguration = pset.getParameter<edm::ParameterSet>("SeedConfiguration");
0581 
0582   if (seedConfiguration.getParameter<bool>("applyHOverECut")) {
0583     if ((hcalCfg_.hOverEConeSize != 0) &&
0584         (hcalCfg_.hOverEConeSize != seedConfiguration.getParameter<double>("hOverEConeSize"))) {
0585       edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
0586           << "The H/E cone size (" << hcalCfg_.hOverEConeSize << ") is different from ecal seeding ("
0587           << seedConfiguration.getParameter<double>("hOverEConeSize") << ").";
0588     }
0589     if (cutsCfg_.maxHOverEBarrelCone < seedConfiguration.getParameter<double>("maxHOverEBarrel")) {
0590       edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
0591           << "The max barrel cone H/E is lower than during ecal seeding.";
0592     }
0593     if (cutsCfg_.maxHOverEEndcapsCone < seedConfiguration.getParameter<double>("maxHOverEEndcaps")) {
0594       edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
0595           << "The max endcaps cone H/E is lower than during ecal seeding.";
0596     }
0597   }
0598 
0599   if (cutsCfg_.minSCEtBarrel < seedConfiguration.getParameter<double>("SCEtCut")) {
0600     edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
0601         << "The minimum super-cluster Et in barrel is lower than during ecal seeding.";
0602   }
0603   if (cutsCfg_.minSCEtEndcaps < seedConfiguration.getParameter<double>("SCEtCut")) {
0604     edm::LogWarning("GsfElectronAlgo|InconsistentParameters")
0605         << "The minimum super-cluster Et in endcaps is lower than during ecal seeding.";
0606   }
0607 }
0608 
0609 //=======================================================================================
0610 // Ambiguity solving
0611 //=======================================================================================
0612 
0613 void GsfElectronProducer::setAmbiguityData(reco::GsfElectronCollection& electrons,
0614                                            edm::Event const& event,
0615                                            bool ignoreNotPreselected) const {
0616   // Getting required event data
0617   auto const& beamspot = event.get(inputCfg_.beamSpotTag);
0618   auto gsfPfRecTracks =
0619       useGsfPfRecTracks_ ? event.getHandle(gsfPfRecTracksTag_) : edm::Handle<reco::GsfPFRecTrackCollection>{};
0620   auto const& barrelRecHits = event.get(inputCfg_.barrelRecHitCollection);
0621   auto const& endcapRecHits = event.get(inputCfg_.endcapRecHitCollection);
0622 
0623   if (strategyCfg_.ambSortingStrategy == 0) {
0624     std::sort(electrons.begin(), electrons.end(), egamma::isBetterElectron);
0625   } else if (strategyCfg_.ambSortingStrategy == 1) {
0626     std::sort(electrons.begin(), electrons.end(), egamma::isInnermostElectron);
0627   } else {
0628     throw cms::Exception("GsfElectronAlgo|UnknownAmbiguitySortingStrategy")
0629         << "value of strategyCfg_.ambSortingStrategy is : " << strategyCfg_.ambSortingStrategy;
0630   }
0631 
0632   // init
0633   for (auto& electron : electrons) {
0634     electron.clearAmbiguousGsfTracks();
0635     electron.setAmbiguous(false);
0636   }
0637 
0638   // get ambiguous from GsfPfRecTracks
0639   if (useGsfPfRecTracks_) {
0640     for (auto& e1 : electrons) {
0641       bool found = false;
0642       for (auto const& gsfPfRecTrack : *gsfPfRecTracks) {
0643         if (gsfPfRecTrack.gsfTrackRef() == e1.gsfTrack()) {
0644           if (found) {
0645             edm::LogWarning("GsfElectronAlgo") << "associated gsfPfRecTrack already found";
0646           } else {
0647             found = true;
0648             for (auto const& duplicate : gsfPfRecTrack.convBremGsfPFRecTrackRef()) {
0649               e1.addAmbiguousGsfTrack(duplicate->gsfTrackRef());
0650             }
0651           }
0652         }
0653       }
0654     }
0655   }
0656   // or search overlapping clusters
0657   else {
0658     for (auto e1 = electrons.begin(); e1 != electrons.end(); ++e1) {
0659       if (e1->ambiguous())
0660         continue;
0661       if (ignoreNotPreselected && !isPreselected(*e1))
0662         continue;
0663 
0664       SuperClusterRef scRef1 = e1->superCluster();
0665       CaloClusterPtr eleClu1 = e1->electronCluster();
0666       LogDebug("GsfElectronAlgo") << "Blessing electron with E/P " << e1->eSuperClusterOverP() << ", cluster "
0667                                   << scRef1.get() << " & track " << e1->gsfTrack().get();
0668 
0669       for (auto e2 = e1 + 1; e2 != electrons.end(); ++e2) {
0670         if (e2->ambiguous())
0671           continue;
0672         if (ignoreNotPreselected && !isPreselected(*e2))
0673           continue;
0674 
0675         SuperClusterRef scRef2 = e2->superCluster();
0676         CaloClusterPtr eleClu2 = e2->electronCluster();
0677 
0678         // search if same cluster
0679         bool sameCluster = false;
0680         if (strategyCfg_.ambClustersOverlapStrategy == 0) {
0681           sameCluster = (scRef1 == scRef2);
0682         } else if (strategyCfg_.ambClustersOverlapStrategy == 1) {
0683           float eMin = 1.;
0684           float threshold = eMin * cosh(EleRelPoint(scRef1->position(), beamspot.position()).eta());
0685           using egamma::sharedEnergy;
0686           sameCluster = ((sharedEnergy(*eleClu1, *eleClu2, barrelRecHits, endcapRecHits) >= threshold) ||
0687                          (sharedEnergy(*scRef1->seed(), *eleClu2, barrelRecHits, endcapRecHits) >= threshold) ||
0688                          (sharedEnergy(*eleClu1, *scRef2->seed(), barrelRecHits, endcapRecHits) >= threshold) ||
0689                          (sharedEnergy(*scRef1->seed(), *scRef2->seed(), barrelRecHits, endcapRecHits) >= threshold));
0690         } else {
0691           throw cms::Exception("GsfElectronAlgo|UnknownAmbiguityClustersOverlapStrategy")
0692               << "value of strategyCfg_.ambClustersOverlapStrategy is : " << strategyCfg_.ambClustersOverlapStrategy;
0693         }
0694 
0695         // main instructions
0696         if (sameCluster) {
0697           LogDebug("GsfElectronAlgo") << "Discarding electron with E/P " << e2->eSuperClusterOverP() << ", cluster "
0698                                       << scRef2.get() << " and track " << e2->gsfTrack().get();
0699           e1->addAmbiguousGsfTrack(e2->gsfTrack());
0700           e2->setAmbiguous(true);
0701         } else if (e1->gsfTrack() == e2->gsfTrack()) {
0702           edm::LogWarning("GsfElectronAlgo") << "Forgetting electron with E/P " << e2->eSuperClusterOverP()
0703                                              << ", cluster " << scRef2.get() << " and track " << e2->gsfTrack().get();
0704           e2->setAmbiguous(true);
0705         }
0706       }
0707     }
0708   }
0709 }
0710 
0711 bool GsfElectronProducer::isPreselected(GsfElectron const& ele) const {
0712   bool passCutBased = ele.passingCutBasedPreselection();
0713   bool passPF = ele.passingPflowPreselection();
0714   // it is worth nothing for gedGsfElectrons, this does nothing as its not set
0715   // till GedGsfElectron finaliser, this is always false
0716   bool passmva = ele.passingMvaPreselection();
0717   if (!ele.ecalDrivenSeed()) {
0718     if (ele.pt() > strategyCfg_.MaxElePtForOnlyMVA)
0719       return passmva && passCutBased;
0720     else
0721       return passmva;
0722   } else {
0723     return passCutBased || passPF || passmva;
0724   }
0725 }
0726 
0727 // ------------ method called to produce the data  ------------
0728 void GsfElectronProducer::produce(edm::Event& event, const edm::EventSetup& setup) {
0729   HcalPFCuts const* hcalCuts = nullptr;
0730   if (cutsFromDB_) {
0731     hcalCuts = &setup.getData(hcalCutsToken_);
0732   }
0733 
0734   // check configuration
0735   if (!ecalSeedingParametersChecked_) {
0736     ecalSeedingParametersChecked_ = true;
0737     auto seeds = event.getHandle(inputCfg_.seedsTag);
0738     if (!seeds.isValid()) {
0739       edm::LogWarning("GsfElectronAlgo|UnreachableSeedsProvenance")
0740           << "Cannot check consistency of parameters with ecal seeding ones,"
0741           << " because the original collection of seeds is not any more available.";
0742     } else {
0743       checkEcalSeedingParameters(edm::parameterSet(seeds.provenance()->stable(), event.processHistory()));
0744     }
0745   }
0746 
0747   auto electrons = algo_->completeElectrons(event, setup, globalCache(), hcalCuts);
0748   if (resetMvaValuesUsingPFCandidates_) {
0749     const auto gsfMVAInputMap = matchWithPFCandidates(event.get(egmPFCandidateCollection_));
0750     for (auto& el : electrons) {
0751       el.setMvaInput(gsfMVAInputMap.find(el.gsfTrack())->second);  // set Run2 MVA inputs
0752     }
0753     setMVAOutputs(electrons, globalCache(), event.get(inputCfg_.vtxCollectionTag), dnnPFidEnabled_, extetaboundary_);
0754   }
0755 
0756   // all electrons
0757   logElectrons(electrons, event, "GsfElectronAlgo Info (before preselection)");
0758   // preselection
0759   if (strategyCfg_.applyPreselection) {
0760     electrons.erase(
0761         std::remove_if(electrons.begin(), electrons.end(), [this](auto const& ele) { return !isPreselected(ele); }),
0762         electrons.end());
0763     logElectrons(electrons, event, "GsfElectronAlgo Info (after preselection)");
0764   }
0765   // ambiguity
0766   setAmbiguityData(electrons, event, strategyCfg_.ignoreNotPreselected);
0767   if (strategyCfg_.applyAmbResolution) {
0768     electrons.erase(std::remove_if(electrons.begin(), electrons.end(), std::mem_fn(&reco::GsfElectron::ambiguous)),
0769                     electrons.end());
0770     logElectrons(electrons, event, "GsfElectronAlgo Info (after amb. solving)");
0771   }
0772   // 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
0773   if (hcalRun2EffDepth_) {
0774     for (auto& ele : electrons)
0775       ele.hcalToRun2EffDepth();
0776   }
0777   // final filling
0778   event.emplace(electronPutToken_, std::move(electrons));
0779 }
0780 
0781 #include "FWCore/Framework/interface/MakerMacros.h"
0782 DEFINE_FWK_MODULE(GsfElectronProducer);