CMS 3D CMS Logo

/data/git/CMSSW_5_3_11_patch5/src/DataFormats/PatCandidates/src/Tau.cc

Go to the documentation of this file.
00001 //
00002 // $Id: Tau.cc,v 1.22 2011/10/27 16:37:04 wmtan Exp $
00003 //
00004 
00005 #include "DataFormats/PatCandidates/interface/Tau.h"
00006 #include "DataFormats/JetReco/interface/GenJet.h"
00007 
00008 
00009 using namespace pat;
00010 
00011 
00013 Tau::Tau() :
00014     Lepton<reco::BaseTau>()
00015     ,embeddedIsolationTracks_(false)
00016     ,isolationTracksTransientRefVectorFixed_(false)
00017     ,embeddedLeadTrack_(false)
00018     ,embeddedSignalTracks_(false)
00019     ,signalTracksTransientRefVectorFixed_(false)
00020     ,embeddedLeadPFCand_(false)
00021     ,embeddedLeadPFChargedHadrCand_(false)
00022     ,embeddedLeadPFNeutralCand_(false)
00023     ,embeddedSignalPFCands_(false)
00024     ,signalPFCandsRefVectorFixed_(false)
00025     ,embeddedSignalPFChargedHadrCands_(false)
00026     ,signalPFChargedHadrCandsRefVectorFixed_(false)
00027     ,embeddedSignalPFNeutralHadrCands_(false)
00028     ,signalPFNeutralHadrCandsRefVectorFixed_(false)
00029     ,embeddedSignalPFGammaCands_(false)
00030     ,signalPFGammaCandsRefVectorFixed_(false)
00031     ,embeddedIsolationPFCands_(false)
00032     ,isolationPFCandsRefVectorFixed_(false)
00033     ,embeddedIsolationPFChargedHadrCands_(false)
00034     ,isolationPFChargedHadrCandsRefVectorFixed_(false)
00035     ,embeddedIsolationPFNeutralHadrCands_(false)
00036     ,isolationPFNeutralHadrCandsRefVectorFixed_(false)
00037     ,embeddedIsolationPFGammaCands_(false)
00038     ,isolationPFGammaCandsRefVectorFixed_(false)
00039 {
00040 }
00041 
00043 Tau::Tau(const reco::BaseTau & aTau) :
00044     Lepton<reco::BaseTau>(aTau)
00045     ,embeddedIsolationTracks_(false)
00046     ,isolationTracksTransientRefVectorFixed_(false)
00047     ,embeddedLeadTrack_(false)
00048     ,embeddedSignalTracks_(false)
00049     ,signalTracksTransientRefVectorFixed_(false)
00050     ,embeddedLeadPFCand_(false)
00051     ,embeddedLeadPFChargedHadrCand_(false)
00052     ,embeddedLeadPFNeutralCand_(false)
00053     ,embeddedSignalPFCands_(false)
00054     ,signalPFCandsRefVectorFixed_(false)
00055     ,embeddedSignalPFChargedHadrCands_(false)
00056     ,signalPFChargedHadrCandsRefVectorFixed_(false)
00057     ,embeddedSignalPFNeutralHadrCands_(false)
00058     ,signalPFNeutralHadrCandsRefVectorFixed_(false)
00059     ,embeddedSignalPFGammaCands_(false)
00060     ,signalPFGammaCandsRefVectorFixed_(false)
00061     ,embeddedIsolationPFCands_(false)
00062     ,isolationPFCandsRefVectorFixed_(false)
00063     ,embeddedIsolationPFChargedHadrCands_(false)
00064     ,isolationPFChargedHadrCandsRefVectorFixed_(false)
00065     ,embeddedIsolationPFNeutralHadrCands_(false)
00066     ,isolationPFNeutralHadrCandsRefVectorFixed_(false)
00067     ,embeddedIsolationPFGammaCands_(false)
00068     ,isolationPFGammaCandsRefVectorFixed_(false)
00069 {
00070     const reco::PFTau * pfTau = dynamic_cast<const reco::PFTau *>(&aTau);
00071     if (pfTau != 0) pfSpecific_.push_back(pat::tau::TauPFSpecific(*pfTau));
00072     const reco::CaloTau * caloTau = dynamic_cast<const reco::CaloTau *>(&aTau);
00073     if (caloTau != 0) caloSpecific_.push_back(pat::tau::TauCaloSpecific(*caloTau));
00074 }
00075 
00077 Tau::Tau(const edm::RefToBase<reco::BaseTau> & aTauRef) :
00078     Lepton<reco::BaseTau>(aTauRef)
00079     ,embeddedIsolationTracks_(false)
00080     ,isolationTracksTransientRefVectorFixed_(false)
00081     ,embeddedLeadTrack_(false)
00082     ,embeddedSignalTracks_(false)
00083     ,signalTracksTransientRefVectorFixed_(false)
00084     ,embeddedLeadPFCand_(false)
00085     ,embeddedLeadPFChargedHadrCand_(false)
00086     ,embeddedLeadPFNeutralCand_(false)
00087     ,embeddedSignalPFCands_(false)
00088     ,signalPFCandsRefVectorFixed_(false)
00089     ,embeddedSignalPFChargedHadrCands_(false)
00090     ,signalPFChargedHadrCandsRefVectorFixed_(false)
00091     ,embeddedSignalPFNeutralHadrCands_(false)
00092     ,signalPFNeutralHadrCandsRefVectorFixed_(false)
00093     ,embeddedSignalPFGammaCands_(false)
00094     ,signalPFGammaCandsRefVectorFixed_(false)
00095     ,embeddedIsolationPFCands_(false)
00096     ,isolationPFCandsRefVectorFixed_(false)
00097     ,embeddedIsolationPFChargedHadrCands_(false)
00098     ,isolationPFChargedHadrCandsRefVectorFixed_(false)
00099     ,embeddedIsolationPFNeutralHadrCands_(false)
00100     ,isolationPFNeutralHadrCandsRefVectorFixed_(false)
00101     ,embeddedIsolationPFGammaCands_(false)
00102     ,isolationPFGammaCandsRefVectorFixed_(false)
00103 {
00104     const reco::PFTau * pfTau = dynamic_cast<const reco::PFTau *>(aTauRef.get());
00105     if (pfTau != 0) pfSpecific_.push_back(pat::tau::TauPFSpecific(*pfTau));
00106     const reco::CaloTau * caloTau = dynamic_cast<const reco::CaloTau *>(aTauRef.get());
00107     if (caloTau != 0) caloSpecific_.push_back(pat::tau::TauCaloSpecific(*caloTau));
00108 }
00109 
00111 Tau::Tau(const edm::Ptr<reco::BaseTau> & aTauRef) :
00112     Lepton<reco::BaseTau>(aTauRef)
00113     ,embeddedIsolationTracks_(false)
00114     ,isolationTracksTransientRefVectorFixed_(false)
00115     ,embeddedLeadTrack_(false)
00116     ,embeddedSignalTracks_(false)
00117     ,signalTracksTransientRefVectorFixed_(false)
00118     ,embeddedLeadPFCand_(false)
00119     ,embeddedLeadPFChargedHadrCand_(false)
00120     ,embeddedLeadPFNeutralCand_(false)
00121     ,embeddedSignalPFCands_(false)
00122     ,signalPFCandsRefVectorFixed_(false)
00123     ,embeddedSignalPFChargedHadrCands_(false)
00124     ,signalPFChargedHadrCandsRefVectorFixed_(false)
00125     ,embeddedSignalPFNeutralHadrCands_(false)
00126     ,signalPFNeutralHadrCandsRefVectorFixed_(false)
00127     ,embeddedSignalPFGammaCands_(false)
00128     ,signalPFGammaCandsRefVectorFixed_(false)
00129     ,embeddedIsolationPFCands_(false)
00130     ,isolationPFCandsRefVectorFixed_(false)
00131     ,embeddedIsolationPFChargedHadrCands_(false)
00132     ,isolationPFChargedHadrCandsRefVectorFixed_(false)
00133     ,embeddedIsolationPFNeutralHadrCands_(false)
00134     ,isolationPFNeutralHadrCandsRefVectorFixed_(false)
00135     ,embeddedIsolationPFGammaCands_(false)
00136     ,isolationPFGammaCandsRefVectorFixed_(false)
00137 {
00138     const reco::PFTau * pfTau = dynamic_cast<const reco::PFTau *>(aTauRef.get());
00139     if (pfTau != 0) pfSpecific_.push_back(pat::tau::TauPFSpecific(*pfTau));
00140     const reco::CaloTau * caloTau = dynamic_cast<const reco::CaloTau *>(aTauRef.get());
00141     if (caloTau != 0) caloSpecific_.push_back(pat::tau::TauCaloSpecific(*caloTau));
00142 }
00143 
00145 Tau::~Tau() {
00146 }
00147 
00148 std::ostream& 
00149 reco::operator<<(std::ostream& out, const pat::Tau& obj) 
00150 {
00151   if(!out) return out;
00152   
00153   out << "\tpat::Tau: ";
00154   out << std::setiosflags(std::ios::right);
00155   out << std::setiosflags(std::ios::fixed);
00156   out << std::setprecision(3);
00157   out << " E/pT/eta/phi " 
00158       << obj.energy()<<"/"
00159       << obj.pt()<<"/"
00160       << obj.eta()<<"/"
00161       << obj.phi();
00162   return out; 
00163 }
00164 
00166 const reco::TrackRefVector & Tau::isolationTracks() const {
00167   if (embeddedIsolationTracks_) {
00168     if (!isolationTracksTransientRefVectorFixed_) {
00169         reco::TrackRefVector trackRefVec;
00170         for (unsigned int i = 0; i < isolationTracks_.size(); i++) {
00171           trackRefVec.push_back(reco::TrackRef(&isolationTracks_, i));
00172         }
00173         isolationTracksTransientRefVector_.swap(trackRefVec);
00174         isolationTracksTransientRefVectorFixed_ = true;
00175     }
00176     return isolationTracksTransientRefVector_;
00177   } else {
00178     return reco::BaseTau::isolationTracks();
00179   }
00180 }
00181 
00182 
00184 reco::TrackRef Tau::leadTrack() const {
00185   if (embeddedLeadTrack_) {
00186     return reco::TrackRef(&leadTrack_, 0);
00187   } else {
00188     return reco::BaseTau::leadTrack();
00189   }
00190 }
00191 
00192 
00194 const reco::TrackRefVector & Tau::signalTracks() const {
00195   if (embeddedSignalTracks_) {
00196     reco::TrackRefVector trackRefVec;
00197     if (!signalTracksTransientRefVectorFixed_) {
00198         for (unsigned int i = 0; i < signalTracks_.size(); i++) {
00199           trackRefVec.push_back(reco::TrackRef(&signalTracks_, i));
00200         }
00201         signalTracksTransientRefVector_.swap(trackRefVec);
00202         signalTracksTransientRefVectorFixed_ = true;
00203     }
00204     return signalTracksTransientRefVector_;
00205   } else {
00206     return reco::BaseTau::signalTracks();
00207   }
00208 }
00209 
00210 
00212 void Tau::embedIsolationTracks() {
00213   isolationTracks_.clear();
00214   reco::TrackRefVector trackRefVec = reco::BaseTau::isolationTracks();
00215   for (unsigned int i = 0; i < trackRefVec.size(); i++) {
00216     isolationTracks_.push_back(*trackRefVec.at(i));
00217   }
00218   embeddedIsolationTracks_ = true;
00219 }
00220 
00221 
00223 void Tau::embedLeadTrack() {
00224   leadTrack_.clear();
00225   if (reco::BaseTau::leadTrack().isNonnull()) {
00226       leadTrack_.push_back(*reco::BaseTau::leadTrack());
00227       embeddedLeadTrack_ = true;
00228   }
00229 }
00230 
00231 
00233 void Tau::embedSignalTracks(){
00234   signalTracks_.clear();
00235   reco::TrackRefVector trackRefVec = reco::BaseTau::signalTracks();
00236   for (unsigned int i = 0; i < trackRefVec.size(); i++) {
00237     signalTracks_.push_back(*trackRefVec.at(i));
00238   }
00239   embeddedSignalTracks_ = true;
00240 }
00241 
00242 
00244 void Tau::setGenJet(const reco::GenJetRef& gj) {
00245   genJet_.clear();
00246   genJet_.push_back(*gj);
00247 }
00248 
00250 const reco::GenJet * Tau::genJet() const {
00251   return (genJet_.size() > 0 ? &genJet_.front() : 0);
00252 }
00253 
00254 
00255 // method to retrieve a tau ID (or throw)
00256 float Tau::tauID(const std::string & name) const {
00257   for (std::vector<IdPair>::const_iterator it = tauIDs_.begin(), ed = tauIDs_.end(); it != ed; ++it) {
00258     if (it->first == name) return it->second;
00259   }
00260   cms::Exception ex("Key not found");
00261   ex << "pat::Tau: the ID " << name << " can't be found in this pat::Tau.\n";
00262   ex << "The available IDs are: ";
00263   for (std::vector<IdPair>::const_iterator it = tauIDs_.begin(), ed = tauIDs_.end(); it != ed; ++it) {
00264     ex << "'" << it->first << "' ";
00265   }
00266   ex << ".\n";
00267   throw ex;
00268 }
00269 // check if an ID is there
00270 bool Tau::isTauIDAvailable(const std::string & name) const {
00271   for (std::vector<IdPair>::const_iterator it = tauIDs_.begin(), ed = tauIDs_.end(); it != ed; ++it) {
00272     if (it->first == name) return true;
00273   }
00274   return false;
00275 }
00276 
00277 
00278 const pat::tau::TauPFSpecific & Tau::pfSpecific() const {
00279   if (!isPFTau()) throw cms::Exception("Type Error") << "Requesting a PFTau-specific information from a pat::Tau which wasn't made from a PFTau.\n";
00280   return pfSpecific_[0]; 
00281 }
00282 
00283 const pat::tau::TauCaloSpecific & Tau::caloSpecific() const {
00284   if (!isCaloTau()) throw cms::Exception("Type Error") << "Requesting a CaloTau-specific information from a pat::Tau which wasn't made from a CaloTau.\n";
00285   return caloSpecific_[0]; 
00286 }
00287 
00288 const reco::Candidate::LorentzVector& Tau::p4Jet() const
00289 {
00290   if ( isCaloTau() ) return caloSpecific().p4Jet_;
00291   if ( isPFTau()   ) return pfSpecific().p4Jet_;
00292   throw cms::Exception("Type Error") << "Requesting a CaloTau/PFTau-specific information from a pat::Tau which wasn't made from either a CaloTau or a PFTau.\n";
00293 }
00294 
00295 float Tau::etaetaMoment() const
00296 {
00297   if ( isCaloTau() ) return caloSpecific().etaetaMoment_;
00298   if ( isPFTau()   ) return pfSpecific().etaetaMoment_;
00299   throw cms::Exception("Type Error") << "Requesting a CaloTau/PFTau-specific information from a pat::Tau which wasn't made from either a CaloTau or a PFTau.\n";
00300 }
00301 
00302 float Tau::phiphiMoment() const
00303 {
00304   if ( isCaloTau() ) return caloSpecific().phiphiMoment_;
00305   if ( isPFTau()   ) return pfSpecific().phiphiMoment_;
00306   throw cms::Exception("Type Error") << "Requesting a CaloTau/PFTau-specific information from a pat::Tau which wasn't made from either a CaloTau or a PFTau.\n";
00307 }
00308 
00309 float Tau::etaphiMoment() const
00310 {
00311   if ( isCaloTau() ) return caloSpecific().etaphiMoment_;
00312   if ( isPFTau()   ) return pfSpecific().etaphiMoment_;
00313   throw cms::Exception("Type Error") << "Requesting a CaloTau/PFTau-specific information from a pat::Tau which wasn't made from either a CaloTau or a PFTau.\n";
00314 }
00315 
00316 void Tau::setDecayMode(int decayMode)
00317 {
00318   if (!isPFTau()) throw cms::Exception("Type Error") << "Requesting a PFTau-specific information from a pat::Tau which wasn't made from a PFTau.\n";
00319   pfSpecific_[0].decayMode_ = decayMode;
00320 } 
00321 
00323 void Tau::embedLeadPFCand() {
00324   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00325     return;
00326   }
00327   leadPFCand_.clear();
00328   if (pfSpecific_[0].leadPFCand_.isNonnull() ) {
00329     leadPFCand_.push_back(*pfSpecific_[0].leadPFCand_); //already set in C-tor
00330     embeddedLeadPFCand_ = true;
00331   }
00332 }
00334 void Tau::embedLeadPFChargedHadrCand() {
00335   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00336     return;
00337   }
00338   leadPFChargedHadrCand_.clear();
00339   if (pfSpecific_[0].leadPFChargedHadrCand_.isNonnull() ) {
00340     leadPFChargedHadrCand_.push_back(*pfSpecific_[0].leadPFChargedHadrCand_); //already set in C-tor
00341     embeddedLeadPFChargedHadrCand_ = true;
00342   }
00343 }
00345 void Tau::embedLeadPFNeutralCand() {
00346   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00347     return;
00348   }
00349   leadPFNeutralCand_.clear();
00350   if (pfSpecific_[0].leadPFNeutralCand_.isNonnull() ) {
00351     leadPFNeutralCand_.push_back(*pfSpecific_[0].leadPFNeutralCand_); //already set in C-tor
00352     embeddedLeadPFNeutralCand_ = true;
00353   }
00354 }
00355 
00356 void Tau::embedSignalPFCands() {
00357   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00358     return;
00359   }
00360   reco::PFCandidateRefVector candRefVec = pfSpecific_[0].selectedSignalPFCands_;
00361   for (unsigned int i = 0; i < candRefVec.size(); i++) {
00362     signalPFCands_.push_back(*candRefVec.at(i));
00363   }
00364   embeddedSignalPFCands_ = true;
00365 }
00366 void Tau::embedSignalPFChargedHadrCands() {
00367   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00368     return;
00369   }
00370   reco::PFCandidateRefVector candRefVec = pfSpecific_[0].selectedSignalPFChargedHadrCands_;
00371   for (unsigned int i = 0; i < candRefVec.size(); i++) {
00372     signalPFChargedHadrCands_.push_back(*candRefVec.at(i));
00373   }
00374   embeddedSignalPFChargedHadrCands_ = true;
00375 }
00376 void Tau::embedSignalPFNeutralHadrCands() {
00377   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00378     return;
00379   }
00380   reco::PFCandidateRefVector candRefVec = pfSpecific_[0].selectedSignalPFNeutrHadrCands_;
00381   for (unsigned int i = 0; i < candRefVec.size(); i++) {
00382     signalPFNeutralHadrCands_.push_back(*candRefVec.at(i));
00383   }
00384   embeddedSignalPFNeutralHadrCands_ = true;
00385 }
00386 void Tau::embedSignalPFGammaCands() {
00387   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00388     return;
00389   }
00390   reco::PFCandidateRefVector candRefVec = pfSpecific_[0].selectedSignalPFGammaCands_;
00391   for (unsigned int i = 0; i < candRefVec.size(); i++) {
00392     signalPFGammaCands_.push_back(*candRefVec.at(i));
00393   }
00394   embeddedSignalPFGammaCands_ = true;
00395 }
00396 
00397 void Tau::embedIsolationPFCands() {
00398   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00399     return;
00400   }
00401   reco::PFCandidateRefVector candRefVec = pfSpecific_[0].selectedIsolationPFCands_;
00402   for (unsigned int i = 0; i < candRefVec.size(); i++) {
00403     isolationPFCands_.push_back(*candRefVec.at(i));
00404   }
00405   embeddedIsolationPFCands_ = true;
00406 }
00407 
00408 void Tau::embedIsolationPFChargedHadrCands() {
00409   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00410     return;
00411   }
00412   reco::PFCandidateRefVector candRefVec = pfSpecific_[0].selectedIsolationPFChargedHadrCands_;
00413   for (unsigned int i = 0; i < candRefVec.size(); i++) {
00414     isolationPFChargedHadrCands_.push_back(*candRefVec.at(i));
00415   }
00416   embeddedIsolationPFChargedHadrCands_ = true;
00417 }
00418 void Tau::embedIsolationPFNeutralHadrCands() {
00419   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00420     return;
00421   }
00422   reco::PFCandidateRefVector candRefVec = pfSpecific_[0].selectedIsolationPFNeutrHadrCands_;
00423   for (unsigned int i = 0; i < candRefVec.size(); i++) {
00424     isolationPFNeutralHadrCands_.push_back(*candRefVec.at(i));
00425   }
00426   embeddedIsolationPFNeutralHadrCands_ = true;
00427 }
00428 void Tau::embedIsolationPFGammaCands() {
00429   if (!isPFTau() ) {//additional check with warning in pat::tau producer
00430     return;
00431   }
00432   reco::PFCandidateRefVector candRefVec = pfSpecific_[0].selectedIsolationPFGammaCands_;
00433   for (unsigned int i = 0; i < candRefVec.size(); i++) {
00434     isolationPFGammaCands_.push_back(*candRefVec.at(i));
00435   }
00436   embeddedIsolationPFGammaCands_ = true;
00437 }
00438 
00439 const reco::PFCandidateRef Tau::leadPFChargedHadrCand() const { 
00440   if(!embeddedLeadPFChargedHadrCand_)
00441     return pfSpecific().leadPFChargedHadrCand_; 
00442   else
00443     return reco::PFCandidateRef(&leadPFChargedHadrCand_,0);
00444 }
00445 
00446 const reco::PFCandidateRef Tau::leadPFNeutralCand() const { 
00447   if(!embeddedLeadPFNeutralCand_)
00448     return pfSpecific().leadPFNeutralCand_;
00449   else
00450     return reco::PFCandidateRef(&leadPFNeutralCand_,0);
00451 }
00452 
00453 const reco::PFCandidateRef Tau::leadPFCand() const { 
00454   if(!embeddedLeadPFCand_)
00455     return pfSpecific().leadPFCand_;
00456   else
00457     return reco::PFCandidateRef(&leadPFCand_,0);
00458 }
00459 
00460 const reco::PFCandidateRefVector & Tau::signalPFCands() const { 
00461   if (embeddedSignalPFCands_) {
00462     if (!signalPFCandsRefVectorFixed_) {
00463       reco::PFCandidateRefVector aRefVec;
00464       for (unsigned int i = 0; i < signalPFCands_.size(); i++) {
00465         aRefVec.push_back(reco::PFCandidateRef(&signalPFCands_, i) );
00466       }
00467       signalPFCandsTransientRefVector_.swap(aRefVec);
00468       signalPFCandsRefVectorFixed_ = true;
00469     }
00470     return signalPFCandsTransientRefVector_;
00471   } else
00472     return pfSpecific().selectedSignalPFCands_; 
00473 }
00474 
00475 const reco::PFCandidateRefVector & Tau::signalPFChargedHadrCands() const {
00476   if (embeddedSignalPFChargedHadrCands_) {
00477     if (!signalPFChargedHadrCandsRefVectorFixed_) {
00478       reco::PFCandidateRefVector aRefVec;
00479       for (unsigned int i = 0; i < signalPFChargedHadrCands_.size(); i++) {
00480         aRefVec.push_back(reco::PFCandidateRef(&signalPFChargedHadrCands_, i) );
00481       }
00482       signalPFChargedHadrCandsTransientRefVector_.swap(aRefVec);
00483       signalPFChargedHadrCandsRefVectorFixed_ = true;
00484     }
00485     return signalPFChargedHadrCandsTransientRefVector_;
00486   } else
00487     return pfSpecific().selectedSignalPFChargedHadrCands_;
00488 } 
00489 
00490 const reco::PFCandidateRefVector & Tau::signalPFNeutrHadrCands() const {
00491   if (embeddedSignalPFNeutralHadrCands_) {
00492     if (!signalPFNeutralHadrCandsRefVectorFixed_) {
00493       reco::PFCandidateRefVector aRefVec;
00494       for (unsigned int i = 0; i < signalPFNeutralHadrCands_.size(); i++) {
00495         aRefVec.push_back(reco::PFCandidateRef(&signalPFNeutralHadrCands_, i) );
00496       }
00497       signalPFNeutralHadrCandsTransientRefVector_.swap(aRefVec);
00498       signalPFNeutralHadrCandsRefVectorFixed_ = true;
00499     }
00500     return signalPFNeutralHadrCandsTransientRefVector_;
00501   } else
00502     return pfSpecific().selectedSignalPFNeutrHadrCands_;
00503 } 
00504 
00505 const reco::PFCandidateRefVector & Tau::signalPFGammaCands() const {
00506   if (embeddedSignalPFGammaCands_) {
00507     if (!signalPFGammaCandsRefVectorFixed_) {
00508       reco::PFCandidateRefVector aRefVec;
00509       for (unsigned int i = 0; i < signalPFGammaCands_.size(); i++) {
00510         aRefVec.push_back(reco::PFCandidateRef(&signalPFGammaCands_, i) );
00511       }
00512       signalPFGammaCandsTransientRefVector_.swap(aRefVec);
00513       signalPFGammaCandsRefVectorFixed_ = true;
00514     }
00515     return signalPFGammaCandsTransientRefVector_;
00516   } else
00517     return pfSpecific().selectedSignalPFGammaCands_;
00518 }
00519 
00520 const std::vector<reco::RecoTauPiZero> & Tau::signalPiZeroCandidates() const {
00521   return pfSpecific().signalPiZeroCandidates_;
00522 }
00523 
00524 const reco::PFCandidateRefVector & Tau::isolationPFCands() const {
00525   if (embeddedIsolationPFCands_) {
00526     if (!isolationPFCandsRefVectorFixed_) {
00527       reco::PFCandidateRefVector aRefVec;
00528       for (unsigned int i = 0; i < isolationPFCands_.size(); i++) {
00529         aRefVec.push_back(reco::PFCandidateRef(&isolationPFCands_, i) );
00530       }
00531       isolationPFCandsTransientRefVector_.swap(aRefVec);
00532       isolationPFCandsRefVectorFixed_ = true;
00533     }
00534     return isolationPFCandsTransientRefVector_;
00535   } else
00536     return pfSpecific().selectedIsolationPFCands_;
00537 } 
00538 
00539 const reco::PFCandidateRefVector & Tau::isolationPFChargedHadrCands() const {
00540   if (embeddedIsolationPFChargedHadrCands_) {
00541     if (!isolationPFChargedHadrCandsRefVectorFixed_) {
00542       reco::PFCandidateRefVector aRefVec;
00543       for (unsigned int i = 0; i < isolationPFChargedHadrCands_.size(); i++) {
00544         aRefVec.push_back(reco::PFCandidateRef(&isolationPFChargedHadrCands_, i) );
00545       }
00546       isolationPFChargedHadrCandsTransientRefVector_.swap(aRefVec);
00547       isolationPFChargedHadrCandsRefVectorFixed_ = true;
00548     }
00549     return isolationPFChargedHadrCandsTransientRefVector_;
00550   } else
00551     return pfSpecific().selectedIsolationPFChargedHadrCands_;
00552 } 
00553 
00554 const reco::PFCandidateRefVector & Tau::isolationPFNeutrHadrCands() const {
00555   if (embeddedIsolationPFNeutralHadrCands_) {
00556     if (!isolationPFNeutralHadrCandsRefVectorFixed_) {
00557       reco::PFCandidateRefVector aRefVec;
00558       for (unsigned int i = 0; i < isolationPFNeutralHadrCands_.size(); i++) {
00559         aRefVec.push_back(reco::PFCandidateRef(&isolationPFNeutralHadrCands_, i) );
00560       }
00561       isolationPFNeutralHadrCandsTransientRefVector_.swap(aRefVec);
00562       isolationPFNeutralHadrCandsRefVectorFixed_ = true;
00563     }
00564     return isolationPFNeutralHadrCandsTransientRefVector_;
00565   } else
00566     return pfSpecific().selectedIsolationPFNeutrHadrCands_;
00567 } 
00568 
00569 const reco::PFCandidateRefVector & Tau::isolationPFGammaCands() const {
00570   if (embeddedIsolationPFGammaCands_) {
00571     if (!isolationPFGammaCandsRefVectorFixed_) {
00572       reco::PFCandidateRefVector aRefVec;
00573       for (unsigned int i = 0; i < isolationPFGammaCands_.size(); i++) {
00574         aRefVec.push_back(reco::PFCandidateRef(&isolationPFGammaCands_, i) );
00575       }
00576       isolationPFGammaCandsTransientRefVector_.swap(aRefVec);
00577       isolationPFGammaCandsRefVectorFixed_ = true;
00578     }
00579     return isolationPFGammaCandsTransientRefVector_;
00580   } else
00581     return pfSpecific().selectedIsolationPFGammaCands_;
00582 }
00583 
00584 const std::vector<reco::RecoTauPiZero> & Tau::isolationPiZeroCandidates() const {
00585   return pfSpecific().isolationPiZeroCandidates_;
00586 }
00587 
00590 
00591 // initialize the jet to a given JEC level during creation starting from Uncorrected
00592 void Tau::initializeJEC(unsigned int level, unsigned int set)
00593 {
00594   currentJECSet(set);
00595   currentJECLevel(level);
00596   setP4(jec_[set].correction(level)*p4());
00597 }
00598 
00600 int Tau::jecSet(const std::string& set) const
00601 {
00602   for ( std::vector<pat::TauJetCorrFactors>::const_iterator corrFactor = jec_.begin(); 
00603         corrFactor != jec_.end(); ++corrFactor ) {
00604     if ( corrFactor->jecSet() == set ) return corrFactor-jec_.begin(); 
00605   }
00606   return -1;
00607 }
00608 
00610 const std::vector<std::string> Tau::availableJECSets() const
00611 {
00612   std::vector<std::string> sets;
00613   for ( std::vector<pat::TauJetCorrFactors>::const_iterator corrFactor = jec_.begin(); 
00614         corrFactor != jec_.end(); ++corrFactor ) {
00615     sets.push_back(corrFactor->jecSet());
00616   }
00617   return sets;
00618 }
00619 
00620 const std::vector<std::string> Tau::availableJECLevels(const int& set) const
00621 {
00622   return set>=0 ? jec_.at(set).correctionLabels() : std::vector<std::string>();
00623 }
00624 
00627 float Tau::jecFactor(const std::string& level, const std::string& set) const
00628 {
00629   for ( unsigned int idx = 0; idx < jec_.size(); ++idx ) {
00630     if ( set.empty() || jec_.at(idx).jecSet() == set ){
00631       if ( jec_[idx].jecLevel(level) >= 0 ) 
00632         return jecFactor(jec_[idx].jecLevel(level), idx);
00633       else
00634         throw cms::Exception("InvalidRequest") 
00635           << "This JEC level " << level << " does not exist. \n";
00636     }
00637   }
00638   throw cms::Exception("InvalidRequest") 
00639     << "This jet does not carry any jet energy correction factor information \n"
00640     << "for a jet energy correction set with label " << set << "\n";
00641 }
00642 
00645 float Tau::jecFactor(const unsigned int& level, const unsigned int& set) const
00646 {
00647   if ( !jecSetsAvailable() )
00648     throw cms::Exception("InvalidRequest") 
00649       << "This jet does not carry any jet energy correction factor information \n";
00650   if ( !jecSetAvailable(set) )
00651     throw cms::Exception("InvalidRequest") 
00652       << "This jet does not carry any jet energy correction factor information \n"
00653       << "for a jet energy correction set with index " << set << "\n";
00654   return jec_.at(set).correction(level)/jec_.at(currentJECSet_).correction(currentJECLevel_);
00655 }
00656 
00659 Tau Tau::correctedTauJet(const std::string& level, const std::string& set) const
00660 {
00661   // rescale p4 of the jet; the update of current values is
00662   // done within the called jecFactor function
00663   for ( unsigned int idx = 0; idx < jec_.size(); ++idx ) {
00664     if ( set.empty() || jec_.at(idx).jecSet() == set ) {
00665       if ( jec_[idx].jecLevel(level) >= 0 ) 
00666         return correctedTauJet(jec_[idx].jecLevel(level), idx);
00667       else
00668         throw cms::Exception("InvalidRequest") 
00669           << "This JEC level " << level << " does not exist. \n";
00670     }
00671   }
00672   throw cms::Exception("InvalidRequest") 
00673     << "This JEC set " << set << " does not exist. \n";
00674 }
00675 
00678 Tau Tau::correctedTauJet(const unsigned int& level, const unsigned int& set) const
00679 {
00680   Tau correctedTauJet(*this);
00681   //rescale p4 of the jet
00682   correctedTauJet.setP4(jecFactor(level, set)*p4());
00683   // update current level and set
00684   correctedTauJet.currentJECSet(set); 
00685   correctedTauJet.currentJECLevel(level); 
00686   return correctedTauJet;
00687 }
00688