-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #120 from rest-for-physics/lobis-th2d
New generator TRestGeant4ParticleSourceCosmics
- Loading branch information
Showing
4 changed files
with
211 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
|
||
#ifndef REST_TRESTGEANT4PARTICLESOURCECOSMICS_H | ||
#define REST_TRESTGEANT4PARTICLESOURCECOSMICS_H | ||
|
||
#include <TH2D.h> | ||
#include <TRandom3.h> | ||
#include <TRestGeant4ParticleSource.h> | ||
|
||
class TRestGeant4ParticleSourceCosmics : public TRestGeant4ParticleSource { | ||
private: | ||
std::set<std::string> fParticleNames; | ||
std::string fFilename; | ||
std::map<std::string, double> fParticleWeights; | ||
|
||
std::map<std::string, TH2D*> fHistograms; | ||
static std::mutex fMutex; | ||
static std::unique_ptr<TRandom3> fRandom; | ||
|
||
public: | ||
void Update() override; | ||
void InitFromConfigFile() override; | ||
|
||
static void SetSeed(unsigned int seed); | ||
|
||
TRestGeant4ParticleSourceCosmics(); | ||
~TRestGeant4ParticleSourceCosmics() = default; | ||
|
||
const char* GetName() const override { return "TRestGeant4ParticleSourceCosmics"; } | ||
|
||
ClassDefOverride(TRestGeant4ParticleSourceCosmics, 1); | ||
}; | ||
|
||
#endif // REST_TRESTGEANT4PARTICLESOURCECOSMICS_H |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
|
||
#include "TRestGeant4ParticleSourceCosmics.h" | ||
|
||
#include <TFile.h> | ||
#include <TH2D.h> | ||
|
||
using namespace std; | ||
|
||
mutex TRestGeant4ParticleSourceCosmics::fMutex; | ||
unique_ptr<TRandom3> TRestGeant4ParticleSourceCosmics::fRandom = nullptr; | ||
|
||
const map<string, string> geant4ParticleNames = { | ||
{"neutron", "neutron"}, {"proton", "proton"}, {"gamma", "gamma"}, {"electron", "e-"}, {"muon", "mu-"}}; | ||
|
||
TRestGeant4ParticleSourceCosmics::TRestGeant4ParticleSourceCosmics() = default; | ||
|
||
void TRestGeant4ParticleSourceCosmics::InitFromConfigFile() { | ||
lock_guard<mutex> lock(fMutex); | ||
|
||
cout << "TRestGeant4ParticleSourceCosmics::InitFromConfigFile" << endl; | ||
fFilename = GetParameter("filename"); | ||
const auto particles = GetParameter("particles", "neutron,proton,gamma,electron,muon"); | ||
|
||
std::istringstream iss(particles); | ||
std::string name; | ||
while (std::getline(iss, name, ',')) { | ||
fParticleNames.insert(name); | ||
} | ||
|
||
for (const auto& particle : fParticleNames) { | ||
if (geant4ParticleNames.find(particle) == geant4ParticleNames.end()) { | ||
cerr << "Particle name '" << particle << "' is not allowed." << endl; | ||
exit(1); | ||
} | ||
} | ||
|
||
auto file = TFile::Open(fFilename.c_str(), "READ"); | ||
if (file == nullptr) { | ||
cerr << "File '" << fFilename << "' not found." << endl; | ||
exit(1); | ||
} | ||
for (const auto& particle : fParticleNames) { | ||
auto histogram = file->Get<TH2D>(string(particle + "_energy_zenith").c_str()); | ||
if (histogram == nullptr) { | ||
cerr << "Histogram '" << particle << "' not found in file '" << fFilename << "'." << endl; | ||
exit(1); | ||
} | ||
fHistograms[particle] = histogram; | ||
} | ||
|
||
double sum = 0; | ||
for (const auto& particle : fParticleNames) { | ||
auto hist = fHistograms.at(particle); | ||
fParticleWeights[particle] += hist->GetEntries(); | ||
sum += fParticleWeights.at(particle); | ||
} | ||
for (auto& entry : fParticleWeights) { | ||
entry.second /= sum; | ||
cout << "TRestGeant4ParticleSourceCosmics::InitFromConfigFile: particle: " << entry.first | ||
<< " sampling weight: " << entry.second << endl; | ||
} | ||
|
||
// TODO: how to safely close the file? | ||
} | ||
|
||
void TRestGeant4ParticleSourceCosmics::Update() { | ||
lock_guard<mutex> lock(fMutex); | ||
|
||
RemoveParticles(); | ||
|
||
string particleName; | ||
if (fParticleNames.size() == 1) { | ||
particleName = *fParticleNames.begin(); | ||
} else { | ||
const auto random = fRandom->Uniform(0, 1); | ||
// choose a random particle based on the weights | ||
double sum = 0; | ||
for (const auto& entry : fParticleWeights) { | ||
sum += entry.second; | ||
if (random <= sum) { | ||
particleName = entry.first; | ||
break; | ||
} | ||
} | ||
} | ||
|
||
auto& hist = fHistograms.at(particleName); | ||
|
||
double energy, zenith; | ||
hist->GetRandom2(energy, zenith, fRandom.get()); | ||
|
||
particleName = geant4ParticleNames.at(particleName); | ||
|
||
TRestGeant4Particle particle; | ||
particle.SetParticleName(particleName); | ||
|
||
particle.SetEnergy(energy * 1000); // Convert from MeV to keV | ||
|
||
double phi = fRandom->Uniform(0, 1) * TMath::TwoPi(); | ||
double zenithRad = zenith * TMath::DegToRad(); | ||
|
||
// direction towards -y (can be rotated later) | ||
const TVector3 direction = {TMath::Sin(zenithRad) * TMath::Cos(phi), -TMath::Cos(zenithRad), | ||
TMath::Sin(zenithRad) * TMath::Sin(phi)}; | ||
|
||
particle.SetDirection(direction); | ||
|
||
AddParticle(particle); | ||
} | ||
|
||
void TRestGeant4ParticleSourceCosmics::SetSeed(unsigned int seed) { | ||
cout << "TRestGeant4ParticleSourceCosmics::SetSeed: " << seed << endl; | ||
fRandom = std::make_unique<TRandom3>(seed); | ||
} |