Skip to content

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Latest commit

 

History

175 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Table of contents

  1. The des_cluster project
  2. Running Cosmolike projects (Basic instructions)
  3. Running Hybrid Cosmolike-ML emulators
  4. Exploring notebooks
  5. The plotting functions
  6. The notebook wrappers
  7. Likelihood options and nuisance parameters
  8. Cluster options
  9. Nuisance parameters
  10. Synthetic data
  11. Files
  12. Regenerating the data
  13. Unit tests and validation tools
  14. Status and known limitations
  15. Computing covariances
  16. Appendix: Which accuracy settings are available?

The des_cluster project

This project runs the DES Y6-style joint analysis of galaxy clusters, galaxy clustering, and weak lensing of arXiv:2503.13631 in Cocoa. The cluster code is a port of the original CosmoLike cluster code (arXiv:2008.10757) into Cocoa's cosmolike_core, where it lives in the files ending in _cluster. The file PORT_PLAN.md records the model, the design decisions, the validation, and the status of the port.

The project provides two likelihoods:

likelihood name in the paper blocks
des_cluster.combo_4x2pt_N CL+GC = 4x2pt + N cluster counts, cluster lensing, cluster clustering, cluster x galaxy clustering, galaxy clustering (MagLim lens bins 1-3)
des_cluster.combo_6x2pt_N CL+3x2pt = 6x2pt + N the blocks above plus cosmic shear, galaxy-galaxy lensing, and galaxy clustering of all six MagLim lens bins

Both likelihoods read one joint data vector of 2812 entries and one covariance; they differ only in the scale-cut mask. The blocks are stored in the order ss, gs, gg, cg, N, cc, cs:

block content layout entries kept by the 4x2pt + N mask kept by the 6x2pt + N mask
ss cosmic shear, $\xi_+$ then $\xi_-$ [source pair][$\theta$] 400 0 190
gs galaxy-galaxy lensing $\gamma_t$ [(lens, source) pair][$\theta$] 480 0 312
gg galaxy clustering $w_{gg}$ [lens bin][$\theta$] 120 31 69
cg cluster x galaxy clustering $w_{cg}$ [(cluster z bin, lens bin) pair][richness bin][$\theta$] 240 128 128
N cluster counts [cluster z bin][richness bin] 12 12 12
cc cluster clustering $w_{cc}$ [cluster z bin][richness pair][$\theta$] 600 230 230
cs cluster lensing, $\Sigma = Y \gamma_t$ [(cluster z bin, source bin) pair][richness bin][$\theta$] 960 488 488
total 2812 889 1429

The binning is the one of the paper: three cluster redshift bins with $z_\lambda$ edges [0.2, 0.4, 0.55, 0.65], four richness bins with $\lambda$ edges [20, 30, 45, 60, 500], six MagLim lens bins, four source bins, and 20 logarithmic angular bins between 2.5 and 250 arcmin.

Warning

All data in this project are synthetic. No public DES cluster data vectors or covariances exist (neither for Y1 nor for Y3), so the project ships a DES Y6-like stand-in: the data vector is the model itself, computed at the fiducial point of Table I of arXiv:2503.13631, and the covariance is an analytic Gaussian covariance. Nothing here is a DES measurement, and no chain run on these files is a DES result. The section Synthetic data describes the files and how to regenerate them.

Warning

The code and examples of this project are in alpha stage. Read Status and known limitations before using the results.

Running Cosmolike projects (Basic instructions)

From Cocoa/Readme instructions:

Note

Cocoa provides several cosmolike projects that can be loaded and compiled using setup_cocoa.sh and compile_cocoa.sh scripts. Cocoa skips the project des_cluster by default. To activate it, comment the line export IGNORE_COSMOLIKE_DES_CLUSTER_CODE=1 on set_installation_options.sh

[Adapted from Cocoa/set_installation_options.sh shell script]
(...)
# ------------------------------------------------------------------------------
# The keys below control which cosmolike projects will be installed and compiled 
# ------------------------------------------------------------------------------
#export IGNORE_COSMOLIKE_LSST_Y1_CODE=1
export IGNORE_COSMOLIKE_DES_Y3_CODE=1
(...)
export IGNORE_COSMOLIKE_DES_CLUSTER_CODE=1
(...)
# URL of Cosmolike projects below ----------------------------------------------
(...)
# WARNING: des_cluster is not production ready.
export DES_CLUSTER_URL="https://github.com/CosmoLike/cocoa_des_cluster.git"
export DES_CLUSTER_NAME="des_cluster"
export DES_CLUSTER_GIT_TAG="v5.06"

Note

The covariance data/des_cluster_y6_cov.npy (32 MB) is stored with Git LFS. A clone without git lfs pull holds a small pointer file in its place, and the likelihoods cannot load it.

Note

If users want to recompile cosmolike, there is no need to rerun the Cocoa general scripts. Instead, run the following three commands:

 source start_cocoa.sh

and

 source ./installation_scripts/setup_cosmolike_projects.sh

and

  source ./installation_scripts/compile_all_projects.sh

or (in case users just want to compile des_cluster project)

  source ./projects/des_cluster/scripts/compile_des_cluster.sh

Tip

Assuming Cocoa is installed on a local (not remote!) machine, type the command below after step 2 to run Jupyter Notebooks.

jupyter notebook --no-browser --port=8888

The terminal will then show a message similar to the following template:

(...)
[... NotebookApp] Jupyter Notebook 6.1.1 is running at:
[... NotebookApp] http://f0a13949f6b5:8888/?token=XXX
[... NotebookApp] or http://127.0.0.1:8888/?token=XXX
[... NotebookApp] Use Control-C to stop this server and shut down all kernels (twice to skip confirmation).

Now go to the local internet browser and type http://127.0.0.1:8888/?token=XXX, where XXX is the previously saved token displayed on the line

[... NotebookApp] or http://127.0.0.1:8888/?token=XXX

The project des_cluster contains three jupyter notebook examples located at projects/des_cluster (see Exploring notebooks).

To run the example

Step 1️⃣: activate the cocoa Conda environment, and the private Python environment

  conda activate cocoa

and

  source start_cocoa.sh

Step 2️⃣: Select the number of OpenMP cores (the commands below set it to 8).

  • Linux

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=close; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    
  • macOS (arm)

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=disabled; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    

Step 3️⃣: The folder projects/des_cluster contains examples. So, run the cobaya-run on the first example following the commands below.

The examples numbered 1 run 4x2pt + N, and the examples numbered 2 run 6x2pt + N. The examples of this section compute the Boltzmann inputs with CAMB (Takahashi Halofit).

Warning

(Linux only) In some HPC nodes, numa can cause you problems. If that is the case, replace numa with slot

  • One model evaluation:

    • Linux

      "${CONDA_PREFIX}"/bin/mpirun -n 1 --oversubscribe \
        --mca pml ob1 --mca btl vader,tcp,self \
        --bind-to core:overload-allowed --report-bindings \
        --rank-by slot --map-by numa:pe=${OMP_NUM_THREADS} \
        cobaya-run ./projects/des_cluster/EXAMPLE_EVALUATE1.yaml -f
      
    • macOS (arm)

       mpirun -n 1 --oversubscribe \
        cobaya-run ./projects/des_cluster/EXAMPLE_EVALUATE1.yaml -f
      

    EXAMPLE_EVALUATE1.yaml and EXAMPLE_EVALUATE2.yaml evaluate the likelihood at the point of the synthetic data vector (Table I of arXiv:2503.13631), so they return $\chi^2 = 0$: the data vector is the model at that point, and the frozen copies of these examples in the unit tests record exactly 0.

  • MCMC (Metropolis-Hastings Algorithm):

    • Linux

      "${CONDA_PREFIX}"/bin/mpirun -n 4 --oversubscribe \
        --mca pml ob1 --mca btl vader,tcp,self \
        --bind-to core:overload-allowed --report-bindings \
        --rank-by slot --map-by numa:pe=${OMP_NUM_THREADS} \
        cobaya-run ./projects/des_cluster/EXAMPLE_MCMC1.yaml -f
      
    • macOS (arm)

        mpirun -n 4 --oversubscribe \
          cobaya-run ./projects/des_cluster/EXAMPLE_MCMC1.yaml -f
      

    EXAMPLE_MCMC1.yaml and EXAMPLE_MCMC2.yaml sample $\Lambda$CDM, as in the paper, with the neutrino mass free (w and w0pwa are fixed at -1; to sample $w_0$-$w_a$, give them a prior as in the evaluate examples). No proposal covariance is shipped for the cluster combinations, so the first run learns it.

