File indexing completed on 2024-04-09 02:22:09
0001 #include <memory>
0002
0003 #include "DataFormats/Common/interface/RefToPtr.h"
0004 #include "DataFormats/TauReco/interface/PFTau.h"
0005
0006
0007 namespace reco {
0008
0009 PFTau::PFTau() {
0010 leadPFChargedHadrCandsignedSipt_ = NAN;
0011 isolationPFChargedHadrCandsPtSum_ = NAN;
0012 isolationPFGammaCandsEtSum_ = NAN;
0013 maximumHCALPFClusterEt_ = NAN;
0014 emFraction_ = NAN;
0015 hcalTotOverPLead_ = NAN;
0016 hcalMaxOverPLead_ = NAN;
0017 hcal3x3OverPLead_ = NAN;
0018 ecalStripSumEOverPLead_ = NAN;
0019 bremsRecoveryEOverPLead_ = NAN;
0020 electronPreIDOutput_ = NAN;
0021 electronPreIDDecision_ = NAN;
0022 caloComp_ = NAN;
0023 segComp_ = NAN;
0024 muonDecision_ = NAN;
0025 decayMode_ = kNull;
0026 bendCorrMass_ = 0.;
0027 signalConeSize_ = 0.;
0028 }
0029
0030 PFTau::PFTau(Charge q, const LorentzVector& p4, const Point& vtx) : BaseTau(q, p4, vtx) {
0031 leadPFChargedHadrCandsignedSipt_ = NAN;
0032 isolationPFChargedHadrCandsPtSum_ = NAN;
0033 isolationPFGammaCandsEtSum_ = NAN;
0034 maximumHCALPFClusterEt_ = NAN;
0035
0036 emFraction_ = NAN;
0037 hcalTotOverPLead_ = NAN;
0038 hcalMaxOverPLead_ = NAN;
0039 hcal3x3OverPLead_ = NAN;
0040 ecalStripSumEOverPLead_ = NAN;
0041 bremsRecoveryEOverPLead_ = NAN;
0042 electronPreIDOutput_ = NAN;
0043 electronPreIDDecision_ = NAN;
0044
0045 caloComp_ = NAN;
0046 segComp_ = NAN;
0047 muonDecision_ = NAN;
0048 decayMode_ = kNull;
0049 bendCorrMass_ = 0.;
0050 signalConeSize_ = 0.;
0051 }
0052
0053 PFTau* PFTau::clone() const { return new PFTau(*this); }
0054
0055
0056 const JetBaseRef& PFTau::jetRef() const { return jetRef_; }
0057 void PFTau::setjetRef(const JetBaseRef& x) { jetRef_ = x; }
0058
0059 const PFTauTagInfoRef& PFTau::pfTauTagInfoRef() const { return PFTauTagInfoRef_; }
0060
0061 void PFTau::setpfTauTagInfoRef(const PFTauTagInfoRef x) { PFTauTagInfoRef_ = x; }
0062
0063 const CandidatePtr& PFTau::leadChargedHadrCand() const { return leadChargedHadrCand_; }
0064 const CandidatePtr& PFTau::leadNeutralCand() const { return leadNeutralCand_; }
0065 const CandidatePtr& PFTau::leadCand() const { return leadCand_; }
0066
0067 void PFTau::setleadChargedHadrCand(const CandidatePtr& myLead) { leadChargedHadrCand_ = myLead; }
0068 void PFTau::setleadNeutralCand(const CandidatePtr& myLead) { leadNeutralCand_ = myLead; }
0069 void PFTau::setleadCand(const CandidatePtr& myLead) { leadCand_ = myLead; }
0070
0071 float PFTau::leadPFChargedHadrCandsignedSipt() const { return leadPFChargedHadrCandsignedSipt_; }
0072 void PFTau::setleadPFChargedHadrCandsignedSipt(const float& x) { leadPFChargedHadrCandsignedSipt_ = x; }
0073
0074 const std::vector<CandidatePtr>& PFTau::signalCands() const { return selectedSignalCands_; }
0075 void PFTau::setsignalCands(const std::vector<CandidatePtr>& myParts) { selectedSignalCands_ = myParts; }
0076 const std::vector<CandidatePtr>& PFTau::signalChargedHadrCands() const { return selectedSignalChargedHadrCands_; }
0077 void PFTau::setsignalChargedHadrCands(const std::vector<CandidatePtr>& myParts) {
0078 selectedSignalChargedHadrCands_ = myParts;
0079 }
0080 const std::vector<CandidatePtr>& PFTau::signalNeutrHadrCands() const { return selectedSignalNeutrHadrCands_; }
0081 void PFTau::setsignalNeutrHadrCands(const std::vector<CandidatePtr>& myParts) {
0082 selectedSignalNeutrHadrCands_ = myParts;
0083 }
0084 const std::vector<CandidatePtr>& PFTau::signalGammaCands() const { return selectedSignalGammaCands_; }
0085 void PFTau::setsignalGammaCands(const std::vector<CandidatePtr>& myParts) { selectedSignalGammaCands_ = myParts; }
0086
0087 const std::vector<CandidatePtr>& PFTau::isolationCands() const { return selectedIsolationCands_; }
0088 void PFTau::setisolationCands(const std::vector<CandidatePtr>& myParts) { selectedIsolationCands_ = myParts; }
0089 const std::vector<CandidatePtr>& PFTau::isolationChargedHadrCands() const {
0090 return selectedIsolationChargedHadrCands_;
0091 }
0092 void PFTau::setisolationChargedHadrCands(const std::vector<CandidatePtr>& myParts) {
0093 selectedIsolationChargedHadrCands_ = myParts;
0094 }
0095 const std::vector<CandidatePtr>& PFTau::isolationNeutrHadrCands() const { return selectedIsolationNeutrHadrCands_; }
0096 void PFTau::setisolationNeutrHadrCands(const std::vector<CandidatePtr>& myParts) {
0097 selectedIsolationNeutrHadrCands_ = myParts;
0098 }
0099 const std::vector<CandidatePtr>& PFTau::isolationGammaCands() const { return selectedIsolationGammaCands_; }
0100 void PFTau::setisolationGammaCands(const std::vector<CandidatePtr>& myParts) {
0101 selectedIsolationGammaCands_ = myParts;
0102 }
0103
0104 namespace {
0105 template <typename T, typename U>
0106 void setCache(const T& iFrom, const edm::AtomicPtrCache<U>& oCache) {
0107 if (not oCache.isSet()) {
0108
0109 auto temp = std::make_unique<U>();
0110 temp->reserve(iFrom.size());
0111 for (auto const& ref : iFrom) {
0112 temp->push_back(*ref);
0113 }
0114 oCache.set(std::move(temp));
0115 }
0116 }
0117
0118 template <typename T>
0119 T& makeCacheIfNeeded(edm::AtomicPtrCache<T>& oCache) {
0120 if (not oCache.isSet()) {
0121 oCache.set(std::make_unique<T>());
0122 }
0123 return *oCache;
0124 }
0125
0126 template <typename T>
0127 void copyToCache(T&& iFrom, edm::AtomicPtrCache<T>& oCache) {
0128 oCache.reset();
0129 oCache.set(std::make_unique<T>(std::move(iFrom)));
0130 }
0131
0132 std::unique_ptr<reco::PFCandidatePtr> convertToPFPtr(const reco::CandidatePtr& ptr) {
0133 if (ptr.isNonnull()) {
0134 const reco::PFCandidate* pf_cand = dynamic_cast<const reco::PFCandidate*>(&*ptr);
0135 if (pf_cand != nullptr) {
0136 return std::make_unique<reco::PFCandidatePtr>(ptr);
0137 } else
0138 throw cms::Exception("Type Mismatch")
0139 << "This PFTau was not made from PFCandidates, but it is being tried to access a PFCandidate.\n";
0140 }
0141 return std::make_unique<reco::PFCandidatePtr>();
0142 }
0143
0144 std::unique_ptr<std::vector<reco::PFCandidatePtr> > convertToPFPtrs(const std::vector<reco::CandidatePtr>& cands) {
0145 std::unique_ptr<std::vector<reco::PFCandidatePtr> > newSignalPFCands{new std::vector<reco::PFCandidatePtr>{}};
0146 bool isPF = false;
0147 for (auto& cand : cands) {
0148
0149 if (!isPF) {
0150 const reco::PFCandidate* pf_cand = dynamic_cast<const reco::PFCandidate*>(&*cand);
0151 if (pf_cand != nullptr) {
0152 isPF = true;
0153 newSignalPFCands->reserve(cands.size());
0154 } else
0155 throw cms::Exception("Type Mismatch")
0156 << "This PFTau was not made from PFCandidates, but it is being tried to access PFCandidates.\n";
0157 }
0158 const auto& newPtr = edm::Ptr<reco::PFCandidate>(cand);
0159 newSignalPFCands->push_back(newPtr);
0160 }
0161 return newSignalPFCands;
0162 }
0163 }
0164
0165 const PFCandidatePtr PFTau::leadPFChargedHadrCand() const {
0166 if (!leadPFChargedHadrCand_.isSet())
0167 leadPFChargedHadrCand_.set(convertToPFPtr(leadChargedHadrCand_));
0168 return *leadPFChargedHadrCand_;
0169 }
0170
0171 const PFCandidatePtr PFTau::leadPFNeutralCand() const {
0172 if (!leadPFNeutralCand_.isSet())
0173 leadPFNeutralCand_.set(convertToPFPtr(leadNeutralCand_));
0174 return *leadPFNeutralCand_;
0175 }
0176
0177 const PFCandidatePtr PFTau::leadPFCand() const {
0178 if (!leadPFCand_.isSet())
0179 leadPFCand_.set(convertToPFPtr(leadCand_));
0180 return *leadPFCand_;
0181 }
0182
0183 const std::vector<reco::PFCandidatePtr>& PFTau::signalPFCands() const {
0184 if (!selectedTransientSignalPFCands_.isSet()) {
0185 selectedTransientSignalPFCands_.set(convertToPFPtrs(selectedSignalCands_));
0186 }
0187 return *selectedTransientSignalPFCands_;
0188 }
0189
0190 const std::vector<reco::PFCandidatePtr>& PFTau::signalPFChargedHadrCands() const {
0191 if (!selectedTransientSignalPFChargedHadrCands_.isSet()) {
0192 selectedTransientSignalPFChargedHadrCands_.set(convertToPFPtrs(selectedSignalChargedHadrCands_));
0193 }
0194 return *selectedTransientSignalPFChargedHadrCands_;
0195 }
0196
0197 const std::vector<reco::PFCandidatePtr>& PFTau::signalPFNeutrHadrCands() const {
0198 if (!selectedTransientSignalPFNeutrHadrCands_.isSet()) {
0199 selectedTransientSignalPFNeutrHadrCands_.set(convertToPFPtrs(selectedSignalNeutrHadrCands_));
0200 }
0201 return *selectedTransientSignalPFNeutrHadrCands_;
0202 }
0203
0204 const std::vector<reco::PFCandidatePtr>& PFTau::signalPFGammaCands() const {
0205 if (!selectedTransientSignalPFGammaCands_.isSet()) {
0206 selectedTransientSignalPFGammaCands_.set(convertToPFPtrs(selectedSignalGammaCands_));
0207 }
0208 return *selectedTransientSignalPFGammaCands_;
0209 }
0210
0211 const std::vector<reco::PFCandidatePtr>& PFTau::isolationPFCands() const {
0212 if (!selectedTransientIsolationPFCands_.isSet()) {
0213 selectedTransientIsolationPFCands_.set(convertToPFPtrs(selectedIsolationCands_));
0214 }
0215 return *selectedTransientIsolationPFCands_;
0216 }
0217
0218 const std::vector<reco::PFCandidatePtr>& PFTau::isolationPFChargedHadrCands() const {
0219 if (!selectedTransientIsolationPFChargedHadrCands_.isSet()) {
0220 selectedTransientIsolationPFChargedHadrCands_.set(convertToPFPtrs(selectedIsolationChargedHadrCands_));
0221 }
0222 return *selectedTransientIsolationPFChargedHadrCands_;
0223 }
0224
0225 const std::vector<reco::PFCandidatePtr>& PFTau::isolationPFNeutrHadrCands() const {
0226 if (!selectedTransientIsolationPFNeutrHadrCands_.isSet()) {
0227 selectedTransientIsolationPFNeutrHadrCands_.set(convertToPFPtrs(selectedIsolationNeutrHadrCands_));
0228 }
0229 return *selectedTransientIsolationPFNeutrHadrCands_;
0230 }
0231
0232 const std::vector<reco::PFCandidatePtr>& PFTau::isolationPFGammaCands() const {
0233 if (!selectedTransientIsolationPFGammaCands_.isSet()) {
0234 selectedTransientIsolationPFGammaCands_.set(convertToPFPtrs(selectedIsolationGammaCands_));
0235 }
0236 return *selectedTransientIsolationPFGammaCands_;
0237 }
0238
0239
0240 const std::vector<RecoTauPiZero>& PFTau::signalPiZeroCandidates() const {
0241
0242 setCache(signalPiZeroCandidatesRefs_, signalPiZeroCandidates_);
0243 return *signalPiZeroCandidates_;
0244 }
0245
0246 std::vector<RecoTauPiZero>& PFTau::signalPiZeroCandidatesRestricted() {
0247
0248 return makeCacheIfNeeded(signalPiZeroCandidates_);
0249 }
0250
0251 void PFTau::setsignalPiZeroCandidates(std::vector<RecoTauPiZero> cands) {
0252 copyToCache(std::move(cands), signalPiZeroCandidates_);
0253 }
0254
0255 void PFTau::setSignalPiZeroCandidatesRefs(RecoTauPiZeroRefVector cands) {
0256 signalPiZeroCandidatesRefs_ = std::move(cands);
0257 }
0258
0259 const std::vector<RecoTauPiZero>& PFTau::isolationPiZeroCandidates() const {
0260
0261 setCache(isolationPiZeroCandidatesRefs_, isolationPiZeroCandidates_);
0262 return *isolationPiZeroCandidates_;
0263 }
0264
0265 std::vector<RecoTauPiZero>& PFTau::isolationPiZeroCandidatesRestricted() {
0266
0267 return makeCacheIfNeeded(isolationPiZeroCandidates_);
0268 }
0269
0270 void PFTau::setIsolationPiZeroCandidatesRefs(RecoTauPiZeroRefVector cands) {
0271 isolationPiZeroCandidatesRefs_ = std::move(cands);
0272 }
0273
0274 void PFTau::setisolationPiZeroCandidates(std::vector<RecoTauPiZero> cands) {
0275 copyToCache(std::move(cands), signalPiZeroCandidates_);
0276 }
0277
0278
0279 PFRecoTauChargedHadronRef PFTau::leadTauChargedHadronCandidate() const {
0280 if (!signalTauChargedHadronCandidatesRefs_.empty()) {
0281 return signalTauChargedHadronCandidatesRefs_[0];
0282 } else {
0283 return PFRecoTauChargedHadronRef();
0284 }
0285 }
0286
0287 const std::vector<PFRecoTauChargedHadron>& PFTau::signalTauChargedHadronCandidates() const {
0288
0289 setCache(signalTauChargedHadronCandidatesRefs_, signalTauChargedHadronCandidates_);
0290 return *signalTauChargedHadronCandidates_;
0291 }
0292
0293 std::vector<PFRecoTauChargedHadron>& PFTau::signalTauChargedHadronCandidatesRestricted() {
0294
0295 return makeCacheIfNeeded(signalTauChargedHadronCandidates_);
0296 }
0297
0298 void PFTau::setSignalTauChargedHadronCandidates(std::vector<PFRecoTauChargedHadron> cands) {
0299 copyToCache(std::move(cands), signalTauChargedHadronCandidates_);
0300 }
0301
0302 void PFTau::setSignalTauChargedHadronCandidatesRefs(PFRecoTauChargedHadronRefVector cands) {
0303 signalTauChargedHadronCandidatesRefs_ = std::move(cands);
0304 }
0305
0306 const std::vector<PFRecoTauChargedHadron>& PFTau::isolationTauChargedHadronCandidates() const {
0307
0308 setCache(isolationTauChargedHadronCandidatesRefs_, isolationTauChargedHadronCandidates_);
0309 return *isolationTauChargedHadronCandidates_;
0310 }
0311
0312 std::vector<PFRecoTauChargedHadron>& PFTau::isolationTauChargedHadronCandidatesRestricted() {
0313
0314 return makeCacheIfNeeded(isolationTauChargedHadronCandidates_);
0315 }
0316
0317 void PFTau::setIsolationTauChargedHadronCandidates(std::vector<PFRecoTauChargedHadron> cands) {
0318 copyToCache(std::move(cands), isolationTauChargedHadronCandidates_);
0319 }
0320
0321 void PFTau::setIsolationTauChargedHadronCandidatesRefs(PFRecoTauChargedHadronRefVector cands) {
0322 isolationTauChargedHadronCandidatesRefs_ = std::move(cands);
0323 }
0324
0325 PFTau::hadronicDecayMode PFTau::decayMode() const { return decayMode_; }
0326
0327 void PFTau::setDecayMode(const PFTau::hadronicDecayMode& dm) { decayMode_ = dm; }
0328
0329
0330 float PFTau::isolationPFChargedHadrCandsPtSum() const { return isolationPFChargedHadrCandsPtSum_; }
0331 void PFTau::setisolationPFChargedHadrCandsPtSum(const float& x) { isolationPFChargedHadrCandsPtSum_ = x; }
0332
0333 float PFTau::isolationPFGammaCandsEtSum() const { return isolationPFGammaCandsEtSum_; }
0334 void PFTau::setisolationPFGammaCandsEtSum(const float& x) { isolationPFGammaCandsEtSum_ = x; }
0335
0336 float PFTau::maximumHCALPFClusterEt() const { return maximumHCALPFClusterEt_; }
0337 void PFTau::setmaximumHCALPFClusterEt(const float& x) { maximumHCALPFClusterEt_ = x; }
0338
0339
0340 float PFTau::emFraction() const { return emFraction_; }
0341 float PFTau::hcalTotOverPLead() const { return hcalTotOverPLead_; }
0342 float PFTau::hcalMaxOverPLead() const { return hcalMaxOverPLead_; }
0343 float PFTau::hcal3x3OverPLead() const { return hcal3x3OverPLead_; }
0344 float PFTau::ecalStripSumEOverPLead() const { return ecalStripSumEOverPLead_; }
0345 float PFTau::bremsRecoveryEOverPLead() const { return bremsRecoveryEOverPLead_; }
0346 reco::TrackRef PFTau::electronPreIDTrack() const { return electronPreIDTrack_; }
0347 float PFTau::electronPreIDOutput() const { return electronPreIDOutput_; }
0348 bool PFTau::electronPreIDDecision() const { return electronPreIDDecision_; }
0349
0350 void PFTau::setemFraction(const float& x) { emFraction_ = x; }
0351 void PFTau::sethcalTotOverPLead(const float& x) { hcalTotOverPLead_ = x; }
0352 void PFTau::sethcalMaxOverPLead(const float& x) { hcalMaxOverPLead_ = x; }
0353 void PFTau::sethcal3x3OverPLead(const float& x) { hcal3x3OverPLead_ = x; }
0354 void PFTau::setecalStripSumEOverPLead(const float& x) { ecalStripSumEOverPLead_ = x; }
0355 void PFTau::setbremsRecoveryEOverPLead(const float& x) { bremsRecoveryEOverPLead_ = x; }
0356 void PFTau::setelectronPreIDTrack(const reco::TrackRef& x) { electronPreIDTrack_ = x; }
0357 void PFTau::setelectronPreIDOutput(const float& x) { electronPreIDOutput_ = x; }
0358 void PFTau::setelectronPreIDDecision(const bool& x) { electronPreIDDecision_ = x; }
0359
0360
0361 bool PFTau::hasMuonReference() const {
0362 if (leadChargedHadrCand_.isNull())
0363 return false;
0364 else if (leadChargedHadrCand_.isNonnull()) {
0365 const reco::PFCandidate* pf_cand = dynamic_cast<const reco::PFCandidate*>(&*leadChargedHadrCand_);
0366 if (pf_cand) {
0367 reco::MuonRef muonRef = pf_cand->muonRef();
0368 if (muonRef.isNull())
0369 return false;
0370 else if (muonRef.isNonnull())
0371 return true;
0372 }
0373 }
0374 return false;
0375 }
0376
0377 float PFTau::caloComp() const { return caloComp_; }
0378 float PFTau::segComp() const { return segComp_; }
0379 bool PFTau::muonDecision() const { return muonDecision_; }
0380 void PFTau::setCaloComp(const float& x) { caloComp_ = x; }
0381 void PFTau::setSegComp(const float& x) { segComp_ = x; }
0382 void PFTau::setMuonDecision(const bool& x) { muonDecision_ = x; }
0383
0384 CandidatePtr PFTau::sourceCandidatePtr(size_type i) const {
0385 if (i != 0)
0386 return CandidatePtr();
0387 return jetRef().castTo<CandidatePtr>();
0388 }
0389
0390 bool PFTau::overlap(const Candidate& theCand) const {
0391 const RecoCandidate* theRecoCand = dynamic_cast<const RecoCandidate*>(&theCand);
0392 return (theRecoCand != nullptr && (checkOverlap(track(), theRecoCand->track())));
0393 }
0394
0395 void PFTau::dump(std::ostream& out) const {
0396 if (!out)
0397 return;
0398
0399 if (pfTauTagInfoRef().isNonnull()) {
0400 out << "Its TauTagInfo constituents :" << std::endl;
0401 out << "# Tracks " << pfTauTagInfoRef()->Tracks().size() << std::endl;
0402 out << "# PF charged hadr. cand's " << pfTauTagInfoRef()->PFChargedHadrCands().size() << std::endl;
0403 out << "# PF neutral hadr. cand's " << pfTauTagInfoRef()->PFNeutrHadrCands().size() << std::endl;
0404 out << "# PF gamma cand's " << pfTauTagInfoRef()->PFGammaCands().size() << std::endl;
0405 }
0406 out << "in detail :" << std::endl;
0407
0408 out << "Pt of the PFTau " << pt() << std::endl;
0409 const CandidatePtr& theLeadCand = leadChargedHadrCand();
0410 if (!theLeadCand) {
0411 out << "No Lead Cand " << std::endl;
0412 } else {
0413 out << "Lead Cand PDG Id " << (*theLeadCand).pdgId() << std::endl;
0414 out << "Lead Cand Pt " << (*theLeadCand).pt() << std::endl;
0415 out << "Lead Cand Charge " << (*theLeadCand).charge() << std::endl;
0416 out << "Inner point position (x,y,z) of the PFTau (" << vx() << "," << vy() << "," << vz() << ")" << std::endl;
0417 out << "Charge of the PFTau " << charge() << std::endl;
0418 out << "Et of the highest Et HCAL PFCluster " << maximumHCALPFClusterEt() << std::endl;
0419 out << "Number of SignalChargedHadrCands = " << signalChargedHadrCands().size() << std::endl;
0420 out << "Number of SignalGammaCands = " << signalGammaCands().size() << std::endl;
0421 out << "Number of IsolationChargedHadrCands = " << isolationChargedHadrCands().size() << std::endl;
0422 out << "Number of IsolationGammaCands = " << isolationGammaCands().size() << std::endl;
0423 out << "Sum of Pt of charged hadr. PFCandidates in isolation annulus around Lead PF = "
0424 << isolationPFChargedHadrCandsPtSum() << std::endl;
0425 out << "Sum of Et of gamma PFCandidates in other isolation annulus around Lead PF = "
0426 << isolationPFGammaCandsEtSum() << std::endl;
0427 }
0428
0429 }
0430
0431 std::ostream& operator<<(std::ostream& out, const reco::PFTau& tau) {
0432 if (!out)
0433 return out;
0434
0435 out << std::setprecision(3) << "PFTau "
0436 << " charge: " << tau.charge() << " "
0437 << " pt:" << tau.pt() << " "
0438 << " eta:" << tau.eta() << " "
0439 << " phi:" << tau.phi() << " "
0440 << " mass:" << tau.mass() << " "
0441 << " dm: " << tau.decayMode() << " " << tau.signalCands().size() << "," << tau.signalChargedHadrCands().size()
0442 << "," << tau.signalGammaCands().size() << "," << tau.signalPiZeroCandidates().size() << ","
0443 << tau.signalNeutrHadrCands().size() << " "
0444
0445 << tau.isolationCands().size() << "," << tau.isolationChargedHadrCands().size() << ","
0446 << tau.isolationGammaCands().size() << "," << tau.isolationPiZeroCandidates().size() << ","
0447 << tau.isolationNeutrHadrCands().size();
0448
0449 return out;
0450 }
0451
0452 }