Belle II Software  release-05-01-25
CRY.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2015 Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Torben Ferber *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 
11 #include <generators/cry/CRY.h>
12 
13 #include <framework/gearbox/Unit.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/utilities/IOIntercept.h>
16 #include <mdst/dataobjects/MCParticleGraph.h>
17 
18 #include <TDatabasePDG.h>
19 #include <TRandom3.h>
20 
21 #include <VecGeom/volumes/UnplacedBox.h>
22 #include <VecGeom/volumes/UnplacedOrb.h>
23 #include <VecGeom/volumes/UnplacedTube.h>
24 #include <VecGeom/base/LorentzVector.h>
25 
26 #include <string>
27 #include <vector>
28 #include <sstream>
29 
30 namespace Belle2 {
35  void CRY::init()
36  {
37  std::stringstream setupString;
38  setupString << " returnGammas " << m_returnGammas << std::endl;
39  setupString << " returnKaons " << m_returnKaons << std::endl;
40  setupString << " returnPions " << m_returnPions << std::endl;
41  setupString << " returnProtons " << m_returnProtons << std::endl;
42  setupString << " returnNeutrons " << m_returnNeutrons << std::endl;
43  setupString << " returnElectrons " << m_returnElectrons << std::endl;
44  setupString << " returnMuons " << m_returnMuons << std::endl;
45  setupString << " date " << m_date << std::endl;
46  setupString << " latitude " << 36.0 << std::endl;
47  setupString << " altitude " << 0 << std::endl;
48  setupString << " subboxLength " << m_subboxLength << std::endl;
49 
51  initLogCapture.start();
52 
53  // CRY setup
54  m_crySetup.reset(new CRYSetup(setupString.str(), m_cosmicDataDir));
55  // Set the random generator to the setup
56  m_crySetup->setRandomFunction([]()->double { return gRandom->Rndm(); });
57  // Set up the generator
58  m_cryGenerator.reset(new CRYGenerator(m_crySetup.get()));
59 
60  initLogCapture.finish();
61 
62  // set up the acceptance box
63  const auto coords = m_acceptSize.size();
64  if (coords == 1) {
65  m_acceptance.reset(new vecgeom::UnplacedOrb(m_acceptSize[0]));
66  } else if (coords == 2) {
67  m_acceptance.reset(new vecgeom::SUnplacedTube<vecgeom::TubeTypes::NonHollowTube>(0, m_acceptSize[0], m_acceptSize[1], 0, 2 * M_PI));
68  } else if (coords == 3) {
69  m_acceptance.reset(new vecgeom::UnplacedBox(m_acceptSize[0], m_acceptSize[1], m_acceptSize[2]));
70  } else {
71  B2FATAL("Acceptance volume needs to have one, two or three values for sphere, cylinder and box respectively");
72  }
73  const double maxSize = *std::max_element(m_acceptSize.begin(), m_acceptSize.end());
74  if ((2 * maxSize) > (m_subboxLength * Unit::m)) {
75  B2FATAL("Acceptance bigger than world volume" << LogVar("acceptance", 2 * maxSize) << LogVar("subboxLength",
77  }
78  // and the world box
79  m_world.reset(new vecgeom::UnplacedBox(m_subboxLength / 2. * Unit::m, m_subboxLength / 2. * Unit::m,
80  m_subboxLength / 2. * Unit::m));
81  }
82 
83  void CRY::generateEvent(MCParticleGraph& mcGraph)
84  {
85  bool eventInAcceptance = 0;
86  static std::vector<CRYParticle*> ev;
87  const size_t startIndex = mcGraph.size();
88  double productionShift = std::numeric_limits<double>::infinity();
89 
90  //force at least particle in acceptance box
91  for (int iTrial = 0; iTrial < m_maxTrials; ++iTrial) {
92  m_totalTrials++;
93  // Generate one event
94  ev.clear();
95  m_cryGenerator->genEvent(&ev);
96  // check all particles
97  for (auto* p : ev) {
98  const int pdg = p->PDGid();
99  const double kineticEnergy = p->ke() * Unit::MeV;
100  if (kineticEnergy < m_kineticEnergyThreshold) continue;
101 
102  const double mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
103  const double etot = kineticEnergy + mass;
104  // since etot is at least mass this cannot be negative
105  const double ptot = sqrt(etot * etot - mass * mass);
106 
107  // Momentum
108  // We have x horizontal, y up and z along the beam. So uvw -> zxy, xc yc zc -> zxy
109  const double px = ptot * p->v();
110  const double py = ptot * p->w();
111  const double pz = ptot * p->u();
112  // Vertex
113  const double vx = p->y() * Unit::m;
114  const double vy = p->z() * Unit::m;
115  const double vz = p->x() * Unit::m;
116  // Time
117  double time = p->t() * Unit::s;
118 
119  vecgeom::Vector3D<double> pos(vx, vy, vz);
120  vecgeom::LorentzVector<double> mom(px, py, pz, etot);
121  const double speed = (mass == 0 ? 1 : mom.Beta()) * Const::speedOfLight;
122 
123  // Project on the boundary of the world box
124  auto inside = m_world->Inside(pos);
125  if (inside == vecgeom::kInside) {
126  // inside the world volume, go backwards in time to the world box
127  const auto dir = -mom.vect().Unit();
128  double dist = m_world->DistanceToOut(pos, dir);
129  pos += dist * dir;
130  time -= dist / speed;
131  } else if (inside == vecgeom::kOutside) {
132  // outside the world volume, go forwards in time to the world box
133  // this should not happen but better safe then sorry ...
134  const auto dir = mom.vect().Unit();
135  double dist = m_world->DistanceToIn(pos, dir);
136  if (dist == vecgeom::InfinityLength<double>()) continue;
137  pos += dist * dir;
138  time += dist / speed;
139  }
140  // Intersect with the acceptance box
141  double dist = m_acceptance->DistanceToIn(pos, mom.vect().Unit());
142  if (dist == vecgeom::InfinityLength<double>()) continue;
143 
144  // We want to keep this one
145  auto& particle = mcGraph.addParticle();
146  // all particle of a generator are primary
147  particle.addStatus(MCParticle::c_PrimaryParticle);
148  // all particle of CRY are stable
149  particle.addStatus(MCParticle::c_StableInGenerator);
150  particle.setPDG(pdg);
151  particle.setFirstDaughter(0);
152  particle.setLastDaughter(0);
153  particle.setMomentum(TVector3(mom.x(), mom.y(), mom.z()));
154  particle.setMass(mass);
155  particle.setEnergy(mom.e());
156  particle.setProductionVertex(TVector3(pos.x(), pos.y(), pos.z()));
157  particle.setProductionTime(time);
158  eventInAcceptance = true;
159 
160  // calculate shift in time necessary to be at y=0 for t=0
161  const vecgeom::Vector3D<double> normalVector(0., 1., 0.); // normal to the global generation plane
162  const vecgeom::Vector3D<double> origin(0, 0, 0);
163  const double distance = ((origin - pos) * normalVector) / (mom.vect().Unit() * normalVector);
164  // and check which is the shift needed to have the first particle at t=0&y=0
165  productionShift = std::min(time - (distance / speed), productionShift);
166  }
167  // clean up CRY event
168  for (auto* p : ev) delete p;
169 
170  // and if we have something in the acceptance then we're done
171  if (eventInAcceptance) {
172  // just shift the times to have the first particle hit y=0 at t=0 (modulo magnetic field)
173  for (size_t i = startIndex; i < mcGraph.size(); ++i) {
174  mcGraph[i].setProductionTime(mcGraph[i].getProductionTime() - productionShift + m_timeOffset);
175  }
176  //everything else is done
177  return;
178  }
179  }
180  B2ERROR("Number of trials exceeds maxTrials increase number of maxTrials" << LogVar("maxTrials", m_maxTrials));
181  }
182 
183  void CRY::term()
184  {
185  B2RESULT("Total time simulated: " << m_cryGenerator->timeSimulated() << " seconds");
186  B2RESULT("Total number of events simulated: " << m_totalTrials);
187  }
188 
189 
191 }
Belle2::CRY::m_returnProtons
bool m_returnProtons
Whether or not CRY should return protons.
Definition: CRY.h:162
Belle2::Unit::s
static const double s
[second]
Definition: Unit.h:105
Belle2::CRY::m_cryGenerator
std::unique_ptr< CRYGenerator > m_cryGenerator
The CRY generator.
Definition: CRY.h:168
Belle2::CRY::m_acceptance
std::unique_ptr< vecgeom::VUnplacedVolume > m_acceptance
acceptance shape
Definition: CRY.h:170
Belle2::CRY::m_returnElectrons
bool m_returnElectrons
Whether or not CRY should return electrons.
Definition: CRY.h:164
Belle2::CRY::m_timeOffset
double m_timeOffset
time offset in nanoseconds.
Definition: CRY.h:154
Belle2::CRY::m_returnKaons
bool m_returnKaons
Whether or not CRY should return kaons.
Definition: CRY.h:160
Belle2::CRY::m_date
std::string m_date
date used for generation (month-day-year).
Definition: CRY.h:156
Belle2::CRY::generateEvent
void generateEvent(MCParticleGraph &mcGraph)
Generates one single event.
Definition: CRY.cc:91
Belle2::Unit::MeV
static const double MeV
[megaelectronvolt]
Definition: Unit.h:124
Belle2::Const::speedOfLight
static const double speedOfLight
[cm/ns]
Definition: Const.h:568
Belle2::CRY::m_cosmicDataDir
std::string m_cosmicDataDir
directory that holds cosmic data files.
Definition: CRY.h:151
Belle2::CRY::m_maxTrials
int m_maxTrials
number of trials per event.
Definition: CRY.h:157
Belle2::CRY::term
void term()
Terminates the generator.
Definition: CRY.cc:191
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::CRY::m_acceptSize
std::vector< double > m_acceptSize
Shape parameters for the acceptance shape.
Definition: CRY.h:153
Belle2::CRY::init
void init()
Initializes the generator.
Definition: CRY.cc:43
Belle2::CRY::m_world
std::unique_ptr< vecgeom::VUnplacedVolume > m_world
world box shape
Definition: CRY.h:169
Belle2::CRY::m_crySetup
std::unique_ptr< CRYSetup > m_crySetup
The CRY generator setup.
Definition: CRY.h:167
Belle2::CRY::m_totalTrials
int m_totalTrials
total number of thrown events.
Definition: CRY.h:158
LogVar
Class to store variables with their name which were sent to the logging service.
Definition: LogVariableStream.h:24
Belle2::Unit::m
static const double m
[meters]
Definition: Unit.h:79
Belle2::CRY::m_returnPions
bool m_returnPions
Whether or not CRY should return pions.
Definition: CRY.h:161
Belle2::CRY::m_kineticEnergyThreshold
double m_kineticEnergyThreshold
kinetic energy threshold.
Definition: CRY.h:155
Belle2::MCParticle::c_StableInGenerator
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
Definition: MCParticle.h:60
Belle2::CRY::m_returnMuons
bool m_returnMuons
Whether or not CRY should return muons.
Definition: CRY.h:165
Belle2::IOIntercept::OutputToLogMessages
Capture stdout and stderr and convert into log messages.
Definition: IOIntercept.h:236
Belle2::LogConfig::c_Debug
@ c_Debug
Debug: for code development.
Definition: LogConfig.h:36
Belle2::LogConfig::c_Warning
@ c_Warning
Warning: for potential problems that the user should pay attention to.
Definition: LogConfig.h:39
Belle2::CRY::m_subboxLength
int m_subboxLength
length of the square n-n plane in Cry in meters
Definition: CRY.h:152
Belle2::CRY::m_returnNeutrons
bool m_returnNeutrons
Whether or not CRY should return neutrons.
Definition: CRY.h:163
Belle2::CRY::m_returnGammas
bool m_returnGammas
Whether or not CRY should return gammas.
Definition: CRY.h:159
Belle2::MCParticle::c_PrimaryParticle
@ c_PrimaryParticle
bit 0: Particle is primary particle.
Definition: MCParticle.h:58