1
0
Fork 0
mirror of https://github.com/gwm17/Mask.git synced 2024-11-12 21:48:50 -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();
void ReadDistributionFile(const std::string& file);
inline void AttachRandomNumberGenerator(std::mt19937* random) { generator = random; }
double GetRandomCosTheta();
inline int GetL() { return L; }
inline double GetBranchingRatio() { return branchingRatio; }
private:
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_prob_dist;

View File

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

View File

@ -7,8 +7,6 @@
#include "TwoStepSystem.h"
#include "ThreeStepSystem.h"
#include <random>
namespace Mask {
class Kinematics {
@ -42,7 +40,6 @@ namespace Mask {
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);
std::string FindSymbol(int Z, int A);
static MassLookup* GetInstance() {
if(s_instance == nullptr) {
s_instance = new MassLookup();
}
static MassLookup& GetInstance() {
static MassLookup s_instance;
return s_instance;
}
@ -36,8 +34,6 @@ namespace Mask {
std::unordered_map<std::string, double> massTable;
std::unordered_map<int, std::string> elementTable;
static MassLookup* s_instance;
//constants
static constexpr double u_to_mev = 931.4940954;
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);
/*Set sampling parameters*/
virtual void SetRandomGenerator(std::mt19937* gen);
inline void SetBeamDistro(double mean, double sigma) {
if(m_beamDist)
delete m_beamDist;
@ -63,7 +62,6 @@ namespace Mask {
//Sampling information
std::normal_distribution<double> *m_beamDist, *m_exDist;
std::uniform_real_distribution<double> *m_theta1Range, *m_phi1Range;
std::mt19937* generator; //not owned by ReactionSystem
bool target_set_flag, gen_set_flag;
int rxnLayer;

View File

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

View File

@ -1,5 +1,5 @@
----------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
SavePlots: yes
----------Reaction Information----------

View File

@ -1,4 +1,5 @@
#include "AngularDistribution.h"
#include "RandomGenerator.h"
#include <fstream>
#include <cmath>
#include <iostream>
@ -7,12 +8,12 @@
namespace Mask {
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) :
generator(nullptr), branchingRatio(1.0), L(0), isoFlag(true)
branchingRatio(1.0), L(0), isoFlag(true)
{
ReadDistributionFile(file);
}
@ -80,24 +81,19 @@ namespace Mask {
}
double AngularDistribution::GetRandomCosTheta() {
if(!IsGeneratorSet()) {
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);
if(isoFlag)
return uniform_cosine_dist(RandomGenerator::GetInstance().GetGenerator());
double test, probability;
double costheta;
test = uniform_prob_dist(*generator);
test = uniform_prob_dist(RandomGenerator::GetInstance().GetGenerator());
if(test > branchingRatio) return -10;
do {
probability = 0.0;
costheta = uniform_cosine_dist(*generator);
test = uniform_prob_dist(*generator);
costheta = uniform_cosine_dist(RandomGenerator::GetInstance().GetGenerator());
test = uniform_prob_dist(RandomGenerator::GetInstance().GetGenerator());
for(unsigned int i=0; i<constants.size(); i++)
probability += constants[i]*P_l(i*2, costheta);
} while(test > probability);

View File

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

View File

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

View File

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

View File

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

View File

@ -19,16 +19,16 @@ namespace Mask {
Nucleus::Nucleus(int Z, int A) :
Vec4(), m_z(Z), m_a(A), m_theta_cm(0), m_detectFlag(false)
{
m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A);
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A);
m_gs_mass = MassLookup::GetInstance().FindMass(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.
}
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)
{
m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A);
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A);
m_gs_mass = MassLookup::GetInstance().FindMass(Z, A);
m_symbol = MassLookup::GetInstance().FindSymbol(Z, A);
}
Nucleus::~Nucleus() {}
@ -38,8 +38,8 @@ namespace Mask {
m_z = Z;
m_a = A;
m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A);
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A);
m_gs_mass = MassLookup::GetInstance().FindMass(Z, A);
m_symbol = MassLookup::GetInstance().FindSymbol(Z, A);
SetVectorCartesian(0,0,0,m_gs_mass);
return true;
}

View File

@ -1,4 +1,5 @@
#include "OneStepSystem.h"
#include "RandomGenerator.h"
namespace Mask {
@ -48,18 +49,16 @@ namespace Mask {
}
void OneStepSystem::RunSystem() {
if(!gen_set_flag) return;
//Link up the target if it hasn't been done yet
if(!target_set_flag) {
LinkTarget();
}
//Sample parameters
double bke = (*m_beamDist)(*generator);
double rxnTheta = std::acos((*m_theta1Range)(*generator));
double rxnPhi = (*m_phi1Range)(*generator);
double residEx = (*m_exDist)(*generator);
double bke = (*m_beamDist)(RandomGenerator::GetInstance().GetGenerator());
double rxnTheta = std::acos((*m_theta1Range)(RandomGenerator::GetInstance().GetGenerator()));
double rxnPhi = (*m_phi1Range)(RandomGenerator::GetInstance().GetGenerator());
double residEx = (*m_exDist)(RandomGenerator::GetInstance().GetGenerator());
step1.SetBeamKE(bke);
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 {
ReactionSystem::ReactionSystem() :
m_beamDist(nullptr), m_theta1Range(nullptr), m_phi1Range(nullptr), m_exDist(nullptr), generator(nullptr), target_set_flag(false),
gen_set_flag(false), rxnLayer(0), m_sys_equation("")
m_beamDist(nullptr), m_theta1Range(nullptr), m_phi1Range(nullptr), m_exDist(nullptr), target_set_flag(false),
rxnLayer(0), m_sys_equation("")
{
}
@ -17,11 +17,6 @@ namespace Mask {
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) {
target.AddLayer(zt, at, stoich, thickness);
}

View File

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

View File

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