CMS 3D CMS Logo

PFElecTkProducer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: PFTracking
4 // Class: PFElecTkProducer
5 //
6 // Original Author: Michele Pioppi
7 // Created: Tue Jan 23 15:26:39 CET 2007
8 
9 
10 
11 // system include files
12 #include <memory>
13 
14 // user include files
36 
37 #include "TMath.h"
38 using namespace std;
39 using namespace edm;
40 using namespace reco;
42  conf_(iConfig)
43 {
44 
45 
46  gsfTrackLabel_ = consumes<reco::GsfTrackCollection>(iConfig.getParameter<InputTag>
47  ("GsfTrackModuleLabel"));
48 
49  pfTrackLabel_ = consumes<reco::PFRecTrackCollection>(iConfig.getParameter<InputTag>
50  ("PFRecTrackLabel"));
51 
52  primVtxLabel_ = consumes<reco::VertexCollection>(iConfig.getParameter<InputTag>
53  ("PrimaryVertexLabel"));
54 
55  pfEcalClusters_ = consumes<reco::PFClusterCollection>(iConfig.getParameter<InputTag>
56  ("PFEcalClusters"));
57 
58  pfNuclear_ = consumes<reco::PFDisplacedTrackerVertexCollection>(iConfig.getParameter<InputTag>
59  ("PFNuclear"));
60 
61  pfConv_ = consumes<reco::PFConversionCollection>(iConfig.getParameter<InputTag>
62  ("PFConversions"));
63 
64  pfV0_ = consumes<reco::PFV0Collection>(iConfig.getParameter<InputTag>
65  ("PFV0"));
66 
67  useNuclear_ = iConfig.getParameter<bool>("useNuclear");
68  useConversions_ = iConfig.getParameter<bool>("useConversions");
69  useV0_ = iConfig.getParameter<bool>("useV0");
70  debugGsfCleaning_ = iConfig.getParameter<bool>("debugGsfCleaning");
71 
72  produces<GsfPFRecTrackCollection>();
73  produces<GsfPFRecTrackCollection>( "Secondary" ).setBranchAlias( "secondary" );
74 
75 
76  trajinev_ = iConfig.getParameter<bool>("TrajInEvents");
77  modemomentum_ = iConfig.getParameter<bool>("ModeMomentum");
78  applySel_ = iConfig.getParameter<bool>("applyEGSelection");
79  applyGsfClean_ = iConfig.getParameter<bool>("applyGsfTrackCleaning");
80  applyAngularGsfClean_ = iConfig.getParameter<bool>("applyAlsoGsfAngularCleaning");
81  detaCutGsfClean_ = iConfig.getParameter<double>("maxDEtaGsfAngularCleaning");
82  dphiCutGsfClean_ = iConfig.getParameter<double>("maxDPhiBremTangGsfAngularCleaning");
83  useFifthStepForTrackDriven_ = iConfig.getParameter<bool>("useFifthStepForTrackerDrivenGsf");
84  useFifthStepForEcalDriven_ = iConfig.getParameter<bool>("useFifthStepForEcalDrivenGsf");
85  maxPtConvReco_ = iConfig.getParameter<double>("MaxConvBremRecoPT");
86  detaGsfSC_ = iConfig.getParameter<double>("MinDEtaGsfSC");
87  dphiGsfSC_ = iConfig.getParameter<double>("MinDPhiGsfSC");
88  SCEne_ = iConfig.getParameter<double>("MinSCEnergy");
89 
90  // set parameter for convBremFinder
91  useConvBremFinder_ = iConfig.getParameter<bool>("useConvBremFinder");
92 
93  mvaConvBremFinderIDBarrelLowPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutBarrelLowPt");
94  mvaConvBremFinderIDBarrelHighPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutBarrelHighPt");
95  mvaConvBremFinderIDEndcapsLowPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutEndcapsLowPt");
96  mvaConvBremFinderIDEndcapsHighPt_ = iConfig.getParameter<double>("pf_convBremFinderID_mvaCutEndcapsHighPt");
97 
98 }
99 
100 
102 { }
103 
104 
105 //
106 // member functions
107 //
108 
109 // ------------ method called to produce the data ------------
110 void
112 {
113 
114 
115  //create the empty collections
116  auto gsfPFRecTrackCollection = std::make_unique<GsfPFRecTrackCollection>();
117 
118  auto gsfPFRecTrackCollectionSecondary = std::make_unique<GsfPFRecTrackCollection>();
119 
120  //read collections of tracks
121  Handle<GsfTrackCollection> gsftrackscoll;
122  iEvent.getByToken(gsfTrackLabel_,gsftrackscoll);
123 
124  //read collections of trajectories
126 
127  //read pfrectrack collection
128  Handle<PFRecTrackCollection> thePfRecTrackCollection;
129  iEvent.getByToken(pfTrackLabel_,thePfRecTrackCollection);
130  const PFRecTrackCollection& PfRTkColl = *(thePfRecTrackCollection.product());
131 
132  // PFClusters
133  Handle<PFClusterCollection> theECPfClustCollection;
134  iEvent.getByToken(pfEcalClusters_,theECPfClustCollection);
135  const PFClusterCollection& theEcalClusters = *(theECPfClustCollection.product());
136 
137  //Primary Vertexes
138  Handle<reco::VertexCollection> thePrimaryVertexColl;
139  iEvent.getByToken(primVtxLabel_,thePrimaryVertexColl);
140 
141  // Displaced Vertex
143  if( useNuclear_ )
144  iEvent.getByToken(pfNuclear_, pfNuclears);
145 
146  // Conversions
148  if( useConversions_ )
149  iEvent.getByToken(pfConv_,pfConversions);
150 
151  // V0
153  if( useV0_ )
154  iEvent.getByToken(pfV0_, pfV0);
155 
156 
157 
158 
159  GsfTrackCollection gsftracks = *(gsftrackscoll.product());
160  vector<Trajectory> tjvec(0);
161  if (trajinev_){
162  iEvent.getByToken(gsfTrackLabel_,TrajectoryCollection);
163 
164  tjvec= *(TrajectoryCollection.product());
165  }
166 
167 
168  vector<reco::GsfPFRecTrack> selGsfPFRecTracks;
169  vector<reco::GsfPFRecTrack> primaryGsfPFRecTracks;
170  std::map<unsigned int, std::vector<reco::GsfPFRecTrack> > GsfPFMap;
171 
172  for( unsigned igsf = 0; igsf < gsftracks.size(); igsf++ ) {
173  GsfTrackRef trackRef(gsftrackscoll, igsf);
174  gsfInnerMomentumCache_.push_back(trackRef->pMode());
176  GlobalVector i_innMom;
177  if(i_inTSOS.isValid()){
178  mtsMode_->momentumFromModeCartesian(i_inTSOS,i_innMom);
179  gsfInnerMomentumCache_.back() = i_innMom.mag();
180  }
181  }
182 
183  for (unsigned int igsf=0; igsf<gsftracks.size();igsf++) {
184 
185  GsfTrackRef trackRef(gsftrackscoll, igsf);
186 
187  int kf_ind=FindPfRef(PfRTkColl,gsftracks[igsf],false);
188 
189  if (kf_ind>=0) {
190 
191  PFRecTrackRef kf_ref(thePfRecTrackCollection,
192  kf_ind);
193 
194  // remove fifth step tracks
195  if( useFifthStepForEcalDriven_ == false
196  || useFifthStepForTrackDriven_ == false) {
197 
198  bool isFifthStepTrack = PFTrackAlgoTools::isFifthStep(kf_ref->trackRef()->algo());
199  bool isEcalDriven = true;
200  bool isTrackerDriven = true;
201 
202  if (&(*trackRef->seedRef())==nullptr) {
203  isEcalDriven = false;
204  isTrackerDriven = false;
205  }
206  else {
207  auto const& SeedFromRef= static_cast<ElectronSeed const&>(*(trackRef->extra()->seedRef()) );
208  if(SeedFromRef.caloCluster().isNull())
209  isEcalDriven = false;
210  if(SeedFromRef.ctfTrack().isNull())
211  isTrackerDriven = false;
212  }
213  //note: the same track could be both ecalDriven and trackerDriven
214  if(isFifthStepTrack &&
215  isEcalDriven &&
216  isTrackerDriven == false &&
217  useFifthStepForEcalDriven_ == false) {
218  continue;
219  }
220 
221  if(isFifthStepTrack &&
222  isTrackerDriven &&
223  isEcalDriven == false &&
224  useFifthStepForTrackDriven_ == false) {
225  continue;
226  }
227 
228  if(isFifthStepTrack &&
229  isTrackerDriven &&
230  isEcalDriven &&
231  useFifthStepForTrackDriven_ == false &&
232  useFifthStepForEcalDriven_ == false) {
233  continue;
234  }
235  }
236 
237  pftrack_=GsfPFRecTrack( gsftracks[igsf].charge(),
239  igsf, trackRef,
240  kf_ref);
241  } else {
242  PFRecTrackRef dummyRef;
243  pftrack_=GsfPFRecTrack( gsftracks[igsf].charge(),
245  igsf, trackRef,
246  dummyRef);
247  }
248 
249 
250  bool validgsfbrem = false;
251  if(trajinev_) {
252  validgsfbrem = pfTransformer_->addPointsAndBrems(pftrack_,
253  gsftracks[igsf],
254  tjvec[igsf],
255  modemomentum_);
256  } else {
257  validgsfbrem = pfTransformer_->addPointsAndBrems(pftrack_,
258  gsftracks[igsf],
259  mtsTransform_);
260  }
261 
262  bool passSel = true;
263  if(applySel_)
264  passSel = applySelection(gsftracks[igsf]);
265 
266  if(validgsfbrem && passSel)
267  selGsfPFRecTracks.push_back(pftrack_);
268  }
269 
270 
271  unsigned int count_primary = 0;
272  if(!selGsfPFRecTracks.empty()) {
273  for(unsigned int ipfgsf=0; ipfgsf<selGsfPFRecTracks.size();ipfgsf++) {
274 
275  vector<unsigned int> secondaries(0);
276  secondaries.clear();
277  bool keepGsf = true;
278 
279  if(applyGsfClean_) {
280  keepGsf = resolveGsfTracks(selGsfPFRecTracks,ipfgsf,secondaries,theEcalClusters);
281  }
282 
283  //is primary?
284  if(keepGsf == true) {
285 
286  // Find kf tracks from converted brem photons
287  if(convBremFinder_->foundConvBremPFRecTrack(thePfRecTrackCollection,thePrimaryVertexColl,
288  pfNuclears,pfConversions,pfV0,
289  globalCache(),
291  theEcalClusters,selGsfPFRecTracks[ipfgsf])) {
292  const vector<PFRecTrackRef>& convBremPFRecTracks(convBremFinder_->getConvBremPFRecTracks());
293  for(unsigned int ii = 0; ii<convBremPFRecTracks.size(); ii++) {
294  selGsfPFRecTracks[ipfgsf].addConvBremPFRecTrackRef(convBremPFRecTracks[ii]);
295  }
296  }
297 
298  // save primaries gsf tracks
299  // gsfPFRecTrackCollection->push_back(selGsfPFRecTracks[ipfgsf]);
300  primaryGsfPFRecTracks.push_back(selGsfPFRecTracks[ipfgsf]);
301 
302 
303  // NOTE:: THE TRACKID IS USED TO LINK THE PRIMARY GSF TRACK. THIS NEEDS
304  // TO BE CHANGED AS SOON AS IT IS POSSIBLE TO CHANGE DATAFORMATS
305  // A MODIFICATION HERE IMPLIES A MODIFICATION IN PFBLOCKALGO.CC/H
306  unsigned int primGsfIndex = selGsfPFRecTracks[ipfgsf].trackId();
307  vector<reco::GsfPFRecTrack> trueGsfPFRecTracks;
308  if(!secondaries.empty()) {
309  // loop on secondaries gsf tracks (from converted brems)
310  for(unsigned int isecpfgsf=0; isecpfgsf<secondaries.size();isecpfgsf++) {
311 
312  PFRecTrackRef refsecKF = selGsfPFRecTracks[(secondaries[isecpfgsf])].kfPFRecTrackRef();
313 
314  unsigned int secGsfIndex = selGsfPFRecTracks[(secondaries[isecpfgsf])].trackId();
315  GsfTrackRef secGsfRef = selGsfPFRecTracks[(secondaries[isecpfgsf])].gsfTrackRef();
316 
317  if(refsecKF.isNonnull()) {
318  // NOTE::IT SAVED THE TRACKID OF THE PRIMARY!!! THIS IS USED IN PFBLOCKALGO.CC/H
319  secpftrack_= GsfPFRecTrack( gsftracks[secGsfIndex].charge(),
321  primGsfIndex, secGsfRef,
322  refsecKF);
323  }
324  else{
325  PFRecTrackRef dummyRef;
326  // NOTE::IT SAVED THE TRACKID OF THE PRIMARY!!! THIS IS USED IN PFBLOCKALGO.CC/H
327  secpftrack_= GsfPFRecTrack( gsftracks[secGsfIndex].charge(),
329  primGsfIndex, secGsfRef,
330  dummyRef);
331  }
332 
333  bool validgsfbrem = false;
334  if(trajinev_) {
335  validgsfbrem = pfTransformer_->addPointsAndBrems(secpftrack_,
336  gsftracks[secGsfIndex],
337  tjvec[secGsfIndex],
338  modemomentum_);
339  } else {
340  validgsfbrem = pfTransformer_->addPointsAndBrems(secpftrack_,
341  gsftracks[secGsfIndex],
342  mtsTransform_);
343  }
344 
345  if(validgsfbrem) {
346  gsfPFRecTrackCollectionSecondary->push_back(secpftrack_);
347  trueGsfPFRecTracks.push_back(secpftrack_);
348  }
349  }
350  }
351  GsfPFMap.insert(pair<unsigned int,std::vector<reco::GsfPFRecTrack> >(count_primary,trueGsfPFRecTracks));
352  trueGsfPFRecTracks.clear();
353  count_primary++;
354  }
355  }
356  }
357 
358 
359  const edm::OrphanHandle<GsfPFRecTrackCollection> gsfPfRefProd =
360  iEvent.put(std::move(gsfPFRecTrackCollectionSecondary),"Secondary");
361 
362 
363  //now the secondary GsfPFRecTracks are in the event, the Ref can be created
364  createGsfPFRecTrackRef(gsfPfRefProd,primaryGsfPFRecTracks,GsfPFMap);
365 
366  for(unsigned int iGSF = 0; iGSF<primaryGsfPFRecTracks.size();iGSF++){
367  gsfPFRecTrackCollection->push_back(primaryGsfPFRecTracks[iGSF]);
368  }
369  iEvent.put(std::move(gsfPFRecTrackCollection));
370 
371  selGsfPFRecTracks.clear();
372  GsfPFMap.clear();
373  primaryGsfPFRecTracks.clear();
374 
375  std::vector<double>().swap(gsfInnerMomentumCache_);
376 }
377 
378 // create the secondary GsfPFRecTracks Ref
379 void
381  std::vector<reco::GsfPFRecTrack>& gsfPFRecTrackPrimary,
382  const std::map<unsigned int, std::vector<reco::GsfPFRecTrack> >& MapPrimSec) {
383  unsigned int cgsf=0;
384  unsigned int csecgsf=0;
385  for (std::map<unsigned int, std::vector<reco::GsfPFRecTrack> >::const_iterator igsf = MapPrimSec.begin();
386  igsf != MapPrimSec.end(); igsf++,cgsf++) {
387  vector<reco::GsfPFRecTrack> SecGsfPF = igsf->second;
388  for (unsigned int iSecGsf=0; iSecGsf < SecGsfPF.size(); iSecGsf++) {
389  edm::Ref<reco::GsfPFRecTrackCollection> refgprt(gsfPfHandle,csecgsf);
390  gsfPFRecTrackPrimary[cgsf].addConvBremGsfPFRecTrackRef(refgprt);
391  ++csecgsf;
392  }
393  }
394 
395  return;
396 }
397 // ------------- method for find the corresponding kf pfrectrack ---------------------
398 int
400  const reco::GsfTrack& gsftk,
401  bool otherColl){
402 
403 
404  if (&(*gsftk.seedRef())==nullptr) return -1;
405  auto const & ElSeedFromRef=static_cast<ElectronSeed const&>( *(gsftk.extra()->seedRef()) );
406  //CASE 1 ELECTRONSEED DOES NOT HAVE A REF TO THE CKFTRACK
407  if (ElSeedFromRef.ctfTrack().isNull()){
408  reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
409  reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
410  unsigned int i_pf=0;
411  int ibest=-1;
412  unsigned int ish_max=0;
413  float dr_min=1000;
414  //SEARCH THE PFRECTRACK THAT SHARES HITS WITH THE ELECTRON SEED
415  // Here the cpu time can be improved.
416  for(;pft!=pftend;++pft){
417  unsigned int ish=0;
418 
419  float dph= fabs(pft->trackRef()->phi()-gsftk.phi());
420  if (dph>TMath::Pi()) dph-= TMath::TwoPi();
421  float det=fabs(pft->trackRef()->eta()-gsftk.eta());
422  float dr =sqrt(dph*dph+det*det);
423 
425  pft->trackRef()->recHitsBegin();
426  trackingRecHit_iterator hhit_end=
427  pft->trackRef()->recHitsEnd();
428 
429 
430 
431  for(;hhit!=hhit_end;++hhit){
432  if (!(*hhit)->isValid()) continue;
434  gsftk.seedRef()->recHits().first;
436  gsftk.seedRef()->recHits().second;
437  for(;hit!=hit_end;++hit){
438  if (!(hit->isValid())) continue;
439  if((*hhit)->sharesInput(&*(hit),TrackingRecHit::all)) ish++;
440  // if((hit->geographicalId()==(*hhit)->geographicalId())&&
441  // (((*hhit)->localPosition()-hit->localPosition()).mag()<0.01)) ish++;
442  }
443 
444  }
445 
446 
447  if ((ish>ish_max)||
448  ((ish==ish_max)&&(dr<dr_min))){
449  ish_max=ish;
450  dr_min=dr;
451  ibest=i_pf;
452  }
453 
454 
455 
456  i_pf++;
457  }
458  if (ibest<0) return -1;
459 
460  if((ish_max==0) || (dr_min>0.05))return -1;
461  if(otherColl && (ish_max==0)) return -1;
462  return ibest;
463  }
464  else{
465  //ELECTRON SEED HAS A REFERENCE
466 
467  reco::PFRecTrackCollection::const_iterator pft=PfRTkColl.begin();
468  reco::PFRecTrackCollection::const_iterator pftend=PfRTkColl.end();
469  unsigned int i_pf=0;
470 
471  for(;pft!=pftend;++pft){
472  //REF COMPARISON
473  if (pft->trackRef()==ElSeedFromRef.ctfTrack()){
474  return i_pf;
475  }
476  i_pf++;
477  }
478  }
479  return -1;
480 }
481 
482 // -- method to apply gsf electron selection to EcalDriven seeds
483 bool
485  if (&(*gsftk.seedRef())==nullptr) return false;
486  auto const& ElSeedFromRef=static_cast<ElectronSeed const&>( *(gsftk.extra()->seedRef()) );
487 
488  bool passCut = false;
489  if (ElSeedFromRef.ctfTrack().isNull()){
490  if(ElSeedFromRef.caloCluster().isNull()) return passCut;
491  auto const* scRef = static_cast<SuperCluster const*>(ElSeedFromRef.caloCluster().get());
492  //do this just to know if exist a SC?
493  if(scRef) {
494  float caloEne = scRef->energy();
495  float feta = fabs(scRef->eta()-gsftk.etaMode());
496  float fphi = fabs(scRef->phi()-gsftk.phiMode());
497  if (fphi>TMath::Pi()) fphi-= TMath::TwoPi();
498  if(caloEne > SCEne_ && feta < detaGsfSC_ && fabs(fphi) < dphiGsfSC_)
499  passCut = true;
500  }
501  }
502  else {
503  // get all the gsf found by tracker driven
504  passCut = true;
505  }
506  return passCut;
507 }
508 bool
509 PFElecTkProducer::resolveGsfTracks(const vector<reco::GsfPFRecTrack> & GsfPFVec,
510  unsigned int ngsf,
511  vector<unsigned int> &secondaries,
512  const reco::PFClusterCollection & theEClus) {
513  bool debugCleaning = debugGsfCleaning_;
514  bool n_keepGsf = true;
515 
516  const reco::GsfTrackRef& nGsfTrack = GsfPFVec[ngsf].gsfTrackRef();
517 
518  if (&(*nGsfTrack->seedRef())==nullptr) return false;
519  auto const& nElSeedFromRef=static_cast<ElectronSeed const&>( *(nGsfTrack->extra()->seedRef()) );
520 
521  /* // now gotten from cache below
522  TrajectoryStateOnSurface inTSOS = mtsTransform_.innerStateOnSurface((*nGsfTrack));
523  GlobalVector ninnMom;
524  float nPin = nGsfTrack->pMode();
525  if(inTSOS.isValid()){
526  mtsMode_->momentumFromModeCartesian(inTSOS,ninnMom);
527  nPin = ninnMom.mag();
528  }
529  */
530  float nPin = gsfInnerMomentumCache_[nGsfTrack.key()];
531 
532  float neta = nGsfTrack->innerMomentum().eta();
533  float nphi = nGsfTrack->innerMomentum().phi();
534 
535 
536 
537 
538  if(debugCleaning)
539  cout << " PFElecTkProducer:: considering track " << nGsfTrack->pt()
540  << " eta,phi " << nGsfTrack->eta() << ", " << nGsfTrack->phi() << endl;
541 
542 
543  for (unsigned int igsf=0; igsf< GsfPFVec.size();igsf++) {
544  if(igsf != ngsf ) {
545  reco::GsfTrackRef iGsfTrack = GsfPFVec[igsf].gsfTrackRef();
546 
547  if(debugCleaning)
548  cout << " PFElecTkProducer:: and comparing with track " << iGsfTrack->pt()
549  << " eta,phi " << iGsfTrack->eta() << ", " << iGsfTrack->phi() << endl;
550 
551  float ieta = iGsfTrack->innerMomentum().eta();
552  float iphi = iGsfTrack->innerMomentum().phi();
553  float feta = fabs(neta - ieta);
554  float fphi = fabs(nphi - iphi);
555  if (fphi>TMath::Pi()) fphi-= TMath::TwoPi();
556 
557 
558  // apply a superloose preselection only to avoid un-useful cpu time: hard-coded for this reason
559  if(feta < 0.5 && fabs(fphi) < 1.0) {
560  if(debugCleaning)
561  cout << " Entering angular superloose preselection " << endl;
562 
563  /* //now taken from cache below
564  TrajectoryStateOnSurface i_inTSOS = mtsTransform_.innerStateOnSurface((*iGsfTrack));
565  GlobalVector i_innMom;
566  float iPin = iGsfTrack->pMode();
567  if(i_inTSOS.isValid()){
568  mtsMode_->momentumFromModeCartesian(i_inTSOS,i_innMom);
569  iPin = i_innMom.mag();
570  }
571  */
572  float iPin = gsfInnerMomentumCache_[iGsfTrack.key()];
573 
574  if (&(*iGsfTrack->seedRef())==nullptr) continue;
575  auto const& iElSeedFromRef=static_cast<ElectronSeed const&>( *(iGsfTrack->extra()->seedRef()) );
576 
577  float SCEnergy = -1.;
578  // Check if two tracks match the same SC
579  bool areBothGsfEcalDriven = false;;
580  bool isSameSC = isSameEgSC(nElSeedFromRef,iElSeedFromRef,areBothGsfEcalDriven,SCEnergy);
581 
582  // CASE1 both GsfTracks ecalDriven and match the same SC
583  if(areBothGsfEcalDriven ) {
584  if(isSameSC) {
585  float nEP = SCEnergy/nPin;
586  float iEP = SCEnergy/iPin;
587  if(debugCleaning)
588  cout << " Entering SAME supercluster case "
589  << " nEP " << nEP
590  << " iEP " << iEP << endl;
591 
592 
593 
594  // if same SC take the closest or if same
595  // distance the best E/p
596 
597  // Innermost using LostHits technology
598  bool isSameLayer = false;
599  bool iGsfInnermostWithLostHits =
600  isInnerMostWithLostHits(nGsfTrack,iGsfTrack,isSameLayer);
601 
602 
603  if(debugCleaning)
604  cout << " iGsf is InnerMostWithLostHits " << iGsfInnermostWithLostHits
605  << " isSameLayer " << isSameLayer << endl;
606 
607  if (iGsfInnermostWithLostHits) {
608  n_keepGsf = false;
609  return n_keepGsf;
610  }
611  else if(isSameLayer){
612  if(fabs(iEP-1) < fabs(nEP-1)) {
613  n_keepGsf = false;
614  return n_keepGsf;
615  }
616  else{
617  secondaries.push_back(igsf);
618  }
619  }
620  else {
621  // save secondaries gsf track (put selection)
622  secondaries.push_back(igsf);
623  }
624  } // end same SC case
625  }
626  else {
627  // enter in the condition where at least one track is trackerDriven
628  float minBremDphi = minTangDist(GsfPFVec[ngsf],GsfPFVec[igsf]);
629  float nETot = 0.;
630  float iETot = 0.;
631  bool isBothGsfTrackerDriven = false;
632  bool nEcalDriven = false;
633  bool iEcalDriven = false;
634  bool isSameScEgPf = isSharingEcalEnergyWithEgSC(GsfPFVec[ngsf],
635  GsfPFVec[igsf],
636  nElSeedFromRef,
637  iElSeedFromRef,
638  theEClus,
639  isBothGsfTrackerDriven,
640  nEcalDriven,
641  iEcalDriven,
642  nETot,
643  iETot);
644 
645  // check if the first hit of iGsfTrack < nGsfTrack
646  bool isSameLayer = false;
647  bool iGsfInnermostWithLostHits =
648  isInnerMostWithLostHits(nGsfTrack,iGsfTrack,isSameLayer);
649 
650  if(isSameScEgPf) {
651  // CASE 2 : One Gsf has reference to a SC and the other one not or both not
652 
653  if(debugCleaning) {
654  cout << " Sharing ECAL energy passed "
655  << " nEtot " << nETot
656  << " iEtot " << iETot << endl;
657  if(isBothGsfTrackerDriven)
658  cout << " Both Track are trackerDriven " << endl;
659  }
660 
661  // Innermost using LostHits technology
662  if (iGsfInnermostWithLostHits) {
663  n_keepGsf = false;
664  return n_keepGsf;
665  }
666  else if(isSameLayer){
667  // Thirt Case: One Gsf has reference to a SC and the other one not or both not
668  // gsf tracks starts from the same layer
669  // check number of sharing modules (at least 50%)
670  // check number of sharing hits (at least 2)
671  // check charge flip inner/outer
672 
673 
674  // they share energy
675  if(isBothGsfTrackerDriven == false) {
676  // if at least one Gsf track is EcalDriven choose that one.
677  if(iEcalDriven) {
678  n_keepGsf = false;
679  return n_keepGsf;
680  }
681  else {
682  secondaries.push_back(igsf);
683  }
684  }
685  else {
686  // if both tracks are tracker driven choose that one with the best E/p
687  // with ETot = max(En,Ei)
688 
689  float ETot = -1;
690  if(nETot != iETot) {
691  if(nETot > iETot)
692  ETot = nETot;
693  else
694  ETot = iETot;
695  }
696  else {
697  ETot = nETot;
698  }
699  float nEP = ETot/nPin;
700  float iEP = ETot/iPin;
701 
702 
703  if(debugCleaning)
704  cout << " nETot " << nETot
705  << " iETot " << iETot
706  << " ETot " << ETot << endl
707  << " nPin " << nPin
708  << " iPin " << iPin
709  << " nEP " << nEP
710  << " iEP " << iEP << endl;
711 
712 
713  if(fabs(iEP-1) < fabs(nEP-1)) {
714  n_keepGsf = false;
715  return n_keepGsf;
716  }
717  else{
718  secondaries.push_back(igsf);
719  }
720  }
721  }
722  else {
723  secondaries.push_back(igsf);
724  }
725  }
726  else if(feta < detaCutGsfClean_ && minBremDphi < dphiCutGsfClean_) {
727  // very close tracks
728  bool secPushedBack = false;
729  if(nEcalDriven == false && nETot == 0.) {
730  n_keepGsf = false;
731  return n_keepGsf;
732  }
733  else if(iEcalDriven == false && iETot == 0.) {
734  secondaries.push_back(igsf);
735  secPushedBack = true;
736  }
737  if(debugCleaning)
738  cout << " Close Tracks "
739  << " feta " << feta << " fabs(fphi) " << fabs(fphi)
740  << " minBremDphi " << minBremDphi
741  << " nETot " << nETot
742  << " iETot " << iETot
743  << " nLostHits " << nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS)
744  << " iLostHits " << iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS) << endl;
745 
746  // apply selection only if one track has lost hits
748  if (iGsfInnermostWithLostHits) {
749  n_keepGsf = false;
750  return n_keepGsf;
751  }
752  else if(isSameLayer == false) {
753  if(secPushedBack == false)
754  secondaries.push_back(igsf);
755  }
756  }
757  }
758  else if(feta < 0.1 && minBremDphi < 0.2){
759  // failed all the conditions, discard only tracker driven tracks
760  // with no PFClusters linked.
761  if(debugCleaning)
762  cout << " Close Tracks and failed all the conditions "
763  << " feta " << feta << " fabs(fphi) " << fabs(fphi)
764  << " minBremDphi " << minBremDphi
765  << " nETot " << nETot
766  << " iETot " << iETot
767  << " nLostHits " << nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS)
768  << " iLostHits " << iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS) << endl;
769 
770  if(nEcalDriven == false && nETot == 0.) {
771  n_keepGsf = false;
772  return n_keepGsf;
773  }
774  // Here I do not push back the secondary because considered fakes...
775  }
776  }
777  }
778  }
779  }
780 
781  return n_keepGsf;
782 }
783 float
785  const reco::GsfPFRecTrack& secGsf) {
786 
787  float minDphi = 1000.;
788 
789 
790  std::vector<reco::PFBrem> primPFBrem = primGsf.PFRecBrem();
791  std::vector<reco::PFBrem> secPFBrem = secGsf.PFRecBrem();
792 
793 
794  unsigned int cbrem = 0;
795  for (unsigned isbrem = 0; isbrem < secPFBrem.size(); isbrem++) {
796  if(secPFBrem[isbrem].indTrajPoint() == 99) continue;
797  const reco::PFTrajectoryPoint& atSecECAL
798  = secPFBrem[isbrem].extrapolatedPoint( reco::PFTrajectoryPoint::ECALEntrance );
799  if( ! atSecECAL.isValid() ) continue;
800  float secPhi = atSecECAL.positionREP().Phi();
801 
802  unsigned int sbrem = 0;
803  for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
804  if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
805  const reco::PFTrajectoryPoint& atPrimECAL
806  = primPFBrem[ipbrem].extrapolatedPoint( reco::PFTrajectoryPoint::ECALEntrance );
807  if( ! atPrimECAL.isValid() ) continue;
808  sbrem++;
809  if(sbrem <= 3) {
810  float primPhi = atPrimECAL.positionREP().Phi();
811 
812  float dphi = fabs(primPhi - secPhi);
813  if (dphi>TMath::Pi()) dphi-= TMath::TwoPi();
814  if(fabs(dphi) < minDphi) {
815  minDphi = fabs(dphi);
816  }
817  }
818  }
819 
820 
821  cbrem++;
822  if(cbrem == 3)
823  break;
824  }
825  return minDphi;
826 }
827 bool
829  const reco::ElectronSeed& iSeed,
830  bool& bothGsfEcalDriven,
831  float& SCEnergy) {
832 
833  bool isSameSC = false;
834 
835  if(nSeed.caloCluster().isNonnull() && iSeed.caloCluster().isNonnull()) {
836  auto const* nscRef = static_cast<SuperCluster const*>(nSeed.caloCluster().get());
837  auto const* iscRef = static_cast<SuperCluster const*>(iSeed.caloCluster().get());
838 
839  if(nscRef && iscRef) {
840  bothGsfEcalDriven = true;
841  if(nscRef == iscRef) {
842  isSameSC = true;
843  // retrieve the supercluster energy
844  SCEnergy = nscRef->energy();
845  }
846  }
847  }
848  return isSameSC;
849 }
850 bool
852  const reco::GsfPFRecTrack& iGsfPFRecTrack,
853  const reco::ElectronSeed& nSeed,
854  const reco::ElectronSeed& iSeed,
855  const reco::PFClusterCollection& theEClus,
856  bool& bothGsfTrackerDriven,
857  bool& nEcalDriven,
858  bool& iEcalDriven,
859  float& nEnergy,
860  float& iEnergy) {
861 
862  bool isSharingEnergy = false;
863 
864  //which is EcalDriven?
865  bool oneEcalDriven = true;
866  SuperCluster const* scRef = nullptr;
867  GsfPFRecTrack gsfPfTrack;
868 
869  if(nSeed.caloCluster().isNonnull()) {
870  scRef = static_cast<SuperCluster const*>(nSeed.caloCluster().get());
871  assert(scRef);
872  nEnergy = scRef->energy();
873  nEcalDriven = true;
874  gsfPfTrack = iGsfPFRecTrack;
875  }
876  else if(iSeed.caloCluster().isNonnull()){
877  scRef = static_cast<SuperCluster const*>(iSeed.caloCluster().get());
878  assert(scRef);
879  iEnergy = scRef->energy();
880  iEcalDriven = true;
881  gsfPfTrack = nGsfPFRecTrack;
882  }
883  else{
884  oneEcalDriven = false;
885  }
886 
887  if(oneEcalDriven) {
888  //run a basic reconstruction for the particle flow
889 
890  vector<PFCluster> vecPFClusters;
891  vecPFClusters.clear();
892 
893  for (PFClusterCollection::const_iterator clus = theEClus.begin();
894  clus != theEClus.end();
895  clus++ ) {
896  PFCluster clust = *clus;
897  clust.calculatePositionREP();
898 
899  float deta = fabs(scRef->position().eta() - clust.position().eta());
900  float dphi = fabs(scRef->position().phi() - clust.position().phi());
901  if (dphi>TMath::Pi()) dphi-= TMath::TwoPi();
902 
903  // Angle preselection between the supercluster and pfclusters
904  // this is needed just to save some cpu-time for this is hard-coded
905  if(deta < 0.5 && fabs(dphi) < 1.0) {
906  double distGsf = gsfPfTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
907  LinkByRecHit::testTrackAndClusterByRecHit(gsfPfTrack , clust ) : -1.;
908  // check if it touch the GsfTrack
909  if(distGsf > 0.) {
910  if(nEcalDriven)
911  iEnergy += clust.energy();
912  else
913  nEnergy += clust.energy();
914  vecPFClusters.push_back(clust);
915  }
916  // check if it touch the Brem-tangents
917  else {
918  vector<PFBrem> primPFBrem = gsfPfTrack.PFRecBrem();
919  for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
920  if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
921  const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
922  double dist = pfBremTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
923  LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack , clust, true ) : -1.;
924  if(dist > 0.) {
925  if(nEcalDriven)
926  iEnergy += clust.energy();
927  else
928  nEnergy += clust.energy();
929  vecPFClusters.push_back(clust);
930  }
931  }
932  }
933  } // END if angle preselection
934  } // PFClusters Loop
935  if(!vecPFClusters.empty() ) {
936  for(unsigned int pf = 0; pf < vecPFClusters.size(); pf++) {
937  bool isCommon = ClusterClusterMapping::overlap(vecPFClusters[pf],*scRef);
938  if(isCommon) {
939  isSharingEnergy = true;
940  }
941  break;
942  }
943  }
944  }
945  else {
946  // both tracks are trackerDriven, try ECAL energy matching also in this case.
947 
948  bothGsfTrackerDriven = true;
949  vector<PFCluster> nPFCluster;
950  vector<PFCluster> iPFCluster;
951 
952  nPFCluster.clear();
953  iPFCluster.clear();
954 
955  for (PFClusterCollection::const_iterator clus = theEClus.begin();
956  clus != theEClus.end();
957  clus++ ) {
958  PFCluster clust = *clus;
959  clust.calculatePositionREP();
960 
961  float ndeta = fabs(nGsfPFRecTrack.gsfTrackRef()->eta() - clust.position().eta());
962  float ndphi = fabs(nGsfPFRecTrack.gsfTrackRef()->phi() - clust.position().phi());
963  if (ndphi>TMath::Pi()) ndphi-= TMath::TwoPi();
964  // Apply loose preselection with the track
965  // just to save cpu time, for this hard-coded
966  if(ndeta < 0.5 && fabs(ndphi) < 1.0) {
967 
968  double distGsf = nGsfPFRecTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
969  LinkByRecHit::testTrackAndClusterByRecHit(nGsfPFRecTrack , clust ) : -1.;
970  if(distGsf > 0.) {
971  nPFCluster.push_back(clust);
972  nEnergy += clust.energy();
973  }
974  else {
975  const vector<PFBrem>& primPFBrem = nGsfPFRecTrack.PFRecBrem();
976  for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
977  if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
978  const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
979  double dist = pfBremTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
980  LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack , clust, true ) : -1.;
981  if(dist > 0.) {
982  nPFCluster.push_back(clust);
983  nEnergy += clust.energy();
984  break;
985  }
986  }
987  }
988  }
989 
990  float ideta = fabs(iGsfPFRecTrack.gsfTrackRef()->eta() - clust.position().eta());
991  float idphi = fabs(iGsfPFRecTrack.gsfTrackRef()->phi() - clust.position().phi());
992  if (idphi>TMath::Pi()) idphi-= TMath::TwoPi();
993  // Apply loose preselection with the track
994  // just to save cpu time, for this hard-coded
995  if(ideta < 0.5 && fabs(idphi) < 1.0) {
996  double dist = iGsfPFRecTrack.extrapolatedPoint( reco::PFTrajectoryPoint::ECALShowerMax ).isValid() ?
997  LinkByRecHit::testTrackAndClusterByRecHit(iGsfPFRecTrack , clust ) : -1.;
998  if(dist > 0.) {
999  iPFCluster.push_back(clust);
1000  iEnergy += clust.energy();
1001  }
1002  else {
1003  vector<PFBrem> primPFBrem = iGsfPFRecTrack.PFRecBrem();
1004  for(unsigned ipbrem = 0; ipbrem < primPFBrem.size(); ipbrem++) {
1005  if(primPFBrem[ipbrem].indTrajPoint() == 99) continue;
1006  const reco::PFRecTrack& pfBremTrack = primPFBrem[ipbrem];
1007  double dist = LinkByRecHit::testTrackAndClusterByRecHit(pfBremTrack , clust, true );
1008  if(dist > 0.) {
1009  iPFCluster.push_back(clust);
1010  iEnergy += clust.energy();
1011  break;
1012  }
1013  }
1014  }
1015  }
1016  }
1017 
1018 
1019  if(!nPFCluster.empty() && !iPFCluster.empty()) {
1020  for(unsigned int npf = 0; npf < nPFCluster.size(); npf++) {
1021  for(unsigned int ipf = 0; ipf < iPFCluster.size(); ipf++) {
1022  bool isCommon = ClusterClusterMapping::overlap(nPFCluster[npf],iPFCluster[ipf]);
1023  if(isCommon) {
1024  isSharingEnergy = true;
1025  break;
1026  }
1027  }
1028  if(isSharingEnergy)
1029  break;
1030  }
1031  }
1032  }
1033 
1034  return isSharingEnergy;
1035 }
1037  const reco::GsfTrackRef& iGsfTrack,
1038  bool& sameLayer) {
1039 
1040  // copied by the class RecoEgamma/EgammaElectronAlgos/src/EgAmbiguityTools.cc
1041  // obsolete but the code is kept: now using lost hits method
1042 
1043  const reco::HitPattern &gsfHitPattern1 = nGsfTrack->hitPattern();
1044  const reco::HitPattern &gsfHitPattern2 = iGsfTrack->hitPattern();
1045 
1046  // retrieve first valid hit
1047  int gsfHitCounter1 = 0 ;
1048  trackingRecHit_iterator elHitsIt1 ;
1049  for
1050  ( elHitsIt1 = nGsfTrack->recHitsBegin() ;
1051  elHitsIt1 != nGsfTrack->recHitsEnd() ;
1052  elHitsIt1++, gsfHitCounter1++ )
1053  { if (((**elHitsIt1).isValid())) break ; }
1054 
1055  int gsfHitCounter2 = 0 ;
1056  trackingRecHit_iterator elHitsIt2 ;
1057  for
1058  ( elHitsIt2 = iGsfTrack->recHitsBegin() ;
1059  elHitsIt2 != iGsfTrack->recHitsEnd() ;
1060  elHitsIt2++, gsfHitCounter2++ )
1061  { if (((**elHitsIt2).isValid())) break ; }
1062 
1063  uint32_t gsfHit1 = gsfHitPattern1.getHitPattern(HitPattern::TRACK_HITS, gsfHitCounter1) ;
1064  uint32_t gsfHit2 = gsfHitPattern2.getHitPattern(HitPattern::TRACK_HITS, gsfHitCounter2) ;
1065 
1066 
1067  if (gsfHitPattern1.getSubStructure(gsfHit1)!=gsfHitPattern2.getSubStructure(gsfHit2))
1068  {
1069  return (gsfHitPattern2.getSubStructure(gsfHit2)<gsfHitPattern1.getSubStructure(gsfHit1));
1070  }
1071  else if (gsfHitPattern1.getLayer(gsfHit1)!=gsfHitPattern2.getLayer(gsfHit2))
1072  {
1073  return (gsfHitPattern2.getLayer(gsfHit2)<gsfHitPattern1.getLayer(gsfHit1));
1074  }
1075  else
1076  {
1077  sameLayer = true;
1078  return false;
1079  }
1080 }
1082  const reco::GsfTrackRef& iGsfTrack,
1083  bool& sameLayer) {
1084 
1085  // define closest using the lost hits on the expectedhitsineer
1086  unsigned int nLostHits = nGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1087  unsigned int iLostHits = iGsfTrack->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1088 
1089  if (nLostHits!=iLostHits) {
1090  return (nLostHits > iLostHits);
1091  }
1092  else {
1093  sameLayer = true;
1094  return false;
1095  }
1096 }
1097 
1098 
1099 
1100 // ------------ method called once each job just before starting event loop ------------
1101 void
1103  const EventSetup& iSetup)
1104 {
1106  iSetup.get<IdealMagneticFieldRecord>().get(magneticField);
1107 
1109  iSetup.get<TrackerDigiGeometryRecord>().get(tracker);
1110 
1111  mtsTransform_ = MultiTrajectoryStateTransform(tracker.product(),magneticField.product());
1112 
1113  pfTransformer_.reset( new PFTrackTransformer(math::XYZVector(magneticField->inTesla(GlobalPoint(0,0,0)))) );
1114 
1116  iSetup.get<TransientTrackRecord>().get("TransientTrackBuilder", builder);
1117  TransientTrackBuilder thebuilder = *(builder.product());
1118 
1119  convBremFinder_.reset( new ConvBremPFTrackFinder(thebuilder,
1124 
1125 }
1126 
1127 // ------------ method called once each job just after ending the event loop ------------
1128 void
1130  const EventSetup& iSetup) {
1131  pfTransformer_.reset();
1132  convBremFinder_.reset();
1133 }
1134 
1135 //define this as a plug-in
const REPPoint & positionREP() const
trajectory position in (rho, eta, phi) base
bool trajinev_
Trajectory of GSfTracks in the event?
const double TwoPi
const double Pi
const edm::RefToBase< TrajectorySeed > & seedRef() const
Definition: Track.h:213
value_type const * get() const
Definition: RefToBase.h:234
T getParameter(std::string const &) const
const math::XYZPoint & position() const
cluster centroid position
Definition: CaloCluster.h:129
reconstructed track used as an input to particle flow
Definition: PFRecTrack.h:22
edm::EDGetTokenT< reco::PFRecTrackCollection > pfTrackLabel_
static uint32_t getLayer(uint16_t pattern)
Definition: HitPattern.h:700
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
Definition: Event.h:136
static bool overlap(const reco::CaloCluster &sc1, const reco::CaloCluster &sc, float minfrac=0.01, bool debug=false)
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
edm::EDGetTokenT< reco::GsfTrackCollection > gsfTrackLabel_
void createGsfPFRecTrackRef(const edm::OrphanHandle< reco::GsfPFRecTrackCollection > &gsfPfHandle, std::vector< reco::GsfPFRecTrack > &gsfPFRecTrackPrimary, const std::map< unsigned int, std::vector< reco::GsfPFRecTrack > > &MapPrimSec)
const TrackExtraRef & extra() const
reference to "extra" object
Definition: Track.h:189
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
double mvaConvBremFinderIDEndcapsLowPt_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:519
const std::vector< reco::PFBrem > & PFRecBrem() const
Definition: GsfPFRecTrack.h:51
const CaloClusterRef & caloCluster() const
Definition: ElectronSeed.h:94
double phi() const
azimuthal angle of momentum vector
Definition: TrackBase.h:645
bool applySelection(const reco::GsfTrack &)
bool isNonnull() const
Checks for non-null.
Definition: RefToBase.h:337
key_type key() const
Accessor for product key.
Definition: Ref.h:265
bool momentumFromModeCartesian(const TrajectoryStateOnSurface tsos, GlobalVector &momentum) const
reco::GsfPFRecTrack secpftrack_
std::unique_ptr< ConvBremPFTrackFinder > convBremFinder_
void swap(Association< C > &lhs, Association< C > &rhs)
Definition: Association.h:116
~PFElecTkProducer() override
Destructor.
edm::EDGetTokenT< reco::VertexCollection > primVtxLabel_
const MultiTrajectoryStateMode * mtsMode_
double mvaConvBremFinderIDBarrelLowPt_
int iEvent
Definition: GenABIO.cc:230
T mag() const
Definition: PV3DBase.h:67
double eta() const
pseudorapidity of momentum vector
Definition: TrackBase.h:651
void calculatePositionREP()
computes posrep_ once and for all
Definition: PFCluster.h:100
edm::EDGetTokenT< reco::PFV0Collection > pfV0_
const reco::GsfTrackRef & gsfTrackRef() const
Definition: GsfPFRecTrack.h:39
recHitContainer::const_iterator const_iterator
T sqrt(T t)
Definition: SSEVec.h:18
std::vector< GsfTrack > GsfTrackCollection
collection of GsfTracks
Definition: GsfTrackFwd.h:9
double energy() const
cluster energy
Definition: CaloCluster.h:124
edm::EDGetTokenT< reco::PFDisplacedTrackerVertexCollection > pfNuclear_
const reco::PFTrajectoryPoint & extrapolatedPoint(unsigned layerid) const
Definition: PFTrack.cc:76
bool isSameEgSC(const reco::ElectronSeed &nSeed, const reco::ElectronSeed &iSeed, bool &bothGsfEcalDriven, float &SCEnergy)
virtual GlobalVector inTesla(const GlobalPoint &gp) const =0
Field value ad specified global point, in Tesla.
static uint32_t getSubStructure(uint16_t pattern)
Definition: HitPattern.h:691
double energy() const
cluster energy
Definition: PFCluster.h:82
ii
Definition: cuy.py:588
bool isInnerMostWithLostHits(const reco::GsfTrackRef &nGsfTrack, const reco::GsfTrackRef &iGsfTrack, bool &sameLayer)
PFElecTkProducer(const edm::ParameterSet &, const convbremhelpers::HeavyObjectCache *)
Constructor.
void endRun(const edm::Run &, const edm::EventSetup &) override
int FindPfRef(const reco::PFRecTrackCollection &PfRTkColl, const reco::GsfTrack &, bool)
bool resolveGsfTracks(const std::vector< reco::GsfPFRecTrack > &GsfPFVec, unsigned int ngsf, std::vector< unsigned int > &secondaries, const reco::PFClusterCollection &theEClus)
bool isValid() const
is this point valid ?
T const * product() const
Definition: Handle.h:81
bool isFifthStep(const reco::TrackBase::TrackAlgorithm &)
XYZVectorD XYZVector
spatial vector with cartesian internal representation
Definition: Vector3D.h:30
const T & get() const
Definition: EventSetup.h:58
range recHits() const
double mvaConvBremFinderIDBarrelHighPt_
double mvaConvBremFinderIDEndcapsHighPt_
edm::EDGetTokenT< reco::PFConversionCollection > pfConv_
std::vector< Trajectory > TrajectoryCollection
TrajectoryStateOnSurface innerStateOnSurface(const reco::GsfTrack &tk) const
void beginRun(const edm::Run &, const edm::EventSetup &) override
fixed size matrix
HLT enums.
double etaMode() const
pseudorapidity of momentum vector from mode
Definition: GsfTrack.h:59
reco::GsfPFRecTrack pftrack_
void produce(edm::Event &, const edm::EventSetup &) override
Produce the PFRecTrack collection.
double phiMode() const
azimuthal angle of momentum vector from mode
Definition: GsfTrack.h:57
bool useConvBremFinder_
Conv Brem Finder.
std::vector< PFCluster > PFClusterCollection
collection of PFCluster objects
Definition: PFClusterFwd.h:9
A PFTrack holds several trajectory points, which basically contain the position and momentum of a tra...
std::unique_ptr< PFTrackTransformer > pfTransformer_
PFTrackTransformer.
std::vector< double > gsfInnerMomentumCache_
uint16_t getHitPattern(HitCategory category, int position) const
Definition: HitPattern.h:515
T const * product() const
Definition: ESHandle.h:86
static double testTrackAndClusterByRecHit(const reco::PFRecTrack &track, const reco::PFCluster &cluster, bool isBrem=false, bool debug=false)
Definition: LinkByRecHit.cc:18
float minTangDist(const reco::GsfPFRecTrack &primGsf, const reco::GsfPFRecTrack &secGsf)
std::vector< PFRecTrack > PFRecTrackCollection
collection of PFRecTrack objects
Definition: PFRecTrackFwd.h:9
edm::EDGetTokenT< reco::PFClusterCollection > pfEcalClusters_
bool isSharingEcalEnergyWithEgSC(const reco::GsfPFRecTrack &nGsfPFRecTrack, const reco::GsfPFRecTrack &iGsfPFRecTrack, const reco::ElectronSeed &nSeed, const reco::ElectronSeed &iSeed, const reco::PFClusterCollection &theEClus, bool &bothGsfTrackerDriven, bool &nEcalDriven, bool &iEcalDriven, float &nEnergy, float &iEnergy)
def move(src, dest)
Definition: eostools.py:510
Definition: Run.h:43
MultiTrajectoryStateTransform mtsTransform_
bool isInnerMost(const reco::GsfTrackRef &nGsfTrack, const reco::GsfTrackRef &iGsfTrack, bool &sameLayer)