Skip to content

Batch Pipelines

Use Pipeline to retrieve and decode days to months of data and save it to the Store as daily Parquet shards. For a single day in a notebook, load() and write_parquet() are enough (Working With Arrays).

Supported sources

Only KAGUYA PACE (esa1, esa2, ima, iea) currently has a Pipeline execution backend. Calling run(), scan(), or stream() on endpoints without one, such as LRS, raises PipelineError.

Arrange stages

A Pipeline is created from an endpoint's pipeline(time); add stages and execute with run() at the end. Adding stages runs nothing.

time = spn.period("2008-01-01", "2008-01-04")

pipe = (
    spn.kaguya.esa1.energy_flux.pipeline(time)
    .calibrate(calibration="auto")
    .quicklook("esa1_energy_flux")
    .write("kaguya.esa1.energy_flux", layer="normalized", partition="day")
)
Stage Meaning
download(), decode(), normalize() Make source retrieval, decoding, and normalization explicit
calibrate(...) Apply calibration (PACE energy_flux)
select_variables(...) Choose several variables of an instrument (when built from the instrument's pipeline())
quicklook(name, ...) After saving, write PNG and JSON to the dataset's preview/
write(dataset_id, layer=..., partition="day") Set the output; partition="day" writes daily shards
from_normalized() Read a dataset already saved in the Store instead of source files

Check before running

pipe.plan()                    # inputs, stages, output
result = pipe.run(dry_run=True)
print(result)                  # same result format, nothing executed

Run

result = pipe.run()
result.to_dict()               # status, run ID, output dataset, log path

To protect existing datasets, a run stops by default if the output already exists.

Argument Behavior
mode="create" (default) Stop if the output exists
mode="append" Add shards
mode="replace" Replace; not supported with PACE daily shards
resume=True Reuse completed ranges; do nothing if the whole range is complete
only_failed=True Rebuild only failed shards
on_error="continue" Continue after a shard fails and record it as failed (default "fail" stops)
download="never" Change the download policy for this run only

Every run gets a run ID, and the dataset's logs/<run_id>.json records start and end times, row counts, and shard counts per stage. The manifest's provenance also holds the stage list, time range, download policy, and run ID.

Read saved data

lazy = spn.kaguya.esa1.counts.pipeline(time).from_normalized().scan()      # Polars LazyFrame
frame = spn.kaguya.esa1.counts.pipeline(time).from_normalized().collect()

for day_frame in pipe.stream(partition="day"):
    process(day_frame)

stream supports "all" and "day", and for PACE also "shard" for each saved shard.

Heavy full-period computations

Heavy processing over the full mission, such as model fits, uses separate CLIs designed around daily shards, resuming, and parallel runs. See ER Full-Period Batch for an example. Adding Pipeline support to a new data source is described in Adding A Data Source.