gea-program 0.57.0__tar.gz → 0.59.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.57.0/gea_program.egg-info → gea_program-0.59.0}/PKG-INFO +26 -1
- {gea_program-0.57.0 → gea_program-0.59.0}/README.md +25 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/__init__.py +1 -1
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/__main__.py +65 -4
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/acceptance_tests.py +319 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/declarations.py +371 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/dossier.py +12 -1
- gea_program-0.59.0/gea/help/declare.md +13 -0
- gea_program-0.59.0/gea/help/hydraulics.md +19 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/torque-drag.md +1 -1
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/helplib.py +2 -1
- gea_program-0.59.0/gea/hydraulics.py +778 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/service.py +26 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/torque_drag.py +16 -6
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/web/app.html +84 -5
- {gea_program-0.57.0 → gea_program-0.59.0/gea_program.egg-info}/PKG-INFO +26 -1
- {gea_program-0.57.0 → gea_program-0.59.0}/gea_program.egg-info/SOURCES.txt +2 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/pyproject.toml +1 -1
- gea_program-0.57.0/gea/help/declare.md +0 -13
- {gea_program-0.57.0 → gea_program-0.59.0}/LICENSE +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/alerts.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/backup.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/bench.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/blind_harness.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog_map.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/catalog_register.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/certificates.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/cli.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/client_reports.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/collision.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/config_versioning.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/conformance.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/control_room.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/correlation.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/dashboard.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/decline.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/deviation.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/dlis.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/dnp3.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/doctor.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/dossier_verify.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/drill_string.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/earth_model.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/economics.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/ed25519.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/edr.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/elevation.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/etp.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/example_register_map.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/fat_sat.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/files.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/follower.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/forward_model.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/frac_hits.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/friction_priors.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/gamma.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/geodesy.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/geomag.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/hartip.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/IT_SECURITY.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/alarms.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/alerts.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/backup.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/catalog.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/charts.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/collision.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/company-sign-in.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/conformance.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/control-room.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/data-in.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/decline.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/dlis.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/doctor.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/dossier.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/drift.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/economics.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/edr.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/etp.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/files.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/frac-hits.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/historian.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/https.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/instruments.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/interval.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/invoice-check.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/map.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/month-end.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/notifications.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/opseis.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/osdu.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/patches.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/plan.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/pore-pressure.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/quality.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/report-history.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/rig-time.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/seismic.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/setup.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/simulation.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/site.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/sites.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/slip.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/soak.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/sra.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/start.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/structure.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/tools.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/transients.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/vibration.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/well-report.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/help/well3d.md +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/housekeeping.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/interval.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/invoice_check.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/jobs.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/live_ports.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/loadtest.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/modbus.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/model_card.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/month_end.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/notify.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/oidc.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/oidc_mock.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/opcua_port.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/operator_app.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/osdu.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/pad_summary.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/patches.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/pdf_report.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/penetrator.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/permits.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/piwebapi.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/pore_pressure.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/ports.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/ppdm.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/project.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/quakeml.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reconciler.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/WMM2025.COF +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/iscwsa_rev4_example.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/iscwsa_rev5_example.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/owsg_tool_models.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/report_history.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/rig_state.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/sample_record.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/sbom.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seedlink.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/segy.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_array.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_film.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_response.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_track.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/series_cache.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/service_life.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/shapefile.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/shell.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/shut_in.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/simulation.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/site_map.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/sla_report.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/slip.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/soak.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/sra.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/store_forward.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/strata_join.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/structure.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/supervisor.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/survey_view.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/telemetry.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/tls.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/tool_library.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/transient.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/vibration.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/well3d.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/well_assembler.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/well_report.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/wellplan.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/wellpos.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/wits0.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/witsml.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/workspace.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea/xlsx_read.py +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.57.0 → gea_program-0.59.0}/setup.cfg +0 -0
- {gea_program-0.57.0 → gea_program-0.59.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.59.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
|
|
@@ -659,6 +659,31 @@ EIA) or a declared price, with the net revenue interest, severance tax and
|
|
|
659
659
|
operating cost declared. A forecast is not a reserves report, and the page
|
|
660
660
|
says so. The **Decline curves** tab, `gea decline`, `gea help decline`.
|
|
661
661
|
|
|
662
|
+
### The declarations workbook
|
|
663
|
+
|
|
664
|
+
Everything the operator declares about a pad goes in through one sheet -
|
|
665
|
+
`gea declare --workspace C:\site --template pad3.xlsx` writes it as an
|
|
666
|
+
Excel workbook already filled with what is declared; `gea declare
|
|
667
|
+
--workspace C:\site --file pad3.xlsx` checks it row by row and `--apply`
|
|
668
|
+
writes it. Beside the wells, rates, runs and casing, it carries the
|
|
669
|
+
engineering: the survey program and plans, pore pressure and measured
|
|
670
|
+
pressures, the torque-and-drag string, the hydraulics (string, hole, mud,
|
|
671
|
+
viscometer, nozzles), frac stage tables and monitored wells, production
|
|
672
|
+
and the decline terms. A well with no directional survey is read on the
|
|
673
|
+
drilling recorder's own Interpolated TVD where one is needed, labelled as
|
|
674
|
+
the recorder's interpolation. `gea help declare`.
|
|
675
|
+
|
|
676
|
+
### Hydraulics and ECD
|
|
677
|
+
|
|
678
|
+
The pressures the mud makes while it circulates, from the six-speed
|
|
679
|
+
viscometer (the API RP 13D power law: the pipe from 600/300, the annulus
|
|
680
|
+
from 100/3): the standpipe pressure part by part - surface lines, string,
|
|
681
|
+
motor and MWD, bit, annulus - the bit's hydraulics, the ECD at every depth
|
|
682
|
+
against the pore pressure and fracture gradient, surge and swab and the
|
|
683
|
+
fastest safe trip at each bit depth, and the standpipe pressure the rig
|
|
684
|
+
measured against the model. The **Hydraulics & ECD** tab, `gea hydraulics`,
|
|
685
|
+
`gea help hydraulics`.
|
|
686
|
+
|
|
662
687
|
### Torque and drag
|
|
663
688
|
|
|
664
689
|
The hook load and torque the drill string should take at each bit depth, by
|
|
@@ -620,6 +620,31 @@ EIA) or a declared price, with the net revenue interest, severance tax and
|
|
|
620
620
|
operating cost declared. A forecast is not a reserves report, and the page
|
|
621
621
|
says so. The **Decline curves** tab, `gea decline`, `gea help decline`.
|
|
622
622
|
|
|
623
|
+
### The declarations workbook
|
|
624
|
+
|
|
625
|
+
Everything the operator declares about a pad goes in through one sheet -
|
|
626
|
+
`gea declare --workspace C:\site --template pad3.xlsx` writes it as an
|
|
627
|
+
Excel workbook already filled with what is declared; `gea declare
|
|
628
|
+
--workspace C:\site --file pad3.xlsx` checks it row by row and `--apply`
|
|
629
|
+
writes it. Beside the wells, rates, runs and casing, it carries the
|
|
630
|
+
engineering: the survey program and plans, pore pressure and measured
|
|
631
|
+
pressures, the torque-and-drag string, the hydraulics (string, hole, mud,
|
|
632
|
+
viscometer, nozzles), frac stage tables and monitored wells, production
|
|
633
|
+
and the decline terms. A well with no directional survey is read on the
|
|
634
|
+
drilling recorder's own Interpolated TVD where one is needed, labelled as
|
|
635
|
+
the recorder's interpolation. `gea help declare`.
|
|
636
|
+
|
|
637
|
+
### Hydraulics and ECD
|
|
638
|
+
|
|
639
|
+
The pressures the mud makes while it circulates, from the six-speed
|
|
640
|
+
viscometer (the API RP 13D power law: the pipe from 600/300, the annulus
|
|
641
|
+
from 100/3): the standpipe pressure part by part - surface lines, string,
|
|
642
|
+
motor and MWD, bit, annulus - the bit's hydraulics, the ECD at every depth
|
|
643
|
+
against the pore pressure and fracture gradient, surge and swab and the
|
|
644
|
+
fastest safe trip at each bit depth, and the standpipe pressure the rig
|
|
645
|
+
measured against the model. The **Hydraulics & ECD** tab, `gea hydraulics`,
|
|
646
|
+
`gea help hydraulics`.
|
|
647
|
+
|
|
623
648
|
### Torque and drag
|
|
624
649
|
|
|
625
650
|
The hook load and torque the drill string should take at each bit depth, by
|
|
@@ -533,11 +533,11 @@ def main(argv=None) -> int:
|
|
|
533
533
|
p_ds.add_argument("--actor", type=str, default="cli")
|
|
534
534
|
p_ds.add_argument("--json", action="store_true")
|
|
535
535
|
|
|
536
|
-
p_dc = sub.add_parser("declare", help="the declarations sheet: wells' identity, position and elevation, surveys, rates, items and AFEs, fleet tools, drill-string runs, ESP penetrators and drives - one CSV, checked against the workspace before anything is written")
|
|
536
|
+
p_dc = sub.add_parser("declare", help="the declarations sheet: wells' identity, position and elevation, surveys, rates, items and AFEs, fleet tools, drill-string runs, ESP penetrators and drives, the survey program and plans, pore pressure, torque and drag, hydraulics, frac stages, production - one CSV or Excel workbook, checked against the workspace before anything is written")
|
|
537
537
|
p_dc.add_argument("--workspace", type=str, required=True)
|
|
538
538
|
p_dc.add_argument("--file", type=str, default=None, help="the sheet (CSV); every row is planned NEW, CHANGE or SAME and nothing is written without --apply")
|
|
539
539
|
p_dc.add_argument("--apply", action="store_true", help="write the NEW and CHANGE rows (only when the sheet has no error)")
|
|
540
|
-
p_dc.add_argument("--template", type=str, default=None, help="write the sheet for this workspace, filled with what is already declared, to this path")
|
|
540
|
+
p_dc.add_argument("--template", type=str, default=None, help="write the sheet for this workspace, filled with what is already declared, to this path (.xlsx: an Excel workbook; otherwise CSV)")
|
|
541
541
|
p_dc.add_argument("--actor", type=str, default="cli")
|
|
542
542
|
p_dc.add_argument("--json", action="store_true")
|
|
543
543
|
|
|
@@ -646,6 +646,24 @@ def main(argv=None) -> int:
|
|
|
646
646
|
p_dc.add_argument("--actor", type=str, default="cli")
|
|
647
647
|
p_dc.add_argument("--json", action="store_true")
|
|
648
648
|
|
|
649
|
+
p_hy = sub.add_parser("hydraulics", help="the pressures the mud makes while it circulates - the standpipe, the bit, the annulus, the ECD against the pore pressure and fracture gradient, surge and swab - and the standpipe pressure the rig measured")
|
|
650
|
+
p_hy.add_argument("--workspace", type=str, default=None)
|
|
651
|
+
p_hy.add_argument("--well", type=str, default=None)
|
|
652
|
+
p_hy.add_argument("--example", action="store_true", help="the worked example (Volve 15/9-F-10 with an example mud, string and hole)")
|
|
653
|
+
p_hy.add_argument("--string", type=str, default=None, help="sections from the bit up: 'BHA:350:6.75:2.875; drill pipe::5:4.276' (what:length_ft:od_in:id_in)")
|
|
654
|
+
p_hy.add_argument("--hole", type=str, default=None, help="sections from the surface down: '9-5/8 casing:3500:8.681; open hole::8.75' (what:bottom_md_ft:id_in)")
|
|
655
|
+
p_hy.add_argument("--fann", type=str, default=None, help="the viscometer dial: '600=60 300=38 200=30 100=21 6=7 3=6'")
|
|
656
|
+
p_hy.add_argument("--nozzles", type=str, default=None, help="nozzle sizes in 32nds of an inch: '14 14 14 14 14'")
|
|
657
|
+
for k_, h_ in (("mw", "mud weight, ppg"), ("flow", "pump rate, gal/min"), ("bit", "bit diameter, in"), ("surface", "surface lines' pressure loss, psi"),
|
|
658
|
+
("surface-ref", "the rate (gal/min) the surface loss was declared at"), ("tools", "motor and MWD pressure drop, psi"),
|
|
659
|
+
("trip", "average stand speed tripping, ft/min"), ("pp", "a pore pressure for the hole when the Pore pressure tab has none, ppg"),
|
|
660
|
+
("fg", "a fracture gradient for the hole when the Pore pressure tab has none, ppg")):
|
|
661
|
+
p_hy.add_argument("--" + k_, type=str, default=None, help=h_)
|
|
662
|
+
p_hy.add_argument("--source", type=str, default="", help="where the mud, string and hole figures came from")
|
|
663
|
+
p_hy.add_argument("--write", action="store_true")
|
|
664
|
+
p_hy.add_argument("--actor", type=str, default="cli")
|
|
665
|
+
p_hy.add_argument("--json", action="store_true")
|
|
666
|
+
|
|
649
667
|
p_td = sub.add_parser("torque-drag", help="the hook load and torque the string should take at each bit depth (soft-string model), the broomstick, and the friction factors that fit the rig's own trips")
|
|
650
668
|
p_td.add_argument("--workspace", type=str, default=None)
|
|
651
669
|
p_td.add_argument("--well", type=str, default=None)
|
|
@@ -2334,8 +2352,11 @@ def main(argv=None) -> int:
|
|
|
2334
2352
|
except WorkspaceError as e:
|
|
2335
2353
|
raise SystemExit(f"declare: {e}")
|
|
2336
2354
|
if a.template:
|
|
2337
|
-
|
|
2338
|
-
|
|
2355
|
+
if a.template.lower().endswith(".xlsx"):
|
|
2356
|
+
_DC.template_xlsx(ws, a.template)
|
|
2357
|
+
else:
|
|
2358
|
+
with open(a.template, "w", encoding="utf-8", newline="") as f:
|
|
2359
|
+
f.write(_DC.template(ws))
|
|
2339
2360
|
print(f"wrote {a.template}: fill in the blanks, then gea declare --workspace {a.workspace} --file {a.template}")
|
|
2340
2361
|
return 0
|
|
2341
2362
|
if not a.file:
|
|
@@ -2577,6 +2598,46 @@ def main(argv=None) -> int:
|
|
|
2577
2598
|
raise SystemExit(f"decline: {e.args[0] if e.args else e}")
|
|
2578
2599
|
print(_json.dumps(r, default=str) if a.json else _DCA.text(r))
|
|
2579
2600
|
return 0
|
|
2601
|
+
elif a.cmd == "hydraulics":
|
|
2602
|
+
import json as _json
|
|
2603
|
+
from . import hydraulics as _HYD
|
|
2604
|
+
from .cli import _safe_stdout
|
|
2605
|
+
from .workspace import Workspace, WorkspaceError
|
|
2606
|
+
_safe_stdout()
|
|
2607
|
+
try:
|
|
2608
|
+
ws = Workspace(a.workspace) if a.workspace else None
|
|
2609
|
+
scene = "example" if (a.example or ws is None) else "workspace"
|
|
2610
|
+
keys_ = {"mw": "mw_ppg", "flow": "flow_gpm", "bit": "bit_in", "surface": "surface_psi", "surface_ref": "surface_ref_gpm", "tools": "tools_psi",
|
|
2611
|
+
"trip": "trip_ft_min", "pp": "pp_ppg", "fg": "fg_ppg"}
|
|
2612
|
+
vals_ = {v: getattr(a, k) for k, v in keys_.items() if getattr(a, k) is not None}
|
|
2613
|
+
if ws is not None and (vals_ or any(x is not None for x in (a.string, a.hole, a.fann, a.nozzles))):
|
|
2614
|
+
if not a.well:
|
|
2615
|
+
raise ValueError("--well is needed")
|
|
2616
|
+
fann_ = None
|
|
2617
|
+
if a.fann is not None:
|
|
2618
|
+
fann_ = {}
|
|
2619
|
+
for p_ in a.fann.replace(",", " ").split():
|
|
2620
|
+
k_, _, v_ = p_.partition("=")
|
|
2621
|
+
if not v_:
|
|
2622
|
+
raise ValueError(f"--fann takes SPEED=DIAL pairs, e.g. 600=60 300=38, not {p_!r}")
|
|
2623
|
+
fann_[k_.strip()] = v_.strip()
|
|
2624
|
+
c_ = _HYD.set_well(ws, a.actor, a.well, a.source, a.string, a.hole, fann_, a.nozzles, **vals_)
|
|
2625
|
+
print(f"{a.well}: mud {c_['mw_ppg']:g} ppg, {c_['flow_gpm']:g} gpm; string {len(c_.get('string') or [])} section(s), hole {len(c_.get('hole') or [])} section(s); "
|
|
2626
|
+
f"viscometer {' '.join(f'{k}={v:g}' for k, v in (c_.get('fann') or {}).items()) or 'not declared'}")
|
|
2627
|
+
return 0
|
|
2628
|
+
if a.write:
|
|
2629
|
+
if ws is None:
|
|
2630
|
+
raise ValueError("--write needs --workspace")
|
|
2631
|
+
r_ = _HYD.write_report(ws, __version__, a.well, a.actor, scene)
|
|
2632
|
+
print(f"wrote {r_['report_id']}: {r_['paths']['html']}")
|
|
2633
|
+
if r_['paths'].get('pdf'):
|
|
2634
|
+
print(f" printable: {r_['paths']['pdf']}")
|
|
2635
|
+
return 0
|
|
2636
|
+
r = _HYD.page(ws, scene, a.well)
|
|
2637
|
+
except (KeyError, ValueError, OSError, WorkspaceError) as e:
|
|
2638
|
+
raise SystemExit(f"hydraulics: {e.args[0] if e.args else e}")
|
|
2639
|
+
print(_json.dumps(r, default=str) if a.json else _HYD.text(r))
|
|
2640
|
+
return 0
|
|
2580
2641
|
elif a.cmd == "torque-drag":
|
|
2581
2642
|
import json as _json
|
|
2582
2643
|
from . import torque_drag as _TND
|
|
@@ -12821,6 +12821,323 @@ def section_cz_it_review(tmp: str) -> None:
|
|
|
12821
12821
|
"SECURITY.md says how to report a vulnerability" + (f" - failed: {failed3}" if failed3 else ""))
|
|
12822
12822
|
|
|
12823
12823
|
|
|
12824
|
+
def section_da_hydraulics(tmp: str) -> None:
|
|
12825
|
+
"""Section DA - hydraulics and ECD: the power law's losses against their closed forms (Hagen-Poiseuille, the slot,
|
|
12826
|
+
Blasius) and API RP 13D's field-unit forms, the bit against its classic formula; a record whose standpipe pressure is
|
|
12827
|
+
the model's plus a known amount, read back; the worked example's ECD against its window, surge and swab; the API, the
|
|
12828
|
+
CLI, the report, the dossier, the tab and the help."""
|
|
12829
|
+
import http.cookiejar
|
|
12830
|
+
import math as _m
|
|
12831
|
+
import subprocess as _sp
|
|
12832
|
+
import urllib.request
|
|
12833
|
+
import urllib.error
|
|
12834
|
+
import zipfile as _zf
|
|
12835
|
+
from . import __version__ as _ver
|
|
12836
|
+
from . import dossier as DZ
|
|
12837
|
+
from . import helplib as H
|
|
12838
|
+
from . import hydraulics as HY
|
|
12839
|
+
from . import well3d as W
|
|
12840
|
+
from .workspace import Workspace
|
|
12841
|
+
from .service import Service, Users
|
|
12842
|
+
pkg = Path(__file__).parent
|
|
12843
|
+
d = Path(tmp, "hydraulics"); d.mkdir()
|
|
12844
|
+
|
|
12845
|
+
# -- DA1 by hand --------------------------------------------------------------------------------------------------------
|
|
12846
|
+
mu, q = 0.03, 50.0
|
|
12847
|
+
lp = HY.pipe_loss(q, 4.0, 1000.0, 8.33, 1.0, mu)
|
|
12848
|
+
Q, D = q * HY.GPM, 4.0 * HY.IN
|
|
12849
|
+
V = Q / (_m.pi * D * D / 4.0)
|
|
12850
|
+
hp = 32.0 * mu * V * 1000.0 * HY.FT / D ** 2 / HY.PSI
|
|
12851
|
+
la = HY.annulus_loss(q, 8.5, 5.0, 1000.0, 8.33, 1.0, mu)
|
|
12852
|
+
Va = q * HY.GPM / (_m.pi * ((8.5 * HY.IN) ** 2 - (5.0 * HY.IN) ** 2) / 4.0)
|
|
12853
|
+
slot = 48.0 * mu * Va * 1000.0 * HY.FT / (3.5 * HY.IN) ** 2 / HY.PSI
|
|
12854
|
+
f_t = HY.friction(1e5, 1.0, 16.0)[0]
|
|
12855
|
+
rh = HY.rheology({"600": 56, "300": 36, "200": 28, "100": 20, "6": 6, "3": 5})
|
|
12856
|
+
n, K = rh["n_pipe"], rh["K_pipe"]
|
|
12857
|
+
api = HY.pipe_loss(550.0, 4.276, 1000.0, 10.5, n, K)
|
|
12858
|
+
Vf = 24.51 * 550.0 / 4.276 ** 2 # ft/min
|
|
12859
|
+
mu_api = 100.0 * (5.11 * 56 / 1022 ** n) * (1.6 * Vf / 4.276) ** (n - 1) * ((3 * n + 1) / (4 * n)) ** n
|
|
12860
|
+
re_api = 15.467 * Vf * 4.276 * 10.5 / mu_api
|
|
12861
|
+
dp_api = 1.076 * 10.5 * Vf ** 2 * api["f"] / 1e5 / 4.276 * 1000.0
|
|
12862
|
+
bt = HY.bit(550.0, 10.5, [13] * 6, 8.5)
|
|
12863
|
+
refused = []
|
|
12864
|
+
for bad in ({"600": 56}, {"600": 30, "300": 36}, {"600": 56, "300": 36, "450": 40}, {"600": 400, "300": 36}):
|
|
12865
|
+
try:
|
|
12866
|
+
HY.rheology(bad); refused.append(False)
|
|
12867
|
+
except ValueError:
|
|
12868
|
+
refused.append(True)
|
|
12869
|
+
for fn, arg in ((HY.check_string, [{"what": "x", "length_ft": 100, "od_in": 5, "id_in": 6}]), (HY.check_hole, [{"what": "a", "bottom_md_ft": 1000, "id_in": 8},
|
|
12870
|
+
{"what": "b", "bottom_md_ft": 500, "id_in": 8}, {"what": "c", "id_in": 8}]),
|
|
12871
|
+
(HY.parse_sections, "BHA:300:6.75"), (HY.annulus_loss, None)):
|
|
12872
|
+
try:
|
|
12873
|
+
fn(arg, "string") if fn is HY.parse_sections else (HY.annulus_loss(500, 5.0, 6.0, 100, 10, 0.5, 0.5) if fn is HY.annulus_loss else fn(arg))
|
|
12874
|
+
refused.append(False)
|
|
12875
|
+
except ValueError:
|
|
12876
|
+
refused.append(True)
|
|
12877
|
+
c1 = {
|
|
12878
|
+
"newtonian": abs(lp["psi"] / hp - 1) < 1e-4 and lp["regime"] == "laminar" and abs(la["psi"] / slot - 1) < 1e-9 and abs(f_t / (0.0791 / 1e5 ** 0.25) - 1) < 0.01,
|
|
12879
|
+
"rheology": rh["pv_cp"] == 20 and rh["yp_lbf_100ft2"] == 16 and abs(rh["n_pipe"] - _m.log2(56 / 36)) < 1e-4 and abs(rh["n_ann"] - _m.log(20 / 5) / _m.log(170.2 / 5.11)) < 1e-4
|
|
12880
|
+
and rh["tau0_lbf_100ft2"] == 4 and rh["annulus_from"] == "100 and 3 rpm",
|
|
12881
|
+
"api_forms": abs(api["v_ft_min"] / Vf - 1) < 1e-3 and abs(api["mu_cp"] / mu_api - 1) < 1e-3 and abs(api["re"] / re_api - 1) < 2e-3 and abs(api["psi"] / dp_api - 1) < 1e-3,
|
|
12882
|
+
"bit": abs(bt["psi"] / (156.5 * 10.5 * 550.0 ** 2 / (6 * 13 ** 2) ** 2) - 1) < 1e-3 and abs(bt["tfa_in2"] - 6 * _m.pi / 4 * (13 / 32) ** 2) < 1e-3
|
|
12883
|
+
and abs(bt["hhp"] - bt["psi"] * 550 / 1714) < 0.1,
|
|
12884
|
+
"refused": all(refused) and len(refused) == 8,
|
|
12885
|
+
}
|
|
12886
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
12887
|
+
ok(not failed1,
|
|
12888
|
+
"DA1 the losses by hand: a Newtonian fluid's laminar loss in a pipe is Hagen-Poiseuille's and in the annulus the slot's, exactly; its turbulent "
|
|
12889
|
+
"friction factor Blasius's to 1 %; the viscometer's PV, YP, the pipe's n from 600/300 and the annulus's from 100/3; the velocity, effective "
|
|
12890
|
+
"viscosity, Reynolds number and loss equal to API RP 13D's field-unit forms; the bit's loss the classic 156.5 rho Q^2 / (sum d^2)^2; readings "
|
|
12891
|
+
"missing, falling or out of range, a bore wider than the pipe, a hole out of order, a short section and a pipe wider than its hole refused"
|
|
12892
|
+
+ (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
12893
|
+
|
|
12894
|
+
# -- DA2 a record made by the model, read back ---------------------------------------------------------------------------
|
|
12895
|
+
f = HY.selftest_files(str(d))
|
|
12896
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
|
|
12897
|
+
wid = ws.add_well_file(f["record"], display="HY-1", actor="tester")["id"]
|
|
12898
|
+
ws.set_well(wid, surface={"lat": 31.42, "lon": -104.10, "datum": "NAD83", "elevation": {"ft": 3000.0, "datum": "KB", "source": "test plat"}}, actor="tester")
|
|
12899
|
+
no_survey = HY.page(ws, "workspace", wid)["detail"]
|
|
12900
|
+
W.attach_trajectory(ws, wid, "s.csv", Path(f["survey"]).read_bytes(), "tester", "true", "ft", None, None, None, "test survey")
|
|
12901
|
+
no_decl = HY.page(ws, "workspace", wid)["detail"]
|
|
12902
|
+
c = f["config"]
|
|
12903
|
+
HY.set_well(ws, "tester", wid, "mud report (test)", string=c["string"], hole=c["hole"], fann=c["fann"], nozzles_32=c["nozzles_32"], mw_ppg=c["mw_ppg"],
|
|
12904
|
+
flow_gpm=500, bit_in=8.75, tools_psi=400, pp_ppg=9.5, fg_ppg=14.5)
|
|
12905
|
+
r = HY.page(ws, "workspace", wid)["result"]
|
|
12906
|
+
rc = r["record"]
|
|
12907
|
+
cc = r["circulating"]
|
|
12908
|
+
c2 = {
|
|
12909
|
+
"needs": "survey" in no_survey and "string" in no_decl and "viscometer" in no_decl,
|
|
12910
|
+
"record": rc and rc["bins"] >= 20 and abs(rc["median_difference_psi"] - f["offset_psi"]) <= 10.0 and rc["spread_psi"] < 30.0,
|
|
12911
|
+
"parts": abs(sum(cc["parts"].values()) - cc["spp_psi"]) < 1.0 and cc["parts"]["tools"] == 400.0 and cc["parts"]["surface"] == 0.0,
|
|
12912
|
+
"ecd": cc["ecd_bit_ppg"] > c["mw_ppg"] and all(e_ >= c["mw_ppg"] for e_ in r["ecd"]["ecd_ppg"])
|
|
12913
|
+
and abs(cc["ecd_bit_ppg"] - (c["mw_ppg"] + cc["parts"]["annulus"] / (0.052 * cc["tvd_bit_ft"]))) < 0.002,
|
|
12914
|
+
"window": r["window_how"].startswith("declared") and r["min_fg_margin"]["ppg"] == min(x for x in r["ecd"]["margin_fg_ppg"] if x is not None),
|
|
12915
|
+
}
|
|
12916
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
12917
|
+
ok(not failed2,
|
|
12918
|
+
"DA2 a drilling record made by the model - drilling from 4,000 to 10,000 ft at 500 gpm and circulating at 350 gpm, its standpipe pressure the "
|
|
12919
|
+
"model's plus 120 psi and noise - read back while pumping: the median difference 120 psi to within 10 over 20 or more depth bins; the standpipe "
|
|
12920
|
+
"pressure the sum of its parts; the ECD at the bit the mud weight plus the annular loss over 0.052 TVD; a well without a survey or its "
|
|
12921
|
+
"declarations says what it needs" + (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
12922
|
+
|
|
12923
|
+
# -- DA3 the worked example ----------------------------------------------------------------------------------------------
|
|
12924
|
+
ex = HY.example()
|
|
12925
|
+
t = ex["trips"]
|
|
12926
|
+
s_hi = HY.surge_swab(ex["config"], ex["rheology"], ex["td_ft"], 180.0, lambda z: ex["tvd_td_ft"] * z / ex["td_ft"])
|
|
12927
|
+
s_lo = HY.surge_swab(ex["config"], ex["rheology"], ex["td_ft"], 90.0, lambda z: ex["tvd_td_ft"] * z / ex["td_ft"])
|
|
12928
|
+
rates = ex["by_rate"]
|
|
12929
|
+
c3 = {
|
|
12930
|
+
"example": ex["well"] == "15/9-F-10" and abs(ex["td_ft"] - 5300.07 / 0.3048) < 5.0 and "not from Volve" in ex["config"]["source"]
|
|
12931
|
+
and 2000 < ex["circulating"]["spp_psi"] < 5000 and ex["circulating"]["ecd_bit_ppg"] > ex["config"]["mw_ppg"],
|
|
12932
|
+
"rates": all(b["spp_psi"] > a["spp_psi"] and b["ecd_bit_ppg"] >= a["ecd_bit_ppg"] for a, b in zip(rates, rates[1:])),
|
|
12933
|
+
"surge": all(su > ex["config"]["mw_ppg"] > sw for su, sw in zip(t["surge_ppg"], t["swab_ppg"])) and s_hi["psi"] > s_lo["psi"] > 0,
|
|
12934
|
+
"speeds": all(v is not None and v > 0 for v in t["run_max_ft_min"] + t["pull_max_ft_min"])
|
|
12935
|
+
and HY.surge_swab(ex["config"], ex["rheology"], ex["td_ft"], t["run_max_ft_min"][-1], lambda z: ex["tvd_td_ft"] * z / ex["td_ft"])["surge_ppg"] <= 14.0 + 0.02,
|
|
12936
|
+
}
|
|
12937
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
12938
|
+
ok(not failed3,
|
|
12939
|
+
"DA3 the worked example, Volve 15/9-F-10's survey to its 5,300 m TD with a mud, string and hole declared for the example: the standpipe pressure "
|
|
12940
|
+
"and the ECD rising with the rate; surge above and swab below the mud weight at every bit depth, more at a faster trip; the fastest run keeping "
|
|
12941
|
+
"the surge within the declared fracture gradient" + (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
12942
|
+
|
|
12943
|
+
# -- DA4 the API, the CLI, the report, the dossier, the tab and the help -------------------------------------------------
|
|
12944
|
+
Users(str(Path(wsp, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
|
|
12945
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
12946
|
+
base_url = svc.url.rstrip("/")
|
|
12947
|
+
|
|
12948
|
+
def opener(name, pw_):
|
|
12949
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
12950
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
12951
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
12952
|
+
return o
|
|
12953
|
+
|
|
12954
|
+
def call(o, method, path, body=None):
|
|
12955
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
12956
|
+
if method == "POST":
|
|
12957
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
12958
|
+
try:
|
|
12959
|
+
with o.open(rq, timeout=120) as rr_:
|
|
12960
|
+
return rr_.status, json.loads(rr_.read())
|
|
12961
|
+
except urllib.error.HTTPError as e:
|
|
12962
|
+
return e.code, json.loads(e.read())
|
|
12963
|
+
try:
|
|
12964
|
+
V_, O_ = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
|
|
12965
|
+
s_vg, vg = call(V_, "GET", "/api/hydraulics?well=" + wid)
|
|
12966
|
+
s_ve, ve = call(V_, "GET", "/api/hydraulics?scene=example")
|
|
12967
|
+
s_vs, _ = call(V_, "POST", "/api/hydraulics/settings", {"well_id": wid, "mw_ppg": 11.2, "source": "x"})
|
|
12968
|
+
s_os, os_ = call(O_, "POST", "/api/hydraulics/settings", {"well_id": wid, "mw_ppg": "11.2", "r600": "62", "r300": "40", "r100": "22", "r3": "6",
|
|
12969
|
+
"nozzles_32": "13 13 13 13 13", "hole": "9-5/8 casing:3500:8.681; open hole::8.75", "source": "mud report (test)"})
|
|
12970
|
+
s_bf, _ = call(O_, "POST", "/api/hydraulics/settings", {"well_id": wid, "r600": "30", "r300": "40", "source": "x"})
|
|
12971
|
+
s_bh, _ = call(O_, "POST", "/api/hydraulics/settings", {"well_id": wid, "flow_gpm": 9000, "source": "x"})
|
|
12972
|
+
s_ns, _ = call(O_, "POST", "/api/hydraulics/settings", {"well_id": wid, "mw_ppg": 12})
|
|
12973
|
+
s_vw, _ = call(V_, "POST", "/api/hydraulics/write", {"well_id": wid})
|
|
12974
|
+
s_ow, ow = call(O_, "POST", "/api/hydraulics/write", {"well_id": wid})
|
|
12975
|
+
finally:
|
|
12976
|
+
svc.stop()
|
|
12977
|
+
cli_x = _sp.run([sys.executable, "-m", "gea", "hydraulics", "--example"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
12978
|
+
cli_s = _sp.run([sys.executable, "-m", "gea", "hydraulics", "--workspace", wsp, "--well", wid, "--flow", "450", "--fann", "600=60 300=38 100=21 3=6",
|
|
12979
|
+
"--source", "mud report (test)"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
12980
|
+
cli_b = _sp.run([sys.executable, "-m", "gea", "hydraulics", "--workspace", wsp, "--well", wid, "--fann", "600:60", "--source", "x"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
12981
|
+
cli_t = _sp.run([sys.executable, "-m", "gea", "hydraulics", "--workspace", wsp, "--well", wid], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
12982
|
+
dz = DZ.build(ws, "tester", _ver, None)
|
|
12983
|
+
names = _zf.ZipFile(Path(ws.reports_dir, dz["path"])).namelist()
|
|
12984
|
+
audit = Path(ws.audit_path).read_text(encoding="utf-8")
|
|
12985
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
12986
|
+
c4 = {
|
|
12987
|
+
"api": s_vg == 200 and vg["result"]["record"]["bins"] >= 20 and s_ve == 200 and ve["result"]["well"] == "15/9-F-10" and s_vs == 403 and s_os == 200
|
|
12988
|
+
and os_["fann"] == {"600": 62.0, "300": 40.0, "100": 22.0, "3": 6.0} and os_["nozzles_32"] == [13.0] * 5 and os_["mw_ppg"] == 11.2
|
|
12989
|
+
and s_bf == 400 and s_bh == 400 and s_ns == 400 and s_vw == 403 and s_ow == 200 and ow["report_id"].startswith("HYD-"),
|
|
12990
|
+
"cli": cli_x.returncode == 0 and "standpipe" in cli_x.stdout and "ECD at the bit" in cli_x.stdout and cli_s.returncode == 0 and "450 gpm" in cli_s.stdout
|
|
12991
|
+
and cli_b.returncode != 0 and "SPEED=DIAL" in (cli_b.stderr + cli_b.stdout) and cli_t.returncode == 0 and "against the record" in cli_t.stdout,
|
|
12992
|
+
"report": PR_read_ok(Path(ws.reports_dir, "wells", wid, "hydraulics.pdf")) and all(x in audit for x in ("hydraulics.declare", "report.hydraulics")),
|
|
12993
|
+
"dossier": "declarations/drillstring/hydraulics.json" in names and f"results/hydraulics/{wid}.json" in names,
|
|
12994
|
+
"page": all(x in page_src for x in ("VIEWS.hydraulics", "['#/hydraulics', 'Hydraulics & ECD']", "/api/hydraulics/settings", "hyChart", "hySppChart")),
|
|
12995
|
+
"help": not H.check("hydraulics") and H.VIEW_TOPIC.get("hydraulics") == "hydraulics",
|
|
12996
|
+
}
|
|
12997
|
+
failed4 = [k for k, v in c4.items() if not v]
|
|
12998
|
+
ok(not failed4,
|
|
12999
|
+
"DA4 the tab's data for a viewer (the well, the worked example); the declarations by an operator only, with a source, readings and rates in "
|
|
13000
|
+
"range; `gea hydraulics` prints the example and a well and declares the viscometer as SPEED=DIAL; the report with its PDF, audited; the "
|
|
13001
|
+
"signed dossier carries the declarations and the result; the tab and the help page"
|
|
13002
|
+
+ (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
|
|
13003
|
+
|
|
13004
|
+
|
|
13005
|
+
def section_db_declarations_engineering(tmp: str) -> None:
|
|
13006
|
+
"""Section DB - the declarations sheet carries the engineering: the survey program, a plan, the pore-pressure
|
|
13007
|
+
settings and a measured pressure, the torque-and-drag string, the hydraulics, a frac stage table and its monitor,
|
|
13008
|
+
production and the decline terms - planned NEW, written, then SAME on a second import and from the template; every
|
|
13009
|
+
malformed row refused with nothing written; the sheet as an Excel workbook; a well with no survey read on the
|
|
13010
|
+
drilling recorder's own TVD, labelled so."""
|
|
13011
|
+
import csv as _csv
|
|
13012
|
+
import io as _io
|
|
13013
|
+
import shutil as _sh
|
|
13014
|
+
import subprocess as _sp
|
|
13015
|
+
from . import __version__ as _ver
|
|
13016
|
+
from . import declarations as DC
|
|
13017
|
+
from . import decline as DCA
|
|
13018
|
+
from . import edr as E
|
|
13019
|
+
from . import frac_hits as FH
|
|
13020
|
+
from . import helplib as H
|
|
13021
|
+
from . import hydraulics as HY
|
|
13022
|
+
from . import pore_pressure as PPF
|
|
13023
|
+
from . import torque_drag as TND
|
|
13024
|
+
from . import wellplan as WPL
|
|
13025
|
+
from . import xlsx_read as XR
|
|
13026
|
+
from .workspace import Workspace
|
|
13027
|
+
pkg = Path(__file__).parent
|
|
13028
|
+
d = Path(tmp, "declare_eng"); d.mkdir()
|
|
13029
|
+
hy = HY.selftest_files(str(d / "hy"))
|
|
13030
|
+
fh = FH.selftest_files(str(d / "fh"))
|
|
13031
|
+
dc = DCA.selftest_files(str(d / "dc"))
|
|
13032
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
|
|
13033
|
+
w1 = ws.add_well_file(hy["record"], display="HY-1", actor="tester")["id"]
|
|
13034
|
+
w2 = ws.add_well_file(fh["gauge"], display="MON-1", actor="tester")["id"]
|
|
13035
|
+
sheet_dir = d / "sheet"; sheet_dir.mkdir()
|
|
13036
|
+
_sh.copy(hy["survey"], sheet_dir / "plan.csv"); _sh.copy(fh["stages"], sheet_dir / "stages.csv"); _sh.copy(dc["path"], sheet_dir / "production.csv")
|
|
13037
|
+
rows = [
|
|
13038
|
+
["[survey_program]", "well", "program", "source"], ["", "HY-1", "0-1000:MWD+SRGM, 1000-:MWD+IFR1", "survey program rev 1 (test)"],
|
|
13039
|
+
["[plans]", "well", "file", "azimuth_reference", "md_unit", "source"], ["", "HY-1", "plan.csv", "true", "ft", "well plan rev 2 (test)"],
|
|
13040
|
+
["[pore_pressure]", "well", "indicator", "bit_in", "nct_top_m", "nct_bottom_m", "source"], ["", "HY-1", "dexponent", "8.75", "1300", "2000", "drilling program (test)"],
|
|
13041
|
+
["[pressures]", "well", "depth_m", "depth_kind", "value", "unit", "kind", "source"], ["", "HY-1", "2100", "tvd", "13.5", "ppg", "lot", "LOT at the 9-5/8 shoe (test)"],
|
|
13042
|
+
["[torque_drag]", "well", "string", "mud_ppg", "mu_cased", "mu_open", "source"], ["", "HY-1", "BHA:350:6.75:95:6.75; drill pipe::5:22.6:6.625", "11", "0.2", "0.28", "BHA report (test)"],
|
|
13043
|
+
["[hydraulics]", "well", "string", "hole", "mw_ppg", "fann", "flow_gpm", "nozzles_32", "bit_in", "tools_psi", "pp_ppg", "fg_ppg", "source"],
|
|
13044
|
+
["", "HY-1", "BHA:350:6.75:2.875; drill pipe::5:4.276", "9-5/8 casing:3500:8.681; open hole::8.75", "11", "600=60 300=38 100=21 6=7 3=6", "500",
|
|
13045
|
+
"14 14 14 14 14", "8.75", "400", "9.5", "14.5", "mud report (test)"],
|
|
13046
|
+
["[frac_stages]", "well", "file", "depth_unit", "source"], ["", "HY-1", "stages.csv", "ft", "post-job report (test)"],
|
|
13047
|
+
["[frac_monitors]", "well", "channel"], ["", "MON-1", "P_gauge_psi"],
|
|
13048
|
+
["[production]", "well", "file", "source"], ["", "HY-1", "production.csv", "monthly report (test)"],
|
|
13049
|
+
["[decline_terms]", "well", "terminal_decline", "price_basis", "oil_price", "gas_price", "opex_month", "source"], ["", "HY-1", "0.08", "flat", "70", "3", "9000", "budget deck (test)"],
|
|
13050
|
+
]
|
|
13051
|
+
buf = _io.StringIO(); _csv.writer(buf, lineterminator="\n").writerows(rows); text = buf.getvalue()
|
|
13052
|
+
p1 = DC.apply(ws, text, "tester", str(sheet_dir))
|
|
13053
|
+
a1 = DC.apply(ws, text, "tester", str(sheet_dir), write=True)
|
|
13054
|
+
p2 = DC.apply(ws, text, "tester", str(sheet_dir))
|
|
13055
|
+
tpl = DC.template(ws)
|
|
13056
|
+
pt = DC.apply(ws, tpl, "tester", str(sheet_dir))
|
|
13057
|
+
hcfg, tcfg, pcfg = HY.well_config(ws, w1), TND.well_config(ws, w1), PPF.well_config(ws, w1)
|
|
13058
|
+
meas = (PPF._load(ws).get("measured") or {}).get(w1) or []
|
|
13059
|
+
c1 = {
|
|
13060
|
+
"planned": not p1["errors"] and p1["counts"]["NEW"] == 10 and p1["counts"]["CHANGE"] == 0 and sorted({s["table"] for s in p1["steps"]}) == sorted(DC.ENG_ORDER),
|
|
13061
|
+
"written": a1["applied"] and len(a1["written"]) == 10,
|
|
13062
|
+
"landed": WPL.well_settings(ws, w1)["program"] == [{"to_md_m": 1000.0, "model": "MWD+SRGM"}, {"to_md_m": None, "model": "MWD+IFR1"}]
|
|
13063
|
+
and bool(ws.well(w1).get("plan")) and pcfg["indicator"] == "dexponent" and pcfg["bit_in"] == 8.75
|
|
13064
|
+
and meas and meas[0]["kind"] == "lot" and meas[0]["unit"] == "ppg" and len(tcfg["string"]) == 2 and tcfg["mu_open"] == 0.28
|
|
13065
|
+
and hcfg["fann"] == {"600": 60.0, "300": 38.0, "100": 21.0, "6": 7.0, "3": 6.0} and hcfg["nozzles_32"] == [14.0] * 5 and len(hcfg["hole"]) == 2
|
|
13066
|
+
and FH.stages(ws).get(w1, {}).get("stages") == 6 and FH.settings(ws)["monitors"].get(w2, {}).get("channel") == "P_gauge_psi"
|
|
13067
|
+
and DCA.production(ws, w1) and DCA.well_config(ws, w1)["oil_price"] == 70.0,
|
|
13068
|
+
"again": not p2["errors"] and p2["counts"]["NEW"] == 0 and p2["counts"]["CHANGE"] == 0 and p2["counts"]["SAME"] == 10,
|
|
13069
|
+
"template": not pt["errors"] and pt["counts"]["NEW"] == 0 and pt["counts"]["CHANGE"] == 0 and all(f"[{t}]" in tpl for t in DC.ENG_ORDER),
|
|
13070
|
+
}
|
|
13071
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
13072
|
+
ok(not failed1,
|
|
13073
|
+
"DB1 one sheet carries the engineering - the survey program, a plan, the pore-pressure settings and a leak-off test, the torque-and-drag string, "
|
|
13074
|
+
"the hydraulics (string, hole, mud, viscometer, nozzles), a frac stage table and its monitored well, production and the decline terms: ten rows "
|
|
13075
|
+
"planned NEW, written through each tab's own function, SAME on a second import; the template lists every table and carries what is declared, "
|
|
13076
|
+
"so importing it writes nothing" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
13077
|
+
|
|
13078
|
+
# -- DB2 every malformed row refused, nothing written ---------------------------------------------------------------------
|
|
13079
|
+
bad = {
|
|
13080
|
+
"survey_program": ["", "HY-1", "0-1000:NO-SUCH-TOOL", "x"], "plans": ["", "HY-1", "missing.csv", "true", "ft", "x"],
|
|
13081
|
+
"pore_pressure": ["", "HY-1", "dexponent", "99", "1300", "2000", "x"], "pressures": ["", "HY-1", "2100", "tvd", "13.5", "ppg", "guess", "x"],
|
|
13082
|
+
"torque_drag": ["", "HY-1", "BHA:350", "11", "0.2", "0.28", "x"],
|
|
13083
|
+
"hydraulics": ["", "HY-1", "", "", "11", "600:60", "500", "40 40", "8.75", "400", "9.5", "14.5", "x"],
|
|
13084
|
+
"frac_stages": ["", "HY-1", "stages.csv", "yards", "x"], "decline_terms": ["", "HY-1", "0.08", "spot", "70", "3", "9000", "x"],
|
|
13085
|
+
}
|
|
13086
|
+
errs = {}
|
|
13087
|
+
for t, r in bad.items():
|
|
13088
|
+
hdr = next(x for x in rows if x[0] == f"[{t}]")
|
|
13089
|
+
b_ = _io.StringIO(); _csv.writer(b_, lineterminator="\n").writerows([hdr, r]); bp = DC.apply(ws, b_.getvalue(), "tester", str(sheet_dir), write=True)
|
|
13090
|
+
errs[t] = (len(bp["errors"]) == 1 and not bp["written"] and not bp["applied"])
|
|
13091
|
+
mixed = rows[:2] + [["[pressures]", "well", "depth_m", "value", "kind", "source"], ["", "HY-1", "-5", "13", "pore", "x"]]
|
|
13092
|
+
b_ = _io.StringIO(); _csv.writer(b_, lineterminator="\n").writerows(mixed); mp = DC.apply(ws, b_.getvalue(), "tester", str(sheet_dir), write=True)
|
|
13093
|
+
ok(all(errs.values()) and len(mp["errors"]) == 1 and not mp["written"],
|
|
13094
|
+
"DB2 a tool model that does not exist, a plan file that is not there, a bit size out of range, a pressure of no known kind, a string section "
|
|
13095
|
+
"short of its figures, a viscometer pair without '=' and nozzles over 32/32, a depth unit of yards, a price basis of 'spot' - each refused with "
|
|
13096
|
+
"its row named; a sheet with one bad row writes none of its good rows"
|
|
13097
|
+
+ (f" [failed: {', '.join(k for k, v in errs.items() if not v)}]" if not all(errs.values()) else ""))
|
|
13098
|
+
|
|
13099
|
+
# -- DB3 the sheet as an Excel workbook --------------------------------------------------------------------------------
|
|
13100
|
+
xp = str(d / "declarations.xlsx")
|
|
13101
|
+
DC.template_xlsx(ws, xp)
|
|
13102
|
+
xb = Path(xp).read_bytes()
|
|
13103
|
+
px = DC.apply(ws, XR.text_of(xb), "tester", str(sheet_dir))
|
|
13104
|
+
cli_t = _sp.run([sys.executable, "-m", "gea", "declare", "--workspace", wsp, "--template", str(d / "t2.xlsx")], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
13105
|
+
cli_p = _sp.run([sys.executable, "-m", "gea", "declare", "--workspace", wsp, "--file", str(d / "t2.xlsx")], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
13106
|
+
ok(XR.is_xlsx(xb) and not px["errors"] and px["counts"]["NEW"] == 0 and px["counts"]["CHANGE"] == 0 and px["counts"]["SAME"] >= 10
|
|
13107
|
+
and cli_t.returncode == 0 and XR.is_xlsx(Path(d / "t2.xlsx").read_bytes()) and cli_p.returncode == 0 and "nothing to write" in cli_p.stdout,
|
|
13108
|
+
"DB3 the template as an Excel workbook (gea declare --template declarations.xlsx, and the Download on the Setup page): a workbook the import "
|
|
13109
|
+
"reads back to the same plan - nothing new to write")
|
|
13110
|
+
|
|
13111
|
+
# -- DB4 no survey: the recorder's own TVD -------------------------------------------------------------------------------
|
|
13112
|
+
st = E.read(hy["record"])
|
|
13113
|
+
out = Path(ws.reports_dir, "wells", w1); out.mkdir(parents=True, exist_ok=True)
|
|
13114
|
+
E.write_record(st, str(out), _ver)
|
|
13115
|
+
rp = HY.recorder_path(ws, w1)
|
|
13116
|
+
r_h = HY.page(ws, "workspace", w1)["result"]
|
|
13117
|
+
TND.set_well(ws, "tester", w1, "BHA report (test)", TND.parse_string("BHA:350:6.75:95:6.75; drill pipe::5:22.6:6.625"), 11)
|
|
13118
|
+
r_t = TND.page(ws, "workspace", w1)["result"]
|
|
13119
|
+
from . import well3d as W
|
|
13120
|
+
W.attach_trajectory(ws, w1, "s.csv", Path(hy["survey"]).read_bytes(), "tester", "true", "ft", None, None, None, "test survey")
|
|
13121
|
+
r_s = HY.page(ws, "workspace", w1)["result"]
|
|
13122
|
+
help_txt = H.page("declare") or ""
|
|
13123
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
13124
|
+
c4 = {
|
|
13125
|
+
"path": rp and rp["md_ft"][0] == 0.0 and abs(max(rp["tvd_ft"]) - 7480.0) < 30.0 and max(rp["inc_deg"]) <= 61.0 and "not a survey" in rp["source"],
|
|
13126
|
+
"hydraulics": r_h and r_h["path_from"] == "recorder" and "Interpolated TVD" in r_h["how"] and abs(r_h["record"]["median_difference_psi"] - hy["offset_psi"]) <= 10.0
|
|
13127
|
+
and abs(r_h["tvd_td_ft"] - r_s["tvd_td_ft"]) < 30.0,
|
|
13128
|
+
"torque_drag": r_t and r_t["path_from"] == "recorder" and "one vertical plane" in r_t["how"] and 55.0 <= r_t["max_inc_deg"] <= 61.0,
|
|
13129
|
+
"survey_first": r_s["path_from"] == "survey",
|
|
13130
|
+
"help": not H.check("declare") and all(f"[{t}]" in help_txt for t in DC.ENG_ORDER) and "Interpolated TVD" in (H.page("hydraulics") or "")
|
|
13131
|
+
and "/api/declare/template?format=xlsx" in page_src,
|
|
13132
|
+
}
|
|
13133
|
+
failed4 = [k for k, v in c4.items() if not v]
|
|
13134
|
+
ok(not failed4,
|
|
13135
|
+
"DB4 a well with no survey attached is read on the drilling recorder's own Interpolated TVD, labelled as the recorder's interpolation and not a "
|
|
13136
|
+
"survey: the hydraulics' TVDs within 30 ft of the survey's and the standpipe offset recovered the same; torque and drag on an inclination-only path "
|
|
13137
|
+
"in one vertical plane, said so; a survey, once attached, is used instead; the help names every table"
|
|
13138
|
+
+ (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
|
|
13139
|
+
|
|
13140
|
+
|
|
12824
13141
|
def PR_read_ok(path) -> bool:
|
|
12825
13142
|
from . import pdf_report as PR
|
|
12826
13143
|
try:
|
|
@@ -12936,6 +13253,8 @@ def main() -> int:
|
|
|
12936
13253
|
section_cx_https(tmp)
|
|
12937
13254
|
section_cy_company_sign_in(tmp)
|
|
12938
13255
|
section_cz_it_review(tmp)
|
|
13256
|
+
section_da_hydraulics(tmp)
|
|
13257
|
+
section_db_declarations_engineering(tmp)
|
|
12939
13258
|
if _FAILS:
|
|
12940
13259
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
12941
13260
|
for f in _FAILS:
|