Agents Module#
The agents module provides the multi-agent system for automating geophysical workflows using Large Language Models.
Base Classes#
Base Agent Class for Multi-Agent System
Provides the foundation for all specialized agents in the workflow.
- class PyHydroGeophysX.agents.base_agent.AgentResult(status: ~typing.Literal['success', 'failed', 'needs_review'], summary: str, data: ~typing.Dict[str, ~typing.Any], warnings: ~typing.List[str] = <factory>, next_suggested_action: str | None = None, llm_interpretation: str | None = None, elapsed_seconds: float = 0.0, cost_estimate_usd: float | None = None, error: str | None = None, error_fix_hint: str | None = None)[source]#
Bases:
objectStandard user-facing result returned by agent workflows.
- Parameters:
status ({"success", "failed", "needs_review"}) – Execution state for the agent or workflow.
summary (str) – One-sentence human-readable summary. This is always populated.
data (dict) – Numerical, object, or artifact outputs.
warnings (list of str, optional) – Non-fatal issues the user should review.
next_suggested_action (str, optional) – Suggested next step for the user.
llm_interpretation (str, optional) – AI-generated interpretation. UIs should label this before rendering.
elapsed_seconds (float, optional) – Wall-clock runtime.
cost_estimate_usd (float, optional) – Approximate LLM cost associated with this result.
error (str, optional) – Error message when
status="failed".error_fix_hint (str, optional) – Plain-language fix hint for the user.
- Returns:
Dict-like result object. Existing code can continue to call
result["status"]orresult.get("artifact_key").- Return type:
- Raises:
KeyError – Raised by
__getitem__when a key is not present.
Examples
>>> result = AgentResult(status="success", summary="Loaded data.", data={"n": 2}) >>> result["status"] 'success' >>> result.get("n") 2
- cost_estimate_usd: float | None = None#
- data: Dict[str, Any]#
- elapsed_seconds: float = 0.0#
- error: str | None = None#
- error_fix_hint: str | None = None#
- classmethod from_dict(payload: Dict[str, Any], default_summary: str = 'Agent completed.') AgentResult[source]#
Create an
AgentResultfrom a legacy dictionary.- Parameters:
payload (dict) – Legacy result dictionary.
default_summary (str, optional) – Summary to use if the dictionary does not provide one.
- Returns:
Normalized result object.
- Return type:
- Raises:
TypeError – If
payloadis not a dictionary.
Examples
>>> AgentResult.from_dict({"status": "success", "value": 1}).get("value") 1
- llm_interpretation: str | None = None#
- next_suggested_action: str | None = None#
- status: Literal['success', 'failed', 'needs_review']#
- summary: str#
- to_dict(include_data_keys: bool = True) Dict[str, Any][source]#
Return a dictionary representation.
- Parameters:
include_data_keys (bool, optional) – If True, merge
datainto the top level for legacy callers.- Returns:
Serialized result.
- Return type:
dict
- Raises:
None –
Examples
>>> AgentResult("success", "ok", {"x": 1}).to_dict()["x"] 1
- warnings: List[str]#
- class PyHydroGeophysX.agents.base_agent.BaseAgent(name: str, api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
ABCAbstract base class for all agents in the multi-agent system.
Each agent is specialized for a specific task and can communicate with other agents through the coordinator.
- abstractmethod execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Execute the agent’s primary task.
- Parameters:
input_data – Input data dictionary
- Returns:
Dictionary containing execution results
- property llm_enabled: bool#
Model access can use either an API key or saved local CLI login.
- llm_usage_ledger: List[Dict[str, Any]]#
- query_llm(prompt: str, system_message: str = None, temperature: float = 0.7, max_tokens: int = 1000, on_text: Callable[[str], None] | None = None) str[source]#
Query the LLM API for assistance. Supports multiple LLM providers: OpenAI (GPT), Google (Gemini), and Anthropic (Claude).
- Parameters:
prompt – User prompt for the LLM
system_message – System message defining agent behavior
temperature – Sampling temperature (0-1)
max_tokens – Maximum tokens in response
on_text – Called with the reply so far as it is generated, when given: the reply is streamed (OpenAI and Claude; Gemini calls it once, with the whole reply). The return value is the same either way.
- Returns:
LLM response as string
- static run_legacy_agent_workflow(workflow_config, api_key, llm_model, llm_provider, output_dir, progress_callback=None)[source]#
Unified agent workflow: infers task type from config and runs the appropriate pipeline.
The pre-controller implementation, kept reachable because it covers workflow types whose tools cannot be exercised here - there is no ParFlow output, no SEG-Y file and no GPU on this machine - and because a run that behaves differently can then be compared against the code it replaced. Reached by setting
PHGX_LEGACY_WORKFLOW=1. The code lives inPyHydroGeophysX.agents._legacy_workflow. Supported: data fusion, time-lapse, direct ERT conversion. Returns: results dict, execution plan, interpretation, report files- Parameters:
workflow_config – Configuration dictionary from ContextInputAgent
api_key – LLM API key
llm_model – LLM model name
llm_provider – LLM provider (‘openai’, ‘gemini’, ‘claude’)
output_dir – Output directory path
progress_callback – Optional callback function(step: str, progress: float, details: str)
- static run_unified_agent_workflow(workflow_config, api_key, llm_model, llm_provider, output_dir, progress_callback=None, **kwargs)[source]#
Run one workflow, choosing each step from what the run has produced.
Kept as the entry point every caller already uses - the desktop studio, the Streamlit app and the one-click runner - while what happens behind it changed. It used to classify the request into one of eight workflow types and run that type’s fixed sequence; it now builds a run context and hands it to the controller in
PyHydroGeophysX.agents.runtime, which picks each step from the tools whose inputs exist and observes the result before picking the next.The returned execution plan is derived from the steps that ran, so it can no longer advertise a step the run skipped.
Set
PHGX_LEGACY_WORKFLOW=1to runrun_legacy_agent_workflow()instead, which is the implementation this replaced.
- save_results(output_dir: str)[source]#
Save agent results to disk, preserving numpy arrays and PyGIMLi meshes.
numpy arrays →
{agent}_{key}.npyPyGIMLi meshes →
{agent}_{key}.bmsEverything else →
{agent}_results.json(metadata)
- Parameters:
output_dir (str) – Target directory; created if absent.
- Returns:
Path to the JSON metadata file.
- Return type:
str
- validate_input_file(file_path: Any, supported_extensions: Iterable[str], field_name: str = 'data_file', max_size_mb: float | None = None) AgentResult | None[source]#
Validate a user-provided input file before processing.
- Parameters:
file_path (Any) – Path-like value to validate.
supported_extensions (iterable of str) – Allowed file extensions, including the leading dot.
field_name (str, optional) – Name of the field being validated.
max_size_mb (float, optional) – Optional file-size limit in megabytes.
- Returns:
Failure result if validation fails; otherwise None.
- Return type:
AgentResult or None
- Raises:
None –
Examples
>>> BaseAgent.__dict__["validate_input_file"] <function BaseAgent.validate_input_file at ...
- PyHydroGeophysX.agents.base_agent.CLAUDE_UNCAPPED_TOKENS = 16000#
Claude’s reply cap when the caller sets none. The Messages API needs a number, and the Anthropic SDK refuses a request it expects to outlast ten minutes without streaming (above about 21,000 tokens); every Claude model the studio offers can write this much.
Coordinator#
Agent Coordinator for Multi-Agent Workflow
Coordinates the execution of multiple specialized agents to complete the full geophysical processing workflow. Supports cross-modal geophysical data processing (ERT, seismic, and more) with multiple LLM API providers (GPT, Gemini, Claude).
- class PyHydroGeophysX.agents.agent_coordinator.AgentCoordinator(api_key: str | None = None, output_dir: str = 'results/agents', llm_provider: str = 'openai')[source]#
Bases:
objectCoordinates multiple agents to execute a complete workflow.
The coordinator manages cross-modal geophysical workflows such as: “load geophysical data → process → invert → convert to hydrologic parameters → report” with support for multiple data types (ERT, seismic, etc.) and LLM providers (GPT, Gemini, Claude).
- execute_workflow(config: Dict[str, Any], dry_run: bool = False, resume: bool = False) Any[source]#
Execute the complete workflow with registered agents.
- Parameters:
config –
Configuration dictionary containing:
user_request: Optional natural-language request. It is read as the preview reads it: the ERT files it names are run when this dictionary names none, the instrument, petrophysical parameters and seismic data it names fill what is left out, and keys set here win. What it states that the run does not use is reported in
warningsdata_file: Path to ERT data file (
ert_fileis accepted)time_lapse_files: Survey files in acquisition order; when given, every one is loaded and inverted together (a time-lapse inversion) and data_file is ignored
instrument: Instrument type (E4D, Syscal, etc.)
inversion_params: Parameters for inversion
petrophysical_params: Parameters for water content conversion. The water-content step runs unless the configuration says otherwise (
convert_to_water_content, or a request that asks for resistivity only), read as the runtime reads ituse_seismic: Whether to include seismic processing (default: False)
seismic_data: Seismic travel-time data for the structure constraint, loaded or as a file path
use_climate: Whether to include climate data (default: False)
climate_config: Climate data configuration (coords/geometry, dates, etc.)
ert_timestamps: Timestamps for ERT acquisitions (for climate alignment)
A configuration naming
tdem_file,em_file,seismic_fileorraw_seismic_file, or a request that asks for TDEM, is refused: this pipeline has no step for them, andBaseAgent.run_unified_agent_workflow()runs them.dry_run – If True, return a preview plan without executing.
resume – If True, load checkpointed intermediate results and skip already-completed steps.
- Returns:
Dictionary containing workflow results, or
AgentResultwhendry_run=True.
- preview_workflow(config: Dict[str, Any]) AgentResult[source]#
Resolve and validate a workflow plan without running processing.
- Parameters:
config (dict) – Workflow configuration. May include
user_requestorrequestfor deterministic preview parsing.- Returns:
Preview result with resolved config, validation warnings, plan, and approximate LLM cost.
- Return type:
- Raises:
None –
Examples
>>> import tempfile >>> coordinator = AgentCoordinator(api_key=None, output_dir=tempfile.mkdtemp()) >>> result = coordinator.preview_workflow({"data_file": "missing.ohm"}) ===== PyHydroGeophysX Agent Preview ===== ... >>> result["status"] 'failed'
Input Agents#
ContextInputAgent#
Context Input Agent for Natural Language Workflow Configuration
Translates user’s natural language requests into structured workflow configurations. Supports multiple LLM providers (OpenAI GPT, Google Gemini, Anthropic Claude).
- class PyHydroGeophysX.agents.context_input_agent.ContextInputAgent(api_key: str | None = None, model: str = 'gpt-4', llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent that interprets natural language requests and generates workflow configurations.
This agent uses LLM to understand user intent and create appropriate configuration dictionaries for the AgentCoordinator, including parameters for: - Data loading (file paths, instruments, CRS) - Inversion settings (regularization, iterations, time-lapse mode) - Petrophysical parameters - Climate data integration - Seismic constraints - Uncertainty quantification
- execute(input_data: Dict[str, Any]) AgentResult[source]#
Execute the context input agent (parse natural language request).
- Parameters:
input_data – Dictionary containing: - user_request: Natural language workflow description - available_data: Optional dict with available files/instruments
- Returns:
status: ‘success’ or ‘failed’
workflow_config: Generated configuration
explanation: Human-readable explanation
- Return type:
Dictionary containing
- explain_config(config: Dict[str, Any]) str[source]#
Generate human-readable explanation of workflow configuration.
- Parameters:
config – Workflow configuration dictionary
- Returns:
Formatted explanation string
- parse_request(user_request: str, available_data: Dict[str, Any] | None = None) Dict[str, Any][source]#
Parse natural language request into workflow configuration.
Uses TWO focused prompts for better reliability: 1. Inversion configuration prompt (ERT-specific parameters) 2. Climate configuration prompt (meteorological parameters)
Without an API key, or when a model call fails, the request is read by the deterministic rules of
preview_config()instead, with a warning saying so. It used to raise “OPENAI API key not found”, so a caller without a key had no configuration at all.- Parameters:
user_request – Natural language description of desired workflow
available_data – Optional dict with available data files, instruments, etc.
- Returns:
Dict containing workflow_config ready for AgentCoordinator
- parse_workers = 4#
Extraction questions
parse_request()keeps in flight at once after the router has answered. 1 asks them one after another, as it used to.
- preview_config(user_request: str, available_data: Dict[str, Any] | None = None) AgentResult[source]#
Build a deterministic preview config without calling an LLM.
- Parameters:
user_request (str) – Natural-language workflow request.
available_data (dict, optional) – Optional file and instrument hints supplied by the caller.
- Returns:
Preview configuration with missing-field warnings.
- Return type:
- Raises:
None –
Examples
>>> agent = ContextInputAgent(api_key=None) >>> result = agent.preview_config("Run ERT inversion on data.ohm") >>> result.get("workflow_config")["data_file"] 'data.ohm'
- request_inputs(user_request: str, known_files: Sequence[Any] = (), methods: Dict[str, Any] | None = None) Dict[str, Any][source]#
What a request states, read by deterministic rules, without defaults.
The files it names (ERT surveys, an electrode file, seismic, TDEM and GPR data), the instrument and petrophysical parameters written into it.
preview_config()completes this with defaults into a runnable configuration; a caller that has a configuration of its own takes only this, so the parser’s defaults cannot replace the caller’s.- Parameters:
user_request (str) – Natural-language workflow request.
known_files (sequence of str, optional) – Files the caller already uses as ERT data. The request naming them does not make them seismic or TDEM data.
methods (dict, optional) – A model’s reading of which methods the request is about (
request_methods:{"gpr": True, "seismic": False}). Where it says yes or no, it decides what an ambiguous file is - a SEG-Y line is GPR or seismic - in place of the words of the request.
- Returns:
Only the keys the request gives a value for.
- Return type:
dict
- Raises:
None –
Examples
>>> agent = ContextInputAgent(api_key=None) >>> agent.request_inputs("Invert a.ohm, measured with a Syscal") {'data_file': 'a.ohm', 'ert_file': 'a.ohm', 'instrument': 'Syscal'} >>> agent.request_inputs("Invert survey.dat with the seismic structure from srt.dat", ... known_files=["survey.dat"])["seismic_file"] 'srt.dat' >>> agent.request_inputs("Process the GPR line line1.sgy at 0.08 m/ns") {'gpr_file': 'line1.sgy', 'gpr_velocity': 0.08} >>> agent.request_inputs("Process line1.sgy", methods={"gpr": True, "seismic": False}) {'gpr_file': 'line1.sgy'}
- suggest_improvements(config: Dict[str, Any], site_conditions: str | None = None) str[source]#
Suggest improvements to configuration based on best practices.
- Parameters:
config – Current workflow configuration
site_conditions – Optional description of site conditions
- Returns:
Suggestions for improving the configuration
- PyHydroGeophysX.agents.context_input_agent.drop_borrowed_ert_files(config: Dict[str, Any], roles: Dict[str, Any] | None = None) Dict[str, Any][source]#
configwithout ERT data that is another method’s input.The parser’s ERT stage is told its data file is required, so a request to process TEM2Go data came back with the project the user had selected as TDEM data given as
data_filetoo. The run’s route then showed Load ERT data, Run ERT inversion and Evaluate inversion quality after the TDEM inversion, and its report waited for the ERT loader to be offered a .tiw file. A file given to another method - the same file, or one inside the survey folder another method names - is that method’s data only, and a TEMcompany project is TDEM data whatever key it came under.- Parameters:
config (dict) – The workflow configuration.
roles (dict, optional) – Inputs the caller selected by role and has not merged into
configyet; they decide which files are taken, and are not added.
- Returns:
A new configuration. A TEM project dropped from the ERT keys becomes
tdem_filewhen no TDEM data is named.- Return type:
dict
Examples
>>> drop_borrowed_ert_files({'data_file': 'p.tiw', 'ert_file': 'p.tiw', ... 'tdem_file': 'p.tiw'}) {'tdem_file': 'p.tiw'} >>> drop_borrowed_ert_files({'data_file': 'Sep06/project.tiw'}, {'tdem_file': 'Sep06'}) {} >>> drop_borrowed_ert_files({'data_file': 'p.tiw'}) {'tdem_file': 'p.tiw'} >>> drop_borrowed_ert_files({'data_file': 'a.ohm', 'tdem_file': 'Sep06'}) {'data_file': 'a.ohm', 'tdem_file': 'Sep06'}
- PyHydroGeophysX.agents.context_input_agent.drop_unstated_petrophysics(config, request)[source]#
Remove petrophysical values the request does not contain, and say which.
Whether a water content is reliable turns on whose petrophysical relationship it used, and a value the parser produced itself - from the example in its own prompt, or a misread - would be reported as the user’s. A value counts as stated when the request contains that number, or the percentage it is a fraction of.
- Returns:
"key value"for each value removed.- Return type:
list of str
Examples
>>> config = {'petrophysical_params': {'n': 1.8, 'porosity': 0.3}, ... 'layer_params': {'regolith': {'rho_sat_range': [50, 250], ... 'n_range': [1.3, 2.2]}}} >>> drop_unstated_petrophysics(config, 'n is 1.8, porosity 30%, rho_sat 50 to 250 ohm-m') ['regolith n_range [1.3, 2.2]'] >>> config['layer_params'] {'regolith': {'rho_sat_range': [50, 250]}}
- PyHydroGeophysX.agents.context_input_agent.gpr_from_reply(reply: Any, request: str) Tuple[Dict[str, Any], List[str]][source]#
The GPR configuration in the model’s answer, and a note on each value set aside.
The line (
gpr_file), the velocity in m/ns or the permittivity it stands for, and the processing options. A velocity or permittivity the request does not contain is the model’s own - a “typical” 0.1 m/ns - and every depth would rest on it unsaid, so it is dropped and the run told; a velocity converted from cm/ns counts as stated.Examples
>>> gpr_from_reply({"gpr_file": "a.DZT", "gpr_velocity": 0.1, ... "gpr_params": {"migrate": True, "velocity": 0.1}}, "migrate a.DZT") ({'gpr_file': 'a.DZT', 'gpr_params': {'migrate': True}}, ['The model read a radar velocity of 0.1 m/ns that the request does not state; it was not used.']) >>> gpr_from_reply({"gpr_file": "a.DZT", "gpr_velocity": 0.09}, "a.DZT at 9 cm/ns")[0] {'gpr_file': 'a.DZT', 'gpr_velocity': 0.09}
ERTLoaderAgent#
ERT Loader Agent
Specialized agent for loading and quality-checking ERT field data.
- class PyHydroGeophysX.agents.ert_loader_agent.ERTLoaderAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent specialized in loading ERT data from various instruments.
Uses PyHydroGeophysX data_processing module to load, validate, and prepare ERT data for inversion.
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Load and process ERT data.
- Parameters:
input_data – Dictionary containing: - data_file: Path to ERT data file - instrument: Instrument type (E4D, Syscal, ABEM, etc.) - project_dir: Project directory - crs: Coordinate reference system (‘local’ or EPSG code) - quality_check: Whether to perform quality checks (default: True)
- Returns:
Dictionary containing loaded ERT data and quality metrics
SeismicAgent#
Seismic Data Processing Agent
Specialized agent for processing seismic refraction data and extracting velocity structures. Supports standalone seismic refraction tomography (SRT) inversion workflows.
- class PyHydroGeophysX.agents.seismic_agent.SeismicAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent specialized in seismic refraction tomography (SRT) processing.
Uses PyGIMLI and PyHydroGeophysX seismic processing modules to invert seismic travel time data and extract velocity interfaces for structural constraints.
Supports two modes: - ‘inversion’: Load seismic data file and run SRT inversion - ‘interface’: Extract velocity interfaces from existing velocity model
- Example (with your own travel-time file):
>>> agent = SeismicAgent() >>> result = agent.execute({ ... 'seismic_file': 'seismic_data.dat', ... 'velocity_threshold': 1200, ... 'output_dir': 'results/seismic' ... })
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Process seismic data and extract velocity structure.
- Parameters:
input_data – Dictionary containing
seismic_fileor pre-loadedseismic_data(a path given asseismic_datais read asseismic_file), optional velocity thresholds, inversion parameters, an output directory, and anextract_interfacesflag. Supported inversion parameters includelam,zWeight,vTop,vBottom,paraDepth,paraMaxCellSize, andlimits.- Returns:
Dictionary containing velocity model, mesh, interfaces, and visualizations
- interfaces_from_model(mesh, velocity_model, thresholds, output_dir: str) Dict[float, Dict[str, Any]][source]#
Trace each threshold velocity through the model, and save it as x, z.
- pick_travel_times(input_data: Dict[str, Any]) Dict[str, Any][source]#
First-arrival travel times picked from a raw SEG-Y file, for the inversion.
The picking half of
execute(), on its own so a workflow can show it as a step and stop before the inversion when the picks are wrong. Takesraw_seismic_file,output_dir,geophone_fileandtopography_file,align_originandfirst_break_paramsasexecute()does;first_break_params['reciprocity_check'](default True) leaves out shots whose times disagree with their reciprocals (reciprocal_shot_check()), andfirst_break_params['neighbour_check'](default True) picks again the picks that disagree with the neighbouring shots’ at the same geophone (neighbour_shot_check()).Returns the travel-time file and the picks (
traveltime_file,first_break_picks_file,picks_figure,gathers_figure- shot gathers as wiggles with their picks -n_picks,dropped_shots,segy_metadata) with the geometry and picking warnings, or a failed result - withorigin_mismatchwhen the coordinate file and the headers sit in two frames.
- static survey_scaled_defaults(seismic_data) Dict[str, Any][source]#
Inversion settings scaled to this survey, for any the caller does not give.
The fixed defaults (a 30 m deep mesh of 2 m cells, velocities from 500 m/s at the surface to 5000 m/s, bounded below at 300 m/s) describe a line hundreds of metres long over regolith. On an 11.5 m spread of 0.5 m geophones over soil with a 120 m/s surface layer they left the picks a median 4.9 ms from the model; scaled, 1.4 ms. Each setting is scaled only where the survey calls for it, so a long line keeps the fixed values:
paraDepth: 0.4 of the line’s length, at most 30 m;paraMaxCellSize: two sensor spacings, at most 2 m;vTop: the direct wave’s velocity (offsets of two spacings or less), at most 500 m/s;vBottom: one and a half times the apparent velocity at the far offsets - about the refractor’s velocity over flat layers - at least twicevTopand at most 5000 m/s;limits: from half the direct-wave velocity, at most 300 m/s, to 8000 m/s.
ClimateDataAgent#
Processing Agents#
ERTInversionAgent#
ERT Inversion Agent
Specialized agent for performing ERT inversion with optional structural constraints.
- class PyHydroGeophysX.agents.ert_inversion_agent.ERTInversionAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent specialized in ERT inversion.
Uses PyHydroGeophysX inversion module to perform resistivity inversion with optional structural constraints from seismic data.
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Perform ERT inversion (standard or time-lapse).
- Parameters:
input_data –
Dictionary containing:
ert_data: Loaded ERT data (for standard inversion)
inversion_mode: ‘standard’ or ‘time-lapse’
time_lapse_data: List of ERT datasets (for time-lapse)
time_lapse_method: recorded only; the solver implements one scheme (see PyHydroGeophysX.agents._method)
temporal_regularization: Temporal smoothing weight (for time-lapse)
inversion_params: Inversion parameters (lambda, max_iter, etc.)
use_structure_constraint: Whether to use seismic structure (default: False)
seismic_structure: Optional seismic structure data
output_dir: Directory for saving results
interpret: Ask the model to interpret the result (default: True, when there is an API key). A quality loop that re-inverts passes False: it keeps one model of several.
- Returns:
Dictionary containing inversion results
InversionEvaluationAgent#
Inversion Evaluation Agent
Specialized agent for evaluating ERT inversion quality and automatically adjusting regularization parameters to achieve optimal results.
- class PyHydroGeophysX.agents.inversion_evaluation_agent.InversionEvaluationAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent specialized in evaluating inversion quality and optimizing parameters.
This agent: 1. Evaluates inversion results using multiple quality metrics 2. Determines if results are acceptable 3. Automatically adjusts regularization parameters if needed 4. Triggers re-inversion with improved parameters
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Evaluate inversion results and adjust parameters if needed.
- Parameters:
input_data –
Dictionary containing:
inversion_results: Results from ERTInversionAgent
ert_data: Original ERT data
inversion_params: Current inversion parameters
time_lapse_data: List of ERT datasets (for time-lapse)
inversion_mode: ‘standard’ or ‘time-lapse’
auto_adjust: Whether to automatically adjust and re-run (default: True)
max_attempts: Maximum total evaluations, including the initial result (default: 3, allowing at most two re-inversions)
quality_threshold: Overall quality threshold (default: 70)
progress_callback: Optional callback for transparent loop logs
custom_thresholds: Optional custom quality thresholds
- Returns:
status: ‘success’, ‘needs_review’, or ‘failed’
quality_score: Overall quality score (0-100)
quality_metrics: Detailed quality metrics
recommendations: List of improvement recommendations
adjusted_params: Adjusted parameters (if auto_adjust=True)
final_results: Best inversion results
evaluation_history: History of all attempts
- Return type:
Dictionary containing
TDEMAgent#
TDEM (Time-Domain Electromagnetic) Agent
Agent for processing Time-Domain Electromagnetic data using SimPEG. Supports forward modeling, inversion, and integration with hydrological models.
- class PyHydroGeophysX.agents.tdem_agent.TDEMAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent for Time-Domain Electromagnetic (TDEM) data processing.
This agent provides functionality for: - Loading TDEM sounding data from text files - Forward modeling from hydrological models (MODFLOW, ParFlow) - 1D TDEM inversion with L2 and sparse (IRLS) regularization - Petrophysical conversion between water content and conductivity - Visualization and reporting
- Example (with your own sounding file):
>>> agent = TDEMAgent() >>> result = agent.execute({ ... 'data_file': 'tdem_data.txt', ... 'source_radius': 10.0, ... 'n_layers': 20, ... 'output_dir': 'results/tdem' ... })
- UNCERTAINTY_NAMES = ('unc', 'err', 'std', 'noise', 'sigma')#
Header names that mark a column as an uncertainty rather than a sounding.
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Execute TDEM workflow based on input configuration.
- Parameters:
input_data –
Dictionary containing: - data_file: Path to TDEM data file (optional if forward modeling) - mode: ‘inversion’, ‘forward’, or ‘hydro_to_tdem’ - source_radius: Loop radius in meters (default: 10) - n_layers: Number of layers for inversion (default: 20) - output_dir: Output directory for results - use_irls: Use sparse regularization (default: True)
For forward modeling: - thicknesses: Layer thicknesses (m) - conductivity: Layer conductivities (S/m)
For hydro_to_tdem: - water_content: Water content array - porosity: Porosity array - layer_thicknesses: Layer thicknesses (m) - petrophysical_params: Petrophysical parameters
- Returns:
Dictionary containing results based on mode
DataFusionAgent#
Data Fusion Agent
Intelligent coordinator for multi-method geophysical workflows. This agent understands which geophysical methods should work together and orchestrates complex data fusion workflows like seismic-constrained ERT inversion.
The DataFusionAgent is designed to be extensible for future multi-method combinations.
- class PyHydroGeophysX.agents.data_fusion_agent.DataFusionAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent for intelligent coordination of multi-method geophysical workflows.
This agent understands common geophysical data fusion patterns and can recommend and execute appropriate multi-method workflows based on user requirements.
- Supported Fusion Patterns:
ERT + Seismic: Structure-constrained resistivity inversion
ERT + Gravity: Density-constrained models
Multiple Time-Lapse: Joint temporal inversion
(Extensible for future methods)
- FUSION_PATTERNS = {'full_integration': {'benefits': 'Complete geological-to-hydrological workflow with constraints', 'description': 'Structure-constrained ERT with hydrological conversion', 'methods': ['seismic', 'ert', 'petrophysics'], 'workflow': ['seismic_inversion', 'interface_extraction', 'constrained_ert', 'petrophysics_conversion']}, 'petrophysics_integration': {'benefits': 'Direct hydrological interpretation from geophysical data', 'description': 'Convert resistivity to hydrological properties', 'methods': ['ert', 'petrophysics'], 'workflow': ['ert_inversion', 'petrophysics_conversion']}, 'structure_constraint': {'benefits': 'Improved layer boundary resolution and reduced artifacts', 'description': 'Use seismic velocity interfaces to constrain ERT inversion', 'methods': ['seismic', 'ert'], 'workflow': ['seismic_inversion', 'interface_extraction', 'constrained_ert']}}#
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Execute multi-method data fusion workflow.
- Parameters:
input_data – Dictionary containing: - fusion_pattern: Name of fusion pattern or ‘auto’ for LLM recommendation - methods: List of available methods (e.g., [‘seismic’, ‘ert’]) - workflow_config: Configuration for the fusion workflow - data: Dictionary of data for each method - output_dir: Directory for saving results
- Returns:
Dictionary containing fused results and workflow metadata
- execute_full_workflow(input_data: Dict[str, Any]) Dict[str, Any][source]#
Execute the complete multi-method data fusion workflow, not just planning.
This method actually runs the agents and produces results, unlike execute() which only creates a plan.
- Parameters:
input_data – Dictionary containing: - fusion_pattern: Name of fusion pattern - methods: List of available methods - workflow_config: Configuration for the fusion workflow - data: Dictionary of data for each method - output_dir: Directory for saving results
- Returns:
Dictionary containing complete workflow results
- get_available_patterns() Dict[str, Dict][source]#
Get information about all available fusion patterns.
- Returns:
Dictionary of fusion patterns with descriptions
- validate_workflow(available_methods: List[str], desired_pattern: str) Dict[str, Any][source]#
Validate if a desired fusion pattern can be executed with available methods.
- Parameters:
available_methods – List of available methods
desired_pattern – Desired fusion pattern name
- Returns:
Validation result dictionary
StructureConstraintAgent#
Structure Constraint Agent
Applies seismic velocity interfaces as structural constraints to ERT inversion. Implements the workflow from Ex_Structure_resinv.py for creating structure-constrained resistivity models.
- class PyHydroGeophysX.agents.structure_constraint_agent.StructureConstraintAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent for applying structural constraints from seismic data to ERT inversion.
This agent creates ERT meshes that honor geological boundaries derived from seismic velocity interfaces, leading to more accurate resistivity models that preserve sharp layer contrasts.
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Execute structure-constrained ERT inversion.
- Parameters:
input_data – Dictionary containing: - ert_data: ERT measurement data - seismic_data: (Optional) Seismic traveltime data for interface extraction - interface_coords: (Optional) Tuple of (x, z) coordinates from seismic - velocity_threshold: (Optional) Velocity threshold for interface extraction - seismic_params: (Optional) Parameters for seismic inversion - inversion_params: ERT inversion parameters - output_dir: Directory for saving results - mesh_quality: Mesh quality parameter (default: 31)
- Returns:
Dictionary containing constrained resistivity model and mesh
Conversion Agents#
PetrophysicsAgent#
Petrophysics Agent
Converts resistivity models to hydrological properties (water content, saturation, porosity) using structure-constrained petrophysical models with Monte Carlo uncertainty quantification. Implements the workflow from Ex_MC_Hydro.py.
- PyHydroGeophysX.agents.petrophysics_agent.LAYER_RANGE_KEYS = (('rho_sat_range', 'rho_sat'), ('n_range', 'n'), ('porosity_range', 'porosity'))#
The per-layer ranges a request can give, and the parameter each one sets.
- class PyHydroGeophysX.agents.petrophysics_agent.PetrophysicsAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent for converting resistivity to hydrological properties with uncertainty.
This agent uses Archie’s law and modified petrophysical models to convert resistivity to water content, incorporating: - Layer-specific parameters from structural constraints - Monte Carlo uncertainty quantification - Surface conductivity effects in clay-rich materials
- DEFAULT_LAYER_PARAMS = {'bedrock': {'m': {'mean': 1.9, 'std': 0.2}, 'n': {'mean': 1.7, 'std': 0.2}, 'porosity': {'mean': 0.25, 'std': 0.15}, 'rho_fluid': 20.0, 'sigma_sur': {'mean': 0.0, 'std': 0.0}}, 'regolith': {'m': {'mean': 1.3, 'std': 0.1}, 'n': {'mean': 2.1, 'std': 0.1}, 'porosity': {'mean': 0.42, 'std': 0.05}, 'rho_fluid': 20.0, 'sigma_sur': {'mean': 0.005, 'std': 0.005}}}#
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Convert resistivity to water content with uncertainty quantification.
- Parameters:
input_data – Dictionary containing: - resistivity_model: Resistivity values (can be 1D or 2D for time-lapse) - mesh: PyGIMLI mesh with cell markers - cell_markers: Array identifying geological layers - layer_params: Dictionary of parameters for each layer (optional) - n_realizations: Number of Monte Carlo samples (default: 100) - output_dir: Directory for saving results
- Returns:
Dictionary containing water content statistics and uncertainty
WaterContentAgent#
Water Content Conversion Agent
Specialized agent for converting resistivity to water content using petrophysical models.
- class PyHydroGeophysX.agents.water_content_agent.WaterContentAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent specialized in converting resistivity to water content.
Uses PyHydroGeophysX petrophysical models and Monte Carlo uncertainty quantification to estimate water content from resistivity.
- execute(input_data: Dict[str, Any]) Dict[str, Any][source]#
Convert resistivity to water content.
- Parameters:
input_data – Dictionary containing: - inversion_results: ERT inversion results - petrophysical_params: Parameters for each layer (rhos, n, porosity, etc.) - uncertainty_analysis: Whether to run Monte Carlo (default: False) - n_realizations: Number of MC realizations (default: 100) - output_dir: Directory for saving results
- Returns:
Dictionary containing water content estimates and uncertainties