Designing an experiment before there is any data · step 1 of 6
Two atoms, one number
How do you get resolving power against a question nobody has measured?
In 1910 there were two pictures of the atom and no experiment between them. A hard positive centre and a charge smeared through the whole atom both fitted everything anyone had. You cannot design against a debate — so the first move is to find the number the two pictures disagree about.
They are one model at two values of the radius R of the positive charge, six decades apart. An alpha stopped head-on gets no closer than D; one scattered through an angle gets no closer than a known multiple of it; so a charge of radius R kills the scattering past a cut-off angle. Turning the debate into a parameter is what makes everything after this possible.
scattering.py is the case study's own module and it holds the physics: the mean expression, the parameters and their priors, the detector geometry. It is a hand-built ModelSpec rather than anything axiom generates, which is what a problem with real physics in it looks like. The porting tutorial builds the easier kind, a SurfaceSpec, from scratch.
closest approach, head-on
D_CLOSEST = 2 * Z_ALPHA * Z_FOIL * COULOMB_MEV_FM / E_ALPHA * 1e-15 # a constant of the beam and the foil, not a fitted quantity
closest approach at angle θ
# the floor no amount of counting can beat floor = S.D_CLOSEST / 2.0
where a charge of radius R kills the tail
lam = Param(
name="lam",
dimension=dimensionless(),
prior=Prior(family="normal",
hyper={"mu": -4.0, "sigma": 6.0}),
)
# the one axis the two atoms are two points on
import sys
sys.path.insert(0, "nbs/case-studies/rutherford")
import scattering as s
print(f"closest approach D : {s.D_CLOSEST * 1e15:.1f} fm")
print(f"a hard centre would be : {s.R_NUCLEUS * 1e15:.1f} fm")
print(f"a diffuse atom would be : {s.R_ATOM * 1e15:,.0f} fm")
print()
for name, radius in (("hard centre", s.R_NUCLEUS), ("diffuse atom", s.R_ATOM)):
sine = s.cutoff_sine(radius)
where = "no cut-off in range" if sine >= 1.0 else f"{sine:.2e}"
print(f"{name:14s} sin(theta_cut/2) = {where}")
print()
print("the two hypotheses are two values of one parameter, lam:")
print(f" hard centre lam = {s.LAM_HARD:+.2f}")
print(f" diffuse atom lam = {s.LAM_DIFFUSE:+.2f}")
# the numbers the apparatus diagram on this page is drawn from
apparatus = {
"energy_mev": s.E_ALPHA,
"d_fm": s.D_CLOSEST * 1e15,
"foil_um": s.FOIL_THICKNESS * 1e6,
"beam_per_s": s.BEAM_RATE,
"angles": [st.theta_deg for st in s.PLAN if st.foil],
}
closest approach D : 59.2 fm a hard centre would be : 7.3 fm a diffuse atom would be : 135,000 fm hard centre sin(theta_cut/2) = no cut-off in range diffuse atom sin(theta_cut/2) = 2.19e-04 the two hypotheses are two values of one parameter, lam: hard centre lam = +6.91 diffuse atom lam = -8.42
Every line above was captured by running this code at build time. The steps share one namespace, so the code on this page is the code you would type after the steps before it.