sanitized
This commit is contained in:
parent
a0c4e3a7ac
commit
8240310039
|
|
@ -139,27 +139,18 @@ int main(int argc, char **argv){
|
||||||
// Register signal handler
|
// Register signal handler
|
||||||
std::signal(SIGINT, handler);
|
std::signal(SIGINT, handler);
|
||||||
|
|
||||||
TGraph* elossBeam = LoadELoss("../ELoss/HeLoss/E_vs_x_Al-27.dat"); // x = path length (cm), y = beam energy (MeV)
|
|
||||||
TGraph* elossBeamInverse = new TGraph(elossBeam->GetN());
|
|
||||||
for( int p = 0; p < elossBeam->GetN(); p++ ){
|
|
||||||
double x, y;
|
|
||||||
elossBeam->GetPoint(p, x, y);
|
|
||||||
elossBeamInverse->SetPoint(p, y, x);
|
|
||||||
}
|
|
||||||
elossBeamInverse->Sort(); // TGraph::Eval requires ascending x
|
|
||||||
|
|
||||||
//To set beam energy loss, use energy loss app, and create table with target isotope, set Initial beam energy as max energy
|
//To set beam energy loss, use energy loss app, and create table with target isotope, set Initial beam energy as max energy
|
||||||
transfer.SetA(27, 13, 0); // 22Mg projectile
|
transfer.SetA(27, 13, 0); // 22Mg projectile
|
||||||
transfer.Seta(4, 2); // 4He target
|
transfer.Seta(4, 2); // 4He target
|
||||||
transfer.Setb(1, 1); // outgoing proton from the primary transfer
|
transfer.Setb(1, 1); // outgoing proton from the primary transfer
|
||||||
transfer.SetB(30, 14); // 30Si* heavy product
|
transfer.SetB(30, 14); // 30Si* heavy product
|
||||||
|
double beamE = 56.1;
|
||||||
const ReactionConfig reactionConfig = transfer.GetRectionConfig();
|
const ReactionConfig reactionConfig = transfer.GetRectionConfig();
|
||||||
const double beamA = reactionConfig.beamA; // mass number of 14N beam
|
const double beamA = reactionConfig.beamA; // mass number of 14N beam
|
||||||
//const double beamE = 72 / beamA; // beam energy in MeV
|
|
||||||
|
|
||||||
// Excited state lists (projectile and heavy-product excitation states)
|
// Excited state lists (projectile and heavy-product excitation states)
|
||||||
std::vector<float> ExAList = {0}; // Beam excited energy
|
std::vector<float> ExAList = {0}; // Beam excited energy
|
||||||
std::vector<float> ExList = {0.0, 2.2, 3.4, 6.0}; // Heavy product excited energy
|
std::vector<float> ExList = {0.0}; // Heavy product excited energy
|
||||||
|
|
||||||
const int kMBeam = reactionConfig.beamA; // mass number of beam
|
const int kMBeam = reactionConfig.beamA; // mass number of beam
|
||||||
const int kMTarget = reactionConfig.targetA; // mass number of target
|
const int kMTarget = reactionConfig.targetA; // mass number of target
|
||||||
|
|
@ -194,6 +185,36 @@ int main(int argc, char **argv){
|
||||||
double vertexZRange[2] = { -174.3, 174.3}; // -174.3, 174.3 (full length of gas volume, centered at 0)
|
double vertexZRange[2] = { -174.3, 174.3}; // -174.3, 174.3 (full length of gas volume, centered at 0)
|
||||||
const double beamEntranceZ = -280 - 174.3; //vertexZRange[0]; // mm, assumed beam entrance into the gas
|
const double beamEntranceZ = -280 - 174.3; //vertexZRange[0]; // mm, assumed beam entrance into the gas
|
||||||
|
|
||||||
|
TGraph* elossBeam = LoadELoss("../ELoss/HeLoss/E_vs_x_Al-27.dat"); // x = path length (cm), y = beam energy (MeV)
|
||||||
|
// Build a temporary inverse (energy -> path) to locate the path at beamE.
|
||||||
|
TGraph* elossBeamInverseRaw = new TGraph(elossBeam->GetN());
|
||||||
|
for( int p = 0; p < elossBeam->GetN(); p++ ){
|
||||||
|
double x, y;
|
||||||
|
elossBeam->GetPoint(p, x, y);
|
||||||
|
elossBeamInverseRaw->SetPoint(p, y, x);
|
||||||
|
}
|
||||||
|
elossBeamInverseRaw->Sort(); // TGraph::Eval requires ascending x
|
||||||
|
|
||||||
|
const double pathAtBeamE = elossBeamInverseRaw->Eval(beamE);
|
||||||
|
|
||||||
|
// Keep only energies <= beamE and shift path so beamE corresponds to x = 0.
|
||||||
|
TGraph* elossBeamFiltered = new TGraph();
|
||||||
|
for( int p = 0; p < elossBeam->GetN(); p++ ){
|
||||||
|
double x, y;
|
||||||
|
elossBeam->GetPoint(p, x, y);
|
||||||
|
if( y <= beamE ){
|
||||||
|
const int n = elossBeamFiltered->GetN();
|
||||||
|
elossBeamFiltered->SetPoint(n, x - pathAtBeamE, y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TGraph* elossBeamInverse = new TGraph(elossBeamFiltered->GetN());
|
||||||
|
for( int p = 0; p < elossBeamFiltered->GetN(); p++ ){
|
||||||
|
double x, y;
|
||||||
|
elossBeamFiltered->GetPoint(p, x, y);
|
||||||
|
elossBeamInverse->SetPoint(p, y, x);
|
||||||
|
}
|
||||||
|
elossBeamInverse->Sort(); // TGraph::Eval requires ascending x
|
||||||
|
|
||||||
// detector resolution / uncertainty parameters
|
// detector resolution / uncertainty parameters
|
||||||
double sigmaSX3_W = 0; // mm, if < 0 use mid-point (no spread in SX3 horizontal dimension)
|
double sigmaSX3_W = 0; // mm, if < 0 use mid-point (no spread in SX3 horizontal dimension)
|
||||||
|
|
@ -277,8 +298,8 @@ int main(int argc, char **argv){
|
||||||
tree1->Branch("phiCM", &phiCM, "phiCM/D");
|
tree1->Branch("phiCM", &phiCM, "phiCM/D");
|
||||||
|
|
||||||
// outgoing particles in lab frame (light/heavy)
|
// outgoing particles in lab frame (light/heavy)
|
||||||
double thetab, phib, Tb, qqqTb;
|
double thetab, phib, Tb, qqqTb, sx3Tb;
|
||||||
double thetaB, phiB, TB, qqqTB;
|
double thetaB, phiB, TB, qqqTB, sx3TB;
|
||||||
std::array<double, 2> T;
|
std::array<double, 2> T;
|
||||||
tree1->Branch("thetab", &thetab, "thetab/D"); // polar angle of light particle in lab frame
|
tree1->Branch("thetab", &thetab, "thetab/D"); // polar angle of light particle in lab frame
|
||||||
tree1->Branch("phib", &phib, "phib/D"); // azimuthal angle of light particle in lab frame
|
tree1->Branch("phib", &phib, "phib/D"); // azimuthal angle of light particle in lab frame
|
||||||
|
|
@ -288,7 +309,9 @@ int main(int argc, char **argv){
|
||||||
tree1->Branch("TB", &TB, "TB/D"); // kinetic energy of heavy particle at vertex (before energy loss)
|
tree1->Branch("TB", &TB, "TB/D"); // kinetic energy of heavy particle at vertex (before energy loss)
|
||||||
tree1->Branch("T", &T, "T/D"); // placeholder for true Q-value, currently set to 0 for simplicity
|
tree1->Branch("T", &T, "T/D"); // placeholder for true Q-value, currently set to 0 for simplicity
|
||||||
tree1->Branch("qqqTb", &qqqTb, "qqqTb/D"); // kinetic energy of light particle at vertex (before energy loss) for events where the light particle hits the QQQ, currently set to 0 for simplicity
|
tree1->Branch("qqqTb", &qqqTb, "qqqTb/D"); // kinetic energy of light particle at vertex (before energy loss) for events where the light particle hits the QQQ, currently set to 0 for simplicity
|
||||||
tree1->Branch("qqqTB", &qqqTB, "qqqTB/D"); // kinetic energy of heavy particle at vertex (before energy loss) for events where the light
|
tree1->Branch("qqqTB", &qqqTB, "qqqTB/D"); // kinetic energy of heavy particle at vertex (before energy loss) for events where the light particle hits the QQQ, currently set to 0 for simplicity
|
||||||
|
tree1->Branch("sx3Tb", &sx3Tb, "sx3Tb/D"); // kinetic energy of light particle at vertex (before energy loss) for events where the light particle hits the SX3, currently set to 0 for simplicity
|
||||||
|
tree1->Branch("sx3TB", &sx3TB, "sx3TB/D"); // kinetic energy of heavy particle at vertex (before energy loss) for events where the light particle hits the SX3, currently set to 0 for simplicity
|
||||||
|
|
||||||
double Esx3, Eqqq, Edet;
|
double Esx3, Eqqq, Edet;
|
||||||
tree1->Branch("Esx3", &Esx3, "Esx3/D");
|
tree1->Branch("Esx3", &Esx3, "Esx3/D");
|
||||||
|
|
@ -405,9 +428,9 @@ int main(int argc, char **argv){
|
||||||
// vertex position in target volume
|
// vertex position in target volume
|
||||||
vertexX = (vertexXRange[1]- vertexXRange[0])*gRandom->Rndm() + vertexXRange[0];
|
vertexX = (vertexXRange[1]- vertexXRange[0])*gRandom->Rndm() + vertexXRange[0];
|
||||||
vertexY = (vertexYRange[1]- vertexYRange[0])*gRandom->Rndm() + vertexYRange[0];
|
vertexY = (vertexYRange[1]- vertexYRange[0])*gRandom->Rndm() + vertexYRange[0];
|
||||||
beamEnergy = gRandom->Uniform(0, 56.1);
|
beamEnergy = gRandom->Uniform(0, beamE); // MeV, sample beam energy at vertex from uniform distribution between 0 and initial beam energy
|
||||||
KEA = beamEnergy / beamA;
|
KEA = beamEnergy / beamA;
|
||||||
beamPath_cm = elossBeamInverse->Eval(beamEnergy); // interpolate path length (cm) that gives this beam energy
|
beamPath_cm = elossBeamInverse->Eval(beamEnergy); // beamE maps to x=0 after path shift
|
||||||
vertexZ = beamEntranceZ + beamPath_cm * 10.0; // cm -> mm
|
vertexZ = beamEntranceZ + beamPath_cm * 10.0; // cm -> mm
|
||||||
|
|
||||||
//vertexZ = (vertexZRange[1]- vertexZRange[0])*gRandom->Rndm() + vertexZRange[0];
|
//vertexZ = (vertexZRange[1]- vertexZRange[0])*gRandom->Rndm() + vertexZRange[0];
|
||||||
|
|
@ -563,7 +586,7 @@ int main(int argc, char **argv){
|
||||||
b, "He", Tb,
|
b, "He", Tb,
|
||||||
distance_C);
|
distance_C);
|
||||||
|
|
||||||
EPC = Eanode - Ecathode;
|
|
||||||
|
|
||||||
if (Esx3 <= 0 || Eanode <= 0 || Ecathode <= 0) {
|
if (Esx3 <= 0 || Eanode <= 0 || Ecathode <= 0) {
|
||||||
Esx3 = NAN;
|
Esx3 = NAN;
|
||||||
|
|
@ -571,9 +594,13 @@ int main(int argc, char **argv){
|
||||||
Ex = NAN;
|
Ex = NAN;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Edet = Esx3;
|
sx3Tb = Tb; // for simplicity, using the same kinetic energy for SX3 hit events, can be modified to simulate energy loss if desired
|
||||||
|
sx3TB = TB;
|
||||||
|
qqqTb = TMath::QuietNaN(); // mark kinetic energy as invalid for SX3 hit case
|
||||||
|
qqqTB = TMath::QuietNaN();
|
||||||
Eqqq = TMath::QuietNaN(); // mark QQQ energy as invalid for SX3 hit case
|
Eqqq = TMath::QuietNaN(); // mark QQQ energy as invalid for SX3 hit case
|
||||||
|
Edet = Esx3;
|
||||||
|
EPC = Eanode - Ecathode;
|
||||||
AutoHist2D::Fill("beamEnergy_vs_vZ", vertexZ / 10, beamEnergy, "vZ (cm)", "beamEnergy (MeV)");
|
AutoHist2D::Fill("beamEnergy_vs_vZ", vertexZ / 10, beamEnergy, "vZ (cm)", "beamEnergy (MeV)");
|
||||||
AutoHist2D::Fill("EPC x sin(theta) vs Esx3", Esx3, EPC * sin(thetab * TMath::DegToRad()), "Esx3 (MeV)", "EPC x sin(theta) (MeV)");
|
AutoHist2D::Fill("EPC x sin(theta) vs Esx3", Esx3, EPC * sin(thetab * TMath::DegToRad()), "Esx3 (MeV)", "EPC x sin(theta) (MeV)");
|
||||||
tree1->Fill();
|
tree1->Fill();
|
||||||
|
|
@ -595,12 +622,6 @@ int main(int argc, char **argv){
|
||||||
rePhi1 = TMath::QuietNaN();
|
rePhi1 = TMath::QuietNaN();
|
||||||
z0 = TMath::QuietNaN();
|
z0 = TMath::QuietNaN();
|
||||||
|
|
||||||
qqqTb = Tb; // for simplicity, using the same kinetic energy for QQQ hit events, can be modified to simulate energy loss if desired
|
|
||||||
qqqTB = TB;
|
|
||||||
|
|
||||||
Tb = TMath::QuietNaN(); // mark kinetic energy as invalid for SX3 hit case
|
|
||||||
TB = TMath::QuietNaN();
|
|
||||||
|
|
||||||
TVector3 hitPos = qqq->GetHitPos();
|
TVector3 hitPos = qqq->GetHitPos();
|
||||||
|
|
||||||
qqqX = hitPos.X();
|
qqqX = hitPos.X();
|
||||||
|
|
@ -629,24 +650,29 @@ int main(int argc, char **argv){
|
||||||
Eqqq = CalculateEnergyLoss(vertexX, vertexY, vertexZ,
|
Eqqq = CalculateEnergyLoss(vertexX, vertexY, vertexZ,
|
||||||
qqqX, qqqY, qqqZ,
|
qqqX, qqqY, qqqZ,
|
||||||
b, "He",
|
b, "He",
|
||||||
qqqTb, distance_qqq);
|
Tb, distance_qqq);
|
||||||
dl = distance_qqq;
|
dl = distance_qqq;
|
||||||
double distance_A;
|
double distance_A;
|
||||||
Eanode = CalculateEnergyLoss(vertexX, vertexY, vertexZ,
|
Eanode = CalculateEnergyLoss(vertexX, vertexY, vertexZ,
|
||||||
aX, aY, aZ,
|
aX, aY, aZ,
|
||||||
b, "He",
|
b, "He",
|
||||||
qqqTb, distance_A);
|
Tb, distance_A);
|
||||||
double distance_C;
|
double distance_C;
|
||||||
Ecathode = CalculateEnergyLoss(vertexX, vertexY, vertexZ,
|
Ecathode = CalculateEnergyLoss(vertexX, vertexY, vertexZ,
|
||||||
cX, cY, cZ,
|
cX, cY, cZ,
|
||||||
b, "He",
|
b, "He",
|
||||||
qqqTb, distance_C);
|
Tb, distance_C);
|
||||||
|
|
||||||
if (Eqqq <= 0 || Eanode <= 0 || Ecathode <= 0) {
|
if (Eqqq <= 0 || Eanode <= 0 || Ecathode <= 0) {
|
||||||
Eqqq = NAN;
|
Eqqq = NAN;
|
||||||
Ex = NAN;
|
Ex = NAN;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qqqTb = Tb; // for simplicity, using the same kinetic energy for QQQ hit events, can be modified to simulate energy loss if desired
|
||||||
|
qqqTB = TB;
|
||||||
|
sx3Tb = TMath::QuietNaN(); // mark kinetic energy as invalid for QQQ hit case
|
||||||
|
sx3TB = TMath::QuietNaN();
|
||||||
Esx3 = TMath::QuietNaN(); // mark SX3 energy as invalid for QQQ hit case
|
Esx3 = TMath::QuietNaN(); // mark SX3 energy as invalid for QQQ hit case
|
||||||
Edet = Eqqq;
|
Edet = Eqqq;
|
||||||
EPC = Eanode - Ecathode;
|
EPC = Eanode - Ecathode;
|
||||||
|
|
@ -656,7 +682,6 @@ int main(int argc, char **argv){
|
||||||
beamEnergy = TMath::QuietNaN(); // mark beam energy as invalid for QQQ hit case
|
beamEnergy = TMath::QuietNaN(); // mark beam energy as invalid for QQQ hit case
|
||||||
tree1->Fill();
|
tree1->Fill();
|
||||||
|
|
||||||
|
|
||||||
}else{
|
}else{
|
||||||
// no valid SX3 hit: mark clearly invalid
|
// no valid SX3 hit: mark clearly invalid
|
||||||
sx3Up = -1;
|
sx3Up = -1;
|
||||||
|
|
@ -675,6 +700,10 @@ int main(int argc, char **argv){
|
||||||
z0 = TMath::QuietNaN();
|
z0 = TMath::QuietNaN();
|
||||||
Tb = TMath::QuietNaN(); // mark kinetic energy as invalid for no hit case
|
Tb = TMath::QuietNaN(); // mark kinetic energy as invalid for no hit case
|
||||||
TB = TMath::QuietNaN();
|
TB = TMath::QuietNaN();
|
||||||
|
sx3Tb = TMath::QuietNaN();
|
||||||
|
sx3TB = TMath::QuietNaN();
|
||||||
|
qqqTb = TMath::QuietNaN();
|
||||||
|
qqqTB = TMath::QuietNaN();
|
||||||
// fill tree with original data (no energy loss for these events)
|
// fill tree with original data (no energy loss for these events)
|
||||||
//comment out tree fill for no hit case
|
//comment out tree fill for no hit case
|
||||||
//tree1->Fill();
|
//tree1->Fill();
|
||||||
|
|
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
73
ELoss/material_definitions.py
Normal file
73
ELoss/material_definitions.py
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
"""Shared material definitions for ELoss analysis scripts."""
|
||||||
|
|
||||||
|
import pycatima as catima
|
||||||
|
|
||||||
|
R_GAS_CONSTANT = 8.3144 # J/mol/K
|
||||||
|
|
||||||
|
|
||||||
|
def _gas_molar_density(p_torr, temp_k):
|
||||||
|
"""Return molar density in mol/m^3 from pressure (Torr) and temperature (K)."""
|
||||||
|
p_pa = p_torr * 133.322
|
||||||
|
return p_pa / (R_GAS_CONSTANT * temp_k)
|
||||||
|
|
||||||
|
|
||||||
|
def build_material(medium, p_torr, temp_k):
|
||||||
|
"""
|
||||||
|
Build a CATIMA material and return (material, density_g_cm3).
|
||||||
|
|
||||||
|
Supported media names:
|
||||||
|
- He
|
||||||
|
- PureHe
|
||||||
|
- Si
|
||||||
|
- kapton
|
||||||
|
"""
|
||||||
|
medium_key = medium.strip().lower()
|
||||||
|
|
||||||
|
if medium_key == "he":
|
||||||
|
m_he = 4.0026
|
||||||
|
m_c = 12.0000
|
||||||
|
m_o = 15.9949
|
||||||
|
|
||||||
|
material_def = [
|
||||||
|
(m_he, 2, 0.96),
|
||||||
|
(m_c, 6, 0.04),
|
||||||
|
(m_o, 8, 0.08),
|
||||||
|
]
|
||||||
|
|
||||||
|
molar_density = _gas_molar_density(p_torr, temp_k)
|
||||||
|
m_mix_avg = 0.96 * m_he + 0.04 * (m_c + 2 * m_o)
|
||||||
|
rho_g_cm3 = (molar_density * m_mix_avg) / 1e6
|
||||||
|
|
||||||
|
elif medium_key == "purehe":
|
||||||
|
m_he = 4.0026
|
||||||
|
material_def = [(m_he, 2, 1.0)]
|
||||||
|
|
||||||
|
molar_density = _gas_molar_density(p_torr, temp_k)
|
||||||
|
m_mix_avg = m_he
|
||||||
|
rho_g_cm3 = (molar_density * m_mix_avg) / 1e6
|
||||||
|
|
||||||
|
elif medium_key == "si":
|
||||||
|
m_si = 28.084
|
||||||
|
material_def = [(m_si, 14, 1.0)]
|
||||||
|
rho_g_cm3 = 2.33
|
||||||
|
|
||||||
|
elif medium_key == "kapton":
|
||||||
|
m_h = 1.008
|
||||||
|
m_c = 12.011
|
||||||
|
m_n = 14.007
|
||||||
|
m_o = 15.999
|
||||||
|
|
||||||
|
material_def = [
|
||||||
|
(m_h, 1, 0.026),
|
||||||
|
(m_c, 6, 0.691),
|
||||||
|
(m_n, 7, 0.073),
|
||||||
|
(m_o, 8, 0.209),
|
||||||
|
]
|
||||||
|
rho_g_cm3 = 1.42
|
||||||
|
|
||||||
|
else:
|
||||||
|
raise ValueError(f"Unsupported medium: {medium}")
|
||||||
|
|
||||||
|
material = catima.Material(material_def)
|
||||||
|
material.density(rho_g_cm3)
|
||||||
|
return material, rho_g_cm3
|
||||||
Loading…
Reference in New Issue
Block a user