Source code for pycsamt.api.pipe.config
"""Global pipeline configuration for pyCSAMT.
Centralises all output, display, and execution settings used by
:mod:`pycsamt.pipeline`. Follows the same singleton + configure/reset
pattern as the rest of :mod:`pycsamt.api`.
Examples
--------
Override output format temporarily::
from pycsamt.api.pipe import PYCSAMT_PIPE
with PYCSAMT_PIPE.context(plot_dpi=300, plot_fmt="pdf"):
result = pipeline.run(sites)
Change global defaults::
from pycsamt.api.pipe import configure_pipe
configure_pipe(output_root="my_project/results", show_progress=False)
"""
from __future__ import annotations
import copy
from collections.abc import Generator
from contextlib import contextmanager
from dataclasses import dataclass, field, fields
from typing import Any
_ON_STEP_ERROR = {"raise", "warn", "skip"}
_PROGRESS_STYLES = {"bar", "log", "silent"}
_REPORT_FORMATS = {"html", "txt"}
[docs]
@dataclass
class PipelineAPIConfig:
"""Runtime configuration for the pyCSAMT pipeline engine.
Attributes
----------
output_root:
Default root directory when no *outdir* is passed to
:meth:`~pycsamt.pipeline.Pipeline.run`.
processed_subdir:
Sub-directory inside *output_root* that receives the processed EDI
files.
plots_subdir:
Sub-directory inside *output_root* that receives all QC figures,
organised into one sub-folder per pipeline step.
on_step_error:
Behaviour when a step raises an exception. ``"raise"`` re-raises
immediately; ``"warn"`` logs a warning and continues with the
previous sites; ``"skip"`` is silent.
save_intermediate:
If ``True``, EDI files are also written after each step (into
``plots_subdir/<step>/edi_snapshot/``).
show_progress:
Enable console progress output while the pipeline runs.
progress_style:
``"bar"`` – tqdm-style progress bar (requires *tqdm*; falls back to
``"log"`` when unavailable).
``"log"`` – one line per step.
``"silent"`` – no output.
repr_width:
Character width used when printing the pipeline summary.
plot_dpi:
DPI for saved figures.
plot_fmt:
File extension / format for saved figures (``"png"``, ``"pdf"``,
``"svg"``).
report_formats:
Sequence of report types to write. Each item must be ``"html"``
or ``"txt"``.
"""
output_root: str = "pipe_results"
processed_subdir: str = "processed"
plots_subdir: str = "plots"
on_step_error: str = "warn"
save_intermediate: bool = False
show_progress: bool = True
progress_style: str = "bar"
repr_width: int = 80
plot_dpi: int = 150
plot_fmt: str = "png"
report_formats: tuple = field(default_factory=lambda: ("html", "txt"))
# ------------------------------------------------------------------
# Public API
# ------------------------------------------------------------------
[docs]
@contextmanager
def context(self, **kw: Any) -> Generator[PipelineAPIConfig, None, None]:
"""Temporarily override config values, then restore them."""
snapshot = {k: getattr(self, k) for k in kw}
try:
self.configure(**kw)
yield self
finally:
for k, v in snapshot.items():
setattr(self, k, v)
[docs]
def reset(self) -> None:
"""Restore all attributes to package defaults."""
_defaults = PipelineAPIConfig()
for f in fields(self):
setattr(self, f.name, getattr(_defaults, f.name))
[docs]
def clone(self) -> PipelineAPIConfig:
"""Return a deep copy of this config."""
return copy.deepcopy(self)
# ------------------------------------------------------------------
# Display
# ------------------------------------------------------------------
def __repr__(self) -> str:
lines = ["PipelineAPIConfig"]
for f in fields(self):
lines.append(f" {f.name}: {getattr(self, f.name)!r}")
return "\n".join(lines)
# ---------------------------------------------------------------------------
# Singleton + convenience helpers
# ---------------------------------------------------------------------------
PYCSAMT_PIPE: PipelineAPIConfig = PipelineAPIConfig()
[docs]
def reset_pipe() -> None:
"""Reset :data:`PYCSAMT_PIPE` to package defaults."""
PYCSAMT_PIPE.reset()
__all__ = [
"PYCSAMT_PIPE",
"PipelineAPIConfig",
"configure_pipe",
"reset_pipe",
]