9#include <generators/cry/CRY.h>
11#include <framework/gearbox/Unit.h>
12#include <framework/logging/Logger.h>
13#include <framework/utilities/IOIntercept.h>
14#include <mdst/dataobjects/MCParticleGraph.h>
16#include <Math/Vector3D.h>
17#include <Math/Vector4D.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 <geometry/GeometryManager.h>
25#include "G4VPhysicalVolume.hh"
26#include "G4LogicalVolume.hh"
40 std::stringstream setupString;
48 setupString <<
" date " <<
m_date << std::endl;
49 setupString <<
" latitude " << 36.0 << std::endl;
50 setupString <<
" altitude " << 0 << std::endl;
54 initLogCapture.
start();
59 m_crySetup->setRandomFunction([]()->
double {
return gRandom->Rndm(); });
69 }
else if (coords == 2) {
71 }
else if (coords == 3) {
74 B2FATAL(
"Acceptance volume needs to have one, two or three values for sphere, cylinder and box respectively");
79 B2FATAL(
"No geometry found -> Add the Geometry module to the path before the CRY module.");
81 G4Box* topbox = (G4Box*) volume->GetLogicalVolume()->GetSolid();
83 B2FATAL(
"No G4Box found -> Check the logical volume of the geometry.");
95 B2INFO(
"World size [" << halfLength_x /
Unit::cm <<
", " << halfLength_x /
Unit::cm <<
", " << halfLength_x /
Unit::cm <<
"]");
98 const double minWorld = std::min({halfLength_x, halfLength_y, halfLength_z, });
99 if (maxSize > (minWorld /
Unit::cm)) {
100 B2FATAL(
"Acceptance bigger than world volume " <<
LogVar(
"acceptance", maxSize)
108 bool eventInAcceptance = 0;
109 static std::vector<CRYParticle*> ev;
112 for (
int iTrial = 0; iTrial <
m_maxTrials; ++iTrial) {
119 const int pdg = p->PDGid();
120 const double kineticEnergy = p->ke() *
Unit::MeV;
123 const double mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
124 const double etot = kineticEnergy + mass;
126 const double ptot =
sqrt(etot * etot - mass * mass);
130 const double px = ptot * p->v();
131 const double py = ptot * p->w();
132 const double pz = ptot * p->u();
134 const double vx = p->y() *
Unit::m;
135 const double vy = p->z() *
Unit::m;
136 const double vz = p->x() *
Unit::m;
149 vecgeom::Vector3D<double> pos(vx, vy, vz);
150 const ROOT::Math::PxPyPzEVector mom(px, py, pz, etot);
151 const ROOT::Math::XYZVector momVec(mom.Px(), mom.Py(), mom.Pz());
152 const auto momDir = momVec.Unit();
156 auto inside =
m_world->Inside(pos);
157 if (inside == vecgeom::kInside) {
159 const vecgeom::Vector3D<double> dir(-momDir.X(), -momDir.Y(), -momDir.Z());
160 double dist =
m_world->DistanceToOut(pos, dir);
162 time -= dist / speed;
163 }
else if (inside == vecgeom::kOutside) {
166 const vecgeom::Vector3D<double> dir(momDir.X(), momDir.Y(), momDir.Z());
167 double dist =
m_world->DistanceToIn(pos, dir);
168 if (dist == vecgeom::InfinityLength<double>())
continue;
170 time += dist / speed;
173 const vecgeom::Vector3D<double> dir(momDir.X(), momDir.Y(), momDir.Z());
175 if (dist == vecgeom::InfinityLength<double>())
continue;
183 particle.setPDG(pdg);
184 particle.setFirstDaughter(0);
185 particle.setLastDaughter(0);
186 particle.setMomentum(momVec);
187 particle.setMass(mass);
188 particle.setEnergy(mom.E());
189 particle.setProductionVertex(ROOT::Math::XYZVector(pos.x(), pos.y(), pos.z()));
190 particle.setProductionTime(time);
191 eventInAcceptance =
true;
194 for (
auto* p : ev)
delete p;
196 if (eventInAcceptance) {
201 B2ERROR(
"Number of trials exceeds maxTrials increase number of maxTrials" <<
LogVar(
"maxTrials",
m_maxTrials));
206 B2RESULT(
"Total time simulated: " <<
m_cryGenerator->timeSimulated() <<
" seconds");
207 B2RESULT(
"Total number of events simulated: " <<
m_totalTrials);
bool m_returnElectrons
Whether or not CRY should return electrons.
std::string m_cosmicDataDir
directory that holds cosmic data files.
std::unique_ptr< vecgeom::VUnplacedVolume > m_acceptance
acceptance shape
bool m_returnKaons
Whether or not CRY should return kaons.
bool m_returnMuons
Whether or not CRY should return muons.
int m_subboxLength
length of the square n-n plane in Cry in meters
bool m_returnGammas
Whether or not CRY should return gammas.
std::vector< double > m_acceptSize
Shape parameters for the acceptance shape.
std::string m_date
date used for generation (month-day-year).
std::unique_ptr< vecgeom::VUnplacedVolume > m_world
world box shape
double m_kineticEnergyThreshold
kinetic energy threshold.
std::unique_ptr< CRYGenerator > m_cryGenerator
The CRY generator.
std::unique_ptr< CRYSetup > m_crySetup
The CRY generator setup.
bool m_returnProtons
Whether or not CRY should return protons.
bool m_returnNeutrons
Whether or not CRY should return neutrons.
int m_totalTrials
total number of thrown events.
bool m_returnPions
Whether or not CRY should return pions.
int m_maxTrials
number of trials per event.
static const double speedOfLight
[cm/ns]
bool start()
Start intercepting the output.
Capture stdout and stderr and convert into log messages.
bool finish()
Finish the capture and emit the message if output has appeard on stdout or stderr.
@ c_Debug
Debug: for code development.
@ c_Warning
Warning: for potential problems that the user should pay attention to.
Class to build, validate and sort a particle decay chain.
@ c_PrimaryParticle
bit 0: Particle is primary particle.
@ c_StableInGenerator
bit 1: Particle is stable, i.e., not decaying in the generator.
static const double mm
[millimeters]
static const double m
[meters]
static const double MeV
[megaelectronvolt]
static const double cm
Standard units with the value = 1.
G4VPhysicalVolume * getTopVolume()
Return a pointer to the top volume.
static GeometryManager & getInstance()
Return a reference to the instance.
Class to store variables with their name which were sent to the logging service.
void init()
Initializes the generator.
void generateEvent(MCParticleGraph &mcGraph)
Generates one single event.
void term()
Terminates the generator.
double sqrt(double a)
sqrt for double
GraphParticle & addParticle()
Add new particle to the graph.
Abstract base class for different kinds of events.