Skip to content

torchsky.spectrophotometry

Stability: core. Names on this page follow the deprecation policy in contributing.

Unit-explicit passbands and deterministic synthetic photometry.

Guides: photometry, spectral-axes


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.spectrophotometry unless the group text says otherwise.

Top-level namespace

Unit-explicit passbands and deterministic synthetic photometry.

The public contract uses wavelength in Angstrom internally. A passband is a dimensionless throughput curve, and spectra are sampled F_lambda values. Photon-counting integrations use the detector response throughput * lambda weight. No optional astronomy package is required, so applications can add their own FITS/table adapters without making this numerical surface depend on file formats.

Passband dataclass

Passband(
    wavelength: Tensor,
    throughput: Tensor,
    name: str = "",
    wavelength_unit: WavelengthUnit = "angstrom",
)

Validated dimensionless throughput curve for one astronomical band.

Parameters:

Name Type Description Default
wavelength Tensor

Strictly increasing one-dimensional wavelength samples.

required
throughput Tensor

Dimensionless nonnegative response at each wavelength.

required
name str

Optional band identifier.

''
wavelength_unit WavelengthUnit

"angstrom" or "nm".

'angstrom'

Examples:

>>> import torch
>>> from torchsky.spectrophotometry import Passband
>>> band = Passband(torch.tensor([4000.0, 5000.0]), torch.tensor([0.0, 1.0]))
>>> band.wavelength_unit
'angstrom'

effective_wavelength property

effective_wavelength: Tensor

Photon-weighted effective wavelength in Angstrom.

name class-attribute instance-attribute

name: str = ''

pivot_wavelength property

pivot_wavelength: Tensor

Pivot wavelength in Angstrom for converting mean F_lambda and F_nu.

throughput instance-attribute

throughput: Tensor

wavelength instance-attribute

wavelength: Tensor

wavelength_unit class-attribute instance-attribute

wavelength_unit: WavelengthUnit = 'angstrom'

__post_init__

__post_init__() -> None

evaluate

evaluate(wavelength: Tensor) -> Tensor

Linear throughput at Angstrom-native wavelength; zero outside support.

from_samples classmethod

from_samples(
    wavelength: Tensor,
    throughput: Tensor,
    *,
    name: str = "",
    wavelength_unit: WavelengthUnit = "angstrom",
) -> Passband

Canonicalize an unsorted curve, averaging duplicate wavelengths.

to

to(device: device | str) -> Passband

Return the canonical passband on device.

Passband samples remain float64 calibration metadata on devices that support it. Evaluation casts them to the query dtype, so moving a scene or observation never silently lowers the precision of the stored response curve. A device without float64 (MPS) holds the curve in float32, the same rule Passband applies to tensors created there.

PhotometryResult dataclass

PhotometryResult(
    value: Tensor,
    unit: str,
    coverage: Tensor,
    valid: Tensor,
)

Synthetic photometry values and the coverage diagnostics that qualify them.

coverage instance-attribute

coverage: Tensor

unit instance-attribute

unit: str

valid instance-attribute

valid: Tensor

value instance-attribute

value: Tensor

evaluate_throughput

evaluate_throughput(
    wavelength: Tensor,
    *,
    passband: Passband | None = None,
    center: Tensor | float | None = None,
    sigma: float | None = None,
    lambda_center_map: Tensor | None = None,
    wavelength_unit: WavelengthUnit = "angstrom",
) -> Tensor

Evaluate tabulated or Gaussian throughput at wavelength.

Gaussian / LVF paths use the caller's wavelength unit. Tabulated :class:Passband queries are converted to Angstrom. lambda_center_map makes the Gaussian centre position-dependent (linear-variable filters).

flux_to_magnitude

flux_to_magnitude(
    flux: Tensor, zero_point: float | Tensor
) -> Tensor

Convert positive fluxes to magnitudes for an explicit flux zero point.

magnitude_to_flux

magnitude_to_flux(
    magnitude: Tensor, zero_point: float | Tensor
) -> Tensor

Convert magnitudes to flux using an explicit zero point.

synthetic_photometry

synthetic_photometry(
    wavelength: Tensor,
    flux_lambda: Tensor,
    passband: Passband,
    *,
    output: PhotometryOutput = "mean_f_lambda",
    min_coverage: float = 0.99,
    mask: Tensor | None = None,
    weighting: Weighting = "photon",
) -> PhotometryResult

Integrate one spectrum or a batch through a passband.

wavelength may be 1D (shared grid) or match flux_lambda including a trailing spectral axis. flux_lambda is per Angstrom in arbitrary units for mean_f_lambda. For f_nu_microjy and ab_mag it must be cgs F_lambda in erg s^-1 cm^-2 Angstrom^-1. Missing or insufficiently covered bands return NaN values and valid=False.

