CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
List of all members | Public Member Functions | Private Types | Private Member Functions | Private Attributes
PFElectronAlgo Class Reference

#include <PFElectronAlgo.h>

Public Member Functions

const std::vector
< reco::PFCandidate > & 
getAllElectronCandidates ()
 
const std::vector
< reco::PFCandidate > & 
getElectronCandidates ()
 
const std::vector
< reco::PFCandidateElectronExtra > & 
getElectronExtra ()
 
bool isElectronValidCandidate (const reco::PFBlockRef &blockRef, std::vector< bool > &active, const reco::Vertex &primaryVertex)
 
 PFElectronAlgo (const double mvaEleCut, std::string mvaWeightFileEleID, const boost::shared_ptr< PFSCEnergyCalibration > &thePFSCEnergyCalibration, const boost::shared_ptr< PFEnergyCalibration > &thePFEnergyCalibration, 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 setEGElectronCollection (const reco::GsfElectronCollection &egelectrons)
 
 ~PFElectronAlgo ()
 

Private Types

typedef std::map< unsigned int,
std::vector< unsigned int > > 
AssMap
 

Private Member Functions

unsigned int FindClosestElement (const unsigned int iele, std::multimap< double, unsigned int > &Elems, float &chi2cut, std::vector< bool > &active, const reco::PFBlockRef &blockRef)
 
bool isPrimaryTrack (const reco::PFBlockElementTrack &KfEl, const reco::PFBlockElementGsfTrack &GsfEl)
 
void RunPFElectron (const reco::PFBlockRef &blockRef, std::vector< bool > &active, const reco::Vertex &primaryVertex)
 
void SetActive (const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_, std::vector< bool > &active)
 
void SetCandidates (const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_)
 
void SetIDOutputs (const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_, const reco::Vertex &primaryVertex)
 
bool SetLinks (const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_, std::vector< bool > &active, const reco::Vertex &primaryVertex)
 

Private Attributes

std::vector< reco::PFCandidateallElCandidate_
 
bool applyCrackCorrections_
 
std::vector< double > BDToutput_
 
float chi2_gsf
 
float chi2_kf
 
double coneEcalIsoForEgammaSC_
 
double coneTrackIsoForEgammaSC_
 
std::vector< std::pair
< unsigned int, unsigned int > > 
convGsfTrack_
 
float DEtaGsfEcalClust
 
float dPtOverPt_gsf
 
float DPtOverPt_gsf
 
float DPtOverPt_kf
 
float earlyBrem
 
float EGsfPoutMode
 
std::vector< reco::PFCandidateelCandidate_
 
std::map< unsigned int,
std::vector< reco::PFCandidate > > 
electronConstituents_
 
std::vector
< reco::PFCandidateElectronExtra
electronExtra_
 
float Eta_gsf
 
float EtotBremPinPoutMode
 
float EtotPinMode
 
std::vector< std::pair
< unsigned int, unsigned int > > 
fifthStepKfTrack_
 
float firstBrem
 
std::vector< bool > GsfTrackSingleEcal_
 
float HOverHE
 
float HOverPin
 
bool isvalid_
 
float lateBrem
 
float lnPt_gsf
 
std::vector< bool > lockExtraKf_
 
double mvaEleCut_
 
const char * mvaWeightFile_
 
float nhit_gsf
 
float nhit_kf
 
unsigned int nTrackIsoForEgammaSC_
 
float SigmaEtaEta
 
double sumEtEcalIsoForEgammaSC_barrel_
 
double sumEtEcalIsoForEgammaSC_endcap_
 
double sumPtTrackIsoForEgammaSC_barrel_
 
double sumPtTrackIsoForEgammaSC_endcap_
 
const std::vector
< reco::GsfElectron > * 
theGsfElectrons_
 
boost::shared_ptr
< PFEnergyCalibration
thePFEnergyCalibration_
 
boost::shared_ptr
< PFSCEnergyCalibration
thePFSCEnergyCalibration_
 
TMVA::Reader * tmvaReader_
 
bool useEGammaSupercluster_
 
bool useEGElectrons_
 
bool usePFSCEleCalib_
 

Detailed Description

Definition at line 26 of file PFElectronAlgo.h.

Member Typedef Documentation

typedef std::map< unsigned int, std::vector<unsigned int> > PFElectronAlgo::AssMap
private

Definition at line 71 of file PFElectronAlgo.h.

Constructor & Destructor Documentation

PFElectronAlgo::PFElectronAlgo ( const double  mvaEleCut,
std::string  mvaWeightFileEleID,
const boost::shared_ptr< PFSCEnergyCalibration > &  thePFSCEnergyCalibration,
const boost::shared_ptr< PFEnergyCalibration > &  thePFEnergyCalibration,
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 
)

Definition at line 33 of file PFElectronAlgo.cc.

References chi2_gsf, chi2_kf, DEtaGsfEcalClust, DPtOverPt_gsf, dPtOverPt_gsf, EGsfPoutMode, Eta_gsf, EtotBremPinPoutMode, EtotPinMode, firstBrem, HOverHE, lateBrem, lnPt_gsf, nhit_kf, SigmaEtaEta, and tmvaReader_.

47  :
48  mvaEleCut_(mvaEleCut),
49  thePFSCEnergyCalibration_(thePFSCEnergyCalibration),
50  thePFEnergyCalibration_(thePFEnergyCalibration),
53  useEGElectrons_(useEGElectrons),
62 {
63  // Set the tmva reader
64  tmvaReader_ = new TMVA::Reader("!Color:Silent");
65  tmvaReader_->AddVariable("lnPt_gsf",&lnPt_gsf);
66  tmvaReader_->AddVariable("Eta_gsf",&Eta_gsf);
67  tmvaReader_->AddVariable("dPtOverPt_gsf",&dPtOverPt_gsf);
68  tmvaReader_->AddVariable("DPtOverPt_gsf",&DPtOverPt_gsf);
69  //tmvaReader_->AddVariable("nhit_gsf",&nhit_gsf);
70  tmvaReader_->AddVariable("chi2_gsf",&chi2_gsf);
71  //tmvaReader_->AddVariable("DPtOverPt_kf",&DPtOverPt_kf);
72  tmvaReader_->AddVariable("nhit_kf",&nhit_kf);
73  tmvaReader_->AddVariable("chi2_kf",&chi2_kf);
74  tmvaReader_->AddVariable("EtotPinMode",&EtotPinMode);
75  tmvaReader_->AddVariable("EGsfPoutMode",&EGsfPoutMode);
76  tmvaReader_->AddVariable("EtotBremPinPoutMode",&EtotBremPinPoutMode);
77  tmvaReader_->AddVariable("DEtaGsfEcalClust",&DEtaGsfEcalClust);
78  tmvaReader_->AddVariable("SigmaEtaEta",&SigmaEtaEta);
79  tmvaReader_->AddVariable("HOverHE",&HOverHE);
80 // tmvaReader_->AddVariable("HOverPin",&HOverPin);
81  tmvaReader_->AddVariable("lateBrem",&lateBrem);
82  tmvaReader_->AddVariable("firstBrem",&firstBrem);
83  tmvaReader_->BookMVA("BDT",mvaWeightFileEleID.c_str());
84 }
float EtotBremPinPoutMode
tuple coneTrackIsoForEgammaSC
tuple sumPtTrackIsoForEgammaSC_endcap
double coneEcalIsoForEgammaSC_
TMVA::Reader * tmvaReader_
tuple coneEcalIsoForEgammaSC
tuple sumPtTrackIsoForEgammaSC_barrel
double sumEtEcalIsoForEgammaSC_barrel_
tuple sumEtEcalIsoForEgammaSC_barrel
double sumEtEcalIsoForEgammaSC_endcap_
tuple sumEtEcalIsoForEgammaSC_endcap
tuple usePFSCEleCalib
double sumPtTrackIsoForEgammaSC_endcap_
tuple useEGammaSupercluster
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
double coneTrackIsoForEgammaSC_
double sumPtTrackIsoForEgammaSC_barrel_
tuple applyCrackCorrections
unsigned int nTrackIsoForEgammaSC_
tuple nTrackIsoForEgammaSC
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration_
bool applyCrackCorrections_
bool useEGammaSupercluster_
PFElectronAlgo::~PFElectronAlgo ( )
inline

Definition at line 47 of file PFElectronAlgo.h.

References tmvaReader_.

47 {delete tmvaReader_;};
TMVA::Reader * tmvaReader_

Member Function Documentation

unsigned int PFElectronAlgo::FindClosestElement ( const unsigned int  iele,
std::multimap< double, unsigned int > &  Elems,
float &  chi2cut,
std::vector< bool > &  active,
const reco::PFBlockRef blockRef 
)
private
const std::vector<reco::PFCandidate>& PFElectronAlgo::getAllElectronCandidates ( )
inline

Definition at line 62 of file PFElectronAlgo.h.

References allElCandidate_.

Referenced by PFAlgo::processBlock().

62 {return allElCandidate_;};
std::vector< reco::PFCandidate > allElCandidate_
const std::vector<reco::PFCandidate>& PFElectronAlgo::getElectronCandidates ( )
inline

Definition at line 59 of file PFElectronAlgo.h.

References elCandidate_.

Referenced by PFAlgo::processBlock().

59 {return elCandidate_;};
std::vector< reco::PFCandidate > elCandidate_
const std::vector< reco::PFCandidateElectronExtra>& PFElectronAlgo::getElectronExtra ( )
inline

Definition at line 65 of file PFElectronAlgo.h.

References electronExtra_.

Referenced by PFAlgo::processBlock().

65 {return electronExtra_;};
std::vector< reco::PFCandidateElectronExtra > electronExtra_
bool PFElectronAlgo::isElectronValidCandidate ( const reco::PFBlockRef blockRef,
std::vector< bool > &  active,
const reco::Vertex primaryVertex 
)
inline

Definition at line 50 of file PFElectronAlgo.h.

References isvalid_, and RunPFElectron().

Referenced by PFAlgo::processBlock().

53  {
54  isvalid_=false;
55  RunPFElectron(blockRef,active, primaryVertex);
56  return isvalid_;};
void RunPFElectron(const reco::PFBlockRef &blockRef, std::vector< bool > &active, const reco::Vertex &primaryVertex)
bool PFElectronAlgo::isPrimaryTrack ( const reco::PFBlockElementTrack KfEl,
const reco::PFBlockElementGsfTrack GsfEl 
)
private

Definition at line 2668 of file PFElectronAlgo.cc.

References reco::PFBlockElementGsfTrack::GsftrackRefPF(), edm::Ref< C, T, F >::isNonnull(), and reco::PFBlockElementTrack::trackRefPF().

Referenced by SetCandidates(), SetIDOutputs(), and SetLinks().

2669  {
2670  bool isPrimary = false;
2671 
2672  GsfPFRecTrackRef gsfPfRef = GsfEl.GsftrackRefPF();
2673 
2674  if(gsfPfRef.isNonnull()) {
2675  PFRecTrackRef kfPfRef = KfEl.trackRefPF();
2676  PFRecTrackRef kfPfRef_fromGsf = (*gsfPfRef).kfPFRecTrackRef();
2677  if(kfPfRef.isNonnull() && kfPfRef_fromGsf.isNonnull()) {
2678  reco::TrackRef kfref= (*kfPfRef).trackRef();
2679  reco::TrackRef kfref_fromGsf = (*kfPfRef_fromGsf).trackRef();
2680  if(kfref.isNonnull() && kfref_fromGsf.isNonnull()) {
2681  if(kfref == kfref_fromGsf)
2682  isPrimary = true;
2683  }
2684  }
2685  }
2686 
2687  return isPrimary;
2688 }
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
const GsfPFRecTrackRef & GsftrackRefPF() const
const PFRecTrackRef & trackRefPF() const
void PFElectronAlgo::RunPFElectron ( const reco::PFBlockRef blockRef,
std::vector< bool > &  active,
const reco::Vertex primaryVertex 
)
private

Definition at line 85 of file PFElectronAlgo.cc.

References allElCandidate_, BDToutput_, convGsfTrack_, elCandidate_, electronConstituents_, electronExtra_, fifthStepKfTrack_, isvalid_, lockExtraKf_, SetActive(), SetCandidates(), SetIDOutputs(), and SetLinks().

Referenced by isElectronValidCandidate().

87  {
88 
89  // the maps are initialized
90  AssMap associatedToGsf;
91  AssMap associatedToBrems;
92  AssMap associatedToEcal;
93 
94  // should be cleaned as often as often as possible
95  elCandidate_.clear();
96  electronExtra_.clear();
97  allElCandidate_.clear();
98  electronConstituents_.clear();
99  fifthStepKfTrack_.clear();
100  convGsfTrack_.clear();
101  // SetLinks finds all the elements (kf,ecal,ps,hcal,brems)
102  // associated to each gsf track
103  bool blockHasGSF = SetLinks(blockRef,associatedToGsf,
104  associatedToBrems,associatedToEcal,
105  active, primaryVertex);
106 
107  // check if there is at least a gsf track in the block.
108  if (blockHasGSF) {
109 
110  BDToutput_.clear();
111 
112  lockExtraKf_.clear();
113  // For each GSF track is initialized a BDT value = -1
114  BDToutput_.assign(associatedToGsf.size(),-1.);
115  lockExtraKf_.assign(associatedToGsf.size(),true);
116 
117  // The FinalID is run and BDToutput values is assigned
118  SetIDOutputs(blockRef,associatedToGsf,associatedToBrems,associatedToEcal,primaryVertex);
119 
120  // For each GSF track that pass the BDT configurable cut a pf candidate electron is created.
121  // This function finds also the best estimation of the initial electron 4-momentum.
122 
123  SetCandidates(blockRef,associatedToGsf,associatedToBrems,associatedToEcal);
124  if (elCandidate_.size() > 0 ){
125  isvalid_ = true;
126  // when a pfelectron candidate is created all the elements associated to the
127  // electron are locked.
128  SetActive(blockRef,associatedToGsf,associatedToBrems,associatedToEcal,active);
129  }
130  } // endif blockHasGSF
131 }
std::vector< std::pair< unsigned int, unsigned int > > fifthStepKfTrack_
bool SetLinks(const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_, std::vector< bool > &active, const reco::Vertex &primaryVertex)
std::map< unsigned int, std::vector< unsigned int > > AssMap
void SetCandidates(const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_)
std::vector< std::pair< unsigned int, unsigned int > > convGsfTrack_
std::vector< reco::PFCandidateElectronExtra > electronExtra_
void SetActive(const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_, std::vector< bool > &active)
std::vector< bool > lockExtraKf_
std::vector< double > BDToutput_
void SetIDOutputs(const reco::PFBlockRef &blockRef, AssMap &associatedToGsf_, AssMap &associatedToBrems_, AssMap &associatedToEcal_, const reco::Vertex &primaryVertex)
std::map< unsigned int, std::vector< reco::PFCandidate > > electronConstituents_
std::vector< reco::PFCandidate > elCandidate_
std::vector< reco::PFCandidate > allElCandidate_
void PFElectronAlgo::SetActive ( const reco::PFBlockRef blockRef,
AssMap associatedToGsf_,
AssMap associatedToBrems_,
AssMap associatedToEcal_,
std::vector< bool > &  active 
)
private

Definition at line 2545 of file PFElectronAlgo.cc.

References reco::PFBlock::associatedElements(), BDToutput_, createPayload::block, reco::PFBlockElement::BREM, convGsfTrack_, reco::PFBlockElement::ECAL, reco::PFBlock::elements(), bookConverter::elements, fifthStepKfTrack_, plotBeamSpotDB::first, reco::PFBlockElementGsfTrack::GsftrackRef(), reco::PFBlock::linkData(), reco::PFBlock::LINKTEST_ALL, lockExtraKf_, mvaEleCut_, reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, edm::second(), theGsfElectrons_, reco::PFBlockElement::TRACK, and useEGElectrons_.

Referenced by RunPFElectron().

2549  {
2550  const reco::PFBlock& block = *blockRef;
2551  PFBlock::LinkData linkData = block.linkData();
2552 
2554 
2555  unsigned int cgsf=0;
2556  for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
2557  igsf != associatedToGsf_.end(); igsf++,cgsf++) {
2558 
2559  unsigned int gsf_index = igsf->first;
2560  const reco::PFBlockElementGsfTrack * GsfEl =
2561  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
2562  reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
2563 
2564  // lock only the elements that pass the BDT cut
2565  bool bypassmva=false;
2566  if(useEGElectrons_) {
2567  GsfElectronEqual myEqual(RefGSF);
2568  std::vector<reco::GsfElectron>::const_iterator itcheck=find_if(theGsfElectrons_->begin(),theGsfElectrons_->end(),myEqual);
2569  if(itcheck!=theGsfElectrons_->end()) {
2570  if(BDToutput_[cgsf] >= -1.)
2571  bypassmva=true;
2572  }
2573  }
2574 
2575  if(BDToutput_[cgsf] < mvaEleCut_ && bypassmva == false) continue;
2576 
2577 
2578  active[gsf_index] = false; // lock the gsf
2579  vector<unsigned int> assogsf_index = igsf->second;
2580  for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
2581  PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
2582  // lock the elements associated to the gsf: ECAL, Brems
2583  active[(assogsf_index[ielegsf])] = false;
2584  if (assoele_type == reco::PFBlockElement::ECAL) {
2585  unsigned int keyecalgsf = assogsf_index[ielegsf];
2586 
2587  // added protection against fifth step
2588  if(fifthStepKfTrack_.size() > 0) {
2589  for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
2590  if(fifthStepKfTrack_[itr].first == keyecalgsf) {
2591  active[(fifthStepKfTrack_[itr].second)] = false;
2592  }
2593  }
2594  }
2595 
2596  // added locking for conv gsf tracks and kf tracks
2597  if(convGsfTrack_.size() > 0) {
2598  for(unsigned int iconv = 0; iconv < convGsfTrack_.size(); iconv++) {
2599  if(convGsfTrack_[iconv].first == keyecalgsf) {
2600  // lock the GSF track
2601  active[(convGsfTrack_[iconv].second)] = false;
2602  // lock also the KF track associated
2603  std::multimap<double, unsigned> convKf;
2604  block.associatedElements( convGsfTrack_[iconv].second,
2605  linkData,
2606  convKf,
2609  if(convKf.size() > 0) {
2610  active[convKf.begin()->second] = false;
2611  }
2612  }
2613  }
2614  }
2615 
2616 
2617  vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
2618  for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
2619  // lock the elements associated to ECAL: PS1,PS2, for the moment not HCAL
2620  if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS1)
2621  active[(assoecalgsf_index[ips])] = false;
2622  if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::PS2)
2623  active[(assoecalgsf_index[ips])] = false;
2624  if (elements[(assoecalgsf_index[ips])].type() == reco::PFBlockElement::TRACK) {
2625  if(lockExtraKf_[cgsf] == true) {
2626  active[(assoecalgsf_index[ips])] = false;
2627  }
2628  }
2629  }
2630  } // End if ECAL
2631  if (assoele_type == reco::PFBlockElement::BREM) {
2632  unsigned int brem_index = assogsf_index[ielegsf];
2633  vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
2634  for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
2635  if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
2636  unsigned int keyecalbrem = assobrem_index[ibrem];
2637  // lock the ecal cluster associated to the brem
2638  active[(assobrem_index[ibrem])] = false;
2639 
2640  // add protection against fifth step
2641  if(fifthStepKfTrack_.size() > 0) {
2642  for(unsigned int itr = 0; itr < fifthStepKfTrack_.size(); itr++) {
2643  if(fifthStepKfTrack_[itr].first == keyecalbrem) {
2644  active[(fifthStepKfTrack_[itr].second)] = false;
2645  }
2646  }
2647  }
2648 
2649  vector<unsigned int> assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
2650  // lock the elements associated to ECAL: PS1,PS2, for the moment not HCAL
2651  for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
2652  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1)
2653  active[(assoelebrem_index[ielebrem])] = false;
2654  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2)
2655  active[(assoelebrem_index[ielebrem])] = false;
2656  }
2657  }
2658  }
2659  } // End if BREM
2660  } // End loop on elements from gsf track
2661  } // End loop on gsf track
2662  return;
2663 }
std::vector< std::pair< unsigned int, unsigned int > > fifthStepKfTrack_
type
Definition: HCALResponse.h:21
const reco::GsfTrackRef & GsftrackRef() const
std::vector< std::pair< unsigned int, unsigned int > > convGsfTrack_
std::map< unsigned int, Link > LinkData
Definition: PFBlock.h:46
const std::vector< reco::GsfElectron > * theGsfElectrons_
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
const LinkData & linkData() const
Definition: PFBlock.h:112
dictionary elements
U second(std::pair< T, U > const &p)
std::vector< bool > lockExtraKf_
std::vector< double > BDToutput_
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
Block of elements.
Definition: PFBlock.h:30
void PFElectronAlgo::SetCandidates ( const reco::PFBlockRef blockRef,
AssMap associatedToGsf_,
AssMap associatedToBrems_,
AssMap associatedToEcal_ 
)
private

