1
0
Fork 0
mirror of https://github.com/gwm17/Mask.git synced 2025-06-30 20:18:51 -04:00

Fixed some stylistic incosistencies. Incorporated all classes used for Mask into the Mask namespace. Updated some comments.

This commit is contained in:
Gordon McCann 2021-09-06 16:18:49 -04:00
parent 170cc7afb0
commit e96b29accf
31 changed files with 1490 additions and 1484 deletions

View File

@ -5,20 +5,22 @@
#include <vector> #include <vector>
#include <random> #include <random>
class AngularDistribution { namespace Mask {
public:
class AngularDistribution {
public:
AngularDistribution(); AngularDistribution();
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(std::mt19937* random) { generator = random; }; inline void AttachRandomNumberGenerator(std::mt19937* random) { generator = random; }
double GetRandomCosTheta(); double GetRandomCosTheta();
int GetL() { return L; }; inline int GetL() { return L; }
double GetBranchingRatio() { return branchingRatio; }; inline double GetBranchingRatio() { return branchingRatio; }
private: private:
bool IsIsotropic(); inline bool IsIsotropic() { return isoFlag; }
bool IsGeneratorSet() { inline bool IsGeneratorSet() {
if(generator) { if(generator) {
return true; return true;
} else { } else {
@ -34,6 +36,8 @@ private:
int L; int L;
std::vector<double> constants; std::vector<double> constants;
bool isoFlag; bool isoFlag;
}; };
}
#endif #endif

View File

@ -1,10 +1,12 @@
#ifndef ELOSS_TABLES_H #ifndef ELOSS_TABLES_H
#define ELOSS_TABLES_H #define ELOSS_TABLES_H
#define MAX_Z 93 //Maximum number of elements for which we have hydrogen coefficients namespace Mask {
/*Atomic Masses for elements H through U. Taken from ELAST data*/ #define MAX_Z 93 //Maximum number of elements for which we have hydrogen coefficients
static double NATURAL_MASS[MAX_Z] =
/*Atomic Masses for elements H through U. Taken from ELAST data*/
static double NATURAL_MASS[MAX_Z] =
{0, {0,
1.00797, 4.0026, 6.939, 9.0122, 10.818, 1.00797, 4.0026, 6.939, 9.0122, 10.818,
12.01115, 14.0067, 15.9994, 18.99984, 20.183, 12.01115, 14.0067, 15.9994, 18.99984, 20.183,
@ -26,13 +28,13 @@ static double NATURAL_MASS[MAX_Z] =
222., 223., 226., 227., 232.038, 222., 223., 226., 227., 232.038,
231., 238.03 }; 231., 238.03 };
/*Stopping power coefficients for hydrogen into Z /*Stopping power coefficients for hydrogen into Z
*Taken from Ziegler, Hydrogen Stopping Powers and Ranges in All Elements, Volume 3 of *Taken from Ziegler, Hydrogen Stopping Powers and Ranges in All Elements, Volume 3 of
*The Stopping and Ranges of Ions in Matter, 1977, Pergamon Press Inc. *The Stopping and Ranges of Ions in Matter, 1977, Pergamon Press Inc.
*Expanded table for method given in O.G. Spanc *Expanded table for method given in O.G. Spanc
*Note: some elements represent extrapolations when there was no data to fit *Note: some elements represent extrapolations when there was no data to fit
*/ */
static double HYDROGEN_COEFF[MAX_Z][12] = { static double HYDROGEN_COEFF[MAX_Z][12] = {
/*Blank*/{0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.}, /*Blank*/{0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.,0.},
/*H*/{1.262,1.44,242.6,1.2E4,0.1159,0.0005099,5.436E4,-5.052,2.049,-0.3044,0.01966,-0.0004659}, /*H*/{1.262,1.44,242.6,1.2E4,0.1159,0.0005099,5.436E4,-5.052,2.049,-0.3044,0.01966,-0.0004659},
/*He*/{1.229,1.397,484.5,5873,0.05225,0.00102,2.451E4,-2.158,0.8278,-0.1172,0.007259,-0.000166}, /*He*/{1.229,1.397,484.5,5873,0.05225,0.00102,2.451E4,-2.158,0.8278,-0.1172,0.007259,-0.000166},
@ -126,5 +128,6 @@ static double HYDROGEN_COEFF[MAX_Z][12] = {
/*Th*/{7.71, 8.679,1.883E4,586.3,0.002641,0.04589,1239,-20.04,6.967,-0.8741,0.04752,-0.0009516}, /*Th*/{7.71, 8.679,1.883E4,586.3,0.002641,0.04589,1239,-20.04,6.967,-0.8741,0.04752,-0.0009516},
/*Pa*/{7.407, 8.336,1.901E4,586.3,0.002603,0.0464,1221,-20.11,6.981,-0.8749,0.04752,-0.0009512}, /*Pa*/{7.407, 8.336,1.901E4,586.3,0.002603,0.0464,1221,-20.11,6.981,-0.8749,0.04752,-0.0009512},
/*U*/{7.29, 8.204,1.918E4,586.3,0.002573,0.04691,1207,-20.18,6.995,-0.8757,0.04753,-0.0009508} /*U*/{7.29, 8.204,1.918E4,586.3,0.002573,0.04691,1207,-20.18,6.995,-0.8757,0.04753,-0.0009508}
}; };
}
#endif #endif

View File

@ -19,7 +19,8 @@ Written by G.W. McCann Aug. 2020
#include <cmath> #include <cmath>
#include "MassLookup.h" #include "MassLookup.h"
class EnergyLoss { namespace Mask {
class EnergyLoss {
public: public:
EnergyLoss(); EnergyLoss();
@ -50,8 +51,8 @@ class EnergyLoss {
static constexpr double MAX_H_E_PER_U = 100000.0; static constexpr double MAX_H_E_PER_U = 100000.0;
static constexpr double AVOGADRO = 0.60221367; //N_A times 10^(-24) for converting static constexpr double AVOGADRO = 0.60221367; //N_A times 10^(-24) for converting
static constexpr double MEV2U = 1.0/931.4940954; static constexpr double MEV2U = 1.0/931.4940954;
static constexpr double PI = 3.14159265358979323846;
static constexpr double H_RESTMASS = 938.27231; //MeV, for beta calc static constexpr double H_RESTMASS = 938.27231; //MeV, for beta calc
}; };
}
#endif #endif

View File

@ -1,7 +1,7 @@
/* /*
LayeredTarget.h LayeredTarget.h
Functional unit for targets in the SPANCRedux environment. Contains a Functional unit for targets in the Mask environment. Contains a
set (read: vector) of Targets for use in reaction calculations. In this set (read: vector) of Targets for use in reaction calculations. In this
way handles situations such as carbon backed targets way handles situations such as carbon backed targets
@ -15,10 +15,11 @@ Written by G.W. McCann Aug. 2020
#include <vector> #include <vector>
#include <string> #include <string>
#include <iostream>
#include "Target.h" #include "Target.h"
class LayeredTarget { namespace Mask {
class LayeredTarget {
public: public:
LayeredTarget(); LayeredTarget();
@ -27,15 +28,17 @@ class LayeredTarget {
double GetProjectileEnergyLoss(int zp, int ap, double startEnergy, int rxnLayer, double angle); double GetProjectileEnergyLoss(int zp, int ap, double startEnergy, int rxnLayer, double angle);
double GetEjectileEnergyLoss(int ze, int ae, double startEnergy, int rxnLayer, double angle); double GetEjectileEnergyLoss(int ze, int ae, double startEnergy, int rxnLayer, double angle);
double GetEjectileReverseEnergyLoss(int ze, int ae, double startEnergy, int rxnLayer, double angle); double GetEjectileReverseEnergyLoss(int ze, int ae, double startEnergy, int rxnLayer, double angle);
int GetNumberOfLayers();
int FindLayerContaining(int Z, int A); int FindLayerContaining(int Z, int A);
void SetName(std::string& n); inline int GetNumberOfLayers() { return layers.size(); }
Target& GetLayerInfo(int index); inline void SetName(std::string& n) { name = n; }
std::string& GetName(); inline const Target& GetLayerInfo(int index) { return layers[index]; }
inline const std::string& GetName() { return name; }
private: private:
std::vector<Target> layers; std::vector<Target> layers;
std::string name; std::string name;
}; };
}
#endif #endif

View File

@ -1,12 +1,16 @@
#ifndef LEGENDREPOLY_H #ifndef LEGENDREPOLY_H
#define LEGENDREPOLY_H #define LEGENDREPOLY_H
double P_l(int l, double x); namespace Mask {
double P_l_ROOT(double* x, double* pars);
double Normed_P_l_sq(int l, double x);
double P_0(double x); double P_l(int l, double x);
double P_1(double x); double P_l_ROOT(double* x, double* pars);
double P_2(double x); double Normed_P_l_sq(int l, double x);
double P_0(double x);
double P_1(double x);
double P_2(double x);
}
#endif #endif

View File

@ -12,18 +12,18 @@ 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
#include <iostream>
#include <fstream> #include <fstream>
#include <string> #include <string>
#include <unordered_map> #include <unordered_map>
#include <stdexcept>
class MassLookup { namespace Mask {
class MassLookup {
public: public:
~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() { static MassLookup* GetInstance() {
if(s_instance == nullptr) { if(s_instance == nullptr) {
s_instance = new MassLookup(); s_instance = new MassLookup();
@ -42,6 +42,8 @@ class MassLookup {
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;
}; };
}
#endif #endif

View File

@ -14,8 +14,8 @@
namespace Mask { namespace Mask {
class Reaction { class Reaction {
public: public:
Reaction(); Reaction();
Reaction(int zt, int at, int zp, int ap, int ze, int ae); Reaction(int zt, int at, int zp, int ap, int ze, int ae);
~Reaction(); ~Reaction();
@ -25,7 +25,6 @@ public:
void SetBeamKE(double bke); void SetBeamKE(double bke);
void SetEjectileThetaType(int type); void SetEjectileThetaType(int type);
/*Setters and getters*/
inline void SetLayeredTarget(LayeredTarget* targ) { target = targ; }; inline void SetLayeredTarget(LayeredTarget* targ) { target = targ; };
inline void SetPolarRxnAngle(double theta) { m_theta = theta; }; inline void SetPolarRxnAngle(double theta) { m_theta = theta; };
inline void SetAzimRxnAngle(double phi) { m_phi = phi; }; inline void SetAzimRxnAngle(double phi) { m_phi = phi; };
@ -47,17 +46,17 @@ public:
inline const Nucleus& GetTarget() const { return reactants[0]; }; inline const Nucleus& GetTarget() const { return reactants[0]; };
inline const Nucleus& GetEjectile() const { return reactants[2]; }; inline const Nucleus& GetEjectile() const { return reactants[2]; };
inline const Nucleus& GetResidual() const { return reactants[3]; }; inline const Nucleus& GetResidual() const { return reactants[3]; };
inline void ResetTarget() { reactants[0].SetVectorCartesian(0,0,0,0); };
inline void ResetProjectile() { reactants[1].SetVectorCartesian(0,0,0,0); };
inline void ResetEjectile() { reactants[2].SetVectorCartesian(0,0,0,0); };
inline void ResetResidual() { reactants[3].SetVectorCartesian(0,0,0,0); };
inline int GetRxnLayer() { return rxnLayer; }; inline int GetRxnLayer() { return rxnLayer; };
inline void ResetTarget() { reactants[0].SetVectorCartesian(0,0,0, reactants[0].GetGroundStateMass()); }
inline void ResetProjectile() { reactants[1].SetVectorCartesian(0,0,0, reactants[1].GetGroundStateMass()); }
inline void ResetEjectile() { reactants[2].SetVectorCartesian(0,0,0, reactants[2].GetGroundStateMass()); }
inline void ResetResidual() { reactants[3].SetVectorCartesian(0,0,0, reactants[3].GetGroundStateMass()); }
private: private:
void CalculateDecay(); //target -> light_decay (eject) + heavy_decay(resid)
void CalculateReaction(); //target + project -> eject + resid void CalculateReaction(); //target + project -> eject + resid
void CalculateReactionThetaLab(); void CalculateReactionThetaLab();
void CalculateReactionThetaCM(); void CalculateReactionThetaCM();
void CalculateDecay(); //target -> light_decay (eject) + heavy_decay(resid)
Nucleus reactants[4]; //0=target, 1=projectile, 2=ejectile, 3=residual Nucleus reactants[4]; //0=target, 1=projectile, 2=ejectile, 3=residual
LayeredTarget* target; //not owned by Reaction LayeredTarget* target; //not owned by Reaction
@ -72,8 +71,8 @@ private:
static constexpr int lab = 0; static constexpr int lab = 0;
static constexpr int center_of_mass = 1; static constexpr int center_of_mass = 1;
}; };
}; }
#endif #endif

View File

@ -10,69 +10,69 @@
namespace Mask { namespace Mask {
class XRotation { class XRotation {
public: public:
XRotation(); XRotation();
XRotation(double ang); XRotation(double ang);
~XRotation(); ~XRotation();
Vec3 Rotate(const Vec3& vector); Vec3 Rotate(const Vec3& vector);
inline void SetAngle(double ang) { m_angle = ang; GenerateMatrix(); }; inline void SetAngle(double ang) { m_angle = ang; GenerateMatrix(); }
inline XRotation GetInverse() { return XRotation(-m_angle); }; inline XRotation GetInverse() { return XRotation(-m_angle); }
inline Vec3 operator*(const Vec3& vector) { inline Vec3 operator*(const Vec3& vector) {
double x = m_matrix[0][0]*vector[0] + m_matrix[0][1]*vector[1] + m_matrix[0][2]*vector[2]; double x = m_matrix[0][0]*vector[0] + m_matrix[0][1]*vector[1] + m_matrix[0][2]*vector[2];
double y = m_matrix[1][0]*vector[0] + m_matrix[1][1]*vector[1] + m_matrix[1][2]*vector[2]; double y = m_matrix[1][0]*vector[0] + m_matrix[1][1]*vector[1] + m_matrix[1][2]*vector[2];
double z = m_matrix[2][0]*vector[0] + m_matrix[2][1]*vector[1] + m_matrix[2][2]*vector[2]; double z = m_matrix[2][0]*vector[0] + m_matrix[2][1]*vector[1] + m_matrix[2][2]*vector[2];
return Vec3(x, y, z); return Vec3(x, y, z);
}; }
private: private:
void GenerateMatrix(); void GenerateMatrix();
double m_angle; double m_angle;
double m_matrix[3][3]; double m_matrix[3][3];
}; };
class YRotation { class YRotation {
public: public:
YRotation(); YRotation();
YRotation(double ang); YRotation(double ang);
~YRotation(); ~YRotation();
Vec3 Rotate(const Vec3& vector); Vec3 Rotate(const Vec3& vector);
inline void SetAngle(double ang) { m_angle = ang; GenerateMatrix(); }; inline void SetAngle(double ang) { m_angle = ang; GenerateMatrix(); }
inline YRotation GetInverse() { return YRotation(-m_angle); }; inline YRotation GetInverse() { return YRotation(-m_angle); }
inline Vec3 operator*(const Vec3& vector) { inline Vec3 operator*(const Vec3& vector) {
double x = m_matrix[0][0]*vector[0] + m_matrix[0][1]*vector[1] + m_matrix[0][2]*vector[2]; double x = m_matrix[0][0]*vector[0] + m_matrix[0][1]*vector[1] + m_matrix[0][2]*vector[2];
double y = m_matrix[1][0]*vector[0] + m_matrix[1][1]*vector[1] + m_matrix[1][2]*vector[2]; double y = m_matrix[1][0]*vector[0] + m_matrix[1][1]*vector[1] + m_matrix[1][2]*vector[2];
double z = m_matrix[2][0]*vector[0] + m_matrix[2][1]*vector[1] + m_matrix[2][2]*vector[2]; double z = m_matrix[2][0]*vector[0] + m_matrix[2][1]*vector[1] + m_matrix[2][2]*vector[2];
return Vec3(x, y, z); return Vec3(x, y, z);
}; }
private: private:
void GenerateMatrix(); void GenerateMatrix();
double m_angle; double m_angle;
double m_matrix[3][3]; double m_matrix[3][3];
}; };
class ZRotation { class ZRotation {
public: public:
ZRotation(); ZRotation();
ZRotation(double ang); ZRotation(double ang);
~ZRotation(); ~ZRotation();
Vec3 Rotate(const Vec3& vector); Vec3 Rotate(const Vec3& vector);
inline void SetAngle(double ang) { m_angle = ang; GenerateMatrix();}; inline void SetAngle(double ang) { m_angle = ang; GenerateMatrix(); }
inline ZRotation GetInverse() { return ZRotation(-m_angle); }; inline ZRotation GetInverse() { return ZRotation(-m_angle); }
inline Vec3 operator*(const Vec3& vector) { inline Vec3 operator*(const Vec3& vector) {
double x = m_matrix[0][0]*vector[0] + m_matrix[0][1]*vector[1] + m_matrix[0][2]*vector[2]; double x = m_matrix[0][0]*vector[0] + m_matrix[0][1]*vector[1] + m_matrix[0][2]*vector[2];
double y = m_matrix[1][0]*vector[0] + m_matrix[1][1]*vector[1] + m_matrix[1][2]*vector[2]; double y = m_matrix[1][0]*vector[0] + m_matrix[1][1]*vector[1] + m_matrix[1][2]*vector[2];
double z = m_matrix[2][0]*vector[0] + m_matrix[2][1]*vector[1] + m_matrix[2][2]*vector[2]; double z = m_matrix[2][0]*vector[0] + m_matrix[2][1]*vector[1] + m_matrix[2][2]*vector[2];
return Vec3(x, y, z); return Vec3(x, y, z);
}; }
private: private:
void GenerateMatrix(); void GenerateMatrix();
double m_angle; double m_angle;
double m_matrix[3][3]; double m_matrix[3][3];
}; };
}; }
#endif #endif

View File

@ -171,4 +171,5 @@ private:
}; };
#endif #endif

