gea-program 0.84.0__tar.gz → 0.85.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.84.0/gea_program.egg-info → gea_program-0.85.0}/PKG-INFO +19 -4
- {gea_program-0.84.0 → gea_program-0.85.0}/README.md +18 -3
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/__init__.py +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/__main__.py +51 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/acceptance_tests.py +213 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/dossier.py +16 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/driller.md +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/install.md +2 -2
- gea_program-0.85.0/gea/help/plume.md +13 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/reader.md +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/recorder.md +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/01-install.md +2 -2
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/14-production-pages.md +6 -5
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/19-dossier-reader.md +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/22-updates.md +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/23-vpn.md +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/25-install-recorder.md +2 -2
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/29-driller-rig.md +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial.md +2 -2
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/helplib.py +2 -1
- gea_program-0.85.0/gea/plume.py +709 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/service.py +14 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/web/app.html +55 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/well3d.py +18 -0
- {gea_program-0.84.0 → gea_program-0.85.0/gea_program.egg-info}/PKG-INFO +19 -4
- {gea_program-0.84.0 → gea_program-0.85.0}/gea_program.egg-info/SOURCES.txt +2 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/pyproject.toml +1 -1
- {gea_program-0.84.0 → gea_program-0.85.0}/LICENSE +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/alerts.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/backup.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/bench.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/bit_seismic.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/blind_harness.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/casing_design.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog_map.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/catalog_register.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/certificates.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/cli.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/client_reports.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/collision.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/config_versioning.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/conformance.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/control_room.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/correlation.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/dashboard.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/declarations.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/decline.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/deviation.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/dlis.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/dnp3.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/doctor.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/dossier_verify.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/drill_string.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/driller_link.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/earth_model.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/economics.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/ed25519.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/edr.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/elevation.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/etp.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/example_register_map.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/fat_sat.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/field_pull.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/files.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/fluid.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/follower.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/forward_model.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/frac_hits.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/friction_priors.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/gamma.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/geodesy.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/geomag.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/hartip.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/IT_SECURITY.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/alarms.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/alerts.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/backup.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/bit-image.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/casing.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/catalog.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/charts.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/collision.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/company-sign-in.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/conformance.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/control-room.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/data-in.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/declare.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/decline.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/dlis.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/doctor.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/dossier.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/drift.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/economics.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/edr.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/etp.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/files.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/fluid.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/frac-hits.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/historian.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/https.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/hydraulics.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/instruments.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/interval.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/invoice-check.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/map.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/month-end.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/notifications.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/opseis.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/osdu.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/patches.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/plan.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/pore-pressure.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/quality.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/records.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/report-history.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/rig-time.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/rocks.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/seismic.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/setup.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/simulation.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/site.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/sites.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/slip.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/soak.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/sra.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/start.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/structure.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tools.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/torque-drag.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/transients.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/02-sign-in.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/03-site.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/04-add-well.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/05-records.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/06-well-page.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/07-declare.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/08-patches.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/09-alarms.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/10-control-room.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/11-summary-month.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/12-where-the-well-is.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/13-drilling-pages.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/15-seismic.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/16-seismicity.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/17-recorder-office.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/18-reports.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/20-admin.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/21-upkeep.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/24-the-box.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/26-monitor.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/27-mirror-vpn.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/tutorial/28-driller-office.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/vibration.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/vpn.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/well-report.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/help/well3d.md +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/housekeeping.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/hydraulics.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/icon.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/interval.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/invoice_check.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/jobs.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/launcher.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/live_ports.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/loadtest.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/modbus.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/model_card.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/month_end.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/notify.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/oidc.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/oidc_mock.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/opcua_port.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/operator_app.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/osdu.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/pad_summary.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/patches.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/pdf_report.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/penetrator.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/permits.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/piwebapi.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/pore_pressure.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/ports.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/ppdm.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/project.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/quakeml.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reader.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reader_app.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reconciler.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/recorder_link.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/WMM2025.COF +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/iscwsa_rev4_example.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/iscwsa_rev5_example.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/owsg_tool_models.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/report_history.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/rig_state.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/sample_record.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/sbom.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seedlink.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/segy.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_array.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_film.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_response.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_track.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/series_cache.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/service_life.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/shapefile.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/shell.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/shut_in.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/simulation.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/site_map.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/sla_report.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/slip.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/soak.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/sra.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/store_forward.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/strata_join.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/structure.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/supervisor.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/survey_view.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/telemetry.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/timestamp.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/tls.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/tool_library.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/torque_drag.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/transient.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/tray.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/tutorial.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/updates.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/vibration.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/vpn.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/web/reader.html +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/well_assembler.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/well_records.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/well_report.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/wellplan.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/wellpos.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/winident.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/wits0.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/witsml.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/workspace.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/workspaces.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/x25519.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea/xlsx_read.py +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.84.0 → gea_program-0.85.0}/setup.cfg +0 -0
- {gea_program-0.84.0 → gea_program-0.85.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.85.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
|
|
@@ -847,7 +847,7 @@ unsigned, the key hand-overs - and shows the reports as they were signed. A
|
|
|
847
847
|
reader made from the workspace knows the site's key fingerprints, so it
|
|
848
848
|
says whether a dossier is the site's; it allows no network request, and it
|
|
849
849
|
leaves the trusted time-stamp to `verify_dossier.py`. For a client who wants
|
|
850
|
-
it installed, every release also carries `GEA-Reader-Setup-0.
|
|
850
|
+
it installed, every release also carries `GEA-Reader-Setup-0.85.0.exe`: GEA
|
|
851
851
|
Reader as a Windows program of its own - its own icon and taskbar button,
|
|
852
852
|
Check with GEA Reader on a dossier's right-click menu, fingerprints the client
|
|
853
853
|
saves kept on that computer, nothing of GEA-Program. `gea help reader`.
|
|
@@ -966,6 +966,21 @@ pressure rise there and the volume it would take for the water itself to
|
|
|
966
966
|
arrive, every projection labelled SIMULATION. The **Fluid balance** tab,
|
|
967
967
|
`gea fluid`, `gea help fluid`.
|
|
968
968
|
|
|
969
|
+
### Pressure plume
|
|
970
|
+
|
|
971
|
+
The ledger's barrels put into the declared formation on a plan grid
|
|
972
|
+
centred on the injection well and stepped forward day by day - single-phase,
|
|
973
|
+
slightly compressible flow by explicit finite differences, checked against
|
|
974
|
+
the line source on the page. The rise drawn as contours at every month's
|
|
975
|
+
end of the record and a year on, both continued at the last rates and shut
|
|
976
|
+
in now; the cells over a declared threshold as the area of review, in acres
|
|
977
|
+
and reach; every mapped fault within the radius read for its rise and its
|
|
978
|
+
slip tendency at each snapshot, with the first day its margin would be used
|
|
979
|
+
up; a fault layer declared sealing blocks the flow and the plume piles up
|
|
980
|
+
against it. The same contours drawn at the declared top in the 3D tab and
|
|
981
|
+
carried in the dossier. Every figure a SIMULATION, said on every line. The
|
|
982
|
+
**Pressure plume** tab, `gea plume`, `gea help plume`.
|
|
983
|
+
|
|
969
984
|
### Plan vs actual and the survey tools
|
|
970
985
|
|
|
971
986
|
Each well against its directional plan: at every survey station, how far
|
|
@@ -1630,7 +1645,7 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1630
1645
|
|
|
1631
1646
|
### The Windows installer
|
|
1632
1647
|
|
|
1633
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1648
|
+
Every release also carries `GEA-Program-Setup-0.85.0.exe` (for 0.85.0): the
|
|
1634
1649
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1635
1650
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1636
1651
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
@@ -1649,7 +1664,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1649
1664
|
software deployment:
|
|
1650
1665
|
|
|
1651
1666
|
```
|
|
1652
|
-
GEA-Program-Setup-0.
|
|
1667
|
+
GEA-Program-Setup-0.85.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1653
1668
|
```
|
|
1654
1669
|
|
|
1655
1670
|
The setup is built by Inno Setup 6 from `tools/installer.iss` in the same
|
|
@@ -808,7 +808,7 @@ unsigned, the key hand-overs - and shows the reports as they were signed. A
|
|
|
808
808
|
reader made from the workspace knows the site's key fingerprints, so it
|
|
809
809
|
says whether a dossier is the site's; it allows no network request, and it
|
|
810
810
|
leaves the trusted time-stamp to `verify_dossier.py`. For a client who wants
|
|
811
|
-
it installed, every release also carries `GEA-Reader-Setup-0.
|
|
811
|
+
it installed, every release also carries `GEA-Reader-Setup-0.85.0.exe`: GEA
|
|
812
812
|
Reader as a Windows program of its own - its own icon and taskbar button,
|
|
813
813
|
Check with GEA Reader on a dossier's right-click menu, fingerprints the client
|
|
814
814
|
saves kept on that computer, nothing of GEA-Program. `gea help reader`.
|
|
@@ -927,6 +927,21 @@ pressure rise there and the volume it would take for the water itself to
|
|
|
927
927
|
arrive, every projection labelled SIMULATION. The **Fluid balance** tab,
|
|
928
928
|
`gea fluid`, `gea help fluid`.
|
|
929
929
|
|
|
930
|
+
### Pressure plume
|
|
931
|
+
|
|
932
|
+
The ledger's barrels put into the declared formation on a plan grid
|
|
933
|
+
centred on the injection well and stepped forward day by day - single-phase,
|
|
934
|
+
slightly compressible flow by explicit finite differences, checked against
|
|
935
|
+
the line source on the page. The rise drawn as contours at every month's
|
|
936
|
+
end of the record and a year on, both continued at the last rates and shut
|
|
937
|
+
in now; the cells over a declared threshold as the area of review, in acres
|
|
938
|
+
and reach; every mapped fault within the radius read for its rise and its
|
|
939
|
+
slip tendency at each snapshot, with the first day its margin would be used
|
|
940
|
+
up; a fault layer declared sealing blocks the flow and the plume piles up
|
|
941
|
+
against it. The same contours drawn at the declared top in the 3D tab and
|
|
942
|
+
carried in the dossier. Every figure a SIMULATION, said on every line. The
|
|
943
|
+
**Pressure plume** tab, `gea plume`, `gea help plume`.
|
|
944
|
+
|
|
930
945
|
### Plan vs actual and the survey tools
|
|
931
946
|
|
|
932
947
|
Each well against its directional plan: at every survey station, how far
|
|
@@ -1591,7 +1606,7 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1591
1606
|
|
|
1592
1607
|
### The Windows installer
|
|
1593
1608
|
|
|
1594
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1609
|
+
Every release also carries `GEA-Program-Setup-0.85.0.exe` (for 0.85.0): the
|
|
1595
1610
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1596
1611
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1597
1612
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
@@ -1610,7 +1625,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1610
1625
|
software deployment:
|
|
1611
1626
|
|
|
1612
1627
|
```
|
|
1613
|
-
GEA-Program-Setup-0.
|
|
1628
|
+
GEA-Program-Setup-0.85.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1614
1629
|
```
|
|
1615
1630
|
|
|
1616
1631
|
The setup is built by Inno Setup 6 from `tools/installer.iss` in the same
|
|
@@ -590,6 +590,19 @@ def main(argv=None) -> int:
|
|
|
590
590
|
p_fl.add_argument("--write", action="store_true", help="write the report under reports/fluid/ (fluid_balance.json, .md, the ledger CSVs)")
|
|
591
591
|
p_fl.add_argument("--actor", type=str, default="cli")
|
|
592
592
|
p_fl.add_argument("--json", action="store_true")
|
|
593
|
+
p_pm = sub.add_parser("plume", help="the pressure plume (SIMULATION): the ledger's barrels put into the formation on a plan grid and stepped through time - the rise as contours at every month's end and a year on, continued or shut in; the area of review over a declared threshold; every mapped fault's rise and slip tendency through time, sealing or open as declared")
|
|
594
|
+
p_pm.add_argument("--workspace", type=str, default=None, help="the workspace folder; without one the self-test runs (the grid against the line source, a sealing fault, the contours)")
|
|
595
|
+
p_pm.add_argument("--formation", type=str, default=None, help="one formation's plume (default: every formation with an injection ledger)")
|
|
596
|
+
p_pm.add_argument("--threshold-psi", type=float, default=None, help="settings: the area of review's threshold, psi (default 50)")
|
|
597
|
+
p_pm.add_argument("--cells", type=int, default=None, help="settings: cells per side of the grid, odd, 21 to 121 (default 81)")
|
|
598
|
+
p_pm.add_argument("--radius-km", type=float, default=None, help="settings: the radius the faults are taken within (default 25)")
|
|
599
|
+
p_pm.add_argument("--projection-days", type=int, default=None, help="settings: how far beyond the record to project (default 365)")
|
|
600
|
+
p_pm.add_argument("--sealing", type=str, default=None, help="settings: a structure layer whose faults block flow (with --source)")
|
|
601
|
+
p_pm.add_argument("--open", dest="open_layer", type=str, default=None, help="settings: a structure layer whose faults do not block flow again")
|
|
602
|
+
p_pm.add_argument("--source", type=str, default="", help="where the sealing declaration comes from")
|
|
603
|
+
p_pm.add_argument("--write", action="store_true", help="write reports/plume/plume.json and .md")
|
|
604
|
+
p_pm.add_argument("--actor", type=str, default="cli")
|
|
605
|
+
p_pm.add_argument("--json", action="store_true")
|
|
593
606
|
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")
|
|
594
607
|
p_os.add_argument("--workspace", type=str, default=None)
|
|
595
608
|
p_os.add_argument("--scene", type=str, default=None, choices=("workspace", "mahoning"), help="your wells (the default with --workspace) or the public worked example")
|
|
@@ -2687,6 +2700,44 @@ def main(argv=None) -> int:
|
|
|
2687
2700
|
raise SystemExit(f"fluid: {e.args[0] if e.args else e}")
|
|
2688
2701
|
print(_json.dumps(p, default=str) if a.json else _FL.text(p))
|
|
2689
2702
|
return 0
|
|
2703
|
+
elif a.cmd == "plume":
|
|
2704
|
+
import json as _json
|
|
2705
|
+
from . import plume as _PM
|
|
2706
|
+
from .cli import _safe_stdout
|
|
2707
|
+
from .workspace import Workspace, WorkspaceError
|
|
2708
|
+
_safe_stdout()
|
|
2709
|
+
if not a.workspace:
|
|
2710
|
+
r = _PM.selftest()
|
|
2711
|
+
print(_json.dumps(r, default=str) if a.json else "\n".join(f"{'PASS' if c['pass'] else 'FAIL'} {c['check']}: {c['value']}" for c in r["checks"]) + f"\n{'OK' if r['ok'] else 'FAILED'} - {r['label']} (grid {r['grid']['n']} x {r['grid']['n']}, {r['grid']['dx_ft']} ft, {r['grid']['substeps_per_day']} sub-steps a day)")
|
|
2712
|
+
return 0 if r["ok"] else 1
|
|
2713
|
+
try:
|
|
2714
|
+
ws = Workspace(a.workspace)
|
|
2715
|
+
except WorkspaceError as e:
|
|
2716
|
+
raise SystemExit(f"plume: {e}")
|
|
2717
|
+
try:
|
|
2718
|
+
if any(v is not None for v in (a.threshold_psi, a.cells, a.radius_km, a.projection_days, a.sealing, a.open_layer)):
|
|
2719
|
+
sealing = {}
|
|
2720
|
+
if a.sealing:
|
|
2721
|
+
sealing[a.sealing] = True
|
|
2722
|
+
if a.open_layer:
|
|
2723
|
+
sealing[a.open_layer] = False
|
|
2724
|
+
st_ = _PM.set_settings(ws, a.actor, a.threshold_psi, a.cells, a.radius_km, sealing or None, a.projection_days, a.source)
|
|
2725
|
+
print("settings: " + ", ".join(f"{k} {v}" for k, v in st_.items() if k in ("threshold_psi", "cells", "radius_km", "projection_days", "sealing_layers")))
|
|
2726
|
+
return 0
|
|
2727
|
+
if a.write:
|
|
2728
|
+
from . import __version__ as _ver85
|
|
2729
|
+
r = _PM.write_report(ws, _ver85, a.actor)
|
|
2730
|
+
print(f"written: {', '.join(r['files'])} under {r['folder']}")
|
|
2731
|
+
p = r["page"]
|
|
2732
|
+
else:
|
|
2733
|
+
p = _PM.page(ws, a.formation)
|
|
2734
|
+
except (_PM.PlumeError, WorkspaceError, ValueError, OSError) as e:
|
|
2735
|
+
raise SystemExit(f"plume: {e.args[0] if e.args else e}")
|
|
2736
|
+
if a.json:
|
|
2737
|
+
print(_json.dumps(p, default=str))
|
|
2738
|
+
else:
|
|
2739
|
+
print(_PM.text(p))
|
|
2740
|
+
return 0
|
|
2690
2741
|
elif a.cmd == "seismicity":
|
|
2691
2742
|
import json as _json
|
|
2692
2743
|
from . import op_seismicity as _OS
|
|
@@ -17627,6 +17627,218 @@ def section_eb_fluid(tmp: str) -> None:
|
|
|
17627
17627
|
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
17628
17628
|
|
|
17629
17629
|
|
|
17630
|
+
def section_ec_plume(tmp: str) -> None:
|
|
17631
|
+
"""Section EC - the pressure plume: the grid against the line source, the barrels held, the symmetric field, a sealing
|
|
17632
|
+
fault shading its far side, the contours and the area of review of a radial field, shut-in relaxing; the workspace
|
|
17633
|
+
(the ledger's wells on the grid with the mapped faults, the snapshots through the record and the two projections,
|
|
17634
|
+
the area of review growing, a fault's slip tendency through time and its first day past the line, a layer declared
|
|
17635
|
+
sealing piling the plume up, the settings with their refusals, the report, the 3D layers at the declared top, the
|
|
17636
|
+
dossier's results, the words free of the client-report terms); the routes, the tab, the command, the help, the
|
|
17637
|
+
README and the lesson."""
|
|
17638
|
+
import http.cookiejar
|
|
17639
|
+
import math
|
|
17640
|
+
import subprocess as _sp
|
|
17641
|
+
import urllib.error
|
|
17642
|
+
import urllib.request
|
|
17643
|
+
import zipfile as _zf
|
|
17644
|
+
from datetime import datetime, timedelta
|
|
17645
|
+
from . import __version__ as _ver
|
|
17646
|
+
from . import client_reports as CR
|
|
17647
|
+
from . import dossier as DZ
|
|
17648
|
+
from . import fluid as FL
|
|
17649
|
+
from . import geodesy as GD
|
|
17650
|
+
from . import helplib as H
|
|
17651
|
+
from . import plume as PM
|
|
17652
|
+
from . import shapefile as SF
|
|
17653
|
+
from . import well3d as W3
|
|
17654
|
+
from .service import Service, Users
|
|
17655
|
+
from .workspace import Workspace, WorkspaceError
|
|
17656
|
+
pkg = Path(__file__).parent
|
|
17657
|
+
d = Path(tmp, "ec"); d.mkdir()
|
|
17658
|
+
# -- EC1 the arithmetic -------------------------------------------------------------------------------------------------
|
|
17659
|
+
st = PM.selftest()
|
|
17660
|
+
k, h, phi, mu, ct = 20.0, 200.0, 0.1, 0.8, 8e-6
|
|
17661
|
+
n = 41; g = PM.Grid(n, 400.0, h, phi, k, mu, ct)
|
|
17662
|
+
sub = max(1, int(math.ceil(1.0 / g.dt_max_days())))
|
|
17663
|
+
c = (n // 2, n // 2)
|
|
17664
|
+
dp = PM.step_days(g, np.zeros((n, n)), {c: 3000.0}, 20.0, sub * 20)
|
|
17665
|
+
ls = FL.line_source_dp_psi(3000.0, k, h, phi, mu, ct, 5 * 400.0, 20 * 24.0)
|
|
17666
|
+
two = PM.step_days(g, np.zeros((n, n)), {c: 3000.0, (c[0], c[1] + 6): -1500.0}, 20.0, sub * 20)
|
|
17667
|
+
lines = PM.contours(g, dp, float(dp[c[0], c[1] + 4]))
|
|
17668
|
+
aor = PM.area_of_review(g, dp, float(dp[c[0], c[1] + 4]), 0.0, 0.0)
|
|
17669
|
+
c1 = {
|
|
17670
|
+
"selftest": st["ok"] and st["label"] == "SIMULATION" and len(st["checks"]) == 7,
|
|
17671
|
+
"theis": abs(float(dp[c[0], c[1] + 5]) / ls - 1.0) < 0.06,
|
|
17672
|
+
"storage": abs(float(np.sum(g.storage * dp)) / (3000.0 * 20) - 1.0) < 0.02 and abs(g.storage[0, 0] - 400.0 * 400.0 * h * phi * ct / 5.614583) < 1e-6
|
|
17673
|
+
and abs(g.Tx[0, 0] - 0.001127 * k * h / mu) < 1e-9,
|
|
17674
|
+
"superposition": abs(float(np.sum(g.storage * two)) / (1500.0 * 20) - 1.0) < 0.02 and float(two[c[0], c[1] + 6]) < 0.0 < float(two[c]),
|
|
17675
|
+
"contour": len(lines) >= 1 and abs(float(np.mean([math.hypot(x, y) for x, y in max(lines, key=len)])) / 400.0 - 4.0) < 0.5,
|
|
17676
|
+
"aor": abs(aor["area_acres"] / (math.pi * 1600.0 ** 2 / 43560.0) - 1.0) < 0.2 and 1700.0 < aor["reach_ft"] < 2100.0 and not aor["touches_edge"],
|
|
17677
|
+
"seal": (lambda g2: (g2.seal_segment(1000.0, -3000.0, 1000.0, 3000.0) >= 14 and g2.Tx[c[0], c[1] + 2] == 0.0 and g2.Tx[c[0], c[1] + 1] != 0.0))(PM.Grid(n, 400.0, h, phi, k, mu, ct)),
|
|
17678
|
+
"stability": 0 < g.dt_max_days() < 1.0 and sub == int(math.ceil(1.0 / g.dt_max_days())),
|
|
17679
|
+
}
|
|
17680
|
+
failed1 = [k_ for k_, v in c1.items() if not v]
|
|
17681
|
+
ok(not failed1,
|
|
17682
|
+
"EC1 the arithmetic: the self-test's seven checks on labelled grids; a 41 x 41 grid of 400 ft cells against the line source at 5 cells after 20 days "
|
|
17683
|
+
"(within 6%), the storage and transmissibility by the field-unit formulas, the grid holding the barrels (within 2%), an injector and a producer "
|
|
17684
|
+
"superposed (the net held, the producer's cell below zero), the contour of a radial field a circle of 4 cells, its area of review pi r^2 within 20%, "
|
|
17685
|
+
"a sealing segment zeroing the faces it separates and no other, the stability sub-steps" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
17686
|
+
# -- EC2 the workspace --------------------------------------------------------------------------------------------------
|
|
17687
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
|
|
17688
|
+
inj = ws.add_well_records("SWD 1", actor="tester"); prod = ws.add_well_records("Producer 7H", actor="tester")
|
|
17689
|
+
for w_, la, lo in ((inj, 31.96, -102.24), (prod, 31.965, -102.24)):
|
|
17690
|
+
ws.set_well(w_["id"], surface={"lat": la, "lon": lo, "datum": "NAD83", "elevation": {"ft": 2900.0, "datum": "KB", "source": "test plat"}}, actor="tester")
|
|
17691
|
+
ws.set_well(inj["id"], disposal={"top_interval_ft": 8700.0, "base_interval_ft": 9300.0, "depth_reference": "TVD", "depth_tier": "deep"}, actor="tester")
|
|
17692
|
+
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", "shmax_azimuth_deg": 80.0, "azimuth_source": "the gate"}, actor="tester")
|
|
17693
|
+
kmlat = 1 / 111.195; kmlon = 1 / (111.195 * math.cos(math.radians(31.96)))
|
|
17694
|
+
feats = [([[(-102.24 + 0.914 * kmlon, 31.94), (-102.24 + 0.914 * kmlon, 31.98)]], {"name": "East fault"}), # 3,000 ft east, N-S
|
|
17695
|
+
([[(-102.27, 31.96 + 2 * kmlat), (-102.21, 31.96 + 2 * kmlat)]], {"name": "North fault"})] # 2 km north, E-W: 10 deg to SHmax
|
|
17696
|
+
wkt = 'GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.257223563]],PRIMEM["Greenwich",0.0],UNIT["Degree",0.0174532925199433]]'
|
|
17697
|
+
SF.write(str(d / "faults"), "PolyLine", feats, [("name", "C", 20, 0)], wkt)
|
|
17698
|
+
with _zf.ZipFile(str(d / "faults.zip"), "w") as z:
|
|
17699
|
+
for ext in (".shp", ".shx", ".dbf", ".prj"):
|
|
17700
|
+
z.write(str(d / ("faults" + ext)), "faults" + ext)
|
|
17701
|
+
lay = ws.add_layer(str(d / "faults.zip"), "Gate faults", actor="tester", feature_kind="fault", citation="the gate's own layer")
|
|
17702
|
+
empty = PM.page(ws)
|
|
17703
|
+
FL.declare_well(ws, "tester", inj["id"], role="injection", formation="Ellenburger", source="completion report W-2")
|
|
17704
|
+
FL.declare_well(ws, "tester", prod["id"], role="production", formation="Ellenburger", sg=1.05, source="permit")
|
|
17705
|
+
sc = FL.synthetic_scene(days=240, leak_fraction=0.0, seed=5)
|
|
17706
|
+
FL.attach_report(ws, "tester", inj["id"], "h10.csv", sc["csv"].encode(), "H-10 (gate)")
|
|
17707
|
+
pcsv = "Date,Oil (bbl),Water (bbl)\n" + "\n".join(f"{(datetime(2026, 1, 1) + timedelta(days=i)).strftime('%Y-%m-%d')},{50 + i % 7},{300 + i % 11}" for i in range(200)) + "\n"
|
|
17708
|
+
FL.attach_report(ws, "tester", prod["id"], "prod.csv", pcsv.encode(), "production report (gate)")
|
|
17709
|
+
FL.declare_formation(ws, "tester", "Ellenburger", "petrophysics (gate)", porosity=0.12, thickness_ft=100.0, area_acres=11000.0)
|
|
17710
|
+
undeclared = PM.page(ws)
|
|
17711
|
+
FL.declare_formation(ws, "tester", "Ellenburger", "petrophysics (gate)", k_md=50.0, mu_cp=0.6, p_initial_psi=3000.0)
|
|
17712
|
+
refused = {}
|
|
17713
|
+
for name, fn in (("thr", lambda: PM.set_settings(ws, "tester", threshold_psi=0.1)), ("cells_even", lambda: PM.set_settings(ws, "tester", cells=80)),
|
|
17714
|
+
("cells_big", lambda: PM.set_settings(ws, "tester", cells=201)), ("radius", lambda: PM.set_settings(ws, "tester", radius_km=500)),
|
|
17715
|
+
("proj", lambda: PM.set_settings(ws, "tester", projection_days=5)), ("seal_src", lambda: PM.set_settings(ws, "tester", sealing={lay["id"]: True})),
|
|
17716
|
+
("seal_layer", lambda: PM.set_settings(ws, "tester", sealing={"nowhere": True}, source="x"))):
|
|
17717
|
+
try:
|
|
17718
|
+
fn(); refused[name] = False
|
|
17719
|
+
except PM.PlumeError:
|
|
17720
|
+
refused[name] = True
|
|
17721
|
+
PM.set_settings(ws, "tester", threshold_psi=50.0, cells=61, radius_km=25.0, projection_days=365)
|
|
17722
|
+
pg = PM.page(ws)
|
|
17723
|
+
pl = pg["plumes"][0]
|
|
17724
|
+
rec = [s_ for s_ in pl["snapshots"] if s_["kind"] == "record"]; cont = [s_ for s_ in pl["snapshots"] if s_["kind"] == "continued"]; shut = [s_ for s_ in pl["snapshots"] if s_["kind"] == "shut-in"]
|
|
17725
|
+
fl = {f_["name"]: f_ for f_ in pl["faults"]}
|
|
17726
|
+
east_last = next(r_ for r_ in rec[-1]["faults"] if r_["name"] == "East fault"); north_last = next(r_ for r_ in rec[-1]["faults"] if r_["name"] == "North fault")
|
|
17727
|
+
PM.set_settings(ws, "tester", sealing={lay["id"]: True}, source="the gate's fault study")
|
|
17728
|
+
pg2 = PM.page(ws); pl2 = pg2["plumes"][0]
|
|
17729
|
+
east2 = next(r_ for r_ in [s_ for s_ in pl2["snapshots"] if s_["kind"] == "record"][-1]["faults"] if r_["name"] == "East fault")
|
|
17730
|
+
PM.set_settings(ws, "tester", sealing={lay["id"]: False}, source="the gate's fault study")
|
|
17731
|
+
PM.set_settings(ws, "tester", cells=21) # both wells in one 7,400 ft cell: their rates add, neither is lost
|
|
17732
|
+
one_cell = PM.page(ws)["plumes"][0]
|
|
17733
|
+
PM.set_settings(ws, "tester", cells=61)
|
|
17734
|
+
wr = PM.write_report(ws, _ver, "tester")
|
|
17735
|
+
txt = (Path(wr["folder"]) / "plume.md").read_text(encoding="utf-8").lower()
|
|
17736
|
+
frame = GD._tm(31.96, -102.24, 1.0, 0.0, 0.0, "WGS84")
|
|
17737
|
+
l3, sk3 = PM.scene_layers(ws, frame)
|
|
17738
|
+
dz = DZ.build(ws, "tester", _ver, None)
|
|
17739
|
+
names = _zf.ZipFile(Path(ws.reports_dir, dz["path"])).namelist()
|
|
17740
|
+
audit = Path(ws.audit_path).read_text(encoding="utf-8")
|
|
17741
|
+
# the producer, 1,819 ft north, sits on the grid: its cell's rise is positive (the injector's) but below the injector's
|
|
17742
|
+
wl = {w_["well"]: w_ for w_ in pl["wells"]}
|
|
17743
|
+
c2 = {
|
|
17744
|
+
"empty": empty["status"] == "EMPTY" and "No plume" in empty["lines"][0],
|
|
17745
|
+
"undeclared": undeclared["plumes"][0]["status"] == "NOT DECLARED" and "k md" in undeclared["plumes"][0]["notes"][0],
|
|
17746
|
+
"refusals": all(refused.values()),
|
|
17747
|
+
"grid": pl["status"] == "OK" and pl["frame"]["cells"] == 61 and pl["frame"]["substeps_per_day"] >= 1 and pl["properties"]["uniform"] and pl["label"] == "SIMULATION"
|
|
17748
|
+
and wl[inj["id"]]["in_grid"] and wl[prod["id"]]["in_grid"] and abs(wl[prod["id"]]["y_ft"] - 1819.0) < 60.0 and abs(wl[prod["id"]]["x_ft"]) < 20.0,
|
|
17749
|
+
"snapshots": len(rec) == 8 and rec[-1]["day"] == 240 and len(cont) == 4 and len(shut) == 4 and cont[-1]["day"] == 605
|
|
17750
|
+
and all(rec[i]["aor"]["area_acres"] <= rec[i + 1]["aor"]["area_acres"] + 1e-6 for i in range(len(rec) - 1))
|
|
17751
|
+
and cont[-1]["aor"]["area_acres"] > rec[-1]["aor"]["area_acres"] and shut[-1]["dp_max_psi"] < rec[-1]["dp_max_psi"] * 0.2
|
|
17752
|
+
and 0 < rec[-1]["wells"][prod["id"]] < rec[-1]["wells"][inj["id"]],
|
|
17753
|
+
"check": pl["check"]["points"] and all(0.9 < p_["ratio"] < 1.1 for p_ in pl["check"]["points"]) and abs(pl["balance"]["left_through_edge_bbl"]) < 0.02 * pl["balance"]["net_bbl"],
|
|
17754
|
+
"faults": set(fl) == {"East fault", "North fault"} and not fl["East fault"]["sealing"] and east_last["inside_aor"] and east_last["dp_max_psi"] > north_last["dp_max_psi"]
|
|
17755
|
+
and north_last["Ts"] > east_last["Ts"] and north_last["slip_status"] == "BELOW THE FRICTION LINE" and fl["North fault"]["first_past_line"] is not None
|
|
17756
|
+
and fl["North fault"]["first_past_line"]["kind"] == "continued" and fl["East fault"]["first_past_line"] is None and pl["stress"]["state"] is not None,
|
|
17757
|
+
"one_cell": one_cell["status"] == "OK" and abs(one_cell["balance"]["stored_bbl"] / one_cell["balance"]["net_bbl"] - 1.0) < 0.05,
|
|
17758
|
+
"sealing": pl2["faults"][0]["sealing"] and pl2["faults"][0].get("faces_sealed", 0) >= 5 and east2["dp_max_psi"] > east_last["dp_max_psi"] * 1.3 and pl2["sealing_layers"] == [lay["id"]],
|
|
17759
|
+
"written": set(wr["files"]) == {"plume.json", "plume.md"} and "simulation" in txt and "area of review" in txt.replace("the area over", "area of review") and not [t for t in CR.FORBIDDEN_TERMS if t in txt],
|
|
17760
|
+
"three_d": len(l3) == 2 and all(l_["role"] == "plume" and l_["lines"] and abs(l_["lines"][0]["z"] - (8700.0 - 2900.0) * 0.3048) < 0.2 for l_ in l3) and not sk3
|
|
17761
|
+
and (lambda sc_: any(l_.get("role") == "plume" for l_ in sc_["layers"]) or any("plume" in (x_.get("id") or "") for x_ in sc_["layers_not_drawn"]))(W3.workspace_scene(ws)),
|
|
17762
|
+
"dossier": "results/plume.json" in names and "results/fluid_balance.json" in names
|
|
17763
|
+
and all(x in audit for x in ("plume.settings", "plume.report")),
|
|
17764
|
+
}
|
|
17765
|
+
failed2 = [k_ for k_, v in c2.items() if not v]
|
|
17766
|
+
ok(not failed2,
|
|
17767
|
+
"EC2 the workspace: no plume until the ledger has an injection well, NOT DECLARED until the formation has its permeability; a threshold below a psi, an even or "
|
|
17768
|
+
"too-large grid, a radius or a projection out of range, a sealing declaration without its source or for no layer - each declined; the injector and the "
|
|
17769
|
+
"producer on a 61-cell grid in a frame centred on the injector (the producer 1,819 ft north), eight month-end snapshots of the record then four continued "
|
|
17770
|
+
"and four shut in - the area of review growing through the record, larger a year on if continued, the rise under a fifth if shut in, the producer's cell "
|
|
17771
|
+
"raised but under the injector's; the grid within 10% of the line source and the edge losing under 2%; the two mapped faults with the near one inside the "
|
|
17772
|
+
"area of review and the higher rise, the one along SHmax the higher slip tendency and the first past the friction line only in the continued projection; "
|
|
17773
|
+
"two wells in one cell of a 21-cell grid adding up (the net held); the layer declared sealing piling the plume up against the east fault by a third or more; "
|
|
17774
|
+
"the report written free of the client-report terms; the 3D "
|
|
17775
|
+
"layers at the declared top of the interval; the dossier's results/plume.json and results/fluid_balance.json; the audit lines"
|
|
17776
|
+
+ (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
17777
|
+
# -- EC3 the routes, the tab, the command, the help, the README and the lesson -----------------------------------------------
|
|
17778
|
+
Users(str(Path(wsp, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
|
|
17779
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
17780
|
+
base_url = svc.url.rstrip("/")
|
|
17781
|
+
|
|
17782
|
+
def opener(name, pw_):
|
|
17783
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
17784
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
17785
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
17786
|
+
return o
|
|
17787
|
+
|
|
17788
|
+
def call(o, method, path, body=None):
|
|
17789
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
17790
|
+
if method == "POST":
|
|
17791
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
17792
|
+
try:
|
|
17793
|
+
with o.open(rq, timeout=120) as rr_:
|
|
17794
|
+
return rr_.status, json.loads(rr_.read())
|
|
17795
|
+
except urllib.error.HTTPError as e:
|
|
17796
|
+
return e.code, json.loads(e.read())
|
|
17797
|
+
try:
|
|
17798
|
+
V, O = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
|
|
17799
|
+
s_vg, vg = call(V, "GET", "/api/plume")
|
|
17800
|
+
s_vf, vf = call(V, "GET", "/api/plume?formation=Nowhere")
|
|
17801
|
+
s_vs, _ = call(V, "POST", "/api/plume/settings", {"threshold_psi": 25})
|
|
17802
|
+
s_os, os_ = call(O, "POST", "/api/plume/settings", {"threshold_psi": "25", "cells": "41"})
|
|
17803
|
+
s_bs, _ = call(O, "POST", "/api/plume/settings", {"cells": "40"})
|
|
17804
|
+
s_sl, sl_ = call(O, "POST", "/api/plume/settings", {"sealing": {lay["id"]: True}, "source": "api"})
|
|
17805
|
+
s_ns, _ = call(O, "POST", "/api/plume/settings", {"sealing": {lay["id"]: True}})
|
|
17806
|
+
s_ow, ow = call(O, "POST", "/api/plume/write", {})
|
|
17807
|
+
s_vw, _ = call(V, "POST", "/api/plume/write", {})
|
|
17808
|
+
s_g2, g2 = call(V, "GET", "/api/plume")
|
|
17809
|
+
s_3d, sc3 = call(V, "GET", "/api/3d/scene/workspace")
|
|
17810
|
+
finally:
|
|
17811
|
+
svc.stop()
|
|
17812
|
+
cli_s = _sp.run([sys.executable, "-m", "gea", "plume"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
17813
|
+
cli_w = _sp.run([sys.executable, "-m", "gea", "plume", "--workspace", wsp], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
17814
|
+
cli_j = _sp.run([sys.executable, "-m", "gea", "plume", "--workspace", wsp, "--formation", "Ellenburger", "--json"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
17815
|
+
cli_t = _sp.run([sys.executable, "-m", "gea", "plume", "--workspace", wsp, "--threshold-psi", "50", "--open", lay["id"]], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
17816
|
+
cli_b = _sp.run([sys.executable, "-m", "gea", "plume", "--workspace", wsp, "--sealing", lay["id"]], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
17817
|
+
cli_r = _sp.run([sys.executable, "-m", "gea", "plume", "--workspace", wsp, "--write"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
17818
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
17819
|
+
readme = (pkg.parent / "README.md").read_text(encoding="utf-8") if (pkg.parent / "README.md").is_file() else ""
|
|
17820
|
+
lesson = (pkg / "help" / "tutorial" / "14-production-pages.md").read_text(encoding="utf-8")
|
|
17821
|
+
c3 = {
|
|
17822
|
+
"api": s_vg == 200 and vg["status"] == "OK" and vg["label"] == "SIMULATION" and s_vf == 200 and vf["status"] == "EMPTY" and s_vs == 403 and s_os == 200 and os_["threshold_psi"] == 25.0
|
|
17823
|
+
and os_["cells"] == 41 and s_bs == 400 and s_sl == 200 and sl_["sealing_layers"] == [lay["id"]] and s_ns == 400 and s_ow == 200 and "plume.json" in ow["files"] and s_vw == 403
|
|
17824
|
+
and s_g2 == 200 and g2["plumes"][0]["frame"]["cells"] == 41 and g2["plumes"][0]["threshold_psi"] == 25.0 and g2["plumes"][0]["faults"][0]["sealing"]
|
|
17825
|
+
and s_3d == 200 and (any((l_.get("role") == "plume") for l_ in sc3.get("layers", [])) or any("plume" in (x_.get("id") or "") for x_ in sc3.get("layers_not_drawn", []))),
|
|
17826
|
+
"cli": cli_s.returncode == 0 and "OK - SIMULATION" in cli_s.stdout and cli_w.returncode == 0 and "snapshots" in cli_w.stdout and "shut-in" in cli_w.stdout
|
|
17827
|
+
and cli_j.returncode == 0 and json.loads(cli_j.stdout)["plumes"][0]["formation"] == "Ellenburger" and cli_t.returncode == 0 and "sealing_layers []" in cli_t.stdout
|
|
17828
|
+
and cli_b.returncode != 0 and "source" in cli_b.stderr and cli_r.returncode == 0 and "plume.md" in cli_r.stdout,
|
|
17829
|
+
"page": all(x in page_src for x in ("VIEWS.plume", "['#/plume', 'Pressure plume']", "/api/plume/settings", "pmPlan", "help('plume')", "SIMULATION")),
|
|
17830
|
+
"help": not H.check("plume") and H.VIEW_TOPIC.get("plume") == "plume" and any(t == "plume" for t, _, _ in H.INDEX)
|
|
17831
|
+
and all(x in (H.page("plume") or "") for x in ("0.001127", "Theis", "SIMULATION", "gea plume --workspace C:\\site", "sealing")),
|
|
17832
|
+
"readme_lesson": (not readme or ("### Pressure plume" in readme and "`gea plume`" in readme)) and "Pressure plume" in lesson and "plume" in lesson.split("Help:")[-1],
|
|
17833
|
+
}
|
|
17834
|
+
failed3 = [k_ for k_, v in c3.items() if not v]
|
|
17835
|
+
ok(not failed3,
|
|
17836
|
+
"EC3 on the API (anyone reads the plume, one formation or all; only an operator keeps settings, declares a layer sealing - with its source - or writes; an "
|
|
17837
|
+
"even grid is 400; the 3D scene carries the plume), the command (the self-test, the snapshots, one formation as JSON, settings kept and a sealing "
|
|
17838
|
+
"declaration without its source stopped, the report), the tab with its plan view, the help page, the README and lesson 14"
|
|
17839
|
+
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
17840
|
+
|
|
17841
|
+
|
|
17630
17842
|
def main() -> int:
|
|
17631
17843
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
17632
17844
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -17762,6 +17974,7 @@ def main() -> int:
|
|
|
17762
17974
|
section_dz_textbook_oracle(tmp)
|
|
17763
17975
|
section_ea_vpn_client(tmp)
|
|
17764
17976
|
section_eb_fluid(tmp)
|
|
17977
|
+
section_ec_plume(tmp)
|
|
17765
17978
|
if _FAILS:
|
|
17766
17979
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
17767
17980
|
for f in _FAILS:
|
|
@@ -267,6 +267,8 @@ def _gather(ws, well_id: Optional[str]) -> Dict[str, List[tuple]]:
|
|
|
267
267
|
out_list = out['report']
|
|
268
268
|
if not well_id:
|
|
269
269
|
files_in(rep, 'reports')
|
|
270
|
+
files_in(os.path.join(rep, 'fluid'), 'reports/fluid') # the fluid ledger and the material balance
|
|
271
|
+
files_in(os.path.join(rep, 'plume'), 'reports/plume') # the pressure plume (SIMULATION)
|
|
270
272
|
for w in wells:
|
|
271
273
|
files_in(os.path.join(rep, 'wells', w['id']), f"reports/wells/{w['id']}")
|
|
272
274
|
out_list = out['declaration']
|
|
@@ -284,7 +286,7 @@ def _gather(ws, well_id: Optional[str]) -> Dict[str, List[tuple]]:
|
|
|
284
286
|
('drillstring', 'casing.json'), ('wellpath', 'collision.json'), ('wellpath', 'survey_program.json'),
|
|
285
287
|
('completion', 'frac', 'stages.json'), ('completion', 'frac', 'settings.json'), ('geomech', 'pore_pressure.json'),
|
|
286
288
|
('drillstring', 'torque_drag.json'), ('economics', 'production', 'production.json'), ('drillstring', 'hydraulics.json'),
|
|
287
|
-
('drillstring', 'casing_design.json')):
|
|
289
|
+
('drillstring', 'casing_design.json'), ('records', 'fluid.json'), ('records', 'plume.json')):
|
|
288
290
|
p = os.path.join(ws.path, *rel)
|
|
289
291
|
if os.path.isfile(p):
|
|
290
292
|
out_list.append((p, 'declarations/' + '/'.join(rel)))
|
|
@@ -411,6 +413,19 @@ def _results(ws, well_id: Optional[str]) -> List[tuple]:
|
|
|
411
413
|
out.append(('results/frac_hits.json', json.dumps({**r, 'stages': st}, indent=1, sort_keys=True, default=str).encode('utf-8')))
|
|
412
414
|
except Exception as e:
|
|
413
415
|
out.append(('results/frac_hits_not_run.txt', f'the frac-hit check did not run: {type(e).__name__}: {e}\n'.encode('utf-8')))
|
|
416
|
+
try:
|
|
417
|
+
from . import fluid as FLd
|
|
418
|
+
from . import plume as PLd
|
|
419
|
+
fp = FLd.page(ws)
|
|
420
|
+
if fp['wells']:
|
|
421
|
+
out.append(('results/fluid_balance.json', json.dumps({k: v for k, v in fp.items() if k != 'wells'} | {'wells': [{k: v for k, v in w.items() if k != 'days'} for w in fp['wells']]},
|
|
422
|
+
indent=1, sort_keys=True, default=str).encode('utf-8')))
|
|
423
|
+
pp = PLd.page(ws)
|
|
424
|
+
if pp['plumes']:
|
|
425
|
+
slim = [{**pl, 'snapshots': [{k: v for k, v in s_.items() if k != 'contours'} for s_ in pl.get('snapshots', [])]} for pl in pp['plumes']]
|
|
426
|
+
out.append(('results/plume.json', json.dumps({**pp, 'plumes': slim}, indent=1, sort_keys=True, default=str).encode('utf-8')))
|
|
427
|
+
except Exception as e:
|
|
428
|
+
out.append(('results/fluid_not_run.txt', f'the fluid balance and the plume did not run: {type(e).__name__}: {e}\n'.encode('utf-8')))
|
|
414
429
|
return out
|
|
415
430
|
|
|
416
431
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> A program on the rig PC that reads the rig's own feed and the pre-drill model, places the bit in the layer with a position filter, and, every 30 ft, recommends in the driller's units what to do next - a policy trained by reinforcement learning in a physics twin of the lateral - with the driller's answer, every command, and the records pulled into GEA.
|
|
4
4
|
|
|
5
|
-
**The command**: on the rig PC, `GEA-Driller-0.
|
|
5
|
+
**The command**: on the rig PC, `GEA-Driller-0.85.0.tar.gz` from the release (or the kit's `installers` folder, fetched on the Audit / Update tab): unpack it and run `sudo sh install.sh` on Linux or `install.cmd` on Windows, once; edit its config - the EDR's WITS0 feed (`tcp`, the host and port; `serial`, the COM port), the pre-drill model (the target layer's top TVD at the heel, its thickness and dip, the gamma in, above and below, the deep-resistivity tool, the heel's MD and TVD), the tool's cap, the limits - and restart it. The driller's screen is at port 8790 of the rig PC: `http://192.168.1.60:8790/live`. It shows the section with the model's layer window, the hole drilled through it and - since 0.78.0 - the **position filter**'s band: where the layer is from the readings, as a geosteerer places it (a particle filter over the layer's offset from the model, its dip error and its thickness, moved every decision and kept to the guesses that explain the gamma and the deep-resistivity distance), with the probability the bit is in the layer, above or below it and the distance to the top and the base with its spread, sixty feet ahead; the agent reads the same estimate, and so does the textbook driller it is judged against. Then the recommendation in words - *Build +1.5°/100 ft (toolface up, 25% steering); 25 klb WOB, 120 rpm, 500 gpm* - with its reasons (what the deep-resistivity tool says, the gamma against the model's values, the model's bracket, the limits) and the confidence of each choice, the rig's numbers against the limits, and **Accept**, **Reject** or **Did something else…** with the operator's name. In GEA: the **Drill string** tab's card **GEA Driller** - the rig PC's address and the well, **Pull**: the records come in checked against their hashes, and the table says how many decisions, accepted, rejected, done otherwise, the hole under advice, the armed sections and the commands. **Open the driller's screen** opens the rig PC's screen from its address. Before there is a rig PC: **Start the twin as the rig** runs the driller's program on this computer with a scene drilling itself under the agent - **Open its screen** is the driller's screen with the twin behind it, labelled SIMULATION - and **Pull from it** brings its records in; **Stop it** closes them. **Shadow a drilled well** (since 0.79.0): a well of this workspace with a drilling-recorder export is replayed through the advisor - every 30 ft the agent sees what the rig had shown to that point and nothing past it, and its recommendation is set beside what the record did next: the build actually made over the following 90 ft, the weight, speed and flow used, and at each stretch the gamma marks as out of the layer, whether the advisor called the way back at the first reading. The report, **SHADOW MODE**, is under the well's reports with a drawing of the lateral against the layer; the layer model is read off the well's own gamma in hindsight and says so - and grades how well it fits the well (good, fair, poor: a well steered to a rock that is not the low gamma reads poor, and the agent's calls against a poor model mean little) - unless the site's pre-drill model is given: a file `wells\Well-30636033\driller\model.json` with the config's `model` block (the target layer's top TVD at the heel, its thickness and dip, the gamma in, above and below, the heel's MD and TVD) is used whenever it is there (`gea workspace --path C:\site --action driller-shadow --well Well-30636033`). The export is read on this computer and nothing of it leaves it. Agreement with the driller says the two would have done alike, not that either was right. **The third dimension** (since 0.80.0): the lateral has an azimuth. The config's model carries the plan's azimuth (`plan_azimuth_deg`; empty, the first survey's at the heel is taken), the layer's dip across the plan line (`cross_dip_deg`, positive deepening to the right), the corridor the hole may run in to the right and left of the plan line (`corridor_ft`, the lease line and the offset wells) and where the heel sits across it (`heel_offset_ft`); the feed's surveys and the continuous azimuth (WITS item 0832, or the config's mapping) place the bit by minimum curvature along the plan, right of its line and in depth, and the screen draws the plan view - the corridor as a band, the hole against the plan line - under the section. The recommendation gains the aim - where to point the azimuth, along the plan or 4° left or right of it, and the turn that asks from where the hole points: *Build +1.5°/100 ft and aim 4° right of the plan (azimuth 44.0°), turning right 2.0°/100 ft (toolface 53°, 42% steering)* - with the build and the turn held together inside the DLS limit, and **Did something else…** takes the aim, or the turn made instead; the position filter carries the cross dip and reads it only when the hole moves across the plan line, leaving the model's value standing until then. In the twin the layer is a surface, the faults have a strike, the tool walks, and a hole that leaves the corridor by 150 ft is lost; the agent is judged on the hole in the corridor as well as in the layer (`gea-driller evaluate` prints both). Shadow mode reads the record's `azimuth_deg` column when it has one and sets the turn the advisor would have asked beside the turn the record made; without it the record's turns are not judged, and the report says so. **The vibration index from the feed** (since 0.81.0): a rig without a downhole vibration tool left the agent blind to the stick-slip and the whirl it was trained to ease, and the closed loop's vibration limit could never trip. Now the rig PC reads an index off the surface channels every EDR sends: over the last minute (`rig.vibration_window_s`), the surface torque's RMS about its mean as a fraction of the mean - the measure the Drill string page calls the oscillation index - times root two for the amplitude, and the same of the weight on bit and the hook load; stick-slip is the torque amplitude over 0.4, lateral vibration the weight amplitude over 0.2 (the twin's scale, where 1.2 is the limit), and the index is the larger. The downhole tool's item (WITS 0830) is taken instead whenever it comes, and every decision records which it read: the tile on the screen says *downhole tool* or *from surface data, stick-slip*, the reasons say *vibration 1.35 derived from the surface data (stick-slip, the surface torque swinging ±54%) over the limit 1.2*, and the limit disarms the loop on either. A surface proxy, labelled; on the twin as the rig it tracks the twin's own index within a few hundredths. The lateral file GEA writes for shadow mode carries, per foot, the surface channels' mean and RMS over the seconds of that foot (`torque_mean`, `torque_rms`, `wob_mean`, `wob_rms`, `hkld_mean`, `hkld_rms`, `rpm_mean`, `rpm_rms`, `spp_mean`, `spp_rms`), the replay reads the index off them for every decision, and the report says how often it stood over the limit and how often the advisor asked for less weight or more speed there than the record used; a record without torque or weight statistics says so and the advisor sees none. **The bar and the ceiling** (since 0.82.0): the agent is judged between two drillers on the same held-out scenes. The textbook driller is the bar - what a careful directional driller and geosteerer do by the book from the same observation the agent gets and nothing more: aim at the middle of the layer as the filter places it, steer back hard when the filter says the bit is out, lean away from a boundary the gamma's trend is running at, the rated weight in a calm hole in the layer and not while the hole fills, over the vibration limit lighter and faster first and heavier and slower when that did not quiet it, circulate at 40% of a bed, ream a balled bit, hold the plan line; it has a driller's memory of its own last decisions and none of the twin's secret. The oracle is the ceiling - the same driller told the twin's own layer at the bit and 120 ft ahead of it, which no policy can beat because it sees what no tool measures. `gea-driller evaluate` prints the three rows and how far the agent stands from the bar toward the ceiling; the self-test refuses a policy that does not beat the textbook, and the gate holds it under the oracle. The figures are a simulation's, labelled; a stronger textbook lowers the agent's standing without changing the agent, and that is the point of it. Over a cellular modem the rig PC joins GEA-VPN as a member of kind `driller` and GEA pulls from `http://10.77.0.4:8790`. The closed loop: `closed_loop.allowed` in the rig PC's config puts the switch on its screen; an operator arms it by name for one section of at most 500 ft (**Arm for this section**), every decision then goes to the downlink as a command, and the loop disarms itself on a stale feed, a crossed limit, the section's end or **Disarm now** - and this version's only downlink is the null one, which keeps every command on record and sends none, because no vendor's downlink protocol ships with it. From a terminal: `gea workspace --path C:\site --action driller-pull --box http://192.168.1.60:8790 --well SWD-1`; on the rig PC `gea-driller sim --seed 7 --pace 3 --port 8790`, `gea-driller evaluate --scenes 20`, `gea-driller train --seconds 600 --out policy.json`, `gea-driller selftest`.
|
|
6
6
|
|
|
7
7
|
**What it writes**: on the rig PC, `decisions.jsonl` (every observation, recommendation, confidence, reasons and answer), `commands.jsonl` (every arming, command and disarming with its reason) and `surveys.csv`, each with a `.sha256` beside it, and `manifest.json`. In GEA, `wells\SWD-1\driller\` holds the same files as pulled, `manifest.json` and `last_pull.json` with the summary; the audit lines `driller.pull`, `driller.sim_start`, `driller.sim_stop`. The twin as the rig writes under `field\sim-driller\data`.
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> GEA-Program-Setup: the program installed for you like any Windows program - a window of its own, an icon in the notification area, Start-menu and desktop shortcuts, an Add/Remove Programs entry, upgrades in place - with no administrator rights and the site's data left where it is.
|
|
4
4
|
|
|
5
|
-
**The command**: download the setup from the release on GitHub (`GEA-Program-Setup-0.
|
|
5
|
+
**The command**: download the setup from the release on GitHub (`GEA-Program-Setup-0.85.0.exe` for this version) and run it. It installs for you alone, under `%LOCALAPPDATA%\Programs\GEA-Program`, and asks for the site workspace - the folder that holds the wells, reports, records, accounts and keys. An existing one such as `C:\site` is used exactly as it is, its name included; for a new one (by default `%LOCALAPPDATA%\GEA-Program\site`) it also asks the site's name, which heads every report, and makes the workspace with it (left empty, the workspace is named after its folder; an administrator renames the site in Administration's site settings). Then the Start menu's **GEA-Program** (and the desktop shortcut) starts the control panel when it is not running and opens it in a window of its own. A newer setup installs over the older one: it stops the control panel, replaces the program, keeps the workspace and the choices made before. For a site's software deployment: `GEA-Program-Setup-0.85.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"` (`/SITENAME` names a workspace the setup makes; one that exists keeps its own name). From a terminal: `gea launch` does what the shortcut does, `gea launch --selftest` says what it would do, `gea tray --selftest` checks the icon.
|
|
6
6
|
|
|
7
7
|
**The window**: Microsoft Edge's app window (`msedge --app=`: the control panel with no tabs and no address bar, its own button on the taskbar, which shows the program's derrick and pins as GEA-Program, not as Edge), with a browser profile of its own (`%LOCALAPPDATA%\GEA-Program\window`, no extensions; the first time, Edge may say it signed that profile in to your Microsoft account - Got it), else Google Chrome's, else a tab in the default browser. Where the browser keeps no cookies (its settings or a policy block them), the sign-in page says so and the control panel holds the sign-in itself, in the window's address, until the window is closed. The control panel itself runs with no window of its own: `gea supervise` keeps it running in the background, starts it again when it asks for a restart, and writes everything it would have shown in a console - the start, the sign-ins, the jobs, a stop and why - to `records\console.log` in the workspace. No PowerShell or console window opens. The kit's `start-dashboard.cmd` still runs it in a console window, for a site that wants to watch it there.
|
|
8
8
|
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
**The number to check**: Add/Remove Programs lists GEA-Program with the version you installed; `gea doctor --workspace C:\site` ends with `nothing blocks serving`; the Start menu's **Verify GEA-Program** runs the acceptance gate from the installation and ends with `[ACCEPTANCE] OK - N checks passed`. The release's build installs, upgrades and uninstalls the setup silently before it is published, with the control panel running, and checks the workspace untouched afterwards.
|
|
20
20
|
|
|
21
|
-
**Signed**: when the publisher's code-signing certificate is configured for the build, the setup is signed with it (Authenticode, timestamped) and Windows names the publisher; until then it ships unsigned and Windows SmartScreen says "unknown publisher" (More info, then Run anyway). The build's provenance holds either way: `gh attestation verify GEA-Program-Setup-0.
|
|
21
|
+
**Signed**: when the publisher's code-signing certificate is configured for the build, the setup is signed with it (Authenticode, timestamped) and Windows names the publisher; until then it ships unsigned and Windows SmartScreen says "unknown publisher" (More info, then Run anyway). The build's provenance holds either way: `gh attestation verify GEA-Program-Setup-0.85.0.exe -R Daniel8Murphy0007/GEA-Program`. The uninstaller the setup leaves behind is Inno Setup's own and is not signed separately.
|
|
22
22
|
|
|
23
23
|
**What this page will not call a measurement**: the icon's running or stopped is whether the control panel's port answers on this computer, read every three seconds - not whether every patch, job or report behind it is healthy (Home and the Verification page say that).
|
|
24
24
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Pressure plume
|
|
2
|
+
|
|
3
|
+
> Where the ledger's barrels have raised the formation's pressure, on a grid, through time - a SIMULATION. The Fluid balance tab's daily volumes go into the declared formation on a plan grid centred on the injection well and the pressure is stepped forward day by day; the rise is drawn as contours at every month's end of the record and a year on, both if the wells continue at their last rates and if they shut in now; the cells over a declared threshold are the area of review, in acres and reach; every mapped fault within the radius is read for its rise and its slip tendency at each snapshot, and the first day its margin to the friction line would be used up. A projection on a uniform declared formation, to be checked against a neighbour's gauge - never a reading of one.
|
|
4
|
+
|
|
5
|
+
**The command**: the Pressure plume tab, once the Fluid balance tab has an injection well with a formation, a volume record and a surface position, and the formation has its permeability, thickness and porosity declared. Pick a snapshot to draw it in plan; the faults are solid when declared sealing and dashed when open, amber inside the area of review and red past the friction line. Settings: the threshold (50 psi unless changed), the grid's cells per side, the radius the faults are taken within, how far to project; a fault layer is declared SEALING with its source, and is OPEN otherwise, because a map says nothing about what a fault does to flow. The 3D tab draws the same contours at the declared top of the disposal interval. From a terminal: `gea plume --workspace C:\site` prints the snapshots; `gea plume --workspace C:\site --threshold-psi 25 --cells 101 --radius-km 15 --projection-days 730` keeps settings; `gea plume --workspace C:\site --sealing Hennings-2021-basement-faults --source "the operator's fault study 2025"` declares a layer sealing (`--open` undoes it); `gea plume --workspace C:\site --write` writes the report; `gea plume` alone runs the self-test.
|
|
6
|
+
|
|
7
|
+
**What it writes**: `records/plume.json` (the settings and the sealing declarations with their source) in the workspace; with `--write` or the button, `reports/plume/plume.json` and `.md`; the signed dossier carries `results/plume.json` (every snapshot's figures, without the contour coordinates) beside `results/fluid_balance.json`; the settings and the report are lines in the audit log.
|
|
8
|
+
|
|
9
|
+
**The arithmetic**: single-phase, slightly compressible flow in field units on a square grid of cells of side dx (ft) centred on the injection well in a local transverse Mercator frame. A cell stores V_p c_t = dx^2 h phi c_t / 5.6146 barrels per psi; two cells exchange T = 0.001127 k A / (mu L) barrels per day per psi, A = h dx and L = dx, the harmonic mean of k h across the face; the formation is uniform in k, h and phi (a map of either is the next step, and the page says they are uniform). Each day every well's barrels go into its cell as a source and the pressure is advanced explicitly in sub-steps kept under the stability limit (0.45 of the smallest cell's storage over its transmissibilities); the grid's edge holds the initial pressure and lies 2 x the radius of investigation at the end of the projection out, or 2,000 ft beyond the farthest well. A sealing fault zeroes the transmissibility of every face between two cells on opposite sides of its segments. The area of review counts the cells at or above the threshold (acres = cells x dx^2 / 43,560) and its reach is the farthest such cell from the injection well. Each fault's rise is the largest cell value along its segments; its slip tendency is `slip`'s arithmetic (Morris 1996 Ts; the pressure to slip at the declared friction) with that rise as the pore-pressure increase, at the declared gradients and SHmax azimuth, for the layer's own dip or the declared dips. The projections start from the last day's field: CONTINUED holds each well's last thirty days' mean rate, SHUT IN sets every rate to zero. The grid is checked against the line source (Theis) at 4 and 8 cells from the main well at the end of the record, on the page, and on a uniform grid at a constant rate in the self-test (within 6 % at 3, 6 and 10 cells).
|
|
10
|
+
|
|
11
|
+
**The number to check**: the balance line - the barrels the grid holds as pressure against the barrels put in (the difference left through the edge, or the storage a sealed fault denied); the page's line-source comparison; on the self-test, the symmetric field, the contour at the 6-cell rise a circle of 6 cells' radius, the area of review within 15 % of pi r^2, the far side of a sealing fault shaded and the near side piled up.
|
|
12
|
+
|
|
13
|
+
**What this page will not call a measurement**: any of it - the plume is a projection on declared numbers, labelled SIMULATION on every line, and a neighbour's own gauge is the check (the calibration against it is the next module); the pressure at the injection well itself (its cell is an average over the cell, not the wellbore); a fault sealing or open (declared, default open, said in the table); a fault's depth, dip or activity beyond what the layer states; the area of review as a regulatory boundary (the threshold is the site's declaration, and the Commission's own rule for the well governs); heterogeneity it has no map of.
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
|
|
5
5
|
**The command**: Reports tab -> Signed dossiers -> **Download GEA Reader for your clients**, or `gea reader --workspace C:\site --out C:\site\GEA-Reader.html`. Send the file once, by any channel (email, a USB stick, the client's portal); send the site's key fingerprint separately - by phone, email or in the contract - as for any dossier. The client opens GEA-Reader.html, drops a dossier on it (or chooses it), and reads the verdict: **Valid** (signed with the site's key, or with a newer key the site's key handed over to), **Valid, but signed by a key you were not given**, or **Not valid** with the reason. Below the verdict: each check, the signer's fingerprint, the key hand-overs, and every file the dossier holds - a report opens in the page as it was signed, a PDF in the browser's own viewer, a table or a log as text, and any file can be saved. A dossier that lists source records by hash without carrying them lets the client choose their copies and checks each against its hash.
|
|
6
6
|
|
|
7
|
-
**The program**: for a client who wants it installed, **GEA-Reader-Setup-0.
|
|
7
|
+
**The program**: for a client who wants it installed, **GEA-Reader-Setup-0.85.0.exe** on the release page installs GEA Reader as a Windows program of its own, for the signed-in user, with no administrator rights and nothing of GEA-Program: GEA Reader in the Start menu and on the desktop with its own icon (a white page with a green seal, on blue) and its own taskbar button, and **Check with GEA Reader** on the right-click menu of .zip files (on Windows 11, under Show more options), which opens the dossier at once. It opens the same page in Microsoft Edge's app window with a browser profile of its own (`%LOCALAPPDATA%\GEA-Reader\window`), so a fingerprint the client saves - **Remember this fingerprint**, with whose it is - stays on that computer, and every later dossier signed with that key reads **Valid** with the name the client gave it. `GEA-Reader-portable-0.85.0.zip` is the same program to unzip and run (`GEA-Reader.cmd`). `python\python.exe -m gea_reader --selftest`, in the installed folder, checks the page, the icon, the taskbar identity and the hand-over of a dossier without opening a window.
|
|
8
8
|
|
|
9
9
|
**What it writes**: the one file, GEA-Reader.html (about 40 KB): the checks, written in the page's own script - Ed25519 (RFC 8032) in its own arithmetic, SHA-256 from the browser - and, when made from a workspace, the site's name and the fingerprints of every key it has signed with (the current one and each retired one from the key history: public halves only; the signing key never leaves `keys\`). The audit log records each download (`reader.download`) and each `gea reader` (`reader.write`) with the fingerprints the reader carried. The reader page writes nothing on the client's computer but the fingerprints a client saves (in the browser's storage for the page): it reads the zip it is given, in memory, and a saved copy goes where the client's browser saves downloads. The installed program also writes the page it opens to `%LOCALAPPDATA%\GEA-Reader\page` (with the dossier inside it when one was right-clicked; removed ten minutes later) and its right-click entry under the user's own registry keys, removed with the program.
|
|
10
10
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> GEA Recorder is the program on the pad: a Raspberry Pi in a sealed box that records the ground channels (geophones, accelerometers, electrode dipoles) through a 24-bit ADC and the rig's WITS0 feed, every sample on one GPS-disciplined clock, into hourly miniSEED files with a SHA-256 beside each and a manifest, and serves one status page on the pad network. Nothing to type: power it and it records. GEA pulls its files in and makes stations of them.
|
|
4
4
|
|
|
5
|
-
**The command**: the **Seismic** tab, the card **Field recorder**: the box's address on the pad network (`http://192.168.1.50:8780` - the status page shows the address) or the folder of the USB mirror carried to the office, a station name if the site's is not wanted, then **Pull** (a job). GEA fetches the manifest, downloads every file it does not have, checks each against its SHA-256, and makes or updates two stations: the array of the ground-motion sensors (band 8-80 Hz, the sensors' positions from the box's config) and the electrode station (0.01-5 Hz); each sensor's hours are joined in order into one record, nothing re-sampled or filtered. Pull again later: only the new hours come across, and the stations are updated in place. From a terminal: `gea workspace --path C:\site --action field-pull --box http://192.168.1.50:8780`. On the box: `gea-recorder status`, `gea-recorder selftest`; `sudo sh kiosk.sh` once puts the live view full-screen on a monitor on the box's HDMI port from boot - RECORDING in green or what is wrong in red, the clock, the rig's depth, every channel's last minute and the ground sensors' spectrogram, nothing to press - and the same view is at `/live` on the box's page from any browser on the pad network; `sudo sh install.sh` once, from the release's `GEA-Recorder-0.
|
|
5
|
+
**The command**: the **Seismic** tab, the card **Field recorder**: the box's address on the pad network (`http://192.168.1.50:8780` - the status page shows the address) or the folder of the USB mirror carried to the office, a station name if the site's is not wanted, then **Pull** (a job). GEA fetches the manifest, downloads every file it does not have, checks each against its SHA-256, and makes or updates two stations: the array of the ground-motion sensors (band 8-80 Hz, the sensors' positions from the box's config) and the electrode station (0.01-5 Hz); each sensor's hours are joined in order into one record, nothing re-sampled or filtered. Pull again later: only the new hours come across, and the stations are updated in place. From a terminal: `gea workspace --path C:\site --action field-pull --box http://192.168.1.50:8780`. On the box: `gea-recorder status`, `gea-recorder selftest`; `sudo sh kiosk.sh` once puts the live view full-screen on a monitor on the box's HDMI port from boot - RECORDING in green or what is wrong in red, the clock, the rig's depth, every channel's last minute and the ground sensors' spectrogram, nothing to press - and the same view is at `/live` on the box's page from any browser on the pad network; `sudo sh install.sh` once, from the release's `GEA-Recorder-0.85.0.tar.gz`; the box's README has the parts list, the wiring and the three chrony lines for the GPS clock.
|
|
6
6
|
|
|
7
7
|
**Before there is a Pi**: on the same card, **Start the simulated box**: the recorder's own program runs on this computer with its test signal in place of the ADC (a process of its own, its files under `field\sim-box\` in the workspace, its page on port 8781), **Open its monitor** shows the live screen the attendant will see, **Pull from it** brings its files in as stations, **Stop it** closes every file and lists them. **Open the box's monitor** opens any real box's live screen from its address. The kit and the setup install the recorder's program beside GEA for this; a pip install adds it with `pip install gea-recorder`. **From the office, over the internet**: GEA-VPN (`gea help vpn`, Administration) gives every box a private address the office pulls from (`http://10.77.0.3:8780`) through a tunnel from the pad's cellular modem; the box's zip from that card holds `vpn.sh`, run once on the Pi.
|
|
8
8
|
|