File indexing completed on 2022-10-01 01:01:51
0001 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidate.h"
0002
0003
0004 #include "DataFormats/MuonReco/interface/Muon.h"
0005 #include "DataFormats/GsfTrackReco/interface/GsfTrack.h"
0006 #include "DataFormats/ParticleFlowReco/interface/PFDisplacedVertex.h"
0007 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateElectronExtra.h"
0008 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidatePhotonExtra.h"
0009 #include "DataFormats/ParticleFlowCandidate/interface/PFCandidateEGammaExtra.h"
0010 #include "DataFormats/EgammaCandidates/interface/Conversion.h"
0011 #include "DataFormats/EgammaCandidates/interface/Photon.h"
0012
0013 #include "FWCore/Utilities/interface/Exception.h"
0014
0015 #include <ostream>
0016 #include <iomanip>
0017
0018 using namespace reco;
0019 using namespace std;
0020
0021 #include "DataFormats/ParticleFlowCandidate/src/CountBits.h"
0022
0023 PFCandidate::PFCandidate()
0024 : elementsInBlocks_(nullptr),
0025 ecalERatio_(1.),
0026 hcalERatio_(1.),
0027 hoERatio_(1.),
0028 rawEcalEnergy_(0.),
0029 rawHcalEnergy_(0.),
0030 rawHoEnergy_(0.),
0031 ps1Energy_(0.),
0032 ps2Energy_(0.),
0033 flags_(0),
0034 deltaP_(0.),
0035 vertexType_(kCandVertex),
0036 mva_Isolated_(PFCandidate::bigMva_),
0037 mva_e_pi_(PFCandidate::bigMva_),
0038 mva_e_mu_(PFCandidate::bigMva_),
0039 mva_pi_mu_(PFCandidate::bigMva_),
0040 mva_nothing_gamma_(PFCandidate::bigMva_),
0041 mva_nothing_nh_(PFCandidate::bigMva_),
0042 mva_gamma_nh_(PFCandidate::bigMva_),
0043 dnn_e_sigIsolated_(PFCandidate::bigMva_),
0044 dnn_e_sigNonIsolated_(PFCandidate::bigMva_),
0045 dnn_e_bkgNonIsolated_(PFCandidate::bigMva_),
0046 dnn_e_bkgTau_(PFCandidate::bigMva_),
0047 dnn_e_bkgPhoton_(PFCandidate::bigMva_),
0048 dnn_gamma_(PFCandidate::bigMva_),
0049 getter_(nullptr),
0050 storedRefsBitPattern_(0),
0051 time_(0.f),
0052 timeError_(-1.f) {
0053 muonTrackType_ = reco::Muon::None;
0054
0055 setPdgId(translateTypeToPdgId(X));
0056 refsInfo_.reserve(3);
0057 std::fill(hcalDepthEnergyFractions_.begin(), hcalDepthEnergyFractions_.end(), 0.f);
0058 }
0059
0060 const math::XYZPoint& PFCandidate::vertex() const { return vertexLegacy(vertexType_); }
0061
0062 PFCandidate::PFCandidate(const PFCandidatePtr& sourcePtr) : PFCandidate(*sourcePtr) {
0063 sourcePtr_ = sourcePtr;
0064 hcalDepthEnergyFractions_ = sourcePtr->hcalDepthEnergyFractions_;
0065 }
0066
0067 PFCandidate::PFCandidate(Charge charge, const LorentzVector& p4, ParticleType partId)
0068 : CompositeCandidate(charge, p4),
0069 elementsInBlocks_(nullptr),
0070 ecalERatio_(1.),
0071 hcalERatio_(1.),
0072 hoERatio_(1.),
0073 rawEcalEnergy_(0.),
0074 rawHcalEnergy_(0.),
0075 rawHoEnergy_(0.),
0076 ps1Energy_(0.),
0077 ps2Energy_(0.),
0078 flags_(0),
0079 deltaP_(0.),
0080 vertexType_(kCandVertex),
0081 mva_Isolated_(PFCandidate::bigMva_),
0082 mva_e_pi_(PFCandidate::bigMva_),
0083 mva_e_mu_(PFCandidate::bigMva_),
0084 mva_pi_mu_(PFCandidate::bigMva_),
0085 mva_nothing_gamma_(PFCandidate::bigMva_),
0086 mva_nothing_nh_(PFCandidate::bigMva_),
0087 mva_gamma_nh_(PFCandidate::bigMva_),
0088 dnn_e_sigIsolated_(PFCandidate::bigMva_),
0089 dnn_e_sigNonIsolated_(PFCandidate::bigMva_),
0090 dnn_e_bkgNonIsolated_(PFCandidate::bigMva_),
0091 dnn_e_bkgTau_(PFCandidate::bigMva_),
0092 dnn_e_bkgPhoton_(PFCandidate::bigMva_),
0093 dnn_gamma_(PFCandidate::bigMva_),
0094 getter_(nullptr),
0095 storedRefsBitPattern_(0),
0096 time_(0.f),
0097 timeError_(-1.f) {
0098 refsInfo_.reserve(3);
0099 blocksStorage_.reserve(10);
0100 elementsStorage_.reserve(10);
0101 std::fill(hcalDepthEnergyFractions_.begin(), hcalDepthEnergyFractions_.end(), 0.f);
0102
0103 muonTrackType_ = reco::Muon::None;
0104
0105
0106
0107
0108 if (partId == h || partId == e || partId == mu) {
0109 if (charge == 0) {
0110 string err;
0111 err += "Attempt to construct a charged PFCandidate with a zero charge";
0112 throw cms::Exception("InconsistentValue", err.c_str());
0113 }
0114 } else {
0115 if (charge) {
0116 string err;
0117 err += "Attempt to construct a neutral PFCandidate ";
0118 err += "with a non-zero charge";
0119 throw cms::Exception("InconsistentValue", err.c_str());
0120 }
0121 }
0122 setPdgId(translateTypeToPdgId(partId));
0123 }
0124
0125 PFCandidate::PFCandidate(PFCandidate const& iOther)
0126 : CompositeCandidate(iOther),
0127 elementsInBlocks_(nullptr),
0128 blocksStorage_(iOther.blocksStorage_),
0129 elementsStorage_(iOther.elementsStorage_),
0130 sourcePtr_(iOther.sourcePtr_),
0131 muonTrackType_(iOther.muonTrackType_),
0132 ecalERatio_(iOther.ecalERatio_),
0133 hcalERatio_(iOther.hcalERatio_),
0134 hoERatio_(iOther.hoERatio_),
0135 rawEcalEnergy_(iOther.rawEcalEnergy_),
0136 rawHcalEnergy_(iOther.rawHcalEnergy_),
0137 rawHoEnergy_(iOther.rawHoEnergy_),
0138 ps1Energy_(iOther.ps1Energy_),
0139 ps2Energy_(iOther.ps2Energy_),
0140 flags_(iOther.flags_),
0141 deltaP_(iOther.deltaP_),
0142 vertexType_(iOther.vertexType_),
0143 mva_Isolated_(iOther.mva_Isolated_),
0144 mva_e_pi_(iOther.mva_e_pi_),
0145 mva_e_mu_(iOther.mva_e_mu_),
0146 mva_pi_mu_(iOther.mva_pi_mu_),
0147 mva_nothing_gamma_(iOther.mva_nothing_gamma_),
0148 mva_nothing_nh_(iOther.mva_nothing_nh_),
0149 mva_gamma_nh_(iOther.mva_gamma_nh_),
0150 dnn_e_sigIsolated_(iOther.dnn_e_sigIsolated_),
0151 dnn_e_sigNonIsolated_(iOther.dnn_e_sigNonIsolated_),
0152 dnn_e_bkgNonIsolated_(iOther.dnn_e_bkgNonIsolated_),
0153 dnn_e_bkgTau_(iOther.dnn_e_bkgTau_),
0154 dnn_e_bkgPhoton_(iOther.dnn_e_bkgPhoton_),
0155 dnn_gamma_(iOther.dnn_gamma_),
0156 positionAtECALEntrance_(iOther.positionAtECALEntrance_),
0157 getter_(iOther.getter_),
0158 storedRefsBitPattern_(iOther.storedRefsBitPattern_),
0159 refsInfo_(iOther.refsInfo_),
0160 refsCollectionCache_(iOther.refsCollectionCache_),
0161 time_(iOther.time_),
0162 timeError_(iOther.timeError_),
0163 hcalDepthEnergyFractions_(iOther.hcalDepthEnergyFractions_) {
0164 auto tmp = iOther.elementsInBlocks_.load(std::memory_order_acquire);
0165 if (nullptr != tmp) {
0166 elementsInBlocks_.store(new ElementsInBlocks{*tmp}, std::memory_order_release);
0167 }
0168 }
0169
0170 PFCandidate& PFCandidate::operator=(PFCandidate const& iOther) {
0171 CompositeCandidate::operator=(iOther);
0172 auto tmp = iOther.elementsInBlocks_.load(std::memory_order_acquire);
0173 if (nullptr != tmp) {
0174 delete elementsInBlocks_.exchange(new ElementsInBlocks{*tmp}, std::memory_order_acq_rel);
0175 } else {
0176 delete elementsInBlocks_.exchange(nullptr, std::memory_order_acq_rel);
0177 }
0178 blocksStorage_ = iOther.blocksStorage_;
0179 elementsStorage_ = iOther.elementsStorage_;
0180 sourcePtr_ = iOther.sourcePtr_;
0181 muonTrackType_ = iOther.muonTrackType_;
0182 ecalERatio_ = iOther.ecalERatio_;
0183 hcalERatio_ = iOther.hcalERatio_;
0184 hoERatio_ = iOther.hoERatio_;
0185 rawEcalEnergy_ = iOther.rawEcalEnergy_;
0186 rawHcalEnergy_ = iOther.rawHcalEnergy_;
0187 rawHoEnergy_ = iOther.rawHoEnergy_;
0188 ps1Energy_ = iOther.ps1Energy_;
0189 ps2Energy_ = iOther.ps2Energy_;
0190 flags_ = iOther.flags_;
0191 deltaP_ = iOther.deltaP_;
0192 vertexType_ = iOther.vertexType_;
0193 mva_Isolated_ = iOther.mva_Isolated_;
0194 mva_e_pi_ = iOther.mva_e_pi_;
0195 mva_e_mu_ = iOther.mva_e_mu_;
0196 mva_pi_mu_ = iOther.mva_pi_mu_;
0197 mva_nothing_gamma_ = iOther.mva_nothing_gamma_;
0198 mva_nothing_nh_ = iOther.mva_nothing_nh_;
0199 mva_gamma_nh_ = iOther.mva_gamma_nh_;
0200 dnn_e_sigIsolated_ = iOther.dnn_e_sigIsolated_;
0201 dnn_e_sigNonIsolated_ = iOther.dnn_e_sigNonIsolated_;
0202 dnn_e_bkgNonIsolated_ = iOther.dnn_e_bkgNonIsolated_;
0203 dnn_e_bkgTau_ = iOther.dnn_e_bkgTau_;
0204 dnn_e_bkgPhoton_ = iOther.dnn_e_bkgPhoton_;
0205 dnn_gamma_ = iOther.dnn_gamma_;
0206 positionAtECALEntrance_ = iOther.positionAtECALEntrance_;
0207 getter_ = iOther.getter_;
0208 storedRefsBitPattern_ = iOther.storedRefsBitPattern_;
0209 refsInfo_ = iOther.refsInfo_;
0210 refsCollectionCache_ = iOther.refsCollectionCache_;
0211 time_ = iOther.time_;
0212 timeError_ = iOther.timeError_;
0213 hcalDepthEnergyFractions_ = iOther.hcalDepthEnergyFractions_;
0214 return *this;
0215 }
0216
0217 PFCandidate::~PFCandidate() { delete elementsInBlocks_.load(std::memory_order_acquire); }
0218
0219 PFCandidate* PFCandidate::clone() const { return new PFCandidate(*this); }
0220
0221 void PFCandidate::addElementInBlock(const reco::PFBlockRef& blockref, unsigned elementIndex) {
0222
0223 if (blocksStorage_.empty())
0224 blocksStorage_ = Blocks(blockref.id());
0225 blocksStorage_.push_back(blockref);
0226 elementsStorage_.push_back(elementIndex);
0227 auto ptr = elementsInBlocks_.exchange(nullptr);
0228 delete ptr;
0229 }
0230
0231 PFCandidate::ParticleType PFCandidate::translatePdgIdToType(int pdgid) const {
0232 switch (std::abs(pdgid)) {
0233 case 211:
0234 return h;
0235 case 11:
0236 return e;
0237 case 13:
0238 return mu;
0239 case 22:
0240 return gamma;
0241 case 130:
0242 return h0;
0243 case 1:
0244 return h_HF;
0245 case 2:
0246 return egamma_HF;
0247 case 0:
0248 return X;
0249 default:
0250 return X;
0251 }
0252 }
0253
0254 int PFCandidate::translateTypeToPdgId(ParticleType type) const {
0255 int thecharge = charge();
0256
0257 switch (type) {
0258 case h:
0259 return thecharge * 211;
0260 case e:
0261 return thecharge * (-11);
0262 case mu:
0263 return thecharge * (-13);
0264 case gamma:
0265 return 22;
0266 case h0:
0267 return 130;
0268 case h_HF:
0269 return 1;
0270 case egamma_HF:
0271 return 2;
0272 case X:
0273 default:
0274 return 0;
0275 }
0276 }
0277
0278 void PFCandidate::setParticleType(ParticleType type) { setPdgId(translateTypeToPdgId(type)); }
0279
0280 bool PFCandidate::overlap(const reco::Candidate& other) const {
0281 CandidatePtr myPtr = sourceCandidatePtr(0);
0282 if (myPtr.isNull())
0283 return false;
0284 for (size_t i = 0, n = other.numberOfSourceCandidatePtrs(); i < n; ++i) {
0285 CandidatePtr otherPtr = other.sourceCandidatePtr(i);
0286 if ((otherPtr == myPtr) || (sourcePtr_.isNonnull() && otherPtr.isNonnull() && sourcePtr_->overlap(*otherPtr))) {
0287 return true;
0288 }
0289 }
0290 return false;
0291 }
0292
0293
0294 void PFCandidate::rescaleMomentum(double rescaleFactor) {
0295 if (rescaleFactor < 0)
0296 throw cms::Exception(
0297 "NegativeScaling",
0298 "Scale factor " + std::to_string(rescaleFactor) + " is < 0. Cannot rescale momentum by this value");
0299 float rescaleE = std::sqrt(p() * p() * (rescaleFactor * rescaleFactor - 1) / (energy() * energy()) + 1);
0300 LorentzVector rescaledp4(rescaleFactor * px(), rescaleFactor * py(), rescaleFactor * pz(), rescaleE * energy());
0301 setP4(rescaledp4);
0302 }
0303
0304 void PFCandidate::setFlag(Flags theFlag, bool value) {
0305 if (value)
0306 flags_ = flags_ | (1 << theFlag);
0307 else
0308 flags_ = flags_ ^ (1 << theFlag);
0309 }
0310
0311 bool PFCandidate::flag(Flags theFlag) const { return (flags_ >> theFlag) & 1; }
0312
0313 ostream& reco::operator<<(ostream& out, const PFCandidate& c) {
0314 if (!out)
0315 return out;
0316
0317 out << "\tPFCandidate type: " << c.particleId();
0318 out << setiosflags(ios::right);
0319 out << setiosflags(ios::fixed);
0320 out << setprecision(3);
0321 out << " E/pT/eta/phi " << c.energy() << "/" << c.pt() << "/" << c.eta() << "/" << c.phi();
0322 if (c.flag(PFCandidate::T_FROM_DISP))
0323 out << ", T_FROM_DISP" << endl;
0324 else if (c.flag(PFCandidate::T_TO_DISP))
0325 out << ", T_TO_DISP" << endl;
0326 else if (c.flag(PFCandidate::T_FROM_GAMMACONV))
0327 out << ", T_FROM_GAMMACONV" << endl;
0328 else if (c.flag(PFCandidate::GAMMA_TO_GAMMACONV))
0329 out << ", GAMMA_TO_GAMMACONV" << endl;
0330
0331 out << ", blocks/iele: ";
0332
0333 PFCandidate::ElementsInBlocks eleInBlocks = c.elementsInBlocks();
0334 for (unsigned i = 0; i < eleInBlocks.size(); i++) {
0335 PFBlockRef blockRef = eleInBlocks[i].first;
0336 unsigned indexInBlock = eleInBlocks[i].second;
0337
0338 out << "(" << blockRef.key() << "|" << indexInBlock << "), ";
0339 }
0340
0341 out << " source:" << c.sourcePtr_.id() << "/" << c.sourcePtr_.key();
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356 if (c.particleId() == PFCandidate::e && c.electronExtraRef().isNonnull() && c.electronExtraRef().isAvailable()) {
0357 out << std::endl << *(c.electronExtraRef());
0358 }
0359 out << resetiosflags(ios::right | ios::fixed);
0360 return out;
0361 }
0362
0363 static unsigned long long bitPackRefInfo(const edm::RefCore& iCore, size_t iIndex) {
0364 unsigned long long bitPack = iIndex;
0365 bitPack |= static_cast<unsigned long long>(iCore.id().productIndex()) << 32;
0366 bitPack |= static_cast<unsigned long long>(iCore.id().processIndex()) << 48;
0367 return bitPack;
0368 }
0369
0370 void PFCandidate::storeRefInfo(unsigned int iMask,
0371 unsigned int iBit,
0372 bool iIsValid,
0373 const edm::RefCore& iCore,
0374 size_t iKey,
0375 const edm::EDProductGetter* iGetter) {
0376 size_t index = s_refsBefore[storedRefsBitPattern_ & iMask];
0377 if (nullptr == getter_) {
0378 getter_ = iGetter;
0379 }
0380
0381 if (iIsValid) {
0382 if (0 == (storedRefsBitPattern_ & iBit)) {
0383 refsInfo_.insert(refsInfo_.begin() + index, bitPackRefInfo(iCore, iKey));
0384 if (iGetter == nullptr)
0385 refsCollectionCache_.insert(refsCollectionCache_.begin() + index, static_cast<void const*>(iCore.productPtr()));
0386 else
0387 refsCollectionCache_.insert(refsCollectionCache_.begin() + index, nullptr);
0388 } else {
0389 assert(refsInfo_.size() > index);
0390 *(refsInfo_.begin() + index) = bitPackRefInfo(iCore, iKey);
0391 if (iGetter == nullptr)
0392 *(refsCollectionCache_.begin() + index) = static_cast<void const*>(iCore.productPtr());
0393 else
0394 *(refsCollectionCache_.begin() + index) = nullptr;
0395 }
0396 storedRefsBitPattern_ |= iBit;
0397 } else {
0398 if (storedRefsBitPattern_ & iBit) {
0399 refsInfo_.erase(refsInfo_.begin() + index);
0400 refsCollectionCache_.erase(refsCollectionCache_.begin() + index);
0401 storedRefsBitPattern_ ^= iBit;
0402 }
0403 }
0404 }
0405
0406 bool PFCandidate::getRefInfo(
0407 unsigned int iMask, unsigned int iBit, edm::ProductID& oProductID, size_t& oIndex, size_t& aIndex) const {
0408 if (0 == (iBit & storedRefsBitPattern_)) {
0409 return false;
0410 }
0411 aIndex = s_refsBefore[storedRefsBitPattern_ & iMask];
0412 unsigned long long bitPacked = refsInfo_[aIndex];
0413 oIndex = bitPacked & 0xFFFFFFFFULL;
0414 unsigned short productIndex = (bitPacked & 0x0000FFFF00000000ULL) >> 32;
0415 unsigned short processIndex = (bitPacked & 0xFFFF000000000000ULL) >> 48;
0416 oProductID = edm::ProductID(processIndex, productIndex);
0417 return true;
0418 }
0419
0420 void PFCandidate::setTrackRef(const reco::TrackRef& iRef) {
0421 if (!charge()) {
0422 string err;
0423 err += "PFCandidate::setTrackRef: this is a neutral candidate! ";
0424 err += "particleId_=";
0425 char num[4];
0426 sprintf(num, "%d", particleId());
0427 err += num;
0428
0429 throw cms::Exception("InconsistentReference", err.c_str());
0430 }
0431
0432 storeRefInfo(kRefTrackMask, kRefTrackBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0433 }
0434
0435 reco::TrackRef PFCandidate::trackRef() const { GETREF(reco::Track, kRefTrackMask, kRefTrackBit); }
0436
0437 void PFCandidate::setMuonRef(reco::MuonRef const& iRef) {
0438 if (trackRef() != iRef->track()) {
0439 string err;
0440 err += "PFCandidate::setMuonRef: inconsistent track references!";
0441
0442 throw cms::Exception("InconsistentReference", err.c_str());
0443 }
0444
0445 storeRefInfo(kRefMuonMask, kRefMuonBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0446 }
0447
0448 reco::MuonRef PFCandidate::muonRef() const { GETREF(reco::Muon, kRefMuonMask, kRefMuonBit); }
0449
0450
0451 void PFCandidate::setGsfTrackRef(reco::GsfTrackRef const& iRef) {
0452
0453
0454
0455
0456
0457
0458
0459
0460
0461
0462
0463
0464 storeRefInfo(kRefGsfTrackMask, kRefGsfTrackBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0465 }
0466
0467 reco::GsfTrackRef PFCandidate::gsfTrackRef() const { GETREF(reco::GsfTrack, kRefGsfTrackMask, kRefGsfTrackBit); }
0468
0469
0470 void PFCandidate::setDisplacedVertexRef(const reco::PFDisplacedVertexRef& iRef, Flags type) {
0471 if (particleId() != h) {
0472 string err;
0473 err += "PFCandidate::setDisplacedVertexRef: this is not a hadron! particleId_=";
0474 char num[4];
0475 sprintf(num, "%d", particleId());
0476 err += num;
0477
0478 throw cms::Exception("InconsistentReference", err.c_str());
0479 } else if (!flag(T_FROM_DISP) && !flag(T_TO_DISP)) {
0480 string err;
0481 err += "PFCandidate::setDisplacedVertexRef: particule flag is neither T_FROM_DISP nor T_TO_DISP";
0482
0483 throw cms::Exception("InconsistentReference", err.c_str());
0484 }
0485
0486 if (type == T_TO_DISP && flag(T_TO_DISP))
0487 storeRefInfo(kRefDisplacedVertexDauMask,
0488 kRefDisplacedVertexDauBit,
0489 iRef.isNonnull(),
0490 iRef.refCore(),
0491 iRef.key(),
0492 iRef.productGetter());
0493 else if (type == T_FROM_DISP && flag(T_FROM_DISP))
0494 storeRefInfo(kRefDisplacedVertexMotMask,
0495 kRefDisplacedVertexMotBit,
0496 iRef.isNonnull(),
0497 iRef.refCore(),
0498 iRef.key(),
0499 iRef.productGetter());
0500 else if ((type == T_FROM_DISP && !flag(T_FROM_DISP)) || (type == T_TO_DISP && !flag(T_TO_DISP))) {
0501 string err;
0502 err += "PFCandidate::setDisplacedVertexRef: particule flag is not switched on";
0503
0504 throw cms::Exception("InconsistentReference", err.c_str());
0505 }
0506 }
0507
0508 reco::PFDisplacedVertexRef PFCandidate::displacedVertexRef(Flags type) const {
0509 if (type == T_TO_DISP) {
0510 GETREF(reco::PFDisplacedVertex, kRefDisplacedVertexDauMask, kRefDisplacedVertexDauBit);
0511 } else if (type == T_FROM_DISP) {
0512 GETREF(reco::PFDisplacedVertex, kRefDisplacedVertexMotMask, kRefDisplacedVertexMotBit);
0513 }
0514 return reco::PFDisplacedVertexRef();
0515 }
0516
0517
0518 void PFCandidate::setConversionRef(reco::ConversionRef const& iRef) {
0519 if (particleId() != gamma) {
0520 string err;
0521 err += "PFCandidate::setConversionRef: this is not a (converted) photon ! particleId_=";
0522 char num[4];
0523 sprintf(num, "%d", particleId());
0524 err += num;
0525
0526 throw cms::Exception("InconsistentReference", err.c_str());
0527 } else if (!flag(GAMMA_TO_GAMMACONV)) {
0528 string err;
0529 err += "PFCandidate::setConversionRef: particule flag is not GAMMA_TO_GAMMACONV";
0530
0531 throw cms::Exception("InconsistentReference", err.c_str());
0532 }
0533
0534 storeRefInfo(
0535 kRefConversionMask, kRefConversionBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0536 }
0537
0538 reco::ConversionRef PFCandidate::conversionRef() const {
0539 GETREF(reco::Conversion, kRefConversionMask, kRefConversionBit);
0540 }
0541
0542
0543 void PFCandidate::setV0Ref(reco::VertexCompositeCandidateRef const& iRef) {
0544 storeRefInfo(kRefV0Mask, kRefV0Bit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0545 }
0546
0547 reco::VertexCompositeCandidateRef PFCandidate::v0Ref() const {
0548 GETREF(reco::VertexCompositeCandidate, kRefV0Mask, kRefV0Bit);
0549 }
0550
0551
0552 void PFCandidate::setGsfElectronRef(reco::GsfElectronRef const& iRef) {
0553 storeRefInfo(
0554 kRefGsfElectronMask, kRefGsfElectronBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0555 }
0556
0557 reco::GsfElectronRef PFCandidate::gsfElectronRef() const {
0558 GETREF(reco::GsfElectron, kRefGsfElectronMask, kRefGsfElectronBit);
0559 }
0560
0561
0562 void PFCandidate::setPFElectronExtraRef(reco::PFCandidateElectronExtraRef const& iRef) {
0563 storeRefInfo(kRefPFElectronExtraMask,
0564 kRefPFElectronExtraBit,
0565 iRef.isNonnull(),
0566 iRef.refCore(),
0567 iRef.key(),
0568 iRef.productGetter());
0569 }
0570
0571 reco::PFCandidateElectronExtraRef PFCandidate::electronExtraRef() const {
0572 GETREF(reco::PFCandidateElectronExtra, kRefPFElectronExtraMask, kRefPFElectronExtraBit);
0573 }
0574
0575 reco::PhotonRef PFCandidate::photonRef() const { GETREF(reco::Photon, kRefPhotonMask, kRefPhotonBit); }
0576
0577 reco::PFCandidatePhotonExtraRef PFCandidate::photonExtraRef() const {
0578 GETREF(reco::PFCandidatePhotonExtra, kRefPFPhotonExtraMask, kRefPFPhotonExtraBit);
0579 }
0580
0581 reco::PFCandidateEGammaExtraRef PFCandidate::egammaExtraRef() const {
0582 GETREF(reco::PFCandidateEGammaExtra, kRefPFEGammaExtraMask, kRefPFEGammaExtraBit);
0583 }
0584
0585 reco::SuperClusterRef PFCandidate::superClusterRef() const {
0586 GETREF(reco::SuperCluster, kRefSuperClusterMask, kRefSuperClusterBit);
0587 }
0588
0589 void PFCandidate::setPhotonRef(const reco::PhotonRef& iRef) {
0590 if (particleId() != gamma && particleId() != e) {
0591 string err;
0592 err += "PFCandidate::setSuperClusterRef: this is not an electron neither a photon ! particleId_=";
0593 char num[4];
0594 sprintf(num, "%d", particleId());
0595 err += num;
0596
0597 throw cms::Exception("InconsistentReference", err.c_str());
0598 }
0599
0600 storeRefInfo(kRefPhotonMask, kRefPhotonBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0601 }
0602
0603 void PFCandidate::setSuperClusterRef(const reco::SuperClusterRef& iRef) {
0604 if (particleId() != gamma && particleId() != e) {
0605 string err;
0606 err += "PFCandidate::setSuperClusterRef: this is not an electron neither a photon ! particleId_=";
0607 char num[4];
0608 sprintf(num, "%d", particleId());
0609 err += num;
0610
0611 throw cms::Exception("InconsistentReference", err.c_str());
0612 }
0613
0614 storeRefInfo(
0615 kRefSuperClusterMask, kRefSuperClusterBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0616 }
0617
0618 void PFCandidate::setPFPhotonExtraRef(const reco::PFCandidatePhotonExtraRef& iRef) {
0619 storeRefInfo(
0620 kRefPFPhotonExtraMask, kRefPFPhotonExtraBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0621 }
0622
0623 void PFCandidate::setPFEGammaExtraRef(const reco::PFCandidateEGammaExtraRef& iRef) {
0624 storeRefInfo(
0625 kRefPFEGammaExtraMask, kRefPFEGammaExtraBit, iRef.isNonnull(), iRef.refCore(), iRef.key(), iRef.productGetter());
0626 }
0627
0628 const math::XYZPoint& PFCandidate::vertexLegacy(PFCandidate::PFVertexType vertexType) const {
0629 switch (vertexType) {
0630 case kCandVertex:
0631 return LeafCandidate::vertex();
0632 break;
0633
0634 case kTrkVertex:
0635 return trackRef()->vertex();
0636 break;
0637 case kComMuonVertex:
0638 return muonRef()->combinedMuon()->vertex();
0639 break;
0640 case kSAMuonVertex:
0641 return muonRef()->standAloneMuon()->vertex();
0642 break;
0643 case kTrkMuonVertex:
0644 return muonRef()->track()->vertex();
0645 break;
0646 case kTPFMSMuonVertex:
0647 return muonRef()->tpfmsTrack()->vertex();
0648 break;
0649 case kPickyMuonVertex:
0650 return muonRef()->pickyTrack()->vertex();
0651 break;
0652 case kDYTMuonVertex:
0653 return muonRef()->dytTrack()->vertex();
0654 break;
0655
0656 case kGSFVertex:
0657 return gsfTrackRef()->vertex();
0658 break;
0659 }
0660 return LeafCandidate::vertex();
0661 }
0662
0663 const PFCandidate::ElementsInBlocks& PFCandidate::elementsInBlocks() const {
0664 if (nullptr == elementsInBlocks_.load(std::memory_order_acquire)) {
0665 std::unique_ptr<ElementsInBlocks> temp(new ElementsInBlocks(blocksStorage_.size()));
0666 for (unsigned int icopy = 0; icopy != blocksStorage_.size(); ++icopy)
0667 (*temp)[icopy] = std::make_pair(blocksStorage_[icopy], elementsStorage_[icopy]);
0668 ElementsInBlocks* expected = nullptr;
0669 if (elementsInBlocks_.compare_exchange_strong(expected, temp.get(), std::memory_order_acq_rel)) {
0670 temp.release();
0671 }
0672 }
0673 return *(elementsInBlocks_.load(std::memory_order_acquire));
0674 }