Definition at line 1909 of file PFElectronAlgo.cc.

References reco::CompositeCandidate::addDaughter(), reco::PFCandidate::addElementInBlock(), allElCandidate_, applyCrackCorrections_, reco::PFBlock::associatedElements(), BDToutput_, createPayload::block, reco::PFBlockElement::BREM, RecoTauCleanerPlugins::charge, GetRecoTauVFromDQM_MC_cff::cl, reco::PFBlockElementCluster::clusterRef(), gather_cfg::cout, reco::PFCandidate::e, reco::PFBlockElement::ECAL, EE, elCandidate_, electronConstituents_, electronExtra_, reco::PFBlock::elements(), bookConverter::elements, reco::PFCandidate::gamma, edm::Ref< C, T, F >::get(), PFEnergyResolution::getEnergyResolutionEm(), reco::PFBlockElementGsfTrack::GsftrackRef(), reco::PFBlockElement::HCAL, patCandidatesForDimuonsSequences_cff::hcal, edm::Ref< C, T, F >::isAvailable(), edm::Ref< C, T, F >::isNonnull(), isPrimaryTrack(), reco::PFBlock::linkData(), reco::PFBlock::LINKTEST_ALL, M_PI, mvaEleCut_, nhit_gsf, nhit_kf, HLT_FULL_cff::particleType, PFClusterWidthAlgo::pflowEtaWidth(), PFClusterWidthAlgo::pflowPhiWidth(), reco::PFBlockElementBrem::positionAtECALEntrance(), reco::PFBlockElementGsfTrack::positionAtECALEntrance(), reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, pileupReCalc_HLTpaths::scale, reco::PFCandidate::set_mva_e_pi(), reco::PFCandidate::setEcalEnergy(), reco::PFCandidate::setGsfTrackRef(), reco::PFCandidate::setHcalEnergy(), reco::PFCandidate::setPositionAtECALEntrance(), reco::PFCandidate::setPs1Energy(), reco::PFCandidate::setPs2Energy(), reco::PFCandidate::setSuperClusterRef(), reco::PFCandidate::setTrackRef(), reco::PFCandidate::setVertexSource(), funct::sin(), mathSSE::sqrt(), theGsfElectrons_, thePFEnergyCalibration_, thePFSCEnergyCalibration_, reco::PFBlockElement::TRACK, reco::PFBlockElementTrack::trackRef(), useEGElectrons_, and usePFSCEleCalib_.

Referenced by RunPFElectron().

