Source code for pycsamt.models.mare2dem

# Author: LKouadio <etanoyau@gmail.com>
# License: LGPL-3.0
"""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 :class:`SourceManager` to download and
build it before running inversions.

Ported MATLAB scripts (complete)
---------------------------------
**I/O** (``a_util/io/`` + ``a_util/data/``):

* ``.emdata`` / ``.EMResp`` reader + writer
* ``.resistivity`` reader + writer (all anisotropy modes)
* Triangle ``.poly`` PSLG reader + writer
* ``.settings`` parallel-decomposition writer
* ``.emdata_group`` data-group file reader + writer
* Group-RMS CSV log reader
* Most-recently-modified file finder

**Data management**:

* Data-type code lookup table
* High-level ``.emdata`` builder from MT / CSEM survey configs
* ZMM impedance file reader + MT data-file builder
* Synthetic noise addition + ``make_synthetic_data`` wrapper
* Multi-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 (``pyproj`` with pure-Python WGS-84 fallback)
* Survey area-of-interest estimator
* Triangle FEM region flood-fill assignment

**Model construction**:

* 2-D resistivity grid → MARE2DEM ``.poly`` + ``.resistivity``
* Topography import + profile projection

**Model comparison**:

* Log10 (or custom) difference of two ``.resistivity`` files

**Plotting**:

* RMS convergence curve
* Survey map (Rx/Tx positions in UTM)
* Receiver geometry QC (6-panel)
* Transmitter geometry QC
* ``.poly`` PSLG mesh plot
* Resistivity 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.
"""

# ---- configuration ----
from .builder import InputBuilder
from .config import Mare2DEMConfig

# ---- compatibility wrappers (original stub API) ----
from .data import EMData

# ---- model diff ----
from .diff import diff_resistivity

# ---- EDI → MT data builder ----
from .edi import make_mt_data_from_edi, stations_from_edi

# ---- geometry utilities ----
from .geom import (
    ELLIPSOIDS,
    do_rects_overlap,
    dp_simplify,
    estimate_area_of_interest,
    get_centroids,
    get_intersections,
    get_line_orientation,
    get_triangle_regions,
    lonlat_to_utm,
    parse_topo,
    project_onto_line,
    simplify_poly,
    topo_depth,
    topo_slope,
    triangle_areas,
    triangle_centroids,
    utm_to_lonlat,
)

# ---- model construction from grid ----
from .grid_to_m2d import grid_to_mare2dem

# ---- topography import ----
from .import_topo import TopoConfig, TopoProfile, import_topo

# ---- I/O tools (full parsers) ----
from .iotools import (
    # data codes
    DATA_CODES,
    CSEMConfig,
    # data group
    DataGroupFile,
    DCConfig,
    # emdata
    EMDataFile,
    # group RMS log
    GroupRMSLog,
    MTConfig,
    # poly
    PolyFile,
    # resistivity
    ResistivityFile,
    # settings
    SettingsFile,
    UTMOrigin,
    code_component,
    code_label,
    code_representation,
    # most recent
    get_most_recent,
    is_csem_code,
    is_mt_code,
    read_data_group,
    read_emdata,
    read_group_rms_log,
    read_poly,
    read_resistivity,
    write_data_group,
    write_emdata,
    write_poly,
    write_resistivity,
    write_settings,
)

# ---- log parsers ----
from .log import (
    GroupRMSLog,
    IterationRecord,
    Mare2DEMLog,
    read_group_rms_log,
)

# ---- file merge ----
from .merge import merge_data_files, merge_emdata
from .mesh import PolyMesh, ResistivityModel

# ---- synthetic noise ----
from .noise import (
    NoiseConfig,
    add_synthetic_noise,
    make_synthetic_data,
)

# ---- plots ----
from .plot import (
    PlotConvergence,
    PlotModel,
    PlotResponse,
    PlotRxParams,
    PlotSurveyLayout,
    PlotTxParams,
    plot_poly,
)

# ---- run lifecycle ----
from .results import InversionResult
from .runner import Mare2DEMRunner

# ---- source management ----
from .source import SourceManager

# ---- survey data builder ----
from .survey import (
    CSEMSurveyConfig,
    MTSurveyConfig,
    make_data_file,
)

# ---- file-type detection ----
from .validation import (
    Mare2DEMFileType,
    detect_file_type,
    is_emdata_file,
    is_log_file,
    is_resistivity_file,
    is_response_file,
    is_settings_file,
)

# ---- ZMM reader + MT data builder ----
from .zmm import (
    ZMMStation,
    make_mt_data_from_stations,
    make_mt_data_from_zmm,
    read_zmm,
)

__all__ = [
    # config
    "Mare2DEMConfig",
    # source management
    "SourceManager",
    # file-type detection
    "Mare2DEMFileType",
    "detect_file_type",
    "is_emdata_file",
    "is_resistivity_file",
    "is_settings_file",
    "is_log_file",
    "is_response_file",
    # data codes
    "DATA_CODES",
    "code_label",
    "code_component",
    "code_representation",
    "is_mt_code",
    "is_csem_code",
    # emdata I/O
    "EMDataFile",
    "UTMOrigin",
    "CSEMConfig",
    "MTConfig",
    "DCConfig",
    "read_emdata",
    "write_emdata",
    # resistivity I/O
    "ResistivityFile",
    "read_resistivity",
    "write_resistivity",
    # poly I/O
    "PolyFile",
    "read_poly",
    "write_poly",
    # settings I/O
    "SettingsFile",
    "write_settings",
    # group RMS log
    "GroupRMSLog",
    "read_group_rms_log",
    # data group
    "DataGroupFile",
    "read_data_group",
    "write_data_group",
    # most recent file
    "get_most_recent",
    # geometry
    "parse_topo",
    "topo_depth",
    "topo_slope",
    "get_intersections",
    "do_rects_overlap",
    "dp_simplify",
    "simplify_poly",
    "get_centroids",
    "triangle_centroids",
    "triangle_areas",
    "lonlat_to_utm",
    "utm_to_lonlat",
    "ELLIPSOIDS",
    "estimate_area_of_interest",
    "get_triangle_regions",
    "get_line_orientation",
    "project_onto_line",
    # survey builder
    "MTSurveyConfig",
    "CSEMSurveyConfig",
    "make_data_file",
    # ZMM
    "ZMMStation",
    "read_zmm",
    "make_mt_data_from_zmm",
    "make_mt_data_from_stations",
    # EDI → emdata
    "stations_from_edi",
    "make_mt_data_from_edi",
    # noise
    "NoiseConfig",
    "add_synthetic_noise",
    "make_synthetic_data",
    # merge
    "merge_data_files",
    "merge_emdata",
    # grid to MARE2DEM
    "grid_to_mare2dem",
    # topo import
    "TopoConfig",
    "TopoProfile",
    "import_topo",
    # model diff
    "diff_resistivity",
    # compatibility wrappers
    "EMData",
    "ResistivityModel",
    "PolyMesh",
    # logs
    "Mare2DEMLog",
    "IterationRecord",
    # run lifecycle
    "InversionResult",
    "Mare2DEMRunner",
    "InputBuilder",
    # plots
    "PlotConvergence",
    "PlotSurveyLayout",
    "PlotRxParams",
    "PlotTxParams",
    "plot_poly",
    "PlotModel",
    "PlotResponse",
]