diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 066f855..5b65afe 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -213,8 +213,37 @@ jobs: # re-run here too -- cheap relative to the cosmosis run, and it # confirms they also pass with the full stack installed (not just # in the stripped-down fast env). - pytest tests -v + pytest tests -v --cov --cov-branch --cov-report=xml + env: + DISPLAY: test + - name: Upload coverage reports to Codecov + uses: codecov/codecov-action@v5 + with: + token: ${{ secrets.CODECOV_TOKEN }} + + + doc-valid: + name: Documentation Validation + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: conda-incubator/setup-miniconda@v3 + with: + activate-environment: clpipe-full + environment-file: ${{ env.FULL_ENV_FILE }} + - uses: actions/cache@v4 + with: + path: ${{ env.CONDA }}/pkgs + key: ${{ runner.os }}-conda-${{ env.CONDA_ENV_NAME }} + - name: Install the package + shell: bash -l {0} + run: | + pip install . -vv --no-deps --no-build-isolation + - name: Run the docs + shell: bash -l {0} + run: | + make -C docs/ html # ------------------------------------------------------------------ # # (Optional, disabled) lint. Enable in a separate formatting PR once # # the pipeline files are actually black/isort-clean, so the # diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml new file mode 100644 index 0000000..f613b27 --- /dev/null +++ b/.github/workflows/docs.yml @@ -0,0 +1,58 @@ +name: docs + +# Builds the Sphinx HTML docs on every PR/push touching them (as a check), +# and publishes to GitHub Pages on pushes to main. +# One-time setup: Settings -> Pages -> Source: "GitHub Actions". + +on: + push: + branches: [main] + paths: ["docs/**", "clpipe/**", ".github/workflows/docs.yml"] + pull_request: + paths: ["docs/**", "clpipe/**", ".github/workflows/docs.yml"] + workflow_dispatch: + +permissions: + contents: read + +concurrency: + group: pages-${{ github.ref }} + cancel-in-progress: true + +jobs: + build: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - uses: actions/setup-python@v5 + with: + python-version: "3.12" + cache: pip + cache-dependency-path: docs/requirements.txt + + - name: Install doc dependencies + run: pip install -r docs/requirements.txt + + - name: Build HTML docs + working-directory: docs + run: make html + + - name: Upload artifact (for inspection and Pages) + uses: actions/upload-pages-artifact@v3 + with: + path: docs/_build/html + + deploy: + needs: build + if: github.event_name != 'pull_request' && (github.ref == 'refs/heads/main') + runs-on: ubuntu-latest + permissions: + pages: write + id-token: write + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + steps: + - id: deployment + uses: actions/deploy-pages@v4 diff --git a/.gitignore b/.gitignore index 23ad31d..b83a2a5 100644 --- a/.gitignore +++ b/.gitignore @@ -4,6 +4,7 @@ __pycache__/ *.py[cod] *.so +.coverage # ───────────────────────────────────────── # Jupyter @@ -28,3 +29,7 @@ slurm* *.tmp *.swp *~ +# ───────────────────────────────────────── +# Documentation +# ───────────────────────────────────────── +docs/_build diff --git a/README.md b/README.md index 28bf6e9..8afefc5 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,31 @@ +

+drawing +