mask, when given, is True for samples that exist. Masked wavelengths are dropped from the integral and do not count toward filter coverage.

weighting="photon" (default) is a photon-counting detector, mean F_lambda = int F R lambda dlambda / int R lambda dlambda; "energy" is an energy-counting one (bolometers, some published curves), int F R dlambda / int R dlambda. Coverage is measured with the same weight.

Parameters:

Name Type Description Default
wavelength Tensor

Shared or per-spectrum wavelength samples.

required
flux_lambda Tensor

Flux density per Angstrom on the trailing spectral axis.

required
passband Passband

Photon-counting throughput curve.

required
output PhotometryOutput

Requested mean-flux, microjansky, or AB-magnitude representation.

'mean_f_lambda'
min_coverage float

Minimum passband response fraction required for validity.

0.99
mask Tensor | None

Optional valid-sample mask.

None
weighting Weighting

"photon" or "energy" counting response.

'photon'

Returns:

Type Description
PhotometryResult

Photometry values, unit, passband coverage, and validity mask.

Examples:

>>> import torch
>>> from torchsky.spectrophotometry import Passband, synthetic_photometry
>>> band = Passband(torch.tensor([4000.0, 5000.0]), torch.ones(2))
>>> synthetic_photometry(band.wavelength, torch.ones(2), band).value.item()
1.0

synthetic_photometry_bands

synthetic_photometry_bands(
    wavelength: Tensor,
    flux_lambda: Tensor,
    passbands: Sequence[Passband],
    *,
    output: PhotometryOutput = "mean_f_lambda",
    min_coverage: float = 0.99,
    mask: Tensor | None = None,
    weighting: Weighting = "photon",
) -> PhotometryResult

Integrate through many passbands; values have a trailing band axis.

throughput_from_mapping

throughput_from_mapping(
    band_id: str, spec: Mapping[str, Any]
) -> Passband | dict[str, Any]

Build a :class:Passband or Gaussian/LVF dict from a filter-profile mapping.

vega_spectrum

vega_spectrum(
    device: device | str | None = None,
) -> tuple[Tensor, Tensor]

The CALSPEC spectrum of Vega, packaged with torchsky.

alpha_lyr_stis_012 (Bohlin, Hubeny & Rauch 2020): HST/STIS data from 1152 to 10200 A joined to a 9550 K model, normalised to 3.47e-9 erg s^-1 cm^-2 A^-1 at 5556 A. Public-domain STScI data, 92 kB in the wheel.

Parameters:

Name Type Description Default
device device | str | None

Target device; float64 where the device supports it.

None

Returns:

Type Description
tuple[Tensor, Tensor]

Vacuum wavelength in Angstrom and F_lambda in cgs units.

Examples:

>>> from torchsky.spectrophotometry import vega_spectrum
>>> wave, flux = vega_spectrum()
>>> wave.shape == flux.shape, float(wave[0]) < 1000.0
(True, True)

vega_zero_point

vega_zero_point(
    passband: Passband,
    *,
    output: Literal[
        "mean_f_lambda", "f_nu_microjy"
    ] = "mean_f_lambda",
    weighting: Weighting = "photon",
) -> Tensor

Band-averaged flux of Vega, the zero point of a Vega magnitude system.

m_Vega = -2.5 log10(<F> / vega_zero_point(band)) with <F> from :func:synthetic_photometry in the same output and weighting; pass it to :func:flux_to_magnitude. Vega has magnitude zero in every band by this definition (systems that assign Vega 0.03 mag add that offset). Uses :func:vega_spectrum.

Parameters:

Name Type Description Default
passband Passband

Band to integrate through.

required
output Literal['mean_f_lambda', 'f_nu_microjy']

"mean_f_lambda" (cgs per Angstrom) or "f_nu_microjy".

'mean_f_lambda'
weighting Weighting

"photon" or "energy" counting response.

'photon'

Returns:

Type Description
Tensor

Scalar zero-point flux.

Raises:

Type Description
ValueError

If the passband is not covered by the Vega spectrum.

Examples:

>>> import torch
>>> from torchsky.spectrophotometry import Passband, vega_zero_point
>>> band = Passband(torch.tensor([5546.0, 5556.0, 5566.0]), torch.tensor([0.0, 1.0, 0.0]))
>>> round(float(vega_zero_point(band)) * 1e9, 2)
3.47

Typing

PhotometryOutput

typing.Literal['mean_f_lambda', 'f_nu_microjy', 'ab_mag']

WavelengthUnit

typing.Literal['angstrom', 'nm']

Weighting

typing.Literal['photon', 'energy']