CMS 3D CMS Logo

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PATElectronProducer.cc
Go to the documentation of this file.
1 //
3 
7 
13 
16 
19 
22 
25 
30 
39 
41 
43 
45 
46 #include <vector>
47 #include <memory>
48 
49 using namespace pat;
50 using namespace std;
51 
53  : // general configurables
54  electronToken_(consumes<edm::View<reco::GsfElectron>>(iConfig.getParameter<edm::InputTag>("electronSource"))),
55  hConversionsToken_(consumes<reco::ConversionCollection>(edm::InputTag("allConversions"))),
56  embedGsfElectronCore_(iConfig.getParameter<bool>("embedGsfElectronCore")),
57  embedGsfTrack_(iConfig.getParameter<bool>("embedGsfTrack")),
58  embedSuperCluster_(iConfig.getParameter<bool>("embedSuperCluster")),
59  embedPflowSuperCluster_(iConfig.getParameter<bool>("embedPflowSuperCluster")),
60  embedSeedCluster_(iConfig.getParameter<bool>("embedSeedCluster")),
61  embedBasicClusters_(iConfig.getParameter<bool>("embedBasicClusters")),
62  embedPreshowerClusters_(iConfig.getParameter<bool>("embedPreshowerClusters")),
63  embedPflowBasicClusters_(iConfig.getParameter<bool>("embedPflowBasicClusters")),
64  embedPflowPreshowerClusters_(iConfig.getParameter<bool>("embedPflowPreshowerClusters")),
65  embedTrack_(iConfig.getParameter<bool>("embedTrack")),
66  addGenMatch_(iConfig.getParameter<bool>("addGenMatch")),
67  embedGenMatch_(addGenMatch_ ? iConfig.getParameter<bool>("embedGenMatch") : false),
68  embedRecHits_(iConfig.getParameter<bool>("embedRecHits")),
69  // pflow configurables
70  useParticleFlow_(iConfig.getParameter<bool>("useParticleFlow")),
71  usePfCandidateMultiMap_(iConfig.getParameter<bool>("usePfCandidateMultiMap")),
72  pfElecToken_(!usePfCandidateMultiMap_
73  ? consumes<reco::PFCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfElectronSource"))
74  : edm::EDGetTokenT<reco::PFCandidateCollection>()),
75  pfCandidateMapToken_(!usePfCandidateMultiMap_ ? mayConsume<edm::ValueMap<reco::PFCandidatePtr>>(
76  iConfig.getParameter<edm::InputTag>("pfCandidateMap"))
77  : edm::EDGetTokenT<edm::ValueMap<reco::PFCandidatePtr>>()),
78  pfCandidateMultiMapToken_(usePfCandidateMultiMap_
79  ? consumes<edm::ValueMap<std::vector<reco::PFCandidateRef>>>(
80  iConfig.getParameter<edm::InputTag>("pfCandidateMultiMap"))
81  : edm::EDGetTokenT<edm::ValueMap<std::vector<reco::PFCandidateRef>>>()),
82  embedPFCandidate_(iConfig.getParameter<bool>("embedPFCandidate")),
83  // mva input variables
84  addMVAVariables_(iConfig.getParameter<bool>("addMVAVariables")),
85  reducedBarrelRecHitCollection_(iConfig.getParameter<edm::InputTag>("reducedBarrelRecHitCollection")),
86  reducedBarrelRecHitCollectionToken_(mayConsume<EcalRecHitCollection>(reducedBarrelRecHitCollection_)),
87  reducedEndcapRecHitCollection_(iConfig.getParameter<edm::InputTag>("reducedEndcapRecHitCollection")),
88  reducedEndcapRecHitCollectionToken_(mayConsume<EcalRecHitCollection>(reducedEndcapRecHitCollection_)),
89  // PFCluster Isolation maps
90  addPFClusterIso_(iConfig.getParameter<bool>("addPFClusterIso")),
91  addPuppiIsolation_(iConfig.getParameter<bool>("addPuppiIsolation")),
92  ecalPFClusterIsoT_(consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("ecalPFClusterIsoMap"))),
93  hcalPFClusterIsoT_(consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("hcalPFClusterIsoMap"))),
94  // embed high level selection variables?
95  embedHighLevelSelection_(iConfig.getParameter<bool>("embedHighLevelSelection")),
96  beamLineToken_(consumes<reco::BeamSpot>(iConfig.getParameter<edm::InputTag>("beamLineSrc"))),
97  pvToken_(mayConsume<std::vector<reco::Vertex>>(iConfig.getParameter<edm::InputTag>("pvSrc"))),
98  addElecID_(iConfig.getParameter<bool>("addElectronID")),
99  pTComparator_(),
100  isolator_(iConfig.exists("userIsolation") ? iConfig.getParameter<edm::ParameterSet>("userIsolation")
101  : edm::ParameterSet(),
102  consumesCollector(),
103  false),
104  addEfficiencies_(iConfig.getParameter<bool>("addEfficiencies")),
105  addResolutions_(iConfig.getParameter<bool>("addResolutions")),
106  useUserData_(iConfig.exists("userData"))
107 
108 {
109  // MC matching configurables (scheduled mode)
110 
111  if (addGenMatch_) {
112  if (iConfig.existsAs<edm::InputTag>("genParticleMatch")) {
114  iConfig.getParameter<edm::InputTag>("genParticleMatch")));
115  } else {
117  iConfig.getParameter<std::vector<edm::InputTag>>("genParticleMatch"),
118  [this](edm::InputTag const& tag) { return consumes<edm::Association<reco::GenParticleCollection>>(tag); });
119  }
120  }
121  // resolution configurables
122  if (addResolutions_) {
124  }
125  if (addPuppiIsolation_) {
126  //puppi
128  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationChargedHadrons"));
130  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationNeutralHadrons"));
132  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiIsolationPhotons"));
133  //puppiNoLeptons
135  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationChargedHadrons"));
137  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationNeutralHadrons"));
139  consumes<edm::ValueMap<float>>(iConfig.getParameter<edm::InputTag>("puppiNoLeptonsIsolationPhotons"));
140  }
141  // electron ID configurables
142  if (addElecID_) {
143  // it might be a single electron ID
144  if (iConfig.existsAs<edm::InputTag>("electronIDSource")) {
145  elecIDSrcs_.push_back(NameTag("", iConfig.getParameter<edm::InputTag>("electronIDSource")));
146  }
147  // or there might be many of them
148  if (iConfig.existsAs<edm::ParameterSet>("electronIDSources")) {
149  // please don't configure me twice
150  if (!elecIDSrcs_.empty()) {
151  throw cms::Exception("Configuration")
152  << "PATElectronProducer: you can't specify both 'electronIDSource' and 'electronIDSources'\n";
153  }
154  // read the different electron ID names
155  edm::ParameterSet idps = iConfig.getParameter<edm::ParameterSet>("electronIDSources");
156  std::vector<std::string> names = idps.getParameterNamesForType<edm::InputTag>();
157  for (std::vector<std::string>::const_iterator it = names.begin(), ed = names.end(); it != ed; ++it) {
158  elecIDSrcs_.push_back(NameTag(*it, idps.getParameter<edm::InputTag>(*it)));
159  }
160  }
161  // but in any case at least once
162  if (elecIDSrcs_.empty()) {
163  throw cms::Exception("Configuration")
164  << "PATElectronProducer: id addElectronID is true, you must specify either:\n"
165  << "\tInputTag electronIDSource = <someTag>\n"
166  << "or\n"
167  << "\tPSet electronIDSources = { \n"
168  << "\t\tInputTag <someName> = <someTag> // as many as you want \n "
169  << "\t}\n";
170  }
171  }
173  elecIDSrcs_, [this](NameTag const& tag) { return mayConsume<edm::ValueMap<float>>(tag.second); });
174  // construct resolution calculator
175 
176  // // IsoDeposit configurables
177  // if (iConfig.exists("isoDeposits")) {
178  // edm::ParameterSet depconf = iConfig.getParameter<edm::ParameterSet>("isoDeposits");
179  // if (depconf.exists("tracker")) isoDepositLabels_.push_back(std::make_pair(TrackerIso, depconf.getParameter<edm::InputTag>("tracker")));
180  // if (depconf.exists("ecal")) isoDepositLabels_.push_back(std::make_pair(ECalIso, depconf.getParameter<edm::InputTag>("ecal")));
181  // if (depconf.exists("hcal")) isoDepositLabels_.push_back(std::make_pair(HCalIso, depconf.getParameter<edm::InputTag>("hcal")));
182 
183  // if (depconf.exists("user")) {
184  // std::vector<edm::InputTag> userdeps = depconf.getParameter<std::vector<edm::InputTag> >("user");
185  // std::vector<edm::InputTag>::const_iterator it = userdeps.begin(), ed = userdeps.end();
186  // int key = UserBaseIso;
187  // for ( ; it != ed; ++it, ++key) {
188  // isoDepositLabels_.push_back(std::make_pair(IsolationKeys(key), *it));
189  // }
190  // }
191  // }
192  // isoDepositTokens_ = edm::vector_transform(isoDepositLabels_, [this](std::pair<IsolationKeys,edm::InputTag> const & label){return consumes<edm::ValueMap<IsoDeposit> >(label.second);});
193 
194  // for mini-iso
195  computeMiniIso_ = iConfig.getParameter<bool>("computeMiniIso");
196  miniIsoParamsE_ = iConfig.getParameter<std::vector<double>>("miniIsoParamsE");
197  miniIsoParamsB_ = iConfig.getParameter<std::vector<double>>("miniIsoParamsB");
198  if (computeMiniIso_ && (miniIsoParamsE_.size() != 9 || miniIsoParamsB_.size() != 9)) {
199  throw cms::Exception("ParameterError") << "miniIsoParams must have exactly 9 elements.\n";
200  }
201  if (computeMiniIso_)
202  pcToken_ = consumes<pat::PackedCandidateCollection>(iConfig.getParameter<edm::InputTag>("pfCandsForMiniIso"));
203 
204  // read isoDeposit labels, for direct embedding
205  readIsolationLabels(iConfig, "isoDeposits", isoDepositLabels_, isoDepositTokens_);
206  // read isolation value labels, for direct embedding
208  // read isolation value labels for non PF identified electron, for direct embedding
210  // Efficiency configurables
211  if (addEfficiencies_) {
213  pat::helper::EfficiencyLoader(iConfig.getParameter<edm::ParameterSet>("efficiencies"), consumesCollector());
214  }
215  // Check to see if the user wants to add user data
216  if (useUserData_) {
218  PATUserDataHelper<Electron>(iConfig.getParameter<edm::ParameterSet>("userData"), consumesCollector());
219  }
220 
221  // consistency check
223  throw cms::Exception("Configuration", "usePfCandidateMultiMap not supported when useParticleFlow is set to true");
224 
225  // produces vector of muons
226  produces<std::vector<Electron>>();
227 }
228 
230 
232  // switch off embedding (in unschedules mode)
233  if (iEvent.isRealData()) {
234  addGenMatch_ = false;
235  embedGenMatch_ = false;
236  }
237 
238  edm::ESHandle<CaloTopology> theCaloTopology;
239  iSetup.get<CaloTopologyRecord>().get(theCaloTopology);
240  ecalTopology_ = &(*theCaloTopology);
241 
242  // Get the collection of electrons from the event
244  iEvent.getByToken(electronToken_, electrons);
245 
247  if (computeMiniIso_)
248  iEvent.getByToken(pcToken_, pc);
249 
250  // for additional mva variables
251  edm::InputTag reducedEBRecHitCollection(string("reducedEcalRecHitsEB"));
252  edm::InputTag reducedEERecHitCollection(string("reducedEcalRecHitsEE"));
253  //EcalClusterLazyTools lazyTools(iEvent, iSetup, reducedEBRecHitCollection, reducedEERecHitCollection);
254  EcalClusterLazyTools lazyTools(
256 
257  // for conversion veto selection
259  iEvent.getByToken(hConversionsToken_, hConversions);
260 
261  // Get the ESHandle for the transient track builder, if needed for
262  // high level selection embedding
264 
265  if (isolator_.enabled())
266  isolator_.beginEvent(iEvent, iSetup);
267 
269  efficiencyLoader_.newEvent(iEvent);
271  resolutionLoader_.newEvent(iEvent, iSetup);
272 
274  for (size_t j = 0, nd = isoDepositTokens_.size(); j < nd; ++j) {
275  iEvent.getByToken(isoDepositTokens_[j], deposits[j]);
276  }
277 
279  for (size_t j = 0; j < isolationValueTokens_.size(); ++j) {
281  }
282 
284  for (size_t j = 0; j < isolationValueNoPFIdTokens_.size(); ++j) {
286  }
287 
288  // prepare the MC matching
289  GenAssociations genMatches(genMatchTokens_.size());
290  if (addGenMatch_) {
291  for (size_t j = 0, nd = genMatchTokens_.size(); j < nd; ++j) {
292  iEvent.getByToken(genMatchTokens_[j], genMatches[j]);
293  }
294  }
295 
296  // prepare ID extraction
297  std::vector<edm::Handle<edm::ValueMap<float>>> idhandles;
298  std::vector<pat::Electron::IdPair> ids;
299  if (addElecID_) {
300  idhandles.resize(elecIDSrcs_.size());
301  ids.resize(elecIDSrcs_.size());
302  for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
303  iEvent.getByToken(elecIDTokens_[i], idhandles[i]);
304  ids[i].first = elecIDSrcs_[i].first;
305  }
306  }
307 
308  // prepare the high level selection:
309  // needs beamline
310  reco::TrackBase::Point beamPoint(0, 0, 0);
313  bool beamSpotIsValid = false;
314  bool primaryVertexIsValid = false;
315 
316  // Get the beamspot
317  edm::Handle<reco::BeamSpot> beamSpotHandle;
318  iEvent.getByToken(beamLineToken_, beamSpotHandle);
319 
321  // Get the primary vertex
323  iEvent.getByToken(pvToken_, pvHandle);
324 
325  // This is needed by the IPTools methods from the tracking group
326  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", trackBuilder);
327 
328  if (pvHandle.isValid() && !pvHandle->empty()) {
329  primaryVertex = pvHandle->at(0);
330  primaryVertexIsValid = true;
331  } else {
332  edm::LogError("DataNotAvailable")
333  << "No primary vertex available from EventSetup, not adding high level selection \n";
334  }
335  }
336  //value maps for puppi isolation
337  edm::Handle<edm::ValueMap<float>> PUPPIIsolation_charged_hadrons;
338  edm::Handle<edm::ValueMap<float>> PUPPIIsolation_neutral_hadrons;
339  edm::Handle<edm::ValueMap<float>> PUPPIIsolation_photons;
340  //value maps for puppiNoLeptons isolation
341  edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_charged_hadrons;
342  edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_neutral_hadrons;
343  edm::Handle<edm::ValueMap<float>> PUPPINoLeptonsIsolation_photons;
344  if (addPuppiIsolation_) {
345  //puppi
346  iEvent.getByToken(PUPPIIsolation_charged_hadrons_, PUPPIIsolation_charged_hadrons);
347  iEvent.getByToken(PUPPIIsolation_neutral_hadrons_, PUPPIIsolation_neutral_hadrons);
348  iEvent.getByToken(PUPPIIsolation_photons_, PUPPIIsolation_photons);
349  //puppiNoLeptons
350  iEvent.getByToken(PUPPINoLeptonsIsolation_charged_hadrons_, PUPPINoLeptonsIsolation_charged_hadrons);
351  iEvent.getByToken(PUPPINoLeptonsIsolation_neutral_hadrons_, PUPPINoLeptonsIsolation_neutral_hadrons);
352  iEvent.getByToken(PUPPINoLeptonsIsolation_photons_, PUPPINoLeptonsIsolation_photons);
353  }
354 
355  std::vector<Electron>* patElectrons = new std::vector<Electron>();
356 
357  if (useParticleFlow_) {
359  iEvent.getByToken(pfElecToken_, pfElectrons);
360  unsigned index = 0;
361 
362  for (reco::PFCandidateConstIterator i = pfElectrons->begin(); i != pfElectrons->end(); ++i, ++index) {
363  reco::PFCandidateRef pfRef(pfElectrons, index);
364  reco::PFCandidatePtr ptrToPFElectron(pfElectrons, index);
365  // reco::CandidateBaseRef pfBaseRef( pfRef );
366 
367  reco::GsfTrackRef PfTk = i->gsfTrackRef();
368 
369  bool Matched = false;
370  bool MatchedToAmbiguousGsfTrack = false;
371  for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end();
372  ++itElectron) {
373  unsigned int idx = itElectron - electrons->begin();
374  auto elePtr = electrons->ptrAt(idx);
375  if (Matched || MatchedToAmbiguousGsfTrack)
376  continue;
377 
378  reco::GsfTrackRef EgTk = itElectron->gsfTrack();
379 
380  if (itElectron->gsfTrack() == i->gsfTrackRef()) {
381  Matched = true;
382  } else {
383  for (reco::GsfTrackRefVector::const_iterator it = itElectron->ambiguousGsfTracksBegin();
384  it != itElectron->ambiguousGsfTracksEnd();
385  it++) {
386  MatchedToAmbiguousGsfTrack |= (bool)(i->gsfTrackRef() == (*it));
387  }
388  }
389 
390  if (Matched || MatchedToAmbiguousGsfTrack) {
391  // ptr needed for finding the matched gen particle
392  reco::CandidatePtr ptrToGsfElectron(electrons, idx);
393 
394  // ref to base needed for the construction of the pat object
395  const edm::RefToBase<reco::GsfElectron>& elecsRef = electrons->refAt(idx);
396  Electron anElectron(elecsRef);
397  anElectron.setPFCandidateRef(pfRef);
398  if (addPuppiIsolation_) {
399  anElectron.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[elePtr],
400  (*PUPPIIsolation_neutral_hadrons)[elePtr],
401  (*PUPPIIsolation_photons)[elePtr]);
402  anElectron.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[elePtr],
403  (*PUPPINoLeptonsIsolation_neutral_hadrons)[elePtr],
404  (*PUPPINoLeptonsIsolation_photons)[elePtr]);
405  } else {
406  anElectron.setIsolationPUPPI(-999., -999., -999.);
407  anElectron.setIsolationPUPPINoLeptons(-999., -999., -999.);
408  }
409 
410  //it should be always true when particleFlow electrons are used.
411  anElectron.setIsPF(true);
412 
413  if (embedPFCandidate_)
414  anElectron.embedPFCandidate();
415 
416  if (useUserData_) {
417  userDataHelper_.add(anElectron, iEvent, iSetup);
418  }
419 
420  double ip3d = -999; // for mva variable
421 
422  // embed high level selection
424  // get the global track
425  const reco::GsfTrackRef& track = PfTk;
426 
427  // Make sure the collection it points to is there
428  if (track.isNonnull() && track.isAvailable()) {
429  reco::TransientTrack tt = trackBuilder->build(track);
430  embedHighLevel(anElectron, track, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
431 
432  std::pair<bool, Measurement1D> ip3dpv = IPTools::absoluteImpactParameter3D(tt, primaryVertex);
433  ip3d = ip3dpv.second.value(); // for mva variable
434  }
435  }
436 
437  //Electron Id
438 
439  if (addElecID_) {
440  //STANDARD EL ID
441  for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
442  ids[i].second = (*idhandles[i])[elecsRef];
443  }
444  //SPECIFIC PF ID
445  ids.push_back(std::make_pair("pf_evspi", pfRef->mva_e_pi()));
446  ids.push_back(std::make_pair("pf_evsmu", pfRef->mva_e_mu()));
447  anElectron.setElectronIDs(ids);
448  }
449 
450  if (addMVAVariables_) {
451  // add missing mva variables
452  std::vector<float> vCov = lazyTools.localCovariances(*(itElectron->superCluster()->seed()));
453  anElectron.setMvaVariables(vCov[1], ip3d);
454  }
455  // PFClusterIso
456  if (addPFClusterIso_) {
457  // Get PFCluster Isolation
458  edm::Handle<edm::ValueMap<float>> ecalPFClusterIsoMapH;
459  iEvent.getByToken(ecalPFClusterIsoT_, ecalPFClusterIsoMapH);
460  edm::Handle<edm::ValueMap<float>> hcalPFClusterIsoMapH;
461  iEvent.getByToken(hcalPFClusterIsoT_, hcalPFClusterIsoMapH);
463  newPFIsol.sumEcalClusterEt = (*ecalPFClusterIsoMapH)[elecsRef];
464  newPFIsol.sumHcalClusterEt = (*hcalPFClusterIsoMapH)[elecsRef];
465  anElectron.setPfIsolationVariables(newPFIsol);
466  }
467 
468  std::vector<DetId> selectedCells;
469  bool barrel = itElectron->isEB();
470  //loop over sub clusters
471  if (embedBasicClusters_) {
472  for (reco::CaloCluster_iterator clusIt = itElectron->superCluster()->clustersBegin();
473  clusIt != itElectron->superCluster()->clustersEnd();
474  ++clusIt) {
475  //get seed (max energy xtal)
476  DetId seed = lazyTools.getMaximum(**clusIt).first;
477  //get all xtals in 5x5 window around the seed
478  std::vector<DetId> dets5x5 =
481  selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
482 
483  //get all xtals belonging to cluster
484  for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
485  selectedCells.push_back(hit.first);
486  }
487  }
488  }
489 
490  if (embedPflowBasicClusters_ && itElectron->parentSuperCluster().isNonnull()) {
491  for (reco::CaloCluster_iterator clusIt = itElectron->parentSuperCluster()->clustersBegin();
492  clusIt != itElectron->parentSuperCluster()->clustersEnd();
493  ++clusIt) {
494  //get seed (max energy xtal)
495  DetId seed = lazyTools.getMaximum(**clusIt).first;
496  //get all xtals in 5x5 window around the seed
497  std::vector<DetId> dets5x5 =
500  selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
501 
502  //get all xtals belonging to cluster
503  for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
504  selectedCells.push_back(hit.first);
505  }
506  }
507  }
508 
509  //remove duplicates
510  std::sort(selectedCells.begin(), selectedCells.end());
511  std::unique(selectedCells.begin(), selectedCells.end());
512 
513  // Retrieve the corresponding RecHits
514 
516  if (barrel)
518  else
520 
521  EcalRecHitCollection selectedRecHits;
522  const EcalRecHitCollection* recHits = rechitsH.product();
523 
524  unsigned nSelectedCells = selectedCells.size();
525  for (unsigned icell = 0; icell < nSelectedCells; ++icell) {
526  EcalRecHitCollection::const_iterator it = recHits->find(selectedCells[icell]);
527  if (it != recHits->end()) {
528  selectedRecHits.push_back(*it);
529  }
530  }
531  selectedRecHits.sort();
532  if (embedRecHits_)
533  anElectron.embedRecHits(&selectedRecHits);
534 
535  // set conversion veto selection
536  bool passconversionveto = false;
537  if (hConversions.isValid()) {
538  // this is recommended method
539  passconversionveto =
540  !ConversionTools::hasMatchedConversion(*itElectron, *hConversions, beamSpotHandle->position());
541  } else {
542  // use missing hits without vertex fit method
543  passconversionveto =
544  itElectron->gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) < 1;
545  }
546 
547  anElectron.setPassConversionVeto(passconversionveto);
548 
549  // fillElectron(anElectron,elecsRef,pfBaseRef,
550  // genMatches, deposits, isolationValues);
551 
552  //COLIN small warning !
553  // we are currently choosing to take the 4-momentum of the PFCandidate;
554  // the momentum of the GsfElectron is saved though
555  // we must therefore match the GsfElectron.
556  // because of this, we should not change the source of the electron matcher
557  // to the collection of PFElectrons in the python configuration
558  // I don't know what to do with the efficiencyLoader, since I don't know
559  // what this class is for.
561  anElectron, ptrToPFElectron, ptrToGsfElectron, ptrToGsfElectron, genMatches, deposits, isolationValues);
562 
563  //COLIN need to use fillElectron2 in the non-pflow case as well, and to test it.
564 
565  if (computeMiniIso_)
566  setElectronMiniIso(anElectron, pc.product());
567 
568  patElectrons->push_back(anElectron);
569  }
570  }
571  //if( !Matched && !MatchedToAmbiguousGsfTrack) std::cout << "!!!!A pf electron could not be matched to a gsf!!!!" << std::endl;
572  }
573  }
574 
575  else {
579  bool pfCandsPresent = false, valMapPresent = false;
581  iEvent.getByToken(pfCandidateMultiMapToken_, ValMultiMapH);
582  } else {
583  pfCandsPresent = iEvent.getByToken(pfElecToken_, pfElectrons);
584  valMapPresent = iEvent.getByToken(pfCandidateMapToken_, ValMapH);
585  }
586 
587  for (edm::View<reco::GsfElectron>::const_iterator itElectron = electrons->begin(); itElectron != electrons->end();
588  ++itElectron) {
589  // construct the Electron from the ref -> save ref to original object
590  //FIXME: looks like a lot of instances could be turned into const refs
591  unsigned int idx = itElectron - electrons->begin();
592  edm::RefToBase<reco::GsfElectron> elecsRef = electrons->refAt(idx);
593  reco::CandidateBaseRef elecBaseRef(elecsRef);
594  Electron anElectron(elecsRef);
595  auto elePtr = electrons->ptrAt(idx);
596 
597  // Is this GsfElectron also identified as an e- in the particle flow?
598  bool pfId = false;
599 
601  for (const reco::PFCandidateRef& pf : (*ValMultiMapH)[elePtr]) {
602  if (pf->particleId() == reco::PFCandidate::e) {
603  pfId = true;
604  anElectron.setPFCandidateRef(pf);
605  break;
606  }
607  }
608  } else if (pfCandsPresent) {
609  // PF electron collection not available.
610  const reco::GsfTrackRef& trkRef = itElectron->gsfTrack();
611  int index = 0;
612  for (reco::PFCandidateConstIterator ie = pfElectrons->begin(); ie != pfElectrons->end(); ++ie, ++index) {
613  if (ie->particleId() != reco::PFCandidate::e)
614  continue;
615  const reco::GsfTrackRef& pfTrkRef = ie->gsfTrackRef();
616  if (trkRef == pfTrkRef) {
617  pfId = true;
618  reco::PFCandidateRef pfRef(pfElectrons, index);
619  anElectron.setPFCandidateRef(pfRef);
620  break;
621  }
622  }
623  } else if (valMapPresent) {
624  // use value map if PF collection not available
625  const edm::ValueMap<reco::PFCandidatePtr>& myValMap(*ValMapH);
626  // Get the PFCandidate
627  const reco::PFCandidatePtr& pfElePtr(myValMap[elecsRef]);
628  pfId = pfElePtr.isNonnull();
629  }
630  // set PFId function
631  anElectron.setIsPF(pfId);
632 
633  // add resolution info
634 
635  // Isolation
636  if (isolator_.enabled()) {
637  isolator_.fill(*electrons, idx, isolatorTmpStorage_);
638  typedef pat::helper::MultiIsolator::IsolationValuePairs IsolationValuePairs;
639  // better to loop backwards, so the vector is resized less times
640  for (IsolationValuePairs::const_reverse_iterator it = isolatorTmpStorage_.rbegin(),
641  ed = isolatorTmpStorage_.rend();
642  it != ed;
643  ++it) {
644  anElectron.setIsolation(it->first, it->second);
645  }
646  }
647 
648  for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
649  anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[elecsRef]);
650  }
651 
652  // add electron ID info
653  if (addElecID_) {
654  for (size_t i = 0; i < elecIDSrcs_.size(); ++i) {
655  ids[i].second = (*idhandles[i])[elecsRef];
656  }
657  anElectron.setElectronIDs(ids);
658  }
659 
660  if (useUserData_) {
661  userDataHelper_.add(anElectron, iEvent, iSetup);
662  }
663 
664  double ip3d = -999; //for mva variable
665 
666  // embed high level selection
668  // get the global track
669  reco::GsfTrackRef track = itElectron->gsfTrack();
670 
671  // Make sure the collection it points to is there
672  if (track.isNonnull() && track.isAvailable()) {
673  reco::TransientTrack tt = trackBuilder->build(track);
674  embedHighLevel(anElectron, track, tt, primaryVertex, primaryVertexIsValid, beamSpot, beamSpotIsValid);
675 
676  std::pair<bool, Measurement1D> ip3dpv = IPTools::absoluteImpactParameter3D(tt, primaryVertex);
677  ip3d = ip3dpv.second.value(); // for mva variable
678  }
679  }
680 
681  if (addMVAVariables_) {
682  // add mva variables
683  std::vector<float> vCov = lazyTools.localCovariances(*(itElectron->superCluster()->seed()));
684  anElectron.setMvaVariables(vCov[1], ip3d);
685  }
686 
687  // PFCluster Isolation
688  if (addPFClusterIso_) {
689  // Get PFCluster Isolation
690  edm::Handle<edm::ValueMap<float>> ecalPFClusterIsoMapH;
691  iEvent.getByToken(ecalPFClusterIsoT_, ecalPFClusterIsoMapH);
692  edm::Handle<edm::ValueMap<float>> hcalPFClusterIsoMapH;
693  iEvent.getByToken(hcalPFClusterIsoT_, hcalPFClusterIsoMapH);
695  newPFIsol.sumEcalClusterEt = (*ecalPFClusterIsoMapH)[elecsRef];
696  newPFIsol.sumHcalClusterEt = (*hcalPFClusterIsoMapH)[elecsRef];
697  anElectron.setPfIsolationVariables(newPFIsol);
698  }
699 
700  if (addPuppiIsolation_) {
701  anElectron.setIsolationPUPPI((*PUPPIIsolation_charged_hadrons)[elePtr],
702  (*PUPPIIsolation_neutral_hadrons)[elePtr],
703  (*PUPPIIsolation_photons)[elePtr]);
704  anElectron.setIsolationPUPPINoLeptons((*PUPPINoLeptonsIsolation_charged_hadrons)[elePtr],
705  (*PUPPINoLeptonsIsolation_neutral_hadrons)[elePtr],
706  (*PUPPINoLeptonsIsolation_photons)[elePtr]);
707  } else {
708  anElectron.setIsolationPUPPI(-999., -999., -999.);
709  anElectron.setIsolationPUPPINoLeptons(-999., -999., -999.);
710  }
711 
712  std::vector<DetId> selectedCells;
713  bool barrel = itElectron->isEB();
714  //loop over sub clusters
715  if (embedBasicClusters_) {
716  for (reco::CaloCluster_iterator clusIt = itElectron->superCluster()->clustersBegin();
717  clusIt != itElectron->superCluster()->clustersEnd();
718  ++clusIt) {
719  //get seed (max energy xtal)
720  DetId seed = lazyTools.getMaximum(**clusIt).first;
721  //get all xtals in 5x5 window around the seed
722  std::vector<DetId> dets5x5 =
725  selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
726 
727  //get all xtals belonging to cluster
728  for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
729  selectedCells.push_back(hit.first);
730  }
731  }
732  }
733 
734  if (embedPflowBasicClusters_ && itElectron->parentSuperCluster().isNonnull()) {
735  for (reco::CaloCluster_iterator clusIt = itElectron->parentSuperCluster()->clustersBegin();
736  clusIt != itElectron->parentSuperCluster()->clustersEnd();
737  ++clusIt) {
738  //get seed (max energy xtal)
739  DetId seed = lazyTools.getMaximum(**clusIt).first;
740  //get all xtals in 5x5 window around the seed
741  std::vector<DetId> dets5x5 =
744  selectedCells.insert(selectedCells.end(), dets5x5.begin(), dets5x5.end());
745 
746  //get all xtals belonging to cluster
747  for (const std::pair<DetId, float>& hit : (*clusIt)->hitsAndFractions()) {
748  selectedCells.push_back(hit.first);
749  }
750  }
751  }
752 
753  //remove duplicates
754  std::sort(selectedCells.begin(), selectedCells.end());
755  std::unique(selectedCells.begin(), selectedCells.end());
756 
757  // Retrieve the corresponding RecHits
758 
760  if (barrel)
762  else
764 
765  EcalRecHitCollection selectedRecHits;
766  const EcalRecHitCollection* recHits = rechitsH.product();
767 
768  unsigned nSelectedCells = selectedCells.size();
769  for (unsigned icell = 0; icell < nSelectedCells; ++icell) {
770  EcalRecHitCollection::const_iterator it = recHits->find(selectedCells[icell]);
771  if (it != recHits->end()) {
772  selectedRecHits.push_back(*it);
773  }
774  }
775  selectedRecHits.sort();
776  if (embedRecHits_)
777  anElectron.embedRecHits(&selectedRecHits);
778 
779  // set conversion veto selection
780  bool passconversionveto = false;
781  if (hConversions.isValid()) {
782  // this is recommended method
783  passconversionveto =
784  !ConversionTools::hasMatchedConversion(*itElectron, *hConversions, beamSpotHandle->position());
785  } else {
786  // use missing hits without vertex fit method
787  passconversionveto =
788  itElectron->gsfTrack()->hitPattern().numberOfLostHits(reco::HitPattern::MISSING_INNER_HITS) < 1;
789  }
790  anElectron.setPassConversionVeto(passconversionveto);
791 
792  // add sel to selected
793  fillElectron(
794  anElectron, elecsRef, elecBaseRef, genMatches, deposits, pfId, isolationValues, isolationValuesNoPFId);
795 
796  if (computeMiniIso_)
797  setElectronMiniIso(anElectron, pc.product());
798 
799  patElectrons->push_back(anElectron);
800  }
801  }
802 
803  // sort electrons in pt
804  std::sort(patElectrons->begin(), patElectrons->end(), pTComparator_);
805 
806  // add the electrons to the event output
807  std::unique_ptr<std::vector<Electron>> ptr(patElectrons);
808  iEvent.put(std::move(ptr));
809 
810  // clean up
811  if (isolator_.enabled())
813 }
814 
816  const edm::RefToBase<reco::GsfElectron>& elecRef,
817  const reco::CandidateBaseRef& baseRef,
818  const GenAssociations& genMatches,
819  const IsoDepositMaps& deposits,
820  const bool pfId,
823  //COLIN: might want to use the PFCandidate 4-mom. Which one is in use now?
824  // if (useParticleFlow_)
825  // aMuon.setP4( aMuon.pfCandidateRef()->p4() );
826 
827  //COLIN:
828  //In the embedding case, the reference cannot be used to look into a value map.
829  //therefore, one has to had the PFCandidateRef to this function, which becomes a bit
830  //too much specific.
831 
832  // in fact, this function needs a baseref or ptr for genmatch
833  // and a baseref or ptr for isodeposits and isolationvalues.
834  // baseref is not needed
835  // the ptrForIsolation and ptrForMatching should be defined upstream.
836 
837  // is the concrete elecRef needed for the efficiency loader? what is this loader?
838  // how can we make it compatible with the particle flow electrons?
839 
841  anElectron.embedGsfElectronCore();
842  if (embedGsfTrack_)
843  anElectron.embedGsfTrack();
844  if (embedSuperCluster_)
845  anElectron.embedSuperCluster();
847  anElectron.embedPflowSuperCluster();
848  if (embedSeedCluster_)
849  anElectron.embedSeedCluster();
851  anElectron.embedBasicClusters();
853  anElectron.embedPreshowerClusters();
855  anElectron.embedPflowBasicClusters();
857  anElectron.embedPflowPreshowerClusters();
858  if (embedTrack_)
859  anElectron.embedTrack();
860 
861  // store the match to the generated final state muons
862  if (addGenMatch_) {
863  for (size_t i = 0, n = genMatches.size(); i < n; ++i) {
864  if (useParticleFlow_) {
865  reco::GenParticleRef genElectron = (*genMatches[i])[anElectron.pfCandidateRef()];
866  anElectron.addGenParticleRef(genElectron);
867  } else {
868  reco::GenParticleRef genElectron = (*genMatches[i])[elecRef];
869  anElectron.addGenParticleRef(genElectron);
870  }
871  }
872  if (embedGenMatch_)
873  anElectron.embedGenParticle();
874  }
875 
876  if (efficiencyLoader_.enabled()) {
877  efficiencyLoader_.setEfficiencies(anElectron, elecRef);
878  }
879 
880  if (resolutionLoader_.enabled()) {
881  resolutionLoader_.setResolutions(anElectron);
882  }
883 
884  for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
885  if (useParticleFlow_) {
886  reco::PFCandidateRef pfcandref = anElectron.pfCandidateRef();
887  assert(!pfcandref.isNull());
888  reco::CandidatePtr source = pfcandref->sourceCandidatePtr(0);
889  anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[source]);
890  } else
891  anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[elecRef]);
892  }
893 
894  for (size_t j = 0; j < isolationValues.size(); ++j) {
895  if (useParticleFlow_) {
896  reco::CandidatePtr source = anElectron.pfCandidateRef()->sourceCandidatePtr(0);
897  anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[source]);
898  } else if (pfId) {
899  anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[elecRef]);
900  }
901  }
902 
903  //for electrons not identified as PF electrons
904  for (size_t j = 0; j < isolationValuesNoPFId.size(); ++j) {
905  if (!pfId) {
906  anElectron.setIsolation(isolationValueLabelsNoPFId_[j].first, (*isolationValuesNoPFId[j])[elecRef]);
907  }
908  }
909 }
910 
912  const reco::CandidatePtr& candPtrForIsolation,
913  const reco::CandidatePtr& candPtrForGenMatch,
914  const reco::CandidatePtr& candPtrForLoader,
915  const GenAssociations& genMatches,
916  const IsoDepositMaps& deposits,
917  const IsolationValueMaps& isolationValues) const {
918  //COLIN/Florian: use the PFCandidate 4-mom.
919  anElectron.setEcalDrivenMomentum(anElectron.p4());
920  anElectron.setP4(anElectron.pfCandidateRef()->p4());
921 
922  // is the concrete elecRef needed for the efficiency loader? what is this loader?
923  // how can we make it compatible with the particle flow electrons?
924 
926  anElectron.embedGsfElectronCore();
927  if (embedGsfTrack_)
928  anElectron.embedGsfTrack();
929  if (embedSuperCluster_)
930  anElectron.embedSuperCluster();
932  anElectron.embedPflowSuperCluster();
933  if (embedSeedCluster_)
934  anElectron.embedSeedCluster();
936  anElectron.embedBasicClusters();
938  anElectron.embedPreshowerClusters();
940  anElectron.embedPflowBasicClusters();
942  anElectron.embedPflowPreshowerClusters();
943  if (embedTrack_)
944  anElectron.embedTrack();
945 
946  // store the match to the generated final state muons
947 
948  if (addGenMatch_) {
949  for (size_t i = 0, n = genMatches.size(); i < n; ++i) {
950  reco::GenParticleRef genElectron = (*genMatches[i])[candPtrForGenMatch];
951  anElectron.addGenParticleRef(genElectron);
952  }
953  if (embedGenMatch_)
954  anElectron.embedGenParticle();
955  }
956 
957  //COLIN what's this? does it have to be GsfElectron specific?
958  if (efficiencyLoader_.enabled()) {
959  efficiencyLoader_.setEfficiencies(anElectron, candPtrForLoader);
960  }
961 
962  if (resolutionLoader_.enabled()) {
963  resolutionLoader_.setResolutions(anElectron);
964  }
965 
966  for (size_t j = 0, nd = deposits.size(); j < nd; ++j) {
968  isoDepositLabels_[j].first == pat::HcalIso || deposits[j]->contains(candPtrForGenMatch.id())) {
969  anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForGenMatch]);
970  } else if (deposits[j]->contains(candPtrForIsolation.id())) {
971  anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForIsolation]);
972  } else {
973  anElectron.setIsoDeposit(isoDepositLabels_[j].first, (*deposits[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
974  }
975  }
976 
977  for (size_t j = 0; j < isolationValues.size(); ++j) {
979  isolationValueLabels_[j].first == pat::HcalIso || isolationValues[j]->contains(candPtrForGenMatch.id())) {
980  anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[candPtrForGenMatch]);
981  } else if (isolationValues[j]->contains(candPtrForIsolation.id())) {
982  anElectron.setIsolation(isolationValueLabels_[j].first, (*isolationValues[j])[candPtrForIsolation]);
983  } else {
985  (*isolationValues[j])[candPtrForIsolation->sourceCandidatePtr(0)]);
986  }
987  }
988 }
989 
991  pat::PFIsolation miniiso;
992  if (anElectron.isEE())
993  miniiso = pat::getMiniPFIsolation(pc,
994  anElectron.p4(),
995  miniIsoParamsE_[0],
996  miniIsoParamsE_[1],
997  miniIsoParamsE_[2],
998  miniIsoParamsE_[3],
999  miniIsoParamsE_[4],
1000  miniIsoParamsE_[5],
1001  miniIsoParamsE_[6],
1002  miniIsoParamsE_[7],
1003  miniIsoParamsE_[8]);
1004  else
1005  miniiso = pat::getMiniPFIsolation(pc,
1006  anElectron.p4(),
1007  miniIsoParamsB_[0],
1008  miniIsoParamsB_[1],
1009  miniIsoParamsB_[2],
1010  miniIsoParamsB_[3],
1011  miniIsoParamsB_[4],
1012  miniIsoParamsB_[5],
1013  miniIsoParamsB_[6],
1014  miniIsoParamsB_[7],
1015  miniIsoParamsB_[8]);
1016  anElectron.setMiniPFIsolation(miniiso);
1017 }
1018 
1019 // ParameterSet description for module
1022  iDesc.setComment("PAT electron producer module");
1023 
1024  // input source
1025  iDesc.add<edm::InputTag>("pfCandidateMap", edm::InputTag("no default"))->setComment("input collection");
1026  iDesc.add<edm::InputTag>("electronSource", edm::InputTag("no default"))->setComment("input collection");
1027 
1028  iDesc.ifValue(
1029  edm::ParameterDescription<bool>("addPFClusterIso", false, true),
1031  "ecalPFClusterIsoMap", edm::InputTag("electronEcalPFClusterIsolationProducer"), true) and
1033  "hcalPFClusterIsoMap", edm::InputTag("electronHcalPFClusterIsolationProducer"), true)) or
1034  false >> (edm::ParameterDescription<edm::InputTag>("ecalPFClusterIsoMap", edm::InputTag(""), true) and
1035  edm::ParameterDescription<edm::InputTag>("hcalPFClusterIsoMap", edm::InputTag(""), true)));
1036 
1037  iDesc.ifValue(edm::ParameterDescription<bool>("addPuppiIsolation", false, true),
1039  "puppiIsolationChargedHadrons",
1040  edm::InputTag("egmElectronPUPPIIsolation", "h+-DR030-BarVeto000-EndVeto001"),
1041  true) and
1043  "puppiIsolationNeutralHadrons",
1044  edm::InputTag("egmElectronPUPPIIsolation", "h0-DR030-BarVeto000-EndVeto000"),
1045  true) and
1047  "puppiIsolationPhotons",
1048  edm::InputTag("egmElectronPUPPIIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1049  true) and
1051  "puppiNoLeptonsIsolationChargedHadrons",
1052  edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1053  true) and
1055  "puppiNoLeptonsIsolationNeutralHadrons",
1056  edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1057  true) and
1059  "puppiNoLeptonsIsolationPhotons",
1060  edm::InputTag("egmElectronPUPPINoLeptonsIsolation", "gamma-DR030-BarVeto000-EndVeto008"),
1061  true)) or
1062  false >> edm::EmptyGroupDescription());
1063 
1064  // embedding
1065  iDesc.add<bool>("embedGsfElectronCore", true)->setComment("embed external gsf electron core");
1066  iDesc.add<bool>("embedGsfTrack", true)->setComment("embed external gsf track");
1067  iDesc.add<bool>("embedSuperCluster", true)->setComment("embed external super cluster");
1068  iDesc.add<bool>("embedPflowSuperCluster", true)->setComment("embed external super cluster");
1069  iDesc.add<bool>("embedSeedCluster", true)->setComment("embed external seed cluster");
1070  iDesc.add<bool>("embedBasicClusters", true)->setComment("embed external basic clusters");
1071  iDesc.add<bool>("embedPreshowerClusters", true)->setComment("embed external preshower clusters");
1072  iDesc.add<bool>("embedPflowBasicClusters", true)->setComment("embed external pflow basic clusters");
1073  iDesc.add<bool>("embedPflowPreshowerClusters", true)->setComment("embed external pflow preshower clusters");
1074  iDesc.add<bool>("embedTrack", false)->setComment("embed external track");
1075  iDesc.add<bool>("embedRecHits", true)->setComment("embed external RecHits");
1076 
1077  // pf specific parameters
1078  iDesc.add<edm::InputTag>("pfElectronSource", edm::InputTag("pfElectrons"))
1079  ->setComment("particle flow input collection");
1080  auto&& usePfCandidateMultiMap = edm::ParameterDescription<bool>("usePfCandidateMultiMap", false, true);
1081  usePfCandidateMultiMap.setComment(
1082  "take ParticleFlow candidates from pfCandidateMultiMap instead of matching to pfElectrons by Gsf track "
1083  "reference");
1085  true >> edm::ParameterDescription<edm::InputTag>("pfCandidateMultiMap", true) or
1086  false >> edm::EmptyGroupDescription());
1087  iDesc.add<bool>("useParticleFlow", false)->setComment("whether to use particle flow or not");
1088  iDesc.add<bool>("embedPFCandidate", false)->setComment("embed external particle flow object");
1089 
1090  // MC matching configurables
1091  iDesc.add<bool>("addGenMatch", true)->setComment("add MC matching");
1092  iDesc.add<bool>("embedGenMatch", false)->setComment("embed MC matched MC information");
1093  std::vector<edm::InputTag> emptySourceVector;
1094  iDesc
1095  .addNode(edm::ParameterDescription<edm::InputTag>("genParticleMatch", edm::InputTag(), true) xor
1096  edm::ParameterDescription<std::vector<edm::InputTag>>("genParticleMatch", emptySourceVector, true))
1097  ->setComment("input with MC match information");
1098 
1099  // electron ID configurables
1100  iDesc.add<bool>("addElectronID", true)->setComment("add electron ID variables");
1101  edm::ParameterSetDescription electronIDSourcesPSet;
1102  electronIDSourcesPSet.setAllowAnything();
1103  iDesc
1104  .addNode(
1105  edm::ParameterDescription<edm::InputTag>("electronIDSource", edm::InputTag(), true) xor
1106  edm::ParameterDescription<edm::ParameterSetDescription>("electronIDSources", electronIDSourcesPSet, true))
1107  ->setComment("input with electron ID variables");
1108 
1109  // mini-iso
1110  iDesc.add<bool>("computeMiniIso", false)->setComment("whether or not to compute and store electron mini-isolation");
1111  iDesc.add<edm::InputTag>("pfCandsForMiniIso", edm::InputTag("packedPFCandidates"))
1112  ->setComment("collection to use to compute mini-iso");
1113  iDesc.add<std::vector<double>>("miniIsoParamsE", std::vector<double>())
1114  ->setComment("mini-iso parameters to use for endcap electrons");
1115  iDesc.add<std::vector<double>>("miniIsoParamsB", std::vector<double>())
1116  ->setComment("mini-iso parameters to use for barrel electrons");
1117 
1118  // IsoDeposit configurables
1119  edm::ParameterSetDescription isoDepositsPSet;
1120  isoDepositsPSet.addOptional<edm::InputTag>("tracker");
1121  isoDepositsPSet.addOptional<edm::InputTag>("ecal");
1122  isoDepositsPSet.addOptional<edm::InputTag>("hcal");
1123  isoDepositsPSet.addOptional<edm::InputTag>("pfAllParticles");
1124  isoDepositsPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1125  isoDepositsPSet.addOptional<edm::InputTag>("pfChargedAll");
1126  isoDepositsPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1127  isoDepositsPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1128  isoDepositsPSet.addOptional<edm::InputTag>("pfPhotons");
1129  isoDepositsPSet.addOptional<std::vector<edm::InputTag>>("user");
1130  iDesc.addOptional("isoDeposits", isoDepositsPSet);
1131 
1132  // isolation values configurables
1133  edm::ParameterSetDescription isolationValuesPSet;
1134  isolationValuesPSet.addOptional<edm::InputTag>("tracker");
1135  isolationValuesPSet.addOptional<edm::InputTag>("ecal");
1136  isolationValuesPSet.addOptional<edm::InputTag>("hcal");
1137  isolationValuesPSet.addOptional<edm::InputTag>("pfAllParticles");
1138  isolationValuesPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1139  isolationValuesPSet.addOptional<edm::InputTag>("pfChargedAll");
1140  isolationValuesPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1141  isolationValuesPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1142  isolationValuesPSet.addOptional<edm::InputTag>("pfPhotons");
1143  isolationValuesPSet.addOptional<std::vector<edm::InputTag>>("user");
1144  iDesc.addOptional("isolationValues", isolationValuesPSet);
1145 
1146  // isolation values configurables
1147  edm::ParameterSetDescription isolationValuesNoPFIdPSet;
1148  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("tracker");
1149  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("ecal");
1150  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("hcal");
1151  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfAllParticles");
1152  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfChargedHadrons");
1153  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfChargedAll");
1154  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfPUChargedHadrons");
1155  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfNeutralHadrons");
1156  isolationValuesNoPFIdPSet.addOptional<edm::InputTag>("pfPhotons");
1157  isolationValuesNoPFIdPSet.addOptional<std::vector<edm::InputTag>>("user");
1158  iDesc.addOptional("isolationValuesNoPFId", isolationValuesNoPFIdPSet);
1159 
1160  // Efficiency configurables
1161  edm::ParameterSetDescription efficienciesPSet;
1162  efficienciesPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
1163  iDesc.add("efficiencies", efficienciesPSet);
1164  iDesc.add<bool>("addEfficiencies", false);
1165 
1166  // Check to see if the user wants to add user data
1167  edm::ParameterSetDescription userDataPSet;
1169  iDesc.addOptional("userData", userDataPSet);
1170 
1171  // electron shapes
1172  iDesc.add<bool>("addMVAVariables", true)->setComment("embed extra variables in pat::Electron : sip3d, sigmaIEtaIPhi");
1173  iDesc.add<edm::InputTag>("reducedBarrelRecHitCollection", edm::InputTag("reducedEcalRecHitsEB"));
1174  iDesc.add<edm::InputTag>("reducedEndcapRecHitCollection", edm::InputTag("reducedEcalRecHitsEE"));
1175 
1176  edm::ParameterSetDescription isolationPSet;
1177  isolationPSet.setAllowAnything(); // TODO: the pat helper needs to implement a description.
1178  iDesc.add("userIsolation", isolationPSet);
1179 
1180  // Resolution configurables
1182 
1183  iDesc.add<bool>("embedHighLevelSelection", true)->setComment("embed high level selection");
1184  edm::ParameterSetDescription highLevelPSet;
1185  highLevelPSet.setAllowAnything();
1186  iDesc.addNode(edm::ParameterDescription<edm::InputTag>("beamLineSrc", edm::InputTag(), true))
1187  ->setComment("input with high level selection");
1189  ->setComment("input with high level selection");
1190 
1191  descriptions.add("PATElectronProducer", iDesc);
1192 }
1193 
1194 // embed various impact parameters with errors
1195 // embed high level selection
1200  bool primaryVertexIsValid,
1202  bool beamspotIsValid) {
1203  // Correct to PV
1204 
1205  // PV2D
1206  std::pair<bool, Measurement1D> result =
1207  IPTools::signedTransverseImpactParameter(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex);
1208  double d0_corr = result.second.value();
1209  double d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
1210  anElectron.setDB(d0_corr, d0_err, pat::Electron::PV2D);
1211 
1212  // PV3D
1213  result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), primaryVertex);
1214  d0_corr = result.second.value();
1215  d0_err = primaryVertexIsValid ? result.second.error() : -1.0;
1216  anElectron.setDB(d0_corr, d0_err, pat::Electron::PV3D);
1217 
1218  // Correct to beam spot
1219  // make a fake vertex out of beam spot
1220  reco::Vertex vBeamspot(beamspot.position(), beamspot.covariance3D());
1221 
1222  // BS2D
1223  result = IPTools::signedTransverseImpactParameter(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot);
1224  d0_corr = result.second.value();
1225  d0_err = beamspotIsValid ? result.second.error() : -1.0;
1226  anElectron.setDB(d0_corr, d0_err, pat::Electron::BS2D);
1227 
1228  // BS3D
1229  result = IPTools::signedImpactParameter3D(tt, GlobalVector(track->px(), track->py(), track->pz()), vBeamspot);
1230  d0_corr = result.second.value();
1231  d0_err = beamspotIsValid ? result.second.error() : -1.0;
1232  anElectron.setDB(d0_corr, d0_err, pat::Electron::BS3D);
1233 
1234  // PVDZ
1235  anElectron.setDB(
1236  track->dz(primaryVertex.position()), std::hypot(track->dzError(), primaryVertex.zError()), pat::Electron::PVDZ);
1237 }
1238 
1240 
const PflowIsolationVariables & pfIsolationVariables() const
Definition: GsfElectron.h:650
void readIsolationLabels(const edm::ParameterSet &iConfig, const char *psetName, IsolationLabels &labels, std::vector< edm::EDGetTokenT< edm::ValueMap< T > > > &tokens)
void setMvaVariables(double sigmaIetaIphi, double ip3d)
set missing mva input variables
bool enabled() const
&#39;true&#39; if this there is at least one efficiency configured
T getParameter(std::string const &) const
void setComment(std::string const &value)
Assists in assimilating all pat::UserData into pat objects.
ParameterDescriptionNode * ifValue(ParameterDescription< T > const &switchParameter, std::unique_ptr< ParameterDescriptionCases< T >> cases)
void embedRecHits(const EcalRecHitCollection *rechits)
method to store the RecHits internally - can be called from the PATElectronProducer ...
void newEvent(const edm::Event &event)
To be called for each new event, reads in the ValueMaps for efficiencies.
void setP4(P4Kind kind, const LorentzVector &p4, float p4Error, bool setCandidate)
Definition: GsfElectron.cc:188
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:131
ParameterDescriptionBase * addOptional(U const &iLabel, T const &value)
const edm::EDGetTokenT< reco::ConversionCollection > hConversionsToken_
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:238
edm::EDGetTokenT< edm::ValueMap< float > > PUPPINoLeptonsIsolation_charged_hadrons_
void setIsolation(IsolationKeys key, float value)
Definition: Lepton.h:115
const GreaterByPt< Electron > pTComparator_
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:160
bool contains(EventRange const &lh, EventID const &rh)
Definition: EventRange.cc:37
edm::EDGetTokenT< edm::ValueMap< float > > PUPPIIsolation_charged_hadrons_
const bool useParticleFlow_
pflow specific
void setElectronIDs(const std::vector< IdPair > &ids)
Store multiple electron ID values, discarding existing ones. The first one in the list becomes the &#39;d...
Definition: Electron.h:141
Covariance3DMatrix covariance3D() const
return only 3D position covariance matrix
Definition: BeamSpot.h:112
const LorentzVector & p4(P4Kind kind) const
Definition: GsfElectron.cc:211
const edm::EDGetTokenT< reco::PFCandidateCollection > pfElecToken_
std::vector< double > miniIsoParamsE_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:525
void setAllowAnything()
allow any parameter label/value pairs
double zError() const
error on z
Definition: Vertex.h:127
edm::EDGetTokenT< edm::ValueMap< float > > PUPPIIsolation_neutral_hadrons_
const edm::EDGetTokenT< edm::ValueMap< float > > ecalPFClusterIsoT_
std::pair< bool, Measurement1D > signedTransverseImpactParameter(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:57
void embedSuperCluster()
method to store the electron&#39;s SuperCluster internally
std::vector< pat::PackedCandidate > PackedCandidateCollection
void embedHighLevel(pat::Electron &anElectron, reco::GsfTrackRef track, reco::TransientTrack &tt, reco::Vertex &primaryVertex, bool primaryVertexIsValid, reco::BeamSpot &beamspot, bool beamspotIsValid)
std::vector< EcalRecHit >::const_iterator const_iterator
reco::TransientTrack build(const reco::Track *p) const
std::pair< bool, Measurement1D > absoluteImpactParameter3D(const reco::TransientTrack &transientTrack, const reco::Vertex &vertex)
Definition: IPTools.cc:38
void setPFCandidateRef(const reco::PFCandidateRef &ref)
add a reference to the source IsolatedPFCandidate
Definition: Electron.h:179
void fillElectron(Electron &aElectron, const ElectronBaseRef &electronRef, const reco::CandidateBaseRef &baseRef, const GenAssociations &genMatches, const IsoDepositMaps &deposits, const bool pfId, const IsolationValueMaps &isolationValues, const IsolationValueMaps &isolationValuesNoPFId) const
common electron filling, for both the standard and PF2PAT case
void push_back(T const &t)
ParameterDescriptionNode * addNode(ParameterDescriptionNode const &node)
std::pair< bool, Measurement1D > signedImpactParameter3D(const reco::TransientTrack &track, const GlobalVector &direction, const reco::Vertex &vertex)
Definition: IPTools.cc:81
void embedGsfElectronCore()
method to store the electron&#39;s core internally
void setPassConversionVeto(bool flag)
Definition: Electron.h:257
const edm::EDGetTokenT< edm::ValueMap< float > > hcalPFClusterIsoT_
PFCandidateCollection::const_iterator PFCandidateConstIterator
iterator
void setEcalDrivenMomentum(const Candidate::LorentzVector &mom)
Definition: Electron.h:204
void setResolutions(pat::PATObject< T > &obj) const
Sets the efficiencies for this object, using the reference to the original objects.
std::vector< edm::EDGetTokenT< edm::ValueMap< float > > > elecIDTokens_
void setPfIsolationVariables(const PflowIsolationVariables &iso)
Definition: GsfElectron.h:659
bool isRealData() const
Definition: EventBase.h:62
const Point & position() const
position
Definition: Vertex.h:113
const std::string names[nVars_]
bool isAvailable() const
Definition: Ref.h:537
bool isEE() const
Definition: GsfElectron.h:329
const edm::EDGetTokenT< edm::View< reco::GsfElectron > > electronToken_
const bool addMVAVariables_
mva input variables
std::vector< double > miniIsoParamsB_
void embedPflowSuperCluster()
method to store the electron&#39;s PflowSuperCluster internally
bool enabled() const
&#39;true&#39; if this there is at least one efficiency configured
void setIsoDeposit(IsolationKeys key, const IsoDeposit &dep)
Sets the IsoDeposit associated with some key; if it is already existent, it is overwritten.
Definition: Lepton.h:191
Definition: HeavyIon.h:7
static void fillDescription(edm::ParameterSetDescription &iDesc)
std::vector< std::string > getParameterNamesForType(bool trackiness=true) const
Definition: ParameterSet.h:168
const edm::EDGetTokenT< std::vector< reco::Vertex > > pvToken_
bool enabled() const
True if it has a non null configuration.
Definition: MultiIsolator.h:55
const edm::EDGetTokenT< edm::ValueMap< reco::PFCandidatePtr > > pfCandidateMapToken_
void setComment(std::string const &value)
pat::helper::MultiIsolator isolator_
std::vector< edm::Handle< edm::Association< reco::GenParticleCollection > > > GenAssociations
void setDB(double dB, double edB, IPTYPE type)
Set impact parameter of a certain type and its uncertainty.
edm::EDGetTokenT< edm::ValueMap< float > > PUPPIIsolation_photons_
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void beginEvent(const edm::Event &event, const edm::EventSetup &eventSetup)
Produces pat::Electron&#39;s.
void embedSeedCluster()
method to store the electron&#39;s seedcluster internally
PATElectronProducer(const edm::ParameterSet &iConfig)
const bool embedHighLevelSelection_
embed high level selection variables?
reco::PFCandidateRef pfCandidateRef() const
reference to the source PFCandidates; null if this has been built from a standard electron ...
void embedGenParticle()
Definition: PATObject.h:773
void newEvent(const edm::Event &event, const edm::EventSetup &setup)
To be called for each new event, reads in the EventSetup object.
std::vector< edm::EDGetTokenT< edm::Association< reco::GenParticleCollection > > > genMatchTokens_
static bool hasMatchedConversion(const reco::GsfElectron &ele, const reco::ConversionCollection &convCol, const math::XYZPoint &beamspot, bool allowCkfMatch=true, float lxyMin=2.0, float probMin=1e-6, unsigned int nHitsBeforeVtxMax=0)
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
def unique(seq, keepstr=True)
Definition: tier0.py:24
void setIsolationPUPPINoLeptons(float chargedhadrons_, float neutralhadrons_, float photons_)
sets PUPPINoLeptons isolations
Definition: Electron.h:167
std::vector< edm::Handle< edm::ValueMap< IsoDeposit > > > IsoDepositMaps
std::vector< edm::EDGetTokenT< edm::ValueMap< IsoDeposit > > > isoDepositTokens_
edm::EDGetTokenT< edm::ValueMap< float > > PUPPINoLeptonsIsolation_neutral_hadrons_
const edm::EDGetTokenT< EcalRecHitCollection > reducedEndcapRecHitCollectionToken_
math::XYZPoint Point
point in the space
Definition: TrackBase.h:80
void embedPflowBasicClusters()
method to store the electron&#39;s pflow basic clusters
edm::Ref< PFCandidateCollection > PFCandidateRef
persistent reference to a PFCandidate
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void embedBasicClusters()
method to store the electron&#39;s basic clusters
bool isValid() const
Definition: HandleBase.h:70
std::pair< std::string, edm::InputTag > NameTag
edm::EDGetTokenT< edm::ValueMap< float > > PUPPINoLeptonsIsolation_photons_
bool isNull() const
Checks for null.
Definition: Ref.h:235
std::vector< edm::Handle< edm::ValueMap< double > > > IsolationValueMaps
void embedGsfTrack()
method to store the electron&#39;s GsfTrack internally
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override
bool isNonnull() const
Checks for non-null.
Definition: Ptr.h:146
std::vector< Conversion > ConversionCollection
Definition: Conversion.h:13
const_iterator end() const
Definition: DetId.h:17
std::vector< reco::PFCandidate > PFCandidateCollection
collection of PFCandidates
std::vector< std::pair< pat::IsolationKeys, float > > IsolationValuePairs
Definition: MultiIsolator.h:17
const edm::EDGetTokenT< reco::BeamSpot > beamLineToken_
void fillElectron2(Electron &anElectron, const reco::CandidatePtr &candPtrForIsolation, const reco::CandidatePtr &candPtrForGenMatch, const reco::CandidatePtr &candPtrForLoader, const GenAssociations &genMatches, const IsoDepositMaps &deposits, const IsolationValueMaps &isolationValues) const
void addGenParticleRef(const reco::GenParticleRef &ref)
Definition: PATObject.h:756
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
Definition: transform.h:11
std::vector< edm::EDGetTokenT< edm::ValueMap< double > > > isolationValueNoPFIdTokens_
virtual std::vector< DetId > getWindow(const DetId &id, const int &northSouthSize, const int &eastWestSize) const
T const * product() const
Definition: Handle.h:69
static void fillDescription(edm::ParameterSetDescription &iDesc)
Method for documentation and validation of PSet.
pat::helper::EfficiencyLoader efficiencyLoader_
const edm::EDGetTokenT< EcalRecHitCollection > reducedBarrelRecHitCollectionToken_
void setIsPF(bool hasPFCandidate)
Definition: Electron.h:174
const edm::EDGetTokenT< edm::ValueMap< std::vector< reco::PFCandidateRef > > > pfCandidateMultiMapToken_
pat::PATUserDataHelper< pat::Electron > userDataHelper_
void setEfficiencies(pat::PATObject< T > &obj, const R &originalRef) const
Sets the efficiencies for this object, using the reference to the original objects.
Analysis-level electron class.
Definition: Electron.h:51
const CaloTopology * ecalTopology_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
const CaloSubdetectorTopology * getSubdetectorTopology(const DetId &id) const
access the subdetector Topology for the given subdetector directly
Definition: CaloTopology.cc:17
void setMiniPFIsolation(PFIsolation const &iso)
Definition: Lepton.h:217
ProductID id() const
Accessor for product ID.
Definition: Ptr.h:158
IsolationLabels isolationValueLabelsNoPFId_
void setElectronMiniIso(pat::Electron &anElectron, const pat::PackedCandidateCollection *pc)
void embedPreshowerClusters()
method to store the electron&#39;s preshower clusters
iterator find(key_type k)
fixed size matrix
HLT enums.
boost::indirect_iterator< typename seq_t::const_iterator > const_iterator
Definition: View.h:86
IsolationLabels isolationValueLabels_
PFIsolation getMiniPFIsolation(const pat::PackedCandidateCollection *pfcands, const math::XYZTLorentzVector &p4, float mindr=0.05, float maxdr=0.2, float kt_scale=10.0, float ptthresh=0.5, float deadcone_ch=0.0001, float deadcone_pu=0.01, float deadcone_ph=0.01, float deadcone_nh=0.01, float dZ_cut=0.0)
T get() const
Definition: EventSetup.h:73
pat::helper::KinResolutionsLoader resolutionLoader_
const Point & position() const
position
Definition: BeamSpot.h:59
void embedPflowPreshowerClusters()
method to store the electron&#39;s pflow preshower clusters
std::vector< edm::EDGetTokenT< edm::ValueMap< double > > > isolationValueTokens_
void embedTrack()
method to store the electron&#39;s Track internally
pat::helper::MultiIsolator::IsolationValuePairs isolatorTmpStorage_
primaryVertex
hltOfflineBeamSpot for HLTMON
edm::Ptr< PFCandidate > PFCandidatePtr
persistent Ptr to a PFCandidate
void setIsolationPUPPI(float chargedhadrons_, float neutralhadrons_, float photons_)
sets PUPPI isolations
Definition: Electron.h:161
static std::string const source
Definition: EdmProvDump.cc:47
edm::EDGetTokenT< pat::PackedCandidateCollection > pcToken_
def move(src, dest)
Definition: eostools.py:511
void embedPFCandidate()
embed the PFCandidate pointed to by pfCandidateRef_
Global3DVector GlobalVector
Definition: GlobalVector.h:10
std::vector< NameTag > elecIDSrcs_
void fill(const edm::View< T > &coll, int idx, IsolationValuePairs &isolations) const
Definition: MultiIsolator.h:84