![]() |
![]() |
#include <PhysicsTools/HepMCCandAlgos/interface/FlavorHistoryProducer.h>
Public Member Functions | |
FlavorHistoryProducer (const edm::ParameterSet &) | |
constructor | |
~FlavorHistoryProducer () | |
destructor | |
Private Member Functions | |
void | beginJob (const edm::EventSetup &) |
module init at begin of job | |
void | getAncestors (const reco::Candidate &c, std::vector< reco::Candidate const * > &moms) |
void | produce (edm::Event &e, const edm::EventSetup &) |
process one event | |
Private Attributes | |
double | etaMaxParticle_ |
double | etaMaxShower_ |
std::string | flavorHistoryName_ |
int | pdgIdToSelect_ |
double | ptMinParticle_ |
double | ptMinShower_ |
edm::InputTag | src_ |
bool | verbose_ |
Definition at line 64 of file FlavorHistoryProducer.h.
FlavorHistoryProducer::FlavorHistoryProducer | ( | const edm::ParameterSet & | p | ) |
constructor
Definition at line 74 of file FlavorHistoryProducer.cc.
References flavorHistoryName_.
00074 : 00075 src_( p.getParameter<InputTag>( "src" ) ), 00076 pdgIdToSelect_( p.getParameter<int> ("pdgIdToSelect") ), 00077 ptMinParticle_( p.getParameter<double>( "ptMinParticle") ), 00078 ptMinShower_( p.getParameter<double>( "ptMinShower") ), 00079 etaMaxParticle_( p.getParameter<double>( "etaMaxParticle" )), 00080 etaMaxShower_( p.getParameter<double>( "etaMaxShower" )), 00081 flavorHistoryName_( p.getParameter<string>("flavorHistoryName") ), 00082 verbose_( p.getUntrackedParameter<bool>( "verbose" ) ) 00083 { 00084 produces<vector<FlavorHistory> >(flavorHistoryName_); 00085 }
FlavorHistoryProducer::~FlavorHistoryProducer | ( | ) |
void FlavorHistoryProducer::beginJob | ( | const edm::EventSetup & | es | ) | [private, virtual] |
module init at begin of job
Reimplemented from edm::EDProducer.
Definition at line 90 of file FlavorHistoryProducer.cc.
void FlavorHistoryProducer::getAncestors | ( | const reco::Candidate & | c, | |
std::vector< reco::Candidate const * > & | moms | |||
) | [private] |
Referenced by produce().
void FlavorHistoryProducer::produce | ( | edm::Event & | e, | |
const edm::EventSetup & | ||||
) | [private, virtual] |
process one event
Implements edm::EDProducer.
Definition at line 93 of file FlavorHistoryProducer.cc.
References funct::abs(), GenMuonPlsPt100GeV_cfg::cout, reco::Candidate::daughter(), lat::endl(), eta, etaMaxShower_, find(), flavorHistoryName_, getAncestors(), edm::Event::getByLabel(), i, j, reco::Candidate::mother(), reco::Candidate::numberOfDaughters(), reco::Candidate::numberOfMothers(), p, reco::Particle::pdgId(), pdgIdToSelect_, ptMinShower_, edm::Event::put(), src_, StDecayID::status, reco::Particle::status(), and verbose_.
00094 { 00095 00096 if ( verbose_ ) cout << "Producing flavor history" << endl; 00097 00098 // Get a handle to the particle collection (OwnVector) 00099 Handle<CandidateView > particlesViewH; 00100 evt.getByLabel( src_, particlesViewH ); 00101 00102 // Copy the View to an vector for easier iterator manipulation convenience 00103 vector<const Candidate* > particles; 00104 for( CandidateView::const_iterator p = particlesViewH->begin(); p != particlesViewH->end(); ++p ) { 00105 particles.push_back(&*p); 00106 } 00107 00108 // Make a new flavor history vector 00109 auto_ptr<vector<FlavorHistory> > flavorHistoryVector ( new vector<FlavorHistory> () ) ; 00110 00111 // ------------------------------------------------------------ 00112 // Loop over partons 00113 // ------------------------------------------------------------ 00114 vector<const Candidate* >::size_type j; 00115 vector<const Candidate* >::size_type j_max = particles.size(); 00116 for( j=0; j<j_max; ++j ) { 00117 00118 if ( verbose_ ) cout << "Processing particle " << j << endl; 00119 00120 // Get the candidate 00121 const Candidate *p = particles[j]; 00122 // Set up indices that we'll need for the flavor history 00123 vector<Candidate const *>::size_type partonIndex=j; 00124 vector<Candidate const *>::size_type progenitorIndex=0; 00125 vector<Candidate const *>::size_type sisterIndex=0; 00126 bool foundProgenitor = false; 00127 bool foundSister = false; 00128 FlavorHistory::FLAVOR_T flavorSource=FlavorHistory::FLAVOR_NULL; 00129 00130 00131 int idabs = abs( (p)->pdgId() ); 00132 int nDa = (p)->numberOfDaughters(); 00133 00134 // Check if we have a status 2 or 3 particle, which is a parton before the string. 00135 // Only consider quarks. 00136 if ( idabs <= FlavorHistory::tQuarkId && p->status() == 2 ) { 00137 // Ensure the parton in question has daughters 00138 if ( nDa > 0 ) { 00139 // Ensure the parton passes some minimum kinematic cuts 00140 if((p)->pt() > ptMinShower_ && fabs((p)->eta())<etaMaxShower_) { 00141 00142 00143 if(verbose_) cout << "--------------------------" << endl; 00144 if(verbose_) cout << "Processing particle " << j << " = " << *p << endl; 00145 00146 00147 //Main (but simple) workhorse to get all ancestors 00148 vector<Candidate const *> allParents; 00149 getAncestors( *p, allParents ); 00150 00151 if(verbose_) { 00152 cout << "Parents : " << endl; 00153 vector<Candidate const *>::const_iterator iprint = allParents.begin(), 00154 iprintend = allParents.end(); 00155 for ( ; iprint != iprintend; ++iprint ) 00156 cout << **iprint << endl; 00157 } 00158 00159 00160 // ------------------------------------------------------------- 00161 // Identify the ancestry of the Quark 00162 // 00163 // 00164 // Matrix Element: 00165 // Status 3 parent with precisely 2 "grandparents" that 00166 // is outside of the "initial" section (0-5) that has the 00167 // same ID as the status 2 parton in question. 00168 // NOTE: This is not the actual ultimate progenitor, 00169 // but this is the signature of matrix element decays. 00170 // The ultimate progenitor is the parent of the status 3 00171 // parton. 00172 // 00173 // Flavor excitation: 00174 // Almost the same as the matrix element classification, 00175 // but has only one outgoing parton product instead of two. 00176 // 00177 // Gluon splitting: 00178 // Parent is a quark of a different flavor than the parton 00179 // in question, or a gluon. Can come from either ISR or FSR. 00180 // 00181 // True decay: 00182 // Decays from a resonance like top, Higgs, etc. 00183 // ------------------------------------------------------------- 00184 vector<Candidate const *>::size_type a_size = allParents.size(); 00185 int parentIndex=0; 00186 00187 // 00188 // Loop over all the ancestors of this parton and find the progenitor. 00189 // 00190 for( vector<Candidate const *>::size_type i=0 ; i < a_size && !foundProgenitor; ++i,++parentIndex ) { 00191 const Candidate * aParent=allParents[i]; 00192 vector<Candidate const *>::const_iterator found = find(particles.begin(),particles.end(),aParent); 00193 00194 00195 // Get the index of the progenitor candidate 00196 progenitorIndex = found - particles.begin(); 00197 00198 int aParentId = abs(aParent->pdgId()); 00199 00200 // ----------------------------------------------------------------------- 00201 // Here we examine particles that were produced after the collision 00202 // ----------------------------------------------------------------------- 00203 if( aParent->numberOfMothers() == 2 && progenitorIndex > 5 ) { 00204 // Here is where we have a matrix element process. 00205 // The signature is to have a status 3 parent with precisely 2 parents 00206 // that is outside of the "initial" section (0-5) that has the 00207 // same ID as the status 2 parton in question. 00208 // NOTE: This is not the actual ultimate progenitor, but this is 00209 // the signature of matrix element decays. The ultimate progentitor 00210 // is the parent of the status 3 parton. 00211 // ALSO NOTE: If this parton has no sister, then this will be classified as 00212 // a flavor excitation. The only difference, since the initial states are 00213 // mostly gluons, is that the matrix element cases have a sister, 00214 // while the flavor excitation cases do not. 00215 // If we do not find a sister below, this will be classified as a flavor 00216 // excitation. 00217 if( aParentId == pdgIdToSelect_ ) { 00218 if(verbose_) cout << "Matrix Element progenitor" << endl; 00219 flavorSource = FlavorHistory::FLAVOR_ME; 00220 00221 // The "true" progenitor is the next parent in the list (the parent of this 00222 // progenitor). 00223 if ( i != a_size - 1 ) { 00224 const Candidate * progenitorCand = allParents[i+1]; 00225 vector<Candidate const *>::const_iterator foundAgain = find( particles.begin(), 00226 particles.end(), 00227 progenitorCand ); 00228 progenitorIndex = foundAgain - particles.begin(); 00229 foundProgenitor = true; 00230 00231 } else { 00232 edm::LogWarning("UnexpectedFormat") << "Error! Parentage information in FlavorHistoryProducer is not what is expected"; 00233 00234 cout << "Particle : " << *p << endl; 00235 cout << "Parents : " << endl; 00236 vector<Candidate const *>::const_iterator iprint = allParents.begin(), 00237 iprintend = allParents.end(); 00238 for ( ; iprint != iprintend; ++iprint ) 00239 cout << **iprint << endl; 00240 00241 foundProgenitor = false; 00242 00243 } 00244 } 00245 // Here we have a gluon splitting from final state radiation. 00246 // The parent is a quark of a different flavor, or a gluon, in the 00247 // final state. 00248 else if( (aParentId > 0 && aParentId < FlavorHistory::tQuarkId ) || aParentId==FlavorHistory::gluonId ) { 00249 if(verbose_) cout << "Gluon splitting progenitor" << endl; 00250 flavorSource = FlavorHistory::FLAVOR_GS; 00251 foundProgenitor = true; 00252 } 00253 // Here we have a true decay. Parent is not a quark or a gluon. 00254 else if( (aParentId>pdgIdToSelect_ && aParentId<FlavorHistory::gluonId) || aParentId > FlavorHistory::gluonId ) { 00255 if(verbose_) cout << "Flavor decay progenitor" << endl; 00256 flavorSource = FlavorHistory::FLAVOR_DECAY; 00257 foundProgenitor = true; 00258 } 00259 } 00260 00261 // ----------------------------------------------------------------------- 00262 // Here we examine particles that were produced before the collision 00263 // ----------------------------------------------------------------------- 00264 else if( progenitorIndex <= 5 ) { 00265 // Parent has a quark daughter equal and opposite to this: ISR 00266 if( aParent->numberOfDaughters() > 0 && 00267 aParent->daughter(0)->pdgId() == -1 * p->pdgId() ) { 00268 if(verbose_) cout << "Gluon splitting progenitor" << endl; 00269 flavorSource = FlavorHistory::FLAVOR_GS; 00270 } 00271 // Otherwise, this is flavor excitation. Rarely happens because 00272 // mostly the initial state is gluons which will be caught by the 00273 // "matrix element" version above. 00274 else { 00275 if(verbose_) cout << "Flavor excitation progenitor" << endl; 00276 flavorSource = FlavorHistory::FLAVOR_EXC; 00277 } 00278 foundProgenitor = true; 00279 } 00280 }// End loop over all parents of this parton to find progenitor 00281 00282 00283 00284 // 00285 // Now find sister of this particle if there is one 00286 // 00287 if ( foundProgenitor && progenitorIndex >= 0 ) { 00288 // Get the progenitor 00289 const Candidate * progenitorCand = particles[progenitorIndex]; 00290 00291 if ( verbose_ ) cout << "Found progenitor: " << *progenitorCand << endl; 00292 00293 // Here is the normal case of a sister around 00294 if ( progenitorCand->numberOfDaughters() >= 2 ) { 00295 const Candidate * sisterCand = 0; 00296 00297 for ( unsigned int iida = 0; iida < progenitorCand->numberOfDaughters(); ++iida ) { 00298 const Candidate * dai = progenitorCand->daughter(iida); 00299 00300 if ( verbose_ ) cout << "Sister candidate " << *dai << endl; 00301 00302 if ( dai->pdgId() == -1 * p->pdgId() ) { 00303 if ( verbose_ ) cout << "Found actual sister" << endl; 00304 sisterCand = dai; 00305 foundSister = true; 00306 } 00307 } 00308 00309 if ( foundSister ) { 00310 // Find index of daughter in master list 00311 vector<Candidate const *>::const_iterator found = find(particles.begin(),particles.end(),sisterCand); 00312 sisterIndex = found - particles.begin(); 00313 if(verbose_) cout << "Sister index = " << sisterIndex << endl; 00314 if ( found != particles.end() ) 00315 if(verbose_) cout << "Sister = " << **found << endl; 00316 } // end if found sister 00317 } 00318 // Here is if we have a "transient" decay in the code that isn't 00319 // really a decay, so we need to look at the parent of the progenitor 00320 else { 00321 const Candidate * grandProgenitorCand = progenitorCand->mother(0); 00322 const Candidate * sisterCand = 0; 00323 00324 if ( verbose_ ) cout << "Looking for sister, progenitor is " << *progenitorCand << endl; 00325 00326 // Make sure the progenitor has two daughters 00327 if ( grandProgenitorCand->numberOfDaughters() >= 2 ) { 00328 00329 for ( unsigned int iida = 0; iida < grandProgenitorCand->numberOfDaughters(); ++iida ) { 00330 const Candidate * dai = grandProgenitorCand->daughter(iida); 00331 00332 if ( verbose_ ) cout << "Looking for sister " << *dai << endl; 00333 00334 if ( dai->pdgId() == -1 * p->pdgId() ) { 00335 if ( verbose_ ) cout << "Found sister" << endl; 00336 sisterCand = dai; 00337 foundSister = true; 00338 } 00339 } 00340 00341 if ( foundSister ) { 00342 // Find index of daughter in master list 00343 vector<Candidate const *>::const_iterator found = find(particles.begin(),particles.end(),sisterCand); 00344 sisterIndex = found - particles.begin(); 00345 if(verbose_) cout << "Sister index = " << sisterIndex << endl; 00346 if ( found != particles.end() ) 00347 if(verbose_) cout << "Sister = " << **found << endl; 00348 } // end if found sister 00349 } // End of have at least 2 grand progenitor daughters 00350 } // End if we have to look at parents of progenitor to find sister 00351 00352 } // end if found progenitor 00353 00354 // ------ 00355 // Here, we change the type from matrix element to flavor excitation 00356 // if there are no sisters present. 00357 // ------ 00358 if ( flavorSource == FlavorHistory::FLAVOR_ME && !foundSister ) { 00359 flavorSource = FlavorHistory::FLAVOR_EXC; 00360 } 00361 00362 }// End if this parton passes some minimal kinematic cuts 00363 }// End if this particle has strings as daughters 00364 }// End if this particle was a status==2 parton 00365 00366 // Make sure we've actually found a sister and a progenitor 00367 if ( !foundProgenitor ) progenitorIndex = 0; 00368 if ( !foundSister ) sisterIndex = 0; 00369 00370 // We've found the particle, add to the list (status 2 only) 00371 if ( idabs == pdgIdToSelect_ && p->status() == 2 ) 00372 flavorHistoryVector->push_back( FlavorHistory( flavorSource, particlesViewH, partonIndex, progenitorIndex, sisterIndex ) ); 00373 } 00374 00375 00376 // ValueMap<FlavorHistory>::Filler filler(*flavorHistory); 00377 // filler.insert( particlesViewH, flavorHistoryVector.begin(), flavorHistoryVector.end() ); 00378 // filler.fill(); 00379 // Now add the flavor history to the event record 00380 if ( verbose_ ) { 00381 cout << "Outputting pdg id = " << pdgIdToSelect_ << " with nelements = " << flavorHistoryVector->size() << endl; 00382 vector<FlavorHistory>::const_iterator i = flavorHistoryVector->begin(), 00383 iend = flavorHistoryVector->end(); 00384 for ( ; i !=iend; ++i ) { 00385 cout << *i << endl; 00386 } 00387 } 00388 evt.put( flavorHistoryVector, flavorHistoryName_ ); 00389 }
double FlavorHistoryProducer::etaMaxParticle_ [private] |
Definition at line 86 of file FlavorHistoryProducer.h.
double FlavorHistoryProducer::etaMaxShower_ [private] |
std::string FlavorHistoryProducer::flavorHistoryName_ [private] |
Definition at line 88 of file FlavorHistoryProducer.h.
Referenced by FlavorHistoryProducer(), and produce().
int FlavorHistoryProducer::pdgIdToSelect_ [private] |
double FlavorHistoryProducer::ptMinParticle_ [private] |
Definition at line 84 of file FlavorHistoryProducer.h.
double FlavorHistoryProducer::ptMinShower_ [private] |
edm::InputTag FlavorHistoryProducer::src_ [private] |
bool FlavorHistoryProducer::verbose_ [private] |