File indexing completed on 2025-02-20 03:45:45
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012 #include "CommonTools/Egamma/interface/ConversionTools.h"
0013 #include "CommonTools/Utils/interface/PtComparator.h"
0014 #include "DataFormats/BeamSpot/interface/BeamSpot.h"
0015 #include "DataFormats/Candidate/interface/CandAssociation.h"
0016 #include "DataFormats/Common/interface/Association.h"
0017 #include "DataFormats/Common/interface/ValueMap.h"
0018 #include "DataFormats/Common/interface/View.h"
0019 #include "DataFormats/EcalDetId/interface/EcalSubdetector.h"
0020 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0021 #include "DataFormats/GsfTrackReco/interface/GsfTrackFwd.h"
0022 #include "DataFormats/HepMCCandidate/interface/GenParticle.h"
0023 #include "DataFormats/HepMCCandidate/interface/GenParticleFwd.h"
0024 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0025 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateFwd.h"
0026 #include "DataFormats/PatCandidates/interface/Electron.h"
0027 #include "DataFormats/PatCandidates/interface/PFIsolation.h"
0028 #include "DataFormats/PatCandidates/interface/UserData.h"
0029 #include "DataFormats/VertexReco/interface/Vertex.h"
0030 #include "FWCore/Framework/interface/Event.h"
0031 #include "FWCore/Framework/interface/stream/EDProducer.h"
0032 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0033 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0034 #include "FWCore/ParameterSet/interface/EmptyGroupDescription.h"
0035 #include "FWCore/ParameterSet/interface/FileInPath.h"
0036 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0037 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0038 #include "FWCore/Utilities/interface/InputTag.h"
0039 #include "FWCore/Utilities/interface/isFinite.h"
0040 #include "FWCore/Utilities/interface/transform.h"
0041 #include "Geometry/CaloTopology/interface/CaloSubdetectorTopology.h"
0042 #include "Geometry/CaloTopology/interface/CaloTopology.h"
0043 #include "Geometry/Records/interface/CaloGeometryRecord.h"
0044 #include "Geometry/Records/interface/CaloTopologyRecord.h"
0045 #include "PhysicsTools/PatAlgos/interface/EfficiencyLoader.h"
0046 #include "PhysicsTools/PatAlgos/interface/KinResolutionsLoader.h"
0047 #include "PhysicsTools/PatAlgos/interface/MultiIsolator.h"
0048 #include "PhysicsTools/PatAlgos/interface/PATUserDataHelper.h"
0049 #include "PhysicsTools/PatUtils/interface/CaloIsolationEnergy.h"
0050 #include "PhysicsTools/PatUtils/interface/MiniIsolation.h"
0051 #include "PhysicsTools/PatUtils/interface/TrackerIsolationPt.h"
0052 #include "RecoEcal/EgammaCoreTools/interface/EcalClusterLazyTools.h"
0053 #include "TrackingTools/IPTools/interface/IPTools.h"
0054 #include "TrackingTools/Records/interface/TransientTrackRecord.h"
0055 #include "TrackingTools/TransientTrack/interface/TransientTrack.h"
0056 #include "TrackingTools/TransientTrack/interface/TransientTrackBuilder.h"
0057
0058 #include <memory>
0059 #include <string>
0060 #include <vector>
0061
0062 namespace pat {
0063
0064 class TrackerIsolationPt;
0065 class CaloIsolationEnergy;
0066 class LeptonLRCalc;
0067
0068 class PATElectronProducer : public edm::stream::EDProducer<> {
0069 public:
0070 explicit PATElectronProducer(const edm::ParameterSet& iConfig);
0071 ~PATElectronProducer() override;
0072
0073 void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override;
0074
0075 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0076
0077 private:
0078
0079 const edm::EDGetTokenT<edm::View<reco::GsfElectron>> electronToken_;
0080 const edm::EDGetTokenT<reco::ConversionCollection> hConversionsToken_;
0081 const bool embedGsfElectronCore_;
0082 const bool embedGsfTrack_;
0083 const bool embedSuperCluster_;
0084 const bool embedPflowSuperCluster_;
0085 const bool embedSeedCluster_;
0086 const bool embedBasicClusters_;
0087 const bool embedPreshowerClusters_;
0088 const bool embedPflowBasicClusters_;
0089 const bool embedPflowPreshowerClusters_;
0090 const bool embedTrack_;
0091 bool addGenMatch_;
0092 bool embedGenMatch_;
0093 const bool embedRecHits_;
0094
0095 edm::EDGetTokenT<pat::PackedCandidateCollection> pcToken_;
0096 bool computeMiniIso_;
0097 std::vector<double> miniIsoParamsE_;
0098 std::vector<double> miniIsoParamsB_;
0099
0100 typedef std::vector<edm::Handle<edm::Association<reco::GenParticleCollection>>> GenAssociations;
0101
0102 std::vector<edm::EDGetTokenT<edm::Association<reco::GenParticleCollection>>> genMatchTokens_;
0103
0104
0105 const bool useParticleFlow_;
0106 const bool usePfCandidateMultiMap_;
0107 const edm::EDGetTokenT<reco::PFCandidateCollection> pfElecToken_;
0108 const edm::EDGetTokenT<edm::ValueMap<reco::PFCandidatePtr>> pfCandidateMapToken_;
0109 const edm::EDGetTokenT<edm::ValueMap<std::vector<reco::PFCandidateRef>>> pfCandidateMultiMapToken_;
0110 const bool embedPFCandidate_;
0111
0112
0113 const bool addMVAVariables_;
0114 const edm::InputTag reducedBarrelRecHitCollection_;
0115 const edm::EDGetTokenT<EcalRecHitCollection> reducedBarrelRecHitCollectionToken_;
0116 const edm::InputTag reducedEndcapRecHitCollection_;
0117 const edm::EDGetTokenT<EcalRecHitCollection> reducedEndcapRecHitCollectionToken_;
0118 const EcalClusterLazyTools::ESGetTokens ecalClusterToolsESGetTokens_;
0119
0120 const bool addPFClusterIso_;
0121 const bool addPuppiIsolation_;
0122 const edm::EDGetTokenT<edm::ValueMap<float>> ecalPFClusterIsoT_;
0123 const edm::EDGetTokenT<edm::ValueMap<float>> hcalPFClusterIsoT_;
0124
0125
0126 const bool embedHighLevelSelection_;
0127 const edm::EDGetTokenT<reco::BeamSpot> beamLineToken_;
0128 const edm::EDGetTokenT<std::vector<reco::Vertex>> pvToken_;
0129
0130 typedef edm::RefToBase<reco::GsfElectron> ElectronBaseRef;
0131 typedef std::vector<edm::Handle<edm::ValueMap<IsoDeposit>>> IsoDepositMaps;
0132 typedef std::vector<edm::Handle<edm::ValueMap<double>>> IsolationValueMaps;
0133
0134
0135 void fillElectron(Electron& aElectron,
0136 const ElectronBaseRef& electronRef,
0137 const reco::CandidateBaseRef& baseRef,
0138 const GenAssociations& genMatches,
0139 const IsoDepositMaps& deposits,
0140 const bool pfId,
0141 const IsolationValueMaps& isolationValues,
0142 const IsolationValueMaps& isolationValuesNoPFId) const;
0143
0144 void fillElectron2(Electron& anElectron,
0145 const reco::CandidatePtr& candPtrForIsolation,
0146 const reco::CandidatePtr& candPtrForGenMatch,
0147 const reco::CandidatePtr& candPtrForLoader,
0148 const GenAssociations& genMatches,
0149 const IsoDepositMaps& deposits,
0150 const IsolationValueMaps& isolationValues) const;
0151
0152
0153 void setElectronMiniIso(pat::Electron& anElectron, const pat::PackedCandidateCollection* pc);
0154
0155
0156
0157 void embedHighLevel(pat::Electron& anElectron,
0158 reco::GsfTrackRef track,
0159 reco::TransientTrack& tt,
0160 reco::Vertex& primaryVertex,
0161 bool primaryVertexIsValid,
0162 reco::BeamSpot& beamspot,
0163 bool beamspotIsValid);
0164
0165 typedef std::pair<pat::IsolationKeys, edm::InputTag> IsolationLabel;
0166 typedef std::vector<IsolationLabel> IsolationLabels;
0167
0168
0169
0170 template <typename T>
0171 void readIsolationLabels(const edm::ParameterSet& iConfig,
0172 const char* psetName,
0173 IsolationLabels& labels,
0174 std::vector<edm::EDGetTokenT<edm::ValueMap<T>>>& tokens);
0175
0176 const bool addElecID_;
0177 typedef std::pair<std::string, edm::InputTag> NameTag;
0178 std::vector<NameTag> elecIDSrcs_;
0179 std::vector<edm::EDGetTokenT<edm::ValueMap<float>>> elecIDTokens_;
0180
0181
0182 const GreaterByPt<Electron> pTComparator_;
0183
0184 pat::helper::MultiIsolator isolator_;
0185 pat::helper::MultiIsolator::IsolationValuePairs isolatorTmpStorage_;
0186 IsolationLabels isoDepositLabels_;
0187 std::vector<edm::EDGetTokenT<edm::ValueMap<IsoDeposit>>> isoDepositTokens_;
0188 IsolationLabels isolationValueLabels_;
0189 std::vector<edm::EDGetTokenT<edm::ValueMap<double>>> isolationValueTokens_;
0190 IsolationLabels isolationValueLabelsNoPFId_;
0191 std::vector<edm::EDGetTokenT<edm::ValueMap<double>>> isolationValueNoPFIdTokens_;
0192
0193 const bool addEfficiencies_;
0194 pat::helper::EfficiencyLoader efficiencyLoader_;
0195
0196 const bool addResolutions_;
0197 pat::helper::KinResolutionsLoader resolutionLoader_;
0198
0199 const bool useUserData_;
0200
0201 edm::EDGetTokenT<edm::ValueMap<float>> PUPPIIsolation_charged_hadrons_;
0202 edm::EDGetTokenT<edm::ValueMap<float>> PUPPIIsolation_neutral_hadrons_;
0203 edm::EDGetTokenT<edm::ValueMap<float>> PUPPIIsolation_photons_;
0204
0205 edm::EDGetTokenT<edm::ValueMap<float>> PUPPINoLeptonsIsolation_charged_hadrons_;
0206 edm::EDGetTokenT<edm::ValueMap<float>> PUPPINoLeptonsIsolation_neutral_hadrons_;
0207 edm::EDGetTokenT<edm::ValueMap<float>> PUPPINoLeptonsIsolation_photons_;
0208 pat::PATUserDataHelper<pat::Electron> userDataHelper_;
0209
0210 const edm::ESGetToken<CaloTopology, CaloTopologyRecord> ecalTopologyToken_;
0211 const edm::ESGetToken<TransientTrackBuilder, TransientTrackRecord> trackBuilderToken_;
0212
0213 const CaloTopology* ecalTopology_;
0214 };
0215 }
0216
0217 template <typename T>
0218 void pat::PATElectronProducer::readIsolationLabels(const edm::ParameterSet& iConfig,
0219 const char* psetName,
0220 pat::PATElectronProducer::IsolationLabels& labels,
0221 std::vector<edm::EDGetTokenT<edm::ValueMap<T>>>& tokens) {
0222 labels.clear();
0223
0224 if (iConfig.exists(psetName)) {
0225 edm::ParameterSet depconf = iConfig.getParameter<edm::ParameterSet>(psetName);
0226
0227 if (depconf.exists("tracker"))
0228 labels.push_back(std::make_pair(pat::TrackIso, depconf.getParameter<edm::InputTag>("tracker")));
0229 if (depconf.exists("ecal"))
0230 labels.push_back(std::make_pair(pat::EcalIso, depconf.getParameter<edm::InputTag>("ecal")));
0231 if (depconf.exists("hcal"))
0232 labels.push_back(std::make_pair(pat::HcalIso, depconf.getParameter<edm::InputTag>("hcal")));
0233 if (depconf.exists("pfAllParticles")) {
0234 labels.push_back(std::make_pair(pat::PfAllParticleIso, depconf.getParameter<edm::InputTag>("pfAllParticles")));
0235 }
0236 if (depconf.exists("pfChargedHadrons")) {
0237 labels.push_back(
0238 std::make_pair(pat::PfChargedHadronIso, depconf.getParameter<edm::InputTag>("pfChargedHadrons")));
0239 }
0240 if (depconf.exists("pfChargedAll")) {
0241 labels.push_back(std::make_pair(pat::PfChargedAllIso, depconf.getParameter<edm::InputTag>("pfChargedAll")));
0242 }
0243 if (depconf.exists("pfPUChargedHadrons")) {
0244 labels.push_back(
0245 std::make_pair(pat::PfPUChargedHadronIso, depconf.getParameter<edm::InputTag>("pfPUChargedHadrons")));
0246 }
0247 if (depconf.exists("pfNeutralHadrons")) {
0248 labels.push_back(
0249 std::make_pair(pat::PfNeutralHadronIso, depconf.getParameter<edm::InputTag>("pfNeutralHadrons")));
0250 }
0251 if (depconf.exists("pfPhotons")) {
0252 labels.push_back(std::make_pair(pat::PfGammaIso, depconf.getParameter<edm::InputTag>("pfPhotons")));
0253 }
0254 if (depconf.exists("user")) {
0255 std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag>>("user");
0256 std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
0257 int key = pat::IsolationKeys::UserBaseIso;
0258 for (; it != ed; ++it, ++key) {
0259 labels.push_back(std::make_pair(pat::IsolationKeys(key), *it));
0260 }
0261 }
0262 }
0263 tokens = edm::vector_transform(
0264 labels, [this](IsolationLabel const& label) { return consumes<edm::ValueMap<T>>(label.second); });
0265 }
0266
0267 using namespace pat;
0268 using namespace std;
0269
0270 PATElectronProducer::PATElectronProducer(const edm::ParameterSet& iConfig)
0271 :
0272 electronToken_(consumes<edm::View<reco::GsfElectron>>(iConfig.getParameter<edm::InputTag>("electronSource"))),
0273 hConversionsToken_(consumes<reco::ConversionCollection>(edm::InputTag("allConversions"))),
0274 embedGsfElectronCore_(iConfig.getParameter<bool>("embedGsfElectronCore")),
0275 embedGsfTrack_(iConfig.getParameter<bool>("embedGsfTrack")),
0276 embedSuperCluster_(iConfig.getParameter<bool>("embedSuperCluster")),
0277 embedPflowSuperCluster_(iConfig.getParameter<bool>("embedPflowSuperCluster")),
0278 embedSeedCluster_(iConfig.getParameter<bool>("embedSeedCluster")),
0279 embedBasicClusters_(iConfig.getParameter<bool>("embedBasicClusters")),
0280 embedPreshowerClusters_(iConfig.getParameter<bool>("embedPreshowerClusters")),
0281 embedPflowBasicClusters_(iConfig.getParameter<bool>("embedPflowBasicClusters")),
0282 embedPflowPreshowerClusters_(iConfig.getParameter<bool>("embedPflowPreshowerClusters")),
0283 embedTrack_(iConfig.getParameter<bool>("embedTrack")),
0284 addGenMatch_(iConfig.getParameter<bool>("addGenMatch")),
0285 embedGenMatch_(addGenMatch_ ? iConfig.getParameter<bool>("embedGenMatch") : false),
0286 embedRecHits_(iConfig.getParameter<bool>("embedRecHits")),
0287
0288 useParticleFlow_(iConfig.getParameter<bool>("useParticleFlow")),
0289 usePfCandidateMultiMap_(iConfig.getParameter<bool>("usePfCandidateMultiMap")),
0290 pfElecToken_(!usePfCandidateMultiMap_
0291 ? consumes<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfElectronSource"))
0292 : edm::EDGetTokenT<reco::PFCandidateCollection>()),
0293 pfCandidateMapToken_(!usePfCandidateMultiMap_ ? mayConsume<edm::ValueMap<reco::PFCandidatePtr>>(
0294 iConfig.getParameter<edm::InputTag>("pfCandidateMap"))
0295 : edm::EDGetTokenT<edm::ValueMap<reco::PFCandidatePtr>>()),
0296 pfCandidateMultiMapToken_(usePfCandidateMultiMap_
0297 ? consumes<edm::ValueMap<std::vector<reco::PFCandidateRef>>>(
0298 iConfig.getParameter<edm::InputTag>("pfCandidateMultiMap"))
0299 : edm::EDGetTokenT<edm::ValueMap<std::vector<reco::PFCandidateRef>>>()),
0300 embedPFCandidate_(iConfig.getParameter<bool>("embedPFCandidate")),
0301
0302 addMVAVariables_(iConfig.getParameter<bool>("addMVAVariables")),
0303 reducedBarrelRecHitCollection_(iConfig.getParameter<edm::InputTag>("reducedBarrelRecHitCollection")),
0304 reducedBarrelRecHitCollectionToken_(mayConsume<EcalRecHitCollection>(reducedBarrelRecHitCollection_)),
0305 reducedEndcapRecHitCollection_(iConfig.getParameter<edm::InputTag>("reducedEndcapRecHitCollection")),
0306 reducedEndcapRecHitCollectionToken_(mayConsume<EcalRecHitCollection>(reducedEndcapRecHitCollection_)),
0307 ecalClusterToolsESGetTokens_{consumesCollector()},
0308
0309 addPFClusterIso_(iConfig.getParameter<bool>("addPFClusterIso")),
0310 addPuppiIsolation_(iConfig.getParameter<bool>("addPuppiIsolation")),
0311 ecalPFClusterIsoT_(consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("ecalPFClusterIsoMap"))),
0312 hcalPFClusterIsoT_(consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("hcalPFClusterIsoMap"))),
0313
0314 embedHighLevelSelection_(iConfig.getParameter<bool>("embedHighLevelSelection")),
0315 beamLineToken_(consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamLineSrc"))),
0316 pvToken_(mayConsume<std::vector<reco::Vertex>>(iConfig.getParameter<edm::InputTag>("pvSrc"))),
0317 addElecID_(iConfig.getParameter<bool>("addElectronID")),
0318 pTComparator_(),
0319 isolator_(iConfig.getParameter<edm::ParameterSet>("userIsolation"), consumesCollector(), false),
0320 addEfficiencies_(iConfig.getParameter<bool>("addEfficiencies")),
0321 addResolutions_(iConfig.getParameter<bool>("addResolutions")),
0322 useUserData_(iConfig.exists("userData")),
0323 ecalTopologyToken_{esConsumes()},
0324 trackBuilderToken_{esConsumes(edm::ESInputTag("", "TransientTrackBuilder"))} {
0325
0326
0327 if (addGenMatch_) {
0328 genMatchTokens_.push_back(consumes<edm::Association<reco::GenParticleCollection>>(
0329 iConfig.getParameter<edm::InputTag>("genParticleMatch")));
0330 }
0331
0332 if (addResolutions_) {
0333 resolutionLoader_ =
0334 pat::helper::KinResolutionsLoader(iConfig.getParameter<edm::ParameterSet>("resolutions"), consumesCollector());
0335 }
0336 if (addPuppiIsolation_) {
0337
0338 PUPPIIsolation_charged_hadrons_ =
0339 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationChargedHadrons"));
0340 PUPPIIsolation_neutral_hadrons_ =
0341 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationNeutralHadrons"));
0342 PUPPIIsolation_photons_ =
0343 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationPhotons"));
0344
0345 PUPPINoLeptonsIsolation_charged_hadrons_ =
0346 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationChargedHadrons"));
0347 PUPPINoLeptonsIsolation_neutral_hadrons_ =
0348 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationNeutralHadrons"));
0349 PUPPINoLeptonsIsolation_photons_ =
0350 consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationPhotons"));
0351 }
0352
0353 if (addElecID_) {
0354
0355 if (iConfig.existsAs<edm::InputTag>("electronIDSource")) {
0356 elecIDSrcs_.push_back(NameTag("", iConfig.getParameter<edm::InputTag>("electronIDSource")));
0357 }
0358
0359 if (iConfig.existsAs<edm::ParameterSet>("electronIDSources")) {
0360
0361 if (!elecIDSrcs_.empty()) {
0362 throw cms::Exception("Configuration")
0363 << "PATElectronProducer: you can't specify both 'electronIDSource' and 'electronIDSources'\n";
0364 }
0365
0366 edm::ParameterSet idps = iConfig.getParameter<edm::ParameterSet>("electronIDSources");
0367 std::vector<std::string> names = idps.getParameterNamesForType<edm::InputTag>();
0368 for (std::vector<std::string>::const_iterator it = names.begin(), ed = names.end(); it != ed; ++it) {
0369 elecIDSrcs_.push_back(NameTag(*it, idps.getParameter<edm::InputTag>(*it)));
0370 }
0371 }
0372
0373 if (elecIDSrcs_.empty()) {
0374 throw cms::Exception("Configuration")
0375 << "PATElectronProducer: id addElectronID is true, you must specify either:\n"
0376 << "\tInputTag electronIDSource = <someTag>\n"
0377 << "or\n"
0378 << "\tPSet electronIDSources = { \n"
0379 << "\t\tInputTag <someName> = <someTag> // as many as you want \n "
0380 << "\t}\n";
0381 }
0382 }
0383 elecIDTokens_ = edm::vector_transform(
0384 elecIDSrcs_, [this](NameTag const& tag) { return mayConsume<edm::ValueMap<float>>(tag.second); });
0385
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404
0405
0406 computeMiniIso_ = iConfig.getParameter<bool>("computeMiniIso");
0407 miniIsoParamsE_ = iConfig.getParameter<std::vector<double>>("miniIsoParamsE");
0408 miniIsoParamsB_ = iConfig.getParameter<std::vector<double>>("miniIsoParamsB");
0409 if (computeMiniIso_ && (miniIsoParamsE_.size() != 9 || miniIsoParamsB_.size() != 9)) {
0410 throw cms::Exception("ParameterError") << "miniIsoParams must have exactly 9 elements.\n";
0411 }
0412 if (computeMiniIso_)
0413 pcToken_ = consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfCandsForMiniIso"));
0414
0415
0416 readIsolationLabels(iConfig, "isoDeposits", isoDepositLabels_, isoDepositTokens_);
0417
0418 readIsolationLabels(iConfig, "isolationValues", isolationValueLabels_, isolationValueTokens_);
0419
0420 readIsolationLabels(iConfig, "isolationValuesNoPFId", isolationValueLabelsNoPFId_, isolationValueNoPFIdTokens_);
0421
0422 if (addEfficiencies_) {
0423 efficiencyLoader_ =
0424 pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"), consumesCollector());
0425 }
0426
0427 if (useUserData_) {
0428 userDataHelper_ =
0429 PATUserDataHelper<Electron>(iConfig.getParameter<edm::ParameterSet>("userData"), consumesCollector());
0430 }
0431
0432
0433 if (useParticleFlow_ && usePfCandidateMultiMap_)
0434 throw cms::Exception("Configuration", "usePfCandidateMultiMap not supported when useParticleFlow is set to true");
0435
0436
0437 produces<std::vector<Electron>>();
0438 }
0439
0440 PATElectronProducer::~PATElectronProducer() {}
0441
0442 void PATElectronProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
0443
0444 if (iEvent.isRealData()) {
0445 addGenMatch_ = false;
0446 embedGenMatch_ = false;
0447 }
0448
0449 ecalTopology_ = &iSetup.getData(ecalTopologyToken_);
0450
0451
0452 edm::Handle<edm::View<reco::GsfElectron>> electrons;
0453 iEvent.getByToken(electronToken_, electrons);
0454
0455 edm::Handle<PackedCandidateCollection> pc;
0456 if (computeMiniIso_)
0457 iEvent.getByToken(pcToken_, pc);
0458
0459
0460 edm::InputTag reducedEBRecHitCollection(string("reducedEcalRecHitsEB"));
0461 edm::InputTag reducedEERecHitCollection(string("reducedEcalRecHitsEE"));
0462
0463 EcalClusterLazyTools lazyTools(iEvent,
0464 ecalClusterToolsESGetTokens_.get(iSetup),
0465 reducedBarrelRecHitCollectionToken_,
0466 reducedEndcapRecHitCollectionToken_);
0467
0468
0469 edm::Handle<reco::ConversionCollection> hConversions;
0470 iEvent.getByToken(hConversionsToken_, hConversions);
0471
0472
0473
0474 edm::ESHandle<TransientTrackBuilder> trackBuilder;
0475
0476 if (isolator_.enabled())
0477 isolator_.beginEvent(iEvent, iSetup);
0478
0479 if (efficiencyLoader_.enabled())
0480 efficiencyLoader_.newEvent(iEvent);
0481 if (resolutionLoader_.enabled())
0482 resolutionLoader_.newEvent(iEvent, iSetup);
0483
0484 IsoDepositMaps deposits(isoDepositTokens_.size());
0485 for (size_t j = 0, nd = isoDepositTokens_.size(); j < nd; ++j) {
0486 iEvent.getByToken(isoDepositTokens_[j], deposits[j]);
0487 }
0488
0489 IsolationValueMaps isolationValues(isolationValueTokens_.size());
0490 for (size_t j = 0; j < isolationValueTokens_.size(); ++j) {
0491 iEvent.getByToken(isolationValueTokens_[j], isolationValues[j]);
0492 }
0493
0494 IsolationValueMaps isolationValuesNoPFId(isolationValueNoPFIdTokens_.size());
0495 for (size_t j = 0; j < isolationValueNoPFIdTokens_.size(); ++j) {
0496 iEvent.getByToken(isolationValueNoPFIdTokens_[j], isolationValuesNoPFId[j]);
0497 }
0498
0499
0500 GenAssociations genMatches(genMatchTokens_.size());
0501 if (addGenMatch_) {
0502 for (size_t j = 0, nd = genMatchTokens_.size(); j < nd; ++j) {
0503 iEvent.getByToken(genMatchTokens_[j], genMatches[j]);
0504 }
0505 }
0506
0507
0508 std::vector<edm::Handle<edm::ValueMap<float>>> idhandles;
0509 std::vector<pat::Electron::IdPair> ids;
0510 if (addElecID_) {
0511 idhandles.resize(elecIDSrcs_.size());
0512 ids.resize(elecIDSrcs_.size());
0513 for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
0514 iEvent.getByToken(elecIDTokens_[i], idhandles[i]);
0515 ids[i].first = elecIDSrcs_[i].first;
0516 }
0517 }
0518
0519
0520
0521 reco::TrackBase::Point beamPoint(0, 0, 0);
0522 reco::Vertex primaryVertex;
0523 reco::BeamSpot beamSpot;
0524 bool beamSpotIsValid = false;
0525 bool primaryVertexIsValid = false;
0526
0527
0528 edm::Handle<reco::BeamSpot> beamSpotHandle;
0529 iEvent.getByToken(beamLineToken_, beamSpotHandle);
0530
0531 if (embedHighLevelSelection_) {
0532
0533 edm::Handle<std::vector<reco::Vertex>> pvHandle;
0534 iEvent.getByToken(pvToken_, pvHandle);
0535
0536
0537 trackBuilder = iSetup.getHandle(trackBuilderToken_);
0538
0539 if (beamSpotHandle.isValid()) {
0540 beamSpot = *beamSpotHandle;
0541 beamSpotIsValid = true;
0542 } else {
0543 edm::LogError("DataNotAvailable") << "No beam spot available from EventSetup, not adding high level selection \n";
0544 }
0545
0546 if (pvHandle.isValid() && !pvHandle->empty()) {
0547 primaryVertex = pvHandle->at(0);
0548 primaryVertexIsValid = true;
0549 } else {
0550 edm::LogError("DataNotAvailable")
0551 << "No primary vertex available from EventSetup, not adding high level selection \n";
0552 }
0553 }
0554
0555 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_charged_hadrons;
0556 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_neutral_hadrons;
0557 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_photons;
0558
0559 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_charged_hadrons;
0560 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_neutral_hadrons;
0561 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_photons;
0562 if (addPuppiIsolation_) {
0563
0564 iEvent.getByToken(PUPPIIsolation_charged_hadrons_, PUPPIIsolation_charged_hadrons);
0565 iEvent.getByToken(PUPPIIsolation_neutral_hadrons_, PUPPIIsolation_neutral_hadrons);
0566 iEvent.getByToken(PUPPIIsolation_photons_, PUPPIIsolation_photons);
0567
0568 iEvent.getByToken(PUPPINoLeptonsIsolation_charged_hadrons_, PUPPINoLeptonsIsolation_charged_hadrons);
0569 iEvent.getByToken(PUPPINoLeptonsIsolation_neutral_hadrons_, PUPPINoLeptonsIsolation_neutral_hadrons);
0570 iEvent.getByToken(PUPPINoLeptonsIsolation_photons_, PUPPINoLeptonsIsolation_photons);
0571 }
0572
0573 std::vector<Electron>* patElectrons = new std::vector<Electron>();
0574
0575 if (useParticleFlow_) {
0576 edm::Handle<reco::PFCandidateCollection> pfElectrons;
0577 iEvent.getByToken(pfElecToken_, pfElectrons);
0578 unsigned index = 0;
0579
0580 for (reco::PFCandidateConstIterator i = pfElectrons->begin(); i != pfElectrons->end(); ++i, ++index) {
0581 reco::PFCandidateRef pfRef(pfElectrons, index);
0582 reco::PFCandidatePtr ptrToPFElectron(pfElectrons, index);
0583
0584
0585 reco::GsfTrackRef PfTk = i->gsfTrackRef();
0586
0587 bool Matched = false;
0588 bool MatchedToAmbiguousGsfTrack = false;
0589 for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end();
0590 ++itElectron) {
0591 unsigned int idx = itElectron - electrons->begin();
0592 auto elePtr = electrons->ptrAt(idx);
0593 if (Matched || MatchedToAmbiguousGsfTrack)
0594 continue;
0595
0596 reco::GsfTrackRef EgTk = itElectron->gsfTrack();
0597
0598 if (itElectron->gsfTrack() == i->gsfTrackRef()) {
0599 Matched = true;
0600 } else {
0601 for (auto const& it : itElectron->ambiguousGsfTracks()) {
0602 MatchedToAmbiguousGsfTrack |= (bool)(i->gsfTrackRef() == it);
0603 }
0604 }
0605
0606 if (Matched || MatchedToAmbiguousGsfTrack) {
0607
0608 reco::CandidatePtr ptrToGsfElectron(electrons, idx);
0609
0610
0611 const edm::RefToBase<reco::GsfElectron>& elecsRef = electrons->refAt(idx);
0612 Electron anElectron(elecsRef);
0613 anElectron.setPFCandidateRef(pfRef);
0614 if (addPuppiIsolation_) {
0615 anElectron.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[elePtr],
0616 (*PUPPIIsolation_neutral_hadrons)[elePtr],
0617 (*PUPPIIsolation_photons)[elePtr]);
0618 anElectron.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[elePtr],
0619 (*PUPPINoLeptonsIsolation_neutral_hadrons)[elePtr],
0620 (*PUPPINoLeptonsIsolation_photons)[elePtr]);
0621 } else {
0622 anElectron.setIsolationPUPPI(-999., -999., -999.);
0623 anElectron.setIsolationPUPPINoLeptons(-999., -999., -999.);
0624 }
0625
0626
0627 anElectron.setIsPF(true);
0628
0629 if (embedPFCandidate_)
0630 anElectron.embedPFCandidate();
0631
0632 if (useUserData_) {
0633 userDataHelper_.add(anElectron, iEvent, iSetup);
0634 }
0635
0636 double ip3d = -999;
0637
0638
0639 if (embedHighLevelSelection_) {
0640
0641 const reco::GsfTrackRef& track = PfTk;
0642
0643
0644 if (track.isNonnull() && track.isAvailable()) {
0645 reco::TransientTrack tt = trackBuilder->build(track);
0646 embedHighLevel(anElectron, track, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
0647
0648 std::pair<bool, Measurement1D> ip3dpv = IPTools::absoluteImpactParameter3D(tt, primaryVertex);
0649 ip3d = ip3dpv.second.value();
0650 }
0651 }
0652
0653
0654
0655 if (addElecID_) {
0656
0657 for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
0658 ids[i].second = (*idhandles[i])[elecsRef];
0659 }
0660
0661 ids.push_back(std::make_pair("pf_evspi", pfRef->mva_e_pi()));
0662 ids.push_back(std::make_pair("pf_evsmu", pfRef->mva_e_mu()));
0663 anElectron.setElectronIDs(ids);
0664 }
0665
0666 if (addMVAVariables_) {
0667
0668 const auto& vCov = lazyTools.localCovariances(*(itElectron->superCluster()->seed()));
0669 anElectron.setMvaVariables(vCov[1], ip3d);
0670 }
0671
0672 if (addPFClusterIso_) {
0673
0674 edm::Handle<edm::ValueMap<float>> ecalPFClusterIsoMapH;
0675 iEvent.getByToken(ecalPFClusterIsoT_, ecalPFClusterIsoMapH);
0676 edm::Handle<edm::ValueMap<float>> hcalPFClusterIsoMapH;
0677 iEvent.getByToken(hcalPFClusterIsoT_, hcalPFClusterIsoMapH);
0678 reco::GsfElectron::PflowIsolationVariables newPFIsol = anElectron.pfIsolationVariables();
0679 newPFIsol.sumEcalClusterEt = (*ecalPFClusterIsoMapH)[elecsRef];
0680 newPFIsol.sumHcalClusterEt = (*hcalPFClusterIsoMapH)[elecsRef];
0681 anElectron.setPfIsolationVariables(newPFIsol);
0682 }
0683
0684 std::vector<DetId> selectedCells;
0685 bool barrel = itElectron->isEB();
0686
0687 if (embedBasicClusters_) {
0688 for (reco::CaloCluster_iterator clusIt = itElectron->superCluster()->clustersBegin();
0689 clusIt != itElectron->superCluster()->clustersEnd();
0690 ++clusIt) {
0691
0692 DetId seed = lazyTools.getMaximum(**clusIt).first;
0693
0694 std::vector<DetId> dets5x5 =
0695 (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalBarrel)->getWindow(seed, 5, 5)
0696 : ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalEndcap)->getWindow(seed, 5, 5);
0697 selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
0698
0699
0700 for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
0701 selectedCells.push_back(hit.first);
0702 }
0703 }
0704 }
0705
0706 if (embedPflowBasicClusters_ && itElectron->parentSuperCluster().isNonnull()) {
0707 for (reco::CaloCluster_iterator clusIt = itElectron->parentSuperCluster()->clustersBegin();
0708 clusIt != itElectron->parentSuperCluster()->clustersEnd();
0709 ++clusIt) {
0710
0711 DetId seed = lazyTools.getMaximum(**clusIt).first;
0712
0713 std::vector<DetId> dets5x5 =
0714 (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalBarrel)->getWindow(seed, 5, 5)
0715 : ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalEndcap)->getWindow(seed, 5, 5);
0716 selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
0717
0718
0719 for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
0720 selectedCells.push_back(hit.first);
0721 }
0722 }
0723 }
0724
0725
0726 std::sort(selectedCells.begin(), selectedCells.end());
0727 auto last = std::unique(selectedCells.begin(), selectedCells.end());
0728 selectedCells.erase(last, selectedCells.end());
0729
0730
0731
0732 edm::Handle<EcalRecHitCollection> rechitsH;
0733 if (barrel)
0734 iEvent.getByToken(reducedBarrelRecHitCollectionToken_, rechitsH);
0735 else
0736 iEvent.getByToken(reducedEndcapRecHitCollectionToken_, rechitsH);
0737
0738 EcalRecHitCollection selectedRecHits;
0739 const EcalRecHitCollection* recHits = rechitsH.product();
0740
0741 unsigned nSelectedCells = selectedCells.size();
0742 for (unsigned icell = 0; icell < nSelectedCells; ++icell) {
0743 EcalRecHitCollection::const_iterator it = recHits->find(selectedCells[icell]);
0744 if (it != recHits->end()) {
0745 selectedRecHits.push_back(*it);
0746 }
0747 }
0748 selectedRecHits.sort();
0749 if (embedRecHits_)
0750 anElectron.embedRecHits(&selectedRecHits);
0751
0752
0753 bool passconversionveto = false;
0754 if (hConversions.isValid()) {
0755
0756 passconversionveto =
0757 !ConversionTools::hasMatchedConversion(*itElectron, *hConversions, beamSpotHandle->position());
0758 } else {
0759
0760 passconversionveto =
0761 itElectron->gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) < 1;
0762 }
0763
0764 anElectron.setPassConversionVeto(passconversionveto);
0765
0766
0767
0768
0769
0770
0771
0772
0773
0774
0775
0776
0777 fillElectron2(
0778 anElectron, ptrToPFElectron, ptrToGsfElectron, ptrToGsfElectron, genMatches, deposits, isolationValues);
0779
0780
0781
0782 if (computeMiniIso_)
0783 setElectronMiniIso(anElectron, pc.product());
0784
0785 patElectrons->push_back(anElectron);
0786 }
0787 }
0788
0789 }
0790 }
0791
0792 else {
0793 edm::Handle<reco::PFCandidateCollection> pfElectrons;
0794 edm::Handle<edm::ValueMap<reco::PFCandidatePtr>> ValMapH;
0795 edm::Handle<edm::ValueMap<std::vector<reco::PFCandidateRef>>> ValMultiMapH;
0796 bool pfCandsPresent = false, valMapPresent = false;
0797 if (usePfCandidateMultiMap_) {
0798 iEvent.getByToken(pfCandidateMultiMapToken_, ValMultiMapH);
0799 } else {
0800 pfCandsPresent = iEvent.getByToken(pfElecToken_, pfElectrons);
0801 valMapPresent = iEvent.getByToken(pfCandidateMapToken_, ValMapH);
0802 }
0803
0804 for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end();
0805 ++itElectron) {
0806
0807
0808 unsigned int idx = itElectron - electrons->begin();
0809 edm::RefToBase<reco::GsfElectron> elecsRef = electrons->refAt(idx);
0810 reco::CandidateBaseRef elecBaseRef(elecsRef);
0811 Electron anElectron(elecsRef);
0812 auto elePtr = electrons->ptrAt(idx);
0813
0814
0815 bool pfId = false;
0816
0817 if (usePfCandidateMultiMap_) {
0818 for (const reco::PFCandidateRef& pf : (*ValMultiMapH)[elePtr]) {
0819 if (pf->particleId() == reco::PFCandidate::e) {
0820 pfId = true;
0821 anElectron.setPFCandidateRef(pf);
0822 break;
0823 }
0824 }
0825 } else if (pfCandsPresent) {
0826
0827 const reco::GsfTrackRef& trkRef = itElectron->gsfTrack();
0828 int index = 0;
0829 for (reco::PFCandidateConstIterator ie = pfElectrons->begin(); ie != pfElectrons->end(); ++ie, ++index) {
0830 if (ie->particleId() != reco::PFCandidate::e)
0831 continue;
0832 const reco::GsfTrackRef& pfTrkRef = ie->gsfTrackRef();
0833 if (trkRef == pfTrkRef) {
0834 pfId = true;
0835 reco::PFCandidateRef pfRef(pfElectrons, index);
0836 anElectron.setPFCandidateRef(pfRef);
0837 break;
0838 }
0839 }
0840 } else if (valMapPresent) {
0841
0842 const edm::ValueMap<reco::PFCandidatePtr>& myValMap(*ValMapH);
0843
0844 const reco::PFCandidatePtr& pfElePtr(myValMap[elecsRef]);
0845 pfId = pfElePtr.isNonnull();
0846 }
0847
0848 anElectron.setIsPF(pfId);
0849
0850
0851
0852
0853 if (isolator_.enabled()) {
0854 isolator_.fill(*electrons, idx, isolatorTmpStorage_);
0855 typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
0856
0857 for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(),
0858 ed = isolatorTmpStorage_.rend();
0859 it != ed;
0860 ++it) {
0861 anElectron.setIsolation(it->first, it->second);
0862 }
0863 }
0864
0865 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
0866 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[elecsRef]);
0867 }
0868
0869
0870 if (addElecID_) {
0871 for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
0872 ids[i].second = (*idhandles[i])[elecsRef];
0873 }
0874 anElectron.setElectronIDs(ids);
0875 }
0876
0877 if (useUserData_) {
0878 userDataHelper_.add(anElectron, iEvent, iSetup);
0879 }
0880
0881 double ip3d = -999;
0882
0883
0884 if (embedHighLevelSelection_) {
0885
0886 reco::GsfTrackRef track = itElectron->gsfTrack();
0887
0888
0889 if (track.isNonnull() && track.isAvailable()) {
0890 reco::TransientTrack tt = trackBuilder->build(track);
0891 embedHighLevel(anElectron, track, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
0892
0893 std::pair<bool, Measurement1D> ip3dpv = IPTools::absoluteImpactParameter3D(tt, primaryVertex);
0894 ip3d = ip3dpv.second.value();
0895 }
0896 }
0897
0898 if (addMVAVariables_) {
0899
0900 const auto& vCov = lazyTools.localCovariances(*(itElectron->superCluster()->seed()));
0901 anElectron.setMvaVariables(vCov[1], ip3d);
0902 }
0903
0904
0905 if (addPFClusterIso_) {
0906
0907 edm::Handle<edm::ValueMap<float>> ecalPFClusterIsoMapH;
0908 iEvent.getByToken(ecalPFClusterIsoT_, ecalPFClusterIsoMapH);
0909 edm::Handle<edm::ValueMap<float>> hcalPFClusterIsoMapH;
0910 iEvent.getByToken(hcalPFClusterIsoT_, hcalPFClusterIsoMapH);
0911 reco::GsfElectron::PflowIsolationVariables newPFIsol = anElectron.pfIsolationVariables();
0912 newPFIsol.sumEcalClusterEt = (*ecalPFClusterIsoMapH)[elecsRef];
0913 newPFIsol.sumHcalClusterEt = (*hcalPFClusterIsoMapH)[elecsRef];
0914 anElectron.setPfIsolationVariables(newPFIsol);
0915 }
0916
0917 if (addPuppiIsolation_) {
0918 anElectron.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[elePtr],
0919 (*PUPPIIsolation_neutral_hadrons)[elePtr],
0920 (*PUPPIIsolation_photons)[elePtr]);
0921 anElectron.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[elePtr],
0922 (*PUPPINoLeptonsIsolation_neutral_hadrons)[elePtr],
0923 (*PUPPINoLeptonsIsolation_photons)[elePtr]);
0924 } else {
0925 anElectron.setIsolationPUPPI(-999., -999., -999.);
0926 anElectron.setIsolationPUPPINoLeptons(-999., -999., -999.);
0927 }
0928
0929 std::vector<DetId> selectedCells;
0930 bool barrel = itElectron->isEB();
0931
0932 if (embedBasicClusters_) {
0933 for (reco::CaloCluster_iterator clusIt = itElectron->superCluster()->clustersBegin();
0934 clusIt != itElectron->superCluster()->clustersEnd();
0935 ++clusIt) {
0936
0937 DetId seed = lazyTools.getMaximum(**clusIt).first;
0938
0939 std::vector<DetId> dets5x5 =
0940 (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalBarrel)->getWindow(seed, 5, 5)
0941 : ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalEndcap)->getWindow(seed, 5, 5);
0942 selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
0943
0944
0945 for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
0946 selectedCells.push_back(hit.first);
0947 }
0948 }
0949 }
0950
0951 if (embedPflowBasicClusters_ && itElectron->parentSuperCluster().isNonnull()) {
0952 for (reco::CaloCluster_iterator clusIt = itElectron->parentSuperCluster()->clustersBegin();
0953 clusIt != itElectron->parentSuperCluster()->clustersEnd();
0954 ++clusIt) {
0955
0956 DetId seed = lazyTools.getMaximum(**clusIt).first;
0957
0958 std::vector<DetId> dets5x5 =
0959 (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalBarrel)->getWindow(seed, 5, 5)
0960 : ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalEndcap)->getWindow(seed, 5, 5);
0961 selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
0962
0963
0964 for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
0965 selectedCells.push_back(hit.first);
0966 }
0967 }
0968 }
0969
0970
0971 std::sort(selectedCells.begin(), selectedCells.end());
0972 auto last = std::unique(selectedCells.begin(), selectedCells.end());
0973 selectedCells.erase(last, selectedCells.end());
0974
0975
0976
0977 edm::Handle<EcalRecHitCollection> rechitsH;
0978 if (barrel)
0979 iEvent.getByToken(reducedBarrelRecHitCollectionToken_, rechitsH);
0980 else
0981 iEvent.getByToken(reducedEndcapRecHitCollectionToken_, rechitsH);
0982
0983 EcalRecHitCollection selectedRecHits;
0984 const EcalRecHitCollection* recHits = rechitsH.product();
0985
0986 unsigned nSelectedCells = selectedCells.size();
0987 for (unsigned icell = 0; icell < nSelectedCells; ++icell) {
0988 EcalRecHitCollection::const_iterator it = recHits->find(selectedCells[icell]);
0989 if (it != recHits->end()) {
0990 selectedRecHits.push_back(*it);
0991 }
0992 }
0993 selectedRecHits.sort();
0994 if (embedRecHits_)
0995 anElectron.embedRecHits(&selectedRecHits);
0996
0997
0998 bool passconversionveto = false;
0999 if (hConversions.isValid()) {
1000
1001 passconversionveto =
1002 !ConversionTools::hasMatchedConversion(*itElectron, *hConversions, beamSpotHandle->position());
1003 } else {
1004
1005 passconversionveto =
1006 itElectron->gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) < 1;
1007 }
1008 anElectron.setPassConversionVeto(passconversionveto);
1009
1010
1011 fillElectron(
1012 anElectron, elecsRef, elecBaseRef, genMatches, deposits, pfId, isolationValues, isolationValuesNoPFId);
1013
1014 if (computeMiniIso_)
1015 setElectronMiniIso(anElectron, pc.product());
1016
1017 patElectrons->push_back(anElectron);
1018 }
1019 }
1020
1021
1022 std::sort(patElectrons->begin(), patElectrons->end(), pTComparator_);
1023
1024
1025 std::unique_ptr<std::vector<Electron>> ptr(patElectrons);
1026 iEvent.put(std::move(ptr));
1027
1028
1029 if (isolator_.enabled())
1030 isolator_.endEvent();
1031 }
1032
1033 void PATElectronProducer::fillElectron(Electron& anElectron,
1034 const edm::RefToBase<reco::GsfElectron>& elecRef,
1035 const reco::CandidateBaseRef& baseRef,
1036 const GenAssociations& genMatches,
1037 const IsoDepositMaps& deposits,
1038 const bool pfId,
1039 const IsolationValueMaps& isolationValues,
1040 const IsolationValueMaps& isolationValuesNoPFId) const {
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058 if (embedGsfElectronCore_)
1059 anElectron.embedGsfElectronCore();
1060 if (embedGsfTrack_)
1061 anElectron.embedGsfTrack();
1062 if (embedSuperCluster_)
1063 anElectron.embedSuperCluster();
1064 if (embedPflowSuperCluster_)
1065 anElectron.embedPflowSuperCluster();
1066 if (embedSeedCluster_)
1067 anElectron.embedSeedCluster();
1068 if (embedBasicClusters_)
1069 anElectron.embedBasicClusters();
1070 if (embedPreshowerClusters_)
1071 anElectron.embedPreshowerClusters();
1072 if (embedPflowBasicClusters_)
1073 anElectron.embedPflowBasicClusters();
1074 if (embedPflowPreshowerClusters_)
1075 anElectron.embedPflowPreshowerClusters();
1076 if (embedTrack_)
1077 anElectron.embedTrack();
1078
1079
1080 if (addGenMatch_) {
1081 for (size_t i = 0, n = genMatches.size(); i < n; ++i) {
1082 if (useParticleFlow_) {
1083 reco::GenParticleRef genElectron = (*genMatches[i])[anElectron.pfCandidateRef()];
1084 anElectron.addGenParticleRef(genElectron);
1085 } else {
1086 reco::GenParticleRef genElectron = (*genMatches[i])[elecRef];
1087 anElectron.addGenParticleRef(genElectron);
1088 }
1089 }
1090 if (embedGenMatch_)
1091 anElectron.embedGenParticle();
1092 }
1093
1094 if (efficiencyLoader_.enabled()) {
1095 efficiencyLoader_.setEfficiencies(anElectron, elecRef);
1096 }
1097
1098 if (resolutionLoader_.enabled()) {
1099 resolutionLoader_.setResolutions(anElectron);
1100 }
1101
1102 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
1103 if (useParticleFlow_) {
1104 reco::PFCandidateRef pfcandref = anElectron.pfCandidateRef();
1105 assert(!pfcandref.isNull());
1106 reco::CandidatePtr source = pfcandref->sourceCandidatePtr(0);
1107 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[source]);
1108 } else
1109 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[elecRef]);
1110 }
1111
1112 for (size_t j = 0; j < isolationValues.size(); ++j) {
1113 if (useParticleFlow_) {
1114 reco::CandidatePtr source = anElectron.pfCandidateRef()->sourceCandidatePtr(0);
1115 anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[source]);
1116 } else if (pfId) {
1117 anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[elecRef]);
1118 }
1119 }
1120
1121
1122 for (size_t j = 0; j < isolationValuesNoPFId.size(); ++j) {
1123 if (!pfId) {
1124 anElectron.setIsolation(isolationValueLabelsNoPFId_[j].first, (*isolationValuesNoPFId[j])[elecRef]);
1125 }
1126 }
1127 }
1128
1129 void PATElectronProducer::fillElectron2(Electron& anElectron,
1130 const reco::CandidatePtr& candPtrForIsolation,
1131 const reco::CandidatePtr& candPtrForGenMatch,
1132 const reco::CandidatePtr& candPtrForLoader,
1133 const GenAssociations& genMatches,
1134 const IsoDepositMaps& deposits,
1135 const IsolationValueMaps& isolationValues) const {
1136
1137 anElectron.setEcalDrivenMomentum(anElectron.p4());
1138 anElectron.setP4(anElectron.pfCandidateRef()->p4());
1139
1140
1141
1142
1143 if (embedGsfElectronCore_)
1144 anElectron.embedGsfElectronCore();
1145 if (embedGsfTrack_)
1146 anElectron.embedGsfTrack();
1147 if (embedSuperCluster_)
1148 anElectron.embedSuperCluster();
1149 if (embedPflowSuperCluster_)
1150 anElectron.embedPflowSuperCluster();
1151 if (embedSeedCluster_)
1152 anElectron.embedSeedCluster();
1153 if (embedBasicClusters_)
1154 anElectron.embedBasicClusters();
1155 if (embedPreshowerClusters_)
1156 anElectron.embedPreshowerClusters();
1157 if (embedPflowBasicClusters_)
1158 anElectron.embedPflowBasicClusters();
1159 if (embedPflowPreshowerClusters_)
1160 anElectron.embedPflowPreshowerClusters();
1161 if (embedTrack_)
1162 anElectron.embedTrack();
1163
1164
1165
1166 if (addGenMatch_) {
1167 for (size_t i = 0, n = genMatches.size(); i < n; ++i) {
1168 reco::GenParticleRef genElectron = (*genMatches[i])[candPtrForGenMatch];
1169 anElectron.addGenParticleRef(genElectron);
1170 }
1171 if (embedGenMatch_)
1172 anElectron.embedGenParticle();
1173 }
1174
1175
1176 if (efficiencyLoader_.enabled()) {
1177 efficiencyLoader_.setEfficiencies(anElectron, candPtrForLoader);
1178 }
1179
1180 if (resolutionLoader_.enabled()) {
1181 resolutionLoader_.setResolutions(anElectron);
1182 }
1183
1184 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
1185 if (isoDepositLabels_[j].first == pat::TrackIso || isoDepositLabels_[j].first == pat::EcalIso ||
1186 isoDepositLabels_[j].first == pat::HcalIso || deposits[j]->contains(candPtrForGenMatch.id())) {
1187 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForGenMatch]);
1188 } else if (deposits[j]->contains(candPtrForIsolation.id())) {
1189 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForIsolation]);
1190 } else {
1191 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
1192 }
1193 }
1194
1195 for (size_t j = 0; j < isolationValues.size(); ++j) {
1196 if (isolationValueLabels_[j].first == pat::TrackIso || isolationValueLabels_[j].first == pat::EcalIso ||
1197 isolationValueLabels_[j].first == pat::HcalIso || isolationValues[j]->contains(candPtrForGenMatch.id())) {
1198 anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[candPtrForGenMatch]);
1199 } else if (isolationValues[j]->contains(candPtrForIsolation.id())) {
1200 anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[candPtrForIsolation]);
1201 } else {
1202 anElectron.setIsolation(isolationValueLabels_[j].first,
1203 (*isolationValues[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
1204 }
1205 }
1206 }
1207
1208 void PATElectronProducer::setElectronMiniIso(Electron& anElectron, const PackedCandidateCollection* pc) {
1209 pat::PFIsolation miniiso;
1210 if (anElectron.isEE())
1211 miniiso = pat::getMiniPFIsolation(pc,
1212 anElectron.polarP4(),
1213 miniIsoParamsE_[0],
1214 miniIsoParamsE_[1],
1215 miniIsoParamsE_[2],
1216 miniIsoParamsE_[3],
1217 miniIsoParamsE_[4],
1218 miniIsoParamsE_[5],
1219 miniIsoParamsE_[6],
1220 miniIsoParamsE_[7],
1221 miniIsoParamsE_[8]);
1222 else
1223 miniiso = pat::getMiniPFIsolation(pc,
1224 anElectron.polarP4(),
1225 miniIsoParamsB_[0],
1226 miniIsoParamsB_[1],
1227 miniIsoParamsB_[2],
1228 miniIsoParamsB_[3],
1229 miniIsoParamsB_[4],
1230 miniIsoParamsB_[5],
1231 miniIsoParamsB_[6],
1232 miniIsoParamsB_[7],
1233 miniIsoParamsB_[8]);
1234 anElectron.setMiniPFIsolation(miniiso);
1235 }
1236
1237
1238 void PATElectronProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
1239 edm::ParameterSetDescription iDesc;
1240 iDesc.setComment("PAT electron producer module");
1241
1242
1243 iDesc.add<edm::InputTag>("pfCandidateMap", edm::InputTag("no default"))->setComment("input collection");
1244 iDesc.add<edm::InputTag>("electronSource", edm::InputTag("no default"))->setComment("input collection");
1245
1246 iDesc.ifValue(
1247 edm::ParameterDescription<bool>("addPFClusterIso", false, true),
1248 true >> (edm::ParameterDescription<edm::InputTag>(
1249 "ecalPFClusterIsoMap", edm::InputTag("electronEcalPFClusterIsolationProducer"), true) and
1250 edm::ParameterDescription<edm::InputTag>(
1251 "hcalPFClusterIsoMap", edm::InputTag("electronHcalPFClusterIsolationProducer"), true)) or
1252 false >> (edm::ParameterDescription<edm::InputTag>("ecalPFClusterIsoMap", edm::InputTag(""), true) and
1253 edm::ParameterDescription<edm::InputTag>("hcalPFClusterIsoMap", edm::InputTag(""), true)));
1254
1255 iDesc.ifValue(edm::ParameterDescription<bool>("addPuppiIsolation", false, true),
1256 true >> (edm::ParameterDescription<edm::InputTag>(
1257 "puppiIsolationChargedHadrons",
1258 edm::InputTag("egmElectronPUPPIIsolation", "h+-DR030-BarVeto000-EndVeto001"),
1259 true) and
1260 edm::ParameterDescription<edm::InputTag>(
1261 "puppiIsolationNeutralHadrons",
1262 edm::InputTag("egmElectronPUPPIIsolation", "h0-DR030-BarVeto000-EndVeto000"),
1263 true) and
1264 edm::ParameterDescription<edm::InputTag>(
1265 "puppiIsolationPhotons",
1266 edm::InputTag("egmElectronPUPPIIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1267 true) and
1268 edm::ParameterDescription<edm::InputTag>(
1269 "puppiNoLeptonsIsolationChargedHadrons",
1270 edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1271 true) and
1272 edm::ParameterDescription<edm::InputTag>(
1273 "puppiNoLeptonsIsolationNeutralHadrons",
1274 edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1275 true) and
1276 edm::ParameterDescription<edm::InputTag>(
1277 "puppiNoLeptonsIsolationPhotons",
1278 edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1279 true)) or
1280 false >> edm::EmptyGroupDescription());
1281
1282
1283 iDesc.add<bool>("embedGsfElectronCore", true)->setComment("embed external gsf electron core");
1284 iDesc.add<bool>("embedGsfTrack", true)->setComment("embed external gsf track");
1285 iDesc.add<bool>("embedSuperCluster", true)->setComment("embed external super cluster");
1286 iDesc.add<bool>("embedPflowSuperCluster", true)->setComment("embed external super cluster");
1287 iDesc.add<bool>("embedSeedCluster", true)->setComment("embed external seed cluster");
1288 iDesc.add<bool>("embedBasicClusters", true)->setComment("embed external basic clusters");
1289 iDesc.add<bool>("embedPreshowerClusters", true)->setComment("embed external preshower clusters");
1290 iDesc.add<bool>("embedPflowBasicClusters", true)->setComment("embed external pflow basic clusters");
1291 iDesc.add<bool>("embedPflowPreshowerClusters", true)->setComment("embed external pflow preshower clusters");
1292 iDesc.add<bool>("embedTrack", false)->setComment("embed external track");
1293 iDesc.add<bool>("embedRecHits", true)->setComment("embed external RecHits");
1294
1295
1296 iDesc.add<edm::InputTag>("pfElectronSource", edm::InputTag("pfElectrons"))
1297 ->setComment("particle flow input collection");
1298 auto&& usePfCandidateMultiMap = edm::ParameterDescription<bool>("usePfCandidateMultiMap", false, true);
1299 usePfCandidateMultiMap.setComment(
1300 "take ParticleFlow candidates from pfCandidateMultiMap instead of matching to pfElectrons by Gsf track "
1301 "reference");
1302 iDesc.ifValue(usePfCandidateMultiMap,
1303 true >> edm::ParameterDescription<edm::InputTag>("pfCandidateMultiMap", true) or
1304 false >> edm::EmptyGroupDescription());
1305 iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
1306 iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
1307
1308
1309 iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
1310 iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
1311 std::vector<edm::InputTag> emptySourceVector;
1312 iDesc
1313 .addNode(edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
1314 edm::ParameterDescription<std::vector<edm::InputTag>>("genParticleMatch", emptySourceVector, true))
1315 ->setComment("input with MC match information");
1316
1317
1318 iDesc.add<bool>("addElectronID", true)->setComment("add electron ID variables");
1319 edm::ParameterSetDescription electronIDSourcesPSet;
1320 electronIDSourcesPSet.setAllowAnything();
1321 iDesc
1322 .addNode(
1323 edm::ParameterDescription<edm::InputTag>("electronIDSource", edm::InputTag(), true) xor
1324 edm::ParameterDescription<edm::ParameterSetDescription>("electronIDSources", electronIDSourcesPSet, true))
1325 ->setComment("input with electron ID variables");
1326
1327
1328 iDesc.add<bool>("computeMiniIso", false)->setComment("whether or not to compute and store electron mini-isolation");
1329 iDesc.add<edm::InputTag>("pfCandsForMiniIso", edm::InputTag("packedPFCandidates"))
1330 ->setComment("collection to use to compute mini-iso");
1331 iDesc.add<std::vector<double>>("miniIsoParamsE", std::vector<double>())
1332 ->setComment("mini-iso parameters to use for endcap electrons");
1333 iDesc.add<std::vector<double>>("miniIsoParamsB", std::vector<double>())
1334 ->setComment("mini-iso parameters to use for barrel electrons");
1335
1336
1337 edm::ParameterSetDescription isoDepositsPSet;
1338 isoDepositsPSet.addOptional<edm::InputTag>("tracker");
1339 isoDepositsPSet.addOptional<edm::InputTag>("ecal");
1340 isoDepositsPSet.addOptional<edm::InputTag>("hcal");
1341 isoDepositsPSet.addOptional<edm::InputTag>("pfAllParticles");
1342 isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1343 isoDepositsPSet.addOptional<edm::InputTag>("pfChargedAll");
1344 isoDepositsPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1345 isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1346 isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
1347 isoDepositsPSet.addOptional<std::vector<edm::InputTag>>("user");
1348 iDesc.addOptional("isoDeposits", isoDepositsPSet);
1349
1350
1351 edm::ParameterSetDescription isolationValuesPSet;
1352 isolationValuesPSet.addOptional<edm::InputTag>("tracker");
1353 isolationValuesPSet.addOptional<edm::InputTag>("ecal");
1354 isolationValuesPSet.addOptional<edm::InputTag>("hcal");
1355 isolationValuesPSet.addOptional<edm::InputTag>("pfAllParticles");
1356 isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1357 isolationValuesPSet.addOptional<edm::InputTag>("pfChargedAll");
1358 isolationValuesPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1359 isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1360 isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
1361 isolationValuesPSet.addOptional<std::vector<edm::InputTag>>("user");
1362 iDesc.addOptional("isolationValues", isolationValuesPSet);
1363
1364
1365 edm::ParameterSetDescription isolationValuesNoPFIdPSet;
1366 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("tracker");
1367 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("ecal");
1368 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("hcal");
1369 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfAllParticles");
1370 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1371 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfChargedAll");
1372 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1373 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1374 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfPhotons");
1375 isolationValuesNoPFIdPSet.addOptional<std::vector<edm::InputTag>>("user");
1376 iDesc.addOptional("isolationValuesNoPFId", isolationValuesNoPFIdPSet);
1377
1378
1379 edm::ParameterSetDescription efficienciesPSet;
1380 efficienciesPSet.setAllowAnything();
1381 iDesc.add("efficiencies", efficienciesPSet);
1382 iDesc.add<bool>("addEfficiencies", false);
1383
1384
1385 edm::ParameterSetDescription userDataPSet;
1386 PATUserDataHelper<Electron>::fillDescription(userDataPSet);
1387 iDesc.addOptional("userData", userDataPSet);
1388
1389
1390 iDesc.add<bool>("addMVAVariables", true)->setComment("embed extra variables in pat::Electron : sip3d, sigmaIEtaIPhi");
1391 iDesc.add<edm::InputTag>("reducedBarrelRecHitCollection", edm::InputTag("reducedEcalRecHitsEB"));
1392 iDesc.add<edm::InputTag>("reducedEndcapRecHitCollection", edm::InputTag("reducedEcalRecHitsEE"));
1393
1394 edm::ParameterSetDescription isolationPSet;
1395 isolationPSet.setAllowAnything();
1396 iDesc.add("userIsolation", isolationPSet);
1397
1398
1399 pat::helper::KinResolutionsLoader::fillDescription(iDesc);
1400
1401 iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
1402 edm::ParameterSetDescription highLevelPSet;
1403 highLevelPSet.setAllowAnything();
1404 iDesc.addNode(edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true))
1405 ->setComment("input with high level selection");
1406 iDesc.addNode(edm::ParameterDescription<edm::InputTag>("pvSrc", edm::InputTag(), true))
1407 ->setComment("input with high level selection");
1408
1409 descriptions.add("PATElectronProducer", iDesc);
1410 }
1411
1412
1413
1414 void PATElectronProducer::embedHighLevel(pat::Electron& anElectron,
1415 reco::GsfTrackRef track,
1416 reco::TransientTrack& tt,
1417 reco::Vertex& primaryVertex,
1418 bool primaryVertexIsValid,
1419 reco::BeamSpot& beamspot,
1420 bool beamspotIsValid) {
1421
1422
1423 anElectron.setDB(track->dxy(primaryVertex.position()),
1424 track->dxyError(primaryVertex.position(), primaryVertex.covariance()),
1425 pat::Electron::PV2D);
1426
1427
1428 std::pair<bool, Measurement1D> result =
1429 IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex);
1430 double d0_corr = result.second.value();
1431 double d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
1432 anElectron.setDB(d0_corr, d0_err, pat::Electron::PV3D);
1433
1434
1435
1436 anElectron.setDB(track->dxy(beamspot), track->dxyError(beamspot), pat::Electron::BS2D);
1437
1438
1439 reco::Vertex vBeamspot(beamspot.position(), beamspot.covariance3D());
1440
1441
1442 result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot);
1443 d0_corr = result.second.value();
1444 d0_err = beamspotIsValid ? result.second.error() : -1.0;
1445 anElectron.setDB(d0_corr, d0_err, pat::Electron::BS3D);
1446
1447
1448 anElectron.setDB(
1449 track->dz(primaryVertex.position()), std::hypot(track->dzError(), primaryVertex.zError()), pat::Electron::PVDZ);
1450 }
1451
1452 #include "FWCore/Framework/interface/MakerMacros.h"
1453 DEFINE_FWK_MODULE(PATElectronProducer);