The outputs are written to projects/des_cluster/chains/.

Running Hybrid Cosmolike-ML emulators

Note

These hybrid examples remain experimental. The checks below verify the workflow; assess emulator accuracy and posterior convergence for your analysis.

The EXAMPLE_EMUL2 examples emulate the background expansion and matter power spectra. CosmoLike still computes the survey projections, bias and intrinsic-alignment contributions. Changing n(z) or nuisance parameters does not require retraining a survey data-vector network.

The shared theory networks live in external_modules/data/emultrf. Install them through the main Cocoa emulator recipe. These networks assume mnu = 0.06 eV; do not sample neutrino mass. Their cold-matter power approximation is not a calibrated massive-neutrino halo model. Check their training range before widening cosmological priors.

Important

The supplied likelihood data are synthetic. Sampling examples demonstrate the workflow; they do not yield DES measurements.

Note

The emulators are fixed at a neutrino mass of 0.06 eV. The EMUL2 examples set mnu to 0.06 eV and do not sample it, while the synthetic data vector was generated with CAMB at $\Omega_\nu h^2 = 0.00083$ (mnu = 0.077 eV). The $\chi^2$ of EXAMPLE_EMUL2_EVALUATE1.yaml and EXAMPLE_EMUL2_EVALUATE2.yaml at the fiducial point is therefore not zero. At equal neutrino mass, the emulated inputs differ from CAMB by $\Delta\chi^2 = 1.6$ on 6x2pt + N (the cluster counts differ by 1.5% in the median).

This project does not distribute a full data-vector emulator: cluster likelihoods reject use_emulator: 1. These examples use use_emulator: 2.

These steps assume Cocoa and this project are installed, the Cocoa Conda environment is active, the shell is Bash, and the current folder is cocoa/Cocoa/.

Step 1️⃣: activate Cocoa.

source start_cocoa.sh

Step 2️⃣: Select the number of OpenMP cores (below, we set it to 4).

  • Linux

    export OMP_NUM_THREADS=4; export OMP_PROC_BIND=close; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    
  • macOS (arm)

    export OMP_NUM_THREADS=4; export OMP_PROC_BIND=disabled; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    

Step 3️⃣: remove GPU access on Linux; these examples use the CPU.

export CUDA_VISIBLE_DEVICES=""

Step 4️⃣: evaluate the first hybrid example.

  • Linux

    "${CONDA_PREFIX}"/bin/mpirun -n 1 --oversubscribe \
      --mca pml ob1 --mca btl vader,tcp,self \
      --bind-to core:overload-allowed --report-bindings \
      --rank-by slot --map-by numa:pe=${OMP_NUM_THREADS} \
      cobaya-run ./projects/des_cluster/EXAMPLE_EMUL2_EVALUATE1.yaml --force
    
  • macOS (arm)

    mpirun -n 1 --oversubscribe \
      cobaya-run ./projects/des_cluster/EXAMPLE_EMUL2_EVALUATE1.yaml --force
    

The YAML selects the CPU for the distance emulator. Keep BLAS at one thread per MPI rank (OPENBLAS_NUM_THREADS=1, MKL_NUM_THREADS=1); on macOS also use VECLIB_MAXIMUM_THREADS=1. The Python sampler entry points set these BLAS limits before importing numerical libraries.

Example Configuration 1 Configuration 2
Fixed evaluation EXAMPLE_EMUL2_EVALUATE1.yaml EXAMPLE_EMUL2_EVALUATE2.yaml
Cobaya MCMC EXAMPLE_EMUL2_MCMC1.yaml EXAMPLE_EMUL2_MCMC2.yaml
Annealed minimization EXAMPLE_EMUL2_MINIMIZE1.py EXAMPLE_EMUL2_MINIMIZE2.py
Parameter profile EXAMPLE_EMUL2_PROFILE1.py EXAMPLE_EMUL2_PROFILE2.py
Nautilus sampling EXAMPLE_EMUL2_NAUTILUS1.py EXAMPLE_EMUL2_NAUTILUS2.py
Repeated evaluations EXAMPLE_EMUL2_BENCHMARK1.yaml EXAMPLE_EMUL2_BENCHMARK2.yaml
PolyChord EXAMPLE_EMUL2_POLY1.yaml EXAMPLE_EMUL2_POLY2.yaml

Configuration 1 uses des_cluster.combo_4x2pt_N, NLA, and des_cluster_y6_4x2ptN.dataset. Configuration 2 uses des_cluster.combo_6x2pt_N, NLA, and des_cluster_y6_6x2ptN.dataset.

The minimization, profile and Nautilus scripts read the corresponding EXAMPLE_EMUL2_EVALUATE1.yaml or 2.yaml; --input selects another evaluate YAML. They require cocoa_hybrid_sampling.py from the matching shared core revision. They do not maintain separate embedded cosmologies. --check evaluates the specified fiducial and prints the sampled parameter order without sampling. Use a new --outroot for each run; these scripts refuse to overwrite results.

Cobaya MCMC

With Cocoa activated in Bash from cocoa/Cocoa/, run the first MCMC example. Use configuration 2 for the second likelihood listed above. Check chain convergence before interpreting posterior constraints.

Step 1️⃣: Select the number of OpenMP cores (below, we set it to 8).

  • Linux

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=close; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    
  • macOS (arm)

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=disabled; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    

Step 2️⃣: remove GPU access on Linux; these examples use the CPU.

export CUDA_VISIBLE_DEVICES=""

Step 3️⃣: start Cobaya's hybrid MCMC.

  • Linux

    "${CONDA_PREFIX}"/bin/mpirun -n 4 --oversubscribe \
      --mca pml ob1 --mca btl vader,tcp,self \
      --bind-to core:overload-allowed --report-bindings \
      --rank-by slot --map-by numa:pe=${OMP_NUM_THREADS} \
      cobaya-run ./projects/des_cluster/EXAMPLE_EMUL2_MCMC1.yaml
    
  • macOS (arm)

    mpirun -n 4 --oversubscribe \
      cobaya-run ./projects/des_cluster/EXAMPLE_EMUL2_MCMC1.yaml
    

Additional YAML workflows above retain their own parameter choices; inspect which parameters are fixed or sampled rather than assuming the evaluate and MCMC configurations have identical priors. PolyChord requires its optional Cocoa installation component.

The benchmark YAML repeats model evaluations for profiling.

Step 1️⃣: Select the number of OpenMP cores (below, we set it to 8).

  • Linux

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=close; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    
  • macOS (arm)

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=disabled; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    

Step 2️⃣: remove GPU access on Linux; these examples use the CPU.

export CUDA_VISIBLE_DEVICES=""

Step 3️⃣: run the first benchmark configuration.

cobaya-run ./projects/des_cluster/EXAMPLE_EMUL2_BENCHMARK1.yaml --force

For the separate PolyChord example:

Step 1️⃣: Select the number of OpenMP cores (below, we set it to 8).

  • Linux

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=close; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    
  • macOS (arm)

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=disabled; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    

Step 2️⃣: remove GPU access on Linux; these examples use the CPU.

export CUDA_VISIBLE_DEVICES=""