1912  {
1913 
1914  const reco::PFBlock& block = *blockRef;
1915  PFBlock::LinkData linkData = block.linkData();
1917  PFEnergyResolution pfresol_;
1918  //PFEnergyCalibration pfcalib_;
1919 
1920  bool DebugIDCandidates = false;
1921 // vector<reco::PFCluster> pfClust_vec(0);
1922 // pfClust_vec.clear();
1923 
1924  unsigned int cgsf=0;
1925  for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
1926  igsf != associatedToGsf_.end(); igsf++,cgsf++) {
1927  unsigned int gsf_index = igsf->first;
1928 
1929 
1930 
1931  // They should be reset for each gsf track
1932  int eecal=0;
1933  int hcal=0;
1934  int charge =0;
1935  // bool goodphi=true;
1936  math::XYZTLorentzVector momentum_kf,momentum_gsf,momentum,momentum_mean;
1937  float dpt=0; float dpt_gsf=0;
1938  float Eene=0; float dene=0; float Hene=0.;
1939  float RawEene = 0.;
1940  double posX=0.;
1941  double posY=0.;
1942  double posZ=0.;
1943  std::vector<float> bremEnergyVec;
1944 
1945  std::vector<const PFCluster*> pfSC_Clust_vec;
1946 
1947  float de_gs = 0., de_me = 0., de_kf = 0.;
1948  float m_el=0.00051;
1949  int nhit_kf=0; int nhit_gsf=0;
1950  bool has_gsf=false;
1951  bool has_kf=false;
1952  math::XYZTLorentzVector newmomentum;
1953  float ps1TotEne = 0;
1954  float ps2TotEne = 0;
1955  vector<unsigned int> elementsToAdd(0);
1956  reco::TrackRef RefKF;
1957 
1958 
1959 
1960  elementsToAdd.push_back(gsf_index);
1961  const reco::PFBlockElementGsfTrack * GsfEl =
1962  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
1963  const math::XYZPointF& posGsfEcalEntrance = GsfEl->positionAtECALEntrance();
1964  reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
1965  if (RefGSF.isNonnull()) {
1966 
1967  has_gsf=true;
1968 
1969  charge= RefGSF->chargeMode();
1970  nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
1971 
1972  momentum_gsf.SetPx(RefGSF->pxMode());
1973  momentum_gsf.SetPy(RefGSF->pyMode());
1974  momentum_gsf.SetPz(RefGSF->pzMode());
1975  float ENE=sqrt(RefGSF->pMode()*
1976  RefGSF->pMode()+m_el*m_el);
1977 
1978  if( DebugIDCandidates )
1979  cout << "SetCandidates:: GsfTrackRef: Ene " << ENE
1980  << " charge " << charge << " nhits " << nhit_gsf <<endl;
1981 
1982  momentum_gsf.SetE(ENE);
1983  dpt_gsf=RefGSF->ptModeError()*
1984  (RefGSF->pMode()/RefGSF->ptMode());
1985 
1986  momentum_mean.SetPx(RefGSF->px());
1987  momentum_mean.SetPy(RefGSF->py());
1988  momentum_mean.SetPz(RefGSF->pz());
1989  float ENEm=sqrt(RefGSF->p()*
1990  RefGSF->p()+m_el*m_el);
1991  momentum_mean.SetE(ENEm);
1992  // dpt_mean=RefGSF->ptError()*
1993  // (RefGSF->p()/RefGSF->pt());
1994  }
1995  else {
1996  if( DebugIDCandidates )
1997  cout << "SetCandidates:: !!!! NULL GSF Track Ref " << endl;
1998  }
1999 
2000  // vector<unsigned int> assogsf_index = associatedToGsf_[igsf].second;
2001  vector<unsigned int> assogsf_index = igsf->second;
2002  unsigned int ecalGsf_index = 100000;
2003  bool FirstEcalGsf = true;
2004  for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
2005  PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
2006  if (assoele_type == reco::PFBlockElement::TRACK) {
2007  elementsToAdd.push_back((assogsf_index[ielegsf])); // Daniele
2008  const reco::PFBlockElementTrack * KfTk =
2009  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assogsf_index[ielegsf])]));
2010  // 19 Mar 2010 do not consider here track from gamam conv
2011  bool isPrim = isPrimaryTrack(*KfTk,*GsfEl);
2012  if(!isPrim) continue;
2013 
2014  RefKF = KfTk->trackRef();
2015  if (RefKF.isNonnull()) {
2016  has_kf = true;
2017  // dpt_kf=(RefKF->ptError()*RefKF->ptError());
2018  nhit_kf=RefKF->hitPattern().trackerLayersWithMeasurement();
2019  momentum_kf.SetPx(RefKF->px());
2020  momentum_kf.SetPy(RefKF->py());
2021  momentum_kf.SetPz(RefKF->pz());
2022  float ENE=sqrt(RefKF->p()*RefKF->p()+m_el*m_el);
2023  if( DebugIDCandidates )
2024  cout << "SetCandidates:: KFTrackRef: Ene " << ENE << " nhits " << nhit_kf << endl;
2025 
2026  momentum_kf.SetE(ENE);
2027  }
2028  else {
2029  if( DebugIDCandidates )
2030  cout << "SetCandidates:: !!!! NULL KF Track Ref " << endl;
2031  }
2032  }
2033 
2034  if (assoele_type == reco::PFBlockElement::ECAL) {
2035  unsigned int keyecalgsf = assogsf_index[ielegsf];
2036  vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
2037  vector<double> ps1Ene(0);
2038  vector<double> ps2Ene(0);
2039  // Important is the PS clusters are not saved before the ecal one, these
2040  // energy are not correctly assigned
2041  // For the moment I get only the closest PS clusters: this has to be changed
2042  for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
2043  PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[ips])].type();
2044  if (typeassoecal == reco::PFBlockElement::PS1) {
2045  PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
2046  ps1Ene.push_back(psref->energy());
2047  elementsToAdd.push_back((assoecalgsf_index[ips]));
2048  }
2049  if (typeassoecal == reco::PFBlockElement::PS2) {
2050  PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
2051  ps2Ene.push_back(psref->energy());
2052  elementsToAdd.push_back((assoecalgsf_index[ips]));
2053  }
2054  if (typeassoecal == reco::PFBlockElement::HCAL) {
2055  const reco::PFBlockElementCluster * clust =
2056  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assoecalgsf_index[ips])]));
2057  elementsToAdd.push_back((assoecalgsf_index[ips]));
2058  Hene+=clust->clusterRef()->energy();
2059  hcal++;
2060  }
2061  }
2062  elementsToAdd.push_back((assogsf_index[ielegsf]));
2063 
2064 
2065  const reco::PFBlockElementCluster * clust =
2066  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assogsf_index[ielegsf])]));
2067 
2068  eecal++;
2069 
2070  const reco::PFCluster& cl(*clust->clusterRef());
2071  //pfClust_vec.push_back((*clust->clusterRef()));
2072 
2073  // The electron RAW energy is the energy of the corrected GSF cluster
2074  double ps1,ps2;
2075  ps1=ps2=0.;
2076  // float EE=pfcalib_.energyEm(cl,ps1Ene,ps2Ene);
2077  float EE = thePFEnergyCalibration_->energyEm(cl,ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
2078  // float RawEE = cl.energy();
2079 
2080  float ceta=cl.position().eta();
2081  float cphi=cl.position().phi();
2082 
2083  /*
2084  float mphi=-2.97025;
2085  if (ceta<0) mphi+=0.00638;
2086 
2087  for (int ip=1; ip<19; ip++){
2088  float df= cphi - (mphi+(ip*6.283185/18));
2089  if (fabs(df)<0.01) goodphi=false;
2090  }
2091  */
2092 
2093  float dE=pfresol_.getEnergyResolutionEm(EE,cl.position().eta());
2094  if( DebugIDCandidates )
2095  cout << "SetCandidates:: EcalCluster: EneNoCalib " << clust->clusterRef()->energy()
2096  << " eta,phi " << ceta << "," << cphi << " Calib " << EE << " dE " << dE <<endl;
2097 
2098  bool elecCluster=false;
2099  if (FirstEcalGsf) {
2100  FirstEcalGsf = false;
2101  elecCluster=true;
2102  ecalGsf_index = assogsf_index[ielegsf];
2103  // std::cout << " PFElectronAlgo / Seed " << EE << std::endl;
2104  RawEene += EE;
2105  }
2106 
2107  // create a photon/electron candidate
2108  math::XYZTLorentzVector clusterMomentum;
2109  math::XYZPoint direction=cl.position()/cl.position().R();
2110  clusterMomentum.SetPxPyPzE(EE*direction.x(),
2111  EE*direction.y(),
2112  EE*direction.z(),
2113  EE);
2114  reco::PFCandidate cluster_Candidate((elecCluster)?charge:0,
2115  clusterMomentum,
2117 
2118  cluster_Candidate.setPs1Energy(ps1);
2119  cluster_Candidate.setPs2Energy(ps2);
2120  // The Raw Ecal energy will be the energy of the basic cluster.
2121  // It will be the corrected energy without the preshower
2122  cluster_Candidate.setEcalEnergy(EE-ps1-ps2,EE);
2123  // std::cout << " PFElectronAlgo, adding Brem (1) " << EE << std::endl;
2124  cluster_Candidate.setPositionAtECALEntrance(math::XYZPointF(cl.position()));
2125  cluster_Candidate.addElementInBlock(blockRef,assogsf_index[ielegsf]);
2126  // store the photon candidate
2127  std::map<unsigned int,std::vector<reco::PFCandidate> >::iterator itcheck=
2128  electronConstituents_.find(cgsf);
2129  if(itcheck==electronConstituents_.end())
2130  {
2131  // beurk
2132  std::vector<reco::PFCandidate> tmpVec;
2133  tmpVec.push_back(cluster_Candidate);
2134  electronConstituents_.insert(std::pair<unsigned int, std::vector<reco::PFCandidate> >
2135  (cgsf,tmpVec));
2136  }
2137  else
2138  {
2139  itcheck->second.push_back(cluster_Candidate);
2140  }
2141 
2142  Eene+=EE;
2143  posX += EE * cl.position().X();
2144  posY += EE * cl.position().Y();
2145  posZ += EE * cl.position().Z();
2146  ps1TotEne+=ps1;
2147  ps2TotEne+=ps2;
2148  dene+=dE*dE;
2149 
2150  //MM Add cluster to the vector pfSC_Clust_vec needed for brem corrections
2151  pfSC_Clust_vec.push_back( &cl );
2152 
2153  }
2154 
2155 
2156 
2157  // Important: Add energy from the brems
2158  if (assoele_type == reco::PFBlockElement::BREM) {
2159  unsigned int brem_index = assogsf_index[ielegsf];
2160  vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
2161  elementsToAdd.push_back(brem_index);
2162  for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
2163  if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
2164  // brem emission is from the considered gsf track
2165  if( assobrem_index[ibrem] != ecalGsf_index) {
2166  unsigned int keyecalbrem = assobrem_index[ibrem];
2167  const vector<unsigned int>& assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
2168  vector<double> ps1EneFromBrem(0);
2169  vector<double> ps2EneFromBrem(0);
2170  for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
2171  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1) {
2172  PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
2173  ps1EneFromBrem.push_back(psref->energy());
2174  elementsToAdd.push_back(assoelebrem_index[ielebrem]);
2175  }
2176  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2) {
2177  PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
2178  ps2EneFromBrem.push_back(psref->energy());
2179  elementsToAdd.push_back(assoelebrem_index[ielebrem]);
2180  }
2181  }
2182  elementsToAdd.push_back(assobrem_index[ibrem]);
2183  reco::PFClusterRef clusterRef = elements[(assobrem_index[ibrem])].clusterRef();
2184  //pfClust_vec.push_back(*clusterRef);
2185  // to get a calibrated PS energy
2186  double ps1=0;
2187  double ps2=0;
2188  float EE = thePFEnergyCalibration_->energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem,ps1,ps2,applyCrackCorrections_);
2189  bremEnergyVec.push_back(EE);
2190  // float RawEE = clusterRef->energy();
2191  float ceta = clusterRef->position().eta();
2192  // float cphi = clusterRef->position().phi();
2193  float dE=pfresol_.getEnergyResolutionEm(EE,ceta);
2194  if( DebugIDCandidates )
2195  cout << "SetCandidates:: BremCluster: Ene " << EE << " dE " << dE <<endl;
2196 
2197  Eene+=EE;
2198  posX += EE * clusterRef->position().X();
2199  posY += EE * clusterRef->position().Y();
2200  posZ += EE * clusterRef->position().Z();
2201  ps1TotEne+=ps1;
2202  ps2TotEne+=ps2;
2203  // Removed 4 March 2009. Florian. The Raw energy is the (corrected) one of the GSF cluster only
2204  // RawEene += RawEE;
2205  dene+=dE*dE;
2206 
2207  //MM Add cluster to the vector pfSC_Clust_vec needed for brem corrections
2208  pfSC_Clust_vec.push_back( clusterRef.get() );
2209 
2210  // create a PFCandidate out of it. Watch out, it is for the e/gamma and tau only
2211  // not to be used by the PFAlgo
2212  math::XYZTLorentzVector photonMomentum;
2213  math::XYZPoint direction=clusterRef->position()/clusterRef->position().R();
2214 
2215  photonMomentum.SetPxPyPzE(EE*direction.x(),
2216  EE*direction.y(),
2217  EE*direction.z(),
2218  EE);
2219  reco::PFCandidate photon_Candidate(0,photonMomentum, reco::PFCandidate::gamma);
2220 
2221  photon_Candidate.setPs1Energy(ps1);
2222  photon_Candidate.setPs2Energy(ps2);
2223  // yes, EE, we want the raw ecal energy of the daugther to have the same definition
2224  // as the GSF cluster
2225  photon_Candidate.setEcalEnergy(EE-ps1-ps2,EE);
2226  // std::cout << " PFElectronAlgo, adding Brem " << EE << std::endl;
2227  photon_Candidate.setPositionAtECALEntrance(math::XYZPointF(clusterRef->position()));
2228  photon_Candidate.addElementInBlock(blockRef,assobrem_index[ibrem]);
2229 
2230  // store the photon candidate
2231  std::map<unsigned int,std::vector<reco::PFCandidate> >::iterator itcheck=
2232  electronConstituents_.find(cgsf);
2233  if(itcheck==electronConstituents_.end())
2234  {
2235  // beurk
2236  std::vector<reco::PFCandidate> tmpVec;
2237  tmpVec.push_back(photon_Candidate);
2238  electronConstituents_.insert(std::pair<unsigned int, std::vector<reco::PFCandidate> >
2239  (cgsf,tmpVec));
2240  }
2241  else
2242  {
2243  itcheck->second.push_back(photon_Candidate);
2244  }
2245  }
2246  }
2247  }
2248  }
2249  } // End Loop On element associated to the GSF tracks
2250  if (has_gsf) {
2251 
2252  // SuperCluster energy corrections
2253  double unCorrEene = Eene;
2254  double absEta = fabs(momentum_gsf.Eta());
2255  double emTheta = momentum_gsf.Theta();
2256  PFClusterWidthAlgo pfSCwidth(pfSC_Clust_vec);
2257  double brLinear = pfSCwidth.pflowPhiWidth()/pfSCwidth.pflowEtaWidth();
2258  pfSC_Clust_vec.clear();
2259 
2260  if( DebugIDCandidates )
2261  cout << "PFEelectronAlgo:: absEta " << absEta << " theta " << emTheta
2262  << " EneRaw " << Eene << " Err " << dene;
2263 
2264  // The calibrations are provided till ET = 200 GeV //No longer a such cut MM
2265  // Protection on at least 1 GeV energy...avoid possible divergencies at very low energy.
2266  if(usePFSCEleCalib_ && unCorrEene > 0.) {
2267  if( absEta < 1.5) {
2268  double Etene = Eene*sin(emTheta);
2269  double emBR_e = thePFSCEnergyCalibration_->SCCorrFBremBarrel(Eene, Etene, brLinear);
2270  double emBR_et = emBR_e*sin(emTheta);
2271  double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaBarrel(emBR_et, absEta);
2272  Eene = emCorrFull_et/sin(emTheta);
2273  }
2274  else {
2275  // double Etene = Eene*sin(emTheta); //not needed anymore for endcaps MM
2276  double emBR_e = thePFSCEnergyCalibration_->SCCorrFBremEndcap(Eene, absEta, brLinear);
2277  double emBR_et = emBR_e*sin(emTheta);
2278  double emCorrFull_et = thePFSCEnergyCalibration_->SCCorrEtEtaEndcap(emBR_et, absEta);
2279  Eene = emCorrFull_et/sin(emTheta);
2280  }
2281  dene = sqrt(dene)*(Eene/unCorrEene);
2282  dene = dene*dene;
2283  }
2284 
2285  if( DebugIDCandidates )
2286  cout << " EneCorrected " << Eene << " Err " << dene << endl;
2287 
2288  // charge determination with the majority method
2289  // if the kf track exists: 2 among 3 of supercluster barycenter position
2290  // gsf track and kf track
2291  if(has_kf && unCorrEene > 0.) {
2292  posX /=unCorrEene;
2293  posY /=unCorrEene;
2294  posZ /=unCorrEene;
2295  math::XYZPoint sc_pflow(posX,posY,posZ);
2296 
2297  std::multimap<double, unsigned int> bremElems;
2298  block.associatedElements( gsf_index,linkData,
2299  bremElems,
2302 
2303  double phiTrack = RefGSF->phiMode();
2304  if(bremElems.size()>0) {
2305  unsigned int brem_index = bremElems.begin()->second;
2306  const reco::PFBlockElementBrem * BremEl =
2307  dynamic_cast<const reco::PFBlockElementBrem*>((&elements[brem_index]));
2308  phiTrack = BremEl->positionAtECALEntrance().phi();
2309  }
2310 
2311  double dphi_normalsc = sc_pflow.Phi() - phiTrack;
2312  if ( dphi_normalsc < -M_PI )
2313  dphi_normalsc = dphi_normalsc + 2.*M_PI;
2314  else if ( dphi_normalsc > M_PI )
2315  dphi_normalsc = dphi_normalsc - 2.*M_PI;
2316 
2317  int chargeGsf = RefGSF->chargeMode();
2318  int chargeKf = RefKF->charge();
2319 
2320  int chargeSC = 0;
2321  if(dphi_normalsc < 0.)
2322  chargeSC = 1;
2323  else
2324  chargeSC = -1;
2325 
2326  if(chargeKf == chargeGsf)
2327  charge = chargeGsf;
2328  else if(chargeGsf == chargeSC)
2329  charge = chargeGsf;
2330  else
2331  charge = chargeKf;
2332 
2333  if( DebugIDCandidates )
2334  cout << "PFElectronAlgo:: charge determination "
2335  << " charge GSF " << chargeGsf
2336  << " charge KF " << chargeKf
2337  << " charge SC " << chargeSC
2338  << " Final Charge " << charge << endl;
2339 
2340  }
2341 
2342  // Think about this...
2343  if ((nhit_gsf<8) && (has_kf)){
2344 
2345  // Use Hene if some condition....
2346 
2347  momentum=momentum_kf;
2348  float Fe=Eene;
2349  float scale= Fe/momentum.E();
2350 
2351  // Daniele Changed
2352  if (Eene < 0.0001) {
2353  Fe = momentum.E();
2354  scale = 1.;
2355  }
2356 
2357 
2358  newmomentum.SetPxPyPzE(scale*momentum.Px(),
2359  scale*momentum.Py(),
2360  scale*momentum.Pz(),Fe);
2361  if( DebugIDCandidates )
2362  cout << "SetCandidates:: (nhit_gsf<8) && (has_kf):: pt " << newmomentum.pt() << " Ene " << Fe <<endl;
2363 
2364 
2365  }
2366  if ((nhit_gsf>7) || (has_kf==false)){
2367  if(Eene > 0.0001) {
2368  de_gs=1-momentum_gsf.E()/Eene;
2369  de_me=1-momentum_mean.E()/Eene;
2370  de_kf=1-momentum_kf.E()/Eene;
2371  }
2372 
2373  momentum=momentum_gsf;
2374  dpt=1/(dpt_gsf*dpt_gsf);
2375 
2376  if(dene > 0.)
2377  dene= 1./dene;
2378 
2379  float Fe = 0.;
2380  if(Eene > 0.0001) {
2381  Fe =((dene*Eene) +(dpt*momentum.E()))/(dene+dpt);
2382  }
2383  else {
2384  Fe=momentum.E();
2385  }
2386 
2387  if ((de_gs>0.05)&&(de_kf>0.05)){
2388  Fe=Eene;
2389  }
2390  if ((de_gs<-0.1)&&(de_me<-0.1) &&(de_kf<0.) &&
2391  (momentum.E()/dpt_gsf) > 5. && momentum_gsf.pt() < 30.){
2392  Fe=momentum.E();
2393  }
2394  float scale= Fe/momentum.E();
2395 
2396  newmomentum.SetPxPyPzE(scale*momentum.Px(),
2397  scale*momentum.Py(),
2398  scale*momentum.Pz(),Fe);
2399  if( DebugIDCandidates )
2400  cout << "SetCandidates::(nhit_gsf>7) || (has_kf==false) " << newmomentum.pt() << " Ene " << Fe <<endl;
2401 
2402 
2403  }
2404  if (newmomentum.pt()>0.5){
2405 
2406  // the pf candidate are created: we need to set something more?
2407  // IMPORTANT -> We need the gsftrackRef, not only the TrackRef??
2408 
2409  if( DebugIDCandidates )
2410  cout << "SetCandidates:: I am before doing candidate " <<endl;
2411 
2412  //vector with the cluster energies (for the extra)
2413  std::vector<float> clusterEnergyVec;
2414  clusterEnergyVec.push_back(RawEene);
2415  clusterEnergyVec.insert(clusterEnergyVec.end(),bremEnergyVec.begin(),bremEnergyVec.end());
2416 
2417  // add the information in the extra
2418  std::vector<reco::PFCandidateElectronExtra>::iterator itextra;
2419  PFElectronExtraEqual myExtraEqual(RefGSF);
2420  itextra=find_if(electronExtra_.begin(),electronExtra_.end(),myExtraEqual);
2421  if(itextra!=electronExtra_.end()) {
2422  itextra->setClusterEnergies(clusterEnergyVec);
2423  }
2424  else {
2425  if(RawEene>0.)
2426  std::cout << " There is a big problem with the electron extra, PFElectronAlgo should crash soon " << RawEene << std::endl;
2427  }
2428 
2431  reco::PFCandidate temp_Candidate;
2432  temp_Candidate = PFCandidate(charge,newmomentum,particleType);
2433  temp_Candidate.set_mva_e_pi(BDToutput_[cgsf]);
2434  temp_Candidate.setEcalEnergy(RawEene,Eene);
2435  // Note the Hcal energy is set but the element is never locked
2436  temp_Candidate.setHcalEnergy(Hene,Hene);
2437  temp_Candidate.setPs1Energy(ps1TotEne);
2438  temp_Candidate.setPs2Energy(ps2TotEne);
2439  temp_Candidate.setTrackRef(RefKF);
2440  // This reference could be NULL it is needed a protection?
2441  temp_Candidate.setGsfTrackRef(RefGSF);
2442  temp_Candidate.setPositionAtECALEntrance(posGsfEcalEntrance);
2443  // Add Vertex
2444  temp_Candidate.setVertexSource(PFCandidate::kGSFVertex);
2445 
2446  // save the superclusterRef when available
2447  if(RefGSF->extra().isAvailable() && RefGSF->extra()->seedRef().isAvailable()) {
2448  reco::ElectronSeedRef seedRef= RefGSF->extra()->seedRef().castTo<reco::ElectronSeedRef>();
2449  if(seedRef.isAvailable() && seedRef->isEcalDriven()) {
2450  reco::SuperClusterRef scRef = seedRef->caloCluster().castTo<reco::SuperClusterRef>();
2451  if(scRef.isNonnull())
2452  temp_Candidate.setSuperClusterRef(scRef);
2453  }
2454  }
2455 
2456  if( DebugIDCandidates )
2457  cout << "SetCandidates:: I am after doing candidate " <<endl;
2458 
2459  for (unsigned int elad=0; elad<elementsToAdd.size();elad++){
2460  temp_Candidate.addElementInBlock(blockRef,elementsToAdd[elad]);
2461  }
2462 
2463  // now add the photons to this candidate
2464  std::map<unsigned int, std::vector<reco::PFCandidate> >::const_iterator itcluster=
2465  electronConstituents_.find(cgsf);
2466  if(itcluster!=electronConstituents_.end())
2467  {
2468  const std::vector<reco::PFCandidate> & theClusters=itcluster->second;
2469  unsigned nclus=theClusters.size();
2470  // std::cout << " PFElectronAlgo " << nclus << " daugthers to add" << std::endl;
2471  for(unsigned iclus=0;iclus<nclus;++iclus)
2472  {
2473  temp_Candidate.addDaughter(theClusters[iclus]);
2474  }
2475  }
2476 
2477  // By-pass the mva is the electron has been pre-selected
2478  bool bypassmva=false;
2479  if(useEGElectrons_) {
2480  GsfElectronEqual myEqual(RefGSF);
2481  std::vector<reco::GsfElectron>::const_iterator itcheck=find_if(theGsfElectrons_->begin(),theGsfElectrons_->end(),myEqual);
2482  if(itcheck!=theGsfElectrons_->end()) {
2483  if(BDToutput_[cgsf] >= -1.) {
2484  // bypass the mva only if the reconstruction went fine
2485  bypassmva=true;
2486 
2487  if( DebugIDCandidates ) {
2488  if(BDToutput_[cgsf] < -0.1) {
2489  float esceg = itcheck->caloEnergy();
2490  cout << " Attention By pass the mva " << BDToutput_[cgsf]
2491  << " SuperClusterEnergy " << esceg
2492  << " PF Energy " << Eene << endl;
2493 
2494  cout << " hoe " << itcheck->hcalOverEcal()
2495  << " tkiso04 " << itcheck->dr04TkSumPt()
2496  << " ecaliso04 " << itcheck->dr04EcalRecHitSumEt()
2497  << " hcaliso04 " << itcheck->dr04HcalTowerSumEt()
2498  << " tkiso03 " << itcheck->dr03TkSumPt()
2499  << " ecaliso03 " << itcheck->dr03EcalRecHitSumEt()
2500  << " hcaliso03 " << itcheck->dr03HcalTowerSumEt() << endl;
2501  }
2502  } // end DebugIDCandidates
2503  }
2504  }
2505  }
2506 
2507  bool mvaSelected = (BDToutput_[cgsf] >= mvaEleCut_);
2508  if( mvaSelected || bypassmva ) {
2509  elCandidate_.push_back(temp_Candidate);
2510  if(itextra!=electronExtra_.end())
2511  itextra->setStatus(PFCandidateElectronExtra::Selected,true);
2512  }
2513  else {
2514  if(itextra!=electronExtra_.end())
2515  itextra->setStatus(PFCandidateElectronExtra::Rejected,true);
2516  }
2517  allElCandidate_.push_back(temp_Candidate);
2518 
2519  // save the status information
2520  if(itextra!=electronExtra_.end()) {
2521  itextra->setStatus(PFCandidateElectronExtra::ECALDrivenPreselected,bypassmva);
2522  itextra->setStatus(PFCandidateElectronExtra::MVASelected,mvaSelected);
2523  }
2524 
2525 
2526  }
2527  else {
2528  BDToutput_[cgsf] = -1.; // if the momentum is < 0.5 ID = false, but not sure
2529  // it could be misleading.
2530  if( DebugIDCandidates )
2531  cout << "SetCandidates:: No Candidate Produced because of Pt cut: 0.5 " <<endl;
2532  }
2533  }
2534  else {
2535  BDToutput_[cgsf] = -1.; // if gsf ref does not exist
2536  if( DebugIDCandidates )
2537  cout << "SetCandidates:: No Candidate Produced because of No GSF Track Ref " <<endl;
2538  }
2539  } // End Loop On GSF tracks
2540  return;
2541 }
bool isAvailable() const
Definition: Ref.h:576
type
Definition: HCALResponse.h:21
void setPs2Energy(float e2)
set corrected PS2 energy
Definition: PFCandidate.h:279
const math::XYZPointF & positionAtECALEntrance() const
const reco::TrackRef & trackRef() const
const reco::GsfTrackRef & GsftrackRef() const
void setPs1Energy(float e1)
set corrected PS1 energy
Definition: PFCandidate.h:273
ParticleType
particle types
Definition: PFCandidate.h:44
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
void setPositionAtECALEntrance(const math::XYZPointF &pos)
set position at ECAL entrance
Definition: PFCandidate.h:348
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
const std::vector< reco::GsfElectron > * theGsfElectrons_
bool isPrimaryTrack(const reco::PFBlockElementTrack &KfEl, const reco::PFBlockElementGsfTrack &GsfEl)
const PFClusterRef & clusterRef() const
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:10
dictionary elements
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
void set_mva_e_pi(float mvaNI)
Definition: PFCandidate.h:311
void setVertexSource(PFVertexType vt)
Definition: PFCandidate.h:406
double getEnergyResolutionEm(double CorrectedEnergy, double eta) const
void addElementInBlock(const reco::PFBlockRef &blockref, unsigned elementIndex)
add an element to the current PFCandidate
Definition: PFCandidate.cc:211
T sqrt(T t)
Definition: SSEVec.h:18
std::vector< double > BDToutput_
T const * get() const
Returns C++ pointer to the item.
Definition: Ref.h:244
void addDaughter(const Candidate &, const std::string &s="")
add a clone of the passed candidate as daughter
std::map< unsigned int, std::vector< reco::PFCandidate > > electronConstituents_
#define M_PI
void setEcalEnergy(float eeRaw, float eeCorr)
set corrected Ecal energy
Definition: PFCandidate.h:217
void setGsfTrackRef(const reco::GsfTrackRef &ref)
set gsftrack reference
Definition: PFCandidate.cc:454
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:12
boost::shared_ptr< PFSCEnergyCalibration > thePFSCEnergyCalibration_
Particle reconstructed by the particle flow algorithm.
Definition: PFCandidate.h:39
void setSuperClusterRef(const reco::SuperClusterRef &scRef)
Definition: PFCandidate.cc:620
tuple cout
Definition: gather_cfg.py:145
void setTrackRef(const reco::TrackRef &ref)
set track reference
Definition: PFCandidate.cc:416
void setHcalEnergy(float ehRaw, float ehCorr)
set corrected Hcal energy
Definition: PFCandidate.h:227
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration_
std::vector< reco::PFCandidate > elCandidate_
tuple particleType
bool applyCrackCorrections_
Block of elements.
Definition: PFBlock.h:30
std::vector< reco::PFCandidate > allElCandidate_
void PFElectronAlgo::setEGElectronCollection ( const reco::GsfElectronCollection egelectrons)

Definition at line 2664 of file PFElectronAlgo.cc.

References theGsfElectrons_.

Referenced by PFAlgo::setEGElectronCollection().

2664  {
2665  theGsfElectrons_ = & egelectrons;
2666 }
const std::vector< reco::GsfElectron > * theGsfElectrons_
void PFElectronAlgo::SetIDOutputs ( const reco::PFBlockRef blockRef,
AssMap associatedToGsf_,
AssMap associatedToBrems_,
AssMap associatedToEcal_,
const reco::Vertex primaryVertex 
)
private

Definition at line 1422 of file PFElectronAlgo.cc.

