00001
00002
00003
00004 #include "PhysicsTools/HepMCCandAlgos/interface/FlavorHistoryProducer.h"
00005
00006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 using namespace std;
00038 using namespace reco;
00039 using namespace edm;
00040
00041
00042 ostream & operator<<( ostream & out, Candidate const & cand)
00043 {
00044 char buff[1000];
00045 sprintf(buff, "%5d, status = %5d, nmo = %5d, nda = %5d, pt = %6.2f, eta = %6.2f, phi = %6.2f, m = %6.2f",
00046 cand.pdgId(), cand.status(),
00047 cand.numberOfMothers(),
00048 cand.numberOfDaughters(),
00049 cand.pt(), cand.eta(), cand.phi(), cand.mass() );
00050 out << buff;
00051 return out;
00052 }
00053
00054 ostream & operator<<( ostream & out, FlavorHistory const & cand)
00055 {
00056 out << "Source = " << cand.flavorSource() << endl;
00057 if ( cand.hasParton() )
00058 out << "Parton = " << cand.parton().key() << " : " << *(cand.parton()) << endl;
00059 if ( cand.hasProgenitor() )
00060 out << "Progenitor = " << cand.progenitor().key() << " : " << *(cand.progenitor()) << endl;
00061 if ( cand.hasSister() )
00062 out << "Sister = " << cand.sister().key() << " : " << *(cand.sister()) << endl;
00063 if ( cand.hasParton() ) {
00064 out << "Ancestry: " << endl;
00065 Candidate const * ipar = cand.parton()->mother();
00066 while ( ipar->numberOfMothers() > 0 ) {
00067 out << *ipar << endl;
00068 ipar = ipar->mother();
00069 }
00070 }
00071 return out;
00072 }
00073
00074 FlavorHistoryProducer::FlavorHistoryProducer( const ParameterSet & p ) :
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 }
00086
00087 FlavorHistoryProducer::~FlavorHistoryProducer() {
00088 }
00089
00090 void FlavorHistoryProducer::beginJob( const EventSetup & es ) {
00091 }
00092
00093 void FlavorHistoryProducer::produce( Event& evt, const EventSetup& )
00094 {
00095
00096 if ( verbose_ ) cout << "Producing flavor history" << endl;
00097
00098
00099 Handle<CandidateView > particlesViewH;
00100 evt.getByLabel( src_, particlesViewH );
00101
00102
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
00109 auto_ptr<vector<FlavorHistory> > flavorHistoryVector ( new vector<FlavorHistory> () ) ;
00110
00111
00112
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
00121 const Candidate *p = particles[j];
00122
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
00135
00136 if ( idabs <= FlavorHistory::tQuarkId && p->status() == 2 ) {
00137
00138 if ( nDa > 0 ) {
00139
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
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
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184 vector<Candidate const *>::size_type a_size = allParents.size();
00185 int parentIndex=0;
00186
00187
00188
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
00196 progenitorIndex = found - particles.begin();
00197
00198 int aParentId = abs(aParent->pdgId());
00199
00200
00201
00202
00203 if( aParent->numberOfMothers() == 2 && progenitorIndex > 5 ) {
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 if( aParentId == pdgIdToSelect_ ) {
00218 if(verbose_) cout << "Matrix Element progenitor" << endl;
00219 flavorSource = FlavorHistory::FLAVOR_ME;
00220
00221
00222
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
00246
00247
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
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
00263
00264 else if( progenitorIndex <= 5 ) {
00265
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
00272
00273
00274 else {
00275 if(verbose_) cout << "Flavor excitation progenitor" << endl;
00276 flavorSource = FlavorHistory::FLAVOR_EXC;
00277 }
00278 foundProgenitor = true;
00279 }
00280 }
00281
00282
00283
00284
00285
00286
00287 if ( foundProgenitor && progenitorIndex >= 0 ) {
00288
00289 const Candidate * progenitorCand = particles[progenitorIndex];
00290
00291 if ( verbose_ ) cout << "Found progenitor: " << *progenitorCand << endl;
00292
00293
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
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 }
00317 }
00318
00319
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
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
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 }
00349 }
00350 }
00351
00352 }
00353
00354
00355
00356
00357
00358 if ( flavorSource == FlavorHistory::FLAVOR_ME && !foundSister ) {
00359 flavorSource = FlavorHistory::FLAVOR_EXC;
00360 }
00361
00362 }
00363 }
00364 }
00365
00366
00367 if ( !foundProgenitor ) progenitorIndex = 0;
00368 if ( !foundSister ) sisterIndex = 0;
00369
00370
00371 if ( idabs == pdgIdToSelect_ && p->status() == 2 )
00372 flavorHistoryVector->push_back( FlavorHistory( flavorSource, particlesViewH, partonIndex, progenitorIndex, sisterIndex ) );
00373 }
00374
00375
00376
00377
00378
00379
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 }
00390
00391
00392
00393 void FlavorHistoryProducer::getAncestors(const Candidate &c,
00394 vector<Candidate const *> & moms )
00395 {
00396
00397 if( c.numberOfMothers() == 1 ) {
00398 const Candidate * dau = &c;
00399 const Candidate * mom = c.mother();
00400 while ( dau->numberOfMothers() != 0) {
00401 moms.push_back( dau );
00402 dau = mom ;
00403 mom = dau->mother();
00404 }
00405 }
00406 }
00407
00408
00409
00410 #include "FWCore/Framework/interface/MakerMacros.h"
00411
00412 DEFINE_FWK_MODULE( FlavorHistoryProducer );