pycsamt.agents.tensor_rotation#

pycsamt.agents.tensor_rotation#

TensorRotationAgent — Apply a strike rotation to impedance tensors and write corrected EDI files.

Closes the loop between PhaseAnalysisAgent (which identifies the optimal strike angle) and the inversion-preparation step: rotated EDIs are written to disk and are ready to be consumed by Occam2D, ModEM, or any external inversion code.

Rotation convention#

The standard two-sided rotation Z' = R(θ) Z R(θ)ᵀ is applied per frequency using rotate_impedance(). Tipper vectors are rotated with rotate_tipper(). A positive angle θ rotates the measurement frame counter-clockwise (geological azimuth convention: N → E positive).

Classes

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

Rotate impedance tensors and tipper vectors by a fixed strike angle.

class pycsamt.agents.tensor_rotation.TensorRotationAgent(*, api_key=None, model=None, llm_provider='claude', strike_deg=0.0)[source]#

Bases: BaseAgent

Rotate impedance tensors and tipper vectors by a fixed strike angle.

Parameters:
  • api_key (str)

  • model (str)

  • llm_provider (str)

  • strike_deg (float — counter-clockwise rotation angle (degrees)) – Default rotation angle (degrees). Overridden by input_data["strike_deg"].

  • keys (Output data)

  • ----------

  • path (sites /)

  • strike_deg

  • output_dir (str — directory for rotated EDI files)

  • overwrite (bool — allow overwriting existing files (default False))

  • file_suffix (str — appended to station name, e.g. "_rot")

  • keys

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

  • applied (strike_deg float — angle)

  • paths (written_paths list[str] — successfully written EDI)

  • list[str] (failed_stations)

  • int (n_written)

  • quality) (z_diag_reduction float — mean Zxx/Zxy before − after (proxy for rotation)

  • dict (figure_paths)

  • dict

Examples

>>> agent = TensorRotationAgent(strike_deg=42.0)
>>> r = agent.execute({
...     "path":       "/data/WILLY_EDIs",
...     "output_dir": "/data/WILLY_rotated",
... })
>>> print(r["n_written"], "EDIs written")
SYSTEM_PROMPT: str = 'You are an expert in MT tensor rotation and coordinate-frame correction.\nGiven a rotation result, write 3-4 sentences that:\n1. State the rotation angle applied and the original coordinate frame.\n2. Describe how the off-diagonal impedances (Zxy, Zyx) changed after rotation.\n3. Assess whether the rotation removed apparent 2-D coupling from the diagonal terms.\n4. Recommend whether further refinement (per-frequency rotation, decomposition) is needed.\nReply in plain English.\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