1
0
Fork 0
mirror of https://github.com/gwm17/Mask.git synced 2024-11-26 12:08:52 -05:00

Singleton'd a random number generator class to avoid chaining a generator manually. Fixed singleton pattern for MassLookup.

This commit is contained in:
Gordon McCann 2021-09-06 17:06:02 -04:00
parent 9149a9268f
commit 1c7bf69f16
21 changed files with 81 additions and 108 deletions

View File

@ -13,22 +13,13 @@ namespace Mask {
AngularDistribution(const std::string& file); AngularDistribution(const std::string& file);
~AngularDistribution(); ~AngularDistribution();
void ReadDistributionFile(const std::string& file); void ReadDistributionFile(const std::string& file);
inline void AttachRandomNumberGenerator(std::mt19937* random) { generator = random; }
double GetRandomCosTheta(); double GetRandomCosTheta();
inline int GetL() { return L; } inline int GetL() { return L; }
inline double GetBranchingRatio() { return branchingRatio; } inline double GetBranchingRatio() { return branchingRatio; }
private: private:
inline bool IsIsotropic() { return isoFlag; } inline bool IsIsotropic() { return isoFlag; }
inline bool IsGeneratorSet() {
if(generator) {
return true;
} else {
return false;
}
}
std::mt19937* generator; //NOT OWNED BY ANGULAR DISTRIBUTION
std::uniform_real_distribution<double> uniform_cosine_dist; std::uniform_real_distribution<double> uniform_cosine_dist;
std::uniform_real_distribution<double> uniform_prob_dist; std::uniform_real_distribution<double> uniform_prob_dist;

View File

@ -14,7 +14,6 @@ namespace Mask {
bool SetNuclei(std::vector<int>& z, std::vector<int>& a) override; bool SetNuclei(std::vector<int>& z, std::vector<int>& a) override;
void RunSystem() override; void RunSystem() override;
void SetRandomGenerator(std::mt19937* gen) override;
inline void SetDecay1Distribution(const std::string& filename) { decay1dist.ReadDistributionFile(filename); } inline void SetDecay1Distribution(const std::string& filename) { decay1dist.ReadDistributionFile(filename); }

View File

@ -7,8 +7,6 @@
#include "TwoStepSystem.h" #include "TwoStepSystem.h"
#include "ThreeStepSystem.h" #include "ThreeStepSystem.h"
#include <random>
namespace Mask { namespace Mask {
class Kinematics { class Kinematics {
@ -42,7 +40,6 @@ namespace Mask {
int m_rxn_type, m_nsamples; int m_rxn_type, m_nsamples;
std::mt19937* global_generator;
}; };
} }

View File

@ -1,5 +0,0 @@
#ifdef __CLING__
#pragma link C++ struct Mask::NucData+;
#endif

View File

@ -24,10 +24,8 @@ namespace Mask {
double FindMass(int Z, int A); double FindMass(int Z, int A);
std::string FindSymbol(int Z, int A); std::string FindSymbol(int Z, int A);
static MassLookup* GetInstance() { static MassLookup& GetInstance() {
if(s_instance == nullptr) { static MassLookup s_instance;
s_instance = new MassLookup();
}
return s_instance; return s_instance;
} }
@ -36,8 +34,6 @@ namespace Mask {
std::unordered_map<std::string, double> massTable; std::unordered_map<std::string, double> massTable;
std::unordered_map<int, std::string> elementTable; std::unordered_map<int, std::string> elementTable;
static MassLookup* s_instance;
//constants //constants
static constexpr double u_to_mev = 931.4940954; static constexpr double u_to_mev = 931.4940954;
static constexpr double electron_mass = 0.000548579909; static constexpr double electron_mass = 0.000548579909;

25
include/RandomGenerator.h Normal file
View File

@ -0,0 +1,25 @@
#ifndef RANDOMGENERATOR_H
#define RANDOMGENERATOR_H
#include <random>
namespace Mask {
class RandomGenerator {
public:
~RandomGenerator();
inline std::mt19937& GetGenerator() { return rng; }
inline static RandomGenerator& GetInstance() {
static RandomGenerator s_instance;
return s_instance;
}
private:
RandomGenerator();
std::mt19937 rng;
};
}
#endif

View File

@ -27,7 +27,6 @@ namespace Mask {
void AddTargetLayer(std::vector<int>& zt, std::vector<int>& at, std::vector<int>& stoich, double thickness); void AddTargetLayer(std::vector<int>& zt, std::vector<int>& at, std::vector<int>& stoich, double thickness);
/*Set sampling parameters*/ /*Set sampling parameters*/
virtual void SetRandomGenerator(std::mt19937* gen);
inline void SetBeamDistro(double mean, double sigma) { inline void SetBeamDistro(double mean, double sigma) {
if(m_beamDist) if(m_beamDist)
delete m_beamDist; delete m_beamDist;
@ -63,7 +62,6 @@ namespace Mask {
//Sampling information //Sampling information
std::normal_distribution<double> *m_beamDist, *m_exDist; std::normal_distribution<double> *m_beamDist, *m_exDist;
std::uniform_real_distribution<double> *m_theta1Range, *m_phi1Range; std::uniform_real_distribution<double> *m_theta1Range, *m_phi1Range;
std::mt19937* generator; //not owned by ReactionSystem
bool target_set_flag, gen_set_flag; bool target_set_flag, gen_set_flag;
int rxnLayer; int rxnLayer;

View File

@ -13,7 +13,6 @@ namespace Mask {
~ThreeStepSystem(); ~ThreeStepSystem();
bool SetNuclei(std::vector<int>& z, std::vector<int>& a) override; bool SetNuclei(std::vector<int>& z, std::vector<int>& a) override;
void RunSystem() override; void RunSystem() override;
void SetRandomGenerator(std::mt19937* gen) override;
inline void SetDecay1Distribution(const std::string& filename) { decay1dist.ReadDistributionFile(filename); }; inline void SetDecay1Distribution(const std::string& filename) { decay1dist.ReadDistributionFile(filename); };
inline void SetDecay2Distribution(const std::string& filename) { decay2dist.ReadDistributionFile(filename); }; inline void SetDecay2Distribution(const std::string& filename) { decay2dist.ReadDistributionFile(filename); };

View File

@ -14,8 +14,6 @@ namespace Mask {
bool SetNuclei(std::vector<int>& z, std::vector<int>& a) override; bool SetNuclei(std::vector<int>& z, std::vector<int>& a) override;
void RunSystem() override; void RunSystem() override;
void SetRandomGenerator(std::mt19937* gen) override;
inline void SetDecay1Distribution(const std::string& filename) { decay1dist.ReadDistributionFile(filename); }; inline void SetDecay1Distribution(const std::string& filename) { decay1dist.ReadDistributionFile(filename); };
inline void SetReactionThetaType(int type) { step1.SetEjectileThetaType(type); }; inline void SetReactionThetaType(int type) { step1.SetEjectileThetaType(type); };

View File

@ -1,5 +1,5 @@
----------Data Information---------- ----------Data Information----------
OutputFile: test/7Bedp_600keV_beam_centered_target_targetgap_BackQQQ_rndmCM_test.mask OutputFile: 7Bedp_600keV_beam_centered_target_targetgap_BackQQQ_rndmCM_test.mask
SaveTree: yes SaveTree: yes
SavePlots: yes SavePlots: yes
----------Reaction Information---------- ----------Reaction Information----------

View File

@ -1,4 +1,5 @@
#include "AngularDistribution.h" #include "AngularDistribution.h"
#include "RandomGenerator.h"
#include <fstream> #include <fstream>
#include <cmath> #include <cmath>
#include <iostream> #include <iostream>
@ -7,12 +8,12 @@
namespace Mask { namespace Mask {
AngularDistribution::AngularDistribution() : AngularDistribution::AngularDistribution() :
generator(nullptr), uniform_cosine_dist(-1.0, 1.0), uniform_prob_dist(0.0, 1.0), branchingRatio(1.0), L(0), isoFlag(true) uniform_cosine_dist(-1.0, 1.0), uniform_prob_dist(0.0, 1.0), branchingRatio(1.0), L(0), isoFlag(true)
{ {
} }
AngularDistribution::AngularDistribution(const std::string& file) : AngularDistribution::AngularDistribution(const std::string& file) :
generator(nullptr), branchingRatio(1.0), L(0), isoFlag(true) branchingRatio(1.0), L(0), isoFlag(true)
{ {
ReadDistributionFile(file); ReadDistributionFile(file);
} }
@ -80,24 +81,19 @@ namespace Mask {
} }
double AngularDistribution::GetRandomCosTheta() { double AngularDistribution::GetRandomCosTheta() {
if(isoFlag)
if(!IsGeneratorSet()) { return uniform_cosine_dist(RandomGenerator::GetInstance().GetGenerator());
std::cerr<<"Random number generator is not set in AngularDistribution! Returning default value of 0"<<std::endl;
return 0.0;
}
if(isoFlag) return uniform_cosine_dist(*generator);
double test, probability; double test, probability;
double costheta; double costheta;
test = uniform_prob_dist(*generator); test = uniform_prob_dist(RandomGenerator::GetInstance().GetGenerator());
if(test > branchingRatio) return -10; if(test > branchingRatio) return -10;
do { do {
probability = 0.0; probability = 0.0;
costheta = uniform_cosine_dist(*generator); costheta = uniform_cosine_dist(RandomGenerator::GetInstance().GetGenerator());
test = uniform_prob_dist(*generator); test = uniform_prob_dist(RandomGenerator::GetInstance().GetGenerator());
for(unsigned int i=0; i<constants.size(); i++) for(unsigned int i=0; i<constants.size(); i++)
probability += constants[i]*P_l(i*2, costheta); probability += constants[i]*P_l(i*2, costheta);
} while(test > probability); } while(test > probability);

View File

@ -1,4 +1,5 @@
#include "DecaySystem.h" #include "DecaySystem.h"
#include "RandomGenerator.h"
namespace Mask { namespace Mask {
@ -15,12 +16,6 @@ namespace Mask {
DecaySystem::~DecaySystem() {} DecaySystem::~DecaySystem() {}
void DecaySystem::SetRandomGenerator(std::mt19937* gen) {
generator = gen;
decay1dist.AttachRandomNumberGenerator(gen);
gen_set_flag = true;
}
bool DecaySystem::SetNuclei(std::vector<int>& z, std::vector<int>& a) { bool DecaySystem::SetNuclei(std::vector<int>& z, std::vector<int>& a) {
if(z.size() != a.size() || z.size() != 2) { if(z.size() != a.size() || z.size() != 2) {
return false; return false;
@ -52,15 +47,13 @@ namespace Mask {
} }
void DecaySystem::RunSystem() { void DecaySystem::RunSystem() {
if(!gen_set_flag) return;
//Link up the target if it hasn't been done yet //Link up the target if it hasn't been done yet
if(!target_set_flag) { if(!target_set_flag) {
LinkTarget(); LinkTarget();
} }
double rxnTheta = std::acos(decay1dist.GetRandomCosTheta()); double rxnTheta = std::acos(decay1dist.GetRandomCosTheta());
double rxnPhi = (*m_phi1Range)(*generator); double rxnPhi = (*m_phi1Range)(RandomGenerator::GetInstance().GetGenerator());
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);
step1.SetAzimRxnAngle(rxnPhi); step1.SetAzimRxnAngle(rxnPhi);

View File

@ -47,7 +47,7 @@ namespace Mask {
if( ZP != zp) { if( ZP != zp) {
ZP = zp; ZP = zp;
AP = ap; AP = ap;
MP = MassLookup::GetInstance()->FindMass(ZP, AP)*MEV2U; MP = MassLookup::GetInstance().FindMass(ZP, AP)*MEV2U;
} }
double e_final = e_initial; double e_final = e_initial;
@ -96,7 +96,7 @@ namespace Mask {
if( ZP != zp) { if( ZP != zp) {
ZP = zp; ZP = zp;
AP = ap; AP = ap;
MP = MassLookup::GetInstance()->FindMass(ZP, AP)*MEV2U; MP = MassLookup::GetInstance().FindMass(ZP, AP)*MEV2U;
} }
double e_initial = e_final; double e_initial = e_final;

View File

@ -9,13 +9,9 @@ namespace Mask {
sys(nullptr) sys(nullptr)
{ {
std::cout<<"----------GWM Kinematics Simulation----------"<<std::endl; std::cout<<"----------GWM Kinematics Simulation----------"<<std::endl;
std::random_device rd;
global_generator = new std::mt19937(rd());
} }
Kinematics::~Kinematics() { Kinematics::~Kinematics() {
delete global_generator;
if(sys) delete sys; if(sys) delete sys;
} }
@ -172,7 +168,6 @@ namespace Mask {
break; break;
} }
} }
sys->SetRandomGenerator(global_generator);
std::cout<<"Number of samples: "<<GetNumberOfSamples()<<std::endl; std::cout<<"Number of samples: "<<GetNumberOfSamples()<<std::endl;

View File

@ -13,7 +13,6 @@ Written by G.W. McCann Aug. 2020
namespace Mask { namespace Mask {
MassLookup* MassLookup::s_instance = nullptr;
MassLookup::MassLookup() { MassLookup::MassLookup() {
@ -36,7 +35,8 @@ namespace Mask {
} }
} }
MassLookup::~MassLookup() {} MassLookup::~MassLookup() {
}
//Returns nuclear mass in MeV //Returns nuclear mass in MeV
double MassLookup::FindMass(int Z, int A) { double MassLookup::FindMass(int Z, int A) {

View File

@ -19,16 +19,16 @@ namespace Mask {
Nucleus::Nucleus(int Z, int A) : Nucleus::Nucleus(int Z, int A) :
Vec4(), m_z(Z), m_a(A), m_theta_cm(0), m_detectFlag(false) Vec4(), m_z(Z), m_a(A), m_theta_cm(0), m_detectFlag(false)
{ {
m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A); m_gs_mass = MassLookup::GetInstance().FindMass(Z, A);
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A); m_symbol = MassLookup::GetInstance().FindSymbol(Z, A);
SetVectorCartesian(0,0,0,m_gs_mass); //by defualt a nucleus has mass given by the g.s. SetVectorCartesian(0,0,0,m_gs_mass); //by defualt a nucleus has mass given by the g.s.
} }
Nucleus::Nucleus(int Z, int A, double px, double py, double pz, double E) : Nucleus::Nucleus(int Z, int A, double px, double py, double pz, double E) :
Vec4(px, py, pz, E), m_z(Z), m_a(A) Vec4(px, py, pz, E), m_z(Z), m_a(A)
{ {
m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A); m_gs_mass = MassLookup::GetInstance().FindMass(Z, A);
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A); m_symbol = MassLookup::GetInstance().FindSymbol(Z, A);
} }
Nucleus::~Nucleus() {} Nucleus::~Nucleus() {}
@ -38,8 +38,8 @@ namespace Mask {
m_z = Z; m_z = Z;
m_a = A; m_a = A;
m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A); m_gs_mass = MassLookup::GetInstance().FindMass(Z, A);
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A); m_symbol = MassLookup::GetInstance().FindSymbol(Z, A);
SetVectorCartesian(0,0,0,m_gs_mass); SetVectorCartesian(0,0,0,m_gs_mass);
return true; return true;
} }

View File

@ -1,4 +1,5 @@
#include "OneStepSystem.h" #include "OneStepSystem.h"
#include "RandomGenerator.h"
namespace Mask { namespace Mask {
@ -48,18 +49,16 @@ namespace Mask {
} }
void OneStepSystem::RunSystem() { void OneStepSystem::RunSystem() {
if(!gen_set_flag) return;
//Link up the target if it hasn't been done yet //Link up the target if it hasn't been done yet
if(!target_set_flag) { if(!target_set_flag) {
LinkTarget(); LinkTarget();
} }
//Sample parameters //Sample parameters
double bke = (*m_beamDist)(*generator); double bke = (*m_beamDist)(RandomGenerator::GetInstance().GetGenerator());
double rxnTheta = std::acos((*m_theta1Range)(*generator)); double rxnTheta = std::acos((*m_theta1Range)(RandomGenerator::GetInstance().GetGenerator()));
double rxnPhi = (*m_phi1Range)(*generator); double rxnPhi = (*m_phi1Range)(RandomGenerator::GetInstance().GetGenerator());
double residEx = (*m_exDist)(*generator); double residEx = (*m_exDist)(RandomGenerator::GetInstance().GetGenerator());
step1.SetBeamKE(bke); step1.SetBeamKE(bke);
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);

11
src/RandomGenerator.cpp Normal file
View File

@ -0,0 +1,11 @@
#include "RandomGenerator.h"
namespace Mask {
RandomGenerator::RandomGenerator() {
std::random_device rd;
rng.seed(rd());
}
RandomGenerator::~RandomGenerator() {
}
}

View File

@ -5,8 +5,8 @@
namespace Mask { namespace Mask {
ReactionSystem::ReactionSystem() : ReactionSystem::ReactionSystem() :
m_beamDist(nullptr), m_theta1Range(nullptr), m_phi1Range(nullptr), m_exDist(nullptr), generator(nullptr), target_set_flag(false), m_beamDist(nullptr), m_theta1Range(nullptr), m_phi1Range(nullptr), m_exDist(nullptr), target_set_flag(false),
gen_set_flag(false), rxnLayer(0), m_sys_equation("") rxnLayer(0), m_sys_equation("")
{ {
} }
@ -17,11 +17,6 @@ namespace Mask {
delete m_exDist; delete m_exDist;
} }
void ReactionSystem::SetRandomGenerator(std::mt19937* gen) {
generator = gen;
gen_set_flag = true;
}
void ReactionSystem::AddTargetLayer(std::vector<int>& zt, std::vector<int>& at, std::vector<int>& stoich, double thickness) { void ReactionSystem::AddTargetLayer(std::vector<int>& zt, std::vector<int>& at, std::vector<int>& stoich, double thickness) {
target.AddLayer(zt, at, stoich, thickness); target.AddLayer(zt, at, stoich, thickness);
} }

View File

@ -1,4 +1,5 @@
#include "ThreeStepSystem.h" #include "ThreeStepSystem.h"
#include "RandomGenerator.h"
#include "KinematicsExceptions.h" #include "KinematicsExceptions.h"
namespace Mask { namespace Mask {
@ -16,12 +17,6 @@ namespace Mask {
ThreeStepSystem::~ThreeStepSystem() {} ThreeStepSystem::~ThreeStepSystem() {}
void ThreeStepSystem::SetRandomGenerator(std::mt19937* gen) {
generator = gen;
decay1dist.AttachRandomNumberGenerator(gen);
decay2dist.AttachRandomNumberGenerator(gen);
gen_set_flag = true;
}
bool ThreeStepSystem::SetNuclei(std::vector<int>&z, std::vector<int>& a) { bool ThreeStepSystem::SetNuclei(std::vector<int>&z, std::vector<int>& a) {
if(z.size() != a.size() || z.size() < 5) { if(z.size() != a.size() || z.size() < 5) {
@ -74,24 +69,22 @@ namespace Mask {
} }
void ThreeStepSystem::RunSystem() { void ThreeStepSystem::RunSystem() {
if(!gen_set_flag) return;
//Link up the target if it hasn't been done yet //Link up the target if it hasn't been done yet
if(!target_set_flag) { if(!target_set_flag) {
LinkTarget(); LinkTarget();
} }
//Sample parameters //Sample parameters
double bke = (*m_beamDist)(*generator); double bke = (*m_beamDist)(RandomGenerator::GetInstance().GetGenerator());
double rxnTheta = acos((*m_theta1Range)(*generator)); double rxnTheta = acos((*m_theta1Range)(RandomGenerator::GetInstance().GetGenerator()));
double rxnPhi = (*m_phi1Range)(*generator); double rxnPhi = (*m_phi1Range)(RandomGenerator::GetInstance().GetGenerator());
double decay1costheta = decay1dist.GetRandomCosTheta(); double decay1costheta = decay1dist.GetRandomCosTheta();
double decay1Theta = std::acos(decay1costheta); double decay1Theta = std::acos(decay1costheta);
double decay1Phi = m_phi2Range(*generator); double decay1Phi = m_phi2Range(RandomGenerator::GetInstance().GetGenerator());
double decay2costheta = decay2dist.GetRandomCosTheta(); double decay2costheta = decay2dist.GetRandomCosTheta();
double decay2Theta = std::acos(decay2costheta); double decay2Theta = std::acos(decay2costheta);
double decay2Phi = m_phi2Range(*generator); double decay2Phi = m_phi2Range(RandomGenerator::GetInstance().GetGenerator());
double residEx = (*m_exDist)(*generator); double residEx = (*m_exDist)(RandomGenerator::GetInstance().GetGenerator());
step1.SetBeamKE(bke); step1.SetBeamKE(bke);
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);

View File

@ -1,4 +1,5 @@
#include "TwoStepSystem.h" #include "TwoStepSystem.h"
#include "RandomGenerator.h"
#include "KinematicsExceptions.h" #include "KinematicsExceptions.h"
namespace Mask { namespace Mask {
@ -18,12 +19,6 @@ namespace Mask {
} }
void TwoStepSystem::SetRandomGenerator(std::mt19937* gen) {
generator = gen;
decay1dist.AttachRandomNumberGenerator(gen);
gen_set_flag = true;
}
bool TwoStepSystem::SetNuclei(std::vector<int>&z, std::vector<int>& a) { bool TwoStepSystem::SetNuclei(std::vector<int>&z, std::vector<int>& a) {
if(z.size() != a.size() || z.size() != 4) { if(z.size() != a.size() || z.size() != 4) {
return false; return false;
@ -66,21 +61,19 @@ namespace Mask {
} }
void TwoStepSystem::RunSystem() { void TwoStepSystem::RunSystem() {
if(!gen_set_flag) return;
//Link up the target if it hasn't been done yet //Link up the target if it hasn't been done yet
if(!target_set_flag) { if(!target_set_flag) {
LinkTarget(); LinkTarget();
} }
//Sample parameters //Sample parameters
double bke = (*m_beamDist)(*generator); double bke = (*m_beamDist)(RandomGenerator::GetInstance().GetGenerator());
double rxnTheta = acos((*m_theta1Range)(*generator)); double rxnTheta = acos((*m_theta1Range)(RandomGenerator::GetInstance().GetGenerator()));
double rxnPhi = (*m_phi1Range)(*generator); double rxnPhi = (*m_phi1Range)(RandomGenerator::GetInstance().GetGenerator());
double decay1costheta = decay1dist.GetRandomCosTheta(); double decay1costheta = decay1dist.GetRandomCosTheta();
double decay1Theta = std::acos(decay1costheta); double decay1Theta = std::acos(decay1costheta);
double decay1Phi = m_phi2Range(*generator); double decay1Phi = m_phi2Range(RandomGenerator::GetInstance().GetGenerator());
double residEx = (*m_beamDist)(*generator); double residEx = (*m_beamDist)(RandomGenerator::GetInstance().GetGenerator());
step1.SetBeamKE(bke); step1.SetBeamKE(bke);
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);