References applyCrackCorrections_, reco::PFBlock::associatedElements(), BDToutput_, createPayload::block, reco::PFBlockElement::BREM, chi2_gsf, chi2_kf, reco::PFBlockElementCluster::clusterRef(), gather_cfg::cout, DEtaGsfEcalClust, DPtOverPt_gsf, dPtOverPt_gsf, DPtOverPt_kf, earlyBrem, reco::PFBlockElement::ECAL, EGsfPoutMode, electronExtra_, reco::PFBlock::elements(), bookConverter::elements, Eta_gsf, EtotBremPinPoutMode, EtotPinMode, firstBrem, spr::goodTrack(), reco::PFBlockElementGsfTrack::GsftrackRef(), reco::PFBlockElement::HCAL, HOverHE, HOverPin, reco::PFBlockElementBrem::indTrajPoint(), PFTrackAlgoTools::isGoodForEGM(), edm::Ref< C, T, F >::isNonnull(), isPrimaryTrack(), lateBrem, reco::PFBlock::linkData(), reco::PFBlock::LINKTEST_ALL, lnPt_gsf, lockExtraKf_, dqm-mbProfile::log, M_PI, mvaEleCut_, nhit_gsf, nhit_kf, PFClusterWidthAlgo::pflowSigmaEtaEta(), reco::PFBlockElementGsfTrack::positionAtECALEntrance(), reco::PFBlockElementGsfTrack::Pout(), reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, reco::PFCandidateElectronExtra::setDeltaEta(), reco::PFCandidateElectronExtra::setEarlyBrem(), reco::PFCandidateElectronExtra::setGsfTrackPout(), reco::PFCandidateElectronExtra::setHadEnergy(), reco::PFCandidateElectronExtra::setKfTrackRef(), reco::PFCandidateElectronExtra::setLateBrem(), reco::PFCandidateElectronExtra::setMVA(), reco::PFCandidateElectronExtra::setSigmaEtaEta(), SigmaEtaEta, funct::sin(), mathSSE::sqrt(), thePFEnergyCalibration_, tmvaReader_, reco::PFBlockElement::TRACK, reco::PFBlockElementTrack::trackRef(), reco::Vertex::tracks_begin(), and reco::Vertex::tracks_end().

Referenced by RunPFElectron().

1426  {
1427  //PFEnergyCalibration pfcalib_;
1428  const reco::PFBlock& block = *blockRef;
1429  PFBlock::LinkData linkData = block.linkData();
1431  bool DebugIDOutputs = false;
1432  if(DebugIDOutputs) cout << " ######## Enter in SetIDOutputs #########" << endl;
1433 
1434  unsigned int cgsf=0;
1435  for (map<unsigned int,vector<unsigned int> >::iterator igsf = associatedToGsf_.begin();
1436  igsf != associatedToGsf_.end(); igsf++,cgsf++) {
1437 
1438  float Ene_ecalgsf = 0.;
1439  float Ene_hcalgsf = 0.;
1440  double sigmaEtaEta = 0.;
1441  float deta_gsfecal = 0.;
1442  float Ene_ecalbrem = 0.;
1443  float Ene_extraecalgsf = 0.;
1444  bool LateBrem = false;
1445  // bool EarlyBrem = false;
1446  int FirstBrem = 1000;
1447  unsigned int ecalGsf_index = 100000;
1448  unsigned int kf_index = 100000;
1449  // unsigned int nhits_gsf = 0;
1450  int NumBrem = 0;
1451  reco::TrackRef RefKF;
1452  double posX=0.;
1453  double posY=0.;
1454  double posZ=0.;
1455 
1456  unsigned int gsf_index = igsf->first;
1457  const reco::PFBlockElementGsfTrack * GsfEl =
1458  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsf_index]));
1459  reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
1460  float Ein_gsf = 0.;
1461  if (RefGSF.isNonnull()) {
1462  float m_el=0.00051;
1463  Ein_gsf =sqrt(RefGSF->pMode()*
1464  RefGSF->pMode()+m_el*m_el);
1465  // nhits_gsf = RefGSF->hitPattern().trackerLayersWithMeasurement();
1466  }
1467  float Eout_gsf = GsfEl->Pout().t();
1468  float Etaout_gsf = GsfEl->positionAtECALEntrance().eta();
1469 
1470 
1471  if (DebugIDOutputs)
1472  cout << " setIdOutput! GSF Track: Ein " << Ein_gsf
1473  << " eta,phi " << Etaout_gsf
1474  <<", " << GsfEl->positionAtECALEntrance().phi() << endl;
1475 
1476 
1477  vector<unsigned int> assogsf_index = igsf->second;
1478  bool FirstEcalGsf = true;
1479  for (unsigned int ielegsf=0;ielegsf<assogsf_index.size();ielegsf++) {
1480  PFBlockElement::Type assoele_type = elements[(assogsf_index[ielegsf])].type();
1481 
1482 
1483  // The RefKf is needed to build pure tracking observables
1484  if(assoele_type == reco::PFBlockElement::TRACK) {
1485  const reco::PFBlockElementTrack * KfTk =
1486  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assogsf_index[ielegsf])]));
1487  // 19 Mar 2010 do not consider here track from gamma conv
1488 
1489  bool isPrim = isPrimaryTrack(*KfTk,*GsfEl);
1490  if(!isPrim) continue;
1491  RefKF = KfTk->trackRef();
1492  kf_index = assogsf_index[ielegsf];
1493  }
1494 
1495 
1496  if (assoele_type == reco::PFBlockElement::ECAL) {
1497  unsigned int keyecalgsf = assogsf_index[ielegsf];
1498  vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(keyecalgsf)->second;
1499 
1500  vector<double> ps1Ene(0);
1501  vector<double> ps2Ene(0);
1502  for(unsigned int ips =0; ips<assoecalgsf_index.size();ips++) {
1503  PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[ips])].type();
1504  if (typeassoecal == reco::PFBlockElement::PS1) {
1505  PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
1506  ps1Ene.push_back(psref->energy());
1507  }
1508  if (typeassoecal == reco::PFBlockElement::PS2) {
1509  PFClusterRef psref = elements[(assoecalgsf_index[ips])].clusterRef();
1510  ps2Ene.push_back(psref->energy());
1511  }
1512  if (typeassoecal == reco::PFBlockElement::HCAL) {
1513  const reco::PFBlockElementCluster * clust =
1514  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(assoecalgsf_index[ips])]));
1515  Ene_hcalgsf+=clust->clusterRef()->energy();
1516  }
1517  }
1518  if (FirstEcalGsf) {
1519  FirstEcalGsf = false;
1520  ecalGsf_index = assogsf_index[ielegsf];
1521  reco::PFClusterRef clusterRef = elements[(assogsf_index[ielegsf])].clusterRef();
1522  double ps1,ps2;
1523  ps1=ps2=0.;
1524  // Ene_ecalgsf = pfcalib_.energyEm(*clusterRef,ps1Ene,ps2Ene);
1525  Ene_ecalgsf = thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
1526  // std::cout << "Test " << Ene_ecalgsf << " PS1 / PS2 " << ps1 << " " << ps2 << std::endl;
1527  posX += Ene_ecalgsf * clusterRef->position().X();
1528  posY += Ene_ecalgsf * clusterRef->position().Y();
1529  posZ += Ene_ecalgsf * clusterRef->position().Z();
1530 
1531  if (DebugIDOutputs)
1532  cout << " setIdOutput! GSF ECAL Cluster E " << Ene_ecalgsf
1533  << " eta,phi " << clusterRef->position().eta()
1534  <<", " << clusterRef->position().phi() << endl;
1535 
1536  deta_gsfecal = clusterRef->position().eta() - Etaout_gsf;
1537 
1538  vector< const reco::PFCluster * > pfClust_vec(0);
1539  pfClust_vec.clear();
1540  pfClust_vec.push_back(&(*clusterRef));
1541 
1542  PFClusterWidthAlgo pfwidth(pfClust_vec);
1543  sigmaEtaEta = pfwidth.pflowSigmaEtaEta();
1544 
1545 
1546  }
1547  else {
1548  reco::PFClusterRef clusterRef = elements[(assogsf_index[ielegsf])].clusterRef();
1549  float TempClus_energy = thePFEnergyCalibration_->energyEm(*clusterRef,ps1Ene,ps2Ene,applyCrackCorrections_);
1550  Ene_extraecalgsf += TempClus_energy;
1551  posX += TempClus_energy * clusterRef->position().X();
1552  posY += TempClus_energy * clusterRef->position().Y();
1553  posZ += TempClus_energy * clusterRef->position().Z();
1554 
1555  if (DebugIDOutputs)
1556  cout << " setIdOutput! Extra ECAL Cluster E "
1557  << TempClus_energy << " Tot " << Ene_extraecalgsf << endl;
1558  }
1559  } // end type Ecal
1560 
1561 
1562  if (assoele_type == reco::PFBlockElement::BREM) {
1563  unsigned int brem_index = assogsf_index[ielegsf];
1564  const reco::PFBlockElementBrem * BremEl =
1565  dynamic_cast<const reco::PFBlockElementBrem*>((&elements[brem_index]));
1566  int TrajPos = (BremEl->indTrajPoint())-2;
1567  //if (TrajPos <= 3) EarlyBrem = true;
1568  if (TrajPos < FirstBrem) FirstBrem = TrajPos;
1569 
1570  vector<unsigned int> assobrem_index = associatedToBrems_.find(brem_index)->second;
1571  for (unsigned int ibrem = 0; ibrem < assobrem_index.size(); ibrem++){
1572  if (elements[(assobrem_index[ibrem])].type() == reco::PFBlockElement::ECAL) {
1573  unsigned int keyecalbrem = assobrem_index[ibrem];
1574  vector<unsigned int> assoelebrem_index = associatedToEcal_.find(keyecalbrem)->second;
1575  vector<double> ps1EneFromBrem(0);
1576  vector<double> ps2EneFromBrem(0);
1577  for (unsigned int ielebrem=0; ielebrem<assoelebrem_index.size();ielebrem++) {
1578  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS1) {
1579  PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
1580  ps1EneFromBrem.push_back(psref->energy());
1581  }
1582  if (elements[(assoelebrem_index[ielebrem])].type() == reco::PFBlockElement::PS2) {
1583  PFClusterRef psref = elements[(assoelebrem_index[ielebrem])].clusterRef();
1584  ps2EneFromBrem.push_back(psref->energy());
1585  }
1586  }
1587  // check if it is a compatible cluster also with the gsf track
1588  if( assobrem_index[ibrem] != ecalGsf_index) {
1589  reco::PFClusterRef clusterRef =
1590  elements[(assobrem_index[ibrem])].clusterRef();
1591  float BremClus_energy = thePFEnergyCalibration_->energyEm(*clusterRef,ps1EneFromBrem,ps2EneFromBrem,applyCrackCorrections_);
1592  Ene_ecalbrem += BremClus_energy;
1593  posX += BremClus_energy * clusterRef->position().X();
1594  posY += BremClus_energy * clusterRef->position().Y();
1595  posZ += BremClus_energy * clusterRef->position().Z();
1596 
1597  NumBrem++;
1598  if (DebugIDOutputs) cout << " setIdOutput::BREM Cluster "
1599  << BremClus_energy << " eta,phi "
1600  << clusterRef->position().eta() <<", "
1601  << clusterRef->position().phi() << endl;
1602  }
1603  else {
1604  LateBrem = true;
1605  }
1606  }
1607  }
1608  }
1609  }
1610  if (Ene_ecalgsf > 0.) {
1611  // here build the new BDT observables
1612 
1613  // ***** Normalization observables ****
1614  if(RefGSF.isNonnull()) {
1615  PFCandidateElectronExtra myExtra(RefGSF) ;
1616  myExtra.setGsfTrackPout(GsfEl->Pout());
1617  myExtra.setKfTrackRef(RefKF);
1618  float Pt_gsf = RefGSF->ptMode();
1619  lnPt_gsf = log(Pt_gsf);
1620  Eta_gsf = RefGSF->etaMode();
1621 
1622  // **** Pure tracking observables.
1623  if(RefGSF->ptModeError() > 0.)
1624  dPtOverPt_gsf = RefGSF->ptModeError()/Pt_gsf;
1625 
1626  nhit_gsf= RefGSF->hitPattern().trackerLayersWithMeasurement();
1627  chi2_gsf = RefGSF->normalizedChi2();
1628  // change GsfEl->Pout().pt() as soon the PoutMode is on the GsfTrack DataFormat
1629  DPtOverPt_gsf = (RefGSF->ptMode() - GsfEl->Pout().pt())/RefGSF->ptMode();
1630 
1631 
1632  nhit_kf = 0;
1633  chi2_kf = -0.01;
1634  DPtOverPt_kf = -0.01;
1635  if (RefKF.isNonnull()) {
1636  nhit_kf= RefKF->hitPattern().trackerLayersWithMeasurement();
1637  chi2_kf = RefKF->normalizedChi2();
1638  // Not used, strange behaviour to be checked. And Kf->OuterPt is
1639  // in track extra.
1640  //DPtOverPt_kf =
1641  // (RefKF->pt() - RefKF->outerPt())/RefKF->pt();
1642 
1643  }
1644 
1645  // **** Tracker-Ecal-Hcal observables
1646  EtotPinMode = (Ene_ecalgsf + Ene_ecalbrem + Ene_extraecalgsf) / Ein_gsf;
1647  EGsfPoutMode = Ene_ecalgsf/Eout_gsf;
1648  EtotBremPinPoutMode = Ene_ecalbrem /(Ein_gsf - Eout_gsf);
1649  DEtaGsfEcalClust = fabs(deta_gsfecal);
1650  myExtra.setSigmaEtaEta(sigmaEtaEta);
1651  myExtra.setDeltaEta(DEtaGsfEcalClust);
1652  SigmaEtaEta = log(sigmaEtaEta);
1653 
1654  lateBrem = -1;
1655  firstBrem = -1;
1656  earlyBrem = -1;
1657  if(NumBrem > 0) {
1658  if (LateBrem) lateBrem = 1;
1659  else lateBrem = 0;
1660  firstBrem = FirstBrem;
1661  if(FirstBrem < 4) earlyBrem = 1;
1662  else earlyBrem = 0;
1663  }
1664 
1665  HOverHE = Ene_hcalgsf/(Ene_hcalgsf + Ene_ecalgsf);
1666  HOverPin = Ene_hcalgsf / Ein_gsf;
1667  myExtra.setHadEnergy(Ene_hcalgsf);
1668  myExtra.setEarlyBrem(earlyBrem);
1669  myExtra.setLateBrem(lateBrem);
1670  // std::cout<< " Inserting in extra " << electronExtra_.size() << std::endl;
1671 
1672  // Put cuts and access the BDT output
1673  if(DPtOverPt_gsf < -0.2) DPtOverPt_gsf = -0.2;
1674  if(DPtOverPt_gsf > 1.) DPtOverPt_gsf = 1.;
1675 
1676  if(dPtOverPt_gsf > 0.3) dPtOverPt_gsf = 0.3;
1677 
1678  if(chi2_gsf > 10.) chi2_gsf = 10.;
1679 
1680  if(DPtOverPt_kf < -0.2) DPtOverPt_kf = -0.2;
1681  if(DPtOverPt_kf > 1.) DPtOverPt_kf = 1.;
1682 
1683  if(chi2_kf > 10.) chi2_kf = 10.;
1684 
1685  if(EtotPinMode < 0.) EtotPinMode = 0.;
1686  if(EtotPinMode > 5.) EtotPinMode = 5.;
1687 
1688  if(EGsfPoutMode < 0.) EGsfPoutMode = 0.;
1689  if(EGsfPoutMode > 5.) EGsfPoutMode = 5.;
1690 
1691  if(EtotBremPinPoutMode < 0.) EtotBremPinPoutMode = 0.01;
1693 
1694  if(DEtaGsfEcalClust > 0.1) DEtaGsfEcalClust = 0.1;
1695 
1696  if(SigmaEtaEta < -14) SigmaEtaEta = -14;
1697 
1698  if(HOverPin < 0.) HOverPin = 0.;
1699  if(HOverPin > 5.) HOverPin = 5.;
1700  double mvaValue = tmvaReader_->EvaluateMVA("BDT");
1701 
1702  // add output observables
1703  BDToutput_[cgsf] = mvaValue;
1704  myExtra.setMVA(mvaValue);
1705  electronExtra_.push_back(myExtra);
1706 
1707 
1708  // IMPORTANT Additional conditions
1709  if(mvaValue > mvaEleCut_) {
1710  // Check if the ecal cluster is isolated.
1711  //
1712  // If there is at least one extra track and H/H+E > 0.05 or SumP(ExtraKf)/EGsf or
1713  // #Tracks > 3 I leave this job to PFAlgo, otherwise I lock those extra tracks.
1714  // Note:
1715  // The tracks coming from the 4 step of the iterative tracking are not considered,
1716  // because they can come from secondary converted brems.
1717  // They are locked to avoid double counting.
1718  // The lock is done in SetActivate function.
1719  // All this can improved but it is already a good step.
1720 
1721 
1722  // Find if the cluster is isolated.
1723  unsigned int iextratrack = 0;
1724  unsigned int itrackHcalLinked = 0;
1725  float SumExtraKfP = 0.;
1726 
1727 
1728  double Etotal = Ene_ecalgsf + Ene_ecalbrem + Ene_extraecalgsf;
1729  posX /=Etotal;
1730  posY /=Etotal;
1731  posZ /=Etotal;
1732  math::XYZPoint sc_pflow(posX,posY,posZ);
1733  double ETtotal = Etotal*sin(sc_pflow.Theta());
1734  double phiTrack = RefGSF->phiMode();
1735  double dphi_normalsc = sc_pflow.Phi() - phiTrack;
1736  if ( dphi_normalsc < -M_PI )
1737  dphi_normalsc = dphi_normalsc + 2.*M_PI;
1738  else if ( dphi_normalsc > M_PI )
1739  dphi_normalsc = dphi_normalsc - 2.*M_PI;
1740  dphi_normalsc = fabs(dphi_normalsc);
1741 
1742 
1743  if(ecalGsf_index < 100000) {
1744  vector<unsigned int> assoecalgsf_index = associatedToEcal_.find(ecalGsf_index)->second;
1745  for(unsigned int itrk =0; itrk<assoecalgsf_index.size();itrk++) {
1746  PFBlockElement::Type typeassoecal = elements[(assoecalgsf_index[itrk])].type();
1747  if(typeassoecal == reco::PFBlockElement::TRACK) {
1748  const reco::PFBlockElementTrack * kfTk =
1749  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(assoecalgsf_index[itrk])]));
1750  // 19 Mar 2010 do not consider here tracks from gamma conv
1751  // This should be not needed because the seleted extra tracks from GammaConv
1752  // will be locked and can not be associated to the ecal elements
1753  //if(kfTk->trackType(reco::PFBlockElement::T_FROM_GAMMACONV)) continue;
1754 
1755 
1756  reco::TrackRef trackref = kfTk->trackRef();
1757  bool goodTrack = PFTrackAlgoTools::isGoodForEGM(trackref->algo());
1758  // iter0, iter1, iter2, iter3 = Algo < 3
1759  // algo 4,5,6,7
1760  int nexhits = trackref->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
1761 
1762  bool trackIsFromPrimaryVertex = false;
1763  for (Vertex::trackRef_iterator trackIt = primaryVertex.tracks_begin(); trackIt != primaryVertex.tracks_end(); ++trackIt) {
1764  if ( (*trackIt).castTo<TrackRef>() == trackref ) {
1765  trackIsFromPrimaryVertex = true;
1766  break;
1767  }
1768  }
1769 
1770  // probably we could now remove the algo request??
1771  if(goodTrack && nexhits == 0 && trackIsFromPrimaryVertex) {
1772  //if(Algo < 3)
1773  if(DebugIDOutputs)
1774  cout << " The ecalGsf cluster is not isolated: >0 KF extra with algo < 3" << endl;
1775 
1776  float p_trk = trackref->p();
1777 
1778  // expected number of inner hits
1779 
1780  if(DebugIDOutputs)
1781  cout << " p_trk " << p_trk
1782  << " nexhits " << nexhits << endl;
1783 
1784  SumExtraKfP += p_trk;
1785  iextratrack++;
1786  // Check if these extra tracks are HCAL linked
1787  std::multimap<double, unsigned int> hcalKfElems;
1788  block.associatedElements( assoecalgsf_index[itrk],linkData,
1789  hcalKfElems,
1792  if(hcalKfElems.size() > 0) {
1793  itrackHcalLinked++;
1794  }
1795  }
1796  }
1797  }
1798  }
1799  if( iextratrack > 0) {
1800  //if(iextratrack > 3 || HOverHE > 0.05 || (SumExtraKfP/Ene_ecalgsf) > 1.
1801  if(iextratrack > 3 || Ene_hcalgsf > 10 || (SumExtraKfP/Ene_ecalgsf) > 1.
1802  || (ETtotal > 50. && iextratrack > 1 && (Ene_hcalgsf/Ene_ecalgsf) > 0.1) ) {
1803  if(DebugIDOutputs)
1804  cout << " *****This electron candidate is discarded: Non isolated # tracks "
1805  << iextratrack << " HOverHE " << HOverHE
1806  << " SumExtraKfP/Ene_ecalgsf " << SumExtraKfP/Ene_ecalgsf
1807  << " SumExtraKfP " << SumExtraKfP
1808  << " Ene_ecalgsf " << Ene_ecalgsf
1809  << " ETtotal " << ETtotal
1810  << " Ene_hcalgsf/Ene_ecalgsf " << Ene_hcalgsf/Ene_ecalgsf
1811  << endl;
1812 
1813  BDToutput_[cgsf] = mvaValue-2.;
1814  lockExtraKf_[cgsf] = false;
1815  }
1816  // if the Ecluster ~ Ptrack and the extra tracks are HCAL linked
1817  // the electron is retained and the kf tracks are not locked
1818  if( (fabs(1.-EtotPinMode) < 0.2 && (fabs(Eta_gsf) < 1.0 || fabs(Eta_gsf) > 2.0)) ||
1819  ((EtotPinMode < 1.1 && EtotPinMode > 0.6) && (fabs(Eta_gsf) >= 1.0 && fabs(Eta_gsf) <= 2.0))) {
1820  if( fabs(1.-EGsfPoutMode) < 0.5 &&
1821  (itrackHcalLinked == iextratrack) &&
1822  kf_index < 100000 ) {
1823 
1824  BDToutput_[cgsf] = mvaValue;
1825  lockExtraKf_[cgsf] = false;
1826  if(DebugIDOutputs)
1827  cout << " *****This electron is reactivated # tracks "
1828  << iextratrack << " #tracks hcal linked " << itrackHcalLinked
1829  << " SumExtraKfP/Ene_ecalgsf " << SumExtraKfP/Ene_ecalgsf
1830  << " EtotPinMode " << EtotPinMode << " EGsfPoutMode " << EGsfPoutMode
1831  << " eta gsf " << fabs(Eta_gsf) << " kf index " << kf_index <<endl;
1832  }
1833  }
1834  }
1835  // This is a pion:
1836  if (HOverPin > 1. && HOverHE > 0.1 && EtotPinMode < 0.5) {
1837  if(DebugIDOutputs)
1838  cout << " *****This electron candidate is discarded HCAL ENERGY "
1839  << " HOverPin " << HOverPin << " HOverHE " << HOverHE << " EtotPinMode" << EtotPinMode << endl;
1840  BDToutput_[cgsf] = mvaValue-4.;
1841  lockExtraKf_[cgsf] = false;
1842  }
1843 
1844  // Reject Crazy E/p values... to be understood in the future how to train a
1845  // BDT in order to avoid to select this bad electron candidates.
1846 
1847  if( EtotPinMode < 0.2 && EGsfPoutMode < 0.2 ) {
1848  if(DebugIDOutputs)
1849  cout << " *****This electron candidate is discarded Low ETOTPIN "
1850  << " EtotPinMode " << EtotPinMode << " EGsfPoutMode " << EGsfPoutMode << endl;
1851  BDToutput_[cgsf] = mvaValue-6.;
1852  }
1853 
1854  // For not-preselected Gsf Tracks ET > 50 GeV, apply dphi preselection
1855  if(ETtotal > 50. && dphi_normalsc > 0.1 ) {
1856  if(DebugIDOutputs)
1857  cout << " *****This electron candidate is discarded Large ANGLE "
1858  << " ETtotal " << ETtotal << " EGsfPoutMode " << dphi_normalsc << endl;
1859  BDToutput_[cgsf] = mvaValue-6.;
1860  }
1861  }
1862 
1863 
1864  if (DebugIDOutputs) {
1865  cout << " **** BDT observables ****" << endl;
1866  cout << " < Normalization > " << endl;
1867  cout << " Pt_gsf " << Pt_gsf << " Pin " << Ein_gsf << " Pout " << Eout_gsf
1868  << " Eta_gsf " << Eta_gsf << endl;
1869  cout << " < PureTracking > " << endl;
1870  cout << " dPtOverPt_gsf " << dPtOverPt_gsf
1871  << " DPtOverPt_gsf " << DPtOverPt_gsf
1872  << " chi2_gsf " << chi2_gsf
1873  << " nhit_gsf " << nhit_gsf
1874  << " DPtOverPt_kf " << DPtOverPt_kf
1875  << " chi2_kf " << chi2_kf
1876  << " nhit_kf " << nhit_kf << endl;
1877  cout << " < track-ecal-hcal-ps " << endl;
1878  cout << " EtotPinMode " << EtotPinMode
1879  << " EGsfPoutMode " << EGsfPoutMode
1880  << " EtotBremPinPoutMode " << EtotBremPinPoutMode
1881  << " DEtaGsfEcalClust " << DEtaGsfEcalClust
1882  << " SigmaEtaEta " << SigmaEtaEta
1883  << " HOverHE " << HOverHE << " Hcal energy " << Ene_hcalgsf
1884  << " HOverPin " << HOverPin
1885  << " lateBrem " << lateBrem
1886  << " firstBrem " << firstBrem << endl;
1887  cout << " !!!!!!!!!!!!!!!! the BDT output !!!!!!!!!!!!!!!!!: direct " << mvaValue
1888  << " corrected " << BDToutput_[cgsf] << endl;
1889 
1890  }
1891  }
1892  else {
1893  if (DebugIDOutputs)
1894  cout << " Gsf Ref isNULL " << endl;
1895  BDToutput_[cgsf] = -2.;
1896  }
1897  } else {
1898  if (DebugIDOutputs)
1899  cout << " No clusters associated to the gsf " << endl;
1900  BDToutput_[cgsf] = -2.;
1901  }
1902  DebugIDOutputs = false;
1903  } // End Loop on Map1
1904  return;
1905 }
type
Definition: HCALResponse.h:21
const math::XYZTLorentzVector & Pout() const
const reco::TrackRef & trackRef() const
const reco::GsfTrackRef & GsftrackRef() const
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
trackRef_iterator tracks_end() const
last iterator over tracks
Definition: Vertex.cc:44
float EtotBremPinPoutMode
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
bool isPrimaryTrack(const reco::PFBlockElementTrack &KfEl, const reco::PFBlockElementGsfTrack &GsfEl)
const PFClusterRef & clusterRef() const
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
const LinkData & linkData() const
Definition: PFBlock.h:112
unsigned int indTrajPoint() const
TMVA::Reader * tmvaReader_
dictionary elements
bool isGoodForEGM(const reco::TrackBase::TrackAlgorithm &)
bool goodTrack(const reco::Track *pTrack, math::XYZPoint leadPV, trackSelectionParameters parameters, bool debug=false)
T sqrt(T t)
Definition: SSEVec.h:18
std::vector< bool > lockExtraKf_
std::vector< double > BDToutput_
#define M_PI
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:12
std::vector< TrackBaseRef >::const_iterator trackRef_iterator
The iteratator for the vector&lt;TrackRef&gt;
Definition: Vertex.h:37
tuple cout
Definition: gather_cfg.py:145
trackRef_iterator tracks_begin() const
first iterator over tracks
Definition: Vertex.cc:39
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration_
bool applyCrackCorrections_
Block of elements.
Definition: PFBlock.h:30
bool PFElectronAlgo::SetLinks ( const reco::PFBlockRef blockRef,
AssMap associatedToGsf_,
AssMap associatedToBrems_,
AssMap associatedToEcal_,
std::vector< bool > &  active,
const reco::Vertex primaryVertex 
)
private

