BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
EvtMTree.cc
Go to the documentation of this file.
1#include <algorithm>
2#include <stdio.h>
3#include <stdlib.h>
4#include <string>
5
6#include "EvtConst.hh"
7#include "EvtKine.hh"
8#include "EvtMTree.hh"
9#include "EvtReport.hh"
10
11// Make sure to include Lineshapes here
12#include "EvtMBreitWigner.hh"
13#include "EvtMTrivialLS.hh"
14
15// Make sure to include Parametrizations
16#include "EvtMHelAmp.hh"
17
18using std::endl;
19
20EvtMTree::EvtMTree( const EvtId* idtbl, int ndaug ) {
21 for ( int i = 0; i < ndaug; ++i ) { _lbltbl.push_back( EvtPDL::name( idtbl[i] ) ); }
22}
23
25 for ( int i = 0; i < _root.size(); ++i ) delete _root[i];
26}
27
28bool EvtMTree::parsecheck( char arg, const string& chars ) {
29 bool ret = false;
30
31 for ( int i = 0; i < chars.size(); ++i ) { ret = ret || ( chars[i] == arg ); }
32
33 return ret;
34}
35
36vector<EvtMNode*> EvtMTree::makeparticles( const string& strid ) {
37 vector<EvtMNode*> particles;
38 vector<int> labels;
39
40 for ( int i = 0; i < _lbltbl.size(); ++i )
41 {
42 if ( _lbltbl[i] == strid ) labels.push_back( i );
43 }
44
45 if ( labels.size() == 0 )
46 {
47 report( ERROR, "EvtGen" ) << "Error unknown particle label " << strid << endl;
48 ::abort();
49 }
50
51 for ( int i = 0; i < labels.size(); ++i )
52 particles.push_back( new EvtMParticle( labels[i], EvtPDL::getId( strid ) ) );
53
54 return particles;
55}
56
57EvtMRes* EvtMTree::makeresonance( const EvtId& id, const string& ls,
58 const vector<string>& lsarg, const string& type,
59 const vector<EvtComplex>& amps,
60 const vector<EvtMNode*>& children ) {
61 EvtMRes* resonance = NULL;
62 EvtMLineShape* lineshape = NULL;
63
64 if ( ls == "BREITWIGNER" ) { lineshape = new EvtMBreitWigner( id, lsarg ); }
65 else if ( ls == "TRIVIAL" ) { lineshape = new EvtMTrivialLS( id, lsarg ); }
66 else
67 {
68 report( ERROR, "EvtGen" ) << "Lineshape " << lineshape << " not recognized." << endl;
69 ::abort();
70 }
71
72 if ( type == "HELAMP" ) { resonance = new EvtMHelAmp( id, lineshape, children, amps ); }
73 else
74 {
75 report( ERROR, "EvtGen" ) << "Model " << type << " not recognized." << endl;
76 ::abort();
77 }
78
79 lineshape->setres( resonance );
80
81 return resonance;
82}
83
84void EvtMTree::parseerror( bool flag, ptype& c_iter, ptype& c_begin, ptype& c_end ) {
85 if ( !flag ) return;
86
87 string error;
88
89 while ( c_begin != c_end )
90 {
91 if ( c_begin == c_iter )
92 {
93 error += '_';
94 error += *c_begin;
95 error += '_';
96 }
97 else error += *c_begin;
98
99 ++c_begin;
100 }
101
102 report( ERROR, "EvtGen" ) << "Parse error at: " << error << endl;
103 ::abort();
104}
105
106string EvtMTree::parseId( ptype& c_iter, ptype& c_begin, ptype& c_end ) {
107 string strid;
108
109 while ( c_iter != c_end )
110 {
111 parseerror( parsecheck( *c_iter, ")[]," ), c_iter, c_begin, c_end );
112 if ( *c_iter == '(' )
113 {
114 ++c_iter;
115 return strid;
116 }
117
118 strid += *c_iter;
119 ++c_iter;
120 }
121
122 return strid;
123}
124
125string EvtMTree::parseKey( ptype& c_iter, ptype& c_begin, ptype& c_end ) {
126 string key;
127
128 while ( *c_iter != ',' )
129 {
130 parseerror( c_iter == c_end || parsecheck( *c_iter, "()[]" ), c_iter, c_begin, c_end );
131 key += *c_iter;
132 ++c_iter;
133 }
134
135 ++c_iter;
136
137 parseerror( c_iter == c_end, c_iter, c_begin, c_end );
138
139 return key;
140}
141
142vector<string> EvtMTree::parseArg( ptype& c_iter, ptype& c_begin, ptype& c_end ) {
143 vector<string> arg;
144
145 if ( *c_iter != '[' ) return arg;
146 ++c_iter;
147
148 string temp;
149 while ( true )
150 {
151 parseerror( c_iter == c_end || parsecheck( *c_iter, "[()" ), c_iter, c_begin, c_end );
152
153 if ( *c_iter == ']' )
154 {
155 ++c_iter;
156 if ( temp.size() > 0 ) arg.push_back( temp );
157 break;
158 }
159
160 if ( *c_iter == ',' )
161 {
162 arg.push_back( temp );
163 temp.erase();
164 ++c_iter;
165 continue;
166 }
167
168 temp += *c_iter;
169 ++c_iter;
170 }
171 parseerror( c_iter == c_end || *c_iter != ',', c_iter, c_begin, c_end );
172 ++c_iter;
173
174 return arg;
175}
176
177vector<EvtComplex> EvtMTree::parseAmps( ptype& c_iter, ptype& c_begin, ptype& c_end ) {
178 vector<string> parg = parseArg( c_iter, c_begin, c_end );
179 parseerror( parg.size() == 0, c_iter, c_begin, c_end );
180
181 // Get parametrization amplitudes
182 vector<string>::iterator amp_iter = parg.begin();
183 vector<string>::iterator amp_end = parg.end();
184 vector<EvtComplex> amps;
185
186 while ( amp_iter != amp_end )
187 {
188 const char* nptr;
189 char* endptr = NULL;
190 double amp = 0.0, phase = 0.0;
191
192 nptr = ( *amp_iter ).c_str();
193 amp = strtod( nptr, &endptr );
194 parseerror( nptr == endptr, c_iter, c_begin, c_end );
195
196 ++amp_iter;
197 parseerror( amp_iter == amp_end, c_iter, c_begin, c_end );
198
199 nptr = ( *amp_iter ).c_str();
200 phase = strtod( nptr, &endptr );
201 parseerror( nptr == endptr, c_iter, c_begin, c_end );
202
203 amps.push_back( amp * exp( EvtComplex( 0.0, phase ) ) );
204
205 ++amp_iter;
206 }
207
208 return amps;
209}
210
211vector<EvtMNode*> EvtMTree::duplicate( const vector<EvtMNode*>& list ) const {
212 vector<EvtMNode*> newlist;
213
214 for ( int i = 0; i < list.size(); ++i ) newlist.push_back( list[i]->duplicate() );
215
216 return newlist;
217}
218
219// XXX Warning it is unsafe to use cl1 after a call to this function XXX
220vector<vector<EvtMNode*>> EvtMTree::unionChildren( const string& nodestr,
221 vector<vector<EvtMNode*>>& cl1 ) {
222 vector<EvtMNode*> cl2 = parsenode( nodestr, false );
223 vector<vector<EvtMNode*>> cl;
224
225 if ( cl1.size() == 0 )
226 {
227 for ( int i = 0; i < cl2.size(); ++i )
228 {
229 vector<EvtMNode*> temp( 1, cl2[i] );
230 cl.push_back( temp );
231 }
232
233 return cl;
234 }
235
236 for ( int i = 0; i < cl1.size(); ++i )
237 {
238 for ( int j = 0; j < cl2.size(); ++j )
239 {
240 vector<EvtMNode*> temp;
241 temp = duplicate( cl1[i] );
242 temp.push_back( cl2[j]->duplicate() );
243
244 cl.push_back( temp );
245 }
246 }
247
248 for ( int i = 0; i < cl1.size(); ++i )
249 for ( int j = 0; j < cl1[i].size(); ++j ) delete cl1[i][j];
250 for ( int i = 0; i < cl2.size(); ++i ) delete ( cl2[i] );
251
252 return cl;
253}
254
255vector<vector<EvtMNode*>> EvtMTree::parseChildren( ptype& c_iter, ptype& c_begin,
256 ptype& c_end ) {
257 bool test = true;
258 int pcount = 0;
259 string nodestr;
260 vector<vector<EvtMNode*>> children;
261
262 parseerror( c_iter == c_end || *c_iter != '[', c_iter, c_begin, c_end );
263 ++c_iter;
264
265 while ( test )
266 {
267 parseerror( c_iter == c_end || pcount < 0, c_iter, c_begin, c_end );
268
269 switch ( *c_iter )
270 {
271 case ')':
272 --pcount;
273 nodestr += *c_iter;
274 break;
275 case '(':
276 ++pcount;
277 nodestr += *c_iter;
278 break;
279 case ']':
280 if ( pcount == 0 )
281 {
282 children = unionChildren( nodestr, children );
283 test = false;
284 }
285 else { nodestr += *c_iter; }
286 break;
287 case ',':
288 if ( pcount == 0 )
289 {
290 children = unionChildren( nodestr, children );
291 nodestr.erase();
292 }
293 else { nodestr += *c_iter; }
294 break;
295 default: nodestr += *c_iter; break;
296 }
297
298 ++c_iter;
299 }
300
301 return children;
302}
303
304vector<EvtMNode*> EvtMTree::parsenode( const string& args, bool rootnode ) {
305 ptype c_iter, c_begin, c_end;
306
307 c_iter = c_begin = args.begin();
308 c_end = args.end();
309
310 string strid = parseId( c_iter, c_begin, c_end );
311
312 // Case 1: Particle
313 if ( c_iter == c_end ) return makeparticles( strid );
314
315 // Case 2: Resonance - parse further
316 EvtId id = EvtPDL::getId( strid );
317 parseerror( EvtId( -1, -1 ) == id, c_iter, c_begin, c_end );
318
319 string ls;
320 vector<string> lsarg;
321
322 if ( rootnode ) { ls = "TRIVIAL"; }
323 else
324 {
325 // Get lineshape (e.g. BREITWIGNER)
326 ls = parseKey( c_iter, c_begin, c_end );
327 lsarg = parseArg( c_iter, c_begin, c_end );
328 }
329
330 // Get resonance parametrization type (e.g. HELAMP)
331 string type = parseKey( c_iter, c_begin, c_end );
332 vector<EvtComplex> amps = parseAmps( c_iter, c_begin, c_end );
333
334 // Children
335 vector<vector<EvtMNode*>> children = parseChildren( c_iter, c_begin, c_end );
336
337 report( ERROR, "EvtGen" ) << children.size() << endl;
338 vector<EvtMNode*> resonances;
339 for ( int i = 0; i < children.size(); ++i )
340 { resonances.push_back( makeresonance( id, ls, lsarg, type, amps, children[i] ) ); }
341
342 parseerror( c_iter == c_end || *c_iter != ')', c_iter, c_begin, c_end );
343
344 return resonances;
345}
346
347bool EvtMTree::validTree( const EvtMNode* root ) const {
348 vector<int> res = root->getresonance();
349 vector<bool> check( res.size(), false );
350
351 for ( int i = 0; i < res.size(); ++i ) { check[res[i]] = true; }
352
353 bool ret = true;
354
355 for ( int i = 0; i < check.size(); ++i ) { ret = ret && check[i]; }
356
357 return ret;
358}
359
360void EvtMTree::addtree( const string& str ) {
361 vector<EvtMNode*> roots = parsenode( str, true );
362 _norm = 0;
363
364 for ( int i = 0; i < roots.size(); ++i )
365 {
366 if ( validTree( roots[i] ) )
367 {
368 _root.push_back( roots[i] );
369 _norm = _norm + 1;
370 }
371 else delete roots[i];
372 }
373
374 _norm = 1.0 / sqrt( _norm );
375}
376
377EvtSpinAmp EvtMTree::amplitude( const vector<EvtVector4R>& product ) const {
378 if ( _root.size() == 0 )
379 {
380 report( ERROR, "EvtGen" ) << "No decay tree present." << endl;
381 ::abort();
382 }
383
384 EvtSpinAmp amp = _root[0]->amplitude( product );
385 for ( int i = 1; i < _root.size(); ++i )
386 {
387 // Assume that helicity amplitude is returned and rotate to standard
388 // amplitude here, do this before adding the amplitudes (different
389 // frames?)
390 amp += _root[i]->amplitude( product );
391 }
392
393 return _norm * amp;
394}
std::string test
std::string root
EvtComplex exp(const EvtComplex &c)
double arg(const EvtComplex &c)
string::const_iterator ptype
Definition EvtMTree.hh:19
ostream & report(Severity severity, const char *facility)
Definition EvtReport.cc:34
@ ERROR
Definition EvtReport.hh:49
*************DOUBLE PRECISION m_pi *DOUBLE PRECISION m_HvecTau2 DOUBLE PRECISION m_HvClone2 DOUBLE PRECISION m_gamma1 DOUBLE PRECISION m_gamma2 DOUBLE PRECISION m_thet1 DOUBLE PRECISION m_thet2 INTEGER m_IFPHOT *COMMON c_Taupair $ !Spin Polarimeter vector first Tau $ !Spin Polarimeter vector second Tau $ !Clone Spin Polarimeter vector first Tau $ !Clone Spin Polarimeter vector second Tau $ !Random Euler angle for cloning st tau $ !Random Euler angle for cloning st tau $ !Random Euler angle for cloning st tau $ !Random Euler angle for cloning nd tau $ !Random Euler angle for cloning nd tau $ !Random Euler angle for cloning nd tau $ !phi of HvecTau1 $ !theta of HvecTau1 $ !phi of HvecTau2 $ !theta of HvecTau2 $ !super key
Definition Taupair.h:42
Definition EvtId.hh:27
void setres(EvtMRes *n)
Definition EvtMRes.hh:13
EvtMTree(const EvtId *idtbl, int ndaug)
Definition EvtMTree.cc:20
void addtree(const string &args)
Definition EvtMTree.cc:360
EvtSpinAmp amplitude(const vector< EvtVector4R > &product) const
Definition EvtMTree.cc:377
~EvtMTree()
Definition EvtMTree.cc:24
static std::string name(EvtId i)
Definition EvtPDL.hh:70
static EvtId getId(const std::string &name)
Definition EvtPDL.cc:272