MARE2DEM#
pycsamt.models.mare2dem provides the pyCSAMT integration layer for
MARE2DEM, a 2.5-D finite-element electromagnetic modelling and inversion
code. MARE2DEM supports magnetotelluric (MT) and controlled-source
electromagnetic (CSEM) workflows, adaptive triangular meshes, topography, and
MPI execution.
pyCSAMT does not vendor the compiled MARE2DEM executable. Instead, it provides the tools needed to manage a MARE2DEM project around that executable:
configuration templates for source, binary, MPI, and file-name settings;
source download/build/location helpers;
native
.emdata,.resistivity,.poly,.settings, log, group RMS, and data-group readers/writers;survey builders for MT and CSEM synthetic or prepared data files;
ZMM-to-MARE2DEM MT data conversion;
geometry utilities for topography, UTM conversion, profile projection, polygon simplification, triangle-region assignment, and area-of-interest estimation;
input builders, runners, result loaders, plotting helpers, model-difference utilities, merge tools, and synthetic-noise helpers.
This page is a practical guide to those pieces. It focuses on how a user should prepare, run, inspect, and archive a MARE2DEM project from pyCSAMT.
When To Use MARE2DEM#
Use the MARE2DEM integration when a project needs a native 2.5-D finite-element workflow rather than a pyCSAMT built-in inversion. Common reasons include:
a survey geometry that is naturally profile-based but not adequately treated by a simple 1-D or 2-D approximation;
MT, CSEM, or combined data that must be represented in MARE2DEM’s native
.emdataformat;topography, seafloor, receiver, or transmitter geometry that should be explicitly represented;
adaptive triangular discretization through Triangle/PSLG
.polygeometry;existing MARE2DEM project files that need Python-side validation, conversion, plotting, or result loading;
an HPC workflow where native input files are prepared locally, run on a cluster, and loaded back into pyCSAMT afterward.
MARE2DEM is not the fastest path for every inversion. If you only need a high-level backend-neutral 2-D run, start with Choosing A Model Backend. MARE2DEM is most valuable when the native file set and engine-specific control are part of the scientific workflow.
Package Map#
The public MARE2DEM package surface is intentionally broad. It includes low level file readers, high level lifecycle helpers, and project utilities.
Area |
Main objects |
Purpose |
|---|---|---|
Configuration |
|
Stores source location, compiler overrides, binary/MPI settings, inversion controls, initial model value, and default file names. |
Source and binary |
|
Locates, downloads, builds, and reports status for the external MARE2DEM source tree and executable. |
Build inputs |
|
Writes a MARE2DEM run directory from an existing |
Execute |
|
Builds the command line, handles MPI options, runs the executable from
the working directory, and can return an |
Load results |
|
Scans output directories, parses iteration logs, exposes RMS history, convergence state, final model, observed data, and response data. |
Native I/O |
|
Reads and writes MARE2DEM-native project files. |
Data management |
|
Builds, converts, and merges MT/CSEM data products. |
Geometry |
|
Handles topography, survey projection, coordinate conversion, polygon cleanup, and triangle-region utilities. |
QC and interpretation |
|
Supports synthetic tests, model comparison, convergence review, survey layout QC, and mesh/geometry inspection. |
Configuration#
Mare2DEMConfig is the source-of-truth object for MARE2DEM runs. It is a
plain dataclass, so it can be created in Python, written as a template, edited
outside Python, and loaded again.
1from pycsamt.models.mare2dem import Mare2DEMConfig
2
3cfg = Mare2DEMConfig(
4 source_dir="/opt/mare2dem/source",
5 binary="MARE2DEM",
6 use_mpi=True,
7 n_procs=16,
8 mpi_command="mpirun",
9 max_iterations=120,
10 target_rms=1.0,
11 initial_rho=10.0,
12 data_file="line12.emdata",
13 resistivity_file="line12.resistivity",
14 settings_file="line12.settings",
15)
16
17cfg.to_template("runs/line12/mare2dem.yml")
18loaded = Mare2DEMConfig.from_file("runs/line12/mare2dem.yml")
The configuration groups five concerns.
Concern |
Fields |
Meaning |
|---|---|---|
Source management |
|
Where the Fortran source lives and which compiler commands should be used when building. |
Binary and MPI |
|
How pyCSAMT should locate and launch the executable. |
Inversion control |
|
Iteration limit and normalized RMS target written into the native model/settings files. |
Initial model |
|
Starting homogeneous half-space resistivity, in ohm metres. |
File names |
|
Native file names used by builders and runners. |
The resistivity_stem property returns the stem of
resistivity_file. MARE2DEM receives this stem on the command line and then
derives related filenames from it. For example, line12.resistivity is
passed as line12.
Source And Binary Management#
SourceManager handles the external source tree. It resolves a source
directory in this order:
the explicit
source_dirargument passed toSourceManager;Mare2DEMConfig.source_dir;the
PYCSAMT_MARE2DEM_SOURCEenvironment variable;the package
_source/directory when it is writable, which is common in editable development installs;a platform user-data directory.
Use status first, before trying to download or build anything.
1from pycsamt.models.mare2dem import Mare2DEMConfig, SourceManager
2
3cfg = Mare2DEMConfig(source_dir="/opt/mare2dem/source")
4source = SourceManager(config=cfg, verbose=1)
5
6status = source.status()
7print(status["source_dir"])
8print(status["downloaded"])
9print(status["built"])
10print(status["binary_path"])
When source code is not present, download can use Git or a source archive.
When source code is present but the binary is missing, build compiles the
external code.
1from pycsamt.models.mare2dem import SourceManager
2
3source = SourceManager(source_dir="/opt/mare2dem/source", verbose=1)
4
5# Network access and compiler availability are environment-dependent.
6# source.download(method="auto")
7# source.build(clean_first=False)
8
9source.print_status()
Compilation is system-dependent. In many environments MARE2DEM requires MPI Fortran/C tooling and Intel MKL/ScaLAPACK/BLACS support. On Windows, build from WSL or another Unix-like environment rather than a native Windows shell.
Binary Resolution#
Mare2DEMRunner resolves the executable through:
Mare2DEMConfig.binaryonPATH;<source_dir>/<binary>;the platform user-data binary location.
Use runner.command as a dry-run check before launching an inversion.
1from pycsamt.models.mare2dem import Mare2DEMConfig, Mare2DEMRunner
2
3cfg = Mare2DEMConfig(
4 binary="MARE2DEM",
5 use_mpi=True,
6 n_procs=8,
7 mpi_command="mpirun",
8 resistivity_file="line12.resistivity",
9)
10
11runner = Mare2DEMRunner("runs/line12/native", config=cfg)
12print(runner.command("line12"))
For cluster workflows, put the command string and the loaded module list in the
run provenance file. The same native directory can then be executed by a job
scheduler and loaded later with InversionResult.
Native Files#
MARE2DEM projects revolve around native text files. pyCSAMT treats these as first-class scientific records, not temporary build artifacts.
File |
Reader/writer |
Role |
|---|---|---|
|
|
Observed or synthetic MT/CSEM/DC data, receiver/transmitter metadata, UTM origin, frequencies, and data rows. |
|
|
Predicted response data produced by the engine. |
|
|
Resistivity parameters, free/fixed flags, bounds, prejudice values, and references to data, settings, and polygon files. |
|
|
Triangle PSLG geometry: nodes, segments, holes, and regions. |
|
|
Parallel decomposition and inversion settings. |
|
|
Group definitions used for grouped RMS diagnostics. |
Group RMS logs |
|
Per-group RMS evolution, useful for diagnosing which data families are controlling the inversion. |
Iteration logs |
|
Iteration number, RMS misfit, roughness, Lagrange multiplier, and convergence state. |
The validation helpers classify common MARE2DEM files by suffix and naming convention.
1from pycsamt.models.mare2dem import detect_file_type, is_response_file
2
3print(detect_file_type("line12.emdata"))
4print(detect_file_type("line12.resistivity"))
5print(is_response_file("line12_MARE2DEM.emdata"))
Build A Run Directory#
InputBuilder writes a minimal MARE2DEM input set. It can start from an
existing .emdata file, an in-memory EMDataFile, or MT/CSEM survey
configuration objects.
1from pycsamt.models.mare2dem import InputBuilder, Mare2DEMConfig
2
3cfg = Mare2DEMConfig(
4 initial_rho=10.0,
5 max_iterations=120,
6 target_rms=1.0,
7 data_file="line12.emdata",
8 resistivity_file="line12.resistivity",
9 settings_file="line12.settings",
10)
11
12builder = InputBuilder(config=cfg, verbose=1)
13files = builder.build(
14 "prepared/line12.emdata",
15 workdir="runs/line12/native",
16)
17
18print(files["data"])
19print(files["model"])
20print(files["settings"])
The builder writes:
the data file, copied or generated into the run directory;
a homogeneous starting
.resistivityfile based oninitial_rho;a
.settingsfile.
For production inversions, the generated starting model is often only the first
step. Review the .resistivity and .poly inputs before launching the
external code.
Create MT Data#
MTSurveyConfig and make_data_file are useful for synthetic tests or
for constructing simple MT-native files from survey arrays.
1import numpy as np
2
3from pycsamt.models.mare2dem import MTSurveyConfig, make_data_file
4
5mt = MTSurveyConfig(
6 frequencies=np.logspace(-3, 3, 25),
7 rx_y=np.linspace(-6000.0, 6000.0, 31),
8 rx_type="land",
9 lTE=True,
10 lTM=True,
11 lTipper=False,
12)
13
14em = make_data_file(
15 "runs/line12/native/line12.emdata",
16 topo=0.0,
17 mt=mt,
18)
19
20print(em.n_data)
For real MT processing, pyCSAMT also includes ZMM readers and converters.
1from pathlib import Path
2
3from pycsamt.models.mare2dem import make_mt_data_from_zmm, read_zmm
4
5station = read_zmm("zmm/station001.zmm")
6print(station.name)
7
8make_mt_data_from_zmm(
9 sorted(Path("zmm").glob("*.zmm")),
10 "runs/line12/native/line12.emdata",
11 error_floor=0.05,
12)
Check the generated data rows carefully. Conversion utilities help with file mechanics, but the interpreter still owns station selection, component choice, frequency band selection, and error-floor policy.
Create CSEM Data#
CSEMSurveyConfig builds a controlled-source survey with transmitter and
receiver layout parameters.
1import numpy as np
2
3from pycsamt.models.mare2dem import CSEMSurveyConfig, make_data_file
4
5csem = CSEMSurveyConfig(
6 frequencies=np.array([0.25, 0.5, 1.0, 2.0]),
7 rx_y=np.linspace(-4000.0, 4000.0, 17),
8 tx_y=np.array([-2500.0, 0.0, 2500.0]),
9 rx_type="marine",
10 tx_type="marine",
11 lEx=True,
12 lEy=True,
13 lBx=True,
14 lBy=True,
15)
16
17make_data_file(
18 "runs/csem_line/native/csem_line.emdata",
19 topo=-1000.0,
20 csem=csem,
21)
For CSEM projects, geometry QC is essential. Plot receiver/transmitter locations, confirm signs and offsets, and record whether coordinates are local profile coordinates, UTM coordinates, or a transformed system.
Merge And Noise Utilities#
MARE2DEM workflows often require combining data families or creating synthetic observations from a forward response. pyCSAMT provides utilities for both.
1from pycsamt.models.mare2dem import merge_data_files
2
3merged = merge_data_files(
4 ["runs/mt/native/mt.emdata", "runs/csem/native/csem.emdata"],
5 "runs/joint/native/joint.emdata",
6)
7
8print(merged.n_data)
Synthetic noise is useful for controlled tests and algorithm validation.
1from pycsamt.models.mare2dem import (
2 NoiseConfig,
3 add_synthetic_noise,
4 read_emdata,
5 write_emdata,
6)
7
8response = read_emdata("runs/forward/native/forward_MARE2DEM.emdata")
9noise = NoiseConfig(
10 mt_rel_noise=0.05,
11 mt_abs_noise_tipper=0.01,
12)
13
14synthetic = add_synthetic_noise(response, noise)
15write_emdata(synthetic, "runs/synthetic/native/synthetic.emdata")
Do not treat noisy synthetic data as field data. Keep synthetic sources, random seeds, and noise parameters in the provenance notes.
Geometry And Topography#
The MARE2DEM integration includes geometry helpers because geometry mistakes are one of the easiest ways to produce convincing but wrong models.
Helper |
Use |
|---|---|
|
Read and interpolate topography/seafloor profiles and compute local slopes. |
|
Convert coordinates with |
|
Estimate profile orientation and project stations onto a survey line. |
|
Simplify polylines and remove collinear polygon nodes. |
|
Find segment intersections with bounding-box pre-filtering. |
|
Compute area-weighted centroids and triangle geometry summaries. |
|
Estimate a practical modelling area from survey geometry. |
|
Assign finite-element regions for Triangle-based meshes. |
Example profile projection:
1import numpy as np
2
3from pycsamt.models.mare2dem import (
4 get_line_orientation,
5 lonlat_to_utm,
6 project_onto_line,
7)
8
9lon = np.array([11.501, 11.507, 11.514])
10lat = np.array([3.842, 3.845, 3.849])
11
12east, north, zone, hemisphere = lonlat_to_utm(lon, lat)
13azimuth = get_line_orientation(north, east)
14cross_profile, along_profile = project_onto_line(
15 north,
16 east,
17 north[0],
18 east[0],
19 azimuth,
20)
21
22print(zone, hemisphere)
23print(along_profile)
For production documentation, include a small figure or table showing original coordinates, projected distances, and topography values. That record is often as important as the inversion result.
Grid And Mesh Utilities#
The package includes helpers for constructing MARE2DEM geometry and models from gridded resistivity information.
1from pycsamt.models.mare2dem import grid_to_mare2dem
2
3files = grid_to_mare2dem(
4 grid="models/resistivity_grid.npy",
5 out_prefix="runs/grid_model/native/line12",
6)
7
8print(files["poly"])
9print(files["resistivity"])
The exact grid format and metadata requirements depend on the upstream grid
object. Always inspect the written .poly and .resistivity files before
using them in an inversion.
Run MARE2DEM#
Once native files are prepared and the executable is available, use
Mare2DEMRunner to launch the run.
1from pycsamt.models.mare2dem import (
2 InversionResult,
3 Mare2DEMConfig,
4 Mare2DEMRunner,
5)
6
7cfg = Mare2DEMConfig.from_file("runs/line12/mare2dem.yml")
8runner = Mare2DEMRunner("runs/line12/native", config=cfg, verbose=1)
9
10# Check the command before running it.
11print(runner.command(cfg.resistivity_stem))
12
13# Run locally. On a cluster, submit the same command through the scheduler.
14# result = runner.run(cfg.resistivity_stem, timeout=None)
15
16# Load an existing completed run.
17result = InversionResult("runs/line12/native", config=cfg)
18print(result.summary())
run returns an InversionResult by default. Set load_result=False if
you only want process execution and will load results later.
1result = runner.run(
2 cfg.resistivity_stem,
3 use_mpi=True,
4 n_procs=16,
5 extra_args=None,
6 timeout=None,
7 load_result=True,
8)
For long inversions, prefer scheduler-managed execution. Build the native
directory with pyCSAMT, submit the command on the cluster, then use
InversionResult after the files are complete.
Inspect Results#
InversionResult scans a run directory for recognized output files and
exposes the main products.
1from pycsamt.models.mare2dem import InversionResult
2
3result = InversionResult("runs/line12/native")
4
5print(result.converged)
6print(result.final_rms)
7print(result.n_iterations)
8print(result.model)
9print(result.data)
10print(result.response)
The log parser exposes the RMS history, roughness history, and regularization multiplier history.
1from pycsamt.models.mare2dem import Mare2DEMLog
2
3log = Mare2DEMLog("runs/line12/native/OccamLog.2012.0")
4
5print(log.final_rms)
6print(log.converged)
7print(log.rms_history())
8print(log.roughness_history())
Group RMS logs should be reviewed when the inversion combines data types, components, stations, or source groups.
1from pycsamt.models.mare2dem import read_group_rms_log
2
3group_log = read_group_rms_log("runs/line12/native/line12.group_rms.log")
4print(group_log.headers)
5print(group_log.rms_log[-1])
A low total RMS can hide a poor fit to one group. Inspect total RMS, group RMS, response residuals, and model roughness together.
Plotting And QC#
The plotting helpers are designed for quality control and interpretation.
Plot helper |
Use |
|---|---|
|
RMS and convergence history from logs. |
|
Receiver/transmitter layout in map/profile coordinates. |
|
Receiver geometry and parameter checks. |
|
Transmitter geometry and parameter checks. |
|
PSLG/ |
|
Model-section visualization support. |
|
Observed/predicted response inspection. |
Example convergence review:
1from pycsamt.models.mare2dem import Mare2DEMLog, PlotConvergence
2
3log = Mare2DEMLog("runs/line12/native/OccamLog.2012.0")
4plotter = PlotConvergence(log)
5plotter.plot()
Before presenting a final model, review at least:
station and transmitter geometry;
topography or bathymetry representation;
mesh or polygon geometry;
RMS history and convergence status;
group RMS history;
observed/predicted response fits;
model smoothness, bounds, and fixed/free parameter behavior.
Model Comparison#
diff_resistivity compares two .resistivity files, typically to inspect
how a model changed between iterations, parameter choices, or preprocessing
decisions.
1from pycsamt.models.mare2dem import diff_resistivity
2
3diff = diff_resistivity(
4 "runs/line12_v01/native/line12.resistivity",
5 "runs/line12_v02/native/line12.resistivity",
6 "runs/comparison/line12_v02_minus_v01.resistivity",
7)
8
9print(diff)
Use model differences as diagnostics, not as standalone geological evidence. Pair them with data-fit changes and model regularization changes.
Recommended Run Layout#
Keep source/build material separate from scientific run directories.
1external/
2 mare2dem/
3 source/
4 build_notes.md
5
6runs/
7 survey_alpha/
8 line12_mare2dem_v01/
9 mare2dem.yml
10 provenance.yml
11 native/
12 line12.emdata
13 line12.poly
14 line12.resistivity
15 line12.settings
16 OccamLog.2012.0
17 line12_MARE2DEM.emdata
18 line12.group_rms.log
19 qc/
20 survey_layout.png
21 convergence.png
22 response_fit.png
23 exports/
24 line12_snapshot.zip
Use versioned run names. MARE2DEM uses simple native filenames, so running several experiments in one directory can easily mix stale outputs with new inputs.
Pre-Run Checklist#
Before launch:
load
Mare2DEMConfigfrom the edited template;confirm source directory and executable resolution;
check
runner.commandand record it;confirm MPI process count and scheduler settings;
verify that
.emdata,.resistivity,.settings, and.polyfiles exist when required;inspect station, transmitter, and profile coordinates;
inspect topography or seafloor representation;
confirm frequency band, components, and error floors;
move old output files out of the run directory;
record pyCSAMT version, MARE2DEM source/binary path, and compiler/MPI context.
Post-Run Checklist#
After completion:
read the main log before plotting;
check
result.converged,result.final_rms, and iteration count;review RMS and roughness histories;
review group RMS where groups are used;
confirm response-file timestamps match the intended run;
compare observed and predicted responses;
inspect the final model against bounds and fixed/free parameter flags;
archive native input and output files with the configuration and provenance.
Common Mistakes#
- Using a stale response file
If the binary fails, an old
*_MARE2DEM.emdatafile can remain in the directory. Check timestamps and logs before loading results.- Passing the wrong stem
MARE2DEM receives the resistivity stem, not usually the full project path.
Mare2DEMRunnernormalizes the stem, but users should still keep filenames consistent.- Mixing coordinate systems
Longitude/latitude, UTM, and local profile distance are different records. State which system is used in every generated native file.
- Treating total RMS as enough
Total RMS can hide poor fits to one component, station range, source, or data family. Review group RMS and response residuals.
- Ignoring build provenance
MARE2DEM behavior can depend on source revision, compiler, MKL/ScaLAPACK, MPI runtime, and cluster environment. Record them.
Next Steps#
Configuration And File I/O for source-of-truth configuration and archive practice.
Choosing A Model Backend for deciding when MARE2DEM is the right integration.
Inversion Concepts for regularized inversion and misfit concepts.
pycsamt.models for generated API reference pages.