Skip to main content

Chita 🐆 — a fast cat(alog) maker

Catalogs from Hierarchical, Image-calibrated, Tuning-free Analysis. Pronounced like cheetah.

Chita is an ultra-fast, multi-scale source extractor for large astronomical images (Roman, Euclid, Rubin era). One run finds point sources, compact and extended galaxies, and low-surface-brightness (LSB) objects. You don't run it twice with "hot" and "cold" settings, and you don't tune it per field.

  • Self-calibrating thresholds. The noise of every filtered map is measured, so 5 sigma means 5 sigma on every image, including drizzled or resampled coadds with correlated noise.
  • Multi-scale in one pass. A PSF-matched detection is combined with a Gaussian pyramid of coarser significance maps. Coarse-scale light that finer scales don't explain becomes a new (LSB) source; envelopes of known sources are attached to them.
  • Statistical deblending. A component tree (dendrogram) with noise-unit tests replaces SExtractor's 32 fixed levels plus a global contrast. Leftover pixels are assigned by a deterministic watershed.
  • Built-in purity estimate. The same detection runs on the inverted image at every scale.
  • Fast. Rust, multi-threaded at every stage, with O(N) or O(N log N) kernels. Results are identical for any thread count.

The design describes the algorithm, and the review covers the existing codes it learns from.

Install

pip install chita

This installs the Python package and the chita command, ready to run on Linux, macOS and Windows with Python 3.9 or newer. Nothing is compiled.

To install the latest code from GitHub instead, which compiles it, first install Rust:

pip install git+https://github.com/lmytime/chita

Command line

chita image.fits                          # -> image.cat.fits (FITS binary table)
chita image.fits -o cat.csv --seg seg.fits --bkg bkg.fits --rms rms.fits
chita image.fits --weight wht.fits --weight-type weight --mask bad.fits --gain 2.0

chita --help lists all options. The defaults are meant to be left alone:

option default meaning
--thresh 5.0 detection: peak significance, in measured sigma of the detection image
--analysis-thresh 2.0 footprint (isophote) significance
--fwhm estimated PSF FWHM (pixels)
--back-size 64 background mesh (pixels)
--contrast 0.005 deblending: minimum flux fraction of a split, applied only above the detection level
--levels auto number of coarse scales (0 disables multi-scale)
--subsources off search large objects for compact sources and clumps inside them (flag 512; experimental with one band)
-j all cores threads

While it runs, chita prints each stage as it finishes, with what it found and how long it took. Under them, a live line shows the running stage: a spinner, a progress bar for the long stages (reading, deblending, coarse scales, measurement) and the elapsed time. A summary closes the run:

  🐆 chita v0.0.1 · fast multi-scale source extraction
     bench/out/real/primer_f444w_sci.fits · 10 threads

  ✓ Read image + weight  8192 × 8192 · 537 MB           299 ms
  ✓ Background (masked)  sky σ 2.82e-3                  398 ms
  ✓ Significance map     correlated noise ×2.50         536 ms
  ✓ Deblending           9,793 sources                  685 ms
  ✓ Coarse scales        +68 sources, 9 envelopes       259 ms
  ⠹ Measurement          ━━━━━━━━━╸──── 6,992/9,861     227 ms

  ╭──────────────────────────────────────────────────────────╮
  │ 9,861 sources in 3.73 s                                  │
  │ 9,793 at the PSF scale · 68 on coarse scales             │
  │ spurious estimate 82 (0.8%), from the inverted image     │
  ╰──────────────────────────────────────────────────────────╯

(Some stage lines are left out here.) When stderr is not a terminal, such as a pipe or a log file, the same lines are printed as the stages finish, without colour or the live line. --color never (or NO_COLOR=1) turns the colour off, and -q prints only errors.

It reads any BITPIX, BSCALE/BZERO/BLANK, and primary or IMAGE-extension FITS. For tile-compressed (.fz) images, use chita.extract_file in Python (it reads them through astropy).

Python

import chita

res = chita.extract(image)                    # 2-D numpy array (any dtype)
res = chita.extract(image, weight=wht, mask=bad, gain=2.0, threads=8)
res = chita.extract_file("image.fits", hdu=1)  # via astropy

cat = res.catalog          # numpy structured array (as_table=True -> astropy Table)
seg = res.segmentation     # 0 = sky, else source id
res.background, res.rms    # full-resolution maps
res.info                   # FWHM used, noise correlation, spurious estimate, timings

Several bands

Images of several bands on one pixel grid are detected jointly and then measured band by band with the same apertures. Detection is not diluted for sources seen in only one or two bands (docs/multiband.md). Inside large objects, compact sources and clumps whose colour differs from the object's are found as sources of their own (flag 512; subsources=False turns this off):

