evtgen is hosted by Hepforge, IPPP Durham
EvtGen  2.0.0
Monte Carlo generator of particle decays, in particular the weak decays of heavy flavour particles such as B mesons.
EvtDecayBase.cpp
Go to the documentation of this file.
1 
2 /***********************************************************************
3 * Copyright 1998-2020 CERN for the benefit of the EvtGen authors *
4 * *
5 * This file is part of EvtGen. *
6 * *
7 * EvtGen is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * EvtGen is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with EvtGen. If not, see <https://www.gnu.org/licenses/>. *
19 ***********************************************************************/
20 
22 
23 #include "EvtGenBase/EvtPDL.hh"
25 #include "EvtGenBase/EvtPatches.hh"
26 #include "EvtGenBase/EvtReport.hh"
28 #include "EvtGenBase/EvtStatus.hh"
29 
30 #include <ctype.h>
31 #include <fstream>
32 #include <iostream>
33 #include <stdlib.h>
34 #include <vector>
35 using std::endl;
36 using std::fstream;
38 {
39  int i;
40  int q = 0;
41  int qpar;
42 
43  //If there are no daughters (jetset etc) then we do not
44  //want to do this test. Why? Because sometimes the parent
45  //will have a nonzero charge.
46 
47  if ( _ndaug != 0 ) {
48  for ( i = 0; i < _ndaug; i++ ) {
49  q += EvtPDL::chg3( _daug[i] );
50  }
51  qpar = EvtPDL::chg3( _parent );
52 
53  if ( q != qpar ) {
54  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
55  << _modelname.c_str() << " generator expected "
56  << " charge to be conserved, found:" << endl;
57  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
58  << "Parent charge of " << ( qpar / 3 ) << endl;
59  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
60  << "Sum of daughter charge of " << ( q / 3 ) << endl;
61  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
62  << "The parent is " << EvtPDL::name( _parent ).c_str() << endl;
63  for ( i = 0; i < _ndaug; i++ ) {
64  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
65  << "Daughter " << EvtPDL::name( _daug[i] ).c_str() << endl;
66  }
67  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
68  << "Will terminate execution!" << endl;
69 
70  ::abort();
71  }
72  }
73 }
74 
75 double EvtDecayBase::getProbMax( double prob )
76 {
77  int i;
78 
79  //diagnostics
80  sum_prob += prob;
81  if ( prob > max_prob )
82  max_prob = prob;
83 
84  if ( defaultprobmax && ntimes_prob <= 500 ) {
85  //We are building up probmax with this iteration
86  ntimes_prob += 1;
87  if ( prob > probmax ) {
88  probmax = prob;
89  }
90  if ( ntimes_prob == 500 ) {
91  probmax *= 1.2;
92  }
93  return 1000000.0 * prob;
94  }
95 
96  if ( prob > probmax * 1.0001 ) {
97  EvtGenReport( EVTGEN_INFO, "EvtGen" )
98  << "prob > probmax:(" << prob << ">" << probmax << ")";
99  EvtGenReport( EVTGEN_INFO, "" ) << "(" << _modelname.c_str() << ") ";
101  << EvtPDL::name( _parent ).c_str() << " -> ";
102  for ( i = 0; i < _ndaug; i++ ) {
104  << EvtPDL::name( _daug[i] ).c_str() << " ";
105  }
106  EvtGenReport( EVTGEN_INFO, "" ) << endl;
107 
108  if ( defaultprobmax )
109  probmax = prob;
110  }
111 
112  ntimes_prob += 1;
113 
114  return probmax;
115 
116 } //getProbMax
117 
118 double EvtDecayBase::resetProbMax( double prob )
119 {
120  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "Reseting prob max\n";
121  EvtGenReport( EVTGEN_INFO, "EvtGen" )
122  << "prob > probmax:(" << prob << ">" << probmax << ")";
123  EvtGenReport( EVTGEN_INFO, "" ) << "(" << _modelname.c_str() << ")";
124  EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::getStdHep( _parent ) << "->";
125 
126  for ( int i = 0; i < _ndaug; i++ ) {
127  EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::getStdHep( _daug[i] ) << " ";
128  }
129  EvtGenReport( EVTGEN_INFO, "" ) << endl;
130 
131  probmax = 0.0;
132  defaultprobmax = 0;
133  ntimes_prob = 0;
134 
135  return prob;
136 }
137 
139 {
140  return std::string( "" );
141 }
142 
143 void EvtDecayBase::command( std::string )
144 {
145  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
146  << "Should never call EvtDecayBase::command" << endl;
147  ::abort();
148 }
149 
150 std::string EvtDecayBase::getParamName( int i )
151 {
152  switch ( i ) {
153  case 0:
154  return "param00";
155  case 1:
156  return "param01";
157  case 2:
158  return "param02";
159  case 3:
160  return "param03";
161  case 4:
162  return "param04";
163  case 5:
164  return "param05";
165  case 6:
166  return "param06";
167  case 7:
168  return "param07";
169  case 8:
170  return "param08";
171  case 9:
172  return "param09";
173  default:
174  return "";
175  }
176 }
177 
178 std::string EvtDecayBase::getParamDefault( int /*i*/ )
179 {
180  return "";
181 }
182 
184 {
185  //This default version of init does nothing;
186  //A specialized version of this function can be
187  //supplied for each decay model to do initialization.
188 
189  return;
190 }
191 
193 {
194  //This function is called if the decay does not have a
195  //specialized initialization.
196  //The default is to set the maximum
197  //probability to 0 and the number of times called to 0
198  //and defaultprobmax to 1 such that the decay will be
199  //generated many many times
200  //in order to generate a reasonable maximum probability
201  //for the decay.
202 
203  defaultprobmax = 1;
204  ntimes_prob = 0;
205  probmax = 0.0;
206 
207 } //initProbMax
208 
209 void EvtDecayBase::saveDecayInfo( EvtId ipar, int ndaug, EvtId* daug, int narg,
210  std::vector<std::string>& args,
211  std::string name, double brfr )
212 {
213  int i;
214 
215  _brfr = brfr;
216  _ndaug = ndaug;
217  _narg = narg;
218  _parent = ipar;
219 
220  _dsum = 0;
221 
222  if ( _ndaug > 0 ) {
223  _daug.resize( _ndaug );
224  for ( i = 0; i < _ndaug; i++ ) {
225  _daug[i] = daug[i];
226  _dsum += daug[i].getAlias();
227  }
228  } else {
229  _daug.clear();
230  }
231 
232  if ( _narg > 0 ) {
233  _args.resize( _narg + 1 );
234  for ( i = 0; i < _narg; i++ ) {
235  _args[i] = args[i];
236  }
237  } else {
238  _args.clear();
239  }
240 
241  _modelname = name;
242 
243  this->init();
244  this->initProbMax();
245 
246  if ( _chkCharge ) {
247  this->checkQ();
248  }
249 
250  if ( defaultprobmax ) {
251  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << "No default probmax for ";
252  EvtGenReport( EVTGEN_INFO, "" ) << "(" << _modelname.c_str() << ") ";
254  << EvtPDL::name( _parent ).c_str() << " -> ";
255  for ( i = 0; i < _ndaug; i++ ) {
257  << EvtPDL::name( _daug[i] ).c_str() << " ";
258  }
259  EvtGenReport( EVTGEN_INFO, "" ) << endl;
261  << "This is fine for development, but must be provided for production."
262  << endl;
263  EvtGenReport( EVTGEN_INFO, "EvtGen" )
264  << "Never fear though - the decay will use the \n";
265  EvtGenReport( EVTGEN_INFO, "EvtGen" )
266  << "500 iterations to build up a good probmax \n";
267  EvtGenReport( EVTGEN_INFO, "EvtGen" )
268  << "before accepting a decay. " << endl;
269  }
270 }
271 
273 {
274  //the default is that the user module does _not_ set
275  // any probmax.
276  defaultprobmax = 1;
277  ntimes_prob = 0;
278  probmax = 0.0;
279 
280  _photos = 0;
281  _verbose = 0;
282  _summary = 0;
283  _parent = EvtId( -1, -1 );
284  _ndaug = 0;
285  _narg = 0;
286  _modelname = "**********";
287 
288  //Default is to check that charge is conserved
289  _chkCharge = 1;
290 
291  //statistics collection!
292 
293  max_prob = 0.0;
294  sum_prob = 0.0;
295 }
296 
298 {
299  if ( ntimes_prob > 0 ) {
300  EvtGenReport( EVTGEN_INFO, "EvtGen" )
301  << "Calls = " << ntimes_prob
302  << " eff: " << sum_prob / ( probmax * ntimes_prob )
303  << " frac. max:" << max_prob / probmax;
305  << " probmax:" << probmax << " max:" << max_prob << " : ";
306  }
307 
308  printInfo();
309 }
310 
312 {
313  EvtGenReport( EVTGEN_INFO, "" ) << EvtPDL::name( _parent ).c_str() << " -> ";
314  for ( int i = 0; i < _ndaug; i++ ) {
316  << EvtPDL::name( _daug[i] ).c_str() << " ";
317  }
318  EvtGenReport( EVTGEN_INFO, "" ) << " (" << _modelname.c_str() << ")" << endl;
319 }
320 
321 void EvtDecayBase::setProbMax( double prbmx )
322 {
323  defaultprobmax = 0;
324  probmax = prbmx;
325 }
326 
328 {
329  defaultprobmax = 0;
330 }
331 
333 {
334  double maxOkMass = EvtPDL::getMaxMass( p->getId() );
335 
336  //protect against vphotons
337  if ( maxOkMass < 0.0000000001 )
338  return 10000000.;
339  //and against already determined masses
340  if ( p->hasValidP4() )
341  maxOkMass = p->mass();
342 
343  EvtParticle* par = p->getParent();
344  if ( par ) {
345  double maxParMass = findMaxMass( par );
346  size_t i;
347  double minDaugMass = 0.;
348  for ( i = 0; i < par->getNDaug(); i++ ) {
349  EvtParticle* dau = par->getDaug( i );
350  if ( dau != p ) {
351  // it might already have a mass
352  if ( dau->isInitialized() || dau->hasValidP4() )
353  minDaugMass += dau->mass();
354  else
355  //give it a bit of phase space
356  minDaugMass += 1.000001 * EvtPDL::getMinMass( dau->getId() );
357  }
358  }
359  if ( maxOkMass > ( maxParMass - minDaugMass ) )
360  maxOkMass = maxParMass - minDaugMass;
361  }
362  return maxOkMass;
363 }
364 
365 // given list of daughters ( by number ) returns a
366 // list of viable masses.
367 
369 {
370  //Need to also check that this mass does not screw
371  //up the parent
372  //This code assumes that for the ith daughter, 0..i-1
373  //already have a mass
374  double maxOkMass = findMaxMass( p );
375 
376  int count = 0;
377  double mass;
378  bool massOk = false;
379  size_t i;
380  while ( !massOk ) {
381  count++;
382  if ( count > 10000 ) {
383  EvtGenReport( EVTGEN_INFO, "EvtGen" )
384  << "Can not find a valid mass for: "
385  << EvtPDL::name( p->getId() ).c_str() << endl;
386  EvtGenReport( EVTGEN_INFO, "EvtGen" )
387  << "Now printing parent and/or grandparent tree\n";
388  if ( p->getParent() ) {
389  if ( p->getParent()->getParent() ) {
390  p->getParent()->getParent()->printTree();
391  EvtGenReport( EVTGEN_INFO, "EvtGen" )
392  << p->getParent()->getParent()->mass() << endl;
393  EvtGenReport( EVTGEN_INFO, "EvtGen" )
394  << p->getParent()->mass() << endl;
395  } else {
396  p->getParent()->printTree();
397  EvtGenReport( EVTGEN_INFO, "EvtGen" )
398  << p->getParent()->mass() << endl;
399  }
400  } else
401  p->printTree();
402  EvtGenReport( EVTGEN_INFO, "EvtGen" )
403  << "maxokmass=" << maxOkMass << " "
404  << EvtPDL::getMinMass( p->getId() ) << " "
405  << EvtPDL::getMaxMass( p->getId() ) << endl;
406  if ( p->getNDaug() ) {
407  for ( i = 0; i < p->getNDaug(); i++ ) {
408  EvtGenReport( EVTGEN_INFO, "EvtGen" )
409  << p->getDaug( i )->mass() << " ";
410  }
411  EvtGenReport( EVTGEN_INFO, "EvtGen" ) << endl;
412  }
413  if ( maxOkMass >= EvtPDL::getMinMass( p->getId() ) ) {
414  EvtGenReport( EVTGEN_INFO, "EvtGen" )
415  << "taking a default value\n";
416  p->setMass( maxOkMass );
417  return;
418  }
419  assert( 0 );
420  }
421  mass = EvtPDL::getMass( p->getId() );
422  //Just need to check that this mass is > than
423  //the mass of all daughters
424  double massSum = 0.;
425  if ( p->getNDaug() ) {
426  for ( i = 0; i < p->getNDaug(); i++ ) {
427  massSum += p->getDaug( i )->mass();
428  }
429  }
430  //some special cases are handled with 0 (stable) or 1 (k0->ks/kl) daughters
431  if ( p->getNDaug() < 2 )
432  massOk = true;
433  if ( p->getParent() ) {
434  if ( p->getParent()->getNDaug() == 1 )
435  massOk = true;
436  }
437  if ( !massOk ) {
438  if ( massSum < mass )
439  massOk = true;
440  if ( mass > maxOkMass )
441  massOk = false;
442  }
443  }
444 
445  p->setMass( mass );
446 }
447 
448 void EvtDecayBase::findMasses( EvtParticle* p, int ndaugs, EvtId daugs[10],
449  double masses[10] )
450 {
451  int i;
452  double mass_sum;
453 
454  int count = 0;
455 
456  if ( !( p->firstornot() ) ) {
457  for ( i = 0; i < ndaugs; i++ ) {
458  masses[i] = p->getDaug( i )->mass();
459  } //for
460  } //if
461  else {
462  p->setFirstOrNot();
463  // if only one daughter do it
464 
465  if ( ndaugs == 1 ) {
466  masses[0] = p->mass();
467  return;
468  }
469 
470  //until we get a combo whose masses are less than _parent mass.
471  do {
472  mass_sum = 0.0;
473 
474  for ( i = 0; i < ndaugs; i++ ) {
475  masses[i] = EvtPDL::getMass( daugs[i] );
476  mass_sum = mass_sum + masses[i];
477  }
478 
479  count++;
480 
481  if ( count == 10000 ) {
482  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
483  << "Decaying particle:" << EvtPDL::name( p->getId() ).c_str()
484  << " (m=" << p->mass() << ")" << endl;
485  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
486  << "To the following daugthers" << endl;
487  for ( i = 0; i < ndaugs; i++ ) {
488  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
489  << EvtPDL::name( daugs[i] ).c_str() << endl;
490  }
491  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
492  << "Has been rejected " << count
493  << " times, will now take minimal masses "
494  << " of daugthers" << endl;
495 
496  mass_sum = 0.;
497  for ( i = 0; i < ndaugs; i++ ) {
498  masses[i] = EvtPDL::getMinMass( daugs[i] );
499  mass_sum = mass_sum + masses[i];
500  }
501  if ( mass_sum > p->mass() ) {
502  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
503  << "Parent mass=" << p->mass()
504  << "to light for daugthers." << endl
505  << "Will throw the event away." << endl;
506  //dont terminate - start over on the event.
508  mass_sum = 0.;
509  // ::abort();
510  }
511  }
512  } while ( mass_sum > p->mass() );
513  } //else
514 
515  return;
516 }
517 
518 void EvtDecayBase::checkNArg( int a1, int a2, int a3, int a4 )
519 {
520  if ( _narg != a1 && _narg != a2 && _narg != a3 && _narg != a4 ) {
521  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
522  << _modelname.c_str() << " generator expected " << endl;
523  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << a1 << endl;
524  ;
525  if ( a2 > -1 ) {
526  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " or " << a2 << endl;
527  }
528  if ( a3 > -1 ) {
529  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " or " << a3 << endl;
530  }
531  if ( a4 > -1 ) {
532  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " or " << a4 << endl;
533  }
534  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
535  << " arguments but found:" << _narg << endl;
536  printSummary();
537  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
538  << "Will terminate execution!" << endl;
539  ::abort();
540  }
541 }
542 void EvtDecayBase::checkNDaug( int d1, int d2 )
543 {
544  if ( _ndaug != d1 && _ndaug != d2 ) {
545  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
546  << _modelname.c_str() << " generator expected ";
547  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << d1;
548  if ( d2 > -1 ) {
549  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << " or " << d2;
550  }
551  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
552  << " daughters but found:" << _ndaug << endl;
553  printSummary();
554  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
555  << "Will terminate execution!" << endl;
556  ::abort();
557  }
558 }
559 
561 {
563  if ( parenttype != sp ) {
564  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
565  << _modelname.c_str() << " did not get the correct parent spin\n";
566  printSummary();
567  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
568  << "Will terminate execution!" << endl;
569  ::abort();
570  }
571 }
572 
574 {
575  EvtSpinType::spintype parenttype = EvtPDL::getSpinType( getDaug( d1 ) );
576  if ( parenttype != sp ) {
577  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
578  << _modelname.c_str()
579  << " did not get the correct daughter spin d=" << d1 << endl;
580  printSummary();
581  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
582  << "Will terminate execution!" << endl;
583  ::abort();
584  }
585 }
586 
588 {
589  if ( !_argsD.empty() )
590  return _argsD.data();
591  //The user has asked for a list of doubles - the arguments
592  //better all be doubles...
593  if ( _narg == 0 )
594  return _argsD.data();
595 
596  _argsD.resize( _narg );
597  for ( int i = 0; i < _narg; i++ ) {
598  char* tc;
599  _argsD[i] = strtod( _args[i].c_str(), &tc );
600  }
601  return _argsD.data();
602 }
603 
604 double EvtDecayBase::getArg( unsigned int j )
605 {
606  // Verify string
607 
608  if ( getParentId().getId() == 25 ) {
609  int i = 0;
610  ++i;
611  }
612 
613  const char* str = _args[j].c_str();
614  int i = 0;
615  while ( str[i] != 0 ) {
616  if ( isalpha( str[i] ) && str[i] != 'e' ) {
617  EvtGenReport( EVTGEN_INFO, "EvtGen" )
618  << "String " << str << " is not a number" << endl;
619  assert( 0 );
620  }
621  i++;
622  }
623 
624  char** tc = 0;
625  double result = strtod( _args[j].c_str(), tc );
626 
627  if ( _storedArgs.size() < j + 1 ) { // then store the argument's value
628  _storedArgs.push_back( result );
629  }
630 
631  return result;
632 }
633 
635 {
636  if ( _ndaug != other._ndaug )
637  return false;
638  if ( _parent != other._parent )
639  return false;
640 
641  std::vector<int> useDs;
642  for ( int i = 0; i < _ndaug; i++ )
643  useDs.push_back( 0 );
644 
645  for ( int i = 0; i < _ndaug; i++ ) {
646  bool foundIt = false;
647  for ( int j = 0; j < _ndaug; j++ ) {
648  if ( useDs[j] == 1 )
649  continue;
650  if ( _daug[i] == other._daug[j] &&
651  _daug[i].getAlias() == other._daug[j].getAlias() ) {
652  foundIt = true;
653  useDs[j] = 1;
654  break;
655  }
656  }
657  if ( foundIt == false )
658  return false;
659  }
660  for ( int i = 0; i < _ndaug; i++ )
661  if ( useDs[i] == 0 )
662  return false;
663 
664  return true;
665 }
void setMass(double m)
Definition: EvtParticle.hh:392
static void findMass(EvtParticle *p)
const char * c_str(Index i)
Definition: EvtCyclic3.cpp:323
bool isInitialized()
Definition: EvtParticle.hh:402
double * getArgs()
static std::string name(EvtId i)
Definition: EvtPDL.cpp:382
double getProbMax(double prob)
void printInfo() const
EvtParticle * getParent() const
Definition: EvtParticle.cpp:96
virtual std::string commandName()
std::vector< std::string > _args
double getArg(unsigned int j)
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.cpp:377
virtual std::string getParamDefault(int i)
virtual std::string getParamName(int i)
virtual void initProbMax()
const double a3
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
virtual void init()
const double a2
std::vector< double > _storedArgs
EvtId getId() const
std::vector< double > _argsD
double resetProbMax(double prob)
const double a1
static int chg3(EvtId i)
Definition: EvtPDL.cpp:372
void setProbMax(double prbmx)
bool hasValidP4()
Definition: EvtParticle.hh:403
void printSummary() const
Definition: EvtId.hh:27
size_t getNDaug() const
EvtId getParentId() const
Definition: EvtDecayBase.hh:61
void printTree() const
void saveDecayInfo(EvtId ipar, int ndaug, EvtId *daug, int narg, std::vector< std::string > &args, std::string name, double brfr)
const double a4
void checkNDaug(int d1, int d2=-1)
static double findMaxMass(EvtParticle *p)
static double getMinMass(EvtId i)
Definition: EvtPDL.cpp:342
void checkSpinParent(EvtSpinType::spintype sp)
void checkNArg(int a1, int a2=-1, int a3=-1, int a4=-1)
std::string _modelname
static void setRejectFlag()
Definition: EvtStatus.hh:26
void checkSpinDaughter(int d1, EvtSpinType::spintype sp)
double mass() const
int firstornot() const
EvtParticle * getDaug(int i)
Definition: EvtParticle.cpp:91
virtual void command(std::string cmd)
int getAlias() const
Definition: EvtId.hh:44
static double getMass(EvtId i)
Definition: EvtPDL.cpp:319
std::vector< EvtId > _daug
static void findMasses(EvtParticle *p, int ndaugs, EvtId daugs[10], double masses[10])
virtual bool matchingDecay(const EvtDecayBase &other) const
static int getStdHep(EvtId id)
Definition: EvtPDL.cpp:362
Index other(Index i, Index j)
Definition: EvtCyclic3.cpp:156
static double getMaxMass(EvtId i)
Definition: EvtPDL.cpp:337
void setFirstOrNot()
Definition: EvtParticle.cpp:77
EvtId getDaug(int i) const
Definition: EvtDecayBase.hh:67