Quickstart#
Prerequisites#
Rust toolchain (1.80+): https://rustup.rs
Optional:
libcfitsio-devfor FITS ingest (see Overview)
Building#
# Show all available targets
make help
# Pure Zarr mode (no C dependencies)
make release
# Full build with FITS ingest (needs libcfitsio-dev)
make release-full
# Install to ~/.cargo/bin
make install # pure Zarr
make install-full # with FITS ingest + zarr-fits binary
Running Calibration#
From a pre-converted Zarr store:
calibrate -i /data/l0/session.zarr \
--output /data/l1/ \
--atm-table atm.catm
From a FITS folder (requires fits-ingest feature):
calibrate -f /data/raw/session_001 \
--output /data/l1/ \
--atm-table atm.catm
This creates session_001.zarr alongside the FITS folder, then calibrates.
On subsequent runs the conversion is skipped automatically.
Standalone FITS Conversion#
zarr-fits convert \
--fits-folder /data/raw/session_001 \
--zarr-path /data/l0/session.zarr
Checking Output#
Read the L1 Zarr store with Python:
import zarr
store = zarr.open("/data/l1/scan_025650", mode="r")
spectra = store["spectra"][:] # [C, D, R, A, S] antenna temperature
t_sys = store["t_sys"][:] # [C, R, A, S] system temperature
flags = store["flags"][:] # [C, D, R, A, S] u16 bitmask
Python Bindings#
cd crates/cal-py && maturin develop
import _cal_rs
scans = _cal_rs.list_scans("/data/l0/session.zarr")
result = _cal_rs.calibrate_store(
input_path="/data/l0/session.zarr",
output_path="/data/l1/",
atm_table_path="atm.catm",
)
print(f"OK: {result['successes']}, Failed: {len(result['failures'])}")
Running Tests#
make test # all tests (needs libcfitsio-dev)
make test-cal # calibration tests only (no cfitsio)
make test-zarr # FITS conversion tests only