import numpy as np
import pymaster as nmt
import matplotlib.pyplot as plt
import healpy as hp
Transitioning to v3¶
This notebook illustrates the changes that were made to the API of NaMaster in version 3.0. The code is not meant to be run as-is, but rather to be used as a reference when updating your own code from version 2 to version 3.
Each cell below showcases one of the changes to the API that users should be aware of, and suggests ways to adapt past pipelines to the new API.
1 No beams in catalog-based fields¶
The previous implementation of catalog-based fields allowed users to pass a beam for the field sampled at the positions of the catalog sources. This has been removed in v3, as it didn't seem to be a very useful option. If you were using beams, we suggest that you instead forward-model them into the theoretical predictions against which you will compare your power spectrum measurements.
###############
# Example of v2 code comparing the power spectrum of a field with an assigned beam to a theory spectrum.
# Calculate the catalog spectrum accounting for the beam
f = nmt.NmtFieldCatalog(positions, weights, field, lmax=lmax, beam=beam)
b = nmt.NmtBin.from_lmax_linear(lmax, nlb)
w = nmt.NmtWorkspace.from_fields(f, f, b)
cl_data = w.decouple_cell(nmt.compute_coupled_cell(f, f)).squeeze()
# Calculate the theory spectrum with the beam effect included in the mode-coupling matrix
cl_prediction = w.decouple_cell(w.couple_cell(cl_theory))
# Compare data and prediction
leff = b.get_effective_ells()
plt.plot(leff, cl_data, label='Data')
plt.plot(leff, cl_prediction, label='Theory')
plt.xlabel(r'$\ell$')
plt.ylabel(r'$C_\ell$')
###############
# Equivalent code in v3.
# Calculate the catalog spectrum without a beam
f = nmt.NmtFieldCatalog(positions, weights, field, lmax=lmax)
b = nmt.NmtBin.from_lmax_linear(lmax, nlb)
w = nmt.NmtWorkspace.from_fields(f, f, b)
cl_data = w.decouple_cell(nmt.compute_coupled_cell(f, f)).squeeze()
# Calculate the theory spectrum forward-modelling the beam
cl_prediction = w.decouple_cell(w.couple_cell(cl_theory*beam**2))
# Compare data and prediction
leff = b.get_effective_ells()
plt.plot(leff, cl_data, label='Data')
plt.plot(leff, cl_prediction, label='Theory')
plt.xlabel(r'$\ell$')
plt.ylabel(r'$C_\ell$')
2 Arguments in catalog field constructors reordered¶
The order of arguments in catalog-based fields has been changed to better reflect the ordering used in other parts of the code (e.g. other fields, or different types of catalog-based fields -- NmtFieldCatalog, NmtFieldCatalogMomentum, NmtFieldCatalogClustering).
To adapt old pipelines to this change, the best advice is to simply use keyword arguments to identify all arguments when creating a field. This is in general good advice anyway, given the large number arguments needed to create a general field.
# E.g. instead of:
f = nmt.NmtFieldCatalogMomentum(positions, weights, field, None, None, lmax, mask, spin)
# Use:
f = nmt.NmtFieldCatalogMomentum(positions, weights, field,
positions_random=None, weights_random=None,
lmax=lmax, mask=mask, spin=spin)
3 Changes to Gaussian covariances¶
The two important changes are:
gaussian_covarianceis a method ofNmtCovarianceWorkspace, instead of a standalone function- The spin combinations of a given covariance are determined when creating the associated
NmtCovarianceWorkspace, unless you passall_spins=True.
# Example of v2 code to calculate covariances
f = nmt.NmtField(mask, None, spin=2)
w = nmt.NmtWorkspace.from_fields(f, f, b)
cw = nmt.NmtCovarianceWorkspace.from_fields(f, f, f, f)
cov = nmt.gaussian_covariance(cw, 2, 2, 2, 2,
cl_theory, cl_theory, cl_theory, cl_theory,
w, wb=w)
# The v3 way is simpler:
...
cov = cw.gaussian_covariance(cl_theory, cl_theory, cl_theory, cl_theory,
w, wb=w)
# If you also want e.g. spin-0 fields for the same NmtCovarianceWorkspace, you can do:
f = nmt.NmtField(mask, None, spin=0)
w_spin0 = nmt.NmtWorkspace.from_fields(f, f, b)
cw = nmt.NmtCovarianceWorkspace.from_fields(f, f, f, f, all_spins=True)
cov_spin2 = cw.gaussian_covariance(cl_theory, cl_theory,
cl_theory, cl_theory,
w, wb=w)
cov_spin0 = cw.gaussian_covariance(cl_theory_spin0, cl_theory_spin0,
cl_theory_spin0, cl_theory_spin0,
w_spin0, wb=w_spin0, spins=[0, 0, 0, 0])
4 Some previously public methods have been made private¶
For NmtCovarianceWorkspaces:
compute_coupling_coefficientsis now private. Use thefrom_fieldsconstructor instead.read_fromis now private. Use thefrom_fileconstructor instead.
# Example of v2 code:
cw = nmt.NmtCovarianceWorkspace()
cw.compute_coupling_coefficients(f, f, f, f)
cw.read_from('cov.fits')
# v3 equivalent:
cw = nmt.NmtCovarianceWorkspace.from_fields(f, f, f, f)
cw = nmt.NmtCovarianceWorkspace.from_file('cov.fits')
5 get_iNKA_cell is a very useful new function¶
Previously, when calculating Gaussian covariance matrices users had to cobble together their own best-guess $C_\ell$, even though a simple prescription (the "improved narrow-kernel approximation" -- iNKA) was provided in Nicola et al. 2020 (and in a near-future paper, Wolz et al. 2026). A new convenience function, get_iNKA_cell can now be used instead.
# Example of the old procedure
f = nmt.NmtField(mask, [mp], spin=2)
b = nmt.NmtBin.from_lmax_linear(lmax, nlb)
w = nmt.NmtWorkspace.from_fields(f, f, b)
cw = nmt.NmtCovarianceWorkspace.from_fields(f, f, f, f)
fsky = np.mean(mask**2)
cl_guess_from_data = nmt.compute_coupled_cell(f, f) / fsky
cl_guess_from_theory = w.couple_cell(cl_theory) / fsky
cov_from_data = nmt.gaussian_covariance(cw, 2, 2, 2, 2
cl_guess_from_data,
cl_guess_from_data,
cl_guess_from_data,
cl_guess_from_data,
w, wb=w)
cov_from_theory = nmt.gaussian_covariance(cw, 2, 2, 2, 2,
cl_guess_from_theory,
cl_guess_from_theory,
cl_guess_from_theory,
cl_guess_from_theory,
w, wb=w)
# In v3, you can do:
f = nmt.NmtField(mask, [mp], spin=2)
b = nmt.NmtBin.from_lmax_linear(lmax, nlb)
w = nmt.NmtWorkspace.from_fields(f, f, b)
cw = nmt.NmtCovarianceWorkspace.from_fields(f, f, f, f)
cl_guess_from_data = nmt.get_iNKA_cell(f, f)
cl_guess_from_theory = nmt.get_iNKA_cell(f, f, cl_theory)
cov_from_data = nmt.gaussian_covariance(cw, 2, 2, 2, 2
cl_guess_from_data,
cl_guess_from_data,
cl_guess_from_data,
cl_guess_from_data,
w, wb=w)
cov_from_theory = nmt.gaussian_covariance(cw, 2, 2, 2, 2,
cl_guess_from_theory,
cl_guess_from_theory,
cl_guess_from_theory,
cl_guess_from_theory,
w, wb=w)
# Note that this is even more important for covariances involving
# catalog-based fields, where this function will take care of
# accounting for the impact of shot noise in maps and masks
# automatically.