gea-program 0.25.0__tar.gz → 0.27.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gea_program-0.25.0/gea_program.egg-info → gea_program-0.27.0}/PKG-INFO +27 -2
- {gea_program-0.25.0 → gea_program-0.27.0}/README.md +26 -1
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/__init__.py +1 -1
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/__main__.py +110 -2
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/acceptance_tests.py +251 -1
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/client_reports.py +27 -0
- gea_program-0.27.0/gea/fixtures/README.md +10 -0
- gea_program-0.27.0/gea/fixtures/comcat_delaware_basin_2026-09.txt +29 -0
- gea_program-0.27.0/gea/fixtures/comcat_youngstown_2011-2012.txt +10 -0
- gea_program-0.27.0/gea/help/slip.md +11 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/sra.md +1 -1
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/helplib.py +1 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/service.py +47 -2
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/shapefile.py +25 -5
- gea_program-0.27.0/gea/slip.py +276 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/sra.py +43 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/structure.py +1 -1
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/web/app.html +44 -5
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/workspace.py +157 -3
- {gea_program-0.25.0 → gea_program-0.27.0/gea_program.egg-info}/PKG-INFO +27 -2
- {gea_program-0.25.0 → gea_program-0.27.0}/gea_program.egg-info/SOURCES.txt +5 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/pyproject.toml +2 -2
- {gea_program-0.25.0 → gea_program-0.27.0}/LICENSE +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/backup.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/bench.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/blind_harness.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/catalog_register.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/certificates.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/cli.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/config_versioning.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/conformance.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/correlation.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/dashboard.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/deviation.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/dlis.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/dnp3.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/doctor.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/earth_model.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/elevation.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/etp.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/example_register_map.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/fat_sat.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/files.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/follower.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/forward_model.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/friction_priors.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/gamma.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/geodesy.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/hartip.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/alarms.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/backup.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/catalog.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/conformance.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/data-in.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/dlis.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/doctor.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/drift.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/etp.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/files.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/historian.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/instruments.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/interval.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/month-end.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/notifications.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/osdu.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/patches.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/quality.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/seismic.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/site.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/sites.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/soak.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/start.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/structure.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/transients.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/vibration.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/housekeeping.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/interval.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/jobs.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/live_ports.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/loadtest.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/modbus.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/model_card.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/month_end.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/notify.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/opcua_port.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/operator_app.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/osdu.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/patches.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/permits.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/piwebapi.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/ports.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/ppdm.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/project.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/quakeml.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/reconciler.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/sample_record.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/sbom.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seedlink.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/segy.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_array.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_film.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_response.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_track.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/service_life.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/shell.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/shut_in.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/sla_report.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/soak.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/store_forward.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/strata_join.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/supervisor.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/survey_view.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/telemetry.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/tool_library.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/transient.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/vibration.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/well_assembler.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/wits0.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea/witsml.py +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/setup.cfg +0 -0
- {gea_program-0.25.0 → gea_program-0.27.0}/tests/test_acceptance.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gea-program
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.27.0
|
|
4
4
|
Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
|
|
5
5
|
Author: Daniel T. Murphy
|
|
6
6
|
License: MPL-2.0
|
|
@@ -125,7 +125,7 @@ gea dashboard --catalog-well volve_f12_f14_production_excerpt:15/9-F-12:10000 --
|
|
|
125
125
|
gea client-report --report accuracy --out client_report
|
|
126
126
|
gea model-cards --out model_cards
|
|
127
127
|
gea sbom --out sbom
|
|
128
|
-
gea accept # the product gate (
|
|
128
|
+
gea accept # the product gate (366 checks)
|
|
129
129
|
gea help drift # the help library, by the job (16 pages; the same text is on every dashboard page)
|
|
130
130
|
gea guide # the click-by-click tester guide (docs/TESTER_GUIDE.md)
|
|
131
131
|
gea gui # the desktop window (pip install "gea-program[desktop]")
|
|
@@ -648,6 +648,31 @@ against it; `gea seedlink --config ... --hello` prints what a server says of
|
|
|
648
648
|
itself; `gea help seedlink`. A TexNet station is served by EarthScope at
|
|
649
649
|
`rtserve.iris.washington.edu:18000`, network `TX`.
|
|
650
650
|
|
|
651
|
+
### ComCat
|
|
652
|
+
|
|
653
|
+
The seismicity response plan reads a TexNet export; it reads the FDSN text
|
|
654
|
+
export of USGS ComCat - or any FDSN event service - the same way, with the
|
|
655
|
+
contributor and magnitude type on every event. `gea comcat --lat --lon
|
|
656
|
+
--radius-km --start --end` prints the query to open; `gea comcat --file`
|
|
657
|
+
reads the answer; `sra-report --catalog` takes it. Proven on two verbatim
|
|
658
|
+
public-domain extracts (the Delaware Basin, September 2026; the 2011
|
|
659
|
+
Youngstown sequence with its M 4.0), kept as fixtures with their provenance.
|
|
660
|
+
|
|
661
|
+
### Slip tendency on the mapped faults
|
|
662
|
+
|
|
663
|
+
The stress state the site declares - the three gradients and the ambient
|
|
664
|
+
pore pressure with their source, the SHmax azimuth with its source or from
|
|
665
|
+
the World Stress Map records near the well (`add-stress-map wsm2016.csv`,
|
|
666
|
+
`wsm --lat --lon`) - resolved on every mapped fault trace within the radius
|
|
667
|
+
of a well at the depth of its declared interval: the slip tendency at the
|
|
668
|
+
ambient and the increased pore pressure, the pressure to slip, the margin
|
|
669
|
+
left after the increase, worst and best declared case. The dip comes from
|
|
670
|
+
the layer where it states one (the Hennings 2021 BEG/TexNet layers do, and
|
|
671
|
+
publish their own pressure-to-slip, printed beside this arithmetic); UTM and
|
|
672
|
+
state-plane layers are unprojected from their .prj parameters. `set-stress`,
|
|
673
|
+
`slip --well`, `gea slip`; the SRA packet's section 2e; `gea help slip`. A
|
|
674
|
+
statement on declared inputs, not a probability and not a verdict.
|
|
675
|
+
|
|
651
676
|
### The catalogue accounted for
|
|
652
677
|
|
|
653
678
|
`gea catalog --list` is the register of the 52 shipped public datasets: for
|
|
@@ -86,7 +86,7 @@ gea dashboard --catalog-well volve_f12_f14_production_excerpt:15/9-F-12:10000 --
|
|
|
86
86
|
gea client-report --report accuracy --out client_report
|
|
87
87
|
gea model-cards --out model_cards
|
|
88
88
|
gea sbom --out sbom
|
|
89
|
-
gea accept # the product gate (
|
|
89
|
+
gea accept # the product gate (366 checks)
|
|
90
90
|
gea help drift # the help library, by the job (16 pages; the same text is on every dashboard page)
|
|
91
91
|
gea guide # the click-by-click tester guide (docs/TESTER_GUIDE.md)
|
|
92
92
|
gea gui # the desktop window (pip install "gea-program[desktop]")
|
|
@@ -609,6 +609,31 @@ against it; `gea seedlink --config ... --hello` prints what a server says of
|
|
|
609
609
|
itself; `gea help seedlink`. A TexNet station is served by EarthScope at
|
|
610
610
|
`rtserve.iris.washington.edu:18000`, network `TX`.
|
|
611
611
|
|
|
612
|
+
### ComCat
|
|
613
|
+
|
|
614
|
+
The seismicity response plan reads a TexNet export; it reads the FDSN text
|
|
615
|
+
export of USGS ComCat - or any FDSN event service - the same way, with the
|
|
616
|
+
contributor and magnitude type on every event. `gea comcat --lat --lon
|
|
617
|
+
--radius-km --start --end` prints the query to open; `gea comcat --file`
|
|
618
|
+
reads the answer; `sra-report --catalog` takes it. Proven on two verbatim
|
|
619
|
+
public-domain extracts (the Delaware Basin, September 2026; the 2011
|
|
620
|
+
Youngstown sequence with its M 4.0), kept as fixtures with their provenance.
|
|
621
|
+
|
|
622
|
+
### Slip tendency on the mapped faults
|
|
623
|
+
|
|
624
|
+
The stress state the site declares - the three gradients and the ambient
|
|
625
|
+
pore pressure with their source, the SHmax azimuth with its source or from
|
|
626
|
+
the World Stress Map records near the well (`add-stress-map wsm2016.csv`,
|
|
627
|
+
`wsm --lat --lon`) - resolved on every mapped fault trace within the radius
|
|
628
|
+
of a well at the depth of its declared interval: the slip tendency at the
|
|
629
|
+
ambient and the increased pore pressure, the pressure to slip, the margin
|
|
630
|
+
left after the increase, worst and best declared case. The dip comes from
|
|
631
|
+
the layer where it states one (the Hennings 2021 BEG/TexNet layers do, and
|
|
632
|
+
publish their own pressure-to-slip, printed beside this arithmetic); UTM and
|
|
633
|
+
state-plane layers are unprojected from their .prj parameters. `set-stress`,
|
|
634
|
+
`slip --well`, `gea slip`; the SRA packet's section 2e; `gea help slip`. A
|
|
635
|
+
statement on declared inputs, not a probability and not a verdict.
|
|
636
|
+
|
|
612
637
|
### The catalogue accounted for
|
|
613
638
|
|
|
614
639
|
`gea catalog --list` is the register of the 52 shipped public datasets: for
|
|
@@ -278,6 +278,19 @@ def main(argv=None) -> int:
|
|
|
278
278
|
p_lp.add_argument("--stream-csv", type=str, default=None, help="also write a historian-style CSV the other commands ingest")
|
|
279
279
|
p_lp.add_argument("--selftest", action="store_true", help="etp: the codec round-trip and a session against the simulated store on the loopback")
|
|
280
280
|
|
|
281
|
+
p_cc = sub.add_parser("comcat", help="USGS ComCat / any FDSN event service: --lat --lon --radius-km --start --end prints the text-format query to open; --file reads the export it returns")
|
|
282
|
+
p_cc.add_argument("--lat", type=float, default=None); p_cc.add_argument("--lon", type=float, default=None); p_cc.add_argument("--radius-km", type=float, default=25.0)
|
|
283
|
+
p_cc.add_argument("--start", type=str, default=None); p_cc.add_argument("--end", type=str, default=None); p_cc.add_argument("--min-mag", type=float, default=1.0)
|
|
284
|
+
p_cc.add_argument("--file", type=str, default=None, help="an FDSN text export to read and summarise")
|
|
285
|
+
p_cc.add_argument("--json", action="store_true")
|
|
286
|
+
p_sl = sub.add_parser("slip", help="slip tendency on the mapped faults of a layer at a position, from declared gradients: --layer --lat --lon --depth-ft --sv --shmin --shmax (--shmax-azimuth or --wsm)")
|
|
287
|
+
p_sl.add_argument("--layer", type=str, required=True); p_sl.add_argument("--member", type=str, default=None); p_sl.add_argument("--feature-kind", type=str, choices=["fault", "fold"], default=None)
|
|
288
|
+
p_sl.add_argument("--lat", type=float, required=True); p_sl.add_argument("--lon", type=float, required=True); p_sl.add_argument("--radius-km", type=float, default=25.0)
|
|
289
|
+
p_sl.add_argument("--depth-ft", type=float, required=True)
|
|
290
|
+
p_sl.add_argument("--sv", type=float, required=True); p_sl.add_argument("--shmin", type=float, required=True); p_sl.add_argument("--shmax", type=float, required=True)
|
|
291
|
+
p_sl.add_argument("--pp", type=float, default=0.433); p_sl.add_argument("--shmax-azimuth", type=float, default=None); p_sl.add_argument("--wsm", type=str, default=None, help="the WSM database CSV: the azimuth from its records within 100 km")
|
|
292
|
+
p_sl.add_argument("--dips", type=float, nargs="+", default=[60.0, 75.0, 90.0]); p_sl.add_argument("--mu", type=float, nargs="+", default=[0.6]); p_sl.add_argument("--delta-pp", type=float, default=0.0)
|
|
293
|
+
p_sl.add_argument("--json", action="store_true")
|
|
281
294
|
p_cat = sub.add_parser("catalog", help="the shipped catalogue: --list every entry with what reads it; --unused the carried ones; --check reads every entry; --friction the measured friction envelope; --core the core check; --entry X --info | --stream-csv")
|
|
282
295
|
p_cat.add_argument("--list", action="store_true"); p_cat.add_argument("--unused", action="store_true"); p_cat.add_argument("--check", action="store_true")
|
|
283
296
|
p_cat.add_argument("--friction", action="store_true"); p_cat.add_argument("--core", action="store_true")
|
|
@@ -319,7 +332,8 @@ def main(argv=None) -> int:
|
|
|
319
332
|
"add-seismic", "refresh-seismic", "remove-seismic", "sar-film", "refresh-all", "add-track", "refresh-track", "remove-track",
|
|
320
333
|
"seismic-dataset", "seismic-field", "add-site", "sites", "site-report", "remove-site", "rename",
|
|
321
334
|
"set-well", "sra-define", "sra-report", "associate", "osdu-export", "quakeml-export", "well-identity", "vibration-report",
|
|
322
|
-
"add-live-station", "live-fold", "live-run", "month-end", "add-layer", "layers", "remove-layer", "structure", "interval"
|
|
335
|
+
"add-live-station", "live-fold", "live-run", "month-end", "add-layer", "layers", "remove-layer", "structure", "interval",
|
|
336
|
+
"set-stress", "add-stress-map", "wsm", "slip"])
|
|
323
337
|
p_ws.add_argument("--stations", type=str, nargs="+", default=None, help="add-track: two or more array station ids of this workspace")
|
|
324
338
|
p_ws.add_argument("--site", type=str, default=None, help="site-report/remove-site: the site id")
|
|
325
339
|
p_ws.add_argument("--api", type=str, default=None, help="set-well: the API number")
|
|
@@ -399,6 +413,18 @@ def main(argv=None) -> int:
|
|
|
399
413
|
p_ws.add_argument("--formation-name", type=str, default=None, help="add-layer: the formation a contours layer maps (Wolfcamp)")
|
|
400
414
|
p_ws.add_argument("--role", type=str, choices=["top", "isopach", "base"], default=None, help="add-layer: what the contours are of that formation: its top elevation, its thickness, or its base")
|
|
401
415
|
p_ws.add_argument("--base-interval-ft", type=float, default=None, help="set-well: base of the disposal interval, ft")
|
|
416
|
+
p_ws.add_argument("--feature-kind", type=str, choices=["fault", "fold"], default=None, help="add-layer: what every feature of a structure layer is when its attributes do not say")
|
|
417
|
+
p_ws.add_argument("--sv", type=float, default=None, help="set-stress: vertical stress gradient, psi/ft")
|
|
418
|
+
p_ws.add_argument("--shmin", type=float, default=None, help="set-stress: minimum horizontal stress gradient, psi/ft")
|
|
419
|
+
p_ws.add_argument("--shmax", type=float, default=None, help="set-stress: maximum horizontal stress gradient, psi/ft")
|
|
420
|
+
p_ws.add_argument("--pp", type=float, default=None, help="set-stress: ambient pore-pressure gradient, psi/ft (hydrostatic 0.433 unless declared)")
|
|
421
|
+
p_ws.add_argument("--shmax-azimuth", type=float, default=None, help="set-stress: SHmax azimuth, degrees from north (or leave it to the stress map)")
|
|
422
|
+
p_ws.add_argument("--azimuth-source", type=str, default=None, help="set-stress: where the azimuth came from")
|
|
423
|
+
p_ws.add_argument("--gradients-source", type=str, default=None, help="set-stress: where the gradients came from")
|
|
424
|
+
p_ws.add_argument("--dips", type=float, nargs="+", default=None, help="set-stress: the dips to run when the layer states none (default 60 75 90)")
|
|
425
|
+
p_ws.add_argument("--mu", type=float, nargs="+", default=None, help="set-stress: the friction coefficients to run (default 0.6)")
|
|
426
|
+
p_ws.add_argument("--delta-pp", type=float, default=None, help="set-stress / slip: the pore-pressure increase to judge at, psi")
|
|
427
|
+
p_ws.add_argument("--depth-ft", type=float, default=None, help="slip: the depth to judge at (default the midpoint of the declared interval)")
|
|
402
428
|
p_ws.add_argument("--depth-ref", type=str, choices=["TVD", "MD"], default=None, help="set-well: the interval depths are true vertical (TVD) or measured (MD) depth")
|
|
403
429
|
p_ws.add_argument("--ref-elev-ft", type=float, default=None, help="set-well: the reference elevation the depths are measured from, ft above sea level")
|
|
404
430
|
p_ws.add_argument("--ref-elev-datum", type=str, choices=["KB", "GL", "DF"], default=None, help="set-well: what that elevation is: kelly bushing, ground level, derrick floor")
|
|
@@ -2095,7 +2121,7 @@ def main(argv=None) -> int:
|
|
|
2095
2121
|
elif a.action == "add-layer":
|
|
2096
2122
|
if not a.layer or not a.name:
|
|
2097
2123
|
raise SystemExit("add-layer needs --name <display> and --layer <shapefile zip | folder | .shp>")
|
|
2098
|
-
L = ws.add_layer(a.layer, a.name, actor=a.actor, citation=a.citation, member=a.member, formation=a.formation_name, role=a.role)
|
|
2124
|
+
L = ws.add_layer(a.layer, a.name, actor=a.actor, citation=a.citation, member=a.member, formation=a.formation_name, role=a.role, feature_kind=a.feature_kind)
|
|
2099
2125
|
tc = ", ".join(f"{k} {v}" for k, v in list(L["type_counts"].items())[:6])
|
|
2100
2126
|
print(f"layer {L['id']} ({L['kind']}): {L['n_features']} {L['shape_type']} features, {L['crs']['kind']} {L['crs'].get('datum') or ''}, extent lon {L['bbox'][0]:.3f}..{L['bbox'][2]:.3f} lat {L['bbox'][1]:.3f}..{L['bbox'][3]:.3f}"
|
|
2101
2127
|
+ (f"; contour value {L['value_attr']}" if L.get('value_attr') else ''))
|
|
@@ -2124,6 +2150,32 @@ def main(argv=None) -> int:
|
|
|
2124
2150
|
for line in L["lines"]:
|
|
2125
2151
|
print(" " + line)
|
|
2126
2152
|
return 0 if r["status"] == "OK" else 1
|
|
2153
|
+
elif a.action == "set-stress":
|
|
2154
|
+
st = ws.set_stress({"sv_psi_ft": a.sv, "shmin_psi_ft": a.shmin, "shmax_psi_ft": a.shmax, "pp_psi_ft": a.pp, "shmax_azimuth_deg": a.shmax_azimuth,
|
|
2155
|
+
"azimuth_source": a.azimuth_source, "gradients_source": a.gradients_source, "dips_deg": a.dips, "mus": a.mu, "delta_pp_psi": a.delta_pp, "note": a.note or ""}, actor=a.actor)
|
|
2156
|
+
print(f"stress: Sv {st['sv_psi_ft']} Shmin {st['shmin_psi_ft']} SHmax {st['shmax_psi_ft']} Pp {st['pp_psi_ft']} psi/ft ({st['gradients_source']}); "
|
|
2157
|
+
f"SHmax azimuth {st.get('shmax_azimuth_deg', 'from the stress map')} ({st.get('azimuth_source', '')}); dips {st['dips_deg']}; mu {st['mus']}; delta Pp {st['delta_pp_psi']} psi"); return 0
|
|
2158
|
+
elif a.action == "add-stress-map":
|
|
2159
|
+
if not a.file:
|
|
2160
|
+
raise SystemExit("add-stress-map needs --file <wsm.csv>")
|
|
2161
|
+
r = ws.add_stress_map(a.file, actor=a.actor, citation=a.citation)
|
|
2162
|
+
print(f"stress map: {r['n_records']} records kept as {r['file']} (sha256 {r['sha256'][:16]})"); return 0
|
|
2163
|
+
elif a.action == "wsm":
|
|
2164
|
+
if a.lat is None or a.lon is None:
|
|
2165
|
+
raise SystemExit("wsm needs --lat --lon [--radius-km]")
|
|
2166
|
+
r = ws.wsm_at(a.lat, a.lon, a.radius_km if a.radius_km is not None else 100.0)
|
|
2167
|
+
print(r.get("statement") or f"{r['status']}: {r.get('note', '')}")
|
|
2168
|
+
for rec in r.get("records", [])[:10]:
|
|
2169
|
+
print(f" {rec['distance_km']:7.1f} km {rec['azimuth']:5.0f} deg {rec['quality']} {rec['regime'] or '?':3s} {rec['type']:4s} {rec['locality'][:40]}")
|
|
2170
|
+
return 0 if r.get("n") else 1
|
|
2171
|
+
elif a.action == "slip":
|
|
2172
|
+
if not a.well:
|
|
2173
|
+
raise SystemExit("slip needs --well <id>")
|
|
2174
|
+
r = ws.well_slip(a.well, a.radius_km if a.radius_km is not None else 25.0, delta_pp_psi=a.delta_pp, depth_ft=a.depth_ft, actor=a.actor)
|
|
2175
|
+
print(f"slip {a.well}: {r['status']}")
|
|
2176
|
+
for line in r["lines"]:
|
|
2177
|
+
print(" " + line)
|
|
2178
|
+
return 0 if r["status"] == "OK" else 1
|
|
2127
2179
|
elif a.action == "interval":
|
|
2128
2180
|
if not a.well:
|
|
2129
2181
|
raise SystemExit("interval needs --well <id>")
|
|
@@ -2304,6 +2356,62 @@ def main(argv=None) -> int:
|
|
|
2304
2356
|
stop.set()
|
|
2305
2357
|
print("etp-sim: stopped")
|
|
2306
2358
|
return 0
|
|
2359
|
+
elif a.cmd == "comcat":
|
|
2360
|
+
import json as _json
|
|
2361
|
+
from . import sra as _SR
|
|
2362
|
+
from . import geodesy as _GD
|
|
2363
|
+
if a.file:
|
|
2364
|
+
c = _SR.read_catalog(a.file)
|
|
2365
|
+
if c.get("format") != "fdsn-text":
|
|
2366
|
+
print(f"comcat: {a.file} is not an FDSN text export (it read as a {c.get('basis', '')[:60]}...)"); return 1
|
|
2367
|
+
ev = c["events"]
|
|
2368
|
+
if a.lat is not None and a.lon is not None:
|
|
2369
|
+
for e in ev:
|
|
2370
|
+
dm = _GD.geodesic_m(a.lat, a.lon, e["lat"], e["lon"])["distance_m"]
|
|
2371
|
+
e["distance_km"] = round(dm / 1000.0, 2) if dm is not None else None
|
|
2372
|
+
if a.json:
|
|
2373
|
+
print(_json.dumps(c, indent=1, default=str)); return 0
|
|
2374
|
+
big = max(ev, key=lambda e: e["magnitude"]) if ev else None
|
|
2375
|
+
ts = sorted(e["time"] for e in ev)
|
|
2376
|
+
print(f"comcat: {c['n_events']} event(s) ({c['n_skipped']} skipped) from {ts[0][:10] if ts else '-'} to {ts[-1][:10] if ts else '-'}; "
|
|
2377
|
+
f"contributors {', '.join(c['contributors'])}; magnitude types {', '.join(c['magnitude_types'])}")
|
|
2378
|
+
if big:
|
|
2379
|
+
print(f" largest: M {big['magnitude']:.1f} {big['mag_type']} {big['time']} at {big['lat']:.4f}, {big['lon']:.4f}, {big['depth_km']} km - {big['place']} ({big['event_id']})")
|
|
2380
|
+
for e in sorted(ev, key=lambda x: x["time"])[:40]:
|
|
2381
|
+
print(f" {e['time'][:19]} M {e['magnitude']:>4.1f} {e['mag_type']:<6s} {e['lat']:9.4f} {e['lon']:10.4f} {str(e['depth_km']):>7s} km " + (f"{e['distance_km']:7.2f} km " if e.get("distance_km") is not None else "") + f"{e['place']}")
|
|
2382
|
+
return 0
|
|
2383
|
+
if a.lat is None or a.lon is None or not a.start or not a.end:
|
|
2384
|
+
raise SystemExit("comcat needs --lat --lon --start --end (--radius-km, --min-mag), or --file <export>")
|
|
2385
|
+
print(_SR.comcat_url(a.lat, a.lon, a.radius_km, a.start, a.end, a.min_mag))
|
|
2386
|
+
print(" open it in a browser (this machine may not reach the service) and save the text it returns; `gea comcat --file <saved>` reads it, and sra-report --catalog takes it.")
|
|
2387
|
+
return 0
|
|
2388
|
+
elif a.cmd == "slip":
|
|
2389
|
+
import json as _json
|
|
2390
|
+
from . import shapefile as _SF, slip as _SL, friction_priors as _FP
|
|
2391
|
+
try:
|
|
2392
|
+
L = _SF.read(a.layer, member=a.member)
|
|
2393
|
+
except (ValueError, OSError) as e:
|
|
2394
|
+
raise SystemExit(f"slip: {e}")
|
|
2395
|
+
if a.feature_kind:
|
|
2396
|
+
L.declared_kind = a.feature_kind
|
|
2397
|
+
az, az_src = a.shmax_azimuth, "declared"
|
|
2398
|
+
if az is None and a.wsm:
|
|
2399
|
+
nb = _SL.wsm_nearby(_SL.read_wsm(a.wsm), a.lat, a.lon, 100.0)
|
|
2400
|
+
if not nb["n"]:
|
|
2401
|
+
raise SystemExit("slip: no World Stress Map record of quality A/B/C within 100 km; declare --shmax-azimuth with its source")
|
|
2402
|
+
az, az_src = nb["azimuth_mean"], nb["statement"]
|
|
2403
|
+
if az is None:
|
|
2404
|
+
raise SystemExit("slip: give --shmax-azimuth or --wsm <wsm.csv>")
|
|
2405
|
+
faults = _SL.faults_in_radius(L, a.lat, a.lon, a.radius_km)
|
|
2406
|
+
r = _SL.statement(faults, a.depth_ft, {"sv_psi_ft": a.sv, "shmin_psi_ft": a.shmin, "shmax_psi_ft": a.shmax, "pp_psi_ft": a.pp}, az, tuple(a.dips), tuple(a.mu), a.delta_pp,
|
|
2407
|
+
sources={"shmax_azimuth": az_src, "gradients": "the command line"})
|
|
2408
|
+
r["friction_envelope"] = _FP.envelope()
|
|
2409
|
+
if a.json:
|
|
2410
|
+
print(_json.dumps(r, indent=1, default=str)); return 0
|
|
2411
|
+
for line in r["lines"]:
|
|
2412
|
+
print(line)
|
|
2413
|
+
print(r["friction_envelope"].get("statement", ""))
|
|
2414
|
+
return 0
|
|
2307
2415
|
elif a.cmd == "catalog":
|
|
2308
2416
|
import json as _json
|
|
2309
2417
|
from . import catalog_register as _CR
|
|
@@ -6179,7 +6179,7 @@ def section_bo_structure(tmp: str) -> None:
|
|
|
6179
6179
|
"counts_and_lines": r["counts_within"] == {"fault": 1, "fold": 1, "other": 0} and f"{g_fault:.2f} km" in ST.lines(r)[0] and "N (" in ST.lines(r)[0] and "North Fault" in ST.lines(r)[0],
|
|
6180
6180
|
"outside_extent": out_ext["status"] == "OUTSIDE LAYER EXTENT" and "extent" in out_ext["note"] and ST.lines(out_ext)[0].startswith("Layer") and "OUTSIDE LAYER EXTENT" in ST.lines(out_ext)[0],
|
|
6181
6181
|
"projected_unprojected": Lp.crs["kind"] == "projected" and Lp.crs["zone"] == "TX_CENTRAL" and abs(plat - (lat0 + dlat)) < 1e-6 and abs(plon - lon0) < 1e-6,
|
|
6182
|
-
"refused_by_name": utm_err and "UTM" in utm_err and "
|
|
6182
|
+
"refused_by_name": utm_err and "UTM" in utm_err and "from its parameters" in utm_err and noprj_err and "no .prj" in noprj_err,
|
|
6183
6183
|
"shx_honoured": Lbad.n == 3 and seq_err and "content length" in seq_err,
|
|
6184
6184
|
}
|
|
6185
6185
|
failed1 = [k for k, v in c1.items() if not v]
|
|
@@ -7072,6 +7072,254 @@ def section_bs_catalog(tmp: str) -> None:
|
|
|
7072
7072
|
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
7073
7073
|
|
|
7074
7074
|
|
|
7075
|
+
def section_bt_slip(tmp: str) -> None:
|
|
7076
|
+
"""Section BT - slip tendency on the mapped faults: the stress resolution against its identities, the regime, Ts and
|
|
7077
|
+
the pressure to slip, the World Stress Map reader and the nearby azimuth; a UTM layer unprojected from its .prj
|
|
7078
|
+
parameters with the fault's own dip and a published pressure-to-slip read beside this arithmetic; the workspace's
|
|
7079
|
+
stress state, stress map and statement through the SRA packet, the API, the page, the CLI; the help."""
|
|
7080
|
+
import http.cookiejar
|
|
7081
|
+
import math as _math
|
|
7082
|
+
import subprocess as _sp
|
|
7083
|
+
import urllib.request
|
|
7084
|
+
import urllib.error
|
|
7085
|
+
import zipfile
|
|
7086
|
+
from . import shapefile as SF
|
|
7087
|
+
from . import slip as SL
|
|
7088
|
+
from . import geodesy as GD
|
|
7089
|
+
from . import helplib as H
|
|
7090
|
+
from .telemetry import TelemetryRecorder, TelemetryConfig
|
|
7091
|
+
from .downhole_engine import DownholeEngine, SimulatorConfig
|
|
7092
|
+
from .workspace import Workspace, WorkspaceError
|
|
7093
|
+
from .service import Service, Users
|
|
7094
|
+
pkg = Path(__file__).parent
|
|
7095
|
+
d = Path(tmp, "bt"); d.mkdir()
|
|
7096
|
+
|
|
7097
|
+
# -- BT1: the arithmetic and the stress map -----------------------------------------------------------------------
|
|
7098
|
+
st = SL.stress_at(8000.0, 1.05, 0.65, 0.95)
|
|
7099
|
+
par = SL.resolve(80.0, 90.0, 80.0, st["Sv"], st["Shmin"], st["SHmax"]) # a vertical plane along SHmax: Shmin, no shear
|
|
7100
|
+
per = SL.resolve(170.0, 90.0, 80.0, st["Sv"], st["Shmin"], st["SHmax"]) # across SHmax: SHmax, no shear
|
|
7101
|
+
d45 = SL.resolve(35.0, 90.0, 80.0, st["Sv"], st["Shmin"], st["SHmax"]) # 45 deg: the mean and the half-difference
|
|
7102
|
+
hor = SL.resolve(0.0, 0.0, 80.0, st["Sv"], st["Shmin"], st["SHmax"]) # a horizontal plane: Sv
|
|
7103
|
+
ts = SL.slip_tendency(35.0, 90.0, st, 80.0, 0.6, 500.0)
|
|
7104
|
+
ts_past = SL.slip_tendency(35.0, 90.0, st, 80.0, 0.6, 2000.0)
|
|
7105
|
+
hdr = "ID,SITE,LAT,LON,AZI,TYPE,DEPTH,QUALITY,REGIME,LOCALITY,COUNTRY\n"
|
|
7106
|
+
rows = "".join(f"w{i},S,{31.3 + 0.05 * i},{-103.6 + 0.04 * i},{(75 + 3 * (i % 5)) % 180},BO,2.5,{'ABC'[i % 3]},{'NF' if i % 2 else 'SS'},Delaware,USA\n" for i in range(12))
|
|
7107
|
+
rows += "far,S,35.0,-100.0,10,FMS,3,A,TF,away,USA\nbad,S,31.4,-103.5,999,BO,2,A,NF,x,USA\nlow,S,31.42,-103.5,120,BO,2,E,NF,x,USA\n"
|
|
7108
|
+
wsm_path = str(d / "wsm_like.csv")
|
|
7109
|
+
Path(wsm_path).write_text(hdr + rows, encoding="utf-8")
|
|
7110
|
+
recs = SL.read_wsm(wsm_path)
|
|
7111
|
+
nb = SL.wsm_nearby(recs, 31.42, -103.50, 100.0)
|
|
7112
|
+
nb_none = SL.wsm_nearby(recs, 45.0, -70.0, 50.0)
|
|
7113
|
+
bad_wsm = None
|
|
7114
|
+
try:
|
|
7115
|
+
SL.read_wsm(io_bytes := b"A,B,C\n1,2,3\n")
|
|
7116
|
+
except ValueError as e:
|
|
7117
|
+
bad_wsm = str(e)
|
|
7118
|
+
c1 = {
|
|
7119
|
+
"identities": abs(par[0] - st["Shmin"]) < 1e-3 and abs(par[1]) < 1e-3 and abs(per[0] - st["SHmax"]) < 1e-3 and abs(per[1]) < 1e-3
|
|
7120
|
+
and abs(d45[0] - (st["SHmax"] + st["Shmin"]) / 2) < 1e-3 and abs(d45[1] - (st["SHmax"] - st["Shmin"]) / 2) < 1e-3 and abs(hor[0] - st["Sv"]) < 1e-3 and abs(hor[1]) < 1e-3,
|
|
7121
|
+
"regime": SL.regime_of(8400, 5200, 7600) == "normal" and SL.regime_of(8000, 5200, 9000) == "strike-slip" and SL.regime_of(5000, 6000, 9000) == "reverse",
|
|
7122
|
+
"tendency": ts["Ts_ambient"] == round(1200.0 / (6400.0 - 3464.0), 3) and ts["pressure_to_slip_psi"] == round(6400.0 - 3464.0 - 1200.0 / 0.6, 1) and ts["margin_after_injection_psi"] == round(ts["pressure_to_slip_psi"] - 500.0, 1)
|
|
7123
|
+
and ts["status"] == "BELOW THE FRICTION LINE" and ts_past["status"] == "PAST THE FRICTION LINE" and ts_past["Ts_injection"] > ts["Ts_injection"],
|
|
7124
|
+
"wsm": len(recs) == 14 and nb["n"] == 12 and abs(nb["azimuth_mean"] - 80.25) < 0.5 and nb["by_quality"] == {"A": 4, "B": 4, "C": 4} and nb["by_regime"] == {"NF": 6, "SS": 6}
|
|
7125
|
+
and nb["spread_deg_median"] <= 6 and nb_none["n"] == 0 and bad_wsm and "columns" in bad_wsm,
|
|
7126
|
+
}
|
|
7127
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
7128
|
+
ok(not failed1,
|
|
7129
|
+
"BT1 the stress resolution against its identities (a vertical plane along SHmax feels Shmin and no shear, across it SHmax, at 45 degrees the mean and the "
|
|
7130
|
+
"half-difference, a horizontal plane Sv), Anderson's regime from the ordering, the slip tendency and the pressure to slip by the published arithmetic, "
|
|
7131
|
+
"past the friction line when the increase exceeds it; the World Stress Map CSV read by column name (a 999 azimuth and a D/E quality left out), the "
|
|
7132
|
+
"records within the radius with the axial mean azimuth, spread, counts by quality and regime; no records, and a file without the columns, named"
|
|
7133
|
+
+ (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
7134
|
+
|
|
7135
|
+
# -- BT2: a UTM layer from its .prj parameters, with dip and a published pressure to slip -----------------------------
|
|
7136
|
+
lat1, lon1 = 31.42, -103.50
|
|
7137
|
+
utm13 = GD.utm(13, True, "WGS84")
|
|
7138
|
+
wkt = ('PROJCS["WGS_1984_UTM_Zone_13N",GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],'
|
|
7139
|
+
'UNIT["Degree",0.0174532925199433]],PROJECTION["Transverse_Mercator"],PARAMETER["False_Easting",500000.0],PARAMETER["False_Northing",0.0],'
|
|
7140
|
+
'PARAMETER["Central_Meridian",-105.0],PARAMETER["Scale_Factor",0.9996],PARAMETER["Latitude_Of_Origin",0.0],UNIT["Meter",1.0]]')
|
|
7141
|
+
|
|
7142
|
+
def en(lat, lon):
|
|
7143
|
+
p_ = GD.project(lat, lon, utm13)
|
|
7144
|
+
return (p_["easting_m"], p_["northing_m"])
|
|
7145
|
+
kmlat = 1.0 / 111.195
|
|
7146
|
+
kmlon = 1.0 / (111.195 * _math.cos(_math.radians(lat1)))
|
|
7147
|
+
# three faults: one along SHmax (92 deg) 3 km north with dip 62 and a published value; one across it; one 40 km away (outside the radius)
|
|
7148
|
+
feats = [([[en(lat1 + 3 * kmlat, lon1 - 0.05), en(lat1 + 3 * kmlat - 0.1 * kmlat * 0.035 * 0, lon1 + 0.05)]], {"dip": 62.0, "note": "HIGH CONFIDENCE", "Pp2S_MPa": 5.0, "BEARING": 92.0}),
|
|
7149
|
+
([[en(lat1 - 0.05, lon1 + 6 * kmlon), en(lat1 + 0.05, lon1 + 6 * kmlon)]], {"dip": 85.0, "note": "LOW CONFIDENCE", "Pp2S_MPa": 20.0, "BEARING": 0.0}),
|
|
7150
|
+
([[en(lat1 + 0.36, lon1 - 0.02), en(lat1 + 0.36, lon1 + 0.02)]], {"dip": 70.0, "note": "FAR", "Pp2S_MPa": 9.0, "BEARING": 90.0})]
|
|
7151
|
+
SF.write(str(d / "utm_faults"), "PolyLine", feats, [("dip", "F", 6, 1), ("note", "C", 20, 0), ("Pp2S_MPa", "F", 10, 4), ("BEARING", "F", 8, 2)], wkt)
|
|
7152
|
+
with zipfile.ZipFile(str(d / "utm_faults.zip"), "w") as z:
|
|
7153
|
+
for ext in (".shp", ".shx", ".dbf", ".prj"):
|
|
7154
|
+
z.write(str(d / ("utm_faults" + ext)), "utm_faults" + ext)
|
|
7155
|
+
L = SF.read(str(d / "utm_faults.zip"))
|
|
7156
|
+
L.declared_kind = "fault"
|
|
7157
|
+
f1 = L.features[0].parts[0][0]
|
|
7158
|
+
faults = SL.faults_in_radius(L, lat1, lon1, 25.0)
|
|
7159
|
+
res = SL.statement(faults, 9000.0, {"sv_psi_ft": 1.05, "shmin_psi_ft": 0.65, "shmax_psi_ft": 0.95, "pp_psi_ft": 0.45}, 92.0, (60.0, 75.0, 90.0), (0.6,), 300.0,
|
|
7160
|
+
sources={"shmax_azimuth": "the gate", "gradients": "the gate"})
|
|
7161
|
+
along = next(r for r in res["faults"] if r["attrs"].get("note") == "HIGH CONFIDENCE")
|
|
7162
|
+
across = next(r for r in res["faults"] if r["attrs"].get("note") == "LOW CONFIDENCE")
|
|
7163
|
+
lcc_wkt = ('PROJCS["NAD_1983_Texas_Centric_Mapping_System_Lambert",GEOGCS["GCS_North_American_1983",DATUM["D_North_American_1983",SPHEROID["GRS_1980",6378137.0,298.257222101]],'
|
|
7164
|
+
'PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]],PROJECTION["Lambert_Conformal_Conic"],PARAMETER["False_Easting",1500000.0],PARAMETER["False_Northing",5000000.0],'
|
|
7165
|
+
'PARAMETER["Central_Meridian",-100.0],PARAMETER["Standard_Parallel_1",27.5],PARAMETER["Standard_Parallel_2",35.0],PARAMETER["Latitude_Of_Origin",18.0],UNIT["Meter",1.0]]')
|
|
7166
|
+
lcc = SF.parse_prj(lcc_wkt)
|
|
7167
|
+
unknown = SF.parse_prj('PROJCS["X",GEOGCS["G",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]]],PROJECTION["Mercator"],PARAMETER["Central_Meridian",0.0],UNIT["Meter",1.0]]')
|
|
7168
|
+
c2 = {
|
|
7169
|
+
"unprojected": L.crs["kind"] == "projected" and L.crs["usable"] and "Transverse Mercator on WGS84" in L.crs["how"] and abs(f1[1] - (lat1 + 3 * kmlat)) < 2e-6 and abs(f1[0] - (lon1 - 0.05)) < 2e-6
|
|
7170
|
+
and lcc["usable"] and lcc["zone_def"]["kind"] == "lcc" and lcc["zone_def"]["lat1"] == 27.5 and not unknown["usable"] and "MERCATOR" in unknown["note"],
|
|
7171
|
+
"faults_found": len(faults) == 2 and along["attrs"]["dip_deg"] == 62.0 and along["attrs"]["published_pressure_to_slip_psi"] == round(5.0 * 145.037738, 1)
|
|
7172
|
+
and abs(along["distance_km"] - 3.0) < 0.05 and abs(along["strike_deg"] - 90.0) < 1.0 and along["dip_source"] == "the layer" and len(along["cases"]) == 1,
|
|
7173
|
+
"statement": along["worst"]["dip_deg"] == 62.0 and across["worst"]["dip_deg"] == 85.0 and along["angle_to_shmax_deg"] <= 3 and across["angle_to_shmax_deg"] > 85
|
|
7174
|
+
and along["worst"]["Ts_injection"] > across["worst"]["Ts_injection"] and res["regime"] == "normal"
|
|
7175
|
+
and along["published"]["pressure_to_slip_psi"] == round(5.0 * 145.037738, 1) and along["published"]["difference_psi"] == round(along["cases"][0]["pressure_to_slip_psi"] - along["published"]["pressure_to_slip_psi"], 1)
|
|
7176
|
+
and any("The layer publishes 725 psi to slip (Pp2S_MPa)" in ln for ln in res["lines"]) and res["faults"][0] is along,
|
|
7177
|
+
}
|
|
7178
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
7179
|
+
ok(not failed2,
|
|
7180
|
+
"BT2 a UTM zone 13N layer unprojected from its .prj parameters (Transverse Mercator on WGS84; a Lambert Conformal Conic parsed the same way; a "
|
|
7181
|
+
"Mercator refused by name); the faults within the radius with the layer's own dip and its published pressure-to-slip read as attributes; the trace "
|
|
7182
|
+
"along SHmax ranked first with the higher tendency, its dip from the layer and one case, the published value printed beside this arithmetic with the difference"
|
|
7183
|
+
+ (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
7184
|
+
|
|
7185
|
+
# -- BT3: the workspace, the SRA packet, the API, the page, the CLI, the help -------------------------------------------
|
|
7186
|
+
hist = str(d / "hist.csv")
|
|
7187
|
+
TelemetryRecorder(engine=DownholeEngine(SimulatorConfig()), config=TelemetryConfig(duration_hours=1.0, seed=5)).run().export_csv(hist)
|
|
7188
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
|
|
7189
|
+
w = ws.add_well_file(hist, display="SWD 1", actor="tester")
|
|
7190
|
+
s0 = ws.well_slip(w["id"], actor="tester")
|
|
7191
|
+
ws.set_well(w["id"], surface={"lat": lat1, "lon": lon1, "datum": "NAD83", "elevation": {"ft": 2950.0, "datum": "KB", "source": "completion report"}}, actor="tester")
|
|
7192
|
+
ws.set_well(w["id"], disposal={"top_interval_ft": 8700.0, "base_interval_ft": 9300.0, "depth_reference": "TVD", "depth_tier": "deep", "channel_pressure": "P_surf_psi",
|
|
7193
|
+
"channel_rate": "Q_bpm", "rate_unit": "bbl/min", "bhp_method": "probe", "channel_bhp": "P_bh_psi"}, actor="tester")
|
|
7194
|
+
s1 = ws.well_slip(w["id"], actor="tester")
|
|
7195
|
+
no_src = None
|
|
7196
|
+
try:
|
|
7197
|
+
ws.set_stress({"sv_psi_ft": 1.05, "shmin_psi_ft": 0.65, "shmax_psi_ft": 0.95}, actor="tester")
|
|
7198
|
+
except WorkspaceError as e:
|
|
7199
|
+
no_src = str(e)
|
|
7200
|
+
stx = ws.set_stress({"sv_psi_ft": 1.05, "shmin_psi_ft": 0.65, "shmax_psi_ft": 0.95, "pp_psi_ft": 0.45, "gradients_source": "the gate's declaration", "delta_pp_psi": 300.0}, actor="tester")
|
|
7201
|
+
s2 = ws.well_slip(w["id"], actor="tester")
|
|
7202
|
+
lay = ws.add_layer(str(d / "utm_faults.zip"), "Gate UTM faults", actor="tester", feature_kind="fault", citation="the gate's own layer")
|
|
7203
|
+
bad_fk = None
|
|
7204
|
+
try:
|
|
7205
|
+
ws.add_layer(str(d / "utm_faults.zip"), "Again", actor="tester", feature_kind="contour")
|
|
7206
|
+
except WorkspaceError as e:
|
|
7207
|
+
bad_fk = str(e)
|
|
7208
|
+
s3 = ws.well_slip(w["id"], actor="tester")
|
|
7209
|
+
sm = ws.add_stress_map(wsm_path, actor="tester", citation="WSM-shaped, the gate")
|
|
7210
|
+
s4 = ws.well_slip(w["id"], actor="tester")
|
|
7211
|
+
wsm_q = ws.wsm_at(lat1, lon1, 100.0)
|
|
7212
|
+
site = ws.add_site("Pad 3 site", wells=[w["id"]], actor="tester")
|
|
7213
|
+
ws.sra_define(site["id"], actor="tester", name="Pad 3 SRA", lat=lat1, lon=lon1, radius_km=9.08, plan_date="2026-01-15")
|
|
7214
|
+
pk = ws.write_sra_packet(site["id"], actor="tester")
|
|
7215
|
+
sra_md = open(pk["paths"]["markdown"], encoding="utf-8").read()
|
|
7216
|
+
audit = [a["action"] for a in ws.audit_log()]
|
|
7217
|
+
users = Users(str(Path(wsp, "users.json"))); users.add("op", "operator-pass-1", "operator")
|
|
7218
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
7219
|
+
base_url = svc.url.rstrip("/")
|
|
7220
|
+
opener = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
7221
|
+
|
|
7222
|
+
def call(method, path, body=None):
|
|
7223
|
+
req = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
7224
|
+
req.add_header("Content-Type", "application/json"); req.add_header("X-GEA-Action", "1")
|
|
7225
|
+
try:
|
|
7226
|
+
with opener.open(req, timeout=120) as rr_:
|
|
7227
|
+
return rr_.status, json.loads(rr_.read())
|
|
7228
|
+
except urllib.error.HTTPError as e:
|
|
7229
|
+
return e.code, json.loads(e.read())
|
|
7230
|
+
try:
|
|
7231
|
+
call("POST", "/api/login", {"name": "op", "password": "operator-pass-1"})
|
|
7232
|
+
st_g, got = call("GET", f"/api/wells/{w['id']}/slip")
|
|
7233
|
+
st_s, stt = call("GET", "/api/stress")
|
|
7234
|
+
st_w, wq = call("GET", f"/api/stress/wsm?lat={lat1}&lon={lon1}")
|
|
7235
|
+
st_d, dec = call("POST", "/api/stress", {"sv_psi_ft": 1.05, "shmin_psi_ft": 0.65, "shmax_psi_ft": 0.95, "gradients_source": "api", "shmax_azimuth_deg": 95.0, "azimuth_source": "api"})
|
|
7236
|
+
st_bad = call("POST", "/api/stress", {"sv_psi_ft": 1.0, "shmin_psi_ft": 0.9, "shmax_psi_ft": 0.5, "gradients_source": "x"})[0]
|
|
7237
|
+
st_p, wrote = call("POST", f"/api/wells/{w['id']}/slip", {"delta_pp_psi": 100.0})
|
|
7238
|
+
import base64 as _b64
|
|
7239
|
+
st_m, mp = call("POST", "/api/stress/map", {"citation": "again", "file": {"filename": "wsm.csv", "content_b64": _b64.b64encode(open(wsm_path, "rb").read()).decode()}})
|
|
7240
|
+
finally:
|
|
7241
|
+
svc.stop()
|
|
7242
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
7243
|
+
help_md = (pkg / "help" / "slip.md").read_text(encoding="utf-8")
|
|
7244
|
+
r_cli = _sp.run([sys.executable, "-m", "gea", "workspace", "--path", wsp, "--action", "slip", "--well", w["id"], "--delta-pp", "300"], capture_output=True, text=True)
|
|
7245
|
+
r_wsm = _sp.run([sys.executable, "-m", "gea", "workspace", "--path", wsp, "--action", "wsm", "--lat", str(lat1), "--lon", str(lon1)], capture_output=True, text=True)
|
|
7246
|
+
r_set = _sp.run([sys.executable, "-m", "gea", "workspace", "--path", wsp, "--action", "set-stress", "--sv", "1.05", "--shmin", "0.65", "--shmax", "0.95", "--gradients-source", "cli", "--shmax-azimuth", "92", "--azimuth-source", "cli"], capture_output=True, text=True)
|
|
7247
|
+
r_sa = _sp.run([sys.executable, "-m", "gea", "slip", "--layer", str(d / "utm_faults.zip"), "--feature-kind", "fault", "--lat", str(lat1), "--lon", str(lon1), "--depth-ft", "9000", "--sv", "1.05", "--shmin", "0.65", "--shmax", "0.95",
|
|
7248
|
+
"--wsm", wsm_path, "--delta-pp", "300"], capture_output=True, text=True)
|
|
7249
|
+
sec2e = sra_md.split("Slip tendency on the mapped faults, from the declared stress state")[1].split("## 2d")[0] if "Slip tendency on the mapped faults" in sra_md else ""
|
|
7250
|
+
c3 = {
|
|
7251
|
+
"refusals_in_order": s0["status"] == "NO SURFACE POSITION" and s1["status"] == "NO STRESS STATE" and no_src and "source" in no_src and s2["status"] == "NO FAULT LAYER"
|
|
7252
|
+
and bad_fk and "'fault' or 'fold'" in bad_fk and s3["status"] == "NO SHMAX AZIMUTH" and "add-stress-map" in s3["note"],
|
|
7253
|
+
"from_the_map": s4["status"] == "OK" and abs(s4["shmax_azimuth_deg"] - 80.25) < 0.5 and "World Stress Map records within 100 km (12" in s4["azimuth_source"] and s4["depth_ft"] == 9000.0
|
|
7254
|
+
and s4["depth_how"].startswith("the midpoint") and s4["delta_pp_psi"] == 300.0 and len(s4["layers"]) == 1 and len(s4["layers"][0]["faults"]) == 2
|
|
7255
|
+
and s4["layers"][0]["faults"][0]["attrs"]["note"] == "HIGH CONFIDENCE" and s4["friction_envelope"]["min"] == 0.21 and sm["n_records"] == 14
|
|
7256
|
+
and wsm_q["n"] == 12 and wsm_q["citation"] == "WSM-shaped, the gate" and os.path.isfile(Path(wsp, "reports", "wells", w["id"], "slip.json")),
|
|
7257
|
+
"sra_section": "## 2e" in sra_md and "| SWD-1 | Gate UTM faults |" in sec2e and "62 (layer)" in sec2e and "published 725 psi (Pp2S_MPa)" in sec2e and "none from the Permian Basin" in sec2e,
|
|
7258
|
+
"audited": "stress.declare" in audit and "stress_map.add" in audit and audit.count("well.slip") >= 4,
|
|
7259
|
+
"api": st_g == 200 and got["status"] == "OK" and st_s == 200 and stt["stress"]["gradients_source"] == "the gate's declaration" and stt["stress_map"]["n_records"] == 14
|
|
7260
|
+
and st_w == 200 and wq["n"] == 12 and st_d == 200 and dec["shmax_azimuth_deg"] == 95.0 and st_bad == 400 and st_p == 200 and wrote["delta_pp_psi"] == 100.0
|
|
7261
|
+
and wrote["shmax_azimuth_deg"] == 95.0 and st_m == 200 and mp["citation"] == "again",
|
|
7262
|
+
"page": "slipCardHtml" in page_src and "stressCardHtml" in page_src and "/api/stress/map" in page_src and "lyFK" in page_src and "'/slip'" in page_src,
|
|
7263
|
+
"cli": r_cli.returncode == 0 and "Slip tendency at 9,000 ft" in r_cli.stdout and "PAST THE FRICTION LINE" in r_cli.stdout or "BELOW THE FRICTION LINE" in r_cli.stdout
|
|
7264
|
+
and r_wsm.returncode == 0 and "12 World Stress Map record(s)" in r_wsm.stdout and r_set.returncode == 0 and "SHmax azimuth 92.0" in r_set.stdout
|
|
7265
|
+
and r_sa.returncode == 0 and "The layer publishes 725 psi to slip" in r_sa.stdout and "run from 0.21 to 0.9" in r_sa.stdout,
|
|
7266
|
+
"help": any(t["topic"] == "slip" for t in H.topics()) and not H.check("slip") and "does not say the fault exists at depth" in help_md.split("will not call a measurement")[1],
|
|
7267
|
+
}
|
|
7268
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
7269
|
+
ok(not failed3,
|
|
7270
|
+
"BT3 the workspace: NO SURFACE POSITION, NO STRESS STATE (gradients without a source refused), NO FAULT LAYER (a feature kind that is not fault or fold "
|
|
7271
|
+
"refused), NO SHMAX AZIMUTH naming the stress map, then OK with the azimuth from the map's records near the well and the depth from the declared interval; "
|
|
7272
|
+
"the SRA packet's section 2e with the layer's dip and the published value; audited; the API declares the state, takes the map, answers the records near a "
|
|
7273
|
+
"position and writes the statement; the page cards; `--action slip`, `wsm`, `set-stress` and `gea slip --wsm`; the help"
|
|
7274
|
+
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
7275
|
+
|
|
7276
|
+
|
|
7277
|
+
def section_bu_comcat(tmp: str) -> None:
|
|
7278
|
+
"""Section BU - the USGS ComCat / FDSN text export read as a catalogue, proven on two verbatim public-domain
|
|
7279
|
+
extracts kept as fixtures (the Delaware Basin, September 2026; the Youngstown 2011 sequence); the SRA seismicity
|
|
7280
|
+
on the real Youngstown sequence; the query builder; the CLI."""
|
|
7281
|
+
import subprocess as _sp
|
|
7282
|
+
from . import sra as SR
|
|
7283
|
+
from . import geodesy as GD
|
|
7284
|
+
pkg = Path(__file__).parent
|
|
7285
|
+
d = Path(tmp, "bu"); d.mkdir()
|
|
7286
|
+
fx = pkg / "fixtures"
|
|
7287
|
+
de = SR.read_catalog(str(fx / "comcat_delaware_basin_2026-09.txt"))
|
|
7288
|
+
yo = SR.read_catalog(str(fx / "comcat_youngstown_2011-2012.txt"))
|
|
7289
|
+
big = max(yo["events"], key=lambda e: e["magnitude"])
|
|
7290
|
+
url = SR.comcat_url(41.1, -80.68, 25.0, "2011-03-01", "2012-03-01", 1.5)
|
|
7291
|
+
# the Youngstown sequence against an SRA-shaped area around the Northstar 1 site: 10 km, M 2.0 threshold, plan date 2011-12-01
|
|
7292
|
+
sra = SR.define("Youngstown", 41.12, -80.69, 10.0, "2011-12-01", threshold_m=2.0, formation_boundary="base of the Knox")
|
|
7293
|
+
from datetime import datetime as _dt, timezone as _tz
|
|
7294
|
+
se = SR.seismicity(sra, yo, as_of=_dt(2012, 2, 1, tzinfo=_tz.utc))
|
|
7295
|
+
far = next(e for e in yo["events"] if e["event_id"] == "ld60004308")
|
|
7296
|
+
dist_far = GD.geodesic_m(41.12, -80.69, far["lat"], far["lon"])["distance_m"] / 1000.0
|
|
7297
|
+
r_file = _sp.run([sys.executable, "-m", "gea", "comcat", "--file", str(fx / "comcat_youngstown_2011-2012.txt"), "--lat", "41.1", "--lon", "-80.68"], capture_output=True, text=True)
|
|
7298
|
+
r_url = _sp.run([sys.executable, "-m", "gea", "comcat", "--lat", "31.42", "--lon", "-103.5", "--radius-km", "30", "--start", "2026-09-01", "--end", "2026-10-01", "--min-mag", "2.5"], capture_output=True, text=True)
|
|
7299
|
+
r_bad = _sp.run([sys.executable, "-m", "gea", "comcat", "--file", str(pkg / "catalog" / "collingwood_1_28_ks_complete.las")], capture_output=True, text=True)
|
|
7300
|
+
help_md = (pkg / "help" / "sra.md").read_text(encoding="utf-8")
|
|
7301
|
+
c1 = {
|
|
7302
|
+
"delaware": de["format"] == "fdsn-text" and de["n_events"] == 28 and de["n_skipped"] == 0 and de["contributors"] == ["tx", "us"] and de["magnitude_types"] == ["mb_lg", "ml"]
|
|
7303
|
+
and max(e["magnitude"] for e in de["events"]) == 3.4 and de["events"][0]["event_id"] == "tx2026tgiogl" and de["events"][0]["time"] == "2026-09-30T13:35:58Z"
|
|
7304
|
+
and de["events"][0]["depth_km"] == 6.2024 and "mixes scales" in de["basis"] and sum(1 for e in de["events"] if e["contributor"] == "us") == 4,
|
|
7305
|
+
"youngstown": yo["n_events"] == 9 and big["event_id"] == "ld60029101" and big["magnitude"] == 4.0 and big["time"] == "2011-12-31T20:05:01Z" and big["lat"] == 41.1215 and big["lon"] == -80.6843333
|
|
7306
|
+
and big["place"] == "3 km NW of Youngstown, Ohio" and yo["contributors"] == ["ld"],
|
|
7307
|
+
"seismicity": se["n_inside"] == 9 and se["largest"]["event_id"] == "ld60029101" and se["largest"]["magnitude"] == 4.0 and se["n_at_or_above"] == 6 and dist_far < 10.0
|
|
7308
|
+
and se["trigger"]["status"] == "TRIGGERED" and se["trigger"]["respond_by"] == "2012-01-02T20:05:01Z" and se["goal"]["clock_started"] == "2011-12-31",
|
|
7309
|
+
"url": url == "https://earthquake.usgs.gov/fdsnws/event/1/query?format=text&starttime=2011-03-01&endtime=2012-03-01&latitude=41.1000&longitude=-80.6800&maxradiuskm=25&minmagnitude=1.5&orderby=time-asc",
|
|
7310
|
+
"cli": r_file.returncode == 0 and "largest: M 4.0 ml 2011-12-31T20:05:01Z at 41.1215, -80.6843" in r_file.stdout and "1.68 km" in r_file.stdout
|
|
7311
|
+
and r_url.returncode == 0 and "maxradiuskm=30&minmagnitude=2.5" in r_url.stdout and r_bad.returncode == 1 and "not an FDSN text export" in r_bad.stdout,
|
|
7312
|
+
"help_and_fixtures": "gea comcat" in help_md and (fx / "README.md").read_text(encoding="utf-8").count("earthquake.usgs.gov/fdsnws/event/1/query") == 2,
|
|
7313
|
+
}
|
|
7314
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
7315
|
+
ok(not failed1,
|
|
7316
|
+
"BU1 the FDSN text export read as a catalogue with contributors and magnitude types: the Delaware Basin window of September 2026 (28 events, TexNet "
|
|
7317
|
+
"and NEIC, ML and mb_Lg, largest M 3.4) and the Youngstown 2011 sequence (9 events, the M 4.0 of 2011-12-31 3 km NW of Youngstown); the SRA seismicity "
|
|
7318
|
+
"on the real sequence inside a 10 km area (six at or above M 2.0, the M 4.0 TRIGGERED, the goal clock from 2011-12-31); the query builder; `gea comcat --file` with distances and `--lat --lon --start --end` printing the query; "
|
|
7319
|
+
"a LAS refused; the help and the fixtures' provenance"
|
|
7320
|
+
+ (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
7321
|
+
|
|
7322
|
+
|
|
7075
7323
|
def main() -> int:
|
|
7076
7324
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
7077
7325
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -7146,6 +7394,8 @@ def main() -> int:
|
|
|
7146
7394
|
section_bq_field_ports(tmp)
|
|
7147
7395
|
section_br_logs_historian(tmp)
|
|
7148
7396
|
section_bs_catalog(tmp)
|
|
7397
|
+
section_bt_slip(tmp)
|
|
7398
|
+
section_bu_comcat(tmp)
|
|
7149
7399
|
if _FAILS:
|
|
7150
7400
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
7151
7401
|
for f in _FAILS:
|
|
@@ -1680,6 +1680,33 @@ def sra_packet_report(pk: dict, evaluated_at: Optional[datetime] = None, program
|
|
|
1680
1680
|
'arithmetic shown, and the declared depth tier (shallow or deep by the base the plan names) is CONSISTENT with the map, INCONSISTENT, or '
|
|
1681
1681
|
'NOT RESOLVED. A contour map is read, not interpolated; the completion report is the record of the interval.'],
|
|
1682
1682
|
[Table(['Well', 'Status', 'Declared interval', 'Against the mapped tops', 'Depth tier against the map'], irows, 'Interval against the tops')]))
|
|
1683
|
+
slrows = []
|
|
1684
|
+
sl_paras = []
|
|
1685
|
+
for wid, sl in (pk.get('slip') or {}).items():
|
|
1686
|
+
if sl.get('status') != 'OK':
|
|
1687
|
+
slrows.append([wid, '-', '-', sl.get('status'), '-', '-', '-', (sl.get('note') or '')[:160]])
|
|
1688
|
+
continue
|
|
1689
|
+
if not sl_paras:
|
|
1690
|
+
sl_paras.append(f"Stress state: {sl['lines'][0]}" if sl.get('lines') else '')
|
|
1691
|
+
for lay in sl.get('layers', []):
|
|
1692
|
+
for fr in lay.get('faults', [])[:12]:
|
|
1693
|
+
w_, b_ = fr['worst'], fr['best']
|
|
1694
|
+
pub = fr.get('published') or {}
|
|
1695
|
+
slrows.append([wid, lay.get('layer_display') or lay.get('layer_id'), fr.get('name') or fr.get('type') or f"trace {fr['index']}", f"{fr['distance_km']:.2f} km / strike {fr['strike_deg']:g}",
|
|
1696
|
+
f"{w_['dip_deg']:g}" + (' (layer)' if fr.get('dip_source') == 'the layer' else ' (declared)'),
|
|
1697
|
+
f"{b_['Ts_injection']:.2f}-{w_['Ts_injection']:.2f}", f"{w_['margin_after_injection_psi']:,.0f} to {b_['margin_after_injection_psi']:,.0f}",
|
|
1698
|
+
(w_['status'] + (f"; published {pub['pressure_to_slip_psi']:,.0f} psi ({pub['field']})" if pub else ''))[:160]])
|
|
1699
|
+
if slrows:
|
|
1700
|
+
env = next((sl.get('friction_envelope') for sl in pk['slip'].values() if sl.get('friction_envelope')), None)
|
|
1701
|
+
secs.append(Section('2e', 'Slip tendency on the mapped faults, from the declared stress state', [
|
|
1702
|
+
'For each well inside the area, the mapped fault traces within the radius against the stress state the site declared - the three gradients and the '
|
|
1703
|
+
'ambient pore pressure, the SHmax azimuth from the declaration or from the World Stress Map records near the well - at the depth of the declared '
|
|
1704
|
+
'interval and the pore-pressure increase the plan is judged at: the shear and effective normal stress on each plane, the slip tendency, and the '
|
|
1705
|
+
'pore-pressure increase that would bring the plane to the friction line (negative: past it under these inputs). The strike comes from the map; '
|
|
1706
|
+
'the dip from the layer when it states one, otherwise the declared range; the friction coefficient as declared. Where a layer publishes its own '
|
|
1707
|
+
'pressure-to-slip (BEG/TexNet Hennings et al. 2021), that number is printed beside this arithmetic. A statement on declared inputs, not a probability '
|
|
1708
|
+
'and not a verdict.'] + sl_paras + ([env['statement']] if env else []),
|
|
1709
|
+
[Table(['Well', 'Layer', 'Fault', 'Distance / strike', 'Dip', 'Ts (after)', 'Pressure to slip after (psi)', 'Worst case'], slrows[:120], 'Slip tendency')]))
|
|
1683
1710
|
ef = pk.get('events_faults') or []
|
|
1684
1711
|
if ef:
|
|
1685
1712
|
paras = ['The catalogue events inside the area, each against the mapped fault traces of every structure layer: the nearest trace to the epicentre by '
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# fixtures
|
|
2
|
+
|
|
3
|
+
Small, verbatim, public-domain extracts kept so the gate can prove a reader on real records without a network.
|
|
4
|
+
|
|
5
|
+
- `comcat_delaware_basin_2026-09.txt` - USGS ComCat, FDSN event web service text output, fetched 2026-10-12:
|
|
6
|
+
`https://earthquake.usgs.gov/fdsnws/event/1/query?format=text&starttime=2026-09-01&endtime=2026-10-01&minlatitude=30.5&maxlatitude=32.5&minlongitude=-104.5&maxlongitude=-102.0&minmagnitude=2.5&orderby=time`
|
|
7
|
+
(28 events M >= 2.5, Delaware and Midland basins; contributors tx = TexNet, us = NEIC). US Government work, public domain.
|
|
8
|
+
- `comcat_youngstown_2011-2012.txt` - the same service, fetched 2026-10-12:
|
|
9
|
+
`https://earthquake.usgs.gov/fdsnws/event/1/query?format=text&starttime=2011-03-01&endtime=2012-03-01&latitude=41.1&longitude=-80.68&maxradiuskm=25&minmagnitude=1.5&orderby=time-asc`
|
|
10
|
+
(9 events within 25 km of Youngstown, Ohio: the 2011 sequence that ended with the M 4.0 of 2011-12-31; contributor ld = Lamont-Doherty). Public domain.
|