furax.obs
Modules:
-
atmosphere– -
landscapes– -
operators– -
pointing– -
stokes–
Classes:
-
AbstractSEDOperator–Abstract base class for Spectral Energy Distribution (SED) operators.
-
BeamOperator–Beam operator with a single transfer function shared across all Stokes components.
-
BeamOperatorIQU–Beam operator with an independent transfer function per Stokes component.
-
CMBOperator–Operator for Cosmic Microwave Background (CMB) spectral energy distribution.
-
DustOperator–Operator for thermal dust spectral energy distribution.
-
HWPOperator–Operator for an ideal half-wave plate (HWP).
-
LinearPolarizerOperator–Operator for an ideal linear polarizer.
-
QURotationOperator–Operator that rotates Q and U Stokes parameters by angle theta.
-
SynchrotronOperator–Operator for synchrotron spectral energy distribution.
-
PointingOperator–Operator that projects sky maps to time-ordered data (TOD) using quaternion pointing.
Functions:
-
negative_log_likelihood–Compute the negative spectral log likelihood.
-
preconditionner–Constructs the MixingMatrixOperator for preconditioning purposes.
-
sky_signal–Computes the estimated sky signal 's'.
-
spectral_cmb_variance–Compute the variance of the CMB component from the spectral estimation.
-
spectral_log_likelihood–Compute the spectral log likelihood.
furax.obs.AbstractSEDOperator
Bases: AbstractLinearOperator
Abstract base class for Spectral Energy Distribution (SED) operators.
SED operators model how astrophysical components emit radiation across frequencies. They broadcast sky maps to multiple frequency channels.
Subclasses must implement the sed() method to define the spectral
energy distribution.
Attributes:
-
frequencies(Float[Array, ' a']) –Array of observation frequencies.
Methods:
Source code in src/furax/obs/operators/_seds.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
frequencies
instance-attribute
__init__(frequencies, *, in_structure)
Source code in src/furax/obs/operators/_seds.py
mv(x)
Source code in src/furax/obs/operators/_seds.py
sed()
abstractmethod
Define the spectral energy distribution transformation.
Returns:
-
Float[Array, ...]–Float[Array, '...']: The transformed SED.
furax.obs.BeamOperator
dataclass
Bases: AbstractLinearOperator
Beam operator with a single transfer function shared across all Stokes components.
Input PyTree leaves are expected to have shape (nfreq, npix). They are
round-tripped through a spherical harmonic transform and the beam is applied
in alm space as a per-multipole, per-frequency scaling.
The operator is symmetric (self-adjoint): applying it twice is equivalent to
squaring the transfer function. Use inverse to obtain the deconvolution
operator (beam_fl replaced by its reciprocal).
Algebraic rule: BeamOperator @ BeamOperator reduces to a single
BeamOperator whose beam_fl is the element-wise product of both
transfer functions (see BeamRule).
Attributes:
-
lmax(int) –Maximum spherical harmonic degree.
-
beam_fl(Float[Array, ...]) –Beam transfer function, shape
(nfreq, lmax+1)for a per-frequency beam, or(lmax+1,)for a beam shared across all frequencies (promoted to 2-D viajnp.atleast_2dbefore broadcasting over frequencies).
Examples:
>>> import jax.numpy as jnp
>>> from furax.obs.stokes import StokesIQU
>>> from furax.obs.operators import BeamOperator
>>> nside, lmax, nfreq = 16, 31, 2
>>> npix = 12 * nside ** 2
>>> structure = StokesIQU.structure_for((nfreq, npix), jnp.float64)
>>> beam_fl = jnp.ones((nfreq, lmax + 1))
>>> op = BeamOperator(lmax=lmax, beam_fl=beam_fl, in_structure=structure)
Methods:
-
mv–Apply the beam to input sky maps.
-
inverse–Return a
BeamOperatorwith the reciprocal transfer function.
Source code in src/furax/obs/operators/_beam_operator.py
lmax
instance-attribute
beam_fl
instance-attribute
mv(x)
Apply the beam to input sky maps.
Parameters:
-
x(PyTree[Inexact[Array, 'nfreq npix']]) –Input PyTree whose leaves have shape
(nfreq, npix)or(npix,)for a single-frequency input.
Returns:
-
PyTree[Inexact[Array, 'nfreq npix']]–Beam-smoothed PyTree with the same structure and leaf shapes as x.
Source code in src/furax/obs/operators/_beam_operator.py
inverse()
Return a BeamOperator with the reciprocal transfer function.
Returns:
-
BeamOperator–A new
BeamOperatorwhosebeam_flequals1 / self.beam_fl.
Source code in src/furax/obs/operators/_beam_operator.py
furax.obs.BeamOperatorIQU
dataclass
Bases: AbstractLinearOperator
Beam operator with an independent transfer function per Stokes component.
Input PyTree leaves are expected to have shape (nfreq, npix). Each leaf
is smoothed with its own transfer function taken from the corresponding leaf
of beam_fl, enabling different beams for I, Q, and U (or any other
Stokes combination).
The operator is symmetric (self-adjoint). Use inverse to obtain the
deconvolution operator (each beam_fl leaf replaced by its reciprocal).
Algebraic rule: BeamOperatorIQU @ BeamOperatorIQU reduces to a single
operator whose per-leaf transfer functions are the element-wise products of
both (see BeamIQURule).
Attributes:
-
lmax(int) –Maximum spherical harmonic degree.
-
beam_fl(PyTree[Float[Array, 'nfreq lp1']]) –PyTree with the same structure as the input maps; each leaf has shape
(nfreq, lmax+1)and carries the per-frequency beam transfer function for that Stokes component.
Examples:
>>> import jax.numpy as jnp
>>> from furax.obs.stokes import StokesIQU
>>> from furax.obs.operators import BeamOperatorIQU
>>> nside, lmax, nfreq = 16, 31, 2
>>> npix = 12 * nside ** 2
>>> structure = StokesIQU.structure_for((nfreq, npix), jnp.float64)
>>> fl = jnp.ones((nfreq, lmax + 1))
>>> beam_fl = StokesIQU(i=fl, q=fl, u=fl)
>>> op = BeamOperatorIQU(lmax=lmax, beam_fl=beam_fl, in_structure=structure)
Methods:
-
mv–Apply per-Stokes beams to input sky maps.
-
inverse–Return a
BeamOperatorIQUwith per-Stokes reciprocal transfer functions.
Source code in src/furax/obs/operators/_beam_operator.py
lmax
instance-attribute
beam_fl
instance-attribute
mv(x)
Apply per-Stokes beams to input sky maps.
Parameters:
-
x(PyTree[Inexact[Array, 'nfreq npix']]) –Input PyTree whose leaves have shape
(nfreq, npix)or(npix,)for a single-frequency input. The PyTree structure must match that ofself.beam_fl.
Returns:
-
PyTree[Inexact[Array, 'nfreq npix']]–Beam-smoothed PyTree with the same structure and leaf shapes as x.
Source code in src/furax/obs/operators/_beam_operator.py
inverse()
Return a BeamOperatorIQU with per-Stokes reciprocal transfer functions.
Returns:
-
BeamOperatorIQU–A new
BeamOperatorIQUwhosebeam_flleaves equal -
BeamOperatorIQU–1 / leaffor each leaf inself.beam_fl.
Source code in src/furax/obs/operators/_beam_operator.py
furax.obs.CMBOperator
Bases: AbstractSEDOperator
Operator for Cosmic Microwave Background (CMB) spectral energy distribution.
The CMB has a blackbody spectrum at T_CMB ~ 2.725 K. In K_CMB units, the SED is constant (unity) across frequencies. In K_RJ units, a frequency-dependent conversion factor is applied.
Attributes:
-
frequencies(Float[Array, ' a']) –Observation frequencies [GHz].
-
units(str) –Output units ('K_CMB' or 'K_RJ').
-
factor(Float[Array, ...] | float) –Unit conversion factor.
Examples:
>>> nu = jnp.array([30, 40, 100]) # GHz
>>> cmb_op = CMBOperator(frequencies=nu, in_structure=landscape.structure)
>>> tod = cmb_op(sky_map) # Broadcasts CMB map to all frequencies
Methods:
Source code in src/furax/obs/operators/_seds.py
factor
instance-attribute
units = field(metadata={'static': True})
class-attribute
instance-attribute
__init__(frequencies, *, in_structure, units='K_CMB')
Source code in src/furax/obs/operators/_seds.py
sed()
Compute the spectral energy distribution for the CMB.
Returns:
-
Float[Array, ...]–Float[Array, '...']: The SED for the CMB.
Source code in src/furax/obs/operators/_seds.py
furax.obs.DustOperator
Bases: AbstractSEDOperator
Operator for thermal dust spectral energy distribution.
Models dust emission as a modified blackbody: a power law times a Planck function. The SED is: (nu/nu0)^(1+beta) * B(nu,T)/B(nu0,T), where B is the Planck function.
Supports spatially varying spectral parameters via patch indices.
Attributes:
-
frequencies(Float[Array, ' a']) –Observation frequencies [GHz].
-
frequency0(float) –Reference frequency [GHz].
-
temperature(Float[Array, ...]) –Dust temperature [K].
-
beta(Float[Array, ...]) –Spectral index (typically ~1.5).
-
units(str) –Output units ('K_CMB' or 'K_RJ').
Examples:
>>> nu = jnp.array([100, 143, 217, 353]) # GHz
>>> dust_op = DustOperator(
... frequencies=nu, frequency0=353, beta=1.54, temperature=20.0,
... in_structure=landscape.structure
... )
>>> tod = dust_op(dust_map)
Methods:
Source code in src/furax/obs/operators/_seds.py
temperature
instance-attribute
temperature_patch_indices
instance-attribute
beta
instance-attribute
beta_patch_indices
instance-attribute
factor
instance-attribute
units = field(metadata={'static': True})
class-attribute
instance-attribute
frequency0 = field(metadata={'static': True})
class-attribute
instance-attribute
__init__(frequencies, *, frequency0=100, temperature, units='K_CMB', temperature_patch_indices=None, beta, beta_patch_indices=None, in_structure)
Source code in src/furax/obs/operators/_seds.py
sed()
Source code in src/furax/obs/operators/_seds.py
furax.obs.HWPOperator
dataclass
Bases: AbstractLinearOperator
Operator for an ideal half-wave plate (HWP).
A HWP flips the sign of the U (and V) Stokes parameters while leaving I and Q unchanged. This models the Mueller matrix diag(1, 1, -1, -1).
The operator is diagonal and symmetric. For a rotating HWP at angle theta,
use HWPOperator.create(..., angles=theta) which computes R(-theta) @ HWP @ R(theta).
Algebraic rule: R(theta) @ HWP = HWP @ R(-theta).
Methods:
Source code in src/furax/obs/operators/_hwp.py
create(shape, dtype=np.float64, stokes='IQU', *, angles=None)
classmethod
Source code in src/furax/obs/operators/_hwp.py
mv(x)
Source code in src/furax/obs/operators/_hwp.py
furax.obs.LinearPolarizerOperator
dataclass
Bases: AbstractLinearOperator
Operator for an ideal linear polarizer.
Extracts the intensity seen by a linear polarizer aligned with the x-axis:
d = 0.5 * (I + Q). For a polarizer at angle psi, use
LinearPolarizerOperator.create(..., angles=psi).
This implements: d = 0.5 * (I + Qcos(2psi) + Usin(2psi)).
Algebraic rule: LinearPolarizer @ HWP = LinearPolarizer.
Methods:
Source code in src/furax/obs/operators/_polarizers.py
create(shape, dtype=np.float64, stokes='IQU', *, angles=None)
classmethod
Source code in src/furax/obs/operators/_polarizers.py
furax.obs.QURotationOperator
dataclass
Bases: AbstractLinearOperator
Operator that rotates Q and U Stokes parameters by angle theta.
Applies the rotation matrix R(theta) which transforms (Q, U) as: Q' = Qcos(2theta) + Usin(2theta) U' = -Qsin(2theta) + Ucos(2theta)
I and V components are unchanged. The operator is orthogonal: R.T = R.I = R(-theta).
Consecutive rotations combine: R(a) @ R(b) = R(a+b).
Attributes:
-
angles(Float[Array, ...]) –Rotation angles in radians.
-
atomic(bool) –If True, prevents this operator from being merged with adjacent QU rotation operators during algebraic reduction.
Methods:
Source code in src/furax/obs/operators/_qu_rotations.py
angles
instance-attribute
atomic = field(kw_only=True, default=False, metadata={'static': True})
class-attribute
instance-attribute
create(shape, dtype=np.float64, stokes='IQU', *, angles, atomic=False)
classmethod
Source code in src/furax/obs/operators/_qu_rotations.py
mv(x)
furax.obs.SynchrotronOperator
Bases: AbstractSEDOperator
Operator for synchrotron spectral energy distribution.
Models synchrotron emission as a power law: (nu/nu0)^beta, with optional spectral index running: (nu/nu0)^(beta + running * log(nu/nu_pivot)).
Supports spatially varying spectral parameters via patch indices.
Attributes:
-
frequencies(Float[Array, ' a']) –Observation frequencies [GHz].
-
frequency0(float) –Reference frequency [GHz].
-
beta_pl(Float[Array, ...]) –Power-law spectral index (typically ~ -3).
-
nu_pivot(float) –Pivot frequency for running [GHz].
-
running(float) –Running of the spectral index.
-
units(str) –Output units ('K_CMB' or 'K_RJ').
Examples:
>>> nu = jnp.array([30, 44, 70]) # GHz
>>> sync_op = SynchrotronOperator(
... frequencies=nu, frequency0=30, beta_pl=-3.0,
... in_structure=landscape.structure
... )
>>> tod = sync_op(synchrotron_map)
Methods:
Source code in src/furax/obs/operators/_seds.py
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | |
beta_pl
instance-attribute
beta_pl_patch_indices
instance-attribute
nu_pivot = field(metadata={'static': True})
class-attribute
instance-attribute
running = field(metadata={'static': True})
class-attribute
instance-attribute
units = field(metadata={'static': True})
class-attribute
instance-attribute
frequency0 = field(metadata={'static': True})
class-attribute
instance-attribute
factor
instance-attribute
__init__(frequencies, *, frequency0=100, nu_pivot=1.0, running=0.0, units='K_CMB', beta_pl, beta_pl_patch_indices=None, in_structure)
Source code in src/furax/obs/operators/_seds.py
sed()
Source code in src/furax/obs/operators/_seds.py
furax.obs.PointingOperator
dataclass
Bases: AbstractLinearOperator
Operator that projects sky maps to time-ordered data (TOD) using quaternion pointing.
Equivalent to: QURotation @ Index @ Ravel, but computed on-the-fly to save memory. For each detector and time sample, it: 1. Computes the sky pixel from boresight and detector quaternions 2. Samples the sky map at that pixel 3. Rotates Stokes QU by the polarization angle
The transpose accumulates TOD into a sky map (binning).
Attributes:
-
landscape(StokesLandscape) –The sky pixelization (HEALPix landscape).
-
qbore(Float[Array, 'samp 4']) –Boresight quaternions, shape (n_samples, 4).
-
qdet(Float[Array, 'det 4']) –Detector quaternions, shape (n_detectors, 4).
-
batch_size(int) –Detector batch size (memory/speed tradeoff; see jax.lax.map documentation).
Methods:
-
create– -
mv–Performs the 'un-pointing' operation, i.e. map->tod.
-
as_stokes_i–Return a copy of this operator restricted to StokesI.
-
as_expanded_operator–Return the equivalent QURotationOperator @ IndexOperator @ RavelOperator.
-
transpose–
Source code in src/furax/obs/pointing.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | |
landscape
instance-attribute
qbore
instance-attribute
qdet
instance-attribute
batch_size = field(metadata={'static': True})
class-attribute
instance-attribute
interpolate = field(metadata={'static': True})
class-attribute
instance-attribute
out_structure
property
create(landscape, boresight_quaternions, detector_quaternions, *, batch_size=32, frame='boresight', interpolate=False)
classmethod
Source code in src/furax/obs/pointing.py
mv(x)
Performs the 'un-pointing' operation, i.e. map->tod.
Source code in src/furax/obs/pointing.py
as_stokes_i(*, interpolate=None)
Return a copy of this operator restricted to StokesI.
Parameters:
-
interpolate(bool | None, default:None) –Override the interpolation flag. If
None(default), the flag is inherited fromself.interpolate.
Source code in src/furax/obs/pointing.py
as_expanded_operator()
Return the equivalent QURotationOperator @ IndexOperator @ RavelOperator.
Equivalent to mv() but as an explicit composition, useful for testing.
Source code in src/furax/obs/pointing.py
furax.obs.negative_log_likelihood(params, nu, N, d, dust_nu0, synchrotron_nu0, patch_indices=single_cluster_indices, op=None, N_2=None, analytical_gradient=False)
Compute the negative spectral log likelihood.
This function returns the negative of the spectral log likelihood, which is useful for optimization procedures where minimizing the negative log likelihood is equivalent to maximizing the likelihood.
Parameters:
-
params(PyTree[Array]) –Dictionary of spectral parameters.
-
nu(Array) –Array of frequencies.
-
N(AbstractLinearOperator) –Noise covariance operator.
-
d(Stokes) –Data in Stokes parameters.
-
dust_nu0(float) –Reference frequency for dust.
-
synchrotron_nu0(float) –Reference frequency for synchrotron.
-
patch_indices(PyTree[Array], default:single_cluster_indices) –Patch indices for spatially varying parameters (default is single_cluster_indices).
-
op(AbstractLinearOperator or None, default:None) –Operator to be applied (default is None).
-
N_2(AbstractLinearOperator or None, default:None) –Secondary noise operator (default is None).
-
analytical_gradient(bool, default:False) –If True, use the custom VJP implementation for analytical gradients. If False (default), use standard automatic differentiation.
Returns:
-
Scalar(Scalar) –The negative spectral log likelihood.
Examples:
>>> from furax.obs import negative_log_likelihood
>>> from furax.obs.stokes import Stokes
>>> from furax import HomothetyOperator
>>> import jax.numpy as jnp
>>> nside = 64
>>> nu_freqs = jnp.array([30., 40., 100.])
>>> d_data = Stokes.zeros((len(nu_freqs), 12 * nside**2)) # Example observed data
>>> inv_noise = HomothetyOperator(jnp.ones(1), in_structure=d_data.structure) # Example inverse noise
>>> params = {'temp_dust': 20.0, 'beta_dust': 1.54, 'beta_pl': -3.0}
>>> dust_nu0_ref = 150.0
>>> synchrotron_nu0_ref = 20.0
>>> nll_val = negative_log_likelihood(params, nu_freqs, inv_noise, d_data, dust_nu0_ref, synchrotron_nu0_ref)
>>> # print(nll_val)
Source code in src/furax/obs/_likelihoods.py
furax.obs.preconditionner(params, nu, d, dust_nu0, synchrotron_nu0, patch_indices=single_cluster_indices)
Constructs the MixingMatrixOperator for preconditioning purposes.
This function builds the mixing matrix operator based on the provided spectral parameters and frequencies, without directly involving the observed data or noise operators. It is typically used to create a preconditioner for iterative solvers in component separation.
Parameters:
-
params(PyTree[Array]) –Dictionary of spectral parameters.
-
nu(Array) –Array of frequencies.
-
d(Stokes) –Data in Stokes parameters, used only to infer the
in_structurefor the MixingMatrixOperator. Its values are not used. -
dust_nu0(float) –Reference frequency for dust.
-
synchrotron_nu0(float) –Reference frequency for synchrotron.
-
patch_indices(PyTree[Array], default:single_cluster_indices) –Patch indices for spatially varying parameters (default is single_cluster_indices).
Returns:
-
MixingMatrixOperator(MixingMatrixOperator) –The constructed mixing matrix operator suitable for preconditioning.
Examples:
>>> from furax.obs import preconditionner
>>> from furax.obs.stokes import Stokes
>>> import jax.numpy as jnp
>>> nside = 64
>>> nu_freqs = jnp.array([30., 40., 100.])
>>> dummy_d = Stokes.zeros((len(nu_freqs), 12 * nside**2)) # Dummy data for structure
>>> params = {'temp_dust': 20.0, 'beta_dust': 1.54, 'beta_pl': -3.0}
>>> dust_nu0_ref = 150.0
>>> synchrotron_nu0_ref = 20.0
>>> A_precond = preconditionner(params, nu_freqs, dummy_d, dust_nu0_ref, synchrotron_nu0_ref)
>>> # The preconditioner can now be used with a solver.
Source code in src/furax/obs/_likelihoods.py
furax.obs.sky_signal(params, nu, N, d, dust_nu0, synchrotron_nu0, patch_indices=single_cluster_indices, op=None, N_2=None, analytical_gradient=False)
Computes the estimated sky signal 's'.
Parameters:
-
params(PyTree[Array]) –Dictionary of spectral parameters.
-
nu(Array) –Array of frequencies.
-
N(AbstractLinearOperator) –Noise covariance operator.
-
d(Stokes) –Data in Stokes parameters.
-
dust_nu0(float) –Reference frequency for dust.
-
synchrotron_nu0(float) –Reference frequency for synchrotron.
-
patch_indices(PyTree[Array], default:single_cluster_indices) –Patch indices for spatially varying parameters (default is single_cluster_indices).
-
op(AbstractLinearOperator or None, default:None) –Operator to be applied (default is None).
-
N_2(AbstractLinearOperator or None, default:None) –Secondary noise operator (default is None).
-
analytical_gradient(bool, default:False) –If True, use the custom VJP implementation for analytical gradients. If False (default), use standard automatic differentiation.
Returns:
-
ComponentParametersDict(ComponentParametersDict) –The estimated sky signal components (e.g., 'cmb', 'dust', 'synchrotron').
Examples:
>>> from furax.obs import sky_signal
>>> from furax.obs.stokes import Stokes
>>> from furax import HomothetyOperator
>>> import jax.numpy as jnp
>>> nside = 64
>>> nu_freqs = jnp.array([30., 40., 100.])
>>> d_data = Stokes.zeros((len(nu_freqs), 12 * nside**2)) # Example observed data
>>> inv_noise = HomothetyOperator(jnp.ones(1), in_structure=d_data.structure) # Example inverse noise
>>> params = {'temp_dust': 20.0, 'beta_dust': 1.54, 'beta_pl': -3.0}
>>> dust_nu0_ref = 150.0
>>> synchrotron_nu0_ref = 20.0
>>> sky_comp = sky_signal(params, nu_freqs, inv_noise, d_data, dust_nu0_ref, synchrotron_nu0_ref)
>>> # print(sky_comp['cmb'].i.shape)
Source code in src/furax/obs/_likelihoods.py
furax.obs.spectral_cmb_variance(params, nu, N, d, dust_nu0, synchrotron_nu0, patch_indices=single_cluster_indices, op=None, N_2=None, analytical_gradient=False)
Compute the variance of the CMB component from the spectral estimation.
This function calculates the variance of the CMB component from the estimated sky signal 's'.
Parameters:
-
params(PyTree[Array]) –Dictionary of spectral parameters.
-
nu(Array) –Array of frequencies.
-
N(AbstractLinearOperator) –Noise covariance operator.
-
d(Stokes) –Data in Stokes parameters.
-
dust_nu0(float) –Reference frequency for dust.
-
synchrotron_nu0(float) –Reference frequency for synchrotron.
-
patch_indices(PyTree[Array], default:single_cluster_indices) –Patch indices for spatially varying parameters (default is single_cluster_indices).
-
op(AbstractLinearOperator or None, default:None) –Operator to be applied (default is None).
-
N_2(AbstractLinearOperator or None, default:None) –Secondary noise operator (default is None).
-
analytical_gradient(bool, default:False) –If True, use the custom VJP implementation for analytical gradients. If False (default), use standard automatic differentiation.
Returns:
-
Scalar(Scalar) –The variance of the CMB component.
Examples:
>>> from furax.obs import spectral_cmb_variance
>>> from furax.obs.stokes import Stokes
>>> from furax import HomothetyOperator
>>> import jax.numpy as jnp
>>> nside = 64
>>> nu_freqs = jnp.array([30., 40., 100.])
>>> d_data = Stokes.zeros((len(nu_freqs), 12 * nside**2)) # Example observed data
>>> inv_noise = HomothetyOperator(jnp.ones(1), in_structure=d_data.structure) # Example inverse noise
>>> params = {'temp_dust': 20.0, 'beta_dust': 1.54, 'beta_pl': -3.0}
>>> dust_nu0_ref = 150.0
>>> synchrotron_nu0_ref = 20.0
>>> cmb_var_val = spectral_cmb_variance(params, nu_freqs, inv_noise, d_data, dust_nu0_ref, synchrotron_nu0_ref)
>>> # print(cmb_var_val)
Source code in src/furax/obs/_likelihoods.py
furax.obs.spectral_log_likelihood(params, nu, N, d, dust_nu0, synchrotron_nu0, patch_indices=single_cluster_indices, op=None, N_2=None, analytical_gradient=False)
Compute the spectral log likelihood.
Parameters:
-
params(PyTree[Array]) –Dictionary of spectral parameters.
-
nu(Array) –Array of frequencies.
-
N(AbstractLinearOperator) –Noise covariance operator.
-
d(Stokes) –Data in Stokes parameters.
-
dust_nu0(float) –Reference frequency for dust.
-
synchrotron_nu0(float) –Reference frequency for synchrotron.
-
patch_indices(PyTree[Array], default:single_cluster_indices) –Patch indices for spatially varying parameters (default is single_cluster_indices).
-
op(AbstractLinearOperator or None, default:None) –Operator to be applied (default is None).
-
N_2(AbstractLinearOperator or None, default:None) –Secondary noise operator (default is None).
-
analytical_gradient(bool, default:False) –If True, use the custom VJP implementation for analytical gradients. If False (default), use standard automatic differentiation.
Returns:
-
Scalar(Scalar) –The spectral log likelihood.
Examples:
>>> from furax.obs import spectral_log_likelihood
>>> from furax.obs.stokes import Stokes
>>> from furax import HomothetyOperator
>>> import jax.numpy as jnp
>>> nside = 64
>>> nu_freqs = jnp.array([30., 40., 100.])
>>> d_data = Stokes.zeros((len(nu_freqs), 12 * nside**2)) # Example observed data
>>> inv_noise = HomothetyOperator(jnp.ones(1), in_structure=d_data.structure) # Example inverse noise
>>> params = {'temp_dust': 20.0, 'beta_dust': 1.54, 'beta_pl': -3.0}
>>> dust_nu0_ref = 150.0
>>> synchrotron_nu0_ref = 20.0
>>> ll_val = spectral_log_likelihood(params, nu_freqs, inv_noise, d_data, dust_nu0_ref, synchrotron_nu0_ref)
>>> # print(ll_val)
Source code in src/furax/obs/_likelihoods.py
furax.obs.atmosphere
Classes:
-
AtmospherePointingOperator–Operator that projects a flat atmosphere map to TOD using quaternion pointing.
Functions:
-
profile_neg_log_likelihood–Negative profile log-likelihood for atmosphere pointing parameters.
-
simulate_kolmogorov_screen–Generate a 2D Gaussian random field with an isotropic power-law spectrum.
AtmospherePointingOperator
dataclass
Bases: PointingOperator
Operator that projects a flat atmosphere map to TOD using quaternion pointing.
Models a "frozen" atmosphere as a 2D intensity pattern on a horizontal plane at
height h, drifting with wind velocity (vx, vy). For each detector and time
sample it:
- Computes the gnomonic projection of the pointing direction onto the plane,
giving physical coordinates
(x, y). - Adds the wind displacement
(vx * t, vy * t)to obtain the atmosphere sample position. - Samples the atmosphere map at that position (nearest-neighbour or bilinear).
- Optionally weights the sample by the airmass loading modulation
1 / sin(el)(enabled withelevation_modulation), accounting for the longer line-of-sight path through the layer at low elevation.
The transpose accumulates TOD back into the atmosphere map (binning).
Attributes:
-
landscape(TangentialLandscape) –The atmosphere map pixelization.
-
qbore(Float[Array, 'samp 4']) –Boresight quaternions in the horizon frame (z-axis = zenith), shape
(n_samples, 4). -
qdet(Float[Array, 'det 4']) –Detector offset quaternions, shape
(n_detectors, 4). -
wind_displacement(Float[Array, 'samp 2']) –Pre-computed wind offset
(vx * t_k, vy * t_k)for each sample, shape(n_samples, 2). -
batch_size(int) –Detector batch size.
-
interpolate(bool) –If
True, use bilinear interpolation; otherwise nearest-neighbour. -
elevation_modulation(bool) –If
True, weight each sample by1 / sin(el)(airmass).
Methods:
-
from_wind–Create an AtmospherePointingOperator.
Source code in src/furax/obs/atmosphere/_operator.py
16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 | |
landscape
instance-attribute
wind_displacement
instance-attribute
elevation_modulation = field(metadata={'static': True})
class-attribute
instance-attribute
from_wind(landscape, boresight_quaternions, detector_quaternions, wind_velocity, times, *, batch_size=16, interpolate=True, elevation_modulation=False)
classmethod
Create an AtmospherePointingOperator.
Parameters:
-
landscape(TangentialLandscape) –The atmosphere map pixelization (height stored here).
-
boresight_quaternions(Float[Array, 'samp 4']) –Boresight pointing in the horizon frame, shape
(n_samples, 4). -
detector_quaternions(Float[Array, 'det 4']) –Detector offset quaternions, shape
(n_detectors, 4). -
wind_velocity(Float[Array, 2]) –Wind velocity
(vx, vy)in the same physical units aslandscape.heightper second. -
times(Float[Array, ' samp']) –Elapsed time for each sample, shape
(n_samples,). -
batch_size(int, default:16) –Detector batch size.
-
interpolate(bool, default:True) –Use bilinear interpolation (default: nearest-neighbour).
-
elevation_modulation(bool, default:False) –Weight each sample by the airmass loading
1 / sin(el).
Source code in src/furax/obs/atmosphere/_operator.py
profile_neg_log_likelihood(pointing_op, d, noise_cov_inv, *, solver=None)
Negative profile log-likelihood for atmosphere pointing parameters.
Assumes a data model d = P(v) m + n where P(v) is the atmosphere pointing
operator parameterised by wind velocity v (or any other pointing parameters).
Computes the "spectral" (profile) negative log-likelihood given (up to a constant) by
-2 log L(v) = (P.T N.I d).T (P.T N.I P).I (P.T N.I d) for use with a minimiser.
Examples:
>>> import lineax as lx
>>> def loss(wind_velocity):
... P = AtmospherePointingOperator.from_wind(
... landscape, qbore, qdet, wind_velocity, times, interpolate=True
... )
... return profile_neg_log_likelihood(P, d_obs, N_inv)
>>> grad = jax.grad(loss)(wind_velocity_init)
Parameters:
-
pointing_op(AbstractLinearOperator) –Atmosphere pointing operator
P(v)for current parameters. -
d(StokesI) –Observed TOD.
-
noise_cov_inv(AbstractLinearOperator) –Inverse noise covariance operator.
-
solver(AbstractLinearSolver | None, default:None) –Linear solver for the map-making step.
Returns:
-
Scalar–Scalar negative profile log-likelihood (suitable for minimisation).
Source code in src/furax/obs/atmosphere/_likelihood.py
simulate_kolmogorov_screen(landscape, key, *, power=-11 / 3, amplitude=1.0)
Generate a 2D Gaussian random field with an isotropic power-law spectrum.
Models a frozen turbulent atmosphere screen using a Kolmogorov-like power
spectrum \(P(k) \propto k^{\text{power}}\). The default exponent
power = -11/3 corresponds to the two-dimensional projection of a 3D
Kolmogorov turbulence field (outer-scale-free regime).
The field is generated in Fourier space: draw complex Gaussian white noise, multiply by \(\sqrt{A}\,k^{\text{power}/2}\), then transform back with an inverse FFT. The DC component is excluded (set to zero) to avoid the singularity at \(k=0\).
Parameters:
-
landscape(TangentialLandscape) –Defines the map shape and dtype. Only
landscape.shapeandlandscape.dtypeare used; height and pixel spacing do not affect the generated field. -
key(Key[Array, '']) –JAX random key.
-
power(float, default:-11 / 3) –Exponent of the power spectrum \(P(k) \propto k^p\). Default
-11/3(Kolmogorov). -
amplitude(float, default:1.0) –Overall amplitude prefactor \(A\). Scales the variance of the output field.
Returns:
-
StokesI–Stokes I map matching the shape and dtype of
landscape.
Source code in src/furax/obs/atmosphere/_simulation.py
furax.obs.landscapes
Classes:
-
Landscape– -
StokesLandscape–Class representing a multidimensional map of Stokes vectors.
-
ProjectionType–Supported WCS projection types.
-
WCSProjection–Class that holds basic WCS projection parameters.
-
WCSLandscape–Base class for WCS-projected Stokes landscapes.
-
CARLandscape–Class representing a CAR (Plate Carrée) projected map of Stokes vectors.
-
HealpixLandscape–Class representing a Healpix-projected map of Stokes vectors.
-
FrequencyLandscape– -
AstropyWCSLandscape–Class representing an astropy WCS map of Stokes vectors.
-
HorizonLandscape–Class representing a map of Stokes vectors in horizon (ground) coordinates.
-
TangentialLandscape–Class representing a flat map in the local tangent plane at zenith.
Landscape
Bases: ABC
Methods:
Attributes:
Source code in src/furax/obs/landscapes.py
shape = shape
instance-attribute
dtype = dtype
instance-attribute
size
property
__init__(shape, dtype=np.float64)
__len__()
normal(key)
abstractmethod
uniform(key, minval=0.0, maxval=1.0)
abstractmethod
full(fill_value)
abstractmethod
zeros()
StokesLandscape
Bases: Landscape
Class representing a multidimensional map of Stokes vectors.
We assume that integer pixel values fall at the center of pixels (as in the FITS WCS standard, see Section 2.1.4 of Greisen et al., 2002, A&A 446, 747).
Attributes:
-
shape–The shape of the array that stores the map values. The dimensions are in the reverse order of the FITS NAXIS* keywords. For a 2-dimensional map, the shape corresponds to (NAXIS2, NAXIS1) or (\(n_\mathrm{row}\), \(n_\mathrm{col}\)), i.e. (\(n_y\), \(n_x\)).
-
pixel_shape–The shape in reversed order. For a 2-dimensional map, the shape corresponds to (NAXIS1, NAXIS2) or (\(n_\mathrm{col}\), \(n_\mathrm{row}\)), i.e. (\(n_x\), \(n_y\)).
-
stokes–The identifier for the Stokes vectors (
I,QU,IQUorIQUV) -
dtype–The data type for the values of the landscape.
Methods:
-
__init__– -
full– -
normal– -
uniform– -
get_coverage– -
world2index– -
world2pixel–Converts angles from WCS to pixel coordinates.
-
pixel2index–Converts multidimensional pixel coordinates into 1-dimensional indices.
-
quat2pixel–Converts quaternion to floating-point pixel coordinates.
-
quat2index–Converts quaternion to 1-dimensional pixel indices.
-
world2interp–Returns (indices, weights) with a trailing neighbor dimension for interpolation.
-
quat2interp–Converts quaternion to (indices, weights) for interpolation.
Source code in src/furax/obs/landscapes.py
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 | |
stokes = stokes
instance-attribute
pixel_shape = shape[::(-1)]
instance-attribute
size
property
structure
property
__init__(shape=None, stokes='IQU', dtype=np.float64, pixel_shape=None)
Source code in src/furax/obs/landscapes.py
full(fill_value)
normal(key)
uniform(key, minval=0.0, maxval=1.0)
get_coverage(arg)
Source code in src/furax/obs/landscapes.py
world2index(theta, phi)
world2pixel(theta, phi)
abstractmethod
Converts angles from WCS to pixel coordinates.
Parameters:
Returns:
-
tuple[Float[Array, ' *dims'], ...]–tuple[float, ...]: x, y, z, ... pixel coordinates
Source code in src/furax/obs/landscapes.py
pixel2index(*coords)
Converts multidimensional pixel coordinates into 1-dimensional indices.
For a map of shape \((n_y, n_x)\), the indices of the pixels are walked from the rightmost dimension \(n_x\) to the leftmost dimension \(n_y\) (row-major layout). In such a map, the pixel with float coordinates \((p_x, p_y)\) has an index \(i = round(p_x) + n_x round(p_y)\).
The indices travel from bottom to top, like the Y-coordinates.
Integer values of the pixel coordinates correspond to the pixel centers. The points \((p_x, p_y)\) strictly inside a pixel centered on the integer coordinates \((i_x, i_y)\) verify
- \(i_x - \frac{1}{2} < p_x < i_x + \frac{1}{2}\)
- \(i_y - \frac{1}{2} < p_y < i_y + \frac{1}{2}\)
The convention for pixels and indices is that the first one starts at zero.
Parameters:
-
*coords(Float[Array, ' *dims'], default:()) –The floating-point pixel coordinates along the X, Y, Z, ... axes.
Returns:
-
Integer[Array, ' *ndims']–The 1-dimensional integer indices associated to the pixel coordinates. The data type is
-
Integer[Array, ' *ndims']–int32, unless the landscape largest index would overflow, in which case it is int64.
Source code in src/furax/obs/landscapes.py
quat2pixel(quat)
Converts quaternion to floating-point pixel coordinates.
Source code in src/furax/obs/landscapes.py
quat2index(quat)
world2interp(theta, phi)
Returns (indices, weights) with a trailing neighbor dimension for interpolation.
Subclasses must override this to support interpolated pointing.
Source code in src/furax/obs/landscapes.py
quat2interp(quat)
Converts quaternion to (indices, weights) for interpolation.
Source code in src/furax/obs/landscapes.py
ProjectionType
WCSProjection
dataclass
Class that holds basic WCS projection parameters.
Methods:
-
__init__– -
__post_init__– -
from_astropy–Extract a WCSProjection from an astropy WCS object.
Attributes:
-
crpix(tuple[float, float]) –Reference pixel
(crpix_x, crpix_y)in 1-indexed FITS convention. -
crval(tuple[float, float]) –Reference coordinate
(lon_deg, lat_deg)in degrees. -
cdelt(tuple[float, float]) –Pixel scale
(cdelt_x_deg, cdelt_y_deg)in degrees per pixel. -
type(ProjectionType) –Projection type (only CAR is supported for now).
Source code in src/furax/obs/landscapes.py
crpix
instance-attribute
Reference pixel (crpix_x, crpix_y) in 1-indexed FITS convention.
crval
instance-attribute
Reference coordinate (lon_deg, lat_deg) in degrees.
cdelt
instance-attribute
Pixel scale (cdelt_x_deg, cdelt_y_deg) in degrees per pixel.
type = ProjectionType.CAR
class-attribute
instance-attribute
Projection type (only CAR is supported for now).
__init__(crpix, crval, cdelt, type=ProjectionType.CAR)
__post_init__()
from_astropy(wcs)
classmethod
Extract a WCSProjection from an astropy WCS object.
Source code in src/furax/obs/landscapes.py
WCSLandscape
Bases: StokesLandscape
Base class for WCS-projected Stokes landscapes.
Methods:
-
__init__– -
to_wcs–Reconstruct an astropy WCS object from the stored projection parameters.
-
class_for–Return the WCSLandscape subclass for the given projection type.
-
from_wcs–Create a WCSLandscape subclass instance from an astropy WCS object.
Attributes:
-
projection– -
crpix(tuple[float, float]) – -
crval(tuple[float, float]) – -
cdelt(tuple[float, float]) –
Source code in src/furax/obs/landscapes.py
projection = projection
instance-attribute
crpix
property
crval
property
cdelt
property
__init__(shape, projection, stokes='IQU', dtype=np.float64)
to_wcs()
Reconstruct an astropy WCS object from the stored projection parameters.
Source code in src/furax/obs/landscapes.py
class_for(projection_type)
classmethod
Return the WCSLandscape subclass for the given projection type.
Source code in src/furax/obs/landscapes.py
from_wcs(shape, wcs, stokes='IQU', dtype=np.float64)
classmethod
Create a WCSLandscape subclass instance from an astropy WCS object.
Dispatches to the appropriate subclass based on the projection type.
Source code in src/furax/obs/landscapes.py
CARLandscape
Bases: WCSLandscape
Class representing a CAR (Plate Carrée) projected map of Stokes vectors.
CAR maps native coordinates linearly to the projection plane (x = φ, y = θ).
Requiring phi_0 = 0 aligns the native and celestial equators, reducing the
celestial-to-native rotation to a pure RA shift and making the full world-to-pixel
mapping linear in (RA, Dec):
where \(\Delta\lambda = ((\lambda - \lambda_0 + 180) \bmod 360) - 180\) handles
the 0°/360° RA wrap, \((\lambda_0, 0.0)\) is crval, \((\delta_x, \delta_y)\)
is cdelt in degrees, and \((c_x, c_y)\) is crpix (1-indexed FITS convention).
Methods:
-
__init__– -
world2pixel–Convert spherical angles to CAR pixel coordinates in pure JAX.
-
world2interp–Returns (indices, weights) for bilinear interpolation (n=4).
Source code in src/furax/obs/landscapes.py
__init__(shape, projection, stokes='IQU', dtype=np.float64)
Source code in src/furax/obs/landscapes.py
world2pixel(theta, phi)
Convert spherical angles to CAR pixel coordinates in pure JAX.
Parameters:
-
theta(float) –Spherical \(\theta\) angle (co-latitude, 0 at north pole).
-
phi(float) –Spherical \(\phi\) angle (longitude).
Returns:
-
tuple[Float[Array, ' *dims'], Float[Array, ' *dims']]–Pixel coordinate pair
(pix_x, pix_y)as float arrays.
Source code in src/furax/obs/landscapes.py
world2interp(theta, phi)
Returns (indices, weights) for bilinear interpolation (n=4).
Source code in src/furax/obs/landscapes.py
HealpixLandscape
Bases: StokesLandscape
Class representing a Healpix-projected map of Stokes vectors.
Methods:
-
__init__– -
quat2index–Convert quaternion to HEALPix pixel index.
-
world2interp–Returns (indices, weights) for bilinear HEALPix interpolation (n=4).
-
world2pixel–Convert angles to HEALPix pixel index.
Attributes:
Source code in src/furax/obs/landscapes.py
nside = nside
instance-attribute
nested = nested
instance-attribute
__init__(nside, stokes='IQU', dtype=np.float64, nested=False)
Source code in src/furax/obs/landscapes.py
quat2index(quat)
Convert quaternion to HEALPix pixel index.
Parameters:
-
quat(float) –Quaternion.
Returns:
-
int(Integer[Array, ' *dims']) –HEALPix pixel index.
Source code in src/furax/obs/landscapes.py
world2interp(theta, phi)
Returns (indices, weights) for bilinear HEALPix interpolation (n=4).
Source code in src/furax/obs/landscapes.py
world2pixel(theta, phi)
Convert angles to HEALPix pixel index.
Parameters:
Returns:
-
int(tuple[Integer[Array, ' *dims'], ...]) –HEALPix pixel index.
Source code in src/furax/obs/landscapes.py
FrequencyLandscape
Bases: HealpixLandscape
Methods:
-
__init__–
Attributes:
-
frequencies– -
shape–
Source code in src/furax/obs/landscapes.py
frequencies = frequencies
instance-attribute
shape = (len(frequencies), 12 * nside ** 2)
instance-attribute
__init__(nside, frequencies, stokes='IQU', dtype=np.float64)
Source code in src/furax/obs/landscapes.py
AstropyWCSLandscape
Bases: StokesLandscape
Class representing an astropy WCS map of Stokes vectors.
Methods:
-
__init__– -
world2pixel–Convert angles to WCS map indices.
Attributes:
-
wcs–
Source code in src/furax/obs/landscapes.py
wcs = wcs
instance-attribute
__init__(shape, wcs, stokes='IQU', dtype=np.float64)
world2pixel(theta, phi)
Convert angles to WCS map indices.
Parameters:
Returns:
-
tuple[Float[Array, ' *dims'], Float[Array, ' *dims']]–WCS map index pairs
Source code in src/furax/obs/landscapes.py
HorizonLandscape
Bases: StokesLandscape
Class representing a map of Stokes vectors in horizon (ground) coordinates.
Contains two axes
AXIS1: altitude (elevation) in radians AXIS2: azimuth in radians
Methods:
-
__init__– -
bin_edges–Return the bin edges of the map.
-
bin_centers–Return the bin centers of the map.
-
world2pixel–Convert angles in radians to Horizon map indices.
Attributes:
Source code in src/furax/obs/landscapes.py
altitude_limits = altitude_limits
instance-attribute
azimuth_limits = azimuth_limits
instance-attribute
__init__(shape, altitude_limits, azimuth_limits, stokes='IQU', dtype=np.float64)
Source code in src/furax/obs/landscapes.py
bin_edges()
Return the bin edges of the map.
Source code in src/furax/obs/landscapes.py
bin_centers()
Return the bin centers of the map.
Source code in src/furax/obs/landscapes.py
world2pixel(theta, phi)
Convert angles in radians to Horizon map indices.
Parameters:
-
theta(float) –Spherical \(\theta\) angle = pi/2 - altitude.
-
phi(float) –Spherical \(\phi\) angle = -azimuth.
Returns:
-
tuple[Integer[Array, ' *dims'], Integer[Array, ' *dims']]–Ground map index pairs
Source code in src/furax/obs/landscapes.py
TangentialLandscape
Bases: StokesLandscape
Class representing a flat map in the local tangent plane at zenith.
Implements the gnomonic (tangential) projection: a ray from the telescope origin in direction \(\hat{v}\) intersects the horizontal plane at height \(h\) at
where \(v_z = \cos\theta\) is the elevation cosine (z-axis = zenith).
The map is a 2D Cartesian grid in physical units (same units as height), centered
at the origin. Pixel spacing is dx along x and dy along y, so the map covers
[-n_x*dx/2, n_x*dx/2] × [-n_y*dy/2, n_y*dy/2].
Attributes:
-
shape–Array shape
(n_y, n_x)in row-major order. -
dx–Pixel spacing along the x-axis (same units as
height). -
dy–Pixel spacing along the y-axis (same units as
height). -
height–Height of the tangent plane above the telescope (same units as
dx/dy). -
stokes–Stokes components stored in the map (default
'I'). -
dtype–Data type for map values.
Methods:
-
__init__– -
from_extent–Create a landscape from physical extent and pixel spacing.
-
xy2pixel–Convert physical coordinates to floating-point pixel coordinates.
-
world2pixel–Convert ISO spherical angles to pixel coordinates via gnomonic projection.
-
quat2xy–Convert quaternions to physical (x, y) coordinates on the tangent plane.
-
quat2pixel–Convert quaternions to floating-point pixel coordinates.
-
xy2interp–Bilinear interpolation weights and indices for physical coordinates.
Source code in src/furax/obs/landscapes.py
575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 | |
dx = dx
instance-attribute
dy = dy
instance-attribute
height = height
instance-attribute
x0 = x0
instance-attribute
y0 = y0
instance-attribute
extent
property
Physical size of the map (x_size, y_size) in the same units as dx/dy.
__init__(shape, dx, dy, height, x0=0.0, y0=0.0, stokes='I', dtype=np.float64)
Source code in src/furax/obs/landscapes.py
from_extent(x_size, y_size, dx, dy, height, x0=0.0, y0=0.0, stokes='I', dtype=np.float64)
classmethod
Create a landscape from physical extent and pixel spacing.
The map is centered at (x0, y0) and covers
[x0 - x_size/2, x0 + x_size/2] × [y0 - y_size/2, y0 + y_size/2].
The number of pixels is ceil(x_size / dx) × ceil(y_size / dy), so the
actual covered area may be slightly larger than requested to accommodate whole
pixels.
Parameters:
-
x_size(float) –Total physical width of the map (same units as
height). -
y_size(float) –Total physical height of the map (same units as
height). -
dx(float) –Pixel spacing along x.
-
dy(float) –Pixel spacing along y.
-
height(float) –Height of the tangent plane above the telescope.
-
x0(float, default:0.0) –Physical x-coordinate of the map center (default 0).
-
y0(float, default:0.0) –Physical y-coordinate of the map center (default 0).
-
stokes(ValidStokesType, default:'I') –Stokes components to store (default
'I'). -
dtype(DTypeLike, default:float64) –Data type for map values.
Source code in src/furax/obs/landscapes.py
xy2pixel(x, y)
Convert physical coordinates to floating-point pixel coordinates.
The map is centered at (x0, y0). Integer pixel coordinates correspond to
pixel centers.
Parameters:
-
x(Float[Array, ' *dims']) –Physical x-coordinates.
-
y(Float[Array, ' *dims']) –Physical y-coordinates.
Returns:
-
tuple[Float[Array, ' *dims'], Float[Array, ' *dims']]–Floating-point pixel coordinate pair
(pix_x, pix_y).
Source code in src/furax/obs/landscapes.py
world2pixel(theta, phi)
Convert ISO spherical angles to pixel coordinates via gnomonic projection.
Parameters:
-
theta(Float[Array, ' *dims']) –Co-latitude from zenith (0 at zenith, \(\pi/2\) at horizon).
-
phi(Float[Array, ' *dims']) –Azimuthal angle.
Returns:
-
tuple[Float[Array, ' *dims'], Float[Array, ' *dims']]–Floating-point pixel coordinate pair
(pix_x, pix_y).
Source code in src/furax/obs/landscapes.py
quat2xy(quat)
Convert quaternions to physical (x, y) coordinates on the tangent plane.
Uses qrot_zaxis to extract the pointing direction and applies the exact
gnomonic projection. This is the primary conversion step used by
AtmospherePointingOperator before
adding wind displacement.
Parameters:
-
quat(Float[Array, '*dims 4']) –Pointing quaternions (z-axis = zenith frame).
Returns:
-
tuple[Float[Array, ' *dims'], Float[Array, ' *dims']]–Physical coordinate pair
(x, y).
Source code in src/furax/obs/landscapes.py
quat2pixel(quat)
Convert quaternions to floating-point pixel coordinates.
Overrides the base-class implementation to use qrot_zaxis directly,
avoiding the round-trip through ISO angles.
Source code in src/furax/obs/landscapes.py
xy2interp(x, y)
Bilinear interpolation weights and indices for physical coordinates.
Returns the four neighbouring pixel indices and their bilinear weights.
Out-of-bounds neighbours are marked with index -1 and weight 0.
Parameters:
-
x(Float[Array, ' *dims']) –Physical x-coordinates.
-
y(Float[Array, ' *dims']) –Physical y-coordinates.
Returns:
-
Integer[Array, ' *dims 4']–(indices, weights)where both have shape(*dims, 4)and the -
Float[Array, ' *dims 4']–trailing axis runs over the four neighbours in order
-
tuple[Integer[Array, ' *dims 4'], Float[Array, ' *dims 4']]–(i0,j0), (i1,j0), (i0,j1), (i1,j1).
Source code in src/furax/obs/landscapes.py
furax.obs.operators
Classes:
-
BeamOperator–Beam operator with a single transfer function shared across all Stokes components.
-
BeamOperatorIQU–Beam operator with an independent transfer function per Stokes component.
-
HWPOperator–Operator for an ideal half-wave plate (HWP).
-
LinearPolarizerOperator–Operator for an ideal linear polarizer.
-
QURotationOperator–Operator that rotates Q and U Stokes parameters by angle theta.
-
AbstractSEDOperator–Abstract base class for Spectral Energy Distribution (SED) operators.
-
CMBOperator–Operator for Cosmic Microwave Background (CMB) spectral energy distribution.
-
DustOperator–Operator for thermal dust spectral energy distribution.
-
NoiseDiagonalOperator–Constructs a diagonal noise operator.
-
SynchrotronOperator–Operator for synchrotron spectral energy distribution.
Functions:
-
MixingMatrixOperator–Constructs a mixing matrix operator from a set of SED operators.
BeamOperator
dataclass
Bases: AbstractLinearOperator
Beam operator with a single transfer function shared across all Stokes components.
Input PyTree leaves are expected to have shape (nfreq, npix). They are
round-tripped through a spherical harmonic transform and the beam is applied
in alm space as a per-multipole, per-frequency scaling.
The operator is symmetric (self-adjoint): applying it twice is equivalent to
squaring the transfer function. Use inverse to obtain the deconvolution
operator (beam_fl replaced by its reciprocal).
Algebraic rule: BeamOperator @ BeamOperator reduces to a single
BeamOperator whose beam_fl is the element-wise product of both
transfer functions (see BeamRule).
Attributes:
-
lmax(int) –Maximum spherical harmonic degree.
-
beam_fl(Float[Array, ...]) –Beam transfer function, shape
(nfreq, lmax+1)for a per-frequency beam, or(lmax+1,)for a beam shared across all frequencies (promoted to 2-D viajnp.atleast_2dbefore broadcasting over frequencies).
Examples:
>>> import jax.numpy as jnp
>>> from furax.obs.stokes import StokesIQU
>>> from furax.obs.operators import BeamOperator
>>> nside, lmax, nfreq = 16, 31, 2
>>> npix = 12 * nside ** 2
>>> structure = StokesIQU.structure_for((nfreq, npix), jnp.float64)
>>> beam_fl = jnp.ones((nfreq, lmax + 1))
>>> op = BeamOperator(lmax=lmax, beam_fl=beam_fl, in_structure=structure)
Methods:
-
mv–Apply the beam to input sky maps.
-
inverse–Return a
BeamOperatorwith the reciprocal transfer function.
Source code in src/furax/obs/operators/_beam_operator.py
lmax
instance-attribute
beam_fl
instance-attribute
mv(x)
Apply the beam to input sky maps.
Parameters:
-
x(PyTree[Inexact[Array, 'nfreq npix']]) –Input PyTree whose leaves have shape
(nfreq, npix)or(npix,)for a single-frequency input.
Returns:
-
PyTree[Inexact[Array, 'nfreq npix']]–Beam-smoothed PyTree with the same structure and leaf shapes as x.
Source code in src/furax/obs/operators/_beam_operator.py
inverse()
Return a BeamOperator with the reciprocal transfer function.
Returns:
-
BeamOperator–A new
BeamOperatorwhosebeam_flequals1 / self.beam_fl.
Source code in src/furax/obs/operators/_beam_operator.py
BeamOperatorIQU
dataclass
Bases: AbstractLinearOperator
Beam operator with an independent transfer function per Stokes component.
Input PyTree leaves are expected to have shape (nfreq, npix). Each leaf
is smoothed with its own transfer function taken from the corresponding leaf
of beam_fl, enabling different beams for I, Q, and U (or any other
Stokes combination).
The operator is symmetric (self-adjoint). Use inverse to obtain the
deconvolution operator (each beam_fl leaf replaced by its reciprocal).
Algebraic rule: BeamOperatorIQU @ BeamOperatorIQU reduces to a single
operator whose per-leaf transfer functions are the element-wise products of
both (see BeamIQURule).
Attributes:
-
lmax(int) –Maximum spherical harmonic degree.
-
beam_fl(PyTree[Float[Array, 'nfreq lp1']]) –PyTree with the same structure as the input maps; each leaf has shape
(nfreq, lmax+1)and carries the per-frequency beam transfer function for that Stokes component.
Examples:
>>> import jax.numpy as jnp
>>> from furax.obs.stokes import StokesIQU
>>> from furax.obs.operators import BeamOperatorIQU
>>> nside, lmax, nfreq = 16, 31, 2
>>> npix = 12 * nside ** 2
>>> structure = StokesIQU.structure_for((nfreq, npix), jnp.float64)
>>> fl = jnp.ones((nfreq, lmax + 1))
>>> beam_fl = StokesIQU(i=fl, q=fl, u=fl)
>>> op = BeamOperatorIQU(lmax=lmax, beam_fl=beam_fl, in_structure=structure)
Methods:
-
mv–Apply per-Stokes beams to input sky maps.
-
inverse–Return a
BeamOperatorIQUwith per-Stokes reciprocal transfer functions.
Source code in src/furax/obs/operators/_beam_operator.py
lmax
instance-attribute
beam_fl
instance-attribute
mv(x)
Apply per-Stokes beams to input sky maps.
Parameters:
-
x(PyTree[Inexact[Array, 'nfreq npix']]) –Input PyTree whose leaves have shape
(nfreq, npix)or(npix,)for a single-frequency input. The PyTree structure must match that ofself.beam_fl.
Returns:
-
PyTree[Inexact[Array, 'nfreq npix']]–Beam-smoothed PyTree with the same structure and leaf shapes as x.
Source code in src/furax/obs/operators/_beam_operator.py
inverse()
Return a BeamOperatorIQU with per-Stokes reciprocal transfer functions.
Returns:
-
BeamOperatorIQU–A new
BeamOperatorIQUwhosebeam_flleaves equal -
BeamOperatorIQU–1 / leaffor each leaf inself.beam_fl.
Source code in src/furax/obs/operators/_beam_operator.py
HWPOperator
dataclass
Bases: AbstractLinearOperator
Operator for an ideal half-wave plate (HWP).
A HWP flips the sign of the U (and V) Stokes parameters while leaving I and Q unchanged. This models the Mueller matrix diag(1, 1, -1, -1).
The operator is diagonal and symmetric. For a rotating HWP at angle theta,
use HWPOperator.create(..., angles=theta) which computes R(-theta) @ HWP @ R(theta).
Algebraic rule: R(theta) @ HWP = HWP @ R(-theta).
Methods:
Source code in src/furax/obs/operators/_hwp.py
create(shape, dtype=np.float64, stokes='IQU', *, angles=None)
classmethod
Source code in src/furax/obs/operators/_hwp.py
mv(x)
Source code in src/furax/obs/operators/_hwp.py
LinearPolarizerOperator
dataclass
Bases: AbstractLinearOperator
Operator for an ideal linear polarizer.
Extracts the intensity seen by a linear polarizer aligned with the x-axis:
d = 0.5 * (I + Q). For a polarizer at angle psi, use
LinearPolarizerOperator.create(..., angles=psi).
This implements: d = 0.5 * (I + Qcos(2psi) + Usin(2psi)).
Algebraic rule: LinearPolarizer @ HWP = LinearPolarizer.
Methods:
Source code in src/furax/obs/operators/_polarizers.py
create(shape, dtype=np.float64, stokes='IQU', *, angles=None)
classmethod
Source code in src/furax/obs/operators/_polarizers.py
QURotationOperator
dataclass
Bases: AbstractLinearOperator
Operator that rotates Q and U Stokes parameters by angle theta.
Applies the rotation matrix R(theta) which transforms (Q, U) as: Q' = Qcos(2theta) + Usin(2theta) U' = -Qsin(2theta) + Ucos(2theta)
I and V components are unchanged. The operator is orthogonal: R.T = R.I = R(-theta).
Consecutive rotations combine: R(a) @ R(b) = R(a+b).
Attributes:
-
angles(Float[Array, ...]) –Rotation angles in radians.
-
atomic(bool) –If True, prevents this operator from being merged with adjacent QU rotation operators during algebraic reduction.
Methods:
Source code in src/furax/obs/operators/_qu_rotations.py
angles
instance-attribute
atomic = field(kw_only=True, default=False, metadata={'static': True})
class-attribute
instance-attribute
create(shape, dtype=np.float64, stokes='IQU', *, angles, atomic=False)
classmethod
Source code in src/furax/obs/operators/_qu_rotations.py
mv(x)
AbstractSEDOperator
Bases: AbstractLinearOperator
Abstract base class for Spectral Energy Distribution (SED) operators.
SED operators model how astrophysical components emit radiation across frequencies. They broadcast sky maps to multiple frequency channels.
Subclasses must implement the sed() method to define the spectral
energy distribution.
Attributes:
-
frequencies(Float[Array, ' a']) –Array of observation frequencies.
Methods:
Source code in src/furax/obs/operators/_seds.py
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 | |
frequencies
instance-attribute
__init__(frequencies, *, in_structure)
Source code in src/furax/obs/operators/_seds.py
mv(x)
Source code in src/furax/obs/operators/_seds.py
sed()
abstractmethod
Define the spectral energy distribution transformation.
Returns:
-
Float[Array, ...]–Float[Array, '...']: The transformed SED.
CMBOperator
Bases: AbstractSEDOperator
Operator for Cosmic Microwave Background (CMB) spectral energy distribution.
The CMB has a blackbody spectrum at T_CMB ~ 2.725 K. In K_CMB units, the SED is constant (unity) across frequencies. In K_RJ units, a frequency-dependent conversion factor is applied.
Attributes:
-
frequencies(Float[Array, ' a']) –Observation frequencies [GHz].
-
units(str) –Output units ('K_CMB' or 'K_RJ').
-
factor(Float[Array, ...] | float) –Unit conversion factor.
Examples:
>>> nu = jnp.array([30, 40, 100]) # GHz
>>> cmb_op = CMBOperator(frequencies=nu, in_structure=landscape.structure)
>>> tod = cmb_op(sky_map) # Broadcasts CMB map to all frequencies
Methods:
Source code in src/furax/obs/operators/_seds.py
factor
instance-attribute
units = field(metadata={'static': True})
class-attribute
instance-attribute
__init__(frequencies, *, in_structure, units='K_CMB')
Source code in src/furax/obs/operators/_seds.py
sed()
Compute the spectral energy distribution for the CMB.
Returns:
-
Float[Array, ...]–Float[Array, '...']: The SED for the CMB.
Source code in src/furax/obs/operators/_seds.py
DustOperator
Bases: AbstractSEDOperator
Operator for thermal dust spectral energy distribution.
Models dust emission as a modified blackbody: a power law times a Planck function. The SED is: (nu/nu0)^(1+beta) * B(nu,T)/B(nu0,T), where B is the Planck function.
Supports spatially varying spectral parameters via patch indices.
Attributes:
-
frequencies(Float[Array, ' a']) –Observation frequencies [GHz].
-
frequency0(float) –Reference frequency [GHz].
-
temperature(Float[Array, ...]) –Dust temperature [K].
-
beta(Float[Array, ...]) –Spectral index (typically ~1.5).
-
units(str) –Output units ('K_CMB' or 'K_RJ').
Examples:
>>> nu = jnp.array([100, 143, 217, 353]) # GHz
>>> dust_op = DustOperator(
... frequencies=nu, frequency0=353, beta=1.54, temperature=20.0,
... in_structure=landscape.structure
... )
>>> tod = dust_op(dust_map)
Methods:
Source code in src/furax/obs/operators/_seds.py
temperature
instance-attribute
temperature_patch_indices
instance-attribute
beta
instance-attribute
beta_patch_indices
instance-attribute
factor
instance-attribute
units = field(metadata={'static': True})
class-attribute
instance-attribute
frequency0 = field(metadata={'static': True})
class-attribute
instance-attribute
__init__(frequencies, *, frequency0=100, temperature, units='K_CMB', temperature_patch_indices=None, beta, beta_patch_indices=None, in_structure)
Source code in src/furax/obs/operators/_seds.py
sed()
Source code in src/furax/obs/operators/_seds.py
NoiseDiagonalOperator
dataclass
Bases: AbstractLinearOperator
Constructs a diagonal noise operator.
This operator applies a noise vector (in a PyTree structure) in an element‐wise multiplication to an input data PyTree.
Attributes:
-
vector(PyTree[Inexact[Array, ...]]) –PyTree of arrays representing the noise values.
-
in_structure(PyTree[ShapeDtypeStruct]) –Input structure (PyTree[jax.ShapeDtypeStruct]) specifying the shape and dtype.
Examples:
>>> import jax
>>> import jax.numpy as jnp
>>> from furax.obs.landscapes import FrequencyLandscape
>>> from furax.obs.operators import NoiseDiagonalOperator
>>>
>>> landscape = FrequencyLandscape(nside=64, frequencies=jnp.linspace(30, 300, 10))
>>> noise_sample = landscape.normal(jax.random.key(0)) # small n
>>> d = landscape.normal(jax.random.key(0)) # d
>>> N = NoiseDiagonalOperator(noise_sample, in_structure=d.structure)
>>> N.I(d).structure
StokesIQU(ShapeDtypeStruct(shape=(3, 10, 49152), dtype=float64))
Methods:
Source code in src/furax/obs/operators/_seds.py
vector
instance-attribute
mv(x)
inverse()
SynchrotronOperator
Bases: AbstractSEDOperator
Operator for synchrotron spectral energy distribution.
Models synchrotron emission as a power law: (nu/nu0)^beta, with optional spectral index running: (nu/nu0)^(beta + running * log(nu/nu_pivot)).
Supports spatially varying spectral parameters via patch indices.
Attributes:
-
frequencies(Float[Array, ' a']) –Observation frequencies [GHz].
-
frequency0(float) –Reference frequency [GHz].
-
beta_pl(Float[Array, ...]) –Power-law spectral index (typically ~ -3).
-
nu_pivot(float) –Pivot frequency for running [GHz].
-
running(float) –Running of the spectral index.
-
units(str) –Output units ('K_CMB' or 'K_RJ').
Examples:
>>> nu = jnp.array([30, 44, 70]) # GHz
>>> sync_op = SynchrotronOperator(
... frequencies=nu, frequency0=30, beta_pl=-3.0,
... in_structure=landscape.structure
... )
>>> tod = sync_op(synchrotron_map)
Methods:
Source code in src/furax/obs/operators/_seds.py
277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 | |
beta_pl
instance-attribute
beta_pl_patch_indices
instance-attribute
nu_pivot = field(metadata={'static': True})
class-attribute
instance-attribute
running = field(metadata={'static': True})
class-attribute
instance-attribute
units = field(metadata={'static': True})
class-attribute
instance-attribute
frequency0 = field(metadata={'static': True})
class-attribute
instance-attribute
factor
instance-attribute
__init__(frequencies, *, frequency0=100, nu_pivot=1.0, running=0.0, units='K_CMB', beta_pl, beta_pl_patch_indices=None, in_structure)
Source code in src/furax/obs/operators/_seds.py
sed()
Source code in src/furax/obs/operators/_seds.py
MixingMatrixOperator(**blocks)
Constructs a mixing matrix operator from a set of SED operators.
This function combines multiple spectral energy distribution (SED) operators into a single block row operator for use in linear models.
Parameters:
-
**blocks(AbstractSEDOperator, default:{}) –Named SED operators to combine into the mixing matrix.
Returns:
-
BlockRowOperator(AbstractLinearOperator) –A reduced block row operator representing the mixing matrix.
Examples:
>>> from furax.obs import CMBOperator, DustOperator, SynchrotronOperator, MixingMatrixOperator
>>> nu = jnp.array([30, 40, 100]) # Frequencies in GHz
>>> in_structure = ... # Define input structure (e.g., using HealpixLandscape)
>>> sky_map = ... # Define sky map
>>> cmb = CMBOperator(nu, in_structure=in_structure)
>>> dust = DustOperator(
... nu,
... frequency0=150.0,
... temperature=20.0,
... beta=1.54,
... in_structure=in_structure
... )
>>> synchrotron = SynchrotronOperator(
... nu,
... frequency0=20.0,
... beta_pl=-3.0,
... in_structure=in_structure
... )
>>> A = MixingMatrixOperator(cmb=cmb, dust=dust, synchrotron=synchrotron)
>>> d = A(sky_map)
Source code in src/furax/obs/operators/_seds.py
furax.obs.pointing
Classes:
-
PointingOperator–Operator that projects sky maps to time-ordered data (TOD) using quaternion pointing.
PointingOperator
dataclass
Bases: AbstractLinearOperator
Operator that projects sky maps to time-ordered data (TOD) using quaternion pointing.
Equivalent to: QURotation @ Index @ Ravel, but computed on-the-fly to save memory. For each detector and time sample, it: 1. Computes the sky pixel from boresight and detector quaternions 2. Samples the sky map at that pixel 3. Rotates Stokes QU by the polarization angle
The transpose accumulates TOD into a sky map (binning).
Attributes:
-
landscape(StokesLandscape) –The sky pixelization (HEALPix landscape).
-
qbore(Float[Array, 'samp 4']) –Boresight quaternions, shape (n_samples, 4).
-
qdet(Float[Array, 'det 4']) –Detector quaternions, shape (n_detectors, 4).
-
batch_size(int) –Detector batch size (memory/speed tradeoff; see jax.lax.map documentation).
Methods:
-
create– -
mv–Performs the 'un-pointing' operation, i.e. map->tod.
-
as_stokes_i–Return a copy of this operator restricted to StokesI.
-
as_expanded_operator–Return the equivalent QURotationOperator @ IndexOperator @ RavelOperator.
-
transpose–
Source code in src/furax/obs/pointing.py
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 | |
landscape
instance-attribute
qbore
instance-attribute
qdet
instance-attribute
batch_size = field(metadata={'static': True})
class-attribute
instance-attribute
interpolate = field(metadata={'static': True})
class-attribute
instance-attribute
out_structure
property
create(landscape, boresight_quaternions, detector_quaternions, *, batch_size=32, frame='boresight', interpolate=False)
classmethod
Source code in src/furax/obs/pointing.py
mv(x)
Performs the 'un-pointing' operation, i.e. map->tod.
Source code in src/furax/obs/pointing.py
as_stokes_i(*, interpolate=None)
Return a copy of this operator restricted to StokesI.
Parameters:
-
interpolate(bool | None, default:None) –Override the interpolation flag. If
None(default), the flag is inherited fromself.interpolate.
Source code in src/furax/obs/pointing.py
as_expanded_operator()
Return the equivalent QURotationOperator @ IndexOperator @ RavelOperator.
Equivalent to mv() but as an explicit composition, useful for testing.
Source code in src/furax/obs/pointing.py
furax.obs.stokes
Classes:
-
Stokes–Stokes container backed by a single dense array with the components on the leading axis.
-
StokesI– -
StokesQU– -
StokesIQU– -
StokesIQUV–
Attributes:
ValidStokesType = Literal['I', 'QU', 'IQU', 'IQUV']
module-attribute
Stokes
dataclass
Bases: ABC
Stokes container backed by a single dense array with the components on the leading axis.
Concrete subclasses (StokesI, StokesQU, StokesIQU, StokesIQUV) each fix which Stokes
components (a subset of I, Q, U, V) they hold. The components are stacked on axis 0 of a single
array field, e.g. a StokesIQU over a (npix,) sky backs a (3, npix) array. Instances
are registered as pytrees with the array as the only leaf.
Examples:
Construct from separate components, positionally or by keyword. Components are promoted to a common dtype and stacked, producing a jax-device array:
>>> import jax.numpy as jnp
>>> from furax.obs.stokes import Stokes, StokesIQU
>>> x = StokesIQU(jnp.ones(4), jnp.zeros(4), jnp.zeros(4))
>>> y = StokesIQU(i=jnp.ones(4), q=jnp.zeros(4), u=jnp.zeros(4))
from_stokes infers the concrete subclass from the number of components given:
from_array wraps an already-stacked array (leading axis = number of components).
A plain numpy.ndarray is kept as-is, with no transfer to a jax device -- this is how
to build a host-only instance, e.g. inside a numpy-only I/O callback:
>>> import numpy as np
>>> host_array = np.zeros((3, 4)) # (n_stokes, npix)
>>> host_only = StokesIQU.from_array(host_array)
>>> isinstance(host_only.data, np.ndarray)
True
Methods:
-
__init__– -
from_array–Wrap a backing array of shape
(len(stokes), *shape). -
__pdoc__– -
__repr__– -
__getitem__– -
__eq__– -
__matmul__–Returns the scalar product between Stokes maps.
-
__abs__– -
__pos__– -
__neg__– -
__add__– -
__sub__– -
__mul__– -
__truediv__– -
__pow__– -
__radd__– -
__rsub__– -
__rmul__– -
__rtruediv__– -
__rpow__– -
ravel–Ravels the batch axes of each Stokes component.
-
reshape–Reshape the batch axes of each Stokes component.
-
rotate_qu–Rotate the Q, U components by an angle whose double-angle cos/sin are given.
-
class_for–Returns the StokesPyTree subclass associated to the specified Stokes types.
-
structure_for– -
from_stokes–Returns a StokesPyTree according to the specified Stokes vectors.
-
from_iquv–Build this Stokes type from the full I, Q, U, V set, keeping only its own components.
-
zeros– -
ones– -
full– -
normal– -
uniform–
Attributes:
-
stokes(ValidStokesType) – -
data(Array) – -
i(Array) – -
q(Array) – -
u(Array) – -
v(Array) – -
shape(tuple[int, ...]) –Returns the common shape of the Stokes components.
-
dtype(dtype) – -
structure(PyTree[ShapeDtypeStruct]) –
Source code in src/furax/obs/stokes.py
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 | |
stokes
class-attribute
data = jnp.stack(components, axis=0)
instance-attribute
i
property
q
property
u
property
v
property
shape
property
Returns the common shape of the Stokes components.
dtype
property
structure
property
__init__(*args, **kwargs)
Source code in src/furax/obs/stokes.py
from_array(array)
classmethod
Wrap a backing array of shape (len(stokes), *shape).
A plain numpy.ndarray is kept as-is (no device transfer); anything else is
coerced through jnp.asarray.
Source code in src/furax/obs/stokes.py
__pdoc__(**kwargs)
__repr__()
__getitem__(index)
Source code in src/furax/obs/stokes.py
__eq__(other)
Source code in src/furax/obs/stokes.py
__matmul__(other)
Returns the scalar product between Stokes maps.
__abs__()
__neg__()
__add__(other)
__sub__(other)
__mul__(other)
__truediv__(other)
__pow__(other)
__radd__(other)
__rsub__(other)
__rmul__(other)
__rtruediv__(other)
__rpow__(other)
ravel()
reshape(shape)
rotate_qu(cos_2angles, sin_2angles)
Rotate the Q, U components by an angle whose double-angle cos/sin are given.
Q' = Q cos2a + U sin2a, U' = -Q sin2a + U cos2a; I and V are unchanged. Q and U are
adjacent rows on the leading Stokes axis, so this updates just those two rows in place.
A type without Q (StokesI) is returned unchanged.
Source code in src/furax/obs/stokes.py
class_for(stokes)
classmethod
Returns the StokesPyTree subclass associated to the specified Stokes types.
Source code in src/furax/obs/stokes.py
structure_for(shape, dtype=np.float64)
classmethod
from_stokes(*args, **keywords)
classmethod
Returns a StokesPyTree according to the specified Stokes vectors.
Examples:
>>> tod_i = Stokes.from_stokes(i)
>>> tod_qu = Stokes.from_stokes(q, u)
>>> tod_iqu = Stokes.from_stokes(i, q, u)
>>> tod_iquv = Stokes.from_stokes(i, q, u, v)
Source code in src/furax/obs/stokes.py
from_iquv(i, q, u, v)
classmethod
Build this Stokes type from the full I, Q, U, V set, keeping only its own components.