adam_core.photometry.bandpasses package¶
Bandpass response curves and asteroid spectral templates.
This subpackage vendors (as package data) a curated set of: - instrument filter response curves (throughput vs wavelength), normalized and stored in Parquet - asteroid reflectance templates (C, S, and mixes like NEO/MBA), also stored in Parquet - precomputed template×filter integrals used to derive color terms efficiently
The initial implementation is data-only: it is designed so magnitude.py can later resolve (observatory_code, reported_band) -> canonical filter_id and use precomputed integrals for higher-fidelity conversions, without changing behavior yet.
- class adam_core.photometry.bandpasses.BandpassCurves(table: Table, **kwargs: int | float | str)[source]¶
Bases:
TableCanonical bandpass response curves.
Each row represents a single filter response curve: wavelength (nm) and a normalized dimensionless throughput (0..1).
- band¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- filter_id¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- instrument¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- schema: ClassVar[pa.Schema] = filter_id: large_string not null instrument: large_string not null band: large_string not null wavelength_nm: large_list<item: double> not null child 0, item: double throughput: large_list<item: double> not null child 0, item: double source: large_string not null¶
- source¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- throughput¶
A column for storing large lists of values (over 231 objects).
Unless you need to represent data with more than 2**31 elements, prefer ListColumn.
The values in the list can be of any type.
Note that all quivr Tables are storing lists of values, so this column type is only useful for storing lists of lists.
- Parameters:
value_type – The type of the values in the list.
nullable – Whether the list can contain null values.
metadata – A dictionary of metadata to attach to the column.
validator – A validator to run against the column’s values.
- wavelength_nm¶
A column for storing large lists of values (over 231 objects).
Unless you need to represent data with more than 2**31 elements, prefer ListColumn.
The values in the list can be of any type.
Note that all quivr Tables are storing lists of values, so this column type is only useful for storing lists of lists.
- Parameters:
value_type – The type of the values in the list.
nullable – Whether the list can contain null values.
metadata – A dictionary of metadata to attach to the column.
validator – A validator to run against the column’s values.
- class adam_core.photometry.bandpasses.ObservatoryBandMap(table: Table, **kwargs: int | float | str)[source]¶
Bases:
TableMap (MPC observatory_code, reported band) -> canonical filter_id.
key is a convenience column: f”{observatory_code}|{reported_band}”.
- filter_id¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- key¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- observatory_code¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- reported_band¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- schema: ClassVar[pa.Schema] = observatory_code: large_string not null reported_band: large_string not null filter_id: large_string not null key: large_string not null¶
- class adam_core.photometry.bandpasses.AsteroidTemplates(table: Table, **kwargs: int | float | str)[source]¶
Bases:
TableAsteroid reflectance templates, including fixed population mixes.
reflectance is dimensionless and should be normalized at 550 nm.
- citation¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- reflectance¶
A column for storing large lists of values (over 231 objects).
Unless you need to represent data with more than 2**31 elements, prefer ListColumn.
The values in the list can be of any type.
Note that all quivr Tables are storing lists of values, so this column type is only useful for storing lists of lists.
- Parameters:
value_type – The type of the values in the list.
nullable – Whether the list can contain null values.
metadata – A dictionary of metadata to attach to the column.
validator – A validator to run against the column’s values.
- schema: ClassVar[pa.Schema] = template_id: large_string not null wavelength_nm: large_list<item: double> not null child 0, item: double reflectance: large_list<item: double> not null child 0, item: double weight_C: double not null weight_S: double not null citation: large_string not null¶
- template_id¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- wavelength_nm¶
A column for storing large lists of values (over 231 objects).
Unless you need to represent data with more than 2**31 elements, prefer ListColumn.
The values in the list can be of any type.
Note that all quivr Tables are storing lists of values, so this column type is only useful for storing lists of lists.
- Parameters:
value_type – The type of the values in the list.
nullable – Whether the list can contain null values.
metadata – A dictionary of metadata to attach to the column.
validator – A validator to run against the column’s values.
- weight_C¶
A column for storing 64-bit floating point numbers.
- weight_S¶
A column for storing 64-bit floating point numbers.
- class adam_core.photometry.bandpasses.TemplateBandpassIntegrals(table: Table, **kwargs: int | float | str)[source]¶
Bases:
TablePrecomputed template×filter integrals.
- The stored scalar is intended for photon-counting synthetic photometry:
I = ∫ F_sun(λ) * R_ast(λ) * T(λ) * λ dλ
where F_sun is the adopted solar spectrum, R_ast is reflectance, and T is throughput.
- filter_id¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- integral_photon¶
A column for storing 64-bit floating point numbers.
- schema: ClassVar[pa.Schema] = template_id: large_string not null filter_id: large_string not null integral_photon: double not null¶
- template_id¶
A column for storing large strings (over 231 bytes long). Large string data is stored in variable-length chunks.
- adam_core.photometry.bandpasses.load_bandpass_curves() BandpassCurves[source]¶
- adam_core.photometry.bandpasses.load_observatory_band_map() ObservatoryBandMap[source]¶
- adam_core.photometry.bandpasses.load_asteroid_templates() AsteroidTemplates[source]¶
- adam_core.photometry.bandpasses.load_template_integrals() TemplateBandpassIntegrals[source]¶
- adam_core.photometry.bandpasses.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
ValueErrorlisting the unresolvable observatory_code|bandpairs. Backward-compatible with prior behavior; the returned ndarray is dense with no None entries.- ”skip”: leave unresolvable rows as
Nonein 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.
- ”raise” (default): raise
- Returns:
Canonical vendored filter_id strings. When
on_unknown="skip"the ndarray dtype remainsobjectand may containNoneentries for rows that could not be resolved; otherwise every entry is a non-empty string.- Return type:
ndarray
- adam_core.photometry.bandpasses.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.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.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.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.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:
- adam_core.photometry.bandpasses.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.