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