torchsky.catalogs¶
Stability: core. Names on this page follow the deprecation policy in contributing.
Catalog streaming, indexing, and crossmatching helpers.
Guides: crossmatch
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.catalogs unless the group text says otherwise.
Top-level namespace¶
Catalog streaming, indexing, and crossmatching helpers.
crossmatch ¶
crossmatch(
left: Any,
right: Any,
radius_arcsec_or_right_lon: Any = None,
right_lat: Any = None,
radius_arcsec: float | Tensor | None = None,
*,
find: str = "best",
streamed: bool = False,
**kwargs: Any,
) -> CrossmatchResult
Unified sky crossmatch entry point.
Supports:
- crossmatch(cat_left, cat_right, radius_arcsec, ...) for :class:Catalog objects
- crossmatch(left_lon, left_lat, right_lon, right_lat, radius_arcsec=..., ...) for coordinate tensors
- crossmatch((left_lon, left_lat), (right_lon, right_lat), radius_arcsec, ...)
- crossmatch(left_arrow, right_arrow, radius_arcsec, streamed=False, ...) for Arrow tables/paths
Catalog¶
Catalog streaming, indexing, and crossmatching helpers.
Catalog
dataclass
¶
Catalog(
lon: Tensor,
lat: Tensor,
frame: str = "ICRS",
epoch: Tensor | float = 2000.0,
pm_lon_coslat_mas_yr: Tensor | None = None,
pm_lat_mas_yr: Tensor | None = None,
parallax_mas: Tensor | None = None,
radial_velocity_km_s: Tensor | None = None,
valid: Tensor | None = None,
columns: dict[str, Tensor] = dict(),
)
Batched table of sky rows on one device.
Required sky columns are lon / lat in degrees. Missing kinematics
stay None. Extra payload lives in columns (same length, same device).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
lon
|
Tensor
|
Longitude tensor in degrees. |
required |
lat
|
Tensor
|
Latitude tensor in degrees, with the same row count as |
required |
frame
|
str
|
Celestial or observed coordinate-frame name. |
'ICRS'
|
epoch
|
Tensor | float
|
Scalar or per-row Julian epoch. |
2000.0
|
pm_lon_coslat_mas_yr
|
Tensor | None
|
Cosine-weighted longitude proper motion in mas/yr. |
None
|
pm_lat_mas_yr
|
Tensor | None
|
Latitude proper motion in mas/yr. |
None
|
parallax_mas
|
Tensor | None
|
Parallax in milliarcseconds. |
None
|
radial_velocity_km_s
|
Tensor | None
|
Radial velocity in km/s. |
None
|
valid
|
Tensor | None
|
Optional per-row validity mask. |
None
|
columns
|
dict[str, Tensor]
|
Additional tensors whose leading dimension matches the catalog. |
dict()
|
Examples:
>>> import torch
>>> from torchsky.catalogs import Catalog
>>> catalog = Catalog(torch.tensor([10.0]), torch.tensor([-2.0]))
>>> len(catalog)
1
_index
class-attribute
instance-attribute
¶
_index: HealpixIndex | None = field(
default=None, init=False, repr=False, compare=False
)
columns
class-attribute
instance-attribute
¶
columns: dict[str, Tensor] = field(default_factory=dict)
pm_lon_coslat_mas_yr
class-attribute
instance-attribute
¶
pm_lon_coslat_mas_yr: Tensor | None = None
radial_velocity_km_s
class-attribute
instance-attribute
¶
radial_velocity_km_s: Tensor | None = None
state
property
¶
state: CatalogState
Return this catalog's celestial kinematic state as a :class:CatalogState.
_optional_rows
staticmethod
¶
_optional_rows(
value: Tensor | None, n: int, device: device
) -> Tensor | None
cone ¶
cone(
lon: Tensor | float,
lat: Tensor | float,
radius_deg: float,
*,
nside: int | None = None,
) -> Tensor
crossmatch ¶
crossmatch(
other: Catalog,
radius_arcsec: float | Tensor | None = None,
*,
find: str = "best",
right_index: HealpixIndex | None = None,
target_epoch: float | Tensor | None = None,
motion: str = "angular",
left_err_arcsec: float | Tensor | str | None = None,
right_err_arcsec: float | Tensor | str | None = None,
) -> CrossmatchResult
Match stored positions, or explicitly propagate to a common Julian year.
motion="angular" requires both PM components for rows whose epoch
changes; "physical" additionally requires parallax and radial
velocity. Missing motion is never filled with zero. A supplied index
must be rebuilt by the caller after frame/epoch changes.
find and the error options follow :func:crossmatch_sky;
left_err_arcsec / right_err_arcsec may also name a column of
self / other (values in arcsec). Epoch/frame alignment reorders
nothing, so returned indices always refer to the original rows.
from_arrow
classmethod
¶
from_arrow(
source: Any,
*,
lon: str = "ra",
lat: str = "dec",
frame: str = "ICRS",
epoch: float = 2000.0,
columns: tuple[str, ...] = (),
) -> Catalog
from_state
classmethod
¶
from_state(
state: CatalogState,
*,
columns: dict[str, Tensor] | None = None,
) -> Catalog
observe ¶
observe(
to_frame: str = "ALTAZ",
*,
obstime_mjd_utc: Any,
site: Site,
eop: EarthOrientation,
pn: PNModel | None = None,
aberration: bool = False,
refraction: bool = False,
refraction_model: Literal[
"refco", "saemundsson"
] = "refco",
) -> Catalog
Core¶
Catalog streaming, indexing, and crossmatching helpers.
CatalogStreamDataset ¶
CatalogStreamDataset(
partitions: Iterable[object]
| Callable[[], Iterable[object]],
loader: Callable[
[object], object
] = _identity_partition,
)
Bases: IterableDataset
Wrap a partition iterator into a PyTorch IterableDataset.
from_arrow
classmethod
¶
from_arrow(
source: Any,
*,
batch_size: int = 65536,
columns: tuple[str, str] = ("ra", "dec"),
) -> CatalogStreamDataset
Build a CatalogStreamDataset that yields (ra, dec) Tensor pairs from Arrow.
Parameters¶
source
A pyarrow.Table, pyarrow.ipc.RecordBatchReader, or a path
string / pathlib.Path to an Arrow IPC Feather file.
batch_size
Row count per yielded batch.
columns
Column names for RA (degrees) and Dec (degrees).
CrossmatchResult
dataclass
¶
CrossmatchResult(
left_index: Tensor,
right_index: Tensor,
separation_arcsec: Tensor,
)
crossmatch_sky ¶
crossmatch_sky(
left_ra_deg: Tensor,
left_dec_deg: Tensor,
right_ra_deg: Tensor,
right_dec_deg: Tensor,
*,
radius_arcsec: float | Tensor | None = None,
left_chunk_size: int = 65536,
right_chunk_size: int = 65536,
find: str = "best",
right_index: HealpixIndex | None = None,
device: device | str | None = None,
left_err_arcsec: float | Tensor | None = None,
right_err_arcsec: float | Tensor | None = None,
left_distance: Tensor | None = None,
right_distance: Tensor | None = None,
distance_tol: float | None = None,
) -> CrossmatchResult
Chunked exact angular crossmatch on one in-memory tile.
Matchers (choose one radius rule):
- sky:
radius_arcsec(scalar or per-left-row), pair kept whenseparation <= radius. - skyerr:
left_err_arcsec/right_err_arcsec(scalar or per row, either side optional, missing side = 0), pair kept whenseparation <= err_left[i] + err_right[j]. Candidate windows usemax(err_left) + max(err_right); the exact test uses each pair's sum. - sky + distance (STILTS
skywith a 1-d cut): also passleft_distance,right_distanceanddistance_tol; a pair must additionally satisfy|d_left - d_right| <= distance_tol(NaN never matches).
find selects which pairs are returned:
"best"/"best1": nearest right row per left row (right rows may repeat); ties go to the lowest right index."best2": nearest left row per right row (left rows may repeat); ties go to the lowest left index."mutual": STILTSfind=best. Exactly the mutual-best pairs (best1intersected withbest2, same tie rules); a row whose best partner prefers another row is left unmatched."symmetric": greedy one-to-one (not STILTS). Ascending separation, ties by lowest left then lowest right index; every row is used at most once and the assignment is maximal."all": every pair inside the threshold.
"all" is ordered by left index, separation, then right index; the other
modes by left index, then right index. Use
:func:~torchsky.catalogs.join_rows for join semantics with unmatched rows.
radius_arcsec may be a positive scalar or a per-left-row tensor. Pass
right_index to reuse a nested HealpixIndex (find best1/all and
sky matcher only). device moves inputs onto that device when given.
On MPS the work dtype is float32, so thresholds below the float32 position
resolution are not meaningful there.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left_ra_deg
|
Tensor
|
Left-catalog right ascensions in degrees. |
required |
left_dec_deg
|
Tensor
|
Left-catalog declinations in degrees. |
required |
right_ra_deg
|
Tensor
|
Right-catalog right ascensions in degrees. |
required |
right_dec_deg
|
Tensor
|
Right-catalog declinations in degrees. |
required |
radius_arcsec
|
float | Tensor | None
|
Scalar or per-left-row match radius in arcseconds. |
None
|
left_chunk_size
|
int
|
Maximum left rows processed per outer chunk. |
65536
|
right_chunk_size
|
int
|
Maximum candidate right rows processed per chunk. |
65536
|
find
|
str
|
|
'best'
|
right_index
|
HealpixIndex | None
|
Reusable nested HEALPix index for the right catalog. |
None
|
device
|
device | str | None
|
Optional compute device. |
None
|
left_err_arcsec
|
float | Tensor | None
|
Per-left-row error radius (skyerr matcher). |
None
|
right_err_arcsec
|
float | Tensor | None
|
Per-right-row error radius (skyerr matcher). |
None
|
left_distance
|
Tensor | None
|
Per-left-row distance for the distance cut. |
None
|
right_distance
|
Tensor | None
|
Per-right-row distance for the distance cut. |
None
|
distance_tol
|
float | None
|
Largest allowed distance difference. |
None
|
Returns:
| Type | Description |
|---|---|
CrossmatchResult
|
Matching row indices and great-circle separations in arcseconds. |
Examples:
>>> import torch
>>> from torchsky.catalogs import crossmatch_sky
>>> result = crossmatch_sky(torch.tensor([0.0]), torch.tensor([0.0]), torch.tensor([0.0]), torch.tensor([0.0]), radius_arcsec=1.0)
>>> result.right_index.tolist()
[0]
crossmatch_sky_from_arrow ¶
crossmatch_sky_from_arrow(
left_source: Any,
right_source: Any,
*,
radius_arcsec: float,
left_columns: tuple[str, str] = ("ra", "dec"),
right_columns: tuple[str, str] = ("ra", "dec"),
batch_size: int = 131072,
find: str = "best",
) -> CrossmatchResult
Crossmatch Arrow inputs through temporary HEALPix tiles.
Both catalogs are streamed once (partitioned by coarse HEALPix pixel
into temporary Parquet files with a coarse_pixel column). Per-pixel
tiles are then loaded one at a time for fine-grained distance
computation. Coordinate memory scales with the largest tile and its
neighboring right tiles. Pixel metadata and returned pairs remain in RAM.
Indices always refer to the original input row order, including across
batches. Use them to select native ID columns without converting IDs to float.
For uniformly distributed sky positions and a well-chosen coarse nside, per-pixel tile size is typically a few thousand rows regardless of whether the total catalog has 10^6 or 10^9 rows.
Parameters¶
left_source, right_source
Each can be a pyarrow.Table, pyarrow.ipc.RecordBatchReader,
or a path string / pathlib.Path to an Arrow IPC file (Feather
format v2). File sources use memory-mapped I/O.
radius_arcsec
Match radius in arcseconds.
left_columns, right_columns
(ra_column_name, dec_column_name) for each catalog.
batch_size
Row count per streaming batch during the tiling phase.
find
"best" selects one nearest right row per left row, breaking ties
by original right row index. "all" returns every pair in radius.
crossmatch_sky_streamed ¶
crossmatch_sky_streamed(
left_batches: Iterable[tuple[Tensor, Tensor]],
right_ra_deg: Tensor,
right_dec_deg: Tensor,
*,
radius_arcsec: float,
right_chunk_size: int = 65536,
) -> CrossmatchResult
Streamed crossmatch where the left catalog arrives in batches.
The right catalog must fit in memory (required for the coarse HEALPix
index). The left catalog is consumed incrementally from left_batches,
which yields (ra_deg, dec_deg) tensor pairs.
Parameters¶
left_batches
Iterator yielding (ra_tensor, dec_tensor) pairs (each 1-D
float64). Batches are concatenated in order and their indices are
mapped back into the final left_index output.
right_ra_deg, right_dec_deg
Full right-catalog coordinates (1-D float64).
radius_arcsec
Match radius in arcseconds.
right_chunk_size
Right-side chunk size for the inner distance loop.
Deblending¶
torchsky.catalogs.deblending.FactorizationBlendDiagnostics
dataclass
¶
FactorizationBlendDiagnostics(
group_index: int,
source_indices: Tensor,
component_ids: Tensor,
converged: bool,
iterations: int,
initial_objective: Tensor,
final_objective: Tensor,
accepted_steps: int,
final_step_size: float,
morphology_sums: Tensor,
zero_morphology_indices: Tensor,
spectrum_gauge_parameter_indices: Tensor,
failure_reason: str | None,
)
torchsky.catalogs.deblending.FitAdequacyDiagnostics
dataclass
¶
FitAdequacyDiagnostics(
evaluated_pixel_count: int,
fitted_parameter_count: int,
degrees_of_freedom: int,
chi_square: Tensor,
reduced_chi_square: Tensor,
upper_reduced_chi_square: Tensor,
heldout_log_likelihood: Tensor | None,
evaluation: Literal["heldout", "in_sample"],
inadequate: bool,
reason: str | None,
)
torchsky.catalogs.deblending.KnownComponentFitError ¶
KnownComponentFitError(message: str, result: object)
Bases: RuntimeError
torchsky.catalogs.deblending.MorphologySpectrumDeblendResult
dataclass
¶
MorphologySpectrumDeblendResult(
catalog: Catalog,
scene: SourceCatalogScene,
initial_scene: SourceCatalogScene,
spectra: Tensor,
initial_spectra: Tensor,
morphologies: tuple[Tensor, ...],
initial_morphologies: tuple[Tensor, ...],
covariance: BlockSparseCovariance,
predictions: tuple[Tensor, ...],
residuals: tuple[Tensor, ...],
grouping: SourceGrouping,
diagnostics: tuple[FactorizationBlendDiagnostics, ...],
linear_diagnostics: tuple[object, ...],
adequacy: FitAdequacyDiagnostics,
background_coefficients: tuple[Tensor, ...],
provenance: dict[str, object],
)
torchsky.catalogs.deblending.ParametricBlendDiagnostics
dataclass
¶
ParametricBlendDiagnostics(
group_index: int,
source_indices: Tensor,
component_ids: Tensor,
parameter_indices: Tensor,
parameter_labels: tuple[str, ...],
converged: bool,
iterations: int,
initial_objective: Tensor,
final_objective: Tensor,
damping: float,
rank: int,
condition_number: float,
gauge_parameter_indices: Tensor,
covariance: Tensor,
catastrophic_swap: bool,
failure_reason: str | None,
)
torchsky.catalogs.deblending.ParametricBounds
dataclass
¶
ParametricBounds(
position_arcsec: float = 2.0,
gaussian_sigma_arcsec: tuple[float, float] = (
0.05,
30.0,
),
sersic_radius_arcsec: tuple[float, float] = (
0.05,
60.0,
),
sersic_axis_ratio: tuple[float, float] = (0.05, 1.0),
sersic_index: tuple[float, float] = (0.3, 8.0),
angle_delta_deg: float = 180.0,
)
gaussian_sigma_arcsec
class-attribute
instance-attribute
¶
gaussian_sigma_arcsec: tuple[float, float] = (0.05, 30.0)
sersic_axis_ratio
class-attribute
instance-attribute
¶
sersic_axis_ratio: tuple[float, float] = (0.05, 1.0)
sersic_radius_arcsec
class-attribute
instance-attribute
¶
sersic_radius_arcsec: tuple[float, float] = (0.05, 60.0)
torchsky.catalogs.deblending.ParametricDeblendResult
dataclass
¶
ParametricDeblendResult(
catalog: Catalog,
scene: SourceCatalogScene,
initial_scene: SourceCatalogScene,
coefficients: Tensor,
covariance: BlockSparseCovariance,
nonlinear_covariance: tuple[Tensor, ...],
predictions: tuple[Tensor, ...],
residuals: tuple[Tensor, ...],
grouping: SourceGrouping,
diagnostics: tuple[ParametricBlendDiagnostics, ...],
linear_diagnostics: tuple[object, ...],
adequacy: FitAdequacyDiagnostics,
background_coefficients: tuple[Tensor, ...],
provenance: dict[str, object],
)
torchsky.catalogs.deblending.fit_morphology_spectrum_deblending ¶
fit_morphology_spectrum_deblending(
observations: Sequence[FieldObservation],
scene: SourceCatalogScene,
*,
monotonic: bool | Tensor = False,
symmetric: bool | Tensor = False,
background: BackgroundModel = "constant",
max_iterations: int = 50,
step_size: float = 0.1,
backtracking: float = 0.5,
step_tolerance: float = 1e-05,
objective_tolerance: float = 1e-08,
max_group_size: int = 64,
heldout_masks: Sequence[Tensor] | None = None,
adequacy_sigma: float = 5.0,
failure_policy: FailurePolicy = "raise",
index_nside: int | None = None,
footprint_order: int | None = None,
chunk_size: int | None = None,
rank_rtol: float | None = None,
rank_atol: float = 0.0,
) -> MorphologySpectrumDeblendResult
Fit fixed-count nonnegative component morphologies and spectra by blocks.
torchsky.catalogs.deblending.fit_parametric_deblending ¶
fit_parametric_deblending(
observations: Sequence[FieldObservation],
scene: SourceCatalogScene,
*,
refine_positions: bool | Tensor = True,
refine_shapes: bool | Tensor = True,
bounds: ParametricBounds | None = None,
linear_solver: Literal["signed", "nnls"] = "nnls",
background: BackgroundModel = "constant",
max_iterations: int = 20,
initial_damping: float = 0.01,
finite_difference_step: float = 0.001,
step_tolerance: float = 0.0001,
objective_tolerance: float = 1e-08,
max_group_size: int = 64,
heldout_masks: Sequence[Tensor] | None = None,
adequacy_sigma: float = 5.0,
failure_policy: FailurePolicy = "raise",
index_nside: int | None = None,
footprint_order: int | None = None,
chunk_size: int | None = None,
rank_rtol: float | None = None,
rank_atol: float = 0.0,
) -> ParametricDeblendResult
Refine supplied point, Gaussian, and bounded-Sersic components by LM.
Index¶
Catalog streaming, indexing, and crossmatching helpers.
HealpixIndex
dataclass
¶
HealpixIndex(
nside: int,
nest: bool,
lon: Tensor,
lat: Tensor,
order: Tensor,
unique_pixels: Tensor,
bucket_starts: Tensor,
bucket_stops: Tensor,
)
Bucketed nested-HEALPix index over catalog rows.
Build once, then query_disc / lookup. Crossmatch uses the same
buckets; a later fused gather can replace lookup without API churn.
build
classmethod
¶
build(
lon: Tensor,
lat: Tensor,
*,
nside: int | None = None,
nest: bool = True,
) -> HealpixIndex
expand ¶
expand(pixels: Tensor) -> tuple[Tensor, Tensor]
Map per-query pixels [N] to (query_index, row_index) pairs.
lookup ¶
lookup(pixels: Tensor) -> Tensor
Row indices whose HEALPix pixel is in pixels (vectorized gather).
lookup_moc ¶
lookup_moc(footprint: MOC) -> Tensor
Rows inside a MOC using occupied buckets for candidate pruning.
query_disc ¶
query_disc(
lon: Tensor | float,
lat: Tensor | float,
radius_deg: float,
) -> Tensor
Row indices whose positions lie within radius_deg of the center.
cap_covering_pixels ¶
cap_covering_pixels(
nside: int,
lon_deg: Tensor | float,
lat_deg: Tensor | float,
radius_rad: float,
*,
nest: bool = True,
) -> Tensor
Pixels whose centers lie in the cap of radius radius_rad.
Small caps expand nested neighbours (O(hops^2)). Wide caps use
query_disc. Callers that need a sound match covering pass r + 2ρ.
nside_for_cap ¶
nside_for_cap(
radius_rad: float, *, max_nside: int = _MAX_NSIDE
) -> int
Coarsest power-of-two NSIDE whose max pixel radius is <= radius_rad.
If the cap is larger than an nside=1 pixel, return 1. If even max_nside
pixels are larger than the cap, return max_nside (covering stays sound
via the r + 2ρ pad; tiles are just coarser).
Multi¶
Catalog streaming, indexing, and crossmatching helpers.
ManyMatchResult
dataclass
¶
ManyMatchResult(
index: Tensor,
n_members: Tensor,
group_size: Tensor,
separation_arcsec: Tensor,
)
One output row per match group across C catalogues.
index[g, c] is the row of catalogue c in output row g (-1 if
absent). n_members counts present entries; group_size counts every
member of the underlying group (equal to n_members in pairs mode).
separation_arcsec[g, c] is the separation to the reference (pairs)
or the nearest link in the group (group); NaN when absent or unlinked.
SelfMatchResult
dataclass
¶
SelfMatchResult(
left_index: Tensor,
right_index: Tensor,
separation_arcsec: Tensor,
group_id: Tensor | None = None,
group_size: Tensor | None = None,
n_groups: int = 0,
)
Pairs i < j within one catalogue, optionally with FoF groups.
group_id / group_size are per row (None unless group=True).
Rows with no partner get group_id = -1 and group_size = 1; groups
of two or more rows are numbered 0..n_groups-1 by smallest member row.
crossmatch_exact ¶
crossmatch_exact(
left_key: Tensor,
right_key: Tensor,
*,
find: str = "all",
) -> CrossmatchResult
Equal-key join (STILTS exact): O((N + M) log M + K).
Keys are 1-d tensors (integers or floats; NaN never matches). Separations
are returned as zeros. find follows :func:crossmatch_sky; every pair
scores equally, so ties resolve by lowest row index ("symmetric" pairs
the lowest rows of each key first).
crossmatch_many ¶
crossmatch_many(
catalogs: Sequence[Any],
radius_arcsec: float | None = None,
*,
mode: str = "pairs",
reference: int = 0,
err_arcsec: Sequence[float | Tensor | None]
| None = None,
) -> ManyMatchResult
Match C >= 2 catalogues (STILTS tmatchn).
Each catalogue is a Catalog or a (lon_deg, lat_deg) pair. A pair of
rows matches when separation <= radius_arcsec or, with err_arcsec
(one scalar/tensor/None per catalogue), <= err_a + err_b.
mode="pairs" (multimode=pairs): every other catalogue is matched to
catalogs[reference] with find="best1": each reference row takes its
nearest partner (ties by lowest row) in every other catalogue, so one
entry may serve several reference rows. Output rows are all reference rows
in order (-1 where no partner), then, for each other catalogue in
order, its rows that are no reference row's partner (alone in their row).
Two non-reference rows are never linked directly.
mode="group" (multimode=group): friends-of-friends over all
cross-catalogue pairs; one output row per group, ordered by the group's
smallest stacked row (catalogue order, then row). A group may hold several
rows of one catalogue (chains); the representative of catalogue c is
the member with the smallest separation to any linked member of another
catalogue, ties by lowest row index. Same-catalogue pairs are not links.
crossmatch_self ¶
crossmatch_self(
lon_deg: Tensor,
lat_deg: Tensor,
radius_arcsec: float | Tensor | None = None,
*,
err_arcsec: float | Tensor | None = None,
group: bool = False,
left_chunk_size: int = 65536,
right_chunk_size: int = 65536,
) -> SelfMatchResult
Pairs within one catalogue (STILTS tmatch1).
Returns every pair i < j (no self pairs, each pair once) with
separation <= radius_arcsec or, with err_arcsec (scalar or per row),
separation <= err[i] + err[j]. With group=True also returns
friends-of-friends groups (connected components of the pair graph) as
per-row group_id and group_size (STILTS action=identify).
Candidate generation is the declination-strip index, so cost is
O(N log N + K); components use scatter-min union-find.
join_rows ¶
join_rows(
result: CrossmatchResult,
n_left: int,
n_right: int,
join: str = "1and2",
) -> tuple[Tensor, Tensor]
Row-index pairs for a STILTS join type, -1 where a side is absent.
join is one of 1and2 (matched pairs), 1or2 (matched pairs plus
every unmatched row of both), all1 / all2 (matched pairs plus the
unmatched rows of table 1 / 2), 1not2 / 2not1 (unmatched rows only).
Output order: matched pairs as given, then unmatched left rows ascending,
then unmatched right rows ascending. Costs O(K + N + M).
Returns:
| Type | Description |
|---|---|
tuple[Tensor, Tensor]
|
|
Photometry¶
torchsky.catalogs.photometry.BlendFitDiagnostics
dataclass
¶
BlendFitDiagnostics(
group_index: int,
source_indices: Tensor,
exposure_indices: Tensor,
parameter_indices: Tensor,
active_parameter_indices: Tensor,
data_rank: int,
active_rank: int,
parameter_count: int,
active_parameter_count: int,
condition_number: float,
rank_cutoff: Tensor,
information_eigenvalues: Tensor,
gauge_parameter_indices: Tensor,
solver: PhotometrySolver,
converged: bool,
iterations: int,
)
torchsky.catalogs.photometry.BlockSparseCovariance
dataclass
¶
BlockSparseCovariance(
parameter_count: int,
parameter_indices: tuple[Tensor, ...],
blocks: tuple[Tensor, ...],
constrained: bool,
)
torchsky.catalogs.photometry.ForwardPhotometryResult
dataclass
¶
ForwardPhotometryResult(
catalog: Catalog,
scene: SourceCatalogScene,
coefficients: Tensor,
covariance: BlockSparseCovariance,
predictions: tuple[Tensor, ...],
residuals: tuple[Tensor, ...],
grouping: SourceGrouping,
diagnostics: tuple[BlendFitDiagnostics, ...],
background_coefficients: tuple[Tensor, ...],
provenance: dict[str, object],
)
torchsky.catalogs.photometry.SourceGrouping
dataclass
¶
SourceGrouping(
source_exposures: tuple[Tensor, ...],
exposure_sources: tuple[Tensor, ...],
blend_groups: tuple[Tensor, ...],
group_exposures: tuple[Tensor, ...],
observation_footprints: tuple[MOC, ...],
)
torchsky.catalogs.photometry.build_source_groups ¶
build_source_groups(
scene: SourceCatalogScene,
observations: Sequence[FieldObservation],
*,
index_nside: int | None = None,
footprint_order: int | None = None,
) -> SourceGrouping
Build exact source-exposure and source-overlap groups with HEALPix/MOCs.
torchsky.catalogs.photometry.fit_forced_photometry ¶
fit_forced_photometry(
observations: Sequence[FieldObservation],
scene: SourceCatalogScene,
*,
solver: PhotometrySolver = "signed",
background: BackgroundModel = "constant",
index_nside: int | None = None,
footprint_order: int | None = None,
chunk_size: int | None = None,
rank_rtol: float | None = None,
rank_atol: float = 0.0,
nnls_max_iterations: int = 256,
) -> ForwardPhotometryResult
Fit known fixed source templates on native exposures without detection.
Typing¶
BackgroundModel
typing.Literal['none', 'constant', 'planar']
FailurePolicy
typing.Literal['raise', 'return']
PhotometrySolver
typing.Literal['signed', 'nnls']