adam_core.photometry.bandpasses.api module

Runtime APIs for the bandpass-driven photometry implementation.

Bandpass curves are vendored from the SVO Filter Profile Service. Please see REFERENCES.md for the required acknowledgement and citations when using this service.

adam_core.photometry.bandpasses.api.load_bandpass_curves() BandpassCurves[source]
adam_core.photometry.bandpasses.api.load_observatory_band_map() ObservatoryBandMap[source]
adam_core.photometry.bandpasses.api.load_asteroid_templates() AsteroidTemplates[source]
adam_core.photometry.bandpasses.api.load_template_integrals() TemplateBandpassIntegrals[source]
adam_core.photometry.bandpasses.api.map_to_canonical_filter_bands(observatory_codes: Array | ChunkedArray | ndarray[tuple[Any, ...], dtype[object_]] | Iterable[str], bands: Array | ChunkedArray | ndarray[tuple[Any, ...], dtype[object_]] | Iterable[str], *, allow_fallback_filters: bool = True, on_unknown: Literal['raise', 'skip'] = 'raise') ndarray[tuple[Any, ...], dtype[object_]][source]

Suggest canonical (vendored) bandpass filter IDs for a set of observations.

This function is intended to be called by users before passing filters into bandpass-driven magnitude APIs. It applies the following resolution strategy:

  • If the provided band is already a canonical vendored filter_id (i.e., we have a curve for it), it is passed through unchanged.

  • Else, if (observatory_code, band) is present in ObservatoryBandMap, that mapping is used.

  • Else, apply a conservative fallback for generic bands:

    u/g/r/i/z -> SDSS_u/g/r/i/z y -> PS1_y

Parameters:
  • observatory_codes (array-like) – MPC observatory codes.

  • bands (array-like) – Reported band labels OR canonical vendored filter IDs.

  • allow_fallback_filters (bool, optional) –

    If True, allow generic-band fallbacks when no (observatory_code, band) mapping is available:

    u/g/r/i/z -> SDSS_u/g/r/i/z y -> PS1_y

    If False, raise if any row would require those fallbacks. Canonical filter_id inputs are always passed through. Defaults to True.

  • on_unknown (Literal["raise", "skip"], optional) –

    Behavior when a row cannot be resolved to a vendored canonical filter_id through pass-through, the observatory-band mapping table, or the generic u/g/r/i/z/y fallback set (if enabled).

    ”raise” (default): raise ValueError listing the unresolvable

    observatory_code|band pairs. Backward-compatible with prior behavior; the returned ndarray is dense with no None entries.

    ”skip”: leave unresolvable rows as None in the returned ndarray

    and do not raise. Callers must tolerate None entries (typically by skipping bandpass-dependent computation for those rows). Useful for ingest pipelines (e.g. precovery against MPC astrometry) where some fraction of rows genuinely have no canonical bandpass — amateur “clear” / unfiltered reports, observatory codes whose reported band is not in the vendored mapping table, etc. — and the right behavior is to keep those rows in the dataset while marking them as not photometrically gated.

Returns:

Canonical vendored filter_id strings. When on_unknown="skip" the ndarray dtype remains object and may contain None entries for rows that could not be resolved; otherwise every entry is a non-empty string.

Return type:

ndarray

adam_core.photometry.bandpasses.api.assert_filter_ids_have_curves(filter_ids: Array | ChunkedArray | ndarray[tuple[Any, ...], dtype[object_]] | Iterable[str]) None[source]

Raise if any filter_id is not present in vendored BandpassCurves.

adam_core.photometry.bandpasses.api.get_integrals(template_id: str, filter_ids: ndarray[tuple[Any, ...], dtype[object_]]) ndarray[tuple[Any, ...], dtype[float64]][source]

Return solar-weighted mean reflectance values for template_id across filter_ids.

Supports both vendored templates (precomputed) and custom templates registered at runtime via register_custom_template.

adam_core.photometry.bandpasses.api.compute_mix_integrals(weight_C: float, weight_S: float, filter_ids: ndarray[tuple[Any, ...], dtype[object_]]) ndarray[tuple[Any, ...], dtype[float64]][source]

Compute integrals for a C/S linear mix using precomputed base integrals.

This avoids recomputing any convolution and supports arbitrary weights.

adam_core.photometry.bandpasses.api.bandpass_delta_mag(composition: str | tuple[float, float], source_filter_id: str, target_filter_id: str) float[source]

Compute a constant magnitude offset between two canonical filters for a composition.

The delta is defined as:

Δm = m_target - m_source = -2.5 log10(<R>_target / <R>_source)

where <R> is the solar-weighted band-averaged reflectance for the composition (see get_integrals).

adam_core.photometry.bandpasses.api.bandpass_color_terms(composition: str | tuple[float, float], *, source_filter_id: str = 'V', target_filter_ids: Iterable[str] | None = None) dict[str, float][source]

Return delta magnitudes relative to source_filter_id for a set of canonical filters.

Returns:

Mapping: target_filter_id -> Δm where Δm = m_target - m_source.

Return type:

dict

adam_core.photometry.bandpasses.api.register_custom_template(template_id: str, wavelength_nm: ndarray[tuple[Any, ...], dtype[float64]], reflectance: ndarray[tuple[Any, ...], dtype[float64]]) None[source]

Register a custom reflectance template in-process and compute missing integrals lazily.

Notes

  • This does not modify vendored Parquet data.

  • This is intended for NumPy paths. JAX-compiled tables in magnitude.py cannot be extended at runtime without recompilation.