codexconstant-loading-acoustic-clock.py
constant-loading-acoustic-clock.py
"""Explicit constant-R, constant-potential oscillator and stipulated ruler example.
Run from _media. Tested with Python 3.14, numpy 2.3.5, matplotlib 3.10.7.
These are analytic model curves, not CMB data or a Boltzmann-code spectrum.
"""
from pathlib import Path
import matplotlib.pyplot as plt
import numpy as np
def response(phase, loading):
"""y = (Theta_0 + Psi)/Psi; y(0)=1/3 and dy/dphase(0)=0."""
return (1/3 + loading)*np.cos(phase) - loading
def main():
fig, axes = plt.subplots(1, 2, figsize=(10.8, 4.8), dpi=120, facecolor="white")
fig.suptitle("Two effects to distinguish: acoustic response and angular size",
fontsize=15, y=.96)
phase = np.linspace(0, 4*np.pi, 1001)
ax = axes[0]
for loading, color in [(0, "#2464a4"), (.6, "#bc4a2a")]:
ax.plot(phase/np.pi, response(phase, loading), label=f"R = {loading:g}", color=color, lw=2)
ax.axhline(-loading, color=color, ls=":", lw=1)
ax.set(xlabel=r"Acoustic phase $q/\pi = k r_s/\pi$",
ylabel=r"$y=(\Theta_0+\Psi)/\Psi$", xlim=(0, 4), ylim=(-1.85, .65),
title="Constant loading and gravitational potential")
ax.set_xticks(range(5))
ax.legend(loc="upper right", frameon=False)
ax.text(.2, -1.72, r"$y_{qq}+y=-R$; $y(0)=1/3$, $y_q(0)=0$", fontsize=10)
ax.grid(alpha=.18)
ax = axes[1]
distance = np.linspace(11500, 17000, 100)
theta = 144/14000
ax.plot(distance/1000, theta*distance, color="#2464a4", lw=2,
label=r"Same $\theta_* = r_s/D_M$")
examples = [(14000, 144, "A"), (15400, 158.4, "B")]
for d, r, name in examples:
ax.scatter(d/1000, r, s=55, color="#bc4a2a", zorder=4)
ax.annotate(f"{name}: ({d/1000:g} Gpc, {r:g} Mpc)", (d/1000, r),
xytext=(-105, 14), textcoords="offset points", fontsize=9)
ax.set(xlabel=r"Transverse comoving distance $D_M$ (Gpc)",
ylabel=r"Comoving sound horizon $r_s$ (Mpc)",
title="Stipulated ruler example: same angular scale",
xlim=(11.5, 17), ylim=(110, 190))
ax.text(11.85, 119, r"$\theta_*=0.589^\circ$, $\ell_A=\pi/\theta_*=305.4$"+"\nBoth lengths × 1.1 leaves the ratio unchanged.", fontsize=10,
bbox={"facecolor": "white", "edgecolor": "none", "alpha": .92})
ax.legend(loc="upper left", frameon=False)
ax.grid(alpha=.18)
fig.text(.5, .035, "Analytic teaching models: no damping, evolving gravity, sky projection or measured bandpowers.",
ha="center", fontsize=10)
fig.subplots_adjust(left=.075, right=.985, top=.82, bottom=.19, wspace=.31)
fig.savefig(Path(__file__).with_suffix(".png").name, facecolor="white")
plt.close(fig)
if __name__ == "__main__":
main()