gea-program 0.53.0__tar.gz → 0.54.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.53.0 → gea_program-0.54.0}/PKG-INFO +12 -1
- {gea_program-0.53.0 → gea_program-0.54.0}/README.md +11 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/__init__.py +1 -1
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/__main__.py +51 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/acceptance_tests.py +175 -0
- gea_program-0.54.0/gea/decline.py +553 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/dossier.py +14 -2
- gea_program-0.54.0/gea/help/decline.md +17 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/helplib.py +2 -1
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/service.py +20 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/web/app.html +56 -1
- {gea_program-0.53.0 → gea_program-0.54.0}/gea_program.egg-info/PKG-INFO +12 -1
- {gea_program-0.53.0 → gea_program-0.54.0}/gea_program.egg-info/SOURCES.txt +2 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/pyproject.toml +1 -1
- {gea_program-0.53.0 → gea_program-0.54.0}/LICENSE +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/alerts.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/backup.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/bench.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/blind_harness.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog_map.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/catalog_register.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/certificates.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/cli.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/client_reports.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/collision.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/config_versioning.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/conformance.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/control_room.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/correlation.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/dashboard.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/declarations.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/deviation.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/dlis.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/dnp3.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/doctor.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/dossier_verify.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/drill_string.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/earth_model.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/economics.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/ed25519.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/edr.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/elevation.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/etp.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/etp12_schemas.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/example_register_map.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/fat_sat.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/files.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/fixtures/README.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/fixtures/ne_110m_coastline.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/follower.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/forward_model.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/frac_hits.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/friction_priors.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/gamma.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/geodesy.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/geomag.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/hartip.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/alarms.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/alerts.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/backup.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/catalog.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/charts.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/collision.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/conformance.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/control-room.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/data-in.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/declare.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/dlis.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/doctor.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/dossier.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/drift.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/drillstring.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/economics.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/edr.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/etp.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/field-ports.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/files.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/frac-hits.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/historian.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/instruments.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/interval.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/invoice-check.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/map.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/month-end.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/notifications.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/opseis.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/osdu.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/pad-summary.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/patches.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/penetrator.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/plan.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/pore-pressure.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/ppdm.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/quakeml.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/quality.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/report-history.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/rig-time.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/seedlink.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/seismic.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/setup.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/simulation.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/site.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/sites.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/slip.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/soak.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/sra.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/start.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/structure.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/tools.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/torque-drag.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/transients.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/vibration.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/well-report.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/help/well3d.md +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/housekeeping.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/interval.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/invoice_check.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/jobs.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/live_ports.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/loadtest.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/modbus.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/modbus_rtu.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/model_card.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/month_end.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/notify.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/op_seismicity.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/opcua_port.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/operator_app.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/osdu.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/pad_summary.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/patches.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/pdf_report.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/penetrator.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/permits.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/piwebapi.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/pore_pressure.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/ports.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/ppdm.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/project.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/quakeml.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reconciler.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/WMM2025.COF +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/eia_prices.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/iscwsa_rev4_example.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/iscwsa_rev5_example.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/mahoning_example.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/mud_motor_specs.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/owsg_tool_models.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/penetrator_ratings.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/seismicity_protocols.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/tool_sources.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/us_outline.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/us_outline.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_3d.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_surfaces.json.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/reference/volve_well_picks.csv.gz +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/report_history.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/rig_state.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/sample_record.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/sbom.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seedlink.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/segy.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_array.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_film.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_response.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_track.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/seismic_watch.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/series_cache.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/service_life.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/setup_checklist.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/shapefile.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/shell.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/shut_in.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/simulation.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/site_map.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/sla_report.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/slip.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/soak.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/sra.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/store_forward.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/strata_join.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/structure.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/supervisor.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/survey_view.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/telemetry.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/tool_catalog.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/tool_library.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/tool_taxonomy.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/torque_drag.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/transient.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/vibration.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/well3d.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/well_assembler.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/well_report.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/wellplan.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/wellpos.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/wits0.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/witsml.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/workspace.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea/xlsx_read.py +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.53.0 → gea_program-0.54.0}/setup.cfg +0 -0
- {gea_program-0.53.0 → gea_program-0.54.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.54.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,17 @@ 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
|
+
### Decline curves
|
|
652
|
+
|
|
653
|
+
Each well's monthly production fitted by Arps's curves - the modified
|
|
654
|
+
hyperbolic, turned exponential at a terminal decline - forecast month by
|
|
655
|
+
month to its economic limit and valued: the estimated ultimate recovery,
|
|
656
|
+
and the net cash flow discounted at the declared rate, at the SEC 12-month
|
|
657
|
+
average of the first-of-month WTI and Henry Hub prices (shipped from the
|
|
658
|
+
EIA) or a declared price, with the net revenue interest, severance tax and
|
|
659
|
+
operating cost declared. A forecast is not a reserves report, and the page
|
|
660
|
+
says so. The **Decline curves** tab, `gea decline`, `gea help decline`.
|
|
661
|
+
|
|
651
662
|
### Torque and drag
|
|
652
663
|
|
|
653
664
|
The hook load and torque the drill string should take at each bit depth, by
|
|
@@ -609,6 +609,17 @@ 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
|
+
### Decline curves
|
|
613
|
+
|
|
614
|
+
Each well's monthly production fitted by Arps's curves - the modified
|
|
615
|
+
hyperbolic, turned exponential at a terminal decline - forecast month by
|
|
616
|
+
month to its economic limit and valued: the estimated ultimate recovery,
|
|
617
|
+
and the net cash flow discounted at the declared rate, at the SEC 12-month
|
|
618
|
+
average of the first-of-month WTI and Henry Hub prices (shipped from the
|
|
619
|
+
EIA) or a declared price, with the net revenue interest, severance tax and
|
|
620
|
+
operating cost declared. A forecast is not a reserves report, and the page
|
|
621
|
+
says so. The **Decline curves** tab, `gea decline`, `gea help decline`.
|
|
622
|
+
|
|
612
623
|
### Torque and drag
|
|
613
624
|
|
|
614
625
|
The hook load and torque the drill string should take at each bit depth, by
|
|
@@ -622,6 +622,21 @@ def main(argv=None) -> int:
|
|
|
622
622
|
p_pl.add_argument("--actor", type=str, default="cli")
|
|
623
623
|
p_pl.add_argument("--json", action="store_true")
|
|
624
624
|
|
|
625
|
+
p_dc = sub.add_parser("decline", help="each well's monthly production fitted by Arps's curves, forecast to its economic limit and valued at the SEC 12-month price or a declared one")
|
|
626
|
+
p_dc.add_argument("--workspace", type=str, required=True)
|
|
627
|
+
p_dc.add_argument("--well", type=str, default=None)
|
|
628
|
+
p_dc.add_argument("--attach", type=str, default=None, help="attach FILE as the well's monthly production (CSV or Excel)")
|
|
629
|
+
p_dc.add_argument("--remove", action="store_true")
|
|
630
|
+
for k_, h_ in (("terminal-decline", "the terminal decline, effective annual (0.08 = 8 %%)"), ("b-max", "the largest b fitted"), ("oil-price", "USD/bbl"),
|
|
631
|
+
("gas-price", "USD/MMBtu"), ("price-basis", "sec or flat"), ("nri", "the net revenue interest"), ("severance", "the severance tax (0.046 = 4.6 %%)"),
|
|
632
|
+
("opex", "the operating cost, USD a month"), ("discount", "the discount rate (0.10)"), ("start", "fit from this month (YYYY-MM)"),
|
|
633
|
+
("as-of", "value as of this date (YYYY-MM-DD)")):
|
|
634
|
+
p_dc.add_argument("--" + k_, type=str, default=None, help=h_)
|
|
635
|
+
p_dc.add_argument("--source", type=str, default="", help="where the production or the terms came from")
|
|
636
|
+
p_dc.add_argument("--write", action="store_true")
|
|
637
|
+
p_dc.add_argument("--actor", type=str, default="cli")
|
|
638
|
+
p_dc.add_argument("--json", action="store_true")
|
|
639
|
+
|
|
625
640
|
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")
|
|
626
641
|
p_td.add_argument("--workspace", type=str, default=None)
|
|
627
642
|
p_td.add_argument("--well", type=str, default=None)
|
|
@@ -2486,6 +2501,42 @@ def main(argv=None) -> int:
|
|
|
2486
2501
|
raise SystemExit(f"collision: {e.args[0] if e.args else e}")
|
|
2487
2502
|
print(_json.dumps({k: v for k, v in r.items()}, default=str) if a.json else _CO.text(r))
|
|
2488
2503
|
return 0
|
|
2504
|
+
elif a.cmd == "decline":
|
|
2505
|
+
import json as _json
|
|
2506
|
+
from . import decline as _DCA
|
|
2507
|
+
from .cli import _safe_stdout
|
|
2508
|
+
from .workspace import Workspace, WorkspaceError
|
|
2509
|
+
_safe_stdout()
|
|
2510
|
+
try:
|
|
2511
|
+
ws = Workspace(a.workspace)
|
|
2512
|
+
terms = {"terminal_decline": a.terminal_decline, "b_max": a.b_max, "oil_price": a.oil_price, "gas_price": a.gas_price, "price_basis": a.price_basis,
|
|
2513
|
+
"nri": a.nri, "severance": a.severance, "opex_month": a.opex, "discount": a.discount, "start": a.start}
|
|
2514
|
+
if (a.attach or a.remove or any(v is not None for v in terms.values()) or a.write) and not a.well:
|
|
2515
|
+
raise ValueError("--well is needed")
|
|
2516
|
+
if a.attach:
|
|
2517
|
+
with open(a.attach, "rb") as f_:
|
|
2518
|
+
r_ = _DCA.attach(ws, a.well, os.path.basename(a.attach), f_.read(), a.actor, a.source)
|
|
2519
|
+
print(f"production attached to {a.well}: {r_['months']} months, {r_['first']} to {r_['last']}")
|
|
2520
|
+
return 0
|
|
2521
|
+
if a.remove:
|
|
2522
|
+
_DCA.remove(ws, a.well, a.actor)
|
|
2523
|
+
print(f"production removed from {a.well}")
|
|
2524
|
+
return 0
|
|
2525
|
+
if any(v is not None for v in terms.values()):
|
|
2526
|
+
c_ = _DCA.set_config(ws, a.actor, a.well, a.source, **{k: v for k, v in terms.items() if v is not None})
|
|
2527
|
+
print(f"{a.well}: terminal {c_['terminal_decline']:g}, price {c_['price_basis']}, NRI {c_['nri']:g}, severance {c_['severance']:g}, opex {c_['opex_month']:,.0f}/month, discount {c_['discount']:g}")
|
|
2528
|
+
return 0
|
|
2529
|
+
if a.write:
|
|
2530
|
+
r_ = _DCA.write_report(ws, __version__, a.well, a.actor)
|
|
2531
|
+
print(f"wrote {r_['report_id']}: {r_['paths']['html']}")
|
|
2532
|
+
if r_['paths'].get('pdf'):
|
|
2533
|
+
print(f" printable: {r_['paths']['pdf']}")
|
|
2534
|
+
return 0
|
|
2535
|
+
r = _DCA.page(ws, a.well, a.as_of)
|
|
2536
|
+
except (KeyError, ValueError, OSError, WorkspaceError) as e:
|
|
2537
|
+
raise SystemExit(f"decline: {e.args[0] if e.args else e}")
|
|
2538
|
+
print(_json.dumps(r, default=str) if a.json else _DCA.text(r))
|
|
2539
|
+
return 0
|
|
2489
2540
|
elif a.cmd == "torque-drag":
|
|
2490
2541
|
import json as _json
|
|
2491
2542
|
from . import torque_drag as _TND
|
|
@@ -12065,6 +12065,180 @@ def section_cv_torque_drag(tmp: str) -> None:
|
|
|
12065
12065
|
+ (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
|
|
12066
12066
|
|
|
12067
12067
|
|
|
12068
|
+
def section_cw_decline(tmp: str) -> None:
|
|
12069
|
+
"""Section CW - decline curves: Arps's rate and cumulative and the modified hyperbolic against their closed forms
|
|
12070
|
+
and the decline conversions; a production table built on known curves fitted back and forecast; the economic limit,
|
|
12071
|
+
the discounted value and the SEC 12-month price; the API, the CLI, the report, the dossier, the tab and the help."""
|
|
12072
|
+
import http.cookiejar
|
|
12073
|
+
import math as _m
|
|
12074
|
+
import subprocess as _sp
|
|
12075
|
+
import urllib.request
|
|
12076
|
+
import urllib.error
|
|
12077
|
+
import zipfile as _zf
|
|
12078
|
+
from datetime import date as _date
|
|
12079
|
+
import numpy as _np
|
|
12080
|
+
from . import __version__ as _ver
|
|
12081
|
+
from . import decline as DCA
|
|
12082
|
+
from . import dossier as DZ
|
|
12083
|
+
from . import edr as E
|
|
12084
|
+
from . import helplib as H
|
|
12085
|
+
from . import xlsx_read as XR
|
|
12086
|
+
from .workspace import Workspace
|
|
12087
|
+
from .service import Service, Users
|
|
12088
|
+
pkg = Path(__file__).parent
|
|
12089
|
+
d = Path(tmp, "decline"); d.mkdir()
|
|
12090
|
+
|
|
12091
|
+
# -- CW1 the curves by hand --------------------------------------------------------------------------------------------
|
|
12092
|
+
qi, Di = 1000.0, 0.002
|
|
12093
|
+
t = _np.array([0.0, 100.0, 1000.0])
|
|
12094
|
+
e_ok = _np.allclose(DCA.rate(t, qi, Di, 0.0), qi * _np.exp(-Di * t)) and _np.allclose(DCA.cum(t, qi, Di, 0.0), qi / Di * (1 - _np.exp(-Di * t)))
|
|
12095
|
+
h_ok = _np.allclose(DCA.rate(t, qi, Di, 0.5), qi / (1 + 0.5 * Di * t) ** 2) and _np.allclose(DCA.cum(t, qi, Di, 0.5), qi / (0.5 * Di) * (1 - (1 + 0.5 * Di * t) ** -1))
|
|
12096
|
+
a_ok = _np.allclose(DCA.cum(t, qi, Di, 1.0), qi / Di * _np.log(1 + Di * t))
|
|
12097
|
+
tt = _np.linspace(0, 20000, 200001)
|
|
12098
|
+
q_mh = DCA.rate(tt, qi, Di, 1.5, 0.0002)
|
|
12099
|
+
trap = float(_np.sum(0.5 * (q_mh[1:] + q_mh[:-1]) * _np.diff(tt)))
|
|
12100
|
+
ts = (Di / 0.0002 - 1) / (1.5 * Di)
|
|
12101
|
+
i_s = int(_np.searchsorted(tt, ts))
|
|
12102
|
+
dq = _np.diff(_np.log(q_mh))
|
|
12103
|
+
c1 = {
|
|
12104
|
+
"arps": e_ok and h_ok and a_ok,
|
|
12105
|
+
"modified": abs(float(DCA.cum(_np.array([20000.0]), qi, Di, 1.5, 0.0002)[0]) / trap - 1) < 1e-6 and abs(dq[i_s + 5] / 0.1 + 0.0002) < 1e-9 and q_mh[i_s - 1] > q_mh[i_s],
|
|
12106
|
+
"conversions": abs(DCA.effective_annual(DCA.nominal_daily(0.65, 1.1), 1.1) - 0.65) < 1e-12 and abs(DCA.effective_annual(DCA.nominal_daily(0.08, 0.0), 0.0) - 0.08) < 1e-12
|
|
12107
|
+
and abs(DCA.effective_annual(0.001, 0.0) - (1 - _m.exp(-0.36525))) < 1e-12,
|
|
12108
|
+
"sec": DCA.sec_price([f"2025-{m:02d}-0{k}" for m in range(1, 13) for k in (2, 3)] + ["2024-12-31"], [float(m * 10 + k) for m in range(1, 13) for k in (2, 3)] + [999.0],
|
|
12109
|
+
_date(2026, 1, 1))["price"] == round(sum(m * 10 + 2 for m in range(1, 13)) / 12.0, 4)
|
|
12110
|
+
and DCA.sec_price(["2025-06-01"], [50.0], _date(2026, 1, 1)) is None,
|
|
12111
|
+
}
|
|
12112
|
+
failed1 = [k for k, v in c1.items() if not v]
|
|
12113
|
+
ok(not failed1,
|
|
12114
|
+
"CW1 Arps's curves by hand: the exponential, hyperbolic and harmonic rates and cumulatives in closed form; the modified "
|
|
12115
|
+
"hyperbolic's cumulative equal to the integral of its rate, exponential at the terminal decline from the switch; the "
|
|
12116
|
+
"effective and nominal declines inverse to each other; the SEC price the average of each month's first quote of the 12 "
|
|
12117
|
+
"months before, and none when a month is missing"
|
|
12118
|
+
+ (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
|
|
12119
|
+
|
|
12120
|
+
# -- CW2 a table built on known curves, fitted back ---------------------------------------------------------------------
|
|
12121
|
+
f = DCA.selftest_files(str(d))
|
|
12122
|
+
prod = DCA.read_production(Path(f["path"]).read_bytes())
|
|
12123
|
+
so = DCA.analyse_stream(prod, "oil", {**DCA.DEFAULTS})
|
|
12124
|
+
Dn, Dm = DCA.nominal_daily(f["De"], f["b"]), DCA.nominal_daily(f["Dterm"], 0.0)
|
|
12125
|
+
th = _np.array(so["history"]["t"])
|
|
12126
|
+
q_true = DCA.rate(th, f["qi"], Dn, f["b"], Dm)
|
|
12127
|
+
q_fit = DCA.rate(th - so["t0_days"], so["fit"]["qi"], so["fit"]["Di"], so["fit"]["b"], so["Dmin"])
|
|
12128
|
+
t_end = th[-1] + 30 * 365.25
|
|
12129
|
+
eur_true = float(DCA.cum(_np.array([t_end]), f["qi"], Dn, f["b"], Dm)[0])
|
|
12130
|
+
eur_fit = float(DCA.cum(_np.array([t_end - so["t0_days"]]), so["fit"]["qi"], so["fit"]["Di"], so["fit"]["b"], so["Dmin"])[0])
|
|
12131
|
+
days_ok = all(abs(so["history"]["q"][i] - so["history"]["v"][i] / prod[i]["days"]) < 1e-3 for i in (7, 19))
|
|
12132
|
+
XR.write_simple(str(d / "p.xlsx"), [["Production Month", "Oil Volume", "Gas Volume", "Days On"], ["2024-01", 3000, 6000, 31], ["2024-02", 2700, 5500, 29]])
|
|
12133
|
+
px = DCA.read_production((d / "p.xlsx").read_bytes())
|
|
12134
|
+
refused = 0
|
|
12135
|
+
for bad in ("Month,Oil\n2024-01,-5\n", "Month,Oil\n2024-01,5\n2024-01,6\n", "Oil,Gas\n1,2\n", "Month,Oil,Days\n2024-01,5,40\n", "Month,Note\n2024-01,x\n"):
|
|
12136
|
+
try:
|
|
12137
|
+
DCA.read_production(bad.encode())
|
|
12138
|
+
except ValueError:
|
|
12139
|
+
refused += 1
|
|
12140
|
+
c2 = {
|
|
12141
|
+
"fit": abs(so["fit"]["b"] - f["b"]) <= 0.15 and float(_np.max(_np.abs(q_fit - q_true) / q_true)) < 0.04 and so["months_fitted"] == 48,
|
|
12142
|
+
"eur": abs(eur_fit / eur_true - 1) < 0.05,
|
|
12143
|
+
"days": days_ok,
|
|
12144
|
+
"table": len(prod) == 48 and prod[0]["month"] == "2022-01" and px[1]["days"] == 29 and px[0]["oil"] == 3000 and refused == 5,
|
|
12145
|
+
}
|
|
12146
|
+
failed2 = [k for k, v in c2.items() if not v]
|
|
12147
|
+
ok(not failed2,
|
|
12148
|
+
"CW2 a well's 48 months built on a known curve (900 bbl/d, b 1.1, 65 % a year, 8 % terminal, 3 % noise, four months part "
|
|
12149
|
+
"shut in) fitted back: b within 0.15, the rate within 4 % over the history, the 30-year recovery within 5 %; a part month's "
|
|
12150
|
+
"rate its volume over its producing days; a table read from Excel by its names; a negative volume, a month twice, no month, "
|
|
12151
|
+
"more than 31 days or no stream refused"
|
|
12152
|
+
+ (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
|
|
12153
|
+
|
|
12154
|
+
# -- CW3 the forecast, the limit and the value ---------------------------------------------------------------------------
|
|
12155
|
+
one = [{"month": f"2020-{m:02d}", "oil": 3000.0 * _m.exp(-0.01 * 30.4375 * (m - 1)), "gas": None, "water": None, "days": None} for m in range(1, 13)]
|
|
12156
|
+
cfg = {**DCA.DEFAULTS, "terminal_decline": None, "nri": 1.0, "severance": 0.0, "opex_month": 0.0, "discount": 0.0, "years": 1.0}
|
|
12157
|
+
r1 = DCA.analyse(one, cfg, {"oil": 50.0, "gas": 0.0})
|
|
12158
|
+
vol12 = sum(m_["oil"] for m_ in r1["forecast"]["months"])
|
|
12159
|
+
cfg2 = {**cfg, "opex_month": 500.0, "years": 20.0}
|
|
12160
|
+
r2 = DCA.analyse(one, cfg2, {"oil": 50.0, "gas": 0.0})
|
|
12161
|
+
last_net = r2["forecast"]["months"][-1]["net_usd"]
|
|
12162
|
+
cfg3 = {**cfg, "discount": 0.10, "years": 1.0}
|
|
12163
|
+
r3 = DCA.analyse(one, cfg3, {"oil": 50.0, "gas": 0.0})
|
|
12164
|
+
pv_hand = sum(m_["net_usd"] * 1.1 ** (-((i + 0.5) / 12)) for i, m_ in enumerate(r3["forecast"]["months"]))
|
|
12165
|
+
c3 = {
|
|
12166
|
+
"exponential": r1["streams"]["oil"]["fit"]["b"] == 0.0 and abs(r1["streams"]["oil"]["fit"]["Di"] / (0.01) - 1) < 0.01 and len(r1["forecast"]["months"]) == 12
|
|
12167
|
+
and abs(r1["forecast"]["undiscounted_usd"] / (50.0 * vol12) - 1) < 1e-3,
|
|
12168
|
+
"limit": r2["forecast"]["limit_month"] is not None and r2["forecast"]["stopped_by"] == "the economic limit" and last_net > 0
|
|
12169
|
+
and 3 <= len(r2["forecast"]["months"]) <= 12 and 50.0 * r2["forecast"]["months"][-1]["oil"] > 500.0,
|
|
12170
|
+
"pv": abs(r3["forecast"]["pv_usd"] - pv_hand) < 2.0 and r3["forecast"]["pv_usd"] < r3["forecast"]["undiscounted_usd"],
|
|
12171
|
+
}
|
|
12172
|
+
failed3 = [k for k, v in c3.items() if not v]
|
|
12173
|
+
ok(not failed3,
|
|
12174
|
+
"CW3 the forecast: a year of exponential decline at 1 % a day fitted as exponential and carried a year forward, its revenue "
|
|
12175
|
+
"the volume times the price; an operating cost stopping it at the economic limit on the last month that still pays; the "
|
|
12176
|
+
"value discounted mid-month as by hand"
|
|
12177
|
+
+ (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
|
|
12178
|
+
|
|
12179
|
+
# -- CW4 the API, the CLI, the report, the dossier, the tab and the help -------------------------------------------------
|
|
12180
|
+
ev = E.selftest_events(str(d))
|
|
12181
|
+
wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
|
|
12182
|
+
wid = ws.add_well_file(ev["path"], display="PROD-1", actor="tester")["id"]
|
|
12183
|
+
nothing = DCA.page(ws, wid)["detail"]
|
|
12184
|
+
Users(str(Path(wsp, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
|
|
12185
|
+
svc = Service(wsp, port=0, scheduler=False).start()
|
|
12186
|
+
base_url = svc.url.rstrip("/")
|
|
12187
|
+
|
|
12188
|
+
def opener(name, pw_):
|
|
12189
|
+
o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
|
|
12190
|
+
rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
|
|
12191
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
|
|
12192
|
+
return o
|
|
12193
|
+
|
|
12194
|
+
def call(o, method, path, body=None):
|
|
12195
|
+
rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
12196
|
+
if method == "POST":
|
|
12197
|
+
rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
|
|
12198
|
+
try:
|
|
12199
|
+
with o.open(rq, timeout=120) as rr_:
|
|
12200
|
+
return rr_.status, json.loads(rr_.read())
|
|
12201
|
+
except urllib.error.HTTPError as e:
|
|
12202
|
+
return e.code, json.loads(e.read())
|
|
12203
|
+
content = Path(f["path"]).read_text(encoding="utf-8")
|
|
12204
|
+
try:
|
|
12205
|
+
V, O = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
|
|
12206
|
+
s_va, _ = call(V, "POST", "/api/decline/attach", {"well_id": wid, "filename": "p.csv", "content": content, "source": "x"})
|
|
12207
|
+
s_ns, _ = call(O, "POST", "/api/decline/attach", {"well_id": wid, "filename": "p.csv", "content": content, "source": ""})
|
|
12208
|
+
s_oa, oa = call(O, "POST", "/api/decline/attach", {"well_id": wid, "filename": "p.csv", "content": content, "source": "monthly report (test)"})
|
|
12209
|
+
s_vg, vg = call(V, "GET", "/api/decline?well=" + wid + "&as_of=2026-01-01")
|
|
12210
|
+
s_bt, _ = call(O, "POST", "/api/decline/settings", {"well_id": wid, "nri": 1.5, "source": "x"})
|
|
12211
|
+
s_bp, _ = call(O, "POST", "/api/decline/settings", {"well_id": wid, "price_basis": "spot", "source": "x"})
|
|
12212
|
+
s_ot, ot = call(O, "POST", "/api/decline/settings", {"well_id": wid, "price_basis": "flat", "oil_price": "70", "gas_price": "3", "source": "budget deck (test)"})
|
|
12213
|
+
s_fg, fg = call(V, "GET", "/api/decline?well=" + wid)
|
|
12214
|
+
s_vw, _ = call(V, "POST", "/api/decline/write", {"well_id": wid})
|
|
12215
|
+
s_ow, ow = call(O, "POST", "/api/decline/write", {"well_id": wid})
|
|
12216
|
+
finally:
|
|
12217
|
+
svc.stop()
|
|
12218
|
+
cli_t = _sp.run([sys.executable, "-m", "gea", "decline", "--workspace", wsp, "--well", wid], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
12219
|
+
cli_s = _sp.run([sys.executable, "-m", "gea", "decline", "--workspace", wsp, "--well", wid, "--opex", "9000", "--source", "LOE (test)"], capture_output=True, text=True, cwd=str(pkg.parent))
|
|
12220
|
+
dz = DZ.build(ws, "tester", _ver, None)
|
|
12221
|
+
names = _zf.ZipFile(Path(ws.reports_dir, dz["path"])).namelist()
|
|
12222
|
+
audit = Path(ws.audit_path).read_text(encoding="utf-8")
|
|
12223
|
+
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
12224
|
+
c4 = {
|
|
12225
|
+
"api": "production" in nothing and s_va == 403 and s_ns == 400 and s_oa == 200 and oa["months"] == 48 and s_vg == 200 and vg["result"]["as_of"] == "2026-01-01"
|
|
12226
|
+
and "SEC average" in vg["result"]["price_how"]["oil"] and s_bt == 400 and s_bp == 400 and s_ot == 200 and ot["oil_price"] == 70.0
|
|
12227
|
+
and s_fg == 200 and fg["result"]["prices"]["oil"] == 70.0 and s_vw == 403 and s_ow == 200 and ow["report_id"].startswith("DCA-"),
|
|
12228
|
+
"cli": cli_t.returncode == 0 and "EUR" in cli_t.stdout and "70 USD/bbl declared" in cli_t.stdout and cli_s.returncode == 0 and "opex 9,000/month" in cli_s.stdout,
|
|
12229
|
+
"report": PR_read_ok(Path(ws.reports_dir, "wells", wid, "decline_curves.pdf")) and all(x in audit for x in ("production.attach", "production.terms", "report.decline_curves")),
|
|
12230
|
+
"dossier": "declarations/economics/production/production.json" in names and f"declarations/economics/production/{wid}/p.csv" in names and f"results/decline/{wid}.json" in names,
|
|
12231
|
+
"page": all(x in page_src for x in ("VIEWS.decline", "['#/decline', 'Decline curves']", "/api/decline/attach", "dcChart")),
|
|
12232
|
+
"help": not H.check("decline") and H.VIEW_TOPIC.get("decline") == "decline",
|
|
12233
|
+
}
|
|
12234
|
+
failed4 = [k for k, v in c4.items() if not v]
|
|
12235
|
+
ok(not failed4,
|
|
12236
|
+
"CW4 on the API (anyone reads a well's curves at a chosen date, valued at the SEC price; only an operator attaches production "
|
|
12237
|
+
"- with its source - or declares terms - a net revenue interest of 1.5 or an unknown price basis refused - or writes the "
|
|
12238
|
+
"report), the CLI, the report as PDF, a signed dossier carrying the production and the curves, the tab and the help"
|
|
12239
|
+
+ (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
|
|
12240
|
+
|
|
12241
|
+
|
|
12068
12242
|
def PR_read_ok(path) -> bool:
|
|
12069
12243
|
from . import pdf_report as PR
|
|
12070
12244
|
try:
|
|
@@ -12176,6 +12350,7 @@ def main() -> int:
|
|
|
12176
12350
|
section_ct_frac_hits(tmp)
|
|
12177
12351
|
section_cu_pore_pressure(tmp)
|
|
12178
12352
|
section_cv_torque_drag(tmp)
|
|
12353
|
+
section_cw_decline(tmp)
|
|
12179
12354
|
if _FAILS:
|
|
12180
12355
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
12181
12356
|
for f in _FAILS:
|