pycsamt.models.mare2dem#
pycsamt.models.mare2dem — Python interface to the MARE2DEM EM inversion code.
MARE2DEM (Modeling with Adaptively Refined Elements for 2.5-D Electromagnetic inversion) implements finite-element MT and CSEM forward modelling and Occam-style regularized inversion. It is an MPI-parallel Fortran code developed by Kerry Key at LDEO, Columbia University.
Because the compiled binary is ~49 MB, the source tree is not
bundled in the repository. Use SourceManager to download and
build it before running inversions.
Ported MATLAB scripts (complete)#
I/O (a_util/io/ + a_util/data/):
.emdata/.EMRespreader + writer.resistivityreader + writer (all anisotropy modes)Triangle
.polyPSLG reader + writer.settingsparallel-decomposition writer.emdata_groupdata-group file reader + writerGroup-RMS CSV log reader
Most-recently-modified file finder
Data management:
Data-type code lookup table
High-level
.emdatabuilder from MT / CSEM survey configsZMM impedance file reader + MT data-file builder
Synthetic noise addition +
make_synthetic_datawrapperMulti-file merge utility
Geometry (a_util/geom/, a_util/mapping/):
Topography interpolation + slope angles
Line-segment intersections (bounding-box pre-filtered)
Douglas-Peucker polyline simplification
PSLG polygon simplification (collinear node removal)
Area-weighted triangle region centroids
Survey-profile line orientation
Station-to-profile projection
UTM ↔ Lon/Lat conversion (
pyprojwith pure-Python WGS-84 fallback)Survey area-of-interest estimator
Triangle FEM region flood-fill assignment
Model construction:
2-D resistivity grid → MARE2DEM
.poly+.resistivityTopography import + profile projection
Model comparison:
Log10 (or custom) difference of two
.resistivityfiles
Plotting:
RMS convergence curve
Survey map (Rx/Tx positions in UTM)
Receiver geometry QC (6-panel)
Transmitter geometry QC
.polyPSLG mesh plotResistivity section stub (pending full mesh parser)
Quick start#
Step 1 — Download and compile (once per machine):
from pycsamt.models.mare2dem import SourceManager
sm = SourceManager(verbose=1)
sm.download() # git-clone from Bitbucket
sm.build() # requires Intel oneAPI + MKL
Step 2 — Create a data file from MT survey parameters:
import numpy as np
from pycsamt.models.mare2dem import MTSurveyConfig, make_data_file
mt = MTSurveyConfig(
frequencies=np.logspace(-3, 3, 20),
rx_y=np.linspace(-5000, 5000, 20),
rx_type='marine', lTE=True, lTM=True,
)
em = make_data_file('survey.emdata', topo=-1000.0, mt=mt)
Step 3 — Prepare a full input set and run:
from pycsamt.models.mare2dem import Mare2DEMConfig, InputBuilder, Mare2DEMRunner
cfg = Mare2DEMConfig(initial_rho=1.0, n_procs=8)
InputBuilder(cfg).build('survey.emdata', workdir='./run')
result = Mare2DEMRunner('./run', cfg).run('mare2dem')
result.print_summary()
References
Key, K. (2016). MARE2DEM: A 2-D inversion code for controlled-source electromagnetic and magnetotelluric data. Geophysical Journal International, 207(1), 571–588. doi:10.1093/gji/ggw290.
- class pycsamt.models.mare2dem.Mare2DEMConfig(source_dir=None, fc_compiler=None, cc_compiler=None, binary='MARE2DEM', use_mpi=True, n_procs=4, mpi_command='mpirun', max_iterations=150, target_rms=1.0, initial_rho=1.0, data_file='mare2dem.emdata', resistivity_file='mare2dem.resistivity', settings_file='mare2dem.settings')#
Bases:
objectCollect settings that define a MARE2DEM run.
Mare2DEMConfigis the central configuration object for the MARE2DEM wrapper. It is a plain dataclass whose fields cover source management, MPI execution, inversion control, starting model, and default file names.The configuration is shared by
SourceManager,InputBuilder,Mare2DEMRunner, andInversionResultso that all components of a workflow use consistent parameters.Source Management#
- source_dirpath-like or None, default None
Explicit path to the MARE2DEM Fortran source tree. When
None,SourceManagerapplies a four-level fallback: thePYCSAMT_MARE2DEM_SOURCEenvironment variable, the bundled_source/directory inside the package (writable dev installs), and finally the platform user-data directory (PyPI installs). Set this field when the source tree lives at an unconventional location.- fc_compilerstr or None, default None
MPI-Fortran compiler used to build MARE2DEM from source. When
None,SourceManager.build()auto-detects in the ordermpiifort(Intel oneAPI),mpifort(generic OpenMPI/MPICH). Intel compilers are preferred because the MARE2DEM Makefile uses Intel-specific pre-processor flags and the Intel MKL is required.- cc_compilerstr or None, default None
MPI-C compiler used for the Triangle mesh library and ScaLAPACK. Auto-detects
mpiiccthenmpiccwhenNone.
Binary And MPI#
- binarystr, default “MARE2DEM”
Name or absolute path of the compiled MARE2DEM executable. The runner first checks whether the name is on
PATH, then looks inside the resolved source directory, and finally checks the user-data directory. Use an absolute path to pin a specific build.- use_mpibool, default True
Whether to launch MARE2DEM through an MPI wrapper. MARE2DEM is an MPI-parallel code; serial execution is not supported by the official distribution. Set to
Falseonly when testing with a special single-process build.- n_procsint, default 4
Number of MPI processes requested when
use_mpiisTrue. Each process handles a subset of the spatial wavenumbers. Typical values range from 4 to the number of physical cores available on the node.- mpi_commandstr, default “mpirun”
MPI launcher command. Common alternatives are
"mpiexec"and"srun"(SLURM). The value is prepended to the MARE2DEM command line whenuse_mpiisTrue.
Inversion Control#
- max_iterationsint, default 150
Maximum number of Occam inversion iterations MARE2DEM is allowed to perform before stopping regardless of the misfit target.
- target_rmsfloat, default 1.0
Normalized RMS misfit target. MARE2DEM stops iterating when the data misfit falls below this value. Lower values demand a tighter fit and may produce more structured models.
Initial Model#
- initial_rhofloat, default 1.0
Starting half-space resistivity in ohm-metres for the initial homogeneous resistivity model. MARE2DEM internally uses log10-resistivity, so the value must be positive.
File Names#
- data_filestr, default “mare2dem.emdata”
Default MARE2DEM data filename. The file uses the
.emdataextension and records source–receiver geometry, observed data, and data uncertainties for one or more EM methods (MT, CSEM, or combined).- resistivity_filestr, default “mare2dem.resistivity”
Default MARE2DEM resistivity model filename. The file describes the 2-D finite-element mesh and layer resistivities and is the primary input file stem passed to the binary.
- settings_filestr, default “mare2dem.settings”
Default MARE2DEM inversion-settings filename. It controls inversion type (Occam vs NLCG), iteration limits, target misfit, output verbosity, and optional regularization parameters.
- ivar resistivity_stem:
The stem of
resistivity_filewithout its extension. MARE2DEM receives this stem as its only positional argument and derives the data and settings filenames from it.- vartype resistivity_stem:
str
Notes
MARE2DEM implements 2.5-D finite-element MT and CSEM forward modelling in the frequency domain with an Occam-style regularized inversion [1]_. The inversion minimizes an objective of the form
\[\begin{split}\Phi(m) = \| W_d (F(m) - d) \|_2^2 + \\lambda \| \\nabla m \|_2^2,\end{split}\]where \(F(m)\) is the 2.5-D FEM forward operator, \(d\) is the observed data vector, and \(W_d\) is the data-weighting operator. The configuration fields
target_rmsandmax_iterationsbound the inversion iteration.Source-Of-Truth Files#
The recommended workflow is:
Generate a template with
write_template().Edit the values in the generated file.
Load the edited file with
from_file().Pass the configuration to
SourceManager,InputBuilder,Mare2DEMRunner.
See also
SourceManagerDownload and compile the MARE2DEM Fortran source.
InputBuilderWrite MARE2DEM resistivity model, data, and settings files.
Mare2DEMRunnerLaunch the MARE2DEM binary subprocess.
InversionResultLoad MARE2DEM inversion output files.
Examples
Create a default configuration:
>>> from pycsamt.models.mare2dem.config import Mare2DEMConfig >>> cfg = Mare2DEMConfig() >>> cfg.resistivity_stem 'mare2dem'
Configure a parallel run with 8 MPI processes:
>>> cfg = Mare2DEMConfig(use_mpi=True, n_procs=8)
Point to a custom source directory:
>>> cfg = Mare2DEMConfig(source_dir="/opt/mare2dem_source")
References
- property resistivity_stem: str#
Return the stem of
resistivity_filewithout extension.
- to_template(path='mare2dem_config.py', *, fmt=None)#
Write this configuration as an editable template file.
- Parameters:
path (path-like, default "mare2dem_config.py") – Destination file.
fmt ({"py", "json", "yml", "yaml"}, optional) – Output format. Defaults to
.pywhen the path has no recognized suffix.
- Returns:
Path of the generated template.
- Return type:
- classmethod write_template(path='mare2dem_config.py', *, fmt=None)#
Write a default editable MARE2DEM configuration file.
- Parameters:
path (path-like, default "mare2dem_config.py") – Destination file. Suffixes
.py,.json,.yml, and.yamlselect the output format.fmt ({"py", "json", "yml", "yaml"}, optional) – Explicit output format.
- Returns:
Path of the generated source-of-truth file.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.config import Mare2DEMConfig >>> path = Mare2DEMConfig.write_template("mare2dem_config.py") >>> path.name 'mare2dem_config.py'
- classmethod from_file(path, *, strict=True)#
Create a configuration from a source-of-truth file.
- Parameters:
path (path-like) – Python, JSON, YML, or YAML configuration file generated by
write_template().strict (bool, default True) – If
True, unknown keys raiseValueError.
- Returns:
Configuration populated from the edited file.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.config import Mare2DEMConfig >>> Mare2DEMConfig.write_template("mare2dem_config.json") PosixPath('mare2dem_config.json') >>> cfg = Mare2DEMConfig.from_file("mare2dem_config.json") >>> cfg.binary 'MARE2DEM'
- classmethod read(path, *, strict=True)#
Create a configuration from a source-of-truth file.
- Parameters:
path (path-like) – Python, JSON, YML, or YAML configuration file generated by
write_template().strict (bool, default True) – If
True, unknown keys raiseValueError.
- Returns:
Configuration populated from the edited file.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.config import Mare2DEMConfig >>> Mare2DEMConfig.write_template("mare2dem_config.json") PosixPath('mare2dem_config.json') >>> cfg = Mare2DEMConfig.from_file("mare2dem_config.json") >>> cfg.binary 'MARE2DEM'
- class pycsamt.models.mare2dem.SourceManager(config=None, source_dir=None, **kwargs)#
Bases:
Mare2DEMBaseManage the MARE2DEM Fortran source: download, build, and locate.
SourceManageris the entry point for obtaining a working MARE2DEM binary. It separates source management from inversion execution so that users who already have a compiled binary can skip directly toMare2DEMRunner.Source-directory resolution#
The directory where sources are stored follows this priority:
source_dirconstructor argument.config.source_dirfield.PYCSAMT_MARE2DEM_SOURCEenvironment variable.Bundled
_source/inside the installed package (writable dev installs only).Platform user-data directory — the safe PyPI fallback:
Linux / WSL:
~/.local/share/pycsamt/mare2dem/macOS:
~/Library/Application Support/pycsamt/mare2dem/Windows:
%LOCALAPPDATA%\\pycsamt\\mare2dem\\
- param config:
Configuration object. Supplies
source_dir,fc_compiler,cc_compiler, andbinary.- type config:
Mare2DEMConfig, optional
- param source_dir:
Explicit path that overrides
config.source_dirand the environment variable.- type source_dir:
path-like, optional
- param verbose:
Verbosity level.
0orFalsekeeps the object quiet. Positive values enable diagnostic messages through the instance logger. Larger values may be used to request more detailed run, parsing, or build information.- type verbose:
int or bool, default 0
- param logger:
Logger for progress and diagnostic messages. If omitted, a class-specific PyCSAMT logger is created automatically. Provide a logger when integrating MARE2DEM workflows into an application-wide logging configuration.
- type logger:
logging.Logger, optional
Notes
MARE2DEM requires Intel compilers (
mpiifort,mpiicc) and the Intel MKL. When Intel oneAPI is installed, source thesetvars.shscript before callingbuild():source /opt/intel/oneapi/setvars.sh python -c " from pycsamt.models.mare2dem import SourceManager sm = SourceManager(verbose=1) sm.download() sm.build() "
Windows native builds are not supported. Use WSL2.
Examples
Quick-start — download and build:
>>> from pycsamt.models.mare2dem import SourceManager >>> sm = SourceManager(verbose=1) >>> sm.download() # clones from Bitbucket >>> sm.build() # compiles with auto-detected compilers
Check status without downloading:
>>> sm.print_status()
Point to sources already on disk:
>>> sm = SourceManager(source_dir="/data/mare2dem_source") >>> sm.build(inc_file="/data/mare2dem_source/include/habanero.inc")
See also
Mare2DEMRunnerLaunch the compiled MARE2DEM executable for inversion.
Mare2DEMConfigConfiguration controlling compiler selection and binary name.
References
[1] Key, K. (2016). MARE2DEM: A 2-D inversion code for controlled-source electromagnetic and magnetotelluric data. Geophysical Journal International, 207(1), 571-588. doi:10.1093/gji/ggw290.
- resolve_source_dir()#
Return the directory where MARE2DEM sources should live.
The resolution order is:
Explicit
source_dirargument passed to the constructor.config.source_dirfield.PYCSAMT_MARE2DEM_SOURCEenvironment variable.Bundled
_source/inside the package (only when writable — i.e. editable / development installs).Platform user-data directory (always writable).
- Returns:
Resolved directory (created if it does not yet exist).
- Return type:
- resolve_binary()#
Return the path to the compiled MARE2DEM binary or
None.Resolution order:
Binary name found on
PATH.<source_dir>/MARE2DEM.Platform user-data directory
MARE2DEM.
- Return type:
Path | None
- download(*, method='auto', force=False)#
Download the MARE2DEM source tree.
- Parameters:
method ({"auto", "git", "archive"}, default "auto") – Download strategy.
"auto"tries"git"first and falls back to"archive".force (bool, default False) – Re-download even if the source tree is already present.
- Returns:
Source directory containing the downloaded tree.
- Return type:
- Raises:
RuntimeError – When neither
gitnorrequestsis available, or when the download fails.
- build(*, inc_file=None, fc=None, cc=None, clean_first=False)#
Compile MARE2DEM from the downloaded source.
- Parameters:
inc_file (path-like or None, default None) – Explicit Make include file. When
None, one is auto-generated from the detected compilers and MKL.fc (str or None, default None) – MPI-Fortran compiler override. Falls back to
config.fc_compilerthen auto-detection.cc (str or None, default None) – MPI-C compiler override. Falls back to
config.cc_compilerthen auto-detection.clean_first (bool, default False) – Run
make clean_allbefore compiling to start fresh.
- Returns:
Path to the compiled
MARE2DEMbinary.- Return type:
- Raises:
FileNotFoundError – When the source tree is not present. Call
download()first.RuntimeError – When the build fails or the binary is not found after the build.
- status()#
Return a summary dictionary of source and build status.
- Returns:
Keys:
source_dir,downloaded,binary_path,built,fc,cc,mklroot.- Return type:
- print_status()#
Print a human-readable source and build status report.
- Return type:
None
- Parameters:
config (Mare2DEMConfig | None)
- class pycsamt.models.mare2dem.Mare2DEMFileType(*values)#
Bases:
EnumEnumeration of recognized MARE2DEM file types.
- EMDATA = 1#
- RESISTIVITY = 2#
- POLY = 3#
- SETTINGS = 4#
- LOG = 5#
- RESPONSE = 6#
- SENSITIVITY = 7#
- UNKNOWN = 8#
- pycsamt.models.mare2dem.detect_file_type(path)#
Detect the MARE2DEM file type from the file extension and name.
- Parameters:
path (path-like) – Path to the file to classify.
- Returns:
Detected file type, or
Mare2DEMFileType.UNKNOWN.- Return type:
- pycsamt.models.mare2dem.is_emdata_file(path)#
Return
Truewhen path is a MARE2DEM observed-data file.
- pycsamt.models.mare2dem.is_resistivity_file(path)#
Return
Truewhen path is a MARE2DEM resistivity model file.
- pycsamt.models.mare2dem.is_settings_file(path)#
Return
Truewhen path is a MARE2DEM settings file.
- pycsamt.models.mare2dem.is_log_file(path)#
Return
Truewhen path is a MARE2DEM log file.
- pycsamt.models.mare2dem.is_response_file(path)#
Return
Truewhen path is a MARE2DEM predicted-response file.
- pycsamt.models.mare2dem.code_label(code)#
Return
"Component — Representation"for an integer data code.- Parameters:
code (int) – Integer data-type code from the DATA block of a
.emdatafile.- Returns:
Human-readable label, e.g.
"Zxy (TE) — Phase"or"Unknown (code=7)".- Return type:
Examples
>>> code_label(104) 'Zxy (TE) — Phase' >>> code_label(27) 'Ex — Log10 Amplitude'
- pycsamt.models.mare2dem.code_component(code)#
Return the EM component name for code, or
""if unknown.
- pycsamt.models.mare2dem.code_representation(code)#
Return the representation name for code, or
""if unknown.
- pycsamt.models.mare2dem.is_mt_code(code)#
Return
Truewhen code belongs to the MT data type range.
- pycsamt.models.mare2dem.is_csem_code(code)#
Return
Truewhen code belongs to the CSEM data type range.
- class pycsamt.models.mare2dem.EMDataFile(path=None, format='EMData_2.3', is_response=False, comment='', utm=<factory>, csem=None, mt=None, dc=None, data=<factory>)#
Bases:
objectComplete contents of one MARE2DEM
.emdataor.EMRespfile.- Variables:
path (pathlib.Path or None) – Source file path, if loaded from disk.
format (str) – Format string from the file header (e.g.
"EMData_2.3").is_response (bool) –
Truewhen the file is a response file (8-column DATA block).comment (str) – Optional free-text comment from the file header.
utm (UTMOrigin) – UTM origin metadata.
csem (CSEMConfig or None) – CSEM configuration section, or
Noneif absent.mt (MTConfig or None) – MT configuration section, or
Noneif absent.dc (DCConfig or None) – DC configuration section, or
Noneif absent.data (numpy.ndarray, shape (n_data, 6) or (n_data, 8)) – DATA block. Columns for observed data:
[type, freq#, tx#, rx#, data, std_err]. Response files add[response, residual].
- Parameters:
- csem: CSEMConfig | None = None#
- class pycsamt.models.mare2dem.UTMOrigin(grid=0, hemi='N', north0=0.0, east0=0.0, theta=0.0)#
Bases:
objectUTM mapping metadata for the 2-D profile.
- Variables:
- Parameters:
- class pycsamt.models.mare2dem.CSEMConfig(phase_convention='lag', reciprocity_used='', frequencies=<factory>, time_offsets=None, tdem_waveform=None, transmitters=<factory>, transmitter_type=<factory>, transmitter_name=<factory>, receivers=<factory>, receiver_name=<factory>)#
Bases:
objectCSEM source–receiver configuration and data parameters.
- Variables:
phase_convention (str) –
'lag'or'lead'.reciprocity_used (str) –
'yes','no', or''.frequencies (numpy.ndarray, shape (n_freq,)) – CSEM frequencies in Hz.
time_offsets (numpy.ndarray or None) – Time offsets for TDEM modeling.
tdem_waveform (numpy.ndarray or None) – TDEM waveform, shape (n_pts, 2).
transmitters (numpy.ndarray, shape (n_tx, 7)) – Columns: x, y, z, azimuth, dip, length, solve_corr.
transmitter_type (list of str) – Dipole type per transmitter (
'edipole'or'bdipole').receivers (numpy.ndarray, shape (n_rx, 8)) – Columns: x, y, z, theta, alpha, beta, length, solve_corr.
- Parameters:
- class pycsamt.models.mare2dem.MTConfig(frequencies=<factory>, receivers=<factory>, receiver_name=<factory>)#
Bases:
objectMT receiver configuration and frequency list.
- Variables:
frequencies (numpy.ndarray, shape (n_freq,)) – MT frequencies in Hz.
receivers (numpy.ndarray, shape (n_rx, 8)) – Columns: x, y, z, theta, alpha, beta, length, solve_static.
receiver_name (list of str) – Receiver labels (station names).
- Parameters:
- class pycsamt.models.mare2dem.DCConfig(tx_electrodes=<factory>, rx_electrodes=<factory>, transmitters=<factory>, receivers=<factory>, transmitter_name=<factory>, receiver_name=<factory>)#
Bases:
objectDC resistivity electrode and receiver configuration.
- Variables:
tx_electrodes (numpy.ndarray, shape (n_tx_el, 3)) – Transmitter electrode positions (x, y, z).
rx_electrodes (numpy.ndarray, shape (n_rx_el, 3)) – Receiver electrode positions (x, y, z).
transmitters (numpy.ndarray, shape (n_tx, 2)) – Integer electrode-index pairs (A, B) for each transmitter.
receivers (numpy.ndarray, shape (n_rx, 2)) – Integer electrode-index pairs (M, N) for each receiver.
- Parameters:
- pycsamt.models.mare2dem.read_emdata(path, *, silent=False)#
Read a MARE2DEM
.emdataor.EMRespfile.Port of
m2d_readEMData2DFile.m.- Parameters:
path (path-like) – File to read.
silent (bool, default False) – Suppress warnings on unrecognised format strings.
- Returns:
Parsed file contents.
- Return type:
- Raises:
FileNotFoundError – When path does not exist.
ValueError – When the format string in the header is not recognised and
silent=False.
Examples
>>> from pycsamt.models.mare2dem.iotools.emdata import read_emdata >>> em = read_emdata("survey.emdata") >>> em.n_mt_receivers 12
- pycsamt.models.mare2dem.write_emdata(em, path)#
Write an
EMDataFileto path.Port of
m2d_writeEMData2DFile.m.- Parameters:
em (EMDataFile) – Data to write.
path (path-like) – Destination
.emdatafile.
- Returns:
Path of the written file.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.iotools.emdata import write_emdata >>> write_emdata(em, "survey_out.emdata") PosixPath('survey_out.emdata')
- class pycsamt.models.mare2dem.ResistivityFile(resistivity_file='mare2dem.resistivity', poly_file='mare2dem.poly', data_file='mare2dem.emdata', settings_file='mare2dem.settings', version='mare2dem_1.1', anisotropy='isotropic', target_misfit=1.0, max_iterations=100, iteration=0, log10_lagrange=5.0, roughness=None, misfit=None, date_time='', bounds_transform='bandpass', global_bounds=<factory>, roughness_penalty_method='gradient', yz_penalty_weights=<factory>, penalty_cut_weight=0.1, roughness_with_prejudice=False, beta_mgs=0.0, anisotropy_penalty_weight=None, anisotropy_ratio_roughness_weight=None, debug_level=1, inversion_method='occam', rms_threshold=0.85, converge_slowly='no', resistivity=<factory>, free_parameter=<factory>, bounds=<factory>, prejudice=<factory>, data_group_file='', joint_inv_weight_type='', penalty_file='', fixed_mu_cut=None)#
Bases:
objectContents of one MARE2DEM
.resistivityfile.- Variables:
resistivity_file (str) – Output filename (used when writing).
poly_file (str) – Triangle mesh (
.poly) file stem referenced by this model.data_file (str) –
.emdatafile referenced by this model.settings_file (str) –
.settingsfile referenced by this model.version (str) – Format version string (e.g.
"mare2dem_1.1").anisotropy (str) – Anisotropy mode:
"isotropic"(default),"triaxial","tix","tiy","tiz","tiz_ratio","isotropic_ip","isotropic_complex".target_misfit (float) – Target normalized RMS misfit.
max_iterations (int) – Maximum inversion iterations.
iteration (int) – Current iteration number (output from inversion).
log10_lagrange (float) – Log10 Lagrange (regularization) trade-off value.
roughness (float or None) – Model roughness at this iteration.
misfit (float or None) – Normalized misfit at this iteration.
date_time (str) – Date/time stamp written by MARE2DEM.
bounds_transform (str) – Bounds transform type (
"bandpass").global_bounds (numpy.ndarray, shape (2,)) – Lower and upper log10-resistivity bounds.
roughness_penalty_method (str) – Smoothing type (
"gradient"or"first_difference").yz_penalty_weights (numpy.ndarray, shape (2,)) – Smoothing weights (y, z).
penalty_cut_weight (float) – Penalty cut weight.
roughness_with_prejudice (bool) – Use prejudice in regularization.
beta_mgs (float) – Minimum gradient support weight.
anisotropy_penalty_weight (float or None) – Anisotropic penalty weight.
anisotropy_ratio_roughness_weight (float or None) – Anisotropic ratio roughness weight.
debug_level (int) – Verbosity / print level.
inversion_method (str) – Inversion method string.
rms_threshold (float) – Misfit decrease threshold.
converge_slowly (str) –
"yes"or"no".resistivity (numpy.ndarray, shape (n_regions, nrho)) – Log10-resistivity per region per component.
free_parameter (numpy.ndarray, shape (n_regions, nrho)) – Free-parameter index (0 = fixed, >0 = free parameter number).
bounds (numpy.ndarray, shape (n_regions, 2*nrho)) – Lower / upper bounds per region component.
prejudice (numpy.ndarray, shape (n_regions, 2*nrho)) – Prejudice value and weight per region component.
- Parameters:
resistivity_file (str)
poly_file (str)
data_file (str)
settings_file (str)
version (str)
anisotropy (str)
target_misfit (float)
max_iterations (int)
iteration (int)
log10_lagrange (float)
roughness (float | None)
misfit (float | None)
date_time (str)
bounds_transform (str)
global_bounds (ndarray)
roughness_penalty_method (str)
yz_penalty_weights (ndarray)
penalty_cut_weight (float)
roughness_with_prejudice (bool)
beta_mgs (float)
anisotropy_penalty_weight (float | None)
anisotropy_ratio_roughness_weight (float | None)
debug_level (int)
inversion_method (str)
rms_threshold (float)
converge_slowly (str)
resistivity (ndarray)
free_parameter (ndarray)
bounds (ndarray)
prejudice (ndarray)
data_group_file (str)
joint_inv_weight_type (str)
penalty_file (str)
fixed_mu_cut (float | None)
- pycsamt.models.mare2dem.read_resistivity(path, *, no_data=False)#
Read a MARE2DEM
.resistivityfile.Port of
m2d_readResistivity.m.- Parameters:
path (path-like) – File to read.
no_data (bool, default False) – When
True, stop reading before the region resistivity table. Useful for quickly inspecting header metadata in large iteration output files.
- Returns:
Parsed file contents.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.iotools.resistivity import read_resistivity >>> rf = read_resistivity("mare2dem.resistivity") >>> rf.num_regions 1234
- pycsamt.models.mare2dem.write_resistivity(rf, path=None)#
Write a
ResistivityFileto path.Port of
m2d_writeResistivity.m.- Parameters:
rf (ResistivityFile) – Model to write.
path (path-like or None) – Destination file. When
None, usesrf.resistivity_file.
- Returns:
Path of the written file.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.iotools.resistivity import write_resistivity >>> write_resistivity(rf, "mare2dem_iter10.resistivity") PosixPath('mare2dem_iter10.resistivity')
- class pycsamt.models.mare2dem.PolyFile#
Bases:
objectContents of one Triangle
.polyPSLG file.- Variables:
nodes (numpy.ndarray, shape (n_nodes, 2)) – Node (x, y) coordinates. A MARE2DEM
.polyfile uses a right-handed coordinate system where the second coordinate is depth (z positive down).node_attributes (numpy.ndarray, shape (n_nodes, n_attr) or shape (0,)) – Optional per-node attribute values.
node_boundary_markers (numpy.ndarray, shape (n_nodes,) or shape (0,)) – Optional per-node boundary marker integers.
segments (numpy.ndarray, shape (n_segs, 2) with int dtype) – Segment endpoint node-index pairs (1-based).
segment_markers (numpy.ndarray, shape (n_segs,) or shape (0,)) – Optional per-segment boundary marker integers.
holes (numpy.ndarray, shape (n_holes, 2) or shape (0, 2)) – Hole point coordinates.
regions (numpy.ndarray, shape (n_reg, 4) or shape (0, 4)) – Region attribute and area-constraint points. Columns: x, y, attribute, max_area.
- pycsamt.models.mare2dem.read_poly(path)#
Read a Triangle
.polyPSLG file.Port of
m2d_readPoly.m.- Parameters:
path (path-like) – File to read. If the node count is zero (triangulation already done), the function automatically looks for the companion
.nodeand.elefiles in the same directory.- Returns:
Parsed PSLG contents.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.iotools.poly import read_poly >>> poly = read_poly("mare2dem.poly") >>> poly.n_nodes 4812
- pycsamt.models.mare2dem.write_poly(pf, path)#
Write a
PolyFileto path.Port of
m2d_writePoly.m.- Parameters:
pf (PolyFile) – PSLG data to write.
path (path-like) – Destination
.polyfile.
- Returns:
Path of the written file.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.iotools.poly import write_poly >>> write_poly(pf, "mare2dem.poly") PosixPath('mare2dem.poly')
- class pycsamt.models.mare2dem.SettingsFile(tolerance=1.0, tx_per_group=10, csem_rx_per_group=40, csem_freq_per_group=1, mt_rx_per_group=40, mt_freq_per_group=1, use_mesh_coarsening=True, use_mt_scattered_field=False, print_adaptive=True, print_decomposition=True)#
Bases:
objectParameters for one MARE2DEM
.settingsfile.- Variables:
tolerance (float) – Target solution accuracy in percent.
tx_per_group (int) – Maximum transmitters per parallel group (≤ 10 recommended).
csem_rx_per_group (int) – CSEM receivers per parallel group.
csem_freq_per_group (int) – CSEM frequencies per group (usually 1).
mt_rx_per_group (int) – MT receivers per parallel group.
mt_freq_per_group (int) – MT frequencies per group (usually 1).
use_mesh_coarsening (bool) – Enable moving-window mesh coarsening for long profiles.
use_mt_scattered_field (bool) – Use scattered-field MT formulation (for deep-water scenarios).
print_adaptive (bool) – Print adaptive refinement iteration stats.
print_decomposition (bool) – Print parallel decomposition settings.
- Parameters:
- pycsamt.models.mare2dem.write_settings(sf, path, *, overwrite=True)#
Write a MARE2DEM
.settingsfile.Port of
m2d_writeSettingsFile.m.- Parameters:
sf (SettingsFile) – Settings to write.
path (path-like) – Destination file.
overwrite (bool, default True) – If
Falseand the file already exists, return the existing path without writing.
- Returns:
Path of the written (or existing) file.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.iotools.settings import SettingsFile, write_settings >>> sf = SettingsFile(tx_per_group=5, csem_rx_per_group=20) >>> write_settings(sf, "mare2dem.settings") PosixPath('mare2dem.settings')
- class pycsamt.models.mare2dem.GroupRMSLog(path=None, headers=<factory>, rms_log=<factory>)#
Bases:
objectContents of one MARE2DEM group-RMS log file.
- Variables:
path (pathlib.Path or None) – Source file.
headers (list of str) – Column names from the first line of the file.
rms_log (numpy.ndarray, shape (n_iterations, n_groups)) – RMS values, one row per iteration.
- Parameters:
- pycsamt.models.mare2dem.read_group_rms_log(path)#
Read a MARE2DEM group-level RMS log file.
Port of
m2d_read_group_rms_log.m.- Parameters:
path (path-like) – CSV-like log file written by MARE2DEM.
- Returns:
Parsed log with headers and numeric RMS table.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.iotools.group_rms import read_group_rms_log >>> log = read_group_rms_log("mare2dem_group_rms.log") >>> log.n_iterations 42
- class pycsamt.models.mare2dem.DataGroupFile(path=None, comment='', group_names=<factory>, group_indices=<factory>)#
Bases:
objectContents of one MARE2DEM
.emdata_groupfile.- Variables:
path (pathlib.Path or None) – Source file path.
comment (str) – Optional free-text comment from the file header.
group_names (list of str) – Ordered list of group name strings.
group_indices (numpy.ndarray, shape (n_data,)) – 1-based group index for each datum. The value at position i selects the group name at
group_names[group_indices[i] - 1].
- Parameters:
- pycsamt.models.mare2dem.read_data_group(path)#
Read a MARE2DEM
.emdata_groupfile.Port of
m2d_readDataGroupFile.m.- Parameters:
path (path-like) – File to read (
Format: EMDataGroup_1.0).- Returns:
Parsed data-group file.
- Return type:
- Raises:
FileNotFoundError – When path does not exist.
ValueError – When the format string is not
EMDataGroup_1.0.
Examples
>>> from pycsamt.models.mare2dem.iotools.data_group import read_data_group >>> dg = read_data_group("survey.emdata_group") >>> dg.group_names ['MT', 'Seafloor CSEM', 'Towed CSEM']
- pycsamt.models.mare2dem.write_data_group(dg, path)#
Write a
DataGroupFileto path.Port of
m2d_writeDataGroupFile.m.- Parameters:
dg (DataGroupFile) – Data to write.
path (path-like) – Destination file.
- Returns:
Path of the written file.
- Return type:
- Raises:
ValueError – When
DataGroupFile.group_namesis empty orDataGroupFile.group_indicesare out of range.
Examples
>>> from pycsamt.models.mare2dem.iotools.data_group import DataGroupFile, write_data_group >>> import numpy as np >>> dg = DataGroupFile(group_names=["MT", "CSEM"], ... group_indices=np.array([1, 1, 2, 2])) >>> write_data_group(dg, "survey.emdata_group") PosixPath('survey.emdata_group')
- pycsamt.models.mare2dem.get_most_recent(file_or_keyword, pattern='*.resistivity', *, search_dir='.')#
Return the most recently modified file matching pattern.
Port of
m2d_getMostRecent.m.- Parameters:
file_or_keyword (str or path-like) – Either a literal file path, or one of the special keywords
'lastiter','last', or'newest'. When a keyword is given the function scans search_dir for files matching pattern and returns the most recently modified one.pattern (str, default “
*.resistivity”) – Glob pattern used when a keyword is given.search_dir (path-like, default ".") – Directory to search when a keyword is given.
- Returns:
Resolved file path, or
Nonewhen the keyword is used but no matching files are found.- Return type:
pathlib.Path or None
Examples
Load the latest inversion model:
>>> from pycsamt.models.mare2dem.iotools.most_recent import get_most_recent >>> path = get_most_recent("newest", "*.resistivity", search_dir="./run") >>> path PosixPath('run/mare2dem.0020.resistivity')
Use a literal path (pass-through):
>>> get_most_recent("mare2dem.0010.resistivity") PosixPath('mare2dem.0010.resistivity')
- pycsamt.models.mare2dem.parse_topo(topo, y)#
Interpolate topography to profile positions y.
Port of
m2d_parseTopo.m.- Parameters:
- Returns:
z (numpy.ndarray, shape (n,)) – Depth of the topographic surface at each y position.
slope_angle (numpy.ndarray, shape (n,)) – Surface slope angle in degrees, positive clockwise from the +y axis towards +z (down). Zero for flat topography.
on_node (numpy.ndarray of bool, shape (n,)) –
Truewhere a y position falls exactly on a topography node. The slope is not well-defined at these points.
- Return type:
Examples
Flat topography at depth 1000 m (e.g. flat seafloor):
>>> import numpy as np >>> from pycsamt.models.mare2dem.geom.topo import parse_topo >>> y = np.array([-5000.0, 0.0, 5000.0]) >>> z, slope, on_node = parse_topo(1000.0, y) >>> z array([1000., 1000., 1000.])
Variable topography:
>>> topo_xy = np.array([[0.0, 500.0], [5000.0, 1000.0], [10000.0, 800.0]]) >>> z, slope, on_node = parse_topo(topo_xy, np.array([2500.0, 5000.0]))
- pycsamt.models.mare2dem.topo_depth(topo, y)#
Return interpolated topographic depth at positions y.
Convenience wrapper around
parse_topo().
- pycsamt.models.mare2dem.topo_slope(topo, y)#
Return topographic slope angle (degrees) at positions y.
Convenience wrapper around
parse_topo().
- pycsamt.models.mare2dem.get_intersections(xya, xyb, *, tol=np.float64(2.220446049250313e-13))#
Find intersections between segments in xya and segment xyb.
Port of
m2d_getIntersections.m.- Parameters:
- Returns:
intersect (numpy.ndarray of int) – Original row indices in xya where an interior intersection with xyb exists.
xi (numpy.ndarray of float) – x coordinates of intersection points.
yi (numpy.ndarray of float) – y coordinates of intersection points.
pa (numpy.ndarray of float, shape (n_a,)) – Parametric position along each segment in xya (
-1for segments not tested).pb (numpy.ndarray of float, shape (n_a,)) – Parametric position along xyb (
-1for untested).
- Return type:
Examples
>>> import numpy as np >>> from pycsamt.models.mare2dem.geom.intersections import get_intersections >>> segs_a = np.array([[0.0, 2.0, 1.0, 1.0]]) # horizontal segment >>> seg_b = np.array([1.0, 1.0, 0.0, 2.0]) # vertical segment >>> inter, xi, yi, pa, pb = get_intersections(segs_a, seg_b) >>> xi array([1.]) >>> yi array([1.])
- pycsamt.models.mare2dem.do_rects_overlap(a_rect, many_rects, *, tol=np.float64(2.220446049250313e-14))#
Return indices of rows in many_rects that overlap a_rect.
Port of the inner
doRectsOverlapfunction inm2d_getIntersections.m.- Parameters:
- Returns:
Row indices of many_rects whose bounding boxes overlap a_rect.
- Return type:
numpy.ndarray of int
- pycsamt.models.mare2dem.dp_simplify(points, tolerance)#
Simplify a polyline using the Douglas-Peucker algorithm.
Port of
m2d_dpsimplify.m.- Parameters:
- Returns:
Simplified polyline with
m <= nvertices.- Return type:
numpy.ndarray, shape (m, 2)
Examples
>>> import numpy as np >>> from pycsamt.models.mare2dem.geom.simplify import dp_simplify >>> pts = np.column_stack([np.linspace(0, 10, 100), ... np.sin(np.linspace(0, np.pi, 100))]) >>> simplified = dp_simplify(pts, tolerance=0.05) >>> len(simplified) < 100 True
- pycsamt.models.mare2dem.simplify_poly(nodes, adjacency, *, tol=1e-10)#
Remove redundant interior nodes from a PSLG polygon.
Port of
m2d_simplify_poly.m.- Parameters:
nodes (array-like, shape (n_nodes, 2)) – Node (y, z) coordinates.
adjacency (array-like, shape (n_nodes, n_nodes)) – Dense or sparse symmetric adjacency matrix. A non-zero
adjacency[i, j]means node i and node j are connected by a segment. Diagonal entries are ignored (self-loops).tol (float, default 1e-10) – Collinearity tolerance used to identify redundant nodes.
- Returns:
nodes_out (numpy.ndarray, shape (m_nodes, 2)) – Pruned node array with redundant interior nodes removed.
adjacency_out (numpy.ndarray, shape (m_nodes, m_nodes)) – Updated adjacency matrix.
- Return type:
Examples
>>> import numpy as np >>> from pycsamt.models.mare2dem.geom.simplify_poly import simplify_poly >>> nodes = np.array([[0.,0.],[1.,0.],[2.,0.],[3.,0.]]) >>> adj = np.zeros((4,4)) >>> adj[0,1]=adj[1,0]=1; adj[1,2]=adj[2,1]=1; adj[2,3]=adj[3,2]=1 >>> n_out, a_out = simplify_poly(nodes, adj) >>> len(n_out) # interior collinear nodes 1 and 2 removed 2
- pycsamt.models.mare2dem.get_centroids(nodes, elements, tri_index)#
Compute area-weighted centroids of mesh regions.
Port of
m2d_getCentroids.m.- Parameters:
nodes (array-like, shape (n_nodes, 2)) – Node (y, z) coordinates.
elements (array-like, shape (n_elements, 3)) – Element connectivity (1-based indices accepted).
tri_index (array-like, shape (n_elements,)) – Region index for each triangle (1-based).
- Returns:
Columns: y_centroid, z_centroid, total_area of each region.
- Return type:
numpy.ndarray, shape (n_regions, 3)
Examples
>>> import numpy as np >>> from pycsamt.models.mare2dem.geom.centroids import get_centroids >>> nodes = np.array([[0.0, 0.0], [1.0, 0.0], [0.0, 1.0], [1.0, 1.0]]) >>> elems = np.array([[1, 2, 3], [2, 4, 3]]) >>> tri_idx = np.array([1, 1]) >>> get_centroids(nodes, elems, tri_idx) array([[0.5, 0.5, 1. ]])
- pycsamt.models.mare2dem.triangle_centroids(nodes, elements)#
Return the centroid of each triangle element.
- Parameters:
nodes (array-like, shape (n_nodes, 2)) – Node (y, z) coordinates.
elements (array-like, shape (n_elements, 3)) – Element connectivity, 0-based or 1-based node indices. The function detects 1-based indices automatically.
- Returns:
Per-element centroid coordinates.
- Return type:
numpy.ndarray, shape (n_elements, 2)
- pycsamt.models.mare2dem.triangle_areas(nodes, elements)#
Return the signed area of each triangle element.
- Parameters:
elements (array-like, shape (n_elements, 3))
- Returns:
Area of each triangle (absolute value).
- Return type:
- pycsamt.models.mare2dem.lonlat_to_utm(lon, lat, *, zone=None, south_hemi=None, ellipsoid='wgs84')#
Convert geographic longitude / latitude to UTM.
Port of
LonLat2UTM.m. Whenpyprojis installed the conversion is delegated to it; otherwise the pure-Python Snyder formulas are used.- Parameters:
lon (float or array-like) – Longitude in decimal degrees (−180 to +180).
lat (float or array-like) – Latitude in decimal degrees.
zone (int, optional) – Force a specific UTM zone. Auto-computed from median longitude when omitted.
south_hemi (bool, optional) – Force southern-hemisphere false northing. Auto-detected from median latitude when omitted.
ellipsoid (str, default "wgs84") – Ellipsoid name (see
ELLIPSOIDS).
- Returns:
easting (numpy.ndarray) – UTM easting in metres.
northing (numpy.ndarray) – UTM northing in metres.
zone (int) – UTM zone used.
south_hemi (bool) – Hemisphere flag used.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.geom.utm import lonlat_to_utm >>> e, n, zone, sh = lonlat_to_utm(-70.0, 42.0) >>> zone 19
- pycsamt.models.mare2dem.utm_to_lonlat(easting, northing, zone, south_hemi=False, *, ellipsoid='wgs84')#
Convert UTM coordinates to geographic longitude / latitude.
Port of
UTM2LonLat.m.- Parameters:
- Returns:
lon (numpy.ndarray) – Longitude in decimal degrees.
lat (numpy.ndarray) – Latitude in decimal degrees.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.geom.utm import utm_to_lonlat >>> lon, lat = utm_to_lonlat(330000.0, 4650000.0, 19, False)
- pycsamt.models.mare2dem.estimate_area_of_interest(em)#
Estimate the y and z limits for display or mesh generation.
Port of
m2d_estimateAreaOfInterest.m.- Parameters:
em (EMDataFile) – Survey data file supplying MT, CSEM, and DC receiver / transmitter positions.
- Returns:
ylim (numpy.ndarray, shape (2,) or None) –
[y_min, y_max]recommended profile extent in metres.Nonewhen no survey geometry is available.zlim (numpy.ndarray, shape (2,) or None) –
[z_min, z_max]recommended depth extent in metres.Nonewhen no survey geometry is available.
- Return type:
Examples
>>> from pycsamt.models.mare2dem import read_emdata >>> from pycsamt.models.mare2dem.geom.area_of_interest import estimate_area_of_interest >>> em = read_emdata("survey.emdata") >>> ylim, zlim = estimate_area_of_interest(em) >>> ylim array([-5500., 5500.])
- pycsamt.models.mare2dem.get_triangle_regions(points, triangles, segments, region_seeds=None)#
Assign each triangle to a numbered region.
Port of
m2d_getTriangleRegions.m.- Parameters:
points (array-like, shape (n_nodes, 2)) – Node (y, z) coordinates.
triangles (array-like, shape (n_tri, 3)) – Triangle connectivity, 1-based node indices.
segments (array-like, shape (n_segs, 2)) – Boundary segment node-index pairs (1-based) that separate regions.
region_seeds (array-like, shape (n_seeds, 2) or None) – One seed point per pre-defined region. Each seed is a (y, z) coordinate inside a region. Pass
Noneif no pre-defined seeds are given; all regions are then discovered automatically.
- Returns:
tri_index (numpy.ndarray, shape (n_tri,)) – Region index for each triangle (1-based).
region_map (numpy.ndarray, shape (n_new_regions,)) – Maps new region indices back to input seed indices (1-based); 0 for regions with no corresponding seed.
- Return type:
Notes
The algorithm builds a sparse adjacency matrix from the boundary segments, zeros out neighbour links that cross boundaries, then performs a BFS flood fill from each seed (or from untouched triangles after the seed pass).
Examples
>>> import numpy as np >>> from pycsamt.models.mare2dem.geom.triangle_regions import get_triangle_regions >>> pts = np.array([[0.,0.],[1.,0.],[0.5,1.]]) >>> tris = np.array([[1,2,3]]) >>> segs = np.array([[1,2]]) >>> tri_index, region_map = get_triangle_regions(pts, tris, segs) >>> tri_index array([1])
- pycsamt.models.mare2dem.get_line_orientation(northings, eastings)#
Estimate the survey profile orientation from station UTM positions.
Port of
m2d_getLineOrientation.m.The function fits a line to the input (northing, easting) pairs and returns its bearing. The result is in the range 0–180°:
0° / 180° → N–S profile
90° → E–W profile
- Parameters:
- Returns:
Line orientation in degrees clockwise from geographic north (0 ≤ result ≤ 180).
- Return type:
Examples
>>> import numpy as np >>> from pycsamt.models.mare2dem.geom.line_orientation import get_line_orientation >>> northings = np.array([0.0, 1000.0, 2000.0]) >>> eastings = np.array([0.0, 0.0, 0.0]) >>> get_line_orientation(northings, eastings) # N-S profile 0.0
- pycsamt.models.mare2dem.project_onto_line(northings, eastings, utm0_north, utm0_east, line_orientation)#
Project UTM (northing, easting) positions onto a survey profile.
- Parameters:
northings (array-like) – Station UTM northings in metres.
eastings (array-like) – Station UTM eastings in metres.
utm0_north (float) – Profile origin northing in metres.
utm0_east (float) – Profile origin easting in metres.
line_orientation (float) – Profile orientation in degrees clockwise from north.
- Returns:
x (numpy.ndarray) – Cross-profile (x) offset in metres.
y (numpy.ndarray) – Along-profile (y) offset in metres.
- Return type:
- class pycsamt.models.mare2dem.MTSurveyConfig(frequencies=<factory>, rx_y=<factory>, rx_type='marine', rx_z=None, rx_z_offset=None, rx_beta=None, rx_name=None, lTE=True, lTM=True, lZDet=False, lTipper=False, lTipperRealImag=False, lMTFields=False)#
Bases:
objectMT receiver and data-selection configuration.
- Parameters:
frequencies (array-like) – MT frequencies in Hz.
rx_y (array-like) – Receiver y positions along the 2-D profile.
rx_type (str) – Receiver placement mode:
'land','marine', or'amphibious'.rx_z (array-like or None) – Override receiver depth positions. When supplied, slope- based tilt angles are not computed.
rx_z_offset (float or array-like or None) – Offset from topography (< 0 above, > 0 below). Overrides the
rx_typedepth rule.rx_beta (float or array-like or None) – Override receiver beta (y-tilt) angles in degrees.
lTE (bool) – Include log10 apparent resistivity and phase (TE mode).
lTM (bool) – Include log10 apparent resistivity and phase (TM mode).
lZDet (bool) – Include impedance-determinant apparent resistivity and phase.
lTipper (bool) – Include TE tipper amplitude and phase.
lTipperRealImag (bool) – Include TE tipper real and imaginary parts.
lMTFields (bool) – Include TE and TM field vectors (Ex, Ey, Ez, Hx, Hy, Hz).
- class pycsamt.models.mare2dem.CSEMSurveyConfig(frequencies=<factory>, tx_y=<factory>, rx_y=None, rx_r=None, tx_z=None, tx_z_offset=None, rx_z=None, rx_z_offset=None, rx_type='marine', tx_type='edipole', tx_azimuth=None, tx_dip=None, tx_length=None, rx_length=None, rx_beta=None, tx_name=None, rx_name=None, phase_convention='lag', min_range=None, max_range=None, lEx=True, lEy=False, lEz=False, lBx=False, lBy=False, lBz=False)#
Bases:
objectCSEM source–receiver and data-selection configuration.
- Parameters:
frequencies (array-like) – CSEM frequencies in Hz.
tx_y (array-like) – Transmitter y positions.
rx_y (array-like or None) – Receiver y positions. Mutually exclusive with rx_r.
rx_r (array-like or None) – Towed receiver offsets from transmitter positions.
tx_z (array-like or None) – Override transmitter depth positions.
tx_z_offset (float or array-like or None) – Transmitter offset relative to topography.
rx_z (array-like or None) – Override receiver depth positions.
rx_z_offset (float or array-like or None) – Receiver offset relative to topography.
rx_type (str) – Receiver placement mode.
tx_type (str) – Dipole type:
'edipole'or'bdipole'.tx_azimuth (float or array-like or None) – Transmitter azimuth (degrees from x towards y).
tx_dip (float or array-like or None) – Transmitter dip (degrees positive down).
tx_length (float or array-like or None) – Electric dipole length in metres.
rx_length (float or array-like or None) – Receiver dipole length in metres.
rx_beta (float or array-like or None) – Receiver beta (y-tilt) angles in degrees.
phase_convention (str) –
'lag'(default) or'lead'.min_range (float or None) – Minimum Tx–Rx range to include in data file.
max_range (float or None) – Maximum Tx–Rx range.
lEx (bool) – Include Ex log10 amplitude and phase.
lEy (bool)
lEz (bool)
lBx (bool)
lBy (bool)
lBz (bool)
- pycsamt.models.mare2dem.make_data_file(out_file, topo, *, mt=None, csem=None, file_type='forward', comment='Created by pycsamt make_data_file', utm=None)#
Create a MARE2DEM
.emdatafile from survey parameters.Port of
m2d_makeDataFile.m.- Parameters:
out_file (path-like) – Output
.emdatafilename.topo (float or array-like (n, 2)) – Topography: scalar depth (flat) or
[y, z]table.mt (MTSurveyConfig, optional) – MT receiver/data configuration.
csem (CSEMSurveyConfig, optional) – CSEM transmitter/receiver/data configuration.
file_type (str, default "forward") –
"forward"or"inversion"(inversion data not yet implemented).comment (str) – Optional comment written on the second line of the file.
utm (UTMOrigin, optional) – UTM mapping metadata.
- Returns:
The constructed data object (also written to out_file).
- Return type:
Examples
MT forward dataset at 10 frequencies, 20 land stations:
>>> import numpy as np >>> from pycsamt.models.mare2dem.survey import MTSurveyConfig, make_data_file >>> freqs = np.logspace(-3, 3, 10) >>> rx_y = np.linspace(-10000, 10000, 20) >>> mt_cfg = MTSurveyConfig(frequencies=freqs, rx_y=rx_y, rx_type="land", lTE=True, lTM=True) >>> em = make_data_file("survey.emdata", topo=0.0, mt=mt_cfg) >>> em.n_mt_receivers 20
- class pycsamt.models.mare2dem.ZMMStation(name='', latitude=0.0, longitude=0.0, declination=0.0, periods=<factory>, apres_te=<factory>, phase_te=<factory>, apres_te_se=<factory>, phase_te_se=<factory>, apres_tm=<factory>, phase_tm=<factory>, apres_tm_se=<factory>, phase_tm_se=<factory>, tipper_zy=None, tipper_zy_se=None, x_profile=0.0, y_profile=0.0, z_profile=0.0)#
Bases:
objectImpedance tensor data from one
.zmmfile.- Variables:
name (str) – Station name.
latitude (float) – Geographic latitude in decimal degrees.
longitude (float) – Geographic longitude in decimal degrees.
declination (float) – Geomagnetic declination to apply (degrees).
periods (numpy.ndarray) – Period samples in seconds.
apres_te (numpy.ndarray) – TE-mode apparent resistivity (Ω·m).
phase_te (numpy.ndarray) – TE-mode phase (degrees).
apres_te_se (numpy.ndarray) – TE apparent resistivity standard error.
phase_te_se (numpy.ndarray) – TE phase standard error (degrees).
apres_tm (numpy.ndarray) – TM-mode apparent resistivity.
phase_tm (numpy.ndarray) – TM-mode phase.
apres_tm_se (numpy.ndarray)
phase_tm_se (numpy.ndarray)
tipper_zy (numpy.ndarray or None) – Complex TE tipper values.
tipper_zy_se (numpy.ndarray or None) – Tipper standard errors.
- Parameters:
name (str)
latitude (float)
longitude (float)
declination (float)
periods (ndarray)
apres_te (ndarray)
phase_te (ndarray)
apres_te_se (ndarray)
phase_te_se (ndarray)
apres_tm (ndarray)
phase_tm (ndarray)
apres_tm_se (ndarray)
phase_tm_se (ndarray)
tipper_zy (ndarray | None)
tipper_zy_se (ndarray | None)
x_profile (float)
y_profile (float)
z_profile (float)
- pycsamt.models.mare2dem.read_zmm(path)#
Read one EMTF
.zmmimpedance file.- Parameters:
path (path-like) – File to read.
- Returns:
Parsed station data.
- Return type:
- Raises:
FileNotFoundError – When path does not exist.
Notes
The reader parses the ZMM 2-column-per-component format:
- Period ZXX.r ZXX.i ZXY.r ZXY.i ZYX.r ZYX.i ZYY.r ZYY.i
TZX.r TZX.i TZY.r TZY.i Coh_XY Coh_YX
Apparent resistivities and phases are derived from the complex impedance components ZXY (TE) and ZYX (TM) using:
ρ_a = |Z|² / (ω · μ₀) φ = atan2(Z.imag, Z.real)
where
ω = 2π / Tandμ₀ = 4π × 10⁻⁷H/m.
- pycsamt.models.mare2dem.make_mt_data_from_zmm(zmm_files, out_file, *, output_modes='all', error_floor_te=0.0, error_floor_tm=0.0, error_floor_tipper=0.0, omit_periods=None, line_orientation=None, declination=0.0, utm0=None, utm_zone='', topo=0.0, rx_z_offset=-0.1)#
Create a MARE2DEM MT data file from a list of
.zmmfiles.Port of
m2d_makeMTDataFromZmm.m.- Parameters:
zmm_files (list of path-like) –
.zmmimpedance files in profile order.out_file (path-like) – Output
.emdatafilename.output_modes (str, default "all") – Comma-separated data types to include:
"TE","TM","tipper","TE+tipper","all impedance", or"all"(TE + TM + tipper).error_floor_te (float) – Relative error floor for TE (e.g. 0.05 = 5 %).
error_floor_tm (float) – Relative error floor for TM.
error_floor_tipper (float) – Absolute tipper error floor.
omit_periods (array-like, shape (n, 2) or None) – Period bands to omit: each row is
[T_min, T_max]in seconds.line_orientation (float or None) – Profile orientation in degrees clockwise from North. Auto-fit from station positions when
None.declination (float, default 0.0) – Geomagnetic declination correction in degrees.
utm0 ((float, float) or None) – Profile UTM origin
(northing, easting)in metres.utm_zone (str, default "") – UTM zone string, e.g.
"19N". Auto-detected when empty.topo (float or array-like) – Topography for receiver placement (see
parse_topo()).rx_z_offset (float, default -0.1) – Vertical offset of receivers relative to topography (m). Negative → above (marine), positive → below (land).
- Returns:
Constructed data file (also written to out_file).
- Return type:
Examples
>>> from pycsamt.models.mare2dem.zmm import make_mt_data_from_zmm >>> em = make_mt_data_from_zmm( ... ["S001.zmm", "S002.zmm"], ... "line1_mt.emdata", ... output_modes="TE+tipper", ... error_floor_te=0.05, ... ) >>> em.n_mt_receivers 2
- pycsamt.models.mare2dem.make_mt_data_from_stations(stations, out_file, *, output_modes='all', error_floor_te=0.0, error_floor_tm=0.0, error_floor_tipper=0.0, omit_periods=None, line_orientation=None, declination=0.0, utm0=None, utm_zone='', topo=0.0, rx_z_offset=-0.1)#
Create a MARE2DEM MT data file from prepared
ZMMStationobjects.Backend shared by
make_mt_data_from_zmm()(stations parsed from.zmmfiles) andpycsamt.models.mare2dem.edi.make_mt_data_from_edi()(stations converted from EDI impedances). Seemake_mt_data_from_zmm()for the parameter documentation; the only difference is that stations are supplied directly.
- pycsamt.models.mare2dem.stations_from_edi(source, *, default_rel_error=0.05, confidence_weighting=False, confidence_method='composite', confidence_weights=None, confidence_min=0.05, confidence_power=1.0)#
Convert an EDI source into
ZMMStationobjects.- Parameters:
source (path-like, Sites, or EDI collection) – Anything accepted by
pycsamt.emtools._core.ensure_sites().default_rel_error (float, default 0.05) – Relative impedance error assumed when the EDIs carry no error block (5 %). Error floors applied later can only raise it.
confidence_weighting (bool, default False) – If
True, inflate the relative impedance errors by the frequency-level confidence ratio (CR) before apparent-resistivity and phase standard errors are computed.confidence_method (str) – Passed to
pycsamt.emtools.qc.frequency_confidence_table().confidence_weights (Mapping[str, float] | None) – Passed to
pycsamt.emtools.qc.frequency_confidence_table().confidence_min (float, default 0.05) – Lower bound applied to CR before inverting it. This prevents one severely degraded datum from producing infinite uncertainty.
confidence_power (float, default 1.0) – Exponent in the uncertainty multiplier
(1 / max(CR, confidence_min)) ** confidence_power.
- Returns:
One station per EDI with valid impedance, coordinates, and a frequency table matching the first station’s. TE is Zxy, TM is Zyx; apparent resistivity uses the field-units convention ρ_a = 0.2 |Z|² / f and TM phase is wrapped by +180° into the first quadrant (same conventions as
read_zmm()).- Return type:
list of ZMMStation
- Raises:
ValueError – When no station yields usable impedance + coordinates.
- pycsamt.models.mare2dem.make_mt_data_from_edi(source, out_file, *, output_modes='all', error_floor_te=0.05, error_floor_tm=0.05, error_floor_tipper=0.0, default_rel_error=0.05, confidence_weighting=False, confidence_method='composite', confidence_weights=None, confidence_min=0.05, confidence_power=1.0, **kwargs)#
Create a MARE2DEM MT
.emdatafile from EDI data.- Parameters:
source (path-like, Sites, or EDI collection) – Anything accepted by
pycsamt.emtools._core.ensure_sites().out_file (path-like) – Output
.emdatafilename.output_modes (str) – See
make_mt_data_from_zmm().error_floor_te (float) – See
make_mt_data_from_zmm().error_floor_tm (float) – See
make_mt_data_from_zmm().error_floor_tipper (float) – See
make_mt_data_from_zmm().default_rel_error (float, default 0.05) – Assumed relative impedance error when the EDIs carry none.
confidence_weighting (bool, default False) – If enabled, CR-derived uncertainty inflation is applied before MARE2DEM data weights are written. The propagated errors are
sigma_rho = 2 rho sigma_Z/|Z|andsigma_phi = degrees(sigma_Z/|Z|)after multiplying the relative impedance error by(1 / max(CR, confidence_min)) ** confidence_power.**kwargs (Any) – Remaining keyword arguments of
make_mt_data_from_stations()(omit_periods,line_orientation,utm0,utm_zone,topo,rx_z_offset,declination).confidence_method (str)
confidence_min (float)
confidence_power (float)
**kwargs
- Returns:
Constructed data file (also written to out_file).
- Return type:
Examples
>>> from pycsamt.models.mare2dem.edi import make_mt_data_from_edi >>> em = make_mt_data_from_edi( ... "data/AMT/WILLY_DATA/L22PLT", ... "run/mare2dem.emdata", ... error_floor_te=0.05, error_floor_tm=0.05, ... ) >>> em.n_mt_receivers 25
- class pycsamt.models.mare2dem.NoiseConfig(mt_rel_noise=0.05, mt_rel_noise_tipper=0.01, mt_abs_noise_tipper=0.01, csem_rel_noise_e=0.05, csem_rel_noise_b=0.05, max_sigma_factor=2.0)#
Bases:
objectPer-data-type noise specifications.
- Variables:
mt_rel_noise (float) – Relative noise for MT apparent resistivity (e.g. 0.05 = 5 %). Phase noise is
mt_rel_noise / 2.mt_rel_noise_tipper (float) – Relative noise for tipper real/imaginary components.
mt_abs_noise_tipper (float) – Absolute noise floor for tipper. Tipper data with amplitude below this value are dropped (NaN).
csem_rel_noise_e (float) – Relative noise for CSEM electric-field responses.
csem_rel_noise_b (float) – Relative noise for CSEM magnetic-field responses.
max_sigma_factor (float, default 2.0) – Clip noise at this many standard deviations to avoid unrealistically large random draws (matches MATLAB
abs(randn) > 2clipping).
- Parameters:
- pycsamt.models.mare2dem.add_synthetic_noise(em, noise, *, seed=None)#
Add synthetic Gaussian noise to MARE2DEM response data.
Port of
m2d_addSyntheticNoise.m.The function reads predicted responses from column 7 of the 8-column DATA block (
is_response=True), adds noise according to noise, and stores the result in columns 5 and 6 (data, std_err). The output DATA block has 6 columns (observed-data format).- Parameters:
em (EMDataFile) – Response file with 8-column DATA block (
Format: EMResp_2.3).noise (NoiseConfig) – Noise specification.
seed (int or None, default None) – Random-number generator seed for reproducibility.
- Returns:
New
EMDataFilewith 6-column DATA block containing the noisy synthetic data and standard errors.- Return type:
- Raises:
ValueError – When
em.datadoes not have 8 columns (not a response file).
Examples
>>> from pycsamt.models.mare2dem import read_emdata >>> from pycsamt.models.mare2dem.noise import NoiseConfig, add_synthetic_noise >>> resp = read_emdata("forward.EMResp") >>> nc = NoiseConfig(mt_rel_noise=0.05) >>> noisy = add_synthetic_noise(resp, nc, seed=42) >>> noisy.n_data 200
- pycsamt.models.mare2dem.make_synthetic_data(in_file, out_file, noise, *, seed=None)#
Read a MARE2DEM response file, add noise, and write a data file.
Port of
m2d_makeSyntheticData.m.- Parameters:
in_file (path-like) – MARE2DEM response file (
.EMResp) with 8-column DATA block.out_file (path-like) – Output
.emdatafile with 6-column noisy DATA block.noise (NoiseConfig) – Noise specification.
seed (int or None, default None) – RNG seed for reproducibility.
- Returns:
The noisy data object (also written to out_file).
- Return type:
Examples
>>> from pycsamt.models.mare2dem.noise import NoiseConfig, make_synthetic_data >>> nc = NoiseConfig(mt_rel_noise=0.05, csem_rel_noise_e=0.05) >>> em = make_synthetic_data("forward.EMResp", "synthetic.emdata", nc, seed=0)
- pycsamt.models.mare2dem.merge_data_files(files_to_merge, out_file, *, keep_duplicate_rx=False)#
Merge MARE2DEM
.emdatafiles and write the result.Port of
m2d_mergeDataFiles.m.- Parameters:
- Returns:
Merged file contents (also written to out_file).
- Return type:
Examples
>>> from pycsamt.models.mare2dem.merge import merge_data_files >>> em = merge_data_files(["mt.emdata", "csem.emdata"], "joint.emdata") >>> em.n_data 3200
- pycsamt.models.mare2dem.merge_emdata(files, *, keep_duplicate_rx=False, comment='')#
Merge a list of
EMDataFileobjects into one.- Parameters:
files (list of EMDataFile) – At least two files to merge.
keep_duplicate_rx (bool, default False) – When
True, identical receiver locations are kept separate (needed for towed CSEM arrays with identical offsets).comment (str) – Comment written into the merged output file header.
- Returns:
Merged data file (not yet written to disk).
- Return type:
- Raises:
ValueError – When fewer than two files are given, or when UTM origins differ.
- pycsamt.models.mare2dem.grid_to_mare2dem(Y, Z, Rho, *, padding_y=50000.0, padding_z=50000.0, out_dir='.', model_name='mare2dem', data_file='mare2dem.emdata', target_misfit=1.0, max_iterations=100)#
Create a MARE2DEM model from a regular 2-D resistivity grid.
Port of
m2d_gridToM2D.m.- Parameters:
Y (array-like, shape (nz, ny)) – y-coordinates (along-profile) of grid cell centres in metres. Values must vary along columns; all rows for the same column share the same y value.
Z (array-like, shape (nz, ny)) – Depth coordinates of grid cell centres in metres (positive down). Values must vary along rows; all columns for the same row share the same z value.
Rho (array-like, shape (nz, ny)) – Resistivity at each cell centre in Ω·m.
padding_y (float, default 50000.0) – Lateral padding in metres added outside the grid.
padding_z (float, default 50000.0) – Vertical padding in metres added below and above the grid.
out_dir (path-like, default ".") – Output directory.
model_name (str, default "mare2dem") – Stem name used for all output files.
data_file (str, default "mare2dem.emdata") – Name of the associated data file written into the model header.
target_misfit (float, default 1.0) – Target normalized RMS misfit.
max_iterations (int, default 100) – Maximum inversion iterations.
- Returns:
Keys
"resistivity","poly","settings".- Return type:
Examples
>>> import numpy as np >>> from pycsamt.models.mare2dem.grid_to_m2d import grid_to_mare2dem >>> y1d = np.linspace(-5000, 5000, 21) >>> z1d = np.linspace(0, 3000, 11) >>> Y, Z = np.meshgrid(y1d, z1d) >>> Rho = np.ones_like(Y) * 10.0 # 10 Ω·m half-space >>> files = grid_to_mare2dem(Y, Z, Rho, out_dir="/tmp/m2d_grid_test") >>> files["resistivity"].exists() True
- class pycsamt.models.mare2dem.TopoConfig(topo_file='', col_longitude=None, col_latitude=None, col_elevation_m=None, col_depth_m=None, col_distance_km=None, col_distance_m=None)#
Bases:
objectConfiguration for loading one topography file.
- Variables:
topo_file (str or path-like) – Path to the topography file (whitespace-separated columns).
col_longitude (int or None) – 1-based column index for longitude. Required when the file has geographic coordinates.
col_latitude (int or None) – 1-based column index for latitude.
col_elevation_m (int or None) – 1-based column for elevation in metres (positive up). Mutually exclusive with col_depth_m.
col_depth_m (int or None) – 1-based column for depth in metres (positive down).
col_distance_km (int or None) – 1-based column for along-profile distance in km.
col_distance_m (int or None) – 1-based column for along-profile distance in metres.
- Parameters:
- class pycsamt.models.mare2dem.TopoProfile(y_topo, z_topo, northings=None, eastings=None)#
Bases:
objectLoaded and projected topography profile.
- Variables:
y_topo (numpy.ndarray) – Along-profile position in metres (MARE2DEM y axis).
z_topo (numpy.ndarray) – Depth in metres, positive down (MARE2DEM z axis).
northings (numpy.ndarray or None) – UTM northing (m) — present when converted from Lon/Lat.
eastings (numpy.ndarray or None) – UTM easting (m) — present when converted from Lon/Lat.
- Parameters:
- pycsamt.models.mare2dem.import_topo(cfg, *, utm_north0=0.0, utm_east0=0.0, utm_theta=0.0, utm_zone=None, south_hemi=False, orientation_tol=5.0)#
Import a topography file and project it onto the survey profile.
Port of
m2d_importTopo.m.- Parameters:
cfg (TopoConfig) – Column layout and file path.
utm_north0 (float) – Profile UTM origin northing (metres).
utm_east0 (float) – Profile UTM origin easting (metres).
utm_theta (float) – Profile UTM theta angle (degrees) — the
stUTM.thetafield from the.emdataUTM block. Note: the survey-line direction istheta + 90°.utm_zone (int or None) – UTM zone number. Required only when Lon/Lat input is used.
south_hemi (bool, default False) – Southern-hemisphere flag for UTM conversion.
orientation_tol (float, default 5.0) – Maximum allowed angle (degrees) between the topography profile orientation and the survey line orientation.
- Returns:
Projected topography (y, z) in MARE2DEM coordinates.
- Return type:
- Raises:
FileNotFoundError – When the topography file does not exist.
ValueError – When the topography and survey orientations differ by more than orientation_tol degrees.
Examples
>>> from pycsamt.models.mare2dem.import_topo import TopoConfig, import_topo >>> cfg = TopoConfig(topo_file="topo.txt", col_distance_km=1, col_depth_m=2) >>> prof = import_topo(cfg, utm_north0=0.0, utm_east0=0.0) >>> prof.y_topo array([0., ...])
- pycsamt.models.mare2dem.diff_resistivity(file1, file2, out_file, *, diff_fn=None)#
Difference two MARE2DEM resistivity files and write the result.
Port of
diffMARE2DEM_Resistivity.m.- Parameters:
file1 (path-like) – First
.resistivityfile (minuend, or reference model).file2 (path-like) – Second
.resistivityfile (subtrahend, or inverted model).out_file (path-like) – Destination
.resistivityfile for the difference model.diff_fn (callable or None, default None) –
Function
(A, B) -> Capplied element-wise to the resistivity arrays. Both A and B have shape(n_regions, nrho). The default is:lambda A, B: np.log10(A) - np.log10(B)
Custom alternatives:
Absolute percentage difference:
lambda A, B: np.abs((A - B) / A * 100)Linear difference:
lambda A, B: A - B
- Returns:
The difference resistivity model (also written to out_file).
- Return type:
- Raises:
ValueError – When the two files have different numbers of regions.
Examples
Default log10 difference:
>>> from pycsamt.models.mare2dem.diff import diff_resistivity >>> dm = diff_resistivity( ... "mare2dem_iter00.resistivity", ... "mare2dem_iter20.resistivity", ... "mare2dem_diff.resistivity", ... ) >>> dm.num_regions 4812
Percentage change:
>>> dm = diff_resistivity( ... "iter00.resistivity", ... "iter20.resistivity", ... "pct_change.resistivity", ... diff_fn=lambda A, B: np.abs((A - B) / A * 100), ... )
- class pycsamt.models.mare2dem.EMData(path=None, **kwargs)#
Bases:
objectThin wrapper around
EMDataFilefor backwards compatibility.Provides the same
path,header,data, andwrite()interface as the original stub while delegating to the full parser.- Parameters:
path (path-like, optional) – Source file. Read immediately when provided.
- class pycsamt.models.mare2dem.ResistivityModel(path=None, **kwargs)#
Bases:
objectThin wrapper around
ResistivityFilefor backwards compatibility.- Parameters:
path (path-like, optional) – Source
.resistivityfile.
- classmethod halfspace(log10_rho=0.0, *, n_nodes=0)#
Return a homogeneous half-space resistivity model stub.
- Parameters:
- Return type:
- class pycsamt.models.mare2dem.PolyMesh(path=None, **kwargs)#
Bases:
objectThin wrapper around
PolyFilefor backwards compatibility.- Parameters:
path (path-like, optional) – Source
.polyfile.
- class pycsamt.models.mare2dem.Mare2DEMLog(path)#
Bases:
objectParse the MARE2DEM per-iteration
OccamLog.2012.0log file.MARE2DEM writes one block per completed iteration containing
Model Misfit,Roughness, andOptimal Mulines. This parser extracts those values and exposes them asIterationRecordobjects.- Parameters:
path (path-like) – Path to the log file (usually
*.logfileor*.log).- Variables:
path (pathlib.Path)
iterations (list of IterationRecord)
converged (bool)
- class pycsamt.models.mare2dem.IterationRecord(iteration, rms, roughness, lambda_)#
Bases:
objectOne completed iteration from a MARE2DEM log file.
- Variables:
- Parameters:
- class pycsamt.models.mare2dem.InversionResult(workdir, config=None, **kwargs)#
Bases:
Mare2DEMBaseLoad and expose MARE2DEM inversion output files.
InversionResultscans a MARE2DEM run directory after the binary has finished and loads the iteration log, final resistivity model, observed-data file, and predicted-response file.- Parameters:
workdir (path-like) – Directory to scan for MARE2DEM output files.
config (Mare2DEMConfig, optional) – Configuration providing default file stems. When omitted, the scanner looks for any
.log,.resistivity,.emdata, and*_MARE2DEM.emdatafiles.**kwargs – Forwarded to
Mare2DEMBase.
- Variables:
workdir (pathlib.Path) – Absolute path of the scanned run directory.
config (Mare2DEMConfig) – Configuration used for file-name hints.
log (Mare2DEMLog or None) – Parsed iteration log.
model (ResistivityModel or None) – Final inverted resistivity model.
data (EMData or None) – Observed data file.
response (EMData or None) – Predicted-response file (
*_MARE2DEM.emdata).
Examples
>>> from pycsamt.models.mare2dem import InversionResult >>> result = InversionResult("./mare2dem_run") >>> result.log.final_rms 0.98 >>> result.log.converged True
- class pycsamt.models.mare2dem.Mare2DEMRunner(workdir, config=None, **kwargs)#
Bases:
Mare2DEMBaseLaunch MARE2DEM inversion subprocesses.
Mare2DEMRunneris the execution layer of the MARE2DEM wrapper. It receives the stem of a.resistivityfile prepared byInputBuilder, selects the configured MARE2DEM executable, and launches the MPI process fromworkdir. After the run it optionally loads output into anInversionResult.The command has the logical form:
mpirun -np 8 MARE2DEM mare2dem
where
mare2demis the stem ofmare2dem.resistivity.- Parameters:
workdir (path-like, default ".") – Directory that contains, or will receive, a MARE2DEM run. The builder writes the resistivity model, data, and settings files here. The runner executes the MARE2DEM binary from this directory so the input file stem is resolved relative to the run folder. The directory is created before output is written.
config (Mare2DEMConfig, optional) – Configuration object controlling the resistivity model, data component selection, inversion parameters, source management, executable name, and MPI settings. If omitted, a default
Mare2DEMConfigis created. Pass an explicit configuration when several MARE2DEM objects must share exactly the same run parameters.verbose (int or bool, default 0) – Verbosity level.
0orFalsekeeps the object quiet. Positive values enable diagnostic messages through the instance logger. Larger values may be used to request more detailed run, parsing, or build information.logger (logging.Logger, optional) – Logger for progress and diagnostic messages. If omitted, a class-specific PyCSAMT logger is created automatically. Provide a logger when integrating MARE2DEM workflows into an application-wide logging configuration.
- Variables:
workdir (pathlib.Path) – Directory from which the subprocess is launched.
config (Mare2DEMConfig) – Configuration used for binary name, MPI, and source management.
Notes
Binary resolution is performed by
_resolve_binary(), which first checksPATH, then delegates toSourceManager.resolve_binary()for locally compiled binaries.See also
SourceManagerDownload and compile the MARE2DEM binary.
InputBuilderWrite the resistivity model, data, and settings files.
InversionResultLoad MARE2DEM output after the run.
References
[1] Key, K. (2016). MARE2DEM: A 2-D inversion code for controlled-source electromagnetic and magnetotelluric data. Geophysical Journal International, 207(1), 571-588. doi:10.1093/gji/ggw290.
- run(resistivity_stem, *, use_mpi=None, n_procs=None, extra_args=None, timeout=None, load_result=True)#
Run a MARE2DEM inversion subprocess.
MARE2DEM receives one positional argument: the stem of the
.resistivityfile. It derives the data filename by replacing the extension with.emdataand the settings filename with.settings.- Parameters:
resistivity_stem (path-like) – Stem or full path to the
.resistivityfile. MARE2DEM strips the extension itself; you may pass either"run"or"run.resistivity". Relative paths are interpreted fromworkdir.use_mpi (bool, optional) – MPI override. Falls back to
config.use_mpi.n_procs (int, optional) – Number of MPI processes. Falls back to
config.n_procs.extra_args (sequence of str, optional) – Additional command-line arguments appended to the MARE2DEM invocation.
timeout (float, optional) – Maximum run time in seconds.
Nonemeans no timeout.load_result (bool, default True) – Whether to scan
workdirand return anInversionResultafter the run completes.
- Returns:
Parsed result object when
load_resultisTrue.Noneotherwise.- Return type:
InversionResult or None
- Raises:
FileNotFoundError – When the MARE2DEM binary cannot be located. Build it first with
SourceManager.subprocess.CalledProcessError – When MARE2DEM exits with a non-zero return code.
subprocess.TimeoutExpired – When
timeoutis set and the process exceeds it.
Examples
Serial run (special single-process build):
>>> from pycsamt.models.mare2dem import Mare2DEMConfig, Mare2DEMRunner >>> cfg = Mare2DEMConfig(use_mpi=False) >>> runner = Mare2DEMRunner("./mare2dem_run", config=cfg) >>> result = runner.run("mare2dem")
MPI run with 8 processes:
>>> cfg = Mare2DEMConfig(use_mpi=True, n_procs=8) >>> runner = Mare2DEMRunner("./mare2dem_run", config=cfg) >>> result = runner.run("mare2dem")
- command(resistivity_stem, *, use_mpi=None, n_procs=None)#
Return the MARE2DEM command string without executing it.
- Parameters:
- Returns:
Shell-quoted command string for display or logging.
- Return type:
Examples
>>> from pycsamt.models.mare2dem import Mare2DEMConfig, Mare2DEMRunner >>> cfg = Mare2DEMConfig(use_mpi=True, n_procs=4) >>> runner = Mare2DEMRunner("./run", config=cfg) >>> "mpirun" in runner.command("mare2dem") True
- class pycsamt.models.mare2dem.InputBuilder(config=None, **kwargs)#
Bases:
Mare2DEMBasePrepare a MARE2DEM working directory from survey parameters.
InputBuilderproduces the three required input files for a MARE2DEM inversion run:the
.emdataobserved-data file;the starting
.resistivitymodel;the
.settingsparallel-decomposition control file.
- Parameters:
config (Mare2DEMConfig, optional) – Configuration for inversion parameters and file names.
verbose (int or bool, default 0) – Verbosity level.
0orFalsekeeps the object quiet. Positive values enable diagnostic messages through the instance logger. Larger values may be used to request more detailed run, parsing, or build information.logger (logging.Logger, optional) – Logger for progress and diagnostic messages. If omitted, a class-specific PyCSAMT logger is created automatically. Provide a logger when integrating MARE2DEM workflows into an application-wide logging configuration.
Examples
Build from an existing
.emdatafile:>>> from pycsamt.models.mare2dem import Mare2DEMConfig, InputBuilder >>> cfg = Mare2DEMConfig(initial_rho=1.0, max_iterations=100) >>> builder = InputBuilder(config=cfg) >>> files = builder.build("survey.emdata", workdir="./run")
Build from MTSurveyConfig:
>>> import numpy as np >>> from pycsamt.models.mare2dem.survey import MTSurveyConfig >>> mt = MTSurveyConfig( ... frequencies=np.logspace(-3, 3, 10), ... rx_y=np.linspace(-5000, 5000, 20), ... rx_type="marine", lTE=True, lTM=True, ... ) >>> files = builder.build(None, workdir="./run", mt=mt)
See also
Mare2DEMRunnerLaunch MARE2DEM on the written input files.
make_data_fileLow-level data file generator.
- write_settings(workdir='.', *, filename=None, **sf_kwargs)#
Write the MARE2DEM
.settingsfile.- Parameters:
workdir (path-like, default ".") – Target directory.
filename (str, optional) – Override the settings filename.
**sf_kwargs – Extra keyword arguments forwarded to
SettingsFile.
- Returns:
Path of the written file.
- Return type:
- write_resistivity(workdir='.', *, filename=None, poly_file=None)#
Write a homogeneous half-space
.resistivityfile.- Parameters:
- Returns:
Path of the written file.
- Return type:
- build(source, workdir='.', *, topo=0.0, mt=None, csem=None, data_filename=None, model_filename=None, settings_filename=None)#
Write a MARE2DEM input set to workdir.
- Parameters:
source (path-like, EMDataFile, or None) – Existing
.emdatafile (copied to workdir) orNone(generate from mt/csem config objects).workdir (path-like, default ".") – Target directory.
topo (float or array-like) – Topography for receiver/transmitter placement (used only when source is
None).mt (MTSurveyConfig, optional) – MT survey config (used when source is
None).csem (CSEMSurveyConfig, optional) – CSEM survey config (used when source is
None).data_filename (str, optional) – Override data file name.
model_filename (str, optional) – Override resistivity model file name.
settings_filename (str, optional) – Override settings file name.
- Returns:
Keys:
"data","model","settings".- Return type:
- class pycsamt.models.mare2dem.PlotConvergence(log_or_result, **kwargs)#
Bases:
Mare2DEMBasePlot RMS misfit convergence from a MARE2DEM log.
- Parameters:
log_or_result (Mare2DEMLog or InversionResult) – Source of iteration records.
Examples
>>> from pycsamt.models.mare2dem import InversionResult, PlotConvergence >>> result = InversionResult("./run") >>> pc = PlotConvergence(result) >>> fig = pc.plot()
- plot(ax=None, *, savefig=None, dpi=150, target_rms=None)#
Draw the RMS-vs-iteration convergence curve.
- Parameters:
ax (matplotlib.axes.Axes | None)
dpi (int)
target_rms (float | None)
- Return type:
- class pycsamt.models.mare2dem.PlotSurveyLayout(em, **kwargs)#
Bases:
Mare2DEMBasePlot survey receiver and transmitter positions on a map.
Port of
plotMARE2DEM_SurveyLayout.m(map view only; GUI removed).- Parameters:
em (EMDataFile) – Data file supplying receiver / transmitter positions and the UTM origin metadata.
**kwargs – Forwarded to
Mare2DEMBase.
Examples
>>> from pycsamt.models.mare2dem import read_emdata >>> from pycsamt.models.mare2dem.plot import PlotSurveyLayout >>> em = read_emdata("survey.emdata") >>> fig = PlotSurveyLayout(em).plot()
- plot(ax=None, *, savefig=None, dpi=150, units='km')#
Draw the survey map: receivers and transmitters in UTM.
- Parameters:
ax (matplotlib.axes.Axes, optional) – Axes to draw on.
savefig (path-like, optional) – Save figure to this path.
dpi (int, default 150) – DPI for the saved figure.
units ({"m", "km"}, default "km") – Display units for axes labels.
- Return type:
- class pycsamt.models.mare2dem.PlotRxParams(em, **kwargs)#
Bases:
Mare2DEMBasePlot receiver geometry parameters (x, y, z, θ, α, β).
Port of the
plotRxParamssub-function inplotMARE2DEM_SurveyLayout.m.- Parameters:
em (EMDataFile) – Survey data file.
**kwargs – Forwarded to
Mare2DEMBase.
- class pycsamt.models.mare2dem.PlotTxParams(em, **kwargs)#
Bases:
Mare2DEMBasePlot CSEM transmitter geometry parameters (x, y, z, azimuth, dip).
Port of the
plotTxParamssub-function inplotMARE2DEM_SurveyLayout.m.- Parameters:
em (Any)
- pycsamt.models.mare2dem.plot_poly(poly_file, ax=None, *, linewidth=1.0, color='k', savefig=None, dpi=150)#
Plot a Triangle
.polyPSLG mesh file.Port of
m2d_plot_poly.m.- Parameters:
poly_file (path-like) – Path to the
.polyfile.ax (matplotlib.axes.Axes, optional) – Axes to draw on.
linewidth (float, default 1.0)
color (str, default "k")
savefig (path-like, optional)
dpi (int, default 150)
- Returns:
The axes with the PSLG drawn.
- Return type:
Examples
>>> from pycsamt.models.mare2dem.plot import plot_poly >>> ax = plot_poly("mare2dem.poly")
- class pycsamt.models.mare2dem.PlotModel(model_or_result, **kwargs)#
Bases:
Mare2DEMBasePlot the log10-resistivity 2-D section.
Renders a colour-filled triangular mesh via
matplotlib.axes.Axes.tripcolor()when Triangle mesh output files (.node+.ele) are found next to the.resistivityfile. Falls back to a histogram of region resistivity values when no mesh is present.- Parameters:
model_or_result (ResistivityModel or InversionResult) – Source of resistivity values and mesh location.
**kwargs – Forwarded to
Mare2DEMBase.
- plot(ax=None, *, savefig=None, dpi=150, cmap='turbo_r', vmin=None, vmax=None)#
Plot the 2-D resistivity section.
When Triangle mesh output files (
.node+.ele) are found next to the.resistivityfile, a colour-filled triangular section is rendered. Otherwise a histogram of resistivity values is shown.- Parameters:
ax (matplotlib.axes.Axes, optional) – Target axes. When
Nonea new figure is created.savefig (path-like, optional) – Save the figure to this path.
dpi (int, default 150) – Output resolution in dots per inch.
cmap (str, default
"turbo_r") – Colour map for the resistivity section.vmin (float, optional) – Lower log10-rho bound for the colour axis.
vmax (float, optional) – Upper log10-rho bound for the colour axis.
- Return type:
- class pycsamt.models.mare2dem.PlotResponse(result, **kwargs)#
Bases:
Mare2DEMBaseCompare observed and predicted MT responses.
Generates a per-receiver grid of subplots overlaying TE and TM apparent resistivity and phase versus period.
- Parameters:
result (InversionResult) – Inversion output containing observed data and MARE2DEM predicted response.
**kwargs – Forwarded to
Mare2DEMBase.
- plot(ax=None, *, savefig=None, dpi=150, station=None, max_rx=4, figsize=None)#
Plot observed vs predicted MT responses.
One figure row per receiver, two columns: apparent resistivity on the left and phase on the right.
- Parameters:
ax (matplotlib.axes.Axes, optional) – Ignored – the method creates its own figure.
savefig (path-like, optional) – Save the figure to this path.
dpi (int, default 150) – Output resolution in dots per inch.
station (str, optional) – Plot only this receiver by name. When
None, the first max_rx receivers are plotted.max_rx (int, default 4) – Maximum number of receivers when station is
None.
- Return type:
- Raises:
ValueError – When the result contains no MT data.