ComPWA
Common Partial-Wave-Analysis Framework
RootGenerator.cpp
Go to the documentation of this file.
1 // Copyright (c) 2015, 2017 The ComPWA Team.
2 // This file is part of the ComPWA framework, check
3 // https://github.com/ComPWA/ComPWA/license.txt for details.
4 
6 
7 #include "Core/Event.hpp"
8 #include "Core/Logging.hpp"
9 #include "Core/Properties.hpp"
10 #include "Core/Random.hpp"
12 
13 namespace ComPWA {
14 namespace Data {
15 namespace Root {
16 
18  : RandomGenerator(seed), Seed(seed) {}
19 
21 
22 int RootUniformRealGenerator::getSeed() const { return Seed; }
23 
25  Seed = seed;
26  RandomGenerator.SetSeed(seed);
27 }
28 
30  const std::vector<double> &FinalStateMasses_,
31  const std::vector<ComPWA::pid> &FinalStatePIDs_)
32  : CMSP4(CMSP4_), FinalStateMasses(FinalStateMasses_),
33  FinalStatePIDs(FinalStatePIDs_), CMSBoostVector(0.0, 0.0, 0.0) {
34  unsigned int nPart = FinalStateMasses.size();
35  if (nPart < 2)
36  throw std::runtime_error(
37  "RootGenerator::RootGenerator() | one particle is not enough!");
38  if (nPart == 2)
39  LOG(INFO)
40  << "RootGenerator::RootGenerator() | only 2 particles in the final"
41  " state! There are no degrees of freedom!";
42 
43  init();
44 }
45 
47  std::vector<pid> InitialS, std::vector<pid> FinalS)
48  : RootGenerator(
49  [&]() {
50  if (InitialS.size() != 1)
51  throw std::runtime_error(
52  "RootGenerator::RootGenerator() | More than one "
53  "particle in initial State! You need to specify a cms "
54  "four-momentum");
55  return ComPWA::FourMomentum(
56  0.0, 0.0, 0.0,
57  findParticle(PartL, InitialS.at(0)).getMass().Value);
58  }(),
59  [&]() {
60  std::vector<double> fsm;
61  for (auto ParticlePid : FinalS) { // particle 0 is mother particle
62  fsm.push_back(findParticle(PartL, ParticlePid).getMass().Value);
63  }
64  return fsm;
65  }(),
66  FinalS) {}
67 
70  : RootGenerator(KinematicsInfo.getInitialStateFourMomentum(),
71  KinematicsInfo.getFinalStateMasses(),
72  KinematicsInfo.getFinalStatePIDs()) {}
73 
76  for (double fsmass : FinalStateMasses) {
77  CMSEnergyMinusMasses -= fsmass;
78  }
79 
80  if (CMSEnergyMinusMasses <= 0)
81  throw std::runtime_error(
82  "RootGenerator::init(): not enough energy for this decay");
83 
84  //
85  //------> the max weight depends on opt:
86  // opt == "Fermi" --> fermi energy dependence for cross section
87  // else --> constant cross section as function of TECM (default)
88  //
89  /*if (strcasecmp(opt, "fermi") == 0) {
90  // ffq[] = pi * (2*pi)**(FNt-2) / (FNt-2)!
91  Double_t ffq[] = {0, 3.141592, 19.73921, 62.01255, 129.8788,
92  204.0131, 256.3704, 268.4705, 240.9780, 189.2637,
93  132.1308, 83.0202, 47.4210, 24.8295, 12.0006,
94  5.3858, 2.2560, 0.8859};
95  fWtMax = TMath::Power(fTeCmTm, fNt - 2) * ffq[fNt - 1] / P.Mag();
96 
97  } else {*/
98  double emmax = CMSEnergyMinusMasses + FinalStateMasses[0];
99  double emmin = 0.0;
100  double wtmax = 1.0;
101  for (unsigned int n = 1; n < FinalStateMasses.size(); ++n) {
102  emmin += FinalStateMasses[n - 1];
103  emmax += FinalStateMasses[n];
104  wtmax *= PDK(emmax, emmin, FinalStateMasses[n]);
105  }
106  MaximumWeight = 1.0 / wtmax;
107 
108  TLorentzVector W(CMSP4.px(), CMSP4.py(), CMSP4.pz(), CMSP4.e());
109  if (W.Beta()) {
110  double w = W.Beta() / W.Rho();
111  CMSBoostVector.SetXYZ(W(0) * w, W(1) * w, W(2) * w);
112  }
113 }
114 
116 RootGenerator::generate(unsigned int NumberOfEvents,
117  UniformRealNumberGenerator &RandomGenerator) const {
118  EventCollection GeneratedPhsp{FinalStatePIDs};
119 
120  for (unsigned int iEvent = 0; iEvent < NumberOfEvents; ++iEvent) {
121 
122  size_t NumberOfFinalStateParticles(FinalStateMasses.size());
123  std::vector<double> OrderedRandomNumbers;
124  OrderedRandomNumbers.reserve(NumberOfFinalStateParticles);
125  OrderedRandomNumbers.push_back(0.0);
126 
127  if (NumberOfFinalStateParticles > 2) {
128  for (unsigned int n = 1; n < NumberOfFinalStateParticles - 1; ++n)
129  OrderedRandomNumbers.push_back(RandomGenerator()); // N-2 random numbers
130  std::sort(OrderedRandomNumbers.begin(), OrderedRandomNumbers.end());
131  }
132  OrderedRandomNumbers.push_back(1.0);
133 
134  double invMas[NumberOfFinalStateParticles], sum = 0.0;
135  for (unsigned int n = 0; n < NumberOfFinalStateParticles; ++n) {
136  sum += FinalStateMasses[n];
137  invMas[n] = OrderedRandomNumbers[n] * CMSEnergyMinusMasses + sum;
138  }
139 
140  // compute the weight of the current event
141  double weight = MaximumWeight;
142  double pd[NumberOfFinalStateParticles];
143  for (unsigned int n = 0; n < NumberOfFinalStateParticles - 1; ++n) {
144  pd[n] = PDK(invMas[n + 1], invMas[n], FinalStateMasses[n + 1]);
145  weight *= pd[n];
146  }
147 
148  std::vector<TLorentzVector> FinalStateLorentzVectors(
149  FinalStateMasses.size());
150 
151  // complete specification of event (Raubold-Lynch method)
152  FinalStateLorentzVectors[0].SetPxPyPzE(
153  0.0, pd[0], 0.0,
154  std::sqrt(std::pow(pd[0], 2) + std::pow(FinalStateMasses[0], 2)));
155 
156  unsigned int i(1);
157  while (true) {
158  FinalStateLorentzVectors[i].SetPxPyPzE(
159  0.0, -pd[i - 1], 0.0,
160  std::sqrt(std::pow(pd[i - 1], 2) + std::pow(FinalStateMasses[i], 2)));
161 
162  double cZ = 2.0 * RandomGenerator() - 1.0;
163  double sZ = std::sqrt(1.0 - std::pow(cZ, 2));
164  double angY = 2.0 * TMath::Pi() * RandomGenerator();
165  double cY = std::cos(angY);
166  double sY = std::sin(angY);
167  for (unsigned int j = 0; j <= i; ++j) {
168  TLorentzVector &v(FinalStateLorentzVectors[j]);
169  double x = v.Px();
170  double y = v.Py();
171  double z = v.Pz();
172  // rotation around Z and Y
173  v.SetPx(cY * (cZ * x - sZ * y) - sY * z);
174  v.SetPy(sZ * x + cZ * y);
175  v.SetPz(sY * (cZ * x - sZ * y) + cY * z);
176  }
177  if (i == NumberOfFinalStateParticles - 1)
178  break;
179  // double beta = 1.0 / std::sqrt(1.0 + std::pow(invMas[i] / pd[i], 2));
180  double beta2 = 1.0 / (1.0 + std::pow(invMas[i] / pd[i], 2));
181  for (unsigned int j = 0; j <= i; ++j) {
182  // FinalStateLorentzVectors[j].Boost(0.0, beta, 0.0);
183  BoostAlongY(FinalStateLorentzVectors[j], beta2);
184  }
185  ++i;
186  }
187 
188  std::vector<FourMomentum> FourMomenta;
189  // final boost of all particles
190  for (unsigned int n = 0; n < NumberOfFinalStateParticles; ++n) {
191  FinalStateLorentzVectors[n].Boost(CMSBoostVector);
192  FourMomenta.push_back(FourMomentum(
193  FinalStateLorentzVectors[n].X(), FinalStateLorentzVectors[n].Y(),
194  FinalStateLorentzVectors[n].Z(), FinalStateLorentzVectors[n].E()));
195  }
196  GeneratedPhsp.Events.push_back(ComPWA::Event{FourMomenta, 1.0});
197  }
198  return GeneratedPhsp;
199 }
200 
201 void RootGenerator::BoostAlongY(TLorentzVector &vec,
202  double beta_squared) const {
203  // Boost this Lorentz vector
204  double y(vec.Y());
205  double t(vec.T());
206 
207  double gamma = 1.0 / std::sqrt(1.0 - beta_squared);
208  double betagamma = 1.0 / std::sqrt((1.0 - beta_squared) / beta_squared);
209 
210  vec.SetY(gamma * y + betagamma * t);
211  vec.SetT(gamma * t + betagamma * y);
212 }
213 
214 double RootGenerator::PDK(double a, double b, double c) const {
215  double x = (a - b - c) * (a + b + c) * (a - b + c) * (a + b - c);
216  return std::sqrt(x) / (2.0 * a);
217 }
218 
219 } // namespace Root
220 } // namespace Data
221 } // namespace ComPWA
ComPWA::EventCollection generate(unsigned int NumberOfEvents, UniformRealNumberGenerator &RandomGenerator) const final
ComPWA four momentum class.
double invariantMass() const
cmplx FADDEEVA() w(cmplx z, double relerr)
Definition: Faddeeva.cc:668
double px() const
double py() const
RootGenerator(const ComPWA::FourMomentum &CMSP4_, const std::vector< double > &FinalStateMasses_, const std::vector< ComPWA::pid > &FinalStatePIDs_)
Constructor for a three particle decay with given masses.
void BoostAlongY(TLorentzVector &vec, double beta_squared) const
const ParticleProperties & findParticle(const ParticleList &list, pid Pid)
Definition: Properties.hpp:93
std::set< ParticleProperties > ParticleList
Definition: Properties.hpp:84
double e() const
double PDK(double a, double b, double c) const
These functions are copied from ROOT.
std::vector< ComPWA::pid > FinalStatePIDs
Data structure containing all kinematic information of a physics event.
Definition: Event.hpp:20
std::vector< double > FinalStateMasses
double pz() const