Skip to content

dmobius3/lambda-cos

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

80 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Λcos: Apparent Phantom Crossing as Template Bias

Code and data for the paper:

B. Shatto, "Apparent Phantom Crossing as Template Bias: A Bounded-Clock Deformation of ΛCDM" (2026).

This repository contains the analysis pipeline, figure-generation scripts, and the LaTeX source for the paper itself (under paper/).


Overview

The Λcos model is a one-parameter deformation of the fiducial flat ΛCDM expansion history using a bounded auxiliary variable. It yields

$$\frac{H^2(z)}{H_0^2} = \alpha,(1+z)^3 ;-; \beta,(1+z) ;+; \Omega_\Lambda$$

with $\alpha$, $\beta$ determined by $s_0$ and a fixed reference $\Omega_\Lambda$. Under the fiducial-matter diagnostic split, the effective residual satisfies $w_\mathrm{eff}(z) > -1$.

Reproducible results in this repository:

  • Joint Pantheon+ + DESI DR2 BAO fit for ΛCDM, Λcos, and wCDM (§V.B, §V.G)
  • Template-bias mock fits across CPL, BA, JBP, and a three-parameter polynomial (§IV.B)
  • CPL threshold scan across $s_0 \in [0.01, 0.40]$ (§IV.C)
  • Prior sensitivity for Λcos under flat, $s_0^2$, and $\log_{10}(s_0)$ priors (§V.C)
  • Ω_Λ sensitivity scan across 0.680–0.715 (§V.D)
  • CMB distance priors for flat ΛCDM, non-flat ΛCDM, Λcos at fixed Ω_Λ, and Λcos with Ω_Λ free (§V.E)
  • Savage-Dickey Bayes factor at the $s_0$ prior boundary (§V.E)
  • Clock exponent comparison for Models A, B, C, D (Appendix A)
  • Linear growth comparison against DESI DR1 ShapeFit+BAO $f\sigma_{s8}$ at six tracer effective redshifts (§VI.C)
  • Figure generation for Figs. 1–6

Follow-up note: the γ-CDM diagnostic check

paper2/gamma_cdm_note.tex (compiled PDF) is a short, standalone two-page note, "A Diagnostic Check on a One-Parameter Matter-Exponent Deformation of ΛCDM." It is not a revision of the paper above and does not depend on it: a separate one-parameter deformation,

$$\frac{H^2(z)}{H_0^2} = \Omega_m,(1+z)^\gamma + \Omega_\Lambda, \qquad \gamma = 3 \text{ recovers } \Lambda\text{CDM},$$

used purely as a diagnostic for how much of the DESI-era preference for dynamical dark energy is driven by the very-low-redshift supernova sample.

On the full Pantheon+ + DESI DR2 BAO vector the deformation prefers $\gamma < 3$ at $\Delta\chi^2 \approx -8.75$. The standard $z > 0.01$ cosmology cut (removing 111 low-$z$ SNe on the usual peculiar-velocity/calibration grounds) reduces this to $\Delta\chi^2 \approx -2.97$, and a $z > 0.1$ stress cut to $-1.89$; a Savage-Dickey comparison favors ΛCDM under both a narrow and a wide prior on $\gamma$. Conclusion: the large apparent preference is substantially a property of the very-low-redshift supernova sample, not evidence for this or any nonstandard late-time expansion history. The note is offered as a small independent data point for the low-redshift supernova-systematics discussion, not as a candidate cosmology.

Supporting analysis: scripts/gamma_gate.py, scripts/diagnose_clock_asymmetry.py, scripts/fit_clock_asymmetry.py, scripts/lcos_z001_robustness.py, with outputs under results/gamma_gate_* and results/clock_asymmetry_*. The note is not yet separately archived with its own DOI; its data-availability statement points to this repository and to the Zenodo deposit of the pipeline above (design commit 343c9d8, results commit 69c4604).


Citation

If you use this code or data, please cite the paper and the Zenodo archive of this repository.

