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