2#include "TRestGeant4ParticleSourceCosmics.h"
9mutex TRestGeant4ParticleSourceCosmics::fMutex;
10unique_ptr<TRandom3> TRestGeant4ParticleSourceCosmics::fRandom =
nullptr;
12const map<string, string> geant4ParticleNames = {
13 {
"neutron",
"neutron"},
16 {
"electron_minus",
"e-"},
17 {
"electron_plus",
"e+"},
18 {
"muon_minus",
"mu-"},
21 {
"neutron_below_1MeV",
"neutron"},
22 {
"neutron_above_10GeV",
"neutron"},
23 {
"neutron_between_1MeV_and_10GeV",
"neutron"},
26TRestGeant4ParticleSourceCosmics::TRestGeant4ParticleSourceCosmics() =
default;
29 lock_guard<mutex> lock(fMutex);
31 cout <<
"TRestGeant4ParticleSourceCosmics::InitFromConfigFile" << endl;
33 const auto particles =
34 GetParameter(
"particles",
"neutron,proton,gamma,electron_minus,electron_plus,muon_minus,muon_plus");
36 const TVector2 energy = Get2DVectorParameterWithUnits(
"energy", {0, 0});
38 if (energy.X() > energy.Y()) {
39 fEnergyRange = {energy.Y(), energy.X()};
41 fEnergyRange = {energy.X(), energy.Y()};
44 fEnergyRange = {fEnergyRange.first / 1000, fEnergyRange.second / 1000};
46 fDirection = Get3DVectorParameterWithUnits(
"direction", {0, -1, 0});
48 std::istringstream iss(particles);
50 while (std::getline(iss, name,
',')) {
51 fParticleNames.insert(name);
54 for (
const auto& particle : fParticleNames) {
55 if (geant4ParticleNames.find(particle) == geant4ParticleNames.end()) {
56 cerr <<
"Particle name '" << particle <<
"' is not allowed." << endl;
61 auto file = TFile::Open(fFilename.c_str(),
"READ");
62 if (file ==
nullptr) {
63 cerr <<
"File '" << fFilename <<
"' not found." << endl;
66 for (
const auto& particle : fParticleNames) {
67 auto histogramFromFile = file->Get<TH2D>(string(particle +
"_energy_zenith").c_str());
68 if (histogramFromFile ==
nullptr) {
69 cerr <<
"Histogram '" << particle <<
"' not found in file '" << fFilename <<
"'." << endl;
72 fHistograms[particle] =
new TH2D(*histogramFromFile);
73 const auto& histogram = fHistograms.at(particle);
74 TH2D* hist =
new TH2D(*histogram);
77 for (
int i = 1; i <= hist->GetNbinsX(); i++) {
78 for (
int j = 1; j <= hist->GetNbinsY(); j++) {
79 const double zenith = hist->GetYaxis()->GetBinCenter(j);
80 const double value = hist->GetBinContent(i, j) / TMath::Cos(zenith * TMath::DegToRad());
81 hist->SetBinContent(i, j, value);
84 fHistogramsTransformed[particle] = hist;
88 for (
const auto& particle : fParticleNames) {
89 auto hist = fHistograms.at(particle);
90 fParticleWeights[particle] += hist->GetEntries();
91 sum += fParticleWeights.at(particle);
93 for (
auto& entry : fParticleWeights) {
95 cout <<
"TRestGeant4ParticleSourceCosmics::InitFromConfigFile: particle: " << entry.first
96 <<
" sampling weight: " << entry.second << endl;
102void TRestGeant4ParticleSourceCosmics::Update() {
103 lock_guard<mutex> lock(fMutex);
108 if (fParticleNames.size() == 1) {
109 particleName = *fParticleNames.begin();
111 const auto random = fRandom->Uniform(0, 1);
114 for (
const auto& entry : fParticleWeights) {
117 particleName = entry.first;
123 auto hist = fHistogramsTransformed.at(particleName);
125 double energy, zenith;
126 if (abs(fEnergyRange.first - fEnergyRange.second) <
128 hist->GetRandom2(energy, zenith, fRandom.get());
132 hist->GetRandom2(energy, zenith, fRandom.get());
135 if (fCounterEnergyTotal < std::numeric_limits<unsigned long long>::max()) {
136 fCounterEnergyTotal++;
139 if (energy >= fEnergyRange.first && energy <= fEnergyRange.second) {
140 if (fCounterEnergyTotal < std::numeric_limits<unsigned long long>::max()) {
141 fCounterEnergyAccepted++;
148 particleName = geant4ParticleNames.at(particleName);
151 particle.SetParticleName(particleName);
153 particle.SetEnergy(energy * 1000);
155 double phi = fRandom->Uniform(0, 1) * TMath::TwoPi();
156 double zenithRad = zenith * TMath::DegToRad();
159 const TVector3 direction = {TMath::Sin(zenithRad) * TMath::Cos(phi), -TMath::Cos(zenithRad),
160 TMath::Sin(zenithRad) * TMath::Sin(phi)};
162 particle.SetDirection(direction);
164 AddParticle(particle);
167void TRestGeant4ParticleSourceCosmics::SetSeed(
unsigned int seed) {
168 cout <<
"TRestGeant4ParticleSourceCosmics::SetSeed: " << seed << endl;
169 fRandom = std::make_unique<TRandom3>(seed);
172double TRestGeant4ParticleSourceCosmics::GetEnergyRangeScalingFactor()
const {
173 if (fCounterEnergyTotal == 0) {
177 if (fParticleNames.size() > 1) {
178 throw std::runtime_error(
179 "TRestGeant4ParticleSourceCosmics::GetEnergyRangeScalingFactor is not implemented for multiple "
183 return double(fCounterEnergyAccepted) / double(fCounterEnergyTotal);
void InitFromConfigFile() override
To make settings from rml file. This method must be implemented in the derived class.
A class used to store particle properties.