gea-program 0.41.0__tar.gz → 0.42.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.41.0 → gea_program-0.42.0}/PKG-INFO +15 -1
- {gea_program-0.41.0 → gea_program-0.42.0}/README.md +14 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/__init__.py +1 -1
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/__main__.py +82 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/acceptance_tests.py +209 -1
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/declarations.py +52 -2
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/fixtures/README.md +6 -0
- gea_program-0.42.0/gea/fixtures/comcat_mahoning_1990-2026.txt +22 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/declare.md +3 -3
- gea_program-0.42.0/gea/help/opseis.md +13 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/helplib.py +2 -1
- gea_program-0.42.0/gea/op_seismicity.py +625 -0
- gea_program-0.42.0/gea/reference/mahoning_example.json +48 -0
- gea_program-0.42.0/gea/reference/seismicity_protocols.json +95 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/service.py +43 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/web/app.html +91 -1
- {gea_program-0.41.0 → gea_program-0.42.0}/gea_program.egg-info/PKG-INFO +15 -1
- {gea_program-0.41.0 → gea_program-0.42.0}/gea_program.egg-info/SOURCES.txt +5 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/pyproject.toml +1 -1
- {gea_program-0.41.0 → gea_program-0.42.0}/LICENSE +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/backup.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/bench.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/blind_harness.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog_map.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/catalog_register.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/certificates.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/cli.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/client_reports.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/config_versioning.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/conformance.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/control_room.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/correlation.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/dashboard.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/deviation.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/dlis.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/dnp3.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/doctor.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/drill_string.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/earth_model.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/economics.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/edr.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/elevation.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/etp.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/example_register_map.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/fat_sat.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/files.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/follower.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/forward_model.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/friction_priors.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/gamma.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/geodesy.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/hartip.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/alarms.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/backup.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/catalog.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/charts.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/conformance.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/control-room.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/data-in.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/dlis.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/doctor.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/drift.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/economics.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/edr.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/etp.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/files.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/historian.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/instruments.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/interval.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/map.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/month-end.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/notifications.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/osdu.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/patches.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/quality.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/seismic.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/setup.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/simulation.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/site.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/sites.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/slip.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/soak.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/sra.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/start.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/structure.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/tools.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/transients.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/vibration.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/well-report.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/help/well3d.md +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/housekeeping.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/interval.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/jobs.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/live_ports.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/loadtest.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/modbus.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/model_card.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/month_end.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/notify.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/opcua_port.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/operator_app.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/osdu.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/patches.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/penetrator.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/permits.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/piwebapi.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/ports.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/ppdm.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/project.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/quakeml.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reconciler.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/sample_record.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/sbom.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seedlink.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/segy.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_array.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_film.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_response.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_track.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/series_cache.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/service_life.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/shapefile.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/shell.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/shut_in.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/simulation.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/site_map.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/sla_report.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/slip.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/soak.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/sra.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/store_forward.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/strata_join.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/structure.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/supervisor.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/survey_view.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/telemetry.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/tool_library.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/transient.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/vibration.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/well3d.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/well_assembler.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/well_report.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/wits0.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/witsml.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea/workspace.py +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.41.0 → gea_program-0.42.0}/setup.cfg +0 -0
- {gea_program-0.41.0 → gea_program-0.42.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.42.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
|
|
@@ -648,6 +648,20 @@ 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
|
+
### Operations and seismicity
|
|
652
|
+
|
|
653
|
+
The Operations & Seismicity tab sets each well's drilling, completion and
|
|
654
|
+
disposal windows against the earthquake catalogue around it: every event
|
|
655
|
+
within the screening distance by its distance and time, whether it fell
|
|
656
|
+
during an operation or in the months after, what the rig was doing when a
|
|
657
|
+
drilling record covers it, the level a regulator's protocol would reach
|
|
658
|
+
(British Columbia, Alberta, Oklahoma, Ohio, Texas, each with its
|
|
659
|
+
document), and the exact test of whether the rate near the well is higher
|
|
660
|
+
while it works than in the rest of the record. The Mahoning Valley, Ohio -
|
|
661
|
+
the 2011 Youngstown sequence against the Northstar 1 injection year, the
|
|
662
|
+
2014 Poland Township events against a stimulation - ships as a worked
|
|
663
|
+
example from the public record. `gea seismicity`, `gea help opseis`.
|
|
664
|
+
|
|
651
665
|
### The declarations sheet
|
|
652
666
|
|
|
653
667
|
Everything the operator declares about a pad comes in from one spreadsheet:
|
|
@@ -609,6 +609,20 @@ 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
|
+
### Operations and seismicity
|
|
613
|
+
|
|
614
|
+
The Operations & Seismicity tab sets each well's drilling, completion and
|
|
615
|
+
disposal windows against the earthquake catalogue around it: every event
|
|
616
|
+
within the screening distance by its distance and time, whether it fell
|
|
617
|
+
during an operation or in the months after, what the rig was doing when a
|
|
618
|
+
drilling record covers it, the level a regulator's protocol would reach
|
|
619
|
+
(British Columbia, Alberta, Oklahoma, Ohio, Texas, each with its
|
|
620
|
+
document), and the exact test of whether the rate near the well is higher
|
|
621
|
+
while it works than in the rest of the record. The Mahoning Valley, Ohio -
|
|
622
|
+
the 2011 Youngstown sequence against the Northstar 1 injection year, the
|
|
623
|
+
2014 Poland Township events against a stimulation - ships as a worked
|
|
624
|
+
example from the public record. `gea seismicity`, `gea help opseis`.
|
|
625
|
+
|
|
612
626
|
### The declarations sheet
|
|
613
627
|
|
|
614
628
|
Everything the operator declares about a pad comes in from one spreadsheet:
|
|
@@ -539,6 +539,33 @@ def main(argv=None) -> int:
|
|
|
539
539
|
p_pn.add_argument("--actor", type=str, default="cli")
|
|
540
540
|
p_pn.add_argument("--json", action="store_true")
|
|
541
541
|
|
|
542
|
+
p_os = sub.add_parser("seismicity", help="operations and seismicity: each well's drilling, completion and disposal windows against the earthquake catalogue around it - the events during and after each, the levels a regulator's protocol would reach, and the rate during operations against the rest of the record; the Mahoning Valley worked example")
|
|
543
|
+
p_os.add_argument("--workspace", type=str, default=None)
|
|
544
|
+
p_os.add_argument("--scene", type=str, default=None, choices=("workspace", "mahoning"), help="your wells (the default with --workspace) or the public worked example")
|
|
545
|
+
p_os.add_argument("--protocol", type=str, default=None, help="a protocol id (--protocols lists them)")
|
|
546
|
+
p_os.add_argument("--radius-km", type=float, default=None, help="the association radius (default 5 km)")
|
|
547
|
+
p_os.add_argument("--screen-km", type=float, default=None, help="the screening distance (default 20 km)")
|
|
548
|
+
p_os.add_argument("--post-days", type=float, default=None, help="the association window after an operation ends (default 90 days)")
|
|
549
|
+
p_os.add_argument("--mc", type=float, default=None, help="the completeness magnitude counted in the rate (default the catalogue's minimum)")
|
|
550
|
+
p_os.add_argument("--set", action="store_true", help="keep --protocol, --radius-km, --screen-km, --post-days and --mc as this workspace's settings")
|
|
551
|
+
p_os.add_argument("--protocols", action="store_true", help="list the protocols and their levels")
|
|
552
|
+
p_os.add_argument("--query", action="store_true", help="print the ComCat query for the workspace's wells (run it where the catalogue service is reachable)")
|
|
553
|
+
p_os.add_argument("--attach", type=str, default=None, help="a catalogue export to attach (with --start --end --min-magnitude --lat --lon --catalog-radius-km --source)")
|
|
554
|
+
p_os.add_argument("--start", type=str, default=None)
|
|
555
|
+
p_os.add_argument("--end", type=str, default=None)
|
|
556
|
+
p_os.add_argument("--min-magnitude", type=float, default=None)
|
|
557
|
+
p_os.add_argument("--lat", type=float, default=None)
|
|
558
|
+
p_os.add_argument("--lon", type=float, default=None)
|
|
559
|
+
p_os.add_argument("--catalog-radius-km", type=float, default=None)
|
|
560
|
+
p_os.add_argument("--source", type=str, default="")
|
|
561
|
+
p_os.add_argument("--declare-op", action="store_true", help="declare an operation window (with --well --kind --start [--end] --source)")
|
|
562
|
+
p_os.add_argument("--well", type=str, default=None)
|
|
563
|
+
p_os.add_argument("--kind", type=str, default=None, choices=("drilling", "completion", "disposal", "injection", "other"))
|
|
564
|
+
p_os.add_argument("--remove-op", type=str, default=None)
|
|
565
|
+
p_os.add_argument("--remove-catalog", type=str, default=None)
|
|
566
|
+
p_os.add_argument("--actor", type=str, default="cli")
|
|
567
|
+
p_os.add_argument("--json", action="store_true")
|
|
568
|
+
|
|
542
569
|
p_sm = sub.add_parser("simulation", help="the simulation in words: the scenes (Volve 15/9-F-4 with its logs and interpretation, Volve F-5 and F-10 on the survey clock, every drilling-recorder well), and what the record says at a depth (the Simulation tab replays it)")
|
|
543
570
|
p_sm.add_argument("--workspace", type=str, default=None)
|
|
544
571
|
p_sm.add_argument("--scene", type=str, default=None, help="e.g. volve-f4, or well:Well-30636033")
|
|
@@ -2144,6 +2171,61 @@ def main(argv=None) -> int:
|
|
|
2144
2171
|
raise SystemExit(f"penetrator: {e.args[0] if e.args else e}")
|
|
2145
2172
|
print(_json.dumps(p, default=str) if a.json else _PN.text(p))
|
|
2146
2173
|
return 0
|
|
2174
|
+
elif a.cmd == "seismicity":
|
|
2175
|
+
import json as _json
|
|
2176
|
+
from . import op_seismicity as _OS
|
|
2177
|
+
from .cli import _safe_stdout
|
|
2178
|
+
from .workspace import Workspace, WorkspaceError
|
|
2179
|
+
_safe_stdout()
|
|
2180
|
+
if a.protocols:
|
|
2181
|
+
for p_ in _OS.protocols()["protocols"]:
|
|
2182
|
+
print(f"{p_['id']}: {p_['name']} - within {p_['radius_km'] if p_['radius_km'] is not None else 'the permit distance'} km of {p_['radius_from']}; covers {', '.join(p_['applies_to'])}")
|
|
2183
|
+
for lv in p_["levels"]:
|
|
2184
|
+
print(f" M {lv['m']:g}{' (' + lv['condition'] + ')' if lv.get('condition') else ''}: {lv['action']}")
|
|
2185
|
+
print(f" {p_['document']} - {p_['url']}{' (a secondary summary)' if p_['source_kind'] == 'secondary' else ''}")
|
|
2186
|
+
return 0
|
|
2187
|
+
ws = None
|
|
2188
|
+
if a.workspace:
|
|
2189
|
+
try:
|
|
2190
|
+
ws = Workspace(a.workspace)
|
|
2191
|
+
except WorkspaceError as e:
|
|
2192
|
+
raise SystemExit(f"seismicity: {e}")
|
|
2193
|
+
try:
|
|
2194
|
+
if a.attach:
|
|
2195
|
+
if ws is None:
|
|
2196
|
+
raise SystemExit("seismicity: --attach needs --workspace")
|
|
2197
|
+
with open(a.attach, "rb") as f:
|
|
2198
|
+
r = _OS.attach_catalog(ws, a.actor, os.path.basename(a.attach), f.read(), a.start, a.end, a.min_magnitude, a.lat, a.lon, a.catalog_radius_km, a.source)
|
|
2199
|
+
print(f"attached {r['file']}: {r['n_events']} event(s), {r['start']} to {r['end']}, M >= {r['min_magnitude']:g}")
|
|
2200
|
+
return 0
|
|
2201
|
+
if a.declare_op:
|
|
2202
|
+
if ws is None or not a.well or not a.kind:
|
|
2203
|
+
raise SystemExit("seismicity: --declare-op needs --workspace, --well and --kind")
|
|
2204
|
+
r = _OS.save_operation(ws, a.actor, a.well, a.kind, a.start, a.end, a.source)
|
|
2205
|
+
print(f"declared {r['id']}: {r['kind']} on {r['well_id']}, {r['start']} to {r['end'] or 'open'}")
|
|
2206
|
+
return 0
|
|
2207
|
+
if a.remove_op:
|
|
2208
|
+
_OS.remove_operation(ws, a.actor, a.remove_op); print(f"removed {a.remove_op}"); return 0
|
|
2209
|
+
if a.remove_catalog:
|
|
2210
|
+
_OS.remove_catalog(ws, a.actor, a.remove_catalog); print(f"removed {a.remove_catalog}"); return 0
|
|
2211
|
+
over = {k: v for k, v in (("protocol", a.protocol), ("radius_km", a.radius_km), ("screen_km", a.screen_km), ("post_days", a.post_days), ("mc", a.mc)) if v is not None}
|
|
2212
|
+
if a.set:
|
|
2213
|
+
if ws is None:
|
|
2214
|
+
raise SystemExit("seismicity: --set needs --workspace")
|
|
2215
|
+
s_ = _OS.set_settings(ws, a.actor, over.get("protocol"), over.get("radius_km"), over.get("screen_km"), over.get("post_days"), over.get("mc"))
|
|
2216
|
+
print("settings: " + ", ".join(f"{k} {v}" for k, v in s_.items()))
|
|
2217
|
+
return 0
|
|
2218
|
+
if over.get("protocol"):
|
|
2219
|
+
_OS.protocol(over["protocol"])
|
|
2220
|
+
r = _OS.page(ws, a.scene or ("workspace" if ws is not None else "mahoning"), over or None)
|
|
2221
|
+
except (ValueError, KeyError, OSError) as e:
|
|
2222
|
+
raise SystemExit(f"seismicity: {e.args[0] if e.args else e}")
|
|
2223
|
+
if a.query:
|
|
2224
|
+
q = r.get("query")
|
|
2225
|
+
print(q["url"] if q else "no well of the workspace has a surface position yet: declare one first")
|
|
2226
|
+
return 0
|
|
2227
|
+
print(_json.dumps(r, default=str) if a.json else _OS.text(r))
|
|
2228
|
+
return 0
|
|
2147
2229
|
elif a.cmd == "simulation":
|
|
2148
2230
|
import json as _json
|
|
2149
2231
|
from . import simulation as _SIM
|
|
@@ -7310,7 +7310,7 @@ def section_bu_comcat(tmp: str) -> None:
|
|
|
7310
7310
|
"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",
|
|
7311
7311
|
"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
|
|
7312
7312
|
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,
|
|
7313
|
-
"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") ==
|
|
7313
|
+
"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") == 3,
|
|
7314
7314
|
}
|
|
7315
7315
|
failed1 = [k for k, v in c1.items() if not v]
|
|
7316
7316
|
ok(not failed1,
|
|
@@ -9703,6 +9703,213 @@ def section_cj_declarations(tmp: str) -> None:
|
|
|
9703
9703
|
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
9704
9704
|
|
|
9705
9705
|
|
|
9706
|
+
def section_ck_operations_seismicity(tmp: str) -> None:
|
|
9707
|
+
"""Section CK - operations and seismicity: the Mahoning Valley worked example from the public record (the 2011
|
|
9708
|
+
Youngstown sequence against Northstar 1's injection year, the 2014 Poland Township events against the Poland-CLL2
|
|
9709
|
+
stimulation, the ComCat catalogue 1990-2026), the protocols each event reaches by the catalogue's magnitude, the
|
|
9710
|
+
exact conditional rate test against its hand value; a labelled synthetic pad; a workspace with a drilling record,
|
|
9711
|
+
an attached catalogue and declared operations; the sheet, the API, the CLI, the tab and the help page."""
|
|
9712
|
+
import http.cookiejar
|
|
9713
|
+
import subprocess as _sp
|
|
9714
|
+
import urllib.request
|
|
9715
|
+
import urllib.error
|
|
9716
|
+
import base64 as _b64
|
|
9717
|
+
from math import comb
|
|
9718
|
+
from . import declarations as DC
|
|
9719
|
+
from . import drill_string as DS
|
|
9720
|
+
from . import helplib as H
|
|
9721
|
+
from . import op_seismicity as OS
|
|
9722
|
+
from .workspace import Workspace
|
|
9723
|
+
from .service import Service, Users
|
|
9724
|
+
pkg = Path(__file__).parent
|
|
9725
|
+
d = Path(tmp, "ck"); d.mkdir()
|
|
9726
|
+
|
|
9727
|
+
# -- CK1 the worked example ------------------------------------------------------------------------------------
|
|
9728
|
+
ex = OS.page(None, "mahoning")
|
|
9729
|
+
W = {w["id"]: w for w in ex["wells"]}
|
|
9730
|
+
ns, pl = W["northstar-1"], W["poland-cll2"]
|
|
9731
|
+
ev_ns = {e["event_id"]: e for e in ns["events"]}
|
|
9732
|
+
ev_pl = {e["event_id"]: e for e in pl["events"]}
|
|
9733
|
+
share = 457.0 / (457.0 + 12982.0)
|
|
9734
|
+
by_prot = {}
|
|
9735
|
+
for pid in ("ohio-odnr-2014", "oklahoma-occ-2016", "alberta-aer-so2-2015", "texas-rrc-2022", "bc-ksmma-2021"):
|
|
9736
|
+
r_ = OS.page(None, "mahoning", {"protocol": pid})
|
|
9737
|
+
by_prot[pid] = sorted((e["event_id"], e["protocol"]["highest"]["m"]) for w in r_["wells"] for e in w["protocol_events"])
|
|
9738
|
+
c1 = {
|
|
9739
|
+
"catalogue": ex["n_events"] == 21 and ex["catalog"]["start"] == "1990-01-01" and ex["catalog"]["min_magnitude"] == 1.0 and (pkg / "fixtures" / "comcat_mahoning_1990-2026.txt").is_file()
|
|
9740
|
+
and "comcat_mahoning_1990-2026.txt" in (pkg / "fixtures" / "README.md").read_text(encoding="utf-8"),
|
|
9741
|
+
"northstar": ns["rate"]["n_operations"] == 8 and ns["rate"]["n_background"] == 0 and ns["rate"]["days_operations"] == 457.0 and ns["rate"]["status"] == "HIGHER DURING OPERATIONS"
|
|
9742
|
+
and abs(ns["rate"]["p_value"] - share ** 8) / share ** 8 < 1e-4 and ns["rate"]["ratio"] is None and ns["rate"]["background_upper_95_per_year"] == round(3 / 12982.0 * 365.25, 4)
|
|
9743
|
+
and ev_ns["ld60029101"]["relation"] == "AFTER" and ev_ns["ld60029101"]["days_after_end"] == 0.8 and ev_ns["ld60029101"]["distance_km"] < 1.0
|
|
9744
|
+
and ev_ns["ld60004308"]["relation"] == "DURING" and not ev_ns["ld60004308"]["within_radius"] and ev_ns["ld60014118"]["relation"] == "AFTER",
|
|
9745
|
+
"poland": pl["rate"]["n_operations"] == 5 and pl["rate"]["n_background"] == 1 and sum(e["relation"] == "DURING" for e in pl["associated"]) == 4
|
|
9746
|
+
and ev_pl["ld60034503"]["relation"] == "AFTER" and ev_pl["ld60047703"]["relation"] == "OUTSIDE" and pl["rate"]["p_value"] < 1e-9
|
|
9747
|
+
and abs(pl["rate"]["p_value"] / sum(comb(6, k) * (96 / 13439) ** k * (1 - 96 / 13439) ** (6 - k) for k in (5, 6)) - 1) < 1e-4,
|
|
9748
|
+
"coverage": ns["coverage"]["inside"] and pl["coverage"]["inside"],
|
|
9749
|
+
"protocols": by_prot["ohio-odnr-2014"] == sorted((x, 1.0) for x in ("ld60034308", "ld60034403", "ld60034408", "ld60065316", "ld60034503"))
|
|
9750
|
+
and by_prot["oklahoma-occ-2016"] == [] and by_prot["alberta-aer-so2-2015"] == sorted((x, 2.0) for x in ("ld60034308", "ld60034408", "ld60065316"))
|
|
9751
|
+
and by_prot["texas-rrc-2022"] == [("ld60029101", 3.5)] and len(by_prot["bc-ksmma-2021"]) == 5,
|
|
9752
|
+
"record_magnitude": any("2.44" in n and "3.0" in n for n in ex["notes"]) and max(e["magnitude"] for e in pl["associated"]) == 2.44,
|
|
9753
|
+
"sources": all(p["url"].startswith("https://") and p["document"] for p in ex["protocols"]) and len(ex["protocols"]) == 5
|
|
9754
|
+
and [p["source_kind"] for p in ex["protocols"] if p["id"] == "ohio-odnr-2014"] == ["secondary"] and "Atkinson" in ex["sources"]["screen"]
|
|
9755
|
+
and "Kim" in ns["operations"][0]["source"] and "Skoumal" in pl["operations"][0]["source"],
|
|
9756
|
+
}
|
|
9757
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
9758
|
+
ok(not failed1,
|
|
9759
|
+
"CK1 the worked example from the public record: ComCat 1990-2026 within 30 km of the Mahoning Valley, 21 events; Northstar 1's eight "
|
|
9760
|
+
"events within 5 km in its injection year and the 90 days after against none in the rest, the probability equal to the share of time to "
|
|
9761
|
+
"the eighth power, the M 4.0 0.8 days after shut-in; Poland-CLL2's four during its stimulation, one the next day, one in 2016 outside; "
|
|
9762
|
+
"Ohio's 1.0 reached by all five, Oklahoma's 2.5 by none at the catalogue's ML 2.44 (the regulator's M 3.0 named), Alberta's 2.0 by "
|
|
9763
|
+
"three, Texas's 3.5 by the M 4.0 after disposal; every protocol with its document, Ohio's marked secondary"
|
|
9764
|
+
+ (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
9765
|
+
|
|
9766
|
+
# -- CK2 the arithmetic -----------------------------------------------------------------------------------------
|
|
9767
|
+
syn = OS.analyse(OS.synthetic_scene())
|
|
9768
|
+
sp = {w["id"]: w for w in syn["wells"]}["pad-1"]
|
|
9769
|
+
ev = {e["event_id"]: e for e in sp["events"]}
|
|
9770
|
+
quiet = OS.synthetic_scene()
|
|
9771
|
+
quiet["events"] = [e for e in quiet["events"] if e["event_id"].startswith("bg")]
|
|
9772
|
+
qr = {w["id"]: w for w in OS.analyse(quiet)["wells"]}["pad-1"]["rate"]
|
|
9773
|
+
one = OS.synthetic_scene()
|
|
9774
|
+
one["events"] = [e for e in one["events"] if e["event_id"].startswith("bg")] + [e for e in one["events"] if e["event_id"] == "op0"]
|
|
9775
|
+
onr = {w["id"]: w for w in OS.analyse(one)["wells"]}["pad-1"]["rate"]
|
|
9776
|
+
two = OS.synthetic_scene()
|
|
9777
|
+
two["wells"].append({"id": "pad-2", "display": "SYNTHETIC pad 2", "lat": 32.005, "lon": -102.0, "operations": [{"kind": "completion", "start": "2024-05-03", "end": "2024-05-06", "source": "s"}]})
|
|
9778
|
+
tw = {w["id"]: w for w in OS.analyse(two)["wells"]}
|
|
9779
|
+
c2 = {
|
|
9780
|
+
"binomial": abs(OS.binom_tail(3, 10, 0.2) - sum(comb(10, k) * 0.2 ** k * 0.8 ** (10 - k) for k in range(3, 11))) < 1e-12 and OS.binom_tail(0, 5, 0.3) == 1.0
|
|
9781
|
+
and OS.binom_tail(6, 5, 0.3) == 0.0 and OS.binom_tail(2, 4, 0.0) == 0.0,
|
|
9782
|
+
"synthetic": sp["rate"]["n_operations"] == 12 and sp["rate"]["status"] == "HIGHER DURING OPERATIONS" and "far" not in ev and ev["op5"]["protocol"]["highest"]["m"] == 3.0
|
|
9783
|
+
and ev["op4"]["protocol"]["highest"]["m"] == 2.0 and [c["m"] for c in ev["op4"]["protocol"]["conditional"]] == [2.2]
|
|
9784
|
+
and sp["cluster"] and len(sp["cluster"][0]["events"]) >= 5 and all(e["relation"] == "DURING" and e["operation"]["kind"] == "completion" for e in sp["associated"]),
|
|
9785
|
+
"unplaced": {w["id"]: w for w in syn["wells"]}["unplaced"]["placed"] is False and "surface position" in {w["id"]: w for w in syn["wells"]}["unplaced"]["notes"][0],
|
|
9786
|
+
"not_distinguished": qr["n_operations"] == 0 and qr["status"] == "NOT DISTINGUISHED" and onr["status"] == "NOT DISTINGUISHED" and onr["n_operations"] == 1,
|
|
9787
|
+
"also": any(x["well"] == "SYNTHETIC pad 2" for e in tw["pad-1"]["events"] for x in e["also"]) and any(x["well"] == "SYNTHETIC pad 1" for e in tw["pad-2"]["events"] for x in e["also"]),
|
|
9788
|
+
"radius": {w["id"]: w for w in OS.analyse({**OS.synthetic_scene(), "settings": {**OS.DEFAULTS, "radius_km": 1.0}})["wells"]}["pad-1"]["rate"]["n_operations"] == 6,
|
|
9789
|
+
}
|
|
9790
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
9791
|
+
ok(not failed2,
|
|
9792
|
+
"CK2 the arithmetic: the binomial tail against the sum by hand; over a labelled synthetic pad twelve events in its completion found "
|
|
9793
|
+
"higher than a twenty-year background, an event 30 km away left out, British Columbia's levels with the after-restart ones only "
|
|
9794
|
+
"conditional, its five-in-72-hours cluster found; a background alone, and one event in the window, NOT DISTINGUISHED; an event near "
|
|
9795
|
+
"two wells' operations named on both; a 1 km radius counting six; a well without a position named"
|
|
9796
|
+
+ (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
9797
|
+
|
|
9798
|
+
# -- CK3 a workspace -------------------------------------------------------------------------------------------
|
|
9799
|
+
synr = DS.synthetic_motor_record(str(d))
|
|
9800
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad CK", actor="tester")
|
|
9801
|
+
we = ws.add_well_file(synr["path"], display="SYNTHETIC EDR well", actor="tester")
|
|
9802
|
+
wf = ws.add_well_file(str(pkg / "sample_well_profile.csv"), display="SYNTHETIC frac well", actor="tester")
|
|
9803
|
+
ws.set_well(we["id"], surface={"lat": 32.0, "lon": -102.0, "datum": "NAD83"}, actor="tester")
|
|
9804
|
+
lines = ["#EventID|Time|Latitude|Longitude|Depth/km|Author|Catalog|Contributor|ContributorID|MagType|Magnitude|MagAuthor|EventLocationName",
|
|
9805
|
+
"tx1|2026-08-01T05:00:00|32.005|-102.004|4|tx|tx|tx|tx1|ml|1.9|tx|syn",
|
|
9806
|
+
"tx2|2026-08-04T05:00:00|32.012|-102.012|4|tx|tx|tx|tx2|ml|2.6|tx|syn",
|
|
9807
|
+
"tx3|2026-08-05T05:00:00|32.013|-102.011|4|tx|tx|tx|tx3|ml|3.1|tx|syn",
|
|
9808
|
+
"tx4|2020-02-01T05:00:00|32.10|-102.10|4|tx|tx|tx|tx4|ml|2.0|tx|syn"]
|
|
9809
|
+
(d / "cat.txt").write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
9810
|
+
(d / "notcat.txt").write_text("hello\nworld\n", encoding="utf-8")
|
|
9811
|
+
bad = {}
|
|
9812
|
+
for k, fn in (("kind", lambda: OS.save_operation(ws, "t", wf["id"], "fracking", "2026-08-03", None, "s")),
|
|
9813
|
+
("order", lambda: OS.save_operation(ws, "t", wf["id"], "completion", "2026-08-03", "2026-08-01", "s")),
|
|
9814
|
+
("source", lambda: OS.save_operation(ws, "t", wf["id"], "completion", "2026-08-03", None, "")),
|
|
9815
|
+
("start", lambda: OS.save_operation(ws, "t", wf["id"], "completion", "", None, "s")),
|
|
9816
|
+
("notcat", lambda: OS.attach_catalog(ws, "t", "notcat.txt", (d / "notcat.txt").read_bytes(), "2016-01-01", "2026-10-18", 1, 32, -102, 40, "s")),
|
|
9817
|
+
("circle", lambda: OS.attach_catalog(ws, "t", "cat.txt", (d / "cat.txt").read_bytes(), "2016-01-01", "2026-10-18", 1, None, -102, 40, "s")),
|
|
9818
|
+
("window", lambda: OS.attach_catalog(ws, "t", "cat.txt", (d / "cat.txt").read_bytes(), "2026-10-18", "2016-01-01", 1, 32, -102, 40, "s")),
|
|
9819
|
+
("settings", lambda: OS.set_settings(ws, "t", radius_km=30, screen_km=10)),
|
|
9820
|
+
("protocol", lambda: OS.set_settings(ws, "t", protocol_id="nope"))):
|
|
9821
|
+
try:
|
|
9822
|
+
fn(); bad[k] = False
|
|
9823
|
+
except (ValueError, KeyError):
|
|
9824
|
+
bad[k] = True
|
|
9825
|
+
sheet = ("[wells],well,lat,lon,datum\n,SYNTHETIC frac well,32.01,-102.01,NAD83\n"
|
|
9826
|
+
"[operations],well,kind,start,end,source\n,SYNTHETIC frac well,completion,2026-08-03,2026-08-08T12:00,stage log\n"
|
|
9827
|
+
"[catalogs],file,start,end,min_magnitude,lat,lon,radius_km,source\n,cat.txt,2016-01-01,2026-10-18,1.0,32.0,-102.0,40,SYNTHETIC catalogue\n")
|
|
9828
|
+
p1 = DC.apply(ws, sheet, "importer", str(d), write=True)
|
|
9829
|
+
p2 = DC.plan(ws, sheet, str(d))
|
|
9830
|
+
tp = DC.plan(ws, DC.template(ws), str(d))
|
|
9831
|
+
OS.set_settings(ws, "tester", protocol_id="bc-ksmma-2021", post_days=30)
|
|
9832
|
+
pg = OS.page(ws)
|
|
9833
|
+
WW = {w["id"]: w for w in pg["wells"]}
|
|
9834
|
+
ee = {e["event_id"]: e for e in WW[we["id"]]["events"]}
|
|
9835
|
+
ef = {e["event_id"]: e for e in WW[wf["id"]]["events"]}
|
|
9836
|
+
c3 = {
|
|
9837
|
+
"refused": all(bad.values()),
|
|
9838
|
+
"sheet": p1["applied"] and p1["counts"] == {"NEW": 3, "CHANGE": 0, "SAME": 0} and p2["counts"] == {"NEW": 0, "CHANGE": 0, "SAME": 3}
|
|
9839
|
+
and not tp["errors"] and tp["counts"]["NEW"] == 0 and tp["counts"]["CHANGE"] == 0 and len(OS.operations(ws)) == 1 and OS.catalogs(ws)[0]["n_events"] == 4,
|
|
9840
|
+
"rig": ee["tx1"]["relation"] == "DURING" and ee["tx1"]["operation"]["kind"] == "drilling" and ee["tx1"]["rig"]["state"] == "drilling"
|
|
9841
|
+
and abs(ee["tx1"]["rig"]["bottom_ft"] - 8300.0) < 1.0 and WW[we["id"]]["operations"][0]["source"].startswith("the drilling record"),
|
|
9842
|
+
"frac": ef["tx3"]["relation"] == "DURING" and ef["tx3"]["protocol"]["highest"]["m"] == 3.0 and ef["tx1"]["relation"] == "OUTSIDE"
|
|
9843
|
+
and any(x["kind"] == "drilling" for x in ef["tx1"]["also"]) and pg["settings"]["post_days"] == 30,
|
|
9844
|
+
"query": pg["query"]["url"].startswith("https://earthquake.usgs.gov/fdsnws/event/1/query?format=text") and pg["query"]["start"] == "1990-01-01",
|
|
9845
|
+
"audit": all(a in [x["action"] for x in ws.audit_log(500)] for a in ("seismicity.operation.declare", "seismicity.catalog.attach", "seismicity.settings")),
|
|
9846
|
+
}
|
|
9847
|
+
Users(str(Path(wsp, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
|
|
9848
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
9849
|
+
base_url = svc.url.rstrip("/")
|
|
9850
|
+
|
|
9851
|
+
def opener(name, pw_):
|
|
9852
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
9853
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
9854
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
9855
|
+
return o
|
|
9856
|
+
|
|
9857
|
+
def call(o, method, path, body=None):
|
|
9858
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
9859
|
+
if method == "POST":
|
|
9860
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
9861
|
+
try:
|
|
9862
|
+
with o.open(rq, timeout=120) as rr_:
|
|
9863
|
+
return rr_.status, json.loads(rr_.read())
|
|
9864
|
+
except urllib.error.HTTPError as e:
|
|
9865
|
+
return e.code, json.loads(e.read())
|
|
9866
|
+
try:
|
|
9867
|
+
V, O = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
|
|
9868
|
+
s_w, wj = call(V, "GET", "/api/opseis")
|
|
9869
|
+
s_m, mj = call(V, "GET", "/api/opseis?scene=mahoning&protocol=texas-rrc-2022&radius_km=10")
|
|
9870
|
+
s_x, _ = call(V, "GET", "/api/opseis?scene=nope")
|
|
9871
|
+
s_n, _ = call(V, "GET", "/api/opseis?radius_km=abc")
|
|
9872
|
+
s_vo, _ = call(V, "POST", "/api/opseis/operation", {"well_id": wf["id"], "kind": "disposal", "start": "2026-09-01", "source": "s"})
|
|
9873
|
+
s_oo, oo = call(O, "POST", "/api/opseis/operation", {"well_id": wf["id"], "kind": "disposal", "start": "2026-09-01", "source": "s"})
|
|
9874
|
+
s_ob, _ = call(O, "POST", "/api/opseis/operation", {"well_id": "nope", "kind": "disposal", "start": "2026-09-01", "source": "s"})
|
|
9875
|
+
s_or, _ = call(O, "POST", "/api/opseis/operation/remove", {"op_id": oo.get("id", "")})
|
|
9876
|
+
s_or2, _ = call(O, "POST", "/api/opseis/operation/remove", {"op_id": oo.get("id", "")})
|
|
9877
|
+
s_oc, _ = call(O, "POST", "/api/opseis/catalog", {"filename": "cat2.txt", "content_b64": _b64.b64encode((d / "cat.txt").read_bytes()).decode(), "start": "2016-01-01",
|
|
9878
|
+
"end": "2026-10-18", "min_magnitude": 1, "lat": 32, "lon": -102, "radius_km": 40, "source": "s"})
|
|
9879
|
+
s_ocb, _ = call(O, "POST", "/api/opseis/catalog", {"filename": "x.txt", "content_b64": "!!", "start": "2016-01-01"})
|
|
9880
|
+
s_rc, _ = call(O, "POST", "/api/opseis/catalog/remove", {"file": "cat2.txt"})
|
|
9881
|
+
s_st, _ = call(O, "POST", "/api/opseis/settings", {"radius_km": 4})
|
|
9882
|
+
s_ac, _ = call(O, "POST", "/api/opseis/nope", {})
|
|
9883
|
+
finally:
|
|
9884
|
+
svc.stop()
|
|
9885
|
+
cli_p = _sp.run([sys.executable, "-m", "gea", "seismicity", "--protocols"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9886
|
+
cli_m = _sp.run([sys.executable, "-m", "gea", "seismicity", "--scene", "mahoning"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9887
|
+
cli_q = _sp.run([sys.executable, "-m", "gea", "seismicity", "--workspace", wsp, "--query"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9888
|
+
cli_w = _sp.run([sys.executable, "-m", "gea", "seismicity", "--workspace", wsp], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9889
|
+
cli_b = _sp.run([sys.executable, "-m", "gea", "seismicity", "--workspace", wsp, "--declare-op", "--well", wf["id"], "--kind", "completion", "--start", "2026-09-09"],
|
|
9890
|
+
capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9891
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
9892
|
+
c3.update({
|
|
9893
|
+
"api": s_w == 200 and len(wj["wells"]) == 2 and wj["scene"] == "workspace" and s_m == 200 and mj["protocol"]["id"] == "texas-rrc-2022" and mj["settings"]["radius_km"] == 10
|
|
9894
|
+
and s_x == 404 and s_n == 400 and s_vo == 403 and s_oo == 200 and s_ob == 404 and s_or == 200 and s_or2 == 404 and s_oc == 200 and s_ocb == 400
|
|
9895
|
+
and s_rc == 200 and s_st == 200 and OS.settings(ws)["radius_km"] == 4 and s_ac == 404,
|
|
9896
|
+
"cli": cli_p.returncode == 0 and "bc-ksmma-2021" in cli_p.stdout and "(after a restart)" in cli_p.stdout and cli_m.returncode == 0 and "Northstar 1" in cli_m.stdout
|
|
9897
|
+
and "probability 1.8e-12" in cli_m.stdout and cli_q.returncode == 0 and cli_q.stdout.startswith("https://earthquake.usgs.gov/")
|
|
9898
|
+
and cli_w.returncode == 0 and "rig: drilling at 8300 ft" in cli_w.stdout and cli_b.returncode != 0 and "source" in (cli_b.stderr + cli_b.stdout),
|
|
9899
|
+
"page": all(x in page_src for x in ("VIEWS.opseis", "['#/opseis', 'Operations & seismicity']", "osChart", "/api/opseis/catalog", "/api/opseis/operation",
|
|
9900
|
+
"What this page will not call a measurement", "km from the well", "the whole catalogue")),
|
|
9901
|
+
"help": any(t[0] == "opseis" for t in H.INDEX) and not H.check("opseis") and H.VIEW_TOPIC.get("opseis") == "opseis",
|
|
9902
|
+
})
|
|
9903
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
9904
|
+
ok(not failed3,
|
|
9905
|
+
"CK3 a workspace: an unknown kind, an end before the start, no source, no start, a file that is no catalogue, a catalogue without its "
|
|
9906
|
+
"circle or with its window backwards, a screen narrower than the radius and an unknown protocol refused; the sheet's operations and "
|
|
9907
|
+
"catalogues written and then SAME, the template round-tripping; the drilling record's span a drilling window and the rig drilling at "
|
|
9908
|
+
"8,300 ft when an event struck; a completion's M 3.1 at British Columbia's 3.0; the ComCat query drawn around the wells; the API, the "
|
|
9909
|
+
"CLI, the tab and the help page"
|
|
9910
|
+
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
9911
|
+
|
|
9912
|
+
|
|
9706
9913
|
def main() -> int:
|
|
9707
9914
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
9708
9915
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -9794,6 +10001,7 @@ def main() -> int:
|
|
|
9794
10001
|
section_ch_simulation(tmp)
|
|
9795
10002
|
section_ci_drill_string(tmp)
|
|
9796
10003
|
section_cj_declarations(tmp)
|
|
10004
|
+
section_ck_operations_seismicity(tmp)
|
|
9797
10005
|
if _FAILS:
|
|
9798
10006
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
9799
10007
|
for f in _FAILS:
|
|
@@ -53,6 +53,11 @@ TABLES: Dict[str, dict] = {
|
|
|
53
53
|
'service_basis', 'service_source', 'fleet_id', 'note') + MOTOR_COLS,
|
|
54
54
|
'need': ('well', 'run', 'class_id'),
|
|
55
55
|
'about': "each run's components from the bit up, in order: the class, maker, model, serial, OD, length, the motor's catalogue id (`gea tools --action motors`) or - for a motor not in the catalogue - its own figures (motor_*) with their source, the service interval with its basis and source"},
|
|
56
|
+
'operations': {'cols': ('well', 'kind', 'start', 'end', 'source', 'note'), 'need': ('well', 'kind', 'start', 'source'),
|
|
57
|
+
'about': "operation windows for Operations & Seismicity: drilling, completion, disposal, injection or other, the start and end in UTC (blank end: still going), and the record it comes from"},
|
|
58
|
+
'catalogs': {'cols': ('file', 'start', 'end', 'min_magnitude', 'lat', 'lon', 'radius_km', 'source'),
|
|
59
|
+
'need': ('file', 'start', 'end', 'min_magnitude', 'lat', 'lon', 'radius_km', 'source'),
|
|
60
|
+
'about': "earthquake catalogue exports (USGS ComCat text or a TexNet CSV, a path beside this sheet) with the window, minimum magnitude and circle they were queried for"},
|
|
56
61
|
'penetrators': {'cols': ('well', 'penetrator', 'installed', 'installer', 'certified', 'certificate', 'motor', 'gauge_distance_in', 'ir_a_megohm',
|
|
57
62
|
'ir_b_megohm', 'ir_c_megohm', 'ir_test_volts', 'ir_min_megohm', 'ir_min_source', 'void_test_psi', 'void_test_minutes',
|
|
58
63
|
'void_held', 'note'),
|
|
@@ -63,8 +68,8 @@ TABLES: Dict[str, dict] = {
|
|
|
63
68
|
'need': ('well', 'source'),
|
|
64
69
|
'about': "the ESP drive's output limits and the motor nameplate, the wellhead's hazardous-area classification (e.g. Class I, Division 1), gas group, temperature class and the site's ambient range"},
|
|
65
70
|
}
|
|
66
|
-
ORDER = ('wells', 'fleet', 'rates', 'items', 'afe', 'surveys', 'runs', 'components', 'penetrators', 'esp_drives')
|
|
67
|
-
APPLY_ORDER = ('wells', 'fleet', 'rates', 'items', 'afe', 'surveys', 'runs', 'penetrators', 'esp_drives')
|
|
71
|
+
ORDER = ('wells', 'fleet', 'rates', 'items', 'afe', 'surveys', 'runs', 'components', 'penetrators', 'esp_drives', 'operations', 'catalogs')
|
|
72
|
+
APPLY_ORDER = ('wells', 'fleet', 'rates', 'items', 'afe', 'surveys', 'runs', 'penetrators', 'esp_drives', 'operations', 'catalogs')
|
|
68
73
|
|
|
69
74
|
|
|
70
75
|
class SheetError(ValueError):
|
|
@@ -482,6 +487,44 @@ def plan(ws, text: str, base_dir: str = '') -> dict:
|
|
|
482
487
|
lambda actor, wid=wid, kw=kw: PN.save_drive(ws, actor, wid, **kw))
|
|
483
488
|
guard('esp_drives', rec, b)
|
|
484
489
|
|
|
490
|
+
from . import op_seismicity as OS
|
|
491
|
+
ops_have = OS.operations(ws)
|
|
492
|
+
seen_ops = set()
|
|
493
|
+
for rec in tables.get('operations', []):
|
|
494
|
+
def b(rec=rec):
|
|
495
|
+
wid = _well_id(ws, rec['well'], wells)
|
|
496
|
+
new = OS.operation_record(ws, wid, rec.get('kind', ''), rec.get('start'), rec.get('end'), rec.get('source', ''), rec.get('note', ''))
|
|
497
|
+
key = (wid, new['kind'], new['start'])
|
|
498
|
+
if key in seen_ops:
|
|
499
|
+
raise SheetError(f"the {new['kind']} operation starting {new['start']} on {wid} is on the sheet twice")
|
|
500
|
+
seen_ops.add(key)
|
|
501
|
+
old = next((o for o in ops_have if (o['well_id'], o['kind'], o['start']) == key), None)
|
|
502
|
+
if old and (old['end'], old['source'], old['note']) == (new['end'], new['source'], new['note']):
|
|
503
|
+
add('operations', rec['_row'], wid, 'SAME', f"{new['kind']} from {new['start']} already declared")
|
|
504
|
+
return
|
|
505
|
+
add('operations', rec['_row'], wid, 'CHANGE' if old else 'NEW', f"{new['kind']} {new['start']} to {new['end'] or 'open'} ({new['source']})",
|
|
506
|
+
lambda actor, wid=wid, rec=rec, oid=(old or {}).get('id'): OS.save_operation(ws, actor, wid, rec.get('kind', ''), rec.get('start'), rec.get('end'),
|
|
507
|
+
rec.get('source', ''), rec.get('note', ''), oid))
|
|
508
|
+
guard('operations', rec, b)
|
|
509
|
+
cats_have = {c['file']: c for c in OS.catalogs(ws)}
|
|
510
|
+
for rec in tables.get('catalogs', []):
|
|
511
|
+
def b(rec=rec):
|
|
512
|
+
p = rec['file'].strip()
|
|
513
|
+
path = p if os.path.isabs(p) else os.path.join(base_dir or '.', p)
|
|
514
|
+
if not os.path.isfile(path):
|
|
515
|
+
raise SheetError(f'no catalogue file {p!r} beside the sheet' + ('' if base_dir else ' (a sheet sent through the browser carries no files: attach catalogues on the Operations & Seismicity tab or from the command line)'))
|
|
516
|
+
with open(path, 'rb') as f:
|
|
517
|
+
content = f.read()
|
|
518
|
+
new = OS.catalog_record(os.path.basename(p), content, rec['start'], rec['end'], rec['min_magnitude'], rec['lat'], rec['lon'], rec['radius_km'], rec['source'])
|
|
519
|
+
old = cats_have.get(new['file'])
|
|
520
|
+
if old and all(old.get(k) == new[k] for k in ('sha256', 'start', 'end', 'min_magnitude', 'circle', 'source')):
|
|
521
|
+
add('catalogs', rec['_row'], None, 'SAME', f"{new['file']} already attached")
|
|
522
|
+
return
|
|
523
|
+
add('catalogs', rec['_row'], None, 'CHANGE' if old else 'NEW', f"{new['file']}: {new['n_events']} event(s), {new['start']} to {new['end']}, M >= {new['min_magnitude']:g}",
|
|
524
|
+
lambda actor, p=p, content=content, rec=rec: OS.attach_catalog(ws, actor, os.path.basename(p), content, rec['start'], rec['end'], rec['min_magnitude'],
|
|
525
|
+
rec['lat'], rec['lon'], rec['radius_km'], rec['source']))
|
|
526
|
+
guard('catalogs', rec, b)
|
|
527
|
+
|
|
485
528
|
steps.sort(key=lambda s: (APPLY_ORDER.index(s['table']), s['row']))
|
|
486
529
|
counts = {k: sum(1 for s in steps if s['action'] == k) for k in ('NEW', 'CHANGE', 'SAME')}
|
|
487
530
|
return {'steps': steps, 'errors': sorted(errs, key=lambda e: int(re.match(r'row (\d+)', e).group(1)) if re.match(r'row (\d+)', e) else 0),
|
|
@@ -619,4 +662,11 @@ def template(ws) -> str:
|
|
|
619
662
|
d = rec.get('drive')
|
|
620
663
|
if d:
|
|
621
664
|
w.writerow(['', wid] + [_g(d.get(k)) if d.get(k) is not None else '' for k in TABLES['esp_drives']['cols'][1:]])
|
|
665
|
+
from . import op_seismicity as OS
|
|
666
|
+
head('operations')
|
|
667
|
+
for o in OS.operations(ws):
|
|
668
|
+
w.writerow(['', o['well_id'], o['kind'], o['start'], o['end'] or '', o['source'], o.get('note', '')])
|
|
669
|
+
head('catalogs')
|
|
670
|
+
for c in OS.catalogs(ws):
|
|
671
|
+
w.writerow(['# ' + c['file'] + ' is attached (' + str(c['n_events']) + ' events); list it here only to replace it'])
|
|
622
672
|
return buf.getvalue()
|
|
@@ -8,6 +8,12 @@ Small, verbatim, public-domain extracts kept so the gate can prove a reader on r
|
|
|
8
8
|
- `comcat_youngstown_2011-2012.txt` - the same service, fetched 2026-10-12:
|
|
9
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
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.
|
|
11
|
+
- `comcat_mahoning_1990-2026.txt` - the same service, read 2026-10-18 through the web reader as text and again as CSV, the two
|
|
12
|
+
readings compared event by event and agreeing on every id, time, position, depth and magnitude (no byte-for-byte fetch, so no hash):
|
|
13
|
+
`https://earthquake.usgs.gov/fdsnws/event/1/query?format=text&starttime=1990-01-01&endtime=2026-10-18&latitude=41.065&longitude=-80.605&maxradiuskm=30&minmagnitude=1&orderby=time-asc`
|
|
14
|
+
(21 events M >= 1.0 within 30 km of the Mahoning Valley, Ohio, 1990 to 2026: none before 2011; the 2011 Youngstown sequence; the
|
|
15
|
+
March 2014 Poland Township sequence; the April 2016 events by Bessemer, Pennsylvania; one in 2024). The Operations & Seismicity
|
|
16
|
+
worked example. Public domain.
|
|
11
17
|
- `ne_110m_coastline.json` - Natural Earth 1:110m coastline (`ne_110m_coastline`), fetched 2026-10-13 from
|
|
12
18
|
`https://github.com/nvkelso/natural-earth-vector` (geojson/ne_110m_coastline.geojson, md5 0b8f91e9d9c4fb607e61e121b5ac48fa):
|
|
13
19
|
134 lines, 5,127 points after rounding to 0.01 degree and dropping consecutive duplicates. Public domain (Natural Earth).
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#EventID|Time|Latitude|Longitude|Depth/km|Author|Catalog|Contributor|ContributorID|MagType|Magnitude|MagAuthor|EventLocationName
|
|
2
|
+
ld60004308|2011-03-17T10:53:11.670|41.126|-80.6056667|3.54|ld|ld|ld|ld60004308|ml|2.1|ld|2 km WSW of Maplewood Park, Ohio
|
|
3
|
+
ld60007303|2011-08-22T08:00:32.640|41.1303333|-80.7081667|5|ld|ld|ld|ld60007303|ml|1.87|ld|2 km SSW of Girard, Ohio
|
|
4
|
+
ld60009603|2011-09-26T01:06:10.840|41.115|-80.6823333|5|ld|ld|ld|ld60009603|ml|2.12|ld|3 km WNW of Youngstown, Ohio
|
|
5
|
+
ld60009803|2011-09-30T00:52:38.710|41.1346667|-80.6845|5|ld|ld|ld|ld60009803|ml|2.44|ld|2 km SSE of Girard, Ohio
|
|
6
|
+
ld60010908|2011-10-20T22:41:10.820|41.1253333|-80.704|6.39|ld|ld|ld|ld60010908|ml|2.04|ld|3 km S of Girard, Ohio
|
|
7
|
+
ld60012603|2011-11-25T06:47:28.250|41.124|-80.6771667|5|ld|ld|ld|ld60012603|ml|1.79|ld|3 km NW of Youngstown, Ohio
|
|
8
|
+
ld60013703|2011-12-24T06:24:58.810|41.1225|-80.7046667|5|ld|ld|ld|ld60013703|ml|2.37|ld|3 km S of Girard, Ohio
|
|
9
|
+
ld60029101|2011-12-31T20:05:01.060|41.1215|-80.6843333|5|ld|ld|ld|ld60029101|ml|4|ld|3 km NW of Youngstown, Ohio
|
|
10
|
+
ld60014118|2012-01-13T22:29:35.120|41.1245|-80.6923333|5.79|ld|ld|ld|ld60014118|ml|1.74|ld|3 km SSE of Girard, Ohio
|
|
11
|
+
ld60034308|2014-03-10T06:26:45.900|41.0103333|-80.5433333|2.54|ld|ld|ld|ld60034308|ml|2.44|ld|2 km SSW of Lowellville, Ohio
|
|
12
|
+
ld60034403|2014-03-10T06:42:44.280|41.0088333|-80.555|5|ld|ld|ld|ld60034403|ml|1.97|ld|3 km SSW of Lowellville, Ohio
|
|
13
|
+
ld60034408|2014-03-10T15:03:47.610|41.0096667|-80.53|5|ld|ld|ld|ld60034408|ml|2.16|ld|2 km S of Lowellville, Ohio
|
|
14
|
+
ld60065316|2014-03-10T15:44:06.780|41.009|-80.5316667|5|ld|ld|ld|ld60065316|ml|2.42|ld|2 km S of Lowellville, Ohio
|
|
15
|
+
ld60034503|2014-03-11T07:01:13.340|41.0025|-80.5336667|5.22|ld|ld|ld|ld60034503|ml|1.86|ld|3 km S of Lowellville, Ohio
|
|
16
|
+
ld60078511|2014-08-31T21:34:10.940|41.196|-80.7765|2.56|ld|ld|ld|ld60078511|ml|1.98|ld|Ohio
|
|
17
|
+
ld60112616|2016-04-25T04:05:25.280|41|-80.46|3|ld|ld|ld|ld60112616|ml|2.04|ld|3 km NE of Bessemer, Pennsylvania
|
|
18
|
+
ld60047603|2016-04-25T08:16:55.120|40.9888333|-80.3863333|3|ld|ld|ld|ld60047603|ml|1.76|ld|1 km W of Oakland, Pennsylvania
|
|
19
|
+
ld60047703|2016-04-25T09:03:02.690|41.0258333|-80.512|3|ld|ld|ld|ld60047703|ml|1.85|ld|2 km ESE of Lowellville, Ohio
|
|
20
|
+
ld60112636|2016-04-25T14:54:26.660|41.0031667|-80.4505|3|ld|ld|ld|ld60112636|ml|2.12|ld|4 km NE of Bessemer, Pennsylvania
|
|
21
|
+
ld60112721|2016-04-26T02:10:23.290|41.0008333|-80.4646667|3|ld|ld|ld|ld60112721|ml|1.86|ld|3 km NE of Bessemer, Pennsylvania
|
|
22
|
+
us6000p7j0|2024-11-25T05:36:04.376|40.937|-80.6673|5.159|us|us|us|us6000p7j0|ml|1.8|us|5 km NNE of Columbiana, Ohio
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
# The declarations sheet
|
|
2
2
|
|
|
3
|
-
> Everything the operator declares about a pad, in one spreadsheet: who each well is and where, its reference elevation, its directional survey, the day rates, the one-off costs and the AFE, the fleet, the drill-string runs,
|
|
3
|
+
> Everything the operator declares about a pad, in one spreadsheet: who each well is and where, its reference elevation, its directional survey, the day rates, the one-off costs and the AFE, the fleet, the drill-string runs, the ESP penetrator and drive, and the operation windows and earthquake catalogues for Operations & Seismicity. Every row is checked against the workspace before anything is written, and the same sheet can be imported again and again.
|
|
4
4
|
|
|
5
|
-
**The command**: on the Setup tab, **Download the sheet** gives this workspace's sheet - every table with its header and a line saying what it takes, already filled with what is declared - and **Check the sheet** reads a sheet saved as CSV and plans each row: NEW, CHANGE (it replaces what is declared) or SAME (already declared exactly so). One error and nothing is written; with no error, **Write** (the operator role) writes the NEW and CHANGE rows. From a terminal: `gea declare --workspace C:\site --template pad3.csv` writes the sheet; `gea declare --workspace C:\site --file pad3.csv` checks it; add `--apply` to write. A directional survey is named by its file beside the sheet, so
|
|
5
|
+
**The command**: on the Setup tab, **Download the sheet** gives this workspace's sheet - every table with its header and a line saying what it takes, already filled with what is declared - and **Check the sheet** reads a sheet saved as CSV and plans each row: NEW, CHANGE (it replaces what is declared) or SAME (already declared exactly so). One error and nothing is written; with no error, **Write** (the operator role) writes the NEW and CHANGE rows. From a terminal: `gea declare --workspace C:\site --template pad3.csv` writes the sheet; `gea declare --workspace C:\site --file pad3.csv` checks it; add `--apply` to write. A directional survey or an earthquake catalogue is named by its file beside the sheet, so those are imported from the terminal (or attached on the well page and the Operations & Seismicity tab).
|
|
6
6
|
|
|
7
|
-
**The layout**: one table after another. A table starts with a row whose first cell is its name in brackets - `[wells]`, `[fleet]`, `[rates]`, `[items]`, `[afe]`, `[surveys]`, `[runs]`, `[components]`, `[penetrators]`, `[esp_drives]` - and whose other cells name its columns in any order; its rows leave the first cell empty. A row starting with `#` is a comment. A well is named by its id or its name. A run's components are listed in `[components]` under the run's name, from the bit up; a motor names its catalogue id, or gives its own figures (`motor_rev_per_gal` ... `motor_source`). Fleet ratings are `key=value` pairs separated by `;`, lists with `/`.
|
|
7
|
+
**The layout**: one table after another. A table starts with a row whose first cell is its name in brackets - `[wells]`, `[fleet]`, `[rates]`, `[items]`, `[afe]`, `[surveys]`, `[runs]`, `[components]`, `[penetrators]`, `[esp_drives]`, `[operations]`, `[catalogs]` - and whose other cells name its columns in any order; its rows leave the first cell empty. A row starting with `#` is a comment. A well is named by its id or its name. A run's components are listed in `[components]` under the run's name, from the bit up; a motor names its catalogue id, or gives its own figures (`motor_rev_per_gal` ... `motor_source`). Fleet ratings are `key=value` pairs separated by `;`, lists with `/`.
|
|
8
8
|
|
|
9
9
|
**What it writes**: through the same functions the forms and commands use, so each declaration is audited the same way under the importing user, and one `declarations.import` line records the import. It adds and replaces; it never removes: a rate that overlaps one already declared, or a fleet tool already there with another datasheet, is an error to resolve where it lives first.
|
|
10
10
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Operations and seismicity
|
|
2
|
+
|
|
3
|
+
> Each well's operations - drilling, completion, disposal, injection - set against the earthquake catalogue around it: what happened near the well while it worked and in the months after, what each event would reach under a regulator's protocol, and whether the earthquake rate near the well differs while it works from the rest of the record. The Mahoning Valley, Ohio, ships as a worked example from the public record.
|
|
4
|
+
|
|
5
|
+
**The command**: the Operations & Seismicity tab. Choose the scene - your wells, or the worked example - and the protocol (British Columbia's Kiskatinaw order, Alberta's Subsurface Order No. 2, Oklahoma's completion notice, Ohio's 2014 permit conditions, Texas's response plan), the association radius (5 km by default), the days after an operation that still count (90) and the completeness magnitude. Each well shows its operations as bands on a time line, every event within the screening distance (20 km) as a circle by its distance from the well and sized by magnitude, the events table with the rig's state at an event during a drilling record, the protocol level each reaches, and the rate comparison. The operator declares operation windows (or the declarations sheet's `[operations]`) and attaches catalogue exports with the window, minimum magnitude and circle they were queried for (or `[catalogs]`); the program cannot reach a catalogue service itself, so the tab gives the ComCat query to open in a browser. From a terminal: `gea seismicity --workspace C:\site`; `--scene mahoning` for the example; `--protocols`; `--query`; `--attach FILE --start --end --min-magnitude --lat --lon --catalog-radius-km --source`; `--declare-op --well W --kind completion --start --end --source`; `--set` keeps the settings.
|
|
6
|
+
|
|
7
|
+
**What it writes**: `seismicity/operations.json`, `seismicity/catalogs.json` with each catalogue file kept verbatim beside it (its SHA-256 recorded), and `seismicity/settings.json` in the workspace; each declaration, attachment, removal and change of settings a line in the audit log. The protocols ship with the program (`reference/seismicity_protocols.json`), each with its document; the worked example's catalogue (`fixtures/comcat_mahoning_1990-2026.txt`) and its wells and dates (`reference/mahoning_example.json`), each with its source.
|
|
8
|
+
|
|
9
|
+
**The arithmetic**: an event's distance is the great-circle distance from the well's declared surface position (converted to WGS84). It is DURING an operation inside its window, AFTER one within the association days that follow, and OUTSIDE otherwise; an event near two wells' operations is named on both, each with the other beside it. The rate comparison counts the events at or above the completeness within the radius over the catalogue's window: n inside the operation windows (with their association days) and m outside. If one constant rate held, n would be binomial in n + m with the share of time inside; the probability of n or more is the exact conditional test for two Poisson rates. HIGHER DURING OPERATIONS means that probability is under 1 % and the rate inside is the higher; otherwise NOT DISTINGUISHED. With no event outside, the background is given as its 95 % upper bound, 3 events over its time.
|
|
10
|
+
|
|
11
|
+
**The number to check**: a distance against a map; for the worked example, Northstar 1's eight events within 5 km during its injection year and the 90 days after against none in the rest of 1990 to 2026; Poland-CLL2's four events during its stimulation and one the next day; the Poland events' ML 2.44 in ComCat against the M 3.0 the regulator and the published study give - a protocol is read against its own magnitude of record.
|
|
12
|
+
|
|
13
|
+
**What this page will not call a measurement**: a cause - a coincidence in time and place is what the record shows; the catalogue's completeness - declared (the query's minimum magnitude by default), not measured, and a sparse network misses small events, so a quiet background is a floor; independence - the test counts every event, so an aftershock sequence weighs as many; the distance to the lateral - it is from the surface position; a protocol's verdict - the level an event reaches by the catalogue's magnitude, while the regulator's catalogue and the permit's own conditions govern.
|
|
@@ -49,6 +49,7 @@ INDEX: List[tuple] = [
|
|
|
49
49
|
('drillstring', 'Drill string', "each run's string from the bit up, every component's usage against its service interval, and the downhole motor's statistics and stability"),
|
|
50
50
|
('declare', 'The declarations sheet', 'everything the operator declares about a pad in one spreadsheet - identity, position, elevation, surveys, rates, AFE, fleet, runs, penetrators and drives - checked row by row before anything is written'),
|
|
51
51
|
('penetrator', 'Completion - the ESP penetrator', "the wellhead penetrator's ratings from its maker's documents, each well's installation record, and the ESP drive, motor and site checked against them; the permanent magnet motor safety note"),
|
|
52
|
+
('opseis', 'Operations and seismicity', "each well's drilling, completion and disposal windows against the earthquake catalogue around it: the events during and after each, the levels a regulator's protocol would reach, the rate during operations against the rest of the record; the Mahoning Valley worked example"),
|
|
52
53
|
('economics', 'Economics', 'each well\'s days, footage and cost by the operator\'s own declared rates, against the EIA oil and gas spot prices while it was drilled, and any series the site imports'),
|
|
53
54
|
('well3d', 'The well in 3D', 'each well\'s path from its directional survey, set among the mapped formation surfaces and contours with its picks, coloured by what was measured along it, and the drill string replayed from the record; the Volve field shipped as the worked example'),
|
|
54
55
|
('charts', 'The charts', 'a well\'s channels stacked on one axis with a linked cursor, zoom and pan from every sample, time or depth for a drilling recorder, the depth events marked, and the drilling progress of every well'),
|
|
@@ -79,7 +80,7 @@ REQUIRED_LINES = ('**The command**', '**What it writes**', '**The number to chec
|
|
|
79
80
|
VIEW_TOPIC: Dict[str, str] = {
|
|
80
81
|
'home': 'start', 'wells': 'data-in', 'well': 'drift', 'live': 'patches', 'patch': 'patches', 'files': 'files', 'alarms': 'alarms',
|
|
81
82
|
'approvals': 'well-tests', 'config': 'site', 'reports': 'drift', 'verify': 'start', 'survey': 'data-in', 'jobs': 'site',
|
|
82
|
-
'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'setup': 'setup', 'map': 'map', '3d': 'well3d', 'simulation': 'simulation', 'drillstring': 'drillstring', 'completion': 'penetrator', 'economics': 'economics', 'control': 'control-room', 'wall': 'control-room', 'audit': 'audit-update', 'tools': 'tools', 'catalog': 'catalog',
|
|
83
|
+
'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'setup': 'setup', 'map': 'map', '3d': 'well3d', 'simulation': 'simulation', 'drillstring': 'drillstring', 'completion': 'penetrator', 'opseis': 'opseis', 'economics': 'economics', 'control': 'control-room', 'wall': 'control-room', 'audit': 'audit-update', 'tools': 'tools', 'catalog': 'catalog',
|
|
83
84
|
}
|
|
84
85
|
|
|
85
86
|
|