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