Definition at line 132 of file PFElectronAlgo.cc.

References applyCrackCorrections_, reco::PFBlock::associatedElements(), createPayload::block, reco::PFBlockElement::BREM, reco::PFBlockElementCluster::clusterRef(), coneEcalIsoForEgammaSC_, convGsfTrack_, gather_cfg::cout, reco::PFBlock::dist(), ECAL, reco::PFBlockElement::ECAL, reco::PFBlock::elements(), bookConverter::elements, fifthStepKfTrack_, reco::PFBlockElement::GSF, reco::PFBlockElementGsfTrack::GsftrackRef(), reco::PFBlockElement::HCAL, i, cuy::ii, cmsHarvester::index, reco::PFBlockElementBrem::indTrajPoint(), edm::OwnVector< T, P >::insert(), PFTrackAlgoTools::isGoodForEGM(), PFMuonAlgo::isMuon(), edm::Ref< C, T, F >::isNonnull(), isPrimaryTrack(), reco::PFBlock::linkData(), reco::PFBlock::LINKTEST_ALL, M_PI, nTrackIsoForEgammaSC_, reco::PFBlockElementBrem::positionAtECALEntrance(), reco::PFBlockElementGsfTrack::positionAtECALEntrance(), reco::PFBlockElementGsfTrack::Pout(), reco::PFBlockElement::PS1, reco::PFBlockElement::PS2, runTheMatrix::ret, funct::sin(), edm::OwnVector< T, P >::size(), mathSSE::sqrt(), sumEtEcalIsoForEgammaSC_barrel_, sumEtEcalIsoForEgammaSC_endcap_, sumPtTrackIsoForEgammaSC_barrel_, sumPtTrackIsoForEgammaSC_endcap_, reco::PFBlockElement::T_FROM_GAMMACONV, thePFEnergyCalibration_, reco::PFBlockElement::TRACK, reco::PFBlockElementTrack::trackRef(), reco::Vertex::tracks_begin(), reco::Vertex::tracks_end(), reco::PFBlockElementGsfTrack::trackType(), and useEGammaSupercluster_.

Referenced by RunPFElectron().

