sys_mapping.glass_mocks
Full-sky lognormal galaxy mock generation using the GLASS package (Tessore et al. 2023).
Generates systematic-free galaxy catalogs matched to the BGS LS10 redshift distribution and surface density. The workflow is:
Measure n(z) from a reference catalog (e.g. Uchuu) with
measure_nz().Generate GLASS mock with
generate_glass_fullsky_mock(): a single tophat redshift shell is used; galaxy positions are drawn from a lognormal density field viaglass.positions_from_delta, and redshifts are sampled from the measured \(n(z)\).
Inputs: NSIDE, target \(N_{\rm gal}\), measured \(n(z)\), seed.
Outputs: dict with keys ra, dec, z, ra_rand,
dec_rand, n_total, nside, seed.
Full-sky lognormal galaxy mock generation using GLASS.
Generates systematic-free galaxy catalogs matched to the BGS LS10 redshift
distribution and surface density. The key advantage over the lognormal
generator in mocks.py is that GLASS produces proper full-sky catalogs
without galactic-cut hacks, using the algorithm of Tessore et al. 2023
(arXiv:2302.01942).
Workflow
Measure n(z) from a reference catalog (e.g. Uchuu).
Call
generate_glass_fullsky_mock()with the measured n(z) to produce galaxy and random positions over the full sky.Downstream pipeline code applies the survey footprint mask and injects systematics via
sys_mapping.simulation.
References
Tessore et al. 2023, OJAp, 6, 11. https://arxiv.org/abs/2302.01942 GLASS code: https://github.com/glass-dev/glass
- class sys_mapping.glass_mocks.MockCatalogDict[source]
Bases:
TypedDictDict returned by mock generators — compatible with simulation pipeline.
- sys_mapping.glass_mocks.measure_nz(z_array, z_min, z_max, n_bins=20)[source]
Histogram a redshift array into equal-width bins.
- Parameters:
- Returns:
z_edges – Bin edges (length
n_bins + 1).nz – Galaxy counts per bin (length
n_bins). Galaxies outside [z_min, z_max] are ignored.
- Return type:
Examples
>>> import numpy as np >>> from sys_mapping.glass_mocks import measure_nz >>> rng = np.random.default_rng(0) >>> z = rng.uniform(0.05, 0.26, 10000) >>> edges, nz = measure_nz(z, 0.05, 0.26, n_bins=10) >>> edges.shape (11,) >>> nz.shape (10,) >>> int(nz.sum()) <= 10000 True
- sys_mapping.glass_mocks.generate_glass_fullsky_mock(nside, n_total, z_edges, nz, *, cl_amplitude=0.0005, rand_factor=10, seed=None)[source]
Generate a full-sky lognormal galaxy mock catalog using GLASS.
The mock has the angular clustering statistics of a lognormal random field with the given power spectrum amplitude, and the redshift distribution set by (z_edges, nz).
- Parameters:
nside (int) – HEALPix resolution for the underlying density field.
n_total (int) – Target total number of galaxies. The actual count will be close but not exactly equal (Poisson sampling).
z_edges (ndarray) – Bin edges of the n(z) histogram (length n_bins + 1). The first edge defines z_min and the last edge defines z_max.
nz (ndarray) – Galaxy counts per redshift bin (length n_bins). Used to sample redshifts; does not need to be normalised.
cl_amplitude (float) – Amplitude of the galaxy angular power spectrum C_ℓ at ℓ=1.
rand_factor (int) – Ratio of randoms to data. Default 10 gives accurate Landy-Szalay.
seed (int | None) – Random seed for reproducibility.
- Returns:
MockCatalogDict with keys
ra,dec,z,ra_rand,dec_rand,n_total,nside,seed.
- Return type:
Notes
The returned catalog is full-sky (no footprint mask applied). Downstream code in
sys_mapping.simulationapplies the LSDR10 systematic maps and the survey footprint.Examples
>>> import numpy as np >>> from sys_mapping.glass_mocks import generate_glass_fullsky_mock, measure_nz >>> rng_z = np.random.default_rng(1) >>> z = rng_z.uniform(0.05, 0.26, 5000) >>> z_edges, nz = measure_nz(z, 0.05, 0.26, n_bins=5) >>> cat = generate_glass_fullsky_mock(nside=16, n_total=5000, ... z_edges=z_edges, nz=nz, seed=0) >>> len(cat['ra']) > 0 True >>> cat['ra'].min() >= 0.0 and cat['ra'].max() < 360.0 True >>> cat['dec'].min() >= -90.0 and cat['dec'].max() <= 90.0 True
- sys_mapping.glass_mocks.generate_glass_delta_map(nside, z_max, *, cl_amplitude=0.0005, seed=None)[source]
Generate a single full-sky lognormal overdensity map with GLASS.
Unlike
generate_glass_fullsky_mock(), this returns the field itself (one tophat shell over[0, z_max]) rather than sampled galaxy positions. The map can then be sampled multiple times — e.g. once for a clean catalog and once for a contaminated catalog that shares the same underlying structure — viasample_positions_from_delta().- Parameters:
- Returns:
(12*nside²,) float array — the galaxy overdensity δ in RING ordering, with
near-zero mean and
1 + δ ≥ 0(lognormal field).
- Return type:
Examples
>>> import numpy as np >>> from sys_mapping.glass_mocks import generate_glass_delta_map >>> delta = generate_glass_delta_map(nside=16, z_max=0.3, seed=0) >>> delta.shape (3072,) >>> bool((1.0 + delta).min() >= 0.0) True
- sys_mapping.glass_mocks.sample_positions_from_delta(delta, ngal_per_arcmin2, *, vis=None, bias=1.0, seed=None)[source]
Poisson-sample galaxy positions tracing an overdensity field.
Thin wrapper over
glass.positions_from_delta(). The expected number of galaxies per pixel isngal_per_arcmin2 × vis × (1 + bias·delta). Passing a visibility/footprint map invisrestricts the sample to the survey area without materialising full-sky positions.This is the count-modulation primitive used to inject systematics into the galaxy number density (as opposed to per-galaxy weights): sample once from a clean
deltaand once from a contaminateddelta(seesys_mapping.contamination.apply_contamination()) sharing the same realisation.- Parameters:
delta (ndarray) – (n_pix,) overdensity map (RING ordering). Must satisfy
1 + δ ≥ 0wherevervis > 0; clip beforehand if a contamination model can push it negative.ngal_per_arcmin2 (float) – Target mean galaxy surface density.
vis (ndarray | None) – Optional (n_pix,) visibility map (e.g. survey coverage in
[0, 1]). Pixels withvis = 0are never sampled.bias (float) – Linear bias passed to GLASS (
δ_g = bias · δ). Use1.0to sample directly fromdeltaas an already-biased galaxy overdensity.seed (int | None) – Random seed for reproducibility.
- Returns:
ra, dec
- Return type:
(n_gal,) arrays in degrees.
rais wrapped to[0, 360).
Examples
>>> import numpy as np, healpy as hp >>> from sys_mapping.glass_mocks import generate_glass_delta_map, sample_positions_from_delta >>> nside = 16 >>> delta = generate_glass_delta_map(nside=nside, z_max=0.3, seed=0) >>> vis = np.zeros(hp.nside2npix(nside)); vis[: vis.size // 2] = 1.0 >>> ra, dec = sample_positions_from_delta(delta, 5.0, vis=vis, seed=1) >>> bool(ra.shape == dec.shape and ra.size > 0) True >>> bool(ra.min() >= 0.0 and ra.max() < 360.0) True