gea-program 0.40.0__tar.gz → 0.41.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.40.0 → gea_program-0.41.0}/PKG-INFO +26 -3
- {gea_program-0.40.0 → gea_program-0.41.0}/README.md +25 -2
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/__init__.py +1 -1
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/__main__.py +70 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/acceptance_tests.py +261 -4
- gea_program-0.41.0/gea/declarations.py +622 -0
- gea_program-0.41.0/gea/help/declare.md +13 -0
- gea_program-0.41.0/gea/help/penetrator.md +15 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/helplib.py +3 -1
- gea_program-0.41.0/gea/penetrator.py +520 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/mud_motor_specs.json +52 -2
- gea_program-0.41.0/gea/reference/penetrator_ratings.json +75 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/tool_sources.json +21 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/service.py +31 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/tool_taxonomy.py +10 -1
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/web/app.html +84 -2
- {gea_program-0.40.0 → gea_program-0.41.0}/gea_program.egg-info/PKG-INFO +26 -3
- {gea_program-0.40.0 → gea_program-0.41.0}/gea_program.egg-info/SOURCES.txt +5 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/pyproject.toml +1 -1
- {gea_program-0.40.0 → gea_program-0.41.0}/LICENSE +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/backup.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/bench.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/blind_harness.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog_map.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/catalog_register.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/certificates.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/cli.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/client_reports.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/config_versioning.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/conformance.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/control_room.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/correlation.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/dashboard.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/deviation.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/dlis.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/dnp3.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/doctor.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/drill_string.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/earth_model.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/economics.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/edr.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/elevation.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/etp.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/example_register_map.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/fat_sat.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/files.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/follower.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/forward_model.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/friction_priors.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/gamma.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/geodesy.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/hartip.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/alarms.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/backup.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/catalog.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/charts.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/conformance.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/control-room.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/data-in.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/dlis.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/doctor.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/drift.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/economics.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/edr.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/etp.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/files.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/historian.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/instruments.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/interval.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/map.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/month-end.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/notifications.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/osdu.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/patches.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/quality.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/seismic.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/setup.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/simulation.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/site.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/sites.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/slip.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/soak.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/sra.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/start.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/structure.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/tools.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/transients.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/vibration.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/well-report.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/help/well3d.md +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/housekeeping.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/interval.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/jobs.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/live_ports.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/loadtest.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/modbus.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/model_card.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/month_end.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/notify.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/opcua_port.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/operator_app.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/osdu.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/patches.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/permits.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/piwebapi.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/ports.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/ppdm.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/project.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/quakeml.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reconciler.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/sample_record.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/sbom.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seedlink.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/segy.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_array.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_film.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_response.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_track.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/series_cache.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/service_life.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/shapefile.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/shell.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/shut_in.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/simulation.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/site_map.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/sla_report.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/slip.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/soak.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/sra.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/store_forward.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/strata_join.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/structure.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/supervisor.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/survey_view.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/telemetry.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/tool_library.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/transient.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/vibration.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/well3d.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/well_assembler.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/well_report.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/wits0.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/witsml.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea/workspace.py +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.40.0 → gea_program-0.41.0}/setup.cfg +0 -0
- {gea_program-0.40.0 → gea_program-0.41.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.41.0
|
|
4
4
|
Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
|
|
5
5
|
Author: Daniel T. Murphy
|
|
6
6
|
License: MPL-2.0
|
|
@@ -648,6 +648,29 @@ against it; `gea seedlink --config ... --hello` prints what a server says of
|
|
|
648
648
|
itself; `gea help seedlink`. A TexNet station is served by EarthScope at
|
|
649
649
|
`rtserve.iris.washington.edu:18000`, network `TX`.
|
|
650
650
|
|
|
651
|
+
### The declarations sheet
|
|
652
|
+
|
|
653
|
+
Everything the operator declares about a pad comes in from one spreadsheet:
|
|
654
|
+
each well's API number, position and reference elevation, its directional
|
|
655
|
+
survey, the day rates, one-off costs and AFE, the fleet, the drill-string
|
|
656
|
+
runs and their components, and the ESP penetrator and drive. Every row is
|
|
657
|
+
checked against the workspace and planned NEW, CHANGE or SAME before
|
|
658
|
+
anything is written; one error and nothing is. The sheet the program writes
|
|
659
|
+
for a workspace is already filled with what is declared, so a site fills in
|
|
660
|
+
the blanks. On the Setup tab, or `gea declare --template`, `gea declare
|
|
661
|
+
--file`, `gea help declare`.
|
|
662
|
+
|
|
663
|
+
### Completion - the ESP wellhead penetrator
|
|
664
|
+
|
|
665
|
+
The Completion tab keeps each ESP well's penetrator installation record -
|
|
666
|
+
the installer and their certification, the motor, the gauge distance, the
|
|
667
|
+
insulation readings, the void test - and checks the well's ESP drive, motor
|
|
668
|
+
nameplate and wellhead against the penetrator's ratings as its maker's
|
|
669
|
+
document prints them, one line each: voltage, current, frequency, phases,
|
|
670
|
+
hazardous area, gas group, temperature class, ambient range and altitude.
|
|
671
|
+
It carries the permanent magnet motor safety note with its sources.
|
|
672
|
+
`gea penetrator`, `gea help penetrator`.
|
|
673
|
+
|
|
651
674
|
### Drill string
|
|
652
675
|
|
|
653
676
|
The Drill String tab holds each run's string from the bit up - drawn as a
|
|
@@ -657,7 +680,7 @@ its declared service interval. The downhole motor tracker charts the
|
|
|
657
680
|
differential against the maker's limits, the stalls, the motor's and the
|
|
658
681
|
bit's speed and a torque estimate, and judges the motor's stability from
|
|
659
682
|
the slow oscillations of the torque and the differential, block by block.
|
|
660
|
-
The tool catalogue carries
|
|
683
|
+
The tool catalogue carries 43 downhole motors with the maker's figures.
|
|
661
684
|
`gea drillstring`, `gea tools --action motors`, `gea help drillstring`.
|
|
662
685
|
|
|
663
686
|
### Simulation
|
|
@@ -785,7 +808,7 @@ library**: every class of downhole tool in use across the industry - bits
|
|
|
785
808
|
and hole openers, motors and rotary steerable systems, MWD and LWD, the drill
|
|
786
809
|
string and its subs, casing and cementing equipment, completion and
|
|
787
810
|
artificial lift, wireline and cased-hole tools, fishing and milling, test
|
|
788
|
-
tools - ninety-
|
|
811
|
+
tools - ninety-seven classes in nine categories. Point at a tool, or Tab to
|
|
789
812
|
it, for a one-line description; click, tap or press Enter for its tutorial:
|
|
790
813
|
what it is, where it runs, how it works, what it shows in the data, what to
|
|
791
814
|
watch, and what this program does with it, with the published figures
|
|
@@ -609,6 +609,29 @@ against it; `gea seedlink --config ... --hello` prints what a server says of
|
|
|
609
609
|
itself; `gea help seedlink`. A TexNet station is served by EarthScope at
|
|
610
610
|
`rtserve.iris.washington.edu:18000`, network `TX`.
|
|
611
611
|
|
|
612
|
+
### The declarations sheet
|
|
613
|
+
|
|
614
|
+
Everything the operator declares about a pad comes in from one spreadsheet:
|
|
615
|
+
each well's API number, position and reference elevation, its directional
|
|
616
|
+
survey, the day rates, one-off costs and AFE, the fleet, the drill-string
|
|
617
|
+
runs and their components, and the ESP penetrator and drive. Every row is
|
|
618
|
+
checked against the workspace and planned NEW, CHANGE or SAME before
|
|
619
|
+
anything is written; one error and nothing is. The sheet the program writes
|
|
620
|
+
for a workspace is already filled with what is declared, so a site fills in
|
|
621
|
+
the blanks. On the Setup tab, or `gea declare --template`, `gea declare
|
|
622
|
+
--file`, `gea help declare`.
|
|
623
|
+
|
|
624
|
+
### Completion - the ESP wellhead penetrator
|
|
625
|
+
|
|
626
|
+
The Completion tab keeps each ESP well's penetrator installation record -
|
|
627
|
+
the installer and their certification, the motor, the gauge distance, the
|
|
628
|
+
insulation readings, the void test - and checks the well's ESP drive, motor
|
|
629
|
+
nameplate and wellhead against the penetrator's ratings as its maker's
|
|
630
|
+
document prints them, one line each: voltage, current, frequency, phases,
|
|
631
|
+
hazardous area, gas group, temperature class, ambient range and altitude.
|
|
632
|
+
It carries the permanent magnet motor safety note with its sources.
|
|
633
|
+
`gea penetrator`, `gea help penetrator`.
|
|
634
|
+
|
|
612
635
|
### Drill string
|
|
613
636
|
|
|
614
637
|
The Drill String tab holds each run's string from the bit up - drawn as a
|
|
@@ -618,7 +641,7 @@ its declared service interval. The downhole motor tracker charts the
|
|
|
618
641
|
differential against the maker's limits, the stalls, the motor's and the
|
|
619
642
|
bit's speed and a torque estimate, and judges the motor's stability from
|
|
620
643
|
the slow oscillations of the torque and the differential, block by block.
|
|
621
|
-
The tool catalogue carries
|
|
644
|
+
The tool catalogue carries 43 downhole motors with the maker's figures.
|
|
622
645
|
`gea drillstring`, `gea tools --action motors`, `gea help drillstring`.
|
|
623
646
|
|
|
624
647
|
### Simulation
|
|
@@ -746,7 +769,7 @@ library**: every class of downhole tool in use across the industry - bits
|
|
|
746
769
|
and hole openers, motors and rotary steerable systems, MWD and LWD, the drill
|
|
747
770
|
string and its subs, casing and cementing equipment, completion and
|
|
748
771
|
artificial lift, wireline and cased-hole tools, fishing and milling, test
|
|
749
|
-
tools - ninety-
|
|
772
|
+
tools - ninety-seven classes in nine categories. Point at a tool, or Tab to
|
|
750
773
|
it, for a one-line description; click, tap or press Enter for its tutorial:
|
|
751
774
|
what it is, where it runs, how it works, what it shows in the data, what to
|
|
752
775
|
watch, and what this program does with it, with the published figures
|
|
@@ -524,6 +524,21 @@ def main(argv=None) -> int:
|
|
|
524
524
|
p_ds.add_argument("--actor", type=str, default="cli")
|
|
525
525
|
p_ds.add_argument("--json", action="store_true")
|
|
526
526
|
|
|
527
|
+
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")
|
|
528
|
+
p_dc.add_argument("--workspace", type=str, required=True)
|
|
529
|
+
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")
|
|
530
|
+
p_dc.add_argument("--apply", action="store_true", help="write the NEW and CHANGE rows (only when the sheet has no error)")
|
|
531
|
+
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")
|
|
532
|
+
p_dc.add_argument("--actor", type=str, default="cli")
|
|
533
|
+
p_dc.add_argument("--json", action="store_true")
|
|
534
|
+
|
|
535
|
+
p_pn = sub.add_parser("penetrator", help="the ESP wellhead penetrator: the penetrators the program knows with their ratings, the permanent magnet motor safety note, and each well's installation record and drive checked against the ratings")
|
|
536
|
+
p_pn.add_argument("--workspace", type=str, default=None)
|
|
537
|
+
p_pn.add_argument("--well", type=str, default=None)
|
|
538
|
+
p_pn.add_argument("--remove", type=str, default=None, choices=("install", "drive"), help="remove the well's installation record or its drive")
|
|
539
|
+
p_pn.add_argument("--actor", type=str, default="cli")
|
|
540
|
+
p_pn.add_argument("--json", action="store_true")
|
|
541
|
+
|
|
527
542
|
p_sm = sub.add_parser("simulation", help="the simulation in words: the scenes (Volve 15/9-F-4 with its logs and interpretation, Volve F-5 and F-10 on the survey clock, every drilling-recorder well), and what the record says at a depth (the Simulation tab replays it)")
|
|
528
543
|
p_sm.add_argument("--workspace", type=str, default=None)
|
|
529
544
|
p_sm.add_argument("--scene", type=str, default=None, help="e.g. volve-f4, or well:Well-30636033")
|
|
@@ -2074,6 +2089,61 @@ def main(argv=None) -> int:
|
|
|
2074
2089
|
raise SystemExit(f"drillstring: {e.args[0] if e.args else e}")
|
|
2075
2090
|
print(_json.dumps(p, default=str) if a.json else _DS.text(p))
|
|
2076
2091
|
return 0
|
|
2092
|
+
elif a.cmd == "declare":
|
|
2093
|
+
import json as _json
|
|
2094
|
+
from . import declarations as _DC
|
|
2095
|
+
from .cli import _safe_stdout
|
|
2096
|
+
from .workspace import Workspace, WorkspaceError
|
|
2097
|
+
_safe_stdout()
|
|
2098
|
+
try:
|
|
2099
|
+
ws = Workspace(a.workspace)
|
|
2100
|
+
except WorkspaceError as e:
|
|
2101
|
+
raise SystemExit(f"declare: {e}")
|
|
2102
|
+
if a.template:
|
|
2103
|
+
with open(a.template, "w", encoding="utf-8", newline="") as f:
|
|
2104
|
+
f.write(_DC.template(ws))
|
|
2105
|
+
print(f"wrote {a.template}: fill in the blanks, then gea declare --workspace {a.workspace} --file {a.template}")
|
|
2106
|
+
return 0
|
|
2107
|
+
if not a.file:
|
|
2108
|
+
raise SystemExit("declare: give --file <sheet.csv> (or --template <out.csv> to start one)")
|
|
2109
|
+
try:
|
|
2110
|
+
with open(a.file, encoding="utf-8-sig") as f:
|
|
2111
|
+
text_ = f.read()
|
|
2112
|
+
except OSError as e:
|
|
2113
|
+
raise SystemExit(f"declare: {e}")
|
|
2114
|
+
p = _DC.apply(ws, text_, a.actor, os.path.dirname(os.path.abspath(a.file)), write=a.apply)
|
|
2115
|
+
print(_json.dumps(p, default=str) if a.json else _DC.text(p))
|
|
2116
|
+
return 1 if p["errors"] else 0
|
|
2117
|
+
elif a.cmd == "penetrator":
|
|
2118
|
+
import json as _json
|
|
2119
|
+
from . import penetrator as _PN
|
|
2120
|
+
from .cli import _safe_stdout
|
|
2121
|
+
from .workspace import Workspace, WorkspaceError
|
|
2122
|
+
_safe_stdout()
|
|
2123
|
+
ws = None
|
|
2124
|
+
if a.workspace:
|
|
2125
|
+
try:
|
|
2126
|
+
ws = Workspace(a.workspace)
|
|
2127
|
+
except WorkspaceError as e:
|
|
2128
|
+
raise SystemExit(f"penetrator: {e}")
|
|
2129
|
+
try:
|
|
2130
|
+
if a.remove:
|
|
2131
|
+
if ws is None or not a.well:
|
|
2132
|
+
raise SystemExit("penetrator: --remove needs --workspace and --well")
|
|
2133
|
+
_PN.remove(ws, a.actor, a.well, a.remove)
|
|
2134
|
+
print(f"removed the {a.remove} record of {a.well}")
|
|
2135
|
+
return 0
|
|
2136
|
+
if a.well:
|
|
2137
|
+
if ws is None:
|
|
2138
|
+
raise SystemExit("penetrator: --well needs --workspace")
|
|
2139
|
+
c = _PN.check(ws, a.well)
|
|
2140
|
+
print(_json.dumps(c, default=str) if a.json else _PN.text_check(c))
|
|
2141
|
+
return 0
|
|
2142
|
+
p = _PN.page(ws)
|
|
2143
|
+
except (ValueError, KeyError, OSError) as e:
|
|
2144
|
+
raise SystemExit(f"penetrator: {e.args[0] if e.args else e}")
|
|
2145
|
+
print(_json.dumps(p, default=str) if a.json else _PN.text(p))
|
|
2146
|
+
return 0
|
|
2077
2147
|
elif a.cmd == "simulation":
|
|
2078
2148
|
import json as _json
|
|
2079
2149
|
from . import simulation as _SIM
|
|
@@ -9309,8 +9309,8 @@ def section_ci_drill_string(tmp: str) -> None:
|
|
|
9309
9309
|
ms = cat["motors"]
|
|
9310
9310
|
m64, m89 = DS.motor_spec("msd-6-3-4-78-6.4"), DS.motor_spec("msd-8-3-8-89-4.0")
|
|
9311
9311
|
c1 = {
|
|
9312
|
-
"catalogue": len(ms) ==
|
|
9313
|
-
and cat["fetched"] == "2026-10-17" and TC.catalog()["counts"]["motors"] ==
|
|
9312
|
+
"catalogue": len(ms) == 43 and len({m["id"] for m in ms}) == 43 and cat["publisher"].startswith("MS Directional") and cat["url"].startswith("https://")
|
|
9313
|
+
and cat["fetched"] == "2026-10-17" and TC.catalog()["counts"]["motors"] == 43,
|
|
9314
9314
|
"sane": all(m["flow_gpm"][0] < m["flow_gpm"][1] and 0 < m["rev_per_gal"] < 2 and m["max_operating_diff_psi"] <= m["max_diff_psi"]
|
|
9315
9315
|
and m["stator_lobes"] == m["rotor_lobes"] + 1 and m["max_torque_ft_lb"] > 0 and m["od_in"] > 4 for m in ms),
|
|
9316
9316
|
"as_printed": (m64["rev_per_gal"], m64["flow_gpm"], m64["max_operating_diff_psi"], m64["max_diff_psi"], m64["max_torque_ft_lb"]) == (0.28, [300, 600], 1000, 1820, 14360)
|
|
@@ -9323,7 +9323,7 @@ def section_ci_drill_string(tmp: str) -> None:
|
|
|
9323
9323
|
c1["unknown"] = True
|
|
9324
9324
|
failed1 = [k for k, v in c1.items() if not v]
|
|
9325
9325
|
ok(not failed1,
|
|
9326
|
-
"CI1 the downhole motor catalogue:
|
|
9326
|
+
"CI1 the downhole motor catalogue: 43 power sections with the maker's flow range, revolutions per gallon, maximum operating and "
|
|
9327
9327
|
"maximum differential, maximum torque and weight on bit as its spec sheets print them, the handbook and the date it was read; "
|
|
9328
9328
|
"every lobe count one more on the stator than the rotor; counted in the tool catalogue; an unknown motor named"
|
|
9329
9329
|
+ (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
@@ -9430,7 +9430,7 @@ def section_ci_drill_string(tmp: str) -> None:
|
|
|
9430
9430
|
cli_m = _sp.run([sys.executable, "-m", "gea", "tools", "--action", "motors"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9431
9431
|
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
9432
9432
|
c3.update({
|
|
9433
|
-
"api": s_g == 200 and len(pg["runs"]) == 2 and pg["runs"][0]["track"]["usage"]["circulating_hours"] == 16.0 and s_m == 200 and len(mm["motors"]) ==
|
|
9433
|
+
"api": s_g == 200 and len(pg["runs"]) == 2 and pg["runs"][0]["track"]["usage"]["circulating_hours"] == 16.0 and s_m == 200 and len(mm["motors"]) == 43
|
|
9434
9434
|
and s_vp == 403 and s_op == 200 and s_bad == 400 and s_nw == 404 and s_rm == 200 and s_rm2 == 404 and s_uw == 404 and s_ac == 404,
|
|
9435
9435
|
"cli": cli.returncode == 0 and "stability: CHANGED" in cli.stdout and "DUE: Positive displacement mud motor" in cli.stdout
|
|
9436
9436
|
and cli_m.returncode == 0 and "msd-6-3-4-78-6.4" in cli_m.stdout,
|
|
@@ -9447,6 +9447,262 @@ def section_ci_drill_string(tmp: str) -> None:
|
|
|
9447
9447
|
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
9448
9448
|
|
|
9449
9449
|
|
|
9450
|
+
def section_cj_declarations(tmp: str) -> None:
|
|
9451
|
+
"""Section CJ - the declarations sheet and the ESP penetrator: the penetrator ratings as the maker's documents print
|
|
9452
|
+
them; an installation record and a drive checked line by line, each way a line can fail found; the sheet planned row
|
|
9453
|
+
by row against the workspace, one error writing nothing, the write going through each declaration's own function,
|
|
9454
|
+
the same sheet again planning only SAME, the template round-tripping; the two motors added to the catalogue; the API,
|
|
9455
|
+
the CLI, the Setup card, the Completion tab and the help pages."""
|
|
9456
|
+
import http.cookiejar
|
|
9457
|
+
import subprocess as _sp
|
|
9458
|
+
import urllib.request
|
|
9459
|
+
import urllib.error
|
|
9460
|
+
from . import declarations as DC
|
|
9461
|
+
from . import drill_string as DS
|
|
9462
|
+
from . import economics as EC
|
|
9463
|
+
from . import helplib as H
|
|
9464
|
+
from . import penetrator as PN
|
|
9465
|
+
from . import tool_taxonomy as TX
|
|
9466
|
+
from .workspace import Workspace
|
|
9467
|
+
from .service import Service, Users
|
|
9468
|
+
pkg = Path(__file__).parent
|
|
9469
|
+
d = Path(tmp, "cj"); d.mkdir()
|
|
9470
|
+
wsp = str(d / "ws")
|
|
9471
|
+
ws = Workspace.create(wsp, "Pad CJ")
|
|
9472
|
+
w1 = ws.add_well_file(str(pkg / "sample_well_profile.csv"), display="ESP-1")
|
|
9473
|
+
w2 = ws.add_well_file(str(pkg / "sample_well_profile.csv"), display="ESP-2")
|
|
9474
|
+
|
|
9475
|
+
# -- CJ1 the penetrator: ratings and the check --------------------------------------------------------------
|
|
9476
|
+
g5 = PN.resolve(None, "genco-gps-5")
|
|
9477
|
+
r5 = g5["ratings"]
|
|
9478
|
+
c1 = {
|
|
9479
|
+
"ratings": (r5["max_volts"], r5["max_amps_fla"], r5["phases"], r5["freq_hz"], r5["proof_test_psi"], r5["working_psi_api"], r5["ambient_f"], r5["altitude_max_m"])
|
|
9480
|
+
== (5000, 300, 3, [10, 100], 10000, 5000, [-30, 110], 2000)
|
|
9481
|
+
and r5["divisions"] == ["Class I, Division 1", "Class I, Division 2"] and r5["zone_group"] == "IIA" and r5["temp_class"] == "T5"
|
|
9482
|
+
and g5["pmm"] is True and g5["certified_installer_required"] is True and "IP-40" in g5["document"] and "Appendix A" in g5["section"],
|
|
9483
|
+
"div2_only": PN.resolve(None, "genco-gps-5d")["ratings"] == {"divisions": ["Class I, Division 2"]} and "IP-20" in PN.resolve(None, "genco-gps-5d")["document"]
|
|
9484
|
+
and "IP-06" in PN.resolve(None, "genco-gps-3")["document"],
|
|
9485
|
+
"no_procedure_text": all(len(json.dumps(p)) < 1500 for p in PN.penetrators()) and "Hot Gloves" not in (pkg / "reference" / "penetrator_ratings.json").read_text(encoding="utf-8"),
|
|
9486
|
+
"pmm_note": len(PN.pmm_note()["text"]) == 3 and "generator" in PN.pmm_note()["text"][0] and any((s.get("url") or "").startswith("https://read.nxtbook.com") for s in PN.pmm_note()["sources"]),
|
|
9487
|
+
"taxonomy": TX.tool_class("wellhead_penetrator")["category"] == "completion" and "Sources (fetched 2026-10-17)" in TX.tutorial_text("wellhead_penetrator")
|
|
9488
|
+
and "Sources (fetched 2026-10-14)" in TX.tutorial_text("pdm_motor"),
|
|
9489
|
+
}
|
|
9490
|
+
bad = {}
|
|
9491
|
+
for k, kw in (("motor", dict(motor_type="diesel")), ("phase", dict(insulation={"D": 5})), ("negative", dict(insulation={"A": -1})),
|
|
9492
|
+
("min_source", dict(ir_min_megohm=500)), ("yesno", dict(void_held="maybe")), ("date", dict(installed="last week"))):
|
|
9493
|
+
try:
|
|
9494
|
+
PN.install_record(ws, w1["id"], "genco-gps-5", **kw); bad[k] = False
|
|
9495
|
+
except ValueError:
|
|
9496
|
+
bad[k] = True
|
|
9497
|
+
for k, kw in (("source", dict()), ("area", dict(area="Zone 9", source="s")), ("freq", dict(freq_min_hz=90, freq_max_hz=30, source="s")),
|
|
9498
|
+
("group", dict(gas_group="Q", source="s"))):
|
|
9499
|
+
try:
|
|
9500
|
+
PN.drive_record(ws, w1["id"], **kw); bad["drive_" + k] = False
|
|
9501
|
+
except ValueError:
|
|
9502
|
+
bad["drive_" + k] = True
|
|
9503
|
+
try:
|
|
9504
|
+
PN.install_record(ws, w1["id"], "nope"); bad["unknown"] = False
|
|
9505
|
+
except KeyError:
|
|
9506
|
+
bad["unknown"] = True
|
|
9507
|
+
c1["refused"] = all(bad.values())
|
|
9508
|
+
PN.save_install(ws, "tester", w1["id"], "genco-gps-5", installed="2026-09-01", installer="J. Doe", certified="yes", certificate="GSC-1", motor_type="pmm",
|
|
9509
|
+
gauge_distance_in=31.25, insulation={"A": 2000, "B": 1800, "C": 2200}, ir_test_volts=5000, void_test_psi=5000, void_test_minutes=15, void_held="yes")
|
|
9510
|
+
part = PN.check(ws, w1["id"])
|
|
9511
|
+
PN.save_drive(ws, "tester", w1["id"], maker="D", model="V", max_volts=4800, max_amps=280, freq_min_hz=30, freq_max_hz=90, phases=3, motor_volts=3200,
|
|
9512
|
+
motor_amps=95, area="CL 1 Div 1", gas_group="D", temp_class="T3", ambient_min_f=10, ambient_max_f=105, source="datasheet")
|
|
9513
|
+
ws.set_well(w1["id"], surface={"lat": 31.9, "lon": -102.1, "datum": "NAD83", "elevation": {"ft": 2900, "datum": "KB", "source": "W-2"}}, actor="tester")
|
|
9514
|
+
good = PN.check(ws, w1["id"])
|
|
9515
|
+
st = {r["item"]: r for r in good["rows"]}
|
|
9516
|
+
PN.save_drive(ws, "tester", w1["id"], maker="D", model="V", max_volts=5200, max_amps=320, freq_min_hz=5, freq_max_hz=120, phases=3, motor_volts=3200,
|
|
9517
|
+
motor_amps=95, area="Class I, Zone 0", gas_group="IIC", temp_class="T6", ambient_min_f=-40, ambient_max_f=105, source="datasheet")
|
|
9518
|
+
PN.save_install(ws, "tester", w1["id"], "genco-gps-5", certified="no", motor_type="PMM", gauge_distance_in=31.25, insulation={"A": 2000, "B": 300, "C": 2200},
|
|
9519
|
+
ir_min_megohm=500, ir_min_source="site standard 4", void_test_psi=6000, void_held="yes")
|
|
9520
|
+
out = PN.check(ws, w1["id"])
|
|
9521
|
+
so = {r["item"]: r["status"] for r in out["rows"]}
|
|
9522
|
+
PN.save_install(ws, "tester", w2["id"], "genco-gps-5d", motor_type="PMM", void_test_psi=3000, void_held="no")
|
|
9523
|
+
PN.save_drive(ws, "tester", w2["id"], area="Class I, Division 1", source="drawing")
|
|
9524
|
+
d2 = {r["item"]: r["status"] for r in PN.check(ws, w2["id"])["rows"]}
|
|
9525
|
+
c1.update({
|
|
9526
|
+
"incomplete": part["status"] == "INCOMPLETE" and {r["item"]: r["status"] for r in part["rows"]}["drive output voltage"] == "NOT DECLARED",
|
|
9527
|
+
"within": good["status"] == "WITHIN" and st["altitude"]["declared"] == round(2900 * 0.3048, 1) and st["hazardous area"]["status"] == "WITHIN"
|
|
9528
|
+
and st["temperature class"]["status"] == "WITHIN" and st["void test"]["status"] == "WITHIN" and st["insulation"]["status"] == "RECORDED"
|
|
9529
|
+
and any("PMM safety note" in n for n in good["notes"]),
|
|
9530
|
+
"outside": out["status"] == "OUTSIDE" and all(so[k] == "OUTSIDE" for k in ("certified installer", "insulation", "void test", "drive output voltage",
|
|
9531
|
+
"drive output current", "drive frequency", "hazardous area", "gas group",
|
|
9532
|
+
"temperature class", "ambient temperature"))
|
|
9533
|
+
and "set its current limit at or below 300 A" in next(r["why"] for r in out["rows"] if r["item"] == "drive output current"),
|
|
9534
|
+
"div2_pen": d2["hazardous area"] == "OUTSIDE" and d2["motor"] == "NOT STATED" and d2["void test"] == "OUTSIDE" and d2["drive output voltage"] == "NOT RATED"
|
|
9535
|
+
and d2["certified installer"] == "NOT STATED",
|
|
9536
|
+
"audit": sum(a["action"].startswith("penetrator.") for a in ws.audit_log(500)) >= 6,
|
|
9537
|
+
})
|
|
9538
|
+
PN.remove(ws, "tester", w2["id"], "drive")
|
|
9539
|
+
try:
|
|
9540
|
+
PN.remove(ws, "tester", w2["id"], "drive"); c1["remove"] = False
|
|
9541
|
+
except KeyError:
|
|
9542
|
+
c1["remove"] = "drive" not in PN.records(ws)[w2["id"]]
|
|
9543
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
9544
|
+
ok(not failed1,
|
|
9545
|
+
"CJ1 the ESP wellhead penetrator: the GPS-5's ratings as its maker's IP-40 Appendix A prints them, the GPS-5D and GPS-3 with only "
|
|
9546
|
+
"the Division 2 of their titles, none of the instructions' procedure text; the PMM safety note with its sources; the penetrator a "
|
|
9547
|
+
"class of the tool library; a bad motor, conductor, reading, date or classification refused; the check INCOMPLETE until the drive "
|
|
9548
|
+
"is declared, WITHIN when every line is, and each of ten lines found OUTSIDE when it is; a Division 2 penetrator at a Division 1 "
|
|
9549
|
+
"wellhead OUTSIDE, its unprinted ratings NOT RATED and its silence on PMM NOT STATED"
|
|
9550
|
+
+ (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
9551
|
+
|
|
9552
|
+
# -- CJ2 the sheet ------------------------------------------------------------------------------------------
|
|
9553
|
+
(d / "survey.csv").write_text("MD,Inc,Azi\n0,0,0\n1000,2,45\n2000,5,50\n", encoding="utf-8")
|
|
9554
|
+
sheet = "\n".join([
|
|
9555
|
+
"# Pad CJ declarations",
|
|
9556
|
+
"[wells],well,api_number,well_name,operator,lat,lon,datum,elevation_ft,elevation_datum,elevation_source",
|
|
9557
|
+
",ESP-2,42-317-41234,Test 2H,Op LLC,31.95,-102.15,NAD83,2910,KB,W-2 completion report",
|
|
9558
|
+
"[fleet],class_id,maker,model,serial,od_in,datasheet,note,ratings",
|
|
9559
|
+
',wellhead_penetrator,Acme,P-9,SN1,,Acme DS-9 rev A,,"max_volts=4160; max_amps_fla=250; freq_hz=10-90; divisions=Class I, Division 2"',
|
|
9560
|
+
"[rates],well,what,usd_per_day,from,to,source",
|
|
9561
|
+
',ESP-2,rig spread,"28,500",2026-01-01,2026-02-01,contract sched B',
|
|
9562
|
+
",ESP-2,rig spread,29000,2026-02-01,,contract sched B amd 1",
|
|
9563
|
+
"[items],well,what,usd,section,source",
|
|
9564
|
+
",ESP-2,8.5 in PDC bit,18000.5,3,invoice 77",
|
|
9565
|
+
"[afe],well,usd,source",
|
|
9566
|
+
",ESP-2,4512345.67,AFE 26-114",
|
|
9567
|
+
"[surveys],well,file,azimuth_reference,grid,declination_deg,md_unit,depth_reference,source",
|
|
9568
|
+
",ESP-2,survey.csv,true,,,ft,KB,operator MWD report",
|
|
9569
|
+
"[runs],well,run,start,end,depth_in_ft,depth_out_ft,note",
|
|
9570
|
+
",ESP-2,Run 1,2026-01-03T06:00,2026-01-06T12:00,1500,9800,",
|
|
9571
|
+
",ESP-2,Run 2,2026-01-07T06:00,,9800,,",
|
|
9572
|
+
"[components],well,run,class_id,maker,model,serial,od_in,length_ft,motor_id,service_limit,service_basis,service_source,motor_rev_per_gal,motor_flow_min_gpm,motor_flow_max_gpm,motor_lobes,motor_source",
|
|
9573
|
+
",ESP-2,Run 1,pdc_bit,Bitco,X616,B1,8.5,1,,,,,,,,,",
|
|
9574
|
+
",ESP-2,Run 1,pdm_motor,,,M77,,28,msd-8-x-7-3-4-hybrid-78-5.9,200,circulating_hours,rental contract,,,,,",
|
|
9575
|
+
",ESP-2,Run 2,pdc_bit,Bitco,X616,B2,8.5,,,,,,,,,,",
|
|
9576
|
+
",ESP-2,Run 2,pdm_motor,Other,OM-1,M9,6.75,,,,,,0.29,300,600,7/8,OM-1 sheet",
|
|
9577
|
+
"[penetrators],well,penetrator,installed,installer,certified,motor,gauge_distance_in,ir_a_megohm,ir_b_megohm,ir_c_megohm,void_test_psi,void_held",
|
|
9578
|
+
",ESP-2,acme-p-9-sn1,2026-09-02,K. Roe,yes,induction,30.5,1500,1600,1700,4000,yes",
|
|
9579
|
+
"[esp_drives],well,maker,model,max_volts,max_amps,freq_min_hz,freq_max_hz,phases,area,source",
|
|
9580
|
+
',ESP-2,DriveCo,VSD 520,4000,240,30,85,3,"Class I, Division 2",VSD 520 datasheet; site drawing E-1',
|
|
9581
|
+
]) + "\n"
|
|
9582
|
+
p0 = DC.apply(ws, sheet, "importer", str(d))
|
|
9583
|
+
nothing = not DC.plan(ws, sheet, str(d))["errors"] and not EC.costs(ws)["wells"].get(w2["id"]) and not DS.runs(ws, w2["id"])
|
|
9584
|
+
errsheet = sheet.replace(",ESP-2,rig spread,29000,2026-02-01,", ",ESP-2,rig spread,29000,2026-01-15,").replace("[afe],well,usd,source", "[afe],well,usd,source,colour") \
|
|
9585
|
+
+ "[runs],well,run\n,ESP-9,Run 9\n,ESP-2,Run 1\n" + "Pad,stray\n[nope],x\n"
|
|
9586
|
+
pe = DC.apply(ws, errsheet, "importer", str(d), write=True)
|
|
9587
|
+
clean_after_error = not EC.costs(ws)["wells"].get(w2["id"]) and not DS.runs(ws, w2["id"]) and not pe["written"]
|
|
9588
|
+
pw = DC.apply(ws, sheet, "importer", str(d), write=True)
|
|
9589
|
+
again = DC.plan(ws, sheet, str(d))
|
|
9590
|
+
tpl = DC.template(ws)
|
|
9591
|
+
tp = DC.plan(ws, tpl, str(d))
|
|
9592
|
+
w2r = ws.well(w2["id"])
|
|
9593
|
+
cw = EC.costs(ws)["wells"][w2["id"]]
|
|
9594
|
+
rs = DS.runs(ws, w2["id"])
|
|
9595
|
+
ec = " | ".join(pe["errors"])
|
|
9596
|
+
c2 = {
|
|
9597
|
+
"plan": p0["counts"] == {"NEW": 10, "CHANGE": 1, "SAME": 0} and not p0["errors"] and not p0["applied"] and nothing,
|
|
9598
|
+
"errors": all(x in ec for x in ("the period overlaps the rate on row", "has no column colour", "no well 'ESP-9'", "is on the sheet twice",
|
|
9599
|
+
"the first column holds a table name", "no table [nope]")) and clean_after_error,
|
|
9600
|
+
"written": pw["applied"] and len(pw["written"]) == 11 and w2r["identity"]["api_number"] == "42-317-41234" and w2r["surface"]["elevation"]["ft"] == 2910
|
|
9601
|
+
and w2r["trajectory"]["stations"] == 3 and len(cw["rates"]) == 2 and cw["rates"][0]["usd_per_day"] == 28500 and cw["afe"]["usd"] == 4512345.67
|
|
9602
|
+
and cw["items"][0]["usd"] == 18000.5 and [r["name"] for r in rs] == ["Run 1", "Run 2"]
|
|
9603
|
+
and rs[0]["components"][1]["motor"]["id"] == "msd-8-x-7-3-4-hybrid-78-5.9" and rs[1]["components"][1]["motor"]["rev_per_gal"] == 0.29
|
|
9604
|
+
and PN.records(ws)[w2["id"]]["install"]["penetrator"] == "acme-p-9-sn1" and PN.records(ws)[w2["id"]]["drive"]["area"] == "Class I, Division 2",
|
|
9605
|
+
"fleet_pen": {r["item"]: r for r in PN.check(ws, w2["id"])["rows"]}["drive frequency"]["status"] == "WITHIN"
|
|
9606
|
+
and {r["item"]: r for r in PN.check(ws, w2["id"])["rows"]}["drive output voltage"]["rated"] == 4160,
|
|
9607
|
+
"same": again["counts"] == {"NEW": 0, "CHANGE": 0, "SAME": 11} and not again["errors"],
|
|
9608
|
+
"template": not tp["errors"] and tp["counts"]["NEW"] == 0 and tp["counts"]["CHANGE"] == 0 and tp["counts"]["SAME"] >= 10 and "[esp_drives]" in tpl
|
|
9609
|
+
and "4512345.67" in tpl and tpl.count("[") >= 10,
|
|
9610
|
+
"audited": any(a["action"] == "declarations.import" and a["actor"] == "importer" for a in ws.audit_log(500))
|
|
9611
|
+
and any(a["action"] == "economics.rate" and a["actor"] == "importer" for a in ws.audit_log(500))
|
|
9612
|
+
and any(a["action"] == "fleet.add" and a["actor"] == "importer" for a in ws.audit_log(500)),
|
|
9613
|
+
}
|
|
9614
|
+
changed = sheet.replace(",ESP-2,4512345.67,AFE 26-114", ",ESP-2,4600000,AFE 26-114 rev 1")
|
|
9615
|
+
pc = DC.plan(ws, changed, str(d))
|
|
9616
|
+
c2["change"] = pc["counts"]["CHANGE"] == 1 and next(s_ for s_ in pc["steps"] if s_["table"] == "afe")["action"] == "CHANGE"
|
|
9617
|
+
by_name = DC.plan(ws, "[afe],well,usd,source\n,ESP-1,1000,a\n", "")
|
|
9618
|
+
c2["by_name"] = by_name["counts"]["NEW"] == 1 and by_name["steps"][0]["well"] == w1["id"]
|
|
9619
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
9620
|
+
ok(not failed2,
|
|
9621
|
+
"CJ2 the declarations sheet: eleven rows over ten tables planned (ten NEW, the installation recorded above a CHANGE) and nothing written until asked; an overlapping rate, an unknown "
|
|
9622
|
+
"column, well or table, a run twice and a stray first cell each named by its row, and with one error nothing written; written, every "
|
|
9623
|
+
"declaration lands where its own command puts it - the well's number, position and elevation, its survey, two rates, an item, the AFE, "
|
|
9624
|
+
"the fleet penetrator whose ratings then drive the check, two runs with a catalogued and a declared motor, the installation and the "
|
|
9625
|
+
"drive - audited under the importer; the same sheet again all SAME; the template it writes round-trips; a changed AFE a CHANGE"
|
|
9626
|
+
+ (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
9627
|
+
|
|
9628
|
+
# -- CJ3 the motors, the API, the CLI, the pages ------------------------------------------------------------
|
|
9629
|
+
cat = DS.catalogue()
|
|
9630
|
+
m7, m8 = DS.motor_spec("msd-7-89-4.3"), DS.motor_spec("msd-8-x-7-3-4-hybrid-78-5.9")
|
|
9631
|
+
c3 = {
|
|
9632
|
+
"motors": len(cat["motors"]) == 43 and (m7["rev_per_gal"], m7["flow_gpm"], m7["max_diff_psi"], m7["max_torque_ft_lb"], m7["max_operating_wob_lb"], m7["lube"])
|
|
9633
|
+
== (0.15, [400, 700], 1400, 22828, 55000, "mud lube")
|
|
9634
|
+
and (m8["rev_per_gal"], m8["flow_gpm"], m8["max_operating_diff_psi"], m8["max_diff_psi"], m8["max_torque_ft_lb"], m8["max_operating_wob_lb"], m8["od_in"])
|
|
9635
|
+
== (0.16, [400, 900], 750, 1390, 21870, 60000, 8.0)
|
|
9636
|
+
and "third time" in cat["how"] and any("keeps the sheet's figure" in n for n in cat["notes"]),
|
|
9637
|
+
}
|
|
9638
|
+
Users(str(Path(wsp, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
|
|
9639
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
9640
|
+
base_url = svc.url.rstrip("/")
|
|
9641
|
+
|
|
9642
|
+
def opener(name, pw_):
|
|
9643
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
9644
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
9645
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
9646
|
+
return o
|
|
9647
|
+
|
|
9648
|
+
def call(o, method, path, body=None):
|
|
9649
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
9650
|
+
if method == "POST":
|
|
9651
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
9652
|
+
try:
|
|
9653
|
+
with o.open(rq, timeout=120) as rr_:
|
|
9654
|
+
return rr_.status, json.loads(rr_.read())
|
|
9655
|
+
except urllib.error.HTTPError as e:
|
|
9656
|
+
return e.code, json.loads(e.read())
|
|
9657
|
+
try:
|
|
9658
|
+
V, O = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
|
|
9659
|
+
s_t, tj = call(V, "GET", "/api/declare/template")
|
|
9660
|
+
s_p, pj = call(V, "GET", "/api/penetrator")
|
|
9661
|
+
s_vd, _ = call(V, "POST", "/api/declare", {"text": tj.get("csv", "")})
|
|
9662
|
+
s_od, oj = call(O, "POST", "/api/declare", {"text": tj.get("csv", "")})
|
|
9663
|
+
s_sv, sv = call(O, "POST", "/api/declare", {"text": sheet})
|
|
9664
|
+
s_e, _ = call(O, "POST", "/api/declare", {"text": ""})
|
|
9665
|
+
s_vi, _ = call(V, "POST", "/api/penetrator/install", {"well_id": w1["id"], "penetrator": "genco-gps-5"})
|
|
9666
|
+
s_oi, _ = call(O, "POST", "/api/penetrator/install", {"well_id": w1["id"], "penetrator": "genco-gps-5", "motor_type": "PMM", "insulation": {"A": 900}})
|
|
9667
|
+
s_bi, _ = call(O, "POST", "/api/penetrator/install", {"well_id": w1["id"], "penetrator": "nope"})
|
|
9668
|
+
s_bd, _ = call(O, "POST", "/api/penetrator/drive", {"well_id": w1["id"], "max_volts": 4000})
|
|
9669
|
+
s_od2, _ = call(O, "POST", "/api/penetrator/drive", {"well_id": w1["id"], "max_volts": 4000, "source": "ds"})
|
|
9670
|
+
s_rm, _ = call(O, "POST", "/api/penetrator/remove", {"well_id": w2["id"], "what": "drive"})
|
|
9671
|
+
s_rm2, _ = call(O, "POST", "/api/penetrator/remove", {"well_id": w2["id"], "what": "drive"})
|
|
9672
|
+
s_ac, _ = call(O, "POST", "/api/penetrator/nope", {})
|
|
9673
|
+
finally:
|
|
9674
|
+
svc.stop()
|
|
9675
|
+
wells_p = {x["well_id"]: x for x in pj.get("wells", [])}
|
|
9676
|
+
sheet_path = d / "pad.csv"
|
|
9677
|
+
sheet_path.write_text(sheet.replace("ESP-2", "ESP-1").replace("Run ", "Lateral ").replace("acme-p-9-sn1", "genco-gps-5"), encoding="utf-8")
|
|
9678
|
+
cli_t = _sp.run([sys.executable, "-m", "gea", "declare", "--workspace", wsp, "--template", str(d / "t.csv")], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9679
|
+
cli_p = _sp.run([sys.executable, "-m", "gea", "declare", "--workspace", wsp, "--file", str(sheet_path)], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9680
|
+
cli_e = _sp.run([sys.executable, "-m", "gea", "declare", "--workspace", wsp, "--file", str(d / "survey.csv")], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9681
|
+
cli_n = _sp.run([sys.executable, "-m", "gea", "penetrator"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9682
|
+
cli_w = _sp.run([sys.executable, "-m", "gea", "penetrator", "--workspace", wsp, "--well", w1["id"]], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
9683
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
9684
|
+
c3.update({
|
|
9685
|
+
"api": s_t == 200 and "[penetrators]" in tj["csv"] and s_p == 200 and len(pj["penetrators"]) == 3 and wells_p[w2["id"]]["install"]["penetrator"] == "acme-p-9-sn1"
|
|
9686
|
+
and s_vd == 403 and s_od == 200 and oj["counts"]["NEW"] == 0 and not oj["errors"] and s_sv == 200 and any("carries no files" in e for e in sv["errors"])
|
|
9687
|
+
and s_e == 400 and s_vi == 403 and s_oi == 200 and s_bi == 404 and s_bd == 400 and s_od2 == 200 and s_rm == 200 and s_rm2 == 404 and s_ac == 404,
|
|
9688
|
+
"cli": cli_t.returncode == 0 and (d / "t.csv").is_file() and cli_p.returncode == 0 and "nothing written yet" in cli_p.stdout and "NEW" in cli_p.stdout
|
|
9689
|
+
and cli_e.returncode == 1 and "this is not a declarations sheet" in cli_e.stdout
|
|
9690
|
+
and cli_n.returncode == 0 and "genco-gps-5" in cli_n.stdout and "Permanent magnet motors" in cli_n.stdout
|
|
9691
|
+
and cli_w.returncode == 0 and "ESP-1:" in cli_w.stdout and "drive output voltage" in cli_w.stdout,
|
|
9692
|
+
"page": all(x in page_src for x in ("VIEWS.completion", "['#/completion', 'Completion']", "id=\"dcCard\"", "/api/declare/template", "Check the sheet",
|
|
9693
|
+
"/api/penetrator/install", "Permanent magnet motors", "Record the installation", "Declare the drive and site")),
|
|
9694
|
+
"help": all(any(t[0] == k for t in H.INDEX) and not H.check(k) for k in ("declare", "penetrator")) and H.VIEW_TOPIC.get("completion") == "penetrator",
|
|
9695
|
+
})
|
|
9696
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
9697
|
+
ok(not failed3,
|
|
9698
|
+
"CJ3 the two motors missing from the catalogue (7 in 8/9 4.3 and 8 in x 7 3/4 in 7/8 5.9) added as their sheets print them and the "
|
|
9699
|
+
"rest read a third time; the API (anyone signed in downloads the sheet and reads the Completion tab, only an operator checks or writes "
|
|
9700
|
+
"one; a sheet through the browser names its survey as carrying no file; an unknown penetrator, a drive with no source, a second removal "
|
|
9701
|
+
"and an unknown action named), the CLI (template, check, a file that is not a sheet, the penetrators, a well's check), the Setup card, "
|
|
9702
|
+
"the Completion tab and the two help pages"
|
|
9703
|
+
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
9704
|
+
|
|
9705
|
+
|
|
9450
9706
|
def main() -> int:
|
|
9451
9707
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
9452
9708
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -9537,6 +9793,7 @@ def main() -> int:
|
|
|
9537
9793
|
section_cg_well_report(tmp)
|
|
9538
9794
|
section_ch_simulation(tmp)
|
|
9539
9795
|
section_ci_drill_string(tmp)
|
|
9796
|
+
section_cj_declarations(tmp)
|
|
9540
9797
|
if _FAILS:
|
|
9541
9798
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
9542
9799
|
for f in _FAILS:
|