test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TopDecaySubset.cc
Go to the documentation of this file.
3 
6 
8 
11  srcToken_ (consumes<reco::GenParticleCollection>(cfg.getParameter<edm::InputTag>("src"))),
12  genEventInfo_srcToken_ (mayConsume < GenEventInfoProduct > (edm::InputTag("generator"))),
13  addRadiation_(cfg.getParameter<bool>("addRadiation")),
14  showerModel_ (kStart),
15  runMode_(kRun1)
16 {
17  // mapping of the corresponding fillMode; see FillMode
18  // enumerator of TopDecaySubset for available modes
19  std::string mode = cfg.getParameter<std::string>( "fillMode" );
20  if(mode=="kME")
21  fillMode_=kME;
22  else if(mode=="kStable")
24  else
25  throw cms::Exception("Configuration") << mode << " is not a supported FillMode!\n";
26 
27  mode = cfg.getParameter<std::string>( "runMode" );
28  if(mode=="Run1")
30  else if(mode=="Run2")
32  else
33  throw cms::Exception("Configuration") << mode << " is not a supported RunMode!\n";
34 
35  // produces a set of GenParticles following
36  // the decay branch of top quarks to the first level of
37  // stable decay products
38  produces<reco::GenParticleCollection>();
39 }
40 
43 {
44 }
45 
47 void
49 {
50  // create target vector
51  std::auto_ptr<reco::GenParticleCollection> target( new reco::GenParticleCollection );
52 
53  // get source collection
55  event.getByToken(srcToken_, src);
56 
57  // find out what generator we are dealing with
58  if (showerModel_ == kStart && runMode_ == kRun2) {
60  }
61 
62  // find top quarks in list of input particles
63  std::vector<const reco::GenParticle*> tops;
64  if(runMode_ == kRun1)
65  tops = findTops(*src);
66  else
67  tops = findPrimalTops(*src);
68 
69  // determine shower model (only in first event)
72 
73  if(showerModel_!=kNone) {
74  // check sanity of W bosons
75  if (runMode_ == kRun1)
76  checkWBosons(tops);
77  else {
78  // nothing for the moment
79  }
80 
81  // get ref product from the event
82  const reco::GenParticleRefProd ref = event.getRefBeforePut<reco::GenParticleCollection>();
83  // clear existing refs
85  if (runMode_ == kRun1) {
86  // fill output
87  fillListing(tops, *target);
88  // fill references
89  fillReferences(ref, *target);
90  }
91  else {
92  std::vector<const reco::GenParticle*> decaying_tops = findDecayingTops(*src);
93  // fill output
94  fillListing(tops, decaying_tops, *target);
95  // fill references
96  fillReferences(ref, *target);
97  }
98  }
99 
100  // write vectors to the event
101  event.put(target);
102 }
103 
105 std::vector<const reco::GenParticle*>
107 {
108  std::vector<const reco::GenParticle*> tops;
109  for(reco::GenParticleCollection::const_iterator t=parts.begin(); t!=parts.end(); ++t){
110  if( std::abs(t->pdgId())==TopDecayID::tID && t->status()==TopDecayID::unfrag )
111  tops.push_back( &(*t) );
112  }
113  return tops;
114 }
115 
118 std::vector<const reco::GenParticle*> TopDecaySubset::findPrimalTops(
120  std::vector<const reco::GenParticle*> tops;
121  for (reco::GenParticleCollection::const_iterator t = parts.begin();
122  t != parts.end(); ++t) {
123  if (std::abs(t->pdgId()) != TopDecayID::tID)
124  continue;
125 
126  bool hasTopMother = false;
127  for (unsigned idx = 0; idx < t->numberOfMothers(); ++idx) {
128  if (std::abs(t->mother(idx)->pdgId()) == TopDecayID::tID)
129  hasTopMother = true;
130  }
131 
132  if (hasTopMother) // not a primal top
133  continue;
134  tops.push_back(&(*t));
135  }
136 
137  return tops;
138 }
139 
142 std::vector<const reco::GenParticle*> TopDecaySubset::findDecayingTops(
144  std::vector<const reco::GenParticle*> tops;
145  for (reco::GenParticleCollection::const_iterator t = parts.begin();
146  t != parts.end(); ++t) {
147  if (std::abs(t->pdgId()) != TopDecayID::tID)
148  continue;
149 
150  bool hasTopDaughter = false;
151  for (unsigned idx = 0; idx < t->numberOfDaughters(); ++idx) {
152  if (std::abs(t->daughter(idx)->pdgId()) == TopDecayID::tID)
153  hasTopDaughter = true;
154  }
155 
156  if (hasTopDaughter) // not a decaying top
157  continue;
158  tops.push_back(&(*t));
159  }
160 
161  return tops;
162 }
163 
167  const reco::GenParticle* top) {
168  unsigned int w_index = 0;
169  for (unsigned idx = 0; idx < top->numberOfDaughters(); ++idx) {
170  if (std::abs(top->daughter(idx)->pdgId()) == TopDecayID::WID) {
171  w_index = idx;
172  break;
173  }
174  }
175  return (reco::GenParticle*)top->daughter(w_index);
176 }
177 
180 //const reco::GenParticle* TopDecaySubset::findDecayingW(
181 // const reco::GenParticle* top) {
182 // const reco::GenParticle* decaying_W = findLastParticleInChain(findPrimalW(top));
183 // return findLastParticleInChain(findPrimalW(top));
184 //}
185 
191  const reco::GenParticle* p) {
192  int particleID = std::abs(p->pdgId());
193  bool containsItself = false;
194  unsigned int d_idx = 0;
195  for (unsigned idx = 0; idx < p->numberOfDaughters(); ++idx) {
196  if (std::abs(p->daughter(idx)->pdgId()) == particleID) {
197  containsItself = true;
198  d_idx = idx;
199  }
200  }
201 
202  if (!containsItself)
203  return p;
204  else {
205  if (showerModel_ == kPythia){
206  // Pythia6 has a weird idea of W bosons (and maybe other particles)
207  // W (status == 3) -> q qbar' W. The new W is status 2 and has no daughters
208  if(p->status() == 3)
209  return p;
210  }
212  }
213 
214 
215 }
216 
219 TopDecaySubset::checkShowerModel(const std::vector<const reco::GenParticle*>& tops) const
220 {
221  for(std::vector<const reco::GenParticle*>::const_iterator it=tops.begin(); it!=tops.end(); ++it){
222  const reco::GenParticle* top = *it;
223  // check for kHerwig type showers: here the status 3 top quark will
224  // have a single status 2 top quark as daughter, which has again 3
225  // or more status 2 daughters
226  if( top->numberOfDaughters()==1){
227  if( top->begin()->pdgId()==top->pdgId() && top->begin()->status()==TopDecayID::stable && top->begin()->numberOfDaughters()>1)
228  return kHerwig;
229  }
230  // check for kPythia type showers: here the status 3 top quark will
231  // have all decay products and a status 2 top quark as daughters
232  // the status 2 top quark will be w/o further daughters
233  if( top->numberOfDaughters()>1 ){
234  bool containsWBoson=false, containsQuarkDaughter=false;
235  for(reco::GenParticle::const_iterator td=top->begin(); td!=top->end(); ++td){
236  if( std::abs(td->pdgId ()) <TopDecayID::tID ) containsQuarkDaughter=true;
237  if( std::abs(td->pdgId ())==TopDecayID::WID ) containsWBoson=true;
238  }
239  if(containsQuarkDaughter && containsWBoson)
240  return kPythia;
241  }
242  }
243  // if neither Herwig nor Pythia like
244  if(tops.size()==0)
245  edm::LogInfo("decayChain")
246  << " Failed to find top quarks in decay chain. Will assume that this a \n"
247  << " non-top sample and produce an empty decaySubset.\n";
248  else
250  " Can not find back any of the supported hadronization models. Models \n"
251  " which are supported are: \n"
252  " Pythia LO(+PS): Top(status 3) --> WBoson(status 3), Quark(status 3)\n"
253  " Herwig NLO(+PS): Top(status 2) --> Top(status 3) --> Top(status 2) \n");
254  return kNone;
255 }
256 
259  edm::Event& event) {
260  edm::Handle < GenEventInfoProduct > genEvtInfoProduct;
261  event.getByToken(genEventInfo_srcToken_, genEvtInfoProduct);
262 
263  std::string moduleName = "";
264  if (genEvtInfoProduct.isValid()) {
265  const edm::Provenance& prov = event.getProvenance(
266  genEvtInfoProduct.id());
267  moduleName = edm::moduleName(prov);
268  }
269 
270  ShowerModel shower(kStart);
271  if (moduleName.find("Pythia6") != std::string::npos)
272  shower = kPythia;
273  else if (moduleName.find("Pythia8") != std::string::npos)
274  shower = kPythia8;
275  else if (moduleName.find("Herwig6") != std::string::npos)
276  shower = kHerwig;
277  else if (moduleName.find("ThePEG") != std::string::npos)
278  // Herwig++
279  shower = kHerwig;
280  else if (moduleName.find("Sherpa") != std::string::npos)
281  shower = kSherpa;
282  else
283  shower = kNone;
284  return shower;
285 }
287 void
288 TopDecaySubset::checkWBosons(std::vector<const reco::GenParticle*>& tops) const
289 {
290  unsigned nTops = tops.size();
291  for(std::vector<const reco::GenParticle*>::iterator it=tops.begin(); it!=tops.end();) {
292  const reco::GenParticle* top = *it;
293  bool isContained=false;
294  bool expectedStatus=false;
295  if(showerModel_!=kPythia && top->begin()==top->end())
297  "showerModel_!=kPythia && top->begin()==top->end()\n");
298  for(reco::GenParticle::const_iterator td=((showerModel_==kPythia) ? top->begin() : top->begin()->begin());
299  td!=((showerModel_==kPythia) ? top->end() : top->begin()->end());
300  ++td){
301  if(std::abs(td->pdgId())==TopDecayID::WID) {
302  isContained=true;
303  if( ((showerModel_==kPythia) ? td->status()==TopDecayID::unfrag : td->status()==TopDecayID::stable) ) {
304  expectedStatus=true;
305  break;
306  }
307  }
308  }
309  if(!expectedStatus) {
310  it=tops.erase(it);
311  if(isContained)
312  edm::LogInfo("decayChain")
313  << " W boson does not have the expected status. This happens, e.g., \n"
314  << " with MC@NLO in the case of additional ttbar pairs from radiated \n"
315  << " gluons. We hope everything is fine, remove the correspdonding top \n"
316  << " quark from our list since it is not part of the primary ttbar pair \n"
317  << " and try to continue. \n";
318  }
319  else
320  it++;
321  }
322  if(tops.size()==0 && nTops!=0)
324  " Did not find a W boson with appropriate status for any of the top \n"
325  " quarks in this event. This means that the hadronization of the W \n"
326  " boson might be screwed up or there is another problem with the \n"
327  " particle listing in this MC sample. Please contact an expert. \n");
328 }
329 
331 void
332 TopDecaySubset::fillListing(const std::vector<const reco::GenParticle*>& tops, reco::GenParticleCollection& target)
333 {
334  unsigned int statusFlag;
335  // determine status flag of the new
336  // particle depending on the FillMode
337  fillMode_ == kME ? statusFlag=3 : statusFlag=2;
338 
339  for(std::vector<const reco::GenParticle*>::const_iterator it=tops.begin(); it!=tops.end(); ++it){
340  const reco::GenParticle* t = *it;
341  // if particle is top or anti-top
342  std::auto_ptr<reco::GenParticle> topPtr( new reco::GenParticle( t->threeCharge(), p4(it, statusFlag), t->vertex(), t->pdgId(), statusFlag, false ) );
343  target.push_back( *topPtr );
344  ++motherPartIdx_;
345  // keep the top index for the map to manage the daughter refs
346  int iTop=motherPartIdx_;
347  std::vector<int> topDaughters;
348  // define the W boson index (to be set later) for the map to
349  // manage the daughter refs
350  int iW = 0;
351  std::vector<int> wDaughters;
352  // sanity check
353  if(showerModel_!=kPythia && t->begin()==t->end())
355  "showerModel_!=kPythia && t->begin()==t->end()\n");
356  //iterate over top daughters
357  for(reco::GenParticle::const_iterator td=((showerModel_==kPythia)?t->begin():t->begin()->begin()); td!=((showerModel_==kPythia)?t->end():t->begin()->end()); ++td){
358  if( td->status()==TopDecayID::unfrag && std::abs( td->pdgId() )<=TopDecayID::bID ){
359  // if particle is beauty or other quark
360  std::auto_ptr<reco::GenParticle> bPtr( new reco::GenParticle( td->threeCharge(), p4( td, statusFlag ), td->vertex(), td->pdgId(), statusFlag, false ) );
361  target.push_back( *bPtr );
362  // increment & push index of the top daughter
363  topDaughters.push_back( ++motherPartIdx_ );
364  if(addRadiation_){
365  addRadiation(motherPartIdx_,td,target);
366  }
367  }
368  // sanity check
369  if(showerModel_!=kPythia && td->begin()==td->end())
371  "showerModel_!=kPythia && td->begin()==td->end()\n");
373  if( buffer->status()==TopDecayID::unfrag && std::abs( buffer->pdgId() )==TopDecayID::WID ){
374  // if particle is a W boson
375  std::auto_ptr<reco::GenParticle> wPtr( new reco::GenParticle( buffer->threeCharge(), p4( buffer, statusFlag), buffer->vertex(), buffer->pdgId(), statusFlag, true ) );
376  target.push_back( *wPtr );
377  // increment & push index of the top daughter
378  topDaughters.push_back( ++motherPartIdx_ );
379  // keep the W idx for the map
380  iW=motherPartIdx_;
381  if(addRadiation_){
382  addRadiation(motherPartIdx_,buffer,target);
383  }
384  if(showerModel_!=kPythia && buffer->begin()==buffer->end())
386  "showerModel_!=kPythia && buffer->begin()==buffer->end()\n");
387  // iterate over W daughters
388  for(reco::GenParticle::const_iterator wd=((showerModel_==kPythia)?buffer->begin():buffer->begin()->begin()); wd!=((showerModel_==kPythia)?buffer->end():buffer->begin()->end()); ++wd){
389  // make sure the W daughter is of status unfrag and not the W itself
390  if( wd->status()==TopDecayID::unfrag && !(std::abs(wd->pdgId())==TopDecayID::WID) ) {
391  std::auto_ptr<reco::GenParticle> qPtr( new reco::GenParticle( wd->threeCharge(), p4( wd, statusFlag ), wd->vertex(), wd->pdgId(), statusFlag, false) );
392  target.push_back( *qPtr );
393  // increment & push index of the top daughter
394  wDaughters.push_back( ++motherPartIdx_ );
395  if( wd->status()==TopDecayID::unfrag && std::abs( wd->pdgId() )==TopDecayID::tauID ){
396  // add tau daughters if the particle is a tau pass
397  // the daughter of the tau which is of status 2
398  //addDaughters(motherPartIdx_, wd->begin(), target);
399  // add tau daughters if the particle is a tau pass
400  // the tau itself, which may add a tau daughter of
401  // of status 2 to the listing
402  addDaughters(motherPartIdx_,wd,target);
403  }
404  }
405  }
406  }
407  if(addRadiation_ && buffer->status()==TopDecayID::stable && ( buffer->pdgId()==TopDecayID::glueID || std::abs(buffer->pdgId())<TopDecayID::bID)){
408  // collect additional radiation from the top
409  std::auto_ptr<reco::GenParticle> radPtr( new reco::GenParticle( buffer->threeCharge(), buffer->p4(), buffer->vertex(), buffer->pdgId(), statusFlag, false ) );
410  target.push_back( *radPtr );
411  // increment & push index of the top daughter
412  topDaughters.push_back( ++motherPartIdx_ );
413  }
414  }
415  // add potential sisters of the top quark;
416  // only for top to prevent double counting
417  if(t->numberOfMothers()>0 && t->pdgId()==TopDecayID::tID){
418  for(reco::GenParticle::const_iterator ts = t->mother()->begin(); ts!=t->mother()->end(); ++ts){
419  // loop over all daughters of the top mother i.e.
420  // the two top quarks and their potential sisters
421  if(std::abs(ts->pdgId())!=t->pdgId() && ts->pdgId()!=t->mother()->pdgId()){
422  // add all further particles but the two top quarks and potential
423  // cases where the mother of the top has itself as daughter
424  reco::GenParticle* cand = new reco::GenParticle( ts->threeCharge(), ts->p4(), ts->vertex(), ts->pdgId(), ts->status(), false );
425  std::auto_ptr<reco::GenParticle> sPtr( cand );
426  target.push_back( *sPtr );
427  if(ts->begin()!=ts->end()){
428  // in case the sister has daughters increment
429  // and add the first generation of daughters
430  addDaughters(++motherPartIdx_,ts->begin(),target,false);
431  }
432  }
433  }
434  }
435  // fill the map for the administration
436  // of daughter indices
437  refs_[ iTop ] = topDaughters;
438  refs_[ iW ] = wDaughters;
439  }
440 }
441 
443  const std::vector<const reco::GenParticle*>& primalTops,
444  const std::vector<const reco::GenParticle*>& decayingTops,
446  std::vector<const reco::GenParticle*>::const_iterator top_start;
447  std::vector<const reco::GenParticle*>::const_iterator top_end;
448  if (fillMode_ == kME) {
449  top_start = primalTops.begin();
450  top_end = primalTops.end();
451  } else {
452  top_start = decayingTops.begin();
453  top_end = decayingTops.end();
454  }
455  for (std::vector<const reco::GenParticle*>::const_iterator it =
456  top_start; it != top_end; ++it) {
457  const reco::GenParticle* t = *it;
458  // summation might happen here
459  std::auto_ptr < reco::GenParticle
460  > topPtr(
461  new reco::GenParticle(t->threeCharge(), t->p4(),
462  t->vertex(), t->pdgId(), t->status(), false));
463  target.push_back(*topPtr);
464  ++motherPartIdx_;
465 
466  // keep the top index for the map to manage the daughter refs
467  int iTop = motherPartIdx_;
468  std::vector<int> topDaughters;
469  // define the W boson index (to be set later) for the map to
470  // manage the daughter refs
471  int iW = 0;
472  std::vector<int> wDaughters;
473  const reco::GenParticle* final_top = findLastParticleInChain(t);
474 
475  //iterate over top daughters
476  for (reco::GenParticle::const_iterator td = final_top->begin();
477  td != final_top->end(); ++td) {
478  if (std::abs(td->pdgId()) <= TopDecayID::bID) {
479  // if particle is beauty or other quark
480  std::auto_ptr < reco::GenParticle
481  > qPtr(
482  new reco::GenParticle(td->threeCharge(),
483  td->p4(), td->vertex(), td->pdgId(),
484  td->status(), false));
485  target.push_back(*qPtr);
486  // increment & push index of the top daughter
487  topDaughters.push_back(++motherPartIdx_);
488  if (addRadiation_) {
489  // for radation to be added we first need to
490  // pick the last quark in the MC chain
492  (reco::GenParticle*) &*td);
493  addRadiation(motherPartIdx_, last_q, target);
494  }
495  } else if (std::abs(td->pdgId()) == TopDecayID::WID) {
496  // ladies and gentleman, we have a W boson
497  std::auto_ptr < reco::GenParticle
498  > WPtr(
499  new reco::GenParticle(td->threeCharge(),
500  td->p4(), td->vertex(), td->pdgId(),
501  td->status(), false));
502  target.push_back(*WPtr);
503  // increment & push index of the top daughter
504  topDaughters.push_back(++motherPartIdx_);
505  iW = motherPartIdx_;
506 
507  // next are the daughers of our W boson
508  // for Pythia 6 this is wrong as the last W has no daughters at all!
509  // instead the status 3 W has 3 daughters: q qbar' and W (WTF??!)
510  const reco::GenParticle* decaying_W = findLastParticleInChain(
511  (reco::GenParticle*) &*td);
512  for (reco::GenParticle::const_iterator wd = decaying_W->begin();
513  wd != decaying_W->end(); ++wd) {
514  if (!(std::abs(wd->pdgId()) == TopDecayID::WID)) {
515  std::auto_ptr < reco::GenParticle
516  > qPtr(
517  new reco::GenParticle(wd->threeCharge(),
518  wd->p4(), wd->vertex(),
519  wd->pdgId(), wd->status(),
520  false));
521  target.push_back(*qPtr);
522  // increment & push index of the top daughter
523  wDaughters.push_back(++motherPartIdx_);
525  (reco::GenParticle*) &*wd);
526  addRadiation(motherPartIdx_, last_q, target);
527  if (std::abs(wd->pdgId()) == TopDecayID::tauID) {
528  // add tau daughters
529  // currently it adds k-mesons etc as well, which
530  // is not what we want.
531  addDaughters(motherPartIdx_, wd, target);
532  }
533  }
534  }
535 
536  } else {
537  if(addRadiation_ && ( td->pdgId()==TopDecayID::glueID ||
538  std::abs(td->pdgId())<TopDecayID::bID)){
539  // collect additional radiation from the top
540  std::auto_ptr<reco::GenParticle> radPtr(
541  new reco::GenParticle( td->threeCharge(),
542  td->p4(), td->vertex(), td->pdgId(), td->status(), false ) );
543  target.push_back( *radPtr );
544  }
545  //other top daughters like Zq for FCNC
546  // for pythia 6 many gluons end up here
547  //std::cout << "other top daughters: to be implemented"
548  // << std::endl;
549  }
550  }
551 
552  // fill the map for the administration
553  // of daughter indices
554  refs_[iTop] = topDaughters;
555  refs_[iW] = wDaughters;
556  }
557 }
558 
561 TopDecaySubset::p4(const std::vector<const reco::GenParticle*>::const_iterator top, int statusFlag)
562 {
563  // calculate the four vector for top/anti-top quarks from
564  // the W boson and the b quark plain or including all
565  // additional radiation depending on switch 'plain'
566  if(statusFlag==TopDecayID::unfrag){
567  // return 4 momentum as it is
568  return (*top)->p4();
569  }
571  for(reco::GenParticle::const_iterator p=(*top)->begin(); p!=(*top)->end(); ++p){
572  if( p->status() == TopDecayID::unfrag ){
573  // descend by one level for each
574  // status 3 particle on the way
575  vec+=p4( p, statusFlag );
576  }
577  else{
578  if( std::abs((*top)->pdgId())==TopDecayID::WID ){
579  // in case of a W boson skip the status
580  // 2 particle to prevent double counting
581  if( std::abs(p->pdgId())!=TopDecayID::WID )
582  vec+=p->p4();
583  }
584  else{
585  // add all four vectors for each stable
586  // particle (status 1 or 2) on the way
587  vec+=p->p4();
588  if( vec.mass()-(*top)->mass()>0 ){
589  // continue adding up gluons and qqbar pairs on the top
590  // line untill the nominal top mass is reached; then
591  // break in order to prevent picking up virtualities
592  break;
593  }
594  }
595  }
596  }
597  return vec;
598 }
599 
603 {
604  // calculate the four vector for all top daughters from
605  // their daughters including additional radiation
606  if(statusFlag==TopDecayID::unfrag){
607  // return 4 momentum as it is
608  return part->p4();
609  }
611  for(reco::GenParticle::const_iterator p=part->begin(); p!=part->end(); ++p){
612  if( p->status()<=TopDecayID::stable && std::abs(p->pdgId ())==TopDecayID::WID){
613  vec=p->p4();
614  }
615  else{
616  if(p->status()<=TopDecayID::stable){
617  // sum up the p4 of all stable particles
618  // (of status 1 or 2)
619  vec+=p->p4();
620  }
621  else{
622  if( p->status()==TopDecayID::unfrag){
623  // if the particle is unfragmented (i.e.
624  // status 3) descend by one level
625  vec+=p4(p, statusFlag);
626  }
627  }
628  }
629  }
630  return vec;
631 }
632 
634 void
636 {
637  std::vector<int> daughters;
638  int idxBuffer = idx;
639  for(reco::GenParticle::const_iterator daughter=part->begin(); daughter!=part->end(); ++daughter){
640  if(daughter->status()<=TopDecayID::stable && daughter->pdgId()!=part->pdgId()){
641  // skip comment lines and make sure that
642  // the particle is not double counted as
643  // daughter of itself
644  std::auto_ptr<reco::GenParticle> ptr( new reco::GenParticle( daughter->threeCharge(), daughter->p4(), daughter->vertex(), daughter->pdgId(), daughter->status(), false) );
645  target.push_back( *ptr );
646  daughters.push_back( ++idx ); //push index of daughter
647  }
648  }
649  if(daughters.size()) {
650  refs_[ idxBuffer ] = daughters;
651  }
652 }
653 
656  std::vector<int> daughters;
657  int idxBuffer = idx;
658  for (reco::GenParticle::const_iterator daughter = part->begin();
659  daughter != part->end(); ++daughter) {
660  // either pick daughters as long as they are different
661  // to the initial particle
662  if (daughter->pdgId() != part->pdgId()) {
663  std::auto_ptr < reco::GenParticle
664  > ptr(
665  new reco::GenParticle(daughter->threeCharge(),
666  daughter->p4(), daughter->vertex(),
667  daughter->pdgId(), daughter->status(),
668  false));
669  target.push_back(*ptr);
670  daughters.push_back(++idx); //push index of daughter
671  }
672  }
673  if (daughters.size()) {
674  refs_[idxBuffer] = daughters;
675  }
676 }
677 
679 void
681 {
682  std::vector<int> daughters;
683  int idxBuffer = idx;
684  for(reco::GenParticle::const_iterator daughter=part->begin(); daughter!=part->end(); ++daughter){
685  std::auto_ptr<reco::GenParticle> ptr( new reco::GenParticle( daughter->threeCharge(), daughter->p4(), daughter->vertex(), daughter->pdgId(), daughter->status(), false) );
686  target.push_back( *ptr );
687  // increment & push index of daughter
688  daughters.push_back( ++idx );
689  // continue recursively if desired
690  if(recursive){
691  addDaughters(idx,daughter,target);
692  }
693  }
694  if(daughters.size()) {
695  refs_[ idxBuffer ] = daughters;
696  }
697 }
698 
700 void
702 {
703  // clear vector of references
704  refs_.clear();
705  // set idx for mother particles to a start value
706  // of -1 (the first entry will raise it to 0)
707  motherPartIdx_=-1;
708 }
709 
711 void
713 {
714  int idx=0;
715  for(reco::GenParticleCollection::iterator p=sel.begin(); p!=sel.end(); ++p, ++idx){
716  //find daughter reference vectors in refs_ and add daughters
717  std::map<int, std::vector<int> >::const_iterator daughters=refs_.find( idx );
718  if( daughters!=refs_.end() ){
719  for(std::vector<int>::const_iterator daughter = daughters->second.begin();
720  daughter!=daughters->second.end(); ++daughter){
721  reco::GenParticle* part = dynamic_cast<reco::GenParticle* > (&(*p));
722  if(part == 0){
723  throw edm::Exception( edm::errors::InvalidReference, "Not a GenParticle" );
724  }
725  part->addDaughter( reco::GenParticleRef(ref, *daughter) );
726  sel[*daughter].addMother( reco::GenParticleRef(ref, idx) );
727  }
728  }
729  }
730 }
std::vector< GenParticle > GenParticleCollection
collection of GenParticles
T getParameter(std::string const &) const
virtual int pdgId() const
PDG identifier.
static bool isContained(const std::vector< unsigned int > &list, int id)
Definition: JetInput.cc:89
tuple cfg
Definition: looper.py:293
void addDaughters(int &idx, const reco::GenParticle::const_iterator part, reco::GenParticleCollection &target, bool recursive=true)
recursively fill vector for all further decay particles of a given particle
static const int bID
Definition: TopGenEvent.h:14
ShowerModel checkShowerModel(const std::vector< const reco::GenParticle * > &tops) const
check the decay chain for the used shower model
ShowerModel showerModel_
parton shower mode (filled in checkShowerModel)
ProductID id() const
Definition: HandleBase.cc:15
virtual void produce(edm::Event &event, const edm::EventSetup &setup)
write output into the event
virtual const Point & vertex() const
vertex position (overwritten by PF...)
static const int glueID
Definition: TopGenEvent.h:15
virtual int status() const
status word
void addRadiation(int &idx, const reco::GenParticle::const_iterator part, reco::GenParticleCollection &target)
fill vector including all radiations from quarks originating from W/top
static const int unfrag
Definition: TopGenEvent.h:12
virtual int threeCharge() const =0
electric charge
virtual int status() const =0
status word
static const int stable
Definition: TopGenEvent.h:11
std::vector< const reco::GenParticle * > findTops(const reco::GenParticleCollection &parts)
find top quarks in list of input particles
void addDaughter(const typename daughters::value_type &)
add a daughter via a reference
void clearReferences()
clear references
static const int tID
Definition: TopGenEvent.h:13
static const int tauID
Definition: TopGenEvent.h:21
edm::EDGetTokenT< GenEventInfoProduct > genEventInfo_srcToken_
input tag for the genEventInfo source
virtual size_type numberOfDaughters() const =0
number of daughters
std::string moduleName(Provenance const &provenance)
Definition: Provenance.cc:27
virtual size_t numberOfMothers() const
number of mothers
const_iterator end() const
last daughter const_iterator
Definition: Candidate.h:146
virtual size_t numberOfDaughters() const
number of daughters
virtual const Candidate * daughter(size_type) const
return daughter at a given position, i = 0, ... numberOfDaughters() - 1 (read only mode) ...
reco::Particle::LorentzVector p4(const std::vector< const reco::GenParticle * >::const_iterator top, int statusFlag)
calculate lorentz vector from input (dedicated to top reconstruction)
void checkWBosons(std::vector< const reco::GenParticle * > &tops) const
check whether W bosons are contained in the original gen particle listing
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool addRadiation_
add radiation or not?
ShowerModel
classification of potential shower types
virtual const Point & vertex() const =0
vertex position
std::vector< const reco::GenParticle * > findDecayingTops(const reco::GenParticleCollection &parts)
virtual int threeCharge() const
electric charge
Definition: LeafCandidate.h:95
edm::EDGetTokenT< reco::GenParticleCollection > srcToken_
input tag for the genParticle source
How EventSelector::AcceptEvent() decides whether to accept an event for output otherwise it is excluding the probing of A single or multiple positive and the trigger will pass if any such matching triggers are PASS or EXCEPTION[A criterion thatmatches no triggers at all is detected and causes a throw.] A single negative with an expectation of appropriate bit checking in the decision and the trigger will pass if any such matching triggers are FAIL or EXCEPTION A wildcarded negative criterion that matches more than one trigger in the trigger but the state exists so we define the behavior If all triggers are the negative crieriion will lead to accepting the event(this again matches the behavior of"!*"before the partial wildcard feature was incorporated).The per-event"cost"of each negative criterion with multiple relevant triggers is about the same as!*was in the past
bool isValid() const
Definition: HandleBase.h:75
void fillReferences(const reco::GenParticleRefProd &refProd, reco::GenParticleCollection &target)
fill references for output vector
virtual int pdgId() const =0
PDG identifier.
std::vector< const reco::GenParticle * > findPrimalTops(const reco::GenParticleCollection &parts)
tuple idx
DEBUGGING if hasattr(process,&quot;trackMonIterativeTracking2012&quot;): print &quot;trackMonIterativeTracking2012 D...
part
Definition: HCALResponse.h:20
TopDecaySubset(const edm::ParameterSet &cfg)
default constructor
RunMode runMode_
run mode (Run1 || Run2)
static const int WID
Definition: TopGenEvent.h:18
std::map< int, std::vector< int > > refs_
management of daughter indices for fillRefs
void fillListing(const std::vector< const reco::GenParticle * > &tops, reco::GenParticleCollection &target)
fill output vector for full decay chain
FillMode fillMode_
const_iterator begin() const
first daughter const_iterator
Definition: Candidate.h:144
volatile std::atomic< bool > shutdown_flag false
~TopDecaySubset()
default destructor
virtual const LorentzVector & p4() const
four-momentum Lorentz vector
Definition: LeafCandidate.h:99
math::XYZTLorentzVector LorentzVector
Lorentz vector.
Definition: Particle.h:21
virtual const Candidate * mother(size_type=0) const
return mother at a given position, i = 0, ... numberOfMothers() - 1 (read only mode) ...
void setup(std::vector< TH2F > &depth, std::string name, std::string units="")
const reco::GenParticle * findPrimalW(const reco::GenParticle *top)
virtual const LorentzVector & p4() const =0
four-momentum Lorentz vector
const reco::GenParticle * findLastParticleInChain(const reco::GenParticle *p)