CMS 3D CMS Logo

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