spicekit 0.1.0__tar.gz → 0.2.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. {spicekit-0.1.0 → spicekit-0.2.1}/Cargo.lock +39 -25
  2. {spicekit-0.1.0 → spicekit-0.2.1}/Cargo.toml +1 -1
  3. spicekit-0.2.1/LICENSE +21 -0
  4. spicekit-0.2.1/LICENSE-NOTICES +30 -0
  5. {spicekit-0.1.0 → spicekit-0.2.1}/PKG-INFO +4 -2
  6. {spicekit-0.1.0/crates/spicekit-py → spicekit-0.2.1}/README.md +1 -1
  7. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/Cargo.toml +2 -0
  8. spicekit-0.2.1/crates/spicekit/LICENSE +21 -0
  9. spicekit-0.2.1/crates/spicekit/LICENSE-NOTICES +30 -0
  10. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/README.md +4 -2
  11. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/src/daf.rs +59 -5
  12. spicekit-0.2.1/crates/spicekit/src/lib.rs +33 -0
  13. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/src/naif_ids.rs +1 -1
  14. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/src/pck.rs +30 -19
  15. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/src/spk.rs +336 -35
  16. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/src/spk_writer.rs +85 -3
  17. spicekit-0.2.1/crates/spicekit-py/LICENSE +21 -0
  18. spicekit-0.2.1/crates/spicekit-py/LICENSE-NOTICES +30 -0
  19. {spicekit-0.1.0 → spicekit-0.2.1/crates/spicekit-py}/README.md +1 -1
  20. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/src/lib.rs +5 -3
  21. {spicekit-0.1.0 → spicekit-0.2.1}/pyproject.toml +2 -1
  22. {spicekit-0.1.0 → spicekit-0.2.1}/python/spicekit/__init__.py +1 -2
  23. spicekit-0.1.0/crates/spicekit/src/lib.rs +0 -27
  24. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/examples/read_spk.rs +0 -0
  25. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/src/frame.rs +0 -0
  26. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/src/naif_builtin_table.rs +0 -0
  27. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit/src/text_kernel.rs +0 -0
  28. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/Cargo.toml +0 -0
  29. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/examples/read_spk.py +0 -0
  30. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/tests/conftest.py +0 -0
  31. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/tests/test_names.py +0 -0
  32. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/tests/test_pck.py +0 -0
  33. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/tests/test_spk.py +0 -0
  34. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/tests/test_spk_writer.py +0 -0
  35. {spicekit-0.1.0 → spicekit-0.2.1}/crates/spicekit-py/tests/test_text_kernel.py +0 -0
  36. {spicekit-0.1.0 → spicekit-0.2.1}/python/spicekit/__init__.pyi +0 -0
  37. {spicekit-0.1.0 → spicekit-0.2.1}/python/spicekit/py.typed +0 -0
@@ -58,7 +58,7 @@ dependencies = [
58
58
  "proc-macro2",
59
59
  "quote",
60
60
  "regex",
61
- "rustc-hash",
61
+ "rustc-hash 1.1.0",
62
62
  "shlex",
63
63
  "which",
64
64
  ]
@@ -81,6 +81,12 @@ version = "3.20.2"
81
81
  source = "registry+https://github.com/rust-lang/crates.io-index"
82
82
  checksum = "5d20789868f4b01b2f2caec9f5c4e0213b41e3e5702a50157d699ae31ced2fcb"
83
83
 
84
+ [[package]]
85
+ name = "bytemuck"
86
+ version = "1.25.0"
87
+ source = "registry+https://github.com/rust-lang/crates.io-index"
88
+ checksum = "c8efb64bd706a16a1bdde310ae86b351e4d21550d98d056f22f8a7f7a2183fec"
89
+
84
90
  [[package]]
85
91
  name = "bytes"
86
92
  version = "1.11.1"
@@ -89,9 +95,9 @@ checksum = "1e748733b7cbc798e1434b6ac524f0c1ff2ab456fe201501e6497c8417a4fc33"
89
95
 
90
96
  [[package]]
