00001 #include "DataFormats/TauReco/interface/PFTauDecayMode.h" 00002 00003 namespace reco{ 00004 PFTauDecayMode::PFTauDecayMode( const VertexCompositeCandidate& chargedPions, 00005 const CompositeCandidate& piZeroes, 00006 const CompositeCandidate& filteredObjects) 00007 { 00008 chargedPions_ = chargedPions; 00009 piZeroes_ = piZeroes; 00010 filteredObjects_ = filteredObjects; 00011 00012 // determine decay mode 00013 unsigned int nCharged = chargedPions_.numberOfDaughters(); 00014 unsigned int nNeutral = piZeroes_.numberOfDaughters(); 00015 hadronicTauDecayModes hadronicTauDecayIndex = static_cast<hadronicTauDecayModes>( ((nCharged - 1)*(maxNumberOfPiZeroCandidatesAllowed+1) + nNeutral) ); 00016 if ( nNeutral > maxNumberOfPiZeroCandidatesAllowed) 00017 hadronicTauDecayIndex = static_cast<hadronicTauDecayModes>( tauDecayOther ); 00018 this->setDecayMode(hadronicTauDecayIndex); 00019 00020 // setup Particle base 00021 for(size_type iCand = 0; iCand < nCharged; ++iCand) 00022 { 00023 const Candidate* theCandToAdd = chargedPions_.daughter(iCand); 00024 this->addDaughter( *theCandToAdd ); 00025 } 00026 for(size_type iCand = 0; iCand < nNeutral; ++iCand) 00027 { 00028 const Candidate* theCandToAdd = piZeroes_.daughter(iCand); 00029 this->addDaughter( *theCandToAdd ); 00030 } 00031 00032 this->setCharge(chargedPions_.charge()); 00033 this->setP4(chargedPions_.p4() + piZeroes_.p4()); 00034 this->setStatus(2); //decayed 00035 this->setPdgId(12); //everyone's favorite lepton! 00036 } 00037 00038 PFTauDecayMode* 00039 PFTauDecayMode::clone() const 00040 { 00041 return new PFTauDecayMode(*this); 00042 } 00043 00044 const VertexCompositeCandidate& 00045 PFTauDecayMode::chargedPions() const 00046 { 00047 return chargedPions_; 00048 } 00049 00050 const CompositeCandidate& 00051 PFTauDecayMode::neutralPions() const 00052 { 00053 return piZeroes_; 00054 } 00055 00056 const CompositeCandidate& 00057 PFTauDecayMode::filteredObjects() const 00058 { 00059 return filteredObjects_; 00060 } 00061 00062 std::vector<const Candidate*> 00063 PFTauDecayMode::chargedPionCandidates() const 00064 { 00065 size_type numberOfChargedPions = chargedPions_.numberOfDaughters(); 00066 std::vector<const Candidate*> output; 00067 for(size_type iterCand = 0; iterCand < numberOfChargedPions; ++iterCand) 00068 output.push_back( chargedPions_.daughter(iterCand) ); 00069 return output; 00070 } 00071 00072 std::vector<const Candidate*> 00073 PFTauDecayMode::neutralPionCandidates() const 00074 { 00075 size_type numberOfChargedPions = piZeroes_.numberOfDaughters(); 00076 std::vector<const Candidate*> output; 00077 for(size_type iterCand = 0; iterCand < numberOfChargedPions; ++iterCand) 00078 output.push_back( piZeroes_.daughter(iterCand) ); 00079 return output; 00080 } 00081 00082 std::vector<const Candidate*> 00083 PFTauDecayMode::decayProductCandidates() const 00084 { 00085 std::vector<const Candidate*> output = this->chargedPionCandidates(); 00086 std::vector<const Candidate*> neutralObjects = this->neutralPionCandidates(); 00087 00088 output.insert(output.end(), neutralObjects.begin(), neutralObjects.end()); 00089 return output; 00090 } 00091 00092 std::vector<const Candidate*> 00093 PFTauDecayMode::filteredObjectCandidates(int absCharge) const 00094 { 00095 size_t numberOfFilteredObjects = filteredObjects_.numberOfDaughters(); 00096 std::vector<const Candidate*> output; 00097 for( size_t iFilteredCand = 0; iFilteredCand < numberOfFilteredObjects; ++iFilteredCand) 00098 { 00099 const Candidate* myCand = filteredObjects_.daughter(iFilteredCand); 00100 if (absCharge < 0 || abs(myCand->charge()) == absCharge) 00101 output.push_back(myCand); 00102 } 00103 return output; 00104 } 00105 00106 std::vector<const Candidate*> 00107 PFTauDecayMode::chargedFilteredObjectCandidates() const 00108 { 00109 return filteredObjectCandidates(1); 00110 } 00111 00112 std::vector<const Candidate*> 00113 PFTauDecayMode::neutralFilteredObjectCandidates() const 00114 { 00115 return filteredObjectCandidates(0); 00116 } 00117 00118 void 00119 PFTauDecayMode::pfMasterClones(const Candidate* input, PFCandidateRefVector& toFill) const 00120 { 00121 if (input->numberOfDaughters() == 0) //we have reached a leaf 00122 { 00123 if (input->hasMasterClone()) // has a master clone 00124 { 00125 PFCandidateRef theCandRef = input->masterClone().castTo<PFCandidateRef>(); 00126 toFill.push_back(theCandRef); 00127 } 00128 else 00129 edm::LogError("PFTauDecayMode") << "Error in pfMasterClones(...) - found a leaf candidate with no Master clone reference!"; 00130 } else // recurse down composite chain 00131 { 00132 size_type numberOfDaughters = input->numberOfDaughters(); 00133 for(size_type iCand = 0; iCand < numberOfDaughters; ++iCand) 00134 { 00135 const Candidate* currentCand = input->daughter(iCand); 00136 pfMasterClones(currentCand, toFill); 00137 } 00138 } 00139 } 00140 00141 PFCandidateRefVector 00142 PFTauDecayMode::associatedChargedPFCandidates() const 00143 { 00144 PFCandidateRefVector output; 00145 const Candidate* input = static_cast<const Candidate*>(&chargedPions_); 00146 if (input->numberOfDaughters()) 00147 pfMasterClones(input, output); 00148 return output; 00149 } 00150 00151 PFCandidateRefVector 00152 PFTauDecayMode::associatedNeutralPFCandidates() const 00153 { 00154 PFCandidateRefVector output; 00155 const Candidate* input = static_cast<const Candidate*>(&piZeroes_); 00156 if (input->numberOfDaughters()) 00157 pfMasterClones(input, output); 00158 return output; 00159 } 00160 00161 PFCandidateRefVector 00162 PFTauDecayMode::filteredPFCandidates() const 00163 { 00164 PFCandidateRefVector output; 00165 const Candidate* input = static_cast<const Candidate*>(&filteredObjects_); 00166 if (input->numberOfDaughters()) 00167 pfMasterClones(input, output); 00168 return output; 00169 } 00170 00171 }