Step 3️⃣: start the first PolyChord configuration.

  • Linux

    "${CONDA_PREFIX}"/bin/mpirun -n 90 --oversubscribe \
      --mca pml ob1 --mca btl vader,tcp,self \
      -x PATH -x LD_LIBRARY_PATH -x PYTHONPATH -x CONDA_PREFIX -x ROOTDIR \
      -x OMP_NUM_THREADS -x OMP_PROC_BIND -x OMP_PLACES -x OMP_DYNAMIC \
      -x OPENBLAS_NUM_THREADS -x MKL_NUM_THREADS -x CLIK_PATH -x CLIK_DATA \
      -x CLIK_PLUGIN -x CUDA_VISIBLE_DEVICES --mca mpi_yield_when_idle 1 \
      --mca btl_tcp_if_exclude lo,docker0,virbr0,ib0 \
      --bind-to core:overload-allowed --report-bindings \
      --rank-by slot --map-by numa:pe=${OMP_NUM_THREADS} \
      cobaya-run ./projects/des_cluster/EXAMPLE_EMUL2_POLY1.yaml
    
  • macOS (arm)

    mpirun -n 12 --oversubscribe \
      cobaya-run ./projects/des_cluster/EXAMPLE_EMUL2_POLY1.yaml
    

Minimization, profiles and Nautilus

These steps assume Cocoa and this project are installed, the Cocoa Conda environment is active, the shell is Bash, and the current folder is cocoa/Cocoa/.

Step 1️⃣: Select the number of OpenMP cores (below, we set it to 8).

  • Linux

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=close; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    
  • macOS (arm)

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=disabled; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    

Step 2️⃣: remove GPU access on Linux; these examples use the CPU.

export CUDA_VISIBLE_DEVICES=""

Step 3️⃣: check the hybrid setup before a long run.

python ./projects/des_cluster/EXAMPLE_EMUL2_MINIMIZE1.py --check

Step 4️⃣: search for a minimum.

  • Linux

    "${CONDA_PREFIX}"/bin/mpirun -n 21 --oversubscribe \
      --mca pml ob1 --mca btl vader,tcp,self \
      -x PATH -x LD_LIBRARY_PATH -x PYTHONPATH -x CONDA_PREFIX -x ROOTDIR \
      -x OMP_NUM_THREADS -x OMP_PROC_BIND -x OMP_PLACES -x OMP_DYNAMIC \
      -x OPENBLAS_NUM_THREADS -x MKL_NUM_THREADS -x CLIK_PATH -x CLIK_DATA \
      -x CLIK_PLUGIN -x CUDA_VISIBLE_DEVICES --mca mpi_yield_when_idle 1 \
      --mca btl_tcp_if_exclude lo,docker0,virbr0,ib0 \
      --bind-to core:overload-allowed --report-bindings \
      --rank-by slot --map-by numa:pe=${OMP_NUM_THREADS} \
      python ./projects/des_cluster/EXAMPLE_EMUL2_MINIMIZE1.py --nstw 200 --outroot hybrid_min1
    
  • macOS (arm)

    mpirun -n 12 --oversubscribe \
      python ./projects/des_cluster/EXAMPLE_EMUL2_MINIMIZE1.py --nstw 200 --outroot hybrid_min1
    

Step 5️⃣: profile the first sampled parameter using that saved minimum.

  • Linux

    "${CONDA_PREFIX}"/bin/mpirun -n 21 --oversubscribe \
      --mca pml ob1 --mca btl vader,tcp,self \
      -x PATH -x LD_LIBRARY_PATH -x PYTHONPATH -x CONDA_PREFIX -x ROOTDIR \
      -x OMP_NUM_THREADS -x OMP_PROC_BIND -x OMP_PLACES -x OMP_DYNAMIC \
      -x OPENBLAS_NUM_THREADS -x MKL_NUM_THREADS -x CLIK_PATH -x CLIK_DATA \
      -x CLIK_PLUGIN -x CUDA_VISIBLE_DEVICES --mca mpi_yield_when_idle 1 \
      --mca btl_tcp_if_exclude lo,docker0,virbr0,ib0 \
      --bind-to core:overload-allowed --report-bindings \
      --rank-by slot --map-by numa:pe=${OMP_NUM_THREADS} \
      python ./projects/des_cluster/EXAMPLE_EMUL2_PROFILE1.py --profile 0 --nstw 200 --numpts 11 --factor 1 --minfile ./projects/des_cluster/chains/hybrid_min1.json --outroot hybrid_profile1
    
  • macOS (arm)

    mpirun -n 12 --oversubscribe \
      python ./projects/des_cluster/EXAMPLE_EMUL2_PROFILE1.py --profile 0 --nstw 200 --numpts 11 --factor 1 --minfile ./projects/des_cluster/chains/hybrid_min1.json --outroot hybrid_profile1
    

Step 6️⃣: run Nautilus as an independent sampling example.

  • Linux

    "${CONDA_PREFIX}"/bin/mpirun -n 90 --oversubscribe \
      --mca pml ob1 --mca btl vader,tcp,self \
      -x PATH -x LD_LIBRARY_PATH -x PYTHONPATH -x CONDA_PREFIX -x ROOTDIR \
      -x OMP_NUM_THREADS -x OMP_PROC_BIND -x OMP_PLACES -x OMP_DYNAMIC \
      -x OPENBLAS_NUM_THREADS -x MKL_NUM_THREADS -x CLIK_PATH -x CLIK_DATA \
      -x CLIK_PLUGIN -x CUDA_VISIBLE_DEVICES --mca mpi_yield_when_idle 1 \
      --mca btl_tcp_if_exclude lo,docker0,virbr0,ib0 \
      --bind-to core:overload-allowed --report-bindings \
      --rank-by slot --map-by numa:pe=${OMP_NUM_THREADS} \
      python ./projects/des_cluster/EXAMPLE_EMUL2_NAUTILUS1.py --nlive 1000 --neff 10000 --maxfeval 100000 --outroot hybrid_nautilus1
    
  • macOS (arm)

    mpirun -n 12 --oversubscribe \
      python ./projects/des_cluster/EXAMPLE_EMUL2_NAUTILUS1.py --nlive 1000 --neff 10000 --maxfeval 100000 --outroot hybrid_nautilus1
    

The annealed Emcee search follows the DES × Planck template. Its objective is −2 log posterior, including nuisance and cosmological priors; the profile is therefore a penalized profile, not a pure likelihood profile. --nstw sets steps per walker per temperature. More steps and independent starts are needed to assess whether a minimum is reliable.

--profile accepts a sampled-parameter name or its printed zero-based index. --factor gives the half-width in proposal standard deviations, clipped to the prior bounds. --cov accepts a covariance whose header lists the sampled parameters in order; without it, the prior covariance sets the proposal. The minimum JSON must come from the same evaluate YAML and parameter order. Older plain-text minimum files are not accepted. Set any additional priors in the input YAML; these scripts do not insert hidden cosmological priors.

Nautilus writes weighted GetDist-compatible rows and a JSON convergence record. Reaching --maxfeval is not convergence. If the budget ends before any posterior samples are retained, only the checkpoint and a JSON record with converged: false are saved. Its prior transform uses Cobaya's one-dimensional prior distributions; external prior factors enter once as additional log weight. Evidence with unnormalized external priors has that normalization limitation. These examples do not certify emulator accuracy or posterior convergence.

Emulator design and optional approximations

Details on the matter power spectrum emulator designs will be presented in the emulator_code repository.

The emulators apply standard neural network techniques to generalize the syren-new Eq. 6 of arXiv:2410.14623 formula for the linear power spectrum (w0waCDM with a fixed neutrino mass of $0.06$ eV) to new models, extended ranges, or higher precision. Similarly, networks generalize the syren-Halofit LCDM nonlinear boost fit (Eq. 11 of arXiv:2402.17492).

MPI across nodes

Note

