gea-program 0.90.0__tar.gz → 0.91.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.90.0 → gea_program-0.91.0}/PKG-INFO +44 -4
- {gea_program-0.90.0 → gea_program-0.91.0}/README.md +43 -3
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/__init__.py +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/__main__.py +57 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/acceptance_tests.py +274 -6
- gea_program-0.91.0/gea/frac_treatment.py +1224 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/driller.md +1 -1
- gea_program-0.91.0/gea/help/frac-treatment.md +13 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/install.md +2 -2
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/mcp.md +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/public-data.md +2 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/reader.md +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/recorder.md +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/01-install.md +2 -2
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/14-production-pages.md +12 -11
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/19-dossier-reader.md +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/22-updates.md +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/23-vpn.md +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/25-install-recorder.md +2 -2
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/29-driller-rig.md +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial.md +2 -2
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/helplib.py +2 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/mcp_server.py +14 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/public_pad.py +163 -5
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/service.py +22 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/web/app.html +128 -2
- {gea_program-0.90.0 → gea_program-0.91.0}/gea_program.egg-info/PKG-INFO +44 -4
- {gea_program-0.90.0 → gea_program-0.91.0}/gea_program.egg-info/SOURCES.txt +2 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/pyproject.toml +1 -1
- {gea_program-0.90.0 → gea_program-0.91.0}/LICENSE +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/alerts.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/backup.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/bench.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/benchmark.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/bit_seismic.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/blind_harness.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/calibration.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/casing_design.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog_map.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/catalog_register.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/certificates.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/cli.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/client_reports.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/collision.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/config_versioning.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/conformance.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/control_room.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/correlation.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/dashboard.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/declarations.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/decline.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/deviation.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/dlis.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/dnp3.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/doctor.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/dossier.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/dossier_verify.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/drill_string.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/driller_link.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/dysfunction.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/earth_model.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/economics.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/ed25519.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/edr.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/elevation.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/etp.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/example_register_map.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/fat_sat.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/field_pull.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/files.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/fluid.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/follower.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/forward_model.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/frac_hits.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/friction_priors.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/front.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/gamma.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/geodesy.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/geomag.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/hartip.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/IT_SECURITY.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/alarms.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/alerts.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/backup.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/benchmark.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/bit-image.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/calibration.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/casing.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/catalog.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/charts.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/collision.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/company-sign-in.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/conformance.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/control-room.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/data-in.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/declare.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/decline.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/dlis.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/doctor.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/dossier.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/drift.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/dysfunction.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/economics.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/edr.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/etp.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/files.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/fluid.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/frac-hits.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/front.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/historian.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/https.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/hydraulics.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/instruments.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/interval.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/invoice-check.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/map.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/month-end.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/notifications.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/opseis.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/osdu.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/patches.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/plan.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/plume.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/pore-pressure.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/quality.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/records.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/report-history.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/rig-time.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/roadmap.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/rocks.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/seismic.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/setup.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/simulation.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/site.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/sites.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/slip.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/soak.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/sra.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/start.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/structure.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tools.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/torque-drag.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/transients.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/02-sign-in.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/03-site.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/04-add-well.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/05-records.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/06-well-page.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/07-declare.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/08-patches.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/09-alarms.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/10-control-room.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/11-summary-month.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/12-where-the-well-is.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/13-drilling-pages.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/15-seismic.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/16-seismicity.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/17-recorder-office.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/18-reports.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/20-admin.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/21-upkeep.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/24-the-box.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/26-monitor.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/27-mirror-vpn.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/tutorial/28-driller-office.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/vibration.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/vpn.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/well-report.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/help/well3d.md +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/housekeeping.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/hydraulics.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/icon.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/interval.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/invoice_check.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/jobs.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/launcher.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/live_ports.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/loadtest.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/modbus.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/model_card.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/month_end.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/notify.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/oidc.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/oidc_mock.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/opcua_port.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/operator_app.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/osdu.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/pad_summary.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/patches.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/pdf_report.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/penetrator.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/permits.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/piwebapi.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/plume.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/pore_pressure.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/ports.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/ppdm.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/project.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/quakeml.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reader.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reader_app.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reconciler.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/recorder_link.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/WMM2025.COF +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/iscwsa_rev4_example.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/iscwsa_rev5_example.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/owsg_tool_models.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/report_history.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/rig_state.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/roadmap.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/sample_record.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/sbom.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seedlink.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/segy.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_array.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_film.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_response.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_track.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/series_cache.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/service_life.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/shapefile.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/shell.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/shut_in.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/simulation.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/site_map.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/sla_report.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/slip.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/soak.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/sra.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/store_forward.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/strata_join.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/structure.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/supervisor.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/survey_view.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/telemetry.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/timestamp.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/tls.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/tool_library.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/torque_drag.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/transient.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/tray.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/tutorial.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/updates.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/vibration.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/vpn.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/web/reader.html +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/well3d.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/well_assembler.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/well_records.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/well_report.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/wellplan.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/wellpos.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/winident.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/wits0.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/witsml.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/workspace.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/workspaces.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/x25519.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea/xlsx_read.py +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.90.0 → gea_program-0.91.0}/setup.cfg +0 -0
- {gea_program-0.90.0 → gea_program-0.91.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.91.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.91.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`.
|
|
@@ -934,6 +934,26 @@ the window. The Dutch offshore well L07-01 (NLOG open data) is the worked
|
|
|
934
934
|
example. The **Pore pressure** tab, `gea pore-pressure`,
|
|
935
935
|
`gea help pore-pressure`.
|
|
936
936
|
|
|
937
|
+
### Frac treatment
|
|
938
|
+
|
|
939
|
+
Each fracturing stage from its own pumping record - the treating pressure,
|
|
940
|
+
the slurry rate and the proppant concentration, second by second, as the
|
|
941
|
+
frac service company gave them (a spreadsheet with its stacked header, a
|
|
942
|
+
frac van's data-acquisition export, or a plain CSV). With nothing fitted to
|
|
943
|
+
a model of the fracture, the page reads what was pumped beside the record's
|
|
944
|
+
own totalisers; the ISIP - a straight line fitted to the pressure after the
|
|
945
|
+
ringing has died down and read back to the moment the rate reached zero,
|
|
946
|
+
over three windows, with the spread between them as its range; the friction
|
|
947
|
+
at the last rate held, and where the rate was stepped down its two parts,
|
|
948
|
+
one with the square of the rate (the pipe and the perforations) and one
|
|
949
|
+
with its root (the path just outside the wellbore); the pressure at 5, 10
|
|
950
|
+
and 15 minutes and against Nolte's G, with a closure candidate offered only
|
|
951
|
+
where the record supports one; and a step-rate test where there was one.
|
|
952
|
+
With the depth of the perforations declared, the bottomhole ISIP and its
|
|
953
|
+
gradient. It hands the Frac hits tab each stage's times. The **Frac
|
|
954
|
+
treatment** tab, `gea frac-treatment`, `gea help frac-treatment`; an
|
|
955
|
+
assistant reads it as the `frac_treatment` tool.
|
|
956
|
+
|
|
937
957
|
### Frac hits
|
|
938
958
|
|
|
939
959
|
What each fracturing stage did to the pressure in the wells around it. A
|
|
@@ -1125,6 +1145,26 @@ that one well's parameters are not the next well's roadmap. The drilling
|
|
|
1125
1145
|
alerts, replayed, find 27 motor stalls on the three wells whose records
|
|
1126
1146
|
can show one, three falls in off-bottom pressure on 78B-32 that no trip followed
|
|
1127
1147
|
and one on 58-32 that a trip out of the hole followed within twelve hours.
|
|
1148
|
+
|
|
1149
|
+
The same site takes the published pumping records of the two deviated
|
|
1150
|
+
wells' stimulation - three stages on 16A(78)-32 in April 2022, nine more
|
|
1151
|
+
and four on 16B(78)-32 in April 2024 - when those files are in the folder
|
|
1152
|
+
too, and the Frac treatment tab reads all sixteen: 132,132 bbl of slurry
|
|
1153
|
+
and 2,969,800 lbm of proppant by the records' own rates, fifteen of the
|
|
1154
|
+
sixteen volumes within 0.6 % of the record's own totaliser (the sixteenth
|
|
1155
|
+
3.6 % under it: that totaliser also counted the lines being primed); an
|
|
1156
|
+
ISIP at every stage, 3,289 to 5,664 psi at the surface; thirteen stages
|
|
1157
|
+
stepped down to the shut-in. The service company's reports are published with the
|
|
1158
|
+
2022 stages, so the page can be checked against them: for stage 1 the
|
|
1159
|
+
company gives a final ISIP of 4,019 psi and 3,715, 3,582 and 3,501 psi
|
|
1160
|
+
after 5, 10 and 15 minutes, and this page reads 3,985 psi (3,975 to 3,997)
|
|
1161
|
+
and 3,720, 3,585 and 3,486; for stage 2, 3,918 psi and 3,664, 3,565 and
|
|
1162
|
+
3,506 against 3,859 (3,852 to 3,862) and 3,665, 3,572 and 3,508. The page's
|
|
1163
|
+
ISIP is the lower because it is read back along the decline, not taken at
|
|
1164
|
+
the top of the ringing. No
|
|
1165
|
+
stage's fall-off shows a closure: the records stop a quarter of an hour
|
|
1166
|
+
after the pumps, and the page says so and offers none.
|
|
1167
|
+
|
|
1128
1168
|
Data: Utah FORGE, Energy & Geoscience Institute at the University of Utah,
|
|
1129
1169
|
funded by the U.S. Department of Energy; Geothermal Data Repository,
|
|
1130
1170
|
gdr.openei.org; CC BY 4.0. The **Public data** tab, `gea public-pad`,
|
|
@@ -1794,7 +1834,7 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1794
1834
|
|
|
1795
1835
|
### The Windows installer
|
|
1796
1836
|
|
|
1797
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1837
|
+
Every release also carries `GEA-Program-Setup-0.91.0.exe` (for 0.91.0): the
|
|
1798
1838
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1799
1839
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1800
1840
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
@@ -1813,7 +1853,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1813
1853
|
software deployment:
|
|
1814
1854
|
|
|
1815
1855
|
```
|
|
1816
|
-
GEA-Program-Setup-0.
|
|
1856
|
+
GEA-Program-Setup-0.91.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1817
1857
|
```
|
|
1818
1858
|
|
|
1819
1859
|
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.91.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`.
|
|
@@ -895,6 +895,26 @@ the window. The Dutch offshore well L07-01 (NLOG open data) is the worked
|
|
|
895
895
|
example. The **Pore pressure** tab, `gea pore-pressure`,
|
|
896
896
|
`gea help pore-pressure`.
|
|
897
897
|
|
|
898
|
+
### Frac treatment
|
|
899
|
+
|
|
900
|
+
Each fracturing stage from its own pumping record - the treating pressure,
|
|
901
|
+
the slurry rate and the proppant concentration, second by second, as the
|
|
902
|
+
frac service company gave them (a spreadsheet with its stacked header, a
|
|
903
|
+
frac van's data-acquisition export, or a plain CSV). With nothing fitted to
|
|
904
|
+
a model of the fracture, the page reads what was pumped beside the record's
|
|
905
|
+
own totalisers; the ISIP - a straight line fitted to the pressure after the
|
|
906
|
+
ringing has died down and read back to the moment the rate reached zero,
|
|
907
|
+
over three windows, with the spread between them as its range; the friction
|
|
908
|
+
at the last rate held, and where the rate was stepped down its two parts,
|
|
909
|
+
one with the square of the rate (the pipe and the perforations) and one
|
|
910
|
+
with its root (the path just outside the wellbore); the pressure at 5, 10
|
|
911
|
+
and 15 minutes and against Nolte's G, with a closure candidate offered only
|
|
912
|
+
where the record supports one; and a step-rate test where there was one.
|
|
913
|
+
With the depth of the perforations declared, the bottomhole ISIP and its
|
|
914
|
+
gradient. It hands the Frac hits tab each stage's times. The **Frac
|
|
915
|
+
treatment** tab, `gea frac-treatment`, `gea help frac-treatment`; an
|
|
916
|
+
assistant reads it as the `frac_treatment` tool.
|
|
917
|
+
|
|
898
918
|
### Frac hits
|
|
899
919
|
|
|
900
920
|
What each fracturing stage did to the pressure in the wells around it. A
|
|
@@ -1086,6 +1106,26 @@ that one well's parameters are not the next well's roadmap. The drilling
|
|
|
1086
1106
|
alerts, replayed, find 27 motor stalls on the three wells whose records
|
|
1087
1107
|
can show one, three falls in off-bottom pressure on 78B-32 that no trip followed
|
|
1088
1108
|
and one on 58-32 that a trip out of the hole followed within twelve hours.
|
|
1109
|
+
|
|
1110
|
+
The same site takes the published pumping records of the two deviated
|
|
1111
|
+
wells' stimulation - three stages on 16A(78)-32 in April 2022, nine more
|
|
1112
|
+
and four on 16B(78)-32 in April 2024 - when those files are in the folder
|
|
1113
|
+
too, and the Frac treatment tab reads all sixteen: 132,132 bbl of slurry
|
|
1114
|
+
and 2,969,800 lbm of proppant by the records' own rates, fifteen of the
|
|
1115
|
+
sixteen volumes within 0.6 % of the record's own totaliser (the sixteenth
|
|
1116
|
+
3.6 % under it: that totaliser also counted the lines being primed); an
|
|
1117
|
+
ISIP at every stage, 3,289 to 5,664 psi at the surface; thirteen stages
|
|
1118
|
+
stepped down to the shut-in. The service company's reports are published with the
|
|
1119
|
+
2022 stages, so the page can be checked against them: for stage 1 the
|
|
1120
|
+
company gives a final ISIP of 4,019 psi and 3,715, 3,582 and 3,501 psi
|
|
1121
|
+
after 5, 10 and 15 minutes, and this page reads 3,985 psi (3,975 to 3,997)
|
|
1122
|
+
and 3,720, 3,585 and 3,486; for stage 2, 3,918 psi and 3,664, 3,565 and
|
|
1123
|
+
3,506 against 3,859 (3,852 to 3,862) and 3,665, 3,572 and 3,508. The page's
|
|
1124
|
+
ISIP is the lower because it is read back along the decline, not taken at
|
|
1125
|
+
the top of the ringing. No
|
|
1126
|
+
stage's fall-off shows a closure: the records stop a quarter of an hour
|
|
1127
|
+
after the pumps, and the page says so and offers none.
|
|
1128
|
+
|
|
1089
1129
|
Data: Utah FORGE, Energy & Geoscience Institute at the University of Utah,
|
|
1090
1130
|
funded by the U.S. Department of Energy; Geothermal Data Repository,
|
|
1091
1131
|
gdr.openei.org; CC BY 4.0. The **Public data** tab, `gea public-pad`,
|
|
@@ -1755,7 +1795,7 @@ attaches the zips to the GitHub release of that tag.
|
|
|
1755
1795
|
|
|
1756
1796
|
### The Windows installer
|
|
1757
1797
|
|
|
1758
|
-
Every release also carries `GEA-Program-Setup-0.
|
|
1798
|
+
Every release also carries `GEA-Program-Setup-0.91.0.exe` (for 0.91.0): the
|
|
1759
1799
|
same Windows kit installed like any Windows program, for the signed-in user
|
|
1760
1800
|
alone and with no administrator rights (`%LOCALAPPDATA%\Programs\GEA-Program`).
|
|
1761
1801
|
It asks for the site workspace (an existing one such as `C:\site` is used as
|
|
@@ -1774,7 +1814,7 @@ it, removes the program and leaves the workspace. Silent, for a site's
|
|
|
1774
1814
|
software deployment:
|
|
1775
1815
|
|
|
1776
1816
|
```
|
|
1777
|
-
GEA-Program-Setup-0.
|
|
1817
|
+
GEA-Program-Setup-0.91.0.exe /VERYSILENT /SUPPRESSMSGBOXES /NORESTART /WORKSPACE="C:\site" /SITENAME="Pad 3" /TASKS="desktopicon"
|
|
1778
1818
|
```
|
|
1779
1819
|
|
|
1780
1820
|
The setup is built by Inno Setup 6 from `tools/installer.iss` in the same
|
|
@@ -682,6 +682,19 @@ def main(argv=None) -> int:
|
|
|
682
682
|
p_bm.add_argument("--write", action="store_true", help="write reports/benchmark/benchmark.json, .md, .csv and stretches.csv")
|
|
683
683
|
p_bm.add_argument("--actor", type=str, default="cli")
|
|
684
684
|
p_bm.add_argument("--json", action="store_true")
|
|
685
|
+
p_ft = sub.add_parser("frac-treatment", help="each fracturing stage from its own pumping record: what was pumped, the ISIP read back through the ringing with its range, the friction and its two parts from a step-down, the fall-off against G, a step-rate test - nothing fitted to a model of the fracture")
|
|
686
|
+
p_ft.add_argument("--workspace", type=str, default=None, help="the workspace folder; without one the self-test runs (stages built with every answer known)")
|
|
687
|
+
p_ft.add_argument("--well", type=str, default=None, help="a well, by its name or id: with --stage, that stage in full")
|
|
688
|
+
p_ft.add_argument("--stage", type=str, default=None, help="the stage (1, 3R, 6A)")
|
|
689
|
+
p_ft.add_argument("--attach", type=str, default=None, help="a stage's treatment record to keep (CSV or Excel: the pressure, the rate and the proppant, second by second); needs --well, --stage and --source")
|
|
690
|
+
p_ft.add_argument("--start", type=str, default=None, help="--attach: the record's first moment, for a file that only has elapsed time (2026-08-03T06:00:00)")
|
|
691
|
+
p_ft.add_argument("--tvd", type=float, default=None, help="declare the true vertical depth of the perforations, ft: for --stage, or every stage of --well; needs --source")
|
|
692
|
+
p_ft.add_argument("--fluid", type=float, default=None, help="with --tvd: the gradient of the fluid in the well at the shut-in, psi/ft (fresh water, 0.433, when not given)")
|
|
693
|
+
p_ft.add_argument("--source", type=str, default="", help="where the record, or the depth, came from")
|
|
694
|
+
p_ft.add_argument("--to-frac-hits", action="store_true", help="give the Frac hits page --well's stage times, read from these records")
|
|
695
|
+
p_ft.add_argument("--write", action="store_true", help="write reports/frac_treatment/frac_treatment.json, .md, stages.csv and a stage table a well")
|
|
696
|
+
p_ft.add_argument("--actor", type=str, default="cli")
|
|
697
|
+
p_ft.add_argument("--json", action="store_true")
|
|
685
698
|
p_pp = sub.add_parser("public-pad", help="a real pad from public data: the Utah FORGE wells' published rig recorders (CC BY 4.0) made into a site of their own - the files to get and where, checked against their sizes and hashes, converted and attached; the program fetches nothing")
|
|
686
699
|
p_pp.add_argument("--folder", type=str, default=None, help="the folder the downloaded files are in; with nothing else, lists each file and whether it is there. Without a folder the self-test runs (stand-ins in each published layout)")
|
|
687
700
|
p_pp.add_argument("--verify", action="store_true", help="hash each file that is there against the SHA-256 this release was checked with")
|
|
@@ -3609,6 +3622,48 @@ def main(argv=None) -> int:
|
|
|
3609
3622
|
raise SystemExit(f"benchmark: {e.args[0] if e.args else e}")
|
|
3610
3623
|
print(_json.dumps(p, default=str) if a.json else _BM.text(p))
|
|
3611
3624
|
return 0
|
|
3625
|
+
elif a.cmd == "frac-treatment":
|
|
3626
|
+
import json as _json
|
|
3627
|
+
from . import frac_treatment as _FT
|
|
3628
|
+
from .cli import _safe_stdout
|
|
3629
|
+
from .workspace import Workspace, WorkspaceError
|
|
3630
|
+
_safe_stdout()
|
|
3631
|
+
if not a.workspace:
|
|
3632
|
+
r = _FT.selftest()
|
|
3633
|
+
print("\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']}")
|
|
3634
|
+
return 0 if r["ok"] else 1
|
|
3635
|
+
try:
|
|
3636
|
+
ws = Workspace(a.workspace)
|
|
3637
|
+
wid = None
|
|
3638
|
+
if a.well:
|
|
3639
|
+
wid = next((w["id"] for w in ws.wells() if a.well in (w["id"], w.get("display"))), None)
|
|
3640
|
+
if wid is None:
|
|
3641
|
+
raise SystemExit(f"frac-treatment: no well {a.well!r} in this workspace")
|
|
3642
|
+
if a.attach:
|
|
3643
|
+
if not (wid and a.stage):
|
|
3644
|
+
raise SystemExit("frac-treatment: --attach needs --well and --stage")
|
|
3645
|
+
with open(a.attach, "rb") as f_:
|
|
3646
|
+
m_ = _FT.attach(ws, wid, a.stage, a.attach, f_.read(), a.actor, a.source, a.start)
|
|
3647
|
+
print(f"kept: stage {m_['stage']}, {m_['samples']:,} samples from {m_['start'] or 'its first sample'} ({m_['layout']}); read as " + ", ".join(f"{k}: {v}" for k, v in m_["read_as"].items()))
|
|
3648
|
+
if a.tvd is not None:
|
|
3649
|
+
if not wid:
|
|
3650
|
+
raise SystemExit("frac-treatment: --tvd needs --well")
|
|
3651
|
+
d_ = _FT.declare(ws, wid, a.actor, a.source, a.tvd, a.fluid, a.stage)
|
|
3652
|
+
print(f"declared for stage {', '.join(d_['stages'])}: perforations at {d_['tvd_ft']:,.0f} ft TVD, fluid {d_['fluid_psi_ft']:g} psi/ft")
|
|
3653
|
+
if a.to_frac_hits:
|
|
3654
|
+
if not wid:
|
|
3655
|
+
raise SystemExit("frac-treatment: --to-frac-hits needs --well")
|
|
3656
|
+
h_ = _FT.to_frac_hits(ws, wid, a.actor)
|
|
3657
|
+
print(f"the Frac hits page has {h_['stages']} stage(s) for this well, {h_['first'][:16]} to {h_['last'][:16]}")
|
|
3658
|
+
if a.write:
|
|
3659
|
+
from . import __version__ as _ver91
|
|
3660
|
+
r = _FT.write_report(ws, _ver91, a.actor)
|
|
3661
|
+
print(f"written: {', '.join(r['files'])} under {r['folder']}")
|
|
3662
|
+
p = _FT.page(ws, wid, a.stage)
|
|
3663
|
+
except (_FT.TreatmentError, WorkspaceError, KeyError, ValueError, OSError) as e:
|
|
3664
|
+
raise SystemExit(f"frac-treatment: {e.args[0] if e.args else e}")
|
|
3665
|
+
print(_json.dumps(p, default=str) if a.json else _FT.text(p))
|
|
3666
|
+
return 0
|
|
3612
3667
|
elif a.cmd == "public-pad":
|
|
3613
3668
|
import json as _json
|
|
3614
3669
|
from . import public_pad as _PP
|
|
@@ -3631,6 +3686,8 @@ def main(argv=None) -> int:
|
|
|
3631
3686
|
print(f" {d_.get('n', '')}/{d_.get('of', '')} {t_}", flush=True)
|
|
3632
3687
|
r = _PP.build(a.folder, a.site, a.actor, verify=True, progress=say_)
|
|
3633
3688
|
print(f"{r['name']} at {r['path']}: " + (f"added {', '.join(r['added'])}" if r["added"] else "nothing to add") + f"; it has {', '.join(r['wells'])}")
|
|
3689
|
+
if r.get("stages"):
|
|
3690
|
+
print(f" and the pumping record of {len(r['stages'])} stimulation stage(s): {', '.join(r['stages'])}")
|
|
3634
3691
|
for e_ in r["record"]["wells"]:
|
|
3635
3692
|
for n_ in e_["notes"]:
|
|
3636
3693
|
print(f" {e_['well']}: {n_}")
|
|
@@ -18763,7 +18763,7 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18763
18763
|
plain = MC._plain({"a": np.float64(1.5), "_work": [1, 2], "b": [np.int64(3), float("nan")], "c": np.arange(4), "d": (1, "x")})
|
|
18764
18764
|
c1 = {
|
|
18765
18765
|
"selftest": st["ok"] and len(st["checks"]) >= 7,
|
|
18766
|
-
"tools": len(defs) ==
|
|
18766
|
+
"tools": len(defs) == 25 and defs[0]["name"] == "site" and all(d_["annotations"]["readOnlyHint"] is True and d_["annotations"]["destructiveHint"] is False and d_["annotations"]["openWorldHint"] is False
|
|
18767
18767
|
and d_["inputSchema"]["type"] == "object" and d_["inputSchema"]["additionalProperties"] is False and d_["title"] for d_ in defs)
|
|
18768
18768
|
and "well" in defs[1]["inputSchema"]["properties"] and "json" in defs[2]["inputSchema"]["properties"] and "json" not in MC.tool_definition("help")["inputSchema"]["properties"]
|
|
18769
18769
|
and not [n_ for n_ in MC.NAMES if any(w_ in n_ for w_ in ("write", "set", "declare", "attach", "remove", "delete", "run"))],
|
|
@@ -18775,7 +18775,7 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18775
18775
|
failed1 = [k_ for k_, v in c1.items() if not v]
|
|
18776
18776
|
ok(not failed1,
|
|
18777
18777
|
"EH1 the MCP server: the self-test (a client of an earlier revision through its handshake and a client of revision 2026-07-28 statelessly, each listing and calling the tools; a line that is "
|
|
18778
|
-
"not JSON, a tool, a well, an argument and a method that do not exist, a batch; a withheld tool; the access log; an assistant's configuration file added to and restored); twenty-
|
|
18778
|
+
"not JSON, a tool, a well, an argument and a method that do not exist, a batch; a withheld tool; the access log; an assistant's configuration file added to and restored); twenty-five tools, "
|
|
18779
18779
|
"each read-only by its own declaration with its arguments closed, none named for a change; the revisions spoken; the command a client starts - the console interpreter, never the windowless "
|
|
18780
18780
|
"one; a page as plain JSON with the working arrays left out" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
18781
18781
|
|
|
@@ -18853,12 +18853,12 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18853
18853
|
and "SIMULATION" in answers["pressure_plume"]["text"].splitlines()[0] and "RIG-1" in answers["site"]["text"] and _ver in answers["site"]["text"],
|
|
18854
18854
|
"json": all(isinstance(v, (dict, list)) for n_, v in parsed.items() if n_ != "well") and parsed["well"] is None and as_json["well"]["is_error"] and parsed["roadmap"]["status"] == "OK" and not [k_ for k_ in parsed["rig_time"] if str(k_).startswith("_")]
|
|
18855
18855
|
and len(parsed["drilling_alerts"]["wells"]) == 2,
|
|
18856
|
-
"child_legacy": rc_o == 0 and len(out_o) == 4 and out_o[0]["result"]["protocolVersion"] == "2025-11-25" and len(out_o[1]["result"]["tools"]) ==
|
|
18856
|
+
"child_legacy": rc_o == 0 and len(out_o) == 4 and out_o[0]["result"]["protocolVersion"] == "2025-11-25" and len(out_o[1]["result"]["tools"]) == 25 and "resultType" not in out_o[1]["result"]
|
|
18857
18857
|
and out_o[2]["result"]["content"][0]["text"] == answers["rig_time"]["text"] and "motor stall" in out_o[3]["result"]["content"][0]["text"] and "Traceback" not in err_o,
|
|
18858
18858
|
"child_modern": rc_m == 0 and len(out_m) == 4 and out_m[0]["result"]["supportedVersions"] == list(MC.SUPPORTED) and out_m[1]["result"]["resultType"] == "complete"
|
|
18859
18859
|
and out_m[1]["result"]["cacheScope"] == "private" and out_m[2]["result"]["_meta"][MC.K_SERVER] == {"name": "gea-program", "title": "GEA-Program", "version": _ver}
|
|
18860
18860
|
and out_m[2]["result"]["isError"] is False and out_m[3]["error"]["code"] == -32022 and out_m[3]["error"]["data"]["requested"] == "2099-01-01" and "Traceback" not in err_m,
|
|
18861
|
-
"withheld": kept["tools"] is not None and "audit" not in kept["tools"] and rc_w == 0 and "audit" not in [t_["name"] for t_ in out_w[0]["result"]["tools"]] and len(out_w[0]["result"]["tools"]) ==
|
|
18861
|
+
"withheld": kept["tools"] is not None and "audit" not in kept["tools"] and rc_w == 0 and "audit" not in [t_["name"] for t_ in out_w[0]["result"]["tools"]] and len(out_w[0]["result"]["tools"]) == 24
|
|
18862
18862
|
and out_w[1]["error"]["code"] == -32602 and "[cut at 3,000 of" in out_w[2]["result"]["content"][0]["text"],
|
|
18863
18863
|
"narrowed": rc_a == 0 and [t_["name"] for t_ in out_a[0]["result"]["tools"]] == ["site"] and out_a[1]["error"]["code"] == -32602,
|
|
18864
18864
|
"no_workspace": rc_x.returncode == 2 and rc_x.stdout == b"" and b"not a workspace" in rc_x.stderr,
|
|
@@ -18926,7 +18926,7 @@ def section_eh_mcp(tmp: str) -> None:
|
|
|
18926
18926
|
its = (pkg / "help" / "IT_SECURITY.md").read_text(encoding="utf-8")
|
|
18927
18927
|
backups = sorted(p_.name for p_ in cfgp.parent.iterdir() if ".before-gea-" in p_.name)
|
|
18928
18928
|
c3 = {
|
|
18929
|
-
"api": s_vg == 200 and len(vg["tools"]) ==
|
|
18929
|
+
"api": s_vg == 200 and len(vg["tools"]) == 25 and all(t_["offered"] for t_ in vg["tools"]) and vg["config"]["mcpServers"]["gea"]["args"][-1] == os.path.abspath(wsp) and len(vg["log"]) >= 6
|
|
18930
18930
|
and vg["claude_desktop"]["found"] and not vg["claude_desktop"]["installed"] and s_vs == 403 and s_os == 200 and os_["offered"] == ["site", "roadmap", "help"] and os_["max_chars"] == 20000
|
|
18931
18931
|
and s_bs == 400 and s_oa == 200,
|
|
18932
18932
|
"claude_desktop": s_oc == 403 and s_ac == 200 and len(ac["done"]) == 1 and cfg_added["globalShortcut"] == "Ctrl+Space" and cfg_added["mcpServers"]["files"] == {"command": "npx", "args": ["-y", "x"]}
|
|
@@ -19067,7 +19067,7 @@ def section_ei_public_pad_benchmark(tmp: str) -> None:
|
|
|
19067
19067
|
and bm["pad_best_connection_min"] is not None and len(bm["stretches"]) >= 3 and all(s_["best_well"] in bm["names"] for s_ in bm["stretches"] if s_["best_rop_ft_h"]),
|
|
19068
19068
|
"report": set(wr["files"]) == {"benchmark.json", "benchmark.md", "benchmark.csv", "stretches.csv"} and len(rows_b) == 6 and rows_b[0].startswith("display,drilled_ft,days,feet_per_day") and len(rows_s) == len(bm["stretches"]) + 1
|
|
19069
19069
|
and "benchmark.report" in audit,
|
|
19070
|
-
"tool": not bm_txt["is_error"] and bm_txt["text"] == BM.text(BM.page(ws)) and "benchmark" in MC.NAMES and len(MC.NAMES) ==
|
|
19070
|
+
"tool": not bm_txt["is_error"] and bm_txt["text"] == BM.text(BM.page(ws)) and "benchmark" in MC.NAMES and len(MC.NAMES) == 25,
|
|
19071
19071
|
}
|
|
19072
19072
|
failed2 = [k_ for k_, v in c2.items() if not v]
|
|
19073
19073
|
ok(not failed2,
|
|
@@ -19160,6 +19160,273 @@ def section_ei_public_pad_benchmark(tmp: str) -> None:
|
|
|
19160
19160
|
"Public data tabs, the help pages, the README and lesson 13" + (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
19161
19161
|
|
|
19162
19162
|
|
|
19163
|
+
def section_ej_frac_treatment(tmp: str) -> None:
|
|
19164
|
+
"""Section EJ - the frac treatment: each stage from its own pumping record. The arithmetic on stages built with
|
|
19165
|
+
every answer known (the ISIP through the ringing, the friction and its two parts, the closure, the extension
|
|
19166
|
+
pressure, the volumes), in other units and other layouts; what is turned away and what is said not to be read;
|
|
19167
|
+
the records kept in a workspace with their hashes, the depth declared, the report, the stage times handed to the
|
|
19168
|
+
Frac hits tab; the published stimulation layouts on the public pad; the assistant's tool; the API, the CLI, the
|
|
19169
|
+
tab, the help, the README and the lessons."""
|
|
19170
|
+
import base64 as _b64
|
|
19171
|
+
import csv as _csv
|
|
19172
|
+
import http.cookiejar
|
|
19173
|
+
import math
|
|
19174
|
+
import subprocess as _sp
|
|
19175
|
+
import urllib.error
|
|
19176
|
+
import urllib.request
|
|
19177
|
+
from datetime import datetime, timedelta
|
|
19178
|
+
from . import __version__ as _ver
|
|
19179
|
+
from . import frac_hits as FH
|
|
19180
|
+
from . import frac_treatment as FT
|
|
19181
|
+
from . import helplib as H
|
|
19182
|
+
from . import mcp_server as MC
|
|
19183
|
+
from . import public_pad as PP
|
|
19184
|
+
from . import tutorial as TU
|
|
19185
|
+
from . import xlsx_read as XR
|
|
19186
|
+
from .service import Service, Users
|
|
19187
|
+
from .workspace import Workspace
|
|
19188
|
+
pkg = Path(__file__).parent
|
|
19189
|
+
d = Path(tmp, "ej"); d.mkdir()
|
|
19190
|
+
os.environ["GEA_WORKSPACES_FILE"] = str(d / "workspaces.json")
|
|
19191
|
+
# -- EJ1 the arithmetic --------------------------------------------------------------------------------------------------
|
|
19192
|
+
st = FT.selftest()
|
|
19193
|
+
rec = FT.synthetic(isip=5200.0, a=0.2, b=80.0, rate=40.0, pump_min=25.0, steps=(30.0, 20.0, 10.0, 5.0), closure_g=0.7, leak_psi=400.0, falloff_min=70.0, step_up=False, seed=11)
|
|
19194
|
+
e = rec["expected"]
|
|
19195
|
+
r = FT.analyse(rec)
|
|
19196
|
+
f = r["final"]; sd = f["step_down"]; pk = r["falloff"].get("pick") or {}
|
|
19197
|
+
# the same stage written in kPa, cubic metres a minute and kilograms a cubic metre
|
|
19198
|
+
si = str(d / "metric.csv")
|
|
19199
|
+
with open(si, "w", encoding="utf-8", newline="") as fh:
|
|
19200
|
+
w = _csv.writer(fh)
|
|
19201
|
+
w.writerow(["Timestamp", "Wellhead Pressure (kPa)", "Slurry Rate (m3/min)", "Proppant Concentration (kg/m3)"])
|
|
19202
|
+
t0 = datetime(2026, 8, 3, 6, 0, 0)
|
|
19203
|
+
for i in range(len(rec["t"])):
|
|
19204
|
+
w.writerow([(t0 + timedelta(seconds=float(rec["t"][i]))).strftime("%Y-%m-%d %H:%M:%S"), f"{rec['pressure'][i] / 0.1450377:.2f}", f"{rec['rate'][i] / 6.289811:.4f}", f"{rec['conc'][i] * 119.8264:.1f}"])
|
|
19205
|
+
rm = FT.read_treatment(Path(si).read_bytes(), "metric.csv")
|
|
19206
|
+
am = FT.analyse(rm)
|
|
19207
|
+
# the pumps back on half a minute after they stopped; a line test at 20 psi; the well opened during the fall-off
|
|
19208
|
+
brief = FT.synthetic(pump_min=10.0, falloff_min=10.0, step_up=False, steps=())
|
|
19209
|
+
k = int(brief["expected"]["shut_in_s"])
|
|
19210
|
+
brief["rate"][k + 30:k + 300] = 20.0
|
|
19211
|
+
brief["pressure"][k + 30:k + 300] = 5000.0
|
|
19212
|
+
ab = FT.analyse(brief)
|
|
19213
|
+
prime = FT.synthetic(pump_min=10.0, falloff_min=10.0, step_up=False)
|
|
19214
|
+
lead = 300
|
|
19215
|
+
tt = np.arange(len(prime["t"]) + lead, dtype=float)
|
|
19216
|
+
pr = {**prime, "t": tt, "pressure": np.concatenate([np.full(lead, 20.0), prime["pressure"]]), "rate": np.concatenate([np.r_[np.full(120, 8.0), np.zeros(lead - 120)], prime["rate"]]),
|
|
19217
|
+
"conc": None, "clean_rate": None, "slurry_total": None}
|
|
19218
|
+
ap = FT.analyse(pr)
|
|
19219
|
+
bled = FT.synthetic(pump_min=10.0, falloff_min=20.0, step_up=False, closure_g=None)
|
|
19220
|
+
kb = int(bled["expected"]["shut_in_s"]) + 660
|
|
19221
|
+
bled["pressure"][kb:] = 15.0
|
|
19222
|
+
abl = FT.analyse(bled)
|
|
19223
|
+
spike = FT.synthetic(pump_min=10.0, falloff_min=6.0, step_up=False)
|
|
19224
|
+
spike["rate"][200] = 400.0; spike["conc"][300:303] = 25.0
|
|
19225
|
+
asp = FT.analyse(spike)
|
|
19226
|
+
errs = {}
|
|
19227
|
+
for name, body in (("empty", b""), ("no_header", b"1,2,3\n4,5,6\n7,8,9\n1,2,3\n4,5,6\n"), ("no_rate", ("Timestamp,Treating Pressure (psi)\n" + "".join(f"2026-08-03 06:00:{i:02d},{4000 + i}\n" for i in range(30))).encode()),
|
|
19228
|
+
("no_time", ("Treating Pressure (psi),Slurry Rate (bpm)\n" + "".join(f"{4000 + i},{10}\n" for i in range(30))).encode())):
|
|
19229
|
+
try:
|
|
19230
|
+
FT.read_treatment(body, name + ".csv"); errs[name] = ""
|
|
19231
|
+
except FT.TreatmentError as ex:
|
|
19232
|
+
errs[name] = str(ex)
|
|
19233
|
+
el = FT.read_treatment(("Elapsed Time (min),Treating Pressure (psi),Slurry Rate (bpm)\n" + "".join(f"{i / 60:.4f},{4000 + i},{10}\n" for i in range(120))).encode(), "elapsed.csv", start="2026-08-03T06:00:00")
|
|
19234
|
+
c1 = {
|
|
19235
|
+
"selftest": st["ok"] and len(st["checks"]) >= 12,
|
|
19236
|
+
"isip": abs(f["isip_psi"] - e["isip"]) <= 0.01 * e["isip"] and not f["wide"] and len(f["windows"]) == 3 and f["isip_low_psi"] <= f["isip_psi"] <= f["isip_high_psi"],
|
|
19237
|
+
"friction": abs(f["friction_psi"] - e["friction"]) <= 0.04 * e["friction"] and f["last_rate_bpm"] == 40.0 and len(sd["points"]) == 5
|
|
19238
|
+
and abs(sd["square_psi"] - e["square"]) <= 0.15 * e["square"] and abs(sd["root_psi"] - e["root"]) <= 0.15 * e["root"] and "both parts" in sd["reads"],
|
|
19239
|
+
"closure": bool(pk) and abs(pk["g"] - 0.7) <= 0.06 and abs(pk["pressure_psi"] - e["closure_psi"]) <= 40.0 and "closure candidate" in r["falloff"]["reads"],
|
|
19240
|
+
"volumes": abs(r["pumping"]["slurry_bbl"] - e["slurry_bbl"]) <= 2 and abs(r["pumping"]["slurry_bbl"] - r["pumping"]["slurry_totaliser_bbl"]) <= 2 and r["pumping"]["proppant_lbm"] > 30000
|
|
19241
|
+
and r["pumping"]["pressure_max_psi"] >= r["pumping"]["pressure_avg_psi"] > e["isip"] and abs(r["pumping"]["rate_avg_bpm"] - 40.0) < 1.5,
|
|
19242
|
+
"metric": rm["read_as"]["pressure"] == "Wellhead Pressure (kpa)" and abs(am["final"]["isip_psi"] - f["isip_psi"]) <= 3 and abs(am["pumping"]["slurry_bbl"] - r["pumping"]["slurry_bbl"]) <= 3
|
|
19243
|
+
and abs(am["final"]["friction_psi"] - f["friction_psi"]) <= 5 and am["start"] == "2026-08-03T06:00:00"
|
|
19244
|
+
and any("no clean rate" in n_ for n_ in am["notes"]) and am["pumping"]["proppant_lbm"] > r["pumping"]["proppant_lbm"],
|
|
19245
|
+
"too_short": ab["shut_ins"][0]["status"] == "TOO SHORT" and "came back on 30 s after" in ab["shut_ins"][0]["why"] and ab["shut_ins"][-1]["status"] == "OK",
|
|
19246
|
+
"surface": ap["not_injection"]["surface"] == 1 and len(ap["shut_ins"]) == 1 and abs(ap["final"]["isip_psi"] - 4200) <= 45 and abs(ap["pumping"]["slurry_bbl"] - prime["expected"]["slurry_bbl"]) <= 2,
|
|
19247
|
+
"bled_off": abs(abl["falloff"]["bled_off_min"] - 11.0) <= 0.2 and 10.0 < abl["falloff"]["minutes"] < 11.1 and abl["falloff"].get("pick") is None and "10" in abl["falloff"]["at"] and "15" not in abl["falloff"]["at"],
|
|
19248
|
+
"spikes": asp["pumping"]["rate_max_bpm"] <= 61.0 and any("3 s of proppant concentration above 12" in n_ for n_ in asp["notes"]) and asp["pumping"]["conc_max_ppg"] == 1.5,
|
|
19249
|
+
"turned_away": "empty" in errs["empty"] and "no header" in errs["no_header"] and "treating pressure and a slurry rate" in errs["no_rate"] and "Treating Pressure" in errs["no_rate"] and "no time column" in errs["no_time"],
|
|
19250
|
+
"elapsed": el["start"] == "2026-08-03T06:00:00" and abs(el["cadence_s"] - 1.0) < 0.01 and el["samples"] == 120,
|
|
19251
|
+
"g": abs(float(FT.g_function(np.array([0.0]), 100.0)[0])) < 1e-12 and abs(float(FT.g_function(np.array([100.0]), 100.0)[0]) - 4 / math.pi * (4 / 3 * (2 ** 1.5 - 1) - 4 / 3)) < 1e-9,
|
|
19252
|
+
}
|
|
19253
|
+
failed1 = [k_ for k_, v in c1.items() if not v]
|
|
19254
|
+
ok(not failed1,
|
|
19255
|
+
"EJ1 a fracturing stage read from its own pumping record, on stages built with the answer known: the ISIP read back through the ringing over three windows to within 1 %; the friction at the "
|
|
19256
|
+
"last rate held and, from a four-step step-down, its part with the square of the rate and its part with the root; the closure where the pressure leaves its line in G; the volume against the "
|
|
19257
|
+
"totaliser; the same stage in kPa, cubic metres a minute and kilograms a cubic metre giving the same figures; pumps back on after half a minute said to leave too little to read; a line test "
|
|
19258
|
+
"at 20 psi not counted as injection; a well opened during the fall-off cutting it there; a rate spike and a flushed densitometer left out and said so; a file with no pressure, no rate, no "
|
|
19259
|
+
"time or no header turned away by name; an elapsed-time file given its start; Nolte's G against its formula" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
19260
|
+
|
|
19261
|
+
# -- EJ2 the workspace, the public pad, the assistant ------------------------------------------------------------------
|
|
19262
|
+
gz = FH.selftest_files(str(d / "gauge"))
|
|
19263
|
+
ws = Workspace.create(str(d / "ws"), "Pad 3", actor="tester")
|
|
19264
|
+
tw = ws.add_well_file(gz["gauge"], display="Treat 1H", actor="tester")["id"]
|
|
19265
|
+
ws.add_well_file(gz["gauge"], display="Monitor 2H", actor="tester")
|
|
19266
|
+
stages_ = {}
|
|
19267
|
+
for n_, (name, isip) in enumerate((("3R", 4100.0), ("10", 4500.0), ("4", 4300.0))):
|
|
19268
|
+
s_ = FT.synthetic(isip=isip, pump_min=9.0, falloff_min=8.0, step_up=False, seed=30 + n_)
|
|
19269
|
+
s_["start"] = f"2026-08-0{3 + n_}T06:00:00"
|
|
19270
|
+
stages_[name] = (s_, isip)
|
|
19271
|
+
FT.write_csv(str(d / "s3r.csv"), stages_["3R"][0]); FT.write_dataacq(str(d / "s10.txt"), stages_["10"][0])
|
|
19272
|
+
rows4 = [["", "Time of", "Treating", "Slurry", "Clean", "Prop", "Slurry Stage"], ["Date", "Day", "Pressure", "Rate", "Rate", "Conc", "Total"], ["(mm:dd:yyyy)", "(hh:mm:ss)", "(psi)", "(bpm)", "(bpm)", "(ppg)", "(bbl)"]]
|
|
19273
|
+
s4 = stages_["4"][0]; t4 = datetime(2026, 8, 5, 6, 0, 0)
|
|
19274
|
+
for i in range(len(s4["t"])):
|
|
19275
|
+
ts = t4 + timedelta(seconds=float(s4["t"][i]))
|
|
19276
|
+
rows4.append([ts.strftime("%Y-%m-%d"), ts.strftime("%H:%M:%S"), round(float(s4["pressure"][i]), 1), round(float(s4["rate"][i]), 2), round(float(s4["clean_rate"][i]), 3), round(float(s4["conc"][i]), 2), round(float(s4["slurry_total"][i]), 2)])
|
|
19277
|
+
XR.write_simple(str(d / "s4.xlsx"), rows4)
|
|
19278
|
+
m3 = FT.attach(ws, tw, "3R", "s3r.csv", (d / "s3r.csv").read_bytes(), "tester", "post-job data (test)")
|
|
19279
|
+
m10 = FT.attach(ws, tw, "10", "s10.txt", (d / "s10.txt").read_bytes(), "tester", "post-job data (test)")
|
|
19280
|
+
m4 = FT.attach(ws, tw, "4", "s4.xlsx", (d / "s4.xlsx").read_bytes(), "tester", "post-job data (test)")
|
|
19281
|
+
refused = {}
|
|
19282
|
+
for name, fn in (("no_source", lambda: FT.attach(ws, tw, "5", "s3r.csv", (d / "s3r.csv").read_bytes(), "tester", "")), ("no_stage", lambda: FT.attach(ws, tw, " ", "s3r.csv", (d / "s3r.csv").read_bytes(), "tester", "x")),
|
|
19283
|
+
("no_well", lambda: FT.attach(ws, "nowhere", "5", "s3r.csv", (d / "s3r.csv").read_bytes(), "tester", "x")), ("bad_tvd", lambda: FT.declare(ws, tw, "tester", "x", 50)),
|
|
19284
|
+
("bad_grad", lambda: FT.declare(ws, tw, "tester", "x", 8000, 2.0)), ("dec_source", lambda: FT.declare(ws, tw, "tester", "", 8000)), ("dec_stage", lambda: FT.declare(ws, tw, "tester", "x", 8000, None, "99")),
|
|
19285
|
+
("no_tvd", lambda: FT.declare(ws, tw, "tester", "x", None))):
|
|
19286
|
+
try:
|
|
19287
|
+
fn(); refused[name] = ""
|
|
19288
|
+
except (ValueError, KeyError) as ex:
|
|
19289
|
+
refused[name] = str(ex.args[0]) if ex.args else "x"
|
|
19290
|
+
p0 = FT.page(ws)
|
|
19291
|
+
FT.declare(ws, tw, "tester", "perforation record (test); fresh water", 8000)
|
|
19292
|
+
FT.declare(ws, tw, "tester", "perforation record (test); brine", 8200, 0.465, "10")
|
|
19293
|
+
p1 = FT.page(ws, tw, "10")
|
|
19294
|
+
by = {r_["stage"]: r_ for r_ in p1["stages"]}
|
|
19295
|
+
det = p1["detail"]
|
|
19296
|
+
wr = FT.write_report(ws, _ver, "tester")
|
|
19297
|
+
csv_rows = (Path(wr["folder"]) / "stages.csv").read_text(encoding="utf-8").strip().splitlines()
|
|
19298
|
+
table = (Path(wr["folder"]) / [x for x in wr["files"] if x.startswith("stage_table_")][0]).read_text(encoding="utf-8").strip().splitlines()
|
|
19299
|
+
fh = FT.to_frac_hits(ws, tw, "tester")
|
|
19300
|
+
fh_rows = FH.stage_rows(ws, tw)
|
|
19301
|
+
kept = Path(ws.path, "completion", "frac", "treatment")
|
|
19302
|
+
FT.remove(ws, tw, "4", "tester")
|
|
19303
|
+
p2 = FT.page(ws)
|
|
19304
|
+
audit = Path(ws.audit_path).read_text(encoding="utf-8")
|
|
19305
|
+
tool = MC.call_tool(ws, "frac_treatment", {"well": "Treat 1H", "stage": "10"}); tool_j = MC.call_tool(ws, "frac_treatment", {"well": "Treat 1H", "stage": "10", "json": True})
|
|
19306
|
+
# the published layouts on the public pad
|
|
19307
|
+
folder, site = str(d / "files"), str(d / "forge-site")
|
|
19308
|
+
PP.standins(folder, stands=13)
|
|
19309
|
+
made_t = PP.treatment_standins(folder)
|
|
19310
|
+
stt = PP.status(folder)
|
|
19311
|
+
seen = []
|
|
19312
|
+
br = PP.build(folder, site, "tester", verify=False, progress=seen.append)
|
|
19313
|
+
fs = Workspace(site); fp = FT.page(fs)
|
|
19314
|
+
off = [abs((r_.get("isip_psi") or 0) - made_t[f"{r_['display']}|{r_['stage']}"]) for r_ in fp["stages"]]
|
|
19315
|
+
prec = PP.record(fs)
|
|
19316
|
+
c2 = {
|
|
19317
|
+
"attached": m3["layout"] == "table" and m10["layout"] == "data-acquisition export" and m4["layout"] == "table with a stacked header" and m4["start"] == "2026-08-05T06:00:00" and len(m3["sha256"]) == 64
|
|
19318
|
+
and m3["read_as"]["rate"] == "Slurry Rate (bpm)" and any("names no units" in n_ for n_ in m10["notes"]) and (kept / tw / "3R" / "s3r.csv").read_bytes() == (d / "s3r.csv").read_bytes()
|
|
19319
|
+
and (kept / tw / "10" / "channels.npz").is_file(),
|
|
19320
|
+
"refused": "where the record came from" in refused["no_source"] and "name the stage" in refused["no_stage"] and "no well" in refused["no_well"] and "between 100 and 40,000" in refused["bad_tvd"]
|
|
19321
|
+
and "between 0.3 and 1.2" in refused["bad_grad"] and "where the depth" in refused["dec_source"] and "no treatment record for stage 99" in refused["dec_stage"] and "give the true vertical depth" in refused["no_tvd"],
|
|
19322
|
+
"page": p0["status"] == "OK" and [r_["stage"] for r_ in p0["stages"]] == ["3R", "4", "10"] and all(abs(by[k_]["isip_psi"] - v[1]) <= 45 for k_, v in stages_.items())
|
|
19323
|
+
and all(r_["gradient_psi_ft"] is None for r_ in p0["stages"]) and "No perforation depth is declared" in " ".join(p0["lines"]) and p0["totals"]["step_downs"] == 3,
|
|
19324
|
+
"declared": abs(by["3R"]["gradient_psi_ft"] - (by["3R"]["isip_psi"] + 0.433 * 8000) / 8000) < 2e-3 and abs(by["10"]["gradient_psi_ft"] - (by["10"]["isip_psi"] + 0.465 * 8200) / 8200) < 2e-3
|
|
19325
|
+
and det["bottomhole"]["source"].endswith("brine") and p1["stage"] == "10" and "ISIP gradient is" in " ".join(p1["lines"]),
|
|
19326
|
+
"traces": set(det["traces"]) >= {"pressure", "rate", "conc", "shut_in"} and len(det["traces"]["pressure"]["t"]) == len(det["traces"]["pressure"]["v"]) and det["traces"]["shut_in"]["t"][0] == -180.0
|
|
19327
|
+
and len(det["falloff"]["g"]) == 120 and det["meta"]["file"] == "s10.txt",
|
|
19328
|
+
"report": set(wr["files"]) >= {"frac_treatment.json", "frac_treatment.md", "stages.csv"} and len(csv_rows) == 4 and csv_rows[0].startswith("display,stage,start,status") and len(table) == 4
|
|
19329
|
+
and table[0] == "Stage,Start Time,End Time,Clean Volume (bbl),Proppant (lb)" and table[1].startswith("3R,2026-08-03 06:0") and "frac_treatment.report" in audit,
|
|
19330
|
+
"to_frac_hits": fh["stages"] == 3 and [x["stage"] for x in fh_rows] == ["3R", "10", "4"] and fh_rows[0]["start"].startswith("2026-08-03T06:0") and "frac.stages" in audit and "the stages' own treatment records" in fh["source"],
|
|
19331
|
+
"removed": [r_["stage"] for r_ in p2["stages"]] == ["3R", "10"] and "frac_treatment.removed" in audit and "frac_treatment.attach" in audit and "frac_treatment.declared" in audit,
|
|
19332
|
+
"tool": not tool["is_error"] and tool["text"] == FT.text(FT.page(ws, tw, "10")) and "traces" not in json.loads(tool_j["text"]).get("detail", {}) and "frac_treatment" in MC.NAMES and len(MC.NAMES) == 25,
|
|
19333
|
+
"public": stt["treatments_present"] == 5 and len(stt["treatments"]) == 5 and stt["treatment_bytes"] > 6e7 and len(br["stages"]) == 16 and {s_.get("step") for s_ in seen} >= {"treatment", "done"} and seen[-1]["stages"] == br["stages"]
|
|
19334
|
+
and [r_["stage"] for r_ in fp["stages"] if r_["display"] == "16A(78)-32"] == ["1", "2", "3", "3R", "4", "5", "6A", "6B", "7", "8", "9", "10"]
|
|
19335
|
+
and [r_["stage"] for r_ in fp["stages"] if r_["display"] == "16B(78)-32"] == ["1", "2", "3", "4"] and max(off) <= 40.0 and fp["lines"][-1].startswith("Data: Utah FORGE")
|
|
19336
|
+
and fp["public_source"]["name"] == "Utah FORGE" and len(prec["treatments"]) == 5 and "gdr.openei.org/submissions/1611" in FT._index(fs)[next(w_["id"] for w_ in fs.wells() if w_["display"] == "16B(78)-32")]["1"]["source"]
|
|
19337
|
+
and PP.build(folder, site, "tester", verify=False)["stages"] == [] and "public_source" not in p2,
|
|
19338
|
+
}
|
|
19339
|
+
failed2 = [k_ for k_, v in c2.items() if not v]
|
|
19340
|
+
ok(not failed2,
|
|
19341
|
+
"EJ2 three stages kept in a workspace from a plain CSV, a spreadsheet with a stacked header and a frac van's export - each file verbatim with its hash, the channels beside it; a record with no "
|
|
19342
|
+
"source, no stage or no such well, and a depth out of range or without its source, each stopped; the stages in the order a crew counts them (3R, 4, 10), each ISIP its own; the depth of the "
|
|
19343
|
+
"perforations declared for the well and again for one stage, and the gradient the surface ISIP plus that column over that depth; the charts' traces; the report with a row a stage and the "
|
|
19344
|
+
"stage table; that table given to the Frac hits tab and read there as three stages; a stage removed; every step in the audit log; the assistant's tool the page's own text, without the "
|
|
19345
|
+
"charts' points. On the public pad: the five stimulation files found in the folder's stimulation folder, sixteen stages attached to the two wells in both published layouts, each ISIP read, "
|
|
19346
|
+
"the credit on the page, and built again nothing added" + (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
19347
|
+
|
|
19348
|
+
# -- EJ3 the routes, the commands, the tab, the help --------------------------------------------------------------------
|
|
19349
|
+
Users(str(Path(ws.path, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(ws.path, "users.json"))).add("op", "op-pass-123", "operator")
|
|
19350
|
+
svc = Service(ws.path, port=0, scheduler=False).start()
|
|
19351
|
+
base_url = svc.url.rstrip("/")
|
|
19352
|
+
|
|
19353
|
+
def opener(name, pw_):
|
|
19354
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
19355
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
19356
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
19357
|
+
return o
|
|
19358
|
+
|
|
19359
|
+
def call(o, method, path, body=None):
|
|
19360
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
19361
|
+
if method == "POST":
|
|
19362
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
19363
|
+
try:
|
|
19364
|
+
with o.open(rq, timeout=300) as rr_:
|
|
19365
|
+
return rr_.status, json.loads(rr_.read())
|
|
19366
|
+
except urllib.error.HTTPError as ex:
|
|
19367
|
+
return ex.code, json.loads(ex.read())
|
|
19368
|
+
from urllib.parse import quote as _q
|
|
19369
|
+
b64 = _b64.b64encode((d / "s4.xlsx").read_bytes()).decode("ascii")
|
|
19370
|
+
try:
|
|
19371
|
+
V, O = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
|
|
19372
|
+
s_v, pv = call(V, "GET", "/api/frac-treatment")
|
|
19373
|
+
s_vs, pvs = call(V, "GET", f"/api/frac-treatment?well={_q(tw)}&stage=3R")
|
|
19374
|
+
s_va, _ = call(V, "POST", "/api/frac-treatment/attach", {"well_id": tw, "stage": "4", "filename": "s4.xlsx", "content_b64": b64, "source": "x"})
|
|
19375
|
+
s_oa, oa = call(O, "POST", "/api/frac-treatment/attach", {"well_id": tw, "stage": "4", "filename": "s4.xlsx", "content_b64": b64, "source": "post-job data (API)"})
|
|
19376
|
+
s_ob, ob = call(O, "POST", "/api/frac-treatment/attach", {"well_id": tw, "stage": "5", "filename": "bad.csv", "content": "Depth,Gamma\n1,2\n", "source": "x"})
|
|
19377
|
+
s_on, _ = call(O, "POST", "/api/frac-treatment/attach", {"well_id": "nowhere", "stage": "5", "filename": "s4.xlsx", "content_b64": b64, "source": "x"})
|
|
19378
|
+
s_od, od = call(O, "POST", "/api/frac-treatment/declare", {"well_id": tw, "stage": "4", "tvd_ft": "8100", "fluid_psi_ft": "", "source": "perforation record (API)"})
|
|
19379
|
+
s_oe, oe = call(O, "POST", "/api/frac-treatment/declare", {"well_id": tw, "tvd_ft": "", "source": "x"})
|
|
19380
|
+
s_of, of_ = call(O, "POST", "/api/frac-treatment/to-frac-hits", {"well_id": tw})
|
|
19381
|
+
s_ow, ow = call(O, "POST", "/api/frac-treatment/write", {})
|
|
19382
|
+
s_vw, _ = call(V, "POST", "/api/frac-treatment/write", {})
|
|
19383
|
+
s_or, _ = call(O, "POST", "/api/frac-treatment/remove", {"well_id": tw, "stage": "4"})
|
|
19384
|
+
s_o2, _ = call(O, "POST", "/api/frac-treatment/remove", {"well_id": tw, "stage": "4"})
|
|
19385
|
+
s_p2, pp2 = call(V, "GET", "/api/public-pad")
|
|
19386
|
+
finally:
|
|
19387
|
+
svc.stop()
|
|
19388
|
+
env = {**os.environ, "PYTHONPATH": str(pkg.parent) + os.pathsep + os.environ.get("PYTHONPATH", "")}
|
|
19389
|
+
run = lambda *a_: _sp.run([sys.executable, "-m", "gea", *a_], capture_output=True, text=True, env=env, cwd=str(d), timeout=600)
|
|
19390
|
+
cli_s, cli_t, cli_j = run("frac-treatment"), run("frac-treatment", "--workspace", ws.path), run("frac-treatment", "--workspace", ws.path, "--well", "Treat 1H", "--stage", "3R", "--json")
|
|
19391
|
+
cli_a = run("frac-treatment", "--workspace", ws.path, "--well", "Treat 1H", "--stage", "4", "--attach", str(d / "s4.xlsx"), "--source", "post-job data (CLI)")
|
|
19392
|
+
cli_d = run("frac-treatment", "--workspace", ws.path, "--well", "Treat 1H", "--stage", "4", "--tvd", "8050", "--fluid", "0.44", "--source", "perforation record (CLI)")
|
|
19393
|
+
cli_h = run("frac-treatment", "--workspace", ws.path, "--well", "Treat 1H", "--to-frac-hits", "--write")
|
|
19394
|
+
cli_x = run("frac-treatment", "--workspace", ws.path, "--well", "Nobody 9H")
|
|
19395
|
+
cli_n = run("frac-treatment", "--workspace", ws.path, "--stage", "4", "--attach", str(d / "s4.xlsx"), "--source", "x")
|
|
19396
|
+
cli_w = run("frac-treatment", "--workspace", str(d / "nowhere"))
|
|
19397
|
+
cli_pl = run("public-pad", "--list")
|
|
19398
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
19399
|
+
readme = (pkg.parent / "README.md").read_text(encoding="utf-8") if (pkg.parent / "README.md").is_file() else ""
|
|
19400
|
+
lesson = (pkg / "help" / "tutorial" / "14-production-pages.md").read_text(encoding="utf-8")
|
|
19401
|
+
hp = H.page("frac-treatment") or ""
|
|
19402
|
+
c3 = {
|
|
19403
|
+
"api_read": s_v == 200 and pv["status"] == "OK" and [r_["stage"] for r_ in pv["stages"]] == ["3R", "10"] and len(pv["not_a_measurement"]) >= 6 and s_vs == 200 and pvs["stage"] == "3R"
|
|
19404
|
+
and pvs["detail"]["final"]["isip_psi"] == pv["stages"][0]["isip_psi"] and "traces" in pvs["detail"],
|
|
19405
|
+
"api_write": s_va == 403 and s_oa == 200 and oa["stage"] == "4" and oa["samples"] == len(s4["t"]) and s_ob == 400 and s_on == 404 and s_od == 200 and od["fluid_psi_ft"] == 0.433 and od["stages"] == ["4"]
|
|
19406
|
+
and s_oe == 400 and "true vertical depth" in oe.get("error", "") and s_of == 200 and of_["stages"] == 3 and s_ow == 200 and "stages.csv" in ow["files"] and s_vw == 403 and s_or == 200 and s_o2 == 404
|
|
19407
|
+
and s_p2 == 200 and len(pp2["treatments"]) == 5 and pp2["treatments"][3]["stages"][0] == "3R",
|
|
19408
|
+
"cli": cli_s.returncode == 0 and cli_s.stdout.strip().splitlines()[-1].startswith("OK - SIMULATION") and cli_t.returncode == 0 and "Frac treatment: each stage from its own pumping record" in cli_t.stdout
|
|
19409
|
+
and cli_j.returncode == 0 and json.loads(cli_j.stdout)["stage"] == "3R" and cli_a.returncode == 0 and "kept: stage 4" in cli_a.stdout and "table with a stacked header" in cli_a.stdout
|
|
19410
|
+
and cli_d.returncode == 0 and "declared for stage 4: perforations at 8,050 ft TVD, fluid 0.44 psi/ft" in cli_d.stdout and cli_h.returncode == 0 and "the Frac hits page has 3 stage(s)" in cli_h.stdout
|
|
19411
|
+
and "written: frac_treatment.json" in cli_h.stdout and cli_x.returncode != 0 and "no well 'Nobody 9H'" in cli_x.stderr and cli_n.returncode != 0 and "--attach needs --well and --stage" in cli_n.stderr
|
|
19412
|
+
and cli_w.returncode != 0 and cli_w.stdout == "" and cli_pl.returncode == 0 and "16B Frac Data.zip" in cli_pl.stdout and "doi:10.15121/2371032" in cli_pl.stdout,
|
|
19413
|
+
"page": all(x in page_src for x in ("VIEWS.treatment", "['#/treatment', 'Frac treatment']", "ftPanel", "ftCharts", "/api/frac-treatment/attach", "/api/frac-treatment/declare", "/api/frac-treatment/to-frac-hits",
|
|
19414
|
+
"help('treatment')", "never two scales on one plot", "The stimulation records", "What this page will not call a measurement")),
|
|
19415
|
+
"help": not H.check("frac-treatment") and not H.check("public-data") and not H.check("mcp") and H.VIEW_TOPIC.get("treatment") == "frac-treatment"
|
|
19416
|
+
and all(x in hp for x in ("gea frac-treatment --workspace C:\\site", "15 to 60 s, 20 to 90 s and 30 to 120 s", "4,019 psi", "3,985 psi", "the pipe and the perforations together", "Nolte"))
|
|
19417
|
+
and "`frac_treatment`" in (H.page("mcp") or "") and "16B Frac Data.zip" in (H.page("public-data") or "") and "stimulation" in (H.page("public-data") or ""),
|
|
19418
|
+
"readme_lesson": (not readme or ("### Frac treatment" in readme and "`gea frac-treatment`" in readme and "2,969,800 lbm" in readme and readme.index("### Frac treatment") < readme.index("### Frac hits")))
|
|
19419
|
+
and "**Frac treatment**" in lesson and "frac-treatment" in lesson.split("Help:")[-1] and not TU.check("production-pages"),
|
|
19420
|
+
}
|
|
19421
|
+
failed3 = [k_ for k_, v in c3.items() if not v]
|
|
19422
|
+
ok(not failed3,
|
|
19423
|
+
"EJ3 on the API (anyone reads the stages and one stage in full with its traces; only an operator attaches a record - a spreadsheet sent whole - declares the depth, hands the stage times to "
|
|
19424
|
+
"the Frac hits tab, writes the report or removes a stage; a file that is no treatment record 400, a well that is not there 404, a stage already removed 404; the public files list carries "
|
|
19425
|
+
"the stimulation files), the commands (the self-test, the table, one stage as JSON, a record attached, the depth declared, the stage times handed over and the report written; a well that is "
|
|
19426
|
+
"not there, an attach with no well and a folder that is no workspace each stopped; the public list naming the stimulation files), the Frac treatment tab with a panel a measure, the help "
|
|
19427
|
+
"page with the published figures it was checked against, the README and lesson 14" + (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
19428
|
+
|
|
19429
|
+
|
|
19163
19430
|
def main() -> int:
|
|
19164
19431
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
19165
19432
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -19302,6 +19569,7 @@ def main() -> int:
|
|
|
19302
19569
|
section_eg_dysfunction(tmp)
|
|
19303
19570
|
section_eh_mcp(tmp)
|
|
19304
19571
|
section_ei_public_pad_benchmark(tmp)
|
|
19572
|
+
section_ej_frac_treatment(tmp)
|
|
19305
19573
|
if _FAILS:
|
|
19306
19574
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
19307
19575
|
for f in _FAILS:
|