11 #include <generators/cry/CRY.h>
13 #include <framework/gearbox/Unit.h>
14 #include <framework/logging/Logger.h>
15 #include <framework/utilities/IOIntercept.h>
16 #include <mdst/dataobjects/MCParticleGraph.h>
18 #include <TDatabasePDG.h>
21 #include <VecGeom/volumes/UnplacedBox.h>
22 #include <VecGeom/volumes/UnplacedOrb.h>
23 #include <VecGeom/volumes/UnplacedTube.h>
24 #include <VecGeom/base/LorentzVector.h>
37 std::stringstream setupString;
45 setupString <<
" date " <<
m_date << std::endl;
46 setupString <<
" latitude " << 36.0 << std::endl;
47 setupString <<
" altitude " << 0 << std::endl;
51 initLogCapture.start();
56 m_crySetup->setRandomFunction([]()->
double {
return gRandom->Rndm(); });
60 initLogCapture.finish();
66 }
else if (coords == 2) {
68 }
else if (coords == 3) {
71 B2FATAL(
"Acceptance volume needs to have one, two or three values for sphere, cylinder and box respectively");
75 B2FATAL(
"Acceptance bigger than world volume" <<
LogVar(
"acceptance", 2 * maxSize) <<
LogVar(
"subboxLength",
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();
98 const int pdg = p->PDGid();
99 const double kineticEnergy = p->ke() *
Unit::MeV;
102 const double mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
103 const double etot = kineticEnergy + mass;
105 const double ptot = sqrt(etot * etot - mass * mass);
109 const double px = ptot * p->v();
110 const double py = ptot * p->w();
111 const double pz = ptot * p->u();
113 const double vx = p->y() *
Unit::m;
114 const double vy = p->z() *
Unit::m;
115 const double vz = p->x() *
Unit::m;
117 double time = p->t() *
Unit::s;
119 vecgeom::Vector3D<double> pos(vx, vy, vz);
120 vecgeom::LorentzVector<double> mom(px, py, pz, etot);
124 auto inside =
m_world->Inside(pos);
125 if (inside == vecgeom::kInside) {
127 const auto dir = -mom.vect().Unit();
128 double dist =
m_world->DistanceToOut(pos, dir);
130 time -= dist / speed;
131 }
else if (inside == vecgeom::kOutside) {
134 const auto dir = mom.vect().Unit();
135 double dist =
m_world->DistanceToIn(pos, dir);
136 if (dist == vecgeom::InfinityLength<double>())
continue;
138 time += dist / speed;
141 double dist =
m_acceptance->DistanceToIn(pos, mom.vect().Unit());
142 if (dist == vecgeom::InfinityLength<double>())
continue;
145 auto& particle = mcGraph.addParticle();
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;
161 const vecgeom::Vector3D<double> normalVector(0., 1., 0.);
162 const vecgeom::Vector3D<double> origin(0, 0, 0);
163 const double distance = ((origin - pos) * normalVector) / (mom.vect().Unit() * normalVector);
165 productionShift = std::min(time - (distance / speed), productionShift);
168 for (
auto* p : ev)
delete p;
171 if (eventInAcceptance) {
173 for (
size_t i = startIndex; i < mcGraph.size(); ++i) {
174 mcGraph[i].setProductionTime(mcGraph[i].getProductionTime() - productionShift +
m_timeOffset);
180 B2ERROR(
"Number of trials exceeds maxTrials increase number of maxTrials" <<
LogVar(
"maxTrials",
m_maxTrials));
185 B2RESULT(
"Total time simulated: " <<
m_cryGenerator->timeSimulated() <<
" seconds");
186 B2RESULT(
"Total number of events simulated: " <<
m_totalTrials);