Running on more than one node.

  1. Network interface. TCP must use an interface routable between compute nodes. A common exclusion list is --mca btl_tcp_if_exclude lo,docker0,virbr0,ib0; adapt it to the cluster. Keep ib0 if routable IP-over-InfiniBand is the intended network. These examples exchange parameter vectors and scalar scores, so communication volume is small; actual scaling still depends on the machine.
  2. Environment. Remote ranks need the same Cocoa paths and libraries: ROOTDIR, PATH, LD_LIBRARY_PATH, PYTHONPATH, CONDA_PREFIX, OpenMP and BLAS settings, and CLIK_PATH/CLIK_DATA/CLIK_PLUGIN when used. Slurm normally exports the submitting environment (--export=ALL). Explicit -x options also forward these variables with SSH launchers. Activate Cocoa before launching; build/download flags do not replace runtime paths. All nodes must see the same files at the same paths.
  3. Slurm geometry. Keep ntasks-per-node × cpus-per-task within the allocated physical cores per node. Set OMP_NUM_THREADS to SLURM_CPUS_PER_TASK and use --map-by numa:pe=${OMP_NUM_THREADS}. The minimization, profile and Nautilus pool reserves one MPI rank as coordinator; the remaining ranks evaluate the model.

Within a Slurm allocation, first activate Cocoa in Bash on the launch node. The following steps assume Open MPI 4 and shared installation/data paths. Omit optional CLIK exports if those variables are not set.

Step 1️⃣: match OpenMP threads to the scheduler allocation.

export OMP_NUM_THREADS="${SLURM_CPUS_PER_TASK}"; export OMP_PROC_BIND=close; \
export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1

Step 2️⃣: launch the hybrid minimizer across the allocated ranks.

"${CONDA_PREFIX}"/bin/mpirun -n "${SLURM_NTASKS}" \
  --mca pml ob1 --mca btl vader,tcp,self \
  --mca btl_tcp_if_exclude lo,docker0,virbr0 \
  --map-by numa:pe=${OMP_NUM_THREADS} --bind-to core --report-bindings \
  -x ROOTDIR -x PATH -x LD_LIBRARY_PATH -x PYTHONPATH -x CONDA_PREFIX \
  -x OMP_NUM_THREADS -x OMP_PROC_BIND -x OMP_PLACES -x OMP_DYNAMIC \
  -x OPENBLAS_NUM_THREADS -x MKL_NUM_THREADS -x CUDA_VISIBLE_DEVICES \
  python ./projects/des_cluster/EXAMPLE_EMUL2_MINIMIZE1.py --nstw 200 --outroot hybrid_multinode

For a Planck likelihood add -x CLIK_PATH -x CLIK_DATA -x CLIK_PLUGIN when those variables are defined. Follow the cluster's MPI module and Slurm launch policy; do not oversubscribe a production allocation. Outside Slurm, supply the hosts and slots with the cluster's --hostfile or --host recipe.

Exploring notebooks

Armadillo was chosen to make a convenient Python API for notebook exploration. This C++ library provides vectors, matrices and three-dimensional arrays called cubes. A small interface layer connects them to NumPy through pybind11, with CARMA handling array conversion. The notebooks expose intermediate quantities; production calculations use the CLI interfaces.

These steps assume Cocoa and this project are installed, the Cocoa Conda environment is active, the shell is Bash, and the current folder is cocoa/Cocoa/.

Compile the project first; the covariance notebook also needs the optional covariance build described below.

Step 1️⃣: activate Cocoa.

source start_cocoa.sh

Step 2️⃣: Select the number of OpenMP cores (below, we set it to 8).

  • Linux

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=close; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    
  • macOS (arm)

    export OMP_NUM_THREADS=8; export OMP_PROC_BIND=disabled; \
    export OMP_PLACES=cores; export OMP_DYNAMIC=FALSE; \
    export OPENBLAS_NUM_THREADS=1; export MKL_NUM_THREADS=1
    

Step 3️⃣: start Jupyter.

jupyter notebook --no-browser --port=8888

Step 4️⃣: open the printed URL and choose a notebook below.

Step 5️⃣: select Kernel → Restart Kernel and Run All Cells.

Notebook Contents
EXAMPLE_EVALUATE1.ipynb The 4x2pt + N cluster observables at the fiducial point, their halo-model ingredients, and their response to the mass-observable relation, through the project wrappers; inspect the setup cells before running.
EXAMPLE_EVALUATE2.ipynb 6x2pt + N parameter sweeps, the baryonic-feedback study with the bfmt theory block (six methods, a $\chi^2$ table and a per-block shift table), the angular binning and the accuracy setting, through the project wrappers; inspect the setup cells before running.
EXAMPLE_EVALUATE_COVARIANCE.ipynb G, SSC, cNG, total, separate 1h–4h matter trispectra and matrix diagnostics.
flowchart TD
  A["Compile the project, start Jupyter"] --> B["EXAMPLE_EVALUATE1.ipynb: 4x2pt + N observables"]
  B --> C["EXAMPLE_EVALUATE2.ipynb: 6x2pt + N sweeps and bfmt feedback"]
  A --> D["Covariance build"]
  D --> E["EXAMPLE_EVALUATE_COVARIANCE.ipynb: joint forecast"]
  W["Notebook wrappers: interface/"] --> B
  W --> C
  P["Plotting functions: plot_datavectors_cluster and cnu"] --> B
  P --> C
  F["bfmt block and its emulators"] --> C
  E --> G["Covariance guide: covariance/README.md"]
Loading

Read EXAMPLE_EVALUATE1.ipynb first: it introduces each cluster observable that EXAMPLE_EVALUATE2.ipynb then varies. The covariance notebook needs the optional covariance build and continues in the covariance guide.

Choose the Python kernel from the activated Cocoa environment and restart it after recompiling. The covariance guide explains the forecast files, figures and refinement workflow.

The notebook EXAMPLE_EVALUATE1.ipynb computes the cluster observables at the fiducial point with the options of EXAMPLE_EVALUATE1.yaml (4x2pt + N) and compares them with the synthetic data where the scale cuts keep them. It covers, in this order: the cluster counts per richness and redshift bin; the halo-model ingredients (the probability of a richness bin given the halo mass, the number density and the bias of each richness bin, the redshift selection kernels, the one-halo cluster-matter power spectrum); cluster lensing, both as $\gamma_t$ and as the $\Sigma = Y\gamma_t$ statistic of the data vector; $w_{cc}$; $w_{cg}$; the non-Limber $w_{cc}$ and $w_{cg}$ against their Limber versions; the Limber spectra $C_\ell^{cs}$, $C_\ell^{cc}$, and $C_\ell^{cg}$; the response of the counts and of $\gamma_t$ to the mass-observable relation; and the $\chi^2$ against the synthetic data vector.

The notebook EXAMPLE_EVALUATE2.ipynb runs 6x2pt + N with the options of EXAMPLE_EVALUATE2.yaml, in the form of parameter sweeps. It computes a reference model at the fiducial point, then varies one parameter at a time (five values each) and shows every block as a ratio to the reference, with the curves colored by the parameter value. The sweeps cover $\Omega_m$ and $A_s$; two parameters of the mass-observable relation ($\ln\lambda_0$ and $\sigma_{\rm int}$); and two parameters of the selection bias ($b_{s2}$ and $r_0$). The $\Omega_m$ sweep also shows the 3x2pt blocks ($\xi_\pm$, galaxy-galaxy lensing, and $w(\theta)$).