View File

@ -21,8 +21,8 @@ private:
std::vector<SabreDetector> detectors; std::vector<SabreDetector> detectors;
Target deadlayer; Mask::Target deadlayer;
Target sabre_eloss; Mask::Target sabre_eloss;
DeadChannelMap dmap; DeadChannelMap dmap;
//Sabre constants //Sabre constants

View File

@ -1,7 +1,7 @@
/* /*
Target.h Target.h
A basic target unit for use in the SPANCRedux environment. A target A basic target unit for use in the Mask environment. A target
is defined as a single compound with elements Z,A of a given stoichiometry is defined as a single compound with elements Z,A of a given stoichiometry
Holds an energy loss class Holds an energy loss class
@ -15,9 +15,12 @@ Written by G.W. McCann Aug. 2020
#include <string> #include <string>
#include <vector> #include <vector>
#include <cmath>
#include "EnergyLoss.h" #include "EnergyLoss.h"
class Target { namespace Mask {
class Target {
public: public:
Target(double thick); Target(double thick);
@ -28,19 +31,19 @@ class Target {
double getEnergyLossHalf(int zp, int ap, double startEnergy, double angle); double getEnergyLossHalf(int zp, int ap, double startEnergy, double angle);
double getReverseEnergyLossTotal(int zp, int ap, double finalEnergy, double angle); double getReverseEnergyLossTotal(int zp, int ap, double finalEnergy, double angle);
double getReverseEnergyLossHalf(int zp, int ap, double finalEnergy, double angle); double getReverseEnergyLossHalf(int zp, int ap, double finalEnergy, double angle);
double& GetThickness(); inline const double& GetThickness() { return thickness; }
int GetNumberOfElements(); inline int GetNumberOfElements() { return Z.size(); }
int GetElementZ(int index); inline int GetElementZ(int index) { return Z[index]; }
int GetElementA(int index); inline int GetElementA(int index) { return A[index]; }
int GetElementStoich(int index); inline int GetElementStoich(int index) { return Stoich[index]; }
private: private:
EnergyLoss eloss; EnergyLoss eloss;
double thickness; double thickness;
std::vector<int> Z, A, Stoich; std::vector<int> Z, A, Stoich;
static constexpr double PI = 3.14159265358979323846;
}; };
}
#endif #endif

View File

@ -11,30 +11,30 @@
namespace Mask { namespace Mask {
class Vec3 { class Vec3 {
public: public:
Vec3(); Vec3();
Vec3(double x, double y, double z); Vec3(double x, double y, double z);
~Vec3(); ~Vec3();
void SetVectorCartesian(double x, double y, double z); void SetVectorCartesian(double x, double y, double z);
void SetVectorSpherical(double r, double theta, double phi); void SetVectorSpherical(double r, double theta, double phi);
inline double GetX() const { return m_data[0]; }; inline double GetX() const { return m_data[0]; }
inline double GetY() const { return m_data[1]; }; inline double GetY() const { return m_data[1]; }
inline double GetZ() const { return m_data[2]; }; inline double GetZ() const { return m_data[2]; }
inline double GetRho() const { return std::sqrt(std::pow(m_data[0], 2.0) + std::pow(m_data[1], 2.0)); }; inline double GetRho() const { return std::sqrt(std::pow(m_data[0], 2.0) + std::pow(m_data[1], 2.0)); }
inline double GetR() const { return std::sqrt(std::pow(m_data[0], 2.0) + std::pow(m_data[1], 2.0) + std::pow(m_data[2], 2.0)); } inline double GetR() const { return std::sqrt(std::pow(m_data[0], 2.0) + std::pow(m_data[1], 2.0) + std::pow(m_data[2], 2.0)); }
inline double GetTheta() const { return Atan2(GetRho(), GetZ()); }; inline double GetTheta() const { return Atan2(GetRho(), GetZ()); }
inline double GetPhi() const { inline double GetPhi() const {
double phi = Atan2(GetY(), GetX()); double phi = Atan2(GetY(), GetX());
if(phi < 0) phi += M_PI*2.0; if(phi < 0) phi += M_PI*2.0;
return phi; return phi;
}; }
inline const double operator[](int index) const { return index>2 || index<0 ? 0.0 : m_data[index]; }; inline const double operator[](int index) const { return index>2 || index<0 ? 0.0 : m_data[index]; }
inline Vec3& operator=(const Vec3& rhs) { SetVectorCartesian(rhs.GetX(), rhs.GetY(), rhs.GetZ()); return *this; }; inline Vec3& operator=(const Vec3& rhs) { SetVectorCartesian(rhs.GetX(), rhs.GetY(), rhs.GetZ()); return *this; }
inline Vec3 operator+(const Vec3& rhs) const { return Vec3(this->GetX()+rhs.GetX(), this->GetY()+rhs.GetY(), this->GetZ()+rhs.GetZ()); }; inline Vec3 operator+(const Vec3& rhs) const { return Vec3(this->GetX()+rhs.GetX(), this->GetY()+rhs.GetY(), this->GetZ()+rhs.GetZ()); }
inline Vec3 operator-(const Vec3& rhs) const { return Vec3(this->GetX()-rhs.GetX(), this->GetY()-rhs.GetY(), this->GetZ()-rhs.GetZ()); }; inline Vec3 operator-(const Vec3& rhs) const { return Vec3(this->GetX()-rhs.GetX(), this->GetY()-rhs.GetY(), this->GetZ()-rhs.GetZ()); }
double Dot(const Vec3& rhs) const; double Dot(const Vec3& rhs) const;
@ -42,7 +42,7 @@ public:
private: private:
//Use instead of std::atan2. Better control over values close to x=0 //Use instead of std::atan2. Better control over values close to x=0
inline double Atan2(double y, double x) const { inline double Atan2(double y, double x) const {
@ -54,8 +54,8 @@ private:
double m_data[3]; double m_data[3];
}; };
}; }
#endif #endif

View File

@ -11,44 +11,44 @@
namespace Mask { namespace Mask {
class Vec4 { class Vec4 {
public: public:
Vec4(); Vec4();
Vec4(double px, double py, double pz, double E); Vec4(double px, double py, double pz, double E);
virtual ~Vec4(); virtual ~Vec4();
void SetVectorCartesian(double px, double py, double pz, double E); void SetVectorCartesian(double px, double py, double pz, double E);
void SetVectorSpherical(double theta, double phi, double p, double E); void SetVectorSpherical(double theta, double phi, double p, double E);
inline double GetE() const {return m_data[3];}; inline double GetE() const { return m_data[3]; }
inline double GetPx() const {return m_data[0];}; inline double GetPx() const { return m_data[0]; }
inline double GetPy() const {return m_data[1];}; inline double GetPy() const { return m_data[1]; }
inline double GetPz() const {return m_data[2];}; inline double GetPz() const { return m_data[2]; }
inline double GetP() const {return std::sqrt(m_data[0]*m_data[0] + m_data[1]*m_data[1] + m_data[2]*m_data[2]);}; inline double GetP() const { return std::sqrt(m_data[0]*m_data[0] + m_data[1]*m_data[1] + m_data[2]*m_data[2]); }
inline double GetPxy() const {return std::sqrt(m_data[0]*m_data[0] + m_data[1]*m_data[1]); }; inline double GetPxy() const { return std::sqrt(m_data[0]*m_data[0] + m_data[1]*m_data[1]); }
inline double GetTheta() const {return GetPxy() == 0.0 && GetPz() == 0.0 ? 0.0 : Atan2(GetPxy(), GetPz());}; inline double GetTheta() const { return GetPxy() == 0.0 && GetPz() == 0.0 ? 0.0 : Atan2(GetPxy(), GetPz()); }
inline double GetPhi() const { inline double GetPhi() const {
double phi = Atan2(GetPy(), GetPx()); double phi = Atan2(GetPy(), GetPx());
if(phi<0) phi += 2.0*M_PI; if(phi<0) phi += 2.0*M_PI;
return GetPx() == 0.0 && GetPy() == 0.0 ? 0.0 : phi; return GetPx() == 0.0 && GetPy() == 0.0 ? 0.0 : phi;
}; }
inline double GetInvMass() const {return std::sqrt(GetE()*GetE() - GetP()*GetP());}; inline double GetInvMass() const { return std::sqrt(GetE()*GetE() - GetP()*GetP()); }
inline double GetKE() const {return GetE() - GetInvMass();}; inline double GetKE() const { return GetE() - GetInvMass(); }
inline const double* GetBoost() const {return &m_boost[0];}; inline const double* GetBoost() const { return &m_boost[0]; }
void ApplyBoost(const double* boost); void ApplyBoost(const double* boost);
//Only intended for use in looping access! //Only intended for use in looping access!
inline const double operator[] (int index) const {return index>3 || index < 0 ? 0.0 : m_data[index];}; inline const double operator[] (int index) const { return index>3 || index < 0 ? 0.0 : m_data[index]; }
inline Vec4& operator=(const Vec4& rhs) {SetVectorCartesian(rhs.GetPx(), rhs.GetPy(), rhs.GetPz(), rhs.GetE()); return *this;}; inline Vec4& operator=(const Vec4& rhs) { SetVectorCartesian(rhs.GetPx(), rhs.GetPy(), rhs.GetPz(), rhs.GetE()); return *this; }
inline Vec4 operator+(const Vec4& rhs) const {return Vec4(rhs.GetPx()+GetPx(), rhs.GetPy()+GetPy(), rhs.GetPz()+GetPz(), rhs.GetE()+GetE());}; inline Vec4 operator+(const Vec4& rhs) const { return Vec4(rhs.GetPx()+GetPx(), rhs.GetPy()+GetPy(), rhs.GetPz()+GetPz(), rhs.GetE()+GetE()); }
inline Vec4 operator-(const Vec4& rhs) const {return Vec4(rhs.GetPx()-GetPx(), rhs.GetPy()-GetPy(), rhs.GetPz()-GetPz(), rhs.GetE()-GetE());}; inline Vec4 operator-(const Vec4& rhs) const { return Vec4(rhs.GetPx()-GetPx(), rhs.GetPy()-GetPy(), rhs.GetPz()-GetPz(), rhs.GetE()-GetE()); }
double Dot(const Vec4& rhs) const; double Dot(const Vec4& rhs) const;
Vec4 Cross(const Vec4& rhs) const; Vec4 Cross(const Vec4& rhs) const;
private: private:
void CalcBoostToCM(); void CalcBoostToCM();
//use instead of std::atan2. Better controll over x=0 //use instead of std::atan2. Better controll over x=0
@ -57,13 +57,13 @@ private:
else if( y > 0 ) return M_PI/2.0; else if( y > 0 ) return M_PI/2.0;
else if( y < 0 ) return -M_PI/2.0; else if( y < 0 ) return -M_PI/2.0;
else return 0.0; else return 0.0;
}; }
double m_data[4]; double m_data[4];
double m_boost[3]; double m_boost[3];
}; };
}; }
#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.mask OutputFile: test/7Bedp_600keV_beam_centered_target_targetgap_BackQQQ_rndmCM_test.mask
SaveTree: yes SaveTree: yes
SavePlots: yes SavePlots: yes
----------Reaction Information---------- ----------Reaction Information----------

View File

@ -4,20 +4,22 @@
#include <iostream> #include <iostream>
#include "LegendrePoly.h" #include "LegendrePoly.h"
AngularDistribution::AngularDistribution() : namespace Mask {
AngularDistribution::AngularDistribution() :
generator(nullptr), uniform_cosine_dist(-1.0, 1.0), uniform_prob_dist(0.0, 1.0), branchingRatio(1.0), L(0), isoFlag(true) generator(nullptr), uniform_cosine_dist(-1.0, 1.0), uniform_prob_dist(0.0, 1.0), branchingRatio(1.0), L(0), isoFlag(true)
{ {
} }
AngularDistribution::AngularDistribution(const std::string& file) : AngularDistribution::AngularDistribution(const std::string& file) :
generator(nullptr), branchingRatio(1.0), L(0), isoFlag(true) generator(nullptr), branchingRatio(1.0), L(0), isoFlag(true)
{ {
ReadDistributionFile(file); ReadDistributionFile(file);
} }
AngularDistribution::~AngularDistribution() {} AngularDistribution::~AngularDistribution() {}
void AngularDistribution::ReadDistributionFile(const std::string& file) { void AngularDistribution::ReadDistributionFile(const std::string& file) {
if(file == "none" || file == "") { if(file == "none" || file == "") {
L=0; L=0;
@ -75,9 +77,9 @@ void AngularDistribution::ReadDistributionFile(const std::string& file) {
isoFlag = false; isoFlag = false;
} }
double AngularDistribution::GetRandomCosTheta() { double AngularDistribution::GetRandomCosTheta() {
if(!IsGeneratorSet()) { if(!IsGeneratorSet()) {
std::cerr<<"Random number generator is not set in AngularDistribution! Returning default value of 0"<<std::endl; std::cerr<<"Random number generator is not set in AngularDistribution! Returning default value of 0"<<std::endl;
@ -101,4 +103,6 @@ double AngularDistribution::GetRandomCosTheta() {
} while(test > probability); } while(test > probability);
return costheta; return costheta;
}
} }

View File

@ -59,7 +59,6 @@ namespace Mask {
LinkTarget(); LinkTarget();
} }
if(step1.IsDecay()) {
double rxnTheta = std::acos(decay1dist.GetRandomCosTheta()); double rxnTheta = std::acos(decay1dist.GetRandomCosTheta());
double rxnPhi = (*m_phi1Range)(*generator); double rxnPhi = (*m_phi1Range)(*generator);
step1.SetPolarRxnAngle(rxnTheta); step1.SetPolarRxnAngle(rxnTheta);
@ -67,9 +66,7 @@ namespace Mask {
step1.TurnOnResidualEloss(); step1.TurnOnResidualEloss();
step1.Calculate(); step1.Calculate();
} else {
return;
}
} }
} }

View File

@ -49,6 +49,7 @@
*/ */
#include "SabreDetector.h" #include "SabreDetector.h"
SabreDetector::SabreDetector() : SabreDetector::SabreDetector() :

