00001 #include "DataFormats/EgammaCandidates/interface/GsfElectron.h"
00002 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
00003 #include "DataFormats/EgammaReco/interface/BasicCluster.h"
00004 #include "DataFormats/EgammaReco/interface/BasicClusterFwd.h"
00005
00006 using namespace reco ;
00007
00008 GsfElectronCoreRef GsfElectron::core() const { return core_ ; }
00009
00010 void GsfElectron::init()
00011 {
00012 passCutBasedPreselection_ = false ;
00013 passMvaPreslection_ = false ;
00014 ambiguous_ = true ;
00015 fbrem_ = 0 ;
00016 class_ = UNKNOWN ;
00017 }
00018
00019 GsfElectron::GsfElectron()
00020 { init() ; }
00021
00022 GsfElectron::GsfElectron( const GsfElectronCoreRef & core )
00023 : core_(core)
00024 { init() ; }
00025
00026 GsfElectron::GsfElectron
00027 ( int charge, const ChargeInfo & chargeInfo,
00028 const GsfElectronCoreRef & core,
00029 const TrackClusterMatching & tcm, const TrackExtrapolations & te,
00030 const ClosestCtfTrack & ctfInfo,
00031 const FiducialFlags & ff, const ShowerShape & ss,
00032 const ConversionRejection & crv,
00033 float fbrem
00034 )
00035 : chargeInfo_(chargeInfo),
00036 core_(core),
00037 trackClusterMatching_(tcm), trackExtrapolations_(te),
00038
00039 fiducialFlags_(ff), showerShape_(ss), conversionRejection_(crv)
00040 {
00041 init() ;
00042 fbrem_ = fbrem ;
00043 setCharge(charge) ;
00044 setVertex(math::XYZPoint(te.positionAtVtx.x(),te.positionAtVtx.y(),te.positionAtVtx.z())) ;
00045 setPdgId(-11*charge) ;
00046 corrections_.ecalEnergy = superCluster()->energy() ;
00047 assert(ctfInfo.ctfTrack==(GsfElectron::core()->ctfTrack())) ;
00048 assert(ctfInfo.shFracInnerHits==(GsfElectron::core()->ctfGsfOverlap())) ;
00049 }
00050
00051 GsfElectron::GsfElectron
00052 ( const GsfElectron & electron,
00053 const GsfElectronCoreRef & core )
00054 : RecoCandidate(electron),
00055 chargeInfo_(electron.chargeInfo_),
00056 core_(core),
00057 trackClusterMatching_(electron.trackClusterMatching_),
00058 trackExtrapolations_(electron.trackExtrapolations_),
00059
00060 fiducialFlags_(electron.fiducialFlags_),
00061 showerShape_(electron.showerShape_),
00062 dr03_(electron.dr03_), dr04_(electron.dr04_),
00063 conversionRejection_(electron.conversionRejection_),
00064 passCutBasedPreselection_(electron.passCutBasedPreselection_),
00065 passMvaPreslection_(electron.passMvaPreslection_),
00066 ambiguous_(electron.ambiguous_),
00067 ambiguousGsfTracks_(electron.ambiguousGsfTracks_),
00068
00069 fbrem_(electron.fbrem_),
00070 class_(electron.class_),
00071 corrections_(electron.corrections_)
00072 {
00073 assert(electron.core()->ctfTrack()==core->ctfTrack()) ;
00074 assert(electron.core()->ctfGsfOverlap()==core->ctfGsfOverlap()) ;
00075 }
00076
00077 GsfElectron::GsfElectron
00078 ( const GsfElectron & electron,
00079 const GsfElectronCoreRef & core,
00080 const CaloClusterPtr & electronCluster,
00081 const TrackRef & closestCtfTrack,
00082 const TrackBaseRef & conversionPartner,
00083 const GsfTrackRefVector & ambiguousTracks )
00084 : RecoCandidate(electron),
00085 chargeInfo_(electron.chargeInfo_),
00086 core_(core),
00087 trackClusterMatching_(electron.trackClusterMatching_),
00088 trackExtrapolations_(electron.trackExtrapolations_),
00089
00090 fiducialFlags_(electron.fiducialFlags_),
00091 showerShape_(electron.showerShape_),
00092 dr03_(electron.dr03_), dr04_(electron.dr04_),
00093 conversionRejection_(electron.conversionRejection_),
00094 passCutBasedPreselection_(electron.passCutBasedPreselection_),
00095 passMvaPreslection_(electron.passMvaPreslection_),
00096 ambiguous_(electron.ambiguous_),
00097 ambiguousGsfTracks_(ambiguousTracks),
00098
00099 fbrem_(electron.fbrem_),
00100 class_(electron.class_),
00101 corrections_(electron.corrections_)
00102 {
00103 trackClusterMatching_.electronCluster = electronCluster ;
00104
00105 conversionRejection_.partner = conversionPartner ;
00106 assert(closestCtfTrack==core->ctfTrack()) ;
00107 assert(electron.core()->ctfGsfOverlap()==core->ctfGsfOverlap()) ;
00108
00109
00110
00111
00112
00113
00114
00115
00116 }
00117
00118 bool GsfElectron::overlap( const Candidate & c ) const {
00119 const RecoCandidate * o = dynamic_cast<const RecoCandidate *>( & c );
00120 return ( o != 0 &&
00121 ( checkOverlap( gsfTrack(), o->gsfTrack() ) ||
00122 checkOverlap( superCluster(), o->superCluster() ) )
00123 );
00124
00125 }
00126
00127 GsfElectron * GsfElectron::clone() const
00128 { return new GsfElectron(*this) ; }
00129
00130 GsfElectron * GsfElectron::clone
00131 (
00132 const GsfElectronCoreRef & core,
00133 const CaloClusterPtr & electronCluster,
00134 const TrackRef & closestCtfTrack,
00135 const TrackBaseRef & conversionPartner,
00136 const GsfTrackRefVector & ambiguousTracks
00137 ) const
00138 { return new GsfElectron(*this,core,electronCluster,closestCtfTrack,conversionPartner,ambiguousTracks) ; }
00139
00140 bool GsfElectron::ecalDriven() const
00141 {
00142 if (!passingCutBasedPreselection()&&!passingMvaPreselection())
00143 {
00144 edm::LogWarning("GsfElectronAlgo|UndefinedPreselectionInfo")
00145 <<"All preselection flags are false,"
00146 <<" either the data is too old or electrons were not preselected." ;
00147 }
00148 return (ecalDrivenSeed()&&passingCutBasedPreselection()) ;
00149 }
00150
00151 void GsfElectron::setCorrectedEcalEnergy( float newEnergy, float newEnergyError )
00152 {
00153 math::XYZTLorentzVectorD momentum = p4() ;
00154 momentum *= newEnergy/momentum.e() ;
00155 setP4(momentum) ;
00156 showerShape_.hcalDepth1OverEcal *= corrections_.ecalEnergy/newEnergy ;
00157 showerShape_.hcalDepth2OverEcal *= corrections_.ecalEnergy/newEnergy ;
00158 trackClusterMatching_.eSuperClusterOverP *= newEnergy/corrections_.ecalEnergy ;
00159 trackClusterMatching_.eSeedClusterOverP *= newEnergy/corrections_.ecalEnergy ;
00160 trackClusterMatching_.eEleClusterOverPout *= newEnergy/corrections_.ecalEnergy ;
00161 corrections_.ecalEnergy = newEnergy ;
00162 corrections_.ecalEnergyError = newEnergyError ;
00163 corrections_.isEcalEnergyCorrected = true ;
00164 }
00165
00166 void GsfElectron::setTrackMomentumError( float trackErr )
00167 { corrections_.trackMomentumError = trackErr ; }
00168
00169 void GsfElectron::setP4
00170 ( P4Kind kind, const reco::Candidate::LorentzVector & p4, float error, bool setCandidate )
00171 {
00172 switch(kind)
00173 {
00174 case P4_FROM_SUPER_CLUSTER:
00175 corrections_.fromSuperClusterP4 = p4 ;
00176 corrections_.fromSuperClusterP4Error = error ;
00177 break ;
00178 case P4_COMBINATION:
00179 corrections_.combinedP4 = p4 ;
00180 corrections_.combinedP4Error = error ;
00181 break ;
00182 case P4_PFLOW_COMBINATION:
00183 corrections_.pflowP4 = p4 ;
00184 corrections_.pflowP4Error = error ;
00185 break ;
00186 default:
00187 throw cms::Exception("GsfElectron")<<"unexpected p4 kind: "<<kind ;
00188 }
00189 if (setCandidate)
00190 {
00191 setP4(p4) ;
00192 corrections_.candidateP4Kind = kind ;
00193 }
00194 }
00195
00196 const Candidate::LorentzVector & GsfElectron::p4( P4Kind kind ) const
00197 {
00198 switch(kind)
00199 {
00200 case P4_FROM_SUPER_CLUSTER: return corrections_.fromSuperClusterP4 ;
00201 case P4_COMBINATION: return corrections_.combinedP4 ;
00202 case P4_PFLOW_COMBINATION: return corrections_.pflowP4 ;
00203 default: throw cms::Exception("GsfElectron")<<"unexpected p4 kind: "<<kind ;
00204 }
00205 }
00206
00207
00208 float GsfElectron::p4Error( P4Kind kind ) const
00209 {
00210 switch(kind)
00211 {
00212 case P4_FROM_SUPER_CLUSTER: return corrections_.fromSuperClusterP4Error ;
00213 case P4_COMBINATION: return corrections_.combinedP4Error ;
00214 case P4_PFLOW_COMBINATION: return corrections_.pflowP4Error ;
00215 default: throw cms::Exception("GsfElectron")<<"unexpected p4 kind: "<<kind ;
00216 }
00217 }
00218