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

Major update. Now uses a homeade file type MaskFile to save data. Separated kinematics simulation (Mask), plotting (RootPlot/python), and detector efficiency (DetectEff). Mask itself no longer depends on ROOT, only RootPlot does.

This commit is contained in:
Gordon McCann 2021-09-03 17:03:41 -04:00
parent 46eb87e65b
commit 170cc7afb0
39 changed files with 1917 additions and 2116 deletions

View File

@ -2,7 +2,6 @@
#define ANASEN_EFFICIENCY_H #define ANASEN_EFFICIENCY_H
#include <string> #include <string>
#include <THashTable.h>
#include "DetectorEfficiency.h" #include "DetectorEfficiency.h"
#include "StripDetector.h" #include "StripDetector.h"
@ -12,16 +11,11 @@ class AnasenEfficiency : public DetectorEfficiency {
public: public:
AnasenEfficiency(); AnasenEfficiency();
~AnasenEfficiency(); ~AnasenEfficiency();
void CalculateEfficiency(const std::string& filename) override; void CalculateEfficiency(const std::string& inputname, const std::string& outputname, const std::string& statsname) override;
void DrawDetectorSystem(const std::string& filename) override; void DrawDetectorSystem(const std::string& filename) override;
double RunConsistencyCheck() override; double RunConsistencyCheck() override;
private: private:
void RunDecay(const std::string& filename) override;
void Run2Step(const std::string& filename) override;
void Run3Step(const std::string& filename) override;
void Run1Step(const std::string& filename) override;
bool IsRing1(double theta, double phi); bool IsRing1(double theta, double phi);
bool IsRing2(double theta, double phi); bool IsRing2(double theta, double phi);
bool IsQQQ(double theta, double phi); bool IsQQQ(double theta, double phi);

View File

@ -1,9 +1,9 @@
#ifndef ANGULARDISTRIBUTION_H #ifndef ANGULARDISTRIBUTION_H
#define ANGULARDISTRIBUTION_H #define ANGULARDISTRIBUTION_H
#include <TRandom3.h>
#include <string> #include <string>
#include <vector> #include <vector>
#include <random>
class AngularDistribution { class AngularDistribution {
public: public:
@ -11,7 +11,7 @@ public:
AngularDistribution(const std::string& file); AngularDistribution(const std::string& file);
~AngularDistribution(); ~AngularDistribution();
void ReadDistributionFile(const std::string& file); void ReadDistributionFile(const std::string& file);
void AttachRandomNumberGenerator(TRandom3* random) { generator = random; }; void AttachRandomNumberGenerator(std::mt19937* random) { generator = random; };
double GetRandomCosTheta(); double GetRandomCosTheta();
int GetL() { return L; }; int GetL() { return L; };
double GetBranchingRatio() { return branchingRatio; }; double GetBranchingRatio() { return branchingRatio; };
@ -26,7 +26,9 @@ private:
} }
} }
TRandom3* generator; //NOT OWNED BY ANGULAR DISTRIBUTION std::mt19937* generator; //NOT OWNED BY ANGULAR DISTRIBUTION
std::uniform_real_distribution<double> uniform_cosine_dist;
std::uniform_real_distribution<double> uniform_prob_dist;
double branchingRatio; double branchingRatio;
int L; int L;

View File

@ -14,16 +14,16 @@ public:
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(TRandom3* gen) 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 const Nucleus& GetTarget() const { return step1.GetTarget(); }; inline const Nucleus& GetTarget() const { return step1.GetTarget(); }
inline const Nucleus& GetEjectile() const { return step1.GetEjectile(); }; inline const Nucleus& GetEjectile() const { return step1.GetEjectile(); }
inline const Nucleus& GetResidual() const { return step1.GetResidual(); }; inline const Nucleus& GetResidual() const { return step1.GetResidual(); }
inline int GetDecay1AngularMomentum() { return decay1dist.GetL(); }; inline int GetDecay1AngularMomentum() { return decay1dist.GetL(); }
inline double GetDecay1BranchingRatio() { return decay1dist.GetBranchingRatio(); }; inline double GetDecay1BranchingRatio() { return decay1dist.GetBranchingRatio(); }
private: private:
@ -36,6 +36,6 @@ private:
}; };
}; }
#endif #endif

View File

@ -1,52 +1,22 @@
#ifndef DETECTOREFFICIENCY_H #ifndef DETECTOREFFICIENCY_H
#define DETECTOREFFICIENCY_H #define DETECTOREFFICIENCY_H
#include <THashTable.h>
#include <TH1.h>
#include <TH2.h>
#include <string> #include <string>
#include <cmath>
class DetectorEfficiency { class DetectorEfficiency {
public: public:
DetectorEfficiency() { m_rxn_type = -1; }; DetectorEfficiency() {};
virtual ~DetectorEfficiency() {}; virtual ~DetectorEfficiency() {};
inline void SetReactionType(int rxntype) { m_rxn_type = rxntype; }; virtual void CalculateEfficiency(const std::string& inputname, const std::string& outputname, const std::string& statsname) = 0;
virtual void CalculateEfficiency(const std::string& filename) = 0;
virtual void DrawDetectorSystem(const std::string& filename) = 0; virtual void DrawDetectorSystem(const std::string& filename) = 0;
virtual double RunConsistencyCheck() = 0; virtual double RunConsistencyCheck() = 0;
protected: protected:
void MyFill(THashTable* table, const std::string& name, const std::string& title, int bins, float min, float max, double val) {
TH1F* h = (TH1F*) table->FindObject(name.c_str());
if(h) {
h->Fill(val);
} else {
h = new TH1F(name.c_str(), title.c_str(), bins, min, max);
h->Fill(val);
table->Add(h);
}
}
void MyFill(THashTable* table, const std::string& name, const std::string& title, int binsx, float minx, float maxx, double valx, int binsy, float miny, float maxy, double valy) {
TH2F* h = (TH2F*) table->FindObject(name.c_str());
if(h) {
h->Fill(valx, valy);
} else {
h = new TH2F(name.c_str(), title.c_str(), binsx, minx, maxx, binsy, miny, maxy);
h->Fill(valx, valy);
table->Add(h);
}
}
inline bool IsDoubleEqual(double x, double y) { return std::fabs(x-y) < epsilon ? true : false; }; inline bool IsDoubleEqual(double x, double y) { return std::fabs(x-y) < epsilon ? true : false; };
virtual void Run2Step(const std::string& filename) = 0;
virtual void Run3Step(const std::string& filename) = 0;
virtual void RunDecay(const std::string& filename) = 0;
virtual void Run1Step(const std::string& filename) = 0;
static constexpr double epsilon = 1.0e-6; static constexpr double epsilon = 1.0e-6;
int m_rxn_type;
}; };
#endif #endif

View File

@ -6,42 +6,26 @@
#include "OneStepSystem.h" #include "OneStepSystem.h"
#include "TwoStepSystem.h" #include "TwoStepSystem.h"
#include "ThreeStepSystem.h" #include "ThreeStepSystem.h"
#include "Plotter.h"
#include <TFile.h> #include <random>
#include <TTree.h>
namespace Mask { namespace Mask {
//For tree
struct NucData {
double KE = -1;
double E = -1;
double Ex = -1;
double p = -1;
double theta = -1;
double theta_cm = -1;
double phi = -1;
int Z = -1;
int A = -1;
};
class Kinematics { class Kinematics {
public: public:
Kinematics(); Kinematics();
~Kinematics(); ~Kinematics();
bool LoadConfig(const char* filename); bool LoadConfig(const std::string& filename);
bool SaveConfig(const char* filename); bool SaveConfig(const std::string& filename);
inline void SetTreeFlag() { save_tree_flag = true; };
inline void SetPlotterFlag() { do_plotter_flag = true; };
inline int GetNumberOfSamples() { return m_nsamples; }; inline int GetNumberOfSamples() { return m_nsamples; };
inline const char* GetSystemName() { return sys == nullptr ? "" : sys->GetSystemEquation().c_str(); }; inline const std::string GetSystemName() { return sys == nullptr ? "" : sys->GetSystemEquation(); };
inline const char* GetOutputName() { return m_outfile_name.c_str(); }; inline const std::string GetOutputName() { return m_outfile_name; };
inline int GetReactionType() { return m_rxn_type; }; inline const int GetReactionType() { return m_rxn_type; };
void Run(); void Run();
enum RxnType { enum RxnType {
ONESTEP_RXN,
ONESTEP_DECAY, ONESTEP_DECAY,
ONESTEP_RXN,
TWOSTEP, TWOSTEP,
THREESTEP THREESTEP
}; };
@ -53,19 +37,14 @@ private:
void RunThreeStep(); void RunThreeStep();
ReactionSystem* sys; ReactionSystem* sys;
Plotter plotman;
NucData ConvertNucleus(const Nucleus& nuc);
bool save_tree_flag, do_plotter_flag;
std::string m_outfile_name; std::string m_outfile_name;
int m_rxn_type, m_nsamples; int m_rxn_type, m_nsamples;
TRandom3* global_generator; std::mt19937* global_generator;
}; };
}; }
#endif #endif

View File

@ -9,6 +9,18 @@
namespace Mask { namespace Mask {
struct MaskFileHeader {
int rxn_type = -1;
int nsamples = -1;
};
struct MaskFileData {
std::vector<double> E, KE, p, theta, phi; //ordered: target, (if not decay)projectile, ejectile, residual, break1...
std::vector<int> Z, A;
std::vector<bool> detect_flag;
bool eof = false; //flag on end of file
};
class MaskFile { class MaskFile {
public: public:
enum class FileType { enum class FileType {
@ -24,29 +36,39 @@ public:
inline bool IsOpen() { return file.is_open(); } inline bool IsOpen() { return file.is_open(); }
void Close(); void Close();
void WriteHeader(std::vector<Nucleus>& data); void WriteHeader(int rxn_type, int nsamples);
void WriteData(std::vector<Nucleus>& data); void WriteData(std::vector<Nucleus>& data);
void ReadHeader(); void WriteData(MaskFileData& data);
std::vector<Nucleus> ReadData(); MaskFileHeader ReadHeader();
MaskFileData ReadData();
private: private:
void FlushBuffer();
void FillBuffer();
FileType file_type; FileType file_type;
std::string filename; std::string filename;
unsigned int buffer_position; unsigned int buffer_position;
int count; unsigned int buffer_end;
unsigned int data_size;
int m_rxn_type;
int buffersize_bytes;
std::fstream file; std::fstream file;
std::vector<std::vector<Nucleus>> data_buffer; std::vector<char> data_buffer;
static constexpr int buffersize = 1000; static constexpr int onestep_rxn_n = 2;
static constexpr int twostep_rxn_n = 4;
static constexpr int threestep_rxn_n = 6;
static constexpr int buffersize = 10000; //number of events
static constexpr int width = 0; static constexpr int width = 0;
static constexpr int precision = 3; static constexpr int precision = 3;
static constexpr std::size_t double_size = sizeof(double);
static constexpr std::size_t int_size = sizeof(int);
static constexpr std::size_t bool_size = sizeof(bool);
}; };
}; };

View File

@ -7,6 +7,7 @@ of this map (MASS) for use throughout code it is included into.
Written by G.W. McCann Aug. 2020 Written by G.W. McCann Aug. 2020
Converted to true singleton to simplify usage -- Aug. 2021 GWM
*/ */
#ifndef MASS_LOOKUP_H #ifndef MASS_LOOKUP_H
#define MASS_LOOKUP_H #define MASS_LOOKUP_H
@ -20,21 +21,27 @@ Written by G.W. McCann Aug. 2020
class MassLookup { class MassLookup {
public: public:
MassLookup();
~MassLookup(); ~MassLookup();
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() {
if(s_instance == nullptr) {
s_instance = new MassLookup();
}
return s_instance;
}
private: private:
MassLookup();
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;
}; };
//static instance for use throught program
static MassLookup MASS;
#endif #endif

View File

@ -28,6 +28,9 @@ public:
inline double GetGroundStateMass() const { return m_gs_mass; }; inline double GetGroundStateMass() const { return m_gs_mass; };
inline const char* GetIsotopicSymbol() const { return m_symbol.c_str(); }; inline const char* GetIsotopicSymbol() const { return m_symbol.c_str(); };
inline double GetThetaCM() const { return m_theta_cm; }; inline double GetThetaCM() const { return m_theta_cm; };
inline void SetDetected() { m_detectFlag = true; };
inline void SetNotDetected() { m_detectFlag = false; };
inline bool IsDetected() { return m_detectFlag; };
inline Nucleus& operator=(const Nucleus& rhs) { inline Nucleus& operator=(const Nucleus& rhs) {
SetIsotope(rhs.GetZ(), rhs.GetA()); SetIsotope(rhs.GetZ(), rhs.GetA());
@ -52,6 +55,8 @@ private:
double m_theta_cm; double m_theta_cm;
std::string m_symbol; std::string m_symbol;
bool m_detectFlag;
}; };
}; };

View File

@ -28,6 +28,6 @@ private:
}; };
}; }
#endif #endif

View File

@ -1,49 +0,0 @@
#ifndef PLOTTER_H
#define PLOTTER_H
#include <TROOT.h>
#include <TH1.h>
#include <TH2.h>
#include <TGraph.h>
#include <THashTable.h>
#include "Nucleus.h"
namespace Mask {
struct GraphData {
std::string name;
std::string title;
std::vector<double> xvec;
std::vector<double> yvec;
int color;
};
class Plotter {
public:
Plotter();
~Plotter();
inline void ClearTable() { table->Clear(); };
inline THashTable* GetTable() {
GenerateGraphs();
return table;
};
void FillData(const Nucleus& nuc, const std::string& modifier = "");
private:
THashTable* table;
void GenerateGraphs();
void MyFill(const char* name, const char* title, int bins, float min, float max, double val);
void MyFill(const char* name, const char* title, int binsx, float minx, float maxx, int binsy, float miny, float maxy, double valx, double valy);
void MyFill(const char* name, const char* title, double valx, double valy, int color); //TGraph
std::vector<TGraph*> garbage_collection;
std::vector<GraphData> graphs;
static constexpr double rad2deg = 180.0/M_PI;
};
};
#endif

View File

@ -8,8 +8,8 @@
#ifndef QQQDETECTOR_H #ifndef QQQDETECTOR_H
#define QQQDETECTOR_H #define QQQDETECTOR_H
#include <TRandom3.h>
#include <cmath> #include <cmath>
#include <vector>
#include "Vec3.h" #include "Vec3.h"
#include "Rotation.h" #include "Rotation.h"

View File

