PyHydroGeophysX package#
Subpackages#
- PyHydroGeophysX.Geophy_modular package
- PyHydroGeophysX.Hydro_modular package
- Submodules
- PyHydroGeophysX.Hydro_modular.hydro_to_ert module
- PyHydroGeophysX.Hydro_modular.hydro_to_fdem module
- PyHydroGeophysX.Hydro_modular.hydro_to_geophysics module
- PyHydroGeophysX.Hydro_modular.hydro_to_gravity module
- PyHydroGeophysX.Hydro_modular.hydro_to_srt module
- PyHydroGeophysX.Hydro_modular.hydro_to_tdem module
- Module contents
- PyHydroGeophysX.agents package
- Submodules
- PyHydroGeophysX.agents.agent_coordinator module
- PyHydroGeophysX.agents.base_agent module
AgentResultAgentResult.cost_estimate_usdAgentResult.dataAgentResult.elapsed_secondsAgentResult.errorAgentResult.error_fix_hintAgentResult.from_dict()AgentResult.get()AgentResult.items()AgentResult.keys()AgentResult.llm_interpretationAgentResult.next_suggested_actionAgentResult.statusAgentResult.summaryAgentResult.to_dict()AgentResult.values()AgentResult.warnings
BaseAgent
- PyHydroGeophysX.agents.climate_data_agent module
- PyHydroGeophysX.agents.code_generation_agent module
- PyHydroGeophysX.agents.context_input_agent module
- PyHydroGeophysX.agents.data_fusion_agent module
- PyHydroGeophysX.agents.ert_inversion_agent module
- PyHydroGeophysX.agents.ert_loader_agent module
- PyHydroGeophysX.agents.fetch_climate_data module
- PyHydroGeophysX.agents.geophysical_inversion_agent module
- PyHydroGeophysX.agents.inversion_evaluation_agent module
- PyHydroGeophysX.agents.model_output_agent module
- PyHydroGeophysX.agents.petrophysics_agent module
- PyHydroGeophysX.agents.report_agent module
- PyHydroGeophysX.agents.seismic_agent module
- PyHydroGeophysX.agents.structure_constraint_agent module
- PyHydroGeophysX.agents.studio_tools module
- PyHydroGeophysX.agents.tdem_agent module
- PyHydroGeophysX.agents.water_content_agent module
- PyHydroGeophysX.agents.workflow_orchestrator_agent module
- Module contents
AgentCoordinatorAgentResultAgentResult.cost_estimate_usdAgentResult.dataAgentResult.elapsed_secondsAgentResult.errorAgentResult.error_fix_hintAgentResult.from_dict()AgentResult.get()AgentResult.items()AgentResult.keys()AgentResult.llm_interpretationAgentResult.next_suggested_actionAgentResult.statusAgentResult.summaryAgentResult.to_dict()AgentResult.values()AgentResult.warnings
BaseAgentContextInputAgentERTInversionAgentERTLoaderAgentGeophysicalInversionAgentSeismicAgentWaterContentAgent
- PyHydroGeophysX.analysis package
- PyHydroGeophysX.assimilation package
- PyHydroGeophysX.core package
- Submodules
- PyHydroGeophysX.core.interpolation module
- PyHydroGeophysX.core.kriging_3d module
- PyHydroGeophysX.core.mesh_3d module
- PyHydroGeophysX.core.mesh_serialization module
- PyHydroGeophysX.core.mesh_utils module
- PyHydroGeophysX.core.plt_utils module
- Module contents
- PyHydroGeophysX.data_access package
- PyHydroGeophysX.data_processing package
- Submodules
- PyHydroGeophysX.data_processing.em1d module
- PyHydroGeophysX.data_processing.ert_data_agent module
- PyHydroGeophysX.data_processing.ert_formats module
- PyHydroGeophysX.data_processing.ert_io module
- PyHydroGeophysX.data_processing.field_formats module
- PyHydroGeophysX.data_processing.gravmag module
- PyHydroGeophysX.data_processing.joint_io module
- PyHydroGeophysX.data_processing.model_csv module
- PyHydroGeophysX.data_processing.run_inputs module
- PyHydroGeophysX.data_processing.seismic module
FirstBreakPickFirstBreakPick.amplitudeFirstBreakPick.field_recordFirstBreakPick.receiver_idFirstBreakPick.receiver_xFirstBreakPick.receiver_zFirstBreakPick.source_idFirstBreakPick.source_xFirstBreakPick.source_zFirstBreakPick.time_sFirstBreakPick.to_dict()FirstBreakPick.trace_indexFirstBreakPick.trace_number
SegyMetadataSeismicDatasetSeismicShotGatherSeismicTraceHeaderSeismicTraceHeader.energy_source_pointSeismicTraceHeader.field_recordSeismicTraceHeader.offsetSeismicTraceHeader.receiver_xSeismicTraceHeader.receiver_ySeismicTraceHeader.receiver_zSeismicTraceHeader.source_xSeismicTraceHeader.source_ySeismicTraceHeader.source_zSeismicTraceHeader.trace_number
apply_agc()bandpass_filter()export_first_breaks()export_traveltime_container()first_breaks_to_traveltime()normalize_traces()pick_first_breaks()read_segy()tukey_taper()
- PyHydroGeophysX.data_processing.table_io module
- PyHydroGeophysX.data_processing.temcompany_reference module
- PyHydroGeophysX.data_processing.ttem module
- Module contents
FirstBreakPickFirstBreakPick.amplitudeFirstBreakPick.field_recordFirstBreakPick.receiver_idFirstBreakPick.receiver_xFirstBreakPick.receiver_zFirstBreakPick.source_idFirstBreakPick.source_xFirstBreakPick.source_zFirstBreakPick.time_sFirstBreakPick.to_dict()FirstBreakPick.trace_indexFirstBreakPick.trace_number
SegyMetadataSeismicDatasetSeismicShotGatherSeismicTraceHeaderSeismicTraceHeader.energy_source_pointSeismicTraceHeader.field_recordSeismicTraceHeader.offsetSeismicTraceHeader.receiver_xSeismicTraceHeader.receiver_ySeismicTraceHeader.receiver_zSeismicTraceHeader.source_xSeismicTraceHeader.source_ySeismicTraceHeader.source_zSeismicTraceHeader.trace_number
TravelTimeModelTravelTimeModelSegmentTravelTimeModelSegment.apparent_velocity_m_sTravelTimeModelSegment.branch_idTravelTimeModelSegment.crossover_offset_mTravelTimeModelSegment.depth_estimate_mTravelTimeModelSegment.intercept_sTravelTimeModelSegment.intercept_time_sTravelTimeModelSegment.segment_indexTravelTimeModelSegment.slope_s_per_mTravelTimeModelSegment.x_maxTravelTimeModelSegment.x_min
apply_agc()bandpass_filter()ensure_dir()export_first_breaks()export_model_csv()export_results_to_csv()export_to_vtk()export_traveltime_container()extract_profile()first_breaks_to_traveltime()fit_velocity_traveltime_model()grid_data()has_reference_models()is_temcompany_source()is_ttem_source()load_2d_array()load_joint_observations()load_line_geometry()load_reference_models()load_sounding()load_temcompany_sounding()load_ttem_sounding()load_xyz_table()model_cell_table()normalize_traces()pick_first_breaks()predict_velocity_traveltimes()qc_products()read_geometrics_dat()read_json()read_seg2_seismic()read_segy()read_tem_fast()regional_residual()save_edited_ert_container()save_joint_observations()spatially_balanced_indices()tukey_taper()write_csv()write_grid_model_csv()write_json()write_layered_model_csv()write_mesh_geometry_csv()write_model_csv()
- PyHydroGeophysX.forward package
- Submodules
- PyHydroGeophysX.forward.em1d module
- PyHydroGeophysX.forward.ert3d module
- PyHydroGeophysX.forward.ert_forward module
- PyHydroGeophysX.forward.fdem_forward module
- PyHydroGeophysX.forward.gravmag module
- PyHydroGeophysX.forward.srt_forward module
- PyHydroGeophysX.forward.tdem_forward module
GATE_SHAPE_NAMESGATE_WINDOWSTDEMForwardModelingTDEMSurveyConfigTDEMSurveyConfig.source_locationTDEMSurveyConfig.source_radiusTDEMSurveyConfig.source_currentTDEMSurveyConfig.receiver_locationTDEMSurveyConfig.receiver_orientationTDEMSurveyConfig.timesTDEMSurveyConfig.waveform_typeTDEMSurveyConfig.analog_lowpassTDEMSurveyConfig.analog_model_points_per_decadeTDEMSurveyConfig.analog_points_per_decadeTDEMSurveyConfig.gate_closeTDEMSurveyConfig.gate_openTDEMSurveyConfig.gate_quadrature_orderTDEMSurveyConfig.gate_windowTDEMSurveyConfig.gate_window_parTDEMSurveyConfig.instrument_model_points_per_decadeTDEMSurveyConfig.instrument_points_per_decadeTDEMSurveyConfig.receiver_locationTDEMSurveyConfig.receiver_orientationTDEMSurveyConfig.receiver_typeTDEMSurveyConfig.source_currentTDEMSurveyConfig.source_locationTDEMSurveyConfig.source_momentTDEMSurveyConfig.source_radiusTDEMSurveyConfig.source_turnsTDEMSurveyConfig.timesTDEMSurveyConfig.waveform_currentsTDEMSurveyConfig.waveform_periodTDEMSurveyConfig.waveform_repetitionsTDEMSurveyConfig.waveform_timesTDEMSurveyConfig.waveform_type
create_tdem_survey()hydro_to_tdem()simulate_tdem_sounding_from_hydro()
- Module contents
ERTForwardModelingFDEMForwardModelingFDEMSurveyConfigSeismicForwardModelingTDEMForwardModelingTDEMSurveyConfigTDEMSurveyConfig.source_locationTDEMSurveyConfig.source_radiusTDEMSurveyConfig.source_currentTDEMSurveyConfig.receiver_locationTDEMSurveyConfig.receiver_orientationTDEMSurveyConfig.timesTDEMSurveyConfig.waveform_typeTDEMSurveyConfig.analog_lowpassTDEMSurveyConfig.analog_model_points_per_decadeTDEMSurveyConfig.analog_points_per_decadeTDEMSurveyConfig.gate_closeTDEMSurveyConfig.gate_openTDEMSurveyConfig.gate_quadrature_orderTDEMSurveyConfig.gate_windowTDEMSurveyConfig.gate_window_parTDEMSurveyConfig.instrument_model_points_per_decadeTDEMSurveyConfig.instrument_points_per_decadeTDEMSurveyConfig.receiver_locationTDEMSurveyConfig.receiver_orientationTDEMSurveyConfig.receiver_typeTDEMSurveyConfig.source_currentTDEMSurveyConfig.source_locationTDEMSurveyConfig.source_momentTDEMSurveyConfig.source_radiusTDEMSurveyConfig.source_turnsTDEMSurveyConfig.timesTDEMSurveyConfig.waveform_currentsTDEMSurveyConfig.waveform_periodTDEMSurveyConfig.waveform_repetitionsTDEMSurveyConfig.waveform_timesTDEMSurveyConfig.waveform_type
create_tdem_survey()ertforandjac()ertforandjac2()ertforward()ertforward2()forward_bodies()gravity_prism()gravity_sphere()hydro_to_tdem()magnetic_dipole()simulate_tdem_sounding_from_hydro()
- PyHydroGeophysX.inversion package
- Submodules
- PyHydroGeophysX.inversion.base module
InversionBaseInversionResultInversionResult.final_modelInversionResult.predicted_dataInversionResult.coverageInversionResult.meshInversionResult.iteration_modelsInversionResult.iteration_data_errorsInversionResult.iteration_chi2InversionResult.metaInversionResult.load()InversionResult.plot_convergence()InversionResult.plot_model()InversionResult.save()
TimeLapseInversionResultTimeLapseInversionResult.final_modelsTimeLapseInversionResult.timestepsTimeLapseInversionResult.all_coverageTimeLapseInversionResult.all_chi2TimeLapseInversionResult.create_time_lapse_animation()TimeLapseInversionResult.load()TimeLapseInversionResult.plot_time_slice()TimeLapseInversionResult.save()
- PyHydroGeophysX.inversion.cross_constraints module
PetrophysicalCouplingStructuralConstraintStructuralConstraint.apply_structural_weights_to_Wm()StructuralConstraint.build_cross_gradient_operator()StructuralConstraint.build_linearized_cross_gradient_blocks()StructuralConstraint.build_local_design_matrix()StructuralConstraint.build_neighborhood_matrix()StructuralConstraint.from_conductivity_model()StructuralConstraint.from_velocity_model()
- PyHydroGeophysX.inversion.em1d module
- PyHydroGeophysX.inversion.em1d_lci module
CHI2_EQUIVALENCEDOI_SENSITIVITY_THRESHOLDLCIResultLCIResult.as_dict()LCIResult.chi2LCIResult.chi2_historyLCIResult.chi2_median_historyLCIResult.chi2_per_soundingLCIResult.diagnosticsLCIResult.iterationsLCIResult.lambda_lateralLCIResult.lambda_searchLCIResult.lambda_verticalLCIResult.modelsLCIResult.n_dataLCIResult.secondsLCIResult.smoothness_scaleLCIResult.stop_reason
LOG_RESISTIVITY_BOUNDSSMOOTHNESS_SCALE_BOUNDSSoundingBlockcumulated_sensitivity()invert_lci()invert_lci_rejecting_outliers()invert_lci_with_robust_errors()lateral_edges()mask_sounding_block()sensitivity_doi()solve_lci()weighted_residuals()
- PyHydroGeophysX.inversion.em1d_priors module
- PyHydroGeophysX.inversion.ert_inversion module
- PyHydroGeophysX.inversion.fdem_inversion module
- PyHydroGeophysX.inversion.gravmag module
- PyHydroGeophysX.inversion.joint module
JointInversionRequestJointInversionResultJointInversionResult.artifactsJointInversionResult.baselineJointInversionResult.chi2JointInversionResult.coverageJointInversionResult.historyJointInversionResult.metaJointInversionResult.methodsJointInversionResult.modelsJointInversionResult.predictedJointInversionResult.statusJointInversionResult.strategyJointInversionResult.summary()JointInversionResult.warnings
JointPairCapabilityget_joint_capabilities()get_joint_capability()normalize_joint_pair()run_joint_inversion()
- PyHydroGeophysX.inversion.joint_api module
JointInversionRequestJointInversionResultJointInversionResult.artifactsJointInversionResult.baselineJointInversionResult.chi2JointInversionResult.coverageJointInversionResult.historyJointInversionResult.metaJointInversionResult.methodsJointInversionResult.modelsJointInversionResult.predictedJointInversionResult.statusJointInversionResult.strategyJointInversionResult.summary()JointInversionResult.warnings
JointMethodAdapterJointPairCapabilityget_joint_capabilities()get_joint_capability()normalize_joint_pair()pair_joint_soundings()split_joint_soundings()validate_profile_interface()
- PyHydroGeophysX.inversion.joint_ert_srt module
JointERTSRTInversionJointERTSRTResultJointERTSRTResult.chi2_ertJointERTSRTResult.chi2_srtJointERTSRTResult.ert_coverageJointERTSRTResult.ert_log_resistivityJointERTSRTResult.ert_predictedJointERTSRTResult.ert_resistivityJointERTSRTResult.iteration_historyJointERTSRTResult.meshJointERTSRTResult.metaJointERTSRTResult.srt_coverageJointERTSRTResult.srt_log_slownessJointERTSRTResult.srt_predictedJointERTSRTResult.srt_velocity
- PyHydroGeophysX.inversion.joint_fdem_tdem module
JointFDEMTDEMInversionJointFDEMTDEMResultJointFDEMTDEMResult.baselineJointFDEMTDEMResult.chi2_fdemJointFDEMTDEMResult.chi2_tdemJointFDEMTDEMResult.conductivityJointFDEMTDEMResult.convergenceJointFDEMTDEMResult.coverage_fdemJointFDEMTDEMResult.coverage_tdemJointFDEMTDEMResult.metaJointFDEMTDEMResult.predicted_fdemJointFDEMTDEMResult.predicted_tdemJointFDEMTDEMResult.resistivityJointFDEMTDEMResult.thicknesses
- PyHydroGeophysX.inversion.joint_gravity_magnetics module
GravityMagneticsJointResultGravityMagneticsJointResult.baselineGravityMagneticsJointResult.chi2_gravityGravityMagneticsJointResult.chi2_magneticsGravityMagneticsJointResult.convergenceGravityMagneticsJointResult.coverage_gravityGravityMagneticsJointResult.coverage_magneticsGravityMagneticsJointResult.cross_gradientGravityMagneticsJointResult.densityGravityMagneticsJointResult.edgesGravityMagneticsJointResult.metaGravityMagneticsJointResult.model_shapeGravityMagneticsJointResult.predicted_gravityGravityMagneticsJointResult.predicted_magneticsGravityMagneticsJointResult.susceptibility
JointGravityMagneticsInversion
- PyHydroGeophysX.inversion.lambda_search module
- PyHydroGeophysX.inversion.metrics module
- PyHydroGeophysX.inversion.multi_method module
- PyHydroGeophysX.inversion.robust_errors module
- PyHydroGeophysX.inversion.srt_inversion module
- PyHydroGeophysX.inversion.srt_time_lapse module
- PyHydroGeophysX.inversion.tdem_inversion module
TDEMInversionTDEMInversionResultTDEMInversionResult.recovered_modelTDEMInversionResult.recovered_conductivityTDEMInversionResult.l2_modelTDEMInversionResult.l2_conductivityTDEMInversionResult.predicted_dataTDEMInversionResult.meshTDEMInversionResult.thicknessesTDEMInversionResult.chi2TDEMInversionResult.iterationsTDEMInversionResult.convergence_historyTDEMInversionResult.chi2TDEMInversionResult.convergence_historyTDEMInversionResult.iterationsTDEMInversionResult.l2_conductivityTDEMInversionResult.l2_modelTDEMInversionResult.meshTDEMInversionResult.predicted_dataTDEMInversionResult.recovered_conductivityTDEMInversionResult.recovered_modelTDEMInversionResult.thicknesses
run_tdem_inversion()
- PyHydroGeophysX.inversion.time_lapse module
- PyHydroGeophysX.inversion.windowed module
- Module contents
ERTInversionFDEMInversionFDEMInversionResultGeophysicalInversionGravityMagneticsJointResultGravityMagneticsJointResult.baselineGravityMagneticsJointResult.chi2_gravityGravityMagneticsJointResult.chi2_magneticsGravityMagneticsJointResult.convergenceGravityMagneticsJointResult.coverage_gravityGravityMagneticsJointResult.coverage_magneticsGravityMagneticsJointResult.cross_gradientGravityMagneticsJointResult.densityGravityMagneticsJointResult.edgesGravityMagneticsJointResult.metaGravityMagneticsJointResult.model_shapeGravityMagneticsJointResult.predicted_gravityGravityMagneticsJointResult.predicted_magneticsGravityMagneticsJointResult.susceptibility
InversionBackendUnavailableInversionBaseInversionResultInversionResult.final_modelInversionResult.predicted_dataInversionResult.coverageInversionResult.meshInversionResult.iteration_modelsInversionResult.iteration_data_errorsInversionResult.iteration_chi2InversionResult.metaInversionResult.load()InversionResult.plot_convergence()InversionResult.plot_model()InversionResult.save()
JointERTSRTInversionJointERTSRTInversion.RCMJointERTSRTInversion.Wd_ertJointERTSRTInversion.Wd_srtJointERTSRTInversion.Wm_ertJointERTSRTInversion.Wm_srtJointERTSRTInversion.XJointERTSRTInversion.dobs_ertJointERTSRTInversion.dobs_srtJointERTSRTInversion.ert_gridJointERTSRTInversion.mrJointERTSRTInversion.mr_refJointERTSRTInversion.mvJointERTSRTInversion.mv_refJointERTSRTInversion.run()JointERTSRTInversion.setup()
JointERTSRTResultJointERTSRTResult.chi2_ertJointERTSRTResult.chi2_srtJointERTSRTResult.ert_coverageJointERTSRTResult.ert_log_resistivityJointERTSRTResult.ert_predictedJointERTSRTResult.ert_resistivityJointERTSRTResult.iteration_historyJointERTSRTResult.meshJointERTSRTResult.metaJointERTSRTResult.srt_coverageJointERTSRTResult.srt_log_slownessJointERTSRTResult.srt_predictedJointERTSRTResult.srt_velocity
JointFDEMTDEMInversionJointFDEMTDEMResultJointFDEMTDEMResult.baselineJointFDEMTDEMResult.chi2_fdemJointFDEMTDEMResult.chi2_tdemJointFDEMTDEMResult.conductivityJointFDEMTDEMResult.convergenceJointFDEMTDEMResult.coverage_fdemJointFDEMTDEMResult.coverage_tdemJointFDEMTDEMResult.metaJointFDEMTDEMResult.predicted_fdemJointFDEMTDEMResult.predicted_tdemJointFDEMTDEMResult.resistivityJointFDEMTDEMResult.thicknesses
JointGravityMagneticsInversionJointInversionRequestJointInversionResultJointInversionResult.artifactsJointInversionResult.baselineJointInversionResult.chi2JointInversionResult.coverageJointInversionResult.historyJointInversionResult.metaJointInversionResult.methodsJointInversionResult.modelsJointInversionResult.predictedJointInversionResult.statusJointInversionResult.strategyJointInversionResult.summary()JointInversionResult.warnings
JointPairCapabilityPetrophysicalCouplingSRTInversionStructuralConstraintStructuralConstraint.apply_structural_weights_to_Wm()StructuralConstraint.build_cross_gradient_operator()StructuralConstraint.build_linearized_cross_gradient_blocks()StructuralConstraint.build_local_design_matrix()StructuralConstraint.build_neighborhood_matrix()StructuralConstraint.from_conductivity_model()StructuralConstraint.from_velocity_model()
TDEMInversionTDEMInversionResultTDEMInversionResult.recovered_modelTDEMInversionResult.recovered_conductivityTDEMInversionResult.l2_modelTDEMInversionResult.l2_conductivityTDEMInversionResult.predicted_dataTDEMInversionResult.meshTDEMInversionResult.thicknessesTDEMInversionResult.chi2TDEMInversionResult.iterationsTDEMInversionResult.convergence_historyTDEMInversionResult.chi2TDEMInversionResult.convergence_historyTDEMInversionResult.iterationsTDEMInversionResult.l2_conductivityTDEMInversionResult.l2_modelTDEMInversionResult.meshTDEMInversionResult.predicted_dataTDEMInversionResult.recovered_conductivityTDEMInversionResult.recovered_modelTDEMInversionResult.thicknesses
TimeLapseERTInversionTimeLapseInversionResultTimeLapseInversionResult.final_modelsTimeLapseInversionResult.timestepsTimeLapseInversionResult.all_coverageTimeLapseInversionResult.all_chi2TimeLapseInversionResult.all_chi2TimeLapseInversionResult.all_coverageTimeLapseInversionResult.create_time_lapse_animation()TimeLapseInversionResult.final_modelsTimeLapseInversionResult.load()TimeLapseInversionResult.plot_time_slice()TimeLapseInversionResult.save()TimeLapseInversionResult.timesteps
TimeLapseSRTInversionWindowedTimeLapseERTInversionfdem_invert()get_joint_capabilities()invert_gravmag()run_joint_inversion()run_tdem_inversion()tdem_invert()tdem_joint_invert()
- PyHydroGeophysX.llm package
- Submodules
- PyHydroGeophysX.llm.providers module
AnthropicProviderIMAGE_PLACEHOLDEROpenAICompatibleProviderOpenAIProviderProviderREQUEST_TIMEOUT_STEXT_ONLY_MODEL_HINTSas_blocks()cap_images()has_image()image_block()make_provider()supports_vision()text_block()to_anthropic_messages()to_anthropic_tools()to_openai_messages()to_openai_tools()window_messages()
- Module contents
- PyHydroGeophysX.model_output package
- Submodules
- PyHydroGeophysX.model_output.base module
- PyHydroGeophysX.model_output.modflow_output module
- PyHydroGeophysX.model_output.parflow_output module
- PyHydroGeophysX.model_output.water_content module
- Module contents
- PyHydroGeophysX.petrophysics package
- Submodules
- PyHydroGeophysX.petrophysics.monte_carlo module
- PyHydroGeophysX.petrophysics.resistivity_models module
- PyHydroGeophysX.petrophysics.velocity_models module
- Module contents
- PyHydroGeophysX.solvers package
- PyHydroGeophysX.uncertainty package
- PyHydroGeophysX.visualization package
- Submodules
- PyHydroGeophysX.visualization.animation module
- PyHydroGeophysX.visualization.basemap module
- PyHydroGeophysX.visualization.ert_style module
- PyHydroGeophysX.visualization.multi_method module
- PyHydroGeophysX.visualization.plotting module
- PyHydroGeophysX.visualization.pyvista_compat module
- PyHydroGeophysX.visualization.raster module
- PyHydroGeophysX.visualization.vtk_export module
- Module contents
create_combined_timelapse_gif()create_difference_gif()create_timelapse_gif()create_timelapse_mp4()export_mesh_to_vtk()export_points_to_vtk()export_structured_vtk()export_structured_vtk_multi()export_timelapse_structured_vtk()export_timelapse_vtk()plot_apparent_resistivity_pseudosection()plot_apparent_resistivity_timelapse()plot_convergence()plot_coverage()plot_cross_section_with_wells()plot_depth_slices()plot_difference_map()plot_electrode_layout()plot_em_data_fit()plot_em_fit_and_residuals()plot_em_residuals()plot_hydro_vs_geophys()plot_layered_profiles()plot_model_section()plot_monitoring_timeseries()plot_multi_method_panel()plot_petrophysical_scatter()plot_pseudosection_matrix()plot_signal_and_noise()plot_time_lapse_panel()plot_timelapse_snapshots()plot_topography()
- PyHydroGeophysX.workflows package
- Submodules
- PyHydroGeophysX.workflows.builtin module
- PyHydroGeophysX.workflows.bundle module
- PyHydroGeophysX.workflows.cli module
- PyHydroGeophysX.workflows.codegen module
- PyHydroGeophysX.workflows.domain module
- PyHydroGeophysX.workflows.em1d module
BackendUnavailablebackend_status()build_em_config()calibrate_to_reference()estimate_data_scale()example_catalog()fdem_forward()fdem_invert()invert_line()is_temcompany_source()is_ttem_source()load_line_geometry()load_sounding()load_sounding_container()load_temcompany_sounding()load_ttem_sounding()model_arrays()model_depth_profile()save_inversion()save_line_csv()save_sounding_container()tdem_forward()tdem_invert()tdem_joint_invert()
- PyHydroGeophysX.workflows.gravmag module
- PyHydroGeophysX.workflows.models module
- PyHydroGeophysX.workflows.recipe module
- PyHydroGeophysX.workflows.registry module
- PyHydroGeophysX.workflows.runner module
- PyHydroGeophysX.workflows.walkthrough module
- Module contents
ArtifactRefModuleDescriptorRunContextWorkflowDescriptorWorkflowRunResultWorkflowSpecWorkflowValidationErrorexport_workflow_bundle()generate_notebook()generate_python()generate_walkthrough()get_workflow()iter_artifact_refs()list_workflows()load_recipe()module_descriptor_for()navigation_key_for()register_workflow()result_key_for()run_workflow()save_recipe()teaching_paths()
Submodules#
PyHydroGeophysX.em1d module#
Compatibility facade for PyHydroGeophysX.workflows.em1d.
Bases:
RuntimeErrorRaised when an optional numerical backend cannot be used.
- PyHydroGeophysX.em1d.backend_status(method: str | None = None) Dict[str, Any][source]#
Report whether the requested EM forward/inversion backend is usable.
The check imports the same method-specific forward class used by inversion. This prevents the UI and AQUAH from announcing a background inversion that cannot start because SimPEG or one of its runtime dependencies is missing.
- PyHydroGeophysX.em1d.build_em_config(method: str, model: Dict[str, Any], geom: Dict[str, Any], inv: Dict[str, Any]) Dict[str, Any][source]#
- PyHydroGeophysX.em1d.calibrate_to_reference(path: str, method: str, geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], ref_resistivity: float, *, max_probe: int = 6, log: ~typing.Callable[[str], None] = <function noop>) float[source]#
Find the
data_scalethat makes the recovered near-surface resistivity match a known/expected value.The amplitude scale and the absolute resistivity level are degenerate — the EM data alone cannot fix the level (any
data_scalefits the data, with the resistivity shifting to compensate). This breaks the degeneracy with EXTERNAL information: the user suppliesref_resistivity(a known background, e.g. from a borehole or regional geology), and this inverts a few probe soundings at two trial scales, fits the near-surface resistivity’s log-linear response to the scale, and solves for the scale that yieldsref_resistivity. Returns the currentdata_scaleunchanged if calibration is not possible.
- PyHydroGeophysX.em1d.estimate_data_scale(path: str, method: str, geom: ~typing.Dict[str, ~typing.Any], *, max_soundings: int = 8, log: ~typing.Callable[[str], None] = <function noop>) float[source]#
Estimate the amplitude calibration (
data_scale) for normalized data.Normalized airborne responses (e.g. moment-normalized dB/dt) differ from the studio’s 1D forward by a near-constant amplitude factor. This fits each sounding’s decay SHAPE to a grid of half-space forward responses at the current geometry and takes the geometric-mean amplitude ratio
forward/observedat the best-fitting resistivity. Returns1.0if it cannot be estimated (so the caller can fall back to no scaling).
- PyHydroGeophysX.em1d.example_catalog() Dict[str, Dict[str, Any]][source]#
Return the desktop EM examples and their documented settings.
Prefer the source checkout for development and fall back to the compact package-data copy installed from a wheel.
- PyHydroGeophysX.em1d.fdem_forward(model: ~typing.Dict[str, ~typing.Any], geom: ~typing.Dict[str, ~typing.Any], log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
1D FDEM forward response (secondary field, real/imag per frequency).
- PyHydroGeophysX.em1d.fdem_invert(data: ~typing.Dict[str, ~typing.Any], geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Invert an FDEM sounding for a layered resistivity model (Occam 1D).
- PyHydroGeophysX.em1d.invert_line(path: str, method: str, geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], *, spacing: float = 50.0, positions: ~numpy.ndarray | None = None, heights: ~numpy.ndarray | None = None, max_soundings: int = 12, lines: ~typing.Sequence[int] | None = None, doi_blank: bool = True, doi_factor: float = 0.5, ref_resistivity: float = 0.0, out_dir: ~pathlib.Path | None = None, initial_models: ~numpy.ndarray | None = None, log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Invert a line on a shared fixed-layer grid.
inv["lci_mode"]selects how the soundings are coupled:simultaneous(the default wheneverlateral_smoothnessis positive)Solves the whole line as one system, with the lateral constraint part of what is being minimized. See
PyHydroGeophysX.inversion.em1d_lci.sequentialThe older block-coordinate passes: each station is re-inverted on its own against the distance-weighted model its neighbours had at the end of the previous pass. Kept because it needs no analytic Jacobian, so it still runs against a forward operator that cannot supply one.
offIndependent 1D inversion per sounding, no lateral coupling.
The models are laid side by side to form a
resistivity(position, depth)section ready forModel3DView.show_model():edges = (ex, ey, ez)(ezis elevation, increasing upward) andmodel3dof shape(n_pos, 1, n_depth).positionsgives the along-line distance of each sounding (the section x-axis);heightsoverrides the sensor height per sounding. Whendoi_blankis set, cells below a per-sounding depth of investigation (a diffusion-depth estimate scaled bydoi_factor) are blanked (NaN) so the unconstrained deep part of an early-time sounding is not shown as railed.inv["robust_errors"]retains all imported gates and iteratively inflates effective errors for large residuals. It overrides hard rejection. The main chi2 uses ORIGINAL errors;result["robust"]records effective errors and a separate effective chi2. Import-time flags and QC still apply.inv["auto_lambda"]re-solves the line at other smoothness weights to reachtarget_chi2.inv["reject_outliers"]drops the gates the converged model cannot explain (beyondoutlier_thresholdsigma, overoutlier_passescycles, never belowmin_data_fractionof the gates) and solves again; what it removed is reported underresult["outliers"]. They address different causes, so they can be used together: relaxing the smoothness helps when the model is too stiff for the data, rejection helps when a minority of gates are simply wrong.linesrestricts the run to the named survey lines, so a line whose data is thinner than the rest can be given its own settings instead of one set having to suit every line. PassingNoneruns from the first station, as before. The lateral constraint already groups by line, so a line inverted on its own is tied exactly as it would be inside a whole-survey run; what changes is which settings reach it, and that the other lines are not re-solved.max_soundingsthen counts within the selection.Stations arrive ordered by line, so a selection is a contiguous block. A set of lines that is not contiguous is refused rather than quietly widened to the span that encloses it, which would invert the lines in between under settings chosen for their neighbours.
- PyHydroGeophysX.em1d.is_temcompany_source(path: str) bool[source]#
Return whether path looks like a TEMcompany/TEM2Go export.
Both complete project directories and the self-describing
*.xyzexports written by TEMImage are accepted.
- PyHydroGeophysX.em1d.is_ttem_source(path: str) bool[source]#
Return whether path contains a TEMcompany tTEM raw acquisition.
- PyHydroGeophysX.em1d.load_line_geometry(path: str) Dict[str, Any][source]#
Load per-sounding line geometry: along-line
positions(m), optional sensorheights(m), and optional map coordinatesx/y(e.g. easting/northing) for plan-view depth slices. Recognizes header names (distance/position for the position; alt/height for the height; easting/northing for the map coordinates, which also derive the distance when no distance column is present). A header-less file is read by column order (1 column = position; 2+ = position, height).positionsis shifted to start at 0.
- PyHydroGeophysX.em1d.load_sounding(path: str, method: str, sounding: int = 0, *, moment: str = 'HM', use_flags: bool = True, max_relative_std: float | None = None, gate_rejection: str = 'truncate', reject_negative: bool = False, min_gates_per_moment: Mapping[str, int] | None = None, ttem_loop_area: float | None = None, ttem_gex_path: str | None = None, ttem_tfi_path: str | None = None) Dict[str, Any][source]#
Load one sounding from a sounding file.
The first column is the abscissa (FDEM: frequency Hz; TDEM: time s). The remaining columns hold the response(s) — a single sounding, or several stacked side by side so one file can carry a whole survey line (common for airborne EM exports).
soundingpicks which one (0-based):TDEM: each extra column is one sounding’s response → column
1 + sounding.FDEM: response columns come in
(real, imag)pairs → one sounding is the pair starting at1 + 2*sounding; a lone trailing real column gives imag = 0.
The returned dict also reports
n_soundingsso the caller can offer a picker.use_flagsapplies only to TEMcompany project databases; seeload_temcompany_sounding().
- PyHydroGeophysX.em1d.load_temcompany_sounding(path: str, sounding: int = 0, moment: str = 'HM', *, use_flags: bool = True, max_relative_std: float | None = None, gate_rejection: str = 'truncate', reject_negative: bool = False, min_gates_per_moment: Mapping[str, int] | None = None) Dict[str, Any][source]#
Load a TEMcompany/TEM2Go sounding from a project folder or XYZ export.
The defaults reproduce the gate selection the project itself records, which was measured rather than assumed. Over 1,503 station-moment datasets of one project, the gates the stored inversion used (
InversionModel.Datasets) are exactly the gates whoseInUseFlagsare set and whose value is finite and not a dummy, with 100 percent agreement. There is no further sign test: 87 low- moment and 251 high-moment datasets keep a non-positive gate. There is no further error cut either, and none is needed, because the largest relative error among the kept gates is exactly 0.250, so TEMImage applied that cut upstream when it wrote the flags. The selection is not even contiguous, so nor truncation: only 36 percent of the high-moment selections are a single run of gates.So
max_relative_std=Noneandreject_negative=Falseare the defaults. Both arguments remain, because a survey whose flags were written by an older an older acquisition release, or one being deliberately treated more strictly, still needs them. Note that the sign test only runs whenmax_relative_stdis set: it condemns a gate alongside a noisy one rather than on its own.use_flags=Falseignores the project’s in-use flags and returns every gate with a finite, non-dummy value. Only a project database records those flags, so it makes no difference to an XYZ export.min_gates_per_momentapplies only to a jointLM+HMread of a project database, which is the only path where dropping one moment still leaves a sounding; see_load_temcompany_joint_database().
- PyHydroGeophysX.em1d.load_ttem_sounding(path: str, sounding: int = 0, moment: str = 'LM+HM', *, max_relative_std: float | None = None, stack_seconds: float = 2.0, loop_area: float | None = None, gex_path: str | None = None, tfi_path: str | None = None) Dict[str, Any][source]#
Load and stack one sounding from a raw TEMcompany tTEM survey.
Data are normalized by measured transmitter current and the loop area from the selected GEX (or an explicit UI override). A selected TFI is applied to each sign-corrected transient sequence before stacking.
- PyHydroGeophysX.em1d.model_arrays(model: Dict[str, Any]) tuple[ndarray, ndarray, ndarray][source]#
Return (thicknesses, resistivity, conductivity) from a model dict.
- PyHydroGeophysX.em1d.model_depth_profile(thicknesses: ndarray, resistivity: ndarray, pad: float = 20.0) tuple[ndarray, ndarray][source]#
Step profile (depth, resistivity) for plotting a layered model.
- PyHydroGeophysX.em1d.save_inversion(result: Dict[str, Any], out_dir: Path) List[str][source]#
Save recovered model + data fit to npy/csv; return written paths.
- PyHydroGeophysX.em1d.tdem_forward(model: ~typing.Dict[str, ~typing.Any], geom: ~typing.Dict[str, ~typing.Any], log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
1D TDEM forward response (dB/dt or H per time channel).
- PyHydroGeophysX.em1d.tdem_invert(data: ~typing.Dict[str, ~typing.Any], geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Invert a TDEM sounding for a layered resistivity model (Occam 1D).
- PyHydroGeophysX.em1d.tdem_joint_invert(data: ~typing.Dict[str, ~typing.Any], geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Invert all available LM/HM gates at one station for one shared 1D model.
PyHydroGeophysX.gravmag module#
Compatibility facade for PyHydroGeophysX.workflows.gravmag.
Bases:
BackendUnavailableSimPEG / discretize / a usable solver could not be imported.
- PyHydroGeophysX.gravmag.backend_status() Dict[str, Any][source]#
Report whether the SimPEG potential-field inversion stack is available.
- PyHydroGeophysX.gravmag.build_gravmag_config(kind: str, settings: Dict[str, Any], bodies: List[Dict[str, Any]], field: Dict[str, Any] | None = None) Dict[str, Any][source]#
- PyHydroGeophysX.gravmag.extract_profile(grid: Dict[str, ndarray], p1: Sequence[float], p2: Sequence[float], n: int = 200) Dict[str, ndarray][source]#
Sample a gridded field along the line p1 -> p2 (bilinear).
- PyHydroGeophysX.gravmag.forward_bodies(xobs: ~numpy.ndarray, yobs: ~numpy.ndarray, kind: str, bodies: ~typing.List[~typing.Dict[str, ~typing.Any]], field: ~typing.Dict[str, ~typing.Any] | None = None, log: ~typing.Callable[[str], None] = <function noop>) ndarray[source]#
Sum the anomaly of a list of bodies. kind = ‘gravity’ or ‘magnetics’.
- PyHydroGeophysX.gravmag.gravity_prism(xobs: ndarray, yobs: ndarray, body: Dict[str, Any]) ndarray[source]#
Vertical gravity (mGal) of a right rectangular prism (Nagy 1966). z down.
- PyHydroGeophysX.gravmag.gravity_sphere(xobs: ndarray, yobs: ndarray, body: Dict[str, Any]) ndarray[source]#
Vertical gravity (mGal) of a buried sphere. z positive down, obs at z=0.
- PyHydroGeophysX.gravmag.grid_data(x: ndarray, y: ndarray, value: ndarray, nx: int = 120, ny: int = 120, method: str = 'linear') Dict[str, ndarray][source]#
Grid scattered station values onto a regular map. Returns xx, yy, zz.
- PyHydroGeophysX.gravmag.invert_gravmag(x, y, value, kind: str, *, z: ~numpy.ndarray | None = None, field: ~typing.Dict[str, ~typing.Any] | None = None, detrend: int = 0, n_xy: int = 22, n_z: int = 12, max_iterations: int = 20, beta0_ratio: float = 1.0, max_stations: int = 600, relative_error: float = 0.03, noise_floor: float | None = None, solver: str = 'simpeg', auto_beta: bool = True, target_chi2: float = 1.0, chi2_tolerance: float = 0.2, max_beta_trials: int = 6, sensitivity_power: float = 1.0, out_dir: str | None = None, random_seed: int | None = 42, log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Run a SimPEG 3D potential-field inversion under the survey.
gravityrecovers a density-contrast model (g/cc);magneticsrecovers a susceptibility model (SI) and needsfield= {inclination, declination, strength_nT}.zis optional per-station elevation (m, positive upward); a missing value falls back to 1 m.detrend(0..3) removes a polynomial regional trend before inversion. The returned grid uses elevation increasing upward.random_seedmakes SimPEG’s eigenvalue-based beta estimate reproducible. RaisesInversionBackendUnavailableif SimPEG is missing.
- PyHydroGeophysX.gravmag.magnetic_dipole(xobs: ndarray, yobs: ndarray, body: Dict[str, Any], field: Dict[str, Any]) ndarray[source]#
Total-field magnetic anomaly (nT) of an induced/magnetized sphere (a dipole).
- PyHydroGeophysX.gravmag.qc_products(x: ndarray, y: ndarray, value: ndarray, *, detrend: int = 1, nx: int = 120, ny: int = 120) Dict[str, Any][source]#
Calculate observed, regional and residual products for map/profile QC.
- PyHydroGeophysX.gravmag.regional_residual(x: ndarray, y: ndarray, value: ndarray, degree: int = 1) Tuple[ndarray, ndarray][source]#
Fit a polynomial regional trend of
degree(1..3); return (regional, residual).
- PyHydroGeophysX.gravmag.save_grid(grid: ~typing.Dict[str, ~numpy.ndarray], out_dir: ~pathlib.Path, name: str = 'anomaly', log: ~typing.Callable[[str], None] = <function noop>) List[str][source]#
Save a grid to npy + CSV + VTK (best-effort). Return written paths.
- PyHydroGeophysX.gravmag.spatially_balanced_indices(x: ndarray, y: ndarray, max_stations: int) ndarray[source]#
Return deterministic farthest-point indices for a spatially balanced subset.
The previous evenly spaced file-row selection could over-sample a survey segment when input rows were ordered by flight line or acquisition order. Farthest-point selection starts near the survey centroid and repeatedly adds the station furthest from the selected set, preserving map coverage without a random seed.
PyHydroGeophysX.gui module#
Local GUI launcher for PyHydroGeophysX.
PyHydroGeophysX.gui_mesh3d module#
Launcher for the 3D Mesh Builder Streamlit app.
PyHydroGeophysX.joint_api module#
Compatibility shim for PyHydroGeophysX.inversion.joint_api.
- class PyHydroGeophysX.joint_api.JointInversionRequest(method_a: str, method_b: str, strategy: str, data: ~typing.Dict[str, ~typing.Any], parameters: ~typing.Dict[str, ~typing.Any] = <factory>, output_dir: str | ~pathlib.Path = 'results/joint_inversion', run_baseline: bool = True)[source]#
Bases:
objectInput contract for a registered joint inversion runner.
- data: Dict[str, Any]#
- method_a: str#
- method_b: str#
- output_dir: str | Path = 'results/joint_inversion'#
- parameters: Dict[str, Any]#
- run_baseline: bool = True#
- strategy: str#
- class PyHydroGeophysX.joint_api.JointInversionResult(methods: ~typing.Tuple[str, str], strategy: str, models: ~typing.Dict[str, ~typing.Any] = <factory>, predicted: ~typing.Dict[str, ~typing.Any] = <factory>, coverage: ~typing.Dict[str, ~typing.Any] = <factory>, chi2: ~typing.Dict[str, float] = <factory>, history: ~typing.List[~typing.Dict[str, ~typing.Any]] = <factory>, baseline: ~typing.Dict[str, ~typing.Any] = <factory>, artifacts: ~typing.Dict[str, str] = <factory>, warnings: ~typing.List[str] = <factory>, meta: ~typing.Dict[str, ~typing.Any] = <factory>, status: str = 'success')[source]#
Bases:
objectMethod-neutral result returned by all registered joint runners.
- artifacts: Dict[str, str]#
- baseline: Dict[str, Any]#
- chi2: Dict[str, float]#
- coverage: Dict[str, Any]#
- history: List[Dict[str, Any]]#
- meta: Dict[str, Any]#
- methods: Tuple[str, str]#
- models: Dict[str, Any]#
- predicted: Dict[str, Any]#
- status: str = 'success'#
- strategy: str#
- warnings: List[str]#
- class PyHydroGeophysX.joint_api.JointMethodAdapter(*args, **kwargs)[source]#
Bases:
ProtocolInterface implemented by a capability-specific request runner.
- capability: JointPairCapability#
- run(request: JointInversionRequest) JointInversionResult[source]#
Execute a validated request and return method-neutral results.
- class PyHydroGeophysX.joint_api.JointPairCapability(methods: Tuple[str, str], strategies: Mapping[str, str], dimension: str, model_parameter: str, implemented: bool, dependencies: Tuple[str, ...] = (), description: str = '', runner: str | None = None, backends: Tuple[str, ...] = ())[source]#
Bases:
objectDescribe the strategies available for one normalized method pair.
- backends: Tuple[str, ...] = ()#
- dependencies: Tuple[str, ...] = ()#
- description: str = ''#
- dimension: str#
- implemented: bool#
- methods: Tuple[str, str]#
- model_parameter: str#
- runner: str | None = None#
- strategies: Mapping[str, str]#
- PyHydroGeophysX.joint_api.get_joint_capabilities(include_planned: bool = True) List[JointPairCapability][source]#
List implemented capabilities and, optionally, planned method pairs.
- PyHydroGeophysX.joint_api.get_joint_capability(method_a: str, method_b: str) JointPairCapability[source]#
Return one capability, including a planned placeholder if unsupported.
- PyHydroGeophysX.joint_api.normalize_joint_pair(method_a: str, method_b: str) Tuple[str, str][source]#
Return a stable pair key and reject duplicate methods.
- PyHydroGeophysX.joint_api.pair_joint_soundings(f_value: Any, t_value: Any, parameters: Mapping[str, Any]) List[Tuple[int, int, str]][source]#
Pair FDEM/TDEM soundings by coordinate or, when safe, by index.
PyHydroGeophysX.table_io module#
Compatibility shim for PyHydroGeophysX.data_processing.table_io.
- PyHydroGeophysX.table_io.ensure_dir(path: str | Path) Path[source]#
Create path and its parents if needed, then return it.
- PyHydroGeophysX.table_io.load_2d_array(path: str | Path) ndarray[source]#
Load an array from NPY, NPZ, CSV, TXT, or DAT input.
- PyHydroGeophysX.table_io.load_xyz_table(path: str | Path, min_cols: int = 2) ndarray[source]#
Load a two-dimensional table with at least min_cols columns.
- PyHydroGeophysX.table_io.read_json(path: str | Path) dict[str, Any] | None[source]#
Read JSON, returning
Nonefor a missing or malformed document.
Module contents#
Public, import-light API for PyHydroGeophysX.
The package root intentionally contains no eager scientific imports. Public objects are resolved on first access so importing a lightweight submodule does not also initialize plotting libraries or optional geophysics engines.
- class PyHydroGeophysX.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: - data_file: Path to ERT data file - instrument: Instrument type (E4D, Syscal, etc.) - inversion_params: Parameters for inversion - petrophysical_params: Parameters for water content conversion - use_seismic: Whether to include seismic processing (default: False) - seismic_data: Optional seismic data file - 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)
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
>>> coordinator = AgentCoordinator(api_key=None) >>> result = coordinator.preview_workflow({"data_file": "missing.ohm"}) >>> result["status"] 'failed'
- class PyHydroGeophysX.ArtifactRef(artifact_id: str, kind: str, path: str, format: str, checksum: str = '', metadata: Mapping[str, ~typing.Any]=<factory>)[source]#
Bases:
objectA serializable reference to a workflow input or output artifact.
- artifact_id: str#
- checksum: str = ''#
- format: str#
- classmethod from_dict(value: Mapping[str, Any]) ArtifactRef[source]#
- classmethod from_path(path: Path, *, artifact_id: str, kind: str, format: str | None = None, base_dir: Path | None = None, metadata: Mapping[str, Any] | None = None, checksum: bool = True) ArtifactRef[source]#
- kind: str#
- metadata: Mapping[str, Any]#
- path: str#
Bases:
RuntimeErrorRaised when an optional numerical backend cannot be used.
- class PyHydroGeophysX.BaseVelocityModel[source]#
Bases:
objectBase class for seismic velocity models.
- class PyHydroGeophysX.BrieModel(exponent: float = 3.0)[source]#
Bases:
objectBrie’s model for calculating the effective bulk modulus of a partially saturated medium.
- calculate_fluid_modulus(saturation: float, water_modulus: float = 2.0, gas_modulus: float = 0.01) float[source]#
Calculate effective fluid bulk modulus using Brie’s equation.
- Parameters:
saturation – Water saturation (0 to 1)
water_modulus – Bulk modulus of water (GPa, default: 2.0)
gas_modulus – Bulk modulus of gas (GPa, default: 0.01)
- Returns:
Effective fluid bulk modulus (GPa)
- calculate_saturated_modulus(dry_modulus: float, mineral_modulus: float, porosity: float, saturation: float, water_modulus: float = 2.0, gas_modulus: float = 0.01) float[source]#
Calculate the saturated bulk modulus based on Brie’s equation.
- Parameters:
dry_modulus – Bulk modulus of the dry rock (GPa)
mineral_modulus – Bulk modulus of the mineral matrix (GPa)
porosity – Porosity of the rock
saturation – Water saturation (0 to 1)
water_modulus – Bulk modulus of water (GPa, default: 2.0)
gas_modulus – Bulk modulus of gas (GPa, default: 0.01)
- Returns:
Saturated bulk modulus (GPa)
- class PyHydroGeophysX.DEMModel[source]#
Bases:
BaseVelocityModelDifferential Effective Medium (DEM) model for calculating elastic properties and seismic velocities of porous rocks.
- calculate_velocity(porosity: ndarray, saturation: ndarray, bulk_modulus: float, shear_modulus: float, mineral_density: float, aspect_ratio: float = 0.1) Tuple[ndarray, ndarray, ndarray][source]#
Calculate P-wave velocity using the DEM model.
- Parameters:
porosity – Porosity values (array)
saturation – Saturation values (array)
bulk_modulus – Initial bulk modulus of the solid matrix (GPa)
shear_modulus – Initial shear modulus of the solid matrix (GPa)
mineral_density – Density of the solid matrix (kg/m³)
aspect_ratio – Aspect ratio of pores (default: 0.1)
- Returns:
Effective bulk modulus (GPa), effective shear modulus (GPa), and P-wave velocity (m/s)
- class PyHydroGeophysX.ERTForwardModeling(mesh: pygimli.Mesh, data: pygimli.DataContainer | None = None)[source]#
Bases:
objectClass for forward modeling of Electrical Resistivity Tomography (ERT) data.
- create_synthetic_data(xpos: ndarray, ypos: ndarray | None = None, mesh: pygimli.Mesh | None = None, res_models: ndarray | None = None, schemeName: str = 'wa', noise_level: float = 0.05, absolute_error: float = 0.0, relative_error: float = 0.05, save_path: str | None = None, show_data: bool = False, seed: int | None = None, xbound: float = 100, ybound: float = 100) Tuple[pygimli.DataContainer, pygimli.Mesh][source]#
Create synthetic ERT data using forward modeling.
This method simulates an ERT survey by placing electrodes, creating a measurement scheme, performing forward modeling to generate synthetic data, and adding noise.
- Parameters:
xpos – X-coordinates of electrodes
ypos – Y-coordinates of electrodes (if None, uses flat surface)
mesh – Mesh for forward modeling
res_models – Resistivity model values
schemeName – Name of measurement scheme (‘wa’, ‘dd’, etc.)
noise_level – Level of Gaussian noise to add
absolute_error – Absolute error for data estimation
relative_error – Relative error for data estimation
save_path – Path to save synthetic data (if None, does not save)
show_data – Whether to display data after creation
seed – Random seed for noise generation
xbound – X boundary extension for mesh
ybound – Y boundary extension for mesh
- Returns:
Tuple of (synthetic ERT data container, simulation mesh)
- forward(resistivity_model: ndarray, log_transform: bool = True) ndarray[source]#
Compute forward response for a given resistivity model.
- Parameters:
resistivity_model – Resistivity model values
log_transform – Whether resistivity_model is log-transformed
- Returns:
Forward response (apparent resistivity)
- forward_and_jacobian(resistivity_model: ndarray, log_transform: bool = True) Tuple[ndarray, ndarray][source]#
Compute forward response and Jacobian matrix.
- Parameters:
resistivity_model – Resistivity model values
log_transform – Whether resistivity_model is log-transformed
- Returns:
Tuple of (forward response, Jacobian matrix)
- get_coverage(resistivity_model: ndarray, log_transform: bool = True) ndarray[source]#
Compute coverage (resolution) for a given resistivity model.
- Parameters:
resistivity_model – Resistivity model values
log_transform – Whether resistivity_model is log-transformed
- Returns:
Coverage values for each cell
- class PyHydroGeophysX.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: ‘difference’, ‘ratio’, or ‘joint’ (for time-lapse) - 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
- Returns:
Dictionary containing inversion results
- class PyHydroGeophysX.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
- class PyHydroGeophysX.FDEMForwardModeling(thicknesses: ndarray, survey_config: FDEMSurveyConfig | None = None, survey: simpeg.electromagnetics.frequency_domain.Survey | None = None)[source]#
Bases:
objectForward modeling of Frequency-Domain EM data using SimPEG.
Supports 1D layered-earth conductivity models.
- forward(conductivity: ndarray) ndarray[source]#
Compute FDEM response for a given conductivity model.
- class PyHydroGeophysX.FDEMSurveyConfig(source_location: ndarray = None, source_radius: float = 10.0, receiver_location: ndarray = None, receiver_orientation: str = 'z', receiver_component: str = 'secondary', frequencies: ndarray = None, waveform_type: str = 'dipole')[source]#
Bases:
objectConfiguration for FDEM survey geometry.
- frequencies: ndarray = None#
- receiver_component: str = 'secondary'#
- receiver_location: ndarray = None#
- receiver_orientation: str = 'z'#
- source_location: ndarray = None#
- source_radius: float = 10.0#
- waveform_type: str = 'dipole'#
- class PyHydroGeophysX.FirstBreakPick(source_id: int, receiver_id: int, time_s: float, source_x: float, source_z: float, receiver_x: float, receiver_z: float, field_record: int, trace_number: int, trace_index: int, amplitude: float)[source]#
Bases:
objectOne first-break pick.
- amplitude: float#
- field_record: int#
- receiver_id: int#
- receiver_x: float#
- receiver_z: float#
- source_id: int#
- source_x: float#
- source_z: float#
- time_s: float#
- trace_index: int#
- trace_number: int#
- class PyHydroGeophysX.GeophysicalInversion(method: str, **kwargs)[source]#
Bases:
objectUnified factory for multi-method geophysical inversion.
Dispatches to the correct inversion engine.
- SUPPORTED = {'ert', 'fdem', 'joint', 'joint_ert_srt', 'srt', 'tdem'}#
- property engine#
- class PyHydroGeophysX.GeophysicalInversionAgent(api_key: str | None = None, model: str | None = None, llm_provider: str = 'openai')[source]#
Bases:
BaseAgentAgent for multi-method inversion orchestration.
Supports SRT and FDEM natively and delegates ERT to ERTInversionAgent.
- class PyHydroGeophysX.GravityMagneticsJointResult(density: ~numpy.ndarray, susceptibility: ~numpy.ndarray, predicted_gravity: ~numpy.ndarray, predicted_magnetics: ~numpy.ndarray, coverage_gravity: ~numpy.ndarray, coverage_magnetics: ~numpy.ndarray, chi2_gravity: float, chi2_magnetics: float, convergence: ~typing.List[~typing.Dict[str, ~typing.Any]], edges: ~typing.Tuple[~numpy.ndarray, ~numpy.ndarray, ~numpy.ndarray], model_shape: ~typing.Tuple[int, int, int], cross_gradient: ~numpy.ndarray, baseline: ~typing.Dict[str, ~typing.Any] = <factory>, meta: ~typing.Dict[str, ~typing.Any] = <factory>)[source]#
Bases:
objectResult of a shared-mesh gravity–magnetics inversion.
- baseline: Dict[str, Any]#
- chi2_gravity: float#
- chi2_magnetics: float#
- convergence: List[Dict[str, Any]]#
- coverage_gravity: ndarray#
- coverage_magnetics: ndarray#
- cross_gradient: ndarray#
- density: ndarray#
- edges: Tuple[ndarray, ndarray, ndarray]#
- meta: Dict[str, Any]#
- model_shape: Tuple[int, int, int]#
- predicted_gravity: ndarray#
- predicted_magnetics: ndarray#
- susceptibility: ndarray#
- class PyHydroGeophysX.HertzMindlinModel(critical_porosity: float = 0.4, coordination_number: float = 4.0)[source]#
Bases:
BaseVelocityModelHertz-Mindlin model and Hashin-Shtrikman bounds for seismic velocity in porous rocks.
- calculate_velocity(porosity: ndarray, saturation: ndarray, bulk_modulus: float, shear_modulus: float, mineral_density: float, depth: float = 1.0) Tuple[ndarray, ndarray][source]#
Calculate P-wave velocity for porous rocks.
- Parameters:
porosity – Porosity values (array)
saturation – Saturation values (array)
bulk_modulus – Bulk modulus of the solid matrix (GPa)
shear_modulus – Shear modulus of the solid matrix (GPa)
mineral_density – Density of the solid matrix (kg/m³)
depth – Depth for pressure estimation (m, default: 1.0)
- Returns:
Tuple of high-bound P-wave velocity (m/s) and low-bound P-wave velocity (m/s)
- class PyHydroGeophysX.HydroModelOutput(model_directory: str)[source]#
Bases:
ABCBase class for all hydrological model outputs.
- calculate_saturation(water_content: ndarray, porosity: float | ndarray) ndarray[source]#
Calculate saturation from water content and porosity.
- Parameters:
water_content – Water content array
porosity – Porosity value(s)
- Returns:
Saturation array
- abstractmethod get_timestep_info() List[Tuple][source]#
Get information about each timestep.
- Returns:
List of timestep information tuples
- abstractmethod load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs) ndarray[source]#
Load data for a range of timesteps.
- Parameters:
start_idx – Starting timestep index
end_idx – Ending timestep index (exclusive)
**kwargs – Additional parameters specific to the model type
- Returns:
Data array for the specified timestep range
- class PyHydroGeophysX.JointGravityMagneticsInversion(gravity_data: Mapping[str, Any], magnetics_data: Mapping[str, Any], *, field: Mapping[str, Any] | None = None, n_xy: int = 12, n_z: int = 8, max_iterations: int = 10, max_stations: int = 600, gravity_relative_error: float = 0.03, magnetics_relative_error: float = 0.03, gravity_noise_floor: float = 0.5, magnetics_noise_floor: float = 2.0, gravity_weight: float = 1.0, magnetics_weight: float = 1.0, cross_gradient_weight: float = 2000000000000.0, beta0_ratio: float = 1.0, gravity_detrend: int = 0, magnetics_detrend: int = 0, run_baseline: bool = True, baseline_max_iterations: int | None = None, random_seed: int | None = 42, output_dir: str | None = None, progress_callback: Callable[[Dict[str, Any]], None] | None = None)[source]#
Bases:
objectJointly recover density and susceptibility with SimPEG cross-gradient coupling.
Inputs are mappings with
x,y,valueand optionalzarrays. Gravity values use mGal and magnetic total-field values use nT. Both surveys are placed on one tensor mesh; the stacked inversion model is split by asimpeg.maps.Wiresmap into density (g/cc) and susceptibility (SI).- run() GravityMagneticsJointResult[source]#
Run the native SimPEG similarity-measure inversion.
- class PyHydroGeophysX.JointInversionRequest(method_a: str, method_b: str, strategy: str, data: ~typing.Dict[str, ~typing.Any], parameters: ~typing.Dict[str, ~typing.Any] = <factory>, output_dir: str | ~pathlib.Path = 'results/joint_inversion', run_baseline: bool = True)[source]#
Bases:
objectInput contract for a registered joint inversion runner.
- data: Dict[str, Any]#
- method_a: str#
- method_b: str#
- output_dir: str | Path = 'results/joint_inversion'#
- parameters: Dict[str, Any]#
- run_baseline: bool = True#
- strategy: str#
- class PyHydroGeophysX.JointInversionResult(methods: ~typing.Tuple[str, str], strategy: str, models: ~typing.Dict[str, ~typing.Any] = <factory>, predicted: ~typing.Dict[str, ~typing.Any] = <factory>, coverage: ~typing.Dict[str, ~typing.Any] = <factory>, chi2: ~typing.Dict[str, float] = <factory>, history: ~typing.List[~typing.Dict[str, ~typing.Any]] = <factory>, baseline: ~typing.Dict[str, ~typing.Any] = <factory>, artifacts: ~typing.Dict[str, str] = <factory>, warnings: ~typing.List[str] = <factory>, meta: ~typing.Dict[str, ~typing.Any] = <factory>, status: str = 'success')[source]#
Bases:
objectMethod-neutral result returned by all registered joint runners.
- artifacts: Dict[str, str]#
- baseline: Dict[str, Any]#
- chi2: Dict[str, float]#
- coverage: Dict[str, Any]#
- history: List[Dict[str, Any]]#
- meta: Dict[str, Any]#
- methods: Tuple[str, str]#
- models: Dict[str, Any]#
- predicted: Dict[str, Any]#
- status: str = 'success'#
- strategy: str#
- warnings: List[str]#
- class PyHydroGeophysX.JointPairCapability(methods: Tuple[str, str], strategies: Mapping[str, str], dimension: str, model_parameter: str, implemented: bool, dependencies: Tuple[str, ...] = (), description: str = '', runner: str | None = None, backends: Tuple[str, ...] = ())[source]#
Bases:
objectDescribe the strategies available for one normalized method pair.
- backends: Tuple[str, ...] = ()#
- dependencies: Tuple[str, ...] = ()#
- description: str = ''#
- dimension: str#
- implemented: bool#
- methods: Tuple[str, str]#
- model_parameter: str#
- runner: str | None = None#
- strategies: Mapping[str, str]#
- class PyHydroGeophysX.MODFLOWPorosity(model_directory: str, model_name: str)[source]#
Bases:
HydroModelOutputClass for processing porosity data from MODFLOW simulations.
- get_timestep_info() List[Tuple][source]#
Get information about each timestep in the model. Returns a minimal placeholder since porosity doesn’t vary with time.
- Returns:
List with single dummy timestep info
- load_porosity() ndarray[source]#
Load porosity data from MODFLOW model (supports both MODFLOW 6 and earlier versions).
- Returns:
3D array of porosity values (nlay, nrow, ncol)
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs) ndarray[source]#
Load porosity for a range of timesteps. Since porosity is typically constant, this returns a stack of identical arrays.
- Parameters:
start_idx – Starting timestep index (unused)
end_idx – Ending timestep index (unused)
- Returns:
4D array of porosity values (nt, nlay, nrow, ncol) where all timesteps are identical
- load_timestep(timestep_idx: int, **kwargs) ndarray[source]#
Load porosity for a specific timestep. Note: For MODFLOW, porosity is typically constant over time, so this returns the same array regardless of timestep.
- Parameters:
timestep_idx – Index of the timestep (unused)
- Returns:
3D array of porosity values
- class PyHydroGeophysX.MODFLOWWaterContent(model_directory: str, idomain: ndarray)[source]#
Bases:
HydroModelOutputClass for processing water content data from MODFLOW simulations.
- get_timestep_info() List[Tuple[int, int, float, float]][source]#
Get information about each timestep in the WaterContent file.
- Returns:
List of tuples (kstp, kper, pertim, totim) for each timestep
- load_time_range(start_idx: int = 0, end_idx: int | None = None, nlay: int = 3) ndarray[source]#
Load water content for a range of timesteps.
- Parameters:
start_idx – Starting timestep index (default: 0)
end_idx – Ending timestep index (exclusive, default: None loads all)
nlay – Number of layers in the model (default: 3)
- Returns:
Water content array with shape (timesteps, nlay, nrows, ncols)
- class PyHydroGeophysX.MeshCreator(quality: float = 28, area: float = 40)[source]#
Bases:
objectClass for creating and managing meshes for geophysical inversion.
- create_from_ert_data(data, max_depth: float = 30.0, quality: float = 34)[source]#
Create a mesh suitable for ERT inversion from ERT data.
- Parameters:
data – PyGIMLI ERT data object
max_depth – Maximum depth of the mesh
quality – Mesh quality parameter
- Returns:
PyGIMLI mesh for ERT inversion
- create_from_layers(surface: ndarray, layers: List[ndarray], bottom_depth: float = 30.0, markers: List[int] = None) pygimli.Mesh[source]#
Create a mesh from surface and layer boundaries.
- Parameters:
surface – Surface coordinates [[x,z],…]
layers – List of layer boundary coordinates
bottom_depth – Depth below surface minimum for mesh bottom
markers – List of markers for each layer (default: [2, 3, 2, …])
- Returns:
PyGIMLI mesh
- class PyHydroGeophysX.ParflowPorosity(model_directory: str, run_name: str)[source]#
Bases:
ParflowOutputProcesses porosity data from ParFlow simulations. Porosity in ParFlow is typically static (time-invariant) and stored in a single PFB file (e.g., <run_name>.out.porosity.pfb or similar).
- get_timestep_info() List[Tuple[int, float]][source]#
Returns timestep information, typically based on other ParFlow outputs (like saturation) as porosity itself is static.
- Returns:
- A list of (timestep_number, time_value) tuples,
derived from self.available_timesteps.
- Return type:
List[Tuple[int, float]]
- load_mask() ndarray[source]#
Load the domain mask data from a ParFlow model. The mask file (.out.mask.pfb) indicates active (1) and inactive (0) cells.
- Returns:
- A 3D NumPy array representing the domain mask (nz, ny, nx).
Values are typically 0 or 1.
- Return type:
np.ndarray
- Raises:
FileNotFoundError – If no standard mask PFB file can be found.
ValueError – If there’s an error reading or processing the PFB file.
- load_porosity() ndarray[source]#
Load the static porosity data from the ParFlow model.
It searches for common ParFlow porosity filename patterns within the model directory.
- Returns:
A 3D NumPy array of porosity values (nz, ny, nx).
- Return type:
np.ndarray
- Raises:
FileNotFoundError – If no standard porosity PFB file can be found.
ValueError – If there’s an error reading or processing the PFB file.
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs: Any) ndarray[source]#
Load porosity data for a conceptual range of timesteps. Since porosity is time-invariant, this method returns a 4D array where the static 3D porosity data is repeated along the time axis.
The number of repetitions along the time axis (nt) is determined by the length of self.available_timesteps (discovered from saturation/pressure files) if end_idx is None, or by min(end_idx - start_idx, len(available_timesteps)). A minimum of 1 repetition is ensured if any timesteps are notionally available.
- Parameters:
start_idx (int, optional) – Starting timestep index (used to determine nt). Defaults to 0.
end_idx (Optional[int], optional) – Ending timestep index (exclusive, used for nt). Defaults to None (use all available timesteps).
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
- A 4D NumPy array of porosity values (nt, nz, ny, nx).
All slices along the time dimension are identical.
- Return type:
np.ndarray
- load_timestep(timestep_idx: int, **kwargs: Any) ndarray[source]#
Load porosity data. For ParFlow, porosity is typically time-invariant. This method returns the static porosity array, ignoring timestep_idx.
- Parameters:
timestep_idx (int) – Index of the timestep (ignored, as porosity is static).
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
A 3D NumPy array of porosity values (nz, ny, nx).
- Return type:
np.ndarray
- class PyHydroGeophysX.ParflowSaturation(model_directory: str, run_name: str)[source]#
Bases:
ParflowOutputProcesses saturation data from ParFlow simulations (.out.satur.*.pfb files).
- get_timestep_info() List[Tuple[int, float]][source]#
Provides information about available ParFlow timesteps.
For ParFlow, the timestep number from the filename often directly corresponds to the simulation time (e.g., if output is every 1 hour, timestep 24 is 24 hours). This method returns a list of tuples: (timestep_number, simulation_time). Currently, simulation_time is simply cast from timestep_number. More accurate time mapping would require parsing ParFlow timing files if complex.
- Returns:
- A list where each tuple is (timestep_number, time_value).
Time_value is float representation of timestep_number.
- Return type:
List[Tuple[int, float]]
- load_time_range(start_idx: int = 0, end_idx: int | None = None, **kwargs: Any) ndarray[source]#
Load saturation data for a specified range of zero-based timestep indices.
- Parameters:
start_idx (int, optional) – Starting zero-based timestep index. Defaults to 0.
end_idx (Optional[int], optional) – Ending zero-based timestep index (exclusive). If None, loads up to the last available timestep. Defaults to None.
**kwargs (Any) – Additional keyword arguments (not used).
- Returns:
- A 4D NumPy array of saturation values (num_timesteps, nz, ny, nx).
Returns an empty 4D array if the range is invalid or no data is found.
- Return type:
np.ndarray
- Raises:
ValueError – If no timesteps are available, or if the specified range is invalid (e.g., start_idx out of bounds, end_idx <= start_idx leading to empty range).
- load_timestep(timestep_idx: int, **kwargs: Any) ndarray[source]#
Load saturation data for a specific, zero-based timestep index.
- Parameters:
timestep_idx (int) – The zero-based index of the timestep to load from the list of available timesteps discovered during initialization.
**kwargs (Any) – Additional keyword arguments (not used by this method).
- Returns:
A 3D NumPy array of saturation values (nz, ny, nx).
- Return type:
np.ndarray
- Raises:
ValueError – If no timesteps are available or if timestep_idx is out of range.
- class PyHydroGeophysX.ProfileInterpolator(point1: List[int], point2: List[int], surface_data: ndarray, origin_x: float = 0.0, origin_y: float = 0.0, pixel_width: float = 1.0, pixel_height: float = -1.0, num_points: int = 200)[source]#
Bases:
objectClass for handling interpolation of data to/from profiles.
- interpolate_3d_data(data: ndarray) ndarray[source]#
Interpolate 3D data (n_layers, ny, nx) to profile.
- Parameters:
data – 3D array of values
- Returns:
Array of interpolated values (n_layers, n_profile_points)
- interpolate_layer_data(layer_data: List[ndarray]) ndarray[source]#
Interpolate multiple layer data to profile.
- Parameters:
layer_data – List of 2D arrays for each layer
- Returns:
Array of interpolated values (n_layers, n_profile_points)
- interpolate_to_mesh(property_values: ndarray, depth_values: ndarray, mesh_x: ndarray, mesh_y: ndarray, mesh_markers: ndarray, ID: ndarray, layer_markers: list = [3, 0, 2]) ndarray[source]#
Interpolate property values from profile to mesh with layer-specific handling.
- Parameters:
property_values – Property values array (n_points or n_layers, n_points)
depth_values – Depth values array (n_layers, n_points)
mesh_x – Coordinates of mesh cells
mesh_y – Coordinates of mesh cells
mesh_markers – Markers indicating different layers in mesh
layer_markers – List of marker values for each layer
- Returns:
Interpolated values for mesh cells
- class PyHydroGeophysX.RunContext(project_root: ~pathlib.Path = <factory>, output_dir: ~pathlib.Path = <factory>, progress: ~typing.Callable[[str], None] = <function _noop_progress>, cancelled: ~typing.Callable[[], bool] = <function _never_cancelled>, object_cache: ~typing.MutableMapping[str, ~typing.Any] = <factory>)[source]#
Bases:
objectProcess-local execution settings that are deliberately absent from recipes.
- static cache_key(ref: ArtifactRef) str[source]#
- cancelled() bool#
- load_object(ref: ArtifactRef, loader: Callable[[Path], Any]) Any[source]#
Load and cache an artifact by
artifact_id + checksum.
- object_cache: MutableMapping[str, Any]#
- output_dir: Path#
- progress() None#
- project_root: Path#
- resolve_artifact(ref: ArtifactRef) Path[source]#
- class PyHydroGeophysX.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
>>> 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, 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
- class PyHydroGeophysX.VRHModel[source]#
Bases:
BaseVelocityModelVoigt-Reuss-Hill (VRH) mixing model for effective elastic properties of composites.
- calculate_properties(fractions: List[float], bulk_moduli: List[float], shear_moduli: List[float], densities: List[float]) Tuple[float, float, float][source]#
Calculate effective elastic properties using the VRH model.
- Parameters:
fractions – Volume fractions of each mineral (must sum to 1)
bulk_moduli – Bulk moduli of each mineral (GPa)
shear_moduli – Shear moduli of each mineral (GPa)
densities – Densities of each mineral (kg/m³)
- Returns:
Effective bulk modulus (GPa), effective shear modulus (GPa), and effective density (kg/m³)
- calculate_velocity(fractions: List[float], bulk_moduli: List[float], shear_moduli: List[float], densities: List[float]) Tuple[float, float][source]#
Calculate P-wave and S-wave velocities using the VRH model.
- Parameters:
fractions – Volume fractions of each mineral (must sum to 1)
bulk_moduli – Bulk moduli of each mineral (GPa)
shear_moduli – Shear moduli of each mineral (GPa)
densities – Densities of each mineral (kg/m³)
- Returns:
P-wave velocity (m/s) and S-wave velocity (m/s)
- PyHydroGeophysX.VRH_model(f: Any = [0.35, 0.25, 0.2, 0.125, 0.075], K: Any = [55.4, 36.6, 75.6, 46.7, 50.4], G: Any = [28.1, 45, 25.6, 23.65, 27.4], rho: Any = [2560, 2650, 2630, 2540, 3050]) Any[source]#
Implements the Voigt-Reuss-Hill (VRH) mixing model to estimate the effective bulk modulus (Km), shear modulus (Gm), and density (rho_b) of a composite material made from various minerals.
Parameters: f (list): Fraction of each mineral in the composite (must sum to 1). K (list): Bulk modulus of each mineral (GPa). G (list): Shear modulus of each mineral (GPa). rho (list): Density of each mineral (kg/m^3).
Returns: Km (float): Effective bulk modulus of the composite material (GPa). Gm (float): Effective shear modulus of the composite material (GPa). rho_b (float): Effective density of the composite material (kg/m^3).
- class PyHydroGeophysX.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
- class PyHydroGeophysX.WorkflowRunResult(status: str, summary: Mapping[str, ~typing.Any]=<factory>, metrics: Mapping[str, ~typing.Any]=<factory>, artifacts: List[ArtifactRef] = <factory>, warnings: List[str] = <factory>, provenance: Mapping[str, ~typing.Any]=<factory>, objects: MutableMapping[str, ~typing.Any]=<factory>)[source]#
Bases:
objectPublic serializable result plus an optional same-process object channel.
- artifacts: List[ArtifactRef]#
- classmethod from_dict(value: Mapping[str, Any]) WorkflowRunResult[source]#
- legacy_payload() Dict[str, Any][source]#
Return a same-process mapping for existing viewers during migration.
Unlike
to_dict(), this deliberately merges the liveobjectschannel back into the summary. It must never be persisted or emitted by CLI/bridge code.
- metrics: Mapping[str, Any]#
- objects: MutableMapping[str, Any]#
- provenance: Mapping[str, Any]#
- status: str#
- summary: Mapping[str, Any]#
- warnings: List[str]#
- class PyHydroGeophysX.WorkflowSpec(workflow_id: str, inputs: Mapping[str, ~typing.Any]=<factory>, parameters: Mapping[str, ~typing.Any]=<factory>, seed: int | None = None, dependencies: List[str] = <factory>, metadata: Mapping[str, ~typing.Any]=<factory>, schema_version: str = '1')[source]#
Bases:
objectEverything required to reproduce one workflow in another process.
- dependencies: List[str]#
- classmethod from_dict(value: Mapping[str, Any]) WorkflowSpec[source]#
- inputs: Mapping[str, Any]#
- metadata: Mapping[str, Any]#
- parameters: Mapping[str, Any]#
- schema_version: str = '1'#
- seed: int | None = None#
- workflow_id: str#
- PyHydroGeophysX.apply_agc(data: ndarray, dt: float, window: float = 0.05, rms: float = 1.0) ndarray[source]#
Apply gate-based automatic gain control to traces.
The implementation follows the MATLAB example’s gate/interpolation logic while handling zero-energy windows safely.
- PyHydroGeophysX.calibrate_to_reference(path: str, method: str, geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], ref_resistivity: float, *, max_probe: int = 6, log: ~typing.Callable[[str], None] = <function noop>) float[source]#
Find the
data_scalethat makes the recovered near-surface resistivity match a known/expected value.The amplitude scale and the absolute resistivity level are degenerate — the EM data alone cannot fix the level (any
data_scalefits the data, with the resistivity shifting to compensate). This breaks the degeneracy with EXTERNAL information: the user suppliesref_resistivity(a known background, e.g. from a borehole or regional geology), and this inverts a few probe soundings at two trial scales, fits the near-surface resistivity’s log-linear response to the scale, and solves for the scale that yieldsref_resistivity. Returns the currentdata_scaleunchanged if calibration is not possible.
- PyHydroGeophysX.create_difference_gif(mesh: Any, models: Sequence[ndarray], reference: ndarray, filename: str, *, mode: str = 'difference', titles: Sequence[str] | None = None, cmap: str = 'RdBu_r', symmetric: bool = True, label: str = '', figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, duration: int = 100, coverage: ndarray | Sequence[ndarray] | None = None) str[source]#
Create a GIF animation showing model changes relative to a reference.
- Parameters:
mesh (pygimli.Mesh)
models (sequence of array-like) – Model snapshots for each frame.
reference (array-like) – Baseline model to subtract / divide.
mode (
'difference'|'ratio'|'percent_change')symmetric (bool) – Center colorbar at zero / one.
:param (other parameters same as
create_timelapse_gif()):- Returns:
Path to the saved GIF file.
- Return type:
str
- PyHydroGeophysX.create_mesh_from_layers(surface: ndarray, line1: ndarray, line2: ndarray, bottom_depth: float = 30.0, quality: float = 28, area: float = 40) Tuple[pygimli.Mesh, ndarray, ndarray][source]#
Create mesh from layer boundaries and get cell centers and markers.
- Parameters:
surface – Surface coordinates [[x,z],…]
line1 – First layer boundary coordinates
line2 – Second layer boundary coordinates
bottom_depth – Depth below surface minimum for mesh bottom
quality – Mesh quality parameter
area – Maximum cell area
- Returns:
PyGIMLI mesh mesh_centers: Array of cell center coordinates markers: Array of cell markers
- Return type:
- PyHydroGeophysX.create_timelapse_gif(mesh: Any, models: Sequence[ndarray], filename: str, *, titles: Sequence[str] | None = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', coverage: ndarray | Sequence[ndarray] | None = None, figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, duration: int = 100, first_frame_duration: int = 500, loop: int = 0) str[source]#
Create a GIF animation of time-lapse model snapshots.
Each frame renders the model on the given mesh using
pg.showand captures it as a PIL image. RequiresPillow.- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all models.
models (sequence of array-like) – Model values for each frame.
filename (str) – Output GIF path.
titles (sequence of str, optional) – Title per frame.
cmap (str or Colormap, optional) – Colormap. Defaults to BlueDarkRed18_18_r if available.
cmin (float, optional) – Fixed color limits.
cmax (float, optional) – Fixed color limits.
log_scale (bool) – Logarithmic color scale.
label (str) – Colorbar label.
coverage (array or list of arrays, optional) – Coverage mask(s).
figsize (tuple) – Figure size per frame.
dpi (int) – Resolution.
duration (int) – Milliseconds per frame.
first_frame_duration (int) – Duration of the first frame in ms (longer for visual pause).
loop (int) – Number of loops (0 = infinite).
- Returns:
Path to the saved GIF file.
- Return type:
str
- PyHydroGeophysX.create_timelapse_mp4(mesh: Any, models: Sequence[ndarray], filename: str, *, titles: Sequence[str] | None = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', coverage: ndarray | Sequence[ndarray] | None = None, figsize: Tuple[float, float] = (8, 2.5), dpi: int = 150, fps: int = 10) str[source]#
Create an MP4 video of time-lapse model snapshots using matplotlib.
Requires
ffmpegto be available on the system path.- Parameters:
mesh (pygimli.Mesh)
models (sequence of array-like)
filename (str) – Output
.mp4path.fps (int) – Frames per second.
:param (other parameters same as
create_timelapse_gif()):- Returns:
Path to the saved MP4 file.
- Return type:
str
- PyHydroGeophysX.ertforandjac(fob: Any, rhomodel: Any, xr: Any) Any[source]#
Forward model and Jacobian for ERT.
- Parameters:
fob (pygimli.ERTModelling) – ERT forward operator.
rhomodel (pg.RVector) – Resistivity model.
xr (np.ndarray) – Log-transformed model parameter.
- Returns:
Log-transformed forward response. J (np.ndarray): Jacobian matrix.
- Return type:
dr (np.ndarray)
- PyHydroGeophysX.ertforandjac2(fob: Any, xr: Any, mesh: Any) Any[source]#
Alternative ERT forward model and Jacobian using log-resistivity values.
- Parameters:
fob (pygimli.ERTModelling) – ERT forward operator.
xr (np.ndarray) – Log-transformed model parameter.
mesh (pg.Mesh) – Mesh for the forward model.
- Returns:
Log-transformed forward response. J (np.ndarray): Jacobian matrix.
- Return type:
dr (np.ndarray)
- PyHydroGeophysX.ertforward(fob: Any, mesh: Any, rhomodel: Any, xr: Any) Any[source]#
Forward model for ERT.
- Parameters:
fob (pygimli.ERTModelling) – ERT forward operator.
mesh (pg.Mesh) – Mesh for the forward model.
rhomodel (pg.RVector) – Resistivity model vector.
xr (np.ndarray) – Log-transformed model parameter (resistivity).
- Returns:
Log-transformed forward response. rhomodel (pg.RVector): Updated resistivity model.
- Return type:
dr (np.ndarray)
- PyHydroGeophysX.ertforward2(fob: Any, xr: Any, mesh: Any) Any[source]#
Simplified ERT forward model.
- Parameters:
fob (pygimli.ERTModelling) – ERT forward operator.
xr (np.ndarray) – Log-transformed model parameter.
mesh (pg.Mesh) – Mesh for the forward model.
- Returns:
Log-transformed forward response.
- Return type:
dr (np.ndarray)
- PyHydroGeophysX.estimate_data_scale(path: str, method: str, geom: ~typing.Dict[str, ~typing.Any], *, max_soundings: int = 8, log: ~typing.Callable[[str], None] = <function noop>) float[source]#
Estimate the amplitude calibration (
data_scale) for normalized data.Normalized airborne responses (e.g. moment-normalized dB/dt) differ from the studio’s 1D forward by a near-constant amplitude factor. This fits each sounding’s decay SHAPE to a grid of half-space forward responses at the current geometry and takes the geometric-mean amplitude ratio
forward/observedat the best-fitting resistivity. Returns1.0if it cannot be estimated (so the caller can fall back to no scaling).
- PyHydroGeophysX.export_first_breaks(picks: Iterable[FirstBreakPick | Dict[str, Any]], filename: str) str[source]#
Export first-break picks to CSV.
- PyHydroGeophysX.export_mesh_to_vtk(mesh: Any, filename: str, cell_data: Dict[str, ndarray] | None = None) str[source]#
Export a PyGIMLi mesh to VTK unstructured grid format.
This uses PyGIMLi’s built-in
mesh.exportVTKwhen available and then optionally injects extra cell data fields.- Parameters:
mesh (pygimli.Mesh) – The mesh to export.
filename (str) – Output
.vtkpath.cell_data (dict of str -> array, optional) – Additional named cell-data arrays to write.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.export_points_to_vtk(points: ndarray, scalars: Dict[str, ndarray], filename: str) str[source]#
Export point-cloud data (e.g. cell centers) to VTK PolyData.
- Parameters:
points (array of shape (N, 3)) – XYZ coordinates.
scalars (dict of str -> array) – Named scalar values at each point.
filename (str) – Output
.vtkpath.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.export_results_to_csv(result: Any, filename: str) str[source]#
Export inversion result arrays to a tabular CSV file.
- PyHydroGeophysX.export_structured_vtk(values: ndarray, filename: str, *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0), scalar_name: str = 'model') str[source]#
Export a 3-D numpy array to VTK structured-points format.
Useful for MODFLOW/ParFlow grids that map directly to a regular grid.
- Parameters:
values (3-D array) – Shape
(nz, ny, nx)— layer, row, column ordering.filename (str) – Output
.vtkpath.dx (float) – Cell spacing in each direction.
dy (float) – Cell spacing in each direction.
dz (float) – Cell spacing in each direction.
origin (tuple of float) –
(x0, y0, z0)origin of the grid.scalar_name (str) – Name for the scalar dataset.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.export_structured_vtk_multi(scalars: Dict[str, ndarray], filename: str, *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0)) str[source]#
Export multiple 3-D arrays as named scalars in a single VTK file.
All arrays must have the same shape
(nz, ny, nx).- Parameters:
scalars (dict of str -> 3-D array) – Named scalar datasets (e.g.
{"resistivity": res, "water_content": wc}).filename (str) – Output
.vtkpath.
- Returns:
Path to the written file.
- Return type:
str
- PyHydroGeophysX.export_timelapse_structured_vtk(models: Sequence[ndarray], output_dir: str, prefix: str = 'timelapse', *, dx: float = 1.0, dy: float = 1.0, dz: float = 1.0, origin: tuple = (0.0, 0.0, 0.0), scalar_name: str = 'model') List[str][source]#
Export time-lapse 3-D arrays as a numbered VTK series.
- Parameters:
models (sequence of 3-D arrays) – Each entry has shape
(nz, ny, nx).output_dir (str) – Output directory.
prefix (str) – File prefix.
dx (float) – Grid spacing.
dy (float) – Grid spacing.
dz (float) – Grid spacing.
origin (tuple) – Grid origin.
scalar_name (str) – Scalar field name.
- Returns:
Paths to generated VTK files.
- Return type:
list of str
- PyHydroGeophysX.export_timelapse_vtk(mesh: Any, models: Sequence[ndarray], output_dir: str, prefix: str = 'timelapse', *, scalar_name: str = 'model', extra_data: Dict[str, Sequence[ndarray]] | None = None) List[str][source]#
Export time-lapse models as a numbered VTK series for ParaView.
Creates files
prefix_0000.vtk,prefix_0001.vtk, … and a.pvdcollection file that ParaView can load as a time series.- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all timesteps.
models (sequence of array-like) – Model values per timestep.
output_dir (str) – Directory for output files.
prefix (str) – Filename prefix.
scalar_name (str) – Name for the primary scalar field.
extra_data (dict of str -> sequence of arrays, optional) – Additional scalar fields per timestep.
- Returns:
Paths to all generated VTK files.
- Return type:
list of str
- PyHydroGeophysX.export_to_vtk(result: Any, mesh: Any, filename: str) str[source]#
Export result/model values to a lightweight VTK PolyData file.
The export writes cell-center points with a single scalar field.
- PyHydroGeophysX.extract_profile(grid: Dict[str, ndarray], p1: Sequence[float], p2: Sequence[float], n: int = 200) Dict[str, ndarray][source]#
Sample a gridded field along the line p1 -> p2 (bilinear).
- PyHydroGeophysX.fdem_invert(data: ~typing.Dict[str, ~typing.Any], geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Invert an FDEM sounding for a layered resistivity model (Occam 1D).
- PyHydroGeophysX.first_breaks_to_traveltime(picks: Iterable[FirstBreakPick | Dict[str, Any]], filename: str, receiver_spacing: float = 1.0, shot_spacing: float | None = None) str[source]#
Export first breaks to a PyGIMLi/BERT travel-time
.datfile.
- PyHydroGeophysX.forward_bodies(xobs: ~numpy.ndarray, yobs: ~numpy.ndarray, kind: str, bodies: ~typing.List[~typing.Dict[str, ~typing.Any]], field: ~typing.Dict[str, ~typing.Any] | None = None, log: ~typing.Callable[[str], None] = <function noop>) ndarray[source]#
Sum the anomaly of a list of bodies. kind = ‘gravity’ or ‘magnetics’.
- PyHydroGeophysX.generate_python(spec: WorkflowSpec, path: str | Path) Path[source]#
Generate a standalone, editable script using only the public workflow API.
- PyHydroGeophysX.get_joint_capabilities(include_planned: bool = True) List[JointPairCapability][source]#
List implemented capabilities and, optionally, planned method pairs.
- PyHydroGeophysX.get_workflow(workflow_id: str) WorkflowDescriptor[source]#
- PyHydroGeophysX.gravity_prism(xobs: ndarray, yobs: ndarray, body: Dict[str, Any]) ndarray[source]#
Vertical gravity (mGal) of a right rectangular prism (Nagy 1966). z down.
- PyHydroGeophysX.gravity_sphere(xobs: ndarray, yobs: ndarray, body: Dict[str, Any]) ndarray[source]#
Vertical gravity (mGal) of a buried sphere. z positive down, obs at z=0.
- PyHydroGeophysX.grid_data(x: ndarray, y: ndarray, value: ndarray, nx: int = 120, ny: int = 120, method: str = 'linear') Dict[str, ndarray][source]#
Grid scattered station values onto a regular map. Returns xx, yy, zz.
- PyHydroGeophysX.interpolate_structure_to_profile(structure_data: List[ndarray], X_grid: ndarray, Y_grid: ndarray, X_pro: ndarray, Y_pro: ndarray) ndarray[source]#
Interpolate multiple structure layers onto profile
- Parameters:
structure_data – List of 2D arrays for each layer
X_grid – X coordinates of original grid
Y_grid – Y coordinates of original grid
X_pro – X coordinates of profile points
Y_pro – Y coordinates of profile points
- Returns:
Array of interpolated values with shape (n_layers, n_points)
- PyHydroGeophysX.interpolate_to_mesh(property_values: ndarray, profile_distance: ndarray, depth_values: ndarray, mesh_x: ndarray, mesh_y: ndarray, mesh_markers: ndarray, ID: Any, layer_markers: list = [3, 0, 2]) ndarray[source]#
Interpolate property values from profile to mesh with layer-specific handling.
- Parameters:
property_values – Property values array (n_points)
profile_distance – Distance along profile (n_points)
depth_values – Depth values array (n_layers, n_points)
mesh_x – X coordinates of mesh cells
mesh_y – Y coordinates of mesh cells
mesh_markers – Markers indicating different layers in mesh
layer_markers – List of marker values for each layer
- Returns:
Interpolated values for mesh cells
- PyHydroGeophysX.interpolate_to_profile(data: ndarray, X_grid: ndarray, Y_grid: ndarray, X_pro: ndarray, Y_pro: ndarray, method: str = 'linear') ndarray[source]#
Interpolate 2D data onto a profile line
- Parameters:
data – 2D array of values to interpolate
X_grid – X coordinates of original grid (meshgrid)
Y_grid – Y coordinates of original grid (meshgrid)
X_pro – X coordinates of profile points
Y_pro – Y coordinates of profile points
method – Interpolation method (‘linear’ or ‘nearest’)
- Returns:
Interpolated values along profile
- PyHydroGeophysX.invert_gravmag(x, y, value, kind: str, *, z: ~numpy.ndarray | None = None, field: ~typing.Dict[str, ~typing.Any] | None = None, detrend: int = 0, n_xy: int = 22, n_z: int = 12, max_iterations: int = 20, beta0_ratio: float = 1.0, max_stations: int = 600, relative_error: float = 0.03, noise_floor: float | None = None, solver: str = 'simpeg', auto_beta: bool = True, target_chi2: float = 1.0, chi2_tolerance: float = 0.2, max_beta_trials: int = 6, sensitivity_power: float = 1.0, out_dir: str | None = None, random_seed: int | None = 42, log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Run a SimPEG 3D potential-field inversion under the survey.
gravityrecovers a density-contrast model (g/cc);magneticsrecovers a susceptibility model (SI) and needsfield= {inclination, declination, strength_nT}.zis optional per-station elevation (m, positive upward); a missing value falls back to 1 m.detrend(0..3) removes a polynomial regional trend before inversion. The returned grid uses elevation increasing upward.random_seedmakes SimPEG’s eigenvalue-based beta estimate reproducible. RaisesInversionBackendUnavailableif SimPEG is missing.
- PyHydroGeophysX.invert_line(path: str, method: str, geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], *, spacing: float = 50.0, positions: ~numpy.ndarray | None = None, heights: ~numpy.ndarray | None = None, max_soundings: int = 12, lines: ~typing.Sequence[int] | None = None, doi_blank: bool = True, doi_factor: float = 0.5, ref_resistivity: float = 0.0, out_dir: ~pathlib.Path | None = None, initial_models: ~numpy.ndarray | None = None, log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Invert a line on a shared fixed-layer grid.
inv["lci_mode"]selects how the soundings are coupled:simultaneous(the default wheneverlateral_smoothnessis positive)Solves the whole line as one system, with the lateral constraint part of what is being minimized. See
PyHydroGeophysX.inversion.em1d_lci.sequentialThe older block-coordinate passes: each station is re-inverted on its own against the distance-weighted model its neighbours had at the end of the previous pass. Kept because it needs no analytic Jacobian, so it still runs against a forward operator that cannot supply one.
offIndependent 1D inversion per sounding, no lateral coupling.
The models are laid side by side to form a
resistivity(position, depth)section ready forModel3DView.show_model():edges = (ex, ey, ez)(ezis elevation, increasing upward) andmodel3dof shape(n_pos, 1, n_depth).positionsgives the along-line distance of each sounding (the section x-axis);heightsoverrides the sensor height per sounding. Whendoi_blankis set, cells below a per-sounding depth of investigation (a diffusion-depth estimate scaled bydoi_factor) are blanked (NaN) so the unconstrained deep part of an early-time sounding is not shown as railed.inv["robust_errors"]retains all imported gates and iteratively inflates effective errors for large residuals. It overrides hard rejection. The main chi2 uses ORIGINAL errors;result["robust"]records effective errors and a separate effective chi2. Import-time flags and QC still apply.inv["auto_lambda"]re-solves the line at other smoothness weights to reachtarget_chi2.inv["reject_outliers"]drops the gates the converged model cannot explain (beyondoutlier_thresholdsigma, overoutlier_passescycles, never belowmin_data_fractionof the gates) and solves again; what it removed is reported underresult["outliers"]. They address different causes, so they can be used together: relaxing the smoothness helps when the model is too stiff for the data, rejection helps when a minority of gates are simply wrong.linesrestricts the run to the named survey lines, so a line whose data is thinner than the rest can be given its own settings instead of one set having to suit every line. PassingNoneruns from the first station, as before. The lateral constraint already groups by line, so a line inverted on its own is tied exactly as it would be inside a whole-survey run; what changes is which settings reach it, and that the other lines are not re-solved.max_soundingsthen counts within the selection.Stations arrive ordered by line, so a selection is a contiguous block. A set of lines that is not contiguous is refused rather than quietly widened to the span that encloses it, which would invert the lines in between under settings chosen for their neighbours.
- PyHydroGeophysX.list_workflows() Tuple[WorkflowDescriptor, ...][source]#
- PyHydroGeophysX.load_line_geometry(path: str) Dict[str, Any][source]#
Load per-sounding line geometry: along-line
positions(m), optional sensorheights(m), and optional map coordinatesx/y(e.g. easting/northing) for plan-view depth slices. Recognizes header names (distance/position for the position; alt/height for the height; easting/northing for the map coordinates, which also derive the distance when no distance column is present). A header-less file is read by column order (1 column = position; 2+ = position, height).positionsis shifted to start at 0.
- PyHydroGeophysX.load_recipe(path: str | Path) WorkflowSpec[source]#
- PyHydroGeophysX.load_sounding(path: str, method: str, sounding: int = 0, *, moment: str = 'HM', use_flags: bool = True, max_relative_std: float | None = None, gate_rejection: str = 'truncate', reject_negative: bool = False, min_gates_per_moment: Mapping[str, int] | None = None, ttem_loop_area: float | None = None, ttem_gex_path: str | None = None, ttem_tfi_path: str | None = None) Dict[str, Any][source]#
Load one sounding from a sounding file.
The first column is the abscissa (FDEM: frequency Hz; TDEM: time s). The remaining columns hold the response(s) — a single sounding, or several stacked side by side so one file can carry a whole survey line (common for airborne EM exports).
soundingpicks which one (0-based):TDEM: each extra column is one sounding’s response → column
1 + sounding.FDEM: response columns come in
(real, imag)pairs → one sounding is the pair starting at1 + 2*sounding; a lone trailing real column gives imag = 0.
The returned dict also reports
n_soundingsso the caller can offer a picker.use_flagsapplies only to TEMcompany project databases; seeload_temcompany_sounding().
- PyHydroGeophysX.magnetic_dipole(xobs: ndarray, yobs: ndarray, body: Dict[str, Any], field: Dict[str, Any]) ndarray[source]#
Total-field magnetic anomaly (nT) of an induced/magnetized sphere (a dipole).
- PyHydroGeophysX.normalize_traces(data: ndarray, trace_axis: int = 1, eps: float = 1e-12) ndarray[source]#
Normalize each seismic trace by its maximum absolute amplitude.
- PyHydroGeophysX.pick_first_breaks(data: SeismicDataset | SeismicShotGather | ndarray, dt: float | None = None, headers: Sequence[SeismicTraceHeader] | None = None, threshold: float = 0.2, noise_multiplier: float = 5.0, min_time: float = 0.0, max_time: float | None = None, polarity: float = 1.0) List[FirstBreakPick][source]#
Pick first arrivals using a simple amplitude/noise threshold.
This assisted picker is intended as a starting point for GUI review rather than a final scientific picking algorithm.
- PyHydroGeophysX.plot_convergence(chi2_history: Sequence[float], *, ax: Any = None, target_chi2: float = 1.0, ylabel: str = '$\\chi^2$', title: str = 'Inversion Convergence') Tuple[source]#
Plot chi-squared convergence curve.
- Parameters:
chi2_history (sequence of float) – Chi-squared value per iteration.
target_chi2 (float) – Target misfit (plotted as a dashed line).
- Return type:
fig, ax
- PyHydroGeophysX.plot_coverage(mesh: Any, coverage: ndarray, *, ax: Any = None, cmap: str = 'YlGn', threshold: float | None = None, title: str = 'Data Coverage') Tuple[source]#
Plot a coverage / sensitivity map.
- Parameters:
mesh (pygimli.Mesh)
coverage (array-like) – Coverage values per cell.
threshold (float, optional) – If given, overlay a contour at this level.
- Return type:
fig, ax, cbar
- PyHydroGeophysX.plot_difference_map(mesh: Any, model_a: ndarray, model_b: ndarray, *, mode: str = 'difference', ax: Any = None, cmap: str = 'RdBu_r', symmetric: bool = True, label: str = '', title: str = '', coverage: ndarray | None = None) Tuple[source]#
Plot the difference or ratio between two models.
- Parameters:
mesh (pygimli.Mesh)
model_a (array-like) – Two model arrays.
result = model_b - model_a(difference) ormodel_b / model_a(ratio).model_b (array-like) – Two model arrays.
result = model_b - model_a(difference) ormodel_b / model_a(ratio).mode (
'difference'|'ratio'|'percent_change')symmetric (bool) – If True, center the colorbar at zero (difference) or one (ratio).
coverage (array-like, optional) – Coverage mask.
- Return type:
fig, ax, cbar
- PyHydroGeophysX.plot_electrode_layout(positions: Dict[str, ndarray], *, ax: Any = None, color_by: str = 'z', cmap: str = 'terrain', title: str = 'Electrode Layout') Tuple[source]#
Scatter-plot electrode positions colored by elevation.
- Parameters:
positions (dict) – Must contain
'x'and'y'keys; optionally'z'.- Return type:
fig, ax
- PyHydroGeophysX.plot_model_section(mesh: Any, values: ndarray, *, ax: Any = None, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', xlabel: str = 'Distance (m)', ylabel: str = 'Elevation (m)', title: str = '', coverage: ndarray | None = None, orientation: str = 'vertical') Tuple[source]#
Plot a 2D model cross-section on a PyGIMLi mesh.
- Parameters:
mesh (pygimli.Mesh) – The mesh to plot on.
values (array-like) – Cell values (resistivity, velocity, water content, etc.).
ax (matplotlib.axes.Axes, optional) – Axes to draw on. Created if None.
cmap (str or Colormap, optional) – Colormap. Defaults to
BlueDarkRed18_18_rif available.cmin (float, optional) – Color limits.
cmax (float, optional) – Color limits.
log_scale (bool) – Use logarithmic color scaling.
label (str) – Colorbar label.
coverage (array-like, optional) – Coverage array for masking low-sensitivity cells.
orientation (str) – Colorbar orientation (
'vertical'or'horizontal').
- Return type:
fig, ax, cbar
- PyHydroGeophysX.plot_monitoring_timeseries(times: ndarray, series: Dict[str, ndarray], *, true_series: Dict[str, ndarray] | None = None, uncertainties: Dict[str, Tuple[ndarray, ndarray]] | None = None, ax: Any = None, ylabel: str = 'Value', title: str = 'Monitoring Point Time Series') Tuple[source]#
Plot estimated (and optionally true) time-series at monitoring points.
- Parameters:
times (array-like) – Time axis.
series (dict of str -> array) – Estimated values keyed by point name.
true_series (dict of str -> array, optional) – True / reference values for comparison (dashed lines).
uncertainties (dict of str -> (lower, upper), optional) – Uncertainty bounds per point for shading.
- Return type:
fig, ax
- PyHydroGeophysX.plot_pseudosection_matrix(data_matrix: ndarray, *, ax: Any = None, cmap: Any = None, vmin: float | None = None, vmax: float | None = None, xlabel: str = 'Time', ylabel: str = 'Measurement #', label: str = 'Apparent resistivity ($\\Omega\\cdot$m)', title: str = '') Tuple[source]#
Plot a time-lapse apparent resistivity matrix as a heatmap.
- Parameters:
data_matrix (2-D array) – Shape
(n_times, n_measurements)or similar.- Return type:
fig, ax, im
- PyHydroGeophysX.plot_timelapse_snapshots(mesh: Any, models: Sequence[ndarray], *, titles: Sequence[str] | None = None, ncols: int = 4, cmap: Any = None, cmin: float | None = None, cmax: float | None = None, log_scale: bool = False, label: str = '', coverage: ndarray | Sequence[ndarray] | None = None, figsize_per_panel: Tuple[float, float] = (4.0, 2.5)) Tuple[source]#
Plot a grid of time-lapse model snapshots.
- Parameters:
mesh (pygimli.Mesh) – Mesh shared by all snapshots.
models (sequence of array-like) – Model arrays for each timestep.
titles (sequence of str, optional) – Panel titles. Defaults to
'Timestep 1','Timestep 2', …ncols (int) – Number of columns.
cmap – Passed to
pg.show.cmin – Passed to
pg.show.cmax – Passed to
pg.show.log_scale – Passed to
pg.show.label – Passed to
pg.show.coverage (array or sequence of arrays, optional) – Coverage mask(s). If a single 1-D array it is reused for all panels. If 2-D,
coverage[i]is used for panel i.figsize_per_panel (tuple) – (width, height) per subplot panel.
- Return type:
fig, axes
- PyHydroGeophysX.plot_topography(topo_grid: ndarray, *, profile_endpoints: List[Tuple[float, float]] | None = None, ax: Any = None, cmap: str = 'terrain', title: str = 'Surface Topography') Tuple[source]#
Plot a 2-D topography grid with optional profile line overlay.
- Parameters:
topo_grid (2-D array) – Elevation raster.
profile_endpoints (list of (row, col) tuples, optional) – If two points are given, draw the profile line.
- Return type:
fig, ax
- PyHydroGeophysX.prepare_2D_profile_data(data: ndarray, XX: ndarray, YY: ndarray, X_pro: ndarray, Y_pro: ndarray) ndarray[source]#
Interpolate multiple 2D gridded data layers onto a profile line.
- Parameters:
data – 3D array of gridded data (n_layers, ny, nx)
XX – Coordinate grids from meshgrid
YY – Coordinate grids from meshgrid
X_pro – Profile line coordinates
Y_pro – Profile line coordinates
- Returns:
Interpolated values along profile (n_layers, n_profile_points)
- PyHydroGeophysX.qc_products(x: ndarray, y: ndarray, value: ndarray, *, detrend: int = 1, nx: int = 120, ny: int = 120) Dict[str, Any][source]#
Calculate observed, regional and residual products for map/profile QC.
- PyHydroGeophysX.read_seg2_seismic(file: str) Dict[str, ndarray][source]#
Read SEG-2 seismic file into arrays.
If ObsPy is available, uses ObsPy SEG-2 reader. Otherwise falls back to text loading for already exported arrays.
- PyHydroGeophysX.read_segy(file: str, max_traces: int | None = None, load_traces: bool = True, prefer_obspy: bool = True) SeismicDataset[source]#
Read a SEG-Y file into traces, headers, and metadata.
Reader order is
segyio->ObsPy-> built-in: the most robust library available is used, and the built-in conservative reader is the final fallback so reads keep working with no third-party SEG-Y dependency installed.- Parameters:
file (str) – SEG-Y path.
max_traces (int, optional) – Maximum number of traces to read. Useful for responsive GUI previews.
load_traces (bool, optional) – If False, parse headers but skip sample arrays (built-in reader only).
prefer_obspy (bool, optional) – When True (default), try ObsPy if
segyiois unavailable or fails.
- Returns:
Parsed seismic dataset.
- Return type:
- PyHydroGeophysX.read_tem_fast(file: str) Dict[str, ndarray][source]#
Read TEM-FAST style text data into SimPEG-ready arrays.
- PyHydroGeophysX.regional_residual(x: ndarray, y: ndarray, value: ndarray, degree: int = 1) Tuple[ndarray, ndarray][source]#
Fit a polynomial regional trend of
degree(1..3); return (regional, residual).
- PyHydroGeophysX.resistivity_to_saturation(resistivity: Any, porosity: Any, m: Any, rho_fluid: Any, n: Any, sigma_sur: Any = 0, a: Any = 1.0) Any[source]#
Convert resistivity to saturation using Waxman-Smits model.
The function calculates saturated resistivity using Archie’s law: rhos = a * rho_fluid * porosity^(-m)
Then solves the Waxman-Smits equation: 1/rho = sigma_sat * S^n + sigma_sur * S^(n-1) where sigma_sat = 1/rhos
- Parameters:
resistivity (array) – Resistivity values (ohm-m)
porosity (array) – Porosity values (fraction, 0-1)
m (float) – Cementation exponent (typically 1.3-2.5)
rho_fluid (float) – Fluid resistivity (ohm-m)
n (float) – Saturation exponent (typically 1.8-2.2)
sigma_sur (float) – Surface conductivity (S/m). Default is 0 (no surface effects)
a (float) – Tortuosity factor. Default is 1.0
- Returns:
Saturation values (fraction, 0-1)
- Return type:
array
- PyHydroGeophysX.resistivity_to_water_content(resistivity: Any, rhos: Any, n: Any, porosity: Any, sigma_sur: Any = 0) Any[source]#
Convert resistivity to water content using Waxman-Smits model.
- Parameters:
resistivity (array) – Resistivity values
rhos (float) – Saturated resistivity without surface effects
n (float) – Saturation exponent
porosity (array) – Porosity values
sigma_sur (float) – Surface conductivity. Default is 0 (no surface effects).
- Returns:
Volumetric water content values
- Return type:
array
- PyHydroGeophysX.run_joint_inversion(*args, **kwargs)[source]#
Lazily load and run the backend selected by a joint request.
- PyHydroGeophysX.run_workflow(spec: WorkflowSpec | Mapping[str, Any], context: RunContext | None = None) WorkflowRunResult[source]#
Validate and execute one registered workflow.
- PyHydroGeophysX.satK(Keff: Any, Km: Any, phi: Any, Sat: Any) Any[source]#
Calculate the saturated bulk modulus (K_sat) based on Brie’s equation.
Parameters: Keff (float): Effective bulk modulus of the dry rock (GPa). Km (float): Bulk modulus of the matrix (GPa). phi (float): Porosity of the rock. Sat (float): Saturation level of the fluid in the pores.
Returns: float: Saturated bulk modulus (GPa).
- PyHydroGeophysX.save_recipe(spec: WorkflowSpec, path: str | Path) Path[source]#
Validate and save a workflow recipe as UTF-8 JSON.
- PyHydroGeophysX.setup_profile_coordinates(point1: List[int], point2: List[int], surface_data: ndarray, origin_x: float = 0.0, origin_y: float = 0.0, pixel_width: float = 1.0, pixel_height: float = -1.0, num_points: int = 200) Tuple[ndarray, ndarray, ndarray, ndarray, ndarray][source]#
Set up profile coordinates based on surface elevation data between two points
- Parameters:
point1 – Starting point indices [col, row]
point2 – Ending point indices [col, row]
surface_data – 2D array of surface elevation data
origin_x – X coordinate of origin
origin_y – Y coordinate of origin
pixel_width – Width of each pixel
pixel_height – Height of each pixel (negative for top-down)
num_points – Number of points along profile
- Returns:
X coordinates along profile Y_pro: Y coordinates along profile L_profile: Distances along profile XX: X coordinate grid YY: Y coordinate grid
- Return type:
X_pro
- PyHydroGeophysX.tdem_invert(data: ~typing.Dict[str, ~typing.Any], geom: ~typing.Dict[str, ~typing.Any], inv: ~typing.Dict[str, ~typing.Any], log: ~typing.Callable[[str], None] = <function noop>) Dict[str, Any][source]#
Invert a TDEM sounding for a layered resistivity model (Occam 1D).
- PyHydroGeophysX.velDEM(phi: Any, Km: Any, Gm: Any, rho_b: Any, Sat: Any, alpha: Any) Any[source]#
Calculate effective bulk modulus (Keff), shear modulus (Geff), and P-wave velocity (Vp) for a rock with varying porosity (phi) based on the DEM model, taking into account the saturation (Sat) and the crack aspect ratio (alpha).
Parameters: phi (np.array): Array of porosities. Km (float): Initial bulk modulus of the material (GPa). Gm (float): Initial shear modulus of the material (GPa). rho_b (float): Density of the solid phase (kg/m^3). Sat (float): Saturation level of the fluid in the cracks (0 to 1, where 1 is fully saturated). alpha (float): Crack aspect ratio.
Returns: Keff1 (np.array): Effective bulk modulus for each porosity value (GPa). Geff1 (np.array): Effective shear modulus for each porosity value (GPa). Vp (np.array): P-wave velocity for each porosity value (m/s).
- PyHydroGeophysX.vel_porous(phi: Any, Km: Any, Gm: Any, rho_b: Any, Sat: Any, depth: Any = 1) Any[source]#
Calculate P-wave velocity (Vp) for a rock with varying porosity (phi) based on the Hertz-Mindlin model and Hashin-Shtrikman bounds, taking into account the saturation (Sat).
Parameters: phi (np.array): Array of porosities. Km (float): Bulk modulus of the solid phase (GPa). Gm (float): Shear modulus of the solid phase (GPa). rho_b (float): Density of the solid phase (kg/m^3). Sat (float): Saturation level of the fluid in the pores (0 to 1, where 1 is fully saturated). depth (float): depth for pressure estimation (m)
Returns: Vp_h (np.array): P-wave velocity for each porosity value (upper Hashin-Shtrikman bound) (m/s). Vp_l (np.array): P-wave velocity for each porosity value (lower Hashin-Shtrikman bound) (m/s).
- PyHydroGeophysX.water_content_to_resistivity(water_content: Any, rhos: Any, n: Any, porosity: Any, sigma_sur: Any = 0) Any[source]#
Convert water content to resistivity using Waxman-Smits model.
- Parameters:
water_content (array) – Volumetric water content (θ)
rhos (float) – Saturated resistivity without surface effects
n (float) – Saturation exponent
porosity (array) – Porosity values (φ)
sigma_sur (float) – Surface conductivity. Default is 0 (no surface effects).
- Returns:
Resistivity values
- Return type:
array