File indexing completed on 2024-04-06 12:04:59
0001
0002
0003
0004 #include "DataFormats/PatCandidates/interface/Tau.h"
0005 #include "DataFormats/JetReco/interface/GenJet.h"
0006 #include "DataFormats/PatCandidates/interface/PackedCandidate.h"
0007 #include <algorithm>
0008 #include <functional>
0009
0010 using namespace pat;
0011 using namespace std::placeholders;
0012
0013
0014 Tau::Tau()
0015 : Lepton<reco::BaseTau>(),
0016 embeddedIsolationTracks_(false),
0017 embeddedLeadTrack_(false),
0018 embeddedSignalTracks_(false),
0019 embeddedLeadPFCand_(false),
0020 embeddedLeadPFChargedHadrCand_(false),
0021 embeddedLeadPFNeutralCand_(false),
0022 embeddedSignalPFCands_(false),
0023 embeddedSignalPFChargedHadrCands_(false),
0024 embeddedSignalPFNeutralHadrCands_(false),
0025 embeddedSignalPFGammaCands_(false),
0026 embeddedIsolationPFCands_(false),
0027 embeddedIsolationPFChargedHadrCands_(false),
0028 embeddedIsolationPFNeutralHadrCands_(false),
0029 embeddedIsolationPFGammaCands_(false) {}
0030
0031
0032 Tau::Tau(const reco::BaseTau& aTau)
0033 : Lepton<reco::BaseTau>(aTau),
0034 embeddedIsolationTracks_(false),
0035 embeddedLeadTrack_(false),
0036 embeddedSignalTracks_(false),
0037 embeddedLeadPFCand_(false),
0038 embeddedLeadPFChargedHadrCand_(false),
0039 embeddedLeadPFNeutralCand_(false),
0040 embeddedSignalPFCands_(false),
0041 embeddedSignalPFChargedHadrCands_(false),
0042 embeddedSignalPFNeutralHadrCands_(false),
0043 embeddedSignalPFGammaCands_(false),
0044 embeddedIsolationPFCands_(false),
0045 embeddedIsolationPFChargedHadrCands_(false),
0046 embeddedIsolationPFNeutralHadrCands_(false),
0047 embeddedIsolationPFGammaCands_(false) {
0048 initFromBaseTau(aTau);
0049 }
0050
0051
0052 Tau::Tau(const edm::RefToBase<reco::BaseTau>& aTauRef)
0053 : Lepton<reco::BaseTau>(aTauRef),
0054 embeddedIsolationTracks_(false),
0055 embeddedLeadTrack_(false),
0056 embeddedSignalTracks_(false),
0057 embeddedLeadPFCand_(false),
0058 embeddedLeadPFChargedHadrCand_(false),
0059 embeddedLeadPFNeutralCand_(false),
0060 embeddedSignalPFCands_(false),
0061 embeddedSignalPFChargedHadrCands_(false),
0062 embeddedSignalPFNeutralHadrCands_(false),
0063 embeddedSignalPFGammaCands_(false),
0064 embeddedIsolationPFCands_(false),
0065 embeddedIsolationPFChargedHadrCands_(false),
0066 embeddedIsolationPFNeutralHadrCands_(false),
0067 embeddedIsolationPFGammaCands_(false) {
0068 initFromBaseTau(*aTauRef);
0069 }
0070
0071
0072 Tau::Tau(const edm::Ptr<reco::BaseTau>& aTauRef)
0073 : Lepton<reco::BaseTau>(aTauRef),
0074 embeddedIsolationTracks_(false),
0075 embeddedLeadTrack_(false),
0076 embeddedSignalTracks_(false),
0077 embeddedLeadPFCand_(false),
0078 embeddedLeadPFChargedHadrCand_(false),
0079 embeddedLeadPFNeutralCand_(false),
0080 embeddedSignalPFCands_(false),
0081 embeddedSignalPFChargedHadrCands_(false),
0082 embeddedSignalPFNeutralHadrCands_(false),
0083 embeddedSignalPFGammaCands_(false),
0084 embeddedIsolationPFCands_(false),
0085 embeddedIsolationPFChargedHadrCands_(false),
0086 embeddedIsolationPFNeutralHadrCands_(false),
0087 embeddedIsolationPFGammaCands_(false) {
0088 initFromBaseTau(*aTauRef);
0089 }
0090
0091 void Tau::initFromBaseTau(const reco::BaseTau& aTau) {
0092 const reco::PFTau* pfTau = dynamic_cast<const reco::PFTau*>(&aTau);
0093 if (pfTau != nullptr) {
0094
0095
0096 const pat::PackedCandidate* pc = dynamic_cast<const pat::PackedCandidate*>(pfTau->leadChargedHadrCand().get());
0097 if (pc != nullptr) {
0098 for (const auto& ptr : pfTau->signalChargedHadrCands())
0099 signalChargedHadrCandPtrs_.push_back(ptr);
0100
0101 for (const auto& ptr : pfTau->signalNeutrHadrCands())
0102 signalNeutralHadrCandPtrs_.push_back(ptr);
0103
0104 for (const auto& ptr : pfTau->signalGammaCands())
0105 signalGammaCandPtrs_.push_back(ptr);
0106
0107 for (const auto& ptr : pfTau->isolationChargedHadrCands())
0108 isolationChargedHadrCandPtrs_.push_back(ptr);
0109
0110 for (const auto& ptr : pfTau->isolationNeutrHadrCands())
0111 isolationNeutralHadrCandPtrs_.push_back(ptr);
0112
0113 for (const auto& ptr : pfTau->isolationGammaCands())
0114 isolationGammaCandPtrs_.push_back(ptr);
0115
0116 std::vector<reco::CandidatePtr> signalLostTracks;
0117 for (const auto& chargedHadron : pfTau->signalTauChargedHadronCandidates()) {
0118 if (chargedHadron.algoIs(reco::PFRecoTauChargedHadron::kTrack) &&
0119 chargedHadron.getLostTrackCandidate().isNonnull()) {
0120 signalLostTracks.push_back(chargedHadron.getLostTrackCandidate());
0121 }
0122 }
0123 this->setSignalLostTracks(signalLostTracks);
0124 } else {
0125 pfSpecific_.push_back(pat::tau::TauPFSpecific(*pfTau));
0126 }
0127 pfEssential_.push_back(pat::tau::TauPFEssential(*pfTau));
0128 }
0129 }
0130
0131
0132 Tau::~Tau() {}
0133
0134 std::ostream& reco::operator<<(std::ostream& out, const pat::Tau& obj) {
0135 if (!out)
0136 return out;
0137
0138 out << "\tpat::Tau: ";
0139 out << std::setiosflags(std::ios::right);
0140 out << std::setiosflags(std::ios::fixed);
0141 out << std::setprecision(3);
0142 out << " E/pT/eta/phi " << obj.energy() << "/" << obj.pt() << "/" << obj.eta() << "/" << obj.phi();
0143 return out;
0144 }
0145
0146
0147 const reco::TrackRefVector& Tau::isolationTracks() const {
0148 if (embeddedIsolationTracks_) {
0149 if (!isolationTracksTransientRefVector_.isSet()) {
0150 std::unique_ptr<reco::TrackRefVector> trackRefVec{new reco::TrackRefVector{}};
0151 trackRefVec->reserve(isolationTracks_.size());
0152 for (unsigned int i = 0; i < isolationTracks_.size(); i++) {
0153 trackRefVec->push_back(reco::TrackRef(&isolationTracks_, i));
0154 }
0155 isolationTracksTransientRefVector_.set(std::move(trackRefVec));
0156 }
0157 return *isolationTracksTransientRefVector_;
0158 } else {
0159 return reco::BaseTau::isolationTracks();
0160 }
0161 }
0162
0163
0164 reco::TrackRef Tau::leadTrack() const {
0165 if (embeddedLeadTrack_) {
0166 return reco::TrackRef(&leadTrack_, 0);
0167 } else {
0168 return reco::BaseTau::leadTrack();
0169 }
0170 }
0171
0172
0173 const reco::TrackRefVector& Tau::signalTracks() const {
0174 if (embeddedSignalTracks_) {
0175 if (!signalTracksTransientRefVector_.isSet()) {
0176 std::unique_ptr<reco::TrackRefVector> trackRefVec{new reco::TrackRefVector{}};
0177 trackRefVec->reserve(signalTracks_.size());
0178 for (unsigned int i = 0; i < signalTracks_.size(); i++) {
0179 trackRefVec->push_back(reco::TrackRef(&signalTracks_, i));
0180 }
0181 signalTracksTransientRefVector_.set(std::move(trackRefVec));
0182 }
0183 return *signalTracksTransientRefVector_;
0184 } else {
0185 return reco::BaseTau::signalTracks();
0186 }
0187 }
0188
0189
0190 void Tau::embedIsolationTracks() {
0191 isolationTracks_.clear();
0192 reco::TrackRefVector trackRefVec = reco::BaseTau::isolationTracks();
0193 for (unsigned int i = 0; i < trackRefVec.size(); i++) {
0194 isolationTracks_.push_back(*trackRefVec.at(i));
0195 }
0196 embeddedIsolationTracks_ = true;
0197 }
0198
0199
0200 void Tau::embedLeadTrack() {
0201 leadTrack_.clear();
0202 if (reco::BaseTau::leadTrack().isNonnull()) {
0203 leadTrack_.push_back(*reco::BaseTau::leadTrack());
0204 embeddedLeadTrack_ = true;
0205 }
0206 }
0207
0208
0209 void Tau::embedSignalTracks() {
0210 signalTracks_.clear();
0211 reco::TrackRefVector trackRefVec = reco::BaseTau::signalTracks();
0212 for (unsigned int i = 0; i < trackRefVec.size(); i++) {
0213 signalTracks_.push_back(*trackRefVec.at(i));
0214 }
0215 embeddedSignalTracks_ = true;
0216 }
0217
0218
0219 void Tau::setGenJet(const reco::GenJetRef& gj) {
0220 genJet_.clear();
0221 genJet_.push_back(*gj);
0222 }
0223
0224
0225 const reco::GenJet* Tau::genJet() const { return (!genJet_.empty() ? &genJet_.front() : nullptr); }
0226
0227
0228 float Tau::tauID(const std::string& name) const {
0229 for (std::vector<IdPair>::const_iterator it = tauIDs_.begin(), ed = tauIDs_.end(); it != ed; ++it) {
0230 if (it->first == name)
0231 return it->second;
0232 }
0233 cms::Exception ex("Key not found");
0234 ex << "pat::Tau: the ID " << name << " can't be found in this pat::Tau.\n";
0235 ex << "The available IDs are: ";
0236 for (std::vector<IdPair>::const_iterator it = tauIDs_.begin(), ed = tauIDs_.end(); it != ed; ++it) {
0237 ex << "'" << it->first << "' ";
0238 }
0239 ex << ".\n";
0240 throw ex;
0241 }
0242
0243 bool Tau::isTauIDAvailable(const std::string& name) const {
0244 for (std::vector<IdPair>::const_iterator it = tauIDs_.begin(), ed = tauIDs_.end(); it != ed; ++it) {
0245 if (it->first == name)
0246 return true;
0247 }
0248 return false;
0249 }
0250
0251 const pat::tau::TauPFSpecific& Tau::pfSpecific() const {
0252 if (!isPFTau())
0253 throw cms::Exception("Type Error")
0254 << "Requesting a PFTau-specific information from a pat::Tau which wasn't made from a PFTau.\n";
0255 return pfSpecific_[0];
0256 }
0257
0258 const pat::tau::TauPFEssential& Tau::pfEssential() const {
0259 if (pfEssential_.empty())
0260 throw cms::Exception("Type Error")
0261 << "Requesting a PFTau-specific information from a pat::Tau which wasn't made from a PFTau.\n";
0262 return pfEssential_[0];
0263 }
0264
0265 reco::Candidate::LorentzVector Tau::p4Jet() const {
0266 if (isPFTau())
0267 return reco::Candidate::LorentzVector(pfEssential().p4Jet_);
0268 throw cms::Exception("Type Error") << "Requesting a PFTau-specific information from a pat::Tau which wasn't "
0269 "made from a PFTau.\n";
0270 }
0271
0272 float Tau::dxy_Sig() const {
0273 if (pfEssential().dxy_error_ != 0)
0274 return (pfEssential().dxy_ / pfEssential().dxy_error_);
0275 else
0276 return 0.;
0277 }
0278
0279 pat::tau::TauPFEssential::CovMatrix Tau::flightLengthCov() const {
0280 pat::tau::TauPFEssential::CovMatrix cov;
0281 const pat::tau::TauPFEssential::CovMatrix& sv = secondaryVertexCov();
0282 const pat::tau::TauPFEssential::CovMatrix& pv = primaryVertexCov();
0283 for (int i = 0; i < dimension; ++i) {
0284 for (int j = 0; j < dimension; ++j) {
0285 cov(i, j) = sv(i, j) + pv(i, j);
0286 }
0287 }
0288 return cov;
0289 }
0290
0291 float Tau::ip3d_Sig() const {
0292 if (pfEssential().ip3d_error_ != 0)
0293 return (pfEssential().ip3d_ / pfEssential().ip3d_error_);
0294 else
0295 return 0.;
0296 }
0297
0298 float Tau::etaetaMoment() const {
0299 if (isPFTau())
0300 return pfSpecific().etaetaMoment_;
0301 throw cms::Exception("Type Error") << "Requesting a PFTau-specific information from a pat::Tau which wasn't "
0302 "made from a PFTau.\n";
0303 }
0304
0305 float Tau::phiphiMoment() const {
0306 if (isPFTau())
0307 return pfSpecific().phiphiMoment_;
0308 throw cms::Exception("Type Error") << "Requesting a PFTau-specific information from a pat::Tau which wasn't "
0309 "made from a PFTau.\n";
0310 }
0311
0312 float Tau::etaphiMoment() const {
0313 if (isPFTau())
0314 return pfSpecific().etaphiMoment_;
0315 throw cms::Exception("Type Error") << "Requesting a PFTau-specific information from a pat::Tau which wasn't "
0316 "made from a PFTau.\n";
0317 }
0318
0319 void Tau::setDecayMode(int decayMode) {
0320 if (!isPFTau())
0321 throw cms::Exception("Type Error")
0322 << "Requesting a PFTau-specific information from a pat::Tau which wasn't made from a PFTau.\n";
0323 pfEssential_[0].decayMode_ = decayMode;
0324 }
0325
0326
0327 void Tau::embedLeadPFCand() {
0328 if (!isPFTau()) {
0329 return;
0330 }
0331 leadPFCand_.clear();
0332 if (pfSpecific_[0].leadPFCand_.isNonnull()) {
0333 leadPFCand_.push_back(*static_cast<const reco::PFCandidate*>(&*pfSpecific_[0].leadPFCand_));
0334 embeddedLeadPFCand_ = true;
0335 }
0336 }
0337
0338 void Tau::embedLeadPFChargedHadrCand() {
0339 if (!isPFTau()) {
0340 return;
0341 }
0342 leadPFChargedHadrCand_.clear();
0343 if (pfSpecific_[0].leadPFChargedHadrCand_.isNonnull()) {
0344 leadPFChargedHadrCand_.push_back(
0345 *static_cast<const reco::PFCandidate*>(&*pfSpecific_[0].leadPFChargedHadrCand_));
0346 embeddedLeadPFChargedHadrCand_ = true;
0347 }
0348 }
0349
0350 void Tau::embedLeadPFNeutralCand() {
0351 if (!isPFTau()) {
0352 return;
0353 }
0354 leadPFNeutralCand_.clear();
0355 if (pfSpecific_[0].leadPFNeutralCand_.isNonnull()) {
0356 leadPFNeutralCand_.push_back(
0357 *static_cast<const reco::PFCandidate*>(&*pfSpecific_[0].leadPFNeutralCand_));
0358 embeddedLeadPFNeutralCand_ = true;
0359 }
0360 }
0361
0362 void Tau::embedSignalPFCands() {
0363 if (!isPFTau()) {
0364 return;
0365 }
0366 std::vector<reco::PFCandidatePtr> candPtrs = pfSpecific_[0].selectedSignalPFCands_;
0367 for (unsigned int i = 0; i < candPtrs.size(); i++) {
0368 signalPFCands_.push_back(candPtrs.at(i));
0369 }
0370 embeddedSignalPFCands_ = true;
0371 }
0372 void Tau::embedSignalPFChargedHadrCands() {
0373 if (!isPFTau()) {
0374 return;
0375 }
0376 std::vector<reco::PFCandidatePtr> candPtrs = pfSpecific_[0].selectedSignalPFChargedHadrCands_;
0377 for (unsigned int i = 0; i < candPtrs.size(); i++) {
0378 signalPFChargedHadrCands_.push_back(candPtrs.at(i));
0379 }
0380 embeddedSignalPFChargedHadrCands_ = true;
0381 }
0382 void Tau::embedSignalPFNeutralHadrCands() {
0383 if (!isPFTau()) {
0384 return;
0385 }
0386 std::vector<reco::PFCandidatePtr> candPtrs = pfSpecific_[0].selectedSignalPFNeutrHadrCands_;
0387 for (unsigned int i = 0; i < candPtrs.size(); i++) {
0388 signalPFNeutralHadrCands_.push_back(candPtrs.at(i));
0389 }
0390 embeddedSignalPFNeutralHadrCands_ = true;
0391 }
0392 void Tau::embedSignalPFGammaCands() {
0393 if (!isPFTau()) {
0394 return;
0395 }
0396 std::vector<reco::PFCandidatePtr> candPtrs = pfSpecific_[0].selectedSignalPFGammaCands_;
0397 for (unsigned int i = 0; i < candPtrs.size(); i++) {
0398 signalPFGammaCands_.push_back(candPtrs.at(i));
0399 }
0400 embeddedSignalPFGammaCands_ = true;
0401 }
0402
0403 void Tau::embedIsolationPFCands() {
0404 if (!isPFTau()) {
0405 return;
0406 }
0407 std::vector<reco::PFCandidatePtr> candPtrs = pfSpecific_[0].selectedIsolationPFCands_;
0408 for (unsigned int i = 0; i < candPtrs.size(); i++) {
0409 isolationPFCands_.push_back(candPtrs.at(i));
0410 }
0411 embeddedIsolationPFCands_ = true;
0412 }
0413
0414 void Tau::embedIsolationPFChargedHadrCands() {
0415 if (!isPFTau()) {
0416 return;
0417 }
0418 std::vector<reco::PFCandidatePtr> candPtrs = pfSpecific_[0].selectedIsolationPFChargedHadrCands_;
0419 for (unsigned int i = 0; i < candPtrs.size(); i++) {
0420 isolationPFChargedHadrCands_.push_back(candPtrs.at(i));
0421 }
0422 embeddedIsolationPFChargedHadrCands_ = true;
0423 }
0424 void Tau::embedIsolationPFNeutralHadrCands() {
0425 if (!isPFTau()) {
0426 return;
0427 }
0428 std::vector<reco::PFCandidatePtr> candPtrs = pfSpecific_[0].selectedIsolationPFNeutrHadrCands_;
0429 for (unsigned int i = 0; i < candPtrs.size(); i++) {
0430 isolationPFNeutralHadrCands_.push_back(candPtrs.at(i));
0431 }
0432 embeddedIsolationPFNeutralHadrCands_ = true;
0433 }
0434 void Tau::embedIsolationPFGammaCands() {
0435 if (!isPFTau()) {
0436 return;
0437 }
0438 std::vector<reco::PFCandidatePtr> candPtrs = pfSpecific_[0].selectedIsolationPFGammaCands_;
0439 for (unsigned int i = 0; i < candPtrs.size(); i++) {
0440 isolationPFGammaCands_.push_back(candPtrs.at(i));
0441 }
0442 embeddedIsolationPFGammaCands_ = true;
0443 }
0444
0445 reco::PFRecoTauChargedHadronRef Tau::leadTauChargedHadronCandidate() const {
0446 if (!isPFTau())
0447 throw cms::Exception("Type Error") << "Requesting content that is not stored in miniAOD.\n";
0448 if (!pfSpecific().signalTauChargedHadronCandidates_.empty()) {
0449 return reco::PFRecoTauChargedHadronRef(&pfSpecific().signalTauChargedHadronCandidates_, 0);
0450 } else {
0451 return reco::PFRecoTauChargedHadronRef();
0452 }
0453 }
0454
0455 const reco::PFCandidatePtr convertToPFCandidatePtr(const reco::CandidatePtr& ptr) {
0456 const reco::PFCandidate* pf_cand = dynamic_cast<const reco::PFCandidate*>(&*ptr);
0457 if (pf_cand)
0458 return edm::Ptr<reco::PFCandidate>(ptr);
0459 return reco::PFCandidatePtr();
0460 }
0461
0462 const reco::PFCandidatePtr Tau::leadPFChargedHadrCand() const {
0463 if (!embeddedLeadPFChargedHadrCand_) {
0464 if (pfSpecific_.empty())
0465 return reco::PFCandidatePtr();
0466 else
0467 return convertToPFCandidatePtr(pfSpecific().leadPFChargedHadrCand_);
0468 } else
0469 return reco::PFCandidatePtr(&leadPFChargedHadrCand_, 0);
0470 }
0471
0472 const reco::PFCandidatePtr Tau::leadPFNeutralCand() const {
0473 if (!embeddedLeadPFNeutralCand_) {
0474 if (pfSpecific_.empty())
0475 return reco::PFCandidatePtr();
0476 else
0477 return convertToPFCandidatePtr(pfSpecific().leadPFNeutralCand_);
0478 } else
0479 return reco::PFCandidatePtr(&leadPFNeutralCand_, 0);
0480 }
0481
0482 const reco::PFCandidatePtr Tau::leadPFCand() const {
0483 if (!embeddedLeadPFCand_) {
0484 if (pfSpecific_.empty())
0485 return reco::PFCandidatePtr();
0486 return convertToPFCandidatePtr(pfSpecific().leadPFCand_);
0487 } else
0488 return reco::PFCandidatePtr(&leadPFCand_, 0);
0489 }
0490
0491 const std::vector<reco::PFCandidatePtr>& Tau::signalPFCands() const {
0492 if (embeddedSignalPFCands_) {
0493 if (!signalPFCandsTransientPtrs_.isSet()) {
0494 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0495 aPtrs->reserve(signalPFCands_.size());
0496 for (unsigned int i = 0; i < signalPFCands_.size(); i++) {
0497 aPtrs->push_back(reco::PFCandidatePtr(&signalPFCands_, i));
0498 }
0499 signalPFCandsTransientPtrs_.set(std::move(aPtrs));
0500 }
0501 return *signalPFCandsTransientPtrs_;
0502 } else {
0503 if (pfSpecific_.empty() || pfSpecific().selectedSignalPFCands_.empty() ||
0504 !pfSpecific().selectedSignalPFCands_.front().isAvailable()) {
0505
0506
0507 if (!signalPFCandsTransientPtrs_.isSet()) {
0508 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0509 signalPFCandsTransientPtrs_.set(std::move(aPtrs));
0510 }
0511 return *signalPFCandsTransientPtrs_;
0512 } else
0513 return pfSpecific().selectedSignalPFCands_;
0514 }
0515 }
0516
0517 const std::vector<reco::PFCandidatePtr>& Tau::signalPFChargedHadrCands() const {
0518 if (embeddedSignalPFChargedHadrCands_) {
0519 if (!signalPFChargedHadrCandsTransientPtrs_.isSet()) {
0520 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0521 aPtrs->reserve(signalPFChargedHadrCands_.size());
0522 for (unsigned int i = 0; i < signalPFChargedHadrCands_.size(); i++) {
0523 aPtrs->push_back(reco::PFCandidatePtr(&signalPFChargedHadrCands_, i));
0524 }
0525 signalPFChargedHadrCandsTransientPtrs_.set(std::move(aPtrs));
0526 }
0527 return *signalPFChargedHadrCandsTransientPtrs_;
0528 } else {
0529 if (pfSpecific_.empty() || pfSpecific().selectedSignalPFChargedHadrCands_.empty() ||
0530 !pfSpecific().selectedSignalPFChargedHadrCands_.front().isAvailable()) {
0531
0532
0533 if (!signalPFChargedHadrCandsTransientPtrs_.isSet()) {
0534 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0535 signalPFChargedHadrCandsTransientPtrs_.set(std::move(aPtrs));
0536 }
0537 return *signalPFChargedHadrCandsTransientPtrs_;
0538 } else
0539 return pfSpecific().selectedSignalPFChargedHadrCands_;
0540 }
0541 }
0542
0543 const std::vector<reco::PFCandidatePtr>& Tau::signalPFNeutrHadrCands() const {
0544 if (embeddedSignalPFNeutralHadrCands_) {
0545 if (!signalPFNeutralHadrCandsTransientPtrs_.isSet()) {
0546 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0547 aPtrs->reserve(signalPFNeutralHadrCands_.size());
0548 for (unsigned int i = 0; i < signalPFNeutralHadrCands_.size(); i++) {
0549 aPtrs->push_back(reco::PFCandidatePtr(&signalPFNeutralHadrCands_, i));
0550 }
0551 signalPFNeutralHadrCandsTransientPtrs_.set(std::move(aPtrs));
0552 }
0553 return *signalPFNeutralHadrCandsTransientPtrs_;
0554 } else {
0555 if (pfSpecific_.empty() || pfSpecific().selectedSignalPFNeutrHadrCands_.empty() ||
0556 !pfSpecific().selectedSignalPFNeutrHadrCands_.front().isAvailable()) {
0557
0558
0559 if (!signalPFNeutralHadrCandsTransientPtrs_.isSet()) {
0560 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0561 signalPFNeutralHadrCandsTransientPtrs_.set(std::move(aPtrs));
0562 }
0563 return *signalPFNeutralHadrCandsTransientPtrs_;
0564 } else
0565 return pfSpecific().selectedSignalPFNeutrHadrCands_;
0566 }
0567 }
0568
0569 const std::vector<reco::PFCandidatePtr>& Tau::signalPFGammaCands() const {
0570 if (embeddedSignalPFGammaCands_) {
0571 if (!signalPFGammaCandsTransientPtrs_.isSet()) {
0572 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0573 aPtrs->reserve(signalPFGammaCands_.size());
0574 for (unsigned int i = 0; i < signalPFGammaCands_.size(); i++) {
0575 aPtrs->push_back(reco::PFCandidatePtr(&signalPFGammaCands_, i));
0576 }
0577 signalPFGammaCandsTransientPtrs_.set(std::move(aPtrs));
0578 }
0579 return *signalPFGammaCandsTransientPtrs_;
0580 } else {
0581 if (pfSpecific_.empty() || pfSpecific().selectedSignalPFGammaCands_.empty() ||
0582 !pfSpecific().selectedSignalPFGammaCands_.front().isAvailable()) {
0583
0584
0585 if (!signalPFGammaCandsTransientPtrs_.isSet()) {
0586 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0587 signalPFGammaCandsTransientPtrs_.set(std::move(aPtrs));
0588 }
0589 return *signalPFGammaCandsTransientPtrs_;
0590 } else
0591 return pfSpecific().selectedSignalPFGammaCands_;
0592 }
0593 }
0594
0595 const std::vector<reco::PFRecoTauChargedHadron>& Tau::signalTauChargedHadronCandidates() const {
0596 if (pfSpecific_.empty())
0597 throw cms::Exception("Type Error") << "Requesting content that is not stored in miniAOD.\n";
0598 return pfSpecific().signalTauChargedHadronCandidates_;
0599 }
0600
0601 const std::vector<reco::RecoTauPiZero>& Tau::signalPiZeroCandidates() const {
0602 if (pfSpecific_.empty())
0603 throw cms::Exception("Type Error") << "Requesting content that is not stored in miniAOD.\n";
0604 return pfSpecific().signalPiZeroCandidates_;
0605 }
0606
0607 const std::vector<reco::PFCandidatePtr>& Tau::isolationPFCands() const {
0608 if (embeddedIsolationPFCands_) {
0609 if (!isolationPFCandsTransientPtrs_.isSet()) {
0610 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0611 aPtrs->reserve(isolationPFCands_.size());
0612 for (unsigned int i = 0; i < isolationPFCands_.size(); i++) {
0613 aPtrs->push_back(reco::PFCandidatePtr(&isolationPFCands_, i));
0614 }
0615 isolationPFCandsTransientPtrs_.set(std::move(aPtrs));
0616 }
0617 return *isolationPFCandsTransientPtrs_;
0618 } else {
0619 if (pfSpecific_.empty() || pfSpecific().selectedIsolationPFCands_.empty() ||
0620 !pfSpecific().selectedIsolationPFCands_.front().isAvailable()) {
0621
0622
0623 if (!isolationPFCandsTransientPtrs_.isSet()) {
0624 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0625 isolationPFCandsTransientPtrs_.set(std::move(aPtrs));
0626 }
0627 return *isolationPFCandsTransientPtrs_;
0628 } else
0629 return pfSpecific().selectedIsolationPFCands_;
0630 }
0631 }
0632
0633 const std::vector<reco::PFCandidatePtr>& Tau::isolationPFChargedHadrCands() const {
0634 if (embeddedIsolationPFChargedHadrCands_) {
0635 if (!isolationPFChargedHadrCandsTransientPtrs_.isSet()) {
0636 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0637 aPtrs->reserve(isolationPFChargedHadrCands_.size());
0638 for (unsigned int i = 0; i < isolationPFChargedHadrCands_.size(); i++) {
0639 aPtrs->push_back(reco::PFCandidatePtr(&isolationPFChargedHadrCands_, i));
0640 }
0641 isolationPFChargedHadrCandsTransientPtrs_.set(std::move(aPtrs));
0642 }
0643 return *isolationPFChargedHadrCandsTransientPtrs_;
0644 } else {
0645 if (pfSpecific_.empty() || pfSpecific().selectedIsolationPFChargedHadrCands_.empty() ||
0646 !pfSpecific().selectedIsolationPFChargedHadrCands_.front().isAvailable()) {
0647
0648
0649 if (!isolationPFChargedHadrCandsTransientPtrs_.isSet()) {
0650 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0651 isolationPFChargedHadrCandsTransientPtrs_.set(std::move(aPtrs));
0652 }
0653 return *isolationPFChargedHadrCandsTransientPtrs_;
0654 } else
0655 return pfSpecific().selectedIsolationPFChargedHadrCands_;
0656 }
0657 }
0658
0659 const std::vector<reco::PFCandidatePtr>& Tau::isolationPFNeutrHadrCands() const {
0660 if (embeddedIsolationPFNeutralHadrCands_) {
0661 if (!isolationPFNeutralHadrCandsTransientPtrs_.isSet()) {
0662 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0663 aPtrs->reserve(isolationPFNeutralHadrCands_.size());
0664 for (unsigned int i = 0; i < isolationPFNeutralHadrCands_.size(); i++) {
0665 aPtrs->push_back(reco::PFCandidatePtr(&isolationPFNeutralHadrCands_, i));
0666 }
0667 isolationPFNeutralHadrCandsTransientPtrs_.set(std::move(aPtrs));
0668 }
0669 return *isolationPFNeutralHadrCandsTransientPtrs_;
0670 } else {
0671 if (pfSpecific_.empty() || pfSpecific().selectedIsolationPFNeutrHadrCands_.empty() ||
0672 !pfSpecific().selectedIsolationPFNeutrHadrCands_.front().isAvailable()) {
0673
0674
0675 if (!isolationPFNeutralHadrCandsTransientPtrs_.isSet()) {
0676 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0677 isolationPFNeutralHadrCandsTransientPtrs_.set(std::move(aPtrs));
0678 }
0679 return *isolationPFNeutralHadrCandsTransientPtrs_;
0680 } else
0681 return pfSpecific().selectedIsolationPFNeutrHadrCands_;
0682 }
0683 }
0684
0685 const std::vector<reco::PFCandidatePtr>& Tau::isolationPFGammaCands() const {
0686 if (embeddedIsolationPFGammaCands_) {
0687 if (!isolationPFGammaCandsTransientPtrs_.isSet()) {
0688 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0689 aPtrs->reserve(isolationPFGammaCands_.size());
0690 for (unsigned int i = 0; i < isolationPFGammaCands_.size(); i++) {
0691 aPtrs->push_back(reco::PFCandidatePtr(&isolationPFGammaCands_, i));
0692 }
0693 isolationPFGammaCandsTransientPtrs_.set(std::move(aPtrs));
0694 }
0695 return *isolationPFGammaCandsTransientPtrs_;
0696 } else {
0697 if (pfSpecific_.empty() || pfSpecific().selectedIsolationPFGammaCands_.empty() ||
0698 !pfSpecific().selectedIsolationPFGammaCands_.front().isAvailable()) {
0699
0700
0701 if (!isolationPFGammaCandsTransientPtrs_.isSet()) {
0702 std::unique_ptr<std::vector<reco::PFCandidatePtr> > aPtrs{new std::vector<reco::PFCandidatePtr>{}};
0703 isolationPFGammaCandsTransientPtrs_.set(std::move(aPtrs));
0704 }
0705 return *isolationPFGammaCandsTransientPtrs_;
0706 } else
0707 return pfSpecific().selectedIsolationPFGammaCands_;
0708 }
0709 }
0710
0711 const std::vector<reco::PFRecoTauChargedHadron>& Tau::isolationTauChargedHadronCandidates() const {
0712 if (pfSpecific_.empty())
0713 throw cms::Exception("Type Error") << "Requesting content that is not stored in miniAOD.\n";
0714 return pfSpecific().isolationTauChargedHadronCandidates_;
0715 }
0716
0717 const std::vector<reco::RecoTauPiZero>& Tau::isolationPiZeroCandidates() const {
0718 if (pfSpecific_.empty())
0719 throw cms::Exception("Type Error") << "Requesting content that is not stored in miniAOD.\n";
0720 return pfSpecific().isolationPiZeroCandidates_;
0721 }
0722
0723
0724
0725
0726
0727 void Tau::initializeJEC(unsigned int level, unsigned int set) {
0728 currentJECSet(set);
0729 currentJECLevel(level);
0730 setP4(jec_[set].correction(level) * p4());
0731 }
0732
0733
0734 int Tau::jecSet(const std::string& set) const {
0735 for (std::vector<pat::TauJetCorrFactors>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
0736 ++corrFactor) {
0737 if (corrFactor->jecSet() == set)
0738 return corrFactor - jec_.begin();
0739 }
0740 return -1;
0741 }
0742
0743
0744 const std::vector<std::string> Tau::availableJECSets() const {
0745 std::vector<std::string> sets;
0746 for (std::vector<pat::TauJetCorrFactors>::const_iterator corrFactor = jec_.begin(); corrFactor != jec_.end();
0747 ++corrFactor) {
0748 sets.push_back(corrFactor->jecSet());
0749 }
0750 return sets;
0751 }
0752
0753 const std::vector<std::string> Tau::availableJECLevels(const int& set) const {
0754 return set >= 0 ? jec_.at(set).correctionLabels() : std::vector<std::string>();
0755 }
0756
0757
0758
0759 float Tau::jecFactor(const std::string& level, const std::string& set) const {
0760 for (unsigned int idx = 0; idx < jec_.size(); ++idx) {
0761 if (set.empty() || jec_.at(idx).jecSet() == set) {
0762 if (jec_[idx].jecLevel(level) >= 0)
0763 return jecFactor(jec_[idx].jecLevel(level), idx);
0764 else
0765 throw cms::Exception("InvalidRequest") << "This JEC level " << level << " does not exist. \n";
0766 }
0767 }
0768 throw cms::Exception("InvalidRequest") << "This jet does not carry any jet energy correction factor information \n"
0769 << "for a jet energy correction set with label " << set << "\n";
0770 }
0771
0772
0773
0774 float Tau::jecFactor(const unsigned int& level, const unsigned int& set) const {
0775 if (!jecSetsAvailable())
0776 throw cms::Exception("InvalidRequest") << "This jet does not carry any jet energy correction factor information \n";
0777 if (!jecSetAvailable(set))
0778 throw cms::Exception("InvalidRequest") << "This jet does not carry any jet energy correction factor information \n"
0779 << "for a jet energy correction set with index " << set << "\n";
0780 return jec_.at(set).correction(level) / jec_.at(currentJECSet_).correction(currentJECLevel_);
0781 }
0782
0783
0784
0785 Tau Tau::correctedTauJet(const std::string& level, const std::string& set) const {
0786
0787
0788 for (unsigned int idx = 0; idx < jec_.size(); ++idx) {
0789 if (set.empty() || jec_.at(idx).jecSet() == set) {
0790 if (jec_[idx].jecLevel(level) >= 0)
0791 return correctedTauJet(jec_[idx].jecLevel(level), idx);
0792 else
0793 throw cms::Exception("InvalidRequest") << "This JEC level " << level << " does not exist. \n";
0794 }
0795 }
0796 throw cms::Exception("InvalidRequest") << "This JEC set " << set << " does not exist. \n";
0797 }
0798
0799
0800
0801 Tau Tau::correctedTauJet(const unsigned int& level, const unsigned int& set) const {
0802 Tau correctedTauJet(*this);
0803
0804 correctedTauJet.setP4(jecFactor(level, set) * p4());
0805
0806 correctedTauJet.currentJECSet(set);
0807 correctedTauJet.currentJECLevel(level);
0808 return correctedTauJet;
0809 }
0810
0811
0812
0813
0814 const reco::CandidatePtr Tau::leadChargedHadrCand() const {
0815 const reco::PFCandidatePtr leadPF = leadPFChargedHadrCand();
0816 if (leadPF.isAvailable() || signalChargedHadrCandPtrs_.isNull())
0817 return leadPF;
0818 reco::CandidatePtr ret;
0819 for (const reco::CandidatePtr& p : signalChargedHadrCandPtrs_) {
0820 if (ret.isNull() || (p->pt() > ret->pt()))
0821 ret = p;
0822 }
0823 return ret;
0824 }
0825
0826
0827 const reco::CandidatePtr Tau::leadNeutralCand() const {
0828 const reco::PFCandidatePtr leadPF = leadPFNeutralCand();
0829 if (leadPF.isAvailable() || signalNeutralHadrCandPtrs_.isNull())
0830 return leadPF;
0831 reco::CandidatePtr ret;
0832 for (const reco::CandidatePtr& p : signalNeutralHadrCandPtrs_) {
0833 if (ret.isNull() || (p->pt() > ret->pt()))
0834 ret = p;
0835 }
0836 return ret;
0837 }
0838
0839
0840 const reco::CandidatePtr Tau::leadCand() const {
0841 const reco::PFCandidatePtr leadPF = leadPFCand();
0842 if (leadPF.isAvailable() || !Tau::ExistSignalCands())
0843 return leadPF;
0844 else
0845 return Tau::signalCands()[0];
0846 }
0847
0848
0849
0850 bool Tau::ExistSignalCands() const {
0851 return !(signalChargedHadrCandPtrs_.isNull() && signalNeutralHadrCandPtrs_.isNull() && signalGammaCandPtrs_.isNull());
0852 }
0853
0854 bool Tau::ExistIsolationCands() const {
0855 return !(isolationChargedHadrCandPtrs_.isNull() && isolationNeutralHadrCandPtrs_.isNull() &&
0856 isolationGammaCandPtrs_.isNull());
0857 }
0858
0859
0860
0861
0862 reco::CandidatePtrVector Tau::signalCands() const {
0863 std::vector<reco::PFCandidatePtr> r0 = signalPFCands();
0864 reco::CandidatePtrVector ret;
0865 if (!Tau::ExistSignalCands() || (!r0.empty() && r0.front().isAvailable())) {
0866 for (const auto& p : r0)
0867 ret.push_back(p);
0868 return ret;
0869 } else {
0870
0871 reco::CandidatePtrVector ret2;
0872 std::vector<std::pair<float, size_t> > pt_index;
0873 size_t index = 0;
0874 ret2.reserve(signalChargedHadrCandPtrs_.size() + signalNeutralHadrCandPtrs_.size() + signalGammaCandPtrs_.size());
0875 pt_index.reserve(signalChargedHadrCandPtrs_.size() + signalNeutralHadrCandPtrs_.size() +
0876 signalGammaCandPtrs_.size());
0877
0878 for (const auto& p : signalChargedHadrCandPtrs_) {
0879 ret2.push_back(p);
0880 pt_index.push_back(std::make_pair(p->pt(), index));
0881 index++;
0882 }
0883 for (const auto& p : signalNeutralHadrCandPtrs_) {
0884 ret2.push_back(p);
0885 pt_index.push_back(std::make_pair(p->pt(), index));
0886 index++;
0887 }
0888 for (const auto& p : signalGammaCandPtrs_) {
0889 ret2.push_back(p);
0890 pt_index.push_back(std::make_pair(p->pt(), index));
0891 index++;
0892 }
0893 std::sort(pt_index.begin(), pt_index.end(), std::greater<>());
0894 ret.reserve(pt_index.size());
0895 for (const auto& p : pt_index) {
0896 ret.push_back(ret2[p.second]);
0897 }
0898 return ret;
0899 }
0900 }
0901
0902
0903
0904 reco::CandidatePtrVector Tau::signalChargedHadrCands() const {
0905 std::vector<reco::PFCandidatePtr> r0 = signalPFChargedHadrCands();
0906 if (signalChargedHadrCandPtrs_.isNull() || (!r0.empty() && r0.front().isAvailable())) {
0907 reco::CandidatePtrVector ret;
0908 for (const auto& p : r0)
0909 ret.push_back(p);
0910 return ret;
0911 } else {
0912 return signalChargedHadrCandPtrs_;
0913 }
0914 }
0915
0916
0917
0918 reco::CandidatePtrVector Tau::signalNeutrHadrCands() const {
0919 std::vector<reco::PFCandidatePtr> r0 = signalPFNeutrHadrCands();
0920 if (signalNeutralHadrCandPtrs_.isNull() || (!r0.empty() && r0.front().isAvailable())) {
0921 reco::CandidatePtrVector ret;
0922 for (const auto& p : r0)
0923 ret.push_back(p);
0924 return ret;
0925 } else {
0926 return signalNeutralHadrCandPtrs_;
0927 }
0928 }
0929
0930
0931
0932 reco::CandidatePtrVector Tau::signalGammaCands() const {
0933 std::vector<reco::PFCandidatePtr> r0 = signalPFGammaCands();
0934 if (signalGammaCandPtrs_.isNull() || (!r0.empty() && r0.front().isAvailable())) {
0935 reco::CandidatePtrVector ret;
0936 for (const auto& p : r0)
0937 ret.push_back(p);
0938 return ret;
0939 } else {
0940 return signalGammaCandPtrs_;
0941 }
0942 }
0943
0944
0945
0946 reco::CandidatePtrVector Tau::isolationCands() const {
0947 std::vector<reco::PFCandidatePtr> r0 = isolationPFCands();
0948 reco::CandidatePtrVector ret;
0949 if (!Tau::ExistIsolationCands() || (!r0.empty() && r0.front().isAvailable())) {
0950 for (const auto& p : r0)
0951 ret.push_back(p);
0952 return ret;
0953 } else {
0954
0955 reco::CandidatePtrVector ret2;
0956 std::vector<std::pair<float, size_t> > pt_index;
0957 ret2.reserve(isolationChargedHadrCandPtrs_.size() + isolationNeutralHadrCandPtrs_.size() +
0958 isolationGammaCandPtrs_.size());
0959 pt_index.reserve(isolationChargedHadrCandPtrs_.size() + isolationNeutralHadrCandPtrs_.size() +
0960 isolationGammaCandPtrs_.size());
0961 size_t index = 0;
0962 for (const auto& p : isolationChargedHadrCandPtrs_) {
0963 ret2.push_back(p);
0964 pt_index.push_back(std::make_pair(p->pt(), index));
0965 index++;
0966 }
0967 for (const auto& p : isolationNeutralHadrCandPtrs_) {
0968 ret2.push_back(p);
0969 pt_index.push_back(std::make_pair(p->pt(), index));
0970 index++;
0971 }
0972 for (const auto& p : isolationGammaCandPtrs_) {
0973 ret2.push_back(p);
0974 pt_index.push_back(std::make_pair(p->pt(), index));
0975 index++;
0976 }
0977 std::sort(pt_index.begin(), pt_index.end(), std::greater<>());
0978 ret.reserve(pt_index.size());
0979 for (const auto& p : pt_index) {
0980 ret.push_back(ret2[p.second]);
0981 }
0982 return ret;
0983 }
0984 }
0985
0986
0987
0988 reco::CandidatePtrVector Tau::isolationChargedHadrCands() const {
0989 std::vector<reco::PFCandidatePtr> r0 = isolationPFChargedHadrCands();
0990 if (isolationChargedHadrCandPtrs_.isNull() || (!r0.empty() && r0.front().isAvailable())) {
0991 reco::CandidatePtrVector ret;
0992 for (const auto& p : r0)
0993 ret.push_back(p);
0994 return ret;
0995 } else {
0996 return isolationChargedHadrCandPtrs_;
0997 }
0998 }
0999
1000
1001
1002 reco::CandidatePtrVector Tau::isolationNeutrHadrCands() const {
1003 reco::CandidatePtrVector ret;
1004 std::vector<reco::PFCandidatePtr> r0 = isolationPFNeutrHadrCands();
1005 if (isolationNeutralHadrCandPtrs_.isNull() || (!r0.empty() && r0.front().isAvailable())) {
1006 reco::CandidatePtrVector ret;
1007 for (const auto& p : r0)
1008 ret.push_back(p);
1009 return ret;
1010 } else {
1011 return isolationNeutralHadrCandPtrs_;
1012 }
1013 }
1014
1015
1016
1017 reco::CandidatePtrVector Tau::isolationGammaCands() const {
1018 std::vector<reco::PFCandidatePtr> r0 = isolationPFGammaCands();
1019 if (isolationGammaCandPtrs_.isNull() || (!r0.empty() && r0.front().isAvailable())) {
1020 reco::CandidatePtrVector ret;
1021 for (const auto& p : r0)
1022 ret.push_back(p);
1023 return ret;
1024 } else {
1025 return isolationGammaCandPtrs_;
1026 }
1027 }
1028
1029 std::vector<reco::CandidatePtr> Tau::signalLostTracks() const {
1030 std::vector<reco::CandidatePtr> ret;
1031 unsigned int i = 0;
1032 std::string label = "_lostTrack_" + std::to_string(i);
1033 while (this->hasUserCand(label)) {
1034 ret.push_back(userCand(label));
1035 i++;
1036 label = "_lostTrack_" + std::to_string(i);
1037 }
1038 return ret;
1039 }
1040
1041 void Tau::setSignalLostTracks(const std::vector<reco::CandidatePtr>& ptrs) {
1042 unsigned int i = 0;
1043 for (const auto& ptr : ptrs) {
1044 std::string label = "_lostTrack_" + std::to_string(i);
1045 addUserCand(label, ptr);
1046 i++;
1047 }
1048 }
1049
1050
1051
1052 size_t Tau::numberOfSourceCandidatePtrs() const {
1053 if (Tau::ExistSignalCands())
1054 return Tau::signalCands().size();
1055 else if (pfSpecific_.empty())
1056 return 0;
1057 else
1058 return pfSpecific().selectedSignalPFCands_.size();
1059 }
1060
1061 reco::CandidatePtr Tau::sourceCandidatePtr(size_type i) const {
1062 if (Tau::ExistSignalCands())
1063 return Tau::signalCands()[i];
1064 else if (pfSpecific_.empty())
1065 return reco::CandidatePtr();
1066 else
1067 return pfSpecific().selectedSignalPFCands_[i];
1068 }