Pipeline Concepts#
The pyCSAMT pipeline system is a reproducible processing engine for MT, AMT, and CSAMT site collections. A pipeline is an ordered list of registered processing steps. Each step receives the current site collection, transforms it or inspects it, and passes the result to the next step.
At the end of a run, pyCSAMT returns a pycsamt.pipeline.PipelineResult
and, when an output directory is enabled, writes a reproducible directory
containing processed EDI files, QC figures, reports, and the exact pipeline
YAML used for the run.
Why Pipelines Exist#
Field data processing often grows from a notebook into a sequence of repeated operations: remove power-line harmonics, drop duplicate frequencies, trim to a band, align stations onto a common frequency grid, correct static shift, make quality-control plots, and prepare the data for inversion.
Pipelines make that sequence explicit. They help you:
repeat the same workflow across multiple survey lines;
save the processing recipe alongside the outputs;
inspect which step changed the data;
run the same workflow from Python and the CLI;
generate reports and QC figures in a predictable directory tree;
share processing decisions with collaborators.
Core Objects#
The pipeline package is exposed through pycsamt.pipeline. Users should
normally import from this public namespace:
1from pycsamt.pipeline import Pipeline, Step
The main objects are:
Object |
Role |
|---|---|
Ordered sequence of |
|
Configured wrapper around one registered processing operation. It
binds a registry code such as |
|
|
Registry descriptor for a step: code, registry name, category, function path, default parameters, QC plot functions, and whether the step transforms the site collection. |
|
Named, ordered collection of steps for common workflows such as
|
One per executed step. Records timing, input/output station count, saved plot paths, parameters, and any stored exception. |
|
Returned by |
The Mental Model#
A pipeline run is a left-to-right data flow:
1input Sites
2 |
3 v
4Step 1: transform or inspect
5 |
6 v
7Step 2: transform or inspect
8 |
9 v
10...
11 |
12 v
13final Sites + PipelineResult + optional files
Most steps transform the site collection and return a new or modified collection. Diagnostic-only steps run a function for side effects or checks and pass the input collection through unchanged.
Step Registry#
Pipeline steps are not arbitrary strings. They are registered in the pipeline step registry. Each registered step has:
a short code, for example
NR001;a registry name, for example
notch_powerline;a category, for example
noise_removalorfrequency;default parameters;
a transform function;
optional QC plot functions;
a
returns_sitesflag.
The code and registry name both identify the same step:
1from pycsamt.pipeline import Step
2
3notch_by_code = Step("NR001", mains_hz=50.0)
4notch_by_name = Step("notch_powerline", mains_hz=50.0)
Use the code form in pipeline configuration files and reports. Use the registry name when it improves readability in exploratory Python code.
Discover available steps from Python:
1from pycsamt.pipeline import Pipeline
2
3print(Pipeline.catalogue())
4print(Pipeline.catalogue("frequency"))
5print(Pipeline.step_info("NR001"))
Discover the same information from the CLI:
1pycsamt pipe steps
2pycsamt pipe steps --category frequency
3pycsamt pipe steps --info NR001
Configured Steps#
A pycsamt.pipeline.Step combines a registry entry with user parameter
overrides. The registry defaults are merged with your overrides.
1from pycsamt.pipeline import Step
2
3# Uses registry defaults except mains_hz.
4step = Step("NR001", mains_hz=60.0)
5print(step)
If the registry default for NR001 includes n_harm and tol_hz, the
configured step still carries those defaults. You only need to provide the
values that should change for the workflow.
Pipeline Structure#
A pipeline stores steps as (label, Step) tuples. The label is the name of
this occurrence in this workflow. It appears in printed summaries, output
subdirectories, reports, and CLI slicing options.
1from pycsamt.pipeline import Pipeline, Step
2
3pipe = Pipeline(
4 [
5 ("notch", Step("NR001", mains_hz=50.0)),
6 ("select_band", Step("FREQ001", band_hz=(0.001, 10000.0))),
7 ("align_grid", Step("FREQ004")),
8 ("qc_snapshot", Step("QC001")),
9 ],
10 name="first_qc",
11)
12
13print(pipe)
Labels should be short, stable, and meaningful. Prefer select_amt_band or
correct_ss over vague labels such as step1.
Building A Pipeline#
There are four common ways to build a pipeline.
Build directly in Python:
1from pycsamt.pipeline import Pipeline, Step
2
3pipe = Pipeline([
4 ("notch", Step("NR001")),
5 ("drop_duplicates", Step("FREQ002")),
6 ("select_band", Step("FREQ001")),
7 ("qc_snapshot", Step("QC001")),
8])
Build from a preset:
1from pycsamt.pipeline import Pipeline
2
3pipe = Pipeline.from_preset("basic_qc")
Build from a config file:
1from pycsamt.pipeline import Pipeline
2
3pipe = Pipeline.from_yaml("config/basic_qc.yaml")
4pipe = Pipeline.from_json("config/basic_qc.json")
5pipe = Pipeline.from_py("config/basic_qc.py")
Build from the CLI:
1pycsamt pipe run data/edis --preset basic_qc
2pycsamt pipe run data/edis --config config/basic_qc.yaml
3pycsamt pipe run data/edis --steps NR001,FREQ002,FREQ001,QC001
Configuration files are documented in Pipeline Configuration Files.
Presets#
Presets are named pipelines for common processing intentions. They are useful when you want a known baseline without writing every step manually.
Examples include:
basic_qcMinimal denoising and frequency cleanup. Good for first-pass inspection.
noise_reductionStacked noise-removal chain for high-EMI environments.
full_processingStandard chain for noise removal, frequency cleanup, skew gate, static-shift correction, and strike rotation.
publication_readyA longer chain for publication-quality outputs.
Use a preset directly:
1from pycsamt.pipeline import Pipeline
2
3pipe = Pipeline.from_preset("publication_ready")
Or generate an editable config from a preset:
1pycsamt pipe init --preset publication_ready \
2 --name line22_publication \
3 --output config/line22_publication.yaml
See Pipeline Presets for the dedicated preset guide.
Mutable Until Run#
A pipeline can be edited before it starts running:
1from pycsamt.pipeline import Pipeline, Step
2
3pipe = Pipeline.from_preset("full_processing")
4pipe.remove("mask_skew")
5pipe.append("final_qc", Step("QC001"))
6pipe.replace("notch", Step("NR001", mains_hz=60.0))
During Pipeline.run, the step list is protected from mutation. This
prevents accidental changes while step results and reports are being produced.
Run Lifecycle#
Calling Pipeline.run performs these operations in order:
Resolve the runtime configuration.
Resolve the output directory.
Save a canonical
pipeline.yamlsnapshot when output is enabled.For each configured step:
count input sites;
run the step transform;
handle errors according to
on_step_error;generate and save QC plots when enabled;
optionally save intermediate EDI snapshots;
create a
pycsamt.pipeline.StepResult.
Write final processed EDI files when
save_edis=True.Write HTML and/or text reports when
save_report=True.Return a
pycsamt.pipeline.PipelineResult.
Example:
1from pycsamt.api import read_edis
2from pycsamt.pipeline import Pipeline
3
4survey = read_edis("data/edis", strict=False)
5pipe = Pipeline.from_preset("basic_qc")
6
7result = pipe.run(
8 survey.to_collection(),
9 outdir="results/basic_qc",
10 save_plots=True,
11 save_edis=True,
12 save_report=True,
13)
14
15print(result.summary())
Output Resolution#
The output directory is resolved in this order:
explicit
outdirpassed toPipeline.run;output_dirstored on a pipeline loaded from a config file;global
PYCSAMT_PIPE.output_root.
Passing outdir=None is an explicit opt-out: the pipeline runs in memory
and writes no output files.
1# Write to the config/default output directory.
2result = pipe.run(sites)
3
4# Override output directory for this run.
5result = pipe.run(sites, outdir="results/experiment_01")
6
7# In-memory run: no files are written.
8result = pipe.run(sites, outdir=None)
Output Directory Contract#
When output is enabled, pyCSAMT writes a predictable run directory:
1results/basic_qc/
2|-- processed/
3| `-- *.edi
4|-- plots/
5| |-- 01_notch/
6| |-- 02_drop_duplicates/
7| `-- ...
8|-- pipeline.yaml
9|-- report.html
10`-- summary.txt
pipeline.yamlReproducible snapshot of the exact pipeline that was run.
processed/Final processed EDI files when
save_edis=True.plots/QC figures generated after individual steps when
save_plots=True.report.htmlandsummary.txtRun reports when
save_report=Trueand the corresponding report formats are enabled.
The output-directory details are documented in Pipeline Outputs.
Error Handling#
Pipeline error behavior is controlled by PYCSAMT_PIPE.on_step_error or by
the CLI --on-error option.
"raise"Re-raise the step exception immediately and stop the run.
"warn"Store the exception in the step result, warn, continue with the previous site collection, and mark the final
PipelineResultas not OK."skip"Store the exception and continue silently with the previous site collection.
Use "raise" during debugging and strict production validation. Use
"warn" for exploratory processing when you want a full report showing
which steps failed.
Runtime Configuration#
Pipeline runtime defaults live in pycsamt.pipeline.PYCSAMT_PIPE.
Configure them globally:
1from pycsamt.pipeline import configure_pipe
2
3configure_pipe(
4 output_root="results",
5 on_step_error="warn",
6 plot_dpi=200,
7 plot_fmt="png",
8 show_progress=True,
9)
Or temporarily with a context manager:
1from pycsamt.pipeline import PYCSAMT_PIPE
2
3with PYCSAMT_PIPE.context(plot_dpi=300, plot_fmt="pdf"):
4 result = pipe.run(sites, outdir="results/high_resolution")
Important runtime settings include:
Setting |
Meaning |
|---|---|
|
Default output root when no explicit run output is provided. |
|
Name of the subdirectory for processed EDI files. |
|
Name of the subdirectory for QC figures. |
|
|
|
Whether to write EDI snapshots after each successful step. |
|
Whether to print progress while running. |
|
Saved figure resolution and format. |
|
Report types to write, usually |
PipelineResult#
Pipeline.run returns a pycsamt.pipeline.PipelineResult. Use it as
the programmatic summary of the run:
1result = pipe.run(sites, outdir="results/basic_qc")
2
3print(result.ok)
4print(result.n_errors)
5print(result.plots)
6print(result.processed_paths)
7print(result.summary())
result.sites_inOriginal site collection passed to
Pipeline.run.result.sites_outFinal site collection after all steps.
result.step_resultsOrdered list of step records.
result.plotsAll saved plot paths across every step.
result.processed_pathsWritten processed EDI files.
result.okTruewhen every step completed without error.
StepResult#
Each pycsamt.pipeline.StepResult records what happened during one
step:
1for step_result in result.step_results:
2 print(step_result.summary_line())
3 if not step_result.ok:
4 print(step_result.error)
Useful fields include step_idx, step_name, step_code,
step_label, params, elapsed_sec, plots, n_sites_in,
n_sites_out, and error.
CLI And Python Equivalence#
The CLI and Python API use the same pipeline engine.
This Python call:
1from pycsamt.api import read_edis
2from pycsamt.pipeline import Pipeline
3
4survey = read_edis("data/edis")
5pipe = Pipeline.from_yaml("config/basic_qc.yaml")
6result = pipe.run(survey.to_collection(), outdir="results/basic_qc")
is conceptually equivalent to:
1pycsamt pipe run data/edis \
2 --config config/basic_qc.yaml \
3 --out results/basic_qc
Use Python when the pipeline is part of a larger analysis script. Use the CLI when the workflow should be easy to repeat from a terminal, automation script, or processing log.
How Concepts Connect#
The pipeline documentation is organized around these ideas:
Pipeline Configuration Files explains how to store pipelines as YAML, JSON, or Python files.
Pipeline Presets explains built-in workflows and when to start from each one.
Pipeline Steps explains registered operations and extension patterns.
Pipeline Outputs explains the generated files and reports.
Pipeline CLI explains the
pycsamt pipecommand group.
In Short#
A pyCSAMT pipeline is a reproducible chain of registered steps:
1from pycsamt.pipeline import Pipeline, Step
2
3pipe = Pipeline([
4 ("notch", Step("NR001")),
5 ("band", Step("FREQ001")),
6 ("qc", Step("QC001")),
7])
8
9result = pipe.run(sites, outdir="results/basic_qc")
The key ideas are simple: registered step codes define what can run, labels
define how a workflow is reported, configs define reproducibility, runtime
settings define output/error behavior, and PipelineResult records what
happened.