@ -12,7 +12,7 @@
#include "Reaction.h" #include "Reaction.h"
#include "KinematicsExceptions.h" #include "KinematicsExceptions.h"
#include <vector> #include <vector>
#include <TRandom3.h> #include <random>
namespace Mask { namespace Mask {
@ -27,13 +27,32 @@ public:
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(TRandom3* gen); virtual void SetRandomGenerator(std::mt19937* gen);
inline void SetBeamDistro(double mean, double sigma) { m_beamDist = std::make_pair(mean, sigma); }; inline void SetBeamDistro(double mean, double sigma) {
inline void SetTheta1Range(double min, double max) { m_theta1Range = std::make_pair(min*deg2rad, max*deg2rad); }; if(m_beamDist)
inline void SetPhi1Range(double min, double max) { m_phi1Range = std::make_pair(min*deg2rad, max*deg2rad); }; delete m_beamDist;
inline void SetExcitationDistro(double mean, double sigma) { m_exDist = std::make_pair(mean, sigma); }; m_beamDist = new std::normal_distribution<double>(mean, sigma);
}
inline const std::string& GetSystemEquation() const { return m_sys_equation; }; inline void SetTheta1Range(double min, double max) {
if(m_theta1Range)
delete m_theta1Range;
m_theta1Range = new std::uniform_real_distribution<double>(std::cos(min*deg2rad), std::cos(max*deg2rad));
}
inline void SetPhi1Range(double min, double max) {
if(m_phi1Range)
delete m_phi1Range;
m_phi1Range = new std::uniform_real_distribution<double>(min*deg2rad, max*deg2rad);
}
inline void SetExcitationDistro(double mean, double sigma) {
if(m_exDist)
delete m_exDist;
m_exDist = new std::normal_distribution<double>(mean, sigma);
}
inline const std::string& GetSystemEquation() const { return m_sys_equation; }
protected: protected:
virtual void LinkTarget() = 0; virtual void LinkTarget() = 0;
@ -42,8 +61,9 @@ protected:
LayeredTarget target; LayeredTarget target;
//Sampling information //Sampling information
std::pair<double, double> m_beamDist, m_theta1Range, m_phi1Range, m_exDist; std::normal_distribution<double> *m_beamDist, *m_exDist;
TRandom3* generator; //not owned by ReactionSystem 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;
@ -51,6 +71,6 @@ protected:
static constexpr double deg2rad = M_PI/180.0; static constexpr double deg2rad = M_PI/180.0;
}; };
}; }
#endif #endif

48
include/RootPlotter.h Normal file
View File

@ -0,0 +1,48 @@
#ifndef ROOTPLOTTER_H
#define ROOTPLOTTER_H
#include <vector>
#include <string>
#include "Nucleus.h"
#include <THashTable.h>
#include <TH1.h>
#include <TH2.h>
#include <TGraph.h>
struct GraphData {
std::string name;
std::string title;
std::vector<double> xvec;
std::vector<double> yvec;
int color;
};
class RootPlotter {
public:
RootPlotter();
~RootPlotter();
inline void ClearTable() { table->Clear(); };
inline THashTable* GetTable() {
GenerateGraphs();
return table;
};
void FillData(const Mask::Nucleus& nuc, const std::string& modifier = "");
private:
THashTable* table;
void GenerateGraphs();
void MyFill(const std::string& name, const std::string& title, int bins, float min, float max, double val);
void MyFill(const std::string& name, const std::string& title, int binsx, float minx, float maxx, int binsy, float miny, float maxy, double valx, double valy);
void MyFill(const std::string& name, const std::string& title, double valx, double valy, int color); //TGraph
std::vector<TGraph*> garbage_collection;
std::vector<GraphData> graphs;
static constexpr double rad2deg = 180.0/M_PI;
};
#endif

View File

@ -5,24 +5,19 @@
#include "SabreDetector.h" #include "SabreDetector.h"
#include "Target.h" #include "Target.h"
#include "DeadChannelMap.h" #include "DeadChannelMap.h"
#include "Kinematics.h" #include "Nucleus.h"
#include <THashTable.h>
class SabreEfficiency : public DetectorEfficiency { class SabreEfficiency : public DetectorEfficiency {
public: public:
SabreEfficiency(); SabreEfficiency();
~SabreEfficiency(); ~SabreEfficiency();
void SetDeadChannelMap(std::string& filename) { dmap.LoadMapfile(filename); }; void SetDeadChannelMap(std::string& filename) { dmap.LoadMapfile(filename); };
void CalculateEfficiency(const std::string& file) override; void CalculateEfficiency(const std::string& inputname, const std::string& outputname, const std::string& statsname) override;
void DrawDetectorSystem(const std::string& filename) override; void DrawDetectorSystem(const std::string& filename) override;
double RunConsistencyCheck() override; double RunConsistencyCheck() override;
private: private:
std::pair<bool,double> IsSabre(Mask::NucData* nucleus); std::pair<bool,double> IsSabre(Mask::Nucleus& nucleus);
void Run2Step(const std::string& filename) override;
void Run3Step(const std::string& filename) override;
void RunDecay(const std::string& filename) override;
void Run1Step(const std::string& filename) override;
std::vector<SabreDetector> detectors; std::vector<SabreDetector> detectors;

30
include/Stopwatch.h Normal file
View File

@ -0,0 +1,30 @@
/*
Stopwatch.h
Simple class designed to provide timing info on parts of the process.
Only for use in development.
Written by G.W. McCann Oct. 2020
*/
#ifndef STOPWATCH_H
#define STOPWATCH_H
#include <chrono>
class Stopwatch {
public:
Stopwatch();
~Stopwatch();
void Start();
void Stop();
double GetElapsedSeconds();
double GetElapsedMilliseconds();
private:
using Time = std::chrono::high_resolution_clock::time_point;
using Clock = std::chrono::high_resolution_clock;
Time start_time, stop_time;
};
#endif

View File

@ -11,9 +11,9 @@
//Back strips from lowest z to highest z //Back strips from lowest z to highest z
#include <TRandom3.h>
#include <cmath> #include <cmath>
#include <vector> #include <vector>
#include <random>
#include "Vec3.h" #include "Vec3.h"
#include "Rotation.h" #include "Rotation.h"
@ -27,7 +27,7 @@ public:
inline Mask::Vec3 GetBackStripCoordinates(int stripch, int corner) { return back_strip_coords[stripch][corner]; }; inline Mask::Vec3 GetBackStripCoordinates(int stripch, int corner) { return back_strip_coords[stripch][corner]; };
inline Mask::Vec3 GetRotatedFrontStripCoordinates(int stripch, int corner) { return rotated_front_strip_coords[stripch][corner]; }; inline Mask::Vec3 GetRotatedFrontStripCoordinates(int stripch, int corner) { return rotated_front_strip_coords[stripch][corner]; };
inline Mask::Vec3 GetRotatedBackStripCoordinates(int stripch, int corner) { return rotated_back_strip_coords[stripch][corner]; }; inline Mask::Vec3 GetRotatedBackStripCoordinates(int stripch, int corner) { return rotated_back_strip_coords[stripch][corner]; };
inline void SetRandomNumberGenerator(TRandom3* random) { m_random = random; }; inline void SetRandomNumberGenerator(std::mt19937* random) { m_random = random; };
Mask::Vec3 GetHitCoordinates(int front_stripch, double front_strip_ratio); Mask::Vec3 GetHitCoordinates(int front_stripch, double front_strip_ratio);
std::pair<int,double> GetChannelRatio(double theta, double phi); std::pair<int,double> GetChannelRatio(double theta, double phi);
@ -51,7 +51,9 @@ private:
Mask::ZRotation zRot; Mask::ZRotation zRot;
TRandom3* m_random; //Not owned by StripDetector! std::uniform_real_distribution<double> m_uniform_fraction;
std::mt19937* m_random; //Not owned by StripDetector!
inline bool ValidChannel(int f) { return ((f >= 0 && f < num_strips) ? true : false); }; inline bool ValidChannel(int f) { return ((f >= 0 && f < num_strips) ? true : false); };
inline bool ValidRatio(double r) { return ((r >= -1 && r <= 1) ? true : false); }; inline bool ValidRatio(double r) { return ((r >= -1 && r <= 1) ? true : false); };

View File

@ -13,7 +13,7 @@ public:
~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(TRandom3* gen) 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); };
@ -37,12 +37,14 @@ protected:
void LinkTarget() override; void LinkTarget() override;
void SetSystemEquation() override; void SetSystemEquation() override;
std::uniform_real_distribution<double> m_phi2Range;
Reaction step1, step2, step3; Reaction step1, step2, step3;
AngularDistribution decay1dist, decay2dist; AngularDistribution decay1dist, decay2dist;
}; };
}; }
#endif #endif

View File

@ -14,7 +14,7 @@ public:
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(TRandom3* gen) 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); };
@ -33,12 +33,14 @@ private:
void LinkTarget() override; void LinkTarget() override;
void SetSystemEquation() override; void SetSystemEquation() override;
std::uniform_real_distribution<double> m_phi2Range;
Reaction step1, step2; Reaction step1, step2;
AngularDistribution decay1dist; AngularDistribution decay1dist;
}; };
}; }
#endif #endif

View File

@ -1,5 +1,5 @@
----------Data Information---------- ----------Data Information----------
OutputFile: /data1/gwm17/mask_tests/7Bedp_600keV_beam_centered_target_targetgap_BackQQQ_rndmCM_test.root OutputFile: /data1/gwm17/mask_tests/7Bedp_600keV_beam_centered_target_targetgap_BackQQQ_rndmCM_test.mask
SaveTree: yes SaveTree: yes
SavePlots: yes SavePlots: yes
----------Reaction Information---------- ----------Reaction Information----------
@ -20,8 +20,8 @@ Z A Stoich
0 0
~ ~
----------Sampling Information---------- ----------Sampling Information----------
NumberOfSamples: 100000 NumberOfSamples: 10000
BeamMeanEnergy(MeV): 0.6 BeamEnergySigma(MeV): 0.001 BeamMeanEnergy(MeV): 0.6 BeamEnergySigma(MeV): 0.0
EjectileThetaType(0=Lab,1=CM): 1 EjectileThetaType(0=Lab,1=CM): 1
EjectileThetaMin(deg): 0.0 EjectileThetaMax(deg): 180.0 EjectileThetaMin(deg): 0.0 EjectileThetaMax(deg): 180.0
EjectilePhiMin(deg): 0.0 EjectilePhiMax(deg): 360.0 EjectilePhiMin(deg): 0.0 EjectilePhiMax(deg): 360.0

View File

@ -12,14 +12,35 @@ project "Mask"
cppdialect "C++11" cppdialect "C++11"
files { files {
"src/**.cpp", "src/*.cpp",
"include/**.h", "include/*.h"
"src/**.cxx"
} }
prebuildcommands { includedirs {
"rootcint -f src/kinematics_dict.cxx include/Kinematics.h include/LinkDef_Kinematics.h", "include"
"{MOVE} src/kinematics_dict_rdict.pcm bin/" }
filter "configurations:Debug"
symbols "On"
filter "configurations:Release"
optimize "On"
project "RootPlot"
kind "ConsoleApp"
language "C++"
targetdir "bin"
objdir "objs"
cppdialect "c++11"
files {
"src/Plotters/ROOT/RootPlotter.cpp",
"src/MaskFile.cpp",
"src/Nucleus.cpp",
"src/Vec4.cpp",
"src/Vec3.cpp",
"src/MassLookup.cpp",
"include/*.h"
} }
filter "system:windows" filter "system:windows"
@ -59,3 +80,33 @@ project "Mask"
filter "configurations:Release" filter "configurations:Release"
optimize "On" optimize "On"
project "DetectEff"
kind "ConsoleApp"
language "C++"
targetdir "bin"
objdir "objs"
cppdialect "c++11"
files {
"src/Detectors/*.cpp",
"src/MaskFile.cpp",
"src/Nucleus.cpp",
"src/Vec4.cpp",
"src/Vec3.cpp",
"src/MassLookup.cpp",
"src/Rotation.cpp",
"src/Target.cpp",
"src/EnergyLoss.cpp",
"include/*.h"
}
includedirs {
"include"
}
filter "configurations:Debug"
symbols "On"
filter "configurations:Release"
optimize "On"

View File