The section Baryonic feedback from the bfmt theory block follows. For six methods (the three SP(k) relations, BCEmu, Flamingo and BCemu2025) it computes the suppression $S(k,z)$ with get_baryon_suppression and the joint data vector with compute_probes, and prints two tables over the 1,429 entries the 6x2pt + N mask keeps. The first gives each method's $\chi^2$ against the synthetic data vector; the $\chi^2$ of the shift between the predictions with and without feedback runs from 4.11 (SP(k) power law) down to 0.04 (BCemu2025). The second gives, per block, the largest shift of a kept entry in units of its error, $\max_i\lvert m_i-m_i^{\rm none}\rvert/\sqrt{C_{ii}}$: it is 0 for the counts with every method, because the mass function reads the linear cold dark matter + baryon power that feedback leaves unchanged, and it reaches 0.72 in galaxy-galaxy lensing (SP(k) power law). Two figures show the cluster tangential shear and $\xi_+$ as ratios to the prediction without feedback. The section needs the bfmt block and the SP(k), BCEmu and FLAMINGO emulators, which Cocoa's setup installs unless IGNORE_BFMT_CODE, IGNORE_PYSPK_CODE, IGNORE_BCEMU_CODE or IGNORE_FBRE_CODE is set in set_installation_options.sh.

The notebook then changes the number of angular bins and the accuracy setting of cosmolike, and ends with the $\chi^2$ against the synthetic data vector.

Note

The notebooks load their support functions from two places. The functions shared by all projects (the CAMB run packaged for cosmolike, the plotting functions) come from Cocoa/external_modules/code/cosmolike_core/cosmolike_notebook_utils/. The functions specific to this project (fiducial values, the compiled-interface calls, the cluster observables) come from interface/cosmolike_des_cluster_notebook_wrappers.py.

The plotting functions

Every data-vector figure of the two notebooks comes from a plotting function. The cluster blocks use plot_datavectors_cluster.py of cosmolike_notebook_utils, the cluster version of the functions the other projects use for the galaxy blocks. The module is imported on its own:

from cosmolike_notebook_utils import plot_datavectors_cluster as pdc
function panels curves inside a panel
plot_N_cluster one per cluster z bin; the x axis is the richness one staircase per model
plot_gammat_cluster_tomo, plot_sigma_cluster_tomo, plot_C_cs_tomo_limber one per (cluster z bin, source bin) pair: columns are cluster z bins, rows are source bins the richness bins
plot_wcc_tomo, plot_C_cc_tomo_limber one per cluster z bin the richness pairs (by default the auto pairs)
plot_wcg_tomo, plot_C_cg_tomo_limber one per (cluster z bin, lens bin) pair of the dataset the richness bins

The functions follow the conventions of the galaxy functions. They take a list of models; param and colorbarlabel color the list by a parameter value; a reference (the *_ref argument) turns every panel into the fractional difference to it; rescale = 1 joins the panels on one y axis, with one power of ten per panel; and show = None returns the figure. The cluster blocks have one more index than the galaxy blocks, the richness bin. The richness bins are curves inside each panel: the color follows the model and the line style follows the richness bin. The argument richness (pairs for $w_{cc}$) selects the bins to draw, counted from 0. The argument data overlays the data vector with its errors and leaves out the points the scale cuts remove. The 3x2pt blocks use the galaxy functions cnu.plot_xi, cnu.plot_gammat_tomo_limber, and cnu.plot_wtheta_tomo. The docstrings of the module document every argument.

The notebook wrappers

The wrappers module drives the compiled interface through the same steps as the likelihoods: it runs CAMB once, pushes the power spectra, growth, and distances into the interface, sets the nuisance parameters, and reads off an observable. Its usage is

import cosmolike_des_cluster_notebook_wrappers as nw
nw.configure(cluster_ytransform=1)       # optional: the yaml options, before init_cosmolike
nw.init_cosmolike(CLprobe="6x2pt_N", with_data=True)
N = nw.N_cluster()                       # (richness bin, z bin)
theta, gammat = nw.gamma_t_cluster()     # (theta, richness, z, source)
nw.get_chi2(omegam=0.31)
function returns
configure(**overrides) nothing; sets the values that mirror the likelihood yaml (lmax, integration_accuracy, the cluster_* switches, the data path). Call it before init_cosmolike
init_cosmolike(CLprobe, with_data, lmax) the parsed dataset file; runs the init sequence of the likelihood. with_data=True also loads the mask, the data vector, and the covariance, which get_datavector and get_chi2 need
dataset_info() the binning and the bin edges of the loaded dataset
N_cluster() cluster counts, array (richness bin, cluster z bin)
gamma_t_cluster() (theta, gammat): cluster tangential shear before the Y transform, the selection bias, and the shear calibration; array ($\theta$, richness bin, cluster z bin, source bin)
sigma_cluster() (theta, sigma): cluster lensing as the data vector holds it, without the mask; same array layout
w_cc(selection_bias) (theta, wcc): array ($\theta$, richness bin 1, richness bin 2, cluster z bin)
w_cg(selection_bias) (theta, wcg): array ($\theta$, richness bin, cluster z bin, lens bin)
C_cs_tomo_limber(ell), C_cc_tomo_limber(ell), C_cg_tomo_limber(ell) the Limber spectra at the multipoles ell, with the layouts above and $\ell$ on the first axis
xi(), gamma_t(), w_theta() the 3x2pt blocks in real space: (theta, xi_plus, xi_minus), (theta, gammat), and (theta, wtheta), in the array layouts of the galaxy plotting functions
prob_richness_bin_given_m(M, z) probability of each richness bin given the halo mass (M200m, in $M_\odot/h$) and the redshift
ncl_richness(z), bcl_richness(z) comoving number density, in $(h/{\rm Mpc})^3$, and richness-weighted linear bias of each richness bin
pcm_1h_richness(k, z) one-halo cluster-matter power spectrum of each richness bin, in $({\rm Mpc}/h)^3$, with k in $h/{\rm Mpc}$
phi_cluster(z) the selection kernels $\langle\phi_i\vert z\rangle$ of the cluster redshift bins
nz_cluster(z), W_cluster(z) the normalized true-redshift distribution and the radial kernels of the cluster bins
get_datavector(), get_chi2() the masked joint theory vector and its $\chi^2$ against the loaded data
cluster_blocks(vector), data_cluster_blocks() the cluster blocks (counts, cluster lensing, $w_{cc}$, $w_{cg}$) of a joint vector, or of the data and their errors, as arrays in the layouts above. Entries that the mask removes or that the data vector does not hold are NaN
get_baryon_suppression(theory_options, point, z_grid, log10k_grid) the suppression $S(k,z)$ of the bfmt theory block as {z: S}, one array over $k$ per redshift, with $k$ in 1/Mpc; it builds a minimal Cobaya model (CAMB, bfmt, and the one likelihood) at the fiducial cosmology
compute_probes(sup=None) every block at the fiducial point in the layouts above (N, sigma, gammat_cluster, wcc and wcg with the selection bias, xi, gammat, wtheta), the masked joint vector dv, its chi2, and the grids z_grid and log10k_grid ($k$ in 1/Mpc) of the CAMB tables; with sup, $\ln S$ is added to a copy of the nonlinear $\ln P$ table, as the likelihood does. Requires init_cosmolike(with_data=True)

get_baryon_suppression and compute_probes run at the fiducial point only. Every other wrapper that computes a model takes the cosmology (omegam, omegab, H0, ns, As_1e9, w, w0pwa, mnu), the accuracy settings, and the nuisance vectors (M, A1, B1, MOR, SEL, ...) as keyword arguments, and falls back to the project fiducial point, which the module holds as plain constants. For example, nw.N_cluster(MOR=[4.3, 0.943, 0.15, 0.207]) changes the mass-observable relation for one call. Each wrapper sets the complete state of the interface on every call, so no call depends on which wrapper ran before it; the module keeps the last CAMB run, so repeated calls at one cosmology cost one CAMB run. The docstrings of the module document every argument and array layout.

Likelihood options and nuisance parameters

