Uncertainty quantification of partial wave transmission coefficients¶
This notebook extends the uncertainty-propagation workflow to angular reaction observables. It shows how the same model choices that affect transmission coefficients flow through to angle-dependent reaction outputs.
1import numpy as np
2from IPython.display import Math, display
3from periodictable import elements
1from matplotlib import pyplot as plt
Compare mass-model inputs to Koning-Delaroche¶
1A, Z = (24, 12)
1name_core = str(elements[Z].symbol)
2display(Math(f"^{{{A}}} \\rm{{{name_core}}}"))
\[\displaystyle ^{24} \rm{Mg}\]
Compute transmission coefficients¶
Let’s use jitr to calculate UQ’ed transmission coefficients using KDUQ Fermi energies and those from a variety of mass models
1from tqdm import tqdm
2
3import jitr
1neutron = (1, 0)
2proton = (1, 1)
3projectile = proton
4target = (A, Z)
1# we have 416 samples from the KDUQ posterior
2kduq_omp_samples = jitr.optical_potentials.kduq.get_samples(proton)
1# com_energy_grid = np.logspace(-1, 1.3, 100)
2lab_energy_grid = np.array([65, 200])
3range_fm = 15
4lmax = 20
1reaction = jitr.reactions.Reaction(target=target, projectile=projectile, process="EL")
1def set_up_grid(core, lab_energy_grid):
2 solvers = []
3 for _i, Elab in enumerate(tqdm(lab_energy_grid)):
4 kinematics = reaction.kinematics(Elab)
5 a = range_fm * kinematics.k + np.pi / 2
6 N = jitr.utils.suggested_basis_size(a)
7 solvers.append(
8 jitr.xs.elastic.IntegralWorkspace(
9 reaction=reaction,
10 kinematics=kinematics,
11 channel_radius_fm=a / kinematics.k,
12 solver=jitr.rmatrix.Solver(N),
13 lmax=lmax,
14 smatrix_abs_tol=0,
15 )
16 )
17 return solvers
1solvers = set_up_grid(target, lab_energy_grid)
100%|███████████████████████████████████████████████████████████████████████████████████| 2/2 [00:14<00:00, 7.29s/it]
Run the uncertainty propagation¶
KDUQ¶
1tcoeff_kduq = np.zeros((lab_energy_grid.size, kduq_omp_samples.shape[0], 2, lmax + 1))
2for j, sample in enumerate(tqdm(kduq_omp_samples)):
3 for i, _Elab in enumerate(lab_energy_grid):
4 rgrid = solvers[i].radial_grid()
5 central_params, spin_orbit_params, coulomb_params = (
6 jitr.optical_potentials.kduq.calculate_params(
7 projectile,
8 target,
9 solvers[i].kinematics.Elab,
10 *sample,
11 )
12 )
13
14 tplus, tminus = solvers[i].transmission_coefficients(
15 jitr.optical_potentials.kduq.central(rgrid, *central_params),
16 jitr.optical_potentials.kduq.spin_orbit(rgrid, *spin_orbit_params),
17 jitr.optical_potentials.kduq.coulomb_charged_sphere(rgrid, *coulomb_params),
18 )
19 tcoeff_kduq[i, j, 0, :] = tplus
20 tcoeff_kduq[i, j, 1, :] = tminus
97%|████████████████████████████████████████████████████████████████████████████▌ | 403/416 [08:09<00:23, 1.81s/it]/home/kyle/umich/jitr/src/jitr/optical_potentials/kduq.py:467: RuntimeWarning: overflow encountered in exp
d2 = d2_0 + d2_A / (1 + np.exp((A - d2_A3) / d2_A2))
100%|███████████████████████████████████████████████████████████████████████████████| 416/416 [08:26<00:00, 1.22s/it]
1data = [np.zeros(lmax + 1)] * 8
2names = [
3 "E=65 MeV, j = l + 1/2",
4 "E=65 MeV, j = l - 1/2",
5 "E=65 MeV, j = l + 1/2, err",
6 "E=65 MeV, j = l - 1/2, err",
7 "E=200 MeV, j = l + 1/2",
8 "E=200 MeV, j = l - 1/2",
9 "E=200 MeV, j = l + 1/2, err",
10 "E=200 MeV, j = l - 1/2, err",
11]
1from pandas import DataFrame as df
1data = df.from_dict(dict(zip(names, data, strict=False)))
1plus_color = "tab:blue"
2minus_color = "tab:orange"
1ci_plus = np.percentile(tcoeff_kduq[0, :, 0, :], 50, axis=0)
2ci_plus_errs = np.percentile(tcoeff_kduq[0, :, 0, :], 84, axis=0) - np.percentile(
3 tcoeff_kduq[0, :, 0, :], 16, axis=0
4)
1ci_minus = np.percentile(tcoeff_kduq[0, :, 1, :], 50, axis=0)
2ci_minus_errs = np.percentile(tcoeff_kduq[0, :, 1, :], 84, axis=0) - np.percentile(
3 tcoeff_kduq[0, :, 1, :], 16, axis=0
4)
1ci_minus[0] = None
2ci_minus_errs[0] = None
1data["E=65 MeV, j = l + 1/2"] = ci_plus
2data["E=65 MeV, j = l + 1/2, err"] = ci_plus_errs
3data["E=65 MeV, j = l - 1/2"] = ci_minus
4data["E=65 MeV, j = l - 1/2, err"] = ci_minus_errs
1fig = plt.figure(figsize=(6, 4))
2ls = np.arange(lmax + 1)
3plt.errorbar(
4 ls,
5 ci_plus * (2 * ls + 1),
6 ci_plus_errs * (2 * ls + 1),
7 linestyle="none",
8 marker="^",
9 label="$j = l + 1/2$",
10)
11
12plt.errorbar(
13 ls[1:],
14 ci_minus[1:] * (2 * ls[1:] + 1),
15 ci_minus_errs[1:] * (2 * ls[1:] + 1),
16 linestyle="none",
17 marker="v",
18 label="$j = l - 1/2$",
19)
20
21# plt.yscale("log")
22plt.xticks([0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20])
23plt.xlabel(r"$\ell$")
24plt.ylabel(r"$(2 \ell +1) \mathcal{T}_{lj}$")
25plt.title(r"$^{24}$Mg(p,p) 65 MeV", fontsize=14)
26plt.legend()
27plt.tight_layout()
1ci_plus = np.percentile(tcoeff_kduq[1, :, 0, :], 50, axis=0)
2ci_plus_errs = np.percentile(tcoeff_kduq[1, :, 0, :], 84, axis=0) - np.percentile(
3 tcoeff_kduq[1, :, 0, :], 16, axis=0
4)
1ci_minus = np.percentile(tcoeff_kduq[1, :, 1, :], 50, axis=0)
2ci_minus_errs = np.percentile(tcoeff_kduq[1, :, 1, :], 84, axis=0) - np.percentile(
3 tcoeff_kduq[1, :, 1, :], 16, axis=0
4)
5ci_minus[0] = None
6ci_minus_errs[0] = None
1data["E=200 MeV, j = l + 1/2"] = ci_plus
2data["E=200 MeV, j = l + 1/2, err"] = ci_plus_errs
3data["E=200 MeV, j = l - 1/2"] = ci_minus
4data["E=200 MeV, j = l - 1/2, err"] = ci_minus_errs
1fig = plt.figure(figsize=(6, 4))
2plt.errorbar(
3 ls,
4 ci_plus * (2 * ls + 1),
5 ci_plus_errs * (2 * ls + 1),
6 linestyle="none",
7 marker="^",
8 label="$j = l + 1/2$",
9)
10
11plt.errorbar(
12 ls[1:],
13 ci_minus[1:] * (2 * ls[1:] + 1),
14 ci_minus_errs[1:] * (2 * ls[1:] + 1),
15 linestyle="none",
16 marker="v",
17 label="$j = l - 1/2$",
18)
19
20# plt.yscale("log")
21plt.xticks([0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20])
22plt.xlabel(r"$\ell$")
23plt.ylabel(r"$(2 \ell +1) \mathcal{T}_{lj}$")
24plt.title(r"$^{24}$Mg(p,p) 200 MeV", fontsize=14)
25plt.legend()
26plt.tight_layout()
1# NBVAL_CHECK_OUTPUT
2data
| E=65 MeV, j = l + 1/2 | E=65 MeV, j = l - 1/2 | E=65 MeV, j = l + 1/2, err | E=65 MeV, j = l - 1/2, err | E=200 MeV, j = l + 1/2 | E=200 MeV, j = l - 1/2 | E=200 MeV, j = l + 1/2, err | E=200 MeV, j = l - 1/2, err | |
|---|---|---|---|---|---|---|---|---|
| 0 | 0.732306 | NaN | 0.103491 | NaN | 0.793631 | NaN | 0.083665 | NaN |
| 1 | 0.714397 | 0.733912 | 0.106325 | 0.101622 | 0.781721 | 0.806950 | 0.086771 | 0.084428 |
| 2 | 0.707490 | 0.740207 | 0.101053 | 0.093985 | 0.765326 | 0.809628 | 0.089057 | 0.087703 |
| 3 | 0.678968 | 0.730161 | 0.100371 | 0.088427 | 0.741524 | 0.808922 | 0.090451 | 0.094959 |
| 4 | 0.656383 | 0.725234 | 0.095936 | 0.075356 | 0.709459 | 0.804422 | 0.101630 | 0.100298 |
| 5 | 0.681355 | 0.689816 | 0.074087 | 0.082002 | 0.664013 | 0.797320 | 0.111231 | 0.107043 |
| 6 | 0.589953 | 0.538968 | 0.083585 | 0.095931 | 0.605166 | 0.781423 | 0.127492 | 0.114318 |
| 7 | 0.358919 | 0.329351 | 0.067499 | 0.065663 | 0.537147 | 0.751475 | 0.154021 | 0.130638 |
| 8 | 0.169756 | 0.165448 | 0.035843 | 0.034335 | 0.465712 | 0.698140 | 0.178390 | 0.146219 |
| 9 | 0.072202 | 0.073235 | 0.017226 | 0.016429 | 0.393139 | 0.621629 | 0.178045 | 0.154005 |
| 10 | 0.029473 | 0.030809 | 0.007992 | 0.007903 | 0.319778 | 0.527126 | 0.162889 | 0.147182 |
| 11 | 0.012078 | 0.012668 | 0.003880 | 0.003637 | 0.249148 | 0.422926 | 0.125635 | 0.130248 |
| 12 | 0.004944 | 0.005216 | 0.001846 | 0.001790 | 0.187534 | 0.319209 | 0.089697 | 0.102278 |
| 13 | 0.002036 | 0.002163 | 0.000890 | 0.000856 | 0.136752 | 0.229855 | 0.061229 | 0.077375 |
| 14 | 0.000841 | 0.000896 | 0.000424 | 0.000425 | 0.096277 | 0.158128 | 0.041666 | 0.055007 |
| 15 | 0.000356 | 0.000377 | 0.000211 | 0.000207 | 0.065568 | 0.105852 | 0.027758 | 0.039233 |
| 16 | 0.000152 | 0.000159 | 0.000100 | 0.000095 | 0.043796 | 0.069592 | 0.018947 | 0.025934 |
| 17 | 0.000065 | 0.000068 | 0.000047 | 0.000046 | 0.029016 | 0.044560 | 0.013011 | 0.017157 |
| 18 | 0.000028 | 0.000029 | 0.000023 | 0.000022 | 0.019050 | 0.028528 | 0.008826 | 0.011763 |
| 19 | 0.000012 | 0.000012 | 0.000011 | 0.000011 | 0.012400 | 0.018159 | 0.006208 | 0.007886 |
| 20 | 0.000005 | 0.000005 | 0.000005 | 0.000005 | 0.008033 | 0.011565 | 0.004265 | 0.005293 |