@ -5,7 +5,7 @@
#include "LegendrePoly.h" #include "LegendrePoly.h"
AngularDistribution::AngularDistribution() : AngularDistribution::AngularDistribution() :
generator(nullptr), branchingRatio(1.0), L(0), isoFlag(true) generator(nullptr), uniform_cosine_dist(-1.0, 1.0), uniform_prob_dist(0.0, 1.0), branchingRatio(1.0), L(0), isoFlag(true)
{ {
} }
@ -84,18 +84,18 @@ double AngularDistribution::GetRandomCosTheta() {
return 0.0; return 0.0;
} }
if(isoFlag) return generator->Uniform(-1.0, 1.0); if(isoFlag) return uniform_cosine_dist(*generator);
double test, probability; double test, probability;
double costheta; double costheta;
test = generator->Uniform(0.0, 1.0); test = uniform_prob_dist(*generator);
if(test > branchingRatio) return -10; if(test > branchingRatio) return -10;
do { do {
probability = 0.0; probability = 0.0;
costheta = generator->Uniform(-1.0, 1.0); costheta = uniform_cosine_dist(*generator);
test = generator->Uniform(0.0, 1.0); test = uniform_prob_dist(*generator);
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

@ -15,7 +15,7 @@ DecaySystem::DecaySystem(std::vector<int>& z, std::vector<int>& a) :
DecaySystem::~DecaySystem() {} DecaySystem::~DecaySystem() {}
void DecaySystem::SetRandomGenerator(TRandom3* gen) { void DecaySystem::SetRandomGenerator(std::mt19937* gen) {
generator = gen; generator = gen;
decay1dist.AttachRandomNumberGenerator(gen); decay1dist.AttachRandomNumberGenerator(gen);
gen_set_flag = true; gen_set_flag = true;
@ -61,7 +61,7 @@ void DecaySystem::RunSystem() {
if(step1.IsDecay()) { if(step1.IsDecay()) {
double rxnTheta = std::acos(decay1dist.GetRandomCosTheta()); double rxnTheta = std::acos(decay1dist.GetRandomCosTheta());
double rxnPhi = generator->Uniform(0, 2.0*M_PI); double rxnPhi = (*m_phi1Range)(*generator);
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);
step1.SetAzimRxnAngle(rxnPhi); step1.SetAzimRxnAngle(rxnPhi);

View File

@ -1,11 +1,8 @@
#include "AnasenEfficiency.h" #include "AnasenEfficiency.h"
#include "Kinematics.h" #include "Kinematics.h"
#include <TH2.h> #include "MaskFile.h"
#include <TH1.h> #include <fstream>
#include <TGraph2D.h> #include <iomanip>
#include <TGraph.h>
#include <TCanvas.h>
#include <TParameter.h>
AnasenEfficiency::AnasenEfficiency() : AnasenEfficiency::AnasenEfficiency() :
DetectorEfficiency() DetectorEfficiency()
@ -24,7 +21,7 @@ AnasenEfficiency::~AnasenEfficiency() {}
void AnasenEfficiency::DrawDetectorSystem(const std::string& filename) { void AnasenEfficiency::DrawDetectorSystem(const std::string& filename) {
TFile* file = TFile::Open(filename.c_str(), "RECREATE"); std::ofstream output(filename);
std::vector<double> x, y, z; std::vector<double> x, y, z;
std::vector<double> cx, cy, cz; std::vector<double> cx, cy, cz;
@ -105,24 +102,18 @@ void AnasenEfficiency::DrawDetectorSystem(const std::string& filename) {
} }
} }
} }
TGraph2D* graph = new TGraph2D(x.size(), &(x[0]), &(y[0]), &(z[0]));
graph->SetName("CornerGraph");
graph->SetMarkerStyle(2);
graph->SetLineColor(1);
TGraph2D* graph2 = new TGraph2D(cx.size(), &(cx[0]), &(cy[0]), &(cz[0])); output<<"ANASEN Geometry File -- Coordinates for Detectors"<<std::endl;
graph2->SetName("CenterGraph"); output<<"Edges: x y z"<<std::endl;
graph2->SetMarkerStyle(2); for(unsigned int i=0; i<x.size(); i++) {
graph2->SetMarkerColor(4); output<<x[i]<<" "<<y[i]<<" "<<z[i]<<std::endl;
}
output<<"Centers: x y z"<<std::endl;
for(unsigned int i=0; i<cx.size(); i++) {
output<<cx[i]<<" "<<cy[i]<<" "<<cz[i]<<std::endl;
}
TCanvas* canvas = new TCanvas(); output.close();
canvas->SetName("ANASEN Detector");
graph->Draw("A|P");
graph2->Draw("same|P");
canvas->Write();
graph->Write();
graph2->Write();
file->Close();
} }
double AnasenEfficiency::RunConsistencyCheck() { double AnasenEfficiency::RunConsistencyCheck() {
@ -248,305 +239,86 @@ bool AnasenEfficiency::IsQQQ(double theta, double phi) {
return false; return false;
} }
void AnasenEfficiency::CalculateEfficiency(const std::string& file) { void AnasenEfficiency::CalculateEfficiency(const std::string& inputname, const std::string& outputname, const std::string& statsname) {
std::cout<<"----------ANASEN Efficiency Calculation----------"<<std::endl; std::cout<<"----------ANASEN Efficiency Calculation----------"<<std::endl;
std::cout<<"Loading in output from kinematics simulation: "<<file<<std::endl; std::cout<<"Loading in output from kinematics simulation: "<<inputname<<std::endl;
std::cout<<"Running efficiency calculation..."<<std::endl; std::cout<<"Running efficiency calculation..."<<std::endl;
switch(m_rxn_type) { Mask::MaskFile input(inputname, Mask::MaskFile::FileType::read);
case Mask::Kinematics::ONESTEP_DECAY: Mask::MaskFile output(outputname, Mask::MaskFile::FileType::write);
{ std::ofstream stats(statsname);
RunDecay(file); stats<<std::setprecision(5);
Mask::MaskFileHeader header = input.ReadHeader();
output.WriteHeader(header.rxn_type, header.nsamples);
stats<<"Efficiency statistics for data from "<<inputname<<" using the ANASEN geometry"<<std::endl;
stats<<"Given in order of target=0, projectile=1, ejectile=2, residual=3, .... etc."<<std::endl;
Mask::MaskFileData data;
std::vector<int> counts;
switch(header.rxn_type) {
case 0:
counts.resize(3, 0);
break; break;
} case 1:
case Mask::Kinematics::ONESTEP_RXN: counts.resize(4, 0);
{
Run1Step(file);
}
case Mask::Kinematics::TWOSTEP:
{
Run2Step(file);
break; break;
} case 2:
case Mask::Kinematics::THREESTEP: counts.resize(6, 0);
{
Run3Step(file);
break; break;
case 3:
counts.resize(8, 0);
break;
default:
{
std::cerr<<"Bad reaction type at AnasenEfficiency::CalculateEfficiency (given value: "<<header.rxn_type<<"). Quiting..."<<std::endl;
input.Close();
output.Close();
stats.close();
return;
} }
} }
int percent5 = header.nsamples*0.05;
int count = 0;
int npercent = 0;
while(true) {
if(++count == percent5) {//Show progress every 5%
npercent++;
count = 0;
std::cout<<"\rPercent completed: "<<npercent*5<<"%"<<std::flush;
}
data = input.ReadData();
if(data.eof)
break;
for(unsigned int i=0; i<data.Z.size(); i++) {
if(data.KE[i] >= threshold && (IsRing1(data.theta[i], data.phi[i]) || IsRing2(data.theta[i], data.phi[i]) || IsQQQ(data.theta[i], data.phi[i]))) {
data.detect_flag[i] = true;
counts[i]++;
} else if(data.detect_flag[i] == true) {
data.detect_flag[i] = false;
}
}
output.WriteData(data);
}
input.Close();
output.Close();
stats<<std::setw(10)<<"Index"<<"|"<<std::setw(10)<<"Efficiency"<<std::endl;
stats<<"---------------------"<<std::endl;
for(unsigned int i=0; i<counts.size(); i++) {
stats<<std::setw(10)<<i<<"|"<<std::setw(10)<<((double)counts[i]/header.nsamples)<<std::endl;
stats<<"---------------------"<<std::endl;
}
stats.close();
std::cout<<std::endl; std::cout<<std::endl;
std::cout<<"Complete."<<std::endl; std::cout<<"Complete."<<std::endl;
std::cout<<"---------------------------------------------"<<std::endl; std::cout<<"---------------------------------------------"<<std::endl;
} }
void AnasenEfficiency::RunDecay(const std::string& filename) {
TFile* input = TFile::Open(filename.c_str(), "UPDATE");
TTree* tree = (TTree*) input->Get("DataTree");
THashTable* table = new THashTable();
Mask::NucData* eject = new Mask::NucData();
Mask::NucData* resid = new Mask::NucData();
tree->SetBranchAddress("ejectile", &eject);
tree->SetBranchAddress("residual", &resid);
double nevents = tree->GetEntries();
//Progress tracking
int percent5 = nevents*0.05;
int count = 0;
int npercent = 0;
int detected_eject=0;
int detected_resid=0;
for(int i=0; i<tree->GetEntries(); i++) {
if(++count == percent5) {//Show progress every 5%
npercent++;
count = 0;
std::cout<<"\rPercent completed: "<<npercent*5<<"%"<<std::flush;
}
tree->GetEntry(i);
if(eject->KE >= threshold && (IsRing1(eject->theta, eject->phi) || IsRing2(eject->theta, eject->phi) || IsQQQ(eject->theta, eject->phi))) {
detected_eject++;
MyFill(table, "detected_eject_theta_ke","detected ejectile theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,eject->theta/deg2rad,300,0.0,30.0,eject->KE);
}
if(resid->KE > threshold && (IsRing1(resid->theta, resid->phi) || IsRing2(resid->theta, resid->phi) || IsQQQ(resid->theta, resid->phi))) {
detected_resid++;
MyFill(table, "detected_resid_theta_ke","detected residual theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,resid->theta/deg2rad,300,0.0,30.0,resid->KE);
}
}
double ejecteff = ((double) detected_eject)/nevents;
double resideff = ((double) detected_resid)/nevents;
TParameter<double> eject_eff("Light Breakup Efficiency", ejecteff);
TParameter<double> resid_eff("Heavy Breakup Efficiency", resideff);
input->cd();
eject_eff.Write();
resid_eff.Write();
table->Write();
input->Close();
}
void AnasenEfficiency::Run1Step(const std::string& filename) {
std::cout<<"SabreEfficiency::Run1Step Not Implemented!"<<std::endl;
return;
}
void AnasenEfficiency::Run2Step(const std::string& filename) {
TFile* input = TFile::Open(filename.c_str(), "UPDATE");
TTree* tree = (TTree*) input->Get("DataTree");
Mask::NucData* eject = new Mask::NucData();
Mask::NucData* break1 = new Mask::NucData();
Mask::NucData* break2 = new Mask::NucData();
THashTable* table = new THashTable();
tree->SetBranchAddress("ejectile", &eject);
tree->SetBranchAddress("breakup1", &break1);
tree->SetBranchAddress("breakup2", &break2);
double nevents = tree->GetEntries();
//Progress tracking
int percent5 = nevents*0.05;
int count = 0;
int npercent = 0;
double costheta_cm =0;
bool break1_flag, break2_flag, eject_flag;
int b1_count=0, b2_count=0, eject_count=0;
int b1b2_count=0, b1e_count=0, b2e_count=0, b1b2e_count=0;
for(int i=0; i<tree->GetEntries(); i++) {
if(++count == percent5) {//Show progress every 5%
npercent++;
count = 0;
std::cout<<"\rPercent completed: "<<npercent*5<<"%"<<std::flush;
}
break1_flag = false;
break2_flag = false;
eject_flag = false;
tree->GetEntry(i);
if(eject->KE >= threshold && (IsRing1(eject->theta, eject->phi) || IsRing2(eject->theta, eject->phi) || IsQQQ(eject->theta, eject->phi))) {
eject_count++;
eject_flag = true;
MyFill(table, "detected_eject_theta_ke","detected ejectile theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,eject->theta/deg2rad,300,0.0,30.0,eject->KE);
}
if(break1->KE >= threshold && (IsRing1(break1->theta, break1->phi) || IsRing2(break1->theta, break1->phi) || IsQQQ(break1->theta, break1->phi))) {
b1_count++;
break1_flag = true;
costheta_cm = std::cos(break1->theta_cm);
MyFill(table,"detected_break1_cm_theta","detected breakup1 CM theta;cos(#theta_{CM})",20,-1.0,1.0,costheta_cm);
MyFill(table, "detected_break1_theta_ke","detected breakup1 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break1->theta/deg2rad,300,0.0,30.0,break1->KE);
}
if(break2->KE >= threshold && (IsRing1(break2->theta, break2->phi) || IsRing2(break2->theta, break2->phi) || IsQQQ(break2->theta, break2->phi))) {
b2_count++;
break2_flag = true;
MyFill(table, "detected_break2_theta_ke","detected breakup2 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break2->theta/deg2rad,300,0.0,30.0,break2->KE);
}
if(break1_flag && break2_flag && eject_flag) {
b1b2e_count++;
b1b2_count++;
b1e_count++;
b2e_count++;
MyFill(table,"b1b2_theta_theta","b1b2_theta_theta;#theta_{3};#theta_{4}",180,0.0,180.0,break1->theta/deg2rad,180,0.0,180.0,break2->theta/deg2rad);
MyFill(table,"b1b2_ke_ke","b1b2_ke_ke;KE_{3};KE_{4}",300,0.0,30.0,break1->KE,300,0.0,30.0,break2->KE);
MyFill(table,"b1b2_phi_phi","b1b2_phi_phi;#phi_{3};#phi_{4}",360,0.0,360.0,break1->phi/deg2rad,360,0.0,360.0,break2->phi/deg2rad);
} else if(break1_flag && eject_flag) {
b1e_count++;
} else if(break2_flag && eject_flag) {
b2e_count++;
} else if(break1_flag && break2_flag) {
b1b2_count++;
MyFill(table,"b1b2_theta_theta","b1b2_theta_theta;#theta_{3};#theta_{4}",180,0.0,180.0,break1->theta/deg2rad,180,0.0,180.0,break2->theta/deg2rad);
MyFill(table,"b1b2_ke_ke","b1b2_ke_ke;KE_{3};KE_{4}",300,0.0,30.0,break1->KE,300,0.0,30.0,break2->KE);
MyFill(table,"b1b2_phi_phi","b1b2_phi_phi;#phi_{3};#phi_{4}",360,0.0,360.0,break1->phi/deg2rad,360,0.0,360.0,break2->phi/deg2rad);
}
}
double eeff = ((double) eject_count)/nevents;
double b1eff = ((double) b1_count)/nevents;
double b2eff = ((double) b2_count)/nevents;
double b1b2eff = b1b2_count/nevents;
double b1eeff = b1e_count/nevents;
double b2eeff = b2e_count/nevents;
double b1b2eeff = b1b2e_count/nevents;
TParameter<double> eject_eff("Ejectile Efficiency", eeff);
TParameter<double> break1_eff("Breakup 1 Efficiency", b1eff);
TParameter<double> break2_eff("Breakup 2 Efficiency", b2eff);
TParameter<double> break1break2_eff("Breakup1 Coincident with Breakup2", b1b2eff);
TParameter<double> break1eject_eff("Breakup1 Coincident with Ejectile", b1eeff);
TParameter<double> break2eject_eff("Breakup2 Coincident with Ejectile", b2eeff);
TParameter<double> break1break2eject_eff("All Three Particles Coincident", b1b2eeff);
input->cd();
table->Write();
eject_eff.Write();
break1_eff.Write();
break2_eff.Write();
break1break2_eff.Write();
break1eject_eff.Write();
break2eject_eff.Write();
break1break2eject_eff.Write();
input->Close();
}
void AnasenEfficiency::Run3Step(const std::string& filename) {
TFile* input = TFile::Open(filename.c_str(), "UPDATE");
TTree* tree = (TTree*) input->Get("DataTree");
THashTable* table = new THashTable();
Mask::NucData* break1 = new Mask::NucData();
Mask::NucData* break3 = new Mask::NucData();
Mask::NucData* break4 = new Mask::NucData();
tree->SetBranchAddress("breakup1", &break1);
tree->SetBranchAddress("breakup3", &break3);
tree->SetBranchAddress("breakup4", &break4);
double nevents = tree->GetEntries();
//Progress tracking
int percent5 = nevents*0.05;
int count = 0;
int npercent = 0;
bool break1_flag, break3_flag, break4_flag;
int b1_count=0, b3_count=0, b4_count=0;
int b1b3_count=0, b1b4_count=0, b3b4_count=0, b1b3b4_count=0;
for(int i=0; i<tree->GetEntries(); i++) {
if(++count == percent5) {//Show progress every 5%
npercent++;
count = 0;
std::cout<<"\rPercent completed: "<<npercent*5<<"%"<<std::flush;
}
break1_flag = false;
break3_flag = false;
break4_flag = false;
tree->GetEntry(i);
if(break1->KE >= threshold && (IsRing1(break1->theta, break1->phi) || IsRing2(break1->theta, break1->phi) || IsQQQ(break1->theta, break1->phi))) {
b1_count++;
break1_flag = true;
MyFill(table, "detected_break1_theta_ke","detected breakup1 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break1->theta/deg2rad,300,0.0,30.0,break1->KE);
}
if(break3->KE >= threshold && (IsRing1(break3->theta, break3->phi) || IsRing2(break3->theta, break3->phi) || IsQQQ(break3->theta, break3->phi))) {
b3_count++;
break3_flag = true;
MyFill(table, "detected_break3_theta_ke","detected breakup3 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break3->theta/deg2rad,300,0.0,30.0,break3->KE);
}
if(break4->KE >= threshold && (IsRing1(break4->theta, break4->phi) || IsRing2(break4->theta, break4->phi) || IsQQQ(break4->theta, break4->phi))) {
b4_count++;
break4_flag = true;
MyFill(table, "detected_break4_theta_ke","detected breakup4 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break4->theta/deg2rad,300,0.0,30.0,break4->KE);
}
if(break1_flag && break3_flag && break4_flag) {
b1b3b4_count++;
b1b3_count++;
b1b4_count++;
b3b4_count++;
MyFill(table,"b3b4_theta_theta","b3b4_theta_theta;#theta_{3};#theta_{4}",180,0.0,180.0,break3->theta/deg2rad,180,0.0,180.0,break4->theta/deg2rad);
MyFill(table,"b3b4_ke_ke","b3b4_ke_ke;KE_{3};KE_{4}",300,0.0,30.0,break3->KE,300,0.0,30.0,break4->KE);
MyFill(table,"b3b4_phi_phi","b3b4_phi_phi;#phi_{3};#phi_{4}",360,0.0,360.0,break3->phi/deg2rad,360,0.0,360.0,break4->phi/deg2rad);
} else if(break1_flag && break3_flag) {
b1b3_count++;
} else if(break1_flag && break4_flag) {
b1b4_count++;
} else if(break3_flag && break4_flag) {
b3b4_count++;
MyFill(table,"b3b4_theta_theta","b3b4_theta_theta;#theta_{3};#theta_{4}",180,0.0,180.0,break3->theta/deg2rad,180,0.0,180.0,break4->theta/deg2rad);
MyFill(table,"b3b4_ke_ke","b3b4_ke_ke;KE_{3};KE_{4}",300,0.0,30.0,break3->KE,300,0.0,30.0,break4->KE);
MyFill(table,"b3b4_phi_phi","b3b4_phi_phi;#phi_{3};#phi_{4}",360,0.0,360.0,break3->phi/deg2rad,360,0.0,360.0,break4->phi/deg2rad);
}
}
double b1eff = ((double) b1_count)/nevents;
double b3eff = ((double) b3_count)/nevents;
double b4eff = ((double) b4_count)/nevents;
double b1b3eff = b1b3_count/nevents;
double b1b4eff = b1b4_count/nevents;
double b3b4eff = b3b4_count/nevents;
double b1b3b4eff = b1b3b4_count/nevents;
TParameter<double> break1_eff("Breakup1 Efficiency", b1eff);
TParameter<double> break3_eff("Breakup3 Efficiency", b3eff);
TParameter<double> break4_eff("Breakup4 Efficiency", b4eff);
TParameter<double> b1b3_eff("Break1 Coincident with Break3", b1b3eff);
TParameter<double> b1b4_eff("Break1 Coincident with Break4", b1b4eff);
TParameter<double> b3b4_eff("Break3 Coincident with Break4", b3b4eff);
TParameter<double> b1b3b4_eff("All Breakups Coincident", b1b3b4eff);
input->cd();
break1_eff.Write();
break3_eff.Write();
break4_eff.Write();
b1b3_eff.Write();
b1b4_eff.Write();
b3b4_eff.Write();
b1b3b4_eff.Write();
table->Write();
input->Close();
}

View File

@ -0,0 +1,33 @@
#include "SabreEfficiency.h"
#include "AnasenEfficiency.h"
#include <iostream>
#include <string>
int main(int argc, char** argv) {
if(argc != 4) {
std::cerr<<"Incorrect number of commandline arguments! Returning."<<std::endl;
return 1;
}
std::string inputname = argv[1];
std::string outputname = argv[2];
std::string statsname = argv[3];
/*
SabreEfficiency sabre;
std::string mapfile = "./etc/DeadChannels.txt";
sabre.SetDeadChannelMap(mapfile);
sabre.CalculateEfficiency(inputname, outputname, statsname);
//std::cout<<"Running consistency check(1=success): "<<sabre.RunConsistencyCheck()<<std::endl;
//sabre.DrawDetectorSystem("/data1/gwm17/10B3He/Feb2021/simulation/SABREGeo.txt");
*/
AnasenEfficiency anasen;
anasen.CalculateEfficiency(inputname, outputname, statsname);
//std::cout<<"Running consistency check(1=success): "<<anasen.RunConsistencyCheck()<<std::endl;
//anasen.DrawDetectorSystem("/data1/gwm17/TRIUMF_7Bed/simulation/ANASENGeo_centered_target_targetGap_BackQQQ_test.root");
return 0;
}

View File

@ -1,12 +1,9 @@
#include "SabreEfficiency.h" #include "SabreEfficiency.h"
#include "MaskFile.h"
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <TFile.h> #include <iomanip>
#include <TTree.h>
#include <TParameter.h>
#include <TGraph.h>
#include <TGraph2D.h>
#include <TCanvas.h>
SabreEfficiency::SabreEfficiency() : SabreEfficiency::SabreEfficiency() :
DetectorEfficiency(), deadlayer(DEADLAYER_THIN), sabre_eloss(SABRE_THICKNESS) DetectorEfficiency(), deadlayer(DEADLAYER_THIN), sabre_eloss(SABRE_THICKNESS)
@ -28,9 +25,9 @@ SabreEfficiency::SabreEfficiency() :
SabreEfficiency::~SabreEfficiency() {} SabreEfficiency::~SabreEfficiency() {}
void SabreEfficiency::CalculateEfficiency(const std::string& file) { void SabreEfficiency::CalculateEfficiency(const std::string& inputname, const std::string& outputname, const std::string& statsname) {
std::cout<<"----------SABRE Efficiency Calculation----------"<<std::endl; std::cout<<"----------SABRE Efficiency Calculation----------"<<std::endl;
std::cout<<"Loading in output from kinematics simulation: "<<file<<std::endl; std::cout<<"Loading in output from kinematics simulation: "<<inputname<<std::endl;
std::cout<<"Running efficiency calculation..."<<std::endl; std::cout<<"Running efficiency calculation..."<<std::endl;
if(!dmap.IsValid()) { if(!dmap.IsValid()) {
@ -40,35 +37,92 @@ void SabreEfficiency::CalculateEfficiency(const std::string& file) {
std::cout<<"---------------------------------------------"<<std::endl; std::cout<<"---------------------------------------------"<<std::endl;
} }
switch(m_rxn_type) {
case Mask::Kinematics::ONESTEP_DECAY: Mask::MaskFile input(inputname, Mask::MaskFile::FileType::read);
{ Mask::MaskFile output(outputname, Mask::MaskFile::FileType::read);
RunDecay(file); std::ofstream stats(statsname);
stats<<std::setprecision(5);
Mask::MaskFileHeader header = input.ReadHeader();
output.WriteHeader(header.rxn_type, header.nsamples);
stats<<"Efficiency statistics for data from "<<inputname<<" using the SPS-SABRE geometry"<<std::endl;
stats<<"Given in order of target=0, projectile=1, ejectile=2, residual=3, .... etc."<<std::endl;
Mask::MaskFileData data;
Mask::Nucleus nucleus;
std::vector<int> counts;
switch(header.rxn_type) {
case 0:
counts.resize(3, 0);
break; break;
} case 1:
case Mask::Kinematics::ONESTEP_RXN: counts.resize(4, 0);
{
Run1Step(file);
break; break;
} case 2:
case Mask::Kinematics::TWOSTEP: counts.resize(6, 0);
{
Run2Step(file);
break; break;
} case 3:
case Mask::Kinematics::THREESTEP: counts.resize(8, 0);
{
Run3Step(file);
break; break;
default:
{
std::cerr<<"Bad reaction type at AnasenEfficiency::CalculateEfficiency (given value: "<<header.rxn_type<<"). Quiting..."<<std::endl;
input.Close();
output.Close();
stats.close();
return;
} }
} }
int percent5 = header.nsamples*0.05;
int count = 0;
int npercent = 0;
while(true) {
if(++count == percent5) {//Show progress every 5%
npercent++;
count = 0;
std::cout<<"\rPercent completed: "<<npercent*5<<"%"<<std::flush;
}
data = input.ReadData();
if(data.eof)
break;
for(unsigned int i=0; i<data.Z.size(); i++) {
nucleus.SetIsotope(data.Z[i], data.A[i]);
nucleus.SetVectorSpherical(data.theta[i], data.phi[i], data.p[i], data.E[i]);
auto result = IsSabre(nucleus);
if(result.first) {
data.detect_flag[i] = true;
counts[i]++;
} else if(data.detect_flag[i] == true) {
data.detect_flag[i] = false;
}
}
output.WriteData(data);
}
input.Close();
output.Close();
stats<<std::setw(10)<<"Index"<<"|"<<std::setw(10)<<"Efficiency"<<std::endl;
stats<<"---------------------"<<std::endl;
for(unsigned int i=0; i<counts.size(); i++) {
stats<<std::setw(10)<<i<<"|"<<std::setw(10)<<((double)counts[i]/header.nsamples)<<std::endl;
stats<<"---------------------"<<std::endl;
}
stats.close();
std::cout<<std::endl; std::cout<<std::endl;
std::cout<<"Complete."<<std::endl; std::cout<<"Complete."<<std::endl;
std::cout<<"---------------------------------------------"<<std::endl; std::cout<<"---------------------------------------------"<<std::endl;
} }
void SabreEfficiency::DrawDetectorSystem(const std::string& filename) { void SabreEfficiency::DrawDetectorSystem(const std::string& filename) {
TFile* output = TFile::Open(filename.c_str(), "RECREATE"); std::ofstream output(filename);
std::vector<double> ringxs, ringys, ringzs; std::vector<double> ringxs, ringys, ringzs;
std::vector<double> wedgexs, wedgeys, wedgezs; std::vector<double> wedgexs, wedgeys, wedgezs;
@ -95,27 +149,16 @@ void SabreEfficiency::DrawDetectorSystem(const std::string& filename) {
} }
} }
TGraph2D* gr = new TGraph2D(ringxs.size(), &(ringxs[0]), &(ringys[0]), &(ringzs[0])); output<<"SABRE Geometry File -- Coordinates for Detectors"<<std::endl;
gr->SetName("ring_detector_edges"); output<<"Edges: x y z"<<std::endl;
gr->SetTitle("SABRE Detector; x(m); y(m); z(m)"); for(unsigned int i=0; i<ringxs.size(); i++) {
gr->SetMarkerStyle(1); output<<ringxs[i]<<" "<<ringys[i]<<" "<<ringzs[i]<<std::endl;
}
for(unsigned int i=0; i<wedgexs.size(); i++) {
output<<wedgexs[i]<<" "<<wedgeys[i]<<" "<<wedgezs[i]<<std::endl;
}
TGraph2D* gw = new TGraph2D(wedgexs.size(), &(wedgexs[0]), &(wedgeys[0]), &(wedgezs[0])); output.close();
gw->SetName("wedge_detector_edges");
gw->SetTitle("SABRE Detector Wedges; x(m); y(m); z(m)");
gw->SetMarkerStyle(1);
TCanvas* canvas = new TCanvas();
canvas->SetName("detector_system");
canvas->cd();
gr->Draw("AP");
gw->Draw("same P");
canvas->Write();
gr->Write();
gw->Write();
output->Close();
} }
double SabreEfficiency::RunConsistencyCheck() { double SabreEfficiency::RunConsistencyCheck() {
@ -141,263 +184,25 @@ double SabreEfficiency::RunConsistencyCheck() {
} }
/*Returns if detected, as well as total energy deposited in SABRE*/ /*Returns if detected, as well as total energy deposited in SABRE*/
std::pair<bool,double> SabreEfficiency::IsSabre(Mask::NucData* nucleus) { std::pair<bool,double> SabreEfficiency::IsSabre(Mask::Nucleus& nucleus) {
if(nucleus->KE <= ENERGY_THRESHOLD) { if(nucleus.GetKE() <= ENERGY_THRESHOLD) {
return std::make_pair(false, 0.0); return std::make_pair(false, 0.0);
} }
Mask::Vec3 coords; Mask::Vec3 coords;
double thetaIncident, eloss, e_deposited; double thetaIncident, eloss, e_deposited;
for(int i=0; i<5; i++) { for(int i=0; i<5; i++) {
auto chan = detectors[i].GetTrajectoryRingWedge(nucleus->theta, nucleus->phi); auto chan = detectors[i].GetTrajectoryRingWedge(nucleus.GetTheta(), nucleus.GetPhi());
if(chan.first != -1 && chan.second != -1) { if(chan.first != -1 && chan.second != -1) {
if(dmap.IsDead(i, chan.first, 0) || dmap.IsDead(i, chan.second, 1)) break; //dead channel check if(dmap.IsDead(i, chan.first, 0) || dmap.IsDead(i, chan.second, 1)) break; //dead channel check
coords = detectors[i].GetTrajectoryCoordinates(nucleus->theta, nucleus->phi); coords = detectors[i].GetTrajectoryCoordinates(nucleus.GetTheta(), nucleus.GetPhi());
thetaIncident = std::acos(coords.Dot(detectors[i].GetNormTilted())/(coords.GetR())); thetaIncident = std::acos(coords.Dot(detectors[i].GetNormTilted())/(coords.GetR()));
eloss = deadlayer.getEnergyLossTotal(nucleus->Z, nucleus->A, nucleus->KE, M_PI - thetaIncident); eloss = deadlayer.getEnergyLossTotal(nucleus.GetZ(), nucleus.GetA(), nucleus.GetKE(), M_PI - thetaIncident);
if((nucleus->KE - eloss) <= ENERGY_THRESHOLD) break; //deadlayer check if((nucleus.GetKE() - eloss) <= ENERGY_THRESHOLD) break; //deadlayer check
e_deposited = sabre_eloss.getEnergyLossTotal(nucleus->Z, nucleus->A, nucleus->KE - eloss, M_PI - thetaIncident); e_deposited = sabre_eloss.getEnergyLossTotal(nucleus.GetZ(), nucleus.GetA(), nucleus.GetKE() - eloss, M_PI - thetaIncident);
return std::make_pair(true, e_deposited); return std::make_pair(true, e_deposited);
} }
} }
return std::make_pair(false,0.0); return std::make_pair(false,0.0);
} }
void SabreEfficiency::RunDecay(const std::string& filename) {
TFile* input = TFile::Open(filename.c_str(), "UPDATE");
TTree* tree = (TTree*) input->Get("DataTree");
THashTable* table = new THashTable();
Mask::NucData* eject = new Mask::NucData();
Mask::NucData* resid = new Mask::NucData();
tree->SetBranchAddress("ejectile", &eject);
tree->SetBranchAddress("residual", &resid);
double nevents = tree->GetEntries();
//Progress tracking
int percent5 = nevents*0.05;
int count = 0;
int npercent = 0;
std::pair<bool, double> eject_result, resid_result;
int detected_eject=0, detected_resid=0;
for(int i=0; i<tree->GetEntries(); i++) {
if(++count == percent5) {//Show progress every 5%
npercent++;
count = 0;
std::cout<<"\rPercent completed: "<<npercent*5<<"%"<<std::flush;
}
tree->GetEntry(i);
eject_result = IsSabre(eject);
resid_result = IsSabre(resid);
if(eject_result.first) {
detected_eject++;
MyFill(table, "detected_eject_theta_ke","detected ejectile theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,eject->theta/DEG2RAD,300,0.0,30.0,eject->KE);
MyFill(table, "detected_eject_theta_edep","detected ejectile theta vs edep;#theta (deg);E deposited(MeV)",180,0.0,180.0,eject->theta/DEG2RAD,300,0.0,30.0,eject_result.second);
}
if(resid_result.first) {
detected_resid++;
MyFill(table, "detected_resid_theta_ke","detected residual theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,resid->theta/DEG2RAD,300,0.0,30.0,resid->KE);
MyFill(table, "detected_resid_theta_edep","detected residual theta vs edep;#theta (deg);E deposited(MeV)",180,0.0,180.0,resid->theta/DEG2RAD,300,0.0,30.0,resid_result.second);
}
}
double ejecteff = ((double) detected_eject)/nevents;
double resideff = ((double) detected_resid)/nevents;
TParameter<double> eject_eff("Ejectile Efficiency", ejecteff);
TParameter<double> resid_eff("Residual Efficiency", resideff);
input->cd();
eject_eff.Write();
resid_eff.Write();
table->Write();
input->Close();
}
void SabreEfficiency::Run1Step(const std::string& filename) {
std::cout<<"SabreEfficiency::Run1Step Not Implemented!"<<std::endl;
return;
}
void SabreEfficiency::Run2Step(const std::string& filename) {
TFile* input = TFile::Open(filename.c_str(), "UPDATE");
TTree* tree = (TTree*) input->Get("DataTree");
Mask::NucData* break1 = new Mask::NucData();
Mask::NucData* break2 = new Mask::NucData();
THashTable* table = new THashTable();
tree->SetBranchAddress("breakup1", &break1);
tree->SetBranchAddress("breakup2", &break2);
double nevents = tree->GetEntries();
//Progress tracking
int percent5 = nevents*0.05;
int count = 0;
int npercent = 0;
double costheta_cm =0;
std::pair<bool, double> break1_result, break2_result;
int detected_b1=0, detected_b2=0;
for(int i=0; i<tree->GetEntries(); i++) {
if(++count == percent5) {//Show progress every 5%
npercent++;
count = 0;
std::cout<<"\rPercent completed: "<<npercent*5<<"%"<<std::flush;
}
tree->GetEntry(i);
break1_result = IsSabre(break1);
break2_result = IsSabre(break2);
if(break1_result.first) {
detected_b1++;
costheta_cm = std::cos(break1->theta_cm);
MyFill(table,"detected_break1_cm_theta","cos(#theta_{CM})",20,-1.0,1.0,costheta_cm);
MyFill(table, "detected_break1_theta_ke","detected break1 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break1->theta/DEG2RAD,300,0.0,30.0,break1->KE);
MyFill(table, "detected_break1_theta_edep","detected break1 theta vs edep;#theta (deg);E deposited(MeV)",180,0.0,180.0,break1->theta/DEG2RAD,300,0.0,30.0,break1_result.second);
}
if(break2_result.first) {
detected_b2++;
MyFill(table, "detected_break2_theta_ke","detected break2 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break2->theta/DEG2RAD,300,0.0,30.0,break2->KE);
MyFill(table, "detected_break2_theta_edep","detected break2 theta vs edep;#theta (deg);E deposited(MeV)",180,0.0,180.0,break2->theta/DEG2RAD,300,0.0,30.0,break2_result.second);
}
}
double b1eff = ((double) detected_b1)/nevents;
double b2eff = ((double) detected_b2)/nevents;
TParameter<double> break1_eff("Breakup1 Efficiency", b1eff);
TParameter<double> break2_eff("Breakup2 Efficiency", b2eff);
input->cd();
table->Write();
break1_eff.Write();
break2_eff.Write();
input->Close();
}
void SabreEfficiency::Run3Step(const std::string& filename) {
TFile* input = TFile::Open(filename.c_str(), "UPDATE");
TTree* tree = (TTree*) input->Get("DataTree");
THashTable* table = new THashTable();
Mask::NucData* break1 = new Mask::NucData();
Mask::NucData* break3 = new Mask::NucData();
Mask::NucData* break4 = new Mask::NucData();
tree->SetBranchAddress("breakup1", &break1);
tree->SetBranchAddress("breakup3", &break3);
tree->SetBranchAddress("breakup4", &break4);
double nevents = tree->GetEntries();
//Progress tracking
int percent5 = nevents*0.05;
int count = 0;
int npercent = 0;
std::pair<bool, double> break1_result, break3_result, break4_result;
int detected_b1=0, detected_b3=0, detected_b4=0;
int b1b3_count=0, b1b4_count=0, b3b4_count=0, b1b3b4_count=0;
for(int i=0; i<tree->GetEntries(); i++) {
if(++count == percent5) {//Show progress every 5%
npercent++;
count = 0;
std::cout<<"\rPercent completed: "<<npercent*5<<"%"<<std::flush;
}
break1_result = IsSabre(break1);
break3_result = IsSabre(break3);
break4_result = IsSabre(break4);
tree->GetEntry(i);
if(break1_result.first) {
detected_b1++;
MyFill(table, "detected_break1_theta_ke","detected break1 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break1->theta/DEG2RAD,300,0.0,30.0,break1->KE);
MyFill(table, "detected_break1_theta_edep","detected break1 theta vs edep;#theta (deg);E deposited(MeV)",180,0.0,180.0,break1->theta/DEG2RAD,300,0.0,30.0,break1_result.second);
}
if(break3_result.first) {
detected_b3++;
MyFill(table, "detected_break3_theta_ke","detected break3 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break3->theta/DEG2RAD,300,0.0,30.0,break3->KE);
MyFill(table, "detected_break3_theta_edep","detected break3 theta vs edep;#theta (deg);E deposited(MeV)",180,0.0,180.0,break3->theta/DEG2RAD,300,0.0,30.0,break3_result.second);
}
if(break4_result.first) {
detected_b1++;
MyFill(table, "detected_break4_theta_ke","detected break4 theta vs ke;#theta (deg);KE(MeV)",180,0.0,180.0,break4->theta/DEG2RAD,300,0.0,30.0,break4->KE);
MyFill(table, "detected_break4_theta_edep","detected break4 theta vs edep;#theta (deg);E deposited(MeV)",180,0.0,180.0,break4->theta/DEG2RAD,300,0.0,30.0,break4_result.second);
}
if(break1_result.first && break3_result.first && break4_result.first) {
b1b3b4_count++;
b1b3_count++;
b1b4_count++;
b3b4_count++;
MyFill(table,"b3b4_theta_theta","b3b4_theta_theta;#theta_{3};#theta_{4}",180,0.0,180.0,break3->theta/DEG2RAD,180,0,180,break4->theta/DEG2RAD);
MyFill(table,"b3b4_ke_ke","b3b4_ke_ke;KE_{3};KE_{4}",150,0.0,15.0,break3->KE,150,0.0,15.0,break4->KE);
MyFill(table,"b3b4_phi_phi","b3b4_phi_phi;#phi_{3};#phi_{4}",360,0.0,360.0,break3->phi/DEG2RAD,360,0.0,360.0,break4->phi/DEG2RAD);
} else if(break1_result.first && break3_result.first) {
b1b3_count++;
} else if(break1_result.first && break4_result.first) {
b1b4_count++;
} else if(break3_result.first && break4_result.first) {
b3b4_count++;
MyFill(table,"b3b4_theta_theta","b3b4_theta_theta;#theta_{3};#theta_{4}",180,0.0,180.0,break3->theta/DEG2RAD,180,0,180,break4->theta/DEG2RAD);
MyFill(table,"b3b4_ke_ke","b3b4_ke_ke;KE_{3};KE_{4}",150,0.0,15.0,break3->KE,150,0.0,15.0,break4->KE);
MyFill(table,"b3b4_phi_phi","b3b4_phi_phi;#phi_{3};#phi_{4}",360,0.0,360.0,break3->phi/DEG2RAD,360,0.0,360.0,break4->phi/DEG2RAD);
}
}
double b1eff = ((double) detected_b1)/nevents;
double b3eff = ((double) detected_b3)/nevents;
double b4eff = ((double) detected_b4)/nevents;
double b1b3eff = b1b3_count/nevents;
double b1b4eff = b1b4_count/nevents;
double b3b4eff = b3b4_count/nevents;
double b1b3b4eff = b1b3b4_count/nevents;
TParameter<double> break1_eff("Breakup1 Efficiency", b1eff);
TParameter<double> break3_eff("Breakup3 Efficiency", b3eff);
TParameter<double> break4_eff("Breakup4 Efficiency", b4eff);
TParameter<double> b1b3_eff("Break1 Coincident with Break3", b1b3eff);
TParameter<double> b1b4_eff("Break1 Coincident with Break4", b1b4eff);
TParameter<double> b3b4_eff("Break3 Coincident with Break4", b3b4eff);
TParameter<double> b1b3b4_eff("All Breakups Coincident", b1b3b4eff);
input->cd();
break1_eff.Write();
break3_eff.Write();
break4_eff.Write();
b1b3_eff.Write();
b1b4_eff.Write();
b3b4_eff.Write();
b1b3b4_eff.Write();
table->Write();
input->Close();
}

View File

@ -13,7 +13,7 @@
*/ */
StripDetector::StripDetector(int ns, double len, double wid, double cphi, double cz, double crho) : StripDetector::StripDetector(int ns, double len, double wid, double cphi, double cz, double crho) :
m_random(nullptr) m_random(nullptr), m_uniform_fraction(0.0, 1.0)
{ {
num_strips = ns; num_strips = ns;
@ -88,7 +88,7 @@ Mask::Vec3 StripDetector::GetHitCoordinates(int front_stripch, double front_stri
double y; double y;
//If we have a random number generator, randomize y position within pixel. Otherwise take halfway. //If we have a random number generator, randomize y position within pixel. Otherwise take halfway.
if(m_random) { if(m_random) {
y = -total_width/2.0 + (front_stripch + m_random->Uniform(0.0, 1.0))*front_strip_width; y = -total_width/2.0 + (front_stripch + m_uniform_fraction(*m_random))*front_strip_width;
} else { } else {
y = -total_width/2.0 + (front_stripch+0.5)*front_strip_width; y = -total_width/2.0 + (front_stripch+0.5)*front_strip_width;
} }

View File

@ -46,7 +46,7 @@ double EnergyLoss::GetEnergyLoss(int zp, int ap, double e_initial, double thickn
if( ZP != zp) { if( ZP != zp) {
ZP = zp; ZP = zp;
AP = ap; AP = ap;
MP = MASS.FindMass(ZP, AP)*MEV2U; MP = MassLookup::GetInstance()->FindMass(ZP, AP)*MEV2U;
} }
double e_final = e_initial; double e_final = e_initial;
@ -98,7 +98,7 @@ double EnergyLoss::GetReverseEnergyLoss(int zp, int ap, double e_final, double t
if( ZP != zp) { if( ZP != zp) {
ZP = zp; ZP = zp;
AP = ap; AP = ap;
MP = MASS.FindMass(ZP, AP)*MEV2U; MP = MassLookup::GetInstance()->FindMass(ZP, AP)*MEV2U;
} }
double e_initial = e_final; double e_initial = e_final;

View File

@ -6,9 +6,12 @@
namespace Mask { namespace Mask {
Kinematics::Kinematics() : Kinematics::Kinematics() :
sys(nullptr), save_tree_flag(false), do_plotter_flag(false), global_generator(new TRandom3(0)) 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() {
@ -16,7 +19,7 @@ Kinematics::~Kinematics() {
if(sys) delete sys; if(sys) delete sys;
} }
bool Kinematics::LoadConfig(const char* filename) { bool Kinematics::LoadConfig(const std::string& filename) {
std::cout<<"Loading configuration in "<<filename<<"..."<<std::endl; std::cout<<"Loading configuration in "<<filename<<"..."<<std::endl;
std::ifstream input(filename); std::ifstream input(filename);
@ -29,9 +32,7 @@ bool Kinematics::LoadConfig(const char* filename) {
getline(input, junk); getline(input, junk);
input>>junk>>m_outfile_name; input>>junk>>m_outfile_name;
input>>junk>>junk; input>>junk>>junk;
if(junk == "yes") save_tree_flag = true;
input>>junk>>junk; input>>junk>>junk;
if(junk == "yes") do_plotter_flag = true;
std::vector<int> avec, zvec, svec; std::vector<int> avec, zvec, svec;
int z, a, s; int z, a, s;
@ -179,21 +180,7 @@ bool Kinematics::LoadConfig(const char* filename) {
return true; return true;
} }
bool Kinematics::SaveConfig(const char* filename) { return true; } bool Kinematics::SaveConfig(const std::string& filename) { return true; }
NucData Kinematics::ConvertNucleus(const Nucleus& nuc) {
NucData datum;
datum.E = nuc.GetE();
datum.KE = nuc.GetKE();
datum.p = nuc.GetP();
datum.theta = nuc.GetTheta();
datum.theta_cm = nuc.GetThetaCM();
datum.phi = nuc.GetPhi();
datum.Ex = nuc.GetExcitationEnergy();
datum.Z = nuc.GetZ();
datum.A = nuc.GetA();
return datum;
}
void Kinematics::Run() { void Kinematics::Run() {
std::cout<<"Running simulation..."<<std::endl; std::cout<<"Running simulation..."<<std::endl;
@ -230,17 +217,10 @@ void Kinematics::RunOneStepRxn() {
return; return;
} }
MaskFile output(m_outfile_name, MaskFile::FileType::write);
TFile* output = TFile::Open(m_outfile_name.c_str(), "RECREATE"); std::vector<Nucleus> data;
TTree* tree; data.resize(4);
NucData targ, proj, eject, residual; output.WriteHeader(m_rxn_type, m_nsamples);
if(save_tree_flag) {
tree = new TTree("DataTree","DataTree");
tree->Branch("target", &targ);
tree->Branch("projectile", &proj);
tree->Branch("ejectile", &eject);
tree->Branch("residual", &residual);
}
//For progress tracking //For progress tracking
@ -248,8 +228,6 @@ void Kinematics::RunOneStepRxn() {
int count = 0; int count = 0;
int npercent = 0; int npercent = 0;
std::vector<Nucleus> data;
data.resize(4);
for(int i=0; i<m_nsamples; i++) { for(int i=0; i<m_nsamples; i++) {
if(++count == percent5) {//Show update every 5 percent if(++count == percent5) {//Show update every 5 percent
npercent++; npercent++;
@ -258,32 +236,15 @@ void Kinematics::RunOneStepRxn() {
} }
this_sys->RunSystem(); this_sys->RunSystem();
data[0] = this_sys->GetTarget();
if(save_tree_flag) { data[1] = this_sys->GetProjectile();
targ = ConvertNucleus(this_sys->GetTarget()); data[2] = this_sys->GetEjectile();
proj = ConvertNucleus(this_sys->GetProjectile()); data[3] = this_sys->GetResidual();
eject = ConvertNucleus(this_sys->GetEjectile()); output.WriteData(data);
residual = ConvertNucleus(this_sys->GetResidual());
tree->Fill();
}
if(do_plotter_flag) {
plotman.FillData(this_sys->GetTarget(), "targ");
plotman.FillData(this_sys->GetProjectile(), "proj");
plotman.FillData(this_sys->GetEjectile(), "eject");
plotman.FillData(this_sys->GetResidual(), "resid");
}
} }
output.Close();
output->cd();
if(save_tree_flag) tree->Write(tree->GetName(), TObject::kOverwrite);
if(do_plotter_flag) {
plotman.GetTable()->Write();
plotman.ClearTable();
}
output->Close();
} }
void Kinematics::RunOneStepDecay() { void Kinematics::RunOneStepDecay() {
@ -292,15 +253,10 @@ void Kinematics::RunOneStepDecay() {
return; return;
} }
TFile* output = TFile::Open(m_outfile_name.c_str(), "RECREATE"); MaskFile output(m_outfile_name, MaskFile::FileType::write);
TTree* tree; std::vector<Nucleus> data;
NucData targ, eject, residual; data.resize(3);
if(save_tree_flag) { output.WriteHeader(m_rxn_type, m_nsamples);
tree = new TTree("DataTree","DataTree");
tree->Branch("target", &targ);
tree->Branch("ejectile", &eject);
tree->Branch("residual", &residual);
}
//For progress tracking //For progress tracking
int percent5 = 0.05*m_nsamples; int percent5 = 0.05*m_nsamples;
@ -315,27 +271,13 @@ void Kinematics::RunOneStepDecay() {
} }
this_sys->RunSystem(); this_sys->RunSystem();
if(save_tree_flag) { data[0] = this_sys->GetTarget();
targ = ConvertNucleus(this_sys->GetTarget()); data[1] = this_sys->GetEjectile();
eject = ConvertNucleus(this_sys->GetEjectile()); data[2] = this_sys->GetResidual();
residual = ConvertNucleus(this_sys->GetResidual()); output.WriteData(data);
tree->Fill();
}
if(do_plotter_flag) {
plotman.FillData(this_sys->GetTarget(), "targ");
plotman.FillData(this_sys->GetEjectile(), "eject");
plotman.FillData(this_sys->GetResidual(), "resid");
} }
} output.Close();
output->cd();
if(save_tree_flag) tree->Write(tree->GetName(), TObject::kOverwrite);
if(do_plotter_flag) {
plotman.GetTable()->Write();
plotman.ClearTable();
}
output->Close();
} }
void Kinematics::RunTwoStep() { void Kinematics::RunTwoStep() {
@ -345,21 +287,10 @@ void Kinematics::RunTwoStep() {
return; return;
} }
MaskFile output(m_outfile_name, MaskFile::FileType::write);
TFile* output = TFile::Open(m_outfile_name.c_str(), "RECREATE"); std::vector<Nucleus> data;
TTree* tree; data.resize(6);
NucData targ, proj, eject, residual, break1, break2; output.WriteHeader(m_rxn_type, m_nsamples);
if(save_tree_flag) {
tree = new TTree("DataTree","DataTree");
tree->Branch("target", &targ);
tree->Branch("projectile", &proj);
tree->Branch("ejectile", &eject);
tree->Branch("residual", &residual);
tree->Branch("breakup1", &break1);
tree->Branch("breakup2", &break2);
}
//For progress tracking //For progress tracking
int percent5 = 0.05*m_nsamples; int percent5 = 0.05*m_nsamples;
@ -374,35 +305,16 @@ void Kinematics::RunTwoStep() {
} }
this_sys->RunSystem(); this_sys->RunSystem();
if(save_tree_flag) { data[0] = this_sys->GetTarget();
targ = ConvertNucleus(this_sys->GetTarget()); data[1] = this_sys->GetProjectile();
proj = ConvertNucleus(this_sys->GetProjectile()); data[2] = this_sys->GetEjectile();
eject = ConvertNucleus(this_sys->GetEjectile()); data[3] = this_sys->GetResidual();
residual = ConvertNucleus(this_sys->GetResidual()); data[4] = this_sys->GetBreakup1();
break1 = ConvertNucleus(this_sys->GetBreakup1()); data[5] = this_sys->GetBreakup2();
break2 = ConvertNucleus(this_sys->GetBreakup2()); output.WriteData(data);
tree->Fill();
}
if(do_plotter_flag) {
plotman.FillData(this_sys->GetTarget(), "targ");
plotman.FillData(this_sys->GetProjectile(), "proj");
plotman.FillData(this_sys->GetEjectile(), "eject");
plotman.FillData(this_sys->GetResidual(), "resid");
plotman.FillData(this_sys->GetBreakup1(), "break1");
plotman.FillData(this_sys->GetBreakup2(), "break2");
} }
} output.Close();
output->cd();
if(save_tree_flag) tree->Write(tree->GetName(), TObject::kOverwrite);
if(do_plotter_flag) {
plotman.GetTable()->Write();
plotman.ClearTable();
}
output->Close();
} }
void Kinematics::RunThreeStep() { void Kinematics::RunThreeStep() {
@ -412,20 +324,10 @@ void Kinematics::RunThreeStep() {
return; return;
} }
TFile* output = TFile::Open(m_outfile_name.c_str(), "RECREATE"); MaskFile output(m_outfile_name, MaskFile::FileType::write);
TTree* tree; std::vector<Nucleus> data;
NucData targ, proj, eject, residual, break1, break2, break3, break4; data.resize(8);
if(save_tree_flag) { output.WriteHeader(m_rxn_type, m_nsamples);
tree = new TTree("DataTree","DataTree");
tree->Branch("target", &targ);
tree->Branch("projectile", &proj);
tree->Branch("ejectile", &eject);
tree->Branch("residual", &residual);
tree->Branch("breakup1", &break1);
tree->Branch("breakup2", &break2);
tree->Branch("breakup3", &break3);
tree->Branch("breakup4", &break4);
}
//For progress updating //For progress updating
int percent5 = 0.05*m_nsamples; int percent5 = 0.05*m_nsamples;
@ -440,36 +342,18 @@ void Kinematics::RunThreeStep() {
} }
this_sys->RunSystem(); this_sys->RunSystem();
if(save_tree_flag) { data[0] = this_sys->GetTarget();
targ = ConvertNucleus(this_sys->GetTarget()); data[1] = this_sys->GetProjectile();
proj = ConvertNucleus(this_sys->GetProjectile()); data[2] = this_sys->GetEjectile();
eject = ConvertNucleus(this_sys->GetEjectile()); data[3] = this_sys->GetResidual();
residual = ConvertNucleus(this_sys->GetResidual()); data[4] = this_sys->GetBreakup1();
break1 = ConvertNucleus(this_sys->GetBreakup1()); data[5] = this_sys->GetBreakup2();
break2 = ConvertNucleus(this_sys->GetBreakup2()); data[6] = this_sys->GetBreakup3();
break3 = ConvertNucleus(this_sys->GetBreakup3()); data[7] = this_sys->GetBreakup4();
break4 = ConvertNucleus(this_sys->GetBreakup4()); output.WriteData(data);
tree->Fill();
}
if(do_plotter_flag) {
plotman.FillData(this_sys->GetTarget(), "targ");
plotman.FillData(this_sys->GetProjectile(), "proj");
plotman.FillData(this_sys->GetEjectile(), "eject");
plotman.FillData(this_sys->GetResidual(), "resid");
plotman.FillData(this_sys->GetBreakup1(), "break1");
plotman.FillData(this_sys->GetBreakup2(), "break2");
plotman.FillData(this_sys->GetBreakup3(), "break3");
plotman.FillData(this_sys->GetBreakup4(), "break4");
}
} }
output->cd(); output.Close();
if(save_tree_flag) tree->Write(tree->GetName(), TObject::kOverwrite);
if(do_plotter_flag) {
plotman.GetTable()->Write();
plotman.ClearTable();
}
output->Close();
} }
}; }

View File

@ -3,15 +3,33 @@
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
/*
FORMAT
HEADER (contains rxntype & nuclei numbers & beam kinetic energy) (64 bits, 8 bytes)
NSAMPLES(32bit) RXNTYPE(32bit)
end HEADER
There are NSAMPLES * (number of saved nuclei) data in the file. The number of nuclei saved is related to the
RXNTYPE. All nuclei (target, projectile, ejectile, residual, break1, etc...) are saved. A datum is as follows:
DATUM (contains kinematic data for a nucleus) (384 bits, 48 bytes)
Z(32bit) A(32bit) DETECTFLAG(32bit) E(64bit) KE(64bit) P(64bit) THETA(64bit) PHI(64bit)
end DATUM
*/
namespace Mask { namespace Mask {
MaskFile::MaskFile() : MaskFile::MaskFile() :
file_type(MaskFile::FileType::none), filename(""), buffer_position(0), count(0), file() file_type(MaskFile::FileType::none), filename(""), buffer_position(0), buffer_end(0), data_size(0), buffersize_bytes(0), file()
{ {
} }
MaskFile::MaskFile(const std::string& name, MaskFile::FileType type) : MaskFile::MaskFile(const std::string& name, MaskFile::FileType type) :
file_type(type), filename(name), buffer_position(0), count(0), file() file_type(type), filename(name), buffer_position(0), buffer_end(0), data_size(0), buffersize_bytes(0), file()
{ {
Open(filename, type); Open(filename, type);
} }
@ -25,155 +43,296 @@ bool MaskFile::Open(const std::string& name, MaskFile::FileType type) {
if(type == FileType::read) { if(type == FileType::read) {
file.open(name, std::ios::in); file.open(name, std::ios::in);
buffer_position = 0; buffer_position = 0;
if(IsOpen()) ReadHeader();
} else if (type == FileType::write) { } else if (type == FileType::write) {
file.open(name, std::ios::out | std::ios::trunc); file.open(name, std::ios::out | std::ios::trunc);
file<<std::setprecision(precision);
file<<std::scientific;
} else if (type == FileType::append) { } else if (type == FileType::append) {
file.open(name, std::ios::out | std::ios::app); file.open(name, std::ios::out | std::ios::app);
file<<std::setprecision(precision);
file<<std::scientific;
} else { } else {
std::cerr<<"Invalid FileType at MaskFile::Open()"<<std::endl; std::cerr<<"Invalid FileType at MaskFile::Open()"<<std::endl;
return IsOpen(); return IsOpen();
} }
count = 0;
return IsOpen(); return IsOpen();
} }
void MaskFile::Close() { void MaskFile::Close() {
if(data_buffer.size() > 0) { //Final flush (if necessary)
FlushBuffer(); if(buffer_position > 0 && buffer_position < buffersize_bytes && (file_type == FileType::write || file_type == FileType::append)) {
file.write(data_buffer.data(), buffer_position);
} }
file.close(); file.close();
} }
void MaskFile::WriteHeader(std::vector<Nucleus>& nuclei) { void MaskFile::WriteHeader(int rxn_type, int nsamples) {
file<<std::setw(width)<<"ZT"<<"," //size of a datum = data nuclei per event * (# doubles per nucleus * sizeof double + # ints per nucleus * sizeof int + sizeof bool)
<<std::setw(width)<<"AT"<<"," if(rxn_type == 0) {
<<std::setw(width)<<"ZP"<<"," m_rxn_type = 0;
<<std::setw(width)<<"AP"<<"," data_size = 3 * ( 5 * double_size + 2 * int_size + bool_size);
<<std::setw(width)<<"ZE"<<","
<<std::setw(width)<<"AE"<<","
<<std::setw(width)<<"ZR"<<","
<<std::setw(width)<<"AR"<<","
<<std::setw(width)<<"ZB1"<<","
<<std::setw(width)<<"AB1"<<","
<<std::setw(width)<<"ZB2"<<","
<<std::setw(width)<<"AB2"<<","
<<std::setw(width)<<"ZB3"<<","
<<std::setw(width)<<"AB3"<<","
<<std::setw(width)<<"ZB4"<<","
<<std::setw(width)<<"AB4"<<","
<<std::setw(width)<<"KEP"<<","
<<std::endl;
file<<std::setw(width)<<nuclei[0].GetZ()<<","
<<std::setw(width)<<nuclei[0].GetA()<<","
<<std::setw(width)<<nuclei[1].GetZ()<<","
<<std::setw(width)<<nuclei[1].GetA()<<","
<<std::setw(width)<<nuclei[2].GetZ()<<","
<<std::setw(width)<<nuclei[2].GetA()<<","
<<std::setw(width)<<nuclei[3].GetZ()<<","
<<std::setw(width)<<nuclei[3].GetA()<<",";
if(nuclei.size() == 6) {
file<<std::setw(width)<<nuclei[4].GetZ()<<","
<<std::setw(width)<<nuclei[4].GetA()<<","
<<std::setw(width)<<nuclei[5].GetZ()<<","
<<std::setw(width)<<nuclei[5].GetA()<<",";
} else if(nuclei.size() == 8) {
file<<std::setw(width)<<nuclei[4].GetZ()<<","
<<std::setw(width)<<nuclei[4].GetA()<<","
<<std::setw(width)<<nuclei[5].GetZ()<<","
<<std::setw(width)<<nuclei[5].GetA()<<","
<<std::setw(width)<<nuclei[6].GetZ()<<","
<<std::setw(width)<<nuclei[6].GetA()<<","
<<std::setw(width)<<nuclei[7].GetZ()<<","
<<std::setw(width)<<nuclei[7].GetA()<<",";
} }
file<<std::setw(width)<<nuclei[1].GetKE()<<","; else if (rxn_type == 1) {
file<<std::endl; m_rxn_type = 1;
data_size = 4 * ( 5 * double_size + 2 * int_size + bool_size);
}
else if (rxn_type == 2) {
m_rxn_type = 2;
data_size = 6 * ( 5 * double_size + 2 * int_size + bool_size);
}
else if (rxn_type == 3) {
m_rxn_type = 3;
data_size = 8 * ( 5 * double_size + 2 * int_size + bool_size);
} else {
std::cerr<<"Invalid number of nuclei at MaskFile::WriteHeader! Returning"<<std::endl;
return;
}
buffersize_bytes = buffersize * data_size; //buffersize_bytes = # of events * size of an event
file<<std::setw(width)<<"Event"<<"," data_buffer.resize(buffersize_bytes);
<<std::setw(width)<<"EE"<<","<<std::setw(width)<<"KEE"<<","<<std::setw(width)<<"PE"<<","<<std::setw(width)<<"ThetaE"<<","<<std::setw(width)<<"PhiE"<<","<<std::setw(width)<<"ThetaCME"<<","
<<std::setw(width)<<"ER"<<","<<std::setw(width)<<"KER"<<","<<std::setw(width)<<"PR"<<","<<std::setw(width)<<"ThetaR"<<","<<std::setw(width)<<"PhiR"<<","<<std::setw(width)<<"ThetaCMR"<<"," file.write((char*) &nsamples, int_size);
<<std::setw(width)<<"EB1"<<","<<std::setw(width)<<"KEB1"<<","<<std::setw(width)<<"PB1"<<","<<std::setw(width)<<"ThetaB1"<<","<<std::setw(width)<<"PhiB1"<<","<<std::setw(width)<<"ThetaCMB1"<<"," file.write((char*) &m_rxn_type, int_size);
<<std::setw(width)<<"EB2"<<","<<std::setw(width)<<"KEB2"<<","<<std::setw(width)<<"PB2"<<","<<std::setw(width)<<"ThetaB2"<<","<<std::setw(width)<<"PhiB2"<<","<<std::setw(width)<<"ThetaCMB2"<<","
<<std::setw(width)<<"EB3"<<","<<std::setw(width)<<"KEB3"<<","<<std::setw(width)<<"PB3"<<","<<std::setw(width)<<"ThetaB3"<<","<<std::setw(width)<<"PhiB3"<<","<<std::setw(width)<<"ThetaCMB3"<<","
<<std::setw(width)<<"EB4"<<","<<std::setw(width)<<"KEB4"<<","<<std::setw(width)<<"PB4"<<","<<std::setw(width)<<"ThetaB4"<<","<<std::setw(width)<<"PhiB4"<<","<<std::setw(width)<<"ThetaCMB4"<<","
<<std::endl;
} }
void MaskFile::ReadHeader() { MaskFileHeader MaskFile::ReadHeader() {
std::string junk; MaskFileHeader header;
std::getline(file, junk); std::vector<char> temp_buffer(4);
file.read(temp_buffer.data(), 4);
header.nsamples = *(int*)(&temp_buffer[0]);
file.read(temp_buffer.data(), 4);
m_rxn_type = *(int*)(&temp_buffer[0]);
//size of a datum = data nuclei per event * (# doubles per nucleus * sizeof double + # ints per nucleus * sizeof int + sizeof bool)
if(m_rxn_type == 0) {
data_size = 3 * ( 5 * double_size + 2 * int_size + bool_size);
}
else if (m_rxn_type == 1) {
data_size = 4 * ( 5 * double_size + 2 * int_size + bool_size);
}
else if (m_rxn_type == 2) {
data_size = 6 * ( 5 * double_size + 2 * int_size + bool_size);
}
else if (m_rxn_type == 3) {
data_size = 8 * ( 5 * double_size + 2 * int_size + bool_size);
} else {
std::cerr<<"Unexpected reaction type at MaskFile::ReadHeader (rxn type = "<<m_rxn_type<<")! Returning"<<std::endl;
return header;
}
buffersize_bytes = buffersize * data_size;//buffersize_bytes = size of a datum * # of events
header.rxn_type = m_rxn_type;
data_buffer.resize(buffersize_bytes);
return header;
} }
void MaskFile::WriteData(std::vector<Nucleus>& data) { void MaskFile::WriteData(std::vector<Nucleus>& data) {
if(count == 0 && data_buffer.size() == 0) {
WriteHeader(data); char* data_pointer;
double datum;
int number;
bool flag;
std::size_t j;
for(unsigned int i=0; i<data.size(); i++) {
number = data[i].GetZ();
data_pointer = (char*) &number;
for(j=0; j<int_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
} }
data_buffer.push_back(data); number = data[i].GetA();
if(data_buffer.size() == buffersize) { data_pointer = (char*) &number;
FlushBuffer(); for(j=0; j<int_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
flag = data[i].IsDetected();
data_pointer = (char*) &flag;
for(j=0; j<bool_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data[i].GetE();
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data[i].GetKE();
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data[i].GetP();
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data[i].GetTheta();
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data[i].GetPhi();
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
} }
} }
void MaskFile::FlushBuffer() { //Flush the buffer when it is full, and reset the position.
for(auto& event : data_buffer) { if(buffer_position == buffersize_bytes) {
file<<std::setw(width)<<count<<","; file.write(data_buffer.data(), data_buffer.size());
for(unsigned int i=2; i< event.size(); i++) {
Nucleus& nuc = event[i];
file<<std::setw(width)<<nuc.GetE()<<","
<<std::setw(width)<<nuc.GetKE()<<","
<<std::setw(width)<<nuc.GetP()<<","
<<std::setw(width)<<nuc.GetTheta()<<","
<<std::setw(width)<<nuc.GetPhi()<<","
<<std::setw(width)<<nuc.GetThetaCM()<<",";
}
file<<std::endl;
count++;
}
data_buffer.clear();
}
std::vector<Nucleus> MaskFile::ReadData() {
if(buffer_position == data_buffer.size()) {
FillBuffer();
buffer_position = 0; buffer_position = 0;
} }
std::vector<Nucleus> data = data_buffer[buffer_position]; }
void MaskFile::WriteData(MaskFileData& data) {
char* data_pointer;
double datum;
int number;
bool flag;
std::size_t j;
for(unsigned int i=0; i<data.Z.size(); i++) {
number = data.Z[i];
data_pointer = (char*) &number;
for(j=0; j<int_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++; buffer_position++;
}
number = data.A[i];
data_pointer = (char*) &number;
for(j=0; j<int_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
flag = data.detect_flag[i];
data_pointer = (char*) &flag;
for(j=0; j<bool_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data.E[i];
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data.KE[i];
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data.p[i];
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data.theta[i];
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
datum = data.phi[i];
data_pointer = (char*) &datum;
for(j=0; j<double_size; j++) {
data_buffer[buffer_position] = *(data_pointer + j);
buffer_position++;
}
}
//Flush the buffer when it is full, and reset the position.
if(buffer_position == buffersize_bytes) {
file.write(data_buffer.data(), data_buffer.size());
buffer_position = 0;
}
}
/*
Read data from the buffer and submit it to the client side as a MaskFileData struct.
When file reaches the end of the file (no more data to read), an empty MaskFileData with
eof == true is sent out signaling that the file is finished.
Should be used like
Mask::MaskFile input(file, Mask::MaskFile::FileType::read);
Mask::MaskFileHeader header = input.ReadHeader();
Mask::MaskFileData data;
while(true) {
data = input.ReadData();
if(data.eof) break;
Do some stuff...
}
input.Close();
Good luck
*/
MaskFileData MaskFile::ReadData() {
MaskFileData data;
//Fill the buffer when needed, reset the positon, and find the end
if(buffer_position == data_buffer.size() || buffer_position == buffer_end) {
file.read(data_buffer.data(), buffersize_bytes);
buffer_position = 0;
buffer_end = file.gcount();
if(buffer_end == 0 && file.eof()) {
data.eof = true;
return data;
}
}
unsigned int local_end = buffer_position + data_size;
if(local_end > buffer_end) {
std::cerr<<"Attempting to read past end of file at MaskFile::ReadData! Returning empty"<<std::endl;
data.eof = true;
return data;
}
while(buffer_position < local_end) {
data.Z.push_back(*(int*)(&data_buffer[buffer_position]));
buffer_position += int_size;
data.A.push_back(*(int*)(&data_buffer[buffer_position]));
buffer_position += int_size;
data.detect_flag.push_back(*(bool*)(&data_buffer[buffer_position]));
buffer_position += bool_size;
data.E.push_back(*(double*)(&data_buffer[buffer_position]));
buffer_position += double_size;
data.KE.push_back(*(double*)(&data_buffer[buffer_position]));
buffer_position += double_size;
data.p.push_back(*(double*)(&data_buffer[buffer_position]));
buffer_position += double_size;
data.theta.push_back(*(double*)(&data_buffer[buffer_position]));
buffer_position += double_size;
data.phi.push_back(*(double*)(&data_buffer[buffer_position]));
buffer_position += double_size;
}
return data; return data;
} }
void MaskFile::FillBuffer() {
std::vector<Nucleus> data;
std::string line;
std::stringstream linebuf;
std::string junk;
int Z, A;
double E, p, theta, phi, tcm;
data_buffer.clear();
while(data_buffer.size() <= buffersize) {
if(!std::getline(file, line)) break;
linebuf.str(line);
while(linebuf>>Z) {
linebuf>>A;
linebuf>>E>>junk>>junk>>p>>theta>>phi>>tcm;
data.emplace_back(Z, A);
data[data.size()-1].SetVectorSpherical(theta, phi, p, E);
data[data.size()-1].SetThetaCM(tcm);
}
data_buffer.push_back(data);
data.clear();
}
}
}; };

View File

@ -16,6 +16,9 @@ Written by G.W. McCann Aug. 2020
Read in AMDC mass file, preformated to remove excess info. Here assumes that by default Read in AMDC mass file, preformated to remove excess info. Here assumes that by default
the file is in a local directory etc/ the file is in a local directory etc/
*/ */
MassLookup* MassLookup::s_instance = nullptr;
MassLookup::MassLookup() { MassLookup::MassLookup() {
std::ifstream massfile("./etc/mass.txt"); std::ifstream massfile("./etc/mass.txt");
if(massfile.is_open()) { if(massfile.is_open()) {
@ -46,13 +49,6 @@ double MassLookup::FindMass(int Z, int A) {
throw MassException(); throw MassException();
} }
return data->second; return data->second;
/*try {
double mass = massTable.at(key);
return mass;
} catch (std::out_of_range& oor) {
std::cerr<<"Mass of "<<key<<" (Z,A) not found in Mass Table! Returning 1"<<std::endl;
return 1;
}*/
} }
//returns element symbol //returns element symbol
@ -63,14 +59,4 @@ std::string MassLookup::FindSymbol(int Z, int A) {
} }
std::string fullsymbol = std::to_string(A) + data->second; std::string fullsymbol = std::to_string(A) + data->second;
return fullsymbol; return fullsymbol;
/*try {
std::string element = elementTable.at(Z);
std::string fullsymbol = std::to_string(A) + element;
return fullsymbol;
} catch (std::out_of_range& oor) {
std::cerr<<"Atomic number: "<<Z<<" not found in Element Table! Returning void."<<std::endl;
std::string element = "void";
return element;
}*/
} }

View File

@ -12,23 +12,23 @@
namespace Mask { namespace Mask {
Nucleus::Nucleus () : Nucleus::Nucleus () :
Vec4(), m_z(0), m_a(0), m_gs_mass(0), m_theta_cm(0), m_symbol("") Vec4(), m_z(0), m_a(0), m_gs_mass(0), m_theta_cm(0), m_symbol(""), m_detectFlag(false)
{ {
} }
Nucleus::Nucleus(int Z, int A) : Nucleus::Nucleus(int Z, int A) :
Vec4(), m_z(Z), m_a(A), m_theta_cm(0) Vec4(), m_z(Z), m_a(A), m_theta_cm(0), m_detectFlag(false)
{ {
m_gs_mass = MASS.FindMass(Z, A); m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A);
m_symbol = MASS.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 = MASS.FindMass(Z, A); m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A);
m_symbol = MASS.FindSymbol(Z, A); m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A);
} }
Nucleus::~Nucleus() {} Nucleus::~Nucleus() {}
@ -38,8 +38,8 @@ bool Nucleus::SetIsotope(int Z, int A) {
m_z = Z; m_z = Z;
m_a = A; m_a = A;
m_gs_mass = MASS.FindMass(Z, A); m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A);
m_symbol = MASS.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

@ -57,10 +57,10 @@ void OneStepSystem::RunSystem() {
if(!step1.IsDecay()) { if(!step1.IsDecay()) {
//Sample parameters //Sample parameters
double bke = generator->Gaus(m_beamDist.first, m_beamDist.second); double bke = (*m_beamDist)(*generator);
double rxnTheta = acos(generator->Uniform(cos(m_theta1Range.first), cos(m_theta1Range.second))); double rxnTheta = std::acos((*m_theta1Range)(*generator));
double rxnPhi = generator->Uniform(m_phi1Range.first, m_phi1Range.second); double rxnPhi = (*m_phi1Range)(*generator);
double residEx = generator->Gaus(m_exDist.first, m_exDist.second); double residEx = (*m_exDist)(*generator);
step1.SetBeamKE(bke); step1.SetBeamKE(bke);
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);

View File

@ -1,89 +0,0 @@
#include "Plotter.h"
#include <iostream>
namespace Mask {
Plotter::Plotter() :
table(new THashTable())
{
}
Plotter::~Plotter() {
for(unsigned int i=0; i<garbage_collection.size(); i++) {
delete garbage_collection[i];
}
garbage_collection.clear();
delete table;
}
void Plotter::FillData(const Nucleus& nuc, const std::string& modifier) {
std::string sym = nuc.GetIsotopicSymbol();
std::string ke_vs_th_name = sym + modifier + "_ke_vs_theta";
std::string ke_vs_th_title = ke_vs_th_name + ";#theta_{lab} (degrees);Kinetic Energy (MeV)";
std::string ke_vs_ph_name = sym + modifier + "_ke_vs_phi";
std::string ke_vs_ph_title = ke_vs_ph_name + ";#phi_{lab} (degrees);Kinetic Energy (MeV)";
std::string ex_name = sym + modifier + "_ex";
std::string ex_title = ex_name + ";E_{ex} (MeV);counts";
std::string angdist_name = sym + modifier +"_angDist";
std::string angdist_title = angdist_name+";cos#right(#theta_{CM}#left);counts";
MyFill(ke_vs_th_name.c_str(), ke_vs_th_title.c_str(), nuc.GetTheta()*rad2deg, nuc.GetKE(), 2);
MyFill(ke_vs_ph_name.c_str(), ke_vs_ph_title.c_str(), nuc.GetPhi()*rad2deg, nuc.GetKE(), 4);
MyFill(ex_name.c_str(),ex_title.c_str(),260,-1.0,25,nuc.GetExcitationEnergy());
MyFill(angdist_name.c_str(), angdist_title.c_str(),100,-1.0,1.0,std::cos(nuc.GetThetaCM()));
}
void Plotter::MyFill(const char* name, const char* title, int bins, float min, float max, double val) {
TH1F* h = (TH1F*) table->FindObject(name);
if(h) {
h->Fill(val);
} else {
h = new TH1F(name, title, bins, min, max);
h->Fill(val);
table->Add(h);
}
}
void Plotter::MyFill(const char* name, const char* title, int binsx, float minx, float maxx, int binsy, float miny, float maxy, double valx, double valy) {
TH2F* h = (TH2F*) table->FindObject(name);
if(h) {
h->Fill(valx, valy);
} else {
h = new TH2F(name, title, binsx, minx, maxx, binsy, miny, maxy);
h->Fill(valx, valy);
table->Add(h);
}
}
void Plotter::MyFill(const char* name, const char* title, double valx, double valy, int color) {
for(auto& g : graphs) {
if(g.name == name) {
g.xvec.push_back(valx);
g.yvec.push_back(valy);
return;
}
}
GraphData new_g;
new_g.name = name;
new_g.title = title;
new_g.xvec.push_back(valx);
new_g.yvec.push_back(valy);
new_g.color = color;
graphs.push_back(new_g);
}
void Plotter::GenerateGraphs() {
for(auto& g : graphs) {
TGraph* graph = new TGraph(g.xvec.size(), &(g.xvec[0]), &(g.yvec[0]));
graph->SetName(g.name.c_str());
graph->SetTitle(g.title.c_str());
graph->SetMarkerColor(g.color);
table->Add(graph);
garbage_collection.push_back(graph);
}
}
};

View File

@ -0,0 +1,137 @@
#include "RootPlotter.h"
#include "MaskFile.h"
#include <TFile.h>
#include <iostream>
RootPlotter::RootPlotter() :
table(new THashTable())
{
}
RootPlotter::~RootPlotter() {}
void RootPlotter::FillData(const Mask::Nucleus& nuc, const std::string& modifier) {
std::string sym = nuc.GetIsotopicSymbol();
std::string ke_vs_th_name = sym + modifier + "_ke_vs_theta";
std::string ke_vs_th_title = ke_vs_th_name + ";#theta_{lab} (degrees);Kinetic Energy (MeV)";
std::string ke_vs_ph_name = sym + modifier + "_ke_vs_phi";
std::string ke_vs_ph_title = ke_vs_ph_name + ";#phi_{lab} (degrees);Kinetic Energy (MeV)";
std::string ex_name = sym + modifier + "_ex";
std::string ex_title = ex_name + ";E_{ex} (MeV);counts";
std::string angdist_name = sym + modifier +"_angDist";
std::string angdist_title = angdist_name+";cos#right(#theta_{CM}#left);counts";
MyFill(ke_vs_th_name.c_str(), ke_vs_th_title.c_str(), nuc.GetTheta()*rad2deg, nuc.GetKE(), 2);
MyFill(ke_vs_ph_name.c_str(), ke_vs_ph_title.c_str(), nuc.GetPhi()*rad2deg, nuc.GetKE(), 4);
MyFill(ex_name.c_str(),ex_title.c_str(),260,-1.0,25,nuc.GetExcitationEnergy());
MyFill(angdist_name.c_str(), angdist_title.c_str(),100,-1.0,1.0,std::cos(nuc.GetThetaCM()));
}
void RootPlotter::MyFill(const std::string& name, const std::string& title, int bins, float min, float max, double val) {
TH1F* h = (TH1F*) table->FindObject(name.c_str());
if(h) {
h->Fill(val);
} else {
h = new TH1F(name.c_str(), title.c_str(), bins, min, max);
h->Fill(val);
table->Add(h);
}
}
void RootPlotter::MyFill(const std::string& name, const std::string& title, int binsx, float minx, float maxx, int binsy, float miny, float maxy, double valx, double valy) {
TH2F* h = (TH2F*) table->FindObject(name.c_str());
if(h) {
h->Fill(valx, valy);
} else {
h = new TH2F(name.c_str(), title.c_str(), binsx, minx, maxx, binsy, miny, maxy);
h->Fill(valx, valy);
table->Add(h);
}
}
void RootPlotter::MyFill(const std::string& name, const std::string& title, double valx, double valy, int color) {
for(auto& g : graphs) {
if(g.name == name) {
g.xvec.push_back(valx);
g.yvec.push_back(valy);
return;
}
}
GraphData new_g;
new_g.name = name;
new_g.title = title;
new_g.xvec.push_back(valx);
new_g.yvec.push_back(valy);
new_g.color = color;
graphs.push_back(new_g);
}
void RootPlotter::GenerateGraphs() {
for(auto& g : graphs) {
TGraph* graph = new TGraph(g.xvec.size(), &(g.xvec[0]), &(g.yvec[0]));
graph->SetName(g.name.c_str());
graph->SetTitle(g.title.c_str());
graph->SetMarkerColor(g.color);
table->Add(graph);
garbage_collection.push_back(graph);
}
}
int main(int argc, char** argv) {
if(argc != 3) {
std::cout<<"Unable to run ROOT plotting tool with incorrect number of arguments! Expected 2 args, given: "<<argc<<" Exiting."<<std::endl;
return 1;
}
std::string inputname = argv[1];
std::string outputname = argv[2];
Mask::MaskFile input(inputname, Mask::MaskFile::FileType::read);
TFile* root_out = TFile::Open(outputname.c_str(), "RECREATE");
RootPlotter plotter;
Mask::MaskFileHeader header = input.ReadHeader();
std::cout<<"File Header -- rxn type: "<<header.rxn_type<<" nsamples: "<<header.nsamples<<std::endl;
Mask::MaskFileData data;
Mask::Nucleus nucleus;
double flush_frac = 0.05;
int count = 0, flush_val = flush_frac*header.nsamples, flush_count = 0;
while(true) {
if(count == flush_val) {
count = 0;
flush_count++;
std::cout<<"\rPercent of file processed: "<<flush_frac*flush_count*100<<"%"<<std::flush;
}
data = input.ReadData();
if(data.eof)
break;
for(unsigned int i=0; i<data.Z.size(); i++) {
nucleus.SetIsotope(data.Z[i], data.A[i]);
nucleus.SetVectorSpherical(data.theta[i], data.phi[i], data.p[i], data.E[i]);
plotter.FillData(nucleus);
if(data.detect_flag[i] == true) {
plotter.FillData(nucleus, "detected");
}
}
count++;
}
std::cout<<std::endl;
input.Close();
root_out->cd();
plotter.GetTable()->Write();
root_out->Close();
return 0;
}

View File

@ -5,13 +5,19 @@
namespace Mask { namespace Mask {
ReactionSystem::ReactionSystem() : ReactionSystem::ReactionSystem() :
m_beamDist(0,0), m_theta1Range(0,0), m_phi1Range(0,0), m_exDist(0,0), 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), generator(nullptr), target_set_flag(false),
gen_set_flag(false), rxnLayer(0), m_sys_equation("")
{ {
} }
ReactionSystem::~ReactionSystem() {} ReactionSystem::~ReactionSystem() {
delete m_beamDist;
delete m_theta1Range;
delete m_phi1Range;
delete m_exDist;
}
void ReactionSystem::SetRandomGenerator(TRandom3* gen) { void ReactionSystem::SetRandomGenerator(std::mt19937* gen) {
generator = gen; generator = gen;
gen_set_flag = true; gen_set_flag = true;
} }
@ -20,4 +26,4 @@ void ReactionSystem::AddTargetLayer(std::vector<int>& zt, std::vector<int>& at,
target.AddLayer(zt, at, stoich, thickness); target.AddLayer(zt, at, stoich, thickness);
} }
}; }

31
src/Stopwatch.cpp Normal file
View File

@ -0,0 +1,31 @@
/*
Stopwatch.cpp
Simple class designed to provide timing info on parts of the process.
Only for use in development.
Written by G.W. McCann Oct. 2020
*/
#include "Stopwatch.h"
Stopwatch::Stopwatch() {
start_time = Clock::now();
stop_time = start_time;
}
Stopwatch::~Stopwatch() {}
void Stopwatch::Start() {
start_time = Clock::now();
}
void Stopwatch::Stop() {
stop_time = Clock::now();
}
double Stopwatch::GetElapsedSeconds() {
return std::chrono::duration_cast<std::chrono::duration<double>>(stop_time-start_time).count();
}
double Stopwatch::GetElapsedMilliseconds() {
return std::chrono::duration_cast<std::chrono::duration<double>>(stop_time-start_time).count()*1000.0;
}

View File

@ -4,21 +4,19 @@
namespace Mask { namespace Mask {
ThreeStepSystem::ThreeStepSystem() : ThreeStepSystem::ThreeStepSystem() :
ReactionSystem() ReactionSystem(), m_phi2Range(0, 2.0*M_PI)
{ {
} }
ThreeStepSystem::ThreeStepSystem(std::vector<int>& z, std::vector<int>& a) : ThreeStepSystem::ThreeStepSystem(std::vector<int>& z, std::vector<int>& a) :
ReactionSystem() ReactionSystem(), m_phi2Range(0, 2.0*M_PI)
{ {
SetNuclei(z, a); SetNuclei(z, a);
} }
ThreeStepSystem::~ThreeStepSystem() { ThreeStepSystem::~ThreeStepSystem() {}
} void ThreeStepSystem::SetRandomGenerator(std::mt19937* gen) {
void ThreeStepSystem::SetRandomGenerator(TRandom3* gen) {
generator = gen; generator = gen;
decay1dist.AttachRandomNumberGenerator(gen); decay1dist.AttachRandomNumberGenerator(gen);
decay2dist.AttachRandomNumberGenerator(gen); decay2dist.AttachRandomNumberGenerator(gen);
@ -84,16 +82,16 @@ void ThreeStepSystem::RunSystem() {
} }
//Sample parameters //Sample parameters
double bke = generator->Gaus(m_beamDist.first, m_beamDist.second); double bke = (*m_beamDist)(*generator);
double rxnTheta = acos(generator->Uniform(cos(m_theta1Range.first), cos(m_theta1Range.second))); double rxnTheta = acos((*m_theta1Range)(*generator));
double rxnPhi = generator->Uniform(m_phi1Range.first, m_phi1Range.second); double rxnPhi = (*m_phi1Range)(*generator);
double decay1costheta = decay1dist.GetRandomCosTheta(); double decay1costheta = decay1dist.GetRandomCosTheta();
double decay1Theta = std::acos(decay1costheta); double decay1Theta = std::acos(decay1costheta);
double decay1Phi = generator->Uniform(0, M_PI*2.0); double decay1Phi = m_phi2Range(*generator);
double decay2costheta = decay2dist.GetRandomCosTheta(); double decay2costheta = decay2dist.GetRandomCosTheta();
double decay2Theta = std::acos(decay2costheta); double decay2Theta = std::acos(decay2costheta);
double decay2Phi = generator->Uniform(0, M_PI*2.0); double decay2Phi = m_phi2Range(*generator);
double residEx = generator->Gaus(m_exDist.first, m_exDist.second); double residEx = (*m_exDist)(*generator);
step1.SetBeamKE(bke); step1.SetBeamKE(bke);
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);
@ -130,4 +128,4 @@ void ThreeStepSystem::RunSystem() {
} }
}; }

View File

@ -4,12 +4,12 @@
namespace Mask { namespace Mask {
TwoStepSystem::TwoStepSystem() : TwoStepSystem::TwoStepSystem() :
ReactionSystem() ReactionSystem(), m_phi2Range(0, 2.0*M_PI)
{ {
} }
TwoStepSystem::TwoStepSystem(std::vector<int>& z, std::vector<int>& a) : TwoStepSystem::TwoStepSystem(std::vector<int>& z, std::vector<int>& a) :
ReactionSystem() ReactionSystem(), m_phi2Range(0, 2.0*M_PI)
{ {
SetNuclei(z, a); SetNuclei(z, a);
} }
@ -18,7 +18,7 @@ TwoStepSystem::~TwoStepSystem() {
} }
void TwoStepSystem::SetRandomGenerator(TRandom3* gen) { void TwoStepSystem::SetRandomGenerator(std::mt19937* gen) {
generator = gen; generator = gen;
decay1dist.AttachRandomNumberGenerator(gen); decay1dist.AttachRandomNumberGenerator(gen);
gen_set_flag = true; gen_set_flag = true;
@ -74,13 +74,13 @@ void TwoStepSystem::RunSystem() {
} }
//Sample parameters //Sample parameters
double bke = generator->Gaus(m_beamDist.first, m_beamDist.second); double bke = (*m_beamDist)(*generator);
double rxnTheta = acos(generator->Uniform(cos(m_theta1Range.first), cos(m_theta1Range.second))); double rxnTheta = acos((*m_theta1Range)(*generator));
double rxnPhi = generator->Uniform(m_phi1Range.first, m_phi1Range.second); double rxnPhi = (*m_phi1Range)(*generator);
double decay1costheta = decay1dist.GetRandomCosTheta(); double decay1costheta = decay1dist.GetRandomCosTheta();
double decay1Theta = std::acos(decay1costheta); double decay1Theta = std::acos(decay1costheta);
double decay1Phi = generator->Uniform(0, M_PI*2.0); double decay1Phi = m_phi2Range(*generator);
double residEx = generator->Gaus(m_exDist.first, m_exDist.second); double residEx = (*m_beamDist)(*generator);
step1.SetBeamKE(bke); step1.SetBeamKE(bke);
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);
@ -104,4 +104,4 @@ void TwoStepSystem::RunSystem() {
} }
}; }

View File

@ -1,21 +1,20 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include "Stopwatch.h"
#include "MaskFile.h"
#include "Kinematics.h" #include "Kinematics.h"
#include "SabreEfficiency.h"
#include "AnasenEfficiency.h"
#include "KinematicsExceptions.h" #include "KinematicsExceptions.h"
#include <TGraph2D.h>
#include <TCanvas.h>
int main(int argc, char** argv) { int main(int argc, char** argv) {
if(argc<2) { if(argc<2) {
std::cerr<<"Incorrect number of arguments!"<<std::endl; std::cerr<<"Incorrect number of arguments!"<<std::endl;
return 1; return 1;
} }
Stopwatch sw;
Mask::Kinematics calculator; Mask::Kinematics calculator;
sw.Start();
try { try {
if(!calculator.LoadConfig(argv[1])) { if(!calculator.LoadConfig(argv[1])) {
return 1; return 1;
@ -26,26 +25,26 @@ int main(int argc, char** argv) {
std::cerr<<"Terminating process."<<std::endl; std::cerr<<"Terminating process."<<std::endl;
return 1; return 1;
} }
sw.Stop();
std::cout<<"Time elapsed(seconds): "<<sw.GetElapsedSeconds()<<std::endl;
Mask::MaskFile input(calculator.GetOutputName(), Mask::MaskFile::FileType::read);
Mask::MaskFileData data;
Mask::MaskFileHeader header = input.ReadHeader();
std::cout<<"Header Found -- rxn type: "<<header.rxn_type<<" nsamples: "<<header.nsamples;
std::cout<<std::endl;
/* int counter=0;
SabreEfficiency sabre; while(!data.eof) {
std::string mapfile = "./etc/DeadChannels.txt"; data = input.ReadData();
sabre.SetReactionType(calculator.GetReactionType()); for(unsigned int i=0; i<data.E.size(); i++)
sabre.SetDeadChannelMap(mapfile); counter++;
sabre.CalculateEfficiency(calculator.GetOutputName()); //std::cout<<"Data Found -- E: "<<data.E[i]<<" KE: "<<data.KE[i]<<" p: "<<data.p[i]<<" theta: "<<data.theta[i]<<" phi: "<<data.phi[i]<<std::endl;
//std::cout<<"Running consistency check(1=success): "<<sabre.RunConsistencyCheck()<<std::endl; }
//sabre.DrawDetectorSystem("/data1/gwm17/10B3He/Feb2021/simulation/SABREGeo.root"); std::cout<<"events found: "<<counter<<std::endl;
*/ input.Close();
std::cout<<"File closed."<<std::endl;
AnasenEfficiency anasen;
anasen.SetReactionType(calculator.GetReactionType());
anasen.CalculateEfficiency(calculator.GetOutputName());
//std::cout<<"Running consistency check(1=success): "<<anasen.RunConsistencyCheck()<<std::endl;
//anasen.DrawDetectorSystem("/data1/gwm17/TRIUMF_7Bed/simulation/ANASENGeo_centered_target_targetGap_BackQQQ_test.root");
return 0; return 0;