00001
00002
00003
00004
00005 #include "DataFormats/PatCandidates/interface/Electron.h"
00006 #include "FWCore/Utilities/interface/Exception.h"
00007
00008 #include <limits>
00009
00010 using namespace pat;
00011
00013 Electron::Electron() :
00014 Lepton<reco::GsfElectron>(),
00015 embeddedGsfElectronCore_(false),
00016 embeddedGsfTrack_(false),
00017 embeddedSuperCluster_(false),
00018 embeddedPflowSuperCluster_(false),
00019 embeddedTrack_(false),
00020 embeddedSeedCluster_(false),
00021 embeddedRecHits_(false),
00022 embeddedPFCandidate_(false),
00023 ecalDrivenMomentum_(Candidate::LorentzVector(0.,0.,0.,0.)),
00024 cachedDB_(false),
00025 dB_(0.0),
00026 edB_(0.0),
00027 ecalRegressionEnergy_(0.0),
00028 ecalTrackRegressionEnergy_(0.0),
00029 ecalRegressionError_(0.0),
00030 ecalTrackRegressionError_(0.0),
00031 ecalScale_(-99999.),
00032 ecalSmear_(-99999.),
00033 ecalRegressionScale_(-99999.),
00034 ecalRegressionSmear_(-99999.),
00035 ecalTrackRegressionScale_(-99999.),
00036 ecalTrackRegressionSmear_(-99999.)
00037 {
00038 initImpactParameters();
00039 }
00040
00042 Electron::Electron(const reco::GsfElectron & anElectron) :
00043 Lepton<reco::GsfElectron>(anElectron),
00044 embeddedGsfElectronCore_(false),
00045 embeddedGsfTrack_(false),
00046 embeddedSuperCluster_(false),
00047 embeddedPflowSuperCluster_(false),
00048 embeddedTrack_(false),
00049 embeddedSeedCluster_(false),
00050 embeddedRecHits_(false),
00051 embeddedPFCandidate_(false),
00052 ecalDrivenMomentum_(anElectron.p4()),
00053 cachedDB_(false),
00054 dB_(0.0),
00055 edB_(0.0)
00056 {
00057 initImpactParameters();
00058 }
00059
00061 Electron::Electron(const edm::RefToBase<reco::GsfElectron> & anElectronRef) :
00062 Lepton<reco::GsfElectron>(anElectronRef),
00063 embeddedGsfElectronCore_(false),
00064 embeddedGsfTrack_(false),
00065 embeddedSuperCluster_(false),
00066 embeddedPflowSuperCluster_(false),
00067 embeddedTrack_(false),
00068 embeddedSeedCluster_(false),
00069 embeddedRecHits_(false),
00070 embeddedPFCandidate_(false),
00071 ecalDrivenMomentum_(anElectronRef->p4()),
00072 cachedDB_(false),
00073 dB_(0.0),
00074 edB_(0.0)
00075 {
00076 initImpactParameters();
00077 }
00078
00080 Electron::Electron(const edm::Ptr<reco::GsfElectron> & anElectronRef) :
00081 Lepton<reco::GsfElectron>(anElectronRef),
00082 embeddedGsfElectronCore_(false),
00083 embeddedGsfTrack_(false),
00084 embeddedSuperCluster_(false),
00085 embeddedPflowSuperCluster_(false),
00086 embeddedTrack_(false),
00087 embeddedSeedCluster_(false),
00088 embeddedRecHits_(false),
00089 embeddedPFCandidate_(false),
00090 ecalDrivenMomentum_(anElectronRef->p4()),
00091 cachedDB_(false),
00092 dB_(0.0),
00093 edB_(0.0)
00094 {
00095 initImpactParameters();
00096 }
00097
00099 Electron::~Electron() {
00100 }
00101
00103 std::ostream&
00104 reco::operator<<(std::ostream& out, const pat::Electron& obj)
00105 {
00106 if(!out) return out;
00107
00108 out << "\tpat::Electron: ";
00109 out << std::setiosflags(std::ios::right);
00110 out << std::setiosflags(std::ios::fixed);
00111 out << std::setprecision(3);
00112 out << " E/pT/eta/phi "
00113 << obj.energy()<<"/"
00114 << obj.pt()<<"/"
00115 << obj.eta()<<"/"
00116 << obj.phi();
00117 return out;
00118 }
00119
00121 void Electron::initImpactParameters() {
00122 for (int i_ = 0; i_<5; ++i_){
00123 ip_.push_back(0.0);
00124 eip_.push_back(0.0);
00125 cachedIP_.push_back(false);
00126 }
00127 }
00128
00129
00131 reco::GsfTrackRef Electron::gsfTrack() const {
00132 if (embeddedGsfTrack_) {
00133 return reco::GsfTrackRef(&gsfTrack_, 0);
00134 } else {
00135 return reco::GsfElectron::gsfTrack();
00136 }
00137 }
00138
00140 reco::GsfElectronCoreRef Electron::core() const {
00141 if (embeddedGsfElectronCore_) {
00142 return reco::GsfElectronCoreRef(&gsfElectronCore_, 0);
00143 } else {
00144 return reco::GsfElectron::core();
00145 }
00146 }
00147
00148
00150 reco::SuperClusterRef Electron::superCluster() const {
00151 if (embeddedSuperCluster_) {
00152 return reco::SuperClusterRef(&superCluster_, 0);
00153 } else {
00154 return reco::GsfElectron::superCluster();
00155 }
00156 }
00157
00159 reco::SuperClusterRef Electron::pflowSuperCluster() const {
00160 if (embeddedPflowSuperCluster_) {
00161 return reco::SuperClusterRef(&pflowSuperCluster_, 0);
00162 } else {
00163 return reco::GsfElectron::pflowSuperCluster();
00164 }
00165 }
00166
00168 reco::CaloClusterPtr Electron::seed() const {
00169 if(embeddedSeedCluster_){
00170 return reco::CaloClusterPtr(&seedCluster_,0);
00171 } else {
00172 return reco::GsfElectron::superCluster()->seed();
00173 }
00174 }
00175
00177 reco::TrackRef Electron::closestCtfTrackRef() const {
00178 if (embeddedTrack_) {
00179 return reco::TrackRef(&track_, 0);
00180 } else {
00181 return reco::GsfElectron::closestCtfTrackRef();
00182 }
00183 }
00184
00185
00186 reco::TrackRef Electron::track() const {
00187 return reco::TrackRef();
00188 }
00189
00191 void Electron::embedGsfElectronCore() {
00192 gsfElectronCore_.clear();
00193 if (reco::GsfElectron::core().isNonnull()) {
00194 gsfElectronCore_.push_back(*reco::GsfElectron::core());
00195 embeddedGsfElectronCore_ = true;
00196 }
00197 }
00198
00200 void Electron::embedGsfTrack() {
00201 gsfTrack_.clear();
00202 if (reco::GsfElectron::gsfTrack().isNonnull()) {
00203 gsfTrack_.push_back(*reco::GsfElectron::gsfTrack());
00204 embeddedGsfTrack_ = true;
00205 }
00206 }
00207
00208
00210 void Electron::embedSuperCluster() {
00211 superCluster_.clear();
00212 if (reco::GsfElectron::superCluster().isNonnull()) {
00213 superCluster_.push_back(*reco::GsfElectron::superCluster());
00214 embeddedSuperCluster_ = true;
00215 }
00216 }
00217
00219 void Electron::embedPflowSuperCluster() {
00220 pflowSuperCluster_.clear();
00221 if (reco::GsfElectron::pflowSuperCluster().isNonnull()) {
00222 pflowSuperCluster_.push_back(*reco::GsfElectron::pflowSuperCluster());
00223 embeddedPflowSuperCluster_ = true;
00224 }
00225 }
00226
00228 void Electron::embedSeedCluster() {
00229 seedCluster_.clear();
00230 if (reco::GsfElectron::superCluster().isNonnull() && reco::GsfElectron::superCluster()->seed().isNonnull()) {
00231 seedCluster_.push_back(*reco::GsfElectron::superCluster()->seed());
00232 embeddedSeedCluster_ = true;
00233 }
00234 }
00235
00237 void Electron::embedBasicClusters() {
00238 basicClusters_.clear();
00239 if (reco::GsfElectron::superCluster().isNonnull()){
00240 reco::CaloCluster_iterator itscl = reco::GsfElectron::superCluster()->clustersBegin();
00241 reco::CaloCluster_iterator itsclE = reco::GsfElectron::superCluster()->clustersEnd();
00242 for(;itscl!=itsclE;++itscl){
00243 basicClusters_.push_back( **itscl ) ;
00244 }
00245 }
00246 }
00247
00249 void Electron::embedPreshowerClusters() {
00250 preshowerClusters_.clear();
00251 if (reco::GsfElectron::superCluster().isNonnull()){
00252 reco::CaloCluster_iterator itscl = reco::GsfElectron::superCluster()->preshowerClustersBegin();
00253 reco::CaloCluster_iterator itsclE = reco::GsfElectron::superCluster()->preshowerClustersEnd();
00254 for(;itscl!=itsclE;++itscl){
00255 preshowerClusters_.push_back( **itscl ) ;
00256 }
00257 }
00258 }
00259
00261 void Electron::embedPflowBasicClusters() {
00262 pflowBasicClusters_.clear();
00263 if (reco::GsfElectron::pflowSuperCluster().isNonnull()){
00264 reco::CaloCluster_iterator itscl = reco::GsfElectron::pflowSuperCluster()->clustersBegin();
00265 reco::CaloCluster_iterator itsclE = reco::GsfElectron::pflowSuperCluster()->clustersEnd();
00266 for(;itscl!=itsclE;++itscl){
00267 pflowBasicClusters_.push_back( **itscl ) ;
00268 }
00269 }
00270 }
00271
00273 void Electron::embedPflowPreshowerClusters() {
00274 pflowPreshowerClusters_.clear();
00275 if (reco::GsfElectron::pflowSuperCluster().isNonnull()){
00276 reco::CaloCluster_iterator itscl = reco::GsfElectron::pflowSuperCluster()->preshowerClustersBegin();
00277 reco::CaloCluster_iterator itsclE = reco::GsfElectron::pflowSuperCluster()->preshowerClustersEnd();
00278 for(;itscl!=itsclE;++itscl){
00279 pflowPreshowerClusters_.push_back( **itscl ) ;
00280 }
00281 }
00282 }
00283
00285 void Electron::embedTrack() {
00286 track_.clear();
00287 if (reco::GsfElectron::closestCtfTrackRef().isNonnull()) {
00288 track_.push_back(*reco::GsfElectron::closestCtfTrackRef());
00289 embeddedTrack_ = true;
00290 }
00291 }
00292
00293
00294 void Electron::embedRecHits(const EcalRecHitCollection * rechits) {
00295 if (rechits!=0) {
00296 recHits_ = *rechits;
00297 embeddedRecHits_ = true;
00298 }
00299 }
00300
00315 float Electron::electronID(const std::string& name) const {
00316 for (std::vector<IdPair>::const_iterator it = electronIDs_.begin(), ed = electronIDs_.end(); it != ed; ++it) {
00317 if (it->first == name) return it->second;
00318 }
00319 cms::Exception ex("Key not found");
00320 ex << "pat::Electron: the ID " << name << " can't be found in this pat::Electron.\n";
00321 ex << "The available IDs are: ";
00322 for (std::vector<IdPair>::const_iterator it = electronIDs_.begin(), ed = electronIDs_.end(); it != ed; ++it) {
00323 ex << "'" << it->first << "' ";
00324 }
00325 ex << ".\n";
00326 throw ex;
00327 }
00328
00330 bool Electron::isElectronIDAvailable(const std::string& name) const {
00331 for (std::vector<IdPair>::const_iterator it = electronIDs_.begin(), ed = electronIDs_.end(); it != ed; ++it) {
00332 if (it->first == name) return true;
00333 }
00334 return false;
00335 }
00336
00337
00339 reco::PFCandidateRef Electron::pfCandidateRef() const {
00340 if (embeddedPFCandidate_) {
00341 return reco::PFCandidateRef(&pfCandidate_, 0);
00342 } else {
00343 return pfCandidateRef_;
00344 }
00345 }
00346
00348 void Electron::embedPFCandidate() {
00349 pfCandidate_.clear();
00350 if ( pfCandidateRef_.isAvailable() && pfCandidateRef_.isNonnull()) {
00351 pfCandidate_.push_back( *pfCandidateRef_ );
00352 embeddedPFCandidate_ = true;
00353 }
00354 }
00355
00358 reco::CandidatePtr Electron::sourceCandidatePtr( size_type i ) const {
00359 if (embeddedPFCandidate_) {
00360 return reco::CandidatePtr( pfCandidateRef_.id(), pfCandidateRef_.get(), pfCandidateRef_.key() );
00361 } else {
00362 return reco::CandidatePtr();
00363 }
00364 }
00365
00366
00367
00378 double Electron::dB(IpType type_) const {
00379
00380 if (type_ == None){
00381 if ( cachedDB_ ) {
00382 return dB_;
00383 } else {
00384 return std::numeric_limits<double>::max();
00385 }
00386 }
00387
00388 else if ( cachedIP_[type_] ) {
00389 return ip_[type_];
00390 } else {
00391 return std::numeric_limits<double>::max();
00392 }
00393 }
00394
00405 double Electron::edB(IpType type_) const {
00406
00407 if (type_ == None) {
00408 if ( cachedDB_ ) {
00409 return edB_;
00410 } else {
00411 return std::numeric_limits<double>::max();
00412 }
00413 }
00414
00415 else if ( cachedIP_[type_] ) {
00416 return eip_[type_];
00417 } else {
00418 return std::numeric_limits<double>::max();
00419 }
00420
00421 }
00422
00424 void Electron::setDB(double dB, double edB, IpType type){
00425 if (type == None) {
00426 dB_ = dB; edB_ = edB;
00427 cachedDB_ = true;
00428 } else {
00429 ip_[type] = dB;
00430 eip_[type] = edB;
00431 cachedIP_[type] = true;
00432 }
00433 }
00434
00436 void Electron::setMvaVariables( double r9, double sigmaIphiIphi, double sigmaIetaIphi, double ip3d){
00437 r9_ = r9;
00438 sigmaIphiIphi_ = sigmaIphiIphi;
00439 sigmaIetaIphi_ = sigmaIetaIphi;
00440 ip3d_ = ip3d;
00441 }