15 namespace ParticleDecaysMC {
18 double ThreeBodym12F2(
double m12,
double M,
double m1,
double m2,
double m3) {
19 double m12k = m12 * m12;
20 return (m12k - (m1 + m2)*(m1 + m2)) * (m12k - (m1 - m2)*(m1 - m2)) * (M*M - (m12 + m3)*(m12 + m3)) * (M*M - (m12 - m3)*(m12 - m3)) / m12k;
25 double l = m1_ + m2_, r = M - m3_;
26 double m1 = 0., m2 = 0.;
27 m1 = l + (r - l) / 3.;
28 m2 = r - (r - l) / 3.;
29 while ((m2 - m1) > 1e-8) {
38 m1 = l + (r - l) / 3.;
39 m2 = r - (r - l) / 3.;
65 double v2 = vx * vx + vy * vy + vz * vz;
66 double gamma = 1. / sqrt(1. - v2);
67 ret.
p0 = gamma * part.
p0 - gamma * (vx * part.
px + vy * part.
py + vz * part.
pz);
68 ret.
px = -gamma * vx * part.
p0 + (1. + (gamma - 1.)*vx*vx / v2) * part.
px +
69 (gamma - 1.)*vx*vy / v2 * part.
py + (gamma - 1.)*vx*vz / v2 * part.
pz;
70 ret.
py = -gamma * vy * part.
p0 + (1. + (gamma - 1.)*vy*vy / v2) * part.
py +
71 (gamma - 1.)*vy*vx / v2 * part.
px + (gamma - 1.)*vy*vz / v2 * part.
pz;
72 ret.
pz = -gamma * vz * part.
p0 + (1. + (gamma - 1.)*vz*vz / v2) * part.
pz +
73 (gamma - 1.)*vz*vx / v2 * part.
px + (gamma - 1.)*vz*vy / v2 * part.
py;
78 std::vector<SimpleParticle> ret(0);
79 ret.push_back(Mother);
80 ret.push_back(Mother);
86 double vx = Mother.
px / Mother.
p0;
87 double vy = Mother.
py / Mother.
p0;
88 double vz = Mother.
pz / Mother.
p0;
90 double ten1 = (Mo.
m*Mo.
m - m2 * m2 + m1 * m1) / 2. / Mo.
m;
91 double tp = sqrt(ten1*ten1 - m1 * m1);
94 double sthe = sqrt(1. - cthe * cthe);
95 ret[0].px = tp * cos(tphi) * sthe;
96 ret[0].py = tp * sin(tphi) * sthe;
97 ret[0].pz = tp * cthe;
99 ret[1].px = -ret[0].px;
100 ret[1].py = -ret[0].py;
101 ret[1].pz = -ret[0].pz;
102 ret[1].p0 = sqrt(m2*m2 + ret[1].px*ret[1].px + ret[1].py*ret[1].py + ret[1].pz*ret[1].pz);
107 ret[0].MotherPDGID = Mother.
PDGID;
108 ret[1].MotherPDGID = Mother.
PDGID;
110 ret[0].epoch = Mother.
epoch + 1;
111 ret[1].epoch = Mother.
epoch + 1;
113 for (
size_t i = 0; i < ret.size(); ++i)
114 if (ret[i].px != ret[i].px) {
115 printf(
"**WARNING** Issue in a two-body decay!\n");
122 std::vector<SimpleParticle> ret(0);
123 if (masses.size() < 1)
return ret;
126 if (masses.size() == 1)
128 masses.push_back(0.);
132 if (masses.size() > 3) {
138 double tmasssum = 0.;
139 for (
size_t i = 0; i < masses.size(); ++i) tmasssum += masses[i];
140 if (Mother2.
m < tmasssum) Mother2.
m = tmasssum + 1e-7;
142 if (masses.size() == 2)
return TwoBodyDecay(Mother2, masses[0], pdgs[0], masses[1], pdgs[1]);
144 for (
size_t i = 0; i < masses.size() - 1; ++i) tmin += masses[i];
145 double tmax = Mother2.
m - masses[masses.size() - 1];
147 if (masses.size() == 3) {
154 std::vector<SimpleParticle> ret1 =
TwoBodyDecay(Mother2, mijk, 11111, masses[masses.size() - 1], pdgs[pdgs.size() - 1]);
155 ret.push_back(ret1[1]);
156 masses.resize(masses.size() - 1);
157 pdgs.resize(pdgs.size() - 1);
159 for (
size_t i = 0; i < ret1.size(); ++i)
160 ret.push_back(ret1[i]);
162 for (
size_t i = 0; i < ret.size(); ++i) {
163 ret[i].MotherPDGID = Mother.
PDGID;
164 ret[i].epoch = Mother.
epoch + 1;
168 for (
int i = 0; i < ret.size(); ++i)
169 if (ret[i].px != ret[i].px) std::cout <<
"**WARNING** NaN in NBodyDecay procedure output!\n";
177 if (masses.size() != pdgs.size()) {
178 std::cout <<
"**WARNING** ShuffleDecayProducts(): size of masses does not match size of pdgs!\n";
181 int N = masses.size();
182 for (
int i = N - 1; i >= 1; --i) {
184 std::swap(masses[j], masses[i]);
185 std::swap(pdgs[j], pdgs[i]);
int threebodysucc
Used for debugging the succes rate in the rejection sampling of .
double TernaryThreeBodym12Maximum(double M, double m1, double m2, double m3)
Determines the maximum of the probability density function used in a three-body decay.
std::vector< SimpleParticle > TwoBodyDecay(const SimpleParticle &Mother, double m1, long long pdg1, double m2, long long pdg2)
Samples the decay products of a two-body decay.
double GetRandomThreeBodym12(double M, double m1, double m2, double m3, double fm12max)
Sample the invariant mass of the leading two daughter particles in a three-body decay.
Contains some extra mathematical functions used in the code.
MTRand randgenMT
The Mersenne Twister random number generator.
Structure holding information about a single particle in the event generator.
double ThreeBodym12F2(double m12, double M, double m1, double m2, double m3)
Square of the probability density function used in a three-body decay (unnormalized) ...
void ShuffleDecayProducts(std::vector< double > &masses, std::vector< long long > &pdgs)
Shuffles the decay products.
double pz
3-momentum components (in GeV)
int epoch
0 - primary particle, 1 - after decay of primary particles, 2 - after a casacde of two decays and so ...
std::vector< SimpleParticle > ManyBodyDecay(const SimpleParticle &Mother, std::vector< double > masses, std::vector< long long > pdgs)
Samples the decay products of a many-body decay.
SimpleParticle LorentzBoost(const SimpleParticle &part, double vx, double vy, double vz)
Lorentz boost of the 4-momentum of a particle.
The main namespace where all classes and functions of the Thermal-FIST library reside.