Time, Regions, And Cases¶
This page specifies time ranges and regions, the View that binds them, the Project workspace, and named Case conditions.
For the workflow first, read Reproducible Analysis.
Time ranges are half-open¶
A SOPRAN time range (TimeRange) includes its start and excludes its stop, so that concatenating daily shards
never counts a boundary sample twice.
spn.period("2008-02-01T03:00", "2008-02-01T04:00")
spn.day("2008-02-01") # 2008-02-01 00:00 up to 2008-02-02 00:00
spn.month("2008-02")
spn.year("2008")
ISO 8601 strings and datetime objects are accepted. Times without a time zone are UTC.
A TimeRange has start and stop (UTC datetime) and the strings start_iso and stop_iso.
Regions carry their longitude convention¶
region = spn.Region(lon=(350, 10), lat=(-5, 5), body="moon")
region.crosses_lon_boundary # True (crosses 0/360)
region.contains(355, 0) # True
region.to_lon_domain("-180_180") # the same Region with longitudes in -180..180
Longitudes default to east-positive 0–360, latitudes to planetocentric. Change them with lon_domain, lon_direction, and lat_type.
How Moon maps use these conventions is in Moon Maps.
View¶
A View is an immutable bundle of period, region, and processing conditions.
view = spn.view(
time=spn.day("2008-02-01"),
region=spn.Region(lon=(120, 160), lat=(-45, -10), body="moon"),
frame="SSE",
download="never",
)
| Kind | Argument | Effect |
|---|---|---|
| Selection | time (or start and stop) |
Default time range of endpoints |
| Selection | region |
Default region of Moon maps |
| Selection | mission, instrument, product, quality |
Recorded as analysis conditions |
| Processing | download |
Download policy of the missions |
| Processing | spice_kernels, time_scale, backend |
Used by the FrameContext from view.frame_context() |
| Processing | frame, cache |
Recorded as analysis conditions |
view.kaguya, view.artemis, view.omni, and view.moon are real spn.Kaguya (and so on) objects.
Methods use view.time when the time is omitted. Registered sources are also available as view.source("kaguya").
Create a new View to change conditions.
view.with_time("2008-02-01T03:00", "2008-02-01T04:00")
view.with_region(None)
view.with_context(frame="GSE", download="missing")
spn.view(...) uses the first sopran.toml found from the current directory upward as the Project settings.
The short entry points such as spn.kaguya do the same.
Project¶
A Project is the working directory of an analysis topic.
project = spn.Project("projects/lunar_wake")
project = spn.Project("projects/lunar_wake", store=spn.Store("/path/to/sopran_data"))
| Item | Meaning |
|---|---|
project.root |
Working directory that holds sopran.toml |
project.store |
Store in use; when omitted, resolved as in Configuration |
project.artifact_root |
Where project.save() writes |
project.view(...) |
A View with this Project's defaults |
project.kaguya etc. |
Mission objects without a time range |
Case¶
A Case is a named set of analysis conditions saved in sopran.toml.
[defaults]
frame = "SSE"
[defaults.region] # default for Cases without a region
body = "moon"
lon = [120, 160]
lat = [-45, -10]
[cases.wake_20080201]
start = "2008-02-01T00:00:00"
stop = "2008-02-02T00:00:00"
[cases.wake_20080201.context] # frame, cache, download, quality, time_scale
download = "never"
[cases.wake_20080201.region]
body = "moon"
lon = [130, 150]
lat = [-30, -20]
case = project.case("wake_20080201")
case.kaguya.esa1.counts.load()
case.with_time("2008-02-01T03:00", "2008-02-01T04:00") # returns a View
case.view # a View with the Case's conditions
Each key resolves from the Case value, then the session settings, then the Project's [defaults], then the user settings.
download is the exception: session settings and environment variables (such as SOPRAN_OFFLINE) outrank the Case value (Configuration).
project.case(name, start=..., stop=...) creates a Case on the spot without writing to sopran.toml.
project.save_case(name, view) appends the view's period, region, and processing conditions to sopran.toml
and writes the same content to cases/<name>.json. It stops if the Case exists. Overwriting is not implemented,
so edit sopran.toml to change a saved Case.
Recording provenance¶
context= is the common argument that writes analysis conditions into figures, artifacts, and datasets.
| Call | Recorded in |
|---|---|
plot(..., context=case), quicklook(..., context=case) |
Figure JSON |
project.save(array, "interim/name", context=case) |
NetCDF and a JSON with the same name |
write_parquet(..., context=case), write_dataset(..., context=case) |
Store manifest |
context accepts a Case, a View, an object with metadata() or to_metadata(), or a JSON-ready dict.
A Case contributes its name, Project location, Store location, time range, region, and defaults.
project.save(value, name) writes anything with to_xarray() as NetCDF under artifact_root
and records the time range, sources, and relative path in JSON. The Project holds temporary outputs;
data reused across analyses belongs in the Store.