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.
EvtRelBreitWignerBarrierFact.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/EvtMassAmp.hh"
26 #include "EvtGenBase/EvtPDL.hh"
27 #include "EvtGenBase/EvtPatches.hh"
28 #include "EvtGenBase/EvtPredGen.hh"
32 
33 #include <algorithm>
34 
36  double mass, double width, double maxRange, EvtSpinType::spintype sp ) :
37  EvtAbsLineShape( mass, width, maxRange, sp )
38 { // double mDaug1, double mDaug2, int l) {
39 
40  _includeDecayFact = true;
41  _includeBirthFact = true;
42  _mass = mass;
43  _width = width;
44  _spin = sp;
45  _blattDecay = 3.0;
46  _blattBirth = 1.0;
47  _maxRange = maxRange;
48  _errorCond = false;
49 
50  double maxdelta = 15.0 * width;
51 
52  if ( maxRange > 0.00001 ) {
53  _massMax = mass + maxdelta;
54  _massMin = mass - maxRange;
55  } else {
56  _massMax = mass + maxdelta;
57  _massMin = mass - 15.0 * width;
58  }
59 
60  _massMax = mass + maxdelta;
61  if ( _massMin < 0. ) {
62  if ( _width > 0.0001 ) {
63  _massMin = 0.00011;
64  } else {
65  _massMin = 0.;
66  }
67  }
68 }
69 
71  const EvtRelBreitWignerBarrierFact& x ) :
72  EvtAbsLineShape( x )
73 {
74  _massMax = x._massMax;
75  _massMin = x._massMin;
78  _maxRange = x._maxRange;
82 }
83 
86 {
87  _mass = x._mass;
88  _width = x._width;
89  _spin = x._spin;
90  _massMax = x._massMax;
91  _massMin = x._massMin;
94  _maxRange = x._maxRange;
98 
99  return *this;
100 }
101 
103 {
104  return new EvtRelBreitWignerBarrierFact( *this );
105 }
106 
107 double EvtRelBreitWignerBarrierFact::getMassProb( double mass, double massPar,
108  int nDaug, double* massDau )
109 {
110  _errorCond = false;
111  //return EvtAbsLineShape::getMassProb(mass,massPar,nDaug,massDau);
112  if ( nDaug != 2 )
113  return EvtAbsLineShape::getMassProb( mass, massPar, nDaug, massDau );
114 
115  double dTotMass = 0.;
116 
117  int i;
118  for ( i = 0; i < nDaug; i++ ) {
119  dTotMass += massDau[i];
120  }
121  //EvtGenReport(EVTGEN_INFO,"EvtGen") << mass << " " << massPar << " " << dTotMass << " "<< endl;
122  // if ( (mass-dTotMass)<0.0001 ) return 0.;
123  //EvtGenReport(EVTGEN_INFO,"EvtGen") << mass << " " << dTotMass << endl;
124  if ( ( mass < dTotMass ) )
125  return 0.;
126 
127  if ( _width < 0.0001 )
128  return 1.;
129 
130  if ( massPar > 0.0000000001 ) {
131  if ( mass > massPar )
132  return 0.;
133  }
134 
135  if ( _errorCond )
136  return 0.;
137 
138  // we did all the work in getRandMass
139  return 1.;
140 }
141 
143  EvtId* dauId, EvtId* othDaugId,
144  double maxMass,
145  double* dauMasses )
146 {
147  if ( nDaug != 2 )
148  return EvtAbsLineShape::getRandMass( parId, nDaug, dauId, othDaugId,
149  maxMass, dauMasses );
150 
151  if ( _width < 0.00001 )
152  return _mass;
153 
154  //first figure out L - take the lowest allowed.
155 
156  EvtSpinType::spintype spinD1 = EvtPDL::getSpinType( dauId[0] );
157  EvtSpinType::spintype spinD2 = EvtPDL::getSpinType( dauId[1] );
158 
159  int t1 = EvtSpinType::getSpin2( spinD1 );
160  int t2 = EvtSpinType::getSpin2( spinD2 );
161  int t3 = EvtSpinType::getSpin2( _spin );
162 
163  int Lmin = -10;
164 
165  // the user has overridden the partial wave to use.
166  for ( unsigned int vC = 0; vC < _userSetPW.size(); vC++ ) {
167  if ( dauId[0] == _userSetPWD1[vC] && dauId[1] == _userSetPWD2[vC] ) {
168  Lmin = 2 * _userSetPW[vC];
169  }
170  if ( dauId[0] == _userSetPWD2[vC] && dauId[1] == _userSetPWD1[vC] ) {
171  Lmin = 2 * _userSetPW[vC];
172  }
173  }
174 
175  // allow for special cases.
176  if ( Lmin < -1 ) {
177  //There are some things I don't know how to deal with
178  if ( t3 > 4 )
179  return EvtAbsLineShape::getRandMass( parId, nDaug, dauId, othDaugId,
180  maxMass, dauMasses );
181  if ( t1 > 4 )
182  return EvtAbsLineShape::getRandMass( parId, nDaug, dauId, othDaugId,
183  maxMass, dauMasses );
184  if ( t2 > 4 )
185  return EvtAbsLineShape::getRandMass( parId, nDaug, dauId, othDaugId,
186  maxMass, dauMasses );
187 
188  //figure the min and max allowwed "spins" for the daughters state
189  Lmin = std::max( t3 - t2 - t1, std::max( t2 - t3 - t1, t1 - t3 - t2 ) );
190  if ( Lmin < 0 )
191  Lmin = 0;
192  assert( Lmin == 0 || Lmin == 2 || Lmin == 4 );
193  }
194 
195  //double massD1=EvtPDL::getMeanMass(dauId[0]);
196  //double massD2=EvtPDL::getMeanMass(dauId[1]);
197  double massD1 = dauMasses[0];
198  double massD2 = dauMasses[1];
199 
200  // I'm not sure how to define the vertex factor here - so retreat to nonRel code.
201  if ( ( massD1 + massD2 ) > _mass )
202  return EvtAbsLineShape::getRandMass( parId, nDaug, dauId, othDaugId,
203  maxMass, dauMasses );
204 
205  //parent vertex factor not yet implemented
206  double massOthD = -10.;
207  double massParent = -10.;
208  int birthl = -10;
209  if ( othDaugId ) {
210  EvtSpinType::spintype spinOth = EvtPDL::getSpinType( *othDaugId );
211  EvtSpinType::spintype spinPar = EvtPDL::getSpinType( *parId );
212 
213  int tt1 = EvtSpinType::getSpin2( spinOth );
214  int tt2 = EvtSpinType::getSpin2( spinPar );
215  int tt3 = EvtSpinType::getSpin2( _spin );
216 
217  //figure the min and max allowwed "spins" for the daughters state
218  if ( ( tt1 <= 4 ) && ( tt2 <= 4 ) ) {
219  birthl = std::max( tt3 - tt2 - tt1,
220  std::max( tt2 - tt3 - tt1, tt1 - tt3 - tt2 ) );
221  if ( birthl < 0 )
222  birthl = 0;
223 
224  massOthD = EvtPDL::getMeanMass( *othDaugId );
225  massParent = EvtPDL::getMeanMass( *parId );
226  }
227 
228  // allow user to override
229  for ( size_t vC = 0; vC < _userSetBirthPW.size(); vC++ ) {
230  if ( *othDaugId == _userSetBirthOthD[vC] &&
231  *parId == _userSetBirthPar[vC] ) {
232  birthl = 2 * _userSetBirthPW[vC];
233  }
234  }
235  }
236  double massM = _massMax;
237  if ( ( maxMass > -0.5 ) && ( maxMass < massM ) )
238  massM = maxMass;
239 
240  //special case... if the parent mass is _fixed_ we can do a little better
241  //and only for a two body decay as that seems to be where we have problems
242 
243  // Define relativistic propagator amplitude
244 
245  EvtTwoBodyVertex vd( massD1, massD2, _mass, Lmin / 2 );
246  vd.set_f( _blattDecay );
248  EvtMassAmp amp( bw, vd );
249 
250  if ( _includeDecayFact ) {
251  amp.addDeathFact();
252  amp.addDeathFactFF();
253  }
254  if ( massParent > -1. ) {
255  if ( _includeBirthFact ) {
256  EvtTwoBodyVertex vb( _mass, massOthD, massParent, birthl / 2 );
257  vb.set_f( _blattBirth );
258  amp.setBirthVtx( vb );
259  amp.addBirthFact();
260  amp.addBirthFactFF();
261  }
262  }
263 
264  EvtAmpPdf<EvtPoint1D> pdf( amp );
265 
266  // Estimate maximum and create predicate for accept reject
267 
268  double tempMaxLoc = _mass;
269  if ( maxMass > -0.5 && maxMass < _mass )
270  tempMaxLoc = maxMass;
271  double tempMax = _massMax;
272  if ( maxMass > -0.5 && maxMass < _massMax )
273  tempMax = maxMass;
274  double tempMinMass = _massMin;
275  if ( massD1 + massD2 > _massMin )
276  tempMinMass = massD1 + massD2;
277 
278  //redo sanity check - is there a solution to our problem.
279  //if not return an error condition that is caught by the
280  //mass prob calculation above.
281  if ( tempMinMass > tempMax ) {
282  _errorCond = true;
283  return tempMinMass;
284  }
285 
286  if ( tempMaxLoc < tempMinMass )
287  tempMaxLoc = tempMinMass;
288 
289  double safetyFactor = 1.2;
290 
292  safetyFactor *
293  pdf.evaluate( EvtPoint1D( tempMinMass, tempMax, tempMaxLoc ) ) );
294 
295  EvtPdfPred<EvtPoint1D> pred( pdf );
296  pred.setMax( max );
297 
298  EvtIntervalFlatPdf flat( tempMinMass, tempMax );
299  EvtPdfGen<EvtPoint1D> gen( flat );
301 
302  EvtPoint1D point = predgen();
303  return point.value();
304 }
void setBirthVtx(const EvtTwoBodyVertex &vb)
Definition: EvtMassAmp.hh:46
void addBirthFactFF()
Definition: EvtMassAmp.hh:53
virtual double getMassProb(double mass, double massPar, int nDaug, double *massDau)
double value() const
Definition: EvtPoint1D.hh:35
double evaluate(const T &p) const
Definition: EvtPdf.hh:79
double getRandMass(EvtId *parId, int nDaug, EvtId *dauId, EvtId *othDaugId, double maxMass, double *dauMasses) override
static EvtSpinType::spintype getSpinType(EvtId i)
Definition: EvtPDL.cpp:377
void set_f(double R)
std::vector< EvtId > _userSetPWD1
EvtRelBreitWignerBarrierFact & operator=(const EvtRelBreitWignerBarrierFact &x)
static double getMeanMass(EvtId i)
Definition: EvtPDL.cpp:314
Definition: EvtId.hh:27
std::vector< EvtId > _userSetBirthOthD
virtual double getRandMass(EvtId *parId, int nDaug, EvtId *dauId, EvtId *othDaugId, double maxMass, double *dauMasses)
double getMassProb(double mass, double massPar, int nDaug, double *massDau) override
static int getSpin2(spintype stype)
Definition: EvtSpinType.cpp:26
std::vector< EvtId > _userSetPWD2
std::vector< int > _userSetPW
EvtSpinType::spintype _spin
void addBirthFact()
Definition: EvtMassAmp.hh:51
std::vector< int > _userSetBirthPW
void addDeathFactFF()
Definition: EvtMassAmp.hh:54
std::vector< EvtId > _userSetBirthPar
void addDeathFact()
Definition: EvtMassAmp.hh:52