31#include "CLHEP/Random/RandGeneral.h"
53 _mb(4.62), _a(2.27), _alphas(0.22), _dGMax(3.),
54 _nbins_mX(0), _nbins_q2(0), _nbins_El(0), _nbins(0),
55 _masscut(0.28), _bins_mX(0), _bins_q2(0), _bins_El(0),
56 _weights(0), _dGamma(0)
70 model_name=
"VUBHYBRID";
83 if (
getNArg() < EvtVubHybrid::nParameters) {
84 report(
ERROR,
"EvtVubHybrid") <<
"EvtVub generator expected "
85 <<
"at least " << EvtVubHybrid::nParameters
86 <<
" arguments but found: " <<
getNArg()
87 <<
"\nWill terminate execution!"<<endl;
89 }
else if (
getNArg() == EvtVubHybrid::nParameters) {
90 report(
WARNING,
"EvtVubHybrid") <<
"EvtVub: generate B -> Xu l nu events "
91 <<
"without using the hybrid reweighting."
94 }
else if (
getNArg() < EvtVubHybrid::nParameters+EvtVubHybrid::nVariables) {
95 report(
ERROR,
"EvtVubHybrid") <<
"EvtVub could not read number of bins for "
96 <<
"all variables used in the reweighting\n"
97 <<
"Will terminate execution!" << endl;
110 const double dGMax0 = 3.;
111 _dGMax = 0.21344+8.905*_alphas;
112 if ( _dGMax < dGMax0 ) _dGMax = dGMax0;
120 static double mB = (mB0<mBP?mB0:mBP);
122 const double xlow = -_mb;
123 const double xhigh = mB-_mb;
124 const int aSize = 10000;
129 for(
int i=0;i<aSize;i++){
130 double kplus =
xlow + (double)(i+0.5)/((double)aSize)*(xhigh-
xlow);
136 for (
int i=0; i<_pf.size(); i++) _pf[i]/=_pf[_pf.size()-1];
140 if (_noHybrid)
return;
146 int nextArg = EvtVubHybrid::nParameters + EvtVubHybrid::nVariables;
148 _nbins = _nbins_mX*_nbins_q2*_nbins_El;
150 int expectArgs = nextArg + _nbins_mX +_nbins_q2 + _nbins_El + _nbins;
154 <<
" finds " <<
getNArg() <<
" arguments, expected " << expectArgs
155 <<
". Something is wrong with the tables of weights or thresholds."
156 <<
"\nWill terminate execution!" << endl;
163 _bins_mX =
new double[_nbins_mX];
164 for (i = 0; i < _nbins_mX; i++,nextArg++) {
165 _bins_mX[i] =
getArg(nextArg);
167 _masscut = _bins_mX[0];
169 _bins_q2 =
new double[_nbins_q2];
170 for (i = 0; i < _nbins_q2; i++,nextArg++) {
171 _bins_q2[i] =
getArg(nextArg);
174 _bins_El =
new double[_nbins_El];
175 for (i = 0; i < _nbins_El; i++,nextArg++) {
176 _bins_El[i] =
getArg(nextArg);
198 double mB,ml,
xlow,xhigh,qplus;
204 const double lp2epsilon=-10;
229 while( kplus >= xhigh || kplus <=
xlow
230 || (_alphas == 0 && kplus >= mB/2-_mb
231 + sqrt(mB*mB/4-_masscut*_masscut))) {
232 kplus = findPFermi();
235 qplus = mB-_mb-kplus;
236 if( (mB-qplus)/2.<=ml)
continue;
244 p2 = pow(10,lp2epsilon*p2);
247 if ( El > ml && El < mB/2) {
249 Eh = z*(mB-qplus)/2+qplus;
250 if ( Eh > 0 && Eh < mB ) {
252 sh = p2*pow(mB-qplus,2)+2*qplus*(Eh-qplus)+qplus*qplus;
253 if ( sh > _masscut*_masscut
254 && mB*mB + sh - 2*mB*Eh > ml*ml) {
261 <<
"EvtVubHybrid decay probability > 1 found: " <<
y << endl;
262 if (
y >= xran ) tryit = 0;
270 q2 = mB*mB + sh - 2*mB*Eh;
277 if (
w >= xran1 ) rew =
false;
301 sttmp = sqrt(1-ctH*ctH);
302 ptmp = sqrt(Eh*Eh-sh);
303 double pHB[4] = {Eh,ptmp*sttmp*
cos(phH),ptmp*sttmp*
sin(phH),ptmp*ctH};
304 p4.
set(pHB[0],pHB[1],pHB[2],pHB[3]);
327 double pWB[4] = {mB-Eh,-pHB[1],-pHB[2],-pHB[3]};
332 double mW2 = mB*mB + sh - 2*mB*Eh;
333 double beta = ptmp/pWB[0];
334 double gamma = pWB[0]/sqrt(mW2);
338 ptmp = (mW2-ml*ml)/2/sqrt(mW2);
339 pLW[0] = sqrt(ml*ml + ptmp*ptmp);
341 double ctL = (El - gamma*pLW[0])/beta/gamma/ptmp;
342 if ( ctL < -1 ) ctL = -1;
343 if ( ctL > 1 ) ctL = 1;
344 sttmp = sqrt(1-ctL*ctL);
347 double xW[3] = {-pWB[2],pWB[1],0};
349 double zW[3] = {pWB[1]/apWB,pWB[2]/apWB,pWB[3]/apWB};
351 double lx = sqrt(xW[0]*xW[0]+xW[1]*xW[1]);
356 double yW[3] = {-pWB[1]*pWB[3],-pWB[2]*pWB[3],pWB[1]*pWB[1]+pWB[2]*pWB[2]};
357 double ly = sqrt(yW[0]*yW[0]+yW[1]*yW[1]+yW[2]*yW[2]);
365 pLW[j+1] = sttmp*
cos(phL)*ptmp*xW[j]
366 + sttmp*
sin(phL)*ptmp*yW[j]
375 double appLB = beta*gamma*pLW[0] + gamma*ctL*apLW;
377 ptmp = sqrt(El*El-ml*ml);
378 double ctLL = appLB/ptmp;
380 if ( ctLL > 1 ) ctLL = 1;
381 if ( ctLL < -1 ) ctLL = -1;
383 double pLB[4] = {El,0,0,0};
384 double pNB[4] = {pWB[0]-El,0,0,0};
387 pLB[j] = pLW[j] + (ctLL*ptmp - ctL*apLW)/apWB*pWB[j];
388 pNB[j] = pWB[j] - pLB[j];
391 p4.
set(pLB[0],pLB[1],pLB[2],pLB[3]);
394 p4.
set(pNB[0],pNB[1],pNB[2],pNB[3]);
401double EvtVubHybrid::findPFermi() {
404 double oOverBins= 1.0/(float(_pf.size()));
406 int nBinsAbove = _pf.size();
409 while (nBinsAbove > nBinsBelow+1) {
410 middle = (nBinsAbove + nBinsBelow+1)>>1;
411 if (ranNum >= _pf[middle]) {
418 double bSize = _pf[nBinsAbove] - _pf[nBinsBelow];
425 return (nBinsBelow + .5) * oOverBins;
428 HepDouble bFract = (ranNum - _pf[nBinsBelow]) / bSize;
430 return (nBinsBelow + bFract) * oOverBins;
441 for (
int i = 0; i < _nbins_mX; i++) {
442 if (mX >= _bins_mX[i]) ibin_mX = i;
444 for (
int i = 0; i < _nbins_q2; i++) {
445 if (q2 >= _bins_q2[i]) ibin_q2 = i;
447 for (
int i = 0; i < _nbins_El; i++) {
448 if (El >= _bins_El[i]) ibin_El = i;
450 int ibin = ibin_mX + ibin_q2*_nbins_mX + ibin_El*_nbins_mX*_nbins_q2;
452 if ( (ibin_mX < 0) || (ibin_q2 < 0) || (ibin_El < 0) ) {
453 report(
ERROR,
"EvtVubHybrid") <<
"Cannot determine hybrid weight "
455 <<
"-> assign weight = 0" << endl;
459 return _weights[ibin];
464 _weights =
new double[_nbins];
467 for (
int i = 0; i < _nbins; i++, startArg++) {
468 _weights[i] =
getArg(startArg);
469 if (_weights[i] > maxw) maxw = _weights[i];
473 report(
ERROR,
"EvtVubHybrid") <<
"EvtVub generator expected at least one "
474 <<
" weight > 0, but found none! "
475 <<
"Will terminate execution!"<<endl;
480 for (
int i = 0; i < _nbins; i++) {
double sin(const BesAngle a)
double cos(const BesAngle a)
DOUBLE_PRECISION xlow[20]
ostream & report(Severity severity, const char *facility)
void checkNDaug(int d1, int d2=-1)
static double getMaxMass(EvtId i)
static EvtId getId(const std::string &name)
double getFPFermi(const double &kplus)
virtual void init(EvtId part_n, const EvtVector4R &p4)=0
void setLifetime(double tau)
EvtParticle * getDaug(int i)
double initializePhaseSpace(int numdaughter, EvtId *daughters, double poleSize=-1., int whichTwo1=0, int whichTwo2=1)
void set(int i, double d)
void readWeights(int startArg=0)
double getWeight(double mX, double q2, double El)
void decay(EvtParticle *p)
void getName(std::string &name)
double getdGdxdzdp(const double &x, const double &z, const double &p2)