LISE agreement
This commit is contained in:
parent
26be64416c
commit
9848725f58
|
|
@ -104,6 +104,7 @@ int main(int argc, char **argv){
|
||||||
transfer.Setb(1, 1); // outgoing proton from the primary transfer
|
transfer.Setb(1, 1); // outgoing proton from the primary transfer
|
||||||
transfer.SetB(30, 14); // 21Na* heavy product
|
transfer.SetB(30, 14); // 21Na* heavy product
|
||||||
const double beamA = 27; // mass number of 27Al beam
|
const double beamA = 27; // mass number of 27Al beam
|
||||||
|
const double beamE = 72.0 / 27.0; // beam energy in MeV
|
||||||
|
|
||||||
bool enableSequentialDecay = false; // turning to false to disable sequential decay for now, can be set to true to enable
|
bool enableSequentialDecay = false; // turning to false to disable sequential decay for now, can be set to true to enable
|
||||||
const int decayDaughterA = 20;
|
const int decayDaughterA = 20;
|
||||||
|
|
@ -363,6 +364,7 @@ int main(int argc, char **argv){
|
||||||
beamEnergy = elossBeam->Eval(beamPath_cm); // MeV
|
beamEnergy = elossBeam->Eval(beamPath_cm); // MeV
|
||||||
beamEnergyLoss = elossBeam->Eval(0.0) - beamEnergy;
|
beamEnergyLoss = elossBeam->Eval(0.0) - beamEnergy;
|
||||||
KEA = beamEnergy / beamA;
|
KEA = beamEnergy / beamA;
|
||||||
|
//KEA = gRandom->Uniform(0, beamE);
|
||||||
transfer.SetIncidentEnergyAngle(KEA, 0, 0);
|
transfer.SetIncidentEnergyAngle(KEA, 0, 0);
|
||||||
transfer.CalReactionConstant();
|
transfer.CalReactionConstant();
|
||||||
|
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -84,6 +84,17 @@ def get_loss_table_path(medium, particle_label):
|
||||||
return os.path.join(script_dir, f"{medium}Loss", f"E_vs_x_{particle_label}.dat")
|
return os.path.join(script_dir, f"{medium}Loss", f"E_vs_x_{particle_label}.dat")
|
||||||
|
|
||||||
|
|
||||||
|
def normalize_particle_label(particle):
|
||||||
|
"""Return the canonical table label for a particle or isotope name."""
|
||||||
|
if isinstance(particle, str):
|
||||||
|
try:
|
||||||
|
_, _, _, label = resolve_particle(particle)
|
||||||
|
return label
|
||||||
|
except Exception:
|
||||||
|
return particle.strip()
|
||||||
|
return str(particle)
|
||||||
|
|
||||||
|
|
||||||
def clear_interpolator_cache():
|
def clear_interpolator_cache():
|
||||||
"""Drop cached energy-loss interpolators and force Python to release memory."""
|
"""Drop cached energy-loss interpolators and force Python to release memory."""
|
||||||
global interp_cache
|
global interp_cache
|
||||||
|
|
@ -111,30 +122,23 @@ def make_E_vs_x(
|
||||||
p_pa = P_TORR * 133.322
|
p_pa = P_TORR * 133.322
|
||||||
molar_density = p_pa / (R * TEMP_K) # mol/m^3
|
molar_density = p_pa / (R * TEMP_K) # mol/m^3
|
||||||
|
|
||||||
# ---------------------------
|
|
||||||
# Medium definition
|
# Medium definition
|
||||||
# ---------------------------
|
|
||||||
if medium == "He":
|
if medium == "He":
|
||||||
|
|
||||||
m_he = 4.0026
|
m_he = 4.0026
|
||||||
m_c = 12.0000
|
m_c = 12.0000
|
||||||
m_o = 15.9949
|
m_o = 15.9949
|
||||||
|
"""
|
||||||
# FIX: do NOT double count oxygen
|
|
||||||
material_def = [
|
material_def = [
|
||||||
(m_he, 2, 0.96),
|
(m_he, 2, 0.96),
|
||||||
((m_c + 2 * m_o), 18, 0.04) # CO2 lumped correctly
|
(m_c, 6, 0.04),
|
||||||
]
|
(m_o, 8, 0.08)
|
||||||
|
] """
|
||||||
|
material_def = [(m_he, 2, 1.0)]
|
||||||
|
|
||||||
#m_mix_avg = 0.96 * m_he + 0.04 * (m_c + 2 * m_o)
|
#m_mix_avg = 0.96 * m_he + 0.04 * (m_c + 2 * m_o)
|
||||||
m_mix_avg = m_he
|
m_mix_avg = 1.0 * m_he
|
||||||
|
rho_g_cm3 = (molar_density * m_mix_avg) / 1e6
|
||||||
#rho_g_cm3 = (molar_density * m_mix_avg) / 1e6
|
|
||||||
if z == 2:
|
|
||||||
rho_g_cm3 = 0.00017
|
|
||||||
#rho_g_cm3 = 8.2928e-5
|
|
||||||
else:
|
|
||||||
rho_g_cm3 = 8.2928e-5
|
|
||||||
|
|
||||||
gas = catima.Material(material_def)
|
gas = catima.Material(material_def)
|
||||||
gas.density(rho_g_cm3)
|
gas.density(rho_g_cm3)
|
||||||
|
|
@ -156,10 +160,10 @@ def make_E_vs_x(
|
||||||
E = np.linspace(0.1, emax_mev, npoints)
|
E = np.linspace(0.1, emax_mev, npoints)
|
||||||
S_mass = np.zeros_like(E)
|
S_mass = np.zeros_like(E)
|
||||||
for i, energy in enumerate(E):
|
for i, energy in enumerate(E):
|
||||||
projectile.T(energy)
|
# CATIMA expects projectile energy in MeV/u, while the table axis stays in total MeV.
|
||||||
|
projectile.T(energy / mass_u)
|
||||||
S_mass[i] = catima.dedx(projectile, gas) # MeV/(g/cm^2)
|
S_mass[i] = catima.dedx(projectile, gas) # MeV/(g/cm^2)
|
||||||
|
|
||||||
# convert to MeV/cm
|
|
||||||
S_linear = S_mass * rho_g_cm3
|
S_linear = S_mass * rho_g_cm3
|
||||||
invS = 1.0 / np.clip(S_linear, 1e-30, None)
|
invS = 1.0 / np.clip(S_linear, 1e-30, None)
|
||||||
x = cumulative_trapezoid(invS[::-1], E[::-1], initial=0)
|
x = cumulative_trapezoid(invS[::-1], E[::-1], initial=0)
|
||||||
|
|
@ -206,12 +210,38 @@ def load_table(filename):
|
||||||
|
|
||||||
def get_interpolators(particle, medium):
|
def get_interpolators(particle, medium):
|
||||||
|
|
||||||
cache_key = (particle.lower(), medium.lower())
|
canonical_particle = normalize_particle_label(particle)
|
||||||
|
cache_key = (canonical_particle.lower(), medium.lower())
|
||||||
|
|
||||||
if cache_key in interp_cache:
|
if cache_key in interp_cache:
|
||||||
return interp_cache[cache_key]
|
return interp_cache[cache_key]
|
||||||
|
|
||||||
filename = get_loss_table_path(medium, particle)
|
candidate_labels = [canonical_particle]
|
||||||
|
if isinstance(particle, str):
|
||||||
|
raw_particle = particle.strip()
|
||||||
|
candidate_labels.extend([
|
||||||
|
raw_particle,
|
||||||
|
canonical_particle.replace("-", "")
|
||||||
|
])
|
||||||
|
|
||||||
|
filename = None
|
||||||
|
seen_candidates = set()
|
||||||
|
for label in candidate_labels:
|
||||||
|
normalized_label = label.strip()
|
||||||
|
if not normalized_label:
|
||||||
|
continue
|
||||||
|
key = normalized_label.lower()
|
||||||
|
if key in seen_candidates:
|
||||||
|
continue
|
||||||
|
seen_candidates.add(key)
|
||||||
|
|
||||||
|
candidate_filename = get_loss_table_path(medium, normalized_label)
|
||||||
|
if os.path.exists(candidate_filename):
|
||||||
|
filename = candidate_filename
|
||||||
|
break
|
||||||
|
|
||||||
|
if filename is None:
|
||||||
|
filename = get_loss_table_path(medium, canonical_particle)
|
||||||
|
|
||||||
x, E = load_table(filename)
|
x, E = load_table(filename)
|
||||||
|
|
||||||
|
|
@ -275,11 +305,29 @@ def resolve_particle(name):
|
||||||
name = name.lower().strip().rstrip("s")
|
name = name.lower().strip().rstrip("s")
|
||||||
if name in particles:
|
if name in particles:
|
||||||
return particles[name]
|
return particles[name]
|
||||||
match = re.match(r"([a-zA-Z]+)[-\s]?(\d+)", name)
|
match = re.match(r"([a-zA-Z]+)[-\s]?(\d+)$", name)
|
||||||
if match:
|
if match:
|
||||||
element_symbol = match.group(1).capitalize()
|
element_symbol = match.group(1).capitalize()
|
||||||
A = int(match.group(2))
|
A = int(match.group(2))
|
||||||
|
|
||||||
|
try:
|
||||||
|
element = pt.elements.symbol(element_symbol)
|
||||||
|
isotope = element[A]
|
||||||
|
|
||||||
|
return (
|
||||||
|
isotope.number, # Z
|
||||||
|
isotope.mass, # mass in u
|
||||||
|
30.0,
|
||||||
|
f"{element_symbol}-{A}"
|
||||||
|
)
|
||||||
|
except Exception:
|
||||||
|
raise ValueError(f"Unknown isotope: {name}")
|
||||||
|
|
||||||
|
match = re.match(r"(\d+)[-\s]?([a-zA-Z]+)$", name)
|
||||||
|
if match:
|
||||||
|
A = int(match.group(1))
|
||||||
|
element_symbol = match.group(2).capitalize()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
element = pt.elements.symbol(element_symbol)
|
element = pt.elements.symbol(element_symbol)
|
||||||
isotope = element[A]
|
isotope = element[A]
|
||||||
|
|
@ -898,7 +946,7 @@ class MyInteractiveApp(cmd.Cmd):
|
||||||
if dl > 0:
|
if dl > 0:
|
||||||
print(f"\nChange in energy: {dE:.6f} MeV")
|
print(f"\nChange in energy: {dE:.6f} MeV")
|
||||||
print(f"Distance travelled: {dl:.6f} cm\n")
|
print(f"Distance travelled: {dl:.6f} cm\n")
|
||||||
print(f"{(dl * 10000):.6f} microns")
|
print(f"{(dl * 10):.6f} mm")
|
||||||
else:
|
else:
|
||||||
print("Error: remake table with larger value, fallen off map")
|
print("Error: remake table with larger value, fallen off map")
|
||||||
except:
|
except:
|
||||||
|
|
@ -1343,7 +1391,7 @@ class MyInteractiveApp(cmd.Cmd):
|
||||||
|
|
||||||
plt.figure(figsize=(7,6))
|
plt.figure(figsize=(7,6))
|
||||||
mask1 = ~np.isnan(Esx3) & ~np.isnan(Edet) & sx3_theta_plot_mask
|
mask1 = ~np.isnan(Esx3) & ~np.isnan(Edet) & sx3_theta_plot_mask
|
||||||
plt.hist2d(Esx3[mask1], Edet[mask1], bins=300)
|
plt.hist2d(Esx3[mask1], Edet[mask1], bins=300, norm="log")
|
||||||
plt.xlabel("Esx3")
|
plt.xlabel("Esx3")
|
||||||
plt.ylabel("Edet")
|
plt.ylabel("Edet")
|
||||||
plt.title("Esx3 vs Edet")
|
plt.title("Esx3 vs Edet")
|
||||||
|
|
@ -1356,12 +1404,12 @@ class MyInteractiveApp(cmd.Cmd):
|
||||||
|
|
||||||
mask1 = ~np.isnan(qqqE) & ~np.isnan(EdetQ) & qqq_theta_plot_mask
|
mask1 = ~np.isnan(qqqE) & ~np.isnan(EdetQ) & qqq_theta_plot_mask
|
||||||
plt.figure(figsize=(7,6))
|
plt.figure(figsize=(7,6))
|
||||||
plt.hist2d(qqqE[mask1], EdetQ[mask1], bins=300)
|
plt.hist2d(qqqE[mask1], EdetQ[mask1], bins=300, norm="log")
|
||||||
plt.xlabel("Eqqq")
|
plt.xlabel("Eqqq")
|
||||||
plt.ylabel("Edet")
|
plt.ylabel("Edet")
|
||||||
plt.title("Eqqq vs Edet")
|
plt.title("Eqqq vs Edet")
|
||||||
plt.yscale("log")
|
#plt.yscale("log")
|
||||||
plt.xscale("log")
|
#plt.xscale("log")
|
||||||
plt.colorbar(label="counts")
|
plt.colorbar(label="counts")
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
plt.savefig(f"{base}/Eqqq_vs_Edet.png")
|
plt.savefig(f"{base}/Eqqq_vs_Edet.png")
|
||||||
|
|
@ -1418,6 +1466,7 @@ class MyInteractiveApp(cmd.Cmd):
|
||||||
plt.plot(theta_deg[order], path_cm[order], color='red', linewidth=2, label='0.1/sin(theta)')
|
plt.plot(theta_deg[order], path_cm[order], color='red', linewidth=2, label='0.1/sin(theta)')
|
||||||
plt.legend()
|
plt.legend()
|
||||||
plt.tight_layout()
|
plt.tight_layout()
|
||||||
|
plt.gca().invert_xaxis()
|
||||||
plt.savefig(f"{base}/Range_vs_theta_with_path.png", dpi=300)
|
plt.savefig(f"{base}/Range_vs_theta_with_path.png", dpi=300)
|
||||||
plt.show()
|
plt.show()
|
||||||
except Exception:
|
except Exception:
|
||||||
|
|
|
||||||
Binary file not shown.
Loading…
Reference in New Issue
Block a user