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