BOSS 8.0.0
BESIII Offline Software System
Loading...
Searching...
No Matches
EvtVub.cc
Go to the documentation of this file.
1//--------------------------------------------------------------------------
2//
3// Environment:
4// This software is part of the EvtGen package developed jointly
5// for the BaBar and CLEO collaborations. If you use all or part
6// of it, please give an appropriate acknowledgement.
7//
8// Copyright Information:
9// Copyright (C) 1998 Caltech, UCSB
10//
11// Module: EvtVub.cc
12//
13// Description: Routine to decay a particle according th phase space
14//
15// Modification history:
16//
17// Sven Menke January 17, 2001 Module created
18//
19//------------------------------------------------------------------------
20//
21#include "EvtVub.hh"
28#include <stdlib.h>
29#include <string>
30// #include "EvtHepRandomEngine.hh"
31#include "CLHEP/Random/RandGeneral.h"
33#include "EvtPFermi.hh"
34#include "EvtVubdGamma.hh"
35using std::endl;
36using namespace CLHEP;
37typedef double HepDouble;
38
39// #include "CLHEP/config/CLHEP.h" //maqm add
40// #include "CLHEP/config/TemplateFunctions.h" //maqm add
41
43 delete _dGamma;
44 delete[] _masses;
45 delete[] _weights;
46}
47
48void EvtVub::getName( std::string& model_name ) { model_name = "VUB"; }
49
51
53
54 // check that there are at least 6 arguments
55
56 if ( getNArg() < 6 )
57 {
58
59 report( ERROR, "EvtGen" )
60 << "EvtVub generator expected "
61 << " at least 6 arguments (mb,a,alpha_s,Nbins,m1,w1,...) but found: " << getNArg()
62 << endl;
63 report( ERROR, "EvtGen" ) << "Will terminate execution!" << endl;
64 ::abort();
65 }
66
67 _mb = getArg( 0 );
68 _a = getArg( 1 );
69 _alphas = getArg( 2 );
70 _nbins = abs( (int)getArg( 3 ) );
71 _storeQplus = ( getArg( 3 ) < 0 ? 1 : 0 );
72 _masses = new double[_nbins];
73 _weights = new double[_nbins];
74
75 if ( getNArg() - 4 != 2 * _nbins )
76 {
77 report( ERROR, "EvtGen" ) << "EvtVub generator expected " << _nbins
78 << " masses and weights but found: " << ( getNArg() - 4 ) / 2
79 << endl;
80 report( ERROR, "EvtGen" ) << "Will terminate execution!" << endl;
81 ::abort();
82 }
83 int i, j = 4;
84 double maxw = 0.;
85 for ( i = 0; i < _nbins; i++ )
86 {
87 _masses[i] = getArg( j++ );
88 if ( i > 0 && _masses[i] <= _masses[i - 1] )
89 {
90 report( ERROR, "EvtGen" ) << "EvtVub generator expected "
91 << " mass bins in ascending order!"
92 << "Will terminate execution!" << endl;
93 ::abort();
94 }
95 _weights[i] = getArg( j++ );
96 if ( _weights[i] < 0 )
97 {
98 report( ERROR, "EvtGen" ) << "EvtVub generator expected "
99 << " weights >= 0, but found: " << _weights[i] << endl;
100 report( ERROR, "EvtGen" ) << "Will terminate execution!" << endl;
101 ::abort();
102 }
103 if ( _weights[i] > maxw ) maxw = _weights[i];
104 }
105 if ( maxw == 0 )
106 {
107 report( ERROR, "EvtGen" ) << "EvtVub generator expected at least one "
108 << " weight > 0, but found none! "
109 << "Will terminate execution!" << endl;
110 ::abort();
111 }
112 for ( i = 0; i < _nbins; i++ ) _weights[i] /= maxw;
113
114 // the maximum dGamma*p2 value depends on alpha_s only:
115
116 const double dGMax0 = 3.;
117 _dGMax = 0.21344 + 8.905 * _alphas;
118 if ( _dGMax < dGMax0 ) _dGMax = dGMax0;
119
120 // for the Fermi Motion we need a B-Meson mass - but it's not critical
121 // to get an exact value; in order to stay in the phase space for
122 // B+- and B0 use the smaller mass
123
124 EvtId BP = EvtPDL::getId( "B+" );
125 EvtId B0 = EvtPDL::getId( "B0" );
126
127 double mB0 = EvtPDL::getMaxMass( B0 );
128 double mBP = EvtPDL::getMaxMass( BP );
129
130 double mB = ( mB0 < mBP ? mB0 : mBP );
131
132 const double xlow = -_mb;
133 const double xhigh = mB - _mb;
134 const int aSize = 10000;
135
136 EvtPFermi pFermi( _a, mB, _mb );
137 // pf is the cumulative distribution
138 // normalized to 1.
139 _pf.resize( aSize );
140 for ( i = 0; i < aSize; i++ )
141 {
142 double kplus = xlow + (double)( i + 0.5 ) / ( (double)aSize ) * ( xhigh - xlow );
143 if ( i == 0 ) _pf[i] = pFermi.getFPFermi( kplus );
144 else _pf[i] = _pf[i - 1] + pFermi.getFPFermi( kplus );
145 }
146 for ( i = 0; i < _pf.size(); i++ ) _pf[i] /= _pf[_pf.size() - 1];
147
148 // static EvtHepRandomEngine myEngine;
149
150 // _pFermi = new RandGeneral(myEngine,pf,aSize,0);
151 _dGamma = new EvtVubdGamma( _alphas );
152
153 // check that there are 3 daughters
154 checkNDaug( 3 );
155}
156
158
160
161 int j;
162 // B+ -> u-bar specflav l+ nu
163
164 EvtParticle *xuhad, *lepton, *neutrino;
165 EvtVector4R p4;
166 // R. Faccini 21/02/03
167 // move the reweighting up , before also shooting the fermi distribution
168 double x, z, p2;
169 double sh = 0.0;
170 double mB, ml, xlow, xhigh, qplus;
171 double El = 0.0;
172 double Eh = 0.0;
173 double kplus;
174 const double lp2epsilon = -10;
175 bool rew( true );
176 while ( rew )
177 {
178
180
181 xuhad = p->getDaug( 0 );
182 lepton = p->getDaug( 1 );
183 neutrino = p->getDaug( 2 );
184
185 mB = p->mass();
186 ml = lepton->mass();
187
188 xlow = -_mb;
189 xhigh = mB - _mb;
190
191 // Fermi motion does not need to be computed inside the
192 // tryit loop as m_b in Gamma0 does not need to be replaced by (m_b+kplus).
193 // The difference however should be of the Order (lambda/m_b)^2 which is
194 // beyond the considered orders in the paper anyway ...
195
196 // for alpha_S = 0 and a mass cut on X_u not all values of kplus are
197 // possible. The maximum value is mB/2-_mb + sqrt(mB^2/4-_masses[0]^2)
198 kplus = 2 * xhigh;
199
200 while ( kplus >= xhigh || kplus <= xlow ||
201 ( _alphas == 0 &&
202 kplus >= mB / 2 - _mb + sqrt( mB * mB / 4 - _masses[0] * _masses[0] ) ) )
203 {
204 kplus = findPFermi(); //_pFermi->shoot();
205 kplus = xlow + kplus * ( xhigh - xlow );
206 }
207 qplus = mB - _mb - kplus;
208 if ( ( mB - qplus ) / 2. <= ml ) continue;
209
210 int tryit = 1;
211 while ( tryit )
212 {
213
214 x = EvtRandom::Flat();
215 z = EvtRandom::Flat( 0, 2 );
217 p2 = pow( 10, lp2epsilon * p2 );
218
219 El = x * ( mB - qplus ) / 2;
220 if ( El > ml && El < mB / 2 )
221 {
222
223 Eh = z * ( mB - qplus ) / 2 + qplus;
224 if ( Eh > 0 && Eh < mB )
225 {
226
227 sh = p2 * pow( mB - qplus, 2 ) + 2 * qplus * ( Eh - qplus ) + qplus * qplus;
228 if ( sh > _masses[0] * _masses[0] && mB * mB + sh - 2 * mB * Eh > ml * ml )
229 {
230
231 double xran = EvtRandom::Flat();
232
233 double y = _dGamma->getdGdxdzdp( x, z, p2 ) / _dGMax * p2;
234
235 if ( y > 1 )
236 report( WARNING, "EvtGen" )
237 << "EvtVub decay probability > 1 found: " << y << endl;
238 if ( y >= xran ) tryit = 0;
239 }
240 }
241 }
242 }
243 // reweight the Mx distribution
244 if ( _nbins > 0 )
245 {
246 double xran1 = EvtRandom::Flat();
247 double m = sqrt( sh );
248 j = 0;
249 while ( j < _nbins && m > _masses[j] ) j++;
250 double w = _weights[j - 1];
251 if ( w >= xran1 ) rew = false;
252 }
253 else { rew = false; }
254 }
255
256 // o.k. we have the three kineamtic variables
257 // now calculate a flat cos Theta_H [-1,1] distribution of the
258 // hadron flight direction w.r.t the B flight direction
259 // because the B is a scalar and should decay isotropic.
260 // Then chose a flat Phi_H [0,2Pi] w.r.t the B flight direction
261 // and and a flat Phi_L [0,2Pi] in the W restframe w.r.t the
262 // W flight direction.
263
264 double ctH = EvtRandom::Flat( -1, 1 );
265 double phH = EvtRandom::Flat( 0, 2 * M_PI );
266 double phL = EvtRandom::Flat( 0, 2 * M_PI );
267
268 // now compute the four vectors in the B Meson restframe
269
270 double ptmp, sttmp;
271 // calculate the hadron 4 vector in the B Meson restframe
272
273 sttmp = sqrt( 1 - ctH * ctH );
274 ptmp = sqrt( Eh * Eh - sh );
275 double pHB[4] = { Eh, ptmp * sttmp * cos( phH ), ptmp * sttmp * sin( phH ), ptmp * ctH };
276 p4.set( pHB[0], pHB[1], pHB[2], pHB[3] );
277 xuhad->init( getDaug( 0 ), p4 );
278
279 if ( _storeQplus )
280 {
281 // cludge to store the hidden parameter q+ with the decay;
282 // the lifetime of the Xu is abused for this purpose.
283 // tau = 1 ps corresponds to ctau = 0.3 mm -> in order to
284 // stay well below BaBars sensitivity we take q+/(10000 GeV) which
285 // goes up to 0.0005 in the most extreme cases as ctau in mm.
286 // To extract q+ back from the StdHepTrk its necessary to get
287 // delta_ctau = Xu->anyDaughter->getVertexTime()-Xu->getVertexTime()
288 // where these pseudo calls refere to the StdHep time stored at
289 // the production vertex in the lab for each particle. The boost
290 // has to be reversed and the result is:
291 //
292 // q+ = delta_ctau * 10000 GeV/mm * Mass_Xu/Energy_Xu
293 //
294 xuhad->setLifetime( qplus / 10000. );
295 }
296
297 // calculate the W 4 vector in the B Meson restrframe
298
299 double apWB = ptmp;
300 double pWB[4] = { mB - Eh, -pHB[1], -pHB[2], -pHB[3] };
301
302 // first go in the W restframe and calculate the lepton and
303 // the neutrino in the W frame
304
305 double mW2 = mB * mB + sh - 2 * mB * Eh;
306 double beta = ptmp / pWB[0];
307 double gamma = pWB[0] / sqrt( mW2 );
308
309 double pLW[4];
310
311 ptmp = ( mW2 - ml * ml ) / 2 / sqrt( mW2 );
312 pLW[0] = sqrt( ml * ml + ptmp * ptmp );
313
314 double ctL = ( El - gamma * pLW[0] ) / beta / gamma / ptmp;
315 if ( ctL < -1 ) ctL = -1;
316 if ( ctL > 1 ) ctL = 1;
317 sttmp = sqrt( 1 - ctL * ctL );
318
319 // eX' = eZ x eW
320 double xW[3] = { -pWB[2], pWB[1], 0 };
321 // eZ' = eW
322 double zW[3] = { pWB[1] / apWB, pWB[2] / apWB, pWB[3] / apWB };
323
324 double lx = sqrt( xW[0] * xW[0] + xW[1] * xW[1] );
325 for ( j = 0; j < 2; j++ ) xW[j] /= lx;
326
327 // eY' = eZ' x eX'
328 double yW[3] = { -pWB[1] * pWB[3], -pWB[2] * pWB[3], pWB[1] * pWB[1] + pWB[2] * pWB[2] };
329 double ly = sqrt( yW[0] * yW[0] + yW[1] * yW[1] + yW[2] * yW[2] );
330 for ( j = 0; j < 3; j++ ) yW[j] /= ly;
331
332 // p_lep = |p_lep| * ( sin(Theta) * cos(Phi) * eX'
333 // + sin(Theta) * sin(Phi) * eY'
334 // + cos(Theta) * eZ')
335 for ( j = 0; j < 3; j++ )
336 pLW[j + 1] = sttmp * cos( phL ) * ptmp * xW[j] + sttmp * sin( phL ) * ptmp * yW[j] +
337 ctL * ptmp * zW[j];
338
339 double apLW = ptmp;
340 // calculate the neutrino 4 vector in the W restframe
341 // double pNW[4] = {sqrt(mW2)-pLW[0],-pLW[1],-pLW[2],-pLW[3]};
342
343 // boost them back in the B Meson restframe
344
345 double appLB = beta * gamma * pLW[0] + gamma * ctL * apLW;
346
347 ptmp = sqrt( El * El - ml * ml );
348 double ctLL = appLB / ptmp;
349
350 if ( ctLL > 1 ) ctLL = 1;
351 if ( ctLL < -1 ) ctLL = -1;
352
353 double pLB[4] = { El, 0, 0, 0 };
354 double pNB[4] = { pWB[0] - El, 0, 0, 0 };
355
356 for ( j = 1; j < 4; j++ )
357 {
358 pLB[j] = pLW[j] + ( ctLL * ptmp - ctL * apLW ) / apWB * pWB[j];
359 pNB[j] = pWB[j] - pLB[j];
360 }
361
362 p4.set( pLB[0], pLB[1], pLB[2], pLB[3] );
363 lepton->init( getDaug( 1 ), p4 );
364
365 p4.set( pNB[0], pNB[1], pNB[2], pNB[3] );
366 neutrino->init( getDaug( 2 ), p4 );
367
368 return;
369}
370
371double EvtVub::findPFermi() {
372
373 double ranNum = EvtRandom::Flat();
374 double oOverBins = 1.0 / ( float( _pf.size() ) );
375 int nBinsBelow = 0; // largest k such that I[k] is known to be <= rand
376 int nBinsAbove = _pf.size(); // largest k such that I[k] is known to be > rand
377 int middle;
378
379 while ( nBinsAbove > nBinsBelow + 1 )
380 {
381 middle = ( nBinsAbove + nBinsBelow + 1 ) >> 1;
382 if ( ranNum >= _pf[middle] ) { nBinsBelow = middle; }
383 else { nBinsAbove = middle; }
384 }
385
386 double bSize = _pf[nBinsAbove] - _pf[nBinsBelow];
387 // binMeasure is always aProbFunc[nBinsBelow],
388
389 if ( bSize == 0 )
390 {
391 // rand lies right in a bin of measure 0. Simply return the center
392 // of the range of that bin. (Any value between k/N and (k+1)/N is
393 // equally good, in this rare case.)
394 return ( nBinsBelow + .5 ) * oOverBins;
395 }
396
397 HepDouble bFract = ( ranNum - _pf[nBinsBelow] ) / bSize;
398
399 return ( nBinsBelow + bFract ) * oOverBins;
400}
double p2[4]
character *LEPTONflag integer iresonances real zeta5 real adp3 real large_3 real zeta5 common params adp3 common switch large_3 common lepton LEPTONflag common RESFIT IRESON common RES iresonances common alpgmu era0 common physparams ERMW common leptomass ml
DOUBLE_PRECISION xlow[20]
double w
ostream & report(Severity severity, const char *facility)
Definition EvtReport.cc:34
@ ERROR
Definition EvtReport.hh:49
@ WARNING
Definition EvtReport.hh:50
double HepDouble
Definition EvtVub.cc:37
#define M_PI
Definition TConstant.h:4
double getArg(int j)
void checkNDaug(int d1, int d2=-1)
EvtId * getDaugs()
EvtId getDaug(int i)
Definition EvtId.hh:27
static double getMaxMass(EvtId i)
Definition EvtPDL.hh:55
static EvtId getId(const std::string &name)
Definition EvtPDL.cc:272
double getFPFermi(const double &kplus)
Definition EvtPFermi.cc:50
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
void setLifetime(double tau)
EvtParticle * getDaug(int i)
double mass() const
double initializePhaseSpace(int numdaughter, EvtId *daughters, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
static double Flat()
Definition EvtRandom.cc:69
void set(int i, double d)
virtual ~EvtVub()
Definition EvtVub.cc:42
void getName(std::string &name)
Definition EvtVub.cc:48
void decay(EvtParticle *p)
Definition EvtVub.cc:159
EvtDecayBase * clone()
Definition EvtVub.cc:50
EvtVub()
Definition EvtVub.hh:37
void initProbMax()
Definition EvtVub.cc:157
void init()
Definition EvtVub.cc:52