CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_5_3_14/src/RecoTauTag/TauTagTools/src/GeneratorTau.cc

Go to the documentation of this file.
00001 #include "RecoTauTag/TauTagTools/interface/GeneratorTau.h"
00002 
00003 float GeneratorTau::getVisNuAngle() const {
00004   LorentzVector suckVector = getVisibleFourVector();
00005   LorentzVector suckNuVector = this->p4() - suckVector;
00006   return angleFinder(suckVector, suckNuVector);
00007 }
00008 
00009 const reco::Candidate* GeneratorTau::getLeadTrack() const {
00010   return static_cast<const Candidate*>(theLeadTrack_);
00011 }
00012 
00013 const reco::GenParticle* GeneratorTau::findLeadTrack() {
00014   std::vector<const reco::GenParticle*>::const_iterator thePion =
00015     genChargedPions_.begin();
00016   double maxPt = 0;
00017   const reco::GenParticle* output = NULL;
00018   for (; thePion != genChargedPions_.end(); ++thePion) {
00019     if ((*thePion)->pt() > maxPt) {
00020       maxPt = (*thePion)->pt();
00021       output = (*thePion);
00022     }
00023   }
00024   theLeadTrack_ = output;
00025   return output;
00026 }
00027 
00028 float GeneratorTau::getOpeningAngle(
00029     const std::vector<const reco::GenParticle*>& theCollection) const {
00030   double output = 0;
00031   std::vector<const reco::GenParticle*>::const_iterator theObject =
00032     theCollection.begin();
00033   for (; theObject != theCollection.end(); ++theObject) {
00034     if (output < angleFinder(theLeadTrack_->p4(), (*theObject)->p4()))
00035       output = angleFinder(theLeadTrack_->p4(), (*theObject)->p4());
00036   }
00037   return output;
00038 }
00039 
00040 float GeneratorTau::getChargedOpeningAngle() const {
00041   return getOpeningAngle(genChargedPions_);
00042 }
00043 
00044 float GeneratorTau::getGammaOpeningAngle() const {
00045   return getOpeningAngle(genGammas_);
00046 }
00047 
00048 GeneratorTau::tauDecayModeEnum GeneratorTau::computeDecayMode(
00049     const reco::GenParticle* theTau) {
00050   //return kUndefined if not a tau
00051   if (theTau == NULL || std::abs(theTau->pdgId()) != 15
00052       || theTau->status() != 2)
00053     return kUndefined;
00054 
00055   tauDecayModeEnum output;
00056 
00057   //counters to determine decay type (adapted from Ricardo's code)
00058   int numElectrons      = 0;
00059   int numMuons          = 0;
00060   int numChargedPions   = 0;
00061   int numNeutralPions   = 0;
00062   int numNeutrinos      = 0;
00063   int numOtherParticles = 0;
00064 
00066   std::vector<const reco::GenParticle* > pdgDecayProductTypes;
00067 
00068   GeneratorTau::decayToPDGClassification(theTau, pdgDecayProductTypes);
00069 
00070   for (std::vector<const reco::GenParticle* >::const_iterator decayProduct =
00071       pdgDecayProductTypes.begin();
00072       decayProduct != pdgDecayProductTypes.end(); ++decayProduct) {
00073     int pdg_id = std::abs( (*decayProduct)->pdgId() );
00074     //edm::LogInfo("GeneratorTau") << "Has decay product w/ PDG ID: " << pdg_id;
00075     if (pdg_id == 11) numElectrons++;
00076     else if (pdg_id == 13) numMuons++;
00077     else if (pdg_id == 211) numChargedPions++;
00078     else if (pdg_id == 111) numNeutralPions++;
00079     else if (pdg_id == 12 ||
00080         pdg_id == 14 ||
00081         pdg_id == 16)  numNeutrinos++;
00082     else if (pdg_id != 22)
00083       numOtherParticles++;
00084   }
00085   output = kOther;
00086 
00087   //determine tauDecayMode
00088   if ( numOtherParticles == 0 ){
00089     if ( numElectrons == 1 ){
00090       //--- tau decays into electrons
00091       output = kElectron;
00092     } else if ( numMuons == 1 ){
00093       //--- tau decays into muons
00094       output = kMuon;
00095     } else {
00096       //--- hadronic tau decays
00097       switch ( numChargedPions ){
00098         case 1 :
00099           switch ( numNeutralPions ){
00100             case 0 :
00101               output = kOneProng0pi0;
00102               break;
00103             case 1 :
00104               output = kOneProng1pi0;
00105               break;
00106             case 2 :
00107               output = kOneProng2pi0;
00108               break;
00109           }
00110           break;
00111         case 3 :
00112           switch ( numNeutralPions ){
00113             case 0 :
00114               output = kThreeProng0pi0;
00115               break;
00116             case 1 :
00117               output = kThreeProng1pi0;
00118               break;
00119           }
00120           break;
00121       }
00122     }
00123   }
00124   return output;
00125 }
00126 
00128   void
00129 GeneratorTau::decayToPDGClassification(const reco::GenParticle* theParticle, std::vector<const reco::GenParticle* >& container)
00130 {
00132   if (theParticle)
00133   {
00134     //edm::LogInfo("Debug") << "It's non-null";
00135     int pdgId = std::abs(theParticle->pdgId());
00136     //edm::LogInfo("Debug") << "PDGID = " << pdgId << " Status = " << theStatus;
00137     if (theParticle->status() == 1 || pdgId == 211 || pdgId == 111 || pdgId == 11 || pdgId == 13)
00138     {
00139       //edm::LogInfo("Debug") << "Adding to container...";
00140       container.push_back(theParticle);
00141       //add neutral pions and this step....
00142       if (pdgId == 111)
00143         genNeutralPions_.push_back(theParticle);
00144     }
00145     else
00146     {
00147       unsigned int nDaughters = theParticle->numberOfDaughters();
00148       for (size_t dIter = 0; dIter < nDaughters; ++dIter)
00149       {
00150         const Candidate * daughter = theParticle->daughter(dIter);
00151         //edm::LogInfo("Debug") << "Recursing on daughter with PDG: " << daughter->pdgId();
00152         GeneratorTau::decayToPDGClassification(static_cast<const reco::GenParticle*>(daughter), container);
00153       }
00154 
00155     }
00156   }
00157 }
00158 
00159 
00160   void
00161 GeneratorTau::computeStableDecayProducts(const reco::GenParticle* theParticle, std::vector<const reco::GenParticle *>& container)
00162 {
00163   if (theParticle)
00164   {
00165     if (theParticle->status() == 1) //status = 1 indicates final state particle
00166     {
00167       //edm::LogInfo("GeneratorTau") << "computeStableDecayProducts: Found a final state daughter with status: " << theParticle->status() << " Num stable decay products so far: " << container.size();
00168       container.push_back(theParticle);
00169     }
00170     else
00171     {
00172       unsigned int nDaughters = theParticle->numberOfDaughters();
00173       for (size_t dIter = 0; dIter < nDaughters; ++dIter)
00174       {
00175         const Candidate * daughter = theParticle->daughter(dIter);
00176         //edm::LogInfo("Debug") << "Recursing on daughter with PDG: " << daughter->pdgId();
00177         GeneratorTau::computeStableDecayProducts(static_cast<const reco::GenParticle*>(daughter), container);
00178       }
00179     }
00180   }
00181 }
00182 
00183 GeneratorTau::GeneratorTau()
00184 {
00185 }
00186 
00187 
00188   void
00189 GeneratorTau::init()
00190 {
00191   //make sure this tau really decays
00192   theDecayMode_        = kUndefined;
00193   aFinalStateTau_      = false;
00194 
00195   //get Decaymode
00196   //edm::LogInfo("GeneratorTau") << "Computing decay mode..";
00197   theDecayMode_ = computeDecayMode(this);
00198 
00199   //make sure it is a real tau decay
00200   if (theDecayMode_ != kUndefined) {
00201     aFinalStateTau_ = true;
00202     //edm::LogInfo("GeneratorTau") << "Found decay type: " << theDecayMode_ << ", computing stable decay products.";
00203     //get the stable decay products
00204     computeStableDecayProducts(this, stableDecayProducts_);
00205     //from the stable products, fill the lists
00206     //edm::LogInfo("GeneratorTau") << "Found " << stableDecayProducts_.size() << " stable decay products, filtering.";
00207     for (std::vector<const reco::GenParticle*>::const_iterator iter = stableDecayProducts_.begin();
00208         iter != stableDecayProducts_.end();
00209         ++iter)
00210     {
00211       //fill vectors
00212       int pdg_id = std::abs( (*iter)->pdgId() );
00213       if (pdg_id == 16 || pdg_id == 12 || pdg_id == 14)
00214         genNus_.push_back( (*iter) );
00215       else  {
00216         visibleDecayProducts_.push_back( (*iter) );
00217         if (pdg_id == 211 || (*iter)->charge() != 0)
00218           genChargedPions_.push_back( (*iter) );
00219         else if (pdg_id == 22)
00220           genGammas_.push_back( (*iter) );
00221       }
00222     }
00223     // find the lead charged object
00224     theLeadTrack_ = findLeadTrack();
00225   }
00226 }
00227 
00228 
00229 
00230 std::vector<LorentzVector>
00231 GeneratorTau::convertMCVectorToLorentzVectors(
00232     const std::vector<const reco::GenParticle*>& theList) const {
00233   std::vector<LorentzVector> output;
00234   std::vector<const reco::GenParticle*>::const_iterator theParticle;
00235   for (theParticle = theList.begin();
00236       theParticle != theList.end(); ++theParticle) {
00237     output.push_back( (*theParticle)->p4() );
00238   }
00239   return output;
00240 }
00241 
00242 std::vector<const reco::Candidate*>
00243 GeneratorTau::getGenChargedPions() const {
00244   std::vector<const reco::Candidate*> output;
00245   std::vector<const GenParticle*>::const_iterator iter;
00246   for (iter = genChargedPions_.begin(); iter != genChargedPions_.end(); ++iter)
00247     output.push_back(static_cast<const reco::Candidate*>(*iter));
00248   return output;
00249 }
00250 
00251 std::vector<const reco::Candidate*>
00252 GeneratorTau::getGenNeutralPions() const {
00253   std::vector<const reco::Candidate*> output;
00254   std::vector<const GenParticle*>::const_iterator iter;
00255   for (iter = genNeutralPions_.begin(); iter != genNeutralPions_.end(); ++iter)
00256     output.push_back(static_cast<const reco::Candidate*>(*iter));
00257   return output;
00258 }
00259 
00260 std::vector<const reco::Candidate*>
00261 GeneratorTau::getGenGammas() const {
00262   std::vector<const reco::Candidate*> output;
00263   std::vector<const GenParticle*>::const_iterator iter;
00264   for (iter = genGammas_.begin(); iter != genGammas_.end(); ++iter)
00265     output.push_back(static_cast<const reco::Candidate*>(*iter));
00266   return output;
00267 }
00268 
00269 std::vector<const reco::Candidate*>
00270 GeneratorTau::getStableDecayProducts() const {
00271   std::vector<const reco::Candidate*> output;
00272   std::vector<const GenParticle*>::const_iterator iter;
00273   for (iter = stableDecayProducts_.begin();
00274       iter != stableDecayProducts_.end(); ++iter)
00275     output.push_back(static_cast<const reco::Candidate*>(*iter));
00276   return output;
00277 }
00278 
00279 std::vector<const reco::Candidate*> GeneratorTau::getGenNu() const {
00280   std::vector<const reco::Candidate*> output;
00281   std::vector<const GenParticle*>::const_iterator iter;
00282   for (iter = genNus_.begin(); iter != genNus_.end(); ++iter)
00283     output.push_back(static_cast<const reco::Candidate*>(*iter));
00284   return output;
00285 }
00286 
00287 std::vector<LorentzVector> GeneratorTau::getChargedPions() const {
00288   return convertMCVectorToLorentzVectors(genChargedPions_);
00289 }
00290 
00291 std::vector<LorentzVector> GeneratorTau::getGammas() const {
00292   return convertMCVectorToLorentzVectors(genGammas_);
00293 }
00294 
00295 std::vector<LorentzVector> GeneratorTau::getVisibleFourVectors() const {
00296   return convertMCVectorToLorentzVectors(visibleDecayProducts_);
00297 }
00298 
00299 LorentzVector GeneratorTau::getVisibleFourVector() const {
00300   LorentzVector output;
00301   std::vector<LorentzVector> tempForSum = getVisibleFourVectors();
00302   for (std::vector<LorentzVector>::iterator iter = tempForSum.begin();
00303       iter != tempForSum.end(); ++iter)
00304     output += (*iter);
00305   return output;
00306 }
00307