REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestGeant4ParticleSourceCosmics.cxx
1
2#include "TRestGeant4ParticleSourceCosmics.h"
3
4#include <TFile.h>
5#include <TH2D.h>
6
7using namespace std;
8
9mutex TRestGeant4ParticleSourceCosmics::fMutex;
10unique_ptr<TRandom3> TRestGeant4ParticleSourceCosmics::fRandom = nullptr;
11
12const map<string, string> geant4ParticleNames = {
13 {"neutron", "neutron"}, {"proton", "proton"}, {"gamma", "gamma"}, {"electron_minus", "e-"},
14 {"electron_plus", "e+"}, {"muon_minus", "mu-"}, {"muon_plus", "mu+"},
15};
16
17TRestGeant4ParticleSourceCosmics::TRestGeant4ParticleSourceCosmics() = default;
18
20 lock_guard<mutex> lock(fMutex);
21
22 cout << "TRestGeant4ParticleSourceCosmics::InitFromConfigFile" << endl;
23 fFilename = GetParameter("filename");
24 const auto particles =
25 GetParameter("particles", "neutron,proton,gamma,electron_minus,electron_plus,muon_minus,muon_plus");
26
27 fDirection = Get3DVectorParameterWithUnits("direction", {0, -1, 0});
28
29 std::istringstream iss(particles);
30 std::string name;
31 while (std::getline(iss, name, ',')) {
32 fParticleNames.insert(name);
33 }
34
35 for (const auto& particle : fParticleNames) {
36 if (geant4ParticleNames.find(particle) == geant4ParticleNames.end()) {
37 cerr << "Particle name '" << particle << "' is not allowed." << endl;
38 exit(1);
39 }
40 }
41
42 auto file = TFile::Open(fFilename.c_str(), "READ");
43 if (file == nullptr) {
44 cerr << "File '" << fFilename << "' not found." << endl;
45 exit(1);
46 }
47 for (const auto& particle : fParticleNames) {
48 auto histogramFromFile = file->Get<TH2D>(string(particle + "_energy_zenith").c_str());
49 if (histogramFromFile == nullptr) {
50 cerr << "Histogram '" << particle << "' not found in file '" << fFilename << "'." << endl;
51 exit(1);
52 }
53 fHistograms[particle] = new TH2D(*histogramFromFile);
54 const auto& histogram = fHistograms.at(particle);
55 TH2D* hist = new TH2D(*histogram);
56 // same as original but Y axis is multiplied by 1/cos(zenith). Integral is also scaled properly when
57 // computing the time of the simulation.
58 for (int i = 1; i <= hist->GetNbinsX(); i++) {
59 for (int j = 1; j <= hist->GetNbinsY(); j++) {
60 const double zenith = hist->GetYaxis()->GetBinCenter(j);
61 const double value = hist->GetBinContent(i, j) / TMath::Cos(zenith * TMath::DegToRad());
62 hist->SetBinContent(i, j, value);
63 }
64 }
65 fHistogramsTransformed[particle] = hist;
66 }
67
68 double sum = 0;
69 for (const auto& particle : fParticleNames) {
70 auto hist = fHistograms.at(particle);
71 fParticleWeights[particle] += hist->GetEntries();
72 sum += fParticleWeights.at(particle);
73 }
74 for (auto& entry : fParticleWeights) {
75 entry.second /= sum;
76 cout << "TRestGeant4ParticleSourceCosmics::InitFromConfigFile: particle: " << entry.first
77 << " sampling weight: " << entry.second << endl;
78 }
79
80 // file->Close();
81}
82
83void TRestGeant4ParticleSourceCosmics::Update() {
84 lock_guard<mutex> lock(fMutex);
85
86 RemoveParticles();
87
88 string particleName;
89 if (fParticleNames.size() == 1) {
90 particleName = *fParticleNames.begin();
91 } else {
92 const auto random = fRandom->Uniform(0, 1);
93 // choose a random particle based on the weights
94 double sum = 0;
95 for (const auto& entry : fParticleWeights) {
96 sum += entry.second;
97 if (random <= sum) {
98 particleName = entry.first;
99 break;
100 }
101 }
102 }
103
104 auto hist = fHistogramsTransformed.at(particleName);
105 double energy, zenith;
106 hist->GetRandom2(energy, zenith, fRandom.get());
107
108 particleName = geant4ParticleNames.at(particleName);
109
110 TRestGeant4Particle particle;
111 particle.SetParticleName(particleName);
112
113 particle.SetEnergy(energy * 1000); // Convert from MeV to keV
114
115 double phi = fRandom->Uniform(0, 1) * TMath::TwoPi();
116 double zenithRad = zenith * TMath::DegToRad();
117
118 // direction towards -y (can be rotated later)
119 const TVector3 direction = {TMath::Sin(zenithRad) * TMath::Cos(phi), -TMath::Cos(zenithRad),
120 TMath::Sin(zenithRad) * TMath::Sin(phi)};
121
122 particle.SetDirection(direction);
123
124 AddParticle(particle);
125}
126
127void TRestGeant4ParticleSourceCosmics::SetSeed(unsigned int seed) {
128 cout << "TRestGeant4ParticleSourceCosmics::SetSeed: " << seed << endl;
129 fRandom = std::make_unique<TRandom3>(seed);
130}
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.
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.