200 lines
3.9 KiB
Python
200 lines
3.9 KiB
Python
import pycatima as catima
|
|
import numpy as np
|
|
import pandas as pd
|
|
from scipy.interpolate import interp1d
|
|
from scipy.integrate import cumulative_trapezoid
|
|
import matplotlib.pyplot as plt
|
|
|
|
# GAS SETUP
|
|
|
|
P_TORR = 400
|
|
TEMP_K = 293.15
|
|
R = 8.3144
|
|
|
|
# Gas density
|
|
p_pa = P_TORR * 133.322
|
|
molar_density = p_pa / (R * TEMP_K)
|
|
|
|
m_he = 4.0026
|
|
m_c = 12.0000
|
|
m_o = 15.9949
|
|
|
|
m_mix_avg = (0.96 * m_he) + (0.04 * (m_c + 2*m_o))
|
|
|
|
rho_g_cm3 = (molar_density * m_mix_avg) / 1e6
|
|
|
|
print(f"Gas density = {rho_g_cm3:.6e} g/cm^3")
|
|
|
|
# MATERIAL
|
|
material_def = [
|
|
(m_he, 2, 0.96),
|
|
(m_c, 6, 0.04),
|
|
(m_o, 8, 0.08)
|
|
]
|
|
|
|
gas_mix = catima.Material(material_def)
|
|
gas_mix.density(rho_g_cm3)
|
|
|
|
# MATERIAL BANK - Additional Materials for Energy Loss Calculations
|
|
|
|
# Kapton (C22H10N2O5)
|
|
# Density: 1.42 g/cm3
|
|
# Molecular weight: 22*12 + 10*1 + 2*14 + 5*16 = 264 + 10 + 28 + 80 = 382 g/mol
|
|
m_h = 1.0078
|
|
m_n = 14.0067
|
|
kapton_molar_mass = 22*m_c + 10*m_h + 2*m_n + 5*m_o # ~382 g/mol
|
|
kapton_material_def = [
|
|
(m_c, 6, 22/382 * kapton_molar_mass / m_c),
|
|
(m_h, 1, 10/382 * kapton_molar_mass / m_h),
|
|
(m_n, 7, 2/382 * kapton_molar_mass / m_n),
|
|
(m_o, 8, 5/382 * kapton_molar_mass / m_o)
|
|
]
|
|
kapton = catima.Material(kapton_material_def)
|
|
kapton.density(1.42) # g/cm3
|
|
|
|
# Mylar (C10H8O4, polyethylene terephthalate)
|
|
# Density: 1.39 g/cm3
|
|
# Molecular weight: 10*12 + 8*1 + 4*16 = 120 + 8 + 64 = 192 g/mol
|
|
mylar_molar_mass = 10*m_c + 8*m_h + 4*m_o # ~192 g/mol
|
|
mylar_material_def = [
|
|
(m_c, 6, 10/192 * mylar_molar_mass / m_c),
|
|
(m_h, 1, 8/192 * mylar_molar_mass / m_h),
|
|
(m_o, 8, 4/192 * mylar_molar_mass / m_o)
|
|
]
|
|
mylar = catima.Material(mylar_material_def)
|
|
mylar.density(1.39) # g/cm3
|
|
|
|
# FUNCTION
|
|
|
|
def make_E_vs_x(
|
|
z,
|
|
mass_u,
|
|
emax_mev,
|
|
label,
|
|
npoints=500,
|
|
material=None
|
|
):
|
|
|
|
if material is None:
|
|
material = gas_mix
|
|
|
|
projectile = catima.Projectile(mass_u, z)
|
|
|
|
# Energy grid
|
|
E = np.linspace(0.01, emax_mev, npoints)
|
|
|
|
# Stopping power array
|
|
S_mass = np.zeros_like(E)
|
|
|
|
for i, energy in enumerate(E):
|
|
|
|
projectile.T(energy / mass_u)
|
|
|
|
# MeV / (g/cm^2)
|
|
S_mass[i] = catima.dedx(projectile, material)
|
|
|
|
# Convert to MeV/cm
|
|
S_linear = S_mass * rho_g_cm3
|
|
|
|
# Sort descending energy
|
|
sort_idx = np.argsort(E)[::-1]
|
|
|
|
E = E[sort_idx]
|
|
S_linear = S_linear[sort_idx]
|
|
|
|
# Integrate dx/dE = 1/S(E)
|
|
invS = 1.0 / S_linear
|
|
|
|
x = cumulative_trapezoid(
|
|
invS,
|
|
E,
|
|
initial=0
|
|
)
|
|
|
|
x = -x
|
|
|
|
# Output table
|
|
output = pd.DataFrame({
|
|
"Distance_cm": x,
|
|
"Energy_MeV": E
|
|
})
|
|
|
|
outfile = f"E_vs_x_{label}.dat"
|
|
|
|
output.to_csv(
|
|
outfile,
|
|
sep='\t',
|
|
index=False
|
|
)
|
|
|
|
print(f"Saved: {outfile}")
|
|
|
|
return x, E
|
|
|
|
# RUN
|
|
#proton parameters: z=1, mass_u=1.0078, emax_mev=20
|
|
#alpha parameters: z=2, mass_u=4.0026, emax_mev=40
|
|
x, E = make_E_vs_x(
|
|
z=1,
|
|
mass_u=1.0078,
|
|
emax_mev=20,
|
|
label="proton"
|
|
)
|
|
|
|
x, E = make_E_vs_x(
|
|
z=2,
|
|
mass_u=4.0026,
|
|
emax_mev=40,
|
|
label="alpha"
|
|
)
|
|
|
|
# Generate tables for kapton
|
|
print("\n=== Generating Kapton Energy Loss Tables ===")
|
|
x, E = make_E_vs_x(
|
|
z=1,
|
|
mass_u=1.0078,
|
|
emax_mev=20,
|
|
label="proton_kapton",
|
|
material=kapton
|
|
)
|
|
|
|
x, E = make_E_vs_x(
|
|
z=2,
|
|
mass_u=4.0026,
|
|
emax_mev=40,
|
|
label="alpha_kapton",
|
|
material=kapton
|
|
)
|
|
|
|
# Generate tables for mylar
|
|
print("\n=== Generating Mylar Energy Loss Tables ===")
|
|
x, E = make_E_vs_x(
|
|
z=1,
|
|
mass_u=1.0078,
|
|
emax_mev=20,
|
|
label="proton_mylar",
|
|
material=mylar
|
|
)
|
|
|
|
x, E = make_E_vs_x(
|
|
z=2,
|
|
mass_u=4.0026,
|
|
emax_mev=40,
|
|
label="alpha_mylar",
|
|
material=mylar
|
|
)
|
|
|
|
# PLOT
|
|
|
|
plt.figure(figsize=(8,6))
|
|
|
|
plt.plot(x, E)
|
|
|
|
plt.xlabel("Distance in Gas (cm)")
|
|
plt.ylabel("Energy (MeV)")
|
|
plt.title("Energy Loss Curve")
|
|
|
|
plt.grid(True)
|
|
|
|
plt.show()
|
|
#gives data in units of Energy (MeV) and Distance (cm). To convert to E(x), you can use the cumulative energy |