CMS 3D CMS Logo

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