pycsamt.agents.forward#

pycsamt.agents.forward#

ForwardModelAgent — Run 1-D, 2-D, or 3-D MT forward solvers.

Wraps pycsamt.forward:

1-D (dim=1)

MT1DForward on a LayeredModel.

2-D (dim=2)

MT2DForward (finite-difference TE + TM) on a Grid2D. Supports halfspace, 1-D-layer, or embedded conductive-anomaly models.

3-D (dim=3)

MT3DForward (quasi-3D profile stacking) on a Grid3D. Supports halfspace and block-anomaly models.

The agent also computes data–model RMS when observed sites are provided (1-D only), letting it act as a model-validation check before inversion.

Classes

ForwardModelAgent(*[, api_key, model, ...])

Run a 1-D, 2-D, or 3-D MT forward model.

class pycsamt.agents.forward.ForwardModelAgent(*, api_key=None, model=None, llm_provider='claude', dim=1, freqs=None)[source]#

Bases: BaseAgent

Run a 1-D, 2-D, or 3-D MT forward model.

Parameters:
  • api_key (str)

  • model (dict or LayeredModel or None)

  • llm_provider (str)

  • dim (int, optional — overrides constructor dim for this call) – Forward solver dimensionality.

  • freqs (array-like, optional — overrides constructor default) – Frequencies (Hz). Defaults to 40 log-spaced points 10⁻⁴–10³ Hz.

  • keys (Output data)

  • ----------

  • model

    1-D / 2-D from 1-D layers: {"resistivities": [...], "thicknesses": [...]}.

    2-D grid type override: add "type": "halfspace" | "anomaly" and grid parameters such as "bg_rho", "anomaly_rho", "anomaly_bounds".

    3-D grid type: "type": "halfspace" | "block_anomaly" with grid parameters.

  • dim

  • nx (int / float, optional (2-D grid))

  • nz (int / float, optional (2-D grid))

  • x_max (int / float, optional (2-D grid))

  • z_max (int / float, optional (2-D grid))

  • ny (int / float (3-D))

  • y_max (int / float (3-D))

  • nx_stations (int / float (3-D))

  • ny_stations (int / float (3-D))

  • n_stations (int, optional — number of surface receivers (2-D))

  • method (str, optional — "quasi3d" (default) for 3-D solver)

  • path (sites /)

  • freqs

  • output_dir (str, optional)

  • component ("xy" (default) or "yx" (1-D component selection))

  • keys

  • ----------------

  • int (dim)

  • 1-D) (layered_model LayeredModel (1-D / 2-D from)

  • 3-D) (grid Grid2D or Grid3D (2-D /)

  • ForwardResponse3D (response ForwardResponse / ForwardResponse2D /)

  • ρa (rho_a ndarray — 1-D)

  • (°) (phase ndarray — 1-D phase)

  • (n_freqs (rho_a_xy ndarray)

  • TE (n_stations) — 2-D)

  • phase (phase_yx ndarray — 3-D YX)

  • TM (rho_a_tm ndarray — 2-D)

  • phase

  • (n_freqs

  • XY (n_stations) — 3-D)

  • phase

  • YX (rho_a_yx ndarray — 3-D)

  • phase

  • ndarray (freqs)

  • None (rms float or)

  • dict (figure_paths)

  • dict

SYSTEM_PROMPT: str = 'You are an expert in MT forward modelling and resistivity earth models.\nGiven a forward model result, write 3-4 sentences that:\n1. Describe the model geometry (dimensionality, layers / grid, resistivity range).\n2. Comment on the synthetic ρa and phase response (frequency range, lateral variation for 2D/3D).\n3. If observed data are provided, interpret the data-model misfit (1-D only).\n4. Suggest which model parameters to adjust to better fit the data or geology.\nReply in plain English. No bullet points or markdown.\n'#

Override in subclasses to give the LLM its domain expertise.

execute(input_data)[source]#

Run this agent on input_data and return an AgentResult.

Subclasses must implement this method. The contract:

  • Reset self._last_cost = 0.0 at the top.

  • Record wall-clock time with t0 = time.time().

  • Return AgentResult(elapsed_seconds=time.time()-t0, cost_estimate_usd=self._last_cost, ...).

Parameters:

input_data (dict[str, Any])

Return type:

AgentResult