xmatcher
xmatcher matches and joins astronomical catalogues from local files, HATS trees, and configured remote archives. Matching features depend on the selected engine and the metadata supplied for each catalogue; the guides document those limits and the memory trade-offs.
Version 0.6.0 is released. The
0.6.0 release notes list what changed and how it was
verified. The
v0.5.0 GitHub release
keeps the old xmatch name, and the
migration notes cover the 0.5.1 rename.
xmatcher match catalog1.parquet catalog2.csv -o matches.parquet -r 1.0
Inputs can be local Parquet, CSV, TSV, or FITS files, HATS directories, configured catalogue names/aliases, or explicit vizier:<id>, tap:<endpoint>/<table>, and hats:<url> identifiers. Coordinate names can be configured or detected. Proper-motion propagation uses declared epoch and motion metadata; mixed coordinate frames are rejected and generic catalogue discovery does not invent positional uncertainties.
📚 Complete Documentation Suite
All detailed architectural references and user guides are organized in the docs/ directory:
- User Guide & Cookbooks (
docs/usage.md): Installation, local and remote matching, explicit memory controls, and distributed workflows with their limits. - Public API Reference (
docs/api.md): Full Python API specifications forCrossMatch,MatchRequest,MatchSpec, observation/candidate release helpers, engines, storage abstractions, and exception hierarchies. - Crossmatch Algorithms & Math (
docs/algorithms.md): Matcher definitions, uncertainty assumptions, score semantics, and engine behavior. - Source & Measurement Releases (
docs/observations.md): Lazy, source-preserving measurement ledgers, photometric unit/limit normalization, property evidence, and checksummed Parquet releases. - Candidate & Association Pipeline (
docs/catalogue-pipeline.md): End-to-end workflow from pinned survey observation and sparse-candidate releases to per-target association hypotheses. - Catalogue Naming (
docs/naming.md): Bare survey names, releases, provider suffixes, and thevizier:/tap:/hats:identifier grammar. - Gaia DR3 master data (
docs/gaia-master-data.md): Survey inventory, staging order, quota model, and validation for the big Gaia-anchored run. - Association Contract v1 (
docs/association-v1.md): Audit-grade versioned association record specification, release directories, component sidecars, and member equivalence tracking.
A documentation index separates current guides from historical release and scaling records.
Capabilities
- Universal Multi-Format I/O:
- Ingests and streams
.parquet,.csv,.tsv,.tab,.fits(via high-speed Torchfits with Astropy fallback), and HATS. - Remote storage connectors: POSIX filesystem, CANFAR VOSpace (
vos:), HTTP/HTTPS, anonymous S3 (s3://HATS trees) and anonymous Hugging Face datasets (hf://datasets/…); public sources only, read-only, mirrored into the cache before matching.
- Ingests and streams
- File I/O and explicit memory controls:
- Parquet, CSV, TSV, FITS, and HATS readers with Parquet/CSV/TSV/FITS outputs.
- Output sinks can stream serialization. Most matching engines still materialize inputs and matches; local pairwise CSV/Parquet requests can opt into the spill path with
--memory-budget-bytesand file output. See memory limits.
- Astrometric and probabilistic matchers:
- Simple radius (
sky) and adaptive per-row astrometric uncertainties (skyerr). - 2D Gaussian error ellipses via Mahalanobis distance (
skyellipse). - Proper-motion epoch propagation (
target_epoch) when epoch and motion metadata are supplied, plus an explicit population drift model (pm_prior) for missing motion. - Sutherland & Saunders (1992) Likelihood Ratio (
lr) with magnitude background subtraction. - Machine learning classifiers (
mlRandom Forest,xgbXGBoost/LightGBM) with self-match pseudo-labeling. - AUF-inspired empirical separation/background scores (
auf) and a flux-augmented heuristic (macauff). These are not full reproductions of the published methods and their scores are not calibrated probabilities. - Bayesian positional qualification (
probabilistic=True) or photometric qualification (prior_columns) with declared errors or explicit error floors, plus simultaneous $N$-way scores (nway_match). These scores use stated assumptions and are not population-calibrated probabilities. - Friends-of-Friends transitive closure object bundles (
fof_match).
- Simple radius (
- Complete Relational Joins:
- Inner (
1and2), Left (all1), Right (all2), Full Outer (1or2,all), and Anti-joins (1not2,2not1). - Relational ID joins on survey identifiers (
--id-join). - Multi-catalogue sequential chains (
crossmatch_multi).
- Inner (
- Local Mirroring & Offline Caching:
xmatcher sync: Mirror remote TAP and HATS surveys into a durable local HATS cache with keyset paging, rate limiting, and progress checkpoints.
- Distributed execution:
engine="ray"parallelizes pairwise HEALPix candidate searches. The coordinator still holds the input frames and final result in memory.engine="ray-union"mirrors inputs into HATS and writes a full-sky, full-outer HATS union. It supportssky,skyerr, andskyellipse; compressed interval planning handles mixed-order/RING layouts and uncertainty or epoch halos in distributed tasks. Planning may scan additional partitions. Output trees add non-null_union_raand_union_decrouting columns and declare NESTED ordering.engine="ray-anchor"keeps one row per anchor source (normally Gaia DR3) and attaches the best counterpart from every survey plussep_second,n_within,crowded,pm_warn, andqualityfields. It is the Gaia-complete master workflow; see docs/ray-anchor.md.
Installation
Requires Python $\ge 3.13$. The checked Pixi environment and local release gate use Python 3.13.
Recommended: Pixi
git clone https://github.com/astroai/xmatcher.git
cd xmatcher
# Install environment and dependencies
pixi install
# Run lint, formatting, bytecode, and offline test checks
pixi run preflight-push
pixi run ci-local
Standard: Pip
python -m pip install "xmatcher==0.6.0"
# Optional integrations; use only the extras you need
python -m pip install "xmatcher[cds,hats-ray,torchfits,ml]==0.6.0"
A source checkout uses the same extras from the tree:
git clone https://github.com/astroai/xmatcher.git
cd xmatcher
python -m pip install ".[cds,hats-ray,torchfits,ml]"
The tensor-native torchsky engine is not a package extra: no torchsky
distribution is published on PyPI. To use it, install xmatcher alongside a
compatible Torchsky checkout. The integration was tested with the sibling
Torchsky 0.4 development source installed editable and Torchfits 1.0.0 from
PyPI.
Command Line Quick Reference
| Task | Command |
|---|---|
| Match two local files | xmatcher match cat1.parquet cat2.csv -o matches.parquet -r 1.5 |
| Match against remote Gaia DR3 | xmatcher match targets.csv gaia -o targets_gaia.parquet -r 1.0 |
| Astrometric error ellipse match | xmatcher match xray.fits optical.parquet --matcher skyellipse --max-error 3.0 |
| Proper-motion drift prior match | xmatcher match old_survey.csv gaia --target-epoch 2016.0 --pm-prior -r 2.0 |
| Relational ID join | xmatcher match cat1.parquet cat2.parquet --id-join --id1 objid --id2 objid |
| Multi-survey 3-way chain | xmatcher match gaia wise.csv 2mass.parquet -r 1.5 -o 3way.parquet |
| Distributed HATS master union | xmatcher match gaia allwise 2mass des --union --engine ray-union -o /data/master.hats |
| Gaia-anchored master (all Gaia rows) | xmatcher match gaia_hats sdss_hats ps1_hats --engine ray-anchor -r 1.5 -o gaia_master.hats |
| Narrow a wide HATS tree | xmatcher project-hats gaia_hats gaia_core.hats --columns Source,RA_ICRS,DE_ICRS,Plx,pmRA,pmDE |
| Mirror remote surveys to local cache | xmatcher sync gaia allwise 2mass |
| Search remote TAP archives | xmatcher search des |
| Discover archive schemas | xmatcher discover noirlab --schema nsc_dr2.object |
| List short names and aliases | xmatcher list --aliases |
| Explicit VizieR / TAP table | xmatcher match targets.csv vizier:II/349/ps1 -r 1.0 |
| Shell completion | xmatcher completion bash |
| Check local config drift | xmatcher doctor |
Python API Quickstart
from xmatcher import CrossMatch, MatchRequest, MatchSpec
cm = CrossMatch()
# 1. Preferred typed request interface
req = MatchRequest(
cat1="optical.parquet",
cat2="infrared.csv",
spec=MatchSpec(radius_arcsec=1.5, matcher="sky", find="best"),
engine="fast", # SciPy cKDTree multi-threaded on 3D unit sphere
)
result_df = cm.crossmatch_request(req)
# 2. Multi-catalogue sequential intersection
result_3way = cm.crossmatch_multi(
["optical.parquet", "infrared.csv", "radio.fits"],
radius_arcsec=2.0,
join_type="1and2",
)
# 3. Friends-of-Friends object bundles
bundles = cm.fof_match(
["survey_a.parquet", "survey_b.parquet", "survey_c.parquet"],
radius_arcsec=1.5,
)
License
MIT License. See LICENSE for details.
Metadata
Release files for xmatcher 0.6.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| xmatcher-0.6.0.tar.gz | 912.1 kB | With provenance | Details for xmatcher-0.6.0.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| xmatcher-0.6.0-py3-none-any.whl | Python 3 | none | any | Details for xmatcher-0.6.0-py3-none-any.whl |
Total release size: 1.2 MB
Release files / xmatcher-0.6.0.tar.gz
| Download URL | xmatcher-0.6.0.tar.gz |
|---|---|
| Size | 912.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ced8aa1c45e51a56c6a24d6534aa839796e8bba6e0c0f5ed5d32e0ed6966516d
|
|
BLAKE2b-256 checksum How to use checksums |
32011a6155e5eb8e77d88ba02855795066f0ef31ab12e619c133c5fd10506a4a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logRelease files / xmatcher-0.6.0-py3-none-any.whl
| Download URL | xmatcher-0.6.0-py3-none-any.whl |
|---|---|
| Size | 281.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0fac44190f192d9158c81468d67a31d974e1e6fda753dd7fce058edf2cec8594
|
|
BLAKE2b-256 checksum How to use checksums |
05264314ee0c0ac576db353eb162630760160271c2c6fb6c2bc7f0d1dc51d55e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logSecurity for xmatcher 0.6.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
Full provenance
All 2 files in this release have been uploaded with provenance metadata.
Attestation for xmatcher-0.6.0.tar.gz
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Oct 22, 2026.
Transparency logA note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.