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.
EvtPropSLPole.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/EvtAmpPdf.hh"
25 #include "EvtGenBase/EvtGenKine.hh"
27 #include "EvtGenBase/EvtMassAmp.hh"
28 #include "EvtGenBase/EvtPDL.hh"
30 #include "EvtGenBase/EvtPatches.hh"
32 #include "EvtGenBase/EvtReport.hh"
41 
43 
44 #include <stdlib.h>
45 #include <string>
46 
48 {
49  return "PROPSLPOLE";
50 }
51 
53 {
54  return new EvtPropSLPole;
55 }
56 
58 {
59  if ( !_isProbMaxSet ) {
60  EvtId parnum, mesnum, lnum, nunum;
61 
62  parnum = getParentId();
63  mesnum = getDaug( 0 );
64  lnum = getDaug( 1 );
65  nunum = getDaug( 2 );
66 
67  double mymaxprob = calcMaxProb( parnum, mesnum, lnum, nunum,
68  SLPoleffmodel.get() );
69 
70  setProbMax( mymaxprob );
71 
72  _isProbMaxSet = true;
73  }
74 
75  double minKstMass = EvtPDL::getMinMass( p->getDaug( 0 )->getId() );
76  double maxKstMass = EvtPDL::getMaxMass( p->getDaug( 0 )->getId() );
77 
78  EvtIntervalFlatPdf flat( minKstMass, maxKstMass );
79  EvtPdfGen<EvtPoint1D> gen( flat );
80  EvtPoint1D point = gen();
81 
82  double massKst = point.value();
83 
84  p->getDaug( 0 )->setMass( massKst );
86 
87  // EvtVector4R p4meson = p->getDaug(0)->getP4();
88 
89  calcamp->CalcAmp( p, _amp2, SLPoleffmodel.get() );
90 
91  EvtParticle* mesonPart = p->getDaug( 0 );
92 
93  double meson_BWAmp = calBreitWigner( mesonPart, point );
94 
95  int list[2];
96  list[0] = 0;
97  list[1] = 0;
98  _amp2.vertex( 0, 0, _amp2.getAmp( list ) * meson_BWAmp );
99  list[0] = 0;
100  list[1] = 1;
101  _amp2.vertex( 0, 1, _amp2.getAmp( list ) * meson_BWAmp );
102 
103  list[0] = 1;
104  list[1] = 0;
105  _amp2.vertex( 1, 0, _amp2.getAmp( list ) * meson_BWAmp );
106  list[0] = 1;
107  list[1] = 1;
108  _amp2.vertex( 1, 1, _amp2.getAmp( list ) * meson_BWAmp );
109 
110  list[0] = 2;
111  list[1] = 0;
112  _amp2.vertex( 2, 0, _amp2.getAmp( list ) * meson_BWAmp );
113  list[0] = 2;
114  list[1] = 1;
115  _amp2.vertex( 2, 1, _amp2.getAmp( list ) * meson_BWAmp );
116 
117  return;
118 }
119 
121 {
122  _isProbMaxSet = false;
123 
124  return;
125 }
126 
128 {
129  checkNDaug( 3 );
130 
131  //We expect the parent to be a scalar
132  //and the daughters to be X lepton neutrino
133 
137 
139 
140  SLPoleffmodel = std::make_unique<EvtSLPoleFF>( getNArg(), getArgs() );
141 
142  switch ( mesontype ) {
143  case EvtSpinType::SCALAR:
144  calcamp = std::make_unique<EvtSemiLeptonicScalarAmp>();
145  break;
146  case EvtSpinType::VECTOR:
147  calcamp = std::make_unique<EvtSemiLeptonicVectorAmp>();
148  break;
149  case EvtSpinType::TENSOR:
150  calcamp = std::make_unique<EvtSemiLeptonicTensorAmp>();
151  break;
152  default:;
153  }
154 }
155 
156 double EvtPropSLPole::calBreitWignerBasic( double maxMass )
157 {
158  if ( _width < 0.0001 )
159  return 1.0;
160  //its not flat - but generated according to a BW
161 
162  double mMin = _massMin;
163  double mMax = _massMax;
164  if ( maxMass > -0.5 && maxMass < mMax )
165  mMax = maxMass;
166 
167  double massGood = EvtRandom::Flat( mMin, mMax );
168 
169  double ampVal = sqrt(
170  1.0 / ( pow( massGood - _mass, 2.0 ) + pow( _width, 2.0 ) / 4.0 ) );
171 
172  return ampVal;
173 }
174 
176 {
177  EvtId mesnum = pmeson->getId();
178  _mass = EvtPDL::getMeanMass( mesnum );
179  _width = EvtPDL::getWidth( mesnum );
180  _maxRange = EvtPDL::getMaxRange( mesnum );
181  EvtSpinType::spintype mesontype = EvtPDL::getSpinType( mesnum );
182  _includeDecayFact = true;
183  _includeBirthFact = true;
184  _spin = mesontype;
185  _blatt = 3.0;
186 
187  double maxdelta = 15.0 * _width;
188 
189  if ( _maxRange > 0.00001 ) {
190  _massMax = _mass + maxdelta;
192  } else {
193  _massMax = _mass + maxdelta;
194  _massMin = _mass - 15.0 * _width;
195  }
196 
197  _massMax = _mass + maxdelta;
198  if ( _massMin < 0. )
199  _massMin = 0.;
200 
201  EvtParticle* par = pmeson->getParent();
202  double maxMass = -1.;
203  if ( par != 0 ) {
204  if ( par->hasValidP4() )
205  maxMass = par->mass();
206  for ( size_t i = 0; i < par->getNDaug(); i++ ) {
207  EvtParticle* tDaug = par->getDaug( i );
208  if ( pmeson != tDaug )
209  maxMass -= EvtPDL::getMinMass( tDaug->getId() );
210  }
211  }
212 
213  EvtId* dauId = 0;
214  double* dauMasses = 0;
215  size_t nDaug = pmeson->getNDaug();
216  if ( nDaug > 0 ) {
217  dauId = new EvtId[nDaug];
218  dauMasses = new double[nDaug];
219  for ( size_t j = 0; j < nDaug; j++ ) {
220  dauId[j] = pmeson->getDaug( j )->getId();
221  dauMasses[j] = pmeson->getDaug( j )->mass();
222  }
223  }
224  EvtId* parId = 0;
225  EvtId* othDaugId = 0;
226  EvtParticle* tempPar = pmeson->getParent();
227  if ( tempPar ) {
228  parId = new EvtId( tempPar->getId() );
229  if ( tempPar->getNDaug() == 2 ) {
230  if ( tempPar->getDaug( 0 ) == pmeson )
231  othDaugId = new EvtId( tempPar->getDaug( 1 )->getId() );
232  else
233  othDaugId = new EvtId( tempPar->getDaug( 0 )->getId() );
234  }
235  }
236 
237  if ( nDaug != 2 )
238  return calBreitWignerBasic( maxMass );
239 
240  if ( _width < 0.00001 )
241  return 1.0;
242 
243  //first figure out L - take the lowest allowed.
244 
245  EvtSpinType::spintype spinD1 = EvtPDL::getSpinType( dauId[0] );
246  EvtSpinType::spintype spinD2 = EvtPDL::getSpinType( dauId[1] );
247 
248  int t1 = EvtSpinType::getSpin2( spinD1 );
249  int t2 = EvtSpinType::getSpin2( spinD2 );
250  int t3 = EvtSpinType::getSpin2( _spin );
251 
252  int Lmin = -10;
253 
254  // allow for special cases.
255  if ( Lmin < -1 ) {
256  //There are some things I don't know how to deal with
257  if ( t3 > 4 )
258  return calBreitWignerBasic( maxMass );
259  if ( t1 > 4 )
260  return calBreitWignerBasic( maxMass );
261  if ( t2 > 4 )
262  return calBreitWignerBasic( maxMass );
263 
264  //figure the min and max allowwed "spins" for the daughters state
265  Lmin = std::max( t3 - t2 - t1, std::max( t2 - t3 - t1, t1 - t3 - t2 ) );
266  if ( Lmin < 0 )
267  Lmin = 0;
268  assert( Lmin == 0 || Lmin == 2 || Lmin == 4 );
269  }
270 
271  //double massD1=EvtPDL::getMeanMass(dauId[0]);
272  //double massD2=EvtPDL::getMeanMass(dauId[1]);
273  double massD1 = dauMasses[0];
274  double massD2 = dauMasses[1];
275 
276  // I'm not sure how to define the vertex factor here - so retreat to nonRel code.
277  if ( ( massD1 + massD2 ) > _mass )
278  return calBreitWignerBasic( maxMass );
279 
280  //parent vertex factor not yet implemented
281  double massOthD = -10.;
282  double massParent = -10.;
283  int birthl = -10;
284  if ( othDaugId ) {
285  EvtSpinType::spintype spinOth = EvtPDL::getSpinType( *othDaugId );
286  EvtSpinType::spintype spinPar = EvtPDL::getSpinType( *parId );
287 
288  int tt1 = EvtSpinType::getSpin2( spinOth );
289  int tt2 = EvtSpinType::getSpin2( spinPar );
290  int tt3 = EvtSpinType::getSpin2( _spin );
291 
292  //figure the min and max allowwed "spins" for the daughters state
293  if ( ( tt1 <= 4 ) && ( tt2 <= 4 ) ) {
294  birthl = std::max( tt3 - tt2 - tt1,
295  std::max( tt2 - tt3 - tt1, tt1 - tt3 - tt2 ) );
296  if ( birthl < 0 )
297  birthl = 0;
298 
299  massOthD = EvtPDL::getMeanMass( *othDaugId );
300  massParent = EvtPDL::getMeanMass( *parId );
301  }
302  }
303  double massM = _massMax;
304  if ( ( maxMass > -0.5 ) && ( maxMass < massM ) )
305  massM = maxMass;
306 
307  //special case... if the parent mass is _fixed_ we can do a little better
308  //and only for a two body decay as that seems to be where we have problems
309 
310  // Define relativistic propagator amplitude
311 
312  EvtTwoBodyVertex vd( massD1, massD2, _mass, Lmin / 2 );
313  vd.set_f( _blatt );
315  EvtMassAmp amp( bw, vd );
316  // if ( _fixMassForMax) amp.fixUpMassForMax();
317  // else std::cout << "problem problem\n";
318  if ( _includeDecayFact ) {
319  amp.addDeathFact();
320  amp.addDeathFactFF();
321  }
322  if ( massParent > -1. ) {
323  if ( _includeBirthFact ) {
324  EvtTwoBodyVertex vb( _mass, massOthD, massParent, birthl / 2 );
325  amp.setBirthVtx( vb );
326  amp.addBirthFact();
327  amp.addBirthFactFF();
328  }
329  }
330 
331  EvtAmpPdf<EvtPoint1D> pdf( amp );
332 
333  double ampVal = sqrt( pdf.evaluate( point ) );
334 
335  if ( parId )
336  delete parId;
337  if ( othDaugId )
338  delete othDaugId;
339  if ( dauId )
340  delete[] dauId;
341  if ( dauMasses )
342  delete[] dauMasses;
343 
344  return ampVal;
345 }
346 
347 double EvtPropSLPole::calcMaxProb( EvtId parent, EvtId meson, EvtId lepton,
348  EvtId nudaug, EvtSemiLeptonicFF* FormFactors )
349 {
350  //This routine takes the arguements parent, meson, and lepton
351  //number, and a form factor model, and returns a maximum
352  //probability for this semileptonic form factor model. A
353  //brute force method is used. The 2D cos theta lepton and
354  //q2 phase space is probed.
355 
356  //Start by declaring a particle at rest.
357 
358  //It only makes sense to have a scalar parent. For now.
359  //This should be generalized later.
360 
361  EvtScalarParticle* scalar_part;
362  EvtParticle* root_part;
363 
364  scalar_part = new EvtScalarParticle;
365 
366  //cludge to avoid generating random numbers!
367  scalar_part->noLifeTime();
368 
369  EvtVector4R p_init;
370 
371  p_init.set( EvtPDL::getMass( parent ), 0.0, 0.0, 0.0 );
372  scalar_part->init( parent, p_init );
373  root_part = (EvtParticle*)scalar_part;
374  // root_part->set_type(EvtSpinType::SCALAR);
375  root_part->setDiagonalSpinDensity();
376 
377  EvtParticle *daughter, *lep, *trino;
378 
379  EvtAmp amp;
380 
381  EvtId listdaug[3];
382  listdaug[0] = meson;
383  listdaug[1] = lepton;
384  listdaug[2] = nudaug;
385 
386  amp.init( parent, 3, listdaug );
387 
388  root_part->makeDaughters( 3, listdaug );
389  daughter = root_part->getDaug( 0 );
390  lep = root_part->getDaug( 1 );
391  trino = root_part->getDaug( 2 );
392 
393  EvtDecayBase* decayer;
394  decayer = EvtDecayTable::getInstance()->getDecayFunc( daughter );
395  if ( decayer ) {
396  daughter->makeDaughters( decayer->nRealDaughters(), decayer->getDaugs() );
397  for ( int ii = 0; ii < decayer->nRealDaughters(); ii++ ) {
398  daughter->getDaug( ii )->setMass(
399  EvtPDL::getMeanMass( daughter->getDaug( ii )->getId() ) );
400  }
401  }
402 
403  //cludge to avoid generating random numbers!
404  daughter->noLifeTime();
405  lep->noLifeTime();
406  trino->noLifeTime();
407 
408  //Initial particle is unpolarized, well it is a scalar so it is
409  //trivial
410  EvtSpinDensity rho;
411  rho.setDiag( root_part->getSpinStates() );
412 
413  double mass[3];
414 
415  double m = root_part->mass();
416 
417  EvtVector4R p4meson, p4lepton, p4nu, p4w;
418  double q2max;
419 
420  double q2, elepton, plepton;
421  int i, j;
422  double erho, prho, costl;
423 
424  double maxfoundprob = 0.0;
425  double prob = -10.0;
426  int massiter;
427 
428  for ( massiter = 0; massiter < 3; massiter++ ) {
429  mass[0] = EvtPDL::getMeanMass( meson );
430  mass[1] = EvtPDL::getMeanMass( lepton );
431  mass[2] = EvtPDL::getMeanMass( nudaug );
432  if ( massiter == 1 ) {
433  mass[0] = EvtPDL::getMinMass( meson );
434  }
435  if ( massiter == 2 ) {
436  mass[0] = EvtPDL::getMaxMass( meson );
437  if ( ( mass[0] + mass[1] + mass[2] ) > m )
438  mass[0] = m - mass[1] - mass[2] - 0.00001;
439  }
440 
441  q2max = ( m - mass[0] ) * ( m - mass[0] );
442 
443  //loop over q2
444 
445  for ( i = 0; i < 25; i++ ) {
446  q2 = ( ( i + 0.5 ) * q2max ) / 25.0;
447 
448  erho = ( m * m + mass[0] * mass[0] - q2 ) / ( 2.0 * m );
449 
450  prho = sqrt( erho * erho - mass[0] * mass[0] );
451 
452  p4meson.set( erho, 0.0, 0.0, -1.0 * prho );
453  p4w.set( m - erho, 0.0, 0.0, prho );
454 
455  //This is in the W rest frame
456  elepton = ( q2 + mass[1] * mass[1] ) / ( 2.0 * sqrt( q2 ) );
457  plepton = sqrt( elepton * elepton - mass[1] * mass[1] );
458 
459  double probctl[3];
460 
461  for ( j = 0; j < 3; j++ ) {
462  costl = 0.99 * ( j - 1.0 );
463 
464  //These are in the W rest frame. Need to boost out into
465  //the B frame.
466  p4lepton.set( elepton, 0.0, plepton * sqrt( 1.0 - costl * costl ),
467  plepton * costl );
468  p4nu.set( plepton, 0.0,
469  -1.0 * plepton * sqrt( 1.0 - costl * costl ),
470  -1.0 * plepton * costl );
471 
472  EvtVector4R boost( ( m - erho ), 0.0, 0.0, 1.0 * prho );
473  p4lepton = boostTo( p4lepton, boost );
474  p4nu = boostTo( p4nu, boost );
475 
476  //Now initialize the daughters...
477 
478  daughter->init( meson, p4meson );
479  lep->init( lepton, p4lepton );
480  trino->init( nudaug, p4nu );
481 
482  calcamp->CalcAmp( root_part, amp, FormFactors );
483 
484  EvtPoint1D* point = new EvtPoint1D( mass[0] );
485 
486  double meson_BWAmp = calBreitWigner( daughter, *point );
487 
488  int list[2];
489  list[0] = 0;
490  list[1] = 0;
491  amp.vertex( 0, 0, amp.getAmp( list ) * meson_BWAmp );
492  list[0] = 0;
493  list[1] = 1;
494  amp.vertex( 0, 1, amp.getAmp( list ) * meson_BWAmp );
495 
496  list[0] = 1;
497  list[1] = 0;
498  amp.vertex( 1, 0, amp.getAmp( list ) * meson_BWAmp );
499  list[0] = 1;
500  list[1] = 1;
501  amp.vertex( 1, 1, amp.getAmp( list ) * meson_BWAmp );
502 
503  list[0] = 2;
504  list[1] = 0;
505  amp.vertex( 2, 0, amp.getAmp( list ) * meson_BWAmp );
506  list[0] = 2;
507  list[1] = 1;
508  amp.vertex( 2, 1, amp.getAmp( list ) * meson_BWAmp );
509 
510  //Now find the probability at this q2 and cos theta lepton point
511  //and compare to maxfoundprob.
512 
513  //Do a little magic to get the probability!!
514  prob = rho.normalizedProb( amp.getSpinDensity() );
515 
516  probctl[j] = prob;
517  }
518 
519  //probclt contains prob at ctl=-1,0,1.
520  //prob=a+b*ctl+c*ctl^2
521 
522  double a = probctl[1];
523  double b = 0.5 * ( probctl[2] - probctl[0] );
524  double c = 0.5 * ( probctl[2] + probctl[0] ) - probctl[1];
525 
526  prob = probctl[0];
527  if ( probctl[1] > prob )
528  prob = probctl[1];
529  if ( probctl[2] > prob )
530  prob = probctl[2];
531 
532  if ( fabs( c ) > 1e-20 ) {
533  double ctlx = -0.5 * b / c;
534  if ( fabs( ctlx ) < 1.0 ) {
535  double probtmp = a + b * ctlx + c * ctlx * ctlx;
536  if ( probtmp > prob )
537  prob = probtmp;
538  }
539  }
540 
541  //EvtGenReport(EVTGEN_DEBUG,"EvtGen") << "prob,probctl:"<<prob<<" "
542  // << probctl[0]<<" "
543  // << probctl[1]<<" "
544  // << probctl[2]<<endl;
545 
546  if ( prob > maxfoundprob ) {
547  maxfoundprob = prob;
548  }
549  }
550  if ( EvtPDL::getWidth( meson ) <= 0.0 ) {
551  //if the particle is narrow dont bother with changing the mass.
552  massiter = 4;
553  }
554  }
555  root_part->deleteTree();
556 
557  maxfoundprob *= 1.1;
558  return maxfoundprob;
559 }
void setMass(double m)
Definition: EvtParticle.hh:392
void setBirthVtx(const EvtTwoBodyVertex &vb)
Definition: EvtMassAmp.hh:46
void addBirthFactFF()
Definition: EvtMassAmp.hh:53
double * getArgs()
virtual int nRealDaughters()
double value() const
Definition: EvtPoint1D.hh:35
static EvtDecayTable * getInstance()
void setDiag(int n)
EvtParticle * getParent() const
Definition: EvtParticle.cpp:96
double evaluate(const T &p) const
Definition: EvtPdf.hh:79
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.cpp:377
void set_f(double R)
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
void initProbMax() override
double calBreitWignerBasic(double maxMass)
static double getMeanMass(EvtId i)
Definition: EvtPDL.cpp:314
int getSpinStates() const
EvtId getId() const
void makeDaughters(unsigned int ndaug, EvtId *id)
void set(int i, double d)
Definition: EvtVector4R.hh:167
EvtRaritaSchwinger boostTo(const EvtRaritaSchwinger &rs, const EvtVector4R p4)
EvtSpinDensity getSpinDensity()
Definition: EvtAmp.cpp:142
std::unique_ptr< EvtSemiLeptonicAmp > calcamp
EvtId * getDaugs()
Definition: EvtDecayBase.hh:66
void setProbMax(double prbmx)
bool hasValidP4()
Definition: EvtParticle.hh:403
const EvtComplex & getAmp(int *ind) const
Definition: EvtAmp.cpp:129
Definition: EvtId.hh:27
size_t getNDaug() const
void vertex(const EvtComplex &amp)
Definition: EvtAmp.cpp:454
EvtDecayBase * getDecayFunc(EvtParticle *p)
std::unique_ptr< EvtSemiLeptonicFF > SLPoleffmodel
EvtId getParentId() const
Definition: EvtDecayBase.hh:61
double calcMaxProb(EvtId parent, EvtId meson, EvtId lepton, EvtId nudaug, EvtSemiLeptonicFF *FormFactors)
double initializePhaseSpace(unsigned int numdaughter, EvtId *daughters, bool forceResetMasses=false, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
void deleteTree()
Definition: EvtAmp.hh:30
void checkNDaug(int d1, int d2=-1)
static double getMinMass(EvtId i)
Definition: EvtPDL.cpp:342
void checkSpinParent(EvtSpinType::spintype sp)
static double Flat()
Definition: EvtRandom.cpp:72
void init(EvtId part_n, double e, double px, double py, double pz)
static int getSpin2(spintype stype)
Definition: EvtSpinType.cpp:26
bool _includeDecayFact
void checkSpinDaughter(int d1, EvtSpinType::spintype sp)
double mass() const
static double getWidth(EvtId i)
Definition: EvtPDL.cpp:352
int getNDaug() const
Definition: EvtDecayBase.hh:65
void addBirthFact()
Definition: EvtMassAmp.hh:51
std::string getName() override
void setDiagonalSpinDensity()
EvtParticle * getDaug(int i)
Definition: EvtParticle.cpp:91
void init() override
static double getMaxRange(EvtId i)
Definition: EvtPDL.cpp:347
bool _includeBirthFact
void decay(EvtParticle *p) override
void noLifeTime()
Definition: EvtParticle.hh:382
EvtAmp _amp2
Definition: EvtDecayAmp.hh:73
static double getMass(EvtId i)
Definition: EvtPDL.cpp:319
EvtSpinType::spintype _spin
EvtDecayBase * clone() override
void addDeathFactFF()
Definition: EvtMassAmp.hh:54
void init(EvtId p, int ndaug, EvtId *daug)
Definition: EvtAmp.cpp:68
double calBreitWigner(EvtParticle *pmeson, EvtPoint1D point)
int getNArg() const
Definition: EvtDecayBase.hh:68
void addDeathFact()
Definition: EvtMassAmp.hh:52
static double getMaxMass(EvtId i)
Definition: EvtPDL.cpp:337
double normalizedProb(const EvtSpinDensity &d)
EvtId getDaug(int i) const
Definition: EvtDecayBase.hh:67