@article{Shatto2026Lambdacos,
  title  = {Apparent Phantom Crossing as Template Bias: A Bounded-Clock
            Deformation of ΛCDM},
  author = {Shatto, B.},
  year   = {2026}
}

@misc{ShattoLambdacosCode2026,
  author = {Shatto, B.},
  title  = {Λcos: Code and Data for "Apparent Phantom Crossing as Template Bias"},
  year   = {2026},
  doi    = {10.5281/zenodo.19798852}
}

Repository contents

.
├── README.md                                  This file
├── LICENSE                                    MIT
├── requirements.txt                           Python dependencies
├── data/
│   ├── pantheon_plus.csv                      Pantheon+ SNe Ia magnitudes
│   ├── pantheon_plus_cov.npy                  1701 × 1701 statistical + systematic covariance
│   ├── desi_dr2_bao.csv                       DESI DR2 BAO observables
│   ├── desi_dr2_bao_cov.npy                   Inter-observable covariance for the 13 BAO points
│   └── desi_dr1_fs_fsigma8.csv                DESI DR1 ShapeFit+BAO compressed fσ_s8 amplitudes at 6 tracer effective redshifts (§VI.C)
├── scripts/
│   ├── fit_lcdm.py                            Flat ΛCDM MCMC fit (§V.B)
│   ├── fit_lcos.py                            Λcos MCMC fit; --omega_lambda VALUE (default 0.685, §V.B)
│   ├── fit_wcdm.py                            wCDM MCMC fit (§V.G)
│   ├── fit_clock_exponents.py                 Clock exponent comparison (Appendix A)
│   ├── fit_lcdm_cmb.py                        ΛCDM + CMB distance priors; --non_flat (§V.E)
│   ├── fit_lcos_cmb.py                        Λcos + CMB distance priors; --free_omega_lambda (§V.E)
│   ├── omega_lambda_scan.py                   Aggregate §V.D Ω_Λ sensitivity table
│   ├── prior_sensitivity.py                   §V.C prior-reweighting of the baseline Λcos chain
│   ├── bayes_factor.py                        §V.E Savage-Dickey Bayes factor at the s₀ prior boundary
│   ├── template_bias.py                       Template-bias mocks + Fig. 1 (§IV.B)
│   ├── threshold_scan.py                      CPL threshold scan + Fig. 2 (§IV.C)
│   ├── make_plots.py                          Λcos corner (Fig. 3) and residuals (Fig. 4)
│   ├── growth.py                              Linear-growth ODE solver for arbitrary E(z); validates against textbook Ω_m(z)^0.55 (§VI.C)
│   ├── compute_rsd_chi2.py                    χ²_RSD comparison vs DESI DR1 FS at the SN+BAO best fit (§VI.C)
│   ├── make_growth_figures.py                 Fig. 5 (fσ_8 trajectories + DR1 FS data) and Fig. 6 (Ω_m(z) diagnostic) (§VI.C)
│   ├── _summary.py                            Shared harmonized summary-JSON schema helper
│   ├── lcos_z001_robustness.py                Paper 1 robustness under the z>0.01 cut (apples-to-apples s0 UL)
│   ├── fit_clock_asymmetry.py                 Continuous clock-asymmetry (ε) fit, two tiers (paper2 precursor)
│   ├── diagnose_clock_asymmetry.py            Post-run diagnostics for the ε fit (audit, Ω_Λ-free scan, SN/BAO split)
│   └── gamma_gate.py                          γ-CDM gate: fits, evidence, and threshold scan for paper2
├── results/                                   MCMC chains, post-burn samples, summaries, generated figures
│   ├── lcdm_chain.npy, lcdm_post.csv, lcdm_summary.json, lcdm_corner.png
│   ├── lcos_chain.npy, lcos_post.csv, lcos_summary.json, lcos_corner.{png,pdf}
│   ├── lcos_omegaL_<v>_*.{npy,csv,json,png}   Λcos at alternative Ω_Λ ∈ {0.680, 0.690, 0.700, 0.715} (§V.D)
│   ├── wcdm_chain.npy, wcdm_post.csv, wcdm_summary.json, wcdm_corner.png
│   ├── lcdm_cmb_*.{npy,csv,json,png}          Flat ΛCDM + CMB priors (§V.E)
│   ├── lcdm_cmb_nonflat_*.{npy,csv,json,png}  Non-flat ΛCDM + CMB priors (§V.E)
│   ├── lcos_cmb_*.{npy,csv,json,png}          Λcos at Ω_Λ = 0.685 + CMB priors (§V.E)
│   ├── lcos_cmb_freeOL_*.{npy,csv,json,png}   Λcos with Ω_Λ free + CMB priors (§V.E)
│   ├── clock_exponent_{A,B,C,D}_chain.npy
│   ├── clock_exponent_{A,B,C,D}_postburn.csv
│   ├── clock_exponent_results.csv             Appendix A summary across all four models
│   ├── prior_sensitivity.csv                  §V.C reweighted-prior medians and 95% upper limits
│   ├── bayes_factor.csv                       §V.E B_01 across bandwidths for stability
│   ├── template_bias.csv, template_bias.{png,pdf}     §IV.B fits and Fig. 1
│   ├── threshold_scan.csv, threshold_scan.{png,pdf}   §IV.C scan and Fig. 2
│   ├── residuals.{png,pdf}                    Fig. 4
│   ├── growth_LCDM_Om0p315.csv                §VI.C growth trajectory at Ω_m = 0.315
│   ├── growth_Lcos_s00p076.csv                §VI.C growth trajectory at the Λcos posterior median
│   ├── growth_Lcos_s00p185.csv                §VI.C growth trajectory at the 95% upper limit
│   ├── rsd_chi2.csv, rsd_residuals.csv        §VI.C χ²_RSD summary and per-tracer pulls
│   ├── fig5_fsigma8.{png,pdf}                 Fig. 5 (fσ_8 + DR1 FS data)
│   ├── fig6_omegam_z.{png,pdf}                Fig. 6 (Ω_m(z) diagnostic)
│   ├── lcos_z001_robustness.{json,log}, lcos_z001_s0_profile.csv, lcos_all_s0_profile.csv   Paper 1 z>0.01 robustness
│   ├── clock_asymmetry_*.{json,csv,log,npy}   ε-fit tiers, gates, and post-run diagnostics (audit, Ω_Λ-free scan, SN/BAO split)
│   └── gamma_gate_*.{json,csv,log}            γ-CDM gate: fits, evidence (primary/robust priors), threshold-scan splits
├── tables/
│   ├── clock_exponent_appendix_A_fits.csv     Curated Appendix A reference values
│   └── omega_lambda_scan.csv                  Aggregated §V.D Ω_Λ sensitivity table
├── figures/
│   ├── fig1_template_bias_overlay.pdf         §IV.B: w(z) overlays for CPL/BA/JBP/Polynomial
│   ├── fig2_threshold_scan.pdf                §IV.C: recovered (w₀, w_a) vs s₀
│   ├── fig3_lcos_corner.pdf                   §V.B: Λcos posterior in (s₀, H₀r_d, M_B)
│   ├── fig4_hubble_residuals.pdf              §V.B: Pantheon+ binned residuals for ΛCDM and Λcos
│   ├── fig5_fsigma8.pdf                       §VI.C: fσ_8(z) trajectories + DESI DR1 FS data
│   └── fig6_omegam_z.pdf                      §VI.C: Ω_m(z) diagnostic out to z = 3
├── paper/                                     LaTeX source for the manuscript
│   ├── paper.tex                              REVTeX 4.2 single-source LaTeX (preamble + body + bibliography)
│   ├── references.bib                         22 entries
│   ├── figures/                               Self-contained copies of ../figures/*.pdf
│   ├── paper.pdf                              Compiled output (single-column, JCAP submission format)
│   ├── Makefile                               Build pipeline (pdflatex + bibtex + pdflatex × 2)
│   └── README.md                              Build instructions
└── paper2/                                    LaTeX source for the follow-up diagnostic note
    ├── gamma_cdm_note.tex                     REVTeX 4.2 two-page note (see "Follow-up note" above)
    └── gamma_cdm_note.pdf                     Compiled output

figures/ holds the paper-facing PDFs at their published filenames. They are stable copies of the corresponding script outputs in results/.


Installation

Python 3.10 or later recommended.

git clone https://github.com/dmobius3/lambda-cos.git
cd lambda-cos
python -m venv venv
source venv/bin/activate
pip install -r requirements.txt

Dependencies (requirements.txt):

numpy>=1.24
scipy>=1.10
emcee>=3.1
corner>=2.2
matplotlib>=3.7
h5py>=3.8
pandas>=2.0

Total install footprint about 200 MB. The primary SN+BAO MCMC fit takes roughly 5 minutes on a recent laptop (32 walkers, 5000 steps).


Quickstart: reproducing the primary fit

The headline result is the joint Pantheon+ + DESI DR2 BAO Λcos fit (§V.B). All scripts are written to be run from the scripts/ directory and resolve paths via ../data/ and ../results/.

cd scripts
python fit_lcos.py

Outputs to results/: lcos_chain.npy, lcos_post.csv, lcos_summary.json, lcos_corner.png.

For the ΛCDM baseline:

python fit_lcdm.py

For wCDM (§V.G):

python fit_wcdm.py

Reference summary values from the deposited posteriors:

Λcos:    s0 median ≈ 0.076  (68% CI: 0.023, 0.143)
         s0 95% UL ≈ 0.185  (flat prior)
         H0 r_d    ≈ 10008  km/s
         M_B       ≈ -19.353
         tau_max   ≈ 46.9
ΛCDM:    Ω_m       ≈ 0.312  (68% CI: 0.304, 0.321)
         H0 r_d    ≈ 10043  km/s
         M_B       ≈ -19.355
         tau_max   ≈ 35.9
wCDM:    Ω_m       ≈ 0.297
         w         ≈ -0.855  (68% CI: -0.89, -0.82)
         Δχ²       ≈ -13.05 vs flat ΛCDM
         ΔAIC      ≈ -11.05
         ΔBIC      ≈  -5.61
         tau_max   ≈ 47.4

Reproducing each figure

cd scripts

# Figure 1 — w(z) recoveries from CPL, BA, JBP, Polynomial
python template_bias.py
# -> results/template_bias.{png,pdf}

# Figure 2 — CPL threshold scan
python threshold_scan.py
# -> results/threshold_scan.{png,pdf}

# Figures 3 and 4 — Λcos corner plot and Pantheon+ residuals
# Requires lcdm_post.csv and lcos_post.csv (run fit_lcdm.py and fit_lcos.py first)
python make_plots.py
# -> results/lcos_corner.{png,pdf}   (Fig. 3)
# -> results/residuals.{png,pdf}     (Fig. 4)

# Figures 5 and 6 — fσ_8(z) with DESI DR1 FS overlay and Ω_m(z) diagnostic
# Requires growth_LCDM_*.csv and growth_Lcos_*.csv (see §VI.C reproduction below)
python make_growth_figures.py
# -> results/fig5_fsigma8.{png,pdf}  (Fig. 5)
# -> results/fig6_omegam_z.{png,pdf} (Fig. 6)

The paper-facing PDFs in figures/ (fig1_template_bias_overlay.pdf, fig2_threshold_scan.pdf, fig3_lcos_corner.pdf, fig4_hubble_residuals.pdf, fig5_fsigma8.pdf, fig6_omegam_z.pdf) are stable copies of the corresponding results/ outputs renamed to match the in-paper figure numbers.


Reproducing the template-bias scan (§IV.C)

cd scripts
python threshold_scan.py

Iterates CPL fits across $s_0 \in [0.01, 0.40]$ in steps of $0.01$, recording $(w_0, w_a, \chi^2)$ at each value to results/threshold_scan.csv and producing Fig. 2.

The single-$s_0$ mock comparison across all four parameterizations (Table in §IV.B) is produced separately by template_bias.py, which writes results/template_bias.csv and Fig. 1.


Reproducing Appendix A (clock exponent selection)

cd scripts
python fit_clock_exponents.py

Models A (n = 0), B (n = −1), C (n = +1), D (n = −1/2) are fit with the same MCMC setup as the primary Λcos run. Outputs to results/:

  • clock_exponent_{A,B,C,D}_chain.npy — full chains
  • clock_exponent_{A,B,C,D}_postburn.csv — post-burn samples
  • clock_exponent_results.csv — summary with one row per model: best-fit parameters, χ² split (SN, BAO, total), Δχ² vs ΛCDM, acceptance fraction

The curated paper-facing values are also deposited at tables/clock_exponent_appendix_A_fits.csv.


Reproducing the Ω_Λ sensitivity scan (§V.D)

cd scripts
python fit_lcos.py --omega_lambda 0.680
python fit_lcos.py --omega_lambda 0.685   # canonical
python fit_lcos.py --omega_lambda 0.690
python fit_lcos.py --omega_lambda 0.700
python fit_lcos.py --omega_lambda 0.715
python omega_lambda_scan.py

Outputs to results/lcos_omegaL_<v>_*.{npy,csv,json,png} for each non-canonical value (the canonical Ω_Λ = 0.685 writes to lcos_* without a suffix). The aggregator reads each summary JSON and produces tables/omega_lambda_scan.csv with one row per Ω_Λ (s₀ median, s₀ 95% UL, χ²_min, χ²_SN, χ²_BAO, Δχ² vs ΛCDM baseline, τ_max, acceptance).


Reproducing §V.E (CMB distance priors)

§V.E adds compressed Planck 2018 distance priors (R = 1.7502 ± 0.0046, ℓ_A = 301.47 ± 0.09) to the SN+BAO likelihood. Four fits in total:

cd scripts
python fit_lcdm_cmb.py                       # Flat ΛCDM + CMB priors  (3 params)
python fit_lcdm_cmb.py --non_flat            # Non-flat ΛCDM + CMB     (4 params, Ω_k = 1 - Ω_m - Ω_Λ - Ω_r)
python fit_lcos_cmb.py                       # Λcos at Ω_Λ = 0.685 + CMB priors (3 params)
python fit_lcos_cmb.py --free_omega_lambda   # Λcos with Ω_Λ free + CMB priors  (4 params)

Outputs:

  • results/lcdm_cmb_* and results/lcdm_cmb_nonflat_* for the two ΛCDM cases
  • results/lcos_cmb_* and results/lcos_cmb_freeOL_* for the two Λcos cases

Each summary JSON reports the χ² split (SN, BAO, CMB), the best-fit point from a post-MCMC optimizer pass, the integrated autocorrelation time per parameter, the acceptance fraction, and (for the 4-parameter fits) the Ω_Λ posterior quantiles.

The CMB priors are implemented with the standard compressed-prior forms

R   = sqrt(Ω_m) * ∫₀^z* dz/E(z)
ℓ_A ≈ π c / (H0 r_d) * ∫₀^z* dz/E(z)        (treating r_d ≈ r_s(z*); ~2% offset for standard cosmology)

with z* = 1090 and Ω_r = 9.15 × 10⁻⁵ included in E(z) for the high-z integral.


Reproducing §VI.C (linear-growth consistency check)

§VI.C compares the linear-growth prediction f σ_8(z) of ΛCDM and Λcos against the DESI DR1 ShapeFit+BAO compressed growth amplitudes (DESI 2024 Paper V, Appendix A, Eqs. A.13–A.24) at six tracer effective redshifts. The Λcos correction enters only through H(z); no perturbation-level parameter is introduced.

cd scripts

# Step 1: validate the growth ODE solver against textbook ΛCDM
python growth.py --validate
# -> max |Δf/f| ≲ 0.5% vs Ω_m(z)^0.55 over z ∈ [0, 2.4]

# Step 2: compute fσ_8(z) trajectories for ΛCDM and Λcos at two s₀ values
python growth.py --model LCDM --Om 0.315
python growth.py --model Lcos --s0 0.076 --OL 0.685
python growth.py --model Lcos --s0 0.185 --OL 0.685
# -> results/growth_LCDM_Om0p315.csv
# -> results/growth_Lcos_s00p076.csv  (posterior median)
# -> results/growth_Lcos_s00p185.csv  (95% upper limit)

# Step 3: χ²_RSD against DESI DR1 FS at the SN+BAO best fit
python compute_rsd_chi2.py
# -> results/rsd_chi2.csv          (per-model χ²_RSD and Δχ²)
# -> results/rsd_residuals.csv     (per-tracer pulls)

# Step 4: figures
python make_growth_figures.py
# -> results/fig5_fsigma8.{png,pdf}   (Fig. 5)
# -> results/fig6_omegam_z.{png,pdf}  (Fig. 6)

Reference values:

χ²_RSD (6 tracer bins, diagonal-error consistency check):
  ΛCDM (Ω_m = 0.315)                4.64
  Λcos (s₀ = 0.076, median)         4.68    Δχ² = +0.04
  Λcos (s₀ = 0.185, 95% UL)         4.90    Δχ² = +0.26

Ω_m(z) split at z = 2.3:
  Λcos – ΛCDM at s₀ = 0.185         −2.9%

Note on data provenance: DESI DR2 (March 2025) released BAO distances only, not a DR2 full-shape product. The growth comparison therefore uses DR1 FS; the combination of DR2 BAO with DR1 FS follows the collaboration's own precedent (Elbers et al., arXiv:2503.14744; Forero-Sánchez et al., arXiv:2602.18761 for the rigorous joint treatment).


Data sources and provenance

Dataset Source Reference
Pantheon+ SNe Ia pantheonplussh0es.github.io Brout et al., Astrophys. J. 938, 110 (2022)
DESI DR2 BAO data.desi.lbl.gov DESI Collaboration, arXiv:2503.14738 (2025)
DESI DR1 ShapeFit+BAO fσ_s8 DESI 2024 Paper V, Appendix A DESI Collaboration, J. Cosmol. Astropart. Phys. 2025, 008, arXiv:2411.12021
Planck 2018 distance priors Compressed (R, ℓ_A) from Planck VI Planck Collaboration VI, Astron. Astrophys. 641, A6 (2020)

The files under data/ are formatted derivatives of the public sources above, repackaged for direct loading by the fit scripts. No proprietary data is included.


Reproducibility notes

  • Random seeding: fit_clock_exponents.py sets RNG_SEED = 12345, which pins the walker initialization only; the emcee chain evolution itself is not seeded. The other MCMC scripts (fit_lcdm.py, fit_lcos.py, fit_wcdm.py) initialize walkers from np.random.randn without an explicit seed. In all cases run-to-run variations are within the posterior thickness and do not change the reported summary values; for boundary-saturated fits (e.g. clock-exponent models B and D) the best-fit s₀ in the flat-likelihood region near the prior floor can vary between runs, while χ² and Δχ² reproduce to ~0.001.
  • MCMC configuration: 32 walkers, 5000 steps, 1000 burn-in across all fit scripts.
  • Numerical accuracy: distance integrals use SciPy's cumulative_trapezoid on a 4000-point grid in z ∈ [0, 2.5] (or up to z_max ≈ 2.4 from the BAO range). For the clock-exponent run the grid extends to 1.002 × max(z_data).
  • Working directory: scripts are run from the scripts/ subdirectory; paths resolve via ../data/ and ../results/.
  • Platform: tested on macOS 14.x and Ubuntu 22.04 with Python 3.11. No GPU required.

License

This repository is released under the MIT License. See LICENSE for the full text.

The Pantheon+ and DESI DR2 BAO data products are redistributed under the terms of their original publications; refer to the linked sources above for their license terms.


Contact

About

Code and data for 'Apparent Phantom Crossing as Template Bias: A Bounded-Clock Deformation of ΛCDM'

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors