gea-program 0.25.0__tar.gz → 0.26.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.26.0}/PKG-INFO +17 -2
- {gea_program-0.25.0 → gea_program-0.26.0}/README.md +16 -1
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/__init__.py +1 -1
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/__main__.py +76 -2
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/acceptance_tests.py +204 -1
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/client_reports.py +27 -0
- gea_program-0.26.0/gea/help/slip.md +11 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/helplib.py +1 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/service.py +47 -2
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/shapefile.py +25 -5
- gea_program-0.26.0/gea/slip.py +276 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/structure.py +1 -1
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/web/app.html +44 -5
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/workspace.py +157 -3
- {gea_program-0.25.0 → gea_program-0.26.0/gea_program.egg-info}/PKG-INFO +17 -2
- {gea_program-0.25.0 → gea_program-0.26.0}/gea_program.egg-info/SOURCES.txt +2 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/pyproject.toml +1 -1
- {gea_program-0.25.0 → gea_program-0.26.0}/LICENSE +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/backup.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/bench.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/blind_harness.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/catalog_register.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/certificates.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/cli.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/config_versioning.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/conformance.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/correlation.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/dashboard.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/deviation.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/dlis.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/dnp3.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/doctor.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/earth_model.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/elevation.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/etp.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/example_register_map.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/fat_sat.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/files.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/follower.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/forward_model.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/friction_priors.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/gamma.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/geodesy.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/hartip.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/alarms.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/backup.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/catalog.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/conformance.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/data-in.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/dlis.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/doctor.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/drift.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/etp.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/files.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/historian.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/instruments.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/interval.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/month-end.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/notifications.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/osdu.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/patches.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/quality.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/seismic.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/site.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/sites.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/soak.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/sra.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/start.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/structure.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/transients.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/vibration.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/housekeeping.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/interval.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/jobs.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/live_ports.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/loadtest.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/modbus.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/model_card.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/month_end.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/notify.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/opcua_port.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/operator_app.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/osdu.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/patches.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/permits.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/piwebapi.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/ports.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/ppdm.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/project.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/quakeml.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/reconciler.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/sample_record.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/sbom.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seedlink.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/segy.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_array.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_film.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_response.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_track.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/service_life.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/shell.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/shut_in.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/sla_report.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/soak.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/sra.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/store_forward.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/strata_join.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/supervisor.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/survey_view.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/telemetry.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/tool_library.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/transient.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/vibration.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/well_assembler.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/wits0.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea/witsml.py +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.25.0 → gea_program-0.26.0}/setup.cfg +0 -0
- {gea_program-0.25.0 → gea_program-0.26.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.26.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 (365 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,21 @@ 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
|
+
### Slip tendency on the mapped faults
|
|
652
|
+
|
|
653
|
+
The stress state the site declares - the three gradients and the ambient
|
|
654
|
+
pore pressure with their source, the SHmax azimuth with its source or from
|
|
655
|
+
the World Stress Map records near the well (`add-stress-map wsm2016.csv`,
|
|
656
|
+
`wsm --lat --lon`) - resolved on every mapped fault trace within the radius
|
|
657
|
+
of a well at the depth of its declared interval: the slip tendency at the
|
|
658
|
+
ambient and the increased pore pressure, the pressure to slip, the margin
|
|
659
|
+
left after the increase, worst and best declared case. The dip comes from
|
|
660
|
+
the layer where it states one (the Hennings 2021 BEG/TexNet layers do, and
|
|
661
|
+
publish their own pressure-to-slip, printed beside this arithmetic); UTM and
|
|
662
|
+
state-plane layers are unprojected from their .prj parameters. `set-stress`,
|
|
663
|
+
`slip --well`, `gea slip`; the SRA packet's section 2e; `gea help slip`. A
|
|
664
|
+
statement on declared inputs, not a probability and not a verdict.
|
|
665
|
+
|
|
651
666
|
### The catalogue accounted for
|
|
652
667
|
|
|
653
668
|
`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 (365 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,21 @@ 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
|
+
### Slip tendency on the mapped faults
|
|
613
|
+
|
|
614
|
+
The stress state the site declares - the three gradients and the ambient
|
|
615
|
+
pore pressure with their source, the SHmax azimuth with its source or from
|
|
616
|
+
the World Stress Map records near the well (`add-stress-map wsm2016.csv`,
|
|
617
|
+
`wsm --lat --lon`) - resolved on every mapped fault trace within the radius
|
|
618
|
+
of a well at the depth of its declared interval: the slip tendency at the
|
|
619
|
+
ambient and the increased pore pressure, the pressure to slip, the margin
|
|
620
|
+
left after the increase, worst and best declared case. The dip comes from
|
|
621
|
+
the layer where it states one (the Hennings 2021 BEG/TexNet layers do, and
|
|
622
|
+
publish their own pressure-to-slip, printed beside this arithmetic); UTM and
|
|
623
|
+
state-plane layers are unprojected from their .prj parameters. `set-stress`,
|
|
624
|
+
`slip --well`, `gea slip`; the SRA packet's section 2e; `gea help slip`. A
|
|
625
|
+
statement on declared inputs, not a probability and not a verdict.
|
|
626
|
+
|
|
612
627
|
### The catalogue accounted for
|
|
613
628
|
|
|
614
629
|
`gea catalog --list` is the register of the 52 shipped public datasets: for
|
|
@@ -278,6 +278,14 @@ 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_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)")
|
|
282
|
+
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)
|
|
283
|
+
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)
|
|
284
|
+
p_sl.add_argument("--depth-ft", type=float, required=True)
|
|
285
|
+
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)
|
|
286
|
+
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")
|
|
287
|
+
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)
|
|
288
|
+
p_sl.add_argument("--json", action="store_true")
|
|
281
289
|
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
290
|
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
291
|
p_cat.add_argument("--friction", action="store_true"); p_cat.add_argument("--core", action="store_true")
|
|
@@ -319,7 +327,8 @@ def main(argv=None) -> int:
|
|
|
319
327
|
"add-seismic", "refresh-seismic", "remove-seismic", "sar-film", "refresh-all", "add-track", "refresh-track", "remove-track",
|
|
320
328
|
"seismic-dataset", "seismic-field", "add-site", "sites", "site-report", "remove-site", "rename",
|
|
321
329
|
"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"
|
|
330
|
+
"add-live-station", "live-fold", "live-run", "month-end", "add-layer", "layers", "remove-layer", "structure", "interval",
|
|
331
|
+
"set-stress", "add-stress-map", "wsm", "slip"])
|
|
323
332
|
p_ws.add_argument("--stations", type=str, nargs="+", default=None, help="add-track: two or more array station ids of this workspace")
|
|
324
333
|
p_ws.add_argument("--site", type=str, default=None, help="site-report/remove-site: the site id")
|
|
325
334
|
p_ws.add_argument("--api", type=str, default=None, help="set-well: the API number")
|
|
@@ -399,6 +408,18 @@ def main(argv=None) -> int:
|
|
|
399
408
|
p_ws.add_argument("--formation-name", type=str, default=None, help="add-layer: the formation a contours layer maps (Wolfcamp)")
|
|
400
409
|
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
410
|
p_ws.add_argument("--base-interval-ft", type=float, default=None, help="set-well: base of the disposal interval, ft")
|
|
411
|
+
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")
|
|
412
|
+
p_ws.add_argument("--sv", type=float, default=None, help="set-stress: vertical stress gradient, psi/ft")
|
|
413
|
+
p_ws.add_argument("--shmin", type=float, default=None, help="set-stress: minimum horizontal stress gradient, psi/ft")
|
|
414
|
+
p_ws.add_argument("--shmax", type=float, default=None, help="set-stress: maximum horizontal stress gradient, psi/ft")
|
|
415
|
+
p_ws.add_argument("--pp", type=float, default=None, help="set-stress: ambient pore-pressure gradient, psi/ft (hydrostatic 0.433 unless declared)")
|
|
416
|
+
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)")
|
|
417
|
+
p_ws.add_argument("--azimuth-source", type=str, default=None, help="set-stress: where the azimuth came from")
|
|
418
|
+
p_ws.add_argument("--gradients-source", type=str, default=None, help="set-stress: where the gradients came from")
|
|
419
|
+
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)")
|
|
420
|
+
p_ws.add_argument("--mu", type=float, nargs="+", default=None, help="set-stress: the friction coefficients to run (default 0.6)")
|
|
421
|
+
p_ws.add_argument("--delta-pp", type=float, default=None, help="set-stress / slip: the pore-pressure increase to judge at, psi")
|
|
422
|
+
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
423
|
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
424
|
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
425
|
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 +2116,7 @@ def main(argv=None) -> int:
|
|
|
2095
2116
|
elif a.action == "add-layer":
|
|
2096
2117
|
if not a.layer or not a.name:
|
|
2097
2118
|
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)
|
|
2119
|
+
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
2120
|
tc = ", ".join(f"{k} {v}" for k, v in list(L["type_counts"].items())[:6])
|
|
2100
2121
|
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
2122
|
+ (f"; contour value {L['value_attr']}" if L.get('value_attr') else ''))
|
|
@@ -2124,6 +2145,32 @@ def main(argv=None) -> int:
|
|
|
2124
2145
|
for line in L["lines"]:
|
|
2125
2146
|
print(" " + line)
|
|
2126
2147
|
return 0 if r["status"] == "OK" else 1
|
|
2148
|
+
elif a.action == "set-stress":
|
|
2149
|
+
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,
|
|
2150
|
+
"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)
|
|
2151
|
+
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']}); "
|
|
2152
|
+
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
|
|
2153
|
+
elif a.action == "add-stress-map":
|
|
2154
|
+
if not a.file:
|
|
2155
|
+
raise SystemExit("add-stress-map needs --file <wsm.csv>")
|
|
2156
|
+
r = ws.add_stress_map(a.file, actor=a.actor, citation=a.citation)
|
|
2157
|
+
print(f"stress map: {r['n_records']} records kept as {r['file']} (sha256 {r['sha256'][:16]})"); return 0
|
|
2158
|
+
elif a.action == "wsm":
|
|
2159
|
+
if a.lat is None or a.lon is None:
|
|
2160
|
+
raise SystemExit("wsm needs --lat --lon [--radius-km]")
|
|
2161
|
+
r = ws.wsm_at(a.lat, a.lon, a.radius_km if a.radius_km is not None else 100.0)
|
|
2162
|
+
print(r.get("statement") or f"{r['status']}: {r.get('note', '')}")
|
|
2163
|
+
for rec in r.get("records", [])[:10]:
|
|
2164
|
+
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]}")
|
|
2165
|
+
return 0 if r.get("n") else 1
|
|
2166
|
+
elif a.action == "slip":
|
|
2167
|
+
if not a.well:
|
|
2168
|
+
raise SystemExit("slip needs --well <id>")
|
|
2169
|
+
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)
|
|
2170
|
+
print(f"slip {a.well}: {r['status']}")
|
|
2171
|
+
for line in r["lines"]:
|
|
2172
|
+
print(" " + line)
|
|
2173
|
+
return 0 if r["status"] == "OK" else 1
|
|
2127
2174
|
elif a.action == "interval":
|
|
2128
2175
|
if not a.well:
|
|
2129
2176
|
raise SystemExit("interval needs --well <id>")
|
|
@@ -2304,6 +2351,33 @@ def main(argv=None) -> int:
|
|
|
2304
2351
|
stop.set()
|
|
2305
2352
|
print("etp-sim: stopped")
|
|
2306
2353
|
return 0
|
|
2354
|
+
elif a.cmd == "slip":
|
|
2355
|
+
import json as _json
|
|
2356
|
+
from . import shapefile as _SF, slip as _SL, friction_priors as _FP
|
|
2357
|
+
try:
|
|
2358
|
+
L = _SF.read(a.layer, member=a.member)
|
|
2359
|
+
except (ValueError, OSError) as e:
|
|
2360
|
+
raise SystemExit(f"slip: {e}")
|
|
2361
|
+
if a.feature_kind:
|
|
2362
|
+
L.declared_kind = a.feature_kind
|
|
2363
|
+
az, az_src = a.shmax_azimuth, "declared"
|
|
2364
|
+
if az is None and a.wsm:
|
|
2365
|
+
nb = _SL.wsm_nearby(_SL.read_wsm(a.wsm), a.lat, a.lon, 100.0)
|
|
2366
|
+
if not nb["n"]:
|
|
2367
|
+
raise SystemExit("slip: no World Stress Map record of quality A/B/C within 100 km; declare --shmax-azimuth with its source")
|
|
2368
|
+
az, az_src = nb["azimuth_mean"], nb["statement"]
|
|
2369
|
+
if az is None:
|
|
2370
|
+
raise SystemExit("slip: give --shmax-azimuth or --wsm <wsm.csv>")
|
|
2371
|
+
faults = _SL.faults_in_radius(L, a.lat, a.lon, a.radius_km)
|
|
2372
|
+
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,
|
|
2373
|
+
sources={"shmax_azimuth": az_src, "gradients": "the command line"})
|
|
2374
|
+
r["friction_envelope"] = _FP.envelope()
|
|
2375
|
+
if a.json:
|
|
2376
|
+
print(_json.dumps(r, indent=1, default=str)); return 0
|
|
2377
|
+
for line in r["lines"]:
|
|
2378
|
+
print(line)
|
|
2379
|
+
print(r["friction_envelope"].get("statement", ""))
|
|
2380
|
+
return 0
|
|
2307
2381
|
elif a.cmd == "catalog":
|
|
2308
2382
|
import json as _json
|
|
2309
2383
|
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,208 @@ 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
|
+
|
|
7075
7277
|
def main() -> int:
|
|
7076
7278
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
7077
7279
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -7146,6 +7348,7 @@ def main() -> int:
|
|
|
7146
7348
|
section_bq_field_ports(tmp)
|
|
7147
7349
|
section_br_logs_historian(tmp)
|
|
7148
7350
|
section_bs_catalog(tmp)
|
|
7351
|
+
section_bt_slip(tmp)
|
|
7149
7352
|
if _FAILS:
|
|
7150
7353
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
7151
7354
|
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,11 @@
|
|
|
1
|
+
# Slip tendency on the mapped faults
|
|
2
|
+
|
|
3
|
+
> After "how far is the nearest mapped fault" comes "how close to slipping is it, under this injection". The open method (Morris slip tendency; the fault slip potential arithmetic of Walsh and Zoback) is a stress state resolved on a fault plane: the vertical and the two horizontal stresses on the plane, the pore pressure taken off, the shear stress against the friction times the effective normal stress. This program does that arithmetic on inputs the site declares with their sources, on the strikes the map gives and the dips the layer states or the site declares, and prints beside every number what it rests on.
|
|
4
|
+
|
|
5
|
+
**The command**: `gea workspace --path C:\site --action set-stress --sv 1.05 --shmin 0.65 --shmax 0.95 --pp 0.45 --gradients-source "Lund Snee & Zoback 2018, Delaware Basin" --shmax-azimuth 92 --azimuth-source "WSM 2016 records within 100 km" --dips 60 75 90 --mu 0.6 --delta-pp 300` declares the stress state (psi/ft gradients; the sources required). `--action add-stress-map --file wsm2016.csv --citation "World Stress Map 2016, Heidbach et al., CC BY 4.0"` keeps the WSM database so `--action wsm --lat --lon --radius-km` gives the SHmax azimuth from the records near a position (the axial mean of the A/B/C-quality records with its spread and count) - and a well with no declared azimuth takes it from there, stated. `--action add-layer --name "Hennings 2021 basement faults" --layer Hennings_2021_BSMT_Pp2Slip.zip --feature-kind fault --citation "..."` brings a faults layer whose attributes do not say "fault" (every feature is declared one); a UTM or state-plane layer is unprojected from its .prj parameters. `--action slip --well <id> --radius-km 25 [--delta-pp 300] [--depth-ft 9000]` writes the statement; the well page's "Slip tendency" card and the SRA packet's section 2e carry it. `gea slip --layer faults.zip --lat --lon --depth-ft --sv --shmin --shmax --shmax-azimuth [--wsm wsm2016.csv] --delta-pp` answers for any position without a workspace.
|
|
6
|
+
|
|
7
|
+
**What it writes**: the stress state at the depth (the midpoint of the declared interval, or the depth given) and the regime its ordering implies; for every mapped fault trace within the radius: its distance, its length-weighted strike and the angle to SHmax, its dip (from the layer's `dip` attribute when present, else each declared dip), the normal and shear stress on the plane, the effective normal stress at the ambient and the increased pore pressure, the slip tendency at both, the pore-pressure increase that brings the plane to the friction line and the margin left after the declared increase - BELOW or PAST THE FRICTION LINE, for the worst and the best declared case; where the layer publishes its own pressure-to-slip (the BEG/TexNet `Pp2S_MPa` of Hennings et al. 2021, computed under their calibrated stress model), that value beside this arithmetic with the difference. The measured friction envelope from the catalogue (`gea catalog --friction`) printed last, so the declared coefficient is seen against measurements. Written to `reports/wells/<id>/slip.json`, audited as `well.slip`; the stress state as `stress.declare`, the map as `stress_map.add`.
|
|
8
|
+
|
|
9
|
+
**The number to check**: the pressure to slip after the increase on the nearest traces, and the count past the friction line in the worst case against the best - a count that flips between the two is a statement about the declared dip and friction, not about the fault. Where the layer publishes its own value, the difference column: a large one means the declared gradients are not the published model's, and the published model is the one with a paper behind it.
|
|
10
|
+
|
|
11
|
+
**What this page will not call a measurement**: a stress state - every gradient and the SHmax azimuth are declared with their source, or taken from the World Stress Map with the count and spread printed; nothing is measured here. A dip - a map carries none; the layer's own attribute or the declared range is used and named on the line. A friction coefficient for the fault - Byerlee's 0.6 unless declared, printed against the catalogue's measured 0.21-0.90. A probability of an earthquake - the method gives a pressure margin on a plane under stated assumptions; it does not say the fault exists at depth, is connected, or will slip. An attribution - an event near a trace is a distance, as the structure page says.
|
|
@@ -43,6 +43,7 @@ INDEX: List[tuple] = [
|
|
|
43
43
|
('dlis', 'The DLIS log', 'a well log as it is delivered (API RP66 V1), read as the standard lays it out: the frames, the channels, what was skipped; into the strata survey'),
|
|
44
44
|
('historian', 'The historian pull', 'an operator\'s gauge history out of the PI System through PI Web API, read-only, every value with its archive time and flags'),
|
|
45
45
|
('field-ports', 'The field ports', 'Modbus RTU on the serial line, DNP3 from the pad RTU, HART-IP from the transmitter itself - read-only, polled, with the stand-ins to rehearse against'),
|
|
46
|
+
('slip', 'Slip tendency on the mapped faults', 'the declared stress state resolved on each mapped fault around a well: the slip tendency, the pressure to slip, the World Stress Map as the SHmax source, the published Hennings values beside'),
|
|
46
47
|
('interval', 'The interval against the mapped tops', 'the declared disposal interval, subsea, beside each formation-top bracket; the depth tier against the mapped base; the catalogue events against the mapped faults'),
|
|
47
48
|
('sra', 'The Seismicity Response Area', 'the packet an operator inside an SRA puts in front of the Commission'),
|
|
48
49
|
('osdu', 'The OSDU-shaped export', 'the site as the manifest an operator\'s data platform loads'),
|
|
@@ -892,7 +892,8 @@ class App:
|
|
|
892
892
|
try:
|
|
893
893
|
return self.ws.add_layer(p, str(body.get('display') or os.path.splitext(name)[0]), actor=user['name'],
|
|
894
894
|
note=str(body.get('note', '')), citation=str(body.get('citation', '')), member=(str(body['member']) if body.get('member') else None),
|
|
895
|
-
formation=(str(body['formation']) if body.get('formation') else None), role=(str(body['role']) if body.get('role') else None)
|
|
895
|
+
formation=(str(body['formation']) if body.get('formation') else None), role=(str(body['role']) if body.get('role') else None),
|
|
896
|
+
feature_kind=(str(body['feature_kind']) if body.get('feature_kind') else None))
|
|
896
897
|
except (WorkspaceError, ValueError) as e:
|
|
897
898
|
raise ApiError(409, str(e))
|
|
898
899
|
finally:
|
|
@@ -1602,7 +1603,7 @@ def make_handler(app: App):
|
|
|
1602
1603
|
**({'live_state': app.live.state(st['id'])} if st.get('live') else {})} for st in app.ws.seismic_stations()],
|
|
1603
1604
|
'site_reports': site})
|
|
1604
1605
|
if path == '/api/layers':
|
|
1605
|
-
return self._json(200, {'layers': app.ws.layers()})
|
|
1606
|
+
return self._json(200, {'layers': app.ws.layers(), 'stress': app.ws.stress(), 'stress_map': app.ws.stress_map()})
|
|
1606
1607
|
if path == '/api/layers/members':
|
|
1607
1608
|
raise ApiError(405, 'POST the zip to list its shapefiles')
|
|
1608
1609
|
if path.startswith('/api/layers/') and path.endswith('/at'):
|
|
@@ -1628,6 +1629,20 @@ def make_handler(app: App):
|
|
|
1628
1629
|
return self._json(200, app.ws.well_interval(wid, float(qs.get('radius_km', ['50'])[0]), actor='page', write=False))
|
|
1629
1630
|
except WorkspaceError as e:
|
|
1630
1631
|
raise ApiError(404, str(e))
|
|
1632
|
+
if path.startswith('/api/wells/') and path.endswith('/slip'):
|
|
1633
|
+
wid = path[len('/api/wells/'):-len('/slip')]
|
|
1634
|
+
try:
|
|
1635
|
+
return self._json(200, app.ws.well_slip(wid, float(qs.get('radius_km', ['25'])[0]), actor='page', write=False))
|
|
1636
|
+
except WorkspaceError as e:
|
|
1637
|
+
raise ApiError(404, str(e))
|
|
1638
|
+
if path == '/api/stress':
|
|
1639
|
+
return self._json(200, {'stress': app.ws.stress(), 'stress_map': app.ws.stress_map()})
|
|
1640
|
+
if path == '/api/stress/wsm':
|
|
1641
|
+
try:
|
|
1642
|
+
lat, lon = float(qs['lat'][0]), float(qs['lon'][0]); rad = float(qs.get('radius_km', ['100'])[0])
|
|
1643
|
+
except (KeyError, ValueError):
|
|
1644
|
+
raise ApiError(400, 'lat and lon are needed')
|
|
1645
|
+
return self._json(200, app.ws.wsm_at(lat, lon, rad))
|
|
1631
1646
|
if path == '/api/seismic/live':
|
|
1632
1647
|
from .seedlink import EXAMPLE_CONFIG as _SLX
|
|
1633
1648
|
return self._json(200, {'stations': app.live.states(), 'example_config': _SLX})
|
|
@@ -1815,6 +1830,36 @@ def make_handler(app: App):
|
|
|
1815
1830
|
return self._json(200, app.ws.well_interval(wid, float((body or {}).get('radius_km') or 50.0), actor=user['name']))
|
|
1816
1831
|
except WorkspaceError as e:
|
|
1817
1832
|
raise ApiError(404, str(e))
|
|
1833
|
+
if path.startswith('/api/wells/') and path.endswith('/slip'):
|
|
1834
|
+
App.require(user, 'operator')
|
|
1835
|
+
wid = path[len('/api/wells/'):-len('/slip')]
|
|
1836
|
+
b = body or {}
|
|
1837
|
+
try:
|
|
1838
|
+
return self._json(200, app.ws.well_slip(wid, float(b.get('radius_km') or 25.0), delta_pp_psi=(float(b['delta_pp_psi']) if b.get('delta_pp_psi') is not None else None),
|
|
1839
|
+
depth_ft=(float(b['depth_ft']) if b.get('depth_ft') is not None else None), actor=user['name']))
|
|
1840
|
+
except WorkspaceError as e:
|
|
1841
|
+
raise ApiError(404, str(e))
|
|
1842
|
+
if path == '/api/stress':
|
|
1843
|
+
App.require(user, 'operator')
|
|
1844
|
+
try:
|
|
1845
|
+
return self._json(200, app.ws.set_stress(body or {}, actor=user['name']))
|
|
1846
|
+
except WorkspaceError as e:
|
|
1847
|
+
raise ApiError(400, str(e))
|
|
1848
|
+
if path == '/api/stress/map':
|
|
1849
|
+
App.require(user, 'operator')
|
|
1850
|
+
f = (body or {}).get('file') or {}
|
|
1851
|
+
tmp_dir = os.path.join(app.ws.path, 'jobs', '_uploads', secrets.token_hex(4))
|
|
1852
|
+
os.makedirs(tmp_dir, exist_ok=True)
|
|
1853
|
+
try:
|
|
1854
|
+
p_ = os.path.join(tmp_dir, 'wsm.csv')
|
|
1855
|
+
with open(p_, 'wb') as fh:
|
|
1856
|
+
fh.write(base64.b64decode(f.get('content_b64') or ''))
|
|
1857
|
+
try:
|
|
1858
|
+
return self._json(200, app.ws.add_stress_map(p_, actor=user['name'], citation=str((body or {}).get('citation', ''))))
|
|
1859
|
+
except WorkspaceError as e:
|
|
1860
|
+
raise ApiError(400, str(e))
|
|
1861
|
+
finally:
|
|
1862
|
+
shutil.rmtree(tmp_dir, ignore_errors=True)
|
|
1818
1863
|
if path.startswith('/api/wells/') and path.endswith('/declare'):
|
|
1819
1864
|
App.require(user, 'operator')
|
|
1820
1865
|
wid = path[len('/api/wells/'):-len('/declare')]
|