Common Workflow Patterns#
This document describes common workflow patterns for using the PyHydroGeophysX multi-agent system, from basic ERT processing to advanced multi-method fusion.
Pattern A: Basic ERT Processing#
Use Case: Single ERT dataset, no constraints
Agents: Context → Loader → Inversion → Evaluation → WaterContent → Report
Workflow Diagram:
User Input
│
▼
ContextInputAgent (parse natural language)
│
▼
ERTLoaderAgent (load data)
│
▼
ERTInversionAgent (invert)
│
▼
InversionEvaluationAgent (evaluate & optimize)
│
▼
WaterContentAgent (convert to WC)
│
▼
ReportAgent (generate report)
Example Code:
from PyHydroGeophysX.agents import (
ERTLoaderAgent,
ERTInversionAgent,
InversionEvaluationAgent,
WaterContentAgent,
ReportAgent
)
# Load data
loader = ERTLoaderAgent(api_key)
data = loader.execute({
'data_file': 'field_ert.ohm',
'instrument': 'E4D',
'quality_check': True
})
# Invert
inverter = ERTInversionAgent(api_key)
inv_result = inverter.execute({
'ert_data': data['ert_data'],
'inversion_mode': 'standard',
'inversion_params': {'lambda': 20}
})
# Evaluate and optimize
evaluator = InversionEvaluationAgent(api_key)
eval_result = evaluator.execute({
'inversion_results': inv_result,
'ert_data': data['ert_data'],
'auto_adjust': True
})
# Convert to water content
converter = WaterContentAgent(api_key)
wc = converter.execute({
'inversion_results': eval_result['final_results'],
'petrophysical_params': {'porosity': 0.35, 'n': 2.0}
})
Pattern B: Time-Lapse Monitoring#
Use Case: Multiple ERT datasets over time
Agents: Context → Loader (xN) → Climate → Inversion (time-lapse) → Evaluation → WaterContent → Report
Special Features:
Temporal regularization
Climate data integration
Difference/ratio/joint methods
Workflow Diagram:
User Input
│
▼
ContextInputAgent (identify time-lapse)
│
▼
ERTLoaderAgent (load multiple datasets)
│
▼
ClimateDataAgent (fetch climate data) [optional]
│
▼
ERTInversionAgent (time-lapse inversion)
│
├─ difference method
├─ ratio method
└─ joint inversion
│
▼
InversionEvaluationAgent (evaluate quality)
│
▼
WaterContentAgent (temporal conversion)
│
▼
ReportAgent (temporal analysis + climate integration)
Example Code:
from PyHydroGeophysX.agents import (
ERTLoaderAgent,
ClimateDataAgent,
ERTInversionAgent,
WaterContentAgent
)
# Load multiple time-lapse datasets
loader = ERTLoaderAgent(api_key)
datasets = []
for file in ['ert_t1.ohm', 'ert_t2.ohm', 'ert_t3.ohm']:
result = loader.execute({'data_file': file, 'instrument': 'E4D'})
datasets.append(result['ert_data'])
# Fetch climate data
climate = ClimateDataAgent(api_key)
climate_data = climate.execute({
'geometry': {'lat': 41.5, 'lon': -91.5},
'start_date': '2024-01-01',
'end_date': '2024-03-31',
'variables': ['precipitation', 'temperature']
})
# Time-lapse inversion
inverter = ERTInversionAgent(api_key)
inv_result = inverter.execute({
'time_lapse_data': datasets,
'inversion_mode': 'time-lapse',
'time_lapse_method': 'ratio',
'temporal_regularization': 10.0
})
Pattern C: Structure-Constrained Fusion#
Use Case: Seismic + ERT with layer identification
Agents: Context → DataFusion → Seismic → Structure → Petrophysics → Report
Special Features:
Interface extraction from seismic velocity
Layer-specific petrophysical parameters
Monte Carlo uncertainty (10,000 realizations)
Workflow Diagram:
User Input
│
▼
ContextInputAgent (parse multi-method request)
│
▼
DataFusionAgent (recommend fusion pattern)
│
├─────────────────┬─────────────────┐
│ │ │
▼ ▼ ▼
SeismicAgent ERTLoaderAgent (other methods)
(velocity) │
│ │
└───────┬───────┘
│
▼
StructureConstraintAgent
(extract interfaces → constrained mesh → constrained inversion)
│
▼
PetrophysicsAgent
(layer-specific conversion with MC uncertainty)
│
▼
ReportAgent
Example Code:
from PyHydroGeophysX.agents import (
DataFusionAgent,
SeismicAgent,
ERTLoaderAgent,
StructureConstraintAgent,
PetrophysicsAgent
)
# Recommend fusion pattern
fusion = DataFusionAgent(api_key)
plan = fusion.execute({
'fusion_pattern': 'auto',
'methods': ['seismic', 'ert'],
'data': {
'seismic': 'seismic.sgt',
'ert': 'ert.ohm'
}
})
# Process seismic data
seismic = SeismicAgent(api_key)
seis_result = seismic.execute({
'seismic_data': 'seismic.sgt',
'velocity_threshold': 1200
})
# Load ERT data
ert_loader = ERTLoaderAgent(api_key)
ert_data = ert_loader.execute({
'data_file': 'ert.ohm',
'instrument': 'E4D'
})
# Structure-constrained inversion
structure = StructureConstraintAgent(api_key)
constrained = structure.execute({
'ert_data': ert_data['ert_data'],
'velocity_model': seis_result['velocity_model'],
'velocity_thresholds': [1000, 1950],
'lambda': 20
})
# Layer-specific petrophysics
petro = PetrophysicsAgent(api_key)
wc = petro.execute({
'resistivity_model': constrained['resistivity_model'],
'mesh': constrained['mesh'],
'cell_markers': constrained['cell_markers'],
'n_realizations': 10000
})
Pattern D: Full Field-Scale Analysis#
Use Case: Complete hydrogeophysical characterization
Agents: Context → DataFusion → Seismic → ERTLoader → Structure → Evaluation → Petrophysics → Report
Special Features:
Multi-method integration
Quality optimization loop
Comprehensive uncertainty quantification
Publication-ready reports
Workflow Diagram:
User Natural Language Request
│
▼
ContextInputAgent
│
▼
DataFusionAgent
│
├─────────────────────────────┐
│ │
▼ ▼
SeismicAgent ERTLoaderAgent
│ │
└───────────┬─────────────────┘
│
▼
StructureConstraintAgent
│
▼
InversionEvaluationAgent
│
┌───┴───┐
│ │
▼ ▼
Adjust Accept
│
▼
PetrophysicsAgent (MC uncertainty)
│
▼
ReportAgent
TDEM Workflow#
Use Case: Time-Domain Electromagnetic sounding from hydrological models
Workflow Diagram:
MODFLOW/ParFlow Data
│
▼
Extract 1D Vertical Profile
│
▼
WS_Model (Waxman-Smits Petrophysics)
│
▼
TDEMForwardModeling
│
▼
Add Synthetic Noise
│
▼
TDEMInversion
│
▼
Compare True vs Recovered
Example Code:
from PyHydroGeophysX.forward.tdem_forward import (
TDEMForwardModeling,
TDEMSurveyConfig
)
from PyHydroGeophysX.inversion.tdem_inversion import TDEMInversion
from PyHydroGeophysX.petrophysics.resistivity_models import WS_Model
import numpy as np
# Convert water content to conductivity
conductivity = 1.0 / WS_Model(
saturation, porosity, sigma_w=0.05, m=1.5, n=2.0, sigma_s=0.001
)
# Configure TDEM survey
times = np.logspace(-5, -2, 31)
survey = TDEMSurveyConfig(
source_location=np.array([0.0, 0.0, 0.0]),
source_radius=10.0,
times=times
)
# Forward modeling
fwd = TDEMForwardModeling(thicknesses, survey)
dobs, dpred, uncertainties = fwd.forward_with_noise(
conductivity, noise_level=0.05
)
# Inversion
inv = TDEMInversion(
times=times,
dobs=dobs,
uncertainties=uncertainties,
source_radius=10.0,
n_layers=20,
use_irls=True
)
result = inv.run()
3D ERT Workflow#
Use Case: 3D ERT forward modeling with MODFLOW integration
Workflow Diagram:
MODFLOW 3D Data
│
▼
Analyze Active Cells (find optimal domain)
│
▼
Create Surface Electrode Array
│
▼
Apply Topography to Electrodes
│
▼
Create 3D Mesh with Topography
│
▼
Interpolate Hydrological Properties
│
▼
Waxman-Smits Conversion
│
▼
3D ERT Forward Modeling
│
▼
PyVista Visualization
Example Code:
from PyHydroGeophysX.core.mesh_3d import (
Mesh3DCreator,
create_3d_ert_data_container
)
from PyHydroGeophysX.petrophysics.resistivity_models import WS_Model
from pygimli.physics import ert
# Initialize mesh creator
creator = Mesh3DCreator(
mesh_directory='./meshes',
elec_refinement=0.3
)
# Create electrodes with topography
electrodes = creator.create_surface_electrode_array(
nx=5, ny=5, dx=4.0, dy=4.0
)
electrodes = creator.apply_topography_to_electrodes(
electrodes, topography_function
)
# Create 3D mesh
mesh = creator.create_3d_mesh_with_topography(
electrode_positions=electrodes,
topography_func=topography_function,
para_depth=14.0,
use_prism_mesh=True
)
# Create data container
data = create_3d_ert_data_container(
electrodes, scheme='dd', dimension=3
)
# Forward modeling
fop = ert.ERTModelling()
fop.setData(data)
fop.setMesh(mesh)
response = fop.response(resistivity_mesh)
Best Practices#
Start Simple: Begin with Pattern A before moving to more complex workflows
Validate Data: Always enable quality_check=True in ERTLoaderAgent
Iterate on Inversion: Use InversionEvaluationAgent with auto_adjust=True
Quantify Uncertainty: Use PetrophysicsAgent with n_realizations >= 1000
Document Results: Always include ReportAgent for reproducibility
Check Chi-Squared: Target chi2 between 0.8 and 1.5 for good data fit
Use Appropriate Constraints: Structure constraints improve resolution but require seismic data