02 — Masking
Purpose: Apply point-source and cluster masks to the full-sky HEALPix CIB and tSZ maps.
This notebook implements the two-step masking pipeline described in §2 of the paper:
Point-source masking — uses
get_point_source_mask_in_healpixto identify pixels above the 2 mJy flux threshold in the CIB map at NSIDE=8192, inpaints them with Gaussian noise, then degrades to NSIDE=2048.Cluster masking — uses
get_apodised_mdpl2_cluster_maskwith the halo catalogue from01_halo_catalogue.ipynbto build apodised circular masks around clusters with M500c ≥ 3×10¹⁴ M☉ at NSIDE=2048. Masked pixels are inpainted with Gaussian noise matching the map mean and standard deviation viainpaint_masked_regions.
Inputs:
Full-sky CIB map (Jy/sr):
data/agora_len_mag_cibmap_act_150ghz.fitsFull-sky tSZ map (Compton-y):
data/agora_ltszNG_bahamas80_bnd_unb_1.0e+12_1.0e+18_lensed.fitsHalo catalogue:
data/halo_catalogue/halo_catalogue_m500gt3e14.npy.npz(from01_halo_catalogue.ipynb)
Outputs:
Masked CIB map (μK):
data/cib_150_masked.fitsMasked tSZ map (μK):
data/tsz_150_masked.fits
Key module functions:
foregrounds_diffusion.masking.get_point_source_mask_in_healpixforegrounds_diffusion.masking.get_apodised_mdpl2_cluster_maskforegrounds_diffusion.preprocessing.inpaint_masked_regions
Paper reference: §2 (point-source and cluster masking descriptions).
[12]:
!pip install -e ~/cmb_foregrounds_diffusion/
Obtaining file:///home/apb86/cmb_foregrounds_diffusion
Installing build dependencies ... done
Checking if build backend supports build_editable ... done
Getting requirements to build editable ... done
Preparing editable metadata (pyproject.toml) ... done
Requirement already satisfied: numpy>=1.26 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (1.26.4)
Requirement already satisfied: scipy>=1.11 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (1.17.0)
Requirement already satisfied: torch>=2.10 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (2.10.0)
Requirement already satisfied: torchvision>=0.25 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (0.25.0)
Requirement already satisfied: accelerate>=1.12 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (1.12.0)
Requirement already satisfied: denoising-diffusion-pytorch>=2.2.5 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (2.2.6)
Requirement already satisfied: healpy>=1.19 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (1.19.0)
Requirement already satisfied: astropy>=7.2 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (7.2.0)
Requirement already satisfied: einops>=0.8 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (0.8.2)
Requirement already satisfied: ema-pytorch>=0.7 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (0.7.9)
Requirement already satisfied: pillow>=12.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (12.1.1)
Requirement already satisfied: pytorch-fid>=0.3 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (0.3.0)
Requirement already satisfied: tqdm>=4.67 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from foregrounds_diffusion==0.1.0) (4.67.3)
Requirement already satisfied: packaging>=20.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from accelerate>=1.12->foregrounds_diffusion==0.1.0) (26.0)
Requirement already satisfied: psutil in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from accelerate>=1.12->foregrounds_diffusion==0.1.0) (7.2.2)
Requirement already satisfied: pyyaml in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from accelerate>=1.12->foregrounds_diffusion==0.1.0) (6.0.3)
Requirement already satisfied: huggingface_hub>=0.21.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from accelerate>=1.12->foregrounds_diffusion==0.1.0) (1.4.1)
Requirement already satisfied: safetensors>=0.4.3 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from accelerate>=1.12->foregrounds_diffusion==0.1.0) (0.7.0)
Requirement already satisfied: pyerfa>=2.0.1.1 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from astropy>=7.2->foregrounds_diffusion==0.1.0) (2.0.1.5)
Requirement already satisfied: astropy-iers-data>=0.2025.10.27.0.39.10 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from astropy>=7.2->foregrounds_diffusion==0.1.0) (0.2026.2.9.0.50.33)
Requirement already satisfied: filelock in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (3.24.0)
Requirement already satisfied: fsspec>=2023.5.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (2026.2.0)
Requirement already satisfied: hf-xet<2.0.0,>=1.2.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (1.2.0)
Requirement already satisfied: httpx<1,>=0.23.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (0.28.1)
Requirement already satisfied: shellingham in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (1.5.4)
Requirement already satisfied: typer-slim in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (0.23.1)
Requirement already satisfied: typing-extensions>=4.1.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (4.15.0)
Requirement already satisfied: anyio in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from httpx<1,>=0.23.0->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (4.12.1)
Requirement already satisfied: certifi in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from httpx<1,>=0.23.0->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (2026.1.4)
Requirement already satisfied: httpcore==1.* in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from httpx<1,>=0.23.0->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (1.0.9)
Requirement already satisfied: idna in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from httpx<1,>=0.23.0->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (3.11)
Requirement already satisfied: h11>=0.16 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from httpcore==1.*->httpx<1,>=0.23.0->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (0.16.0)
Requirement already satisfied: sympy>=1.13.3 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (1.14.0)
Requirement already satisfied: networkx>=2.5.1 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (3.6.1)
Requirement already satisfied: jinja2 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (3.1.6)
Requirement already satisfied: cuda-bindings==12.9.4 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (12.9.4)
Requirement already satisfied: nvidia-cuda-nvrtc-cu12==12.8.93 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (12.8.93)
Requirement already satisfied: nvidia-cuda-runtime-cu12==12.8.90 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (12.8.90)
Requirement already satisfied: nvidia-cuda-cupti-cu12==12.8.90 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (12.8.90)
Requirement already satisfied: nvidia-cudnn-cu12==9.10.2.21 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (9.10.2.21)
Requirement already satisfied: nvidia-cublas-cu12==12.8.4.1 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (12.8.4.1)
Requirement already satisfied: nvidia-cufft-cu12==11.3.3.83 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (11.3.3.83)
Requirement already satisfied: nvidia-curand-cu12==10.3.9.90 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (10.3.9.90)
Requirement already satisfied: nvidia-cusolver-cu12==11.7.3.90 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (11.7.3.90)
Requirement already satisfied: nvidia-cusparse-cu12==12.5.8.93 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (12.5.8.93)
Requirement already satisfied: nvidia-cusparselt-cu12==0.7.1 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (0.7.1)
Requirement already satisfied: nvidia-nccl-cu12==2.27.5 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (2.27.5)
Requirement already satisfied: nvidia-nvshmem-cu12==3.4.5 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (3.4.5)
Requirement already satisfied: nvidia-nvtx-cu12==12.8.90 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (12.8.90)
Requirement already satisfied: nvidia-nvjitlink-cu12==12.8.93 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (12.8.93)
Requirement already satisfied: nvidia-cufile-cu12==1.13.1.3 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (1.13.1.3)
Requirement already satisfied: triton==3.6.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from torch>=2.10->foregrounds_diffusion==0.1.0) (3.6.0)
Requirement already satisfied: cuda-pathfinder~=1.1 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from cuda-bindings==12.9.4->torch>=2.10->foregrounds_diffusion==0.1.0) (1.3.4)
Requirement already satisfied: mpmath<1.4,>=1.1.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from sympy>=1.13.3->torch>=2.10->foregrounds_diffusion==0.1.0) (1.3.0)
Requirement already satisfied: MarkupSafe>=2.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from jinja2->torch>=2.10->foregrounds_diffusion==0.1.0) (3.0.3)
Requirement already satisfied: typer>=0.23.1 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from typer-slim->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (0.23.1)
Requirement already satisfied: click>=8.0.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from typer>=0.23.1->typer-slim->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (8.3.1)
Requirement already satisfied: rich>=10.11.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from typer>=0.23.1->typer-slim->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (14.3.2)
Requirement already satisfied: annotated-doc>=0.0.2 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from typer>=0.23.1->typer-slim->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (0.0.4)
Requirement already satisfied: markdown-it-py>=2.2.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from rich>=10.11.0->typer>=0.23.1->typer-slim->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (4.0.0)
Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from rich>=10.11.0->typer>=0.23.1->typer-slim->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (2.19.2)
Requirement already satisfied: mdurl~=0.1 in /home/apb86/diffusion_project_env/lib64/python3.11/site-packages (from markdown-it-py>=2.2.0->rich>=10.11.0->typer>=0.23.1->typer-slim->huggingface_hub>=0.21.0->accelerate>=1.12->foregrounds_diffusion==0.1.0) (0.1.2)
Building wheels for collected packages: foregrounds_diffusion
Building editable for foregrounds_diffusion (pyproject.toml) ... done
Created wheel for foregrounds_diffusion: filename=foregrounds_diffusion-0.1.0-0.editable-py3-none-any.whl size=4647 sha256=7e3715cbdae5292835f7559969a51225de89123449fcf771b6b276fe9364ec10
Stored in directory: /tmp/pip-ephem-wheel-cache-5_jou8cm/wheels/ad/05/47/d622ea03cc2c607997f65b7643dab9c4f27fa5f37d82097115
Successfully built foregrounds_diffusion
Installing collected packages: foregrounds_diffusion
Attempting uninstall: foregrounds_diffusion
Found existing installation: foregrounds_diffusion 0.1.0
Uninstalling foregrounds_diffusion-0.1.0:
Successfully uninstalled foregrounds_diffusion-0.1.0
Successfully installed foregrounds_diffusion-0.1.0
[notice] A new release of pip is available: 26.0.1 -> 26.1.1
[notice] To update, run: pip install --upgrade pip
1 Configuration
Key physical parameters:
NSIDE_IN = 8192 — native resolution of the AGORA CIB and tSZ FITS files.
NSIDE_OUT = 2048 — output resolution for patch extraction. Downgrading 8192 → 2048 averages over 16 pixels, suppressing small-scale noise without losing the angular scales of interest (ℓ < 7000 → θ > 1.6′).
PTSRC_THRESH_MJY = 2 — flux density threshold at 150 GHz. Pixel values above 2 mJy/beam are flagged and inpainted before training. This matches the cut applied to the training data filename suffix
_2mJy.M500C_THRESHOLD = 3e14 M☉ — cluster mass threshold. Only clusters above this mass receive an apodised circular mask of radius 3θ₅₀₀.
[ ]:
# get_apodised_mdpl2_cluster_mask loads the filtered halo catalogue, projects
# each cluster to a HEALPix disc of angular radius howmanythetaforclusters × θ_500,
# and applies a raised-cosine apodisation taper to avoid sharp mask edges.
# Returns a float mask in [0, 1] (0 = fully masked, 1 = fully unmasked).
# get_point_source_mask_in_healpix applies a spectral index correction
# (S ∝ ν^α with α = 3 for CIB) to convert the threshold from freq0 to freq,
# then identifies all pixels with corrected flux > threshold_mjy_freq0 [mJy/sr].
# Returns a list of HEALPix pixel indices to mask.
import numpy as np
import healpy as hp
from pathlib import Path
from foregrounds_diffusion.masking import (
get_point_source_mask_in_healpix,
get_apodised_mdpl2_cluster_mask,
get_mdpl2_conversion_factors_K_to_MjyperSr,
get_peak_masks,
inpaint_masked_regions,
)
# Anchor to the project root regardless of where the notebook is launched from
PROJECT_ROOT = Path("/home/apb86/cmb_foregrounds_diffusion")
HPC_WORK = Path("/home/apb86/rds/hpc-work")
CIB_FITS = PROJECT_ROOT / "data" / "agora_len_mag_cibmap_act_150ghz.fits"
TSZ_FITS = PROJECT_ROOT / "data" / "agora_ltszNG_bahamas80_bnd_unb_1.0e+12_1.0e+18_lensed.fits"
HALO_CAT = HPC_WORK / "halo_catalogue" / "halo_catalogue_m500gt3e14.npy.npz"
FREQ = 150. # GHz
PTSRC_THRESH_MJY = 2.0 # mJy threshold at 150 GHz
M500C_THRESHOLD = 3e14 # M_sun
NSIDE_IN = 8192
NSIDE_OUT = 2048
TSZ_SPECTRAL_FACTOR = -0.952 * 2.7255e6 # uK per unit Compton-y at 150 GHz
2 Load raw maps
Read both AGORA full-sky maps from the local FITS files. The CIB map is the lensed, magnification-corrected 150 GHz intensity in Jy/sr. The tSZ map is the lensed non-Gaussian Compton-y parameter from the BAHAMAS hydrodynamical simulation. Loading at native NSIDE = 8192 ensures point-source detection uses the full angular resolution before degrading.
[ ]:
cib_jy_sr = hp.read_map(CIB_FITS)
tsz_y = hp.read_map(TSZ_FITS)
print(f"NSIDE = {NSIDE_IN}, Npix = {hp.nside2npix(NSIDE_IN):,}")
print(f"CIB — min: {cib_jy_sr.min():.4f} max: {cib_jy_sr.max():.4f} std: {cib_jy_sr.std():.4f}")
print(f"tSZ — min: {tsz_y.min():.4f} max: {tsz_y.max():.4f} std: {tsz_y.std():.4f}")
rng = np.random.default_rng(seed=42)
3 Convert CIB units
The raw CIB FITS file is in Jy/sr. get_point_source_mask_in_healpix expects MJy/sr (mega-Jansky per steradian), so we multiply by 10⁻⁶. This unit choice is a historical convention in the AGORA pipeline; the absolute value does not affect the mask geometry, only the threshold comparison.
[15]:
# -------------------------------------------------------------------------
# 2. Convert CIB: Jy/sr → mJy/sr for masking
# -------------------------------------------------------------------------
cib_mjy_sr = cib_jy_sr * 1e-6
4 Point-source mask
get_point_source_mask_in_healpix identifies HEALPix pixels whose inferred flux density (after applying a spectral index correction from freq0 = 150 GHz) exceeds 2 mJy. The returned array of pixel indices is converted to a binary mask (0 = masked, 1 = unmasked). Inpainting with Gaussian noise replaces masked pixels with a locally consistent background, preventing the patch extractor from producing patches with sharp mask edges.
[16]:
# get_point_source_mask_in_healpix applies a spectral index correction
# (S ∝ ν^α with α = 3 for CIB) to convert the threshold from freq0 to freq,
# then identifies all pixels with corrected flux > threshold_mjy_freq0 [mJy/sr].
# Returns a list of HEALPix pixel indices to mask.
# -------------------------------------------------------------------------
# 3. Point-source mask from CIB at full resolution
# -------------------------------------------------------------------------
ptsrc_pixels = get_point_source_mask_in_healpix(
freq=FREQ,
hmap_Mjy_per_sr=cib_mjy_sr,
threshold_mjy_freq0=PTSRC_THRESH_MJY,
freq0=150.,
)
ptsrc_mask = np.ones(hp.nside2npix(NSIDE_IN), dtype=np.float32)
ptsrc_mask[ptsrc_pixels] = 0.
print(f"Point-source mask: {(ptsrc_mask == 0).sum():,} pixels masked "
f"({100 * (ptsrc_mask == 0).mean():.2f}%)")
Point-source mask: 26,154 pixels masked (0.00%)
5 Cluster mask
get_apodised_mdpl2_cluster_mask places a smoothly apodised circular mask of angular radius howmanythetaforclusters × θ₅₀₀ around each cluster in the filtered halo catalogue. The apodisation (raised-cosine taper) prevents ringing artefacts when cutting patches that overlap a cluster boundary. The mask is built directly at NSIDE_OUT = 2048 to avoid the computational cost of working at full resolution.
[17]:
# get_apodised_mdpl2_cluster_mask loads the filtered halo catalogue, projects
# each cluster to a HEALPix disc of angular radius howmanythetaforclusters × θ_500,
# and applies a raised-cosine apodisation taper to avoid sharp mask edges.
# Returns a float mask in [0, 1] (0 = fully masked, 1 = fully unmasked).
# -------------------------------------------------------------------------
# 4. Cluster mask at output resolution (cheaper to build at NSIDE=2048)
# -------------------------------------------------------------------------
cluster_mask = get_apodised_mdpl2_cluster_mask(
nside=NSIDE_OUT,
halo_cat_fname=HALO_CAT,
m500c_threshold=M500C_THRESHOLD,
howmanythetaforclusters=3,
apodise=True,
)
print(f"Cluster mask: sky fraction retained = {cluster_mask.mean():.3f}")
Total clusters to mask: 6686
Deleted outdated persistence file, no further action needed (/home/apb86/.colossus/cache/cosmology/planck15_01025226215067a4148b3ddb0d531324, versions 1.2.10/1.0.0).
0
1000
2000
3000
4000
5000
6000
0
5000
Starting apodisation
Cluster mask: sky fraction retained = 0.987
[ ]:
# Inpaint the point-source mask at full resolution (NSIDE=8192) BEFORE degrading
# to NSIDE=2048. This order matters: degrading masked pixels first would spread
# zero-padding artefacts over a 4× larger angular scale.
# -------------------------------------------------------------------------
# 5. Apply point-source mask at full resolution, then degrade
# -------------------------------------------------------------------------
ptsrc_mask_float = ptsrc_mask.astype(np.float32)
cib_inpainted = inpaint_masked_regions(cib_mjy_sr, ptsrc_mask_float, rng=rng)
tsz_inpainted = inpaint_masked_regions(tsz_y, ptsrc_mask_float, rng=rng)
cib_inpainted_2048 = hp.ud_grade(cib_inpainted, nside_out=NSIDE_OUT)
tsz_inpainted_2048 = hp.ud_grade(tsz_inpainted, nside_out=NSIDE_OUT)
# Also degrade point-source mask itself to check coverage at output resolution
ptsrc_mask_2048 = hp.ud_grade(ptsrc_mask, nside_out=NSIDE_OUT)
ptsrc_mask_2048 = np.clip(ptsrc_mask_2048, 0., 1.)
[ ]:
# -------------------------------------------------------------------------
# 6. Apply cluster mask at NSIDE=2048
# -------------------------------------------------------------------------
cib_masked = inpaint_masked_regions(cib_inpainted_2048 * cluster_mask,
cluster_mask, rng=rng)
tsz_masked = inpaint_masked_regions(tsz_inpainted_2048 * cluster_mask,
cluster_mask, rng=rng)
6 Apply masks and degrade
The two masking operations are applied in sequence at their native resolutions: first the point-source mask (inpainting at NSIDE = 8192 before downgrading to 2048), then the cluster mask (applied at NSIDE = 2048). Inpainting is done after each mask step so that the two masked regions receive independent noise realisations drawn from the correct local statistics.
[20]:
# -------------------------------------------------------------------------
# 7. Convert to physical units
# CIB: MJy/sr → uK at 150 GHz
# tSZ: Compton-y → uK at 150 GHz
# -------------------------------------------------------------------------
conv_K_to_MJyperSr = 375.876
cib_masked_uK = (cib_masked / conv_K_to_MJyperSr) * 1e6
tsz_masked_uK = tsz_masked * TSZ_SPECTRAL_FACTOR
print(f"CIB — min: {cib_masked_uK.min():.4e} max: {cib_masked_uK.max():.4e} uK")
print(f"tSZ — min: {tsz_masked_uK.min():.4e} max: {tsz_masked_uK.max():.4e} uK")
CIB — min: -9.8152e+00 max: 1.2193e+02 uK
tSZ — min: -1.9938e+02 max: 8.3041e+00 uK
[21]:
# -------------------------------------------------------------------------
# 8. Save
# -------------------------------------------------------------------------
hp.write_map(PROJECT_ROOT / "data" / "cib_150_masked.fits", cib_masked_uK.astype(np.float32),
overwrite=True)
hp.write_map(PROJECT_ROOT / "data" / "tsz_150_masked.fits", tsz_masked_uK.astype(np.float32),
overwrite=True)
print("Saved masked maps.")
setting the output map dtype to [dtype('float32')]
setting the output map dtype to [dtype('float32')]
Saved masked maps.
[ ]:
7 Convert to physical units
Convert both channels to µK (micro-Kelvin) so that patch normalisation parameters are physically interpretable:
CIB (MJy/sr → µK): divide by the conversion factor 375.876 K/(MJy/sr) at 150 GHz, then multiply by 10⁶.
tSZ (Compton-y → µK): multiply by the spectral function g(x) = x coth(x/2) − 4 evaluated at x = hν / kT_CMB for 150 GHz, giving g(150 GHz) ≈ −4.031. The negative sign reflects the tSZ decrement below the CMB blackbody at frequencies < 218 GHz.
8 Save masked maps
Write both masked, inpainted, and unit-converted maps as FITS files for use in notebook 03 (03_patch_extraction.ipynb). The CIB output is in µK and the tSZ output is in µK (Compton-y × g factor). These files are the direct inputs to the flat-sky patch extractor.