CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
PFElectronAlgo.cc
Go to the documentation of this file.
1 //
2 // Original Author: Daniele Benedetti: daniele.benedetti@cern.ch
3 //
4 
7 //#include "DataFormats/ParticleFlowReco/interface/PFBlockElementGsfTrack.h"
23 
24 #include <iomanip>
25 #include <algorithm>
26 
27 using namespace std;
28 using namespace reco;
29 PFElectronAlgo::PFElectronAlgo(const double mvaEleCut,
30  string mvaWeightFileEleID,
31  const boost::shared_ptr<PFSCEnergyCalibration>& thePFSCEnergyCalibration,
32  bool applyCrackCorrections,
33  bool usePFSCEleCalib,
34  bool useEGElectrons,
41  unsigned int nTrackIsoForEgammaSC,
43  mvaEleCut_(mvaEleCut),
44  thePFSCEnergyCalibration_(thePFSCEnergyCalibration),
45  applyCrackCorrections_(applyCrackCorrections),
46  usePFSCEleCalib_(usePFSCEleCalib),
47  useEGElectrons_(useEGElectrons),
48  useEGammaSupercluster_(useEGammaSupercluster),
49  sumEtEcalIsoForEgammaSC_barrel_(sumEtEcalIsoForEgammaSC_barrel),
50  sumEtEcalIsoForEgammaSC_endcap_(sumEtEcalIsoForEgammaSC_endcap),
51  coneEcalIsoForEgammaSC_(coneEcalIsoForEgammaSC),
52  sumPtTrackIsoForEgammaSC_barrel_(sumPtTrackIsoForEgammaSC_barrel),
53  sumPtTrackIsoForEgammaSC_endcap_(sumPtTrackIsoForEgammaSC_endcap),
54  nTrackIsoForEgammaSC_(nTrackIsoForEgammaSC),
55  coneTrackIsoForEgammaSC_(coneTrackIsoForEgammaSC)
56 {
57  // Set the tmva reader
58  tmvaReader_ = new TMVA::Reader("!Color:Silent");
59  tmvaReader_->AddVariable("lnPt_gsf",&lnPt_gsf);
60  tmvaReader_->AddVariable("Eta_gsf",&Eta_gsf);
61  tmvaReader_->AddVariable("dPtOverPt_gsf",&dPtOverPt_gsf);
62  tmvaReader_->AddVariable("DPtOverPt_gsf",&DPtOverPt_gsf);
63  //tmvaReader_->AddVariable("nhit_gsf",&nhit_gsf);
64  tmvaReader_->AddVariable("chi2_gsf",&chi2_gsf);
65  //tmvaReader_->AddVariable("DPtOverPt_kf",&DPtOverPt_kf);
66  tmvaReader_->AddVariable("nhit_kf",&nhit_kf);
67  tmvaReader_->AddVariable("chi2_kf",&chi2_kf);
68  tmvaReader_->AddVariable("EtotPinMode",&EtotPinMode);
69  tmvaReader_->AddVariable("EGsfPoutMode",&EGsfPoutMode);
70  tmvaReader_->AddVariable("EtotBremPinPoutMode",&EtotBremPinPoutMode);
71  tmvaReader_->AddVariable("DEtaGsfEcalClust",&DEtaGsfEcalClust);
72  tmvaReader_->AddVariable("SigmaEtaEta",&SigmaEtaEta);
73  tmvaReader_->AddVariable("HOverHE",&HOverHE);
74 // tmvaReader_->AddVariable("HOverPin",&HOverPin);
75  tmvaReader_->AddVariable("lateBrem",&lateBrem);
76  tmvaReader_->AddVariable("firstBrem",&firstBrem);
77  tmvaReader_->BookMVA("BDT",mvaWeightFileEleID.c_str());
78 }
80  std::vector<bool>& active){
81 
82  // the maps are initialized
83  AssMap associatedToGsf;
84  AssMap associatedToBrems;
85  AssMap associatedToEcal;
86 
87  // should be cleaned as often as often as possible
88  elCandidate_.clear();
89  electronExtra_.clear();
90  allElCandidate_.clear();
91  electronConstituents_.clear();
92  fifthStepKfTrack_.clear();
93  convGsfTrack_.clear();
94  // SetLinks finds all the elements (kf,ecal,ps,hcal,brems)
95  // associated to each gsf track
96  bool blockHasGSF = SetLinks(blockRef,associatedToGsf,
97  associatedToBrems,associatedToEcal,
98  active);
99 
100  // check if there is at least a gsf track in the block.
101  if (blockHasGSF) {
102 
103  BDToutput_.clear();
104 
105  lockExtraKf_.clear();
106  // For each GSF track is initialized a BDT value = -1
107  BDToutput_.assign(associatedToGsf.size(),-1.);
108  lockExtraKf_.assign(associatedToGsf.size(),true);
109 
110  // The FinalID is run and BDToutput values is assigned
111  SetIDOutputs(blockRef,associatedToGsf,associatedToBrems,associatedToEcal);
112 
113  // For each GSF track that pass the BDT configurable cut a pf candidate electron is created.
114  // This function finds also the best estimation of the initial electron 4-momentum.
115 
116  SetCandidates(blockRef,associatedToGsf,associatedToBrems,associatedToEcal);
117  if (elCandidate_.size() > 0 ){
118  isvalid_ = true;
119  // when a pfelectron candidate is created all the elements associated to the
120  // electron are locked.
121  SetActive(blockRef,associatedToGsf,associatedToBrems,associatedToEcal,active);
122  }
123  } // endif blockHasGSF
124 }
126  AssMap& associatedToGsf_,
127  AssMap& associatedToBrems_,
128  AssMap& associatedToEcal_,
129  std::vector<bool>& active){
130  unsigned int CutIndex = 100000;
131  double CutGSFECAL = 10000. ;
132  // no other cut are not used anymore. We use the default of PFBlockAlgo
133  PFEnergyCalibration pfcalib_;
134  bool DebugSetLinksSummary = false;
135  bool DebugSetLinksDetailed = false;
136 
137  const reco::PFBlock& block = *blockRef;
139  PFBlock::LinkData linkData = block.linkData();
140 
141  bool IsThereAGSFTrack = false;
142  bool IsThereAGoodGSFTrack = false;
143 
144  vector<unsigned int> trackIs(0);
145  vector<unsigned int> gsfIs(0);
146  vector<unsigned int> ecalIs(0);
147 
148  std::vector<bool> localactive(elements.size(),true);
149 
150 
151  // Save the elements in shorter vectors like in PFAlgo.
152  std::multimap<double, unsigned int> kfElems;
153  for(unsigned int iEle=0; iEle<elements.size(); iEle++) {
154  localactive[iEle] = active[iEle];
155  bool thisIsAMuon = false;
156  PFBlockElement::Type type = elements[iEle].type();
157  switch( type ) {
158  case PFBlockElement::TRACK:
159  // Check if the track is already identified as a muon
160  thisIsAMuon = PFMuonAlgo::isMuon(elements[iEle]);
161  // Otherwise store index
162  if ( !thisIsAMuon && active[iEle] ) {
163  trackIs.push_back( iEle );
164  if (DebugSetLinksDetailed)
165  cout<<"TRACK, stored index, continue "<< iEle << endl;
166  }
167  continue;
168  case PFBlockElement::GSF:
169  // Check if the track has a KF partner identified as a muon
170  block.associatedElements( iEle,linkData,
171  kfElems,
174  thisIsAMuon = kfElems.size() ?
175  PFMuonAlgo::isMuon(elements[kfElems.begin()->second]) : false;
176  // Otherwise store index
177  if ( !thisIsAMuon && active[iEle] ) {
178  IsThereAGSFTrack = true;
179  gsfIs.push_back( iEle );
180  if (DebugSetLinksDetailed)
181  cout<<"GSF, stored index, continue "<< iEle << endl;
182  }
183  continue;
184  case PFBlockElement::ECAL:
185  if ( active[iEle] ) {
186  ecalIs.push_back( iEle );
187  if (DebugSetLinksDetailed)
188  cout<<"ECAL, stored index, continue "<< iEle << endl;
189  }
190  continue;
191  default:
192  continue;
193  }
194  }
195  // ******************* Start Link *****************************
196  // Do something only if a gsf track is found in the block
197  if(IsThereAGSFTrack) {
198 
199 
200  // LocalLock the Elements associated to a Kf tracks and not to a Gsf
201  // The clusters associated both to a kf track and to a brem tangend
202  // are then assigned only to the kf track
203  // Could be improved doing this after.
204 
205  // 19 Mar 2010 adding the KF track from Gamma Conv.
206  // They are linked to the GSF tracks they are not considered
207  // anymore in the following ecal cluster locking
208 
209  // cout<<"#########################################################"<<endl;
210  // cout<<"##### Process Block: #####"<<endl;
211  // cout<<"#########################################################"<<endl;
212  // cout<<block<<endl;
213 
214  for(unsigned int iEle=0; iEle<trackIs.size(); iEle++) {
215  std::multimap<double, unsigned int> gsfElems;
216  block.associatedElements( trackIs[iEle], linkData,
217  gsfElems ,
220  if(gsfElems.size() == 0){
221  // This means that the considered kf is *not* associated
222  // to any gsf track
223  std::multimap<double, unsigned int> ecalKfElems;
224  block.associatedElements( trackIs[iEle],linkData,
225  ecalKfElems,
228  if(ecalKfElems.size() > 0) {
229  unsigned int ecalKf_index = ecalKfElems.begin()->second;
230  if(localactive[ecalKf_index]==true) {
231  // Check if this clusters is however well linked to a primary gsf track
232  // if this the case the cluster is not locked.
233 
234  bool isGsfLinked = false;
235  for(unsigned int iGsf=0; iGsf<gsfIs.size(); iGsf++) {
236  // if the ecal cluster is associated contemporary to a KF track
237  // and to a GSF track from conv, it is assigned to the KF track
238  // In this way we can loose some cluster but it is safer for double counting.
239  const reco::PFBlockElementGsfTrack * GsfEl =
240  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsfIs[iGsf]]));
242 
243  std::multimap<double, unsigned int> ecalGsfElems;
244  block.associatedElements( gsfIs[iGsf],linkData,
245  ecalGsfElems,
248  if(ecalGsfElems.size() > 0) {
249  if (ecalGsfElems.begin()->second == ecalKf_index) {
250  isGsfLinked = true;
251  }
252  }
253  }
254  if(isGsfLinked == false) {
255  // add protection against energy loss because
256  // of the tracking fifth step
257  const reco::PFBlockElementTrack * kfEle =
258  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(trackIs[iEle])]));
259  reco::TrackRef refKf = kfEle->trackRef();
260  unsigned int Algo = 0;
261  if (refKf.isNonnull())
262  Algo = refKf->algo();
263  if(Algo < 9) {
264  localactive[ecalKf_index] = false;
265  }
266  else {
267  fifthStepKfTrack_.push_back(make_pair(ecalKf_index,trackIs[iEle]));
268  }
269  }
270  }
271  }
272  } // gsfElems.size()
273  } // loop on kf tracks
274 
275 
276  // start loop on gsf tracks
277  for(unsigned int iEle=0; iEle<gsfIs.size(); iEle++) {
278 
279  if (!localactive[(gsfIs[iEle])]) continue;
280 
281  localactive[gsfIs[iEle]] = false;
282  bool ClosestEcalWithKf = false;
283 
284  if (DebugSetLinksDetailed) cout << " Gsf Index " << gsfIs[iEle] << endl;
285 
286  const reco::PFBlockElementGsfTrack * GsfEl =
287  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[(gsfIs[iEle])]));
288 
289  // if GsfTrack fron converted bremsstralung continue
291  IsThereAGoodGSFTrack = true;
292  float eta_gsf = GsfEl->positionAtECALEntrance().eta();
293  float etaOut_gsf = GsfEl->Pout().eta();
294  float diffOutEcalEta = fabs(eta_gsf-etaOut_gsf);
295  reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
296  float Pin_gsf = 0.01;
297  if (RefGSF.isNonnull() )
298  Pin_gsf = RefGSF->pMode();
299 
300 
301  // Find Associated Kf Track elements and Ecal to KF elements
302  unsigned int KfGsf_index = CutIndex;
303  unsigned int KfGsf_secondIndex = CutIndex;
304  std::multimap<double, unsigned int> kfElems;
305  block.associatedElements( gsfIs[iEle],linkData,
306  kfElems,
309  std::multimap<double, unsigned int> ecalKfElems;
310  if (kfElems.size() > 0) {
311  // 19 Mar 2010 now a loop is needed because > 1 KF track could
312  // be associated to the same GSF track
313 
314  for(std::multimap<double, unsigned int>::iterator itkf = kfElems.begin();
315  itkf != kfElems.end(); ++itkf) {
316  const reco::PFBlockElementTrack * TrkEl =
317  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[itkf->second]));
318 
319  bool isPrim = isPrimaryTrack(*TrkEl,*GsfEl);
320  if(!isPrim)
321  continue;
322 
323  if(localactive[itkf->second] == true) {
324 
325  KfGsf_index = itkf->second;
326  localactive[KfGsf_index] = false;
327  // Find clusters associated to kftrack using linkbyrechit
328  block.associatedElements( KfGsf_index, linkData,
329  ecalKfElems ,
332  }
333  else {
334  KfGsf_secondIndex = itkf->second;
335  }
336  }
337  }
338 
339  // Find the closest Ecal clusters associated to this Gsf
340  std::multimap<double, unsigned int> ecalGsfElems;
341  block.associatedElements( gsfIs[iEle],linkData,
342  ecalGsfElems,
345  double ecalGsf_dist = CutGSFECAL;
346  unsigned int ClosestEcalGsf_index = CutIndex;
347  if (ecalGsfElems.size() > 0) {
348  if(localactive[(ecalGsfElems.begin()->second)] == true) {
349  // check energy compatibility for outer eta != ecal entrance, looping tracks
350  bool compatibleEPout = true;
351  if(diffOutEcalEta > 0.3) {
352  reco::PFClusterRef clusterRef = elements[(ecalGsfElems.begin()->second)].clusterRef();
353  float EoPout = (clusterRef->energy())/(GsfEl->Pout().t());
354  if(EoPout > 5)
355  compatibleEPout = false;
356  }
357  if(compatibleEPout) {
358  ClosestEcalGsf_index = ecalGsfElems.begin()->second;
359  ecalGsf_dist = block.dist(gsfIs[iEle],ClosestEcalGsf_index,
360  linkData,reco::PFBlock::LINKTEST_ALL);
361 
362  // Check that this cluster is not closer to another primary Gsf track
363 
364  std::multimap<double, unsigned int> ecalOtherGsfElems;
365  block.associatedElements( ClosestEcalGsf_index,linkData,
366  ecalOtherGsfElems,
369 
370  if(ecalOtherGsfElems.size()>0) {
371  // get if it is closed to a conv brem gsf tracks
372  const reco::PFBlockElementGsfTrack * gsfCheck =
373  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
374 
375  if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]&&
376  gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
377  ecalGsf_dist = CutGSFECAL;
378  ClosestEcalGsf_index = CutIndex;
379  }
380  }
381  }
382  // do not lock at the moment we need this for the late brem
383  }
384  }
385  // if any cluster is found with the gsf-ecal link, try with kf-ecal
386  else if(ecalKfElems.size() > 0) {
387  if(localactive[(ecalKfElems.begin()->second)] == true) {
388  ClosestEcalGsf_index = ecalKfElems.begin()->second;
389  ecalGsf_dist = block.dist(gsfIs[iEle],ClosestEcalGsf_index,
390  linkData,reco::PFBlock::LINKTEST_ALL);
391  ClosestEcalWithKf = true;
392 
393  // Check if this cluster is not closer to another Gsf track
394  std::multimap<double, unsigned int> ecalOtherGsfElems;
395  block.associatedElements( ClosestEcalGsf_index,linkData,
396  ecalOtherGsfElems,
399  if(ecalOtherGsfElems.size() > 0) {
400  const reco::PFBlockElementGsfTrack * gsfCheck =
401  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
402 
403  if(ecalOtherGsfElems.begin()->second != gsfIs[iEle] &&
405  ecalGsf_dist = CutGSFECAL;
406  ClosestEcalGsf_index = CutIndex;
407  ClosestEcalWithKf = false;
408  }
409  }
410  }
411  }
412 
413  if (DebugSetLinksDetailed)
414  cout << " Closest Ecal to the Gsf/Kf: index " << ClosestEcalGsf_index
415  << " dist " << ecalGsf_dist << endl;
416 
417 
418 
419  // Find the brems associated to this Gsf
420  std::multimap<double, unsigned int> bremElems;
421  block.associatedElements( gsfIs[iEle],linkData,
422  bremElems,
425 
426 
427  multimap<unsigned int,unsigned int> cleanedEcalBremElems;
428  vector<unsigned int> keyBremIndex(0);
429  unsigned int latestBrem_trajP = 0;
430  unsigned int latestBrem_index = CutIndex;
431  for(std::multimap<double, unsigned int>::iterator ieb = bremElems.begin();
432  ieb != bremElems.end(); ++ieb ) {
433  unsigned int brem_index = ieb->second;
434  if(localactive[brem_index] == false) continue;
435 
436 
437  // Find the ecal clusters associated to the brems
438  std::multimap<double, unsigned int> ecalBremsElems;
439 
440  block.associatedElements( brem_index, linkData,
441  ecalBremsElems,
444 
445  for (std::multimap<double, unsigned int>::iterator ie = ecalBremsElems.begin();
446  ie != ecalBremsElems.end();ie++) {
447  unsigned int ecalBrem_index = ie->second;
448  if(localactive[ecalBrem_index] == false) continue;
449 
450  //to be changed, using the distance
451  float ecalBrem_dist = block.dist(brem_index,ecalBrem_index,
452  linkData,reco::PFBlock::LINKTEST_ALL);
453 
454 
455  if (ecalBrem_index == ClosestEcalGsf_index && (ecalBrem_dist + 0.0012) > ecalGsf_dist) continue;
456 
457  // Find the closest brem
458  std::multimap<double, unsigned int> sortedBremElems;
459  block.associatedElements( ecalBrem_index,linkData,
460  sortedBremElems,
463  // check that this brem is that one coming from the same *primary* gsf
464  bool isGoodBrem = false;
465  unsigned int sortedBrem_index = CutIndex;
466  for (std::multimap<double, unsigned int>::iterator ibs = sortedBremElems.begin();
467  ibs != sortedBremElems.end();ibs++) {
468  unsigned int temp_sortedBrem_index = ibs->second;
469  std::multimap<double, unsigned int> sortedGsfElems;
470  block.associatedElements( temp_sortedBrem_index,linkData,
471  sortedGsfElems,
474  bool enteredInPrimaryGsf = false;
475  for (std::multimap<double, unsigned int>::iterator igs = sortedGsfElems.begin();
476  igs != sortedGsfElems.end();igs++) {
477  const reco::PFBlockElementGsfTrack * gsfCheck =
478  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[igs->second]));
479 
480  if(gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
481  if(igs->second == gsfIs[iEle]) {
482  isGoodBrem = true;
483  sortedBrem_index = temp_sortedBrem_index;
484  }
485  enteredInPrimaryGsf = true;
486  break;
487  }
488  }
489  if(enteredInPrimaryGsf)
490  break;
491  }
492 
493  if(isGoodBrem) {
494 
495  // Check that this cluster is not closer to another Gsf Track
496  // The check is not performed on KF track because the ecal clusters are aready locked.
497  std::multimap<double, unsigned int> ecalOtherGsfElems;
498  block.associatedElements( ecalBrem_index,linkData,
499  ecalOtherGsfElems,
502  if (ecalOtherGsfElems.size() > 0) {
503  const reco::PFBlockElementGsfTrack * gsfCheck =
504  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
505  if(ecalOtherGsfElems.begin()->second != gsfIs[iEle] &&
507  continue;
508  }
509  }
510 
511  const reco::PFBlockElementBrem * BremEl =
512  dynamic_cast<const reco::PFBlockElementBrem*>((&elements[sortedBrem_index]));
513 
514  reco::PFClusterRef clusterRef =
515  elements[ecalBrem_index].clusterRef();
516 
517 
518  float sortedBremEcal_deta = fabs(clusterRef->position().eta() - BremEl->positionAtECALEntrance().eta());
519  // Triangular cut on plan chi2:deta -> OLD
520  //if((0.0075*sortedBremEcal_chi2 + 100.*sortedBremEcal_deta -1.5) < 0.) {
521  if(sortedBremEcal_deta < 0.015) {
522 
523  cleanedEcalBremElems.insert(pair<unsigned int,unsigned int>(sortedBrem_index,ecalBrem_index));
524 
525  unsigned int BremTrajP = BremEl->indTrajPoint();
526  if (BremTrajP > latestBrem_trajP) {
527  latestBrem_trajP = BremTrajP;
528  latestBrem_index = sortedBrem_index;
529  }
530  if (DebugSetLinksDetailed)
531  cout << " brem Index " << sortedBrem_index
532  << " associated cluster " << ecalBrem_index << " BremTrajP " << BremTrajP <<endl;
533 
534  // > 1 ecal clusters could be associated to the same brem twice: allowed N-1 link.
535  // But the brem need to be stored once.
536  // locallock the brem and the ecal clusters
537  localactive[ecalBrem_index] = false; // the cluster
538  bool alreadyfound = false;
539  for(unsigned int ii=0;ii<keyBremIndex.size();ii++) {
540  if (sortedBrem_index == keyBremIndex[ii]) alreadyfound = true;
541  }
542  if (alreadyfound == false) {
543  keyBremIndex.push_back(sortedBrem_index);
544  localactive[sortedBrem_index] = false; // the brem
545  }
546  }
547  }
548  }
549  }
550 
551 
552  // Find Possible Extra Cluster associated to the gsf/kf
553  vector<unsigned int> GsfElemIndex(0);
554  vector<unsigned int> EcalIndex(0);
555 
556  // locallock the ecal cluster associated to the gsf
557  if (ClosestEcalGsf_index < CutIndex) {
558  GsfElemIndex.push_back(ClosestEcalGsf_index);
559  localactive[ClosestEcalGsf_index] = false;
560  for (std::multimap<double, unsigned int>::iterator ii = ecalGsfElems.begin();
561  ii != ecalGsfElems.end();ii++) {
562  if(localactive[ii->second]) {
563  // Check that this cluster is not closer to another Gsf Track
564  std::multimap<double, unsigned int> ecalOtherGsfElems;
565  block.associatedElements( ii->second,linkData,
566  ecalOtherGsfElems,
569  if(ecalOtherGsfElems.size()) {
570  if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]) continue;
571  }
572 
573  // get the cluster only if the deta (ecal-gsf) < 0.05
574  reco::PFClusterRef clusterRef = elements[(ii->second)].clusterRef();
575  float etacl = clusterRef->eta();
576  if( fabs(eta_gsf-etacl) < 0.05) {
577  GsfElemIndex.push_back(ii->second);
578  localactive[ii->second] = false;
579  if (DebugSetLinksDetailed)
580  cout << " ExtraCluster From Gsf " << ii->second << endl;
581  }
582  }
583  }
584  }
585 
586  //Add the possibility to link other ecal clusters from kf.
587 
588 // for (std::multimap<double, unsigned int>::iterator ii = ecalKfElems.begin();
589 // ii != ecalKfElems.end();ii++) {
590 // if(localactive[ii->second]) {
591 // // Check that this cluster is not closer to another Gsf Track
592 // std::multimap<double, unsigned int> ecalOtherGsfElems;
593 // block.associatedElements( ii->second,linkData,
594 // ecalOtherGsfElems,
595 // reco::PFBlockElement::GSF,
596 // reco::PFBlock::LINKTEST_CHI2);
597 // if(ecalOtherGsfElems.size()) {
598 // if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]) continue;
599 // }
600 // GsfElemIndex.push_back(ii->second);
601 // reco::PFClusterRef clusterRef = elements[(ii->second)].clusterRef();
602 // float etacl = clusterRef->eta();
603 // if( fabs(eta_gsf-etacl) < 0.05) {
604 // localactive[ii->second] = false;
605 // if (DebugSetLinksDetailed)
606 // cout << " ExtraCluster From KF " << ii->second << endl;
607 // }
608 // }
609 // }
610 
611  //****************** Fill Maps *************************
612 
613  // The GsfMap
614 
615  // if any clusters have been associated to the gsf track
616  // use the Ecal clusters associated to the latest brem and associate it to the gsf
617  if(GsfElemIndex.size() == 0){
618  if(latestBrem_index < CutIndex) {
619  unsigned int ckey = cleanedEcalBremElems.count(latestBrem_index);
620  if(ckey == 1) {
621  unsigned int temp_cal =
622  cleanedEcalBremElems.find(latestBrem_index)->second;
623  GsfElemIndex.push_back(temp_cal);
624  if (DebugSetLinksDetailed)
625  cout << "******************** Gsf Cluster From Brem " << temp_cal
626  << " Latest Brem index " << latestBrem_index
627  << " ************************* " << endl;
628  }
629  else{
630  pair<multimap<unsigned int,unsigned int>::iterator,multimap<unsigned int,unsigned int>::iterator> ret;
631  ret = cleanedEcalBremElems.equal_range(latestBrem_index);
632  multimap<unsigned int,unsigned int>::iterator it;
633  for(it=ret.first; it!=ret.second; ++it) {
634  GsfElemIndex.push_back((*it).second);
635  if (DebugSetLinksDetailed)
636  cout << "******************** Gsf Cluster From Brem " << (*it).second
637  << " Latest Brem index " << latestBrem_index
638  << " ************************* " << endl;
639  }
640  }
641  // erase the brem.
642  unsigned int elToErase = 0;
643  for(unsigned int i = 0; i<keyBremIndex.size();i++) {
644  if(latestBrem_index == keyBremIndex[i]) {
645  elToErase = i;
646  }
647  }
648  keyBremIndex.erase(keyBremIndex.begin()+elToErase);
649  }
650  }
651 
652  // Get Extra Clusters from converted brem gsf tracks. The locallock method
653  // tells me if the ecal cluster has been already assigned to the primary
654  // gsf track or to a brem
655 
656  for(unsigned int iConv=0; iConv<gsfIs.size(); iConv++) {
657  if(iConv != iEle) {
658 
659  const reco::PFBlockElementGsfTrack * gsfConv =
660  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[(gsfIs[iConv])]));
661 
662  // look at only to secondary gsf tracks
664  if (DebugSetLinksDetailed)
665  cout << " PFElectronAlgo:: I'm running on convGsfBrem " << endl;
666  // check if they are linked to the primary
667  float conv_dist = block.dist(gsfIs[iConv],gsfIs[iEle],
668  linkData,reco::PFBlock::LINKTEST_ALL);
669  if(conv_dist > 0.) {
670  // find the closest ecal cluster associated to conversions
671 
672  std::multimap<double, unsigned int> ecalConvElems;
673  block.associatedElements( gsfIs[iConv],linkData,
674  ecalConvElems,
677  if(ecalConvElems.size() > 0) {
678  // the ecal cluster is still active?
679  if(localactive[(ecalConvElems.begin()->second)] == true) {
680  if (DebugSetLinksDetailed)
681  cout << " PFElectronAlgo:: convGsfBrem has a ECAL cluster linked and free" << endl;
682  // Check that this cluster is not closer to another primary Gsf track
683  std::multimap<double, unsigned int> ecalOtherGsfPrimElems;
684  block.associatedElements( ecalConvElems.begin()->second,linkData,
685  ecalOtherGsfPrimElems,
688  if(ecalOtherGsfPrimElems.size()>0) {
689  unsigned int gsfprimcheck_index = ecalOtherGsfPrimElems.begin()->second;
690  const reco::PFBlockElementGsfTrack * gsfCheck =
691  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsfprimcheck_index]));
692  if(gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) continue;
693 
694  reco::PFClusterRef clusterRef = elements[ecalConvElems.begin()->second].clusterRef();
695  if (DebugSetLinksDetailed)
696  cout << " PFElectronAlgo: !!!!!!! convGsfBrem ECAL cluster has been stored !!!!!!! "
697  << " Energy " << clusterRef->energy() << " eta,phi " << clusterRef->position().eta()
698  <<", " << clusterRef->position().phi() << endl;
699 
700  GsfElemIndex.push_back(ecalConvElems.begin()->second);
701  convGsfTrack_.push_back(make_pair(ecalConvElems.begin()->second,gsfIs[iConv]));
702  localactive[ecalConvElems.begin()->second] = false;
703 
704  }
705  }
706  }
707  }
708  }
709  }
710  }
711 
712 
713 
714  EcalIndex.insert(EcalIndex.end(),GsfElemIndex.begin(),GsfElemIndex.end());
715 
716 
717 
718  // The BremMap
719  for(unsigned int i =0;i<keyBremIndex.size();i++) {
720  unsigned int ikey = keyBremIndex[i];
721  unsigned int ckey = cleanedEcalBremElems.count(ikey);
722  vector<unsigned int> BremElemIndex(0);
723  if(ckey == 1) {
724  unsigned int temp_cal =
725  cleanedEcalBremElems.find(ikey)->second;
726  BremElemIndex.push_back(temp_cal);
727  }
728  else{
729  pair<multimap<unsigned int,unsigned int>::iterator,multimap<unsigned int,unsigned int>::iterator> ret;
730  ret = cleanedEcalBremElems.equal_range(ikey);
731  multimap<unsigned int,unsigned int>::iterator it;
732  for(it=ret.first; it!=ret.second; ++it) {
733  BremElemIndex.push_back((*it).second);
734  }
735  }
736  EcalIndex.insert(EcalIndex.end(),BremElemIndex.begin(),BremElemIndex.end());
737  associatedToBrems_.insert(pair<unsigned int,vector<unsigned int> >(ikey,BremElemIndex));
738  }
739 
740 
741  // 19 Mar 2010: add KF and ECAL elements from converted brem photons
742  vector<unsigned int> convBremKFTrack;
743  convBremKFTrack.clear();
744  if (kfElems.size() > 0) {
745  for(std::multimap<double, unsigned int>::iterator itkf = kfElems.begin();
746  itkf != kfElems.end(); ++itkf) {
747  const reco::PFBlockElementTrack * TrkEl =
748  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[itkf->second]));
749  bool isPrim = isPrimaryTrack(*TrkEl,*GsfEl);
750 
751  if(!isPrim) {
752 
753  // search for linked ECAL clusters
754  std::multimap<double, unsigned int> ecalConvElems;
755  block.associatedElements( itkf->second,linkData,
756  ecalConvElems,
759  if(ecalConvElems.size() > 0) {
760  // Further Cleaning: DANIELE This could be improved!
761  TrackRef trkRef = TrkEl->trackRef();
762  // iter0, iter1, iter2, iter3 = Algo < 3
763  unsigned int Algo = whichTrackAlgo(trkRef);
764 
765  float secpin = trkRef->p();
766 
767  const reco::PFBlockElementCluster * clust =
768  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(ecalConvElems.begin()->second)]));
769  float eneclust =clust->clusterRef()->energy();
770 
771  //1) ******* Reject secondary KF tracks linked to also an HCAL cluster with H/(E+H) > 0.1
772  // This is applied also to KF linked to locked ECAL cluster
773  // NOTE: trusting the H/(E+H) and not the conv brem selection increse the number
774  // of charged hadrons around the electron. DANIELE? re-think about this.
775  std::multimap<double, unsigned int> hcalConvElems;
776  block.associatedElements( itkf->second,linkData,
777  hcalConvElems,
780 
781  bool isHoHE = false;
782  bool isHoE = false;
783  bool isPoHE = false;
784 
785  float enehcalclust = -1;
786  if(hcalConvElems.size() > 0) {
787  const reco::PFBlockElementCluster * clusthcal =
788  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(hcalConvElems.begin()->second)]));
789  enehcalclust =clusthcal->clusterRef()->energy();
790  // NOTE: DANIELE? Are you sure you want to use the Algo type here?
791  if( (enehcalclust / (enehcalclust+eneclust) ) > 0.1 && Algo < 3) {
792  isHoHE = true;
793  if(enehcalclust > eneclust)
794  isHoE = true;
795  if(secpin > (enehcalclust+eneclust) )
796  isPoHE = true;
797  }
798  }
799 
800 
801  if(localactive[(ecalConvElems.begin()->second)] == false) {
802 
803  if(isHoE || isPoHE) {
804  if (DebugSetLinksDetailed)
805  cout << "PFElectronAlgo:: LOCKED ECAL REJECTED TRACK FOR H/E or P/(H+E) "
806  << " H/H+E " << enehcalclust/(enehcalclust+eneclust)
807  << " H/E " << enehcalclust/eneclust
808  << " P/(H+E) " << secpin/(enehcalclust+eneclust)
809  << " HCAL ENE " << enehcalclust
810  << " ECAL ENE " << eneclust
811  << " secPIN " << secpin
812  << " Algo Track " << Algo << endl;
813  continue;
814  }
815 
816  // check if this track has been alread assigned to an ECAL cluster
817  for(unsigned int iecal =0; iecal < EcalIndex.size(); iecal++) {
818  // in case this track is already assigned to a locked ECAL cluster
819  // the secondary kf track is also saved for further lock
820  if(EcalIndex[iecal] == ecalConvElems.begin()->second) {
821  if (DebugSetLinksDetailed)
822  cout << " PFElectronAlgo:: Conv Brem Recovery locked cluster and I will lock also the KF track " << endl;
823  convBremKFTrack.push_back(itkf->second);
824  }
825  }
826  }
827  else{
828  // ECAL cluster free
829 
830  //
831  if(isHoHE){
832  if (DebugSetLinksDetailed)
833  cout << "PFElectronAlgo:: FREE ECAL REJECTED TRACK FOR H/H+E "
834  << " H/H+E " << (enehcalclust / (enehcalclust+eneclust) )
835  << " H/E " << enehcalclust/eneclust
836  << " P/(H+E) " << secpin/(enehcalclust+eneclust)
837  << " HCAL ENE " << enehcalclust
838  << " ECAL ENE " << eneclust
839  << " secPIN " << secpin
840  << " Algo Track " << Algo << endl;
841  continue;
842  }
843 
844  // check that this cluster is not cluser to another KF track (primary)
845  std::multimap<double, unsigned int> ecalOtherKFPrimElems;
846  block.associatedElements( ecalConvElems.begin()->second,linkData,
847  ecalOtherKFPrimElems,
850  if(ecalOtherKFPrimElems.size() > 0) {
851 
852  // check that this ECAL clusters is the best associated to at least one of the KF tracks
853  // linked to the considered GSF track
854  bool isFromGSF = false;
855  for(std::multimap<double, unsigned int>::iterator itclos = kfElems.begin();
856  itclos != kfElems.end(); ++itclos) {
857  if(ecalOtherKFPrimElems.begin()->second == itclos->second) {
858  isFromGSF = true;
859  break;
860  }
861  }
862  if(isFromGSF){
863 
864  // Further Cleaning: DANIELE This could be improved!
865 
866 
867  float Epin = eneclust/secpin;
868 
869  // compute the pfsupercluster energy till now
870  float totenergy = 0.;
871  for(unsigned int ikeyecal = 0;
872  ikeyecal<EcalIndex.size(); ikeyecal++){
873  // EcalIndex can have the same cluster save twice (because of the late brem cluster).
874  bool foundcluster = false;
875  if(ikeyecal > 0) {
876  for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
877  if(EcalIndex[ikeyecal] == EcalIndex[i2])
878  foundcluster = true;
879  }
880  }
881  if(foundcluster) continue;
882  const reco::PFBlockElementCluster * clusasso =
883  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(EcalIndex[ikeyecal])]));
884  totenergy += clusasso->clusterRef()->energy();
885  }
886 
887  // Further Cleaning: DANIELE This could be improved!
888  //2) ***** Do not consider secondary tracks if the GSF and brems have failed in finding ECAL clusters
889  if(totenergy == 0.) {
890  if (DebugSetLinksDetailed)
891  cout << "PFElectronAlgo:: REJECTED_NULLTOT totenergy " << totenergy << endl;
892  continue;
893  }
894 
895  //3) ****** Reject secondary KF tracks that have an high E/secPin and that make worse the Etot/pin
896  if(Epin > 3) {
897  double res_before = fabs((totenergy-Pin_gsf)/Pin_gsf);
898  double res_after = fabs(((totenergy+eneclust)-Pin_gsf)/Pin_gsf);
899 
900  if(res_before < res_after) {
901  if (DebugSetLinksDetailed)
902  cout << "PFElectronAlgo::REJECTED_RES totenergy " << totenergy << " Pin_gsf " << Pin_gsf << " cluster to secondary " << eneclust
903  << " Res before " << res_before << " res_after " << res_after << endl;
904  continue;
905  }
906  }
907 
908  if (DebugSetLinksDetailed)
909  cout << "PFElectronAlgo:: conv brem found asso to ECAL linked to a secondary KF " << endl;
910  convBremKFTrack.push_back(itkf->second);
911  GsfElemIndex.push_back(ecalConvElems.begin()->second);
912  EcalIndex.push_back(ecalConvElems.begin()->second);
913  localactive[(ecalConvElems.begin()->second)] = false;
914  localactive[(itkf->second)] = false;
915  }
916  }
917  }
918  }
919  }
920  }
921  }
922 
923  // 4May import EG supercluster
924  if(EcalIndex.size() > 0 && useEGammaSupercluster_) {
925  double sumEtEcalInTheCone = 0.;
926 
927  // Position of the first cluster
928  const reco::PFBlockElementCluster * clust =
929  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[EcalIndex[0]]));
930  double PhiFC = clust->clusterRef()->position().Phi();
931  double EtaFC = clust->clusterRef()->position().Eta();
932 
933  // Compute ECAL isolation ->
934  for(unsigned int iEcal=0; iEcal<ecalIs.size(); iEcal++) {
935  bool foundcluster = false;
936  for(unsigned int ikeyecal = 0;
937  ikeyecal<EcalIndex.size(); ikeyecal++){
938  if(ecalIs[iEcal] == EcalIndex[ikeyecal])
939  foundcluster = true;
940  }
941 
942  // -> only for clusters not already in the PFSCCluster
943  if(foundcluster == false) {
944  const reco::PFBlockElementCluster * clustExt =
945  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[ecalIs[iEcal]]));
946  double eta_clust = clustExt->clusterRef()->position().Eta();
947  double phi_clust = clustExt->clusterRef()->position().Phi();
948  double theta_clust = clustExt->clusterRef()->position().Theta();
949  double deta_clust = eta_clust - EtaFC;
950  double dphi_clust = phi_clust - PhiFC;
951  if ( dphi_clust < -M_PI )
952  dphi_clust = dphi_clust + 2.*M_PI;
953  else if ( dphi_clust > M_PI )
954  dphi_clust = dphi_clust - 2.*M_PI;
955  double DR = sqrt(deta_clust*deta_clust+
956  dphi_clust*dphi_clust);
957 
958  //Jurassic veto in deta
959  if(fabs(deta_clust) > 0.05 && DR < coneEcalIsoForEgammaSC_) {
960  vector<double> ps1Ene(0);
961  vector<double> ps2Ene(0);
962  double ps1,ps2;
963  ps1=ps2=0.;
964  double EE_calib = pfcalib_.energyEm(*(clustExt->clusterRef()),ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
965  double ET_calib = EE_calib*sin(theta_clust);
966  sumEtEcalInTheCone += ET_calib;
967  }
968  }
969  } //EndLoop Additional ECAL clusters in the block
970 
971  // Compute track isolation: number of tracks && sumPt
972  unsigned int sumNTracksInTheCone = 0;
973  double sumPtTracksInTheCone = 0.;
974  for(unsigned int iTrack=0; iTrack<trackIs.size(); iTrack++) {
975  // the track from the electron are already locked at this stage
976  if(localactive[(trackIs[iTrack])]==true) {
977  const reco::PFBlockElementTrack * kfEle =
978  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(trackIs[iTrack])]));
979  reco::TrackRef trkref = kfEle->trackRef();
980  if (trkref.isNonnull()) {
981  double deta_trk = trkref->eta() - RefGSF->etaMode();
982  double dphi_trk = trkref->phi() - RefGSF->phiMode();
983  if ( dphi_trk < -M_PI )
984  dphi_trk = dphi_trk + 2.*M_PI;
985  else if ( dphi_trk > M_PI )
986  dphi_trk = dphi_trk - 2.*M_PI;
987  double DR = sqrt(deta_trk*deta_trk+
988  dphi_trk*dphi_trk);
989 
990  reco::HitPattern kfHitPattern = trkref->hitPattern();
991  int NValPixelHit = kfHitPattern.numberOfValidPixelHits();
992 
993  if(DR < coneTrackIsoForEgammaSC_ && NValPixelHit >=3) {
994  sumNTracksInTheCone++;
995  sumPtTracksInTheCone+=trkref->pt();
996  }
997  }
998  }
999  }
1000 
1001 
1002  bool isBarrelIsolated = false;
1003  if( fabs(EtaFC < 1.478) &&
1004  (sumEtEcalInTheCone < sumEtEcalIsoForEgammaSC_barrel_ &&
1005  (sumNTracksInTheCone < nTrackIsoForEgammaSC_ || sumPtTracksInTheCone < sumPtTrackIsoForEgammaSC_barrel_)))
1006  isBarrelIsolated = true;
1007 
1008 
1009  bool isEndcapIsolated = false;
1010  if( fabs(EtaFC >= 1.478) &&
1011  (sumEtEcalInTheCone < sumEtEcalIsoForEgammaSC_endcap_ &&
1012  (sumNTracksInTheCone < nTrackIsoForEgammaSC_ || sumPtTracksInTheCone < sumPtTrackIsoForEgammaSC_endcap_)))
1013  isEndcapIsolated = true;
1014 
1015 
1016  // only print out
1017  if(DebugSetLinksDetailed) {
1018  if(fabs(EtaFC < 1.478) && isBarrelIsolated == false) {
1019  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS ISOLATION:BARREL *** "
1020  << " sumEtEcalInTheCone " <<sumEtEcalInTheCone
1021  << " sumNTracksInTheCone " << sumNTracksInTheCone
1022  << " sumPtTracksInTheCone " << sumPtTracksInTheCone << endl;
1023  }
1024  if(fabs(EtaFC >= 1.478) && isEndcapIsolated == false) {
1025  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS ISOLATION:ENDCAP *** "
1026  << " sumEtEcalInTheCone " <<sumEtEcalInTheCone
1027  << " sumNTracksInTheCone " << sumNTracksInTheCone
1028  << " sumPtTracksInTheCone " << sumPtTracksInTheCone << endl;
1029  }
1030  }
1031 
1032 
1033 
1034 
1035  if(isBarrelIsolated || isEndcapIsolated ) {
1036 
1037 
1038  // Compute TotEnergy
1039  double totenergy = 0.;
1040  for(unsigned int ikeyecal = 0;
1041  ikeyecal<EcalIndex.size(); ikeyecal++){
1042  // EcalIndex can have the same cluster save twice (because of the late brem cluster).
1043  bool foundcluster = false;
1044  if(ikeyecal > 0) {
1045  for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
1046  if(EcalIndex[ikeyecal] == EcalIndex[i2])
1047  foundcluster = true;;
1048  }
1049  }
1050  if(foundcluster) continue;
1051  const reco::PFBlockElementCluster * clusasso =
1052  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(EcalIndex[ikeyecal])]));
1053  totenergy += clusasso->clusterRef()->energy();
1054  }
1055  // End copute TotEnergy
1056 
1057 
1058  // Find extra cluster from e/g importing
1059  for(unsigned int ikeyecal = 0;
1060  ikeyecal<EcalIndex.size(); ikeyecal++){
1061  // EcalIndex can have the same cluster save twice (because of the late brem cluster).
1062  bool foundcluster = false;
1063  if(ikeyecal > 0) {
1064  for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
1065  if(EcalIndex[ikeyecal] == EcalIndex[i2])
1066  foundcluster = true;
1067  }
1068  }
1069  if(foundcluster) continue;
1070 
1071 
1072  std::multimap<double, unsigned int> ecalFromSuperClusterElems;
1073  block.associatedElements( EcalIndex[ikeyecal],linkData,
1074  ecalFromSuperClusterElems,
1077  if(ecalFromSuperClusterElems.size() > 0) {
1078  for(std::multimap<double, unsigned int>::iterator itsc = ecalFromSuperClusterElems.begin();
1079  itsc != ecalFromSuperClusterElems.end(); ++itsc) {
1080  if(localactive[itsc->second] == false) {
1081  continue;
1082  }
1083 
1084  std::multimap<double, unsigned int> ecalOtherKFPrimElems;
1085  block.associatedElements( itsc->second,linkData,
1086  ecalOtherKFPrimElems,
1089  if(ecalOtherKFPrimElems.size() > 0) {
1090  if(localactive[ecalOtherKFPrimElems.begin()->second] == true) {
1091  if (DebugSetLinksDetailed)
1092  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS KF VETO *** " << endl;
1093  continue;
1094  }
1095  }
1096  bool isInTheEtaRange = false;
1097  const reco::PFBlockElementCluster * clustToAdd =
1098  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[itsc->second]));
1099  double deta_clustToAdd = clustToAdd->clusterRef()->position().Eta() - EtaFC;
1100  double ene_clustToAdd = clustToAdd->clusterRef()->energy();
1101 
1102  if(fabs(deta_clustToAdd) < 0.05)
1103  isInTheEtaRange = true;
1104 
1105  // check for both KF and GSF
1106  bool isBetterEpin = false;
1107  if(isInTheEtaRange == false ) {
1108  if (DebugSetLinksDetailed)
1109  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS GAMMA DETA RANGE *** "
1110  << fabs(deta_clustToAdd) << endl;
1111 
1112  if(KfGsf_index < CutIndex) {
1113  //GSF
1114  double res_before_gsf = fabs((totenergy-Pin_gsf)/Pin_gsf);
1115  double res_after_gsf = fabs(((totenergy+ene_clustToAdd)-Pin_gsf)/Pin_gsf);
1116 
1117  //KF
1118  const reco::PFBlockElementTrack * trackEl =
1119  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[KfGsf_index]));
1120  double Pin_kf = trackEl->trackRef()->p();
1121  double res_before_kf = fabs((totenergy-Pin_kf)/Pin_kf);
1122  double res_after_kf = fabs(((totenergy+ene_clustToAdd)-Pin_kf)/Pin_kf);
1123 
1124  // The new cluster improve both the E/pin?
1125  if(res_after_gsf < res_before_gsf && res_after_kf < res_before_kf ) {
1126  isBetterEpin = true;
1127  }
1128  else {
1129  if (DebugSetLinksDetailed)
1130  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND AND FAILS ALSO RES_EPIN"
1131  << " tot energy " << totenergy
1132  << " Pin_gsf " << Pin_gsf
1133  << " Pin_kf " << Pin_kf
1134  << " cluster from SC to ADD " << ene_clustToAdd
1135  << " Res before GSF " << res_before_gsf << " res_after_gsf " << res_after_gsf
1136  << " Res before KF " << res_before_kf << " res_after_kf " << res_after_kf << endl;
1137  }
1138  }
1139  }
1140 
1141  if(isInTheEtaRange || isBetterEpin) {
1142  if (DebugSetLinksDetailed)
1143  cout << "!!!! PFElectronAlgo:: ECAL from SUPERCLUSTER FOUND !!!!! " << endl;
1144  GsfElemIndex.push_back(itsc->second);
1145  EcalIndex.push_back(itsc->second);
1146  localactive[(itsc->second)] = false;
1147  }
1148  }
1149  }
1150  }
1151  } // END ISOLATION IF
1152  }
1153 
1154 
1155  if(KfGsf_index < CutIndex)
1156  GsfElemIndex.push_back(KfGsf_index);
1157  else if(KfGsf_secondIndex < CutIndex)
1158  GsfElemIndex.push_back(KfGsf_secondIndex);
1159 
1160  // insert the secondary KF tracks
1161  GsfElemIndex.insert(GsfElemIndex.end(),convBremKFTrack.begin(),convBremKFTrack.end());
1162  GsfElemIndex.insert(GsfElemIndex.end(),keyBremIndex.begin(),keyBremIndex.end());
1163  associatedToGsf_.insert(pair<unsigned int, vector<unsigned int> >(gsfIs[iEle],GsfElemIndex));
1164 
1165  // The EcalMap
1166  for(unsigned int ikeyecal = 0;
1167  ikeyecal<EcalIndex.size(); ikeyecal++){
1168 
1169 
1170  vector<unsigned int> EcalElemsIndex(0);
1171 
1172  std::multimap<double, unsigned int> PS1Elems;
1173  block.associatedElements( EcalIndex[ikeyecal],linkData,
1174  PS1Elems,
1177  for( std::multimap<double, unsigned int>::iterator it = PS1Elems.begin();
1178  it != PS1Elems.end();it++) {
1179  unsigned int index = it->second;
1180  if(localactive[index] == true) {
1181 
1182  // Check that this cluster is not closer to another ECAL cluster
1183  std::multimap<double, unsigned> sortedECAL;
1184  block.associatedElements( index, linkData,
1185  sortedECAL,
1188  unsigned jEcal = sortedECAL.begin()->second;
1189  if ( jEcal != EcalIndex[ikeyecal]) continue;
1190 
1191 
1192  EcalElemsIndex.push_back(index);
1193  localactive[index] = false;
1194  }
1195  }
1196 
1197  std::multimap<double, unsigned int> PS2Elems;
1198  block.associatedElements( EcalIndex[ikeyecal],linkData,
1199  PS2Elems,
1202  for( std::multimap<double, unsigned int>::iterator it = PS2Elems.begin();
1203  it != PS2Elems.end();it++) {
1204  unsigned int index = it->second;
1205  if(localactive[index] == true) {
1206  // Check that this cluster is not closer to another ECAL cluster
1207  std::multimap<double, unsigned> sortedECAL;
1208  block.associatedElements( index, linkData,
1209  sortedECAL,
1212  unsigned jEcal = sortedECAL.begin()->second;
1213  if ( jEcal != EcalIndex[ikeyecal]) continue;
1214 
1215  EcalElemsIndex.push_back(index);
1216  localactive[index] = false;
1217  }
1218  }
1219  if(ikeyecal == 0) {
1220  // The first cluster is that one coming from the Gsf.
1221  // Only for this one is found the HCAL cluster using the Track-HCAL link
1222  // and not the Ecal-Hcal not well tested yet.
1223  std::multimap<double, unsigned int> hcalGsfElems;
1224  block.associatedElements( gsfIs[iEle],linkData,
1225  hcalGsfElems,
1228  for( std::multimap<double, unsigned int>::iterator it = hcalGsfElems.begin();
1229  it != hcalGsfElems.end();it++) {
1230  unsigned int index = it->second;
1231  // if(localactive[index] == true) {
1232 
1233  // Check that this cluster is not closer to another GSF
1234  // remove in high energetic jets this is dangerous.
1235 // std::multimap<double, unsigned> sortedGsf;
1236 // block.associatedElements( index, linkData,
1237 // sortedGsf,
1238 // reco::PFBlockElement::GSF,
1239 // reco::PFBlock::LINKTEST_ALL );
1240 // unsigned jGsf = sortedGsf.begin()->second;
1241 // if ( jGsf != gsfIs[iEle]) continue;
1242 
1243  EcalElemsIndex.push_back(index);
1244  localactive[index] = false;
1245 
1246  // }
1247  }
1248  // if the closest ecal cluster has been link with the KF, check KF - HCAL link
1249  if(hcalGsfElems.size() == 0 && ClosestEcalWithKf == true) {
1250  std::multimap<double, unsigned int> hcalKfElems;
1251  block.associatedElements( KfGsf_index,linkData,
1252  hcalKfElems,
1255  for( std::multimap<double, unsigned int>::iterator it = hcalKfElems.begin();
1256  it != hcalKfElems.end();it++) {
1257  unsigned int index = it->second;
1258  if(localactive[index] == true) {
1259 
1260  // Check that this cluster is not closer to another KF
1261  std::multimap<double, unsigned> sortedKf;
1262  block.associatedElements( index, linkData,
1263  sortedKf,
1266  unsigned jKf = sortedKf.begin()->second;
1267  if ( jKf != KfGsf_index) continue;
1268  EcalElemsIndex.push_back(index);
1269  localactive[index] = false;
1270  }
1271  }
1272  }
1273  // Find Other Primary Tracks Associated to the same Gsf Clusters
1274  std::multimap<double, unsigned int> kfEtraElems;
1275  block.associatedElements( EcalIndex[ikeyecal],linkData,
1276  kfEtraElems,
1279  if(kfEtraElems.size() > 0) {
1280  for( std::multimap<double, unsigned int>::iterator it = kfEtraElems.begin();
1281  it != kfEtraElems.end();it++) {
1282  unsigned int index = it->second;
1283 
1284  // 19 Mar 2010 do not consider here tracks from gamma conv
1285  // const reco::PFBlockElementTrack * kfTk =
1286  // dynamic_cast<const reco::PFBlockElementTrack*>((&elements[index]));
1287  // DANIELE ? It is not need because of the local locking
1288  // if(kfTk->isLinkedToDisplacedVertex()) continue;
1289 
1290  bool thisIsAMuon = false;
1291  thisIsAMuon = PFMuonAlgo::isMuon(elements[index]);
1292  if (DebugSetLinksDetailed && thisIsAMuon)
1293  cout << " This is a Muon: index " << index << endl;
1294  if(localactive[index] == true && !thisIsAMuon) {
1295  if(index != KfGsf_index) {
1296  // Check that this track is not closer to another ECAL cluster
1297  // Not Sure here I need this step
1298  std::multimap<double, unsigned> sortedECAL;
1299  block.associatedElements( index, linkData,
1300  sortedECAL,
1303  unsigned jEcal = sortedECAL.begin()->second;
1304  if ( jEcal != EcalIndex[ikeyecal]) continue;
1305  EcalElemsIndex.push_back(index);
1306  localactive[index] = false;
1307  }
1308  }
1309  }
1310  }
1311 
1312  }
1313  associatedToEcal_.insert(pair<unsigned int,vector<unsigned int> >(EcalIndex[ikeyecal],EcalElemsIndex));
1314  }
1315  }// end type GSF
1316  } // endis there a gsf track
1317 
1318  // ******************* End Link *****************************
1319 
1320  //
1321  // Below is only for debugging printout
1322  if (DebugSetLinksSummary) {
1323  if(IsThereAGoodGSFTrack) {
1324  if (DebugSetLinksSummary) cout << " -- The Link Summary --" << endl;
1325  for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToGsf_.begin();
1326  it != associatedToGsf_.end(); it++) {
1327 
1328  if (DebugSetLinksSummary) cout << " AssoGsf " << it->first << endl;
1329  vector<unsigned int> eleasso = it->second;
1330  for(unsigned int i=0;i<eleasso.size();i++) {
1331  PFBlockElement::Type type = elements[eleasso[i]].type();
1332  if(type == reco::PFBlockElement::BREM) {
1333  if (DebugSetLinksSummary)
1334  cout << " AssoGsfElements BREM " << eleasso[i] << endl;
1335  }
1336  else if(type == reco::PFBlockElement::ECAL) {
1337  if (DebugSetLinksSummary)
1338  cout << " AssoGsfElements ECAL " << eleasso[i] << endl;
1339  }
1340  else if(type == reco::PFBlockElement::TRACK) {
1341  if (DebugSetLinksSummary)
1342  cout << " AssoGsfElements KF " << eleasso[i] << endl;
1343  }
1344  else {
1345  if (DebugSetLinksSummary)
1346  cout << " AssoGsfElements ????? " << eleasso[i] << endl;
1347  }
1348  }
1349  }
1350 
1351  for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToBrems_.begin();
1352  it != associatedToBrems_.end(); it++) {
1353  if (DebugSetLinksSummary) cout << " AssoBrem " << it->first << endl;
1354  vector<unsigned int> eleasso = it->second;
1355  for(unsigned int i=0;i<eleasso.size();i++) {
1356  PFBlockElement::Type type = elements[eleasso[i]].type();
1357  if(type == reco::PFBlockElement::ECAL) {
1358  if (DebugSetLinksSummary)
1359  cout << " AssoBremElements ECAL " << eleasso[i] << endl;
1360  }
1361  else {
1362  if (DebugSetLinksSummary)
1363  cout << " AssoBremElements ????? " << eleasso[i] << endl;
1364  }
1365  }
1366  }
1367 
1368  for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToEcal_.begin();
1369  it != associatedToEcal_.end(); it++) {
1370  if (DebugSetLinksSummary) cout << " AssoECAL " << it->first << endl;
1371  vector<unsigned int> eleasso = it->second;
1372  for(unsigned int i=0;i<eleasso.size();i++) {
1373  PFBlockElement::Type type = elements[eleasso[i]].type();
1374  if(type == reco::PFBlockElement::PS1) {
1375  if (DebugSetLinksSummary)
1376  cout << " AssoECALElements PS1 " << eleasso[i] << endl;
1377  }
1378  else if(type == reco::PFBlockElement::PS2) {
1379  if (DebugSetLinksSummary)
1380  cout << " AssoECALElements PS2 " << eleasso[i] << endl;
1381  }
1382  else if(type == reco::PFBlockElement::HCAL) {
1383  if (DebugSetLinksSummary)
1384  cout << " AssoECALElements HCAL " << eleasso[i] << endl;
1385  }
1386  else {
1387  if (DebugSetLinksSummary)
1388  cout << " AssoHCALElements ????? " << eleasso[i] << endl;
1389  }
1390  }
1391  }
1392  if (DebugSetLinksSummary)
1393  cout << "-- End Summary --" << endl;
1394  }
1395 
1396  }
1397  // EndPrintOut
1398  return IsThereAGoodGSFTrack;
1399 }
1400 // This function get the associatedToGsf and associatedToBrems maps and run the final electronID.
1402  AssMap& associatedToGsf_,
1403  AssMap& associatedToBrems_,
1404  AssMap& associatedToEcal_){
1405  PFEnergyCalibration pfcalib_;
1406  const reco::PFBlock& block = *blockRef;
1407  PFBlock::LinkData linkData = block.linkData();
1409  bool DebugIDOutputs = false;
1410  if(DebugIDOutputs) cout << " ######## Enter in SetIDOutputs #########" << endl;
1411 
1412  unsigned int cgsf=0;
1413  for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
1414  igsf != associatedToGsf_.end(); igsf++,cgsf++) {
1415 
1416  float Ene_ecalgsf = 0.;
1417  float Ene_hcalgsf = 0.;
1418  double sigmaEtaEta = 0.;
1419  float deta_gsfecal = 0.;
1420  float Ene_ecalbrem = 0.;
1421  float Ene_extraecalgsf = 0.;
1422  bool LateBrem = false;
1423  bool EarlyBrem = false;
1424  int FirstBrem = 1000;
1425  unsigned int ecalGsf_index = 100000;
1426  unsigned int kf_index = 100000;
1427  unsigned int nhits_gsf = 0;
1428  int NumBrem = 0;
1429  reco::TrackRef RefKF;
1430  double posX=0.;
1431  double posY=0.;
1432  double posZ=0.;
1433 
1434  unsigned int gsf_index = igsf->first;
1435  const reco::PFBlockElementGsfTrack * GsfEl =
1436  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
1437  reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
1438  float Ein_gsf = 0.;
1439  if (RefGSF.isNonnull()) {
1440  float m_el=0.00051;
1441  Ein_gsf =sqrt(RefGSF->pMode()*
1442  RefGSF->pMode()+m_el*m_el);
1443  nhits_gsf = RefGSF->hitPattern().trackerLayersWithMeasurement();
1444  }
1445  float Eout_gsf = GsfEl->Pout().t();
1446  float Etaout_gsf = GsfEl->positionAtECALEntrance().eta();
1447 
1448 
1449  if (DebugIDOutputs)
1450  cout << " setIdOutput! GSF Track: Ein " << Ein_gsf
1451  << " eta,phi " << Etaout_gsf
1452  <<", " << GsfEl->positionAtECALEntrance().phi() << endl;
1453 
1454 
1455  vector<unsigned int> assogsf_index = igsf->second;
1456  bool FirstEcalGsf = true;
1457  for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
1458  PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
1459 
1460 
1461  // The RefKf is needed to build pure tracking observables
1462  if(assoele_type == reco::PFBlockElement::TRACK) {
1463  const reco::PFBlockElementTrack * KfTk =
1464  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assogsf_index[ielegsf])]));
1465  // 19 Mar 2010 do not consider here track from gamma conv
1466 
1467  bool isPrim = isPrimaryTrack(*KfTk,*GsfEl);
1468  if(!isPrim) continue;
1469  RefKF = KfTk->trackRef();
1470  kf_index = assogsf_index[ielegsf];
1471  }
1472 
1473 
1474  if (assoele_type == reco::PFBlockElement::ECAL) {
1475  unsigned int keyecalgsf = assogsf_index[ielegsf];
1476  vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
1477 
1478  vector<double> ps1Ene(0);
1479  vector<double> ps2Ene(0);
1480  for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
1481  PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[ips])].type();
1482  if (typeassoecal == reco::PFBlockElement::PS1) {
1483  PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
1484  ps1Ene.push_back(psref->energy());
1485  }
1486  if (typeassoecal == reco::PFBlockElement::PS2) {
1487  PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
1488  ps2Ene.push_back(psref->energy());
1489  }
1490  if (typeassoecal == reco::PFBlockElement::HCAL) {
1491  const reco::PFBlockElementCluster * clust =
1492  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assoecalgsf_index[ips])]));
1493  Ene_hcalgsf+=clust->clusterRef()->energy();
1494  }
1495  }
1496  if (FirstEcalGsf) {
1497  FirstEcalGsf = false;
1498  ecalGsf_index = assogsf_index[ielegsf];
1499  reco::PFClusterRef clusterRef = elements[(assogsf_index[ielegsf])].clusterRef();
1500  double ps1,ps2;
1501  ps1=ps2=0.;
1502  // Ene_ecalgsf = pfcalib_.energyEm(*clusterRef,ps1Ene,ps2Ene);
1503  Ene_ecalgsf = pfcalib_.energyEm(*clusterRef,ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
1504  // std::cout << "Test " << Ene_ecalgsf << " PS1 / PS2 " << ps1 << " " << ps2 << std::endl;
1505  posX += Ene_ecalgsf * clusterRef->position().X();
1506  posY += Ene_ecalgsf * clusterRef->position().Y();
1507  posZ += Ene_ecalgsf * clusterRef->position().Z();
1508 
1509  if (DebugIDOutputs)
1510  cout << " setIdOutput! GSF ECAL Cluster E " << Ene_ecalgsf
1511  << " eta,phi " << clusterRef->position().eta()
1512  <<", " << clusterRef->position().phi() << endl;
1513 
1514  deta_gsfecal = clusterRef->position().eta() - Etaout_gsf;
1515 
1516  vector< const reco::PFCluster * > pfClust_vec(0);
1517  pfClust_vec.clear();
1518  pfClust_vec.push_back(&(*clusterRef));
1519 
1520  PFClusterWidthAlgo pfwidth(pfClust_vec);
1521  sigmaEtaEta = pfwidth.pflowSigmaEtaEta();
1522 
1523 
1524  }
1525  else {
1526  reco::PFClusterRef clusterRef = elements[(assogsf_index[ielegsf])].clusterRef();
1527  float TempClus_energy = pfcalib_.energyEm(*clusterRef,ps1Ene,ps2Ene,applyCrackCorrections_);
1528  Ene_extraecalgsf += TempClus_energy;
1529  posX += TempClus_energy * clusterRef->position().X();
1530  posY += TempClus_energy * clusterRef->position().Y();
1531  posZ += TempClus_energy * clusterRef->position().Z();
1532 
1533  if (DebugIDOutputs)
1534  cout << " setIdOutput! Extra ECAL Cluster E "
1535  << TempClus_energy << " Tot " << Ene_extraecalgsf << endl;
1536  }
1537  } // end type Ecal
1538 
1539 
1540  if (assoele_type == reco::PFBlockElement::BREM) {
1541  unsigned int brem_index = assogsf_index[ielegsf];
1542  const reco::PFBlockElementBrem * BremEl =
1543  dynamic_cast<const reco::PFBlockElementBrem*>((&elements[brem_index]));
1544  int TrajPos = (BremEl->indTrajPoint())-2;
1545  if (TrajPos <= 3) EarlyBrem = true;
1546  if (TrajPos < FirstBrem) FirstBrem = TrajPos;
1547 
1548  vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
1549  for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
1550  if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
1551  unsigned int keyecalbrem = assobrem_index[ibrem];
1552  vector<unsigned int> assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
1553  vector<double> ps1EneFromBrem(0);
1554  vector<double> ps2EneFromBrem(0);
1555  for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
1556  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1) {
1557  PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
1558  ps1EneFromBrem.push_back(psref->energy());
1559  }
1560  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2) {
1561  PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
1562  ps2EneFromBrem.push_back(psref->energy());
1563  }
1564  }
1565  // check if it is a compatible cluster also with the gsf track
1566  if( assobrem_index[ibrem] != ecalGsf_index) {
1567  reco::PFClusterRef clusterRef =
1568  elements[(assobrem_index[ibrem])].clusterRef();
1569  float BremClus_energy = pfcalib_.energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem,applyCrackCorrections_);
1570  Ene_ecalbrem += BremClus_energy;
1571  posX += BremClus_energy * clusterRef->position().X();
1572  posY += BremClus_energy * clusterRef->position().Y();
1573  posZ += BremClus_energy * clusterRef->position().Z();
1574 
1575  NumBrem++;
1576  if (DebugIDOutputs) cout << " setIdOutput::BREM Cluster "
1577  << BremClus_energy << " eta,phi "
1578  << clusterRef->position().eta() <<", "
1579  << clusterRef->position().phi() << endl;
1580  }
1581  else {
1582  LateBrem = true;
1583  }
1584  }
1585  }
1586  }
1587  }
1588  if (Ene_ecalgsf > 0.) {
1589  // here build the new BDT observables
1590 
1591  // ***** Normalization observables ****
1592  if(RefGSF.isNonnull()) {
1593  PFCandidateElectronExtra myExtra(RefGSF) ;
1594  myExtra.setGsfTrackPout(GsfEl->Pout());
1595  myExtra.setKfTrackRef(RefKF);
1596  float Pt_gsf = RefGSF->ptMode();
1597  lnPt_gsf = log(Pt_gsf);
1598  Eta_gsf = RefGSF->etaMode();
1599 
1600  // **** Pure tracking observables.
1601  if(RefGSF->ptModeError() > 0.)
1602  dPtOverPt_gsf = RefGSF->ptModeError()/Pt_gsf;
1603 
1604  nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
1605  chi2_gsf = RefGSF->normalizedChi2();
1606  // change GsfEl->Pout().pt() as soon the PoutMode is on the GsfTrack DataFormat
1607  DPtOverPt_gsf = (RefGSF->ptMode() - GsfEl->Pout().pt())/RefGSF->ptMode();
1608 
1609 
1610  nhit_kf = 0;
1611  chi2_kf = -0.01;
1612  DPtOverPt_kf = -0.01;
1613  if (RefKF.isNonnull()) {
1614  nhit_kf= RefKF->hitPattern().trackerLayersWithMeasurement();
1615  chi2_kf = RefKF->normalizedChi2();
1616  // Not used, strange behaviour to be checked. And Kf->OuterPt is
1617  // in track extra.
1618  //DPtOverPt_kf =
1619  // (RefKF->pt() - RefKF->outerPt())/RefKF->pt();
1620 
1621  }
1622 
1623  // **** Tracker-Ecal-Hcal observables
1624  EtotPinMode = (Ene_ecalgsf + Ene_ecalbrem + Ene_extraecalgsf) / Ein_gsf;
1625  EGsfPoutMode = Ene_ecalgsf/Eout_gsf;
1626  EtotBremPinPoutMode = Ene_ecalbrem /(Ein_gsf - Eout_gsf);
1627  DEtaGsfEcalClust = fabs(deta_gsfecal);
1628  myExtra.setSigmaEtaEta(sigmaEtaEta);
1629  myExtra.setDeltaEta(DEtaGsfEcalClust);
1630  SigmaEtaEta = log(sigmaEtaEta);
1631 
1632  lateBrem = -1;
1633  firstBrem = -1;
1634  earlyBrem = -1;
1635  if(NumBrem > 0) {
1636  if (LateBrem) lateBrem = 1;
1637  else lateBrem = 0;
1638  firstBrem = FirstBrem;
1639  if(FirstBrem < 4) earlyBrem = 1;
1640  else earlyBrem = 0;
1641  }
1642 
1643  HOverHE = Ene_hcalgsf/(Ene_hcalgsf + Ene_ecalgsf);
1644  HOverPin = Ene_hcalgsf / Ein_gsf;
1645  myExtra.setHadEnergy(Ene_hcalgsf);
1646  myExtra.setEarlyBrem(earlyBrem);
1647  myExtra.setLateBrem(lateBrem);
1648  // std::cout<< " Inserting in extra " << electronExtra_.size() << std::endl;
1649 
1650  // Put cuts and access the BDT output
1651  if(DPtOverPt_gsf < -0.2) DPtOverPt_gsf = -0.2;
1652  if(DPtOverPt_gsf > 1.) DPtOverPt_gsf = 1.;
1653 
1654  if(dPtOverPt_gsf > 0.3) dPtOverPt_gsf = 0.3;
1655 
1656  if(chi2_gsf > 10.) chi2_gsf = 10.;
1657 
1658  if(DPtOverPt_kf < -0.2) DPtOverPt_kf = -0.2;
1659  if(DPtOverPt_kf > 1.) DPtOverPt_kf = 1.;
1660 
1661  if(chi2_kf > 10.) chi2_kf = 10.;
1662 
1663  if(EtotPinMode < 0.) EtotPinMode = 0.;
1664  if(EtotPinMode > 5.) EtotPinMode = 5.;
1665 
1666  if(EGsfPoutMode < 0.) EGsfPoutMode = 0.;
1667  if(EGsfPoutMode > 5.) EGsfPoutMode = 5.;
1668 
1669  if(EtotBremPinPoutMode < 0.) EtotBremPinPoutMode = 0.01;
1671 
1672  if(DEtaGsfEcalClust > 0.1) DEtaGsfEcalClust = 0.1;
1673 
1674  if(SigmaEtaEta < -14) SigmaEtaEta = -14;
1675 
1676  if(HOverPin < 0.) HOverPin = 0.;
1677  if(HOverPin > 5.) HOverPin = 5.;
1678  double mvaValue = tmvaReader_->EvaluateMVA("BDT");
1679 
1680  // add output observables
1681  BDToutput_[cgsf] = mvaValue;
1682  myExtra.setMVA(mvaValue);
1683  electronExtra_.push_back(myExtra);
1684 
1685  // IMPORTANT Additional conditions
1686  if(mvaValue > mvaEleCut_) {
1687  // Check if the ecal cluster is isolated.
1688  //
1689  // If there is at least one extra track and H/H+E > 0.05 or SumP(ExtraKf)/EGsf or
1690  // #Tracks > 3 I leave this job to PFAlgo, otherwise I lock those extra tracks.
1691  // Note:
1692  // The tracks coming from the 4 step of the iterative tracking are not considered,
1693  // because they can come from secondary converted brems.
1694  // They are locked to avoid double counting.
1695  // The lock is done in SetActivate function.
1696  // All this can improved but it is already a good step.
1697 
1698 
1699  // Find if the cluster is isolated.
1700  unsigned int iextratrack = 0;
1701  unsigned int itrackHcalLinked = 0;
1702  float SumExtraKfP = 0.;
1703 
1704 
1705  double Etotal = Ene_ecalgsf + Ene_ecalbrem + Ene_extraecalgsf;
1706  posX /=Etotal;
1707  posY /=Etotal;
1708  posZ /=Etotal;
1709  math::XYZPoint sc_pflow(posX,posY,posZ);
1710  double ETtotal = Etotal*sin(sc_pflow.Theta());
1711  double phiTrack = RefGSF->phiMode();
1712  double dphi_normalsc = sc_pflow.Phi() - phiTrack;
1713  if ( dphi_normalsc < -M_PI )
1714  dphi_normalsc = dphi_normalsc + 2.*M_PI;
1715  else if ( dphi_normalsc > M_PI )
1716  dphi_normalsc = dphi_normalsc - 2.*M_PI;
1717  dphi_normalsc = fabs(dphi_normalsc);
1718 
1719 
1720  if(ecalGsf_index < 100000) {
1721  vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(ecalGsf_index)->second;
1722  for(unsigned int itrk =0; itrk<assoecalgsf_index.size();itrk++) {
1723  PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[itrk])].type();
1724  if(typeassoecal == reco::PFBlockElement::TRACK) {
1725  const reco::PFBlockElementTrack * kfTk =
1726  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assoecalgsf_index[itrk])]));
1727  // 19 Mar 2010 do not consider here tracks from gamma conv
1728  // This should be not needed because the seleted extra tracks from GammaConv
1729  // will be locked and can not be associated to the ecal elements
1730  //if(kfTk->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) continue;
1731 
1732 
1733  reco::TrackRef trackref = kfTk->trackRef();
1734  unsigned int Algo = whichTrackAlgo(trackref);
1735  // iter0, iter1, iter2, iter3 = Algo < 3
1736  // algo 4,5,6,7
1737  if(Algo < 3) {
1738  if(DebugIDOutputs)
1739  cout << " The ecalGsf cluster is not isolated: >0 KF extra with algo < 3" << endl;
1740 
1741  float p_trk = trackref->p();
1742  SumExtraKfP += p_trk;
1743  iextratrack++;
1744  // Check if these extra tracks are HCAL linked
1745  std::multimap<double, unsigned int> hcalKfElems;
1746  block.associatedElements( assoecalgsf_index[itrk],linkData,
1747  hcalKfElems,
1750  if(hcalKfElems.size() > 0) {
1751  itrackHcalLinked++;
1752  }
1753  }
1754  }
1755  }
1756  }
1757  if( iextratrack > 0) {
1758  if(iextratrack > 3 || HOverHE > 0.05 || (SumExtraKfP/Ene_ecalgsf) > 1.
1759  || (ETtotal > 50. && iextratrack > 1 && (Ene_hcalgsf/Ene_ecalgsf) > 0.1) ) {
1760 
1761  if(DebugIDOutputs)
1762  cout << " *****This electron candidate is discarded: Non isolated # tracks "
1763  << iextratrack << " HOverHE " << HOverHE
1764  << " SumExtraKfP/Ene_ecalgsf " << SumExtraKfP/Ene_ecalgsf
1765  << " ETtotal " << ETtotal
1766  << " Ene_hcalgsf/Ene_ecalgsf " << Ene_hcalgsf/Ene_ecalgsf
1767  << endl;
1768 
1769  BDToutput_[cgsf] = mvaValue-2.;
1770  lockExtraKf_[cgsf] = false;
1771  }
1772  // if the Ecluster ~ Ptrack and the extra tracks are HCAL linked
1773  // the electron is retained and the kf tracks are not locked
1774  if( (fabs(1.-EtotPinMode) < 0.2 && (fabs(Eta_gsf) < 1.0 || fabs(Eta_gsf) > 2.0)) ||
1775  ((EtotPinMode < 1.1 && EtotPinMode > 0.6) && (fabs(Eta_gsf) >= 1.0 && fabs(Eta_gsf) <= 2.0))) {
1776  if( fabs(1.-EGsfPoutMode) < 0.5 &&
1777  (itrackHcalLinked == iextratrack) &&
1778  kf_index < 100000 ) {
1779 
1780  BDToutput_[cgsf] = mvaValue;
1781  lockExtraKf_[cgsf] = false;
1782  if(DebugIDOutputs)
1783  cout << " *****This electron is reactivated # tracks "
1784  << iextratrack << " #tracks hcal linked " << itrackHcalLinked
1785  << " SumExtraKfP/Ene_ecalgsf " << SumExtraKfP/Ene_ecalgsf
1786  << " EtotPinMode " << EtotPinMode << " EGsfPoutMode " << EGsfPoutMode
1787  << " eta gsf " << fabs(Eta_gsf) << " kf index " << kf_index <<endl;
1788  }
1789  }
1790  }
1791  // This is a pion:
1792  if (HOverPin > 1. && HOverHE > 0.1 && EtotPinMode < 0.5) {
1793  if(DebugIDOutputs)
1794  cout << " *****This electron candidate is discarded HCAL ENERGY "
1795  << " HOverPin " << HOverPin << " HOverHE " << HOverHE << " EtotPinMode" << EtotPinMode << endl;
1796  BDToutput_[cgsf] = mvaValue-4.;
1797  lockExtraKf_[cgsf] = false;
1798  }
1799 
1800  // Reject Crazy E/p values... to be understood in the future how to train a
1801  // BDT in order to avoid to select this bad electron candidates.
1802 
1803  if( EtotPinMode < 0.2 && EGsfPoutMode < 0.2 ) {
1804  if(DebugIDOutputs)
1805  cout << " *****This electron candidate is discarded Low ETOTPIN "
1806  << " EtotPinMode " << EtotPinMode << " EGsfPoutMode " << EGsfPoutMode << endl;
1807  BDToutput_[cgsf] = mvaValue-6.;
1808  }
1809 
1810  // For not-preselected Gsf Tracks ET > 50 GeV, apply dphi preselection
1811  if(ETtotal > 50. && dphi_normalsc > 0.1 ) {
1812  if(DebugIDOutputs)
1813  cout << " *****This electron candidate is discarded Large ANGLE "
1814  << " ETtotal " << ETtotal << " EGsfPoutMode " << dphi_normalsc << endl;
1815  BDToutput_[cgsf] = mvaValue-6.;
1816  }
1817  }
1818 
1819 
1820  if (DebugIDOutputs) {
1821  cout << " **** BDT observables ****" << endl;
1822  cout << " < Normalization > " << endl;
1823  cout << " lnPt_gsf " << lnPt_gsf
1824  << " Eta_gsf " << Eta_gsf << endl;
1825  cout << " < PureTracking > " << endl;
1826  cout << " dPtOverPt_gsf " << dPtOverPt_gsf
1827  << " DPtOverPt_gsf " << DPtOverPt_gsf
1828  << " chi2_gsf " << chi2_gsf
1829  << " nhit_gsf " << nhit_gsf
1830  << " DPtOverPt_kf " << DPtOverPt_kf
1831  << " chi2_kf " << chi2_kf
1832  << " nhit_kf " << nhit_kf << endl;
1833  cout << " < track-ecal-hcal-ps " << endl;
1834  cout << " EtotPinMode " << EtotPinMode
1835  << " EGsfPoutMode " << EGsfPoutMode
1836  << " EtotBremPinPoutMode " << EtotBremPinPoutMode
1837  << " DEtaGsfEcalClust " << DEtaGsfEcalClust
1838  << " SigmaEtaEta " << SigmaEtaEta
1839  << " HOverHE " << HOverHE
1840  << " HOverPin " << HOverPin
1841  << " lateBrem " << lateBrem
1842  << " firstBrem " << firstBrem << endl;
1843  cout << " !!!!!!!!!!!!!!!! the BDT output !!!!!!!!!!!!!!!!!: direct " << mvaValue
1844  << " corrected " << BDToutput_[cgsf] << endl;
1845 
1846  }
1847  }
1848  else {
1849  if (DebugIDOutputs)
1850  cout << " Gsf Ref isNULL " << endl;
1851  BDToutput_[cgsf] = -2.;
1852  }
1853  } else {
1854  if (DebugIDOutputs)
1855  cout << " No clusters associated to the gsf " << endl;
1856  BDToutput_[cgsf] = -2.;
1857  }
1858  } // End Loop on Map1
1859  return;
1860 }
1861 // This function get the associatedToGsf and associatedToBrems maps and
1862 // compute the electron 4-mom and set the pf candidate, for
1863 // the gsf track with a BDTcut > mvaEleCut_
1865  AssMap& associatedToGsf_,
1866  AssMap& associatedToBrems_,
1867  AssMap& associatedToEcal_){
1868 
1869  const reco::PFBlock& block = *blockRef;
1870  PFBlock::LinkData linkData = block.linkData();
1872  PFEnergyResolution pfresol_;
1873  PFEnergyCalibration pfcalib_;
1874 
1875  bool DebugIDCandidates = false;
1876 // vector<reco::PFCluster> pfClust_vec(0);
1877 // pfClust_vec.clear();
1878 
1879  unsigned int cgsf=0;
1880  for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
1881  igsf != associatedToGsf_.end(); igsf++,cgsf++) {
1882  unsigned int gsf_index = igsf->first;
1883 
1884 
1885 
1886  // They should be reset for each gsf track
1887  int eecal=0;
1888  int hcal=0;
1889  int charge =0;
1890  bool goodphi=true;
1891  math::XYZTLorentzVector momentum_kf,momentum_gsf,momentum,momentum_mean;
1892  float dpt=0; float dpt_kf=0; float dpt_gsf=0; float dpt_mean=0;
1893  float Eene=0; float dene=0; float Hene=0.;
1894  float RawEene = 0.;
1895  double posX=0.;
1896  double posY=0.;
1897  double posZ=0.;
1898  std::vector<float> bremEnergyVec;
1899 
1900  float de_gs = 0., de_me = 0., de_kf = 0.;
1901  float m_el=0.00051;
1902  int nhit_kf=0; int nhit_gsf=0;
1903  bool has_gsf=false;
1904  bool has_kf=false;
1905  math::XYZTLorentzVector newmomentum;
1906  float ps1TotEne = 0;
1907  float ps2TotEne = 0;
1908  vector<unsigned int> elementsToAdd(0);
1909  reco::TrackRef RefKF;
1910 
1911 
1912 
1913  elementsToAdd.push_back(gsf_index);
1914  const reco::PFBlockElementGsfTrack * GsfEl =
1915  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
1916  const math::XYZPointF& posGsfEcalEntrance = GsfEl->positionAtECALEntrance();
1917  reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
1918  if (RefGSF.isNonnull()) {
1919 
1920  has_gsf=true;
1921 
1922  charge= RefGSF->chargeMode();
1923  nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
1924 
1925  momentum_gsf.SetPx(RefGSF->pxMode());
1926  momentum_gsf.SetPy(RefGSF->pyMode());
1927  momentum_gsf.SetPz(RefGSF->pzMode());
1928  float ENE=sqrt(RefGSF->pMode()*
1929  RefGSF->pMode()+m_el*m_el);
1930 
1931  if( DebugIDCandidates )
1932  cout << "SetCandidates:: GsfTrackRef: Ene " << ENE
1933  << " charge " << charge << " nhits " << nhit_gsf <<endl;
1934 
1935  momentum_gsf.SetE(ENE);
1936  dpt_gsf=RefGSF->ptModeError()*
1937  (RefGSF->pMode()/RefGSF->ptMode());
1938 
1939  momentum_mean.SetPx(RefGSF->px());
1940  momentum_mean.SetPy(RefGSF->py());
1941  momentum_mean.SetPz(RefGSF->pz());
1942  float ENEm=sqrt(RefGSF->p()*
1943  RefGSF->p()+m_el*m_el);
1944  momentum_mean.SetE(ENEm);
1945  dpt_mean=RefGSF->ptError()*
1946  (RefGSF->p()/RefGSF->pt());
1947  }
1948  else {
1949  if( DebugIDCandidates )
1950  cout << "SetCandidates:: !!!! NULL GSF Track Ref " << endl;
1951  }
1952 
1953  // vector<unsigned int> assogsf_index = associatedToGsf_[igsf].second;
1954  vector<unsigned int> assogsf_index = igsf->second;
1955  unsigned int ecalGsf_index = 100000;
1956  bool FirstEcalGsf = true;
1957  for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
1958  PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
1959  if (assoele_type == reco::PFBlockElement::TRACK) {
1960  elementsToAdd.push_back((assogsf_index[ielegsf])); // Daniele
1961  const reco::PFBlockElementTrack * KfTk =
1962  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assogsf_index[ielegsf])]));
1963  // 19 Mar 2010 do not consider here track from gamam conv
1964  bool isPrim = isPrimaryTrack(*KfTk,*GsfEl);
1965  if(!isPrim) continue;
1966 
1967  RefKF = KfTk->trackRef();
1968  if (RefKF.isNonnull()) {
1969  has_kf = true;
1970  dpt_kf=(RefKF->ptError()*RefKF->ptError());
1971  nhit_kf=RefKF->hitPattern().trackerLayersWithMeasurement();
1972  momentum_kf.SetPx(RefKF->px());
1973  momentum_kf.SetPy(RefKF->py());
1974  momentum_kf.SetPz(RefKF->pz());
1975  float ENE=sqrt(RefKF->p()*RefKF->p()+m_el*m_el);
1976  if( DebugIDCandidates )
1977  cout << "SetCandidates:: KFTrackRef: Ene " << ENE << " nhits " << nhit_kf << endl;
1978 
1979  momentum_kf.SetE(ENE);
1980  }
1981  else {
1982  if( DebugIDCandidates )
1983  cout << "SetCandidates:: !!!! NULL KF Track Ref " << endl;
1984  }
1985  }
1986 
1987  if (assoele_type == reco::PFBlockElement::ECAL) {
1988  unsigned int keyecalgsf = assogsf_index[ielegsf];
1989  vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
1990  vector<double> ps1Ene(0);
1991  vector<double> ps2Ene(0);
1992  // Important is the PS clusters are not saved before the ecal one, these
1993  // energy are not correctly assigned
1994  // For the moment I get only the closest PS clusters: this has to be changed
1995  for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
1996  PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[ips])].type();
1997  if (typeassoecal == reco::PFBlockElement::PS1) {
1998  PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
1999  ps1Ene.push_back(psref->energy());
2000  elementsToAdd.push_back((assoecalgsf_index[ips]));
2001  }
2002  if (typeassoecal == reco::PFBlockElement::PS2) {
2003  PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
2004  ps2Ene.push_back(psref->energy());
2005  elementsToAdd.push_back((assoecalgsf_index[ips]));
2006  }
2007  if (typeassoecal == reco::PFBlockElement::HCAL) {
2008  const reco::PFBlockElementCluster * clust =
2009  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assoecalgsf_index[ips])]));
2010  elementsToAdd.push_back((assoecalgsf_index[ips]));
2011  Hene+=clust->clusterRef()->energy();
2012  hcal++;
2013  }
2014  }
2015  elementsToAdd.push_back((assogsf_index[ielegsf]));
2016 
2017 
2018  const reco::PFBlockElementCluster * clust =
2019  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assogsf_index[ielegsf])]));
2020 
2021  eecal++;
2022 
2023  const reco::PFCluster& cl(*clust->clusterRef());
2024  //pfClust_vec.push_back((*clust->clusterRef()));
2025 
2026  // The electron RAW energy is the energy of the corrected GSF cluster
2027  double ps1,ps2;
2028  ps1=ps2=0.;
2029  // float EE=pfcalib_.energyEm(cl,ps1Ene,ps2Ene);
2030  float EE = pfcalib_.energyEm(cl,ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
2031  // float RawEE = cl.energy();
2032 
2033  float ceta=cl.position().eta();
2034  float cphi=cl.position().phi();
2035 
2036  float mphi=-2.97025;
2037  if (ceta<0) mphi+=0.00638;
2038  for (int ip=1; ip<19; ip++){
2039  float df= cphi - (mphi+(ip*6.283185/18));
2040  if (fabs(df)<0.01) goodphi=false;
2041  }
2042  float dE=pfresol_.getEnergyResolutionEm(EE,cl.position().eta());
2043  if( DebugIDCandidates )
2044  cout << "SetCandidates:: EcalCluster: EneNoCalib " << clust->clusterRef()->energy()
2045  << " eta,phi " << ceta << "," << cphi << " Calib " << EE << " dE " << dE <<endl;
2046 
2047  bool elecCluster=false;
2048  if (FirstEcalGsf) {
2049  FirstEcalGsf = false;
2050  elecCluster=true;
2051  ecalGsf_index = assogsf_index[ielegsf];
2052  // std::cout << " PFElectronAlgo / Seed " << EE << std::endl;
2053  RawEene += EE;
2054  }
2055 
2056  // create a photon/electron candidate
2057  math::XYZTLorentzVector clusterMomentum;
2058  math::XYZPoint direction=cl.position()/cl.position().R();
2059  clusterMomentum.SetPxPyPzE(EE*direction.x(),
2060  EE*direction.y(),
2061  EE*direction.z(),
2062  EE);
2063  reco::PFCandidate cluster_Candidate((elecCluster)?charge:0,
2064  clusterMomentum,
2066 
2067  cluster_Candidate.setPs1Energy(ps1);
2068  cluster_Candidate.setPs2Energy(ps2);
2069  cluster_Candidate.setEcalEnergy(EE);
2070  // std::cout << " PFElectronAlgo, adding Brem (1) " << EE << std::endl;
2071  // The Raw Ecal energy will be the energy of the basic cluster.
2072  // It will be the corrected energy without the preshower
2073  cluster_Candidate.setRawEcalEnergy(EE-ps1-ps2);
2074  cluster_Candidate.setPositionAtECALEntrance(math::XYZPointF(cl.position()));
2075  cluster_Candidate.addElementInBlock(blockRef,assogsf_index[ielegsf]);
2076  // store the photon candidate
2077  std::map<unsigned int,std::vector<reco::PFCandidate> >::iterator itcheck=
2078  electronConstituents_.find(cgsf);
2079  if(itcheck==electronConstituents_.end())
2080  {
2081  // beurk
2082  std::vector<reco::PFCandidate> tmpVec;
2083  tmpVec.push_back(cluster_Candidate);
2084  electronConstituents_.insert(std::pair<unsigned int, std::vector<reco::PFCandidate> >
2085  (cgsf,tmpVec));
2086  }
2087  else
2088  {
2089  itcheck->second.push_back(cluster_Candidate);
2090  }
2091 
2092  Eene+=EE;
2093  posX += EE * cl.position().X();
2094  posY += EE * cl.position().Y();
2095  posZ += EE * cl.position().Z();
2096  ps1TotEne+=ps1;
2097  ps2TotEne+=ps2;
2098  dene+=dE*dE;
2099  }
2100 
2101 
2102 
2103  // Important: Add energy from the brems
2104  if (assoele_type == reco::PFBlockElement::BREM) {
2105  unsigned int brem_index = assogsf_index[ielegsf];
2106  vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
2107  elementsToAdd.push_back(brem_index);
2108  for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
2109  if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
2110  // brem emission is from the considered gsf track
2111  unsigned int keyecalbrem = assobrem_index[ibrem];
2112  const vector<unsigned int>& assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
2113  vector<double> ps1EneFromBrem(0);
2114  vector<double> ps2EneFromBrem(0);
2115  float ps1EneFromBremTot=0.;
2116  float ps2EneFromBremTot=0.;
2117  for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
2118  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1) {
2119  PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
2120  ps1EneFromBrem.push_back(psref->energy());
2121  ps1EneFromBremTot+=psref->energy();
2122  elementsToAdd.push_back(assoelebrem_index[ielebrem]);
2123  }
2124  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2) {
2125  PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
2126  ps2EneFromBrem.push_back(psref->energy());
2127  ps2EneFromBremTot+=psref->energy();
2128  elementsToAdd.push_back(assoelebrem_index[ielebrem]);
2129  }
2130  }
2131 
2132 
2133  if( assobrem_index[ibrem] != ecalGsf_index) {
2134  elementsToAdd.push_back(assobrem_index[ibrem]);
2135  reco::PFClusterRef clusterRef = elements[(assobrem_index[ibrem])].clusterRef();
2136  //pfClust_vec.push_back(*clusterRef);
2137  // to get a calibrated PS energy
2138  double ps1=0;
2139  double ps2=0;
2140  float EE = pfcalib_.energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem,ps1,ps2,applyCrackCorrections_);
2141  bremEnergyVec.push_back(EE);
2142  // float RawEE = clusterRef->energy();
2143  float ceta = clusterRef->position().eta();
2144  // float cphi = clusterRef->position().phi();
2145  float dE=pfresol_.getEnergyResolutionEm(EE,ceta);
2146  if( DebugIDCandidates )
2147  cout << "SetCandidates:: BremCluster: Ene " << EE << " dE " << dE <<endl;
2148 
2149  Eene+=EE;
2150  posX += EE * clusterRef->position().X();
2151  posY += EE * clusterRef->position().Y();
2152  posZ += EE * clusterRef->position().Z();
2153  ps1TotEne+=ps1;
2154  ps2TotEne+=ps2;
2155  // Removed 4 March 2009. Florian. The Raw energy is the (corrected) one of the GSF cluster only
2156  // RawEene += RawEE;
2157  dene+=dE*dE;
2158 
2159  // create a PFCandidate out of it. Watch out, it is for the e/gamma and tau only
2160  // not to be used by the PFAlgo
2161  math::XYZTLorentzVector photonMomentum;
2162  math::XYZPoint direction=clusterRef->position()/clusterRef->position().R();
2163 
2164  photonMomentum.SetPxPyPzE(EE*direction.x(),
2165  EE*direction.y(),
2166  EE*direction.z(),
2167  EE);
2168  reco::PFCandidate photon_Candidate(0,photonMomentum, reco::PFCandidate::gamma);
2169 
2170  photon_Candidate.setPs1Energy(ps1);
2171  photon_Candidate.setPs2Energy(ps2);
2172  photon_Candidate.setEcalEnergy(EE);
2173  // std::cout << " PFElectronAlgo, adding Brem " << EE << std::endl;
2174  // yes, EE, we want the raw ecal energy of the daugther to have the same definition
2175  // as the GSF cluster
2176  photon_Candidate.setRawEcalEnergy(EE-ps1-ps2);
2177  photon_Candidate.setPositionAtECALEntrance(math::XYZPointF(clusterRef->position()));
2178  photon_Candidate.addElementInBlock(blockRef,assobrem_index[ibrem]);
2179 
2180  // store the photon candidate
2181  std::map<unsigned int,std::vector<reco::PFCandidate> >::iterator itcheck=
2182  electronConstituents_.find(cgsf);
2183  if(itcheck==electronConstituents_.end())
2184  {
2185  // beurk
2186  std::vector<reco::PFCandidate> tmpVec;
2187  tmpVec.push_back(photon_Candidate);
2188  electronConstituents_.insert(std::pair<unsigned int, std::vector<reco::PFCandidate> >
2189  (cgsf,tmpVec));
2190  }
2191  else
2192  {
2193  itcheck->second.push_back(photon_Candidate);
2194  }
2195  }
2196  }
2197  }
2198  }
2199  } // End Loop On element associated to the GSF tracks
2200  if (has_gsf) {
2201 
2202  // SuperCluster energy corrections
2203  double unCorrEene = Eene;
2204  double absEta = fabs(momentum_gsf.Eta());
2205  double emTheta = momentum_gsf.Theta();
2206  if( DebugIDCandidates )
2207  cout << "PFEelectronAlgo:: absEta " << absEta << " theta " << emTheta
2208  << " EneRaw " << Eene << " Err " << dene;
2209 
2210  // The calibrations are provided till ET = 200 GeV
2211  if(usePFSCEleCalib_ && (unCorrEene*sin(emTheta)) < 200 && unCorrEene > 0.) {
2212  if( absEta < 1.5) {
2213  double Etene = Eene*sin(emTheta);
2214  double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaBarrel(Etene, absEta);
2215  Eene = emCorrFull_et/sin(emTheta);
2216  }
2217  else {
2218  double Etene = Eene*sin(emTheta);
2219  double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaEndcap(Etene, absEta);
2220  Eene = emCorrFull_et/sin(emTheta);
2221  }
2222  dene = sqrt(dene)*(Eene/unCorrEene);
2223  dene = dene*dene;
2224  }
2225 
2226  if( DebugIDCandidates )
2227  cout << " EneCorrected " << Eene << " Err " << dene << endl;
2228 
2229 
2230  // charge determination with the majority method
2231  // if the kf track exists: 2 among 3 of supercluster barycenter position
2232  // gsf track and kf track
2233  if(has_kf && unCorrEene > 0.) {
2234  posX /=unCorrEene;
2235  posY /=unCorrEene;
2236  posZ /=unCorrEene;
2237  math::XYZPoint sc_pflow(posX,posY,posZ);
2238 
2239  std::multimap<double, unsigned int> bremElems;
2240  block.associatedElements( gsf_index,linkData,
2241  bremElems,
2244 
2245  double phiTrack = RefGSF->phiMode();
2246  if(bremElems.size()>0) {
2247  unsigned int brem_index = bremElems.begin()->second;
2248  const reco::PFBlockElementBrem * BremEl =
2249  dynamic_cast<const reco::PFBlockElementBrem*>((&elements[brem_index]));
2250  phiTrack = BremEl->positionAtECALEntrance().phi();
2251  }
2252 
2253  double dphi_normalsc = sc_pflow.Phi() - phiTrack;
2254  if ( dphi_normalsc < -M_PI )
2255  dphi_normalsc = dphi_normalsc + 2.*M_PI;
2256  else if ( dphi_normalsc > M_PI )
2257  dphi_normalsc = dphi_normalsc - 2.*M_PI;
2258 
2259  int chargeGsf = RefGSF->chargeMode();
2260  int chargeKf = RefKF->charge();
2261 
2262  int chargeSC = 0;
2263  if(dphi_normalsc < 0.)
2264  chargeSC = 1;
2265  else
2266  chargeSC = -1;
2267 
2268  if(chargeKf == chargeGsf)
2269  charge = chargeGsf;
2270  else if(chargeGsf == chargeSC)
2271  charge = chargeGsf;
2272  else
2273  charge = chargeKf;
2274 
2275  if( DebugIDCandidates )
2276  cout << "PFElectronAlgo:: charge determination "
2277  << " charge GSF " << chargeGsf
2278  << " charge KF " << chargeKf
2279  << " charge SC " << chargeSC
2280  << " Final Charge " << charge << endl;
2281 
2282  }
2283 
2284  // Think about this...
2285  if ((nhit_gsf<8) && (has_kf)){
2286 
2287  // Use Hene if some condition....
2288 
2289  momentum=momentum_kf;
2290  float Fe=Eene;
2291  float scale= Fe/momentum.E();
2292 
2293  // Daniele Changed
2294  if (Eene < 0.0001) {
2295  Fe = momentum.E();
2296  scale = 1.;
2297  }
2298 
2299 
2300  newmomentum.SetPxPyPzE(scale*momentum.Px(),
2301  scale*momentum.Py(),
2302  scale*momentum.Pz(),Fe);
2303  if( DebugIDCandidates )
2304  cout << "SetCandidates:: (nhit_gsf<8) && (has_kf):: pt " << newmomentum.pt() << " Ene " << Fe <<endl;
2305 
2306 
2307  }
2308  if ((nhit_gsf>7) || (has_kf==false)){
2309  if(Eene > 0.0001) {
2310  de_gs=1-momentum_gsf.E()/Eene;
2311  de_me=1-momentum_mean.E()/Eene;
2312  de_kf=1-momentum_kf.E()/Eene;
2313  }
2314 
2315  momentum=momentum_gsf;
2316  dpt=1/(dpt_gsf*dpt_gsf);
2317 
2318  if(dene > 0.)
2319  dene= 1./dene;
2320 
2321  float Fe = 0.;
2322  if(Eene > 0.0001) {
2323  Fe =((dene*Eene) +(dpt*momentum.E()))/(dene+dpt);
2324  }
2325  else {
2326  Fe=momentum.E();
2327  }
2328 
2329  if ((de_gs>0.05)&&(de_kf>0.05)){
2330  Fe=Eene;
2331  }
2332  if ((de_gs<-0.1)&&(de_me<-0.1) &&(de_kf<0.) &&
2333  (momentum.E()/dpt_gsf) > 5. && momentum_gsf.pt() < 30.){
2334  Fe=momentum.E();
2335  }
2336  float scale= Fe/momentum.E();
2337 
2338  newmomentum.SetPxPyPzE(scale*momentum.Px(),
2339  scale*momentum.Py(),
2340  scale*momentum.Pz(),Fe);
2341  if( DebugIDCandidates )
2342  cout << "SetCandidates::(nhit_gsf>7) || (has_kf==false) " << newmomentum.pt() << " Ene " << Fe <<endl;
2343 
2344 
2345  }
2346  if (newmomentum.pt()>0.5){
2347 
2348  // the pf candidate are created: we need to set something more?
2349  // IMPORTANT -> We need the gsftrackRef, not only the TrackRef??
2350 
2351  if( DebugIDCandidates )
2352  cout << "SetCandidates:: I am before doing candidate " <<endl;
2353 
2354  //vector with the cluster energies (for the extra)
2355  std::vector<float> clusterEnergyVec;
2356  clusterEnergyVec.push_back(RawEene);
2357  clusterEnergyVec.insert(clusterEnergyVec.end(),bremEnergyVec.begin(),bremEnergyVec.end());
2358 
2359  // add the information in the extra
2360  std::vector<reco::PFCandidateElectronExtra>::iterator itextra;
2361  PFElectronExtraEqual myExtraEqual(RefGSF);
2362  itextra=find_if(electronExtra_.begin(),electronExtra_.end(),myExtraEqual);
2363  if(itextra!=electronExtra_.end()) {
2364  itextra->setClusterEnergies(clusterEnergyVec);
2365  }
2366  else {
2367  if(RawEene>0.)
2368  std::cout << " There is a big problem with the electron extra, PFElectronAlgo should crash soon " << RawEene << std::endl;
2369  }
2370 
2373  reco::PFCandidate temp_Candidate;
2374  temp_Candidate = PFCandidate(charge,newmomentum,particleType);
2375  temp_Candidate.set_mva_e_pi(BDToutput_[cgsf]);
2376  temp_Candidate.setEcalEnergy(Eene);
2377  temp_Candidate.setRawEcalEnergy(RawEene);
2378  // Note the Hcal energy is set but the element is never locked
2379  temp_Candidate.setHcalEnergy(Hene);
2380  temp_Candidate.setPs1Energy(ps1TotEne);
2381  temp_Candidate.setPs2Energy(ps2TotEne);
2382  temp_Candidate.setTrackRef(RefKF);
2383  // This reference could be NULL it is needed a protection?
2384  temp_Candidate.setGsfTrackRef(RefGSF);
2385  temp_Candidate.setPositionAtECALEntrance(posGsfEcalEntrance);
2386  // Add Vertex
2387  temp_Candidate.setVertex(RefGSF->vertex());
2388 
2389 
2390  if( DebugIDCandidates )
2391  cout << "SetCandidates:: I am after doing candidate " <<endl;
2392 
2393  for (unsigned int elad=0; elad<elementsToAdd.size();elad++){
2394  temp_Candidate.addElementInBlock(blockRef,elementsToAdd[elad]);
2395  }
2396 
2397  if(BDToutput_[cgsf] >= mvaEleCut_)
2398  elCandidate_.push_back(temp_Candidate);
2399 
2400  // now the special candidate for e/gamma & taus
2401  reco::PFCandidate extendedElCandidate(temp_Candidate);
2402  // now add the photons to this candidate
2403  std::map<unsigned int, std::vector<reco::PFCandidate> >::const_iterator itcluster=
2404  electronConstituents_.find(cgsf);
2405  if(itcluster!=electronConstituents_.end())
2406  {
2407  const std::vector<reco::PFCandidate> & theClusters=itcluster->second;
2408  unsigned nclus=theClusters.size();
2409  // std::cout << " PFElectronAlgo " << nclus << " daugthers to add" << std::endl;
2410  for(unsigned iclus=0;iclus<nclus;++iclus)
2411  {
2412  extendedElCandidate.addDaughter(theClusters[iclus]);
2413  }
2414  }
2415 // else
2416 // {
2417 // std::cout << " Did not find any photon connected to " <<cgsf << std::endl;
2418 // }
2419 
2420  allElCandidate_.push_back(extendedElCandidate);
2421 
2422  }
2423  else {
2424  BDToutput_[cgsf] = -1.; // if the momentum is < 0.5 ID = false, but not sure
2425  // it could be misleading.
2426  if( DebugIDCandidates )
2427  cout << "SetCandidates:: No Candidate Produced because of Pt cut: 0.5 " <<endl;
2428  }
2429  }
2430  else {
2431  BDToutput_[cgsf] = -1.; // if gsf ref does not exist
2432  if( DebugIDCandidates )
2433  cout << "SetCandidates:: No Candidate Produced because of No GSF Track Ref " <<endl;
2434  }
2435  } // End Loop On GSF tracks
2436  return;
2437 }
2438 // // This function get the associatedToGsf and associatedToBrems maps and for each pfelectron candidate
2439 // // the element used are set active == false.
2440 // // note: the HCAL cluster are not used for the moments and also are not locked.
2442  AssMap& associatedToGsf_,
2443  AssMap& associatedToBrems_,
2444  AssMap& associatedToEcal_,
2445  std::vector<bool>& active){
2446  const reco::PFBlock& block = *blockRef;
2447  PFBlock::LinkData linkData = block.linkData();
2448 
2450 
2451  unsigned int cgsf=0;
2452  for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
2453  igsf != associatedToGsf_.end(); igsf++,cgsf++) {
2454 
2455  // lock only the elements that pass the BDT cut
2456  if(BDToutput_[cgsf] < mvaEleCut_) continue;
2457 
2458  unsigned int gsf_index = igsf->first;
2459  active[gsf_index] = false; // lock the gsf
2460  vector<unsigned int> assogsf_index = igsf->second;
2461  for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
2462  PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
2463  // lock the elements associated to the gsf: ECAL, Brems
2464  active[(assogsf_index[ielegsf])] = false;
2465  if (assoele_type == reco::PFBlockElement::ECAL) {
2466  unsigned int keyecalgsf = assogsf_index[ielegsf];
2467 
2468  // added protection against fifth step
2469  if(fifthStepKfTrack_.size() > 0) {
2470  for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
2471  if(fifthStepKfTrack_[itr].first == keyecalgsf) {
2472  active[(fifthStepKfTrack_[itr].second)] = false;
2473  }
2474  }
2475  }
2476 
2477  // added locking for conv gsf tracks and kf tracks
2478  if(convGsfTrack_.size() > 0) {
2479  for(unsigned int iconv = 0; iconv < convGsfTrack_.size(); iconv++) {
2480  if(convGsfTrack_[iconv].first == keyecalgsf) {
2481  // lock the GSF track
2482  active[(convGsfTrack_[iconv].second)] = false;
2483  // lock also the KF track associated
2484  std::multimap<double, unsigned> convKf;
2485  block.associatedElements( convGsfTrack_[iconv].second,
2486  linkData,
2487  convKf,
2490  if(convKf.size() > 0) {
2491  active[convKf.begin()->second] = false;
2492  }
2493  }
2494  }
2495  }
2496 
2497 
2498  vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
2499  for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
2500  // lock the elements associated to ECAL: PS1,PS2, for the moment not HCAL
2501  if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS1)
2502  active[(assoecalgsf_index[ips])] = false;
2503  if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS2)
2504  active[(assoecalgsf_index[ips])] = false;
2505  if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::TRACK) {
2506  if(lockExtraKf_[cgsf] == true) {
2507  active[(assoecalgsf_index[ips])] = false;
2508  }
2509  }
2510  }
2511  } // End if ECAL
2512  if (assoele_type == reco::PFBlockElement::BREM) {
2513  unsigned int brem_index = assogsf_index[ielegsf];
2514  vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
2515  for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
2516  if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
2517  unsigned int keyecalbrem = assobrem_index[ibrem];
2518  // lock the ecal cluster associated to the brem
2519  active[(assobrem_index[ibrem])] = false;
2520 
2521  // add protection against fifth step
2522  if(fifthStepKfTrack_.size() > 0) {
2523  for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
2524  if(fifthStepKfTrack_[itr].first == keyecalbrem) {
2525  active[(fifthStepKfTrack_[itr].second)] = false;
2526  }
2527  }
2528  }
2529 
2530  vector<unsigned int> assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
2531  // lock the elements associated to ECAL: PS1,PS2, for the moment not HCAL
2532  for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
2533  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1)
2534  active[(assoelebrem_index[ielebrem])] = false;
2535  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2)
2536  active[(assoelebrem_index[ielebrem])] = false;
2537  }
2538  }
2539  }
2540  } // End if BREM
2541  } // End loop on elements from gsf track
2542  } // End loop on gsf track
2543  return;
2544 }
2546  theGsfElectrons_ = & egelectrons;
2547 }
2548 unsigned int PFElectronAlgo::whichTrackAlgo(const reco::TrackRef& trackRef) {
2549  unsigned int Algo = 0;
2550  switch (trackRef->algo()) {
2551  case TrackBase::ctf:
2552  case TrackBase::iter0:
2553  case TrackBase::iter1:
2554  Algo = 0;
2555  break;
2556  case TrackBase::iter2:
2557  Algo = 1;
2558  break;
2559  case TrackBase::iter3:
2560  Algo = 2;
2561  break;
2562  case TrackBase::iter4:
2563  Algo = 3;
2564  break;
2565  case TrackBase::iter5:
2566  Algo = 4;
2567  break;
2568  default:
2569  Algo = 5;
2570  break;
2571  }
2572  return Algo;
2573 }
2575  const reco::PFBlockElementGsfTrack& GsfEl) {
2576  bool isPrimary = false;
2577 
2578  GsfPFRecTrackRef gsfPfRef = GsfEl.GsftrackRefPF();
2579 
2580  if(gsfPfRef.isNonnull()) {
2581  PFRecTrackRef kfPfRef = KfEl.trackRefPF();
2582  PFRecTrackRef kfPfRef_fromGsf = (*gsfPfRef).kfPFRecTrackRef();
2583  if(kfPfRef.isNonnull() && kfPfRef_fromGsf.isNonnull()) {
2584  reco::TrackRef kfref= (*kfPfRef).trackRef();
2585  reco::TrackRef kfref_fromGsf = (*kfPfRef_fromGsf).trackRef();
2586  if(kfref.isNonnull() && kfref_fromGsf.isNonnull()) {
2587  if(kfref == kfref_fromGsf)
2588  isPrimary = true;
2589  }
2590  }
2591  }
2592 
2593  return isPrimary;
2594 }
std::vector< std::pair< unsigned int, unsigned int > > fifthStepKfTrack_
type
Definition: HCALResponse.h:22
const math::XYZTLorentzVector & Pout() const
void SetIDOutputs(const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_)
void setPs2Energy(float e2)
set corrected PS2 energy
Definition: PFCandidate.h:216
const math::XYZPointF & positionAtECALEntrance() const
int i
Definition: DBlmapReader.cc:9
std::map< unsigned int, std::vector< unsigned int > > AssMap
void setPs1Energy(float e1)
set corrected PS1 energy
Definition: PFCandidate.h:210
ParticleType
particle types
Definition: PFCandidate.h:39
void setMVA(float val)
set the result (mostly for debugging)
void setLateBrem(float val)
set LateBrem
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:42
static bool isMuon(const reco::PFBlockElement &elt)
Check if a block element is a muon.
Definition: PFMuonAlgo.cc:11
void setPositionAtECALEntrance(const math::XYZPointF &pos)
set position at ECAL entrance
Definition: PFCandidate.h:283
float EtotBremPinPoutMode
void SetCandidates(const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_)
std::vector< std::pair< unsigned int, unsigned int > > convGsfTrack_
PFClusterRef clusterRef() const
void setSigmaEtaEta(float val)
set the sigmaetaeta
void setGsfTrackPout(const math::XYZTLorentzVector &pout)
set the pout (not trivial to get from the GSF track)
const math::XYZPointF & positionAtECALEntrance() const
std::vector< reco::PFCandidateElectronExtra > electronExtra_
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
std::map< unsigned int, Link > LinkData
Definition: PFBlock.h:46
size_type size() const
Definition: OwnVector.h:260
void setEarlyBrem(float val)
set EarlyBrem
list elements
Definition: asciidump.py:414
const std::vector< reco::GsfElectron > * theGsfElectrons_
bool isPrimaryTrack(const reco::PFBlockElementTrack &KfEl, const reco::PFBlockElementGsfTrack &GsfEl)
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
const LinkData & linkData() const
Definition: PFBlock.h:112
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< float > > XYZPointF
point in space with cartesian internal representation
Definition: Point3D.h:11
unsigned int indTrajPoint() const
double charge(const std::vector< uint8_t > &Ampls)
std::vector< GsfElectron > GsfElectronCollection
collection of GsfElectron objects
double coneEcalIsoForEgammaSC_
TMVA::Reader * tmvaReader_
dictionary map
Definition: Association.py:160
void set_mva_e_pi(float mva)
Definition: PFCandidate.h:242
U second(std::pair< T, U > const &p)
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:30
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:248
void SetActive(const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_, std::vector< bool > &active)
void RunPFElectron(const reco::PFBlockRef &blockRef, std::vector< bool > &active)
double getEnergyResolutionEm(double CorrectedEnergy, double eta) const
void setEcalEnergy(float ee)
set corrected Ecal energy
Definition: PFCandidate.h:183
double pflowSigmaEtaEta() const
void addElementInBlock(const reco::PFBlockRef &blockref, unsigned elementIndex)
add an element to the current PFCandidate
Definition: PFCandidate.cc:104
T sqrt(T t)
Definition: SSEVec.h:28
reco::GsfTrackRef GsftrackRef() const
int numberOfValidPixelHits() const
Definition: HitPattern.cc:359
double sumEtEcalIsoForEgammaSC_barrel_
std::vector< bool > lockExtraKf_
std::vector< double > BDToutput_
void setDeltaEta(float val)
set the delta eta
double sumEtEcalIsoForEgammaSC_endcap_
bool first
Definition: L1TdeRCT.cc:79
virtual bool trackType(TrackType trType) const
block
Formating index page&#39;s pieces.
Definition: Association.py:187
virtual void setVertex(const Point &vertex)
set vertex
double energyEm(double uncalibratedEnergyECAL, double eta=0, double phi=0) const
void addDaughter(const Candidate &, const std::string &s="")
add a clone of the passed candidate as daughter
void setRawEcalEnergy(float ee)
set corrected Ecal energy
Definition: PFCandidate.h:195
std::map< unsigned int, std::vector< reco::PFCandidate > > electronConstituents_
void setKfTrackRef(const reco::TrackRef &ref)
set kf track reference
double sumPtTrackIsoForEgammaSC_endcap_
#define M_PI
Definition: BFit3D.cc:3
unsigned int whichTrackAlgo(const reco::TrackRef &trackRef)
Log< T >::type log(const T &t)
Definition: Log.h:22
void setGsfTrackRef(const reco::GsfTrackRef &ref)
set gsftrack reference
Definition: PFCandidate.cc:150
PFRecTrackRef trackRefPF() const
void associatedElements(unsigned i, const LinkData &linkData, std::multimap< double, unsigned > &sortedAssociates, reco::PFBlockElement::Type type=PFBlockElement::NONE, LinkTest test=LINKTEST_RECHIT) const
Definition: PFBlock.cc:75
XYZPointD XYZPoint
point in space with cartesian internal representation
Definition: Point3D.h:13
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
reco::TrackRef trackRef() const
bool SetLinks(const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_, std::vector< bool > &active)
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:34
PFElectronAlgo(const double mvaEleCut, std::string mvaWeightFileEleID, const boost::shared_ptr< PFSCEnergyCalibration > &thePFSCEnergyCalibration, bool applyCrackCorrections, bool usePFSCEleCalib, bool useEGElectrons, bool useEGammaSupercluster, double sumEtEcalIsoForEgammaSC_barrel, double sumEtEcalIsoForEgammaSC_endcap, double coneEcalIsoForEgammaSC, double sumPtTrackIsoForEgammaSC_barrel, double sumPtTrackIsoForEgammaSC_endcap, unsigned int nTrackIsoForEgammaSC, double coneTrackIsoForEgammaSC)
void setHcalEnergy(float eh)
set corrected Hcal energy
Definition: PFCandidate.h:189
double sumPtTrackIsoForEgammaSC_barrel_
GsfPFRecTrackRef GsftrackRefPF() const
tuple cout
Definition: gather_cfg.py:41
double dist(unsigned ie1, unsigned ie2, const LinkData &linkData, LinkTest test) const
Definition: PFBlock.h:94
unsigned int nTrackIsoForEgammaSC_
void setTrackRef(const reco::TrackRef &ref)
set track reference
Definition: PFCandidate.cc:134
void setHadEnergy(float val)
set the had energy. The cluster energies should be entered before
Definition: fakeMenu.h:4
std::vector< reco::PFCandidate > elCandidate_
bool applyCrackCorrections_
void setEGElectronCollection(const reco::GsfElectronCollection &egelectrons)
bool useEGammaSupercluster_
Block of elements.
Definition: PFBlock.h:30
std::vector< reco::PFCandidate > allElCandidate_