137  {
138  unsigned int CutIndex = 100000;
139  double CutGSFECAL = 10000. ;
140  // no other cut are not used anymore. We use the default of PFBlockAlgo
141  //PFEnergyCalibration pfcalib_;
142  bool DebugSetLinksSummary = false;
143  bool DebugSetLinksDetailed = false;
144 
145  const reco::PFBlock& block = *blockRef;
147  PFBlock::LinkData linkData = block.linkData();
148 
149  bool IsThereAGSFTrack = false;
150  bool IsThereAGoodGSFTrack = false;
151 
152  vector<unsigned int> trackIs(0);
153  vector<unsigned int> gsfIs(0);
154  vector<unsigned int> ecalIs(0);
155 
156  std::vector<bool> localactive(elements.size(),true);
157 
158 
159  // Save the elements in shorter vectors like in PFAlgo.
160  std::multimap<double, unsigned int> kfElems;
161  for(unsigned int iEle=0; iEle<elements.size(); iEle++) {
162  localactive[iEle] = active[iEle];
163  bool thisIsAMuon = false;
164  PFBlockElement::Type type = elements[iEle].type();
165  switch( type ) {
166  case PFBlockElement::TRACK:
167  // Check if the track is already identified as a muon
168  thisIsAMuon = PFMuonAlgo::isMuon(elements[iEle]);
169  // Otherwise store index
170  if ( !thisIsAMuon && active[iEle] ) {
171  trackIs.push_back( iEle );
172  if (DebugSetLinksDetailed)
173  cout<<"TRACK, stored index, continue "<< iEle << endl;
174  }
175  continue;
176  case PFBlockElement::GSF:
177  // Check if the track has a KF partner identified as a muon
178  block.associatedElements( iEle,linkData,
179  kfElems,
182  thisIsAMuon = kfElems.size() ?
183  PFMuonAlgo::isMuon(elements[kfElems.begin()->second]) : false;
184  // Otherwise store index
185  if ( !thisIsAMuon && active[iEle] ) {
186  IsThereAGSFTrack = true;
187  gsfIs.push_back( iEle );
188  if (DebugSetLinksDetailed)
189  cout<<"GSF, stored index, continue "<< iEle << endl;
190  }
191  continue;
192  case PFBlockElement::ECAL:
193  if ( active[iEle] ) {
194  ecalIs.push_back( iEle );
195  if (DebugSetLinksDetailed)
196  cout<<"ECAL, stored index, continue "<< iEle << endl;
197  }
198  continue;
199  default:
200  continue;
201  }
202  }
203  // ******************* Start Link *****************************
204  // Do something only if a gsf track is found in the block
205  if(IsThereAGSFTrack) {
206 
207 
208  // LocalLock the Elements associated to a Kf tracks and not to a Gsf
209  // The clusters associated both to a kf track and to a brem tangend
210  // are then assigned only to the kf track
211  // Could be improved doing this after.
212 
213  // 19 Mar 2010 adding the KF track from Gamma Conv.
214  // They are linked to the GSF tracks they are not considered
215  // anymore in the following ecal cluster locking
216  if (DebugSetLinksDetailed) {
217  cout<<"#########################################################"<<endl;
218  cout<<"##### Process Block: #####"<<endl;
219  cout<<"#########################################################"<<endl;
220  cout<<block<<endl;
221  }
222 
223 
224  for(unsigned int iEle=0; iEle<trackIs.size(); iEle++) {
225  std::multimap<double, unsigned int> gsfElems;
226  block.associatedElements( trackIs[iEle], linkData,
227  gsfElems ,
230  if(gsfElems.size() == 0){
231  // This means that the considered kf is *not* associated
232  // to any gsf track
233  std::multimap<double, unsigned int> ecalKfElems;
234  block.associatedElements( trackIs[iEle],linkData,
235  ecalKfElems,
238  if(ecalKfElems.size() > 0) {
239  unsigned int ecalKf_index = ecalKfElems.begin()->second;
240  if(localactive[ecalKf_index]==true) {
241  // Check if this clusters is however well linked to a primary gsf track
242  // if this the case the cluster is not locked.
243 
244  bool isGsfLinked = false;
245  for(unsigned int iGsf=0; iGsf<gsfIs.size(); iGsf++) {
246  // if the ecal cluster is associated contemporary to a KF track
247  // and to a GSF track from conv, it is assigned to the KF track
248  // In this way we can loose some cluster but it is safer for double counting.
249  const reco::PFBlockElementGsfTrack * GsfEl =
250  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsfIs[iGsf]]));
252 
253  std::multimap<double, unsigned int> ecalGsfElems;
254  block.associatedElements( gsfIs[iGsf],linkData,
255  ecalGsfElems,
258  if(ecalGsfElems.size() > 0) {
259  if (ecalGsfElems.begin()->second == ecalKf_index) {
260  isGsfLinked = true;
261  }
262  }
263  }
264  if(isGsfLinked == false) {
265  // add protection against energy loss because
266  // of the tracking fifth step
267  const reco::PFBlockElementTrack * kfEle =
268  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(trackIs[iEle])]));
269  reco::TrackRef refKf = kfEle->trackRef();
270 
271  int nexhits = refKf->hitPattern().numberOfLostHits(HitPattern::MISSING_INNER_HITS);
272 
273  bool isGoodTrack=false;
274  if (refKf.isNonnull())
275  isGoodTrack = PFTrackAlgoTools::isGoodForEGM(refKf->algo());
276 
277 
278  bool trackIsFromPrimaryVertex = false;
279  for (Vertex::trackRef_iterator trackIt = primaryVertex.tracks_begin(); trackIt != primaryVertex.tracks_end(); ++trackIt) {
280  if ( (*trackIt).castTo<TrackRef>() == refKf ) {
281  trackIsFromPrimaryVertex = true;
282  break;
283  }
284  }
285 
286  if(isGoodTrack
287  && nexhits == 0 && trackIsFromPrimaryVertex) {
288  localactive[ecalKf_index] = false;
289  } else {
290  fifthStepKfTrack_.push_back(make_pair(ecalKf_index,trackIs[iEle]));
291  }
292  }
293  }
294  }
295  } // gsfElems.size()
296  } // loop on kf tracks
297 
298 
299  // start loop on gsf tracks
300  for(unsigned int iEle=0; iEle<gsfIs.size(); iEle++) {
301 
302  if (!localactive[(gsfIs[iEle])]) continue;
303 
304  localactive[gsfIs[iEle]] = false;
305  bool ClosestEcalWithKf = false;
306 
307  if (DebugSetLinksDetailed) cout << " Gsf Index " << gsfIs[iEle] << endl;
308 
309  const reco::PFBlockElementGsfTrack * GsfEl =
310  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[(gsfIs[iEle])]));
311 
312  // if GsfTrack fron converted bremsstralung continue
314  IsThereAGoodGSFTrack = true;
315  float eta_gsf = GsfEl->positionAtECALEntrance().eta();
316  float etaOut_gsf = GsfEl->Pout().eta();
317  float diffOutEcalEta = fabs(eta_gsf-etaOut_gsf);
318  reco::GsfTrackRef RefGSF = GsfEl->GsftrackRef();
319  float Pin_gsf = 0.01;
320  if (RefGSF.isNonnull() )
321  Pin_gsf = RefGSF->pMode();
322 
323 
324  // Find Associated Kf Track elements and Ecal to KF elements
325  unsigned int KfGsf_index = CutIndex;
326  unsigned int KfGsf_secondIndex = CutIndex;
327  std::multimap<double, unsigned int> kfElems;
328  block.associatedElements( gsfIs[iEle],linkData,
329  kfElems,
332  std::multimap<double, unsigned int> ecalKfElems;
333  if (kfElems.size() > 0) {
334  // 19 Mar 2010 now a loop is needed because > 1 KF track could
335  // be associated to the same GSF track
336 
337  for(std::multimap<double, unsigned int>::iterator itkf = kfElems.begin();
338  itkf != kfElems.end(); ++itkf) {
339  const reco::PFBlockElementTrack * TrkEl =
340  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[itkf->second]));
341 
342  bool isPrim = isPrimaryTrack(*TrkEl,*GsfEl);
343  if(!isPrim)
344  continue;
345 
346  if(localactive[itkf->second] == true) {
347 
348  KfGsf_index = itkf->second;
349  localactive[KfGsf_index] = false;
350  // Find clusters associated to kftrack using linkbyrechit
351  block.associatedElements( KfGsf_index, linkData,
352  ecalKfElems ,
355  }
356  else {
357  KfGsf_secondIndex = itkf->second;
358  }
359  }
360  }
361 
362  // Find the closest Ecal clusters associated to this Gsf
363  std::multimap<double, unsigned int> ecalGsfElems;
364  block.associatedElements( gsfIs[iEle],linkData,
365  ecalGsfElems,
368  double ecalGsf_dist = CutGSFECAL;
369  unsigned int ClosestEcalGsf_index = CutIndex;
370  if (ecalGsfElems.size() > 0) {
371  if(localactive[(ecalGsfElems.begin()->second)] == true) {
372  // check energy compatibility for outer eta != ecal entrance, looping tracks
373  bool compatibleEPout = true;
374  if(diffOutEcalEta > 0.3) {
375  reco::PFClusterRef clusterRef = elements[(ecalGsfElems.begin()->second)].clusterRef();
376  float EoPout = (clusterRef->energy())/(GsfEl->Pout().t());
377  if(EoPout > 5)
378  compatibleEPout = false;
379  }
380  if(compatibleEPout) {
381  ClosestEcalGsf_index = ecalGsfElems.begin()->second;
382  ecalGsf_dist = block.dist(gsfIs[iEle],ClosestEcalGsf_index,
383  linkData,reco::PFBlock::LINKTEST_ALL);
384 
385  // Check that this cluster is not closer to another primary Gsf track
386 
387  std::multimap<double, unsigned int> ecalOtherGsfElems;
388  block.associatedElements( ClosestEcalGsf_index,linkData,
389  ecalOtherGsfElems,
392 
393  if(ecalOtherGsfElems.size()>0) {
394  // get if it is closed to a conv brem gsf tracks
395  const reco::PFBlockElementGsfTrack * gsfCheck =
396  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
397 
398  if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]&&
399  gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
400  ecalGsf_dist = CutGSFECAL;
401  ClosestEcalGsf_index = CutIndex;
402  }
403  }
404  }
405  // do not lock at the moment we need this for the late brem
406  }
407  }
408  // if any cluster is found with the gsf-ecal link, try with kf-ecal
409  else if(ecalKfElems.size() > 0) {
410  if(localactive[(ecalKfElems.begin()->second)] == true) {
411  ClosestEcalGsf_index = ecalKfElems.begin()->second;
412  ecalGsf_dist = block.dist(gsfIs[iEle],ClosestEcalGsf_index,
413  linkData,reco::PFBlock::LINKTEST_ALL);
414  ClosestEcalWithKf = true;
415 
416  // Check if this cluster is not closer to another Gsf track
417  std::multimap<double, unsigned int> ecalOtherGsfElems;
418  block.associatedElements( ClosestEcalGsf_index,linkData,
419  ecalOtherGsfElems,
422  if(ecalOtherGsfElems.size() > 0) {
423  const reco::PFBlockElementGsfTrack * gsfCheck =
424  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
425 
426  if(ecalOtherGsfElems.begin()->second != gsfIs[iEle] &&
428  ecalGsf_dist = CutGSFECAL;
429  ClosestEcalGsf_index = CutIndex;
430  ClosestEcalWithKf = false;
431  }
432  }
433  }
434  }
435 
436  if (DebugSetLinksDetailed)
437  cout << " Closest Ecal to the Gsf/Kf: index " << ClosestEcalGsf_index
438  << " dist " << ecalGsf_dist << endl;
439 
440 
441 
442  // Find the brems associated to this Gsf
443  std::multimap<double, unsigned int> bremElems;
444  block.associatedElements( gsfIs[iEle],linkData,
445  bremElems,
448 
449 
450  multimap<unsigned int,unsigned int> cleanedEcalBremElems;
451  vector<unsigned int> keyBremIndex(0);
452  unsigned int latestBrem_trajP = 0;
453  unsigned int latestBrem_index = CutIndex;
454  for(std::multimap<double, unsigned int>::iterator ieb = bremElems.begin();
455  ieb != bremElems.end(); ++ieb ) {
456  unsigned int brem_index = ieb->second;
457  if(localactive[brem_index] == false) continue;
458 
459 
460  // Find the ecal clusters associated to the brems
461  std::multimap<double, unsigned int> ecalBremsElems;
462 
463  block.associatedElements( brem_index, linkData,
464  ecalBremsElems,
467 
468  for (std::multimap<double, unsigned int>::iterator ie = ecalBremsElems.begin();
469  ie != ecalBremsElems.end();ie++) {
470  unsigned int ecalBrem_index = ie->second;
471  if(localactive[ecalBrem_index] == false) continue;
472 
473  //to be changed, using the distance
474  float ecalBrem_dist = block.dist(brem_index,ecalBrem_index,
475  linkData,reco::PFBlock::LINKTEST_ALL);
476 
477 
478  if (ecalBrem_index == ClosestEcalGsf_index && (ecalBrem_dist + 0.0012) > ecalGsf_dist) continue;
479 
480  // Find the closest brem
481  std::multimap<double, unsigned int> sortedBremElems;
482  block.associatedElements( ecalBrem_index,linkData,
483  sortedBremElems,
486  // check that this brem is that one coming from the same *primary* gsf
487  bool isGoodBrem = false;
488  unsigned int sortedBrem_index = CutIndex;
489  for (std::multimap<double, unsigned int>::iterator ibs = sortedBremElems.begin();
490  ibs != sortedBremElems.end();ibs++) {
491  unsigned int temp_sortedBrem_index = ibs->second;
492  std::multimap<double, unsigned int> sortedGsfElems;
493  block.associatedElements( temp_sortedBrem_index,linkData,
494  sortedGsfElems,
497  bool enteredInPrimaryGsf = false;
498  for (std::multimap<double, unsigned int>::iterator igs = sortedGsfElems.begin();
499  igs != sortedGsfElems.end();igs++) {
500  const reco::PFBlockElementGsfTrack * gsfCheck =
501  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[igs->second]));
502 
503  if(gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) {
504  if(igs->second == gsfIs[iEle]) {
505  isGoodBrem = true;
506  sortedBrem_index = temp_sortedBrem_index;
507  }
508  enteredInPrimaryGsf = true;
509  break;
510  }
511  }
512  if(enteredInPrimaryGsf)
513  break;
514  }
515 
516  if(isGoodBrem) {
517 
518  // Check that this cluster is not closer to another Gsf Track
519  // The check is not performed on KF track because the ecal clusters are aready locked.
520  std::multimap<double, unsigned int> ecalOtherGsfElems;
521  block.associatedElements( ecalBrem_index,linkData,
522  ecalOtherGsfElems,
525  if (ecalOtherGsfElems.size() > 0) {
526  const reco::PFBlockElementGsfTrack * gsfCheck =
527  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[ecalOtherGsfElems.begin()->second]));
528  if(ecalOtherGsfElems.begin()->second != gsfIs[iEle] &&
530  continue;
531  }
532  }
533 
534  const reco::PFBlockElementBrem * BremEl =
535  dynamic_cast<const reco::PFBlockElementBrem*>((&elements[sortedBrem_index]));
536 
537  reco::PFClusterRef clusterRef =
538  elements[ecalBrem_index].clusterRef();
539 
540 
541  float sortedBremEcal_deta = fabs(clusterRef->position().eta() - BremEl->positionAtECALEntrance().eta());
542  // Triangular cut on plan chi2:deta -> OLD
543  //if((0.0075*sortedBremEcal_chi2 + 100.*sortedBremEcal_deta -1.5) < 0.) {
544  if(sortedBremEcal_deta < 0.015) {
545 
546  cleanedEcalBremElems.insert(pair<unsigned int,unsigned int>(sortedBrem_index,ecalBrem_index));
547 
548  unsigned int BremTrajP = BremEl->indTrajPoint();
549  if (BremTrajP > latestBrem_trajP) {
550  latestBrem_trajP = BremTrajP;
551  latestBrem_index = sortedBrem_index;
552  }
553  if (DebugSetLinksDetailed)
554  cout << " brem Index " << sortedBrem_index
555  << " associated cluster " << ecalBrem_index << " BremTrajP " << BremTrajP <<endl;
556 
557  // > 1 ecal clusters could be associated to the same brem twice: allowed N-1 link.
558  // But the brem need to be stored once.
559  // locallock the brem and the ecal clusters
560  localactive[ecalBrem_index] = false; // the cluster
561  bool alreadyfound = false;
562  for(unsigned int ii=0;ii<keyBremIndex.size();ii++) {
563  if (sortedBrem_index == keyBremIndex[ii]) alreadyfound = true;
564  }
565  if (alreadyfound == false) {
566  keyBremIndex.push_back(sortedBrem_index);
567  localactive[sortedBrem_index] = false; // the brem
568  }
569  }
570  }
571  }
572  }
573 
574 
575  // Find Possible Extra Cluster associated to the gsf/kf
576  vector<unsigned int> GsfElemIndex(0);
577  vector<unsigned int> EcalIndex(0);
578 
579  // locallock the ecal cluster associated to the gsf
580  if (ClosestEcalGsf_index < CutIndex) {
581  GsfElemIndex.push_back(ClosestEcalGsf_index);
582  localactive[ClosestEcalGsf_index] = false;
583  for (std::multimap<double, unsigned int>::iterator ii = ecalGsfElems.begin();
584  ii != ecalGsfElems.end();ii++) {
585  if(localactive[ii->second]) {
586  // Check that this cluster is not closer to another Gsf Track
587  std::multimap<double, unsigned int> ecalOtherGsfElems;
588  block.associatedElements( ii->second,linkData,
589  ecalOtherGsfElems,
592  if(ecalOtherGsfElems.size()) {
593  if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]) continue;
594  }
595 
596  // get the cluster only if the deta (ecal-gsf) < 0.05
597  reco::PFClusterRef clusterRef = elements[(ii->second)].clusterRef();
598  float etacl = clusterRef->eta();
599  if( fabs(eta_gsf-etacl) < 0.05) {
600  GsfElemIndex.push_back(ii->second);
601  localactive[ii->second] = false;
602  if (DebugSetLinksDetailed)
603  cout << " ExtraCluster From Gsf " << ii->second << endl;
604  }
605  }
606  }
607  }
608 
609  //Add the possibility to link other ecal clusters from kf.
610 
611 // for (std::multimap<double, unsigned int>::iterator ii = ecalKfElems.begin();
612 // ii != ecalKfElems.end();ii++) {
613 // if(localactive[ii->second]) {
614 // // Check that this cluster is not closer to another Gsf Track
615 // std::multimap<double, unsigned int> ecalOtherGsfElems;
616 // block.associatedElements( ii->second,linkData,
617 // ecalOtherGsfElems,
618 // reco::PFBlockElement::GSF,
619 // reco::PFBlock::LINKTEST_CHI2);
620 // if(ecalOtherGsfElems.size()) {
621 // if(ecalOtherGsfElems.begin()->second != gsfIs[iEle]) continue;
622 // }
623 // GsfElemIndex.push_back(ii->second);
624 // reco::PFClusterRef clusterRef = elements[(ii->second)].clusterRef();
625 // float etacl = clusterRef->eta();
626 // if( fabs(eta_gsf-etacl) < 0.05) {
627 // localactive[ii->second] = false;
628 // if (DebugSetLinksDetailed)
629 // cout << " ExtraCluster From KF " << ii->second << endl;
630 // }
631 // }
632 // }
633 
634  //****************** Fill Maps *************************
635 
636  // The GsfMap
637 
638  // if any clusters have been associated to the gsf track
639  // use the Ecal clusters associated to the latest brem and associate it to the gsf
640  if(GsfElemIndex.size() == 0){
641  if(latestBrem_index < CutIndex) {
642  unsigned int ckey = cleanedEcalBremElems.count(latestBrem_index);
643  if(ckey == 1) {
644  unsigned int temp_cal =
645  cleanedEcalBremElems.find(latestBrem_index)->second;
646  GsfElemIndex.push_back(temp_cal);
647  if (DebugSetLinksDetailed)
648  cout << "******************** Gsf Cluster From Brem " << temp_cal
649  << " Latest Brem index " << latestBrem_index
650  << " ************************* " << endl;
651  }
652  else{
653  pair<multimap<unsigned int,unsigned int>::iterator,multimap<unsigned int,unsigned int>::iterator> ret;
654  ret = cleanedEcalBremElems.equal_range(latestBrem_index);
655  multimap<unsigned int,unsigned int>::iterator it;
656  for(it=ret.first; it!=ret.second; ++it) {
657  GsfElemIndex.push_back((*it).second);
658  if (DebugSetLinksDetailed)
659  cout << "******************** Gsf Cluster From Brem " << (*it).second
660  << " Latest Brem index " << latestBrem_index
661  << " ************************* " << endl;
662  }
663  }
664  // erase the brem.
665  unsigned int elToErase = 0;
666  for(unsigned int i = 0; i<keyBremIndex.size();i++) {
667  if(latestBrem_index == keyBremIndex[i]) {
668  elToErase = i;
669  }
670  }
671  keyBremIndex.erase(keyBremIndex.begin()+elToErase);
672  }
673  }
674 
675  // Get Extra Clusters from converted brem gsf tracks. The locallock method
676  // tells me if the ecal cluster has been already assigned to the primary
677  // gsf track or to a brem
678 
679  for(unsigned int iConv=0; iConv<gsfIs.size(); iConv++) {
680  if(iConv != iEle) {
681 
682  const reco::PFBlockElementGsfTrack * gsfConv =
683  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[(gsfIs[iConv])]));
684 
685  // look at only to secondary gsf tracks
687  if (DebugSetLinksDetailed)
688  cout << " PFElectronAlgo:: I'm running on convGsfBrem " << endl;
689  // check if they are linked to the primary
690  float conv_dist = block.dist(gsfIs[iConv],gsfIs[iEle],
691  linkData,reco::PFBlock::LINKTEST_ALL);
692  if(conv_dist > 0.) {
693  // find the closest ecal cluster associated to conversions
694 
695  std::multimap<double, unsigned int> ecalConvElems;
696  block.associatedElements( gsfIs[iConv],linkData,
697  ecalConvElems,
700  if(ecalConvElems.size() > 0) {
701  // the ecal cluster is still active?
702  if(localactive[(ecalConvElems.begin()->second)] == true) {
703  if (DebugSetLinksDetailed)
704  cout << " PFElectronAlgo:: convGsfBrem has a ECAL cluster linked and free" << endl;
705  // Check that this cluster is not closer to another primary Gsf track
706  std::multimap<double, unsigned int> ecalOtherGsfPrimElems;
707  block.associatedElements( ecalConvElems.begin()->second,linkData,
708  ecalOtherGsfPrimElems,
711  if(ecalOtherGsfPrimElems.size()>0) {
712  unsigned int gsfprimcheck_index = ecalOtherGsfPrimElems.begin()->second;
713  const reco::PFBlockElementGsfTrack * gsfCheck =
714  dynamic_cast<const reco::PFBlockElementGsfTrack*>((&elements[gsfprimcheck_index]));
715  if(gsfCheck->trackType(reco::PFBlockElement::T_FROM_GAMMACONV) == false) continue;
716 
717  reco::PFClusterRef clusterRef = elements[ecalConvElems.begin()->second].clusterRef();
718  if (DebugSetLinksDetailed)
719  cout << " PFElectronAlgo: !!!!!!! convGsfBrem ECAL cluster has been stored !!!!!!! "
720  << " Energy " << clusterRef->energy() << " eta,phi " << clusterRef->position().eta()
721  <<", " << clusterRef->position().phi() << endl;
722 
723  GsfElemIndex.push_back(ecalConvElems.begin()->second);
724  convGsfTrack_.push_back(make_pair(ecalConvElems.begin()->second,gsfIs[iConv]));
725  localactive[ecalConvElems.begin()->second] = false;
726 
727  }
728  }
729  }
730  }
731  }
732  }
733  }
734 
735 
736 
737  EcalIndex.insert(EcalIndex.end(),GsfElemIndex.begin(),GsfElemIndex.end());
738 
739 
740 
741  // The BremMap
742  for(unsigned int i =0;i<keyBremIndex.size();i++) {
743  unsigned int ikey = keyBremIndex[i];
744  unsigned int ckey = cleanedEcalBremElems.count(ikey);
745  vector<unsigned int> BremElemIndex(0);
746  if(ckey == 1) {
747  unsigned int temp_cal =
748  cleanedEcalBremElems.find(ikey)->second;
749  BremElemIndex.push_back(temp_cal);
750  }
751  else{
752  pair<multimap<unsigned int,unsigned int>::iterator,multimap<unsigned int,unsigned int>::iterator> ret;
753  ret = cleanedEcalBremElems.equal_range(ikey);
754  multimap<unsigned int,unsigned int>::iterator it;
755  for(it=ret.first; it!=ret.second; ++it) {
756  BremElemIndex.push_back((*it).second);
757  }
758  }
759  EcalIndex.insert(EcalIndex.end(),BremElemIndex.begin(),BremElemIndex.end());
760  associatedToBrems_.insert(pair<unsigned int,vector<unsigned int> >(ikey,BremElemIndex));
761  }
762 
763 
764  // 19 Mar 2010: add KF and ECAL elements from converted brem photons
765  vector<unsigned int> convBremKFTrack;
766  convBremKFTrack.clear();
767  if (kfElems.size() > 0) {
768  for(std::multimap<double, unsigned int>::iterator itkf = kfElems.begin();
769  itkf != kfElems.end(); ++itkf) {
770  const reco::PFBlockElementTrack * TrkEl =
771  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[itkf->second]));
772  bool isPrim = isPrimaryTrack(*TrkEl,*GsfEl);
773 
774  if(!isPrim) {
775 
776  // search for linked ECAL clusters
777  std::multimap<double, unsigned int> ecalConvElems;
778  block.associatedElements( itkf->second,linkData,
779  ecalConvElems,
782  if(ecalConvElems.size() > 0) {
783  // Further Cleaning: DANIELE This could be improved!
784  TrackRef trkRef = TrkEl->trackRef();
785  // iter0, iter1, iter2, iter3 = Algo < 3
786  bool isGoodTrack = PFTrackAlgoTools::isGoodForEGM(trkRef->algo());
787  float secpin = trkRef->p();
788 
789  const reco::PFBlockElementCluster * clust =
790  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(ecalConvElems.begin()->second)]));
791  float eneclust =clust->clusterRef()->energy();
792 
793  //1) ******* Reject secondary KF tracks linked to also an HCAL cluster with H/(E+H) > 0.1
794  // This is applied also to KF linked to locked ECAL cluster
795  // NOTE: trusting the H/(E+H) and not the conv brem selection increse the number
796  // of charged hadrons around the electron. DANIELE? re-think about this.
797  std::multimap<double, unsigned int> hcalConvElems;
798  block.associatedElements( itkf->second,linkData,
799  hcalConvElems,
802 
803  bool isHoHE = false;
804  bool isHoE = false;
805  bool isPoHE = false;
806 
807  float enehcalclust = -1;
808  if(hcalConvElems.size() > 0) {
809  const reco::PFBlockElementCluster * clusthcal =
810  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(hcalConvElems.begin()->second)]));
811  enehcalclust =clusthcal->clusterRef()->energy();
812  // NOTE: DANIELE? Are you sure you want to use the Algo type here?
813  if( (enehcalclust / (enehcalclust+eneclust) ) > 0.1 && isGoodTrack) {
814  isHoHE = true;
815  if(enehcalclust > eneclust)
816  isHoE = true;
817  if(secpin > (enehcalclust+eneclust) )
818  isPoHE = true;
819  }
820  }
821 
822 
823  if(localactive[(ecalConvElems.begin()->second)] == false) {
824 
825  if(isHoE || isPoHE) {
826  if (DebugSetLinksDetailed)
827  cout << "PFElectronAlgo:: LOCKED ECAL REJECTED TRACK FOR H/E or P/(H+E) "
828  << " H/H+E " << enehcalclust/(enehcalclust+eneclust)
829  << " H/E " << enehcalclust/eneclust
830  << " P/(H+E) " << secpin/(enehcalclust+eneclust)
831  << " HCAL ENE " << enehcalclust
832  << " ECAL ENE " << eneclust
833  << " secPIN " << secpin
834  << " Algo Track " << trkRef->algo() << endl;
835  continue;
836  }
837 
838  // check if this track has been alread assigned to an ECAL cluster
839  for(unsigned int iecal =0; iecal < EcalIndex.size(); iecal++) {
840  // in case this track is already assigned to a locked ECAL cluster
841  // the secondary kf track is also saved for further lock
842  if(EcalIndex[iecal] == ecalConvElems.begin()->second) {
843  if (DebugSetLinksDetailed)
844  cout << " PFElectronAlgo:: Conv Brem Recovery locked cluster and I will lock also the KF track " << endl;
845  convBremKFTrack.push_back(itkf->second);
846  }
847  }
848  }
849  else{
850  // ECAL cluster free
851 
852  //
853  if(isHoHE){
854  if (DebugSetLinksDetailed)
855  cout << "PFElectronAlgo:: FREE ECAL REJECTED TRACK FOR H/H+E "
856  << " H/H+E " << (enehcalclust / (enehcalclust+eneclust) )
857  << " H/E " << enehcalclust/eneclust
858  << " P/(H+E) " << secpin/(enehcalclust+eneclust)
859  << " HCAL ENE " << enehcalclust
860  << " ECAL ENE " << eneclust
861  << " secPIN " << secpin
862  << " Algo Track " << trkRef->algo() << endl;
863  continue;
864  }
865 
866  // check that this cluster is not cluser to another KF track (primary)
867  std::multimap<double, unsigned int> ecalOtherKFPrimElems;
868  block.associatedElements( ecalConvElems.begin()->second,linkData,
869  ecalOtherKFPrimElems,
872  if(ecalOtherKFPrimElems.size() > 0) {
873 
874  // check that this ECAL clusters is the best associated to at least one of the KF tracks
875  // linked to the considered GSF track
876  bool isFromGSF = false;
877  for(std::multimap<double, unsigned int>::iterator itclos = kfElems.begin();
878  itclos != kfElems.end(); ++itclos) {
879  if(ecalOtherKFPrimElems.begin()->second == itclos->second) {
880  isFromGSF = true;
881  break;
882  }
883  }
884  if(isFromGSF){
885 
886  // Further Cleaning: DANIELE This could be improved!
887 
888 
889  float Epin = eneclust/secpin;
890 
891  // compute the pfsupercluster energy till now
892  float totenergy = 0.;
893  for(unsigned int ikeyecal = 0;
894  ikeyecal<EcalIndex.size(); ikeyecal++){
895  // EcalIndex can have the same cluster save twice (because of the late brem cluster).
896  bool foundcluster = false;
897  if(ikeyecal > 0) {
898  for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
899  if(EcalIndex[ikeyecal] == EcalIndex[i2])
900  foundcluster = true;
901  }
902  }
903  if(foundcluster) continue;
904  const reco::PFBlockElementCluster * clusasso =
905  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(EcalIndex[ikeyecal])]));
906  totenergy += clusasso->clusterRef()->energy();
907  }
908 
909  // Further Cleaning: DANIELE This could be improved!
910  //2) ***** Do not consider secondary tracks if the GSF and brems have failed in finding ECAL clusters
911  if(totenergy == 0.) {
912  if (DebugSetLinksDetailed)
913  cout << "PFElectronAlgo:: REJECTED_NULLTOT totenergy " << totenergy << endl;
914  continue;
915  }
916 
917  //3) ****** Reject secondary KF tracks that have an high E/secPin and that make worse the Etot/pin
918  if(Epin > 3) {
919  double res_before = fabs((totenergy-Pin_gsf)/Pin_gsf);
920  double res_after = fabs(((totenergy+eneclust)-Pin_gsf)/Pin_gsf);
921 
922  if(res_before < res_after) {
923  if (DebugSetLinksDetailed)
924  cout << "PFElectronAlgo::REJECTED_RES totenergy " << totenergy << " Pin_gsf " << Pin_gsf << " cluster to secondary " << eneclust
925  << " Res before " << res_before << " res_after " << res_after << endl;
926  continue;
927  }
928  }
929 
930  if (DebugSetLinksDetailed)
931  cout << "PFElectronAlgo:: conv brem found asso to ECAL linked to a secondary KF " << endl;
932  convBremKFTrack.push_back(itkf->second);
933  GsfElemIndex.push_back(ecalConvElems.begin()->second);
934  EcalIndex.push_back(ecalConvElems.begin()->second);
935  localactive[(ecalConvElems.begin()->second)] = false;
936  localactive[(itkf->second)] = false;
937  }
938  }
939  }
940  }
941  }
942  }
943  }
944 
945  // 4May import EG supercluster
946  if(EcalIndex.size() > 0 && useEGammaSupercluster_) {
947  double sumEtEcalInTheCone = 0.;
948 
949  // Position of the first cluster
950  const reco::PFBlockElementCluster * clust =
951  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[EcalIndex[0]]));
952  double PhiFC = clust->clusterRef()->position().Phi();
953  double EtaFC = clust->clusterRef()->position().Eta();
954 
955  // Compute ECAL isolation ->
956  for(unsigned int iEcal=0; iEcal<ecalIs.size(); iEcal++) {
957  bool foundcluster = false;
958  for(unsigned int ikeyecal = 0;
959  ikeyecal<EcalIndex.size(); ikeyecal++){
960  if(ecalIs[iEcal] == EcalIndex[ikeyecal])
961  foundcluster = true;
962  }
963 
964  // -> only for clusters not already in the PFSCCluster
965  if(foundcluster == false) {
966  const reco::PFBlockElementCluster * clustExt =
967  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[ecalIs[iEcal]]));
968  double eta_clust = clustExt->clusterRef()->position().Eta();
969  double phi_clust = clustExt->clusterRef()->position().Phi();
970  double theta_clust = clustExt->clusterRef()->position().Theta();
971  double deta_clust = eta_clust - EtaFC;
972  double dphi_clust = phi_clust - PhiFC;
973  if ( dphi_clust < -M_PI )
974  dphi_clust = dphi_clust + 2.*M_PI;
975  else if ( dphi_clust > M_PI )
976  dphi_clust = dphi_clust - 2.*M_PI;
977  double DR = sqrt(deta_clust*deta_clust+
978  dphi_clust*dphi_clust);
979 
980  //Jurassic veto in deta
981  if(fabs(deta_clust) > 0.05 && DR < coneEcalIsoForEgammaSC_) {
982  vector<double> ps1Ene(0);
983  vector<double> ps2Ene(0);
984  double ps1,ps2;
985  ps1=ps2=0.;
986  double EE_calib = thePFEnergyCalibration_->energyEm(*(clustExt->clusterRef()),ps1Ene,ps2Ene,ps1,ps2,applyCrackCorrections_);
987  double ET_calib = EE_calib*sin(theta_clust);
988  sumEtEcalInTheCone += ET_calib;
989  }
990  }
991  } //EndLoop Additional ECAL clusters in the block
992 
993  // Compute track isolation: number of tracks && sumPt
994  unsigned int sumNTracksInTheCone = 0;
995  double sumPtTracksInTheCone = 0.;
996  for(unsigned int iTrack=0; iTrack<trackIs.size(); iTrack++) {
997  // the track from the electron are already locked at this stage
998  if(localactive[(trackIs[iTrack])]==true) {
999  const reco::PFBlockElementTrack * kfEle =
1000  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[(trackIs[iTrack])]));
1001  reco::TrackRef trkref = kfEle->trackRef();
1002  if (trkref.isNonnull()) {
1003  double deta_trk = trkref->eta() - RefGSF->etaMode();
1004  double dphi_trk = trkref->phi() - RefGSF->phiMode();
1005  if ( dphi_trk < -M_PI )
1006  dphi_trk = dphi_trk + 2.*M_PI;
1007  else if ( dphi_trk > M_PI )
1008  dphi_trk = dphi_trk - 2.*M_PI;
1009  double DR = sqrt(deta_trk*deta_trk+
1010  dphi_trk*dphi_trk);
1011 
1012  int NValPixelHit = trkref->hitPattern().numberOfValidPixelHits();
1013 
1014  if(DR < coneTrackIsoForEgammaSC_ && NValPixelHit >=3) {
1015  sumNTracksInTheCone++;
1016  sumPtTracksInTheCone+=trkref->pt();
1017  }
1018  }
1019  }
1020  }
1021 
1022 
1023  bool isBarrelIsolated = false;
1024  if( fabs(EtaFC < 1.478) &&
1025  (sumEtEcalInTheCone < sumEtEcalIsoForEgammaSC_barrel_ &&
1026  (sumNTracksInTheCone < nTrackIsoForEgammaSC_ || sumPtTracksInTheCone < sumPtTrackIsoForEgammaSC_barrel_)))
1027  isBarrelIsolated = true;
1028 
1029 
1030  bool isEndcapIsolated = false;
1031  if( fabs(EtaFC >= 1.478) &&
1032  (sumEtEcalInTheCone < sumEtEcalIsoForEgammaSC_endcap_ &&
1033  (sumNTracksInTheCone < nTrackIsoForEgammaSC_ || sumPtTracksInTheCone < sumPtTrackIsoForEgammaSC_endcap_)))
1034  isEndcapIsolated = true;
1035 
1036 
1037  // only print out
1038  if(DebugSetLinksDetailed) {
1039  if(fabs(EtaFC < 1.478) && isBarrelIsolated == false) {
1040  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS ISOLATION:BARREL *** "
1041  << " sumEtEcalInTheCone " <<sumEtEcalInTheCone
1042  << " sumNTracksInTheCone " << sumNTracksInTheCone
1043  << " sumPtTracksInTheCone " << sumPtTracksInTheCone << endl;
1044  }
1045  if(fabs(EtaFC >= 1.478) && isEndcapIsolated == false) {
1046  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS ISOLATION:ENDCAP *** "
1047  << " sumEtEcalInTheCone " <<sumEtEcalInTheCone
1048  << " sumNTracksInTheCone " << sumNTracksInTheCone
1049  << " sumPtTracksInTheCone " << sumPtTracksInTheCone << endl;
1050  }
1051  }
1052 
1053 
1054 
1055 
1056  if(isBarrelIsolated || isEndcapIsolated ) {
1057 
1058 
1059  // Compute TotEnergy
1060  double totenergy = 0.;
1061  for(unsigned int ikeyecal = 0;
1062  ikeyecal<EcalIndex.size(); ikeyecal++){
1063  // EcalIndex can have the same cluster save twice (because of the late brem cluster).
1064  bool foundcluster = false;
1065  if(ikeyecal > 0) {
1066  for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
1067  if(EcalIndex[ikeyecal] == EcalIndex[i2])
1068  foundcluster = true;;
1069  }
1070  }
1071  if(foundcluster) continue;
1072  const reco::PFBlockElementCluster * clusasso =
1073  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[(EcalIndex[ikeyecal])]));
1074  totenergy += clusasso->clusterRef()->energy();
1075  }
1076  // End copute TotEnergy
1077 
1078 
1079  // Find extra cluster from e/g importing
1080  for(unsigned int ikeyecal = 0;
1081  ikeyecal<EcalIndex.size(); ikeyecal++){
1082  // EcalIndex can have the same cluster save twice (because of the late brem cluster).
1083  bool foundcluster = false;
1084  if(ikeyecal > 0) {
1085  for(unsigned int i2 = 0; i2<ikeyecal-1; i2++) {
1086  if(EcalIndex[ikeyecal] == EcalIndex[i2])
1087  foundcluster = true;
1088  }
1089  }
1090  if(foundcluster) continue;
1091 
1092 
1093  std::multimap<double, unsigned int> ecalFromSuperClusterElems;
1094  block.associatedElements( EcalIndex[ikeyecal],linkData,
1095  ecalFromSuperClusterElems,
1098  if(ecalFromSuperClusterElems.size() > 0) {
1099  for(std::multimap<double, unsigned int>::iterator itsc = ecalFromSuperClusterElems.begin();
1100  itsc != ecalFromSuperClusterElems.end(); ++itsc) {
1101  if(localactive[itsc->second] == false) {
1102  continue;
1103  }
1104 
1105  std::multimap<double, unsigned int> ecalOtherKFPrimElems;
1106  block.associatedElements( itsc->second,linkData,
1107  ecalOtherKFPrimElems,
1108  reco::PFBlockElement::TRACK,
1110  if(ecalOtherKFPrimElems.size() > 0) {
1111  if(localactive[ecalOtherKFPrimElems.begin()->second] == true) {
1112  if (DebugSetLinksDetailed)
1113  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS KF VETO *** " << endl;
1114  continue;
1115  }
1116  }
1117  bool isInTheEtaRange = false;
1118  const reco::PFBlockElementCluster * clustToAdd =
1119  dynamic_cast<const reco::PFBlockElementCluster*>((&elements[itsc->second]));
1120  double deta_clustToAdd = clustToAdd->clusterRef()->position().Eta() - EtaFC;
1121  double ene_clustToAdd = clustToAdd->clusterRef()->energy();
1122 
1123  if(fabs(deta_clustToAdd) < 0.05)
1124  isInTheEtaRange = true;
1125 
1126  // check for both KF and GSF
1127  bool isBetterEpin = false;
1128  if(isInTheEtaRange == false ) {
1129  if (DebugSetLinksDetailed)
1130  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND BUT FAILS GAMMA DETA RANGE *** "
1131  << fabs(deta_clustToAdd) << endl;
1132 
1133  if(KfGsf_index < CutIndex) {
1134  //GSF
1135  double res_before_gsf = fabs((totenergy-Pin_gsf)/Pin_gsf);
1136  double res_after_gsf = fabs(((totenergy+ene_clustToAdd)-Pin_gsf)/Pin_gsf);
1137 
1138  //KF
1139  const reco::PFBlockElementTrack * trackEl =
1140  dynamic_cast<const reco::PFBlockElementTrack*>((&elements[KfGsf_index]));
1141  double Pin_kf = trackEl->trackRef()->p();
1142  double res_before_kf = fabs((totenergy-Pin_kf)/Pin_kf);
1143  double res_after_kf = fabs(((totenergy+ene_clustToAdd)-Pin_kf)/Pin_kf);
1144 
1145  // The new cluster improve both the E/pin?
1146  if(res_after_gsf < res_before_gsf && res_after_kf < res_before_kf ) {
1147  isBetterEpin = true;
1148  }
1149  else {
1150  if (DebugSetLinksDetailed)
1151  cout << "**** PFElectronAlgo:: SUPERCLUSTER FOUND AND FAILS ALSO RES_EPIN"
1152  << " tot energy " << totenergy
1153  << " Pin_gsf " << Pin_gsf
1154  << " Pin_kf " << Pin_kf
1155  << " cluster from SC to ADD " << ene_clustToAdd
1156  << " Res before GSF " << res_before_gsf << " res_after_gsf " << res_after_gsf
1157  << " Res before KF " << res_before_kf << " res_after_kf " << res_after_kf << endl;
1158  }
1159  }
1160  }
1161 
1162  if(isInTheEtaRange || isBetterEpin) {
1163  if (DebugSetLinksDetailed)
1164  cout << "!!!! PFElectronAlgo:: ECAL from SUPERCLUSTER FOUND !!!!! " << endl;
1165  GsfElemIndex.push_back(itsc->second);
1166  EcalIndex.push_back(itsc->second);
1167  localactive[(itsc->second)] = false;
1168  }
1169  }
1170  }
1171  }
1172  } // END ISOLATION IF
1173  }
1174 
1175 
1176  if(KfGsf_index < CutIndex)
1177  GsfElemIndex.push_back(KfGsf_index);
1178  else if(KfGsf_secondIndex < CutIndex)
1179  GsfElemIndex.push_back(KfGsf_secondIndex);
1180 
1181  // insert the secondary KF tracks
1182  GsfElemIndex.insert(GsfElemIndex.end(),convBremKFTrack.begin(),convBremKFTrack.end());
1183  GsfElemIndex.insert(GsfElemIndex.end(),keyBremIndex.begin(),keyBremIndex.end());
1184  associatedToGsf_.insert(pair<unsigned int, vector<unsigned int> >(gsfIs[iEle],GsfElemIndex));
1185 
1186  // The EcalMap
1187  for(unsigned int ikeyecal = 0;
1188  ikeyecal<EcalIndex.size(); ikeyecal++){
1189 
1190 
1191  vector<unsigned int> EcalElemsIndex(0);
1192 
1193  std::multimap<double, unsigned int> PS1Elems;
1194  block.associatedElements( EcalIndex[ikeyecal],linkData,
1195  PS1Elems,
1198  for( std::multimap<double, unsigned int>::iterator it = PS1Elems.begin();
1199  it != PS1Elems.end();it++) {
1200  unsigned int index = it->second;
1201  if(localactive[index] == true) {
1202 
1203  // Check that this cluster is not closer to another ECAL cluster
1204  std::multimap<double, unsigned> sortedECAL;
1205  block.associatedElements( index, linkData,
1206  sortedECAL,
1209  unsigned jEcal = sortedECAL.begin()->second;
1210  if ( jEcal != EcalIndex[ikeyecal]) continue;
1211 
1212 
1213  EcalElemsIndex.push_back(index);
1214  localactive[index] = false;
1215  }
1216  }
1217 
1218  std::multimap<double, unsigned int> PS2Elems;
1219  block.associatedElements( EcalIndex[ikeyecal],linkData,
1220  PS2Elems,
1223  for( std::multimap<double, unsigned int>::iterator it = PS2Elems.begin();
1224  it != PS2Elems.end();it++) {
1225  unsigned int index = it->second;
1226  if(localactive[index] == true) {
1227  // Check that this cluster is not closer to another ECAL cluster
1228  std::multimap<double, unsigned> sortedECAL;
1229  block.associatedElements( index, linkData,
1230  sortedECAL,
1233  unsigned jEcal = sortedECAL.begin()->second;
1234  if ( jEcal != EcalIndex[ikeyecal]) continue;
1235 
1236  EcalElemsIndex.push_back(index);
1237  localactive[index] = false;
1238  }
1239  }
1240  if(ikeyecal == 0) {
1241  // The first cluster is that one coming from the Gsf.
1242  // Only for this one is found the HCAL cluster using the Track-HCAL link
1243  // and not the Ecal-Hcal not well tested yet.
1244  std::multimap<double, unsigned int> hcalGsfElems;
1245  block.associatedElements( gsfIs[iEle],linkData,
1246  hcalGsfElems,
1249  for( std::multimap<double, unsigned int>::iterator it = hcalGsfElems.begin();
1250  it != hcalGsfElems.end();it++) {
1251  unsigned int index = it->second;
1252  // if(localactive[index] == true) {
1253 
1254  // Check that this cluster is not closer to another GSF
1255  // remove in high energetic jets this is dangerous.
1256 // std::multimap<double, unsigned> sortedGsf;
1257 // block.associatedElements( index, linkData,
1258 // sortedGsf,
1259 // reco::PFBlockElement::GSF,
1260 // reco::PFBlock::LINKTEST_ALL );
1261 // unsigned jGsf = sortedGsf.begin()->second;
1262 // if ( jGsf != gsfIs[iEle]) continue;
1263 
1264  EcalElemsIndex.push_back(index);
1265  localactive[index] = false;
1266 
1267  // }
1268  }
1269  // if the closest ecal cluster has been link with the KF, check KF - HCAL link
1270  if(hcalGsfElems.size() == 0 && ClosestEcalWithKf == true) {
1271  std::multimap<double, unsigned int> hcalKfElems;
1272  block.associatedElements( KfGsf_index,linkData,
1273  hcalKfElems,
1276  for( std::multimap<double, unsigned int>::iterator it = hcalKfElems.begin();
1277  it != hcalKfElems.end();it++) {
1278  unsigned int index = it->second;
1279  if(localactive[index] == true) {
1280 
1281  // Check that this cluster is not closer to another KF
1282  std::multimap<double, unsigned> sortedKf;
1283  block.associatedElements( index, linkData,
1284  sortedKf,
1285  reco::PFBlockElement::TRACK,
1287  unsigned jKf = sortedKf.begin()->second;
1288  if ( jKf != KfGsf_index) continue;
1289  EcalElemsIndex.push_back(index);
1290  localactive[index] = false;
1291  }
1292  }
1293  }
1294  // Find Other Primary Tracks Associated to the same Gsf Clusters
1295  std::multimap<double, unsigned int> kfEtraElems;
1296  block.associatedElements( EcalIndex[ikeyecal],linkData,
1297  kfEtraElems,
1298  reco::PFBlockElement::TRACK,
1300  if(kfEtraElems.size() > 0) {
1301  for( std::multimap<double, unsigned int>::iterator it = kfEtraElems.begin();
1302  it != kfEtraElems.end();it++) {
1303  unsigned int index = it->second;
1304 
1305  // 19 Mar 2010 do not consider here tracks from gamma conv
1306  // const reco::PFBlockElementTrack * kfTk =
1307  // dynamic_cast<const reco::PFBlockElementTrack*>((&elements[index]));
1308  // DANIELE ? It is not need because of the local locking
1309  // if(kfTk->isLinkedToDisplacedVertex()) continue;
1310 
1311  bool thisIsAMuon = false;
1312  thisIsAMuon = PFMuonAlgo::isMuon(elements[index]);
1313  if (DebugSetLinksDetailed && thisIsAMuon)
1314  cout << " This is a Muon: index " << index << endl;
1315  if(localactive[index] == true && !thisIsAMuon) {
1316  if(index != KfGsf_index) {
1317  // Check that this track is not closer to another ECAL cluster
1318  // Not Sure here I need this step
1319  std::multimap<double, unsigned> sortedECAL;
1320  block.associatedElements( index, linkData,
1321  sortedECAL,
1324  unsigned jEcal = sortedECAL.begin()->second;
1325  if ( jEcal != EcalIndex[ikeyecal]) continue;
1326  EcalElemsIndex.push_back(index);
1327  localactive[index] = false;
1328  }
1329  }
1330  }
1331  }
1332 
1333  }
1334  associatedToEcal_.insert(pair<unsigned int,vector<unsigned int> >(EcalIndex[ikeyecal],EcalElemsIndex));
1335  }
1336  }// end type GSF
1337  } // endis there a gsf track
1338 
1339  // ******************* End Link *****************************
1340 
1341  //
1342  // Below is only for debugging printout
1343  if (DebugSetLinksSummary) {
1344  if(IsThereAGoodGSFTrack) {
1345  if (DebugSetLinksSummary) cout << " -- The Link Summary --" << endl;
1346  for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToGsf_.begin();
1347  it != associatedToGsf_.end(); it++) {
1348 
1349  if (DebugSetLinksSummary) cout << " AssoGsf " << it->first << endl;
1350  vector<unsigned int> eleasso = it->second;
1351  for(unsigned int i=0;i<eleasso.size();i++) {
1352  PFBlockElement::Type type = elements[eleasso[i]].type();
1353  if(type == reco::PFBlockElement::BREM) {
1354  if (DebugSetLinksSummary)
1355  cout << " AssoGsfElements BREM " << eleasso[i] << endl;
1356  }
1357  else if(type == reco::PFBlockElement::ECAL) {
1358  if (DebugSetLinksSummary)
1359  cout << " AssoGsfElements ECAL " << eleasso[i] << endl;
1360  }
1361  else if(type == reco::PFBlockElement::TRACK) {
1362  if (DebugSetLinksSummary)
1363  cout << " AssoGsfElements KF " << eleasso[i] << endl;
1364  }
1365  else {
1366  if (DebugSetLinksSummary)
1367  cout << " AssoGsfElements ????? " << eleasso[i] << endl;
1368  }
1369  }
1370  }
1371 
1372  for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToBrems_.begin();
1373  it != associatedToBrems_.end(); it++) {
1374  if (DebugSetLinksSummary) cout << " AssoBrem " << it->first << endl;
1375  vector<unsigned int> eleasso = it->second;
1376  for(unsigned int i=0;i<eleasso.size();i++) {
1377  PFBlockElement::Type type = elements[eleasso[i]].type();
1378  if(type == reco::PFBlockElement::ECAL) {
1379  if (DebugSetLinksSummary)
1380  cout << " AssoBremElements ECAL " << eleasso[i] << endl;
1381  }
1382  else {
1383  if (DebugSetLinksSummary)
1384  cout << " AssoBremElements ????? " << eleasso[i] << endl;
1385  }
1386  }
1387  }
1388 
1389  for(map<unsigned int,vector<unsigned int> >::iterator it = associatedToEcal_.begin();
1390  it != associatedToEcal_.end(); it++) {
1391  if (DebugSetLinksSummary) cout << " AssoECAL " << it->first << endl;
1392  vector<unsigned int> eleasso = it->second;
1393  for(unsigned int i=0;i<eleasso.size();i++) {
1394  PFBlockElement::Type type = elements[eleasso[i]].type();
1395  if(type == reco::PFBlockElement::PS1) {
1396  if (DebugSetLinksSummary)
1397  cout << " AssoECALElements PS1 " << eleasso[i] << endl;
1398  }
1399  else if(type == reco::PFBlockElement::PS2) {
1400  if (DebugSetLinksSummary)
1401  cout << " AssoECALElements PS2 " << eleasso[i] << endl;
1402  }
1403  else if(type == reco::PFBlockElement::HCAL) {
1404  if (DebugSetLinksSummary)
1405  cout << " AssoECALElements HCAL " << eleasso[i] << endl;
1406  }
1407  else {
1408  if (DebugSetLinksSummary)
1409  cout << " AssoHCALElements ????? " << eleasso[i] << endl;
1410  }
1411  }
1412  }
1413  if (DebugSetLinksSummary)
1414  cout << "-- End Summary --" << endl;
1415  }
1416 
1417  }
1418  // EndPrintOut
1419  return IsThereAGoodGSFTrack;
1420 }
std::vector< std::pair< unsigned int, unsigned int > > fifthStepKfTrack_
type
Definition: HCALResponse.h:21
const math::XYZTLorentzVector & Pout() const
const math::XYZPointF & positionAtECALEntrance() const
int i
Definition: DBlmapReader.cc:9
const reco::TrackRef & trackRef() const
tuple ret
prodAgent to be discontinued
const reco::GsfTrackRef & GsftrackRef() const
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
trackRef_iterator tracks_end() const
last iterator over tracks
Definition: Vertex.cc:44
static bool isMuon(const reco::PFBlockElement &elt)
Definition: PFMuonAlgo.cc:155
std::vector< std::pair< unsigned int, unsigned int > > convGsfTrack_
const math::XYZPointF & positionAtECALEntrance() const
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:264
bool isPrimaryTrack(const reco::PFBlockElementTrack &KfEl, const reco::PFBlockElementGsfTrack &GsfEl)
const PFClusterRef & clusterRef() const
const edm::OwnVector< reco::PFBlockElement > & elements() const
Definition: PFBlock.h:107
const LinkData & linkData() const
Definition: PFBlock.h:112
unsigned int indTrajPoint() const
int ii
Definition: cuy.py:588
double coneEcalIsoForEgammaSC_
dictionary elements
bool isGoodForEGM(const reco::TrackBase::TrackAlgorithm &)
T sqrt(T t)
Definition: SSEVec.h:18
double sumEtEcalIsoForEgammaSC_barrel_
double sumEtEcalIsoForEgammaSC_endcap_
virtual bool trackType(TrackType trType) const
#define M_PI
double sumPtTrackIsoForEgammaSC_endcap_
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
std::vector< TrackBaseRef >::const_iterator trackRef_iterator
The iteratator for the vector&lt;TrackRef&gt;
Definition: Vertex.h:37
double sumPtTrackIsoForEgammaSC_barrel_
tuple cout
Definition: gather_cfg.py:145
double dist(unsigned ie1, unsigned ie2, const LinkData &linkData, LinkTest test) const
Definition: PFBlock.h:94
trackRef_iterator tracks_begin() const
first iterator over tracks
Definition: Vertex.cc:39
unsigned int nTrackIsoForEgammaSC_
void insert(const_iterator i, D *&d)
Definition: OwnVector.h:361
boost::shared_ptr< PFEnergyCalibration > thePFEnergyCalibration_
bool applyCrackCorrections_
bool useEGammaSupercluster_
Block of elements.
Definition: PFBlock.h:30

Member Data Documentation

std::vector<reco::PFCandidate> PFElectronAlgo::allElCandidate_
private

Definition at line 113 of file PFElectronAlgo.h.

Referenced by getAllElectronCandidates(), RunPFElectron(), and SetCandidates().

bool PFElectronAlgo::applyCrackCorrections_
private

Definition at line 127 of file PFElectronAlgo.h.

Referenced by SetCandidates(), SetIDOutputs(), and SetLinks().

std::vector<double> PFElectronAlgo::BDToutput_
private

Definition at line 115 of file PFElectronAlgo.h.

Referenced by RunPFElectron(), SetActive(), SetCandidates(), and SetIDOutputs().

float PFElectronAlgo::chi2_gsf
private

Definition at line 146 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

float PFElectronAlgo::chi2_kf
private

Definition at line 146 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

double PFElectronAlgo::coneEcalIsoForEgammaSC_
private

Definition at line 133 of file PFElectronAlgo.h.

Referenced by SetLinks().

double PFElectronAlgo::coneTrackIsoForEgammaSC_
private

Definition at line 137 of file PFElectronAlgo.h.

std::vector< std::pair <unsigned int, unsigned int> > PFElectronAlgo::convGsfTrack_
private

Definition at line 120 of file PFElectronAlgo.h.

Referenced by RunPFElectron(), SetActive(), and SetLinks().

float PFElectronAlgo::DEtaGsfEcalClust
private

Definition at line 153 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

float PFElectronAlgo::dPtOverPt_gsf
private

Definition at line 146 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

float PFElectronAlgo::DPtOverPt_gsf
private

Definition at line 146 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

float PFElectronAlgo::DPtOverPt_kf
private

Definition at line 146 of file PFElectronAlgo.h.

Referenced by SetIDOutputs().

float PFElectronAlgo::earlyBrem
private

Definition at line 156 of file PFElectronAlgo.h.

Referenced by SetIDOutputs().

float PFElectronAlgo::EGsfPoutMode
private

Definition at line 152 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

std::vector<reco::PFCandidate> PFElectronAlgo::elCandidate_
private

Definition at line 112 of file PFElectronAlgo.h.

Referenced by getElectronCandidates(), RunPFElectron(), and SetCandidates().

std::map<unsigned int,std::vector<reco::PFCandidate> > PFElectronAlgo::electronConstituents_
private

Definition at line 114 of file PFElectronAlgo.h.

Referenced by RunPFElectron(), and SetCandidates().

std::vector<reco::PFCandidateElectronExtra > PFElectronAlgo::electronExtra_
private

Definition at line 116 of file PFElectronAlgo.h.

Referenced by getElectronExtra(), RunPFElectron(), SetCandidates(), and SetIDOutputs().

float PFElectronAlgo::Eta_gsf
private

Definition at line 143 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

float PFElectronAlgo::EtotBremPinPoutMode
private

Definition at line 152 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

float PFElectronAlgo::EtotPinMode
private

Definition at line 152 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

std::vector< std::pair <unsigned int, unsigned int> > PFElectronAlgo::fifthStepKfTrack_
private

Definition at line 119 of file PFElectronAlgo.h.

Referenced by RunPFElectron(), SetActive(), and SetLinks().

float PFElectronAlgo::firstBrem
private

Definition at line 156 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

std::vector<bool> PFElectronAlgo::GsfTrackSingleEcal_
private

Definition at line 118 of file PFElectronAlgo.h.

float PFElectronAlgo::HOverHE
private

Definition at line 157 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

float PFElectronAlgo::HOverPin
private

Definition at line 157 of file PFElectronAlgo.h.

Referenced by SetIDOutputs().

bool PFElectronAlgo::isvalid_
private

Definition at line 159 of file PFElectronAlgo.h.

Referenced by isElectronValidCandidate(), and RunPFElectron().

float PFElectronAlgo::lateBrem
private

Definition at line 156 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

float PFElectronAlgo::lnPt_gsf
private

Definition at line 143 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

std::vector<bool> PFElectronAlgo::lockExtraKf_
private

Definition at line 117 of file PFElectronAlgo.h.

Referenced by RunPFElectron(), SetActive(), and SetIDOutputs().

double PFElectronAlgo::mvaEleCut_
private

Definition at line 124 of file PFElectronAlgo.h.

Referenced by SetActive(), SetCandidates(), and SetIDOutputs().

const char* PFElectronAlgo::mvaWeightFile_
private

Definition at line 139 of file PFElectronAlgo.h.

float PFElectronAlgo::nhit_gsf
private

Definition at line 149 of file PFElectronAlgo.h.

Referenced by SetCandidates(), and SetIDOutputs().

float PFElectronAlgo::nhit_kf
private

Definition at line 149 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), SetCandidates(), and SetIDOutputs().

unsigned int PFElectronAlgo::nTrackIsoForEgammaSC_
private

Definition at line 136 of file PFElectronAlgo.h.

Referenced by SetLinks().

float PFElectronAlgo::SigmaEtaEta
private

Definition at line 154 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), and SetIDOutputs().

double PFElectronAlgo::sumEtEcalIsoForEgammaSC_barrel_
private

Definition at line 131 of file PFElectronAlgo.h.

Referenced by SetLinks().

double PFElectronAlgo::sumEtEcalIsoForEgammaSC_endcap_
private

Definition at line 132 of file PFElectronAlgo.h.

Referenced by SetLinks().

double PFElectronAlgo::sumPtTrackIsoForEgammaSC_barrel_
private

Definition at line 134 of file PFElectronAlgo.h.

Referenced by SetLinks().

double PFElectronAlgo::sumPtTrackIsoForEgammaSC_endcap_
private

Definition at line 135 of file PFElectronAlgo.h.

Referenced by SetLinks().

const std::vector<reco::GsfElectron>* PFElectronAlgo::theGsfElectrons_
private

Definition at line 161 of file PFElectronAlgo.h.

Referenced by SetActive(), SetCandidates(), and setEGElectronCollection().

boost::shared_ptr<PFEnergyCalibration> PFElectronAlgo::thePFEnergyCalibration_
private

Definition at line 126 of file PFElectronAlgo.h.

Referenced by SetCandidates(), SetIDOutputs(), and SetLinks().

boost::shared_ptr<PFSCEnergyCalibration> PFElectronAlgo::thePFSCEnergyCalibration_
private

Definition at line 125 of file PFElectronAlgo.h.

Referenced by SetCandidates().

TMVA::Reader* PFElectronAlgo::tmvaReader_
private

Definition at line 123 of file PFElectronAlgo.h.

Referenced by PFElectronAlgo(), SetIDOutputs(), and ~PFElectronAlgo().

bool PFElectronAlgo::useEGammaSupercluster_
private

Definition at line 130 of file PFElectronAlgo.h.

Referenced by SetLinks().

bool PFElectronAlgo::useEGElectrons_
private

Definition at line 129 of file PFElectronAlgo.h.

Referenced by SetActive(), and SetCandidates().

bool PFElectronAlgo::usePFSCEleCalib_
private

Definition at line 128 of file PFElectronAlgo.h.

Referenced by SetCandidates().