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