5 #include <utl/config.h>
7 #include <det/Detector.h>
9 #include <sdet/SDetector.h>
10 #include <sdet/Station.h>
12 #include <evt/Event.h>
14 #include <fwk/CentralConfig.h>
15 #include <fwk/RandomEngineRegistry.h>
16 #include <io/CorsikaUtilities.h>
18 #include <sevt/SEvent.h>
19 #include <sevt/Header.h>
20 #include <sevt/Station.h>
21 #include <sevt/StationSimData.h>
23 #include <mevt/MEvent.h>
24 #include <mevt/Header.h>
26 #include <utl/AugerCoordinateSystem.h>
27 #include <utl/AugerUnits.h>
29 #include <utl/MathConstants.h>
30 #include <utl/Particle.h>
31 #include <utl/NucleusProperties.h>
32 #include <utl/PhysicalConstants.h>
33 #include <utl/Point.h>
34 #include <utl/TimeStamp.h>
35 #include <utl/ErrorLogger.h>
36 #include <utl/RandomEngine.h>
37 #include <utl/Reader.h>
38 #include <utl/Vector.h>
39 #include <utl/TabulatedFunction.h>
40 #include <utl/RandomSamplerFromPDF.h>
41 #include <utl/Plane.h>
43 #include <utl/GeometryUtilities.h>
44 #include <utl/String.h>
45 #include <utl/StringCompare.h>
48 #include <CLHEP/Random/Randomize.h>
60 using CLHEP::RandFlat;
63 namespace ParticleInjectorNEU {
68 ParticleInjector::ParticleInjector() :
80 config <<
" Will create SEvent with time" <<
fEventTime <<
'\n';
82 config <<
" Will not create SEvent\n";
84 config <<
" Injecting in station with id = " <<
fSingleTankID <<
'\n';
86 config <<
" Injecting in all available stations\n";
88 config <<
" number of particles " <<
fParticles.size() <<
'\n';
91 config <<
" position (" <<
fX <<
", " <<
fY <<
", " <<
fZ <<
")";
93 config <<
" Position will be set randomly over a sphere";
95 config <<
" Position will be set randomly over a disk";
97 config <<
" Position will be set randomly with selected PDF";
106 auto topB = CentralConfig::GetInstance()->GetTopBranch(
"ParticleInjector");
108 auto eventTimeB = topB.GetChild(
"EventTime");
116 auto stationIdB = topB.GetChild(
"StationId");
124 auto timeB = topB.GetChild(
"Time");
126 auto discreteB = timeB.GetChild(
"Fixed");
135 auto numberOfParticlesB = topB.GetChild(
"NumberOfParticles");
137 const auto numbers = numberOfParticlesB.GetChild(
"Number").Get<vector<int>>();
138 const auto types = numberOfParticlesB.GetChild(
"Type").Get<vector<int>>();
139 for (
unsigned int i = 0, n = types.size(); i < n; ++i)
150 auto positionB = topB.GetChild(
"Position");
151 auto fixedB = positionB.GetChild(
"Fixed");
154 const auto position = fixedB.Get<vector<double>>();
159 auto diskRadiusB = positionB.GetChild(
"DiskRadius");
163 positionB.GetChild(
"DiskHeight").GetData(
fHeight);
165 auto sphereRadiusB = positionB.GetChild(
"SphereRadius");
168 positionB.GetChild(
"SphereRadius").GetData(
fRadius);
179 auto directionB = topB.GetChild(
"Direction");
180 fixedB = directionB.GetChild(
"Fixed");
182 const auto direction = fixedB.Get<vector<double>>();
183 const double r =
sqrt(
Sqr(direction.at(0)) +
Sqr(direction.at(1)) +
Sqr(direction.at(2)));
192 auto energyB = topB.GetChild(
"Energy");
193 fixedB = energyB.GetChild(
"Fixed");
199 INFO(
"Particles and energies must be equal size for <Fixed> option\n");
204 auto muonsB = energyB.GetChild(
"Muons");
208 auto electronsB = energyB.GetChild(
"Electrons");
212 auto gammasB = energyB.GetChild(
"Gammas");
216 topB.GetChild(
"PropagateToTank").GetData(
fPropagate);
219 auto randomParticlesB = topB.GetChild(
"RandomParticles");
220 if (randomParticlesB) {
221 const auto filename = randomParticlesB.GetChild(
"FileName").Get<
string>();
226 err <<
"The file " <<
filename <<
" contains 0 entries!";
231 const auto randomEntries = randomParticlesB.GetChild(
"RandomEntries").Get<
string>();
233 randomParticlesB.GetChild(
"MinMomentum").GetData(
fMinMomentum);
241 if (topB.GetChild(
"DumpConfiguration"))
251 auto& header =
event.GetHeader();
256 event.GetSEvent().GetHeader().SetTime(
fEventTime);
257 det::Detector::GetInstance().Update(
fEventTime);
262 event.GetMEvent().GetHeader().SetTime(
fEventTime);
263 det::Detector::GetInstance().Update(
fEventTime);
266 auto& sEvent =
event.GetSEvent();
281 for (
auto& station : sEvent.StationsRange())
324 static unsigned int totalSimulatedParticles = 0;
326 const auto& detStation = det::Detector::GetInstance().GetSDetector().GetStation(station);
327 const auto& stationCS = detStation.GetLocalCoordinateSystem();
330 for (
int i = 0; i < nParticles; ++i) {
335 const Point position(x, y, z, stationCS);
339 position,
Vector(0,0,0, stationCS, Vector::kCartesian), time, 1);
343 const int maxTrials = 100;
344 for (
unsigned int trialNumber = 0; trialNumber < maxTrials; ++trialNumber) {
356 stationCS, Vector::kCartesian);
370 const Vector direction(1, zenith, azimuth, stationCS, Vector::kSpherical);
376 position, direction, time, 1, energy);
378 particle = stdParticle;
383 !detStation.IsInsideStation(particle.
GetPosition())) {
397 ++totalSimulatedParticles;
401 info <<
"Injected " << nParticles <<
" particle" <<
String::Plural(nParticles) <<
", "
402 "simulated " << totalSimulatedParticles <<
" particle" <<
String::Plural(totalSimulatedParticles);
439 switch (particleType) {
456 msg <<
"Energy for particle type " << particleType <<
" was not provided. "
457 "Injection in ParticleInjector. Shooting default spectrum";
486 const double theta = acos(RandFlat::shoot(&
fRandomEngine, 0, 1));
488 const double radiusSinTheta =
fRadius * sin(theta);
489 x = radiusSinTheta * cos(phi);
490 y = radiusSinTheta * sin(phi);
497 x = radius * cos(phi);
498 y = radius * sin(phi);
514 auto discreteB = branch.
GetChild(
"Discrete");
517 const auto xx = discreteB.
GetChild(
"x").
Get<vector<double>>();
518 const auto weights = discreteB.GetChild(
"y").Get<vector<double>>();
521 RandomSamplerFromPDF::eDiscrete);
528 const auto formula = pdfB.
Get<
string>();
529 const double min = branch.
GetChild(
"Min").
Get<
double>();
537 const auto fluxes = branch.
GetChild(
"Y").
Get<vector<double>>();
538 const auto xx = branch.
GetChild(
"X").
Get<vector<double>>();
540 RandomSamplerFromPDF::eLinear);
543 ERROR(
"Unkown format of the distribution!");
utl::TimeStamp fEventTime
constexpr T Sqr(const T &x)
Report success to RunController.
void MakeSimData()
Make station simulated data object.
void SetPosition(const utl::Point &position)
std::vector< double > fFixedEnergy
unsigned int fMinMomentum
Describes a particle for Simulation.
PositionFlag fPositionFlag
Class to hold collection (x,y) points and provide interpolation between them.
std::vector< utl::Particle::Type > fParticles
utl::VRandomSampler * fDefaultEnergyDistribution
utl::VRandomSampler * fZDistribution
std::vector< double > fDiscreteParticleTime
#define INFO(message)
Macro for logging informational messages.
void InjectParticles(sevt::Station &station)
fwk::VModule::ResultFlag Run(evt::Event &theEvent)
Run: invoked once per event.
Branch GetChild(const std::string &childName) const
Get child of this Branch by child name.
double shoot(HepEngine &engine) const
Method to shoot random values using a given engine by-passing the static generator.
utl::VRandomSampler * fMuonEnergyDistribution
bool StringEquivalent(const std::string &a, const std::string &b, Predicate p)
Utility to compare strings for equivalence. It takes a predicate to determine the equivalence of indi...
utl::VRandomSampler * fGammaEnergyDistribution
unsigned int fNumberOfEntries
std::vector< double > fDiscreteAzimuth
void GeneratePosition(double &x, double &y, double &z)
utl::VRandomSampler * fXDistribution
const char * Plural(const T n)
utl::VRandomSampler * fYDistribution
Class representing a document branch.
class to hold data at Station level
RandomPart fRandomParticle
bool HasSimData() const
Check whether station simulated data exists.
utl::VRandomSampler * LoadRandomSampler(const utl::Branch &branch)
fwk::VModule::ResultFlag Init()
Initialize: invoked at beginning of run (NOT beginning of event)
utl::VRandomSampler * fZenithDistribution
unsigned int fSingleTankID
void AddParticle(const utl::Particle &particle)
double GenerateEnergy(const utl::Particle::Type particle, const int i)
std::vector< double > fDiscreteZenith
A TimeInterval is used to represent time elapsed between two events.
ResultFlag
Flag returned by module methods to the RunController.
utl::VRandomSampler * fElectronEnergyDistribution
fwk::VModule::ResultFlag Finish()
Finish: invoked at end of the run (NOT end of the event)
Collection of pre-defined random engines.
int CorsikaToPDG(const int corsikaCode)
converters from CORSIKA to PDG particle codes
struct particle_info particle[80]
constexpr double kilometer
const Point & GetPosition() const
Position of the particle.
Report failure to RunController, causing RunController to terminate execution.
utl::CoordinateSystemPtr Get(const std::string &id)
Get a well-known Coordinate System.
void ParticleInjectorConfiguration()
utl::RandomEngine::RandomEngineType & fRandomEngine
#define ERROR(message)
Macro for logging error messages.
const Vector & GetDirection() const
Unit vector giving particle direction.
Class to shoot random numbers given by a user-defined distribution function.
utl::VRandomSampler * fAzimuthDistribution
static bool IsNucleus(const int type)
Check if type code is a valid nucleus.