Author: Cherian Parangot Ittyipe Affiliation: Cardiff University, MSc Astrophysics (Merit, 2024)
This repository implements a full Bayesian MCMC inference pipeline for constraining Early Quintessence (EDE) cosmological parameters using the Planck 2018 CMB temperature and polarisation power spectra.
It accompanies the MSc thesis:
Constraining Early Dark Energy with CMB Anisotropies
Cherian Parangot Ittyipe, Cardiff University, 2024
DOI: 10.5281/zenodo.17681763
| Parameter | Posterior mean ± 1σ |
|---|---|
| 69.56 ± 0.93 km/s/Mpc | |
| 0.083 ± 0.024 | |
| 3.47 ± 0.10 | |
| 2.95 ± 0.24 |
Early Quintessence is a class of dark energy models where a scalar field with a tracking equation of state contributes a non-negligible fraction of the total energy density around the epoch of matter–radiation equality (
The model is parameterised by:
-
$f_\mathrm{EDE}(z_c)$ : fraction of dark energy at critical redshift$z_c$ -
$\log_{10} z_c$ : location of the EDE peak -
$n$ : power-law index of the scalar potential$V(\phi) \propto [1 - \cos(\phi/f)]^n$ -
$\theta_i = \phi_i/f$ : initial field displacement
Theory is computed using CAMB with the built-in EarlyQuintessence dark energy module (Smith et al. 2020).
cmb_ede_mcmc/
├── mcmc/
│ ├── __init__.py
│ ├── theory.py # CAMB interface (EarlyQuintessence D_ell)
│ ├── data.py # Planck 2018 FITS loader
│ ├── likelihood.py # log-prior, log-likelihood, posterior factory
│ └── sampler.py # emcee runner + chain saving utilities
├── analysis/
│ ├── __init__.py
│ ├── diagnostics.py # R-hat, ESS, posterior summary
│ └── plotting.py # traces, corner, spectrum plots
├── notebooks/
│ ├── 01_run_mcmc.ipynb # interactive MCMC run
│ └── 02_analysis.ipynb # diagnostics, corner plot, spectrum
├── data/ # (gitignored) local Planck FITS data
├── results/ # (gitignored) chain outputs
├── run_mcmc.py # CLI entry point
├── params.json # thesis best-fit parameter set (fixed)
├── plot_cmb_from_posterior.py # standalone spectrum plotter
├── requirements.txt
└── README.md
git clone https://github.com/Cherian-pi/cmb-ede-mcmc.git
cd cmb-ede-mcmcpython -m venv .venv
source .venv/bin/activate # Linux/macOS
.venv\Scripts\activate # Windowspip install -r requirements.txtNote: CAMB is included in
requirements.txtand installs theEarlyQuintessence
module automatically on Python ≥ 3.10.
Download COM_PowerSpect_CMB_R2.02.fits from the Planck Legacy Archive (free registration required).
Place it anywhere and set the path as described below.
# Set path to Planck FITS file
export PLANCK_FITS=/path/to/COM_PowerSpect_CMB_R2.02.fits
# Full run (TT + TE + EE, 36 walkers, 500 steps)
python run_mcmc.py
# Quick functional test (not converged)
python run_mcmc.py --burnin 10 --nsteps 50 --nwalkers 22
# Custom output directory
python run_mcmc.py --outdir results/run_TT_only --spectra TTSee python run_mcmc.py --help for all options.
jupyter lab
# Open notebooks/01_run_mcmc.ipynbEdit the PLANCK_FITS path in cell 0, then run all cells.
After the chain completes, open notebooks/02_analysis.ipynb for diagnostics and plots.
python plot_cmb_from_posterior.pyThis reads params.json (thesis best-fit parameters) and plots the CMB TT spectrum against Planck 2018 data without running any MCMC.
The inference runs over a 10-dimensional parameter vector:
| # | Parameter | Description | Prior |
|---|---|---|---|
| 0 | Hubble constant [km/s/Mpc] | Flat [40, 90] | |
| 1 | Baryon density | Flat [0.01, 0.04] | |
| 2 | CDM density | Flat [0.05, 0.30] | |
| 3 | Optical depth | Flat + Gauss(0.0544, 0.0073) | |
| 4 | Spectral index | Flat [0.89, 1.10] | |
| 5 | Primordial amplitude | Flat [1×10⁻⁹, 3×10⁻⁹] | |
| 6 | EDE critical redshift | Flat [2.8, 3.8] | |
| 7 | EDE fraction at |
Flat [0.0, 0.20] | |
| 8 | EDE potential power index | Flat [1.5, 4.0] | |
| 9 | Initial field displacement [rad] | Flat [0, π] |
Each CAMB call takes approximately 0.5–2 seconds on a modern CPU.
A typical converged run (36 walkers × 500 production steps) requires ~9,000 CAMB evaluations and takes 3–10 hours on a single core.
For faster iteration:
- Use
--nsteps 50 --burnin 10for a quick functional test (~20 minutes) - Use multiprocessing:
emcee.EnsembleSampler(pool=multiprocessing.Pool()) - Run on HPC with MPI via
schwimmbad.MPIPool
The best-fit parameter set (params.json) from this inference is used to
generate the CMB TT power spectrum in the companion repository:
→ github.com/Cherian-pi/cmb-spectrum
After a run, results/ contains:
| File | Description |
|---|---|
EDE_Planck_<ts>_flat.csv |
Flat chain (n_samples × 11): parameters + log_posterior |
EDE_Planck_<ts>_chain.npy |
Raw chain (nsteps, nwalkers, ndim) |
EDE_Planck_<ts>_meta.json |
Run metadata (settings, acceptance fraction) |
traces.png |
Walker trace plots |
corner.png |
2D marginal posteriors |
spectrum.png |
Best-fit CMB spectrum vs Planck data |
- Planck 2018: Aghanim et al. 2020, A&A 641 A5 (arXiv:1807.06209)
- Early Quintessence: Smith, Poulin & Amin 2020, PRD 101 063523 (arXiv:1908.06995)
- CAMB: Lewis, Challinor & Lasenby 2000; Howlett et al. 2012 (camb.info)
- emcee: Foreman-Mackey et al. 2013 (arXiv:1202.3665)
- Thesis: Ittyipe 2024, DOI:10.5281/zenodo.17681763
MIT — see LICENSE.