mb = chita.MultiBand(width, height)
for name, sci, err in bands:                    # in wavelength order
    mb.add_band(name, sci, err, weight_type="rms", fwhm=psf_fwhm[name])
det = mb.detect()                               # catalog, segmentation, detection map
det.catalog["det_window"]                       # e.g. "F356W-F444W": the bands that found it
det.info["n_sub"]                               # compact sources and clumps found inside large objects

phot = chita.forced_photometry(sci, det.segmentation, det.catalog, err,
                                 aper_radii=[3.3, 5.0], kron_factors=(2.5, 1.2), fwhm=psf_fwhm[name])

scripts/multiband_catalog.py builds a complete catalog this way:

  • native and PSF-matched photometry;
  • aperture corrections to the total flux from empirical PSFs;
  • random-aperture errors;
  • nJy fluxes;
  • quality columns.

Catalogue columns

Coordinates are 0-based with pixel centres at integers (numpy convention). Add 1 to compare with SExtractor/FITS conventions.

column meaning
x, y isophotal barycentre
x_win, y_win windowed (iterative Gaussian) centroid, as SExtractor's XWIN
x_peak, y_peak brightest pixel
x2, y2, xy, a, b, theta second moments, RMS semi-axes, position angle (rad, CCW from +x)
npix, flux_iso, flux_iso_err segment area and flux
kron_radius, flux_auto, flux_auto_err Kron radius (units of a,b) and Kron-aperture (2.5, min 3.5) flux; neighbours replaced by mirror pixels
flux_aper, flux_aper_err circular apertures (default radii 1 and 2 x FWHM), exact pixel overlap
flux_radius, fwhm half-light radius; FWHM from the half-maximum area
peak, det_sig, snr peak value, peak significance at the detection scale, AUTO S/N
bkg local background (plus the subtracted halo level for ON_HALO objects)
scale detection scale: 0 = PSF scale, k = pyramid level (~2^k px)
parent, nblend footprint id and number of sources deblended from it
host id of the brighter object on whose light (halo or body) this one sits, for ON_HALO objects; else 0
flags 1 blended, 2 edge, 4 masked pixels, 8 saturated, 16 AUTO aperture truncated, 32 windowed centroid failed, 64 neighbours in AUTO aperture, 128 grown with a coarse-scale envelope, 256 on a brighter object's halo or body (host; its light there was subtracted), 512 sub-source: a compact source or clump found inside its host (use circular apertures)

Benchmarks

bench/simulate.py makes GalSim images with known truth: stars, Sérsic galaxies (some with star-forming knots), LSB dwarfs, background structure, and white or correlated noise. bench/validate.py compares Chita with SEP, SExtractor and photutils using one-to-one matching and threshold sweeps. bench/speed.py measures throughput.

python bench/simulate.py --size 4096 --fwhm 2.5 --out bench/out/sim_ground
python bench/validate.py bench/out/sim_ground --sweep --photutils
python bench/speed.py bench/out/sim_ground.fits

Results are in docs/results.md.

On real images, bench/real_eval.py injects sources into a mosaic and recovers them. It covers blank sky and the wings of bright objects, and uses the inverted image as a purity proxy. bench/real_report.py turns its output into tables and a trade-off figure. docs/real_images.md covers JWST/NIRCam mosaics of Abell 2744 and PRIMER-COSMOS: the failure modes they exposed, the fixes, and the comparison with the other codes.

Repository layout

crates/chita-core   Rust library (background, filters, labeling, deblending,
                    measurement, pipeline, FITS I/O)
crates/chita-cli    `chita` command
crates/chita-py     Python bindings (PyO3) + `chita` package + tests
bench/              simulations, validation and speed benchmarks
scripts/            multi-band catalog builder
docs/               review of existing codes, design, results (simulated and real)
pyproject.toml      Python packaging (maturin)
.github/workflows/  tests on every push; packages and releases on version tags

Development

Building from a clone needs Rust ≥ 1.75 and maturin:

maturin develop --release        # the Python package and `chita`, into the active environment
cargo build --release            # the command alone: target/release/chita
cargo test --release             # Rust tests
python -m pytest crates/chita-py/tests

environment.yml creates a conda environment with the benchmark codes as well (SEP, photutils, GalSim, SExtractor):

conda env create -f environment.yml && conda activate chita

Releasing

  1. Set the new version in Cargo.toml ([workspace.package]) and commit.
  2. Tag and push: git tag v0.2.0 && git push origin v0.2.0.

The Release workflow then builds and tests the packages for every platform, publishes them to PyPI and creates the GitHub release. PyPI accepts them because the project trusts this repository's release.yml workflow in the pypi environment (trusted publishing); no token is stored.