The defaults of the two likelihoods are in likelihood/combo_4x2pt_N.yaml and likelihood/combo_6x2pt_N.yaml; the examples repeat the keys discussed below. The model follows arXiv:2503.13631 (the equation numbers below are those of that paper):

  • The counts (eq. 16) use the Tinker mass function and halo bias (M200m) and a lognormal mass-observable relation (eqs. 18-19, pivot mass $5\times10^{14},M_\odot/h$).
  • The cluster-lensing spectrum is the sum of a two-halo term (richness-weighted cluster bias times the nonlinear matter power spectrum) and a one-halo NFW term (eq. 22). The data vector holds $\Sigma = Y\gamma_t$, the Y transform of eq. 15, which involves no critical surface density. The last angular bin of every cluster-lensing row vanishes by construction and is always masked.
  • $w_{cc}$ and $w_{cg}$ use a linear cluster bias times the nonlinear matter power spectrum. Below $\ell = 150$ they are computed without the Limber approximation and with redshift-space distortions, as the original CosmoLike code (lighthouse) and the DES analyses compute them (cluster_adopt_limber_cc: 0, cluster_adopt_limber_cg: 0).
  • The selection bias (eq. 23) multiplies the data vector: $\Sigma$ and $w_{cg}$ by $b_{s1} + b_{s2}\exp(-\theta\chi(\bar z)/r_0)$, and $w_{cc}$ by its square.
  • The real-space statistics are full-sky, bin-averaged Legendre projections.

Cluster options

key default meaning
cluster_kernel_mode 0 radial kernel of the clusters in the two-point functions: 0 = volume only, $dV/dz,\langle\phi_i\vert z\rangle$ (what DES ran); 1 = abundance weighted
cluster_selection_model 2 selection bias: 0 = none; 1 = Y1, mass dependent, inside the bias mass integral; 2 = Y6, scale dependent, on the data vector (eq. 23)
cluster_ytransform 1 cluster lensing: 1 = $\Sigma = Y\gamma_t$ (eq. 15); 0 = $\gamma_t$. The data and covariance files must be in the same space
cluster_include_ia 1 1 = intrinsic alignment of the sources in the two-halo cluster-lensing term
cluster_magnification -2.0 cluster magnification coefficient $C_c$ (eq. 28); 0 switches it off
cluster_hmf_alpha_mode 0 amplitude of the Tinker 2010 mass function: 0 = 0.368 at every redshift (what DES ran); 1 = the redshift-dependent amplitude of halo.c (3-9% fewer clusters at z = 0.2-0.6)
cluster_adopt_limber_cc, cluster_adopt_limber_cg 0 $w_{cc}$ and $w_{cg}$: 0 = below $\ell = 150$, the exact projection of each cluster and lens field (spherical Bessel functions, by FFTLog) with its redshift-space distortion and magnification terms, joined to the Limber spectra through the method of Fang et al. (arXiv:1911.11947); 1 = Limber at every multipole. At the largest angles the two differ by up to 67% in the highest cluster redshift bin, where the bins are thinnest

All halo statistics use cold dark matter plus baryons (cb). Massive neutrinos free-stream out of halos, so the variance integrates CAMB's delta_nonu spectrum at the requested redshift, and the Lagrangian smoothing radius and mass-function density use $\rho_{cb}=\rho_{crit}(\Omega_m-\Omega_\nu)$. FFTLog tabulates $\sigma^2_{cb}(M,a)$ and its mass slope; no scale-independent growth factor is applied to a present-day variance. The Bhattacharya concentration uses $D_{cb}(M,a)=\sigma_{cb}(M,a)/\sigma_{cb}(M,1)$ in its $D^{1.15}$ factor. This is the adopted neutrino extension of that fit, which was not calibrated with massive neutrinos.

The NFW truncation radius still defines an M200m halo relative to the total mean density. The lensing mass weight $M/\rho_m$, lensing kernels, and nonlinear matter spectra also retain total matter. The likelihood always supplies $\Omega_\nu h^2$ and the cb spectrum.

The shipped synthetic data and covariance were computed with this cb-variance calculation (regenerated on 2026-11-04), so the model reproduces the data vector at the fiducial point.

The EMUL2 path has no separate cb spectrum and retains the approximation $P_{cb}=P_{lin}/(1-f_\nu)^2$, with $f_\nu=\Omega_\nu/\Omega_m$ and fixed neutrino mass 0.06 eV. This is the small-scale limit of the spectrum ratio; its counts error against a true cb-spectrum emulator has not been measured.

Three more keys matter for the cluster combinations:

  • integration_accuracy: 1. The cluster combinations run with 1, while the value 0 is not accurate enough for the Y6-like inputs: the tails of the MagLim lens redshift distributions reach z = 2.99. The accuracy sweep tests/validation/knob_sweep.py measured $\Delta\chi^2 = 1.65$ against high-accuracy settings at 0 (galaxy-galaxy lensing 0.92, galaxy clustering 0.47) and $\Delta\chi^2 = 0.048$ at 1, for about 30% more cosmolike time. The cluster blocks contribute $\Delta\chi^2 = 6\times10^{-3}$ either way.
  • accuracyboost. Keep it at 3 or below, as the warning in the likelihood files says: the accuracy sweep reaches boost 2, and larger values have not been measured on the cluster combinations.
  • IA_model: 0. The intrinsic-alignment model is NLA: the cluster lensing code has no TATT.

Galaxy clustering is non-Limber below $\ell = 150$ (adopt_limber_gg: 0), and galaxy-galaxy lensing is Limber (adopt_limber_gs: 1). The likelihoods refuse baryon PCAs with clusters.

Nuisance parameters

The nuisance parameters and their priors come from the likelihood defaults likelihood/params_cluster.yaml, likelihood/params_lens_maglim.yaml, and likelihood/params_source_y6.yaml, so the examples do not list them in their params block. The fiducial values are those of Table I of arXiv:2503.13631, the point of the synthetic data vector.

Clusters (params_cluster.yaml):

name meaning fiducial prior
DES_CL_LNLAMBDA0 $\ln\lambda_0$, amplitude of the mass-observable relation (eq. 19) 4.26 flat [2, 5]
DES_CL_A_LAMBDA $A_{\ln\lambda}$, slope of the relation in $\ln M$ 0.943 flat [0.1, 1.5]
DES_CL_B_LAMBDA $B_{\ln\lambda}$, slope of the relation in $\ln(1+z)$ 0.207 flat [-5, 5]
DES_CL_SIGMA_INT $\sigma_{\rm int}$, intrinsic scatter of the relation (eq. 18) 0.15 flat [0.1, 1]
DES_CL_BS1 $b_{s1}$, selection bias (eq. 23) 1.1 flat [1, 2]
DES_CL_BS2 $b_{s2}$, selection bias (eq. 23) 0.2 flat [-1, 1]
DES_CL_R0 $r_0$, scale of the selection bias, in comoving ${\rm Mpc}/h$ 30 flat [10, 60]
DES_CL_BSZ power of $(1+\bar z)/1.45$ multiplying the selection factor; 0 is the paper's model 0 fixed

Sources (params_source_y6.yaml):

name meaning fiducial prior
DES_DZ_S1 ... DES_DZ_S4 photo-z shift of each source bin 0.034, 0.028, 0.011, -0.010 Gaussian, width 0.018, 0.013, 0.006, 0.013
DES_M1 ... DES_M4 shear calibration of each source bin 0 Gaussian, width 0.008, 0.013, 0.009, 0.012
DES_A1_1 NLA amplitude $a_1$ 0 flat [-5, 5]
DES_A1_2 NLA redshift power $\eta_1$ 0 Gaussian, width 3
DES_A2_1, DES_A2_2, DES_BTA_1 TATT terms, unused under NLA 0, 0, 1 fixed

MagLim lenses (params_lens_maglim.yaml):

