# spicekit
[](https://crates.io/crates/spicekit)
[](https://docs.rs/spicekit)
[](https://pypi.org/project/spicekit/)
[](https://github.com/B612-Asteroid-Institute/spicekit/actions/workflows/ci.yml)
[](./LICENSE)
spicekit is an independent, pure-Rust reader for the SPICE kernel formats
(DAF containers, SPK ephemeris files, binary PCK rotation files, and the
text-kernel subset used for body-name bindings). It is **not affiliated
with or endorsed by NAIF/JPL, and it is not a port of the CSpice
toolkit** — all executable logic is an independent implementation
written from the published NAIF file-format specifications, with no
CSpice linkage and no translated CSpice source. The only CSpice-derived
artifact shipped in this crate is the 692-entry body-name table in
`src/naif_builtin_table.rs`, which is reproduced under NAIF's
distribution terms (see [`LICENSE-NOTICES`](./LICENSE-NOTICES)).
## Install
### Rust
```toml
[dependencies]
spicekit = "0.1"
```
### Python
```bash
pip install spicekit
```
## Scope
`spicekit` implements the subset of SPICE consumed by the
[adam-core](https://github.com/B612-Asteroid-Institute/adam_core) asteroid
dynamics library, which is the project it was originally extracted from:
- **DAF**: memory-mapped container parser (shared by SPK and PCK)
- **SPK**: reader for Types 2, 3, 9, 13; writer for Types 3 and 9
- **PCK**: binary PCK reader producing J2000↔ITRF93 rotations and their
time derivatives at machine precision
- **Text kernels**: parser for `NAIF_BODY_NAME` / `NAIF_BODY_CODE` paired
arrays (custom name ↔ code bindings used by mission kernels). Other
keys (leapseconds, SCLK constants, frame definitions) parse without
error but their contents are not exposed.
- **Built-in NAIF body table**: the 692-entry name ↔ ID map mirrored from
CSpice's `zzidmap.c`, with case-insensitive whitespace-tolerant
matching.
## Non-goals
- No async I/O — sync memory-mapped reads only.
- No CSpice linkage and no FFI in the base crate. CSpice parity is
verified in the sibling `spicekit-bench` crate, which links `cspice-sys`
behind a feature flag and compares every code path against CSpice at
machine-epsilon tolerance.
- No CLI tool.
- Read-only for PCK in v0.1.
## Python bindings
Python bindings are provided by the `spicekit-py` crate in this
workspace (shipped to PyPI as the `spicekit` package). Build and install
with [maturin](https://github.com/PyO3/maturin):
```bash
maturin develop --release --manifest-path crates/spicekit-py/Cargo.toml
```
Then:
```python
import spicekit
spk = spicekit.NaifSpk("/path/to/de440.bsp")
```
## Parity testing and benchmarks
`spicekit-bench` keeps an FFI-based CSpice reference installation and
asserts that every spicekit numeric path bit-matches CSpice at a
science-grade tolerance. It also runs side-by-side latency
microbenchmarks on matched inputs; the latest numbers (regenerated by
CI on every push to `main`) live in [`BENCHMARKS.md`](./BENCHMARKS.md).
See each module's rustdoc for details.
## License and attribution
Licensed under the [MIT License](./LICENSE).
The file `src/naif_builtin_table.rs` contains data extracted from the
NAIF CSpice toolkit (specifically, the NPERM table in `zzidmap.c`). The
NAIF toolkit is distributed by the Jet Propulsion Laboratory under terms
that permit redistribution with attribution — see `LICENSE-NOTICES` for
the full attribution and the relevant NAIF distribution-terms excerpt.
## Test layers
spicekit's own test suite verifies internal correctness (DAF round-trip,
Chebyshev polynomial exactness on coefficient tables, Lagrange exactness
at knot points, text-kernel parser tolerance of LSK/SCLK content, etc.).
CSpice-parity testing — confirming that spicekit's numeric output
bit-matches CSpice at a science-grade tolerance — lives in
`crates/spicekit-bench`, which links the CSpice toolkit and asserts
parity on every code path.