Version 2.6.4#
pyCSAMT 2.6.4 Feature Fix Enhancement Docs Build Tests#
Released 2026-10-02.
pyCSAMT 2.6.4 adds two new command-line surfaces and a standalone format-conversion app, rebuilds most of the desktop suite as studios with a new Edit menu, ships the desktop suite as Windows and Linux installers, extends Agent Master, and fixes more than twenty real bugs, most of them found while raising test coverage.
A standalone format-conversion app Feature#
pyCSAMT Format Studio (pycsamt.app.converter) is a new PySide6
application whose entire job is converting between pyCSAMT’s file formats
– nothing else. Unlike the full desktop suite, it has no survey-loading, QC, correction,
modelling, or interpretation features, which keeps it small enough to hand
to a field or office user as a single frozen binary rather than the full
scientific Python stack most other pyCSAMT surfaces need.
Nine tools live in one window: Inversion → PCSF/PCSM (Occam2D/ModEM
3-D/MARE2DEM working directories, or an AI/DL .npz/.npy array
bundle), PCSF ⇄ PCSM / Validate / Info, EDI ⇄ EMTF-XML, four
document builders (PCBH borehole, PCGL geology legend, PCGS
structural evidence, PCPT points of interest), a batch queue for
converting a mixed folder in one pass, and Settings for persisted
defaults. Launch it with pycsamt-converter or
python -m pycsamt.app.converter after pip install "pycsamt[app]" –
no survey needs to be loaded first, and every action refuses to overwrite
an existing file unless explicitly told to.
For a user who does not want a Python environment at all, a new PyInstaller
spec (packaging/pyinstaller/pycsamt_converter.spec, plus wrapper
build_converter.ps1/.sh scripts) freezes the app into a
double-click-able onedir build under dist/pycsamt-converter/ –
roughly 600 MB, since PyTorch, TensorFlow, and the other pyCSAMT apps are
excluded as unreachable from the converter’s own code. The full desktop
suite is frozen the same way for its installers (see below).
Every page is a thin widget around one plain, Qt-free function in
pycsamt.app.converter.jobs, which calls exactly the same engine as
the CLI commands below – there is no separate, parallel conversion logic
behind the GUI.
New format and airborne CLI commands Feature Enhancement#
Six sub-commands join pycsamt format, all previously reachable only
from Python: build-pcbh, build-pcgl, build-pcgs, build-pcpt
build the four new document types from CSV/XLSX/LAS, and
edi-to-xml/xml-to-edi losslessly convert between SEG EDI and
EMTF-XML, one file or an entire directory. These are the exact commands
the new converter app’s EDI ⇄ XML and four builder pages call.
Making that sharing possible required one internal refactor:
pycsamt.format.convert_engine, the “any source → PCSFModel”
dispatch logic behind pycsamt format convert (detect,
resolve_target, build_model, write_model, model_report),
moves from a private helper inside
pycsamt.cli.commands.format._base into a public, UI-neutral module.
pycsamt format convert’s own behaviour, options, and output are
unchanged – only the module a second consumer (the GUI, or any future
one) needs to import changed.
A second, unrelated command group, ``pycsamt airborne``, adds info
(dataset or single-site summary, text/JSON/CSV) and diagnose
(auto-detects the technology from the loaded sites and builds its
canonical table: ZTEM total-divergence, MobileMT admittance, or
AFMAG/AirMt tilt). Both operate on already-decoded EMTF-XML files or
directories of them through pycsamt.airborne.site.ensure_asites();
pyCSAMT still has no raw-vendor-file reader for airborne systems. ZTEM’s
table is a profile quantity, so a multi-line survey without --line
refuses outright with a message naming the flight lines detected
geometrically from station coordinates, rather than silently
differentiating across a line boundary.
Desktop installers Build#
The desktop suite now installs without a Python environment: a Windows
setup .exe (Inno Setup, packaging/inno/build_installer.ps1) and a
self-extracting Linux .sh (packaging/linux/build_installer.sh,
which also takes --uninstall). Both are built from
packaging/pyinstaller/pycsamt_desktop.spec, which bundles the package
data the frozen app reads at run time, such as the EPSG table, logging
configuration, borehole templates and solver sources. Download them from
the v2.6.4 release (Windows
setup .exe,
Linux .sh);
see Download A Ready-Made Installer.
Agent Master Feature#
Agent Master now keeps the context of a conversation across turns (see
Conversation context and stopping work), hands a task to
the desktop suite and back, checks a run’s preconditions before executing
it, and can cancel a request in progress. The assistant has an answer
benchmark (pycsamt/assistant/evals/) that can run generated scripts
against fixtures inside a Docker image (recipe in
packaging/agent-fixture/); Evaluating answers and scripts
describes it.
More bug fixes Fix#
A coverage pass over 95 files that were below 85 % found these:
pycsamt converton.avgfiles imported a class that does not exist, and on J files wrote an EDI withDATAID='UNKNOWN'and no frequencies; both silently failed.pycsamt transform jraisedTypeErroron every single-file or directory conversion. All three now go through the workingAVGtoEDI/JtoEDItransformers.pycsamt invert resultsread Occam2D’s RMS from the wrong attribute and returned only nulls for ModEM;pycsamt config set agent.modeldid nothing; the ModEM backend passed unrelated config fields to the input builder and failed as “ModEM preparation failed”.Frequency regridding filled values outside a station’s measured band, and
decimate_stepemptied every station by misaligningz,z_errandfreq. The pipeline’sfull_processingalso wiped the data.MARE2DEM
mergededuplicated receiver names and positions separately, so merged.emdatafiles could pair stations with the wrong names.The TensorFlow PINN fit averaged with
meanrather thannanmean, so one missing frequency turned a whole station’s fit into NaN;EMImputerand the joint inverter failed to reload after saving.Plot fixes:
plot_confidence_profileno longer zig-zags across line boundaries, the ZTEM map draws collinear stations, TDEM depth sections lose their slivers, and a single-line fence volume keeps its width.In the installed desktop app, Occam1D could neither build its inputs nor run: the app has no console, so
sys.stdoutisNoneand Occam1D stopped with “stream must provide a callable write method”. It now writes its progress to a silent sink. The 3-D window also no longer starts a web engine until it is first shown, which saves memory at start-up.AVG files written by older pyCSAMT exports (header
skpStationwith no space) were rejected as “Unrecognised AVG header”; they now load.An empty borehole CSV reported “could not detect CSV delimiter” instead of “CSV file is empty”, and the trial’s “days remaining” was one day short (a new 30-day trial showed 29).
EDI parsing fixes Fix#
Both fixes below surfaced while writing the new documentation and running real conversions against the bundled Broken Hill and Gabbs Valley EDI surveys to capture accurate examples – exactly the kind of bug end-to-end documentation testing is supposed to catch.
Converting an
EMTFdocument to EDI wrote everyRHOxx.ERR/PHSxx.ERRresistivity/phase-error block as a literal0.000000E+00at every frequency, even when the impedance itself had real, non-zero variance (ZXX.VARand friends were correct). The cause:emtf_to_edi()attached the impedance error array topycsamt.z.Z’s private_z_errattribute after construction, specifically to avoid an older bug where passing it through the constructor could crash on legitimately missing (NaN) variance components. That older bug is long fixed, but the workaround remained, and it silently skipped the resistivity/phase error-propagation step that only the publicz_errsetter triggers – so the real uncertainty was computed correctly internally and then simply never wrote out, reading instead as “zero uncertainty,” which is scientifically wrong: it claims perfect certainty rather than “not available.” The converter now goes through the public setter, and the same real EDI now carries genuine error-propagated values.As a second line of defence,
pycsamt.seg.edi’s writer now defaults a genuinely absent resistivity/phase error to NaN instead of an array of zeros before serializing it. NaN always becomes the SEG-EDI1.000000E+32EMPTY sentinel regardless of any zero-preservation option, so any future case that still reaches the writer without a computed error correctly reports “unavailable” instead of a misleading exact zero.pycsamt.seg.heads.Headnow normalizes a field written as the literal string"None"(some EDI writers stampDECLINATION=Nonefor an unset value instead of omitting the key entirely) to a real PythonNonewhile parsing.write()already treated that string as equivalent to absent; the read path now agrees, instead of the value reaching a numeric setter as the four-character string"None".
Documentation and tests Docs Build Tests#
Format Converter is a new, complete guide to the converter
app: installation and launch, compiling a standalone build, a tour of the
window chrome, and every one of the nine tool pages with a real screenshot,
a field-by-field option walkthrough, and its equivalent CLI invocation.
pycsamt format convert/detect/info/validate are
cross-referenced to their existing, already-exhaustive entry in
Format Commands rather than duplicated; the six sub-commands documented
nowhere else get full option tables and real captured output instead.
Applications and Overview now count
five applications.
Airborne Commands documents the new pycsamt airborne group the same
way – full option tables plus real output captured from the bundled
ZTEM (Gold Springs, NV), MobileMT (Flammefjeld, Greenland), and AFMAG
(Abitibi, ON / Yulong Belt, CN) sample surveys, including the genuine
multi-line-detection error message.
Every downloadable script under docs/scripts/ (61 files) now starts
with the same #!/usr/bin/env python / # Author: / # License:
header used throughout the rest of the package, since each one is meant to
be downloaded from a documentation page’s code-dropdown and run on its
own, outside the repository.
New CLI test coverage: pycsamt/cli/tests/test_cmd_format_build.py
exercises all four new build-* commands, and
pycsamt/cli/tests/test_cmd_airborne.py exercises airborne info and
airborne diagnose against the real bundled ZTEM/MobileMT/AFMAG sample
directories (new session-scoped conftest.py fixtures), skipping
automatically rather than mocking when that sample data is unavailable.
Compatibility#
This release does not remove or rename any public API. Everything new –
the converter app, the six format build-*/edi-to-xml/xml-to-edi
commands, pycsamt airborne, and the now-public
pycsamt.format.convert_engine – is purely additive.
pycsamt format convert itself behaves exactly as before; only the
private module its Click wrapper delegated to changed location. The two
EDI fixes change values written by a previously-broken path (a real
uncertainty instead of zero, a parsed None instead of a crash) but no
function signatures. Frequency regridding now returns NaN outside a
station’s measured band where it used to extrapolate; code that relied on
those extrapolated values should trim or mask first.