CMS 3D CMS Logo

MCParton.cc

Go to the documentation of this file.
00001 #include "RecoBTag/MCTools/interface/MCParton.h"
00002 #include <Math/GenVector/VectorUtil.h>
00003 
00004 using namespace HepMC;
00005 using namespace std;
00006 
00007 MCParton::MCParton() {
00008   reset() ;
00009 }
00010 
00011 
00012 MCParton::MCParton(const HepMC::GenParticle* particle, const HepMC::GenEvent* event,
00013                 const HepMC::GenParticle* lastParton) : 
00014                 MCBaseParticle(particle,event),
00015                 lastParton_(lastParton)
00016 {
00017   reset();
00018   setParticleProperties( );
00019 }
00020 
00021 void MCParton::reset ( ) {
00022   // reset (additional) data members
00023   flavour_             = 0  ;
00024   flavourAbs_          = 0  ;
00025   statusPythia_        = -1 ;
00026   motherLundCode_      = 0 ;
00027   motherStatusPythia_  = -1 ;
00028   fromPrimaryProcess_  = false ;
00029   fromRadiation_       = false ;
00030   fromGluonSplitting_  = false ;
00031   isFinalParton_       = false ;
00032   //  radiatesGluon_       = false ;
00033   splitsToD_           = false ; 
00034   splitsToU_           = false ; 
00035   splitsToS_           = false ; 
00036   splitsToC_           = false ; 
00037   splitsToB_           = false ;
00038   //  splitsToGluon_       = false ;
00039 
00040   daughterLines_.clear();
00041   summedDaughters_.SetPx (0.0) ;
00042   summedDaughters_.SetPy (0.0) ;
00043   summedDaughters_.SetPz (0.0) ;
00044   summedDaughters_.SetE  (0.0) ;
00045 
00046   isInitialParton_       = false ;
00047   initialPartonHasCloseHF_ = false ;
00048 }
00049 
00050 
00051 void MCParton::setParticleProperties( ) {
00052   //
00053   // only works properly if full history available!!
00054   //
00055 
00056   flavour_      = particleInfo().lundCode () ;
00057   flavourAbs_   = abs ( flavour_ ) ;
00058   statusPythia_ = hepParticle->status() ;
00059 
00060 
00061   bool hasMother = false ;
00062 
00063   MCParticleInfo motherParticleInfo ;
00064 
00065   if ( hepParticle->production_vertex() )  
00066     if   ( hepParticle->production_vertex()->particles_begin(HepMC::parents) != 
00067            hepParticle->production_vertex()->particles_end(HepMC::parents))  {
00068     mother_ = *(hepParticle->production_vertex()->particles_begin(HepMC::parents));
00069     motherParticleInfo.setCode ( mother_->pdg_id()) ;
00070     motherLundCode_ =  motherParticleInfo.lundCode() ;
00071     motherStatusPythia_ = mother_->status() ;
00072     hasMother = true ;
00073   } else {
00074     mother_ = 0;
00075   }
00076   else {
00077     mother_ = 0;
00078   }
00079 
00080 // ThS: Seems to be useless!!!
00081 //   const GenParticle *mother2 = hepParticle->secondMother()  ;
00082 //   if ( indexMother2 > 0 ) {
00083 //     MCParticleInfo Mother2 ( rhe->getParticle(indexMother2)->pid() ) ; 
00084 //   }
00085 
00086   
00087   // for status==3 partons: sum over status 2 daughters
00088   HepMC::GenEvent::particle_const_iterator p;
00089   if ( statusPythia_==3 ) {
00090     for (p = hepEvent->particles_begin(); (*p) != lastParton_; ++p) {
00091       int statusP = (**p).status() ;
00092       if( (*p)->production_vertex() ) {
00093         if ( statusP==2 && (*((*p)->production_vertex()->particles_begin(HepMC::parents)) == hepParticle) ) {
00094           //       cout << "found daughter at "<<(**p).barcode()<<endl;
00095           daughterLines_.push_back (*p) ;
00096           summedDaughters_ += math::XYZTLorentzVector ( (**p).momentum() );
00097         } // ThS: compare with the daughters from the parton itself!
00098       }
00099     }    
00100   }
00101 // cout << "But: "<<hepParticle->beginDaughters()->barcode()<<" - "
00102 // <<hepParticle->endDaughters()->barcode()<<" - "
00103 // <<hepParticle->listChildren ().size()<<" - "
00104 // <<daughterLines_.size()<<endl;
00105   // set it as initial parton if there have been daughters and the mother is not the proton
00106 
00107   if ( daughterLines_.size() >= 1 && motherLundCode_ != 2212 ) isInitialParton_ = true ;
00108 
00109 //   if ( isInitialParton_ ) {
00110 //     cout << "initial parton found " << endl ;
00111 //     cout << "summed daughters : " << summedDaughters_ << endl ;
00112 // 
00113 // //     for (std::vector< GenParticle * >::iterator   pp = hepParticle->listChildren ().begin(); pp != hepParticle->listChildren ().end(); ++pp) {
00114 // //    cout << "But: "<<(**pp).barcode()<<endl;
00115 // //    cout << "But: "<<(**pp).mother()->barcode()<<" - "<<(**pp).barcode()<<endl;
00116 // //   }
00117 //   }
00118 
00119   // to allow to clean up later on:
00120   // check if there are other heavy flavour partons within a cone of certain size
00121   // which do not origin from the initial parton
00122   if (isInitialParton_) {
00123     for (p = hepEvent->particles_begin(); (*p) != lastParton_; ++p) {
00124       int statusP = (**p).status() ;
00125       MCParticleInfo lundCodeP((**p).pdg_id()) ;
00126       int flavourP = abs ( lundCodeP.lundCode() ) ;
00127       double deltaRP = ROOT::Math::VectorUtil::DeltaR(math::XYZTLorentzVector((**p).momentum()), math::XYZTLorentzVector(hepParticle->momentum()));
00128       if( (*p)->production_vertex() ){
00129         if ( statusP==2 &&
00130              *((*p)->production_vertex()->particles_begin(HepMC::parents)) != hepParticle &&
00131              (flavourP==4 || flavourP==5)    &&
00132              deltaRP<0.8 ) {
00133           initialPartonHasCloseHF_ = true ;
00134         }
00135       }
00136     }    
00137   }
00138   
00139   
00140   
00141   // is it primary after rad. (the real primary ones are the ones with Status 3!!)
00142   // yes, if mother itself is a parton and has 'documentation status' = 3
00143   if ( hasMother && motherParticleInfo.isParton() && motherStatusPythia_ == 3 )
00144         fromPrimaryProcess_ = true ;
00145   // but: if it has a status==3 daughter, don't set it!
00146   for (p = hepEvent->particles_begin(); (*p) != lastParton_; ++p) {
00147     if((*p)->production_vertex()){
00148       if ( ((**p).status() == 3)  && 
00149            (*((*p)->production_vertex()->particles_begin(HepMC::parents)) == hepParticle) ) 
00150         fromPrimaryProcess_ = false ; 
00151     }
00152   }
00153   
00154 
00155   
00156   // is it from gluon splitting?
00157   // also check if mother has status == 3
00158   //CW if ( hasMother && motherParticleInfo.isGluon() && motherStatusPythia_==3 )  fromGluonSplitting = true ; 
00159 
00160   //CW new
00161   // is a quark, has status==2, mother has status==3 and different flavour
00162   if ( statusPythia_==2 &&
00163        flavourAbs_>=0 && flavourAbs_<=5 &&
00164        motherStatusPythia_==3 &&
00165        flavour_ != motherLundCode_ ) fromGluonSplitting_ = true ;      
00166   
00167   
00168   // is it a 'final' parton ?
00169   // no daughters -> loop over partons and check if mother
00170   // it has to be status==2 !!
00171   isFinalParton_ = true ;
00172   if ( statusPythia_ != 2 ) isFinalParton_ = false ;
00173   for (p = hepEvent->particles_begin(); (*p) != lastParton_; ++p) {
00174     if((*p)->production_vertex()) if ( *((*p)->production_vertex()->particles_begin(HepMC::parents)) == hepParticle ) isFinalParton_ = false ; 
00175   }
00176 
00177   
00178   // is it a quark that radiates off a gluon?
00179   // (not yet there, needed for anything?)
00180 
00181   
00182   // is it a gluon or light quark that splits? (either direct or subsequent splitting)
00183   // a slitting gluon needs to have a quark and antiquark of same flavour amongst its daughters;
00184   // again, we have to go via all partons and check if they have the current parton as mother
00185   if ( particleInfo().isGluon() ||  particleInfo().isD() || particleInfo().isU() || particleInfo().isS() ) {
00186     int nD (0) , nDBar (0) ;
00187     int nU (0) , nUBar (0) ;
00188     int nS (0) , nSBar (0) ;
00189     int nC (0) , nCBar (0) ;
00190     int nB (0) , nBBar (0) ;
00191     for (p = hepEvent->particles_begin(); (*p) != lastParton_; ++p) {
00192     if((*p)->production_vertex())  if ( *((*p)->production_vertex()->particles_begin(HepMC::parents)) == hepParticle ) {
00193         int pid = (**p).pdg_id();
00194         if ( pid == 1 ) nD++ ;
00195         if ( pid == 2 ) nU++ ;
00196         if ( pid == 3 ) nS++ ;
00197         if ( pid == 4 ) nC++ ;
00198         if ( pid == 5 ) nB++ ;
00199         // bar
00200         if ( pid == -1 ) nDBar++ ;
00201         if ( pid == -2 ) nUBar++ ;
00202         if ( pid == -3 ) nSBar++ ;
00203         if ( pid == -4 ) nCBar++ ;
00204         if ( pid == -5 ) nBBar++ ;
00205       }
00206     }
00207     if ( nD>0 && nDBar>0 ) splitsToD_ = true ; 
00208     if ( nU>0 && nUBar>0 ) splitsToU_ = true ; 
00209     if ( nS>0 && nSBar>0 ) splitsToS_ = true ; 
00210     if ( nC>0 && nCBar>0 ) splitsToC_ = true ; 
00211     if ( nB>0 && nBBar>0 ) splitsToB_ = true ; 
00212   }
00213 //  print();   
00214 }
00215 
00216 
00217 
00218 void MCParton::print() const {
00219   // print all Info for heavy hadron
00220   cout << "--> MCParton:" << endl;
00221   cout << "--> LundCode, flavour, statusPythia: ";
00222   cout.width(8); cout << particleInfo().lundCode();
00223   cout.width(8); cout << flavour_;
00224   cout.width(8); cout << statusPythia_        << endl;
00225 
00226   cout << "--> Mother Lund Code, status :       ";
00227   cout.width(8); cout << motherLundCode_;
00228   cout.width(16); cout << motherStatusPythia_ << endl;
00229 
00230   if ( fromPrimaryProcess_) cout << "--> fromPrimaryProcess ";
00231   if ( fromRadiation_   ) cout << "--> fromRadiation      ";
00232   if ( fromGluonSplitting_) cout << "--> fromGluonSplitting ";
00233   if ( isFinalParton_   ) cout << "--> isFinalParton      ";
00234   if ( isInitialParton_ ) cout << "--> isInitialParton    ";
00235   if ( fromPrimaryProcess_ || fromRadiation_ || fromGluonSplitting_ || isFinalParton_ ||
00236         isInitialParton_ ) cout << endl;
00237     //  cout << "--> radiates gluon         :" << radiatesGluon       << endl;
00238 
00239   if (splitsToD_ || splitsToU_ || splitsToS_ || splitsToC_ || splitsToB_)
00240         cout <<"--> splits to : ";
00241   if (splitsToD_) cout << " D";
00242   if (splitsToU_) cout << " U";
00243   if (splitsToS_) cout << " S";
00244   if (splitsToC_) cout << " C";
00245   if (splitsToB_) cout << " B";
00246   if (splitsToD_ || splitsToU_ || splitsToS_ || splitsToC_ || splitsToB_)
00247     cout << endl;
00248 
00249 //   cout << "--> splitsToGluon          :" << splitsToGluon       << endl;
00250 //   cout << "--> mass                   :" << mass                << endl;
00251 //   cout << "--> eta                    :" << eta                 << endl;
00252 //   cout << "--> phi                    :" << phi                 << endl;
00253 //   cout << "--> pabs                   :" << pabs                << endl;
00254 //   cout << "--> e                      :" << e                   << endl;
00255   cout << "--> Momentum, eta, phi        :" << fourVector().px()<< " , "  
00256     << fourVector().py() << " , " << fourVector().pz() << " , "  
00257     << fourVector().eta()<< " , " << fourVector().phi() <<endl;
00258   cout << "--> Summed daugther momentum  :" << summedDaughters_.px()<< " , "
00259     << summedDaughters_.py() << " , " << summedDaughters_.pz() << " , "
00260     << summedDaughters_.eta()<< " , " << summedDaughters_.phi() <<endl;
00261   cout << endl;
00262 
00263 }
00264   

Generated on Tue Jun 9 17:43:03 2009 for CMSSW by  doxygen 1.5.4