90 #include "reportingUtilsRoot.hpp"
91 #include "physUtils.hpp"
92 #include "factorial.hpp"
103 nBodyPhaseSpaceGen::nBodyPhaseSpaceGen()
105 _weightType (S_U_CHUNG),
109 _maxWeightObserved(0),
112 _kinematicsType (BLOCK),
116 _isoBWMass(1.0),_isoBWWidth(0.01)
128 _n = daughterMasses.size();
130 printErr <<
"number of daughters = " <<
_n <<
" does not make sense." << endl;
149 for (
unsigned int i = 1;
i <
_n; ++
i)
156 _daughters.resize(_n, TLorentzVector(0, 0, 0, 0));
161 _norm = 1 / (2 * pow(twoPi, 2 * (
int)_n - 3) * rpwa::factorial<double>(_n - 2));
165 const double fact = rpwa::factorial<double>(_n - 2);
166 _norm = 8 / (pow(fourPi, 2 * (
int)_n + 1) * fact * fact * (_n - 1));
173 printWarn <<
"unknown weight type. setting normalization to 1." << endl;
188 m.resize(nmbOfDaughters, 0);
190 m[
i] = daughterMasses[
i];
201 const double nBodyMass = nBody.M();
203 printWarn <<
"number of daughter particles = " <<
_n <<
" is smaller than 2. weight is set to 0." << endl;
205 }
else if (nBodyMass <
_mSum[
_n - 1]) {
206 printWarn <<
"n-body mass = " << nBodyMass <<
" is smaller than sum of daughter masses = "
207 <<
_mSum[
_n - 1] <<
". weight is set to 0." << endl;
226 const double maxWeight)
228 const double nBodyMass = nBody.M();
230 printWarn <<
"number of daughter particles = " <<
_n <<
" is smaller than 2. no event generated." << endl;
232 }
else if (nBodyMass <
_mSum[
_n - 1]) {
233 printWarn <<
"n-body mass = " << nBodyMass <<
" is smaller than sum of daughter masses = "
234 <<
_mSum[
_n - 1] <<
". no event generated." << endl;
252 _M[
_n - 1] = nBodyMass;
262 for (
unsigned int i =
_n - 1;
i >= 2; --
i) {
266 const double sqrtU =
_m[
i] /
_M[
i];
267 const double u = sqrtU * sqrtU;
269 const double xMax = (1 - sqrtU) * (1 - sqrtU);
270 const double deltaX = xMax - xMin;
271 const double term = 1 + u - xMin;
272 const double prob = 1 / (
i - (
i - 1) * deltaX / term);
276 x = xMin + deltaX * pow(
random(), 1 / (double)
i) * pow(
random(), 1 / (
double)(
i - 1));
278 x = xMin + deltaX * pow(
random(), 1 / (
double)
i);
280 const double deltaZ = (i * term - (i - 1) * deltaX) * pow(deltaX, (
int)i - 1);
281 _weight *= deltaZ * pow(x / (x - xMin), (
int)i - 2) *
F(x, u) / (1 + u - x);
283 _M[i - 1] =
_M[
i] * sqrt(x);
330 vector<double> r(
_n - 2, 0);
331 for (
unsigned int i = 0;
i < (
_n - 2); ++
i)
333 sort(r.begin(), r.end());
335 const double massInterval = nBodyMass -
_mSum[
_n - 1];
336 for (
unsigned int i = 1;
i < (
_n - 1); ++
i)
337 _M[
i] = _mSum[
i] + r[
i - 1] * massInterval;
359 for (
unsigned int i = 1;
i <
_n; ++
i)
365 for (
unsigned int i = 1; i <
_n; ++
i)
367 const double massInterval =
_M[_n - 1] -
_mSum[_n - 1];
373 const double M2 =
_M[1] *
_M[1];
381 for (
unsigned int i = 1; i <
_n; ++
i)
383 double motherMassMax =
_M[_n - 1] -
_mSum[_n - 1] +
_m[0];
384 double momProdMax = 1;
385 for (
unsigned int i = 1; i <
_n; ++
i) {
386 motherMassMax += _m[
i];
387 momProdMax *= breakupMomentum(motherMassMax,
_mSum[i - 1], _m[i]);
389 _weight = momProd / momProdMax;
398 printWarn <<
"unknown weight type. setting weight to 1." << endl;
405 printWarn <<
"weight = " <<
_weight << endl;
426 for (
unsigned int i = 1;
i <
_n; ++
i) {
428 _daughters[
i].SetPxPyPzE(0, 0, -_breakupMom[
i], sqrt(
_m[i] *
_m[i] + _breakupMom[i] * _breakupMom[i]));
431 const double sT = sqrt(1 - cT * cT);
432 const double cP = cos(
_phi[i]);
433 const double sP = sin(
_phi[i]);
434 for (
unsigned int j = 0; j <=
i; ++j) {
437 const double x = daughter->Px();
438 const double z = daughter->Pz();
439 daughter->SetPz(cT * z - sT * x);
440 daughter->SetPx(sT * z + cT * x);
443 const double x = daughter->Px();
444 const double y = daughter->Py();
445 daughter->SetPx(cP * x - sP * y);
446 daughter->SetPy(sP * x + cP * y);
451 const double betaGammaInv =
_M[
i] / _breakupMom[i + 1];
452 const double beta = 1 / sqrt(1 + betaGammaInv * betaGammaInv);
453 for (
unsigned int j = 0; j <=
i; ++j)
457 const TVector3 boost = nBody.BoostVector();
458 for (
unsigned int j = 0; j <
_n; ++j)
468 TLorentzVector P = nBody;
469 for (
unsigned int i =
_n - 1;
i >= 1; --
i) {
474 daughter->SetPxPyPzE(pT * cos(
_phi[i]),
479 daughter->Boost(P.BoostVector());
488 printErr <<
"unknown kinematics type. cannot calculate event kinematics." << endl;
498 const unsigned int nmbOfIterations)
502 for (
unsigned int i = 0;
i < nmbOfIterations; ++
i) {
506 maxWeight = max(
_weight, maxWeight);
515 out <<
"nBodyPhaseSpaceGen parameters:" << endl
516 <<
" number of daughter particles ............... " <<
_n << endl;
523 out <<
" weight formula ............................. " <<
_weightType << endl
524 <<
" normalization value ........................ " <<
_norm << endl
525 <<
" weight of generated event .................. " <<
_weight << endl
526 <<
" maximum weight used in hit-miss MC ......... " <<
_maxWeight << endl
528 <<
" algorithm for kinematics calculation ....... " <<
_kinematicsType << endl
529 <<
" daughter four-momenta:" << endl;
531 for (
unsigned int i = 0;
i <
_n; ++
i)
532 out <<
" daughter " <<
i <<
": " <<
_daughters[
i] << endl;