File indexing completed on 2023-10-25 09:58:11
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 (pvHandle.isValid() && !pvHandle->empty()) {
0540 primaryVertex = pvHandle->at(0);
0541 primaryVertexIsValid = true;
0542 } else {
0543 edm::LogError("DataNotAvailable")
0544 << "No primary vertex available from EventSetup, not adding high level selection \n";
0545 }
0546 }
0547
0548 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_charged_hadrons;
0549 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_neutral_hadrons;
0550 edm::Handle<edm::ValueMap<float>> PUPPIIsolation_photons;
0551
0552 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_charged_hadrons;
0553 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_neutral_hadrons;
0554 edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_photons;
0555 if (addPuppiIsolation_) {
0556
0557 iEvent.getByToken(PUPPIIsolation_charged_hadrons_, PUPPIIsolation_charged_hadrons);
0558 iEvent.getByToken(PUPPIIsolation_neutral_hadrons_, PUPPIIsolation_neutral_hadrons);
0559 iEvent.getByToken(PUPPIIsolation_photons_, PUPPIIsolation_photons);
0560
0561 iEvent.getByToken(PUPPINoLeptonsIsolation_charged_hadrons_, PUPPINoLeptonsIsolation_charged_hadrons);
0562 iEvent.getByToken(PUPPINoLeptonsIsolation_neutral_hadrons_, PUPPINoLeptonsIsolation_neutral_hadrons);
0563 iEvent.getByToken(PUPPINoLeptonsIsolation_photons_, PUPPINoLeptonsIsolation_photons);
0564 }
0565
0566 std::vector<Electron>* patElectrons = new std::vector<Electron>();
0567
0568 if (useParticleFlow_) {
0569 edm::Handle<reco::PFCandidateCollection> pfElectrons;
0570 iEvent.getByToken(pfElecToken_, pfElectrons);
0571 unsigned index = 0;
0572
0573 for (reco::PFCandidateConstIterator i = pfElectrons->begin(); i != pfElectrons->end(); ++i, ++index) {
0574 reco::PFCandidateRef pfRef(pfElectrons, index);
0575 reco::PFCandidatePtr ptrToPFElectron(pfElectrons, index);
0576
0577
0578 reco::GsfTrackRef PfTk = i->gsfTrackRef();
0579
0580 bool Matched = false;
0581 bool MatchedToAmbiguousGsfTrack = false;
0582 for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end();
0583 ++itElectron) {
0584 unsigned int idx = itElectron - electrons->begin();
0585 auto elePtr = electrons->ptrAt(idx);
0586 if (Matched || MatchedToAmbiguousGsfTrack)
0587 continue;
0588
0589 reco::GsfTrackRef EgTk = itElectron->gsfTrack();
0590
0591 if (itElectron->gsfTrack() == i->gsfTrackRef()) {
0592 Matched = true;
0593 } else {
0594 for (auto const& it : itElectron->ambiguousGsfTracks()) {
0595 MatchedToAmbiguousGsfTrack |= (bool)(i->gsfTrackRef() == it);
0596 }
0597 }
0598
0599 if (Matched || MatchedToAmbiguousGsfTrack) {
0600
0601 reco::CandidatePtr ptrToGsfElectron(electrons, idx);
0602
0603
0604 const edm::RefToBase<reco::GsfElectron>& elecsRef = electrons->refAt(idx);
0605 Electron anElectron(elecsRef);
0606 anElectron.setPFCandidateRef(pfRef);
0607 if (addPuppiIsolation_) {
0608 anElectron.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[elePtr],
0609 (*PUPPIIsolation_neutral_hadrons)[elePtr],
0610 (*PUPPIIsolation_photons)[elePtr]);
0611 anElectron.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[elePtr],
0612 (*PUPPINoLeptonsIsolation_neutral_hadrons)[elePtr],
0613 (*PUPPINoLeptonsIsolation_photons)[elePtr]);
0614 } else {
0615 anElectron.setIsolationPUPPI(-999., -999., -999.);
0616 anElectron.setIsolationPUPPINoLeptons(-999., -999., -999.);
0617 }
0618
0619
0620 anElectron.setIsPF(true);
0621
0622 if (embedPFCandidate_)
0623 anElectron.embedPFCandidate();
0624
0625 if (useUserData_) {
0626 userDataHelper_.add(anElectron, iEvent, iSetup);
0627 }
0628
0629 double ip3d = -999;
0630
0631
0632 if (embedHighLevelSelection_) {
0633
0634 const reco::GsfTrackRef& track = PfTk;
0635
0636
0637 if (track.isNonnull() && track.isAvailable()) {
0638 reco::TransientTrack tt = trackBuilder->build(track);
0639 embedHighLevel(anElectron, track, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
0640
0641 std::pair<bool, Measurement1D> ip3dpv = IPTools::absoluteImpactParameter3D(tt, primaryVertex);
0642 ip3d = ip3dpv.second.value();
0643 }
0644 }
0645
0646
0647
0648 if (addElecID_) {
0649
0650 for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
0651 ids[i].second = (*idhandles[i])[elecsRef];
0652 }
0653
0654 ids.push_back(std::make_pair("pf_evspi", pfRef->mva_e_pi()));
0655 ids.push_back(std::make_pair("pf_evsmu", pfRef->mva_e_mu()));
0656 anElectron.setElectronIDs(ids);
0657 }
0658
0659 if (addMVAVariables_) {
0660
0661 const auto& vCov = lazyTools.localCovariances(*(itElectron->superCluster()->seed()));
0662 anElectron.setMvaVariables(vCov[1], ip3d);
0663 }
0664
0665 if (addPFClusterIso_) {
0666
0667 edm::Handle<edm::ValueMap<float>> ecalPFClusterIsoMapH;
0668 iEvent.getByToken(ecalPFClusterIsoT_, ecalPFClusterIsoMapH);
0669 edm::Handle<edm::ValueMap<float>> hcalPFClusterIsoMapH;
0670 iEvent.getByToken(hcalPFClusterIsoT_, hcalPFClusterIsoMapH);
0671 reco::GsfElectron::PflowIsolationVariables newPFIsol = anElectron.pfIsolationVariables();
0672 newPFIsol.sumEcalClusterEt = (*ecalPFClusterIsoMapH)[elecsRef];
0673 newPFIsol.sumHcalClusterEt = (*hcalPFClusterIsoMapH)[elecsRef];
0674 anElectron.setPfIsolationVariables(newPFIsol);
0675 }
0676
0677 std::vector<DetId> selectedCells;
0678 bool barrel = itElectron->isEB();
0679
0680 if (embedBasicClusters_) {
0681 for (reco::CaloCluster_iterator clusIt = itElectron->superCluster()->clustersBegin();
0682 clusIt != itElectron->superCluster()->clustersEnd();
0683 ++clusIt) {
0684
0685 DetId seed = lazyTools.getMaximum(**clusIt).first;
0686
0687 std::vector<DetId> dets5x5 =
0688 (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalBarrel)->getWindow(seed, 5, 5)
0689 : ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalEndcap)->getWindow(seed, 5, 5);
0690 selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
0691
0692
0693 for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
0694 selectedCells.push_back(hit.first);
0695 }
0696 }
0697 }
0698
0699 if (embedPflowBasicClusters_ && itElectron->parentSuperCluster().isNonnull()) {
0700 for (reco::CaloCluster_iterator clusIt = itElectron->parentSuperCluster()->clustersBegin();
0701 clusIt != itElectron->parentSuperCluster()->clustersEnd();
0702 ++clusIt) {
0703
0704 DetId seed = lazyTools.getMaximum(**clusIt).first;
0705
0706 std::vector<DetId> dets5x5 =
0707 (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalBarrel)->getWindow(seed, 5, 5)
0708 : ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalEndcap)->getWindow(seed, 5, 5);
0709 selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
0710
0711
0712 for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
0713 selectedCells.push_back(hit.first);
0714 }
0715 }
0716 }
0717
0718
0719 std::sort(selectedCells.begin(), selectedCells.end());
0720 std::unique(selectedCells.begin(), selectedCells.end());
0721
0722
0723
0724 edm::Handle<EcalRecHitCollection> rechitsH;
0725 if (barrel)
0726 iEvent.getByToken(reducedBarrelRecHitCollectionToken_, rechitsH);
0727 else
0728 iEvent.getByToken(reducedEndcapRecHitCollectionToken_, rechitsH);
0729
0730 EcalRecHitCollection selectedRecHits;
0731 const EcalRecHitCollection* recHits = rechitsH.product();
0732
0733 unsigned nSelectedCells = selectedCells.size();
0734 for (unsigned icell = 0; icell < nSelectedCells; ++icell) {
0735 EcalRecHitCollection::const_iterator it = recHits->find(selectedCells[icell]);
0736 if (it != recHits->end()) {
0737 selectedRecHits.push_back(*it);
0738 }
0739 }
0740 selectedRecHits.sort();
0741 if (embedRecHits_)
0742 anElectron.embedRecHits(&selectedRecHits);
0743
0744
0745 bool passconversionveto = false;
0746 if (hConversions.isValid()) {
0747
0748 passconversionveto =
0749 !ConversionTools::hasMatchedConversion(*itElectron, *hConversions, beamSpotHandle->position());
0750 } else {
0751
0752 passconversionveto =
0753 itElectron->gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) < 1;
0754 }
0755
0756 anElectron.setPassConversionVeto(passconversionveto);
0757
0758
0759
0760
0761
0762
0763
0764
0765
0766
0767
0768
0769 fillElectron2(
0770 anElectron, ptrToPFElectron, ptrToGsfElectron, ptrToGsfElectron, genMatches, deposits, isolationValues);
0771
0772
0773
0774 if (computeMiniIso_)
0775 setElectronMiniIso(anElectron, pc.product());
0776
0777 patElectrons->push_back(anElectron);
0778 }
0779 }
0780
0781 }
0782 }
0783
0784 else {
0785 edm::Handle<reco::PFCandidateCollection> pfElectrons;
0786 edm::Handle<edm::ValueMap<reco::PFCandidatePtr>> ValMapH;
0787 edm::Handle<edm::ValueMap<std::vector<reco::PFCandidateRef>>> ValMultiMapH;
0788 bool pfCandsPresent = false, valMapPresent = false;
0789 if (usePfCandidateMultiMap_) {
0790 iEvent.getByToken(pfCandidateMultiMapToken_, ValMultiMapH);
0791 } else {
0792 pfCandsPresent = iEvent.getByToken(pfElecToken_, pfElectrons);
0793 valMapPresent = iEvent.getByToken(pfCandidateMapToken_, ValMapH);
0794 }
0795
0796 for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end();
0797 ++itElectron) {
0798
0799
0800 unsigned int idx = itElectron - electrons->begin();
0801 edm::RefToBase<reco::GsfElectron> elecsRef = electrons->refAt(idx);
0802 reco::CandidateBaseRef elecBaseRef(elecsRef);
0803 Electron anElectron(elecsRef);
0804 auto elePtr = electrons->ptrAt(idx);
0805
0806
0807 bool pfId = false;
0808
0809 if (usePfCandidateMultiMap_) {
0810 for (const reco::PFCandidateRef& pf : (*ValMultiMapH)[elePtr]) {
0811 if (pf->particleId() == reco::PFCandidate::e) {
0812 pfId = true;
0813 anElectron.setPFCandidateRef(pf);
0814 break;
0815 }
0816 }
0817 } else if (pfCandsPresent) {
0818
0819 const reco::GsfTrackRef& trkRef = itElectron->gsfTrack();
0820 int index = 0;
0821 for (reco::PFCandidateConstIterator ie = pfElectrons->begin(); ie != pfElectrons->end(); ++ie, ++index) {
0822 if (ie->particleId() != reco::PFCandidate::e)
0823 continue;
0824 const reco::GsfTrackRef& pfTrkRef = ie->gsfTrackRef();
0825 if (trkRef == pfTrkRef) {
0826 pfId = true;
0827 reco::PFCandidateRef pfRef(pfElectrons, index);
0828 anElectron.setPFCandidateRef(pfRef);
0829 break;
0830 }
0831 }
0832 } else if (valMapPresent) {
0833
0834 const edm::ValueMap<reco::PFCandidatePtr>& myValMap(*ValMapH);
0835
0836 const reco::PFCandidatePtr& pfElePtr(myValMap[elecsRef]);
0837 pfId = pfElePtr.isNonnull();
0838 }
0839
0840 anElectron.setIsPF(pfId);
0841
0842
0843
0844
0845 if (isolator_.enabled()) {
0846 isolator_.fill(*electrons, idx, isolatorTmpStorage_);
0847 typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
0848
0849 for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(),
0850 ed = isolatorTmpStorage_.rend();
0851 it != ed;
0852 ++it) {
0853 anElectron.setIsolation(it->first, it->second);
0854 }
0855 }
0856
0857 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
0858 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[elecsRef]);
0859 }
0860
0861
0862 if (addElecID_) {
0863 for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
0864 ids[i].second = (*idhandles[i])[elecsRef];
0865 }
0866 anElectron.setElectronIDs(ids);
0867 }
0868
0869 if (useUserData_) {
0870 userDataHelper_.add(anElectron, iEvent, iSetup);
0871 }
0872
0873 double ip3d = -999;
0874
0875
0876 if (embedHighLevelSelection_) {
0877
0878 reco::GsfTrackRef track = itElectron->gsfTrack();
0879
0880
0881 if (track.isNonnull() && track.isAvailable()) {
0882 reco::TransientTrack tt = trackBuilder->build(track);
0883 embedHighLevel(anElectron, track, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
0884
0885 std::pair<bool, Measurement1D> ip3dpv = IPTools::absoluteImpactParameter3D(tt, primaryVertex);
0886 ip3d = ip3dpv.second.value();
0887 }
0888 }
0889
0890 if (addMVAVariables_) {
0891
0892 const auto& vCov = lazyTools.localCovariances(*(itElectron->superCluster()->seed()));
0893 anElectron.setMvaVariables(vCov[1], ip3d);
0894 }
0895
0896
0897 if (addPFClusterIso_) {
0898
0899 edm::Handle<edm::ValueMap<float>> ecalPFClusterIsoMapH;
0900 iEvent.getByToken(ecalPFClusterIsoT_, ecalPFClusterIsoMapH);
0901 edm::Handle<edm::ValueMap<float>> hcalPFClusterIsoMapH;
0902 iEvent.getByToken(hcalPFClusterIsoT_, hcalPFClusterIsoMapH);
0903 reco::GsfElectron::PflowIsolationVariables newPFIsol = anElectron.pfIsolationVariables();
0904 newPFIsol.sumEcalClusterEt = (*ecalPFClusterIsoMapH)[elecsRef];
0905 newPFIsol.sumHcalClusterEt = (*hcalPFClusterIsoMapH)[elecsRef];
0906 anElectron.setPfIsolationVariables(newPFIsol);
0907 }
0908
0909 if (addPuppiIsolation_) {
0910 anElectron.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[elePtr],
0911 (*PUPPIIsolation_neutral_hadrons)[elePtr],
0912 (*PUPPIIsolation_photons)[elePtr]);
0913 anElectron.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[elePtr],
0914 (*PUPPINoLeptonsIsolation_neutral_hadrons)[elePtr],
0915 (*PUPPINoLeptonsIsolation_photons)[elePtr]);
0916 } else {
0917 anElectron.setIsolationPUPPI(-999., -999., -999.);
0918 anElectron.setIsolationPUPPINoLeptons(-999., -999., -999.);
0919 }
0920
0921 std::vector<DetId> selectedCells;
0922 bool barrel = itElectron->isEB();
0923
0924 if (embedBasicClusters_) {
0925 for (reco::CaloCluster_iterator clusIt = itElectron->superCluster()->clustersBegin();
0926 clusIt != itElectron->superCluster()->clustersEnd();
0927 ++clusIt) {
0928
0929 DetId seed = lazyTools.getMaximum(**clusIt).first;
0930
0931 std::vector<DetId> dets5x5 =
0932 (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalBarrel)->getWindow(seed, 5, 5)
0933 : ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalEndcap)->getWindow(seed, 5, 5);
0934 selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
0935
0936
0937 for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
0938 selectedCells.push_back(hit.first);
0939 }
0940 }
0941 }
0942
0943 if (embedPflowBasicClusters_ && itElectron->parentSuperCluster().isNonnull()) {
0944 for (reco::CaloCluster_iterator clusIt = itElectron->parentSuperCluster()->clustersBegin();
0945 clusIt != itElectron->parentSuperCluster()->clustersEnd();
0946 ++clusIt) {
0947
0948 DetId seed = lazyTools.getMaximum(**clusIt).first;
0949
0950 std::vector<DetId> dets5x5 =
0951 (barrel) ? ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalBarrel)->getWindow(seed, 5, 5)
0952 : ecalTopology_->getSubdetectorTopology(DetId::Ecal, EcalEndcap)->getWindow(seed, 5, 5);
0953 selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
0954
0955
0956 for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
0957 selectedCells.push_back(hit.first);
0958 }
0959 }
0960 }
0961
0962
0963 std::sort(selectedCells.begin(), selectedCells.end());
0964 std::unique(selectedCells.begin(), selectedCells.end());
0965
0966
0967
0968 edm::Handle<EcalRecHitCollection> rechitsH;
0969 if (barrel)
0970 iEvent.getByToken(reducedBarrelRecHitCollectionToken_, rechitsH);
0971 else
0972 iEvent.getByToken(reducedEndcapRecHitCollectionToken_, rechitsH);
0973
0974 EcalRecHitCollection selectedRecHits;
0975 const EcalRecHitCollection* recHits = rechitsH.product();
0976
0977 unsigned nSelectedCells = selectedCells.size();
0978 for (unsigned icell = 0; icell < nSelectedCells; ++icell) {
0979 EcalRecHitCollection::const_iterator it = recHits->find(selectedCells[icell]);
0980 if (it != recHits->end()) {
0981 selectedRecHits.push_back(*it);
0982 }
0983 }
0984 selectedRecHits.sort();
0985 if (embedRecHits_)
0986 anElectron.embedRecHits(&selectedRecHits);
0987
0988
0989 bool passconversionveto = false;
0990 if (hConversions.isValid()) {
0991
0992 passconversionveto =
0993 !ConversionTools::hasMatchedConversion(*itElectron, *hConversions, beamSpotHandle->position());
0994 } else {
0995
0996 passconversionveto =
0997 itElectron->gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) < 1;
0998 }
0999 anElectron.setPassConversionVeto(passconversionveto);
1000
1001
1002 fillElectron(
1003 anElectron, elecsRef, elecBaseRef, genMatches, deposits, pfId, isolationValues, isolationValuesNoPFId);
1004
1005 if (computeMiniIso_)
1006 setElectronMiniIso(anElectron, pc.product());
1007
1008 patElectrons->push_back(anElectron);
1009 }
1010 }
1011
1012
1013 std::sort(patElectrons->begin(), patElectrons->end(), pTComparator_);
1014
1015
1016 std::unique_ptr<std::vector<Electron>> ptr(patElectrons);
1017 iEvent.put(std::move(ptr));
1018
1019
1020 if (isolator_.enabled())
1021 isolator_.endEvent();
1022 }
1023
1024 void PATElectronProducer::fillElectron(Electron& anElectron,
1025 const edm::RefToBase<reco::GsfElectron>& elecRef,
1026 const reco::CandidateBaseRef& baseRef,
1027 const GenAssociations& genMatches,
1028 const IsoDepositMaps& deposits,
1029 const bool pfId,
1030 const IsolationValueMaps& isolationValues,
1031 const IsolationValueMaps& isolationValuesNoPFId) const {
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049 if (embedGsfElectronCore_)
1050 anElectron.embedGsfElectronCore();
1051 if (embedGsfTrack_)
1052 anElectron.embedGsfTrack();
1053 if (embedSuperCluster_)
1054 anElectron.embedSuperCluster();
1055 if (embedPflowSuperCluster_)
1056 anElectron.embedPflowSuperCluster();
1057 if (embedSeedCluster_)
1058 anElectron.embedSeedCluster();
1059 if (embedBasicClusters_)
1060 anElectron.embedBasicClusters();
1061 if (embedPreshowerClusters_)
1062 anElectron.embedPreshowerClusters();
1063 if (embedPflowBasicClusters_)
1064 anElectron.embedPflowBasicClusters();
1065 if (embedPflowPreshowerClusters_)
1066 anElectron.embedPflowPreshowerClusters();
1067 if (embedTrack_)
1068 anElectron.embedTrack();
1069
1070
1071 if (addGenMatch_) {
1072 for (size_t i = 0, n = genMatches.size(); i < n; ++i) {
1073 if (useParticleFlow_) {
1074 reco::GenParticleRef genElectron = (*genMatches[i])[anElectron.pfCandidateRef()];
1075 anElectron.addGenParticleRef(genElectron);
1076 } else {
1077 reco::GenParticleRef genElectron = (*genMatches[i])[elecRef];
1078 anElectron.addGenParticleRef(genElectron);
1079 }
1080 }
1081 if (embedGenMatch_)
1082 anElectron.embedGenParticle();
1083 }
1084
1085 if (efficiencyLoader_.enabled()) {
1086 efficiencyLoader_.setEfficiencies(anElectron, elecRef);
1087 }
1088
1089 if (resolutionLoader_.enabled()) {
1090 resolutionLoader_.setResolutions(anElectron);
1091 }
1092
1093 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
1094 if (useParticleFlow_) {
1095 reco::PFCandidateRef pfcandref = anElectron.pfCandidateRef();
1096 assert(!pfcandref.isNull());
1097 reco::CandidatePtr source = pfcandref->sourceCandidatePtr(0);
1098 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[source]);
1099 } else
1100 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[elecRef]);
1101 }
1102
1103 for (size_t j = 0; j < isolationValues.size(); ++j) {
1104 if (useParticleFlow_) {
1105 reco::CandidatePtr source = anElectron.pfCandidateRef()->sourceCandidatePtr(0);
1106 anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[source]);
1107 } else if (pfId) {
1108 anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[elecRef]);
1109 }
1110 }
1111
1112
1113 for (size_t j = 0; j < isolationValuesNoPFId.size(); ++j) {
1114 if (!pfId) {
1115 anElectron.setIsolation(isolationValueLabelsNoPFId_[j].first, (*isolationValuesNoPFId[j])[elecRef]);
1116 }
1117 }
1118 }
1119
1120 void PATElectronProducer::fillElectron2(Electron& anElectron,
1121 const reco::CandidatePtr& candPtrForIsolation,
1122 const reco::CandidatePtr& candPtrForGenMatch,
1123 const reco::CandidatePtr& candPtrForLoader,
1124 const GenAssociations& genMatches,
1125 const IsoDepositMaps& deposits,
1126 const IsolationValueMaps& isolationValues) const {
1127
1128 anElectron.setEcalDrivenMomentum(anElectron.p4());
1129 anElectron.setP4(anElectron.pfCandidateRef()->p4());
1130
1131
1132
1133
1134 if (embedGsfElectronCore_)
1135 anElectron.embedGsfElectronCore();
1136 if (embedGsfTrack_)
1137 anElectron.embedGsfTrack();
1138 if (embedSuperCluster_)
1139 anElectron.embedSuperCluster();
1140 if (embedPflowSuperCluster_)
1141 anElectron.embedPflowSuperCluster();
1142 if (embedSeedCluster_)
1143 anElectron.embedSeedCluster();
1144 if (embedBasicClusters_)
1145 anElectron.embedBasicClusters();
1146 if (embedPreshowerClusters_)
1147 anElectron.embedPreshowerClusters();
1148 if (embedPflowBasicClusters_)
1149 anElectron.embedPflowBasicClusters();
1150 if (embedPflowPreshowerClusters_)
1151 anElectron.embedPflowPreshowerClusters();
1152 if (embedTrack_)
1153 anElectron.embedTrack();
1154
1155
1156
1157 if (addGenMatch_) {
1158 for (size_t i = 0, n = genMatches.size(); i < n; ++i) {
1159 reco::GenParticleRef genElectron = (*genMatches[i])[candPtrForGenMatch];
1160 anElectron.addGenParticleRef(genElectron);
1161 }
1162 if (embedGenMatch_)
1163 anElectron.embedGenParticle();
1164 }
1165
1166
1167 if (efficiencyLoader_.enabled()) {
1168 efficiencyLoader_.setEfficiencies(anElectron, candPtrForLoader);
1169 }
1170
1171 if (resolutionLoader_.enabled()) {
1172 resolutionLoader_.setResolutions(anElectron);
1173 }
1174
1175 for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
1176 if (isoDepositLabels_[j].first == pat::TrackIso || isoDepositLabels_[j].first == pat::EcalIso ||
1177 isoDepositLabels_[j].first == pat::HcalIso || deposits[j]->contains(candPtrForGenMatch.id())) {
1178 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForGenMatch]);
1179 } else if (deposits[j]->contains(candPtrForIsolation.id())) {
1180 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForIsolation]);
1181 } else {
1182 anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
1183 }
1184 }
1185
1186 for (size_t j = 0; j < isolationValues.size(); ++j) {
1187 if (isolationValueLabels_[j].first == pat::TrackIso || isolationValueLabels_[j].first == pat::EcalIso ||
1188 isolationValueLabels_[j].first == pat::HcalIso || isolationValues[j]->contains(candPtrForGenMatch.id())) {
1189 anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[candPtrForGenMatch]);
1190 } else if (isolationValues[j]->contains(candPtrForIsolation.id())) {
1191 anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[candPtrForIsolation]);
1192 } else {
1193 anElectron.setIsolation(isolationValueLabels_[j].first,
1194 (*isolationValues[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
1195 }
1196 }
1197 }
1198
1199 void PATElectronProducer::setElectronMiniIso(Electron& anElectron, const PackedCandidateCollection* pc) {
1200 pat::PFIsolation miniiso;
1201 if (anElectron.isEE())
1202 miniiso = pat::getMiniPFIsolation(pc,
1203 anElectron.polarP4(),
1204 miniIsoParamsE_[0],
1205 miniIsoParamsE_[1],
1206 miniIsoParamsE_[2],
1207 miniIsoParamsE_[3],
1208 miniIsoParamsE_[4],
1209 miniIsoParamsE_[5],
1210 miniIsoParamsE_[6],
1211 miniIsoParamsE_[7],
1212 miniIsoParamsE_[8]);
1213 else
1214 miniiso = pat::getMiniPFIsolation(pc,
1215 anElectron.polarP4(),
1216 miniIsoParamsB_[0],
1217 miniIsoParamsB_[1],
1218 miniIsoParamsB_[2],
1219 miniIsoParamsB_[3],
1220 miniIsoParamsB_[4],
1221 miniIsoParamsB_[5],
1222 miniIsoParamsB_[6],
1223 miniIsoParamsB_[7],
1224 miniIsoParamsB_[8]);
1225 anElectron.setMiniPFIsolation(miniiso);
1226 }
1227
1228
1229 void PATElectronProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
1230 edm::ParameterSetDescription iDesc;
1231 iDesc.setComment("PAT electron producer module");
1232
1233
1234 iDesc.add<edm::InputTag>("pfCandidateMap", edm::InputTag("no default"))->setComment("input collection");
1235 iDesc.add<edm::InputTag>("electronSource", edm::InputTag("no default"))->setComment("input collection");
1236
1237 iDesc.ifValue(
1238 edm::ParameterDescription<bool>("addPFClusterIso", false, true),
1239 true >> (edm::ParameterDescription<edm::InputTag>(
1240 "ecalPFClusterIsoMap", edm::InputTag("electronEcalPFClusterIsolationProducer"), true) and
1241 edm::ParameterDescription<edm::InputTag>(
1242 "hcalPFClusterIsoMap", edm::InputTag("electronHcalPFClusterIsolationProducer"), true)) or
1243 false >> (edm::ParameterDescription<edm::InputTag>("ecalPFClusterIsoMap", edm::InputTag(""), true) and
1244 edm::ParameterDescription<edm::InputTag>("hcalPFClusterIsoMap", edm::InputTag(""), true)));
1245
1246 iDesc.ifValue(edm::ParameterDescription<bool>("addPuppiIsolation", false, true),
1247 true >> (edm::ParameterDescription<edm::InputTag>(
1248 "puppiIsolationChargedHadrons",
1249 edm::InputTag("egmElectronPUPPIIsolation", "h+-DR030-BarVeto000-EndVeto001"),
1250 true) and
1251 edm::ParameterDescription<edm::InputTag>(
1252 "puppiIsolationNeutralHadrons",
1253 edm::InputTag("egmElectronPUPPIIsolation", "h0-DR030-BarVeto000-EndVeto000"),
1254 true) and
1255 edm::ParameterDescription<edm::InputTag>(
1256 "puppiIsolationPhotons",
1257 edm::InputTag("egmElectronPUPPIIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1258 true) and
1259 edm::ParameterDescription<edm::InputTag>(
1260 "puppiNoLeptonsIsolationChargedHadrons",
1261 edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1262 true) and
1263 edm::ParameterDescription<edm::InputTag>(
1264 "puppiNoLeptonsIsolationNeutralHadrons",
1265 edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1266 true) and
1267 edm::ParameterDescription<edm::InputTag>(
1268 "puppiNoLeptonsIsolationPhotons",
1269 edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1270 true)) or
1271 false >> edm::EmptyGroupDescription());
1272
1273
1274 iDesc.add<bool>("embedGsfElectronCore", true)->setComment("embed external gsf electron core");
1275 iDesc.add<bool>("embedGsfTrack", true)->setComment("embed external gsf track");
1276 iDesc.add<bool>("embedSuperCluster", true)->setComment("embed external super cluster");
1277 iDesc.add<bool>("embedPflowSuperCluster", true)->setComment("embed external super cluster");
1278 iDesc.add<bool>("embedSeedCluster", true)->setComment("embed external seed cluster");
1279 iDesc.add<bool>("embedBasicClusters", true)->setComment("embed external basic clusters");
1280 iDesc.add<bool>("embedPreshowerClusters", true)->setComment("embed external preshower clusters");
1281 iDesc.add<bool>("embedPflowBasicClusters", true)->setComment("embed external pflow basic clusters");
1282 iDesc.add<bool>("embedPflowPreshowerClusters", true)->setComment("embed external pflow preshower clusters");
1283 iDesc.add<bool>("embedTrack", false)->setComment("embed external track");
1284 iDesc.add<bool>("embedRecHits", true)->setComment("embed external RecHits");
1285
1286
1287 iDesc.add<edm::InputTag>("pfElectronSource", edm::InputTag("pfElectrons"))
1288 ->setComment("particle flow input collection");
1289 auto&& usePfCandidateMultiMap = edm::ParameterDescription<bool>("usePfCandidateMultiMap", false, true);
1290 usePfCandidateMultiMap.setComment(
1291 "take ParticleFlow candidates from pfCandidateMultiMap instead of matching to pfElectrons by Gsf track "
1292 "reference");
1293 iDesc.ifValue(usePfCandidateMultiMap,
1294 true >> edm::ParameterDescription<edm::InputTag>("pfCandidateMultiMap", true) or
1295 false >> edm::EmptyGroupDescription());
1296 iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
1297 iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
1298
1299
1300 iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
1301 iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
1302 std::vector<edm::InputTag> emptySourceVector;
1303 iDesc
1304 .addNode(edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
1305 edm::ParameterDescription<std::vector<edm::InputTag>>("genParticleMatch", emptySourceVector, true))
1306 ->setComment("input with MC match information");
1307
1308
1309 iDesc.add<bool>("addElectronID", true)->setComment("add electron ID variables");
1310 edm::ParameterSetDescription electronIDSourcesPSet;
1311 electronIDSourcesPSet.setAllowAnything();
1312 iDesc
1313 .addNode(
1314 edm::ParameterDescription<edm::InputTag>("electronIDSource", edm::InputTag(), true) xor
1315 edm::ParameterDescription<edm::ParameterSetDescription>("electronIDSources", electronIDSourcesPSet, true))
1316 ->setComment("input with electron ID variables");
1317
1318
1319 iDesc.add<bool>("computeMiniIso", false)->setComment("whether or not to compute and store electron mini-isolation");
1320 iDesc.add<edm::InputTag>("pfCandsForMiniIso", edm::InputTag("packedPFCandidates"))
1321 ->setComment("collection to use to compute mini-iso");
1322 iDesc.add<std::vector<double>>("miniIsoParamsE", std::vector<double>())
1323 ->setComment("mini-iso parameters to use for endcap electrons");
1324 iDesc.add<std::vector<double>>("miniIsoParamsB", std::vector<double>())
1325 ->setComment("mini-iso parameters to use for barrel electrons");
1326
1327
1328 edm::ParameterSetDescription isoDepositsPSet;
1329 isoDepositsPSet.addOptional<edm::InputTag>("tracker");
1330 isoDepositsPSet.addOptional<edm::InputTag>("ecal");
1331 isoDepositsPSet.addOptional<edm::InputTag>("hcal");
1332 isoDepositsPSet.addOptional<edm::InputTag>("pfAllParticles");
1333 isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1334 isoDepositsPSet.addOptional<edm::InputTag>("pfChargedAll");
1335 isoDepositsPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1336 isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1337 isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
1338 isoDepositsPSet.addOptional<std::vector<edm::InputTag>>("user");
1339 iDesc.addOptional("isoDeposits", isoDepositsPSet);
1340
1341
1342 edm::ParameterSetDescription isolationValuesPSet;
1343 isolationValuesPSet.addOptional<edm::InputTag>("tracker");
1344 isolationValuesPSet.addOptional<edm::InputTag>("ecal");
1345 isolationValuesPSet.addOptional<edm::InputTag>("hcal");
1346 isolationValuesPSet.addOptional<edm::InputTag>("pfAllParticles");
1347 isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1348 isolationValuesPSet.addOptional<edm::InputTag>("pfChargedAll");
1349 isolationValuesPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1350 isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1351 isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
1352 isolationValuesPSet.addOptional<std::vector<edm::InputTag>>("user");
1353 iDesc.addOptional("isolationValues", isolationValuesPSet);
1354
1355
1356 edm::ParameterSetDescription isolationValuesNoPFIdPSet;
1357 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("tracker");
1358 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("ecal");
1359 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("hcal");
1360 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfAllParticles");
1361 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1362 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfChargedAll");
1363 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1364 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1365 isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfPhotons");
1366 isolationValuesNoPFIdPSet.addOptional<std::vector<edm::InputTag>>("user");
1367 iDesc.addOptional("isolationValuesNoPFId", isolationValuesNoPFIdPSet);
1368
1369
1370 edm::ParameterSetDescription efficienciesPSet;
1371 efficienciesPSet.setAllowAnything();
1372 iDesc.add("efficiencies", efficienciesPSet);
1373 iDesc.add<bool>("addEfficiencies", false);
1374
1375
1376 edm::ParameterSetDescription userDataPSet;
1377 PATUserDataHelper<Electron>::fillDescription(userDataPSet);
1378 iDesc.addOptional("userData", userDataPSet);
1379
1380
1381 iDesc.add<bool>("addMVAVariables", true)->setComment("embed extra variables in pat::Electron : sip3d, sigmaIEtaIPhi");
1382 iDesc.add<edm::InputTag>("reducedBarrelRecHitCollection", edm::InputTag("reducedEcalRecHitsEB"));
1383 iDesc.add<edm::InputTag>("reducedEndcapRecHitCollection", edm::InputTag("reducedEcalRecHitsEE"));
1384
1385 edm::ParameterSetDescription isolationPSet;
1386 isolationPSet.setAllowAnything();
1387 iDesc.add("userIsolation", isolationPSet);
1388
1389
1390 pat::helper::KinResolutionsLoader::fillDescription(iDesc);
1391
1392 iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
1393 edm::ParameterSetDescription highLevelPSet;
1394 highLevelPSet.setAllowAnything();
1395 iDesc.addNode(edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true))
1396 ->setComment("input with high level selection");
1397 iDesc.addNode(edm::ParameterDescription<edm::InputTag>("pvSrc", edm::InputTag(), true))
1398 ->setComment("input with high level selection");
1399
1400 descriptions.add("PATElectronProducer", iDesc);
1401 }
1402
1403
1404
1405 void PATElectronProducer::embedHighLevel(pat::Electron& anElectron,
1406 reco::GsfTrackRef track,
1407 reco::TransientTrack& tt,
1408 reco::Vertex& primaryVertex,
1409 bool primaryVertexIsValid,
1410 reco::BeamSpot& beamspot,
1411 bool beamspotIsValid) {
1412
1413
1414 anElectron.setDB(track->dxy(primaryVertex.position()),
1415 track->dxyError(primaryVertex.position(), primaryVertex.covariance()),
1416 pat::Electron::PV2D);
1417
1418
1419 std::pair<bool, Measurement1D> result =
1420 IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex);
1421 double d0_corr = result.second.value();
1422 double d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
1423 anElectron.setDB(d0_corr, d0_err, pat::Electron::PV3D);
1424
1425
1426
1427 anElectron.setDB(track->dxy(beamspot), track->dxyError(beamspot), pat::Electron::BS2D);
1428
1429
1430 reco::Vertex vBeamspot(beamspot.position(), beamspot.covariance3D());
1431
1432
1433 result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot);
1434 d0_corr = result.second.value();
1435 d0_err = beamspotIsValid ? result.second.error() : -1.0;
1436 anElectron.setDB(d0_corr, d0_err, pat::Electron::BS3D);
1437
1438
1439 anElectron.setDB(
1440 track->dz(primaryVertex.position()), std::hypot(track->dzError(), primaryVertex.zError()), pat::Electron::PVDZ);
1441 }
1442
1443 #include "FWCore/Framework/interface/MakerMacros.h"
1444 DEFINE_FWK_MODULE(PATElectronProducer);