CMS 3D CMS Logo

StDecaySubset.cc

Go to the documentation of this file.
00001 #include "FWCore/Utilities/interface/EDMException.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003 
00004 #include "AnalysisDataFormats/TopObjects/interface/StGenEvent.h"
00005 #include "TopQuarkAnalysis/TopEventProducers/interface/StDecaySubset.h"
00006 
00007 using namespace std;
00008 using namespace reco;
00009 
00010 namespace StDecayID{
00011   static const int status = 3;
00012   static const int tID = 6;
00013   static const int bID = 5;
00014   static const int WID =24;
00015 }
00016 
00017 StDecaySubset::StDecaySubset(const edm::ParameterSet& cfg):
00018   src_ ( cfg.getParameter<edm::InputTag>( "src" ) )
00019 {
00020   switchOption    = cfg.getParameter<int>("SwitchChainType");
00021   produces<reco::GenParticleCollection>();
00022 }
00023 
00024 StDecaySubset::~StDecaySubset()
00025 {
00026 }
00027 
00028 void
00029 StDecaySubset::produce(edm::Event& evt, const edm::EventSetup& setup)
00030 {     
00031   edm::Handle<reco::GenParticleCollection> src;
00032   evt.getByLabel(src_, src);
00033  
00034   const reco::GenParticleRefProd ref = evt.getRefBeforePut<reco::GenParticleCollection>(); 
00035   std::auto_ptr<reco::GenParticleCollection> sel( new reco::GenParticleCollection );
00036 
00037   //clear existing refs
00038   refs_.clear();
00039   //fill output collection
00040   fillOutput( *src, *sel );
00041   //fill references
00042   fillRefs( ref, *sel );
00043 
00044   evt.put( sel );
00045 }
00046 
00047 Particle::LorentzVector StDecaySubset::fourVector(const reco::GenParticle& p)
00048 {
00049   Particle::LorentzVector vec;
00050   GenParticle::const_iterator pd=p.begin();
00051   for( ; pd!=p.end(); ++pd){
00052     if( pd->status()==StDecayID::status ){
00053       vec+=fourVector( *pd );
00054     }
00055     else{
00056       //skip W with status 2 to
00057       //prevent double counting
00058       if( abs(pd->pdgId())!=StDecayID::WID )
00059         vec+=pd->p4();
00060     }
00061   }
00062   return vec;
00063 }
00064 
00065 void StDecaySubset::fillOutput(const reco::GenParticleCollection& src, reco::GenParticleCollection& sel)
00066 {
00067   if (switchOption==1) { // standard option: look for top and W, and navigate through the decay chains
00068     GenParticleCollection::const_iterator t=src.begin();
00069     for(int idx=-1; t!=src.end(); ++t){
00070       if( t->status()==StDecayID::status && abs( t->pdgId() )==StDecayID::tID ){ //is top      
00071         GenParticle* cand = new GenParticle( t->charge(), fourVector( *t ), 
00072                                                                t->vertex(), t->pdgId(), t->status(), false );
00073         auto_ptr<reco::GenParticle> ptr( cand );
00074         sel.push_back( *ptr );
00075         ++idx;
00076 
00077         //keep top index for the map for 
00078         //management of the daughter refs 
00079         int iTop=idx, iW=0;
00080         vector<int> topDaughs, wDaughs;
00081         
00082         //iterate over top daughters
00083         GenParticle::const_iterator td=t->begin();
00084         for( ; td!=t->end(); ++td){
00085           if( td->status()==StDecayID::status && abs( td->pdgId() )==StDecayID::bID ){ //is beauty        
00086             GenParticle* cand = new GenParticle( td->charge(), fourVector( *td ), 
00087                                                                    td->vertex(), td->pdgId(), td->status(), false );
00088             auto_ptr<GenParticle> ptr( cand );
00089             sel.push_back( *ptr );        
00090             topDaughs.push_back( ++idx ); //push index of top daughter
00091           }
00092           if( td->status()==StDecayID::status && abs( td->pdgId() )==StDecayID::WID ){ //is W boson
00093             GenParticle* cand = new GenParticle( td->charge(), fourVector( *td ), 
00094                                                                    td->vertex(), td->pdgId(), td->status(), true );
00095             auto_ptr<GenParticle> ptr( cand );
00096             sel.push_back( *ptr );
00097             topDaughs.push_back( ++idx ); //push index of top daughter
00098             
00099             //keep W idx 
00100             //for the map
00101             iW=idx;
00102 
00103             //iterate over W daughters
00104             GenParticle::const_iterator wd=td->begin();
00105             for( ; wd!=td->end(); ++wd){
00106               if (wd->pdgId() != td->pdgId()) {
00107                 GenParticle* cand = new GenParticle( wd->charge(), fourVector( *wd ), 
00108                                                                        wd->vertex(), wd->pdgId(), wd->status(), false );              auto_ptr<GenParticle> ptr( cand );
00109                 sel.push_back( *ptr );
00110                 wDaughs.push_back( ++idx ); //push index of wBoson daughter
00111               }
00112             }
00113           }
00114         }
00115         refs_[ iTop ]=topDaughs;
00116         refs_[ iW ]=wDaughs;
00117       }
00118     }
00119   } else if (switchOption==2) { // this is needed, for example, for the SingleTop generator, since it doesn't save the intermediate particles (lepton, neutrino and b are directly daughters of the incoming partons)
00120 
00121     int iP;
00122     vector<int> ipDaughs;
00123 
00124     GenParticleCollection::const_iterator ip1=src.begin();
00125     GenParticleCollection::const_iterator ip2=src.begin();
00126     for(int idx=-1; ip1!=src.end(); ++ip1){
00127       for(; ip2!=src.end(); ++ip2){
00128 
00129         //iterate over the daughters of both
00130         GenParticle::const_iterator td1=ip1->begin();
00131         GenParticle::const_iterator td2=ip2->begin();
00132         for( ; td1!=ip1->end(); ++td1){
00133           for( ; td2!=ip2->end(); ++td2){
00134             if (td1 == td2) { // daughter of both initial state partons
00135 
00136               //              ++idx;
00137               //              iP=idx;
00138 
00139               GenParticle* cand = new GenParticle( td2->charge(), fourVector( *td2 ), 
00140                                                                      td2->vertex(), td2->pdgId(), td2->status(), false );
00141               auto_ptr<GenParticle> ptr( cand );
00142               sel.push_back( *ptr );      
00143               ipDaughs.push_back( ++idx ); //push index of daughter
00144               iP=idx;
00145             }
00146             refs_[ iP ]=ipDaughs;
00147           }
00148         }// end of double loop on daughters
00149 
00150       }
00151     }
00152   }
00153 
00154 }
00155 
00156 void StDecaySubset::fillRefs(const reco::GenParticleRefProd& ref, reco::GenParticleCollection& sel)
00157 { 
00158   GenParticleCollection::iterator p=sel.begin();
00159   for(int idx=0; p!=sel.end(); ++p, ++idx){
00160     //find daughter reference vectors in refs_ and add daughters
00161     map<int, vector<int> >::const_iterator daughters=refs_.find( idx );
00162     if( daughters!=refs_.end() ){
00163       vector<int>::const_iterator daughter = daughters->second.begin();
00164       for( ; daughter!=daughters->second.end(); ++daughter){
00165         GenParticle* part = dynamic_cast<GenParticle* > (&(*p));
00166         if(part == 0){
00167           throw edm::Exception( edm::errors::InvalidReference, "Not a GenParticle" );
00168         }
00169         part->addDaughter( GenParticleRef(ref, *daughter) );
00170         sel[*daughter].addMother( GenParticleRef(ref, idx) );
00171       }
00172     }
00173   }
00174 }

Generated on Tue Jun 9 17:48:06 2009 for CMSSW by  doxygen 1.5.4