View File

@ -14,35 +14,36 @@ Written by G.W. McCann Aug. 2020
#include "KinematicsExceptions.h" #include "KinematicsExceptions.h"
#include <iostream> #include <iostream>
EnergyLoss::EnergyLoss() { namespace Mask {
comp_denom = 0;
ZP = -1;
}
EnergyLoss::~EnergyLoss() {} EnergyLoss::EnergyLoss() :
ZP(-1), AP(-1), MP(-1.0), comp_denom(0)
{
}
/*Targets are defined by their atomic number, total number of nucleons, and their stoichiometry within the target compound*/ EnergyLoss::~EnergyLoss() {}
void EnergyLoss::SetTargetComponents(std::vector<int>& Zt, std::vector<int>& At, std::vector<int>& Stoich) {
/*Targets are defined by their atomic number, total number of nucleons, and their stoichiometry within the target compound*/
void EnergyLoss::SetTargetComponents(std::vector<int>& Zt, std::vector<int>& At, std::vector<int>& Stoich) {
comp_denom = 0; comp_denom = 0;
ZT = Zt; ZT = Zt;
AT = At; AT = At;
for(unsigned int i=0; i<Stoich.size(); i++) { for(unsigned int i=0; i<Stoich.size(); i++) {
comp_denom += Stoich[i]; comp_denom += Stoich[i];
if(ZT[i] > MAX_Z) { if(ZT[i] > MAX_Z)
throw ELossException("Maximum allowed target Z exceeded"); throw ELossException("Maximum allowed target Z exceeded");
} }
}
targ_composition.resize(Stoich.size()); targ_composition.resize(Stoich.size());
for(unsigned int i=0; i<Stoich.size(); i++) {
for(unsigned int i=0; i<Stoich.size(); i++)
targ_composition[i] = Stoich[i]/comp_denom; targ_composition[i] = Stoich[i]/comp_denom;
} }
}
/* /*
Returns units of MeV; thickness in ug/cm^2; e_initial in units of MeV Returns units of MeV; thickness in ug/cm^2; e_initial in units of MeV
Energy loss going through the target Energy loss going through the target
*/ */
double EnergyLoss::GetEnergyLoss(int zp, int ap, double e_initial, double thickness) { double EnergyLoss::GetEnergyLoss(int zp, int ap, double e_initial, double thickness) {
if( ZP != zp) { if( ZP != zp) {
ZP = zp; ZP = zp;
AP = ap; AP = ap;
@ -58,8 +59,8 @@ double EnergyLoss::GetEnergyLoss(int zp, int ap, double e_initial, double thickn
int depth=0; int depth=0;
if(thickness == 0.0) return 0; if(thickness == 0.0 || e_initial == 0.0)
else if(e_initial == 0.0) return 0; return 0;
bool go = true; bool go = true;
while(go) { while(go) {
@ -72,29 +73,26 @@ double EnergyLoss::GetEnergyLoss(int zp, int ap, double e_initial, double thickn
go = false; go = false;
x_step = thickness - x_traversed; //get valid portion of last chunk x_step = thickness - x_traversed; //get valid portion of last chunk
e_final -= GetTotalStoppingPower(e_final)*x_step/1000.0; e_final -= GetTotalStoppingPower(e_final)*x_step/1000.0;
if(depth > 20)std::cout<<"depth: "<<depth<<std::endl; if(e_final <= e_threshold)
if(e_final <= e_threshold) {
return e_initial; return e_initial;
}
} else if(depth == MAX_DEPTH) { } else if(depth == MAX_DEPTH) {
return e_initial; return e_initial;
} else { } else {
x_traversed += x_step; x_traversed += x_step;
e_step = GetTotalStoppingPower(e_final)*x_step/1000.0; e_step = GetTotalStoppingPower(e_final)*x_step/1000.0;
e_final -= e_step; e_final -= e_step;
if(e_final <= e_threshold) { if(e_final <= e_threshold)
return e_initial; return e_initial;
} }
} }
}
return e_initial - e_final; return e_initial - e_final;
} }
/* /*
Returns units of MeV; thickness in ug/cm^2; e_final in units of MeV Returns units of MeV; thickness in ug/cm^2; e_final in units of MeV
Energy loss going through the target using energy of particle after traversal Energy loss going through the target using energy of particle after traversal
*/ */
double EnergyLoss::GetReverseEnergyLoss(int zp, int ap, double e_final, double thickness) { double EnergyLoss::GetReverseEnergyLoss(int zp, int ap, double e_final, double thickness) {
if( ZP != zp) { if( ZP != zp) {
ZP = zp; ZP = zp;
AP = ap; AP = ap;
@ -123,14 +121,14 @@ double EnergyLoss::GetReverseEnergyLoss(int zp, int ap, double e_final, double t
} }
return e_initial-e_final; return e_initial-e_final;
} }
/* /*
Returns units of keV/(ug/cm^2) Returns units of keV/(ug/cm^2)
Calculates Electronic stopping power by first calculating SE for hydrogen through the target and then using Calculates Electronic stopping power by first calculating SE for hydrogen through the target and then using
corrections to calculate SE for projectile of interest corrections to calculate SE for projectile of interest
*/ */
double EnergyLoss::GetElectronicStoppingPower(double energy) { double EnergyLoss::GetElectronicStoppingPower(double energy) {
//Wants in units of keV //Wants in units of keV
energy *= 1000.0; energy *= 1000.0;
double e_per_u = energy/MP; double e_per_u = energy/MP;
@ -138,30 +136,25 @@ double EnergyLoss::GetElectronicStoppingPower(double energy) {
if(e_per_u > MAX_H_E_PER_U) { if(e_per_u > MAX_H_E_PER_U) {
throw ELossException("Exceeded maximum allowed energy per nucleon"); throw ELossException("Exceeded maximum allowed energy per nucleon");
} else if (e_per_u > 1000.0) { } else if (e_per_u > 1000.0) {
for(auto& z: ZT) { for(auto& z: ZT)
values.push_back(Hydrogen_dEdx_High(e_per_u, energy, z)); values.push_back(Hydrogen_dEdx_High(e_per_u, energy, z));
}
} else if (e_per_u > 10.0) { } else if (e_per_u > 10.0) {
for(auto& z: ZT) { for(auto& z: ZT)
values.push_back(Hydrogen_dEdx_Med(e_per_u, z)); values.push_back(Hydrogen_dEdx_Med(e_per_u, z));
}
} else if (e_per_u > 0.0) { } else if (e_per_u > 0.0) {
for(auto& z: ZT) { for(auto& z: ZT)
values.push_back(Hydrogen_dEdx_Low(e_per_u, z)); values.push_back(Hydrogen_dEdx_Low(e_per_u, z));
}
} else { } else {
throw ELossException("Negative energy per nucleon"); throw ELossException("Negative energy per nucleon");
} }
if(values.size() == 0) { if(values.size() == 0)
throw ELossException("Size of value array is 0. Unable to iterate over target components"); throw ELossException("Size of value array is 0. Unable to iterate over target components");
}
if(ZP > 1) { //not hydrogen, need to account for effective charge if(ZP > 1) { //not hydrogen, need to account for effective charge
for(unsigned int i=0; i<values.size(); i++) { for(unsigned int i=0; i<values.size(); i++)
values[i] *= CalculateEffectiveChargeRatio(e_per_u, ZT[i]); values[i] *= CalculateEffectiveChargeRatio(e_per_u, ZT[i]);
} }
}
double stopping_total = 0; double stopping_total = 0;
double conversion_factor = 0; double conversion_factor = 0;
@ -172,10 +165,10 @@ double EnergyLoss::GetElectronicStoppingPower(double energy) {
stopping_total *= AVOGADRO/conversion_factor; stopping_total *= AVOGADRO/conversion_factor;
return stopping_total; return stopping_total;
} }
//Returns units of keV/(ug/cm^2) //Returns units of keV/(ug/cm^2)
double EnergyLoss::GetNuclearStoppingPower(double energy) { double EnergyLoss::GetNuclearStoppingPower(double energy) {
energy *= 1000.0; energy *= 1000.0;
double stopping_total = 0.0; double stopping_total = 0.0;
double sn, x, epsilon, conversion_factor; double sn, x, epsilon, conversion_factor;
@ -188,57 +181,63 @@ double EnergyLoss::GetNuclearStoppingPower(double energy) {
} }
return stopping_total; return stopping_total;
}
/*Wrapper function for aquiring total stopping (elec + nuc)*/
double EnergyLoss::GetTotalStoppingPower(double energy) {
if(ZP == 0) {
return GetNuclearStoppingPower(energy);
} }
return GetElectronicStoppingPower(energy)+GetNuclearStoppingPower(energy);
}
/*Charge rel to H*/ /*Wrapper function for aquiring total stopping (elec + nuc)*/
double EnergyLoss::CalculateEffectiveChargeRatio(double e_per_u, int z) { double EnergyLoss::GetTotalStoppingPower(double energy) {
if(ZP == 0)
return GetNuclearStoppingPower(energy);
return GetElectronicStoppingPower(energy)+GetNuclearStoppingPower(energy);
}
/*Charge rel to H*/
double EnergyLoss::CalculateEffectiveChargeRatio(double e_per_u, int z) {
double z_ratio; double z_ratio;
if(ZP == 2) { if(ZP == 2) {
double ln_epu = std::log(e_per_u); double ln_epu = std::log(e_per_u);
double gamma = 1.0+(0.007+0.00005*z)*std::exp(-std::pow(7.6-ln_epu,2.0)); double gamma = 1.0+(0.007+0.00005*z)*std::exp(-std::pow(7.6-ln_epu,2.0));
double alpha = 0.7446 + 0.1429*ln_epu + 0.01562*std::pow(ln_epu, 2.0) - 0.00267*std::pow(ln_epu,3.0) double alpha = 0.7446 + 0.1429*ln_epu + 0.01562*std::pow(ln_epu, 2.0) - 0.00267*std::pow(ln_epu,3.0)
+ 1.338E-6*std::pow(ln_epu,8.0); + 1.338E-6*std::pow(ln_epu,8.0);
z_ratio = gamma*(1.0-std::exp(-alpha))*2.0; //test this; SPANC has factor of 2. mult z_ratio = gamma*(1.0-std::exp(-alpha))*2.0;
} else if (ZP == 3) { } else if (ZP == 3) {
double ln_epu = std::log(e_per_u); double ln_epu = std::log(e_per_u);
double gamma = 1.0+(0.007+0.00005*z)*std::exp(-std::pow(7.6-ln_epu,2.0)); double gamma = 1.0+(0.007+0.00005*z)*std::exp(-std::pow(7.6-ln_epu,2.0));
double alpha = 0.7138+0.002797*e_per_u+1.348E-6*std::pow(e_per_u, 2.0); double alpha = 0.7138+0.002797*e_per_u+1.348E-6*std::pow(e_per_u, 2.0);
z_ratio = gamma*(1-std::exp(-alpha))*3.0; //test this; SPANC has factor of 3. mult z_ratio = gamma*(1-std::exp(-alpha))*3.0;
} else { } else {
double B = 0.886*std::pow(e_per_u/25.0, 0.5)/std::pow(ZP, 2.0/3.0); double B = 0.886*std::pow(e_per_u/25.0, 0.5)/std::pow(ZP, 2.0/3.0);
double A = B + 0.0378*std::sin(PI/2.0*B); double A = B + 0.0378*std::sin(M_PI/2.0*B);
z_ratio = 1.0 - std::exp(-A)*(1.034-0.1777*std::exp(-0.08114*ZP))*z; //test this; SPANC has factor of ZT[i] mult z_ratio = 1.0 - std::exp(-A)*(1.034-0.1777*std::exp(-0.08114*ZP))*z;
} }
return z_ratio*z_ratio; //for stopping power uses ratio sq. return z_ratio*z_ratio; //for stopping power uses ratio sq.
} }
double EnergyLoss::Hydrogen_dEdx_Low(double e_per_u, int z) { double EnergyLoss::Hydrogen_dEdx_Low(double e_per_u, int z) {
return std::sqrt(e_per_u)*HYDROGEN_COEFF[z][0]; return std::sqrt(e_per_u)*HYDROGEN_COEFF[z][0];
} }
double EnergyLoss::Hydrogen_dEdx_Med(double e_per_u, int z) { double EnergyLoss::Hydrogen_dEdx_Med(double e_per_u, int z) {
double x = HYDROGEN_COEFF[z][1]*std::pow(e_per_u, 0.45); double x = HYDROGEN_COEFF[z][1]*std::pow(e_per_u, 0.45);
double y = HYDROGEN_COEFF[z][2]/e_per_u * std::log(1.0+HYDROGEN_COEFF[z][3]/e_per_u+HYDROGEN_COEFF[z][4]*e_per_u); double y = HYDROGEN_COEFF[z][2]/e_per_u * std::log(1.0+HYDROGEN_COEFF[z][3]/e_per_u+HYDROGEN_COEFF[z][4]*e_per_u);
return x*y/(x+y); return x*y/(x+y);
} }
double EnergyLoss::Hydrogen_dEdx_High(double e_per_u, double energy, int z) { double EnergyLoss::Hydrogen_dEdx_High(double e_per_u, double energy, int z) {
energy /= 1000.0; //back to MeV for ease of beta calc energy /= 1000.0; //back to MeV for ease of beta calc
double beta_sq = energy * (energy+2.0*MP/MEV2U)/std::pow(energy+MP/MEV2U, 2.0); double beta_sq = energy * (energy+2.0*MP/MEV2U)/std::pow(energy+MP/MEV2U, 2.0);
double alpha = HYDROGEN_COEFF[z][5]/beta_sq; double alpha = HYDROGEN_COEFF[z][5]/beta_sq;
double epsilon = HYDROGEN_COEFF[z][6]*beta_sq/(1.0-beta_sq) - beta_sq - HYDROGEN_COEFF[z][7]; double epsilon = HYDROGEN_COEFF[z][6]*beta_sq/(1.0-beta_sq) - beta_sq - HYDROGEN_COEFF[z][7];
for(int i=1; i<5; i++) { for(int i=1; i<5; i++)
epsilon += HYDROGEN_COEFF[z][7+i]*std::pow(std::log(e_per_u), i); epsilon += HYDROGEN_COEFF[z][7+i]*std::pow(std::log(e_per_u), i);
}
return alpha * std::log(epsilon);
}
double EnergyLoss::GetRange(double energy) {return 0.0;} //unimplemented return alpha * std::log(epsilon);
}
//unimplemented
double EnergyLoss::GetRange(double energy) {
std::cerr<<"EnergyLoss::GetRange is not implemented! Returning 0.0"<<std::endl;
return 0.0;
}
}

View File

@ -24,7 +24,6 @@ namespace Mask {
std::ifstream input(filename); std::ifstream input(filename);
if(!input.is_open()) { if(!input.is_open()) {
std::cerr<<"Unable to load configuration in "<<filename<<", check that it exists"<<std::endl;
return false; return false;
} }

View File

@ -1,7 +1,7 @@
/* /*
LayeredTarget.h LayeredTarget.h
Functional unit for targets in the SPANCRedux environment. Contains a Functional unit for targets in the Mask environment. Contains a
set (read: vector) of Targets for use in reaction calculations. In this set (read: vector) of Targets for use in reaction calculations. In this
way handles situations such as carbon backed targets way handles situations such as carbon backed targets
@ -11,24 +11,30 @@ Written by G.W. McCann Aug. 2020
*/ */
#include "LayeredTarget.h" #include "LayeredTarget.h"
#include <iostream>
LayeredTarget::LayeredTarget() {} namespace Mask {
LayeredTarget::~LayeredTarget() {} LayeredTarget::LayeredTarget() :
name("")
{
}
/*Add in a Target made of a compound defined by a set of Zs, As, Ss, and a thickness*/ LayeredTarget::~LayeredTarget() {}
void LayeredTarget::AddLayer(std::vector<int>& Z, std::vector<int>& A, std::vector<int>& stoich, double thickness) {
/*Add in a Target made of a compound defined by a set of Zs, As, Ss, and a thickness*/
void LayeredTarget::AddLayer(std::vector<int>& Z, std::vector<int>& A, std::vector<int>& stoich, double thickness) {
Target t(thickness); Target t(thickness);
t.SetElements(Z, A, stoich); t.SetElements(Z, A, stoich);
layers.push_back(t); layers.push_back(t);
} }
/* /*
Here projectile refers to the incoming reactant particle (i.e. the beam) Here projectile refers to the incoming reactant particle (i.e. the beam)
Calculates energy loss assuming that the reaction occurs in the middle of the target Calculates energy loss assuming that the reaction occurs in the middle of the target
Note that the layer order can matter! Note that the layer order can matter!
*/ */
double LayeredTarget::GetProjectileEnergyLoss(int zp, int ap, double startEnergy, int rxnLayer, double angle) { double LayeredTarget::GetProjectileEnergyLoss(int zp, int ap, double startEnergy, int rxnLayer, double angle) {
if(rxnLayer < 0 || ((unsigned int) rxnLayer) > layers.size()) { if(rxnLayer < 0 || ((unsigned int) rxnLayer) > layers.size()) {
std::cerr<<"Reaction layer in eloss calculation is not in range! Returning 0"<<std::endl; std::cerr<<"Reaction layer in eloss calculation is not in range! Returning 0"<<std::endl;
@ -48,14 +54,14 @@ double LayeredTarget::GetProjectileEnergyLoss(int zp, int ap, double startEnergy
} }
return eloss; return eloss;
} }
/* /*
Here ejectile refers to the outgoing reactant particle Here ejectile refers to the outgoing reactant particle
Calculates energy loss assuming that the reaction occurs in the middle of the target Calculates energy loss assuming that the reaction occurs in the middle of the target
Note that the layer order can matter! Note that the layer order can matter!
*/ */
double LayeredTarget::GetEjectileEnergyLoss(int ze, int ae, double startEnergy, int rxnLayer, double angle) { double LayeredTarget::GetEjectileEnergyLoss(int ze, int ae, double startEnergy, int rxnLayer, double angle) {
if(rxnLayer < 0 || ((unsigned int) rxnLayer) > layers.size()) { if(rxnLayer < 0 || ((unsigned int) rxnLayer) > layers.size()) {
std::cerr<<"Reaction layer in eloss calculation is not in range! Returning 0"<<std::endl; std::cerr<<"Reaction layer in eloss calculation is not in range! Returning 0"<<std::endl;
@ -75,10 +81,10 @@ double LayeredTarget::GetEjectileEnergyLoss(int ze, int ae, double startEnergy,
} }
return eloss; return eloss;
} }
/*ReverseEnergyLoss version of GetEjectileEnergyLoss*/ /*ReverseEnergyLoss version of GetEjectileEnergyLoss*/
double LayeredTarget::GetEjectileReverseEnergyLoss(int ze, int ae, double startEnergy, int rxnLayer, double angle) { double LayeredTarget::GetEjectileReverseEnergyLoss(int ze, int ae, double startEnergy, int rxnLayer, double angle) {
if(rxnLayer < 0 || ((unsigned int) rxnLayer) > layers.size()) { if(rxnLayer < 0 || ((unsigned int) rxnLayer) > layers.size()) {
std::cerr<<"Reaction layer in eloss calculation is not in range! Returning 0"<<std::endl; std::cerr<<"Reaction layer in eloss calculation is not in range! Returning 0"<<std::endl;
@ -98,30 +104,15 @@ double LayeredTarget::GetEjectileReverseEnergyLoss(int ze, int ae, double startE
} }
return eloss; return eloss;
}
/*Getters and Setters*/
int LayeredTarget::GetNumberOfLayers() {
return layers.size();
}
int LayeredTarget::FindLayerContaining(int Z, int A) {
for(unsigned int i=0; i<layers.size(); i++) {
if(layers[i].ContainsElement(Z, A)) return i;
} }
int LayeredTarget::FindLayerContaining(int Z, int A) {
for(unsigned int i=0; i<layers.size(); i++)
if(layers[i].ContainsElement(Z, A))
return i;
return -1; return -1;
} }
void LayeredTarget::SetName(std::string& n) {
name = n;
}
Target& LayeredTarget::GetLayerInfo(int index) {
return layers[index];
} }
std::string& LayeredTarget::GetName() {
return name;
}

View File

@ -1,7 +1,9 @@
#include "LegendrePoly.h" #include "LegendrePoly.h"
#include <cmath> #include <cmath>
double P_l(int l, double x) { namespace Mask {
double P_l(int l, double x) {
if(l == 0) { if(l == 0) {
return 1.0; return 1.0;
} else if (l == 1) { } else if (l == 1) {
@ -9,24 +11,26 @@ double P_l(int l, double x) {
} else { } else {
return (2.0*l - 1.0)/l*x*P_l(l-1, x) - (l-1.0)/l*P_l(l-2, x); return (2.0*l - 1.0)/l*x*P_l(l-1, x) - (l-1.0)/l*P_l(l-2, x);
} }
} }
double Normed_P_l_sq(int l, double x) { double Normed_P_l_sq(int l, double x) {
return (2.0*l+1.0)/2.0*std::pow(P_l(l, x), 2.0); return (2.0*l+1.0)/2.0*std::pow(P_l(l, x), 2.0);
} }
double P_0(double x) { double P_0(double x) {
return 1.0; return 1.0;
} }
double P_1(double x) { double P_1(double x) {
return x; return x;
} }
double P_2(double x) { double P_2(double x) {
return 0.5*(3.0*x*x -1.0); return 0.5*(3.0*x*x -1.0);
} }
double P_l_ROOT(double* x, double* pars) { double P_l_ROOT(double* x, double* pars) {
return P_l(pars[0], x[0]); return P_l(pars[0], x[0]);
}
} }

View File

@ -11,16 +11,13 @@ Written by G.W. McCann Aug. 2020
#include "MassLookup.h" #include "MassLookup.h"
#include "KinematicsExceptions.h" #include "KinematicsExceptions.h"
namespace Mask {
/* MassLookup* MassLookup::s_instance = nullptr;
Read in AMDC mass file, preformated to remove excess info. Here assumes that by default
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()) {
std::string junk, A, element; std::string junk, A, element;
int Z; int Z;
@ -37,26 +34,28 @@ MassLookup::MassLookup() {
} else { } else {
throw MassFileException(); throw MassFileException();
} }
} }
MassLookup::~MassLookup() {} MassLookup::~MassLookup() {}
//Returns nuclear mass in MeV //Returns nuclear mass in MeV
double MassLookup::FindMass(int Z, int A) { double MassLookup::FindMass(int Z, int A) {
std::string key = "("+std::to_string(Z)+","+std::to_string(A)+")"; std::string key = "("+std::to_string(Z)+","+std::to_string(A)+")";
auto data = massTable.find(key); auto data = massTable.find(key);
if(data == massTable.end()) { if(data == massTable.end())
throw MassException(); throw MassException();
}
return data->second;
}
//returns element symbol return data->second;
std::string MassLookup::FindSymbol(int Z, int A) {
auto data = elementTable.find(Z);
if(data == elementTable.end()) {
throw MassException();
} }
//returns element symbol
std::string MassLookup::FindSymbol(int Z, int A) {
auto data = elementTable.find(Z);
if(data == elementTable.end())
throw MassException();
std::string fullsymbol = std::to_string(A) + data->second; std::string fullsymbol = std::to_string(A) + data->second;
return fullsymbol; return fullsymbol;
}
} }

View File

@ -11,29 +11,29 @@
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(""), m_detectFlag(false) 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), m_detectFlag(false) Vec4(), m_z(Z), m_a(A), m_theta_cm(0), m_detectFlag(false)
{ {
m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A); m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A);
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A); m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A);
SetVectorCartesian(0,0,0,m_gs_mass); //by defualt a nucleus has mass given by the g.s. SetVectorCartesian(0,0,0,m_gs_mass); //by defualt a nucleus has mass given by the g.s.
} }
Nucleus::Nucleus(int Z, int A, double px, double py, double pz, double E) : Nucleus::Nucleus(int Z, int A, double px, double py, double pz, double E) :
Vec4(px, py, pz, E), m_z(Z), m_a(A) Vec4(px, py, pz, E), m_z(Z), m_a(A)
{ {
m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A); m_gs_mass = MassLookup::GetInstance()->FindMass(Z, A);
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A); m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A);
} }
Nucleus::~Nucleus() {} Nucleus::~Nucleus() {}
bool Nucleus::SetIsotope(int Z, int A) { bool Nucleus::SetIsotope(int Z, int A) {
if(Z>A) return false; if(Z>A) return false;
m_z = Z; m_z = Z;
@ -42,6 +42,6 @@ bool Nucleus::SetIsotope(int Z, int A) {
m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A); m_symbol = MassLookup::GetInstance()->FindSymbol(Z, A);
SetVectorCartesian(0,0,0,m_gs_mass); SetVectorCartesian(0,0,0,m_gs_mass);
return true; return true;
} }
}; }

View File

@ -55,7 +55,6 @@ namespace Mask {
LinkTarget(); LinkTarget();
} }
if(!step1.IsDecay()) {
//Sample parameters //Sample parameters
double bke = (*m_beamDist)(*generator); double bke = (*m_beamDist)(*generator);
double rxnTheta = std::acos((*m_theta1Range)(*generator)); double rxnTheta = std::acos((*m_theta1Range)(*generator));
@ -69,9 +68,6 @@ namespace Mask {
step1.TurnOnResidualEloss(); step1.TurnOnResidualEloss();
step1.Calculate(); step1.Calculate();
} else {
return;
}
} }
} }

View File

@ -11,24 +11,25 @@
namespace Mask { namespace Mask {
Reaction::Reaction() : Reaction::Reaction() :
target(nullptr), m_bke(0), m_theta(0), m_phi(0), m_ex(0), rxnLayer(0), m_eject_theta_type(lab), nuc_initFlag(false), resid_elossFlag(false) target(nullptr), m_bke(0), m_theta(0), m_phi(0), m_ex(0), rxnLayer(0), m_eject_theta_type(lab), nuc_initFlag(false), resid_elossFlag(false)
{ {
} }
Reaction::Reaction(int zt, int at, int zp, int ap, int ze, int ae) : Reaction::Reaction(int zt, int at, int zp, int ap, int ze, int ae) :
target(nullptr), m_bke(0), m_theta(0), m_phi(0), m_ex(0), rxnLayer(0), m_eject_theta_type(lab), resid_elossFlag(false) target(nullptr), m_bke(0), m_theta(0), m_phi(0), m_ex(0), rxnLayer(0), m_eject_theta_type(lab), resid_elossFlag(false)
{ {
SetNuclei(zt, at, zp, ap, ze, ae); SetNuclei(zt, at, zp, ap, ze, ae);
} }
Reaction::~Reaction() Reaction::~Reaction()
{ {
} }
bool Reaction::Calculate() { bool Reaction::Calculate() {
if(!nuc_initFlag) return false; if(!nuc_initFlag)
return false;
if(decayFlag) { if(decayFlag) {
CalculateDecay(); CalculateDecay();
@ -37,18 +38,18 @@ bool Reaction::Calculate() {
CalculateReaction(); CalculateReaction();
return true; return true;
} }
} }
//Deep copy of nucleus array //Deep copy of nucleus array
void Reaction::SetNuclei(const Nucleus* nucs) { void Reaction::SetNuclei(const Nucleus* nucs) {
reactants[0] = nucs[0]; reactants[0] = nucs[0];
reactants[1] = nucs[1]; reactants[1] = nucs[1];
reactants[2] = nucs[2]; reactants[2] = nucs[2];
reactants[3] = nucs[3]; reactants[3] = nucs[3];
nuc_initFlag = true; nuc_initFlag = true;
} }
void Reaction::SetNuclei(int zt, int at, int zp, int ap, int ze, int ae) { void Reaction::SetNuclei(int zt, int at, int zp, int ap, int ze, int ae) {
int zr, ar; int zr, ar;
reactants[0] = Nucleus(zt, at); reactants[0] = Nucleus(zt, at);
reactants[2] = Nucleus(ze, ae); reactants[2] = Nucleus(ze, ae);
@ -69,24 +70,25 @@ void Reaction::SetNuclei(int zt, int at, int zp, int ap, int ze, int ae) {
reactants[3] = Nucleus(zr, ar); reactants[3] = Nucleus(zr, ar);
nuc_initFlag = true; nuc_initFlag = true;
} }
} }
void Reaction::SetBeamKE(double bke) {
if(!nuc_initFlag || decayFlag)
return;
void Reaction::SetBeamKE(double bke) {
if(!nuc_initFlag) return;
else if(decayFlag) return;
m_bke = bke - target->GetProjectileEnergyLoss(reactants[1].GetZ(), reactants[1].GetA(), bke, rxnLayer, 0); m_bke = bke - target->GetProjectileEnergyLoss(reactants[1].GetZ(), reactants[1].GetA(), bke, rxnLayer, 0);
}; }
void Reaction::SetEjectileThetaType(int type) { void Reaction::SetEjectileThetaType(int type) {
if(decayFlag) return; if(decayFlag) return;
if(type != center_of_mass && type != lab) return; if(type != center_of_mass && type != lab) return;
m_eject_theta_type = type; m_eject_theta_type = type;
} }
//Methods given by Iliadis in Nuclear Physics of Stars, Appendix C //Methods given by Iliadis in Nuclear Physics of Stars, Appendix C
//For use with lab frame restricted angles. May not give appropriate disribution for ejectile //For use with lab frame restricted angles. May not give appropriate disribution for ejectile
void Reaction::CalculateReactionThetaLab() { void Reaction::CalculateReactionThetaLab() {
reactants[0].SetVectorCartesian(0.,0.,0.,reactants[0].GetGroundStateMass()); reactants[0].SetVectorCartesian(0.,0.,0.,reactants[0].GetGroundStateMass());
double beam_pz = std::sqrt(m_bke*(m_bke + 2.0 * reactants[1].GetGroundStateMass())); double beam_pz = std::sqrt(m_bke*(m_bke + 2.0 * reactants[1].GetGroundStateMass()));
double beam_E = m_bke + reactants[1].GetGroundStateMass(); double beam_E = m_bke + reactants[1].GetGroundStateMass();
@ -127,10 +129,10 @@ void Reaction::CalculateReactionThetaLab() {
double residE = residKE + reactants[3].GetInvMass(); double residE = residKE + reactants[3].GetInvMass();
reactants[3].SetVectorSpherical(reactants[3].GetTheta(), reactants[3].GetPhi(), residP, residE); reactants[3].SetVectorSpherical(reactants[3].GetTheta(), reactants[3].GetPhi(), residP, residE);
} }
} }
//Methods from original ANASEN. Gives proper distribution for inverse kinematics. //Methods from original ANASEN. Gives proper distribution for inverse kinematics.
void Reaction::CalculateReactionThetaCM() { void Reaction::CalculateReactionThetaCM() {
//Target assumed at rest, with 0 excitation energy //Target assumed at rest, with 0 excitation energy
reactants[0].SetVectorCartesian(0.,0.,0.,reactants[0].GetGroundStateMass()); reactants[0].SetVectorCartesian(0.,0.,0.,reactants[0].GetGroundStateMass());
double beam_pz = std::sqrt(m_bke*(m_bke + 2.0 * reactants[1].GetGroundStateMass())); double beam_pz = std::sqrt(m_bke*(m_bke + 2.0 * reactants[1].GetGroundStateMass()));
@ -176,9 +178,9 @@ void Reaction::CalculateReactionThetaCM() {
double residE = residKE + reactants[3].GetInvMass(); double residE = residKE + reactants[3].GetInvMass();
reactants[3].SetVectorSpherical(reactants[3].GetTheta(), reactants[3].GetPhi(), residP, residE); reactants[3].SetVectorSpherical(reactants[3].GetTheta(), reactants[3].GetPhi(), residP, residE);
} }
} }
void Reaction::CalculateReaction() { void Reaction::CalculateReaction() {
switch(m_eject_theta_type) { switch(m_eject_theta_type) {
case center_of_mass: case center_of_mass:
{ {
@ -191,10 +193,10 @@ void Reaction::CalculateReaction() {
break; break;
} }
} }
} }
//Calculate in CM, where decay is isotropic //Calculate in CM, where decay is isotropic
void Reaction::CalculateDecay() { void Reaction::CalculateDecay() {
double Q = reactants[0].GetInvMass() - reactants[2].GetGroundStateMass() - reactants[3].GetGroundStateMass(); double Q = reactants[0].GetInvMass() - reactants[2].GetGroundStateMass() - reactants[3].GetGroundStateMass();
if(Q < 0) { if(Q < 0) {
@ -236,9 +238,9 @@ void Reaction::CalculateDecay() {
double residE = residKE + reactants[3].GetInvMass(); double residE = residKE + reactants[3].GetInvMass();
reactants[3].SetVectorSpherical(reactants[3].GetTheta(), reactants[3].GetPhi(), residP, residE); reactants[3].SetVectorSpherical(reactants[3].GetTheta(), reactants[3].GetPhi(), residP, residE);
} }
}
} }
};

View File

@ -7,65 +7,65 @@
namespace Mask { namespace Mask {
XRotation::XRotation() : XRotation::XRotation() :
m_angle(0) m_angle(0)
{ {
GenerateMatrix(); GenerateMatrix();
} }
XRotation::XRotation(double angle) : XRotation::XRotation(double angle) :
m_angle(angle) m_angle(angle)
{ {
GenerateMatrix(); GenerateMatrix();
} }
XRotation::~XRotation() {} XRotation::~XRotation() {}
void XRotation::GenerateMatrix() { void XRotation::GenerateMatrix() {
m_matrix[0][0] = 1.0; m_matrix[0][1] = 0.0; m_matrix[0][2] = 0.0; m_matrix[0][0] = 1.0; m_matrix[0][1] = 0.0; m_matrix[0][2] = 0.0;
m_matrix[1][0] = 0.0; m_matrix[1][1] = std::cos(m_angle); m_matrix[1][2] = -std::sin(m_angle); m_matrix[1][0] = 0.0; m_matrix[1][1] = std::cos(m_angle); m_matrix[1][2] = -std::sin(m_angle);
m_matrix[2][0] = 0.0; m_matrix[2][1] = std::sin(m_angle); m_matrix[2][2] = std::cos(m_angle); m_matrix[2][0] = 0.0; m_matrix[2][1] = std::sin(m_angle); m_matrix[2][2] = std::cos(m_angle);
} }
YRotation::YRotation() : YRotation::YRotation() :
m_angle(0) m_angle(0)
{ {
GenerateMatrix(); GenerateMatrix();
} }
YRotation::YRotation(double angle) : YRotation::YRotation(double angle) :
m_angle(angle) m_angle(angle)
{ {
GenerateMatrix(); GenerateMatrix();
} }
YRotation::~YRotation() {} YRotation::~YRotation() {}
void YRotation::GenerateMatrix() { void YRotation::GenerateMatrix() {
m_matrix[0][0] = std::cos(m_angle); m_matrix[0][1] = 0.0; m_matrix[0][2] = -std::sin(m_angle); m_matrix[0][0] = std::cos(m_angle); m_matrix[0][1] = 0.0; m_matrix[0][2] = -std::sin(m_angle);
m_matrix[1][0] = 0.0; m_matrix[1][1] = 1.0; m_matrix[1][2] = 0.0; m_matrix[1][0] = 0.0; m_matrix[1][1] = 1.0; m_matrix[1][2] = 0.0;
m_matrix[2][0] = std::sin(m_angle); m_matrix[2][1] = 0.0; m_matrix[2][2] = std::cos(m_angle); m_matrix[2][0] = std::sin(m_angle); m_matrix[2][1] = 0.0; m_matrix[2][2] = std::cos(m_angle);
} }
ZRotation::ZRotation() : ZRotation::ZRotation() :
m_angle(0) m_angle(0)
{ {
GenerateMatrix(); GenerateMatrix();
} }
ZRotation::ZRotation(double angle) : ZRotation::ZRotation(double angle) :
m_angle(angle) m_angle(angle)
{ {
GenerateMatrix(); GenerateMatrix();
} }
ZRotation::~ZRotation() {} ZRotation::~ZRotation() {}
void ZRotation::GenerateMatrix() { void ZRotation::GenerateMatrix() {
m_matrix[0][0] = std::cos(m_angle); m_matrix[0][1] = -std::sin(m_angle); m_matrix[0][2] = 0.0; m_matrix[0][0] = std::cos(m_angle); m_matrix[0][1] = -std::sin(m_angle); m_matrix[0][2] = 0.0;
m_matrix[1][0] = std::sin(m_angle); m_matrix[1][1] = std::cos(m_angle); m_matrix[1][2] = 0.0; m_matrix[1][0] = std::sin(m_angle); m_matrix[1][1] = std::cos(m_angle); m_matrix[1][2] = 0.0;
m_matrix[2][0] = 0.0; m_matrix[2][1] = 0.0; m_matrix[2][2] = 1.0; m_matrix[2][0] = 0.0; m_matrix[2][1] = 0.0; m_matrix[2][2] = 1.0;
} }
}; };

View File

@ -12,77 +12,70 @@ Written by G.W. McCann Aug. 2020
*/ */
#include "Target.h" #include "Target.h"
/*Targets must be of known thickness*/ namespace Mask {
Target::Target(double thick) {
/*Targets must be of known thickness*/
Target::Target(double thick) {
thickness = thick; thickness = thick;
} }
Target::~Target() { Target::~Target() {}
}
/*Set target elements of given Z, A, S*/ /*Set target elements of given Z, A, S*/
void Target::SetElements(std::vector<int>& z, std::vector<int>& a, std::vector<int>& stoich) { void Target::SetElements(std::vector<int>& z, std::vector<int>& a, std::vector<int>& stoich) {
Z = z; Z = z;
A = a; A = a;
Stoich = stoich; Stoich = stoich;
eloss.SetTargetComponents(Z, A, Stoich); eloss.SetTargetComponents(Z, A, Stoich);
}
/*Element verification*/
bool Target::ContainsElement(int z, int a) {
for(unsigned int i=0; i<Z.size(); i++) {
if( z == Z[i] && a == A[i]) return true;
} }
/*Element verification*/
bool Target::ContainsElement(int z, int a) {
for(unsigned int i=0; i<Z.size(); i++)
if( z == Z[i] && a == A[i])
return true;
return false; return false;
} }
/*Calculates energy loss for travelling all the way through the target*/
double Target::getEnergyLossTotal(int zp, int ap, double startEnergy, double theta) {
if(theta == M_PI/2.)
return startEnergy;
else if (theta > M_PI/2.)
theta = M_PI - theta;
/*Calculates energy loss for travelling all the way through the target*/
double Target::getEnergyLossTotal(int zp, int ap, double startEnergy, double theta) {
if(theta == PI/2.) return startEnergy;
else if (theta > PI/2.) theta = PI - theta;
return eloss.GetEnergyLoss(zp, ap, startEnergy, thickness/fabs(cos(theta))); return eloss.GetEnergyLoss(zp, ap, startEnergy, thickness/fabs(cos(theta)));
} }
/*Calculates energy loss for travelling halfway through the target*/
double Target::getEnergyLossHalf(int zp, int ap, double startEnergy, double theta) {
if(theta == M_PI/2.)
return startEnergy;
else if (theta > M_PI/2.)
theta = M_PI - theta;
/*Calculates energy loss for travelling halfway through the target*/
double Target::getEnergyLossHalf(int zp, int ap, double startEnergy, double theta) {
if(theta == PI/2.) return startEnergy;
else if (theta > PI/2.) theta = PI - theta;
return eloss.GetEnergyLoss(zp, ap, startEnergy, thickness/(2.0*fabs(cos(theta)))); return eloss.GetEnergyLoss(zp, ap, startEnergy, thickness/(2.0*fabs(cos(theta))));
} }
/*Calculates reverse energy loss for travelling all the way through the target*/
double Target::getReverseEnergyLossTotal(int zp, int ap, double finalEnergy, double theta) {
if(theta == M_PI/2.)
return finalEnergy;
else if (theta > M_PI/2.)
theta = M_PI - theta;
/*Calculates reverse energy loss for travelling all the way through the target*/
double Target::getReverseEnergyLossTotal(int zp, int ap, double finalEnergy, double theta) {
if(theta == PI/2.) return finalEnergy;
else if (theta > PI/2.) theta = PI - theta;
return eloss.GetReverseEnergyLoss(zp, ap, finalEnergy, thickness/fabs(cos(theta))); return eloss.GetReverseEnergyLoss(zp, ap, finalEnergy, thickness/fabs(cos(theta)));
} }
/*Calculates reverse energy loss for travelling half way through the target*/
double Target::getReverseEnergyLossHalf(int zp, int ap, double finalEnergy, double theta) {
if(theta == M_PI/2.)
return finalEnergy;
else if (theta > M_PI/2.)
theta = M_PI - theta;
/*Calculates reverse energy loss for travelling half way through the target*/
double Target::getReverseEnergyLossHalf(int zp, int ap, double finalEnergy, double theta) {
if(theta == PI/2.) return finalEnergy;
else if (theta > PI/2.) theta = PI - theta;
return eloss.GetReverseEnergyLoss(zp, ap, finalEnergy, thickness/(2.0*fabs(cos(theta)))); return eloss.GetReverseEnergyLoss(zp, ap, finalEnergy, thickness/(2.0*fabs(cos(theta))));
} }
/*Getter functions*/
double& Target::GetThickness() {
return thickness;
}
int Target::GetNumberOfElements() {
return Z.size();
}
int Target::GetElementZ(int index) {
return Z[index];
}
int Target::GetElementA(int index) {
return A[index];
}
int Target::GetElementStoich(int index) {
return Stoich[index];
} }

View File

@ -8,41 +8,41 @@
namespace Mask { namespace Mask {
Vec3::Vec3() { Vec3::Vec3() {
m_data[0] = 0.; m_data[0] = 0.;
m_data[1] = 0.; m_data[1] = 0.;
m_data[2] = 0.; m_data[2] = 0.;
} }
Vec3::Vec3(double x, double y, double z) { Vec3::Vec3(double x, double y, double z) {
m_data[0] = x; m_data[0] = x;
m_data[1] = y; m_data[1] = y;
m_data[2] = z; m_data[2] = z;
} }
Vec3::~Vec3() {} Vec3::~Vec3() {}
void Vec3::SetVectorCartesian(double x, double y, double z) { void Vec3::SetVectorCartesian(double x, double y, double z) {
m_data[0] = x; m_data[0] = x;
m_data[1] = y; m_data[1] = y;
m_data[2] = z; m_data[2] = z;
} }
void Vec3::SetVectorSpherical(double r, double theta, double phi) { void Vec3::SetVectorSpherical(double r, double theta, double phi) {
m_data[0] = r*std::cos(phi)*std::sin(theta); m_data[0] = r*std::cos(phi)*std::sin(theta);
m_data[1] = r*std::sin(phi)*std::sin(theta); m_data[1] = r*std::sin(phi)*std::sin(theta);
m_data[2] = r*std::cos(theta); m_data[2] = r*std::cos(theta);
} }
double Vec3::Dot(const Vec3& rhs) const { double Vec3::Dot(const Vec3& rhs) const {
return GetX()*rhs.GetX() + GetY()*rhs.GetY() + GetZ()*rhs.GetZ(); return GetX()*rhs.GetX() + GetY()*rhs.GetY() + GetZ()*rhs.GetZ();
} }
Vec3 Vec3::Cross(const Vec3& rhs) const { Vec3 Vec3::Cross(const Vec3& rhs) const {
double x = GetY()*rhs.GetZ() - GetZ()*rhs.GetY(); double x = GetY()*rhs.GetZ() - GetZ()*rhs.GetY();
double y = GetZ()*rhs.GetX() - GetX()*rhs.GetZ(); double y = GetZ()*rhs.GetX() - GetX()*rhs.GetZ();
double z = GetX()*rhs.GetY() - GetY()*rhs.GetX(); double z = GetX()*rhs.GetY() - GetY()*rhs.GetX();
return Vec3(x,y,z); return Vec3(x,y,z);
} }
}; }

View File

@ -10,47 +10,47 @@
namespace Mask { namespace Mask {
Vec4::Vec4() { Vec4::Vec4() {
for(auto& val: m_data) for(auto& val: m_data)
val = 0.0; val = 0.0;
for(auto& val: m_boost) for(auto& val: m_boost)
val = 0.0; val = 0.0;
} }
Vec4::Vec4(double px, double py, double pz, double E) { Vec4::Vec4(double px, double py, double pz, double E) {
m_data[0] = px; m_data[0] = px;
m_data[1] = py; m_data[1] = py;
m_data[2] = pz; m_data[2] = pz;
m_data[3] = E; m_data[3] = E;
CalcBoostToCM(); CalcBoostToCM();
} }
Vec4::~Vec4() {} Vec4::~Vec4() {}
void Vec4::SetVectorCartesian(double px, double py, double pz, double E) { void Vec4::SetVectorCartesian(double px, double py, double pz, double E) {
m_data[0] = px; m_data[0] = px;
m_data[1] = py; m_data[1] = py;
m_data[2] = pz; m_data[2] = pz;
m_data[3] = E; m_data[3] = E;
CalcBoostToCM(); CalcBoostToCM();
} }
void Vec4::SetVectorSpherical(double theta, double phi, double p, double E) { void Vec4::SetVectorSpherical(double theta, double phi, double p, double E) {
m_data[0] = p*cos(phi)*sin(theta); m_data[0] = p*cos(phi)*sin(theta);
m_data[1] = p*sin(phi)*sin(theta); m_data[1] = p*sin(phi)*sin(theta);
m_data[2] = p*cos(theta); m_data[2] = p*cos(theta);
m_data[3] = E; m_data[3] = E;
CalcBoostToCM(); CalcBoostToCM();
} }
void Vec4::CalcBoostToCM() { void Vec4::CalcBoostToCM() {
m_boost[0] = m_data[0]/m_data[3]; m_boost[0] = m_data[0]/m_data[3];
m_boost[1] = m_data[1]/m_data[3]; m_boost[1] = m_data[1]/m_data[3];
m_boost[2] = m_data[2]/m_data[3]; m_boost[2] = m_data[2]/m_data[3];
} }
void Vec4::ApplyBoost(const double* beta) { void Vec4::ApplyBoost(const double* beta) {
double beta2 = beta[0]*beta[0] + beta[1]*beta[1] + beta[2]*beta[2]; double beta2 = beta[0]*beta[0] + beta[1]*beta[1] + beta[2]*beta[2];
double gamma = 1.0/std::sqrt(1.0 - beta2); double gamma = 1.0/std::sqrt(1.0 - beta2);
double bdotp = beta[0]*m_data[0] + beta[1]*m_data[1] + beta[2]*m_data[2]; double bdotp = beta[0]*m_data[0] + beta[1]*m_data[1] + beta[2]*m_data[2];
@ -60,14 +60,14 @@ void Vec4::ApplyBoost(const double* beta) {
GetPy()+gfactor*bdotp*beta[1]+gamma*beta[1]*GetE(), GetPy()+gfactor*bdotp*beta[1]+gamma*beta[1]*GetE(),
GetPz()+gfactor*bdotp*beta[2]+gamma*beta[2]*GetE(), GetPz()+gfactor*bdotp*beta[2]+gamma*beta[2]*GetE(),
gamma*(GetE() + bdotp)); gamma*(GetE() + bdotp));
} }
double Vec4::Dot(const Vec4& rhs) const { double Vec4::Dot(const Vec4& rhs) const {
return GetE()*rhs.GetE() - GetPx()*rhs.GetPx() - GetPy()*rhs.GetPy() - GetPz()*rhs.GetPz(); return GetE()*rhs.GetE() - GetPx()*rhs.GetPx() - GetPy()*rhs.GetPy() - GetPz()*rhs.GetPz();
} }
Vec4 Vec4::Cross(const Vec4& rhs) const { Vec4 Vec4::Cross(const Vec4& rhs) const {
return Vec4(); return Vec4();
} }
}; }

View File

@ -17,6 +17,7 @@ int main(int argc, char** argv) {
sw.Start(); sw.Start();
try { try {
if(!calculator.LoadConfig(argv[1])) { if(!calculator.LoadConfig(argv[1])) {
std::cerr<<"Unable to read input file!"<<std::endl;
return 1; return 1;
} }
calculator.Run(); calculator.Run();