name meaning fiducial prior
DES_DZ_L1 ... DES_DZ_L6 photo-z shift of each lens bin 0.005, 0.003, 0.001, -0.002, 0.001, 0.008 Gaussian, width 0.007, 0.011, 0.006, 0.006, 0.01, 0.01
DES_B1_1 ... DES_B1_6 linear galaxy bias of each lens bin 1.42, 1.66, 1.70, 1.62, 1.78, 1.75 flat [0.8, 3]
DES_PM1 ... DES_PM6 point mass of galaxy-galaxy lensing, in units of $10^{13},M_\odot/h$ 0 flat [-100, 100]
DES_BMAG_1 ... DES_BMAG_6 magnification coefficient of each lens bin -1.57, -1.70, -0.25, 1.50, 2.22, 2.80 fixed
DES_DZ2_L1 ... DES_DZ2_L6 photo-z stretch of each lens bin 1 fixed
DES_B2_1 ... DES_B2_6 nonlinear galaxy bias (the model is linear bias) 0 fixed

4x2pt + N uses lens bins 1-3 only and has no galaxy-galaxy lensing block, so combo_4x2pt_N.yaml fixes the bias and the photo-z shift of lens bins 4-6 at their fiducial values and the six point masses at zero (its fixed_params block): these parameters enter only blocks that the 4x2pt + N mask removes. 6x2pt + N samples the bias and the photo-z shift of all six bins and the six point masses. The clusters have no photo-z nuisance parameter: their redshift selection enters through the fixed kernels $\langle\phi_i|z\rangle$ of data/des_y6_cluster.nz.

likelihood/README.md lists, for every likelihood of this project, what its fixed_params block fixes and which parameters it must not vary, with the reason for each.

The fiducial cosmology of the synthetic data is As_1e9 = 2.19, ns = 0.96859, H0 = 69, omegab = 0.048, omegam = 0.3, $\Omega_\nu h^2 = 0.00083$ (mnu = 0.077 eV), and $w = -1$.

Synthetic data

The synthetic data set is Y6-like in the following sense: the lens and source redshift distributions are the n(z) files of the DES Y6 code comparison kept in the repository of the original CosmoLike cluster code (lighthouse), the binning and the scale cuts are those of arXiv:2503.13631, the parameters are those of its Table I, and the survey area is 4143 deg$^2$ (the DES Y3 cluster footprint of arXiv:2503.13632). The data vector is the model of this code at that point, without noise. The covariance is Gaussian: for the two-point blocks, the full-sky, bin-averaged Gaussian term with shape and shot noise (with the Y transform applied to the cluster-lensing rows); for the counts, Poisson plus sample variance. Its spectra are those of the likelihood: below $\ell = 150$ the clustering spectra of $w_{gg}$, $w_{cc}$ and $w_{cg}$ are non-Limber with redshift-space distortions (computed by the Python reference with spherical Bessel functions, not by FFTLog), and every other spectrum is Limber. The cross-covariance between the counts and the two-point blocks is zero, and the covariance has no super-sample and no trispectrum term. The signal-to-noise of the data vector is 110 for 4x2pt + N and 157 for 6x2pt + N. The files were last regenerated on 2026-11-04, with the cb variance of the halo model and the non-Limber $w_{cc}$ and $w_{cg}$; against the previous files (Limber $w_{cc}$ and $w_{cg}$) the data vector moved by $\Delta\chi^2 = 4.1$ under either mask.

Files

The files of data/ that the cluster likelihoods read:

file content
des_cluster_y6.dataset the base dataset descriptor: file names, binning, cluster redshift and richness edges, survey area, and the lens bin paired with each cluster redshift bin in $w_{cg}$
des_cluster_y6_4x2ptN.dataset, des_cluster_y6_6x2ptN.dataset the descriptors the likelihoods load: the base descriptor with the mask of each combination
des_cluster_y6.datavector the joint synthetic data vector (2812 entries; columns: index, value)
des_cluster_y6_cov.npy the joint covariance: the upper triangle with the diagonal, row by row, as a binary float64 NumPy array (32 MB; cosmolike reads it directly, and numpy.load returns the packed triangle). Stored with Git LFS
des_cluster_y6_4x2ptN.mask, des_cluster_y6_6x2ptN.mask the scale-cut masks of the two combinations
des_y6_maglim.nz, des_y6_source.nz redshift distributions of the six MagLim lens bins and of the four source bins. The z column holds left bin edges (photoz_zmid_convention: 0)
des_y6_cluster.nz the selection kernels $\langle\phi_i\vert z\rangle$ of the three cluster redshift bins: the probability that a cluster at true redshift z lands in each $z_\lambda$ bin. It is a probability, not a normalized distribution, and it is sampled at z (no half-cell offset): the dataset key cluster_zmid_convention = 1. A table that lists left cell edges instead, as the DES and lighthouse tables do, needs cluster_zmid_convention = 0, and each value then belongs half a cell higher
y3_redmapper_counts.txt the DES Y3 redMaPPer counts per redshift and richness bin, from the public Y3 catalog. The model does not read it: make_synthetic_data.py compares the model counts with it, and make_cluster_mask.py reads it for an optional cut on $w_{cc}$ that is off by default

Two dataset keys are optional:

  • cluster_area_file: a table of the survey area of the cluster sample (columns z and deg$^2$). A volume-limited cluster sample loses the parts of the footprint that are too shallow to detect clusters at redshift z, so its area falls at high z; with the key, the counts integrate that area. Without it, the counts use survey_area_deg2 at every redshift, the setting of the synthetic data and of forecasts. In the Cardinal simulation of the DES Y6 analysis the area falls to 69% at z = 0.65 and 8% at z = 0.75, and the constant area overestimates the counts of the 0.55-0.65 bin by 15%.
  • cluster_zmid_convention: what the z column of nz_cluster_file means (default 1, sample points; 0, left cell edges), with the encoding of the galaxy photoz_zmid_convention.

The remaining files (des_y3_real.dataset, des_y3_unblinded_final.txt, des_y3_cov_unblinded_final.txt, des_y3_lens.nz, des_y3_source.nz, 3x2pt_baseline.mask, ones.mask, pca.txt, baryons_logPkR.h5) are a copy of the DES Y3 3x2pt data set of the project des_y3. The galaxy-only likelihoods of this project (cosmic_shear, combo_3x2pt, combo_2x2pt) point at it, as do their examples EXAMPLE_EVALUATE3.yaml (cosmic shear) and EXAMPLE_EVALUATE4.yaml (3x2pt) and their unit tests; the cluster likelihoods do not use it.

The scale cuts are defined at the mean redshift of each bin, at the fiducial cosmology: a point survives when its angle exceeds $R/\chi(\bar z)$, with $R = 2,{\rm Mpc}/h$ for cluster lensing, $8,{\rm Mpc}/h$ for $w_{cg}$ and $w_{gg}$, $16,{\rm Mpc}/h$ for $w_{cc}$, and $6,{\rm Mpc}/h$ for galaxy-galaxy lensing; cosmic shear uses a table of minimum angles per source pair. In cluster lensing, a (cluster bin, source bin) pair is masked entirely when the cluster bin's upper edge lies above the mean redshift of the source bin.

Regenerating the data

The scripts are in scripts/. The commands below assume the Conda cocoa environment is active, start_cocoa.sh was sourced, and the current folder is the cocoa main folder cocoa/Cocoa. Each script documents its options in its header.

step script writes notes
1 make_des_y6_nz.py des_y6_maglim.nz, des_y6_source.nz converts the lens and source n(z) of the DES Y6 code comparison of the lighthouse repository to the cosmolike n(z) format. The default input path is a local checkout of that repository: pass --lens-in and --source-in
2 make_cluster_zdist.py des_y6_cluster.nz tabulates the selection kernels for a Gaussian cluster photo-z of width $0.006,(1+z)$ on a uniform grid (--edges, --sigma0, --sigma-per-bin, --tophat)
3 make_y3_redmapper_counts.py y3_redmapper_counts.txt tabulates the counts of the public DES Y3 redMaPPer catalog (--h5 or --npz)
4 make_cluster_mask.py the two masks applies the scale cuts above; the radii, the rule for the bin angle, and the choice of $\bar z$ are options
5 make_synthetic_data.py des_cluster_y6.datavector, des_cluster_y6_cov.npy computes the data vector with the compiled code and the covariance with the Python reference (tests/reference/ref_covariance_full.py), checks the layout, the positive definiteness of the covariance under each mask, and the signal-to-noise per block, and asserts $\chi^2 < 10^{-6}$ at the fiducial for both combinations
6 make_example_files.py the MCMC and EXAMPLE_EMUL2 YAML examples see below

