Skip to content

torchsky.map.operators.noise

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.

Per-pixel detector likelihoods: the normalized Gaussian negative log-likelihood, and the Poisson-Gaussian mixture for a few electrons per pixel read out with Gaussian noise. Both are also importable from torchsky.map.operators.

Guides: likelihoods


This page is generated from the module source. Import these names from torchsky.map.operators.noise.

Functions

Tensor-native structured-noise primitives for detector observations.

The functions in this module deliberately keep the noise model bounded and interpretable. Pipeline variance planes are combined with positive scalar or leading-axis calibration factors, row-correlated noise is represented by an explicit one-over-frequency PSD, and residual contamination uses a two- component Gaussian/Student-t mixture. There is no free-form variance image.

The FFT whitening filter is relative whitening: it multiplies Fourier modes by sqrt(P_white / P(f)). Thus its output has the same units as its input and a constant PSD is exactly the identity filter. P(f) is a one-sided power spectral density in input-units-squared per Hz; the ratio is independent of the particular orthonormal/non-orthonormal FFT convention.

gaussian_nll

gaussian_nll(
    observed: Tensor,
    expected: Tensor,
    variance: Tensor,
    *,
    reduction: Literal["none", "mean", "sum"] = "mean",
) -> Tensor

Normalized Gaussian detector negative log likelihood.

Per pixel 0.5 * (log(2 pi variance) + (observed - expected)^2 / variance), including the normalization, so values are comparable across noise models and differentiable with respect to expected and variance.

Parameters:

Name Type Description Default
observed Tensor

Measured values.

required
expected Tensor

Model prediction, broadcastable against observed.

required
variance Tensor

Strictly positive per-pixel variance, broadcastable.

required
reduction Literal['none', 'mean', 'sum']

"none" (per pixel), "mean", or "sum".

'mean'

Returns:

Type Description
Tensor

Negative log-likelihood in nats, reduced as requested.

Raises:

Type Description
ValueError

If inputs are not finite or a variance is not positive.

Examples:

>>> import math, torch
>>> from torchsky.map.operators import gaussian_nll
>>> value = gaussian_nll(torch.zeros(3), torch.zeros(3), torch.ones(3))
>>> abs(float(value) - 0.5 * math.log(2.0 * math.pi)) < 1e-6
True

poisson_gaussian_nll

poisson_gaussian_nll(
    observed: Tensor,
    expected_electrons: Tensor,
    read_noise_variance: Tensor,
    *,
    gain: Tensor | float = 1.0,
    background: Tensor | float = 0.0,
    tail_sigma: float = 12.0,
    max_terms: int = 4096,
    reduction: Literal["none", "mean", "sum"] = "mean",
) -> Tensor

Normalized finite-mixture Poisson--Gaussian detector NLL.

The latent electron count is Poisson and the measured value conditional on that count is Gaussian. A per-pixel Poisson support containing at least tail_sigma standard deviations is retained and explicitly renormalized, so the returned finite mixture is a normalized density. Support selection is detached from autograd. Positive-rate derivatives are local to the retained support; changing support can change the finite-mixture law discontinuously. At exactly zero rate, first/second rate and mixed derivatives are the exact right-hand continuation, including a cutoff that increases immediately to the right of zero. Third/higher rate derivatives at zero are unsupported. A requested zero-rate derivative outside the dtype range rejects, while inference-only zero-rate values remain available. Positive-rate autograd uses modal polynomial sums, with separate prior and observation-conditioned pivots, avoiding tiny-rate logarithmic curvature cancellation and density underflow. Derivatives exceeding the modal intermediate range reject; inference-only values use the same retained law's log-sum evaluation in that domain. This is a numeric range contract, not an intensity cutoff or change of physical model. It can conservatively reject a finite final derivative when reference scales underflow or larger intermediate curvature terms are not representable.

The Poisson support is chosen per pixel from the expected rate and the observed value (see _poisson_gaussian_window): the prior window is merged with a tail_sigma window around the mode of the observation-conditioned weight. A far outlier whose posterior window is disjoint from the prior one is scored with the exact unrenormalised Poisson log pmf over its own window. Pixels are processed in chunks of about 2**22 count terms (with activation checkpointing under reverse-mode autograd), so peak memory is independent of frame size.

gain is output units per electron, background is a signed deterministic output-unit offset, and read_noise_variance is in output units squared. Expected electrons are a physical nonnegative integrated Poisson mean, including all independent photon/dark contributions. This normalized finite mixture is not the full untruncated physical law, nor a joint likelihood for correlated charge mixing or read noise. Observations require real float32/float64 tensors; integer and low-precision observations are unsupported. Other tensor parameters follow observation dtype/device by the existing explicit coercion convention.

Parameters:

Name Type Description Default
observed Tensor

Measured values in output units (float32 or float64).

required
expected_electrons Tensor

Non-negative Poisson mean of the electron count.

required
read_noise_variance Tensor

Positive Gaussian read variance in output units squared.

required
gain Tensor | float

Output units per electron.

1.0
background Tensor | float

Signed deterministic offset in output units.

0.0
tail_sigma float

Retained Poisson and posterior support, in standard deviations.

12.0
max_terms int

Largest retained count window per pixel.

4096
reduction Literal['none', 'mean', 'sum']

"none" (per pixel), "mean", or "sum".

'mean'

Returns:

Type Description
Tensor

Negative log-likelihood in nats, reduced as requested.

Examples:

>>> import torch
>>> from torchsky.map.operators import poisson_gaussian_nll
>>> observed = torch.tensor([0.4, 2.1, 5.3], dtype=torch.float64)
>>> rate = torch.full((3,), 2.0, dtype=torch.float64)
>>> nll = poisson_gaussian_nll(observed, rate, torch.tensor(0.25, dtype=torch.float64))
>>> bool(torch.isfinite(nll))
True