+ + + # CLPipe -Repository dedicated to the Cluster Working Group of the DESC-LSST collaboration. +[![Build and Check](https://github.com/LSSTDESC/CLPipe/actions/workflows/ci.yml/badge.svg)](https://github.com/LSSTDESC/CLPipe/actions/workflows/ci.yml) +[![Coverage Status](https://codecov.io/gh/LSSTDESC/CLPipe/branch/main/graph/badge.svg)](https://codecov.io/gh/LSSTDESC/CLPipe) +[![Documentation](https://github.com/LSSTDESC/CLPipe/actions/workflows/docs.yml/badge.svg)](https://lsstdesc.github.io/CLPipe/) + +CLPipe is the current implementation of the LSST DESC Cluster Pipeline, +developed by the Cluster Working Group of the LSST Dark Energy Science +Collaboration (DESC) to prepare cosmological analyses of galaxy clusters with +Rubin LSST data. This repository does not reimplement the analysis tools: it +runs the existing DESC tools together, in a single automated and reproducible +chain, from galaxy and cluster catalogs to cosmological parameter constraints. +TXPipe measures the cluster abundance and the stacked weak lensing profiles, +TJPCov computes the theoretical covariance of the cluster counts, and +Firecrown builds the likelihood, with theory predictions from CROW (built on +CCL and CLMM), which CosmoSIS then samples. + +The stages are connected with [ceci](https://github.com/LSSTDESC/ceci) through +their input and output files, so a stage can be replaced or extended without +changing the rest of the pipeline. The current version runs a binned analysis +of cluster counts and stacked weak lensing profiles, and has been validated on +mock data and on the cosmoDC2 redMaPPer cluster catalog. ## Installation @@ -19,7 +44,7 @@ Because some Python packages required for Firecrown are incompatible with those # IN2P3 conda activate /sps/lsst/groups/clusters/cl_pipeline_project/conda_envs/firecrown_clp -# NERSC +# NERSCstyle="display: block; margin: auto; " conda activate /global/cfs/projectdirs/lsst/groups/CL/cl_pipeline_project/conda_envs/firecrown_clp ``` @@ -92,7 +117,7 @@ Firecrown → inference inputs A separate job must be run to execute the final Firecrown inference — it is not launched automatically as part of the ceci pipeline. -> **Note:** due to missing components in TJPCov, the Firecrown stage +> **Note:** due to missing components in TJPCov, the CLPCovariance stage > currently performs additional computations to rescale the covariance > matrix. diff --git a/clpipe/clp_covariance.py b/clpipe/clp_covariance.py index c3570e0..ee17a48 100644 --- a/clpipe/clp_covariance.py +++ b/clpipe/clp_covariance.py @@ -42,7 +42,6 @@ class CLPCovariance(PipelineStage): "replace_tjpcov_cov": StageParameter(bool, True, msg="Replace TJPCov cluster-count covariance with CROW covariance."), # Selection function "sel_func": StageParameter(bool, True, msg="Include purity and completeness selection functions."), - "wazp_catalog": StageParameter(bool, False, msg="Use WaZP completeness parameters instead of Aguena+16 defaults (extra, non-default)."), "diagonal_shear_covariance": StageParameter( bool, True, msg=( @@ -255,7 +254,6 @@ def replace_crow_counts(self, config_dict, sacc_full, cov_terms, full_cov, cosmo # This function should not exist as it should be implemented in TJPCov. # This is temporary and so most of the options and configurations are fixed. - is_wazp = config_dict.get("wazp_catalog", False) sel_func = config_dict.get("sel_func", True) mor_params = config_dict["mor_parameters"] hmf = ccl.halos.MassFuncDespali16(mass_def="200c") @@ -274,12 +272,6 @@ def replace_crow_counts(self, config_dict, sacc_full, cov_terms, full_cov, cosmo cl_abundance = ClusterAbundance(cosmo, hmf) purity_aguena = None#purity_models.PurityAguena16LnProxy() completeness_aguena = completeness_models.CompletenessAguena16() - if is_wazp: - purity_aguena = None - completeness_aguena['a_n'] = 1.570597 - completeness_aguena['b_n'] = -0.028690 - completeness_aguena['a_logm_piv'] = 14.264386 - completeness_aguena['b_logm_piv'] = 0.029814 redshift_distribution = kernel.SpectroscopicRedshift() if not sel_func: completeness_aguena = None diff --git a/clpipe/clp_firecrown.py b/clpipe/clp_firecrown.py index edccffd..bcc1ea9 100644 --- a/clpipe/clp_firecrown.py +++ b/clpipe/clp_firecrown.py @@ -30,6 +30,7 @@ class CLPFirecrown(PipelineStage): """Firecrown pipeline stage for cluster cosmology analysis. This stage: + - Builds a Firecrown likelihood from a SACC file - Generates the corresponding CosmoSIS configuration - Writes parameter files for sampling, defaulting the cosmological @@ -38,6 +39,7 @@ class CLPFirecrown(PipelineStage): how a parameter gets sampled instead of held fixed Key configuration groups: + - Modeling options (hmf, mass range, redshift range) - Observable selection (cluster counts, shear) - Systematics (purity, completeness) @@ -92,10 +94,10 @@ class CLPFirecrown(PipelineStage): "emcee_walkers": StageParameter(int, 100, msg="Number of emcee walkers."), "emcee_samples": StageParameter(int, 20000, msg="Number of emcee samples."), "emcee_nsteps": StageParameter(int, 20, msg="Number of emcee steps per sample."), - "polycord_live_points": StageParameter(int, 500, msg="Number of PolyChord live points."), - "polycord_num_repeats": StageParameter(int, 30, msg="Number of PolyChord repeats."), - "polycord_tolerance": StageParameter(float, 0.05, msg="PolyChord evidence tolerance."), - "polycord_feedback": StageParameter(int, 1, msg="PolyChord feedback level."), + "polychord_live_points": StageParameter(int, 500, msg="Number of PolyChord live points."), + "polychord_num_repeats": StageParameter(int, 30, msg="Number of PolyChord repeats."), + "polychord_tolerance": StageParameter(float, 0.05, msg="PolyChord evidence tolerance."), + "polychord_feedback": StageParameter(int, 1, msg="PolyChord feedback level."), "resume": StageParameter(bool, False, msg="If True, CosmoSIS appends to the existing chain at `filename` instead of starting fresh"), # Cosmology -- tau is a CAMB input (reionization optical depth), not # a CCL cosmology parameter, so it isn't in the fiducial cosmology @@ -240,7 +242,10 @@ def generate_python_file(self, path_name): # Core CROW imports f.write("from crow import ClusterAbundance, ClusterShearProfile, kernel, mass_proxy\n") f.write("from crow.properties import ClusterProperty\n") - f.write("from crow.recipes.binned_grid import GridBinnedClusterRecipe\n\n") + if use_grid: + f.write("from crow.recipes.binned_grid import GridBinnedClusterRecipe\n\n") + else: + f.write("from crow.recipes.binned_exact import ExactBinnedClusterRecipe\n\n") f.write( "from crow import purity_models, completeness_models\n" ) @@ -411,10 +416,10 @@ def generate_ini_file(self, output_ini_path, likelihood_source_name, values_file emcee_samples = cfg["emcee_samples"] emcee_nsteps = cfg["emcee_nsteps"] - polycord_live_points = cfg["polycord_live_points"] - polycord_num_repeats = cfg["polycord_num_repeats"] - polycord_tolerance = cfg["polycord_tolerance"] - polycord_feedback = cfg["polycord_feedback"] + polychord_live_points = cfg["polychord_live_points"] + polychord_num_repeats = cfg["polychord_num_repeats"] + polychord_tolerance = cfg["polychord_tolerance"] + polychord_feedback = cfg["polychord_feedback"] beta_parameters = cfg["beta_parameters"] with open(output_ini_path, 'w') as f: @@ -478,10 +483,10 @@ def generate_ini_file(self, output_ini_path, likelihood_source_name, values_file f.write(f"nsteps = {emcee_nsteps}\n") f.write("[polychord]\n") - f.write(f"live_points = {polycord_live_points}\n") - f.write(f"num_repeats = {polycord_num_repeats}\n") - f.write(f"tolerance = {polycord_tolerance}\n") - f.write(f"feedback = {polycord_feedback}\n") + f.write(f"live_points = {polychord_live_points}\n") + f.write(f"num_repeats = {polychord_num_repeats}\n") + f.write(f"tolerance = {polychord_tolerance}\n") + f.write(f"feedback = {polychord_feedback}\n") print(f"INI file written to {output_ini_path}") return True diff --git a/clpipe/cluster_theory_pred.py b/clpipe/cluster_theory_pred.py index 104b18e..25136a5 100644 --- a/clpipe/cluster_theory_pred.py +++ b/clpipe/cluster_theory_pred.py @@ -159,6 +159,7 @@ def build_cluster_recipes_from_config(yml_file: str, sacc_file: str, set_params: Build cluster counts and (optionally) shear recipes from a YAML configuration and return theory/data vectors. This function: + - Loads configuration from `yml_file` (supports a top-level CLPFirecrown key). - Builds a pyccl halo mass function and pyccl Cosmology (via build_ccl_cosmology_from_config). - Constructs completeness/purity models if requested. diff --git a/coverage.xml b/coverage.xml new file mode 100644 index 0000000..07034f1 --- /dev/null +++ b/coverage.xml @@ -0,0 +1,952 @@ + + + + + + /home/jacquemier/Working_dir/LSST/CLPipe + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/Makefile b/docs/Makefile new file mode 100644 index 0000000..8015636 --- /dev/null +++ b/docs/Makefile @@ -0,0 +1,31 @@ +# Minimal makefile for Sphinx documentation +# + +# You can set these variables from the command line. +SPHINXOPTS = +SPHINXBUILD = sphinx-build +SPHINXPROJ = CLPipe +SOURCEDIR = . +BUILDDIR = _build +RM = rm -rf +MODULEDIR = ../clpipe + +# Put it first so that "make" without argument is like "make help". +help: + @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) + +.PHONY: help Makefile + +.PHONY: html +html: + @$(SPHINXBUILD) -M html "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -W + +.PHONY: clean +clean: + @$(RM) _build/* api/ api.rst compiled-examples/ + +# Catch-all target: route all unknown targets to Sphinx using the new +# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). +%: Makefile + @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) -W + diff --git a/docs/clp_covariance.txt b/docs/clp_covariance.txt index 97bf26d..57367cb 100644 --- a/docs/clp_covariance.txt +++ b/docs/clp_covariance.txt @@ -1,217 +1,346 @@ CLPCovariance Configuration Options =================================== -This document describes the configuration options available for the -CLPCovariance stage. This stage computes covariance matrices for cluster -observables using TJPCov and outputs an updated SACC file. +This document describes the configuration options of the CLPCovariance +stage. The stage computes the theoretical covariance of the cluster number +counts with TJPCov and writes it into an output SACC file. -------------------------------------------------- Overview -------------------------------------------------- -The CLPCovariance: +CLPCovariance runs the following steps: -- Reads an input SACC file (data vector) -- Computes covariance terms using TJPCov -- Writes a new SACC file with covariance -- Optionally merges existing covariance (for non-cluster observables) -- Optionally replaces cluster-count covariance with a custom CROW-based model +1. Read the input SACC file (data vector) and the fiducial cosmology. +2. Compute the covariance terms listed in cov_type with TJPCov. +3. If the input SACC file also contains other observables with a + covariance (e.g. cluster_delta_sigma), copy those blocks into the new + covariance. +4. If replace_tjpcov_cov is True, replace the cluster-count block with a + CROW-based covariance. +5. Write a single output SACC file with the final covariance. + +Inputs and outputs: + + clusters_sacc_file (input) SACC data vector, from TXPipe + fiducial_cosmology (input) Fiducial cosmology, shared with TXPipe + clusters_sacc_file_cov (output) SACC file with the final covariance + +The cosmology is always read from the fiducial_cosmology input. It is not +set in the stage configuration. + +Input SACC file: + +The cluster_counts data points must each have three tracers, in this order: + +- survey: survey tracer, with sky_area in deg^2 +- bin_richness: richness bin, with lower/upper edges in log10(richness) +- bin_z: redshift bin, with lower/upper edges -------------------------------------------------- -Core Options +Covariance Model -------------------------------------------------- -use_mpi (bool, default: False) - Enable MPI parallelization in TJPCov. - Must be consistent with the execution environment. +The cluster-count covariance is the sum of a Poisson shot-noise term and a +super-sample covariance (SSC) term (Lacasa et al. 2018): -do_xi (bool, default: False) - Whether to compute real-space correlation functions (xi). - Typically False for cluster-count analyses. +```math +[\mathrm{Cov}_N]_{ijkl} = \delta^K_{ik} \, \delta^K_{jl} \, N_{ij} + [\mathrm{Cov}_{\rm SSC}]_{ijkl} -cov_type (list of str) - List of covariance terms to compute. +[\mathrm{Cov}_{\rm SSC}]_{ijkl} = N_{ij} \, N_{kl} \, \langle b \rangle_{ij} \, \langle b \rangle_{kl} \, S_{ik} +``` - Supported values include: - - ClusterCountsGaussian - - ClusterCountsSSC - - ClusterMass (optional, not always used) +where i, k run over redshift bins and j, l over richness bins: - Example: - cov_type: [ClusterCountsGaussian, ClusterCountsSSC] +- N_ij: predicted number of clusters in bin (i, j) +- _ij: halo bias averaged over the clusters in bin (i, j) + (model set by halo_bias) +- S_ik: covariance of the matter density contrast, smoothed by the survey + window, between redshift bins i and k (partial-sky window computed from + the survey area) + +The SSC term scales as N^2, while the shot noise scales as N, so SSC +becomes important for large cluster samples such as LSST (Fumagalli et al. +2021). + +TJPCov computes the shot-noise term (ClusterCountsGaussian) and the SSC +term (ClusterCountsSSC) separately. Both use the halo model, mass–richness +relation and photo-z model set by mor_parameters and photo-z below. -------------------------------------------------- -Cosmology Options +TJPCov Options -------------------------------------------------- -cosmo (str) - Defines how cosmology is provided. +use_mpi (bool, default: False) + Enable MPI parallelization in TJPCov. + Must be consistent with the execution environment. - Options: - - "set": use parameters from config - - (future) external cosmology object or file +do_xi (bool, default: False) + Compute real-space correlation function (xi) terms. + Typically False for cluster-count analyses. -parameters (dict) - Cosmological parameters passed to CCL. +cov_type (list of str, default: [ClusterCountsGaussian, ClusterCountsSSC]) + Covariance terms to compute. Supported values: - Required fields: - Omega_c - Omega_b - h - n_s - sigma8 - w0 - wa - transfer_function + - ClusterCountsGaussian: Poisson shot-noise term (diagonal) + - ClusterCountsSSC: super-sample covariance term + - ClusterMass (optional, not always used) Example: - Omega_c: 0.22 - Omega_b: 0.0448 - h: 0.71 - n_s: 0.963 - sigma8: 0.8 -Note: - These parameters are currently only used in the custom covariance - replacement step (replace_crow_counts), not directly by TJPCov. + ```yaml + cov_type: [ClusterCountsGaussian, ClusterCountsSSC] + ``` -------------------------------------------------- Photo-z Options -------------------------------------------------- -photo-z (dict) +photo-z (dict, required by TJPCov) + Photometric redshift model used by TJPCov. The observed redshift is + Gaussian around the true redshift (truncated at z_phot > 0), with a + scatter that grows with redshift: - sigma_0 (float) - Photometric redshift uncertainty parameter. + ```math + \sigma_z(z) = \sigma_0 \, (1 + z) + ``` + + - sigma_0 (float): photo-z scatter parameter, e.g. 0.05 + + The CROW replacement does not use it: it assumes exact (spectroscopic) + redshifts. Example: + + ```yaml + photo-z: sigma_0: 0.05 + ``` -------------------------------------------------- Mass–Observable Relation (MOR) Options -------------------------------------------------- -mor_parameters (dict) +mor_parameters (dict, required by TJPCov) + Halo model and mass–richness relation. + + Halo model (used by TJPCov only): + + - mass_func (str): halo mass function, e.g. "Despali16". + Supported: Angulo12, Bocquet16, Bocquet20, Despali16, Jenkins01, + Nishimichi19, Press74, Sheth99, Tinker08, Tinker10, Watson13 + - mass_def (str): mass definition, e.g. "200c" + - halo_bias (str): halo bias model, used for in the SSC term, + e.g. "Tinker10". + Supported: Bhattacharya11, Sheth01, Sheth99, Tinker10 - Defines the halo mass function and richness–mass relation. + Mass range (used by TJPCov and CROW): - Halo model: - mass_func (str) : e.g. "Despali16" - mass_def (str) : e.g. "200c" - halo_bias (str) : e.g. "Tinker10" + - min_halo_mass (float): lower mass limit in M_sun, e.g. 1.0e12 + - max_halo_mass (float): upper mass limit in M_sun, e.g. 3.16e15 - Mass range: - min_halo_mass (float) - max_halo_mass (float) + These are linear masses, not log10. - Pivot values: - m_pivot (float) - z_pivot (float) + Mass–richness relation (used by TJPCov and CROW): - Richness–mass relation parameters: - mu_p0, mu_p1, mu_p2 - sigma_p0, sigma_p1, sigma_p2 + The richness follows the Murata et al. (2019) model. At fixed mass and + redshift, ln(richness) is Gaussian. Its mean and its scatter are each + linear in ln(M) and ln(1+z), with 3 parameters each: - These control the mapping between halo mass and observable richness. + ```math + P(\ln\lambda \mid M, z) = \frac{1}{\sqrt{2\pi} \, \sigma_{\ln\lambda}} \exp\left[ -\frac{(\ln\lambda - \mu_{\ln\lambda})^2}{2 \sigma_{\ln\lambda}^2} \right] + + \mu_{\ln\lambda}(M, z) = \mu_0 + \mu_m \ln\frac{M}{M_{\rm piv}} + \mu_z \ln\frac{1+z}{1+z_{\rm piv}} + + \sigma_{\ln\lambda}(M, z) = \sigma_0 + \sigma_m \ln\frac{M}{M_{\rm piv}} + \sigma_z \ln\frac{1+z}{1+z_{\rm piv}} + ``` + + - m_pivot (float): pivot mass, log10(M_piv / M_sun), e.g. 14.3 + - z_pivot (float): pivot redshift z_piv, e.g. 0.5 + - mu_p0, mu_p1, mu_p2 (float): mean parameters mu_0, mu_m, mu_z + - sigma_p0, sigma_p1, sigma_p2 (float): scatter parameters + sigma_0, sigma_m, sigma_z -------------------------------------------------- Pipeline-Specific Options -------------------------------------------------- replace_tjpcov_cov (bool, default: True) - If True, replaces the TJPCov cluster-count covariance with a - custom covariance computed using CROW. + Replace the TJPCov cluster-count covariance with a covariance computed + with CROW (see "Custom Covariance Replacement" below): + + - Diagonal terms are recomputed from CROW theory predictions. + - SSC and Gaussian contributions are combined. + + WARNING: this is a temporary workaround. It should eventually be + handled directly inside TJPCov. + +sel_func (bool, default: True) + Only used when replace_tjpcov_cov is True. + + If True, the CROW counts are weighted by the Aguena & Lima (2018) + completeness model: - This includes: - - Recomputing diagonal terms using theory predictions - - Combining SSC and Gaussian contributions + ```math + c(M, z) = \frac{\left(M / M_0(z)\right)^{n_c(z)}}{1 + \left(M / M_0(z)\right)^{n_c(z)}} - WARNING: - This is a temporary workaround and should ideally be handled - directly inside TJPCov. + n_c(z) = a_n + b_n \, (1 + z), \qquad \log_{10} M_0(z) = a_{\rm piv} + b_{\rm piv} \, (1 + z) + ``` -wazp_catalog (bool, default: False) - Special handling for WaZP catalogs: - - Disables purity model - - Modifies completeness parameters + The completeness parameters are fixed to the CROW defaults, which are + the cosmoDC2 redMaPPer values (a_n = 1.1321, b_n = 0.7751, + a_piv = a_logm_piv = 13.31, b_piv = b_logm_piv = 0.2025). They cannot + be set from the configuration. + + If False, no selection function is applied (c = 1). + The purity model is currently disabled in the code. + +diagonal_shear_covariance (bool, default: True) + Only used when the input SACC file contains other observables with a + covariance (e.g. cluster_delta_sigma). + If True, only the diagonal (per-bin variance) of those blocks is kept. + If False, the full blocks are copied. -------------------------------------------------- Internal Behavior -------------------------------------------------- 1. Covariance Computation ------------------------- +------------------------- -TJPCov computes covariance terms based on cov_type and writes: +TJPCov computes the terms listed in cov_type and writes: clusters_sacc_file_cov.sacc -Additional intermediate files may include: - - clusters_sacc_file_cov_SSC.sacc - - clusters_sacc_file_cov_gauss.sacc +Intermediate files with the individual terms may also be written: + + clusters_sacc_file_cov_SSC.sacc + clusters_sacc_file_cov_gauss.sacc 2. Mixed Data Handling ---------------------- +---------------------- -If the input SACC file contains multiple observables: +If the input SACC file contains other observables besides cluster counts +and already has a covariance: - - Cluster counts covariance is recomputed - - Other covariance blocks (e.g. lensing) are preserved +- The cluster-count covariance is recomputed. +- The other covariance blocks (e.g. lensing) are copied from the input + file, diagonal-only or in full (see diagonal_shear_covariance). -This is handled by: - extract_data_covariance() +This is handled by merge_data_covariance(). 3. Custom Covariance Replacement -------------------------------- -If replace_tjpcov_cov = True: +If replace_tjpcov_cov is True, the cluster-count block is rebuilt with +CROW. For each cluster-count data point a (one richness-redshift bin), +CROW predicts the counts + +```math +\begin{aligned} +N_a = {} & \Omega_S \int_{z_a} dz \int_{\lambda_a} d\ln\lambda \int_{M_{\min}}^{M_{\max}} dM \\ +& \times \frac{d^2V}{dz \, d\Omega} \, \frac{dn}{dM}(M, z) \, P(\ln\lambda \mid M, z) \, c(M, z) +\end{aligned} +``` + +where Omega_S is the survey area in steradians (from the SACC survey +tracer), dn/dM is the Despali16 mass function, and c(M, z) is the +completeness (see sel_func). + +The covariance is then - - The covariance is recomputed using CROW - - Theory predictions for counts are evaluated - - Covariance elements are replaced using: +```math +C_{aa} = N_a + \mathrm{SSC}_{aa} \left( \frac{N_a}{N^{\rm TJPCov}_a} \right)^2 - C_ii = N_theory + SSC * (N_theory^2 / N_gauss^2) - C_ij = SSC_ij * (N_i * N_j) / (N_gauss_i * N_gauss_j) +C_{ab} = \mathrm{SSC}_{ab} \, \frac{N_a \, N_b}{N^{\rm TJPCov}_a \, N^{\rm TJPCov}_b}, \qquad a \neq b +``` - This modifies only the cluster-count block. +where: + +- N_a: CROW theory counts for data point a +- N^TJPCov_a: TJPCov Gaussian (shot-noise) term for data point a, i.e. the + counts predicted by TJPCov +- SSC_ab: TJPCov super-sample covariance term + +The CROW counts are used as the Poisson term on the diagonal. The SSC term +scales as N_a N_b, so it is rescaled from the TJPCov counts to the CROW +counts. Only the cluster-count block is modified. -------------------------------------------------- Known Limitations -------------------------------------------------- -- replace_crow_counts() is a temporary workaround and should not exist - long-term (should be implemented in TJPCov directly). +- replace_crow_counts() is a temporary workaround. It should be removed + once this is implemented in TJPCov. + +- The cosmology is passed to TJPCov both as a CCL object and as a + parameter dictionary. This duplication comes from TJPCov and should be + fixed there. + +- Hardcoded choices in the CROW replacement: + - Mass function: Despali16 (200c), whatever mass_func and mass_def are + - Redshifts: spectroscopic (photo-z sigma_0 is not used) + - Completeness parameters: CROW defaults + - Purity model: disabled + - Grid sizes: mass 80, redshift 40, proxy 40 + - Recipe: GridBinnedClusterRecipe -- Some configuration options (e.g. cosmology) are duplicated and not - consistently used across all steps. +- The covariance is computed once, at the fiducial cosmology and MOR + parameters, and held fixed during inference. -- Hardcoded choices exist: - - Mass function (Despali16) - - Grid sizes - - Recipe type (GridBinnedClusterRecipe) +- The input configuration is not validated. + +-------------------------------------------------- +Pipeline Configuration +-------------------------------------------------- -- No validation is performed on input configuration. +The stage is wired into a ceci pipeline file. This example comes from +examples/cosmodc2_redmapper/baseline/cosmodc2_redmapper_full_analysis/run_in2p3_both/TJPCov.yml: + +```yaml +id: TJPCov +modules: clpipe +launcher: + name: mini + interval: 0.5 +site: + name: local + max_threads: 4 +stages: + - name: CLPCovariance + module_name: clpipe.clp_covariance + nprocess: 1 +inputs: + fiducial_cosmology: /sps/lsst/groups/clusters/cl_pipeline_project/TXPipe_data/cosmodc2/fiducial_cosmology.yml + clusters_sacc_file: /sps/lsst/groups/clusters/cl_pipeline_project/TXPipe_data/cosmodc2/outputs-full-2026//cluster_sacc_catalog.sacc +config: ./config_in2p3_both.yml +resume: false +output_dir: ./outputs_both +log_dir: ./logs_both +``` + +Run it with: + +```bash +ceci TJPCov.yml +``` + +The stage options below go in the stage config file (config: above), +under a CLPCovariance block. -------------------------------------------------- Example Configuration -------------------------------------------------- +```yaml CLPCovariance: use_mpi: False do_xi: False cov_type: [ClusterCountsGaussian, ClusterCountsSSC] - cosmo: 'set' - - parameters: - Omega_c: 0.22 - Omega_b: 0.0448 - h: 0.71 - n_s: 0.963 - sigma8: 0.8 - w0: -1 - wa: 0 - transfer_function: 'boltzmann_camb' + replace_tjpcov_cov: True + sel_func: True + diagonal_shear_covariance: True photo-z: sigma_0: 0.05 @@ -232,9 +361,29 @@ CLPCovariance: sigma_p0: 0.5623 sigma_p1: 0.0455 sigma_p2: -0.0445 +``` -------------------------------------------------- Notes: -- Additional TJPCov parameters can be added depending on the covariance model. -- Ensure consistency between SACC input data and MOR configuration. \ No newline at end of file + +- Additional TJPCov parameters can be added depending on the covariance + model. They are passed through to TJPCov. +- Make sure the SACC input data and the MOR configuration are consistent. + +-------------------------------------------------- +References +-------------------------------------------------- + +- Murata et al. (2019), mass–richness relation: + https://doi.org/10.1093/pasj/psz092 (arXiv:1904.07524) +- Lacasa, Lima & Aguena (2018), super-sample covariance: + https://arxiv.org/abs/1612.05958 +- Fumagalli et al. (2021), impact of sample covariance on cluster counts: + https://arxiv.org/abs/2102.08914 +- Aguena & Lima (2018), completeness and purity: + https://arxiv.org/abs/1611.05468 +- Despali et al. (2016), halo mass function: + https://arxiv.org/abs/1507.05627 +- Tinker et al. (2010), halo bias: + https://arxiv.org/abs/1001.3162 diff --git a/docs/clp_firecrown.txt b/docs/clp_firecrown.txt index 9943756..133b057 100644 --- a/docs/clp_firecrown.txt +++ b/docs/clp_firecrown.txt @@ -1,236 +1,505 @@ CLPFirecrown Configuration Options -====================================== +================================== -This document describes the configuration options available for the -CLPFirecrown stage. These options control the construction of the -Firecrown likelihood, the cluster modeling assumptions, and the sampling -configuration. +This document describes the configuration options of the CLPFirecrown +stage. The stage prepares a cluster cosmology inference with Firecrown and +CosmoSIS: it writes the Firecrown likelihood and the CosmoSIS configuration +files. It does not run the sampler. Sampling is a separate CosmoSIS run +(see "Running the Inference"). -------------------------------------------------- -General Options +Overview -------------------------------------------------- -hmf (str, default: "bocquet16") - Halo Mass Function used in the analysis. - Supported values: - - angulo12 - - bocquet16 - - bocquet20 - - despali16 - - jenkins01 - - press74 - - sheth99 - - tinker08 - - tinker10 - - watson13 +CLPFirecrown runs the following steps: -mass_def (str, default: "200c") - Mass definition used in the halo mass function (e.g. "200c", "500c"). +1. Read the SACC file with covariance (from CLPCovariance) and the fiducial + cosmology. +2. Write the Firecrown likelihood file. It builds CROW recipes for the + cluster counts and/or the stacked shear profile, from the modeling + options below. +3. Write the CosmoSIS pipeline file: consistency, CAMB and the Firecrown + likelihood modules, plus the sampler settings. +4. Write the CosmoSIS values file: cosmological and Firecrown parameters, + with their priors. + +Inputs and outputs: + + clusters_sacc_file_cov (input) SACC data vector with covariance, from CLPCovariance + fiducial_cosmology (input) Fiducial cosmology, shared with TXPipe and CLPCovariance + sampler_file (output) CosmoSIS pipeline file (sampler_file.ini) + likelihood_file (output) Firecrown likelihood (likelihood_file.py) + priors_file (output) CosmoSIS values file with priors (priors_file.ini) + +-------------------------------------------------- +Theory Model +-------------------------------------------------- + +The predictions are computed with CROW. For a redshift bin i and a richness +bin j, the number counts and the stacked lensing profile are + +```math +\begin{aligned} +N_{ij} = {} & \Omega_S \int_{z_i}^{z_{i+1}} dz \int_{\ln\lambda_j}^{\ln\lambda_{j+1}} d\ln\lambda \int_{M_{\min}}^{M_{\max}} dM \\ +& \times \frac{d^2V}{dz \, d\Omega} \, \frac{dn}{dM}(M, z) \, P(\ln\lambda \mid M, z) \, \Phi(M, \lambda, z) +\end{aligned} + +\begin{aligned} +\Theta_{ij}(R) = {} & \frac{\Omega_S}{N_{ij}} \int_{z_i}^{z_{i+1}} dz \int_{\ln\lambda_j}^{\ln\lambda_{j+1}} d\ln\lambda \int_{M_{\min}}^{M_{\max}} dM \\ +& \times \frac{d^2V}{dz \, d\Omega} \, \frac{dn}{dM}(M, z) \, P(\ln\lambda \mid M, z) \, \Phi(M, \lambda, z) \, \Theta(R \mid M) +\end{aligned} +``` + +where: + +- Omega_S: survey area in steradians, from the SACC file +- dn/dM: halo mass function (hmf, mass_def) +- P(ln lambda | M, z): mass–richness relation (see below) +- Phi = c(M, z) / p(lambda, z): selection function, from the completeness + c and the purity p (see below). Each is 1 when disabled. +- Theta(R | M): lensing profile of a halo of mass M, either the excess + surface density DeltaSigma or the reduced tangential shear g_t + +1. Mass–richness relation +------------------------- + +The richness follows the Murata et al. (2019) model. At fixed mass and +redshift, ln(richness) is Gaussian. Its mean and its scatter are each +linear in ln(M) and ln(1+z), with 3 parameters each: + +```math +P(\ln\lambda \mid M, z) = \frac{1}{\sqrt{2\pi} \, \sigma_{\ln\lambda}} \exp\left[ -\frac{(\ln\lambda - \mu_{\ln\lambda})^2}{2 \sigma_{\ln\lambda}^2} \right] + +\mu_{\ln\lambda}(M, z) = \mu_0 + \mu_m \ln\frac{M}{M_{\rm piv}} + \mu_z \ln\frac{1+z}{1+z_{\rm piv}} + +\sigma_{\ln\lambda}(M, z) = \sigma_0 + \sigma_m \ln\frac{M}{M_{\rm piv}} + \sigma_z \ln\frac{1+z}{1+z_{\rm piv}} +``` + +The pivots are set by pivot_mass and pivot_z. The 6 parameters are Firecrown +parameters (see "Firecrown Parameters"). + +2. Completeness +--------------- + +With use_completeness, the Aguena & Lima (2018) completeness model: + +```math +c(M, z) = \frac{\left(M / M_0(z)\right)^{n_c(z)}}{1 + \left(M / M_0(z)\right)^{n_c(z)}} + +n_c(z) = a_n + b_n \, (1 + z), \qquad \log_{10} M_0(z) = a_{\rm piv} + b_{\rm piv} \, (1 + z) +``` + +3. Purity +--------- + +With use_purity, the Aguena & Lima (2018) purity model, written in ln(richness): -min_mass, max_mass (float) - Log10 mass range of clusters used in the analysis. +```math +p(\lambda, z) = \frac{\left(\ln\lambda / \ln\lambda_0(z)\right)^{n_p(z)}}{1 + \left(\ln\lambda / \ln\lambda_0(z)\right)^{n_p(z)}} -min_z, max_z (float) - Redshift range of clusters. +n_p(z) = a_n + b_n \, (1 + z), \qquad \ln\lambda_0(z) = a_{\rm piv} + b_{\rm piv} \, (1 + z) +``` -pivot_mass (float) - Pivot log10 mass used in the mass–observable relation. +4. Lensing profile +------------------ -pivot_z (float) - Pivot redshift used in the mass–observable relation. +Theta(R | M) is computed with CLMM from an NFW profile (one-halo term). The +concentration is the Firecrown parameter cluster_theory_cluster_concentration. +A value below 1 uses the Bhattacharya et al. (2013) mass–concentration +relation instead. The two-halo term and the boost-factor correction can be +added (two_halo_term, boost_factor). -survey_name (str) - Name of the survey used to match SACC data. +For the reduced shear g_t, the lensing efficiency is averaged over the +source redshift distribution (beta_parameters, use_beta_interp). + +5. Likelihood +------------- + +The likelihood is a Gaussian (Firecrown ConstGaussian) over all the selected +statistics: + +- BinnedClusterNumberCounts: counts N_ij (and optionally the mean log mass) +- BinnedClusterShearProfile: stacked DeltaSigma or g_t profiles + +The covariance is read from the SACC file and held fixed during sampling. -------------------------------------------------- Modeling Options -------------------------------------------------- +hmf (str, default: "despali16") + Halo mass function (case-insensitive). Supported values: + + - angulo12 + - bocquet16 + - bocquet20 + - despali16 + - jenkins01 + - press74 + - sheth99 + - tinker08 + - tinker10 + - watson13 + +mass_def (str, default: "200c") + Mass definition used by the halo mass function (e.g. "200c", "500c"). + +min_mass, max_mass (float, default: 12.0, 15.5) + Halo mass integration range, in log10(M / M_sun). + Note: CLPCovariance uses linear masses for the same range. + +min_z, max_z (float, default: 0.2, 0.8) + True redshift integration range. + +pivot_mass (float, default: 14.3) + Pivot mass of the mass–richness relation, log10(M_piv / M_sun). + +pivot_z (float, default: 0.5) + Pivot redshift of the mass–richness relation. + +survey_name (str, default: "cosmodc2_redmapper") + Survey tracer name in the SACC file. Must match it. + +-------------------------------------------------- +Observable Options +-------------------------------------------------- + use_cluster_counts (bool, default: True) - Include cluster number counts in the likelihood. + Include the cluster number counts in the likelihood. use_shear_profile (bool, default: False) - Include cluster shear (or DeltaSigma) profile in the likelihood. + Include the stacked shear profiles in the likelihood. -use_mean_log_mass (bool) - Include mean log-mass observable in the likelihood averaging. +is_deltasigma (bool, default: False) + Theory side: predict DeltaSigma (True) or the reduced shear g_t (False). -use_mean_deltasigma (bool) - Use DeltaSigma instead of reduced shear. +use_mean_deltasigma (bool, default: False) + Data side: read DeltaSigma (True) or the reduced shear g_t (False) from + the SACC file. Set it to the same value as is_deltasigma. -is_deltasigma (bool, default: False) - Controls whether the shear observable is DeltaSigma. +use_mean_log_mass (bool, default: False) + Also use the mean log mass per bin, read from the SACC file. -------------------------------------------------- -Systematics and Corrections +Selection Function Options -------------------------------------------------- -use_completeness (bool or None) - If True, applies a completeness model (Aguena16). - If False or None, no completeness correction is applied. +use_completeness (bool, default: True) + Apply the completeness model c(M, z) (see "Theory Model"). -use_purity (bool or None) - If True, applies a purity model (Aguena16). - If False or None, no purity correction is applied. +use_purity (bool, default: True) + Apply the purity model p(lambda, z) (see "Theory Model"). -cluster_concentration (float or None) - Fixed cluster concentration parameter. - If None, default modeling assumptions are used. +-------------------------------------------------- +Lensing Options +-------------------------------------------------- + +Only used when use_shear_profile is True. two_halo_term (bool, default: False) - Include the two-halo term in the shear model. + Add the two-halo term to the lensing profile. boost_factor (bool, default: False) - Include boost factor corrections in shear modeling. + Apply the boost-factor correction to the lensing profile. + +set_concentration (bool) + Reserved for future use. The stage does not read it yet, so it + currently has no effect. The concentration is set with + cluster_theory_cluster_concentration in firecrown_parameters. + +use_beta_interp (bool, default: False) + Interpolate the mean lensing efficiency in redshift. + Only used for the reduced shear (is_deltasigma: False). + +beta_parameters (list of float, default: [10.0, 5.0]) + Parameters of the mean lensing efficiency , passed to CROW as + [z_inf, zmax]: the redshift taken as infinity, and the maximum source + redshift. Only used for the reduced shear (is_deltasigma: False). + + The first value (z_inf, 10 by default) is also always used as the + maximum redshift of CAMB (zmax in the [camb] section of + sampler_file.ini), even without shear profiles. -------------------------------------------------- -Grid and Interpolation Options +Integration Options -------------------------------------------------- use_grid (bool, default: True) - If True, uses GridBinnedClusterRecipe. - If False, uses ExactBinnedClusterRecipe. + If True, use GridBinnedClusterRecipe: integrals on precomputed grids, + about 100 times faster, recommended for inference. + If False, use ExactBinnedClusterRecipe (direct integration with + NumCosmo), slower, useful to validate the grid results. redshift_grid_size (int, default: 20) - Number of bins in redshift grid. + Number of redshift grid points. mass_grid_size (int, default: 60) - Number of bins in mass grid. + Number of mass grid points. proxy_grid_size (int, default: 20) - Number of bins in observable (richness) grid. - -use_beta_interp (bool, default: False) - Enables interpolation of beta_s in shear calculations. - -beta_parameters (list[float], default: [10.0, 5.0]) - Parameters controlling the beta function in shear modeling. + Number of richness grid points. -use_poisson_noise (bool, default: False) - Adds Poisson noise to the mass–observable relation. +The grid sizes are only used when use_grid is True. -------------------------------------------------- Sampler Options -------------------------------------------------- -sampler (str, default: "test") - Sampler used by CosmoSIS. - Supported examples: - - test - - emcee - - polychord - - metropolis +sampler (str, default: "emcee") + CosmoSIS sampler. Supported values: -emcee_walkers (int) - Number of walkers for emcee sampler. + - test: a single likelihood evaluation, useful to check the setup + - metropolis + - emcee + - polychord -emcee_samples (int) - Total number of samples for emcee. +emcee_walkers (int, default: 100) + Number of emcee walkers. -emcee_nsteps (int) - Number of steps per iteration for emcee. +emcee_samples (int, default: 20000) + Number of emcee samples per walker. -polychord_live_points (int) - Number of live points for Polychord. +emcee_nsteps (int, default: 20) + Number of emcee steps between chain outputs. -polychord_num_repeats (int) - Number of slice sampling repeats. +polychord_live_points (int, default: 500) + Number of PolyChord live points. -polychord_tolerance (float) - Evidence tolerance for stopping criterion. +polychord_num_repeats (int, default: 30) + Number of PolyChord slice-sampling repeats. -polychord_feedback (int) - Verbosity level for Polychord. +polychord_tolerance (float, default: 0.05) + PolyChord evidence tolerance (stopping criterion). + +polychord_feedback (int, default: 1) + PolyChord verbosity level. + +The polychord_* options fill the [polychord] section of sampler_file.ini +(see https://cosmosis.readthedocs.io/en/latest/reference/samplers/polychord.html). + +resume (bool, default: False) + If True, CosmoSIS appends to the existing chain instead of starting a + new one. + +filename (str, optional, default: "output_rp/number_counts_samples.txt") + Path of the output chain file. -------------------------------------------------- Cosmological Parameters -------------------------------------------------- -cosmological_parameters (dict) - Dictionary defining cosmological parameters. +tau (float, default: 0.08) + Optical depth to reionization. It is a CAMB input, not part of the + fiducial cosmology file, so it is set here. + +cosmological_parameters (dict, default: {}) + Overrides on top of the fiducial cosmology. By default, every + cosmological parameter is fixed to its value in fiducial_cosmology. + List a parameter here to sample it. + + Parameter names (CosmoSIS naming): - Format: - parameter_name: - sample: True/False - values: [min, fiducial, max] (if sampled) - or scalar value (if fixed) + omega_c, omega_b, h0, n_s, sigma_8, omega_k, w, wa, tau + + A fixed entry (sample: False) must have the fiducial value, otherwise + the stage fails. To change the fiducial cosmology, edit the + fiducial_cosmology file instead, so that all stages use it. Example: - omega_c: - sample: True - values: [0.1552, 0.2052, 0.3552] + + ```yaml + cosmological_parameters: + omega_c: {'sample': True, 'values': [0.10, 0.22, 0.5]} + sigma_8: {'sample': True, 'values': [0.5, 0.800, 1.1]} + ``` + +-------------------------------------------------- +Firecrown Parameters +-------------------------------------------------- + +firecrown_parameters (dict, default: {}) + Parameters of the CROW models, written to the [firecrown_number_counts] + section of the values file. Set all the parameters of the models you + enable, fixed or sampled. + + Mass–richness relation: + + - mass_distribution_mu0, mass_distribution_mu1, mass_distribution_mu2: + mu_0, mu_m, mu_z + - mass_distribution_sigma0, mass_distribution_sigma1, + mass_distribution_sigma2: sigma_0, sigma_m, sigma_z + + Completeness (use_completeness): + + - completeness_a_n, completeness_b_n: a_n, b_n + - completeness_a_logm_piv, completeness_b_logm_piv: a_piv, b_piv + - CROW defaults (cosmoDC2 redMaPPer): 1.1321, 0.7751, 13.31, 0.2025 + + Purity (use_purity): + + - purity_a_n, purity_b_n: a_n, b_n + - purity_a_logm_piv, purity_b_logm_piv: a_piv, b_piv + - CROW defaults (cosmoDC2 redMaPPer): 1.9830, 0.8121, 2.2183, -0.6592 + + Lensing profile (use_shear_profile): + + - cluster_theory_cluster_concentration: halo concentration + (below 1: Bhattacharya et al. 2013 relation) -------------------------------------------------- -Firecrown Likelihood Parameters +Parameter Format -------------------------------------------------- -firecrown_parameters (dict) - Parameters controlling the cluster mass–observable relation and systematics. +Entries in cosmological_parameters and firecrown_parameters use the same +format: - Same format as cosmological parameters: - sample: True/False - values: [min, fiducial, max] or scalar +```yaml +# Sampled, with a flat prior between min and max: +name: {'sample': True, 'values': [min, start, max]} - Typical parameters include: - - mass_distribution_mu* - - mass_distribution_sigma* - - completeness_* - - purity_* - - cluster_theory_cluster_concentration +# Fixed: +name: {'sample': False, 'values': value} +``` + +-------------------------------------------------- +Pipeline Configuration +-------------------------------------------------- - Additional parameters can be added freely as long as they are - recognized by the Firecrown likelihood. +The stage is wired into a ceci pipeline file. This example comes from +examples/cosmodc2_redmapper/baseline/cosmodc2_redmapper_full_analysis/run_in2p3_both/Firecrown.yml: + +```yaml +id: Firecrown +modules: clpipe +launcher: + name: mini + interval: 0.5 +site: + name: local + max_threads: 4 +stages: + - name: CLPFirecrown + module_name: clpipe.clp_firecrown + nprocess: 1 +inputs: + fiducial_cosmology: /sps/lsst/groups/clusters/cl_pipeline_project/TXPipe_data/cosmodc2/fiducial_cosmology.yml + clusters_sacc_file_cov: ./outputs_both/clusters_sacc_file_cov.sacc +config: ./config_in2p3_both.yml +resume: false +output_dir: ./outputs_both +log_dir: ./logs_both +``` + +The stage options go in the stage config file (config: above), under a +CLPFirecrown block. -------------------------------------------------- -Notes and Caveats +Running the Inference -------------------------------------------------- -- If both use_cluster_counts and use_shear_profile are True, - the likelihood combines both observables. +Generate the files with ceci, then run CosmoSIS from the output directory: -- If only one is enabled, only that observable is used. +```bash +ceci Firecrown.yml + +cd ./outputs_both +cosmosis sampler_file.ini + +# or, with MPI: +mpirun -n 30 cosmosis --mpi sampler_file.ini +``` + +The generated files refer to each other, and to the SACC file, by file +name only. Run CosmoSIS from the output directory, with the SACC file in +it (this is the case when CLPCovariance writes to the same output +directory). CosmoSIS also needs the CSL_DIR environment variable (see the +installation instructions in the README). + +-------------------------------------------------- +Known Limitations +-------------------------------------------------- -- Purity can be forcibly disabled internally when using shear-only - configurations. +- The test and metropolis sampler settings are fixed in the generated + file (metropolis: 1000 samples). -- The SACC file provided as input must match the survey_name. +- The covariance is held fixed during sampling. -- Grid-based recipes are recommended for performance unless exact - integration is required. +- Only the binned likelihood is supported. -- Some parameters (e.g. cluster_concentration) are passed directly - to the underlying modeling code and are not validated here. +- The names in firecrown_parameters are not validated by the stage. -------------------------------------------------- Example Configuration -------------------------------------------------- +This is the CLPFirecrown block of the baseline cosmoDC2 redMaPPer analysis +(counts + stacked DeltaSigma): + +```yaml CLPFirecrown: hmf: 'despali16' + mass_def: '200c' min_mass: 12.0 max_mass: 15.5 min_z: 0.2 max_z: 0.8 - mass_def: '200c' - use_shear_profile: True - use_completeness: True - use_purity: True - use_grid: True - is_deltasigma: True - use_beta_interp: False - beta_parameters: [10.0, 5.0] pivot_mass: 14.3 pivot_z: 0.5 survey_name: 'cosmodc2_redmapper' + + use_cluster_counts: true + use_shear_profile: true + is_deltasigma: true + use_mean_deltasigma: true + use_mean_log_mass: false + + use_completeness: true + use_purity: false + + use_grid: true + use_beta_interp: false + beta_parameters: [10.0, 5.0] + sampler: 'emcee' - use_cluster_counts: True - use_mean_log_mass: False - use_mean_deltasigma: True - emcee_walkers: 50 - emcee_samples: 20000 + emcee_walkers: 100 + emcee_samples: 50000 emcee_nsteps: 20 + cosmological_parameters: + omega_c: {'sample': true, 'values': [0.10, 0.22, 0.5]} + sigma_8: {'sample': true, 'values': [0.5, 0.800, 1.1]} + + firecrown_parameters: + mass_distribution_mu0: {'sample': true, 'values': [2.0, 3.3439, 10.0]} + mass_distribution_mu1: {'sample': true, 'values': [0.5, 0.958236982, 2.0]} + mass_distribution_mu2: {'sample': true, 'values': [-2.0, -0.0192802, 2.0]} + mass_distribution_sigma0: {'sample': true, 'values': [0.1, 0.562317194, 2.0]} + mass_distribution_sigma1: {'sample': true, 'values': [-0.6, 0.04552506, 0.3]} + mass_distribution_sigma2: {'sample': true, 'values': [-0.5, -0.0445, 2.0]} + completeness_a_n: {'sample': false, 'values': 1.1321} + completeness_b_n: {'sample': false, 'values': 0.7751} + completeness_a_logm_piv: {'sample': false, 'values': 13.31} + completeness_b_logm_piv: {'sample': false, 'values': 0.2025} + cluster_theory_cluster_concentration: {'sample': false, 'values': 3.8} +``` + +-------------------------------------------------- +References -------------------------------------------------- -Firecrown parameters can be extended as needed depending on the -likelihood model. \ No newline at end of file +- Murata et al. (2019), mass–richness relation: + https://doi.org/10.1093/pasj/psz092 (arXiv:1904.07524) +- Aguena & Lima (2018), completeness and purity: + https://arxiv.org/abs/1611.05468 +- Despali et al. (2016), halo mass function: + https://arxiv.org/abs/1507.05627 +- Navarro, Frenk & White (1997), NFW profile: + https://arxiv.org/abs/astro-ph/9611107 +- Bhattacharya et al. (2013), mass–concentration relation: + https://arxiv.org/abs/1112.5479 +- Zuntz et al. (2015), CosmoSIS: + https://arxiv.org/abs/1409.3409 +- Foreman-Mackey et al. (2013), emcee: + https://arxiv.org/abs/1202.3665 +- Firecrown: https://github.com/LSSTDESC/firecrown +- CROW: https://github.com/LSSTDESC/crow diff --git a/docs/conf.py b/docs/conf.py new file mode 100644 index 0000000..af8915b --- /dev/null +++ b/docs/conf.py @@ -0,0 +1,47 @@ +project = "CLPipe" +author = "LSST DESC CLPipe Contributors" +release = "0.0.1" + +import os +import sys + +sys.path.insert(0, os.path.abspath("..")) + +root_doc = "index" +extensions = [ + "sphinx.ext.autodoc", + "sphinx.ext.autosummary", + "sphinx.ext.napoleon", + "sphinx.ext.viewcode", + "sphinx_autodoc_typehints", + "sphinx_copybutton", +] + +autosummary_generate = True +autodoc_member_order = "bysource" +autodoc_default_options = {"members": True, "show-inheritance": True} +# Heavy DESC dependencies are not installed in the standalone docs workflow. +autodoc_mock_imports = [ + "ceci", + "crow", + "firecrown", + "pyccl", + "sacc", + "tjpcov", + "cosmosis", + "yaml", + "numpy", +] +exclude_patterns = [ + "_build", + "venv/**", + "Thumbs.db", + ".DS_Store", +] + +html_theme = "sphinx_rtd_theme" +html_theme_options = { + "prev_next_buttons_location": None, + "collapse_navigation": False, + "titles_only": True, +} diff --git a/docs/index.rst b/docs/index.rst new file mode 100644 index 0000000..ac8b809 --- /dev/null +++ b/docs/index.rst @@ -0,0 +1,22 @@ +******************** +CLPipe Documentation +******************** + +The LSST-DESC CLPipe Repository is dedicated to the Cluster Working Group of the DESC-LSST collaboration. + + +The source code is publicly available at https://github.com/LSSTDESC/CLPipe. + + +.. toctree:: + :maxdepth: 2 + :caption: Getting Started + + source/overview + source/installation + source/clp_covariance + source/clp_firecrown + source/LSST DESC software dependencies + source/api + + diff --git a/docs/requirements.txt b/docs/requirements.txt new file mode 100644 index 0000000..2c6d25e --- /dev/null +++ b/docs/requirements.txt @@ -0,0 +1,4 @@ +sphinx +sphinx-autodoc-typehints +sphinx-rtd-theme +sphinx_copybutton \ No newline at end of file diff --git a/docs/source/LSST DESC software dependencies.rst b/docs/source/LSST DESC software dependencies.rst new file mode 100644 index 0000000..6d0defd --- /dev/null +++ b/docs/source/LSST DESC software dependencies.rst @@ -0,0 +1,58 @@ +******************************** +LSST DESC software dependencies +******************************** +This pipeline relies on several Python packages developed by the LSST Dark Energy Science Collaboration (LSST DESC). +It integrates these DESC tools into a unified analysis workflow. +We encourage readers to consult the official documentation for each project; links are provided below. + +.. figure:: diagram.png + :scale: 100 % + :alt: CLPipe and its dependencies diagram + :align: center + + + +-------------------------------------------------- + Package dependencies: +-------------------------------------------------- + +1. CLL +------ +DESC Core Cosmology Library: cosmology routines with validated numerical accuracy + +* https://github.com/LSSTDESC/CCL + +2. CLMM +--------- +The LSST-DESC Cluster Lensing Mass Modeling + +* https://github.com/LSSTDESC/CLMM + + + +3. CROW +------- +The LSST-DESC Cluster Reconstruction of Observables Workbench (CROW) + +* https://github.com/LSSTDESC/CROW + + +4. Firecrown +------------ +Provides the DESC framework to implement likelihoods + +* https://github.com/LSSTDESC/Firecrown + + +5. TJPCov +--------- +A general covariance calculator interface to be used within LSST DESC. + +* https://github.com/LSSTDESC/TJPCov + + +6. TXPipe +--------- + The DESC 3x2pt Pipeline implementation. It measures lensing and clustering 2pt quantities in real and Fourier space + +* https://github.com/LSSTDESC/TXPipe diff --git a/docs/source/api.rst b/docs/source/api.rst new file mode 100644 index 0000000..bbc776e --- /dev/null +++ b/docs/source/api.rst @@ -0,0 +1,19 @@ +API Reference +============= + +Pipeline stages +--------------- + +.. automodule:: clpipe.clp_covariance + +.. automodule:: clpipe.clp_firecrown + +File types +---------- + +.. automodule:: clpipe.file_types + +Cluster theory predictions +-------------------------- + +.. automodule:: clpipe.cluster_theory_pred diff --git a/docs/source/clp_covariance.rst b/docs/source/clp_covariance.rst new file mode 100644 index 0000000..5eebe55 --- /dev/null +++ b/docs/source/clp_covariance.rst @@ -0,0 +1,410 @@ +================================================== +CLPCovariance Configuration Options +================================================== + +This document describes the configuration options of the CLPCovariance +stage. The stage computes the theoretical covariance of the cluster number +counts with TJPCov and writes it into an output SACC file. + +Overview +======== + +CLPCovariance runs the following steps: + +1. Read the input SACC file (data vector) and the fiducial cosmology. +2. Compute the covariance terms listed in ``cov_type`` with TJPCov. +3. If the input SACC file also contains other observables with a + covariance (e.g. ``cluster_delta_sigma``), copy those blocks into the new + covariance. +4. If ``replace_tjpcov_cov`` is True, replace the cluster-count block with a + CROW-based covariance. +5. Write a single output SACC file with the final covariance. + +Inputs and outputs: + +- ``clusters_sacc_file`` (input): SACC data vector, from TXPipe +- ``fiducial_cosmology`` (input): fiducial cosmology, shared with TXPipe +- ``clusters_sacc_file_cov`` (output): SACC file with the final covariance + +The cosmology is always read from the ``fiducial_cosmology`` input. It is not +set in the stage configuration. + +Input SACC file +--------------- + +The ``cluster_counts`` data points must each have three tracers, in this +order: + +- ``survey``: survey tracer, with ``sky_area`` in deg\ :sup:`2` +- ``bin_richness``: richness bin, with lower/upper edges in + :math:`\log_{10}\lambda` +- ``bin_z``: redshift bin, with lower/upper edges + +Covariance Model +================ + +The cluster-count covariance is the sum of a Poisson shot-noise term and a +super-sample covariance (SSC) term +(`Lacasa et al. 2018 `__): + +.. math:: + + [\mathrm{Cov}_N]_{ijkl} = \delta^K_{ik} \, \delta^K_{jl} \, N_{ij} + [\mathrm{Cov}_{\rm SSC}]_{ijkl} + +.. math:: + + [\mathrm{Cov}_{\rm SSC}]_{ijkl} = N_{ij} \, N_{kl} \, \langle b \rangle_{ij} \, \langle b \rangle_{kl} \, S_{ik} + +where :math:`i, k` run over redshift bins and :math:`j, l` over richness +bins: + +- :math:`N_{ij}`: predicted number of clusters in bin :math:`(i, j)` +- :math:`\langle b \rangle_{ij}`: halo bias averaged over the clusters in bin + :math:`(i, j)` (model set by ``halo_bias``) +- :math:`S_{ik}`: covariance of the matter density contrast, smoothed by the + survey window, between redshift bins :math:`i` and :math:`k` + (partial-sky window computed from the survey area) + +The SSC term scales as :math:`N^2`, while the shot noise scales as +:math:`N`, so SSC becomes important for large cluster samples such as LSST +(`Fumagalli et al. 2021 `__). + +TJPCov computes the shot-noise term (``ClusterCountsGaussian``) and the SSC +term (``ClusterCountsSSC``) separately. Both use the halo model, +mass–richness relation and photo-z model set by ``mor_parameters`` and +``photo-z`` below. + +TJPCov Options +============== + +``use_mpi`` (bool, default: False) + Enable MPI parallelization in TJPCov. + Must be consistent with the execution environment. + +``do_xi`` (bool, default: False) + Compute real-space correlation function (xi) terms. + Typically False for cluster-count analyses. + +``cov_type`` (list of str, default: [ClusterCountsGaussian, ClusterCountsSSC]) + Covariance terms to compute. Supported values: + + - ``ClusterCountsGaussian``: Poisson shot-noise term (diagonal) + - ``ClusterCountsSSC``: super-sample covariance term + - ``ClusterMass`` (optional, not always used) + + Example: + + .. code-block:: yaml + + cov_type: [ClusterCountsGaussian, ClusterCountsSSC] + +Photo-z Options +=============== + +``photo-z`` (dict, required by TJPCov) + Photometric redshift model used by TJPCov. The observed redshift is + Gaussian around the true redshift (truncated at :math:`z_{\rm phot} > 0`), + with a scatter that grows with redshift: + + .. math:: + + \sigma_z(z) = \sigma_0 \, (1 + z) + + - ``sigma_0`` (float): photo-z scatter parameter :math:`\sigma_0`, + e.g. 0.05 + + The CROW replacement does not use it: it assumes exact (spectroscopic) + redshifts. + + Example: + + .. code-block:: yaml + + photo-z: + sigma_0: 0.05 + +Mass–Observable Relation (MOR) Options +====================================== + +``mor_parameters`` (dict, required by TJPCov) + Halo model and mass–richness relation. + + **Halo model** (used by TJPCov only): + + - ``mass_func`` (str): halo mass function, e.g. ``"Despali16"``. + Supported: Angulo12, Bocquet16, Bocquet20, Despali16, Jenkins01, + Nishimichi19, Press74, Sheth99, Tinker08, Tinker10, Watson13 + - ``mass_def`` (str): mass definition, e.g. ``"200c"`` + - ``halo_bias`` (str): halo bias model, used for + :math:`\langle b \rangle` in the SSC term, e.g. ``"Tinker10"``. + Supported: Bhattacharya11, Sheth01, Sheth99, Tinker10 + + **Mass range** (used by TJPCov and CROW): + + - ``min_halo_mass`` (float): lower mass limit in + :math:`M_\odot`, e.g. 1.0e12 + - ``max_halo_mass`` (float): upper mass limit in + :math:`M_\odot`, e.g. 3.16e15 + + These are linear masses, not log10. + + **Mass–richness relation** (used by TJPCov and CROW): + + The richness follows the + `Murata et al. (2019) `__ model. + At fixed mass and redshift, :math:`\ln\lambda` is Gaussian. Its mean and + its scatter are each linear in :math:`\ln M` and :math:`\ln(1+z)`, with 3 + parameters each: + + .. math:: + + P(\ln\lambda \mid M, z) = \frac{1}{\sqrt{2\pi} \, \sigma_{\ln\lambda}} \exp\left[ -\frac{(\ln\lambda - \mu_{\ln\lambda})^2}{2 \sigma_{\ln\lambda}^2} \right] + + .. math:: + + \mu_{\ln\lambda}(M, z) = \mu_0 + \mu_m \ln\frac{M}{M_{\rm piv}} + \mu_z \ln\frac{1+z}{1+z_{\rm piv}} + + .. math:: + + \sigma_{\ln\lambda}(M, z) = \sigma_0 + \sigma_m \ln\frac{M}{M_{\rm piv}} + \sigma_z \ln\frac{1+z}{1+z_{\rm piv}} + + - ``m_pivot`` (float): pivot mass + :math:`\log_{10}(M_{\rm piv} / M_\odot)`, e.g. 14.3 + - ``z_pivot`` (float): pivot redshift :math:`z_{\rm piv}`, e.g. 0.5 + - ``mu_p0``, ``mu_p1``, ``mu_p2`` (float): mean parameters + :math:`\mu_0, \mu_m, \mu_z` + - ``sigma_p0``, ``sigma_p1``, ``sigma_p2`` (float): scatter parameters + :math:`\sigma_0, \sigma_m, \sigma_z` + +Pipeline-Specific Options +========================= + +``replace_tjpcov_cov`` (bool, default: True) + Replace the TJPCov cluster-count covariance with a covariance computed + with CROW (see `Custom Covariance Replacement`_ below): + + - Diagonal terms are recomputed from CROW theory predictions. + - SSC and Gaussian contributions are combined. + + .. warning:: + + This is a temporary workaround. It should eventually be handled + directly inside TJPCov. + +``sel_func`` (bool, default: True) + Only used when ``replace_tjpcov_cov`` is True. + + If True, the CROW counts are weighted by the + `Aguena & Lima (2018) `__ completeness + model: + + .. math:: + + c(M, z) = \frac{\left(M / M_0(z)\right)^{n_c(z)}}{1 + \left(M / M_0(z)\right)^{n_c(z)}} + + .. math:: + + n_c(z) = a_n + b_n \, (1 + z), \qquad \log_{10} M_0(z) = a_{\rm piv} + b_{\rm piv} \, (1 + z) + + The completeness parameters are fixed to the CROW defaults, which are the + cosmoDC2 redMaPPer values (:math:`a_n` = 1.1321, :math:`b_n` = 0.7751, + :math:`a_{\rm piv}` = ``a_logm_piv`` = 13.31, + :math:`b_{\rm piv}` = ``b_logm_piv`` = 0.2025). They cannot be set from + the configuration. + + If False, no selection function is applied (:math:`c = 1`). + The purity model is currently disabled in the code. + +``diagonal_shear_covariance`` (bool, default: True) + Only used when the input SACC file contains other observables with a + covariance (e.g. ``cluster_delta_sigma``). + If True, only the diagonal (per-bin variance) of those blocks is kept. + If False, the full blocks are copied. + +Internal Behavior +================= + +Covariance Computation +---------------------- + +TJPCov computes the terms listed in ``cov_type`` and writes: + +.. code-block:: text + + clusters_sacc_file_cov.sacc + +Intermediate files with the individual terms may also be written: + +.. code-block:: text + + clusters_sacc_file_cov_SSC.sacc + clusters_sacc_file_cov_gauss.sacc + +Mixed Data Handling +------------------- + +If the input SACC file contains other observables besides cluster counts +and already has a covariance: + +- The cluster-count covariance is recomputed. +- The other covariance blocks (e.g. lensing) are copied from the input + file, diagonal-only or in full (see ``diagonal_shear_covariance``). + +This is handled by ``merge_data_covariance()``. + +Custom Covariance Replacement +----------------------------- + +If ``replace_tjpcov_cov`` is True, the cluster-count block is rebuilt with +CROW. For each cluster-count data point :math:`a` (one richness-redshift +bin), CROW predicts the counts + +.. math:: + + N_a = {} & \Omega_S \int_{z_a} dz \int_{\lambda_a} d\ln\lambda \int_{M_{\min}}^{M_{\max}} dM \\ + & \times \frac{d^2V}{dz \, d\Omega} \, \frac{dn}{dM}(M, z) \, P(\ln\lambda \mid M, z) \, c(M, z) + +where :math:`\Omega_S` is the survey area in steradians (from the SACC +survey tracer), :math:`dn/dM` is the Despali16 mass function, and +:math:`c(M, z)` is the completeness (see ``sel_func``). + +The covariance is then + +.. math:: + + C_{aa} = N_a + \mathrm{SSC}_{aa} \left( \frac{N_a}{N^{\rm TJPCov}_a} \right)^2 + +.. math:: + + C_{ab} = \mathrm{SSC}_{ab} \, \frac{N_a \, N_b}{N^{\rm TJPCov}_a \, N^{\rm TJPCov}_b}, \qquad a \neq b + +where: + +- :math:`N_a`: CROW theory counts for data point :math:`a` +- :math:`N^{\rm TJPCov}_a`: TJPCov Gaussian (shot-noise) term for data point + :math:`a`, i.e. the counts predicted by TJPCov +- :math:`\mathrm{SSC}_{ab}`: TJPCov super-sample covariance term + +The CROW counts are used as the Poisson term on the diagonal. The SSC term +scales as :math:`N_a N_b`, so it is rescaled from the TJPCov counts to the +CROW counts. Only the cluster-count block is modified. + +Known Limitations +================= + +- ``replace_crow_counts()`` is a temporary workaround. It should be removed + once this is implemented in TJPCov. + +- The cosmology is passed to TJPCov both as a CCL object and as a + parameter dictionary. This duplication comes from TJPCov and should be + fixed there. + +- Hardcoded choices in the CROW replacement: + + - Mass function: Despali16 (200c), whatever ``mass_func`` and + ``mass_def`` are + - Redshifts: spectroscopic (photo-z ``sigma_0`` is not used) + - Completeness parameters: CROW defaults + - Purity model: disabled + - Grid sizes: mass 80, redshift 40, proxy 40 + - Recipe: ``GridBinnedClusterRecipe`` + +- The covariance is computed once, at the fiducial cosmology and MOR + parameters, and held fixed during inference. + +- The input configuration is not validated. + +Pipeline Configuration +====================== + +The stage is wired into a ceci pipeline file. This example comes from +``examples/cosmodc2_redmapper/baseline/cosmodc2_redmapper_full_analysis/run_in2p3_both/TJPCov.yml``: + +.. code-block:: yaml + + id: TJPCov + modules: clpipe + launcher: + name: mini + interval: 0.5 + site: + name: local + max_threads: 4 + stages: + - name: CLPCovariance + module_name: clpipe.clp_covariance + nprocess: 1 + inputs: + fiducial_cosmology: /sps/lsst/groups/clusters/cl_pipeline_project/TXPipe_data/cosmodc2/fiducial_cosmology.yml + clusters_sacc_file: /sps/lsst/groups/clusters/cl_pipeline_project/TXPipe_data/cosmodc2/outputs-full-2026//cluster_sacc_catalog.sacc + config: ./config_in2p3_both.yml + resume: false + output_dir: ./outputs_both + log_dir: ./logs_both + +Run it with: + +.. code-block:: bash + + ceci TJPCov.yml + +The stage options below go in the stage config file (``config:`` above), +under a ``CLPCovariance`` block. + +Example Configuration +===================== + +.. code-block:: yaml + + CLPCovariance: + use_mpi: False + do_xi: False + cov_type: [ClusterCountsGaussian, ClusterCountsSSC] + + replace_tjpcov_cov: True + sel_func: True + diagonal_shear_covariance: True + + photo-z: + sigma_0: 0.05 + + mor_parameters: + mass_func: 'Despali16' + mass_def: '200c' + halo_bias: 'Tinker10' + min_halo_mass: 1.0e12 + max_halo_mass: 3.16e15 + + m_pivot: 14.3 + z_pivot: 0.5 + + mu_p0: 3.3439 + mu_p1: 0.9582 + mu_p2: -0.0193 + sigma_p0: 0.5623 + sigma_p1: 0.0455 + sigma_p2: -0.0445 + +Notes +===== + +- Additional TJPCov parameters can be added depending on the covariance + model. They are passed through to TJPCov. +- Make sure the SACC input data and the MOR configuration are consistent. + +References +========== + +- Murata et al. (2019), mass–richness relation: + `doi:10.1093/pasj/psz092 `__ + (`arXiv:1904.07524 `__) +- Lacasa, Lima & Aguena (2018), super-sample covariance: + `arXiv:1612.05958 `__ +- Fumagalli et al. (2021), impact of sample covariance on cluster counts: + `arXiv:2102.08914 `__ +- Aguena & Lima (2018), completeness and purity: + `arXiv:1611.05468 `__ +- Despali et al. (2016), halo mass function: + `arXiv:1507.05627 `__ +- Tinker et al. (2010), halo bias: + `arXiv:1001.3162 `__ diff --git a/docs/source/clp_firecrown.rst b/docs/source/clp_firecrown.rst new file mode 100644 index 0000000..2974924 --- /dev/null +++ b/docs/source/clp_firecrown.rst @@ -0,0 +1,520 @@ +================================================== +CLPFirecrown Configuration Options +================================================== + +This document describes the configuration options of the CLPFirecrown +stage. The stage prepares a cluster cosmology inference with Firecrown and +CosmoSIS: it writes the Firecrown likelihood and the CosmoSIS configuration +files. It does not run the sampler. Sampling is a separate CosmoSIS run +(see `Running the Inference`_). + +Overview +======== + +CLPFirecrown runs the following steps: + +1. Read the SACC file with covariance (from CLPCovariance) and the fiducial + cosmology. +2. Write the Firecrown likelihood file. It builds CROW recipes for the + cluster counts and/or the stacked shear profile, from the modeling + options below. +3. Write the CosmoSIS pipeline file: consistency, CAMB and the Firecrown + likelihood modules, plus the sampler settings. +4. Write the CosmoSIS values file: cosmological and Firecrown parameters, + with their priors. + +Inputs and outputs: + +- ``clusters_sacc_file_cov`` (input): SACC data vector with covariance, from + CLPCovariance +- ``fiducial_cosmology`` (input): fiducial cosmology, shared with TXPipe and + CLPCovariance +- ``sampler_file`` (output): CosmoSIS pipeline file (``sampler_file.ini``) +- ``likelihood_file`` (output): Firecrown likelihood (``likelihood_file.py``) +- ``priors_file`` (output): CosmoSIS values file with priors + (``priors_file.ini``) + +Theory Model +============ + +The predictions are computed with CROW. For a redshift bin :math:`i` and a +richness bin :math:`j`, the number counts and the stacked lensing profile +are + +.. math:: + + N_{ij} = {} & \Omega_S \int_{z_i}^{z_{i+1}} dz \int_{\ln\lambda_j}^{\ln\lambda_{j+1}} d\ln\lambda \int_{M_{\min}}^{M_{\max}} dM \\ + & \times \frac{d^2V}{dz \, d\Omega} \, \frac{dn}{dM}(M, z) \, P(\ln\lambda \mid M, z) \, \Phi(M, \lambda, z) + +.. math:: + + \Theta_{ij}(R) = {} & \frac{\Omega_S}{N_{ij}} \int_{z_i}^{z_{i+1}} dz \int_{\ln\lambda_j}^{\ln\lambda_{j+1}} d\ln\lambda \int_{M_{\min}}^{M_{\max}} dM \\ + & \times \frac{d^2V}{dz \, d\Omega} \, \frac{dn}{dM}(M, z) \, P(\ln\lambda \mid M, z) \, \Phi(M, \lambda, z) \, \Theta(R \mid M) + +where: + +- :math:`\Omega_S`: survey area in steradians, from the SACC file +- :math:`dn/dM`: halo mass function (``hmf``, ``mass_def``) +- :math:`P(\ln\lambda \mid M, z)`: mass–richness relation (see below) +- :math:`\Phi = c(M, z) / p(\lambda, z)`: selection function, from the + completeness :math:`c` and the purity :math:`p` (see below). Each is 1 + when disabled. +- :math:`\Theta(R \mid M)`: lensing profile of a halo of mass :math:`M`, + either the excess surface density :math:`\Delta\Sigma` or the reduced + tangential shear :math:`g_t` + +Mass–richness relation +---------------------- + +The richness follows the +`Murata et al. (2019) `__ model. At +fixed mass and redshift, :math:`\ln\lambda` is Gaussian. Its mean and its +scatter are each linear in :math:`\ln M` and :math:`\ln(1+z)`, with 3 +parameters each: + +.. math:: + + P(\ln\lambda \mid M, z) = \frac{1}{\sqrt{2\pi} \, \sigma_{\ln\lambda}} \exp\left[ -\frac{(\ln\lambda - \mu_{\ln\lambda})^2}{2 \sigma_{\ln\lambda}^2} \right] + +.. math:: + + \mu_{\ln\lambda}(M, z) = \mu_0 + \mu_m \ln\frac{M}{M_{\rm piv}} + \mu_z \ln\frac{1+z}{1+z_{\rm piv}} + +.. math:: + + \sigma_{\ln\lambda}(M, z) = \sigma_0 + \sigma_m \ln\frac{M}{M_{\rm piv}} + \sigma_z \ln\frac{1+z}{1+z_{\rm piv}} + +The pivots are set by ``pivot_mass`` and ``pivot_z``. The 6 parameters are +Firecrown parameters (see `Firecrown Parameters`_). + +Completeness +------------ + +With ``use_completeness``, the +`Aguena & Lima (2018) `__ completeness +model: + +.. math:: + + c(M, z) = \frac{\left(M / M_0(z)\right)^{n_c(z)}}{1 + \left(M / M_0(z)\right)^{n_c(z)}} + +.. math:: + + n_c(z) = a_n + b_n \, (1 + z), \qquad \log_{10} M_0(z) = a_{\rm piv} + b_{\rm piv} \, (1 + z) + +Purity +------ + +With ``use_purity``, the Aguena & Lima (2018) purity model, written in +:math:`\ln\lambda`: + +.. math:: + + p(\lambda, z) = \frac{\left(\ln\lambda / \ln\lambda_0(z)\right)^{n_p(z)}}{1 + \left(\ln\lambda / \ln\lambda_0(z)\right)^{n_p(z)}} + +.. math:: + + n_p(z) = a_n + b_n \, (1 + z), \qquad \ln\lambda_0(z) = a_{\rm piv} + b_{\rm piv} \, (1 + z) + +Lensing profile +--------------- + +:math:`\Theta(R \mid M)` is computed with CLMM from an NFW profile (one-halo +term). The concentration is the Firecrown parameter +``cluster_theory_cluster_concentration``. A value below 1 uses the +`Bhattacharya et al. (2013) `__ +mass–concentration relation instead. The two-halo term and the boost-factor +correction can be added (``two_halo_term``, ``boost_factor``). + +For the reduced shear :math:`g_t`, the lensing efficiency is averaged over +the source redshift distribution (``beta_parameters``, ``use_beta_interp``). + +Likelihood +---------- + +The likelihood is a Gaussian (Firecrown ``ConstGaussian``) over all the +selected statistics: + +- ``BinnedClusterNumberCounts``: counts :math:`N_{ij}` (and optionally the + mean log mass) +- ``BinnedClusterShearProfile``: stacked :math:`\Delta\Sigma` or :math:`g_t` + profiles + +The covariance is read from the SACC file and held fixed during sampling. + +Modeling Options +================ + +``hmf`` (str, default: "despali16") + Halo mass function (case-insensitive). Supported values: + + - angulo12 + - bocquet16 + - bocquet20 + - despali16 + - jenkins01 + - press74 + - sheth99 + - tinker08 + - tinker10 + - watson13 + +``mass_def`` (str, default: "200c") + Mass definition used by the halo mass function (e.g. ``"200c"``, + ``"500c"``). + +``min_mass``, ``max_mass`` (float, default: 12.0, 15.5) + Halo mass integration range, in :math:`\log_{10}(M / M_\odot)`. + Note: CLPCovariance uses linear masses for the same range. + +``min_z``, ``max_z`` (float, default: 0.2, 0.8) + True redshift integration range. + +``pivot_mass`` (float, default: 14.3) + Pivot mass of the mass–richness relation, + :math:`\log_{10}(M_{\rm piv} / M_\odot)`. + +``pivot_z`` (float, default: 0.5) + Pivot redshift of the mass–richness relation. + +``survey_name`` (str, default: "cosmodc2_redmapper") + Survey tracer name in the SACC file. Must match it. + +Observable Options +================== + +``use_cluster_counts`` (bool, default: True) + Include the cluster number counts in the likelihood. + +``use_shear_profile`` (bool, default: False) + Include the stacked shear profiles in the likelihood. + +``is_deltasigma`` (bool, default: False) + Theory side: predict :math:`\Delta\Sigma` (True) or the reduced shear + :math:`g_t` (False). + +``use_mean_deltasigma`` (bool, default: False) + Data side: read :math:`\Delta\Sigma` (True) or the reduced shear + :math:`g_t` (False) from the SACC file. Set it to the same value as + ``is_deltasigma``. + +``use_mean_log_mass`` (bool, default: False) + Also use the mean log mass per bin, read from the SACC file. + +Selection Function Options +========================== + +``use_completeness`` (bool, default: True) + Apply the completeness model :math:`c(M, z)` (see `Completeness`_). + +``use_purity`` (bool, default: True) + Apply the purity model :math:`p(\lambda, z)` (see `Purity`_). + +Lensing Options +=============== + +Only used when ``use_shear_profile`` is True. + +``two_halo_term`` (bool, default: False) + Add the two-halo term to the lensing profile. + +``boost_factor`` (bool, default: False) + Apply the boost-factor correction to the lensing profile. + +``set_concentration`` (bool) + Reserved for future use. The stage does not read it yet, so it + currently has no effect. The concentration is set with + ``cluster_theory_cluster_concentration`` in ``firecrown_parameters``. + +``use_beta_interp`` (bool, default: False) + Interpolate the mean lensing efficiency :math:`\langle\beta_s\rangle` in + redshift. Only used for the reduced shear (``is_deltasigma: False``). + +``beta_parameters`` (list of float, default: [10.0, 5.0]) + Parameters of the mean lensing efficiency :math:`\langle\beta_s\rangle`, + passed to CROW as ``[z_inf, zmax]``: the redshift taken as infinity, and + the maximum source redshift. Only used for the reduced shear + (``is_deltasigma: False``). + + The first value (``z_inf``, 10 by default) is also always used as the + maximum redshift of CAMB (``zmax`` in the ``[camb]`` section of + ``sampler_file.ini``), even without shear profiles. + +Integration Options +=================== + +``use_grid`` (bool, default: True) + If True, use ``GridBinnedClusterRecipe``: integrals on precomputed + grids, about 100 times faster, recommended for inference. + If False, use ``ExactBinnedClusterRecipe`` (direct integration with + NumCosmo), slower, useful to validate the grid results. + +``redshift_grid_size`` (int, default: 20) + Number of redshift grid points. + +``mass_grid_size`` (int, default: 60) + Number of mass grid points. + +``proxy_grid_size`` (int, default: 20) + Number of richness grid points. + +The grid sizes are only used when ``use_grid`` is True. + +Sampler Options +=============== + +``sampler`` (str, default: "emcee") + CosmoSIS sampler. Supported values: + + - ``test``: a single likelihood evaluation, useful to check the setup + - ``metropolis`` + - ``emcee`` + - ``polychord`` + +``emcee_walkers`` (int, default: 100) + Number of emcee walkers. + +``emcee_samples`` (int, default: 20000) + Number of emcee samples per walker. + +``emcee_nsteps`` (int, default: 20) + Number of emcee steps between chain outputs. + +``polychord_live_points`` (int, default: 500) + Number of PolyChord live points. + +``polychord_num_repeats`` (int, default: 30) + Number of PolyChord slice-sampling repeats. + +``polychord_tolerance`` (float, default: 0.05) + PolyChord evidence tolerance (stopping criterion). + +``polychord_feedback`` (int, default: 1) + PolyChord verbosity level. + +.. note:: + + The ``polychord_*`` options fill the ``[polychord]`` section of + ``sampler_file.ini`` (see the + `CosmoSIS PolyChord sampler `__). + +``resume`` (bool, default: False) + If True, CosmoSIS appends to the existing chain instead of starting a + new one. + +``filename`` (str, optional, default: "output_rp/number_counts_samples.txt") + Path of the output chain file. + +Cosmological Parameters +======================= + +``tau`` (float, default: 0.08) + Optical depth to reionization. It is a CAMB input, not part of the + fiducial cosmology file, so it is set here. + +``cosmological_parameters`` (dict, default: {}) + Overrides on top of the fiducial cosmology. By default, every + cosmological parameter is fixed to its value in ``fiducial_cosmology``. + List a parameter here to sample it. + + Parameter names (CosmoSIS naming): ``omega_c``, ``omega_b``, ``h0``, + ``n_s``, ``sigma_8``, ``omega_k``, ``w``, ``wa``, ``tau``. + + A fixed entry (``sample: False``) must have the fiducial value, otherwise + the stage fails. To change the fiducial cosmology, edit the + ``fiducial_cosmology`` file instead, so that all stages use it. + + Example: + + .. code-block:: yaml + + cosmological_parameters: + omega_c: {'sample': True, 'values': [0.10, 0.22, 0.5]} + sigma_8: {'sample': True, 'values': [0.5, 0.800, 1.1]} + +Firecrown Parameters +==================== + +``firecrown_parameters`` (dict, default: {}) + Parameters of the CROW models, written to the + ``[firecrown_number_counts]`` section of the values file. Set all the + parameters of the models you enable, fixed or sampled. + + **Mass–richness relation:** + + - ``mass_distribution_mu0``, ``mass_distribution_mu1``, + ``mass_distribution_mu2``: :math:`\mu_0, \mu_m, \mu_z` + - ``mass_distribution_sigma0``, ``mass_distribution_sigma1``, + ``mass_distribution_sigma2``: :math:`\sigma_0, \sigma_m, \sigma_z` + + **Completeness** (``use_completeness``): + + - ``completeness_a_n``, ``completeness_b_n``: :math:`a_n, b_n` + - ``completeness_a_logm_piv``, ``completeness_b_logm_piv``: + :math:`a_{\rm piv}, b_{\rm piv}` + - CROW defaults (cosmoDC2 redMaPPer): 1.1321, 0.7751, 13.31, 0.2025 + + **Purity** (``use_purity``): + + - ``purity_a_n``, ``purity_b_n``: :math:`a_n, b_n` + - ``purity_a_logm_piv``, ``purity_b_logm_piv``: + :math:`a_{\rm piv}, b_{\rm piv}` + - CROW defaults (cosmoDC2 redMaPPer): 1.9830, 0.8121, 2.2183, -0.6592 + + **Lensing profile** (``use_shear_profile``): + + - ``cluster_theory_cluster_concentration``: halo concentration + (below 1: Bhattacharya et al. 2013 relation) + +Parameter Format +================ + +Entries in ``cosmological_parameters`` and ``firecrown_parameters`` use the +same format: + +.. code-block:: yaml + + # Sampled, with a flat prior between min and max: + name: {'sample': True, 'values': [min, start, max]} + + # Fixed: + name: {'sample': False, 'values': value} + +Pipeline Configuration +====================== + +The stage is wired into a ceci pipeline file. This example comes from +``examples/cosmodc2_redmapper/baseline/cosmodc2_redmapper_full_analysis/run_in2p3_both/Firecrown.yml``: + +.. code-block:: yaml + + id: Firecrown + modules: clpipe + launcher: + name: mini + interval: 0.5 + site: + name: local + max_threads: 4 + stages: + - name: CLPFirecrown + module_name: clpipe.clp_firecrown + nprocess: 1 + inputs: + fiducial_cosmology: /sps/lsst/groups/clusters/cl_pipeline_project/TXPipe_data/cosmodc2/fiducial_cosmology.yml + clusters_sacc_file_cov: ./outputs_both/clusters_sacc_file_cov.sacc + config: ./config_in2p3_both.yml + resume: false + output_dir: ./outputs_both + log_dir: ./logs_both + +The stage options go in the stage config file (``config:`` above), under a +``CLPFirecrown`` block. + +Running the Inference +===================== + +Generate the files with ceci, then run CosmoSIS from the output directory: + +.. code-block:: bash + + ceci Firecrown.yml + + cd ./outputs_both + cosmosis sampler_file.ini + + # or, with MPI: + mpirun -n 30 cosmosis --mpi sampler_file.ini + +The generated files refer to each other, and to the SACC file, by file name +only. Run CosmoSIS from the output directory, with the SACC file in it (this +is the case when CLPCovariance writes to the same output directory). +CosmoSIS also needs the ``CSL_DIR`` environment variable (see the +installation instructions in the README). + +Known Limitations +================= + +- The ``test`` and ``metropolis`` sampler settings are fixed in the + generated file (``metropolis``: 1000 samples). + +- The covariance is held fixed during sampling. + +- Only the binned likelihood is supported. + +- The names in ``firecrown_parameters`` are not validated by the stage. + +Example Configuration +===================== + +This is the ``CLPFirecrown`` block of the baseline cosmoDC2 redMaPPer +analysis (counts + stacked :math:`\Delta\Sigma`): + +.. code-block:: yaml + + CLPFirecrown: + hmf: 'despali16' + mass_def: '200c' + min_mass: 12.0 + max_mass: 15.5 + min_z: 0.2 + max_z: 0.8 + pivot_mass: 14.3 + pivot_z: 0.5 + survey_name: 'cosmodc2_redmapper' + + use_cluster_counts: true + use_shear_profile: true + is_deltasigma: true + use_mean_deltasigma: true + use_mean_log_mass: false + + use_completeness: true + use_purity: false + + use_grid: true + use_beta_interp: false + beta_parameters: [10.0, 5.0] + + sampler: 'emcee' + emcee_walkers: 100 + emcee_samples: 50000 + emcee_nsteps: 20 + + cosmological_parameters: + omega_c: {'sample': true, 'values': [0.10, 0.22, 0.5]} + sigma_8: {'sample': true, 'values': [0.5, 0.800, 1.1]} + + firecrown_parameters: + mass_distribution_mu0: {'sample': true, 'values': [2.0, 3.3439, 10.0]} + mass_distribution_mu1: {'sample': true, 'values': [0.5, 0.958236982, 2.0]} + mass_distribution_mu2: {'sample': true, 'values': [-2.0, -0.0192802, 2.0]} + mass_distribution_sigma0: {'sample': true, 'values': [0.1, 0.562317194, 2.0]} + mass_distribution_sigma1: {'sample': true, 'values': [-0.6, 0.04552506, 0.3]} + mass_distribution_sigma2: {'sample': true, 'values': [-0.5, -0.0445, 2.0]} + completeness_a_n: {'sample': false, 'values': 1.1321} + completeness_b_n: {'sample': false, 'values': 0.7751} + completeness_a_logm_piv: {'sample': false, 'values': 13.31} + completeness_b_logm_piv: {'sample': false, 'values': 0.2025} + cluster_theory_cluster_concentration: {'sample': false, 'values': 3.8} + +References +========== + +- Murata et al. (2019), mass–richness relation: + `doi:10.1093/pasj/psz092 `__ + (`arXiv:1904.07524 `__) +- Aguena & Lima (2018), completeness and purity: + `arXiv:1611.05468 `__ +- Despali et al. (2016), halo mass function: + `arXiv:1507.05627 `__ +- Navarro, Frenk & White (1997), NFW profile: + `arXiv:astro-ph/9611107 `__ +- Bhattacharya et al. (2013), mass–concentration relation: + `arXiv:1112.5479 `__ +- Zuntz et al. (2015), CosmoSIS: + `arXiv:1409.3409 `__ +- Foreman-Mackey et al. (2013), emcee: + `arXiv:1202.3665 `__ +- Firecrown: https://github.com/LSSTDESC/firecrown +- CROW: https://github.com/LSSTDESC/crow diff --git a/docs/source/clpipe_logo.png b/docs/source/clpipe_logo.png new file mode 100644 index 0000000..f9695d9 Binary files /dev/null and b/docs/source/clpipe_logo.png differ diff --git a/docs/source/diagram.png b/docs/source/diagram.png new file mode 100644 index 0000000..1c3b243 Binary files /dev/null and b/docs/source/diagram.png differ diff --git a/docs/source/installation.rst b/docs/source/installation.rst new file mode 100644 index 0000000..b3c19ad --- /dev/null +++ b/docs/source/installation.rst @@ -0,0 +1,41 @@ +************** +Installation +************** + +Requirements +============ + + +Installation +============ +To install CLPipe you currently need to build it from source. +Note: Do not use pip directly to install the required packages, +as not all dependencies can be installed this way. Instead, use conda, then pip to install clpipe.:: + + + git clone https://github.com/LSSTDESC/CLPipe.git + cd CLPipe + conda env update -f txpipe_environment.yml + conda activate txpipe_clp + pip install . + conda deactivate + + + conda env update -f firecrown_environment.yml + conda activate firecrown_clp + pip install . + conda env config vars set CSL_DIR=${CONDA_PREFIX}/cosmosis-standard-library + conda deactivate + conda activate firecrown_clp + + cd ${CONDA_PREFIX} + source ${CONDA_PREFIX}/bin/cosmosis-configure + cosmosis-build-standard-library main + + +To run the tests you can do:: + + + pytest + + diff --git a/docs/source/overview.rst b/docs/source/overview.rst new file mode 100644 index 0000000..887c571 --- /dev/null +++ b/docs/source/overview.rst @@ -0,0 +1,21 @@ +****************** +Rapid overview +****************** + +clpipe is an automated framework developed within the Legacy +Survey of Space and Time Dark Energy Science Collaboration (LSST DESC) for galaxy cluster cosmology, +in preparation for the first Rubin LSST Data releases. This cluster cosmology pipeline +integrates DESC-developed tools spanning galaxy/cluster catalog ingestion, cluster number count and +stacked weak lensing measurements, modeling, and parameter inference through posterior sampling, +enabling reproducible end-to-end cluster cosmology analyses. We test/validate the pipeline using mock +datasets and the LSST DESC cosmoDC2 simulation, performing a joint analysis of redMaPPer cluster +abundance and stacked weak lensing profiles measured in bins of redshift and richness. We constrain +some cosmological parameters along with six cluster mass–observable relation parameters. Besides +our baseline recovering the fiducial cosmoDC2 values within 2σ, we also showcase the flexibility of the +overall pipeline by assessing the impact of fiducial cosmology, alternative modeling prescriptions, and +cluster finder selection function on the parameter constraints. + +.. figure:: diagram.png + :scale: 100 % + :alt: CLPipe and its dependencies diagram + :align: center \ No newline at end of file diff --git a/firecrown_environment.yml b/firecrown_environment.yml index 32ff9c9..d2bc67f 100644 --- a/firecrown_environment.yml +++ b/firecrown_environment.yml @@ -37,11 +37,6 @@ dependencies: - requests - sacc >= 2.1 - scipy - - sphinx - - sphinx-autoapi - - sphinx-autodoc-typehints - - sphinx-rtd-theme - - sphinxcontrib-apidoc - tabulate - types-pyyaml - urllib3 @@ -55,6 +50,11 @@ dependencies: - types-requests - linkchecker - pytest-json-report + - sphinx + - sphinx-autoapi + - sphinx-autodoc-typehints + - sphinx-rtd-theme + - sphinxcontrib-apidoc - pip: - ceci >= 2.5 - qp-prob @@ -65,3 +65,4 @@ dependencies: - cobaya - isitgr - lsstdesc-crow + - sphinx_copybutton diff --git a/tests/test_clp_covariance.py b/tests/test_clp_covariance.py index 2a2e55f..d2341f5 100644 --- a/tests/test_clp_covariance.py +++ b/tests/test_clp_covariance.py @@ -15,7 +15,6 @@ def _base_tjpcov_config(mor_parameters, **overrides): cfg = { "replace_tjpcov_cov": True, "sel_func": True, - "wazp_catalog": False, "diagonal_shear_covariance": True, "use_mpi": False, "do_xi": False, diff --git a/tests/test_clp_firecrown.py b/tests/test_clp_firecrown.py index df87c6b..c090b54 100644 --- a/tests/test_clp_firecrown.py +++ b/tests/test_clp_firecrown.py @@ -189,6 +189,17 @@ def test_generated_python_is_syntactically_valid(ceci_stack, tmp_path, mock_fidu assert "build_likelihood" in func_names assert "get_cluster_recipe" in func_names + # ast.parse only checks syntax: a recipe class used without being + # imported would only fail when Firecrown loads the file. + imported_names = { + alias.asname or alias.name + for node in ast.walk(tree) if isinstance(node, ast.ImportFrom) + for alias in node.names + } + recipe_cls = "GridBinnedClusterRecipe" if cfg["use_grid"] else "ExactBinnedClusterRecipe" + assert f"{recipe_cls}(" in source + assert recipe_cls in imported_names + if cfg["use_cluster_counts"]: assert "get_cluster_abundance" in func_names assert "BinnedClusterNumberCounts" in source @@ -268,6 +279,27 @@ def test_filename_option_used_not_hardcoded_default(full_stack, tmp_path, mock_f assert parser["output"]["filename"] == custom_filename +def test_polychord_options_written_to_polychord_section(full_stack, tmp_path, mock_fiducial_cosmology): + cfg = _base_firecrown_config( + polychord_live_points=123, + polychord_num_repeats=7, + polychord_tolerance=0.2, + polychord_feedback=2, + ) + sacc_path = tmp_path / "clusters_sacc_file_cov.sacc" + stage = _make_stage(tmp_path, sacc_path, mock_fiducial_cosmology, cfg) + + ini_path = tmp_path / "test_polychord.ini" + assert stage.generate_ini_file(str(ini_path), "likelihood_file.py", "priors_file.ini") + + parser = configparser.ConfigParser() + parser.read(ini_path) + assert parser["polychord"]["live_points"] == "123" + assert parser["polychord"]["num_repeats"] == "7" + assert parser["polychord"]["tolerance"] == "0.2" + assert parser["polychord"]["feedback"] == "2" + + def test_only_cosmo_sampled_writes_correct_priors(full_stack, tmp_path, mock_fiducial_cosmology): cfg = _base_firecrown_config( cosmological_parameters=_as_sampled(COSMOLOGICAL_PARAMETERS),