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 <TDatabasePDG.h>
19#include <VecGeom/volumes/UnplacedBox.h>
20#include <VecGeom/volumes/UnplacedOrb.h>
21#include <VecGeom/volumes/UnplacedTube.h>
22#include <VecGeom/base/LorentzVector.h>
23#include <geometry/GeometryManager.h>
24#include "G4VPhysicalVolume.hh"
25#include "G4LogicalVolume.hh"
39 std::stringstream setupString;
47 setupString <<
" date " <<
m_date << std::endl;
48 setupString <<
" latitude " << 36.0 << std::endl;
49 setupString <<
" altitude " << 0 << std::endl;
53 initLogCapture.
start();
58 m_crySetup->setRandomFunction([]()->
double {
return gRandom->Rndm(); });
68 }
else if (coords == 2) {
70 }
else if (coords == 3) {
73 B2FATAL(
"Acceptance volume needs to have one, two or three values for sphere, cylinder and box respectively");
78 B2FATAL(
"No geometry found -> Add the Geometry module to the path before the CRY module.");
80 G4Box* topbox = (G4Box*) volume->GetLogicalVolume()->GetSolid();
82 B2FATAL(
"No G4Box found -> Check the logical volume of the geometry.");
94 B2INFO(
"World size [" << halfLength_x /
Unit::cm <<
", " << halfLength_x /
Unit::cm <<
", " << halfLength_x /
Unit::cm <<
"]");
97 const double minWorld = std::min({halfLength_x, halfLength_y, halfLength_z, });
98 if (maxSize > (minWorld /
Unit::cm)) {
99 B2FATAL(
"Acceptance bigger than world volume " <<
LogVar(
"acceptance", maxSize)
107 bool eventInAcceptance = 0;
108 static std::vector<CRYParticle*> ev;
111 for (
int iTrial = 0; iTrial <
m_maxTrials; ++iTrial) {
118 const int pdg = p->PDGid();
119 const double kineticEnergy = p->ke() *
Unit::MeV;
122 const double mass = TDatabasePDG::Instance()->GetParticle(pdg)->Mass();
123 const double etot = kineticEnergy + mass;
125 const double ptot =
sqrt(etot * etot - mass * mass);
129 const double px = ptot * p->v();
130 const double py = ptot * p->w();
131 const double pz = ptot * p->u();
133 const double vx = p->y() *
Unit::m;
134 const double vy = p->z() *
Unit::m;
135 const double vz = p->x() *
Unit::m;
148 vecgeom::Vector3D<double> pos(vx, vy, vz);
149 vecgeom::LorentzVector<double> mom(px, py, pz, etot);
153 auto inside =
m_world->Inside(pos);
154 if (inside == vecgeom::kInside) {
156 const auto dir = -mom.vect().Unit();
157 double dist =
m_world->DistanceToOut(pos, dir);
159 time -= dist / speed;
160 }
else if (inside == vecgeom::kOutside) {
163 const auto dir = mom.vect().Unit();
164 double dist =
m_world->DistanceToIn(pos, dir);
165 if (dist == vecgeom::InfinityLength<double>())
continue;
167 time += dist / speed;
170 double dist =
m_acceptance->DistanceToIn(pos, mom.vect().Unit());
171 if (dist == vecgeom::InfinityLength<double>())
continue;
179 particle.setPDG(pdg);
180 particle.setFirstDaughter(0);
181 particle.setLastDaughter(0);
182 particle.setMomentum(ROOT::Math::XYZVector(mom.x(), mom.y(), mom.z()));
183 particle.setMass(mass);
184 particle.setEnergy(mom.e());
185 particle.setProductionVertex(ROOT::Math::XYZVector(pos.x(), pos.y(), pos.z()));
186 particle.setProductionTime(time);
187 eventInAcceptance =
true;
190 for (
auto* p : ev)
delete p;
192 if (eventInAcceptance) {
197 B2ERROR(
"Number of trials exceeds maxTrials increase number of maxTrials" <<
LogVar(
"maxTrials",
m_maxTrials));
202 B2RESULT(
"Total time simulated: " <<
m_cryGenerator->timeSimulated() <<
" seconds");
203 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.