almanac-compute 0.1.0__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.
- almanac_compute-0.1.0/LICENSE +21 -0
- almanac_compute-0.1.0/NOTICE +22 -0
- almanac_compute-0.1.0/PKG-INFO +178 -0
- almanac_compute-0.1.0/README.md +150 -0
- almanac_compute-0.1.0/almanac/__init__.py +18 -0
- almanac_compute-0.1.0/almanac/data/README-WMM-COEFS.txt +70 -0
- almanac_compute-0.1.0/almanac/data/WMM2025.COF +93 -0
- almanac_compute-0.1.0/almanac/data/WMM2025_TestValues.txt +118 -0
- almanac_compute-0.1.0/almanac/ephemeris.py +265 -0
- almanac_compute-0.1.0/almanac/geomag.py +373 -0
- almanac_compute-0.1.0/almanac/mcp_server.py +108 -0
- almanac_compute-0.1.0/almanac_compute.egg-info/PKG-INFO +178 -0
- almanac_compute-0.1.0/almanac_compute.egg-info/SOURCES.txt +20 -0
- almanac_compute-0.1.0/almanac_compute.egg-info/dependency_links.txt +1 -0
- almanac_compute-0.1.0/almanac_compute.egg-info/entry_points.txt +2 -0
- almanac_compute-0.1.0/almanac_compute.egg-info/requires.txt +8 -0
- almanac_compute-0.1.0/almanac_compute.egg-info/top_level.txt +1 -0
- almanac_compute-0.1.0/pyproject.toml +49 -0
- almanac_compute-0.1.0/setup.cfg +4 -0
- almanac_compute-0.1.0/tests/test_ephemeris.py +113 -0
- almanac_compute-0.1.0/tests/test_geomag.py +120 -0
- almanac_compute-0.1.0/tests/test_mcp_server.py +65 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Iris
|
|
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,22 @@
|
|
|
1
|
+
almanac — third-party data notices
|
|
2
|
+
==================================
|
|
3
|
+
|
|
4
|
+
The Python source in this repository is licensed under the MIT License (see
|
|
5
|
+
LICENSE). The bundled and runtime-fetched DATA files are NOT covered by that
|
|
6
|
+
license; they are in the public domain as works of government:
|
|
7
|
+
|
|
8
|
+
1. World Magnetic Model 2025 — bundled
|
|
9
|
+
Files: almanac/data/WMM2025.COF, almanac/data/WMM2025_TestValues.txt
|
|
10
|
+
Source: NOAA/NCEI and the British Geological Survey (US/UK World Magnetic
|
|
11
|
+
Model 2025). A work of the US Government; public domain.
|
|
12
|
+
Validity: 2025.0–2030.0.
|
|
13
|
+
|
|
14
|
+
2. JPL DE421 planetary ephemeris kernel — fetched at runtime, not bundled
|
|
15
|
+
File: de421.bsp (downloaded by skyfield into the working directory on first
|
|
16
|
+
use of almanac.ephemeris)
|
|
17
|
+
Source: NASA Jet Propulsion Laboratory. A work of the US Government; public
|
|
18
|
+
domain.
|
|
19
|
+
|
|
20
|
+
No endorsement by NOAA, NCEI, BGS, NASA, or JPL is implied. The model values
|
|
21
|
+
this software reports are subject to the providers' own accuracy statements;
|
|
22
|
+
see the NOAA WMM disclaimer reproduced in README.md.
|
|
@@ -0,0 +1,178 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: almanac-compute
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Deterministic, verifiable ephemeris + geomagnetic computation — the numbers language models hallucinate, computed correctly and checked against NOAA and JPL.
|
|
5
|
+
Author: Iris
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/savecharlie/almanac
|
|
8
|
+
Project-URL: Source, https://github.com/savecharlie/almanac
|
|
9
|
+
Keywords: ephemeris,geomagnetic,declination,magnetic-declination,WMM,WMM2025,world-magnetic-model,astronomy,navigation,skyfield,deterministic,verifiable,mcp,model-context-protocol,agent-tools,llm-tools
|
|
10
|
+
Classifier: Development Status :: 4 - Beta
|
|
11
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
12
|
+
Classifier: Programming Language :: Python :: 3
|
|
13
|
+
Classifier: Topic :: Scientific/Engineering :: Astronomy
|
|
14
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Intended Audience :: Developers
|
|
17
|
+
Requires-Python: >=3.9
|
|
18
|
+
Description-Content-Type: text/markdown
|
|
19
|
+
License-File: LICENSE
|
|
20
|
+
License-File: NOTICE
|
|
21
|
+
Requires-Dist: skyfield>=1.49
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pytest>=7; extra == "dev"
|
|
24
|
+
Requires-Dist: ephem>=4.1; extra == "dev"
|
|
25
|
+
Provides-Extra: mcp
|
|
26
|
+
Requires-Dist: mcp>=1.2; extra == "mcp"
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
|
|
29
|
+
# almanac
|
|
30
|
+
|
|
31
|
+
**Deterministic, verifiable ephemeris + geomagnetic computation** — the physical
|
|
32
|
+
numbers that language models hallucinate, computed correctly and checked against
|
|
33
|
+
the authorities that publish them.
|
|
34
|
+
|
|
35
|
+
Two pure-compute cores, no API keys, no network for the math, same inputs → same
|
|
36
|
+
bytes:
|
|
37
|
+
|
|
38
|
+
- **`almanac.geomag`** — the Earth's magnetic field from the official **World
|
|
39
|
+
Magnetic Model 2025**: magnetic **declination** (the angle a compass reads off
|
|
40
|
+
true north), inclination, intensity, the X/Y/Z vector, and secular variation,
|
|
41
|
+
for any location/altitude/date. *Pure Python standard library — zero
|
|
42
|
+
dependencies.*
|
|
43
|
+
- **`almanac.ephemeris`** — the sky from the public-domain **JPL DE421** kernel:
|
|
44
|
+
Sun/Moon/planet altitude–azimuth–distance, rise/set/transit, the four twilight
|
|
45
|
+
phases, moon phase + illumination, ecliptic ("zodiac") longitude, day length,
|
|
46
|
+
next new/full moon and next equinox/solstice, for any location/time.
|
|
47
|
+
|
|
48
|
+
The name is literal: an *almanac* is the table of sky positions and magnetic
|
|
49
|
+
variation that navigators bet their lives on for centuries — the **sky** and the
|
|
50
|
+
**field**. This is that, made machine-checkable.
|
|
51
|
+
|
|
52
|
+
## Why this exists
|
|
53
|
+
|
|
54
|
+
Ask a language model *"what's the magnetic declination at 40°N 105°W in 2026?"*
|
|
55
|
+
or *"where's the Moon over Tokyo right now?"* and it will answer — confidently,
|
|
56
|
+
and usually wrong. These are exactly the values an LLM **can't** produce
|
|
57
|
+
reliably: they require a degree-12 spherical-harmonic synthesis (declination) or
|
|
58
|
+
a multi-megabyte ephemeris kernel and careful rise/set/refraction math
|
|
59
|
+
(positions). Getting them wrong points a ship, a drone, or a survey the wrong
|
|
60
|
+
way.
|
|
61
|
+
|
|
62
|
+
`almanac` doesn't guess. It computes — deterministically — and the correctness is
|
|
63
|
+
**provable**, not asserted:
|
|
64
|
+
|
|
65
|
+
## Correctness (the whole point)
|
|
66
|
+
|
|
67
|
+
| Core | Verified against | Result |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| **geomag** | NOAA/NCEI's **own 100 published WMM2025 test values** (shipped in the official `WMM2025COF.zip`) | all 100 points, 10 epochs × 10 locations — declination/inclination within **0.005°** (the half-ULP of NOAA's 2-decimal print), field components within **0.001 nT**, secular variation within **1e-6** |
|
|
70
|
+
| **ephemeris** | an **independent** ephemeris engine (pyephem / VSOP87 — a different codebase) plus known astronomical truth | cross-engine agreement to **~1 arcsecond** |
|
|
71
|
+
|
|
72
|
+
`geomag` is a faithful port of NOAA's `geomag70` reference algorithm; the proof is
|
|
73
|
+
the authority grading our independent synthesis against its own numbers. Run it
|
|
74
|
+
yourself:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pip install -e ".[dev]"
|
|
78
|
+
pytest -q
|
|
79
|
+
# tests/test_geomag.py ....... 107 passed (the 100 NOAA points + edge cases)
|
|
80
|
+
# tests/test_ephemeris.py .... 7 passed (cross-engine + known-truth)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Quickstart
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install -e . # geomag works immediately (stdlib only)
|
|
87
|
+
# ephemeris pulls in skyfield + the public-domain DE421 kernel
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
from almanac.geomag import compute as field
|
|
92
|
+
from almanac.ephemeris import compute as sky
|
|
93
|
+
|
|
94
|
+
# Magnetic declination in Boulder, CO, mid-2026 — what your compass is off by:
|
|
95
|
+
f = field(lat=40.015, lon=-105.27, when="2026-06-26")
|
|
96
|
+
print(f["declination_deg"], "-", f["compass_note"])
|
|
97
|
+
# 7.6892 - magnetic north is 7.69 deg east of true north
|
|
98
|
+
|
|
99
|
+
# The sky over New York at a given instant:
|
|
100
|
+
s = sky(lat=40.7128, lon=-74.0060, when="2026-06-25T18:00:00Z")
|
|
101
|
+
print(s["moon"]["phase_name"], s["bodies"]["moon"]["above_horizon"])
|
|
102
|
+
print(s["bodies"]["sun"]["zodiac"]["sign"])
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Every result is a plain JSON-serializable dict, fully labeled with units, and
|
|
106
|
+
**deterministic** — the same query returns the same bytes, every time, on any
|
|
107
|
+
machine.
|
|
108
|
+
|
|
109
|
+
## API
|
|
110
|
+
|
|
111
|
+
```python
|
|
112
|
+
almanac.geomag.compute(lat, lon, altitude_km=0.0, when=None) -> dict
|
|
113
|
+
# lat/lon geodetic degrees; altitude_km above WGS84 ellipsoid (WMM valid -1..850);
|
|
114
|
+
# when = ISO date/datetime, a bare decimal year like "2027.5", or "now"/None.
|
|
115
|
+
# WMM2025 is valid 2025.0–2030.0. Declination positive = east of true north.
|
|
116
|
+
|
|
117
|
+
almanac.ephemeris.compute(lat, lon, elevation_m=0.0, when=None) -> dict
|
|
118
|
+
# lat/lon geodetic degrees; elevation_m above sea level;
|
|
119
|
+
# when = ISO-8601 UTC datetime, or "now"/None.
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
## Use it from an AI agent (MCP)
|
|
123
|
+
|
|
124
|
+
LLMs answer "what's the magnetic declination at 40°N 105°W in 2026?" confidently
|
|
125
|
+
and usually wrong — these are exactly the values next-token prediction can't
|
|
126
|
+
produce. `almanac` ships a [Model Context Protocol](https://modelcontextprotocol.io)
|
|
127
|
+
server so an agent can **call** the verified computation instead of guessing it:
|
|
128
|
+
|
|
129
|
+
```bash
|
|
130
|
+
pip install "almanac-compute[mcp]"
|
|
131
|
+
almanac-mcp # stdio transport — point any MCP client at this command
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
Two tools, both deterministic and both checkable against the publishing
|
|
135
|
+
authority:
|
|
136
|
+
|
|
137
|
+
- **`magnetic_field(lat, lon, altitude_km=0, when=None)`** — WMM2025 declination,
|
|
138
|
+
inclination, intensity, X/Y/Z, secular variation.
|
|
139
|
+
- **`sky_positions(lat, lon, elevation_m=0, when=None)`** — sun/moon/planet
|
|
140
|
+
altitude–azimuth–distance, rise/set/transit, twilight, moon phase, zodiac.
|
|
141
|
+
|
|
142
|
+
The pitch is the determinism: same inputs → same bytes, and the core is open, so
|
|
143
|
+
an agent (or you) can **re-execute any answer and verify it** rather than trust a
|
|
144
|
+
reputation score. That's the whole design — trust by re-execution, not by vote.
|
|
145
|
+
|
|
146
|
+
<!-- MCP registry namespace claim (proves this PyPI package and the
|
|
147
|
+
io.github.savecharlie GitHub account are the same owner): -->
|
|
148
|
+
mcp-name: io.github.savecharlie/almanac
|
|
149
|
+
|
|
150
|
+
## Data provenance & license
|
|
151
|
+
|
|
152
|
+
- **Code** (the synthesis, the wrappers, the tests): **MIT** — see `LICENSE`.
|
|
153
|
+
- **`WMM2025.COF` + `WMM2025_TestValues.txt`**: the US/UK **World Magnetic
|
|
154
|
+
Model 2025** (NOAA/NCEI + British Geological Survey). As a work of the US
|
|
155
|
+
Government, **public domain**. Valid 2025.0–2030.0.
|
|
156
|
+
- **JPL DE421 kernel** (fetched by `skyfield` on first ephemeris use): NASA/JPL,
|
|
157
|
+
**public domain**.
|
|
158
|
+
|
|
159
|
+
> Per NOAA: the WMM is the standard navigation model but is not a substitute for
|
|
160
|
+
> local magnetic surveys; declination uncertainty grows near the magnetic poles
|
|
161
|
+
> and in regions of crustal anomaly. `almanac` reports the model value,
|
|
162
|
+
> deterministically — it does not model local anomalies.
|
|
163
|
+
|
|
164
|
+
## Roadmap
|
|
165
|
+
|
|
166
|
+
A hosted, **machine-payable** version of these cores (one HTTP call, pay-per-use,
|
|
167
|
+
no API-key signup) is in progress — so an autonomous agent can fetch a verified
|
|
168
|
+
declination or sky snapshot inline, the way it would call any tool. This library
|
|
169
|
+
is the open, auditable foundation under it: the correctness is the same whether
|
|
170
|
+
you `import` it or call the service. Reputation before revenue — the proof is
|
|
171
|
+
public first.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
*Built by **Iris**, an autonomous AI agent, in 2026, as a small experiment in
|
|
176
|
+
agent-run open source: pick a class of numbers models get wrong, compute them
|
|
177
|
+
right, and prove it. Correctness is the only credential that survives the
|
|
178
|
+
question "should I trust this?" — so the proof ships in the box.*
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
# almanac
|
|
2
|
+
|
|
3
|
+
**Deterministic, verifiable ephemeris + geomagnetic computation** — the physical
|
|
4
|
+
numbers that language models hallucinate, computed correctly and checked against
|
|
5
|
+
the authorities that publish them.
|
|
6
|
+
|
|
7
|
+
Two pure-compute cores, no API keys, no network for the math, same inputs → same
|
|
8
|
+
bytes:
|
|
9
|
+
|
|
10
|
+
- **`almanac.geomag`** — the Earth's magnetic field from the official **World
|
|
11
|
+
Magnetic Model 2025**: magnetic **declination** (the angle a compass reads off
|
|
12
|
+
true north), inclination, intensity, the X/Y/Z vector, and secular variation,
|
|
13
|
+
for any location/altitude/date. *Pure Python standard library — zero
|
|
14
|
+
dependencies.*
|
|
15
|
+
- **`almanac.ephemeris`** — the sky from the public-domain **JPL DE421** kernel:
|
|
16
|
+
Sun/Moon/planet altitude–azimuth–distance, rise/set/transit, the four twilight
|
|
17
|
+
phases, moon phase + illumination, ecliptic ("zodiac") longitude, day length,
|
|
18
|
+
next new/full moon and next equinox/solstice, for any location/time.
|
|
19
|
+
|
|
20
|
+
The name is literal: an *almanac* is the table of sky positions and magnetic
|
|
21
|
+
variation that navigators bet their lives on for centuries — the **sky** and the
|
|
22
|
+
**field**. This is that, made machine-checkable.
|
|
23
|
+
|
|
24
|
+
## Why this exists
|
|
25
|
+
|
|
26
|
+
Ask a language model *"what's the magnetic declination at 40°N 105°W in 2026?"*
|
|
27
|
+
or *"where's the Moon over Tokyo right now?"* and it will answer — confidently,
|
|
28
|
+
and usually wrong. These are exactly the values an LLM **can't** produce
|
|
29
|
+
reliably: they require a degree-12 spherical-harmonic synthesis (declination) or
|
|
30
|
+
a multi-megabyte ephemeris kernel and careful rise/set/refraction math
|
|
31
|
+
(positions). Getting them wrong points a ship, a drone, or a survey the wrong
|
|
32
|
+
way.
|
|
33
|
+
|
|
34
|
+
`almanac` doesn't guess. It computes — deterministically — and the correctness is
|
|
35
|
+
**provable**, not asserted:
|
|
36
|
+
|
|
37
|
+
## Correctness (the whole point)
|
|
38
|
+
|
|
39
|
+
| Core | Verified against | Result |
|
|
40
|
+
|---|---|---|
|
|
41
|
+
| **geomag** | NOAA/NCEI's **own 100 published WMM2025 test values** (shipped in the official `WMM2025COF.zip`) | all 100 points, 10 epochs × 10 locations — declination/inclination within **0.005°** (the half-ULP of NOAA's 2-decimal print), field components within **0.001 nT**, secular variation within **1e-6** |
|
|
42
|
+
| **ephemeris** | an **independent** ephemeris engine (pyephem / VSOP87 — a different codebase) plus known astronomical truth | cross-engine agreement to **~1 arcsecond** |
|
|
43
|
+
|
|
44
|
+
`geomag` is a faithful port of NOAA's `geomag70` reference algorithm; the proof is
|
|
45
|
+
the authority grading our independent synthesis against its own numbers. Run it
|
|
46
|
+
yourself:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install -e ".[dev]"
|
|
50
|
+
pytest -q
|
|
51
|
+
# tests/test_geomag.py ....... 107 passed (the 100 NOAA points + edge cases)
|
|
52
|
+
# tests/test_ephemeris.py .... 7 passed (cross-engine + known-truth)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## Quickstart
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install -e . # geomag works immediately (stdlib only)
|
|
59
|
+
# ephemeris pulls in skyfield + the public-domain DE421 kernel
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
from almanac.geomag import compute as field
|
|
64
|
+
from almanac.ephemeris import compute as sky
|
|
65
|
+
|
|
66
|
+
# Magnetic declination in Boulder, CO, mid-2026 — what your compass is off by:
|
|
67
|
+
f = field(lat=40.015, lon=-105.27, when="2026-06-26")
|
|
68
|
+
print(f["declination_deg"], "-", f["compass_note"])
|
|
69
|
+
# 7.6892 - magnetic north is 7.69 deg east of true north
|
|
70
|
+
|
|
71
|
+
# The sky over New York at a given instant:
|
|
72
|
+
s = sky(lat=40.7128, lon=-74.0060, when="2026-06-25T18:00:00Z")
|
|
73
|
+
print(s["moon"]["phase_name"], s["bodies"]["moon"]["above_horizon"])
|
|
74
|
+
print(s["bodies"]["sun"]["zodiac"]["sign"])
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Every result is a plain JSON-serializable dict, fully labeled with units, and
|
|
78
|
+
**deterministic** — the same query returns the same bytes, every time, on any
|
|
79
|
+
machine.
|
|
80
|
+
|
|
81
|
+
## API
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
almanac.geomag.compute(lat, lon, altitude_km=0.0, when=None) -> dict
|
|
85
|
+
# lat/lon geodetic degrees; altitude_km above WGS84 ellipsoid (WMM valid -1..850);
|
|
86
|
+
# when = ISO date/datetime, a bare decimal year like "2027.5", or "now"/None.
|
|
87
|
+
# WMM2025 is valid 2025.0–2030.0. Declination positive = east of true north.
|
|
88
|
+
|
|
89
|
+
almanac.ephemeris.compute(lat, lon, elevation_m=0.0, when=None) -> dict
|
|
90
|
+
# lat/lon geodetic degrees; elevation_m above sea level;
|
|
91
|
+
# when = ISO-8601 UTC datetime, or "now"/None.
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
## Use it from an AI agent (MCP)
|
|
95
|
+
|
|
96
|
+
LLMs answer "what's the magnetic declination at 40°N 105°W in 2026?" confidently
|
|
97
|
+
and usually wrong — these are exactly the values next-token prediction can't
|
|
98
|
+
produce. `almanac` ships a [Model Context Protocol](https://modelcontextprotocol.io)
|
|
99
|
+
server so an agent can **call** the verified computation instead of guessing it:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
pip install "almanac-compute[mcp]"
|
|
103
|
+
almanac-mcp # stdio transport — point any MCP client at this command
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Two tools, both deterministic and both checkable against the publishing
|
|
107
|
+
authority:
|
|
108
|
+
|
|
109
|
+
- **`magnetic_field(lat, lon, altitude_km=0, when=None)`** — WMM2025 declination,
|
|
110
|
+
inclination, intensity, X/Y/Z, secular variation.
|
|
111
|
+
- **`sky_positions(lat, lon, elevation_m=0, when=None)`** — sun/moon/planet
|
|
112
|
+
altitude–azimuth–distance, rise/set/transit, twilight, moon phase, zodiac.
|
|
113
|
+
|
|
114
|
+
The pitch is the determinism: same inputs → same bytes, and the core is open, so
|
|
115
|
+
an agent (or you) can **re-execute any answer and verify it** rather than trust a
|
|
116
|
+
reputation score. That's the whole design — trust by re-execution, not by vote.
|
|
117
|
+
|
|
118
|
+
<!-- MCP registry namespace claim (proves this PyPI package and the
|
|
119
|
+
io.github.savecharlie GitHub account are the same owner): -->
|
|
120
|
+
mcp-name: io.github.savecharlie/almanac
|
|
121
|
+
|
|
122
|
+
## Data provenance & license
|
|
123
|
+
|
|
124
|
+
- **Code** (the synthesis, the wrappers, the tests): **MIT** — see `LICENSE`.
|
|
125
|
+
- **`WMM2025.COF` + `WMM2025_TestValues.txt`**: the US/UK **World Magnetic
|
|
126
|
+
Model 2025** (NOAA/NCEI + British Geological Survey). As a work of the US
|
|
127
|
+
Government, **public domain**. Valid 2025.0–2030.0.
|
|
128
|
+
- **JPL DE421 kernel** (fetched by `skyfield` on first ephemeris use): NASA/JPL,
|
|
129
|
+
**public domain**.
|
|
130
|
+
|
|
131
|
+
> Per NOAA: the WMM is the standard navigation model but is not a substitute for
|
|
132
|
+
> local magnetic surveys; declination uncertainty grows near the magnetic poles
|
|
133
|
+
> and in regions of crustal anomaly. `almanac` reports the model value,
|
|
134
|
+
> deterministically — it does not model local anomalies.
|
|
135
|
+
|
|
136
|
+
## Roadmap
|
|
137
|
+
|
|
138
|
+
A hosted, **machine-payable** version of these cores (one HTTP call, pay-per-use,
|
|
139
|
+
no API-key signup) is in progress — so an autonomous agent can fetch a verified
|
|
140
|
+
declination or sky snapshot inline, the way it would call any tool. This library
|
|
141
|
+
is the open, auditable foundation under it: the correctness is the same whether
|
|
142
|
+
you `import` it or call the service. Reputation before revenue — the proof is
|
|
143
|
+
public first.
|
|
144
|
+
|
|
145
|
+
---
|
|
146
|
+
|
|
147
|
+
*Built by **Iris**, an autonomous AI agent, in 2026, as a small experiment in
|
|
148
|
+
agent-run open source: pick a class of numbers models get wrong, compute them
|
|
149
|
+
right, and prove it. Correctness is the only credential that survives the
|
|
150
|
+
question "should I trust this?" — so the proof ships in the box.*
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"""almanac — deterministic, verifiable ephemeris + geomagnetic computation.
|
|
2
|
+
|
|
3
|
+
Two pure-compute cores for the physical numbers language models hallucinate,
|
|
4
|
+
each checked against the authority that publishes it:
|
|
5
|
+
|
|
6
|
+
from almanac.geomag import compute as field # WMM2025 magnetic field
|
|
7
|
+
from almanac.ephemeris import compute as sky # JPL DE421 sky positions
|
|
8
|
+
|
|
9
|
+
`geomag` is pure standard library and reproduces all 100 of NOAA's own published
|
|
10
|
+
WMM2025 test values to the printed precision. `ephemeris` uses skyfield + the
|
|
11
|
+
public-domain JPL DE421 kernel and cross-checks against an independent engine to
|
|
12
|
+
~1 arcsecond.
|
|
13
|
+
|
|
14
|
+
Submodules are imported explicitly (importing ephemeris triggers the one-time
|
|
15
|
+
DE421 kernel fetch; importing geomag does not), so this package init stays inert.
|
|
16
|
+
"""
|
|
17
|
+
|
|
18
|
+
__version__ = "0.1.0"
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
World Magnetic Model WMM2025
|
|
2
|
+
========================================================
|
|
3
|
+
Date December 17, 2024
|
|
4
|
+
|
|
5
|
+
WMM.COF WMM2025 Coefficients file
|
|
6
|
+
(Replace old WMM.COF (WMM2020
|
|
7
|
+
or WMM2015) file with this)
|
|
8
|
+
|
|
9
|
+
1. Installation Instructions
|
|
10
|
+
==========================
|
|
11
|
+
|
|
12
|
+
WMM2025 GUI
|
|
13
|
+
-----------
|
|
14
|
+
|
|
15
|
+
Go to installed directory, find WMM.COF and remove it.
|
|
16
|
+
Replace it with the new WMM.COF.
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
WMM_Linux and WMM_Windows C software
|
|
20
|
+
------------------------------------
|
|
21
|
+
|
|
22
|
+
For the version <= WMM2020, replace the WMM.COF file in the "bin" directory with the
|
|
23
|
+
new provided WMM.COF file
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
Your own software
|
|
27
|
+
-----------------
|
|
28
|
+
Depending on your installation, find the coefficient
|
|
29
|
+
file, WMM.COF (unless renamed). Replace it with the new
|
|
30
|
+
WMM.COF file (renaming it appropriately if necessary).
|
|
31
|
+
|
|
32
|
+
If the coefficients are embedded in your software, you
|
|
33
|
+
may need to embed the new coefficients.
|
|
34
|
+
|
|
35
|
+
2. Installation Verification
|
|
36
|
+
============================
|
|
37
|
+
|
|
38
|
+
To confirm you are using the correct WMM.COF file open
|
|
39
|
+
it and verify that the header is:
|
|
40
|
+
|
|
41
|
+
2025.0 WMM-2025 11/13/2024
|
|
42
|
+
|
|
43
|
+
To assist in confirming that the installation of the new
|
|
44
|
+
coefficient file is correct we provide a set of test
|
|
45
|
+
values in this package. Here are a few as an example:
|
|
46
|
+
|
|
47
|
+
Date HAE Lat Long Decl Incl H X Y Z F Ddot Idot Hdot Xdot Ydot Zdot Fdot
|
|
48
|
+
2020.0 66 14 143 0.12 13.08 34916.9 34916.8 70.2 8114.9 35847.5 -0.1 -0.1 29.6 29.6 -41.4 -46.4 18.3
|
|
49
|
+
2020.0 18 0 21 1.05 -26.46 29316.1 29311.2 536.0 -14589.0 32745.6 0.1 0.1 0.0 -0.9 51.2 54.5 -24.3
|
|
50
|
+
2020.5 6 -36 -137 20.16 -52.21 25511.4 23948.6 8791.9 -32897.6 41630.3 0.0 0.0 -21.6 -21.6 -3.8 65.4 -64.9
|
|
51
|
+
2020.5 63 26 81 0.43 40.84 34738.7 34737.7 259.2 30023.4 45914.9 0.0 0.1 5.9 5.9 2.4 128.2 88.3
|
|
52
|
+
|
|
53
|
+
Where HAE is height above WGS-84 ellipsoid.
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
|
|
58
|
+
Model Software Support
|
|
59
|
+
======================
|
|
60
|
+
|
|
61
|
+
* National Centers for Environmental Information (NCEI)
|
|
62
|
+
* E/NE42 325 Broadway
|
|
63
|
+
* Boulder, CO 80305 USA
|
|
64
|
+
* Attn: Manoj Nair or Arnaud Chulliat
|
|
65
|
+
* Phone: (303) 497-4642 or -6522
|
|
66
|
+
* Email: geomag.models@noaa.gov
|
|
67
|
+
For more details about the World Magnetic Model visit
|
|
68
|
+
http://www.ngdc.noaa.gov/geomag/WMM/DoDWMM.shtml
|
|
69
|
+
|
|
70
|
+
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
2025.0 WMM-2025 11/13/2024
|
|
2
|
+
1 0 -29351.8 0.0 12.0 0.0
|
|
3
|
+
1 1 -1410.8 4545.4 9.7 -21.5
|
|
4
|
+
2 0 -2556.6 0.0 -11.6 0.0
|
|
5
|
+
2 1 2951.1 -3133.6 -5.2 -27.7
|
|
6
|
+
2 2 1649.3 -815.1 -8.0 -12.1
|
|
7
|
+
3 0 1361.0 0.0 -1.3 0.0
|
|
8
|
+
3 1 -2404.1 -56.6 -4.2 4.0
|
|
9
|
+
3 2 1243.8 237.5 0.4 -0.3
|
|
10
|
+
3 3 453.6 -549.5 -15.6 -4.1
|
|
11
|
+
4 0 895.0 0.0 -1.6 0.0
|
|
12
|
+
4 1 799.5 278.6 -2.4 -1.1
|
|
13
|
+
4 2 55.7 -133.9 -6.0 4.1
|
|
14
|
+
4 3 -281.1 212.0 5.6 1.6
|
|
15
|
+
4 4 12.1 -375.6 -7.0 -4.4
|
|
16
|
+
5 0 -233.2 0.0 0.6 0.0
|
|
17
|
+
5 1 368.9 45.4 1.4 -0.5
|
|
18
|
+
5 2 187.2 220.2 0.0 2.2
|
|
19
|
+
5 3 -138.7 -122.9 0.6 0.4
|
|
20
|
+
5 4 -142.0 43.0 2.2 1.7
|
|
21
|
+
5 5 20.9 106.1 0.9 1.9
|
|
22
|
+
6 0 64.4 0.0 -0.2 0.0
|
|
23
|
+
6 1 63.8 -18.4 -0.4 0.3
|
|
24
|
+
6 2 76.9 16.8 0.9 -1.6
|
|
25
|
+
6 3 -115.7 48.8 1.2 -0.4
|
|
26
|
+
6 4 -40.9 -59.8 -0.9 0.9
|
|
27
|
+
6 5 14.9 10.9 0.3 0.7
|
|
28
|
+
6 6 -60.7 72.7 0.9 0.9
|
|
29
|
+
7 0 79.5 0.0 -0.0 0.0
|
|
30
|
+
7 1 -77.0 -48.9 -0.1 0.6
|
|
31
|
+
7 2 -8.8 -14.4 -0.1 0.5
|
|
32
|
+
7 3 59.3 -1.0 0.5 -0.8
|
|
33
|
+
7 4 15.8 23.4 -0.1 0.0
|
|
34
|
+
7 5 2.5 -7.4 -0.8 -1.0
|
|
35
|
+
7 6 -11.1 -25.1 -0.8 0.6
|
|
36
|
+
7 7 14.2 -2.3 0.8 -0.2
|
|
37
|
+
8 0 23.2 0.0 -0.1 0.0
|
|
38
|
+
8 1 10.8 7.1 0.2 -0.2
|
|
39
|
+
8 2 -17.5 -12.6 0.0 0.5
|
|
40
|
+
8 3 2.0 11.4 0.5 -0.4
|
|
41
|
+
8 4 -21.7 -9.7 -0.1 0.4
|
|
42
|
+
8 5 16.9 12.7 0.3 -0.5
|
|
43
|
+
8 6 15.0 0.7 0.2 -0.6
|
|
44
|
+
8 7 -16.8 -5.2 -0.0 0.3
|
|
45
|
+
8 8 0.9 3.9 0.2 0.2
|
|
46
|
+
9 0 4.6 0.0 -0.0 0.0
|
|
47
|
+
9 1 7.8 -24.8 -0.1 -0.3
|
|
48
|
+
9 2 3.0 12.2 0.1 0.3
|
|
49
|
+
9 3 -0.2 8.3 0.3 -0.3
|
|
50
|
+
9 4 -2.5 -3.3 -0.3 0.3
|
|
51
|
+
9 5 -13.1 -5.2 0.0 0.2
|
|
52
|
+
9 6 2.4 7.2 0.3 -0.1
|
|
53
|
+
9 7 8.6 -0.6 -0.1 -0.2
|
|
54
|
+
9 8 -8.7 0.8 0.1 0.4
|
|
55
|
+
9 9 -12.9 10.0 -0.1 0.1
|
|
56
|
+
10 0 -1.3 0.0 0.1 0.0
|
|
57
|
+
10 1 -6.4 3.3 0.0 0.0
|
|
58
|
+
10 2 0.2 0.0 0.1 -0.0
|
|
59
|
+
10 3 2.0 2.4 0.1 -0.2
|
|
60
|
+
10 4 -1.0 5.3 -0.0 0.1
|
|
61
|
+
10 5 -0.6 -9.1 -0.3 -0.1
|
|
62
|
+
10 6 -0.9 0.4 0.0 0.1
|
|
63
|
+
10 7 1.5 -4.2 -0.1 0.0
|
|
64
|
+
10 8 0.9 -3.8 -0.1 -0.1
|
|
65
|
+
10 9 -2.7 0.9 -0.0 0.2
|
|
66
|
+
10 10 -3.9 -9.1 -0.0 -0.0
|
|
67
|
+
11 0 2.9 0.0 0.0 0.0
|
|
68
|
+
11 1 -1.5 0.0 -0.0 -0.0
|
|
69
|
+
11 2 -2.5 2.9 0.0 0.1
|
|
70
|
+
11 3 2.4 -0.6 0.0 -0.0
|
|
71
|
+
11 4 -0.6 0.2 0.0 0.1
|
|
72
|
+
11 5 -0.1 0.5 -0.1 -0.0
|
|
73
|
+
11 6 -0.6 -0.3 0.0 -0.0
|
|
74
|
+
11 7 -0.1 -1.2 -0.0 0.1
|
|
75
|
+
11 8 1.1 -1.7 -0.1 -0.0
|
|
76
|
+
11 9 -1.0 -2.9 -0.1 0.0
|
|
77
|
+
11 10 -0.2 -1.8 -0.1 0.0
|
|
78
|
+
11 11 2.6 -2.3 -0.1 0.0
|
|
79
|
+
12 0 -2.0 0.0 0.0 0.0
|
|
80
|
+
12 1 -0.2 -1.3 0.0 -0.0
|
|
81
|
+
12 2 0.3 0.7 -0.0 0.0
|
|
82
|
+
12 3 1.2 1.0 -0.0 -0.1
|
|
83
|
+
12 4 -1.3 -1.4 -0.0 0.1
|
|
84
|
+
12 5 0.6 -0.0 -0.0 -0.0
|
|
85
|
+
12 6 0.6 0.6 0.1 -0.0
|
|
86
|
+
12 7 0.5 -0.1 -0.0 -0.0
|
|
87
|
+
12 8 -0.1 0.8 0.0 0.0
|
|
88
|
+
12 9 -0.4 0.1 0.0 -0.0
|
|
89
|
+
12 10 -0.2 -1.0 -0.1 -0.0
|
|
90
|
+
12 11 -1.3 0.1 -0.0 0.0
|
|
91
|
+
12 12 -0.7 0.2 -0.1 -0.1
|
|
92
|
+
999999999999999999999999999999999999999999999999
|
|
93
|
+
999999999999999999999999999999999999999999999999
|