diff --git a/examples/13.IAXO/Neutrons.rml b/examples/13.IAXO/Neutrons.rml
index 6d83fbb..b2179b6 100644
--- a/examples/13.IAXO/Neutrons.rml
+++ b/examples/13.IAXO/Neutrons.rml
@@ -16,6 +16,7 @@ Author: Luis Obis (lobis@unizar.es)
-->
+
diff --git a/include/Application.h b/include/Application.h
index 0408982..a8b7a44 100644
--- a/include/Application.h
+++ b/include/Application.h
@@ -26,6 +26,8 @@ struct Options {
int nRequestedEntries = 0;
int timeLimitSeconds = 0;
+ int runNumber = -1;
+
// reference to original argc and argv necessary to pass to G4UIExecutive
int argc;
char** argv;
diff --git a/include/PrimaryGeneratorAction.h b/include/PrimaryGeneratorAction.h
index 4888275..a9069cf 100644
--- a/include/PrimaryGeneratorAction.h
+++ b/include/PrimaryGeneratorAction.h
@@ -37,6 +37,7 @@ class PrimaryGeneratorAction : public G4VUserPrimaryGeneratorAction {
SimulationManager* fSimulationManager;
static std::mutex fDistributionFormulaMutex;
+ static std::mutex fPrimaryGenerationMutex;
std::vector fTempParticles;
diff --git a/src/Application.cxx b/src/Application.cxx
index 658b553..6f40343 100644
--- a/src/Application.cxx
+++ b/src/Application.cxx
@@ -244,6 +244,18 @@ Options ProcessCommandLineOptions(int argc, char* const argv[]) {
cerr << "--time option requires one argument." << endl;
exit(1);
}
+ } else if (arg == "--runNumber") {
+ if (i + 1 < argc) { // Make sure we aren't at the end of argv!
+ options.runNumber =
+ stoi(argv[++i]); // Increment 'i' so we don't get the argument as the next argv[i].
+ if (options.runNumber < 0) {
+ cout << "--runNumber option error: runNumber cannot be negative" << endl;
+ exit(1);
+ }
+ } else {
+ cerr << "--runNumber option requires one argument." << endl;
+ exit(1);
+ }
} else {
const string argument = argv[i];
if (argument[0] == '-') {
@@ -347,6 +359,10 @@ void Application::Run(const CommandLineOptions::Options& options) {
run->LoadConfigFromFile(inputRmlClean);
+ if (options.runNumber >= 0) {
+ run->SetRunNumber(options.runNumber);
+ }
+
if (!options.outputFile.empty()) {
run->SetOutputFileName(options.outputFile);
}
@@ -362,7 +378,6 @@ void Application::Run(const CommandLineOptions::Options& options) {
run->AddMetadata(fSimulationManager.GetRestMetadata());
run->AddMetadata(fSimulationManager.GetRestPhysicsLists());
-
run->PrintMetadata();
run->FormOutputFile();
diff --git a/src/DataModel.cxx b/src/DataModel.cxx
index da441ee..2e18db9 100644
--- a/src/DataModel.cxx
+++ b/src/DataModel.cxx
@@ -211,6 +211,29 @@ void TRestGeant4Hits::InsertStep(const G4Step* step) {
fKineticEnergy.emplace_back(track->GetKineticEnergy() / CLHEP::keV);
fMomentumDirection.emplace_back(momentum.x(), momentum.y(), momentum.z());
+ string isotopeName;
+ int atomicNumber = 0;
+ int atomicMassNumber = 0;
+
+ if (metadata->GetStoreHadronicTargetInfo() && track->GetCurrentStepNumber() != 0 &&
+ process->GetProcessType() == G4ProcessType::fHadronic) {
+ auto hadronicProcess = dynamic_cast(process);
+ G4Nucleus nucleus = *(hadronicProcess->GetTargetNucleus());
+
+ auto isotope = nucleus.GetIsotope();
+ if (isotope) {
+ isotopeName = isotope->GetName();
+ atomicNumber = isotope->GetZ();
+ atomicMassNumber = isotope->GetN();
+ }
+ }
+
+ if (metadata->GetStoreHadronicTargetInfo()) {
+ fHadronicTargetIsotopeName.emplace_back(isotopeName);
+ fHadronicTargetIsotopeZ.emplace_back(atomicNumber);
+ fHadronicTargetIsotopeA.emplace_back(atomicMassNumber);
+ }
+
SimulationManager::GetOutputManager()->AddEnergyToVolumeForParticleForProcess(energy, volumeName,
particleName, processName);
}
diff --git a/src/PrimaryGeneratorAction.cxx b/src/PrimaryGeneratorAction.cxx
index fdec6fe..f53e732 100644
--- a/src/PrimaryGeneratorAction.cxx
+++ b/src/PrimaryGeneratorAction.cxx
@@ -3,12 +3,11 @@
#include
#include
-#include
#include
+#include
#include
#include
-#include
#include
#include
#include
@@ -39,7 +38,8 @@ G4ThreeVector ComputeCosmicPosition(const G4ThreeVector& direction, double radiu
return position;
}
-std::mutex PrimaryGeneratorAction::fDistributionFormulaMutex = std::mutex();
+std::mutex PrimaryGeneratorAction::fDistributionFormulaMutex;
+std::mutex PrimaryGeneratorAction::fPrimaryGenerationMutex;
TF1* PrimaryGeneratorAction::fEnergyDistributionFunction = nullptr;
TF1* PrimaryGeneratorAction::fAngularDistributionFunction = nullptr;
TF2* PrimaryGeneratorAction::fEnergyAndAngularDistributionFunction = nullptr;
@@ -231,6 +231,7 @@ void PrimaryGeneratorAction::SetGeneratorSpatialDensity(TString str) {
}
void PrimaryGeneratorAction::GeneratePrimaries(G4Event* event) {
+ lock_guard lock(fPrimaryGenerationMutex);
auto simulationManager = fSimulationManager;
TRestGeant4Metadata* restG4Metadata = simulationManager->GetRestMetadata();
@@ -241,6 +242,51 @@ void PrimaryGeneratorAction::GeneratePrimaries(G4Event* event) {
// GeneratePrimaries is called first, and we want to store event origin and position inside
// we should have already written the information from previous event to disk (in endOfEventAction)
+ if (restG4Metadata->GetNumberOfSources() == 1 &&
+ string(restG4Metadata->GetParticleSource(0)->GetName()) == "TRestGeant4ParticleSourceCosmics") {
+ auto source = dynamic_cast(restG4Metadata->GetParticleSource(0));
+
+ if (string(restG4Metadata->GetGeant4PrimaryGeneratorInfo().GetSpatialGeneratorType().Data()) !=
+ "Cosmic") {
+ cerr << "PrimaryGeneratorAction - ERROR: cosmic generator only supports cosmic type: "
+ << restG4Metadata->GetGeant4PrimaryGeneratorInfo().GetSpatialGeneratorType().Data() << endl;
+ exit(1);
+ }
+
+ source->Update();
+
+ const auto particle = source->GetParticles().at(0);
+
+ fParticleGun.SetParticleDefinition(
+ G4ParticleTable::GetParticleTable()->FindParticle(particle.GetParticleName().Data()));
+
+ if (fCosmicCircumscribedSphereRadius == 0.) {
+ // radius in mm
+ fCosmicCircumscribedSphereRadius = fSimulationManager->GetRestMetadata()
+ ->GetGeant4PrimaryGeneratorInfo()
+ .GetSpatialGeneratorCosmicRadius();
+ }
+
+ const auto position = ComputeCosmicPosition(fParticleGun.GetParticleMomentumDirection(),
+ fCosmicCircumscribedSphereRadius);
+
+ fParticleGun.SetParticlePosition(position);
+ fParticleGun.SetParticleEnergy(particle.GetEnergy() * keV);
+ fParticleGun.SetParticleMomentumDirection({particle.GetMomentumDirection().X(),
+ particle.GetMomentumDirection().Y(),
+ particle.GetMomentumDirection().Z()});
+ fParticleGun.GeneratePrimaryVertex(event);
+
+ /*
+ cout << "PrimaryGeneratorAction - INFO: cosmic particle generated: "
+ << fParticleGun.GetParticleDefinition()->GetParticleName()
+ << " energy: " << fParticleGun.GetParticleEnergy() / keV << " keV"
+ << " position: " << fParticleGun.GetParticlePosition() / mm << " mm"
+ << " direction: " << fParticleGun.GetParticleMomentumDirection() << endl;
+ */
+ return;
+ }
+
for (int i = 0; i < restG4Metadata->GetNumberOfSources(); i++) {
restG4Metadata->GetParticleSource(i)->Update();
}