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.
EvtMTree.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 
21 #include "EvtGenBase/EvtMTree.hh"
22 
23 #include "EvtGenBase/EvtConst.hh"
24 #include "EvtGenBase/EvtKine.hh"
26 #include "EvtGenBase/EvtMHelAmp.hh"
29 #include "EvtGenBase/EvtReport.hh"
30 
31 #include <algorithm>
32 #include <stdio.h>
33 #include <stdlib.h>
34 
35 using std::endl;
36 
37 EvtMTree::EvtMTree( const EvtId* idtbl, unsigned int ndaug )
38 {
39  for ( size_t i = 0; i < ndaug; ++i ) {
40  _lbltbl.push_back( EvtPDL::name( idtbl[i] ) );
41  }
42 }
43 
45 {
46  for ( size_t i = 0; i < _root.size(); ++i )
47  delete _root[i];
48 }
49 
50 bool EvtMTree::parsecheck( char arg, const string& chars )
51 {
52  bool ret = false;
53 
54  for ( size_t i = 0; i < chars.size(); ++i ) {
55  ret = ret || ( chars[i] == arg );
56  }
57 
58  return ret;
59 }
60 
61 vector<EvtMNode*> EvtMTree::makeparticles( const string& strid )
62 {
63  vector<EvtMNode*> particles;
64  vector<int> labels;
65 
66  for ( size_t i = 0; i < _lbltbl.size(); ++i ) {
67  if ( _lbltbl[i] == strid )
68  labels.push_back( i );
69  }
70 
71  if ( labels.size() == 0 ) {
72  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
73  << "Error unknown particle label " << strid << endl;
74  ::abort();
75  }
76 
77  for ( size_t i = 0; i < labels.size(); ++i )
78  particles.push_back(
79  new EvtMParticle( labels[i], EvtPDL::getId( strid ) ) );
80 
81  return particles;
82 }
83 
84 EvtMRes* EvtMTree::makeresonance( const EvtId& id, const string& ls,
85  const vector<string>& lsarg, const string& type,
86  const vector<EvtComplex>& amps,
87  const vector<EvtMNode*>& children )
88 {
89  EvtMRes* resonance = NULL;
90  EvtMLineShape* lineshape = NULL;
91 
92  if ( ls == "BREITWIGNER" ) {
93  lineshape = new EvtMBreitWigner( id, lsarg );
94  } else if ( ls == "TRIVIAL" ) {
95  lineshape = new EvtMTrivialLS( id, lsarg );
96  } else {
97  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
98  << "Lineshape " << lineshape << " not recognized." << endl;
99  ::abort();
100  }
101 
102  if ( type == "HELAMP" ) {
103  resonance = new EvtMHelAmp( id, lineshape, children, amps );
104  } else {
105  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
106  << "Model " << type << " not recognized." << endl;
107  ::abort();
108  }
109 
110  lineshape->setres( resonance );
111 
112  return resonance;
113 }
114 
115 void EvtMTree::parseerror( bool flag, ptype& c_iter, ptype& c_begin, ptype& c_end )
116 {
117  if ( !flag )
118  return;
119 
120  string error;
121 
122  while ( c_begin != c_end ) {
123  if ( c_begin == c_iter ) {
124  error += '_';
125  error += *c_begin;
126  error += '_';
127  } else
128  error += *c_begin;
129 
130  ++c_begin;
131  }
132 
133  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << "Parse error at: " << error << endl;
134  ::abort();
135 }
136 
137 string EvtMTree::parseId( ptype& c_iter, ptype& c_begin, ptype& c_end )
138 {
139  string strid;
140 
141  while ( c_iter != c_end ) {
142  parseerror( parsecheck( *c_iter, ")[]," ), c_iter, c_begin, c_end );
143  if ( *c_iter == '(' ) {
144  ++c_iter;
145  return strid;
146  }
147 
148  strid += *c_iter;
149  ++c_iter;
150  }
151 
152  return strid;
153 }
154 
155 string EvtMTree::parseKey( ptype& c_iter, ptype& c_begin, ptype& c_end )
156 {
157  string key;
158 
159  while ( *c_iter != ',' ) {
160  parseerror( c_iter == c_end || parsecheck( *c_iter, "()[]" ), c_iter,
161  c_begin, c_end );
162  key += *c_iter;
163  ++c_iter;
164  }
165 
166  ++c_iter;
167 
168  parseerror( c_iter == c_end, c_iter, c_begin, c_end );
169 
170  return key;
171 }
172 
173 vector<string> EvtMTree::parseArg( ptype& c_iter, ptype& c_begin, ptype& c_end )
174 {
175  vector<string> arg;
176 
177  if ( *c_iter != '[' )
178  return arg;
179  ++c_iter;
180 
181  string temp;
182  while ( true ) {
183  parseerror( c_iter == c_end || parsecheck( *c_iter, "[()" ), c_iter,
184  c_begin, c_end );
185 
186  if ( *c_iter == ']' ) {
187  ++c_iter;
188  if ( temp.size() > 0 )
189  arg.push_back( temp );
190  break;
191  }
192 
193  if ( *c_iter == ',' ) {
194  arg.push_back( temp );
195  temp.clear();
196  ++c_iter;
197  continue;
198  }
199 
200  temp += *c_iter;
201  ++c_iter;
202  }
203  parseerror( c_iter == c_end || *c_iter != ',', c_iter, c_begin, c_end );
204  ++c_iter;
205 
206  return arg;
207 }
208 
209 vector<EvtComplex> EvtMTree::parseAmps( ptype& c_iter, ptype& c_begin,
210  ptype& c_end )
211 {
212  vector<string> parg = parseArg( c_iter, c_begin, c_end );
213  parseerror( parg.size() == 0, c_iter, c_begin, c_end );
214 
215  // Get parametrization amplitudes
216  vector<string>::iterator amp_iter = parg.begin();
217  vector<string>::iterator amp_end = parg.end();
218  vector<EvtComplex> amps;
219 
220  while ( amp_iter != amp_end ) {
221  const char* nptr;
222  char* endptr = NULL;
223  double amp = 0.0, phase = 0.0;
224 
225  nptr = ( *amp_iter ).c_str();
226  amp = strtod( nptr, &endptr );
227  parseerror( nptr == endptr, c_iter, c_begin, c_end );
228 
229  ++amp_iter;
230  parseerror( amp_iter == amp_end, c_iter, c_begin, c_end );
231 
232  nptr = ( *amp_iter ).c_str();
233  phase = strtod( nptr, &endptr );
234  parseerror( nptr == endptr, c_iter, c_begin, c_end );
235 
236  amps.push_back( amp * exp( EvtComplex( 0.0, phase ) ) );
237 
238  ++amp_iter;
239  }
240 
241  return amps;
242 }
243 
244 vector<EvtMNode*> EvtMTree::duplicate( const vector<EvtMNode*>& list ) const
245 {
246  vector<EvtMNode*> newlist;
247 
248  for ( size_t i = 0; i < list.size(); ++i )
249  newlist.push_back( list[i]->duplicate() );
250 
251  return newlist;
252 }
253 
254 // XXX Warning it is unsafe to use cl1 after a call to this function XXX
255 vector<vector<EvtMNode*>> EvtMTree::unionChildren( const string& nodestr,
256  vector<vector<EvtMNode*>>& cl1 )
257 {
258  vector<EvtMNode*> cl2 = parsenode( nodestr, false );
259  vector<vector<EvtMNode*>> cl;
260 
261  if ( cl1.size() == 0 ) {
262  for ( size_t i = 0; i < cl2.size(); ++i ) {
263  vector<EvtMNode*> temp( 1, cl2[i] );
264  cl.push_back( temp );
265  }
266 
267  return cl;
268  }
269 
270  for ( size_t i = 0; i < cl1.size(); ++i ) {
271  for ( size_t j = 0; j < cl2.size(); ++j ) {
272  vector<EvtMNode*> temp;
273  temp = duplicate( cl1[i] );
274  temp.push_back( cl2[j]->duplicate() );
275 
276  cl.push_back( temp );
277  }
278  }
279 
280  for ( size_t i = 0; i < cl1.size(); ++i )
281  for ( size_t j = 0; j < cl1[i].size(); ++j )
282  delete cl1[i][j];
283  for ( size_t i = 0; i < cl2.size(); ++i )
284  delete ( cl2[i] );
285 
286  return cl;
287 }
288 
289 vector<vector<EvtMNode*>> EvtMTree::parseChildren( ptype& c_iter,
290  ptype& c_begin, ptype& c_end )
291 {
292  bool test = true;
293  int pcount = 0;
294  string nodestr;
295  vector<vector<EvtMNode*>> children;
296 
297  parseerror( c_iter == c_end || *c_iter != '[', c_iter, c_begin, c_end );
298  ++c_iter;
299 
300  while ( test ) {
301  parseerror( c_iter == c_end || pcount < 0, c_iter, c_begin, c_end );
302 
303  switch ( *c_iter ) {
304  case ')':
305  --pcount;
306  nodestr += *c_iter;
307  break;
308  case '(':
309  ++pcount;
310  nodestr += *c_iter;
311  break;
312  case ']':
313  if ( pcount == 0 ) {
314  children = unionChildren( nodestr, children );
315  test = false;
316  } else {
317  nodestr += *c_iter;
318  }
319  break;
320  case ',':
321  if ( pcount == 0 ) {
322  children = unionChildren( nodestr, children );
323  nodestr.clear();
324  } else {
325  nodestr += *c_iter;
326  }
327  break;
328  default:
329  nodestr += *c_iter;
330  break;
331  }
332 
333  ++c_iter;
334  }
335 
336  return children;
337 }
338 
339 vector<EvtMNode*> EvtMTree::parsenode( const string& args, bool rootnode )
340 {
341  ptype c_iter, c_begin, c_end;
342 
343  c_iter = c_begin = args.begin();
344  c_end = args.end();
345 
346  string strid = parseId( c_iter, c_begin, c_end );
347 
348  // Case 1: Particle
349  if ( c_iter == c_end )
350  return makeparticles( strid );
351 
352  // Case 2: Resonance - parse further
353  EvtId id = EvtPDL::getId( strid );
354  parseerror( EvtId( -1, -1 ) == id, c_iter, c_begin, c_end );
355 
356  string ls;
357  vector<string> lsarg;
358 
359  if ( rootnode ) {
360  ls = "TRIVIAL";
361  } else {
362  // Get lineshape (e.g. BREITWIGNER)
363  ls = parseKey( c_iter, c_begin, c_end );
364  lsarg = parseArg( c_iter, c_begin, c_end );
365  }
366 
367  // Get resonance parametrization type (e.g. HELAMP)
368  string type = parseKey( c_iter, c_begin, c_end );
369  vector<EvtComplex> amps = parseAmps( c_iter, c_begin, c_end );
370 
371  // Children
372  vector<vector<EvtMNode*>> children = parseChildren( c_iter, c_begin, c_end );
373 
374  EvtGenReport( EVTGEN_ERROR, "EvtGen" ) << children.size() << endl;
375  vector<EvtMNode*> resonances;
376  for ( size_t i = 0; i < children.size(); ++i ) {
377  resonances.push_back(
378  makeresonance( id, ls, lsarg, type, amps, children[i] ) );
379  }
380 
381  parseerror( c_iter == c_end || *c_iter != ')', c_iter, c_begin, c_end );
382 
383  return resonances;
384 }
385 
386 bool EvtMTree::validTree( const EvtMNode* root ) const
387 {
388  vector<int> res = root->getresonance();
389  vector<bool> check( res.size(), false );
390 
391  for ( size_t i = 0; i < res.size(); ++i ) {
392  check[res[i]] = true;
393  }
394 
395  bool ret = true;
396 
397  for ( size_t i = 0; i < check.size(); ++i ) {
398  ret = ret && check[i];
399  }
400 
401  return ret;
402 }
403 
404 void EvtMTree::addtree( const string& str )
405 {
406  vector<EvtMNode*> roots = parsenode( str, true );
407  _norm = 0;
408 
409  for ( size_t i = 0; i < roots.size(); ++i ) {
410  if ( validTree( roots[i] ) ) {
411  _root.push_back( roots[i] );
412  _norm = _norm + 1;
413  } else
414  delete roots[i];
415  }
416 
417  _norm = 1.0 / sqrt( _norm );
418 }
420 {
421  // Set up the rotation matrix for the root particle (for now)
423  EvtSpinType::spintype type = EvtPDL::getSpinType( _root[0]->getid() );
424  int twospin = EvtSpinType::getSpin2( type );
425 
426  vector<EvtSpinType::spintype> types( 2, type );
427  EvtSpinAmp rot( types, EvtComplex( 0.0, 0.0 ) );
428  vector<int> index = rot.iterallowedinit();
429  do {
430  rot( index ) = sd.get( ( index[0] + twospin ) / 2,
431  ( index[1] + twospin ) / 2 );
432  } while ( rot.iterateallowed( index ) );
433 
434  return rot;
435 }
436 
438 {
439  vector<EvtVector4R> product;
440  for ( size_t i = 0; i < p->getNDaug(); ++i )
441  product.push_back( p->getDaug( i )->getP4Lab() );
442 
443  if ( _root.size() == 0 ) {
444  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
445  << "No decay tree present." << endl;
446  ::abort();
447  }
448 
449  EvtSpinAmp amp = _root[0]->amplitude( product );
450  for ( size_t i = 1; i < _root.size(); ++i ) {
451  // Assume that helicity amplitude is returned
452  amp += _root[i]->amplitude( product );
453  }
454  amp = _norm * amp;
455 
456  //ryd
457  return amp;
458 
459  // Do Rotation to Proper Frame
460  EvtSpinAmp newamp = getrotation( p );
461  newamp.extcont( amp, 1, 0 );
462 
463  return newamp;
464 }
vector< EvtMNode * > duplicate(const vector< EvtMNode * > &) const
Definition: EvtMTree.cpp:244
~EvtMTree()
Definition: EvtMTree.cpp:44
static std::string name(EvtId i)
Definition: EvtPDL.cpp:382
string parseId(ptype &, ptype &, ptype &)
Definition: EvtMTree.cpp:137
vector< EvtComplex > parseAmps(ptype &, ptype &, ptype &)
Definition: EvtMTree.cpp:209
EvtSpinAmp getrotation(EvtParticle *) const
Definition: EvtMTree.cpp:419
bool iterateallowed(vector< int > &index) const
Definition: EvtSpinAmp.cpp:442
void extcont(const EvtSpinAmp &, int, int)
Definition: EvtSpinAmp.cpp:522
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.cpp:377
bool validTree(const EvtMNode *) const
Definition: EvtMTree.cpp:386
EvtVector4R getP4Lab() const
vector< vector< EvtMNode * > > parseChildren(ptype &, ptype &, ptype &)
Definition: EvtMTree.cpp:289
bool parsecheck(char, const string &)
Definition: EvtMTree.cpp:50
vector< int > iterallowedinit() const
Definition: EvtSpinAmp.cpp:452
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
string parseKey(ptype &, ptype &, ptype &)
Definition: EvtMTree.cpp:155
const EvtComplex & get(int i, int j) const
EvtMRes * makeresonance(const EvtId &, const string &, const vector< string > &, const string &, const vector< EvtComplex > &, const vector< EvtMNode * > &)
Definition: EvtMTree.cpp:84
void parseerror(bool, ptype &, ptype &, ptype &)
Definition: EvtMTree.cpp:115
vector< vector< EvtMNode * > > unionChildren(const string &, vector< vector< EvtMNode * >> &)
Definition: EvtMTree.cpp:255
vector< EvtMNode * > _root
Definition: EvtMTree.hh:54
EvtMTree(const EvtId *, unsigned int)
Definition: EvtMTree.cpp:37
vector< string > _lbltbl
Definition: EvtMTree.hh:55
void setres(EvtMRes *n)
Definition: EvtMRes.hh:32
Definition: EvtId.hh:27
size_t getNDaug() const
void addtree(const string &)
Definition: EvtMTree.cpp:404
virtual EvtSpinDensity rotateToHelicityBasis() const =0
const vector< int > & getresonance() const
Definition: EvtMNode.hh:60
double _norm
Definition: EvtMTree.hh:56
static EvtId getId(const std::string &name)
Definition: EvtPDL.cpp:287
static int getSpin2(spintype stype)
Definition: EvtSpinType.cpp:26
vector< EvtMNode * > parsenode(const string &, bool)
Definition: EvtMTree.cpp:339
EvtComplex exp(const EvtComplex &c)
Definition: EvtComplex.hh:240
EvtParticle * getDaug(int i)
Definition: EvtParticle.cpp:91
vector< EvtMNode * > makeparticles(const string &)
Definition: EvtMTree.cpp:61
string::const_iterator ptype
Definition: EvtMTree.hh:38
double arg(const EvtComplex &c)
Definition: EvtComplex.hh:214
vector< string > parseArg(ptype &, ptype &, ptype &)
Definition: EvtMTree.cpp:173
EvtSpinAmp amplitude(EvtParticle *) const
Definition: EvtMTree.cpp:437