For example, steps 4 and 5 are

python ./projects/des_cluster/scripts/make_cluster_mask.py

and

python ./projects/des_cluster/scripts/make_synthetic_data.py --threads 3

The two evaluate examples EXAMPLE_EVALUATE1.yaml and EXAMPLE_EVALUATE2.yaml are written by hand and are the source of the cluster examples. The script make_example_files.py derives the YAML examples from them (EXAMPLE_MCMC1.yaml, EXAMPLE_MCMC2.yaml, and the EXAMPLE_EMUL2 evaluate, MCMC, PolyChord and benchmark files), so these files cannot drift apart. Run its steps one at a time:

python ./projects/des_cluster/scripts/make_example_files.py evaluate
python ./projects/des_cluster/scripts/make_example_files.py samplers
python ./projects/des_cluster/scripts/make_example_files.py bench

It reads the emulator and sampler blocks from the projects des_y3 and desy1xplanck, which must be installed. The script examples EXAMPLE_EMUL2_{MINIMIZE,PROFILE,NAUTILUS}{1,2}.py are short launchers of cocoa_hybrid_sampling.py that read EXAMPLE_EMUL2_EVALUATE<n>.yaml when they run, so they follow the derived YAML without being rewritten; the script's scripts step stops with a ValueError on such launchers, and its default step, all, therefore stops before the benchmark files (the docstring of the script describes each step). EXAMPLE_EVALUATE3.yaml, EXAMPLE_EVALUATE4.yaml and EXAMPLE_EVALUATE_COVARIANCE.yaml are hand-written, and the script does not touch them.

Note

A change to the data vector, the n(z), the covariance, the examples, or the likelihood defaults also requires refreshing the snapshot of the unit tests (see tests/data_vector/README.md).

Unit tests and validation tools

The tests/ folder compares likelihood predictions against stored reference values, checks for race conditions from OpenMP threading, and measures the numerical error of the default accuracy settings. tests/README.md describes the checks, how to run them, the input data snapshots, and how to refresh them.

Status and known limitations

The port is complete for the model described above: the two likelihoods run, the compiled code is validated against an independent Python reference, and the unit tests cover both combinations. PORT_PLAN.md (section 7) holds the detailed status. The items below are open.

  • The data are synthetic. The supplied data vector is a noiseless fiducial model, and its covariance is analytic Gaussian: it has no count–two-point cross block, SSC or trispectrum term. The separate covariance notebook computes a joint forecast with SSC and a biased-tracer cNG approximation. It does not replace the supplied likelihood covariance or include every discrete-halo term.
  • Non-Limber $w_{cc}$ and $w_{cg}$ differ from the original CosmoLike code in one approximation. That code computes the non-Limber spectrum of the first richness pair of each cluster redshift bin and rescales it by a ratio of cluster biases at the bin midpoint for the other pairs; this code computes every pair from its own radial kernels. Against it, in the Cardinal setup of arXiv:2503.13631, the pair both codes compute exactly agrees to 0.2-1.0%, and the rescaled pairs differ by up to 7% for the richest pair of the highest redshift bin.
  • Cluster lensing has NLA intrinsic alignment only. There is no TATT in the cluster lensing code, and the examples run NLA in every block.
  • Neutrinos in the halo mass function. The cluster combinations use the cold dark matter + baryon prescription described in Cluster options with one massive neutrino state in CAMB, while DES ran three degenerate ones; the two differ by up to 2.6% in the counts at the same $\Omega_\nu h^2$. One state is the convention of the Cosmolike projects. On the emulator path, whose matter power spectrum emulator has no neutrino input, the likelihood approximates the cb spectrum as $P_{lin}/(1 - f_\nu)^2$.
  • Emulated Boltzmann inputs. The emulators of the EMUL2 examples are fixed at a neutrino mass of 0.06 eV. At equal neutrino mass they differ from CAMB by $\Delta\chi^2 = 1.6$ on 6x2pt + N (the cluster counts differ by 1.5% in the median).
  • The Y1 switches are not validated end to end. The options that reproduce the DES Y1 choices (cluster_selection_model: 1, cluster_ytransform: 0, and the magnification and intrinsic-alignment switches) exist, but only the defaults have been validated.
  • No parameter-recovery chain. No MCMC recovers the input parameters from the synthetic data, and no independent review checks the model against the paper.
  • Thread scaling. Going from 4 to 8 threads gains only a factor of 1.4 on 6x2pt + N; the cause has not been measured. Two optimizations of the cluster tables are left (the one-halo table, and the $w_{cc}$ and $w_{cg}$ spectra tables).
  • Angular binning in the compiled interface. cosmolike caches the bin-averaged Legendre kernels by the number of angular bins and the table key, not by the angular range, so a call to init_binning with a new range and the same number of bins returns the values of the old range. The notebook wrappers avoid this by drawing a new table key on every call.
  • No response functions for the cluster blocks. The data-vector plotting functions of cosmolike_notebook_utils have a cluster version (plot_datavectors_cluster.py); the response helpers (plot_response.py) do not.

Computing covariances

The covariance tools compute Gaussian (G), super-sample (SSC), connected non-Gaussian (cNG) and total matrices before scale cuts. The example is a joint 6×2pt + counts forecast whose Gaussian spectra are non-Limber with redshift-space distortions at low multipoles for every pair with a galaxy or cluster leg, as the likelihood's clustering spectra are; SSC and cNG are Limber. covariance/README.md explains compilation, the production CLI, exploratory notebooks, accuracy settings and output files.

Appendix

FAQ: Which accuracy settings are available?

Data-vector options belong to the selected likelihood block. Covariance options belong to the evaluate YAML's covariance block. They use separate names and settings; changing one does not refine the other.

Data-vector setting What it changes
accuracyboost Overall interpolation-table resolution.
integration_accuracy Quadrature resolution; levels 5/6/7 allow 2048/4096/8192 points per Limber panel. Refine independently of interpolation.
internal_accuracyboost C-FAST-PT convolution grid.
nonlimber_accuracyboost Non-Limber distance sampling.
pk_z_refinement Nested redshift refinement of matter-power inputs.
lmax Real-space angular-transform cutoff, where a real-space transform is used.
kmax_boltzmann Requested Boltzmann power range; coordinate it with the theory settings.

adopt_limber_gg and adopt_limber_gs choose a projection approximation. photoz_interpolation_type chooses how n(z) is interpolated, while photoz_zmid_convention describes the input coordinates. These are modeling or input-convention choices, not interchangeable accuracy boosts.

photoz_histogram_akima: 0 retains the original midpoint n(z) reconstruction; 1 selects histogram preparation followed by Akima for source and lens samples. photoz_histogram_akima_factor chooses 3 (default), 5 or 7 preparation cells per original uniform bin. See the reconstruction comparisons and area plots. The selected first factor never changes with an accuracy boost.

The default data-vector power grid has 1,500 wavenumbers at boost 1. Covariance alone uses power_accuracyboost: 8 to prepare 11,993 nodes by natural cubic interpolation before C linear lookup. Its accuracy_boost refines tables and cutoffs; its integration_accuracy independently selects quadrature levels 0–4. See the complete covariance accuracy table.

CAMB's theory.camb.extra_args.AccuracyBoost controls CAMB, not CosmoLike. Check interpolation, quadrature, input-power sampling and transform cutoffs separately at fixed cosmology and measurement bins. Narrow n(z) overlaps particularly require a quadrature check; increasing accuracyboost alone is not that check. The data-vector test guide and covariance test guide state what each sector actually verifies. A passing regression or a larger boost is not a general claim of survey or Fisher convergence.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages