The one-call Study
LunarTrace 0.2 puts the temporal method behind one call. You name a site, an event interval and a product type. You get back a Study: the observations before and after the event, every PRE × POST pair, the pairs that no other pair beats, and a digest that proves none of it moved.
import lunartrace as lt
study = lt.temporal.study(site=(-69.3741, 32.32), event="2023-08-23T12:33Z/12:35Z", products="LRO/LROC/CDRNAC4", archive="vikram-2026-10-14")study.frontier("angles") # the 13 pairs nothing beatsstudy.why("pair:002ea7a82e1060f1") # names the pair that beat itstudy.save("vikram.study.json") # replays to the same sha256archive="vikram-2026-10-14" replays the archived pages of the 14 October 2026 run. Those
pages ship inside the package, so the call needs no network and returns the same Study every
time. A live call, with archive left out, fetches the Lunar ODE archive now. The archive
grows, so it can return more products than the 108 of that run, and a different digest.
The call is a facade over the method lunartrace.temporal_prepost/v1. It does not add a method
and it does not add a field to the Study record. Everything on this page is a view over that
record.
Run it
Section titled “Run it”Install LunarTrace 0.2 with pip install lunartrace (Install). The call below is the one above, as a session you can paste. The
repr says retained: the Study was compiled from the pages of the 14 October 2026 run.
>>> import lunartrace as lt>>> study = lt.temporal.study(site=(-69.3741, 32.32),... event="2023-08-23T12:33Z/12:35Z",... products="LRO/LROC/CDRNAC4",... archive="vikram-2026-10-14")>>> studyStudy(vikram:minute-envelope · retained · sha256:3d75a662… · 108 products · 2,340 pairs)>>> study.digest'sha256:3d75a662ce75f00cd34dd9ba288012ad471c73b1e56ecf0abe36896d0b199dd0'Each example on these pages is self-contained: copy one into a fresh session and it runs. A
live run says live in its repr and is never claimed to reproduce those numbers.
The frontier, and why a pair is not on it
Section titled “The frontier, and why a pair is not on it”A frontier is the set of pairs that no other pair beats on every objective. No weights are
chosen. The angles frontier minimises the three angle differences and holds 13 of the 2,340
pairs.
>>> import lunartrace as lt>>> study = lt.temporal.study(site="vikram", event="vikram:minute-envelope",... products="LRO/LROC/CDRNAC4", archive="vikram-2026-10-14")>>> len(study.frontier("angles"))13>>> print(study.why("pair:002ea7a82e1060f1"))pair:002ea7a82e1060f1 is off the angles frontier: pair:0033128b0d75e56c is at least as good on every angle (Δsun 2.78° vs 6.79°, Δview 0.29° vs 0.83°, Δphase 2.67° vs 3.14°) and strictly better on one.>>> print(study.why("pair:1ca27f6bd456b92d"))pair:1ca27f6bd456b92d is on the angles frontier: no pair beats it.Save it
Section titled “Save it”The file holds the canonical bytes of the record. Loading it checks the digest again.
>>> import lunartrace as lt>>> study = lt.temporal.study(site="vikram", event="vikram:minute-envelope",... products="LRO/LROC/CDRNAC4", archive="vikram-2026-10-14")>>> study.save("vikram.study.json").name'vikram.study.json'>>> lt.temporal.load("vikram.study.json").digest == study.digestTrueWhere to go next
Section titled “Where to go next”| Page | What it covers |
|---|---|
| Study | The arguments, the registry, live against retained |
| Frontiers and why | The four frontiers and the witness behind each answer |
| Save and replay | The file, the sources bundle, verify and replay |
| Notebook | Open a saved Study as a marimo notebook |
| Command line | The same operations as the lunartrace console script |
| Reference | Every public name |
What this does not claim
Section titled “What this does not claim”The Study’s four limits are in the file, word for word. study.limits returns them:
>>> import lunartrace as lt>>> study = lt.temporal.study(site="vikram", event="vikram:minute-envelope",... products="LRO/LROC/CDRNAC4", archive="vikram-2026-10-14")>>> for limit in study.limits:... print(limit)Temporal PRE/POST adjacency is not a surface-change claim.Footprint intersection with the query box is not image registration or alignment.ODE pagination reconciles the declared Count at query time; archive currentness and a coherent provider snapshot are not established.Source authenticity is not independently established beyond retained byte digests.The Study is recorded as METHOD_EXECUTED. See Limitations
for what each limit rules out.