File indexing completed on 2024-04-06 12:04:56
0001
0002
0003
0004 #include "DataFormats/PatCandidates/interface/Electron.h"
0005 #include "FWCore/Utilities/interface/Exception.h"
0006 #include "DataFormats/Common/interface/RefToPtr.h"
0007
0008 #include <limits>
0009
0010 using namespace pat;
0011
0012
0013 Electron::Electron()
0014 : Lepton<reco::GsfElectron>(),
0015 embeddedGsfElectronCore_(false),
0016 embeddedGsfTrack_(false),
0017 embeddedSuperCluster_(false),
0018 embeddedPflowSuperCluster_(false),
0019 embeddedTrack_(false),
0020 embeddedSeedCluster_(false),
0021 embeddedRecHits_(false),
0022 embeddedPFCandidate_(false),
0023 ecalDrivenMomentum_(Candidate::LorentzVector(0., 0., 0., 0.)),
0024 ecalRegressionEnergy_(0.0),
0025 ecalTrackRegressionEnergy_(0.0),
0026 ecalRegressionError_(0.0),
0027 ecalTrackRegressionError_(0.0),
0028 ecalScale_(-99999.),
0029 ecalSmear_(-99999.),
0030 ecalRegressionScale_(-99999.),
0031 ecalRegressionSmear_(-99999.),
0032 ecalTrackRegressionScale_(-99999.),
0033 ecalTrackRegressionSmear_(-99999.),
0034 packedPFCandidates_(),
0035 associatedPackedFCandidateIndices_() {
0036 initImpactParameters();
0037 }
0038
0039
0040 Electron::Electron(const reco::GsfElectron& anElectron)
0041 : Lepton<reco::GsfElectron>(anElectron),
0042 embeddedGsfElectronCore_(false),
0043 embeddedGsfTrack_(false),
0044 embeddedSuperCluster_(false),
0045 embeddedPflowSuperCluster_(false),
0046 embeddedTrack_(false),
0047 embeddedSeedCluster_(false),
0048 embeddedRecHits_(false),
0049 embeddedPFCandidate_(false),
0050 ecalDrivenMomentum_(anElectron.p4()) {
0051 initImpactParameters();
0052 }
0053
0054
0055 Electron::Electron(const edm::RefToBase<reco::GsfElectron>& anElectronRef)
0056 : Lepton<reco::GsfElectron>(anElectronRef),
0057 embeddedGsfElectronCore_(false),
0058 embeddedGsfTrack_(false),
0059 embeddedSuperCluster_(false),
0060 embeddedPflowSuperCluster_(false),
0061 embeddedTrack_(false),
0062 embeddedSeedCluster_(false),
0063 embeddedRecHits_(false),
0064 embeddedPFCandidate_(false),
0065 ecalDrivenMomentum_(anElectronRef->p4()) {
0066 initImpactParameters();
0067 }
0068
0069
0070 Electron::Electron(const edm::Ptr<reco::GsfElectron>& anElectronRef)
0071 : Lepton<reco::GsfElectron>(anElectronRef),
0072 embeddedGsfElectronCore_(false),
0073 embeddedGsfTrack_(false),
0074 embeddedSuperCluster_(false),
0075 embeddedPflowSuperCluster_(false),
0076 embeddedTrack_(false),
0077 embeddedSeedCluster_(false),
0078 embeddedRecHits_(false),
0079 embeddedPFCandidate_(false),
0080 ecalDrivenMomentum_(anElectronRef->p4()) {
0081 initImpactParameters();
0082 }
0083
0084
0085 Electron::~Electron() {}
0086
0087
0088 std::ostream& reco::operator<<(std::ostream& out, const pat::Electron& obj) {
0089 if (!out)
0090 return out;
0091
0092 out << "\tpat::Electron: ";
0093 out << std::setiosflags(std::ios::right);
0094 out << std::setiosflags(std::ios::fixed);
0095 out << std::setprecision(3);
0096 out << " E/pT/eta/phi " << obj.energy() << "/" << obj.pt() << "/" << obj.eta() << "/" << obj.phi();
0097 return out;
0098 }
0099
0100
0101 void Electron::initImpactParameters() {
0102 std::fill(ip_, ip_ + IpTypeSize, 0.0f);
0103 std::fill(eip_, eip_ + IpTypeSize, 0.0f);
0104 cachedIP_ = 0;
0105 }
0106
0107
0108 reco::GsfTrackRef Electron::gsfTrack() const {
0109 if (embeddedGsfTrack_) {
0110 return reco::GsfTrackRef(&gsfTrack_, 0);
0111 } else {
0112 return reco::GsfElectron::gsfTrack();
0113 }
0114 }
0115
0116
0117 reco::GsfElectronCoreRef Electron::core() const {
0118 if (embeddedGsfElectronCore_) {
0119 return reco::GsfElectronCoreRef(&gsfElectronCore_, 0);
0120 } else {
0121 return reco::GsfElectron::core();
0122 }
0123 }
0124
0125
0126 reco::SuperClusterRef Electron::superCluster() const {
0127 if (embeddedSuperCluster_) {
0128 if (embeddedSeedCluster_ || !basicClusters_.empty() || !preshowerClusters_.empty()) {
0129 if (!superClusterRelinked_.isSet()) {
0130 std::unique_ptr<std::vector<reco::SuperCluster> > sc(new std::vector<reco::SuperCluster>(superCluster_));
0131 if (embeddedSeedCluster_ && !(*sc)[0].seed().isAvailable()) {
0132 (*sc)[0].setSeed(seed());
0133 }
0134 if (!basicClusters_.empty() && !(*sc)[0].clusters().isAvailable()) {
0135 reco::CaloClusterPtrVector clusters;
0136 for (unsigned int iclus = 0; iclus < basicClusters_.size(); ++iclus) {
0137 clusters.push_back(reco::CaloClusterPtr(&basicClusters_, iclus));
0138 }
0139 (*sc)[0].setClusters(clusters);
0140 }
0141 if (!preshowerClusters_.empty() && !(*sc)[0].preshowerClusters().isAvailable()) {
0142 reco::CaloClusterPtrVector clusters;
0143 for (unsigned int iclus = 0; iclus < preshowerClusters_.size(); ++iclus) {
0144 clusters.push_back(reco::CaloClusterPtr(&preshowerClusters_, iclus));
0145 }
0146 (*sc)[0].setPreshowerClusters(clusters);
0147 }
0148 superClusterRelinked_.set(std::move(sc));
0149 }
0150 return reco::SuperClusterRef(&*superClusterRelinked_, 0);
0151 } else {
0152 return reco::SuperClusterRef(&superCluster_, 0);
0153 }
0154
0155 return reco::SuperClusterRef(&superCluster_, 0);
0156 } else {
0157 return reco::GsfElectron::superCluster();
0158 }
0159 }
0160
0161
0162 reco::SuperClusterRef Electron::parentSuperCluster() const {
0163 if (embeddedPflowSuperCluster_) {
0164 return reco::SuperClusterRef(&pflowSuperCluster_, 0);
0165 } else {
0166 return reco::GsfElectron::parentSuperCluster();
0167 }
0168 }
0169
0170
0171 reco::CaloClusterPtr Electron::seed() const {
0172 if (embeddedSeedCluster_) {
0173 return reco::CaloClusterPtr(&seedCluster_, 0);
0174 } else {
0175 return reco::GsfElectron::superCluster()->seed();
0176 }
0177 }
0178
0179
0180 reco::TrackRef Electron::closestCtfTrackRef() const {
0181 if (embeddedTrack_) {
0182 return reco::TrackRef(&track_, 0);
0183 } else {
0184 return reco::GsfElectron::closestCtfTrackRef();
0185 }
0186 }
0187
0188
0189 reco::TrackRef Electron::track() const { return reco::TrackRef(); }
0190
0191
0192 void Electron::embedGsfElectronCore() {
0193 gsfElectronCore_.clear();
0194 if (reco::GsfElectron::core().isNonnull()) {
0195 gsfElectronCore_.push_back(*reco::GsfElectron::core());
0196 embeddedGsfElectronCore_ = true;
0197 }
0198 }
0199
0200
0201 void Electron::embedGsfTrack() {
0202 gsfTrack_.clear();
0203 if (reco::GsfElectron::gsfTrack().isNonnull()) {
0204 gsfTrack_.push_back(*reco::GsfElectron::gsfTrack());
0205 embeddedGsfTrack_ = true;
0206 }
0207 }
0208
0209
0210 void Electron::embedSuperCluster() {
0211 superCluster_.clear();
0212 if (reco::GsfElectron::superCluster().isNonnull()) {
0213 superCluster_.push_back(*reco::GsfElectron::superCluster());
0214 embeddedSuperCluster_ = true;
0215 }
0216 }
0217
0218
0219 void Electron::embedPflowSuperCluster() {
0220 pflowSuperCluster_.clear();
0221 if (reco::GsfElectron::parentSuperCluster().isNonnull()) {
0222 pflowSuperCluster_.push_back(*reco::GsfElectron::parentSuperCluster());
0223 embeddedPflowSuperCluster_ = true;
0224 }
0225 }
0226
0227
0228 void Electron::embedSeedCluster() {
0229 seedCluster_.clear();
0230 if (reco::GsfElectron::superCluster().isNonnull() && reco::GsfElectron::superCluster()->seed().isNonnull()) {
0231 seedCluster_.push_back(*reco::GsfElectron::superCluster()->seed());
0232 embeddedSeedCluster_ = true;
0233 }
0234 }
0235
0236
0237 void Electron::embedBasicClusters() {
0238 basicClusters_.clear();
0239 if (reco::GsfElectron::superCluster().isNonnull()) {
0240 reco::CaloCluster_iterator itscl = reco::GsfElectron::superCluster()->clustersBegin();
0241 reco::CaloCluster_iterator itsclE = reco::GsfElectron::superCluster()->clustersEnd();
0242 for (; itscl != itsclE; ++itscl) {
0243 basicClusters_.push_back(**itscl);
0244 }
0245 }
0246 }
0247
0248
0249 void Electron::embedPreshowerClusters() {
0250 preshowerClusters_.clear();
0251 if (reco::GsfElectron::superCluster().isNonnull()) {
0252 reco::CaloCluster_iterator itscl = reco::GsfElectron::superCluster()->preshowerClustersBegin();
0253 reco::CaloCluster_iterator itsclE = reco::GsfElectron::superCluster()->preshowerClustersEnd();
0254 for (; itscl != itsclE; ++itscl) {
0255 preshowerClusters_.push_back(**itscl);
0256 }
0257 }
0258 }
0259
0260
0261 void Electron::embedPflowBasicClusters() {
0262 pflowBasicClusters_.clear();
0263 if (reco::GsfElectron::parentSuperCluster().isNonnull()) {
0264 reco::CaloCluster_iterator itscl = reco::GsfElectron::parentSuperCluster()->clustersBegin();
0265 reco::CaloCluster_iterator itsclE = reco::GsfElectron::parentSuperCluster()->clustersEnd();
0266 for (; itscl != itsclE; ++itscl) {
0267 pflowBasicClusters_.push_back(**itscl);
0268 }
0269 }
0270 }
0271
0272
0273 void Electron::embedPflowPreshowerClusters() {
0274 pflowPreshowerClusters_.clear();
0275 if (reco::GsfElectron::parentSuperCluster().isNonnull()) {
0276 reco::CaloCluster_iterator itscl = reco::GsfElectron::parentSuperCluster()->preshowerClustersBegin();
0277 reco::CaloCluster_iterator itsclE = reco::GsfElectron::parentSuperCluster()->preshowerClustersEnd();
0278 for (; itscl != itsclE; ++itscl) {
0279 pflowPreshowerClusters_.push_back(**itscl);
0280 }
0281 }
0282 }
0283
0284
0285 void Electron::embedTrack() {
0286 track_.clear();
0287 if (reco::GsfElectron::closestCtfTrackRef().isNonnull()) {
0288 track_.push_back(*reco::GsfElectron::closestCtfTrackRef());
0289 embeddedTrack_ = true;
0290 }
0291 }
0292
0293
0294 void Electron::embedRecHits(const EcalRecHitCollection* rechits) {
0295 if (rechits != nullptr) {
0296 recHits_ = *rechits;
0297 embeddedRecHits_ = true;
0298 }
0299 }
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315 float Electron::electronID(const std::string& name) const {
0316 for (std::vector<IdPair>::const_iterator it = electronIDs_.begin(), ed = electronIDs_.end(); it != ed; ++it) {
0317 if (it->first == name)
0318 return it->second;
0319 }
0320 cms::Exception ex("Key not found");
0321 ex << "pat::Electron: the ID " << name << " can't be found in this pat::Electron.\n";
0322 ex << "The available IDs are: ";
0323 for (std::vector<IdPair>::const_iterator it = electronIDs_.begin(), ed = electronIDs_.end(); it != ed; ++it) {
0324 ex << "'" << it->first << "' ";
0325 }
0326 ex << ".\n";
0327 throw ex;
0328 }
0329
0330
0331 bool Electron::isElectronIDAvailable(const std::string& name) const {
0332 for (std::vector<IdPair>::const_iterator it = electronIDs_.begin(), ed = electronIDs_.end(); it != ed; ++it) {
0333 if (it->first == name)
0334 return true;
0335 }
0336 return false;
0337 }
0338
0339
0340 reco::PFCandidateRef Electron::pfCandidateRef() const {
0341 if (embeddedPFCandidate_) {
0342 return reco::PFCandidateRef(&pfCandidate_, 0);
0343 } else {
0344 return pfCandidateRef_;
0345 }
0346 }
0347
0348
0349 void Electron::embedPFCandidate() {
0350 pfCandidate_.clear();
0351 if (pfCandidateRef_.isAvailable() && pfCandidateRef_.isNonnull()) {
0352 pfCandidate_.push_back(*pfCandidateRef_);
0353 embeddedPFCandidate_ = true;
0354 }
0355 }
0356
0357
0358
0359 reco::CandidatePtr Electron::sourceCandidatePtr(size_type i) const {
0360 if (pfCandidateRef_.isNonnull()) {
0361 if (i == 0) {
0362 return reco::CandidatePtr(edm::refToPtr(pfCandidateRef_));
0363 } else {
0364 i--;
0365 }
0366 }
0367 if (i >= associatedPackedFCandidateIndices_.size()) {
0368 return reco::CandidatePtr();
0369 } else {
0370 return reco::CandidatePtr(edm::refToPtr(
0371 edm::Ref<pat::PackedCandidateCollection>(packedPFCandidates_, associatedPackedFCandidateIndices_[i])));
0372 }
0373 }
0374
0375
0376
0377
0378
0379
0380
0381
0382
0383
0384
0385 double Electron::dB(IpType type_) const {
0386
0387 if (cachedIP_ & (1 << int(type_))) {
0388 return ip_[type_];
0389 } else {
0390 return std::numeric_limits<double>::max();
0391 }
0392 }
0393
0394
0395
0396
0397
0398
0399
0400
0401
0402
0403
0404 double Electron::edB(IpType type_) const {
0405
0406 if (cachedIP_ & (1 << int(type_))) {
0407 return eip_[type_];
0408 } else {
0409 return std::numeric_limits<double>::max();
0410 }
0411 }
0412
0413
0414 void Electron::setDB(double dB, double edB, IpType type) {
0415 ip_[type] = dB;
0416 eip_[type] = edB;
0417 cachedIP_ |= (1 << int(type));
0418 }
0419
0420
0421 void Electron::setMvaVariables(double sigmaIetaIphi, double ip3d) {
0422 sigmaIetaIphi_ = sigmaIetaIphi;
0423 ip3d_ = ip3d;
0424 }
0425
0426 edm::RefVector<pat::PackedCandidateCollection> Electron::associatedPackedPFCandidates() const {
0427 edm::RefVector<pat::PackedCandidateCollection> ret(packedPFCandidates_.id());
0428 for (uint16_t idx : associatedPackedFCandidateIndices_) {
0429 ret.push_back(edm::Ref<pat::PackedCandidateCollection>(packedPFCandidates_, idx));
0430 }
0431 return ret;
0432 }