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
|
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:
BaseAgentRotate 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.0at the top.Record wall-clock time with
t0 = time.time().Return
AgentResult(elapsed_seconds=time.time()-t0, cost_estimate_usd=self._last_cost, ...).
- Parameters:
- Return type: