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.
EvtDalitzTable.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/EvtCyclic3.hh"
25 #include "EvtGenBase/EvtPDL.hh"
27 #include "EvtGenBase/EvtReport.hh"
29 
30 #include <sstream>
31 #include <stdlib.h>
32 
33 using std::endl;
34 using std::fstream;
35 using std::ifstream;
36 
38 {
39  _dalitztable.clear();
40  _readFiles.clear();
41 }
42 
44 {
45  _dalitztable.clear();
46  _readFiles.clear();
47 }
48 
49 EvtDalitzTable* EvtDalitzTable::getInstance( const std::string dec_name,
50  bool verbose )
51 {
52  static EvtDalitzTable* theDalitzTable = 0;
53 
54  if ( theDalitzTable == 0 ) {
55  theDalitzTable = new EvtDalitzTable();
56  }
57 
58  if ( !theDalitzTable->fileHasBeenRead( dec_name ) ) {
59  theDalitzTable->readXMLDecayFile( dec_name, verbose );
60  }
61 
62  return theDalitzTable;
63 }
64 
65 bool EvtDalitzTable::fileHasBeenRead( const std::string dec_name )
66 {
67  std::vector<std::string>::iterator i = _readFiles.begin();
68  for ( ; i != _readFiles.end(); i++ ) {
69  if ( ( *i ).compare( dec_name ) == 0 ) {
70  return true;
71  }
72  }
73  return false;
74 }
75 
76 void EvtDalitzTable::readXMLDecayFile( const std::string dec_name, bool verbose )
77 {
78  if ( verbose ) {
79  EvtGenReport( EVTGEN_INFO, "EvtGen" )
80  << "EvtDalitzTable: Reading in xml parameter file " << dec_name
81  << endl;
82  }
83 
84  _readFiles.push_back( dec_name );
85 
86  EvtDalitzDecayInfo* dalitzDecay = 0;
87  double probMax = 0;
88  EvtId ipar;
89  std::string decayParent = "";
90  std::string daugStr = "";
91  EvtId daughter[3];
92 
93  EvtDalitzPlot dp;
94  EvtComplex cAmp;
95  std::vector<std::pair<EvtCyclic3::Pair, EvtCyclic3::Pair>> angAndResPairs;
96  std::string shape( "" );
98  double mass( 0. ), width( 0. ), FFp( 0. ), FFr( 0. );
99  std::vector<EvtFlatteParam> flatteParams;
100  //Nonres parameters
101  double alpha( 0. );
102  //LASS parameters
103  double aLass( 0. ), rLass( 0. ), BLass( 0. ), phiBLass( 0. ), RLass( 0. ),
104  phiRLass( 0. ), cutoffLass( -1. );
105 
106  EvtParserXml parser;
107  parser.open( dec_name );
108 
109  bool endReached = false;
110 
111  while ( parser.readNextTag() ) {
112  //TAGS FOUND UNDER DATA
113  if ( parser.getParentTagTitle() == "data" ) {
114  if ( parser.getTagTitle() == "dalitzDecay" ) {
115  int nDaughters = 0;
116 
117  decayParent = parser.readAttribute( "particle" );
118  daugStr = parser.readAttribute( "daughters" );
119  probMax = parser.readAttributeDouble( "probMax", -1 );
120 
121  checkParticle( decayParent );
122  ipar = EvtPDL::getId( decayParent );
123 
124  std::istringstream daugStream( daugStr );
125 
126  std::string daugh;
127  while ( std::getline( daugStream, daugh, ' ' ) ) {
128  checkParticle( daugh );
129  daughter[nDaughters++] = EvtPDL::getId( daugh );
130  }
131 
132  if ( nDaughters != 3 ) {
133  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
134  << "Expected to find three daughters for dalitzDecay of "
135  << decayParent << " near line "
136  << parser.getLineNumber() << ", "
137  << "found " << nDaughters << endl;
138  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
139  << "Will terminate execution!" << endl;
140  ::abort();
141  }
142 
143  double m_d1 = EvtPDL::getMass( daughter[0] ),
144  m_d2 = EvtPDL::getMass( daughter[1] ),
145  m_d3 = EvtPDL::getMass( daughter[2] ),
146  M = EvtPDL::getMass( ipar );
147 
148  dp = EvtDalitzPlot( m_d1, m_d2, m_d3, M );
149 
150  dalitzDecay = new EvtDalitzDecayInfo( daughter[0], daughter[1],
151  daughter[2] );
152 
153  } else if ( parser.getTagTitle() == "copyDalitz" ) {
154  int nDaughters = 0;
155  EvtId daughter[3];
156  int nCopyDaughters = 0;
157  EvtId copyDaughter[3];
158 
159  decayParent = parser.readAttribute( "particle" );
160  daugStr = parser.readAttribute( "daughters" );
161 
162  std::string copyParent = parser.readAttribute( "copy" );
163  std::string copyDaugStr = parser.readAttribute( "copyDaughters" );
164 
165  checkParticle( decayParent );
166  ipar = EvtPDL::getId( decayParent );
167 
168  checkParticle( copyParent );
169  EvtId copypar = EvtPDL::getId( copyParent );
170 
171  std::istringstream daugStream( daugStr );
172  std::istringstream copyDaugStream( copyDaugStr );
173 
174  std::string daugh;
175  while ( std::getline( daugStream, daugh, ' ' ) ) {
176  checkParticle( daugh );
177  daughter[nDaughters++] = EvtPDL::getId( daugh );
178  }
179  while ( std::getline( copyDaugStream, daugh, ' ' ) ) {
180  checkParticle( daugh );
181  copyDaughter[nCopyDaughters++] = EvtPDL::getId( daugh );
182  }
183 
184  if ( nDaughters != 3 || nCopyDaughters != 3 ) {
185  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
186  << "Expected to find three daughters for copyDecay of "
187  << decayParent << " from " << copyParent
188  << " near line " << parser.getLineNumber() << ", "
189  << "found " << nDaughters << " and " << nCopyDaughters
190  << endl;
191  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
192  << "Will terminate execution!" << endl;
193  ::abort();
194  }
195 
196  copyDecay( ipar, daughter, copypar, copyDaughter );
197 
198  } else if ( parser.getTagTitle() == "/data" ) { //end of data
199  endReached = true;
200  parser.close();
201  break;
202  }
203  //TAGS FOUND UNDER DALITZDECAY
204  } else if ( parser.getParentTagTitle() == "dalitzDecay" ) {
205  if ( parser.getTagTitle() == "resonance" ) {
206  flatteParams.clear();
207 
208  //Amplitude
209  EvtComplex ampFactor(
210  parser.readAttributeDouble( "ampFactorReal", 1. ),
211  parser.readAttributeDouble( "ampFactorImag", 0. ) );
212  double mag = parser.readAttributeDouble( "mag", -999. );
213  double phase = parser.readAttributeDouble( "phase", -999. );
214  double real = parser.readAttributeDouble( "real", -999. );
215  double imag = parser.readAttributeDouble( "imag", -999. );
216 
217  if ( ( real != -999. || imag != -999. ) && mag == -999. &&
218  phase == -999. ) {
219  if ( real == -999. ) {
220  real = 0;
221  }
222  if ( imag == -999. ) {
223  imag = 0;
224  }
225  mag = sqrt( real * real + imag * imag );
226  phase = atan2( imag, real ) * EvtConst::radToDegrees;
227  }
228  if ( mag == -999. ) {
229  mag = 1.;
230  }
231  if ( phase == -999. ) {
232  phase = 0.;
233  }
234 
235  cAmp = ampFactor *
236  EvtComplex( cos( phase * 1.0 / EvtConst::radToDegrees ),
237  sin( phase * 1.0 / EvtConst::radToDegrees ) ) *
238  mag;
239 
240  //Resonance particle properties
241  mass = 0.;
242  width = 0.;
243  spinType = EvtSpinType::SCALAR;
244 
245  std::string particle = parser.readAttribute( "particle" );
246  if ( particle != "" ) {
247  EvtId resId = EvtPDL::getId( particle );
248  if ( resId == EvtId( -1, -1 ) ) {
249  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
250  << "Unknown particle name:" << particle.c_str()
251  << endl;
252  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
253  << "Will terminate execution!" << endl;
254  ::abort();
255  } else {
256  mass = EvtPDL::getMeanMass( resId );
257  width = EvtPDL::getWidth( resId );
258  spinType = EvtPDL::getSpinType( resId );
259  }
260  }
261 
262  width = parser.readAttributeDouble( "width", width );
263  mass = parser.readAttributeDouble( "mass", mass );
264  switch ( parser.readAttributeInt( "spin", -1 ) ) {
265  case -1: //not set here
266  break;
267  case 0:
268  spinType = EvtSpinType::SCALAR;
269  break;
270  case 1:
271  spinType = EvtSpinType::VECTOR;
272  break;
273  case 2:
274  spinType = EvtSpinType::TENSOR;
275  break;
276  default:
277  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
278  << "Unsupported spin near line "
279  << parser.getLineNumber() << " of XML file." << endl;
280  ::abort();
281  }
282 
283  //Shape and form factors
284  shape = parser.readAttribute( "shape" );
285  FFp = parser.readAttributeDouble( "BlattWeisskopfFactorParent",
286  0.0 );
287  FFr = parser.readAttributeDouble( "BlattWeisskopfFactorResonance",
288  1.5 );
289 
290  //Shape specific attributes
291  if ( shape == "NonRes_Exp" ) {
292  alpha = parser.readAttributeDouble( "alpha", 0.0 );
293  }
294  if ( shape == "LASS" ) {
295  aLass = parser.readAttributeDouble( "a", 2.07 );
296  rLass = parser.readAttributeDouble( "r", 3.32 );
297  BLass = parser.readAttributeDouble( "B", 1.0 );
298  phiBLass = parser.readAttributeDouble( "phiB", 0.0 );
299  RLass = parser.readAttributeDouble( "R", 1.0 );
300  phiRLass = parser.readAttributeDouble( "phiR", 0.0 );
301  cutoffLass = parser.readAttributeDouble( "cutoff", -1.0 );
302  }
303 
304  //Daughter pairs for resonance
305  angAndResPairs.clear();
306 
307  std::string resDaugStr = parser.readAttribute( "resDaughters" );
308  if ( resDaugStr != "" ) {
309  std::istringstream resDaugStream( resDaugStr );
310  std::string resDaug;
311  int nResDaug( 0 );
312  EvtId resDaughter[2];
313  while ( std::getline( resDaugStream, resDaug, ' ' ) ) {
314  checkParticle( resDaug );
315  resDaughter[nResDaug++] = EvtPDL::getId( resDaug );
316  }
317  if ( nResDaug != 2 ) {
318  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
319  << "Resonance must have exactly 2 daughters near line "
320  << parser.getLineNumber() << " of XML file." << endl;
321  ::abort();
322  }
323  int nRes = getDaughterPairs( resDaughter, daughter,
324  angAndResPairs );
325  if ( nRes == 0 ) {
326  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
327  << "Resonance daughters must match decay daughters near line "
328  << parser.getLineNumber() << " of XML file." << endl;
329  ::abort();
330  }
331  if ( parser.readAttributeBool( "normalise", true ) )
332  cAmp /= sqrt( nRes );
333  }
334  if ( angAndResPairs.empty() ) {
335  switch ( parser.readAttributeInt( "daughterPair" ) ) {
336  case 1:
337  angAndResPairs.push_back(
338  std::make_pair( EvtCyclic3::BC, EvtCyclic3::AB ) );
339  break;
340  case 2:
341  angAndResPairs.push_back(
342  std::make_pair( EvtCyclic3::CA, EvtCyclic3::BC ) );
343  break;
344  case 3:
345  angAndResPairs.push_back(
346  std::make_pair( EvtCyclic3::AB, EvtCyclic3::CA ) );
347  break;
348  default:
349  if ( shape ==
350  "NonRes" ) { //We don't expect a pair for non-resonant terms but add dummy values for convenience
351  angAndResPairs.push_back( std::make_pair(
353  break;
354  }
355  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
356  << "Daughter pair must be 1, 2 or 3 near line "
357  << parser.getLineNumber() << " of XML file."
358  << endl;
359  ::abort();
360  }
361  }
362 
363  if ( parser.isTagInline() ) {
364  std::vector<std::pair<EvtCyclic3::Pair, EvtCyclic3::Pair>>::iterator
365  it = angAndResPairs.begin();
366  for ( ; it != angAndResPairs.end(); it++ ) {
367  std::pair<EvtCyclic3::Pair, EvtCyclic3::Pair> pairs = *it;
368  EvtDalitzReso resonance = getResonance(
369  shape, dp, pairs.first, pairs.second, spinType,
370  mass, width, FFp, FFr, alpha, aLass, rLass, BLass,
371  phiBLass, RLass, phiRLass, cutoffLass );
372  dalitzDecay->addResonance( cAmp, resonance );
373  }
374  }
375  } else if ( parser.getTagTitle() == "/dalitzDecay" ) {
376  if ( probMax < 0 ) {
377  EvtGenReport( EVTGEN_INFO, "EvtGen" )
378  << "probMax is not defined for " << decayParent
379  << " -> " << daugStr << endl;
380  EvtGenReport( EVTGEN_INFO, "EvtGen" )
381  << "Will now estimate probMax. This may take a while. Once probMax is calculated, update the XML file to skip this step in future."
382  << endl;
383  probMax = calcProbMax( dp, dalitzDecay );
384  }
385  dalitzDecay->setProbMax( probMax );
386  addDecay( ipar, *dalitzDecay );
387  delete dalitzDecay;
388  dalitzDecay = 0;
389  } else if ( verbose ) {
390  EvtGenReport( EVTGEN_INFO, "EvtGen" )
391  << "Unexpected tag " << parser.getTagTitle()
392  << " found in XML decay file near line "
393  << parser.getLineNumber() << ". Tag will be ignored."
394  << endl;
395  }
396  //TAGS FOUND UNDER RESONANCE
397  } else if ( parser.getParentTagTitle() == "resonance" ) {
398  if ( parser.getTagTitle() == "flatteParam" ) {
399  EvtFlatteParam param( parser.readAttributeDouble( "mass1" ),
400  parser.readAttributeDouble( "mass2" ),
401  parser.readAttributeDouble( "g" ) );
402  flatteParams.push_back( param );
403  } else if ( parser.getTagTitle() == "/resonance" ) {
404  std::vector<std::pair<EvtCyclic3::Pair, EvtCyclic3::Pair>>::iterator
405  it = angAndResPairs.begin();
406  for ( ; it != angAndResPairs.end(); it++ ) {
407  std::pair<EvtCyclic3::Pair, EvtCyclic3::Pair> pairs = *it;
408  EvtDalitzReso resonance = getResonance(
409  shape, dp, pairs.first, pairs.second, spinType, mass,
410  width, FFp, FFr, alpha, aLass, rLass, BLass, phiBLass,
411  RLass, phiRLass, cutoffLass );
412 
413  std::vector<EvtFlatteParam>::iterator flatteIt =
414  flatteParams.begin();
415  for ( ; flatteIt != flatteParams.end(); flatteIt++ ) {
416  resonance.addFlatteParam( ( *flatteIt ) );
417  }
418 
419  dalitzDecay->addResonance( cAmp, resonance );
420  }
421  }
422  }
423  }
424 
425  if ( !endReached ) {
426  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
427  << "Either the decay file ended prematurely or the file is badly formed.\n"
428  << "Error occured near line" << parser.getLineNumber() << endl;
429  ::abort();
430  }
431 }
432 
433 void EvtDalitzTable::checkParticle( std::string particle )
434 {
435  if ( EvtPDL::getId( particle ) == EvtId( -1, -1 ) ) {
436  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
437  << "Unknown particle name:" << particle.c_str() << endl;
438  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
439  << "Will terminate execution!" << endl;
440  ::abort();
441  }
442 }
443 
445 {
446  if ( _dalitztable.find( parent ) != _dalitztable.end() ) {
447  _dalitztable[parent].push_back( dec );
448  } else {
449  _dalitztable[parent].push_back( dec );
450  }
451 }
452 
453 void EvtDalitzTable::copyDecay( EvtId parent, EvtId* daughters, EvtId copy,
454  EvtId* copyd )
455 {
456  EvtDalitzDecayInfo decay( daughters[0], daughters[1], daughters[2] );
457  std::vector<EvtDalitzDecayInfo> copyTable = getDalitzTable( copy );
458  std::vector<EvtDalitzDecayInfo>::iterator i = copyTable.begin();
459  for ( ; i != copyTable.end(); i++ ) {
460  EvtId daughter1 = ( *i ).daughter1();
461  EvtId daughter2 = ( *i ).daughter2();
462  EvtId daughter3 = ( *i ).daughter3();
463 
464  if ( ( copyd[0] == daughter1 && copyd[1] == daughter2 &&
465  copyd[2] == daughter3 ) ||
466  ( copyd[0] == daughter1 && copyd[1] == daughter3 &&
467  copyd[2] == daughter2 ) ||
468  ( copyd[0] == daughter2 && copyd[1] == daughter1 &&
469  copyd[2] == daughter3 ) ||
470  ( copyd[0] == daughter2 && copyd[1] == daughter3 &&
471  copyd[2] == daughter1 ) ||
472  ( copyd[0] == daughter3 && copyd[1] == daughter1 &&
473  copyd[2] == daughter2 ) ||
474  ( copyd[0] == daughter3 && copyd[1] == daughter2 &&
475  copyd[2] == daughter1 ) ) {
476  decay.setProbMax( ( *i ).getProbMax() );
477  std::vector<std::pair<EvtComplex, EvtDalitzReso>>::const_iterator j =
478  ( *i ).getResonances().begin();
479  for ( ; j != ( *i ).getResonances().end(); j++ ) {
480  decay.addResonance( ( *j ) );
481  }
482  addDecay( parent, decay );
483  return;
484  }
485  }
486  //if we get here then there was no match
487  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
488  << "Did not find dalitz decays for particle:" << copy << "\n";
489 }
490 
491 std::vector<EvtDalitzDecayInfo> EvtDalitzTable::getDalitzTable( const EvtId& parent )
492 {
493  std::vector<EvtDalitzDecayInfo> table;
494  if ( _dalitztable.find( parent ) != _dalitztable.end() ) {
495  table = _dalitztable[parent];
496  }
497 
498  if ( table.empty() ) {
499  EvtGenReport( EVTGEN_ERROR, "EvtGen" )
500  << "Did not find dalitz decays for particle:" << parent << "\n";
501  }
502 
503  return table;
504 }
505 
507  std::string shape, EvtDalitzPlot dp, EvtCyclic3::Pair angPair,
508  EvtCyclic3::Pair resPair, EvtSpinType::spintype spinType, double mass,
509  double width, double FFp, double FFr, double alpha, double aLass,
510  double rLass, double BLass, double phiBLass, double RLass, double phiRLass,
511  double cutoffLass )
512 {
513  if ( shape == "RBW" || shape == "RBW_CLEO" ) {
514  return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width,
515  EvtDalitzReso::RBW_CLEO, FFp, FFr );
516  } else if ( shape == "RBW_CLEO_ZEMACH" ) {
517  return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width,
518  EvtDalitzReso::RBW_CLEO_ZEMACH, FFp, FFr );
519  } else if ( shape == "GS" || shape == "GS_CLEO" ) {
520  return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width,
521  EvtDalitzReso::GS_CLEO, FFp, FFr );
522  } else if ( shape == "GS_CLEO_ZEMACH" ) {
523  return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width,
524  EvtDalitzReso::GS_CLEO_ZEMACH, FFp, FFr );
525  } else if ( shape == "GAUSS" || shape == "GAUSS_CLEO" ) {
526  return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width,
527  EvtDalitzReso::GAUSS_CLEO, FFp, FFr );
528  } else if ( shape == "GAUSS_CLEO_ZEMACH" ) {
529  return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width,
531  } else if ( shape == "Flatte" ) {
532  return EvtDalitzReso( dp, resPair, mass );
533  } else if ( shape == "LASS" ) {
534  return EvtDalitzReso( dp, resPair, mass, width, aLass, rLass, BLass,
535  phiBLass, RLass, phiRLass, cutoffLass, true );
536  } else if ( shape == "NonRes" ) {
537  return EvtDalitzReso();
538  } else if ( shape == "NonRes_Linear" ) {
539  return EvtDalitzReso( dp, resPair, EvtDalitzReso::NON_RES_LIN );
540  } else if ( shape == "NonRes_Exp" ) {
541  return EvtDalitzReso( dp, resPair, EvtDalitzReso::NON_RES_EXP, alpha );
542  } else { //NBW
543  if ( shape != "NBW" )
544  EvtGenReport( EVTGEN_WARNING, "EvtGen" )
545  << "EvtDalitzTable: shape " << shape
546  << " is unknown. Defaulting to NBW." << endl;
547  return EvtDalitzReso( dp, angPair, resPair, spinType, mass, width,
548  EvtDalitzReso::NBW, FFp, FFr );
549  }
550 }
551 
553  EvtId* resDaughter, EvtId* daughter,
554  std::vector<std::pair<EvtCyclic3::Pair, EvtCyclic3::Pair>>& angAndResPairs )
555 {
556  int n( 0 );
557  if ( resDaughter[0] == daughter[0] && resDaughter[1] == daughter[1] ) {
558  angAndResPairs.push_back(
559  std::make_pair( EvtCyclic3::BC, EvtCyclic3::AB ) );
560  n++;
561  } else if ( resDaughter[0] == daughter[1] && resDaughter[1] == daughter[0] ) {
562  angAndResPairs.push_back(
563  std::make_pair( EvtCyclic3::CA, EvtCyclic3::AB ) );
564  n++;
565  }
566 
567  if ( resDaughter[0] == daughter[1] && resDaughter[1] == daughter[2] ) {
568  angAndResPairs.push_back(
569  std::make_pair( EvtCyclic3::CA, EvtCyclic3::BC ) );
570  n++;
571  } else if ( resDaughter[0] == daughter[2] && resDaughter[1] == daughter[1] ) {
572  angAndResPairs.push_back(
573  std::make_pair( EvtCyclic3::AB, EvtCyclic3::BC ) );
574  n++;
575  }
576 
577  if ( resDaughter[0] == daughter[2] && resDaughter[1] == daughter[0] ) {
578  angAndResPairs.push_back(
579  std::make_pair( EvtCyclic3::AB, EvtCyclic3::CA ) );
580  n++;
581  } else if ( resDaughter[0] == daughter[0] && resDaughter[1] == daughter[2] ) {
582  angAndResPairs.push_back(
583  std::make_pair( EvtCyclic3::BC, EvtCyclic3::CA ) );
584  n++;
585  }
586 
587  return n;
588 }
589 
591 {
592  double factor = 1.2; //factor to increase our final answer by
593  int nStep( 1000 ); //number of steps - total points will be 3*nStep*nStep
594 
595  double maxProb( 0 );
596  double min( 0 ), max( 0 ), step( 0 ), min2( 0 ), max2( 0 ), step2( 0 );
597 
598  //first do AB, BC
599  min = dp.qAbsMin( EvtCyclic3::AB );
600  max = dp.qAbsMax( EvtCyclic3::AB );
601  step = ( max - min ) / nStep;
602  for ( int i = 0; i < nStep; ++i ) {
603  double qAB = min + i * step;
604  min2 = dp.qMin( EvtCyclic3::BC, EvtCyclic3::AB, qAB );
605  max2 = dp.qMax( EvtCyclic3::BC, EvtCyclic3::AB, qAB );
606  step2 = ( max2 - min2 ) / nStep;
607  for ( int j = 0; j < nStep; ++j ) {
608  double qBC = min2 + j * step2;
609  EvtDalitzCoord coord( EvtCyclic3::AB, qAB, EvtCyclic3::BC, qBC );
610  EvtDalitzPoint point( dp, coord );
611  double prob = calcProb( point, model );
612  if ( prob > maxProb )
613  maxProb = prob;
614  }
615  }
616 
617  //next do BC, CA
618  min = dp.qAbsMin( EvtCyclic3::BC );
619  max = dp.qAbsMax( EvtCyclic3::BC );
620  step = ( max - min ) / nStep;
621  for ( int i = 0; i < nStep; ++i ) {
622  double qBC = min + i * step;
623  min2 = dp.qMin( EvtCyclic3::CA, EvtCyclic3::BC, qBC );
624  max2 = dp.qMax( EvtCyclic3::CA, EvtCyclic3::BC, qBC );
625  step2 = ( max2 - min2 ) / nStep;
626  for ( int j = 0; j < nStep; ++j ) {
627  double qCA = min2 + j * step2;
628  EvtDalitzCoord coord( EvtCyclic3::BC, qBC, EvtCyclic3::CA, qCA );
629  EvtDalitzPoint point( dp, coord );
630  double prob = calcProb( point, model );
631  if ( prob > maxProb )
632  maxProb = prob;
633  }
634  }
635 
636  //finally do CA, AB
637  min = dp.qAbsMin( EvtCyclic3::CA );
638  max = dp.qAbsMax( EvtCyclic3::CA );
639  step = ( max - min ) / nStep;
640  for ( int i = 0; i < nStep; ++i ) {
641  double qCA = min + i * step;
642  min2 = dp.qMin( EvtCyclic3::AB, EvtCyclic3::CA, qCA );
643  max2 = dp.qMax( EvtCyclic3::AB, EvtCyclic3::CA, qCA );
644  step2 = ( max2 - min2 ) / nStep;
645  for ( int j = 0; j < nStep; ++j ) {
646  double qAB = min2 + j * step2;
647  EvtDalitzCoord coord( EvtCyclic3::CA, qCA, EvtCyclic3::AB, qAB );
648  EvtDalitzPoint point( dp, coord );
649  double prob = calcProb( point, model );
650  if ( prob > maxProb )
651  maxProb = prob;
652  }
653  }
654  EvtGenReport( EVTGEN_INFO, "EvtGen" )
655  << "Largest probability found was " << maxProb << endl;
656  EvtGenReport( EVTGEN_INFO, "EvtGen" )
657  << "Setting probMax to " << factor * maxProb << endl;
658  return factor * maxProb;
659 }
660 
662 {
663  std::vector<std::pair<EvtComplex, EvtDalitzReso>> resonances =
664  model->getResonances();
665 
666  EvtComplex amp( 0, 0 );
667  std::vector<std::pair<EvtComplex, EvtDalitzReso>>::iterator i =
668  resonances.begin();
669  for ( ; i != resonances.end(); i++ ) {
670  std::pair<EvtComplex, EvtDalitzReso> res = ( *i );
671  amp += res.first * res.second.evaluate( point );
672  }
673  return abs2( amp );
674 }
int getLineNumber()
Definition: EvtParserXml.hh:37
double calcProbMax(EvtDalitzPlot dp, EvtDalitzDecayInfo *model)
double qAbsMin(EvtCyclic3::Pair i) const
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.cpp:377
std::map< EvtId, std::vector< EvtDalitzDecayInfo > > _dalitztable
std::ostream & EvtGenReport(EvtGenSeverity severity, const char *facility=0)
Definition: EvtReport.cpp:33
double readAttributeDouble(std::string attribute, double defaultValue=-1.)
void addFlatteParam(const EvtFlatteParam &param)
void setProbMax(double probMax)
static double getMeanMass(EvtId i)
Definition: EvtPDL.cpp:314
double abs2(const EvtComplex &c)
Definition: EvtComplex.hh:209
bool open(std::string filename)
std::string getTagTitle()
Definition: EvtParserXml.hh:35
double qMin(EvtCyclic3::Pair i, EvtCyclic3::Pair j, double q) const
bool readAttributeBool(std::string attribute, bool defaultValue=false)
Definition: EvtId.hh:27
void addResonance(EvtComplex amp, EvtDalitzReso res)
void addDecay(EvtId parent, const EvtDalitzDecayInfo &dec)
int getDaughterPairs(EvtId *resDaughter, EvtId *daughter, std::vector< std::pair< EvtCyclic3::Pair, EvtCyclic3::Pair >> &angAndResPairs)
bool readNextTag()
std::string getParentTagTitle()
const std::vector< std::pair< EvtComplex, EvtDalitzReso > > & getResonances() const
static EvtDalitzTable * getInstance(const std::string dec_name="", bool verbose=true)
static EvtId getId(const std::string &name)
Definition: EvtPDL.cpp:287
double imag(const EvtComplex &c)
Definition: EvtComplex.hh:235
void readXMLDecayFile(const std::string dec_name, bool verbose=true)
double calcProb(EvtDalitzPoint point, EvtDalitzDecayInfo *model)
EvtDalitzReso getResonance(std::string shape, EvtDalitzPlot dp, EvtCyclic3::Pair angPair, EvtCyclic3::Pair resPair, EvtSpinType::spintype spinType, double mass, double width, double FFp, double FFr, double alpha, double aLass, double rLass, double BLass, double phiBLass, double RLass, double phiRLass, double cutoffLass)
static double getWidth(EvtId i)
Definition: EvtPDL.cpp:352
int readAttributeInt(std::string attribute, int defaultValue=-1)
static const double radToDegrees
Definition: EvtConst.hh:28
void copyDecay(EvtId parent, EvtId *daughters, EvtId copy, EvtId *copyd)
double qMax(EvtCyclic3::Pair i, EvtCyclic3::Pair j, double q) const
double qAbsMax(EvtCyclic3::Pair i) const
bool isTagInline()
Definition: EvtParserXml.hh:38
static double getMass(EvtId i)
Definition: EvtPDL.cpp:319
std::vector< EvtDalitzDecayInfo > getDalitzTable(const EvtId &parent)
double real(const EvtComplex &c)
Definition: EvtComplex.hh:230
bool fileHasBeenRead(const std::string dec_name)
std::vector< std::string > _readFiles
std::string readAttribute(std::string attribute, std::string defaultValue="")
void checkParticle(std::string particle)