Inversion Commands#
pycsamt invert is the command group for preparing, launching,
inspecting, summarising, and plotting inversion runs. It is designed
around a work directory: the build command writes solver-specific input
files into that directory, the run command launches the external solver
from that directory, and the reporting/plotting commands read the files
that the solver produced.
The command group currently supports two solver families:
occam2dfor 2-D Occam input, execution, result loading, and the Occam-focused diagnostic plots.modemfor ModEM 2-D or 3-D input, execution, result loading, and ModEM-focused model/response plots.
The CLI does not hide the fact that these are different inversion programs. It gives them a shared workflow shape, but the files, model geometry, and some plots remain solver-specific.
Command Map#
Command |
Purpose |
Main output |
|---|---|---|
|
Convert a survey or EDI directory into solver input files. |
A populated inversion work directory. |
|
Launch the external Occam2D or ModEM executable. |
Iteration/model/response files and solver logs. |
|
Inspect a work directory without loading a full result object. |
Readiness flags, file counts, iteration counts, and RMS hints. |
|
Load a completed inversion result and print a compact summary. |
Loaded iteration, final RMS, model shape, and resistivity stats. |
|
Plot a reconstructed model section. |
Figure file or interactive matplotlib window. |
|
Plot convergence through iterations. |
RMS curve, and for Occam2D optional roughness/Lagrange context. |
|
Compare observed and predicted responses. |
Response panels for one or more stations. |
|
Plot apparent-resistivity/phase pseudosections. |
Pseudosection figure. |
|
Plot a ModEM depth/section view. |
ModEM-only section figure. |
|
Extract station-centered 1-D profiles from an Occam2D model. |
Occam2D-only profile figure. |
|
Plot per-site RMS and residual diagnostics. |
Occam2D-only diagnostic figure. |
|
Plot a compact response grid across stations. |
Occam2D-only response-grid figure. |
Mental Model#
An inversion workflow has four distinct stages.
Load a survey.
invert buildresolves the input as an explicitEDI_DIR, an explicit--surveypath, or the active survey set withpycsamt survey set.Write solver files. The builder creates the work directory if it does not exist, applies frequency/error/mesh options, and delegates to the relevant input builder:
pycsamt.models.occam2d.builder.InputBuilderorpycsamt.models.modem.builder.InputBuilder.Run the solver.
invert rundoes not rebuild the input files. It uses the existing work directory, detects or accepts the solver name, and calls the corresponding runner:pycsamt.models.occam2d.runner.OccamRunnerorpycsamt.models.modem.runner.ModEmRunner.Read and plot outputs.
statuschecks file signatures and simple counters.resultsandplotinstantiate the solver-specificInversionResultclass and therefore require completed result files.
This separation is deliberate. It lets you build once, adjust solver files manually when needed, run on a workstation or cluster, and later use the pyCSAMT CLI only for status, summaries, and figures.
Basic Workflow#
Build an Occam2D run from an explicit EDI directory:
pycsamt invert build data/line01_edi --solver occam2d --workdir runs/line01_occam
Launch the solver:
pycsamt invert run runs/line01_occam --max-iter 100 --target-misfit 1.05
Inspect the directory:
pycsamt invert status runs/line01_occam
Summarise the loaded result:
pycsamt invert results runs/line01_occam
Save the standard figures:
pycsamt invert plot model runs/line01_occam --save figures/line01_model.png
pycsamt invert plot misfit runs/line01_occam --save figures/line01_misfit.png
pycsamt invert plot response runs/line01_occam --save figures/line01_response.png
pycsamt invert plot pseudo runs/line01_occam --save figures/line01_pseudo.png
For ModEM, use --solver modem at build time:
pycsamt invert build data/line01_edi --solver modem --modem-mode 3d \
--initial-rho 100 --workdir runs/line01_modem
pycsamt invert run runs/line01_modem --solver modem --async
pycsamt invert status runs/line01_modem --solver modem
Input Resolution#
invert build accepts an optional positional EDI_DIR:
pycsamt invert build EDI_DIR
If EDI_DIR is omitted, the command falls back to --survey and
then to the active survey context:
pycsamt survey set data/line01_edi
pycsamt invert build --solver occam2d --workdir runs/line01_occam
Resolution priority is:
Positional
EDI_DIR.--survey PATH.The active survey saved by
pycsamt survey set.
Use --fresh when you want the survey to be re-parsed from disk rather
than reused from cached context:
pycsamt invert build --fresh --workdir runs/line01_occam
If no explicit path and no active survey are available, the command fails with a survey-context error instead of guessing.
Solver Detection#
Most commands accept --solver occam2d or --solver modem. For
commands that operate on an existing work directory, the option is
optional when the directory contains recognizable files.
Occam2D detection uses signatures such as:
Occam2DMeshOccam2DStartupOccamData.datany
*.iteror*.respfiles
ModEM detection uses signatures such as:
ModEMData.datModEM.invModular_NLCG.log
If a directory is empty, partially copied, or uses non-standard names, pass the solver explicitly:
pycsamt invert status runs/manual_occam --solver occam2d
pycsamt invert results runs/manual_modem --solver modem
Build#
Usage:
pycsamt invert build [EDI_DIR] [OPTIONS]
The build command loads the survey, creates the work directory, prepares
solver configuration, and writes solver input files. The default solver
is occam2d and the default work directory is invert_run.
General options:
Option |
Default |
Meaning |
|---|---|---|
|
|
Select the inversion input format and runner family. |
|
|
Directory where input files are written. |
|
none |
Explicit survey path used when positional |
|
false |
Rebuild survey state from disk before writing inputs. |
|
none |
Keep only frequencies in this Hz range. |
|
solver default |
Occam2D earth layers or ModEM vertical cells. |
|
solver default |
Target horizontal cell size near stations. |
|
quiet |
Increase CLI logging. |
|
false |
Disable colored CLI logging/output. |
Occam2D options:
Option |
Default |
Meaning |
|---|---|---|
|
|
Comma-separated Occam data modes. Values are upper-cased by the
CLI before being passed to |
|
config default |
Relative apparent-resistivity error floor, for example |
|
config default |
Absolute phase error floor in degrees. |
ModEM options:
Option |
Default |
Meaning |
|---|---|---|
|
|
Select ModEM dimensionality. |
|
config default |
Initial half-space resistivity in ohm-m. |
Examples:
pycsamt invert build survey/ --workdir run01
pycsamt invert build survey/ --freq 0.1:1000 --n-layers 60 \
--error-floor-rho 0.05 --workdir run01
pycsamt invert build survey/ --solver modem --modem-mode 3d \
--initial-rho 100 --workdir modem_run
Build is the only command in this group that resolves EDI/survey input. All later commands expect a work directory that already exists.
Run#
Usage:
pycsamt invert run WORKDIR [OPTIONS]
run launches the external executable associated with the selected
solver. It uses OccamRunner for Occam2D and ModEmRunner for
ModEM. The solver can be detected from the work directory or supplied
explicitly.
Options:
Option |
Default |
Meaning |
|---|---|---|
|
auto |
Solver family to launch. |
|
file/config default |
Override the maximum iteration count in the startup/control file. |
|
file/config default |
Override the target RMS misfit for this run. |
|
false |
Start the solver and return immediately. |
|
quiet |
Increase logging. |
|
false |
Disable colored output. |
Synchronous examples:
pycsamt invert run run01
pycsamt invert run run01 --max-iter 100 --target-misfit 1.05
Asynchronous ModEM example:
pycsamt invert run modem_run --solver modem --async
When --async is used, the command prints the process ID and the
stdout log path:
Occam2D:
occam_stdout.logModEM:
modem_stdout.log
When a synchronous run exits with a non-zero code, the CLI reports the solver-specific stderr log:
Occam2D:
occam_stderr.logModEM:
modem_stderr.log
The command assumes that the external solver binary can be discovered by
the configured runner. For ModEM this commonly means the configured
Mod2DMT or Mod3DMT executable is on PATH or provided through
the model configuration. For Occam2D, the runner handles Occam binary
discovery according to the Occam2D runner implementation.
Status#
Usage:
pycsamt invert status WORKDIR [OPTIONS]
status is a lightweight directory inspection command. It does not
require a complete inversion result. It lists files, checks expected
solver signatures, and reports whether the directory appears ready to
run.
Options:
Option |
Default |
Meaning |
|---|---|---|
|
auto |
Solver family. Required when detection fails. |
|
text |
Human-readable table or JSON payload. The shared option accepts
|
|
quiet |
Increase logging. |
|
false |
Disable colored table/log output. |
Occam2D status reports:
total file count and file names in JSON mode;
whether data, mesh, model, and startup files are present;
whether all required run inputs appear present;
number of
*.iterfiles;last
*.iterfile;number of
*.respfiles;last RMS parsed from an Occam log when available.
ModEM status reports:
total file count and file names in JSON mode;
whether data, control, and covariance files are present;
whether data and control files appear sufficient to run;
number of
*.rhomodel files;last
*.rhomodel file.
Examples:
pycsamt invert status run01
pycsamt invert status run01 --format json
pycsamt invert status modem_run --solver modem
JSON output is useful for automation:
pycsamt invert status run01 --format json
The JSON object includes keys such as workdir, solver,
files_present, n_files, ready_to_run, and solver-specific
iteration/model counters.
Results#
Usage:
pycsamt invert results WORKDIR [OPTIONS]
results loads the solver-specific InversionResult object and
prints a compact summary. Unlike status, it expects completed output
files that can be parsed by the result loader.
Options:
Option |
Default |
Meaning |
|---|---|---|
|
auto |
Solver family. Required when detection fails. |
|
latest available |
Load a specific iteration when the result reader supports it. |
|
text |
Human-readable table or JSON payload. The shared option accepts
|
|
quiet |
Increase logging. |
|
false |
Disable colored output. |
The summary includes:
work directory;
solver;
number of iteration files when available;
loaded iteration;
final RMS/misfit when available;
model array shape when available;
log10 rhominimum, maximum, and mean whenrho_2dis available.
Examples:
pycsamt invert results run01
pycsamt invert results run01 --iteration 50
pycsamt invert results run01 --format json
pycsamt invert results modem_run --solver modem
Use status first when you are not sure whether a directory contains
completed result files. results is intentionally stricter because it
constructs the full result object.
Plot Overview#
Usage:
pycsamt invert plot COMMAND WORKDIR [OPTIONS]
All plot commands load an InversionResult first. They then construct
the corresponding plot class and return a matplotlib figure. A figure is
only written or displayed when you pass --save FILE or --show.
Without either option the command creates the figure and prints a message
that it was not saved.
Shared plot options:
Option |
Default |
Meaning |
|---|---|---|
|
auto |
Solver family. Required when detection fails. |
|
latest available |
Load a specific result iteration. |
|
none |
Save the figure as PNG, PDF, SVG, or another matplotlib-supported output format. |
|
false |
Display an interactive matplotlib window. |
|
|
Figure resolution. |
|
|
Matplotlib colormap. Available on model/pseudo/section/1d/per-site commands. |
|
quiet |
Increase logging. |
|
false |
Disable colored output. |
The directory for --save is created automatically when needed:
pycsamt invert plot model run01 --save figures/inversion/model.png
Plot Model#
Usage:
pycsamt invert plot model WORKDIR [OPTIONS]
model plots the reconstructed resistivity model. For Occam2D it uses
pycsamt.models.occam2d.plot.PlotModel. For ModEM it uses
pycsamt.models.modem.plot.PlotModel2D through the current CLI.
Options in addition to the shared plot options:
Option |
Default |
Meaning |
|---|---|---|
|
|
Lower resistivity color-scale bound in ohm-m. |
|
|
Upper resistivity color-scale bound in ohm-m. |
|
none |
Maximum displayed depth. |
|
false |
Hide station markers where supported. |
Examples:
pycsamt invert plot model run01 --save section.png
pycsamt invert plot model run01 --rho-min 1 --rho-max 1000 --depth-max 5000
pycsamt invert plot model modem_run --solver modem --show
Plot Misfit#
Usage:
pycsamt invert plot misfit WORKDIR [OPTIONS]
misfit plots convergence through iterations. Both solvers expose a
PlotMisfit class. Occam2D additionally supports roughness and
Lagrange multiplier display controls through the CLI.
Options in addition to the shared plot options:
Option |
Default |
Meaning |
|---|---|---|
|
false |
Occam2D: hide the roughness secondary axis. |
|
false |
Occam2D: add a lower panel for the Lagrange multiplier. |
Examples:
pycsamt invert plot misfit run01 --show
pycsamt invert plot misfit run01 --save convergence.png --lagrange
Plot Response#
Usage:
pycsamt invert plot response WORKDIR [OPTIONS]
response compares observed and predicted response curves. Use
--station to focus on one station; omit it to let the plot class
select its default station set.
Options in addition to the shared plot options:
Option |
Default |
Meaning |
|---|---|---|
|
all/default |
Plot only the named station. |
Examples:
pycsamt invert plot response run01 --show
pycsamt invert plot response run01 --station S01 --save S01_resp.png
Plot Pseudo#
Usage:
pycsamt invert plot pseudo WORKDIR [OPTIONS]
pseudo plots apparent-resistivity and phase pseudosections from the
loaded inversion result. It is available for both Occam2D and ModEM.
Examples:
pycsamt invert plot pseudo run01 --show
pycsamt invert plot pseudo run01 --cmap viridis --save pseudo.png
Plot Section#
Usage:
pycsamt invert plot section WORKDIR [OPTIONS]
section is ModEM-only. It calls
pycsamt.models.modem.plot.PlotSection. When used on an Occam2D work
directory, the CLI raises a usage error and suggests plot 1d for
Occam2D depth profiles.
Options in addition to the shared plot options:
Option |
Default |
Meaning |
|---|---|---|
|
plot default |
Depth of the requested slice/section control passed to the plotter. |
Examples:
pycsamt invert plot section modem_run --depth 5000 --show
pycsamt invert plot section modem_run --depth 10000 --save slice.png
Plot 1d#
Usage:
pycsamt invert plot 1d WORKDIR [OPTIONS]
1d is Occam2D-only. It samples station-centered depth profiles from
the reconstructed 2-D model through
pycsamt.models.occam2d.plot.PlotSounding1D. When used on a ModEM
work directory, the CLI raises a usage error and suggests plot
section for ModEM depth slices.
Options in addition to the shared plot options:
Option |
Default |
Meaning |
|---|---|---|
|
all/default |
Comma-separated station names to include. |
Examples:
pycsamt invert plot 1d run01 --show
pycsamt invert plot 1d run01 --stations S01,S05,S10 --save profiles.png
Plot Per-Site#
Usage:
pycsamt invert plot per-site WORKDIR [OPTIONS]
per-site is Occam2D-only. It calls
pycsamt.models.occam2d.plot.PlotSiteMisfit and is intended for
checking which stations dominate residuals.
Examples:
pycsamt invert plot per-site run01 --show
pycsamt invert plot per-site run01 --save site_rms.png
Plot Grid#
Usage:
pycsamt invert plot grid WORKDIR [OPTIONS]
grid is Occam2D-only. It calls
pycsamt.models.occam2d.plot.PlotResponseGrid and is useful when you
want a compact scan of response quality across many stations.
Examples:
pycsamt invert plot grid run01 --show
pycsamt invert plot grid run01 --save response_grid.png
Choosing Plots#
Use this quick guide when deciding what to generate after a run:
Question |
Command |
Notes |
|---|---|---|
Did the inversion converge? |
|
Start here before interpreting structure. |
What does the recovered model look like? |
|
Available for both solver families. |
Does the model fit individual stations? |
|
Add |
Are residuals concentrated by station? |
|
Occam2D only. |
Is there a broad data-pattern issue? |
|
Useful before and after inversion. |
What vertical model is below each station? |
|
Occam2D only. |
What does a ModEM section/slice show? |
|
ModEM only. |
How do many station responses compare at once? |
|
Occam2D only. |
Batch Figure Export#
For a completed Occam2D run, a common export set is:
pycsamt invert plot model run01 --save figures/run01/model.png
pycsamt invert plot misfit run01 --save figures/run01/misfit.png
pycsamt invert plot response run01 --save figures/run01/response.png
pycsamt invert plot pseudo run01 --save figures/run01/pseudo.png
pycsamt invert plot 1d run01 --save figures/run01/profiles_1d.png
pycsamt invert plot per-site run01 --save figures/run01/per_site.png
pycsamt invert plot grid run01 --save figures/run01/response_grid.png
For a completed ModEM run:
pycsamt invert plot model modem_run --solver modem --save figures/modem/model.png
pycsamt invert plot misfit modem_run --solver modem --save figures/modem/misfit.png
pycsamt invert plot response modem_run --solver modem --save figures/modem/response.png
pycsamt invert plot pseudo modem_run --solver modem --save figures/modem/pseudo.png
pycsamt invert plot section modem_run --solver modem --depth 10000 \
--save figures/modem/section_10km.png
The --solver flag is optional if the run directory contains standard
solver signatures. It is included above for clarity and for manually
assembled directories.
Text Versus JSON Output#
status and results both support --format json. The shared
CLI option also accepts csv, but these inversion commands currently
emit JSON only for --format json and otherwise print the text table.
Use text for interactive work and JSON for scripts:
pycsamt invert status run01 --format json
pycsamt invert results run01 --format json
Typical script checks are:
ready_to_runfromstatusbefore launching the solver;n_iterations_donefor Occam2D progress tracking;n_model_filesfor ModEM progress tracking;rmsandmodel_shapefromresultsafter completion.
Because results loads a full result object, it can fail on a work
directory that status can still inspect. That distinction is useful:
status answers “what files are here?”, while results answers
“can pyCSAMT parse this completed inversion?”.
Common Failures#
Cannot detect solverThe work directory does not contain standard Occam2D or ModEM file signatures. Pass
--solver occam2dor--solver modem.No active surveyinvert buildwas called withoutEDI_DIRor--surveyand no active survey context has been set. Provide an input path or runpycsamt survey set PATHfirst.Figure created but not savedA plot command ran without
--saveor--show. Re-run with one of those options.section is a ModEM-only sub-commandUse
pycsamt invert plot 1dfor Occam2D depth profiles.1d is an Occam2D-only sub-commandUse
pycsamt invert plot sectionfor ModEM section/slice plots.Error loading resultsThe directory may not contain completed parseable result files, or a specific
--iterationwas requested but is unavailable. Checkpycsamt invert status WORKDIRfirst.- Non-zero solver exit
Check
occam_stderr.logormodem_stderr.login the work directory. Also confirm that the external executable is installed and discoverable by the runner.
Practical Notes#
Keep build and run directories explicit. invert_run is convenient
for quick tests, but named directories such as runs/l18_occam_tm or
runs/line03_modem_3d are much easier to audit later.
Record solver options in your command history or project notes. Build
options such as --freq, --modes, --error-floor-rho,
--n-layers, and --cell-size materially change the inversion
input.
Use status before run when a work directory was copied from
another machine. It gives a quick check that the expected file family is
present before a solver process is launched.
Use results --iteration when comparing a specific iteration across
different parameter tests. Without it, the result loader uses the latest
available iteration.
Use explicit --solver in automated scripts. Auto-detection is
helpful interactively, but explicit solver names make scripts clearer and
reduce ambiguity for unusual file layouts.
Python Equivalents#
The CLI is a thin orchestration layer over the model packages. For Python workflows, use the same underlying modules directly.
Occam2D build/run/read pattern:
from pathlib import Path
from pycsamt.emtools._core import ensure_sites
from pycsamt.models.occam2d.config import OccamConfig
from pycsamt.models.occam2d.builder import InputBuilder
from pycsamt.models.occam2d.runner import OccamRunner
from pycsamt.models.occam2d.results import InversionResult
sites = ensure_sites("data/line01_edi", recursive=True, verbose=0)
cfg = OccamConfig(modes=["TE", "TM"])
cfg.freq_min = 0.1
cfg.freq_max = 1000.0
cfg.error_floor_rho = 0.05
workdir = Path("runs/line01_occam")
InputBuilder(source=sites, workdir=workdir, config=cfg, verbose=1).build()
OccamRunner(workdir=workdir, verbose=1).run(max_iter=100, target_misfit=1.05)
result = InversionResult(workdir=workdir)
fig = result.plot_model(depth_max=5000)
fig.savefig("figures/line01_model.png", dpi=150, bbox_inches="tight")
ModEM build/read pattern:
from pathlib import Path
from pycsamt.emtools._core import ensure_sites
from pycsamt.models.modem.config import ModEmConfig
from pycsamt.models.modem.builder import InputBuilder
from pycsamt.models.modem.results import InversionResult
sites = ensure_sites("data/line01_edi", recursive=True, verbose=0)
cfg = ModEmConfig(mode="3d")
cfg.freq_min = 0.1
cfg.freq_max = 1000.0
cfg.initial_rho = 100.0
workdir = Path("runs/line01_modem")
InputBuilder(config=cfg).build(sites, workdir=workdir)
result = InversionResult(workdir=workdir)
These Python snippets mirror the CLI modules. They are useful when a project needs custom configuration that is not exposed as a command-line option yet.