91
97
  name = "cc"
92
- version = "1.2.60"
98
+ version = "1.2.61"
93
99
  source = "registry+https://github.com/rust-lang/crates.io-index"
94
- checksum = "43c5703da9466b66a946814e1adf53ea2c90f10063b86290cc9eb67ce3478a20"
100
+ checksum = "d16d90359e986641506914ba71350897565610e87ce0ad9e6f28569db3dd5c6d"
95
101
  dependencies = [
96
102
  "find-msvc-tools",
97
103
  "shlex",
@@ -619,9 +625,9 @@ dependencies = [
619
625
 
620
626
  [[package]]
621
627
  name = "idna_adapter"
622
- version = "1.2.1"
628
+ version = "1.2.2"
623
629
  source = "registry+https://github.com/rust-lang/crates.io-index"
624
- checksum = "3acae9609540aa318d1bc588455225fb2085b9ed0c4f6bd0d9d5bcd86f1a0344"
630
+ checksum = "cb68373c0d6620ef8105e855e7745e18b0d00d3bdb07fb532e434244cdb9a714"
625
631
  dependencies = [
626
632
  "icu_normalizer",
627
633
  "icu_properties",
@@ -672,9 +678,9 @@ checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682"
672
678
 
673
679
  [[package]]
674
680
  name = "js-sys"
675
- version = "0.3.95"
681
+ version = "0.3.97"
676
682
  source = "registry+https://github.com/rust-lang/crates.io-index"
677
- checksum = "2964e92d1d9dc3364cae4d718d93f227e3abb088e747d92e0395bfdedf1c12ca"
683
+ checksum = "a1840c94c045fbcf8ba2812c95db44499f7c64910a912551aaaa541decebcacf"
678
684
  dependencies = [
679
685
  "cfg-if",
680
686
  "futures-util",
@@ -702,9 +708,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2"
702
708
 
703
709
  [[package]]
704
710
  name = "libc"
705
- version = "0.2.185"
711
+ version = "0.2.186"
706
712
  source = "registry+https://github.com/rust-lang/crates.io-index"
707
- checksum = "52ff2c0fe9bc6cb6b14a0592c2ff4fa9ceb83eea9db979b0487cd054946a2b8f"
713
+ checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
708
714
 
709
715
  [[package]]
710
716
  name = "libloading"
@@ -878,7 +884,7 @@ dependencies = [
878
884
  "num-integer",
879
885
  "num-traits",
880
886
  "pyo3",
881
- "rustc-hash",
887
+ "rustc-hash 1.1.0",
882
888
  ]
883
889
 
884
890
  [[package]]
@@ -1183,6 +1189,12 @@ version = "1.1.0"
1183
1189
  source = "registry+https://github.com/rust-lang/crates.io-index"
1184
1190
  checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
1185
1191
 
1192
+ [[package]]
1193
+ name = "rustc-hash"
1194
+ version = "2.1.2"
1195
+ source = "registry+https://github.com/rust-lang/crates.io-index"
1196
+ checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe"
1197
+
1186
1198
  [[package]]
1187
1199
  name = "rustix"
1188
1200
  version = "0.38.44"
@@ -1362,17 +1374,19 @@ dependencies = [
1362
1374
 
1363
1375
  [[package]]
1364
1376
  name = "spicekit"
1365
- version = "0.1.0"
1377
+ version = "0.2.1"
1366
1378
  dependencies = [
1379
+ "bytemuck",
1367
1380
  "memmap2",
1368
1381
  "rayon",
1382
+ "rustc-hash 2.1.2",
1369
1383
  "tempfile",
1370
1384
  "thiserror",
1371
1385
  ]
1372
1386
 
1373
1387
  [[package]]
1374
1388
  name = "spicekit-bench"
1375
- version = "0.1.0"
1389
+ version = "0.2.1"
1376
1390
  dependencies = [
1377
1391
  "cspice-sys",
1378
1392
  "spicekit",
@@ -1381,7 +1395,7 @@ dependencies = [
1381
1395
 
1382
1396
  [[package]]
1383
1397
  name = "spicekit-py"
1384
- version = "0.1.0"
1398
+ version = "0.2.1"
1385
1399
  dependencies = [
1386
1400
  "ndarray",
1387
1401
  "numpy",
@@ -1659,9 +1673,9 @@ dependencies = [
1659
1673
 
1660
1674
  [[package]]
1661
1675
  name = "wasm-bindgen"
1662
- version = "0.2.118"
1676
+ version = "0.2.120"
1663
1677
  source = "registry+https://github.com/rust-lang/crates.io-index"
1664
- checksum = "0bf938a0bacb0469e83c1e148908bd7d5a6010354cf4fb73279b7447422e3a89"
1678
+ checksum = "df52b6d9b87e0c74c9edfa1eb2d9bf85e5d63515474513aa50fa181b3c4f5db1"
1665
1679
  dependencies = [
1666
1680
  "cfg-if",
1667
1681
  "once_cell",
@@ -1672,9 +1686,9 @@ dependencies = [
1672
1686
 
1673
1687
  [[package]]
1674
1688
  name = "wasm-bindgen-futures"
1675
- version = "0.4.68"
1689
+ version = "0.4.70"
1676
1690
  source = "registry+https://github.com/rust-lang/crates.io-index"
1677
- checksum = "f371d383f2fb139252e0bfac3b81b265689bf45b6874af544ffa4c975ac1ebf8"
1691
+ checksum = "af934872acec734c2d80e6617bbb5ff4f12b052dd8e6332b0817bce889516084"
1678
1692
  dependencies = [
1679
1693
  "js-sys",
1680
1694
  "wasm-bindgen",
@@ -1682,9 +1696,9 @@ dependencies = [
1682
1696
 
1683
1697
  [[package]]
1684
1698
  name = "wasm-bindgen-macro"
1685
- version = "0.2.118"
1699
+ version = "0.2.120"
1686
1700
  source = "registry+https://github.com/rust-lang/crates.io-index"
1687
- checksum = "eeff24f84126c0ec2db7a449f0c2ec963c6a49efe0698c4242929da037ca28ed"
1701
+ checksum = "78b1041f495fb322e64aca85f5756b2172e35cd459376e67f2a6c9dffcedb103"
1688
1702
  dependencies = [
1689
1703
  "quote",
1690
1704
  "wasm-bindgen-macro-support",
@@ -1692,9 +1706,9 @@ dependencies = [
1692
1706
 
1693
1707
  [[package]]
1694
1708
  name = "wasm-bindgen-macro-support"
1695
- version = "0.2.118"
1709
+ version = "0.2.120"
1696
1710
  source = "registry+https://github.com/rust-lang/crates.io-index"
1697
- checksum = "9d08065faf983b2b80a79fd87d8254c409281cf7de75fc4b773019824196c904"
1711
+ checksum = "9dcd0ff20416988a18ac686d4d4d0f6aae9ebf08a389ff5d29012b05af2a1b41"
1698
1712
  dependencies = [
1699
1713
  "bumpalo",
1700
1714
  "proc-macro2",
@@ -1705,9 +1719,9 @@ dependencies = [
1705
1719
 
1706
1720
  [[package]]
1707
1721
  name = "wasm-bindgen-shared"
1708
- version = "0.2.118"
1722
+ version = "0.2.120"
1709
1723
  source = "registry+https://github.com/rust-lang/crates.io-index"
1710
- checksum = "5fd04d9e306f1907bd13c6361b5c6bfc7b3b3c095ed3f8a9246390f8dbdee129"
1724
+ checksum = "49757b3c82ebf16c57d69365a142940b384176c24df52a087fb748e2085359ea"
1711
1725
  dependencies = [
1712
1726
  "unicode-ident",
1713
1727
  ]
@@ -1748,9 +1762,9 @@ dependencies = [
1748
1762
 
1749
1763
  [[package]]
1750
1764
  name = "web-sys"
1751
- version = "0.3.95"
1765
+ version = "0.3.97"
1752
1766
  source = "registry+https://github.com/rust-lang/crates.io-index"
1753
- checksum = "4f2dfbb17949fa2088e5d39408c48368947b86f7834484e87b73de55bc14d97d"
1767
+ checksum = "2eadbac71025cd7b0834f20d1fe8472e8495821b4e9801eb0a60bd1f19827602"
1754
1768
  dependencies = [
1755
1769
  "js-sys",
1756
1770
  "wasm-bindgen",
@@ -3,7 +3,7 @@ members = ["crates/*"]
3
3
  resolver = "2"
4
4
 
5
5
  [workspace.package]
6
- version = "0.1.0"
6
+ version = "0.2.1"
7
7
  edition = "2021"
8
8
  rust-version = "1.85"
9
9
  license = "MIT"
spicekit-0.2.1/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026, Asteroid Institute
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ Third-Party Attributions
2
+ ========================
3
+
4
+ src/naif_builtin_table.rs
5
+ -------------------------
6
+
7
+ The data in this file (the 692-entry built-in body-name ↔ NAIF ID map)
8
+ was extracted from NASA's CSpice toolkit — specifically from the NPERM
9
+ table in `zzidmap.c`. CSpice is distributed by the Navigation and
10
+ Ancillary Information Facility (NAIF) at the Jet Propulsion Laboratory,
11
+ California Institute of Technology.
12
+
13
+ The NAIF toolkit is distributed without restriction; NAIF asks only for
14
+ attribution when the toolkit or derived artifacts are redistributed.
15
+ The canonical distribution statement (from the NAIF toolkit's
16
+ distribution-terms documentation) is:
17
+
18
+ Copyright (C) [year], California Institute of Technology.
19
+ U.S. Government sponsorship acknowledged.
20
+
21
+ spicekit acknowledges NAIF as the source of the body-name ↔ ID data
22
+ embedded in `naif_builtin_table.rs`. Users who rely on that data in
23
+ redistributed work should verify the current NAIF distribution-terms
24
+ document, available with any CSpice toolkit release, for any updated
25
+ requirements.
26
+
27
+ spicekit is not a port of CSpice. All executable logic in this crate is
28
+ an independent implementation written from the NAIF SPK / PCK / DAF file
29
+ format specifications (which are published separately from the toolkit,
30
+ in the NAIF "required reading" documents).
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: spicekit
3
- Version: 0.1.0
3
+ Version: 0.2.1
4
4
  Classifier: Development Status :: 4 - Beta
5
5
  Classifier: Intended Audience :: Science/Research
6
6
  Classifier: License :: OSI Approved :: MIT License
@@ -19,6 +19,8 @@ Requires-Dist: naif-de440 ; extra == 'test'
19
19
  Requires-Dist: naif-earth-itrf93 ; extra == 'test'
20
20
  Requires-Dist: naif-eop-high-prec ; extra == 'test'
21
21
  Provides-Extra: test
22
+ License-File: LICENSE
23
+ License-File: LICENSE-NOTICES
22
24
  Summary: Python bindings for spicekit: pure-Rust NAIF kernel readers (DAF/SPK/PCK/text kernels).
23
25
  Author: Asteroid Institute
24
26
  Author-email: Alec Koumjian <alec@b612foundation.org>
@@ -33,7 +35,7 @@ Project-URL: Repository, https://github.com/B612-Asteroid-Institute/spicekit
33
35
 
34
36
  [![PyPI](https://img.shields.io/pypi/v/spicekit.svg)](https://pypi.org/project/spicekit/)
35
37
  [![CI](https://github.com/B612-Asteroid-Institute/spicekit/actions/workflows/ci.yml/badge.svg)](https://github.com/B612-Asteroid-Institute/spicekit/actions/workflows/ci.yml)
36
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)
38
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
37
39
 
38
40
  Python bindings for [`spicekit`](../spicekit), a pure-Rust reader for
39
41
  NASA/NAIF SPICE kernel formats (DAF, SPK, PCK, text kernels). Independent
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![PyPI](https://img.shields.io/pypi/v/spicekit.svg)](https://pypi.org/project/spicekit/)
4
4
  [![CI](https://github.com/B612-Asteroid-Institute/spicekit/actions/workflows/ci.yml/badge.svg)](https://github.com/B612-Asteroid-Institute/spicekit/actions/workflows/ci.yml)
5
- [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](../../LICENSE)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)
6
6
 
7
7
  Python bindings for [`spicekit`](../spicekit), a pure-Rust reader for
8
8
  NASA/NAIF SPICE kernel formats (DAF, SPK, PCK, text kernels). Independent
@@ -15,8 +15,10 @@ categories = ["science", "aerospace", "parser-implementations"]
15
15
  path = "src/lib.rs"
16
16
 
17
17
  [dependencies]
18
+ bytemuck = "1.16"
18
19
  memmap2 = "0.9"
19
20
  rayon = "1.11"
21
+ rustc-hash = "2.0"
20
22
  thiserror = "2.0"
21
23
 
22
24
  [dev-dependencies]
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2026, Asteroid Institute
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,30 @@
1
+ Third-Party Attributions
2
+ ========================
3
+
4
+ src/naif_builtin_table.rs
5
+ -------------------------
6
+
7
+ The data in this file (the 692-entry built-in body-name ↔ NAIF ID map)
8
+ was extracted from NASA's CSpice toolkit — specifically from the NPERM
9
+ table in `zzidmap.c`. CSpice is distributed by the Navigation and
10
+ Ancillary Information Facility (NAIF) at the Jet Propulsion Laboratory,
11
+ California Institute of Technology.
12
+
13
+ The NAIF toolkit is distributed without restriction; NAIF asks only for
14
+ attribution when the toolkit or derived artifacts are redistributed.
15
+ The canonical distribution statement (from the NAIF toolkit's
16
+ distribution-terms documentation) is:
17
+
18
+ Copyright (C) [year], California Institute of Technology.
19
+ U.S. Government sponsorship acknowledged.
20
+
21
+ spicekit acknowledges NAIF as the source of the body-name ↔ ID data
22
+ embedded in `naif_builtin_table.rs`. Users who rely on that data in
23
+ redistributed work should verify the current NAIF distribution-terms
24
+ document, available with any CSpice toolkit release, for any updated
25
+ requirements.
26
+
27
+ spicekit is not a port of CSpice. All executable logic in this crate is
28
+ an independent implementation written from the NAIF SPK / PCK / DAF file
29
+ format specifications (which are published separately from the toolkit,
30
+ in the NAIF "required reading" documents).
@@ -77,11 +77,13 @@ import spicekit
77
77
  spk = spicekit.NaifSpk("/path/to/de440.bsp")
78
78
  ```
79
79
 
80
- ## Parity testing
80
+ ## Parity testing and benchmarks
81
81
 
82
82
  `spicekit-bench` keeps an FFI-based CSpice reference installation and
83
83
  asserts that every spicekit numeric path bit-matches CSpice at a
84
- science-grade tolerance.
84
+ science-grade tolerance. It also runs side-by-side latency
85
+ microbenchmarks on matched inputs; the latest numbers (regenerated by
86
+ CI on every push to `main`) live in [`BENCHMARKS.md`](./BENCHMARKS.md).
85
87
 
86
88
  See each module's rustdoc for details.
87
89
 
@@ -1,11 +1,34 @@
1
1
  //! NAIF DAF (Double-precision Array File) container reader.
2
2
  //!
3
- //! All adam-core NAIF data — SPK, PCK, and CK — live inside DAF files. This
4
- //! module parses the file record and summary/name record chain, yielding
5
- //! typed `Summary` descriptors. Payload interpretation (e.g. SPK Type 2
3
+ //! DAF is the shared on-disk container behind every binary SPICE
4
+ //! kernel format — SPK, PCK, and CK — so this module is the entry
5
+ //! point for the per-kernel-type parsers above it. It parses the
6
+ //! file record and the summary/name record chain, yielding typed
7
+ //! [`Summary`] descriptors; payload interpretation (e.g. SPK Type 2
6
8
  //! Chebyshev coefficients) is the caller's responsibility.
7
9
  //!
8
10
  //! Reference: NAIF "DAF Required Reading" (daf.req).
11
+ //!
12
+ //! # Host-endianness assumption
13
+ //!
14
+ //! [`DafFile::doubles_native`] reinterprets `LTL-IEEE` on-disk bytes as
15
+ //! native `f64` with no byte-swap, which is only correct on
16
+ //! little-endian hosts. We currently fail to compile on big-endian
17
+ //! targets rather than silently produce byte-reversed values. The
18
+ //! supported targets (Linux/macOS/Windows on `x86_64` and `aarch64`)
19
+ //! are all little-endian; adding big-endian support requires either a
20
+ //! byte-swap path here or routing the hot paths back through the
21
+ //! existing endian-agnostic [`DafFile::read_doubles`].
22
+
23
+ #[cfg(not(target_endian = "little"))]
24
+ compile_error!(
25
+ "spicekit currently requires a little-endian host (DafFile::doubles_native \
26
+ reinterprets LTL-IEEE bytes as native f64 with no byte-swap). The supported \
27
+ targets — Linux/macOS/Windows on x86_64 and aarch64 — are all little-endian. \
28
+ Adding big-endian support requires either a byte-swap path in doubles_native \
29
+ or routing SPK/PCK hot paths back through read_doubles (which uses \
30
+ f64::from_le_bytes and is endian-agnostic)."
31
+ );
9
32
 
10
33
  use std::path::Path;
11
34
  use std::sync::Arc;
@@ -67,8 +90,9 @@ pub struct Summary {
67
90
  impl DafFile {
68
91
  pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, DafError> {
69
92
  let file = std::fs::File::open(path)?;
70
- // SAFETY: the mapped file is read-only; adam-core does not modify
71
- // SPK/PCK kernels after they've been delivered to the NAIF package.
93
+ // SAFETY: the mapping is read-only; SPK/PCK kernels are
94
+ // immutable artifacts — NAIF distributes them as fixed-content
95
+ // releases and consumers must not modify them in place.
72
96
  let mmap = unsafe { Mmap::map(&file)? };
73
97
  Self::from_mmap(mmap)
74
98
  }
@@ -234,6 +258,36 @@ impl DafFile {
234
258
  Ok(out)
235
259
  }
236
260
 
261
+ /// Zero-copy view of a double range as a `&[f64]` slice into the
262
+ /// memory-mapped file.
263
+ ///
264
+ /// This is the hot-path accessor used by SPK/PCK segment
265
+ /// evaluators: it does **no allocation** and **no per-double
266
+ /// byte-decoding loop** — the bytes are reinterpreted in place.
267
+ ///
268
+ /// Correctness rests on four invariants:
269
+ /// 1. **Host endianness**: the host is little-endian, so the native
270
+ /// `f64` byte order matches the on-disk LTL-IEEE byte order.
271
+ /// Enforced at compile time by the module-level
272
+ /// `compile_error!` above; big-endian builds fail to compile.
273
+ /// 2. **File endianness**: we rejected non-`LTL-IEEE` files at
274
+ /// [`DafFile::open`] (via the private `from_mmap` helper), so
275
+ /// on-disk bytes are LE IEEE-754 f64.
276
+ /// 3. **Alignment**: DAF addresses are 1-indexed counts of 8-byte
277
+ /// doubles; `mmap` returns a base pointer that is page-aligned
278
+ /// (≥ 4096 B) so every DAF double address lands on an 8-byte
279
+ /// boundary.
280
+ /// 4. **Length**: the byte length is `(end_addr - start_addr + 1) * 8`,
281
+ /// exactly a multiple of 8.
282
+ ///
283
+ /// `bytemuck::cast_slice` validates (3) and (4) at runtime, so this
284
+ /// function is fully safe; on a malformed mmap it would panic before
285
+ /// returning bad data.
286
+ pub fn doubles_native(&self, start_addr: u32, end_addr: u32) -> Result<&[f64], DafError> {
287
+ let bytes = self.double_slice(start_addr, end_addr)?;
288
+ Ok(bytemuck::cast_slice(bytes))
289
+ }
290
+
237
291
  /// Zero-copy view of a double range as a &[u8] slice.
238
292
  pub fn double_slice(&self, start_addr: u32, end_addr: u32) -> Result<&[u8], DafError> {
239
293
  if start_addr == 0 || end_addr < start_addr {
@@ -0,0 +1,33 @@
1
+ //! Pure-Rust readers (and writer) for NASA/NAIF SPICE kernel formats.
2
+ //!
3
+ //! Implements the subset of SPICE this crate explicitly supports — DAF
4
+ //! containers, SPK ephemerides, binary PCK rotations, and the
5
+ //! body-name slice of text kernels — with memory-mapped I/O and no
6
+ //! FFI. The DAF parser ([`daf`]) is the shared container reader; the
7
+ //! per-kernel-type parsers ([`spk`], [`pck`], [`text_kernel`]) build
8
+ //! on top of it. [`spk_writer`] emits SPK Type 3 and Type 9 segments.
9
+ //!
10
+ //! This crate does not link CSPICE. Bit-for-bit parity against CSPICE
11
+ //! is asserted in the sibling `spicekit-bench` crate, which links
12
+ //! `cspice-sys` behind a feature flag and exercises every numeric
13
+ //! code path (`spkez`, `pxform`, `sxform`, `bodc2n`, `bodn2c`, plus
14
+ //! the text-kernel precedence semantics) at machine-epsilon
15
+ //! tolerance.
16
+
17
+ pub mod daf;
18
+ pub mod frame;
19
+ pub mod naif_ids;
20
+ pub mod pck;
21
+ pub mod spk;
22
+ pub mod spk_writer;
23
+ pub mod text_kernel;
24
+
25
+ pub use daf::{DafError, DafFile, Summary};
26
+ pub use frame::{rotate_state, NaifFrame, OBLIQUITY_J2000_RAD};
27
+ pub use naif_ids::{bodc2n, bodn2c, NaifIdError};
28
+ pub use pck::{PckError, PckFile, PckSegment};
29
+ pub use spk::{SpkError, SpkFile, SpkSegment};
30
+ pub use spk_writer::{SpkWriter, SpkWriterError, Type3Record, Type3Segment, Type9Segment};
31
+ pub use text_kernel::{
32
+ parse_body_bindings, parse_body_bindings_from_str, BodyBinding, TextKernelError,
33
+ };
@@ -12,7 +12,7 @@
12
12
  //! per-backend body-name registry, which takes precedence over this
13
13
  //! table (last-loaded-wins, matching CSpice).
14
14
  //!
15
- //! Reference: https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html
15
+ //! Reference: <https://naif.jpl.nasa.gov/pub/naif/toolkit_docs/C/req/naif_ids.html>
16
16
 
17
17
  use std::collections::HashMap;
18
18
  use std::sync::OnceLock;
@@ -1,12 +1,15 @@
1
1
  //! Binary PCK (Planetary Constants Kernel) reader.
2
2
  //!
3
- //! Adam-core only needs time-varying planetary body orientations for the
4
- //! Earth-associated `ITRF93` frame. Binary PCK shares the DAF container
5
- //! with SPK, but the summary layout differs (NI=5 instead of 6, with
6
- //! `center` absent: segments describe a single body-fixed frame wrt a
7
- //! reference inertial frame). The payload is the standard Type 2
8
- //! Chebyshev record, but with 3 Euler-angle channels rather than 3
9
- //! position channels. The angles follow the NAIF 3-1-3 convention:
3
+ //! This module reads time-varying planetary body orientations from
4
+ //! binary PCKs. Scope is currently the Earth-associated `ITRF93` frame
5
+ //! and any other body-fixed frames stored as PCK Type 2 Chebyshev
6
+ //! Euler-angle records — the format used by NAIF's standard Earth EOP
7
+ //! kernels. Binary PCK shares the DAF container with SPK, but the
8
+ //! summary layout differs (NI=5 instead of 6, with `center` absent:
9
+ //! segments describe a single body-fixed frame wrt a reference
10
+ //! inertial frame). The payload is the standard Type 2 Chebyshev
11
+ //! record, but with 3 Euler-angle channels rather than 3 position
12
+ //! channels. The angles follow the NAIF 3-1-3 convention:
10
13
  //! `(t1, t2, t3)` such that `R_ref→body = Rz(t3) · Rx(t2) · Rz(t1)`.
11
14
  //! The `ref` frame is the segment's reference inertial frame — the
12
15
  //! standard Earth PCKs use `ECLIPJ2000` (NAIF frame ID 17), so
@@ -20,18 +23,19 @@
20
23
  //!
21
24
  //! Kernel precedence: three PCKs (`predict`, `historical`, `high_prec`)
22
25
  //! may cover overlapping epoch ranges. Last-loaded-wins matches
23
- //! CSPICE `furnsh` semantics: the caller is expected to load kernels in
24
- //! precedence order (least- to most-precise) and the file they opened
25
- //! most recently "wins" for overlapping coverage. This crate offers a
26
- //! per-file reader; multi-file composition is handled at the Python
27
- //! layer with a simple list-of-readers dispatcher.
26
+ //! CSPICE `furnsh` semantics: the caller is expected to load kernels
27
+ //! in precedence order (least- to most-precise) and the file they
28
+ //! opened most recently "wins" for overlapping coverage. This crate
29
+ //! offers a per-file reader; multi-file composition (a list-of-
30
+ //! readers dispatcher) is the caller's responsibility — see the
31
+ //! `spicekit-py` Python bindings for one such implementation.
28
32
 
29
33
  use std::path::Path;
30
34
 
31
35
  use thiserror::Error;
32
36
 
33
37
  use crate::daf::{DafError, DafFile};
34
- use crate::spk::cheby_val_and_deriv;
38
+ use crate::spk::cheby3_val_and_deriv;
35
39
 
36
40
  #[derive(Debug, Error)]
37
41
  pub enum PckError {
@@ -110,7 +114,7 @@ impl PckType2 {
110
114
  let idx = raw_idx.clamp(0, self.n_records as isize - 1) as usize;
111
115
  let rec_start = self.start_addr + (idx * self.rsize) as u32;
112
116
  let rec_end = rec_start + self.rsize as u32 - 1;
113
- let rec = self.file.read_doubles(rec_start, rec_end)?;
117
+ let rec = self.file.doubles_native(rec_start, rec_end)?;
114
118
 
115
119
  let mid = rec[0];
116
120
  let radius = rec[1];
@@ -124,12 +128,19 @@ impl PckType2 {
124
128
  let dec_c = &rec[2 + n..2 + 2 * n];
125
129
  let w_c = &rec[2 + 2 * n..2 + 3 * n];
126
130
 
127
- let (ra, dra) = cheby_val_and_deriv(ra_c, s);
128
- let (dec, ddec) = cheby_val_and_deriv(dec_c, s);
129
- let (w, dw) = cheby_val_and_deriv(w_c, s);
130
-
131
+ // Three-channel evaluation with shared T_k(s) / dT_k/ds basis
132
+ // recurrence — mathematically equivalent to three independent
133
+ // calls but ~3x cheaper on the recurrence half of the work.
134
+ let (ang, dang) = cheby3_val_and_deriv(ra_c, dec_c, w_c, s);
131
135
  let inv_r = 1.0 / radius;
132
- Ok([ra, dec, w, dra * inv_r, ddec * inv_r, dw * inv_r])
136
+ Ok([
137
+ ang[0],
138
+ ang[1],
139
+ ang[2],
140
+ dang[0] * inv_r,
141
+ dang[1] * inv_r,
142
+ dang[2] * inv_r,
143
+ ])
133
144
  }
134
145
  }
135
146