Building inside a conda shell

Some conda setups export CFLAGS for a different architecture (for example -march=core2 from an Intel anaconda on Apple Silicon). Chita itself has no C code. If you add C-based dependencies, build with env -u CFLAGS -u CPPFLAGS cargo build --release.

Metadata

Release files for chita 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for chita 0.0.1
File Size Uploaded Provenance Actions
chita-0.0.1.tar.gz 128.6 kB With provenance Details for chita-0.0.1.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for chita 0.0.1
File Actions
chita-0.0.1-cp39-abi3-win_amd64.whl CPython 3.9 abi3 Windows x86-64 Details for chita-0.0.1-cp39-abi3-win_amd64.whl
chita-0.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl CPython 3.9 abi3 Linux glibc 2.17+ x86-64 Details for chita-0.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
chita-0.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl CPython 3.9 abi3 Linux glibc 2.17+ ARM64 Details for chita-0.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
chita-0.0.1-cp39-abi3-macosx_10_12_universal2.macosx_10_12_x86_64.macosx_11_0_arm64.whl CPython 3.9 abi3 macOS 11.0+ ARM64, macOS 10.12+ universal2 (ARM64, x86-64), macOS 10.12+ x86-64 Details for chita-0.0.1-cp39-abi3-macosx_10_12_universal2.macosx_10_12_x86_64.macosx_11_0_arm64.whl

Total release size: 5.0 MB

Release files / chita-0.0.1.tar.gz

Download URL chita-0.0.1.tar.gz
Size 128.6 kB
Tags Source
SHA-256 checksum
How to use checksums
bc146d09f16f4d9e4d4ec6f4ee7a7b8517227e7075c5f1be1e79529134f7ac87
BLAKE2b-256 checksum
How to use checksums
abd951eafe02a7584d66481f83e3beeef0b99f8b233b9c37489424d6ea6ccb67
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 30, 2026.

Transparency log

Release files / chita-0.0.1-cp39-abi3-win_amd64.whl

Download URL chita-0.0.1-cp39-abi3-win_amd64.whl
Size 956.0 kB
Tags CPython 3.9 Windows x86-64 abi3
SHA-256 checksum
How to use checksums
1e7f5f1a44e09648843ada52e53e9cc1017391908c08eda1a94990710bd5a815
BLAKE2b-256 checksum
How to use checksums
5c2a65c2a7d8cd6d9926f3c18541324e4b8924d00e1fe98221454c8ef70eeb3f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 30, 2026.

Transparency log

Release files / chita-0.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl

Download URL chita-0.0.1-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl
Size 1.0 MB
Tags CPython 3.9 Linux glibc 2.17+ x86-64 abi3
SHA-256 checksum
How to use checksums
8d77ee1929febf59c51167e1fa7e0a81fe776117b1e6592c36695af9d3f3103c
BLAKE2b-256 checksum
How to use checksums
93084de4cfaeb3c1dbf03b5884c393362b7b7db1da62c0faf6d801916acb4e0c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 30, 2026.

Transparency log

Release files / chita-0.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl

Download URL chita-0.0.1-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl
Size 967.8 kB
Tags CPython 3.9 Linux glibc 2.17+ ARM64 abi3
SHA-256 checksum
How to use checksums
168d2506a6026080a2e60207e6ddb834a7a74eb873549f31e9262e47ccd4af44
BLAKE2b-256 checksum
How to use checksums
769ac08339bd6a80ffa950d34c65327f9d76aeba6e31e4bfd3fc3ab651e9a842
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 30, 2026.

Transparency log

Release files / chita-0.0.1-cp39-abi3-macosx_10_12_universal2.macosx_10_12_x86_64.macosx_11_0_arm64.whl

Download URL chita-0.0.1-cp39-abi3-macosx_10_12_universal2.macosx_10_12_x86_64.macosx_11_0_arm64.whl
Size 1.9 MB
Tags CPython 3.9 abi3 macOS 10.12+ universal2 (ARM64, x86-64) macOS 10.12+ x86-64 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
6c3bd95fe81053459cbf349e87043d095e23ec0717fc4de3cb88bba887aa6f21
BLAKE2b-256 checksum
How to use checksums
64854af23024672bab8da4caf8f64f9491ab26b86cacd68e2ebfd29104ef966f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

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 30, 2026.

Transparency log

Security for chita 0.0.1

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 5 files in this release have been uploaded with provenance metadata.

Select from 5 files

Attestation for chita-0.0.1.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 30, 2026.

Transparency log

A 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.

Release history Release notifications | RSS feed

This release

0.0.1 This release

5 release files Full provenance

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page