torchsky.map.field.chromatic¶
Experimental surface
These APIs are under active development. Names, defaults, and result objects may change between minor releases; pin a version if you depend on them in production.
Chromatic PSF fields and continuous-wavelength sky fields integrated over band transmission curves.
This reference is generated from the package source. Names are grouped by
the module that defines them; import every name from the public
namespace torchsky.map.field.chromatic unless the group text says otherwise.
Top-level namespace¶
Chromatic PSF fields and continuous-wavelength sky fields for multiband forward models.
These are the building blocks of a forward model in which a single sky
s(x, y, lambda) is observed through each band's transmission curve and a
PSF that varies smoothly with wavelength and detector position:
m_b(p) = sum_q w_bq sum_k u_k(p; lambda_b) [K_k(.; lambda_bq) * s(., lambda_bq)](T(p))
- :class:
ChromaticPSFField-- one network for every band: kernel coordinates are expressed in diffraction unitsdx * pixel / (lambda / D)so the Airy-like structure scales with wavelength by construction, plus pixel-unit coordinates for pixel response and jitter. Kernel0is a normalised, non-negative core; kernels1..are zero-sum perturbations mixed with weights that vary smoothly over the detector. - :class:
LogLambdaRBFBasis-- a partition-of-unity spectral basis uniform inlog lambda, optionally with a learned smooth correction. - :class:
SpectralSkyField--s(x, y, lambda) = sum_k a_k(x, y) phi_k(lambda)with any coefficient provider (pixel grid or neural field) and band quadrature nodes from :func:torchsky.filter_profiles.photon_quadrature.
Everything is plain torch and runs on CPU, CUDA and MPS.
ChromaticPSFField ¶
ChromaticPSFField(
*,
num_channels: int,
num_detectors: int,
pixel_scale_arcsec: float,
aperture_m: float = 6.5,
num_kernels: int = 4,
size: int = 31,
hidden: int = 96,
max_diffraction_radius: float = 24.0,
lambda_ref_um: float = 2.0,
)
Bases: Module
PSF basis field smooth in wavelength and detector position.
Parameters¶
num_channels:
Number of optical channels sharing the field (e.g. 2 for NIRCam SW/LW);
a channel embedding conditions the kernel network.
num_detectors:
Detectors with their own (learned) embedding for the spatial weights.
pixel_scale_arcsec:
Pixel scale of the grid the kernels are sampled on.
aperture_m:
Telescope diameter, used for lambda / D.
num_kernels:
Kernel 0 is the normalised core, the others zero-sum perturbations.
size:
Odd kernel side in grid pixels.
max_diffraction_radius:
Normaliser of the diffraction-unit coordinates (in lambda / D).
kernel_net
instance-attribute
¶
kernel_net = Sequential(
Linear(2 * 2 * 6 + 2 * 2 * 4 + cond, hidden),
SiLU(),
Linear(hidden, hidden),
SiLU(),
Linear(hidden, hidden),
SiLU(),
Linear(hidden, num_kernels),
)
weight_net
instance-attribute
¶
weight_net = Sequential(
Linear(2 * 2 * 3 + cond + 4, 48),
SiLU(),
Linear(48, 48),
SiLU(),
Linear(48, max(num_kernels - 1, 1)),
)
basis ¶
basis(lam_um: Tensor, channel: Tensor) -> Tensor
Kernels at wavelengths lam_um (M,) and channels (M,): (M, num_kernels, size, size).
centring_penalty ¶
centring_penalty(lam_um: Tensor, channel: Tensor) -> Tensor
Sum of squared first moments of every kernel: pins the PSF centroid, which is otherwise degenerate with the astrometric solution.
weights ¶
weights(
lam_um: Tensor,
channel: Tensor,
detector: Tensor,
u: Tensor,
v: Tensor,
) -> Tensor
Mixing weights (N, num_kernels) at detector coordinates u, v in [-1, 1].
lam_um, channel and detector broadcast against u.
LogLambdaRBFBasis ¶
LogLambdaRBFBasis(
num_basis: int,
lam_min_um: float,
lam_max_um: float,
*,
learned: bool = False,
)
Bases: Module
phi_k(lambda): K normalised Gaussian bumps uniform in log lambda on
[lam_min, lam_max] (a partition of unity), optionally plus a learned smooth
correction initialised at zero.
SpectralSkyField ¶
SpectralSkyField(
coefficients: Module,
basis: LogLambdaRBFBasis,
nodes_um: Tensor,
node_weights: Tensor,
*,
spectral_smoothness: float = 0.0,
scale: float = 1.0,
smoothness_mode: str = "relative",
floor: float = 3.0,
)
Bases: Module
Continuous sky s(x, y, lambda) = sum_k a_k(x, y) phi_k(lambda).
coefficients is any module returning (K, H, W) (a pixel grid or a neural
field); nodes_um / node_weights are (B, Q) band quadrature nodes, e.g.
from :func:torchsky.filter_profiles.photon_quadrature.
The spectral prior penalises the second difference of a_k across k.
smoothness_mode="relative" (the default) divides it by each pixel's own
spectral level (mean_k |a_k| + floor * scale), so a colour gradient costs the
same for a faint galaxy as for a bright one; "absolute" divides by scale
only and flattens the spectra of bright sources.
at_nodes ¶
at_nodes() -> tuple[Tensor, Tensor]
(B, Q, H, W) sky at every quadrature node and (B, H, W) band averages.
spectral_coefficients_from_bands ¶
spectral_coefficients_from_bands(
band_images: Tensor,
nodes_um: Tensor,
node_weights: Tensor,
basis: LogLambdaRBFBasis,
*,
smoothness: float = 1e-05,
) -> Tensor
Initial a_k that reproduce band_images (B, H, W) through the band
quadrature: ridge least squares with a second-difference prior across k.