gea-program 0.10.0__tar.gz → 0.11.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.10.0 → gea_program-0.11.0}/PKG-INFO +18 -3
- {gea_program-0.10.0 → gea_program-0.11.0}/README.md +17 -2
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/__init__.py +1 -1
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/__main__.py +31 -1
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/acceptance_tests.py +136 -1
- gea_program-0.11.0/gea/help/osdu.md +13 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/site.md +1 -1
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/start.md +1 -1
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/helplib.py +2 -1
- gea_program-0.11.0/gea/osdu.py +413 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/service.py +76 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/web/app.html +10 -1
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/workspace.py +43 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea_program.egg-info/PKG-INFO +18 -3
- {gea_program-0.10.0 → gea_program-0.11.0}/gea_program.egg-info/SOURCES.txt +2 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/pyproject.toml +1 -1
- {gea_program-0.10.0 → gea_program-0.11.0}/LICENSE +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/accuracy_statement.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/alarm_engine.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/bench.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/blind_harness.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/med_160_sapropels.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/certificates.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/cli.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/client_reports.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/config_versioning.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/correlation.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/dashboard.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/deviation.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/doctor.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/downhole_engine.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/drift_monitor.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/earth_model.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/example_register_map.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/fat_sat.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/files.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/follower.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/forward_model.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/gamma.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/gauge_aging.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/gauge_specs.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/geodesy.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/gravity_reference.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/TESTER_GUIDE.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/alarms.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/audit-update.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/data-in.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/doctor.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/drift.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/files.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/instruments.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/notifications.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/patches.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/quality.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/seismic.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/sites.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/sra.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/transients.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/upkeep.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/help/well-tests.md +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/housekeeping.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/inverse_engine.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/jobs.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/live_ports.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/loadtest.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/matplotlib_demo.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/modbus.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/model_card.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/mqtt_port.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/notify.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/opcua_port.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/operator_app.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/patches.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/permits.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/ports.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/profile_catalog.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/project.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/qt6_downhole_app.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/reconciler.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/reference/libmseed_steim.provenance.json +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/rock_inventory.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/sample_record.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/sample_well_profile.csv +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/sbom.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/segy.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_array.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_assoc.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_detect.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_film.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_harmonic.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_qc.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_response.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_signature.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_track.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_uncertainty.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/seismic_unlisted.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/sensor_swap.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/service_life.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/shell.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/shut_in.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/sla_report.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/sra.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/store_forward.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/strata_join.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/supervisor.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/survey_cmd.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/survey_view.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/telemetry.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/tool_library.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/transient.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/well_assembler.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/well_test_validation.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/wits0.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea/witsml.py +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea_program.egg-info/dependency_links.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea_program.egg-info/entry_points.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea_program.egg-info/requires.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/gea_program.egg-info/top_level.txt +0 -0
- {gea_program-0.10.0 → gea_program-0.11.0}/setup.cfg +0 -0
- {gea_program-0.10.0 → gea_program-0.11.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.11.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
|
|
@@ -125,12 +125,12 @@ gea dashboard --catalog-well volve_f12_f14_production_excerpt:15/9-F-12:10000 --
|
|
|
125
125
|
gea client-report --report accuracy --out client_report
|
|
126
126
|
gea model-cards --out model_cards
|
|
127
127
|
gea sbom --out sbom
|
|
128
|
-
gea accept # the product gate (
|
|
128
|
+
gea accept # the product gate (320 checks)
|
|
129
129
|
gea help drift # the help library, by the job (16 pages; the same text is on every dashboard page)
|
|
130
130
|
gea guide # the click-by-click tester guide (docs/TESTER_GUIDE.md)
|
|
131
131
|
gea gui # the desktop window (pip install "gea-program[desktop]")
|
|
132
132
|
gea workspace --path C:\site --action init --name "Pad 3" # a site folder
|
|
133
|
-
gea serve --workspace C:\site # the dashboard as the door: http://127.0.0.1:8765/
|
|
133
|
+
gea serve --workspace C:\site # the dashboard as the door: opens http://127.0.0.1:8765/ in your browser
|
|
134
134
|
gea doctor --workspace C:\site # which code runs, can it serve, with every fix
|
|
135
135
|
gea files --workspace C:\site --action list --root historian # the import roots, detection by content, import, export, packs
|
|
136
136
|
gea transient --file historian.csv --params params.json --out pta # shut-ins and build-up analysis with a band
|
|
@@ -551,6 +551,21 @@ and a daily export under the Notice's own parameter names. It will not
|
|
|
551
551
|
invent a volume for a well with no rate channel, a tier from depth alone, or
|
|
552
552
|
an aftershock: those are declarations, and the packet says so.
|
|
553
553
|
|
|
554
|
+
### The OSDU-shaped export
|
|
555
|
+
|
|
556
|
+
What a buyer's data team asks for on the first call. `gea workspace --action
|
|
557
|
+
osdu-export --site <id> --partition ... --acl-owner ... --acl-viewer ...
|
|
558
|
+
--legal-tag ...` writes the site as an `osdu:wks:Manifest:1.0.0` to the
|
|
559
|
+
published well-known schemas: each well as Well and Wellbore 1.0.0 with its
|
|
560
|
+
API and UIC as name aliases, its record as a WellLog 1.1.0 in the time
|
|
561
|
+
domain over a File.Generic dataset with the file's SHA-256, each seismic
|
|
562
|
+
station as a generic component with its records as datasets, the site as the
|
|
563
|
+
work product, the files copied beside it. Every position goes out twice - as
|
|
564
|
+
given on its own datum with that datum's EPSG code, and on WGS 84 with the
|
|
565
|
+
operation between them written out; a point on an unknown datum gets no WGS
|
|
566
|
+
84 coordinates and is named. Without the operator's partition, ACL and legal
|
|
567
|
+
tag the manifest is NOT LOADABLE and says so. `gea help osdu`.
|
|
568
|
+
|
|
554
569
|
### Audit / Update
|
|
555
570
|
|
|
556
571
|
The Audit / Update tab holds three things. The whole audit log
|
|
@@ -86,12 +86,12 @@ gea dashboard --catalog-well volve_f12_f14_production_excerpt:15/9-F-12:10000 --
|
|
|
86
86
|
gea client-report --report accuracy --out client_report
|
|
87
87
|
gea model-cards --out model_cards
|
|
88
88
|
gea sbom --out sbom
|
|
89
|
-
gea accept # the product gate (
|
|
89
|
+
gea accept # the product gate (320 checks)
|
|
90
90
|
gea help drift # the help library, by the job (16 pages; the same text is on every dashboard page)
|
|
91
91
|
gea guide # the click-by-click tester guide (docs/TESTER_GUIDE.md)
|
|
92
92
|
gea gui # the desktop window (pip install "gea-program[desktop]")
|
|
93
93
|
gea workspace --path C:\site --action init --name "Pad 3" # a site folder
|
|
94
|
-
gea serve --workspace C:\site # the dashboard as the door: http://127.0.0.1:8765/
|
|
94
|
+
gea serve --workspace C:\site # the dashboard as the door: opens http://127.0.0.1:8765/ in your browser
|
|
95
95
|
gea doctor --workspace C:\site # which code runs, can it serve, with every fix
|
|
96
96
|
gea files --workspace C:\site --action list --root historian # the import roots, detection by content, import, export, packs
|
|
97
97
|
gea transient --file historian.csv --params params.json --out pta # shut-ins and build-up analysis with a band
|
|
@@ -512,6 +512,21 @@ and a daily export under the Notice's own parameter names. It will not
|
|
|
512
512
|
invent a volume for a well with no rate channel, a tier from depth alone, or
|
|
513
513
|
an aftershock: those are declarations, and the packet says so.
|
|
514
514
|
|
|
515
|
+
### The OSDU-shaped export
|
|
516
|
+
|
|
517
|
+
What a buyer's data team asks for on the first call. `gea workspace --action
|
|
518
|
+
osdu-export --site <id> --partition ... --acl-owner ... --acl-viewer ...
|
|
519
|
+
--legal-tag ...` writes the site as an `osdu:wks:Manifest:1.0.0` to the
|
|
520
|
+
published well-known schemas: each well as Well and Wellbore 1.0.0 with its
|
|
521
|
+
API and UIC as name aliases, its record as a WellLog 1.1.0 in the time
|
|
522
|
+
domain over a File.Generic dataset with the file's SHA-256, each seismic
|
|
523
|
+
station as a generic component with its records as datasets, the site as the
|
|
524
|
+
work product, the files copied beside it. Every position goes out twice - as
|
|
525
|
+
given on its own datum with that datum's EPSG code, and on WGS 84 with the
|
|
526
|
+
operation between them written out; a point on an unknown datum gets no WGS
|
|
527
|
+
84 coordinates and is named. Without the operator's partition, ACL and legal
|
|
528
|
+
tag the manifest is NOT LOADABLE and says so. `gea help osdu`.
|
|
529
|
+
|
|
515
530
|
### Audit / Update
|
|
516
531
|
|
|
517
532
|
The Audit / Update tab holds three things. The whole audit log
|
|
@@ -282,7 +282,7 @@ def main(argv=None) -> int:
|
|
|
282
282
|
choices=["init", "add-file", "add-catalog", "add-live", "remove", "list", "migrate", "refresh", "audit",
|
|
283
283
|
"add-seismic", "refresh-seismic", "remove-seismic", "sar-film", "refresh-all", "add-track", "refresh-track", "remove-track",
|
|
284
284
|
"seismic-dataset", "seismic-field", "add-site", "sites", "site-report", "remove-site", "rename",
|
|
285
|
-
"set-well", "sra-define", "sra-report", "associate"])
|
|
285
|
+
"set-well", "sra-define", "sra-report", "associate", "osdu-export"])
|
|
286
286
|
p_ws.add_argument("--stations", type=str, nargs="+", default=None, help="add-track: two or more array station ids of this workspace")
|
|
287
287
|
p_ws.add_argument("--site", type=str, default=None, help="site-report/remove-site: the site id")
|
|
288
288
|
p_ws.add_argument("--api", type=str, default=None, help="set-well: the API number")
|
|
@@ -309,6 +309,13 @@ def main(argv=None) -> int:
|
|
|
309
309
|
p_ws.add_argument("--start", type=str, default=None, help="sra-report: first day of the record, YYYY-MM-DD")
|
|
310
310
|
p_ws.add_argument("--end", type=str, default=None, help="sra-report: last day of the record, YYYY-MM-DD")
|
|
311
311
|
p_ws.add_argument("--vp", type=float, default=5.8, help="associate: the P velocity of the model, km/s (declared)")
|
|
312
|
+
p_ws.add_argument("--partition", type=str, default="", help="osdu-export: the platform's data partition id (declared)")
|
|
313
|
+
p_ws.add_argument("--acl-owner", type=str, nargs="*", default=None, help="osdu-export: ACL owners group(s)")
|
|
314
|
+
p_ws.add_argument("--acl-viewer", type=str, nargs="*", default=None, help="osdu-export: ACL viewers group(s)")
|
|
315
|
+
p_ws.add_argument("--legal-tag", type=str, nargs="*", default=None, help="osdu-export: legal tag(s)")
|
|
316
|
+
p_ws.add_argument("--country", type=str, nargs="*", default=None, help="osdu-export: otherRelevantDataCountries (default US)")
|
|
317
|
+
p_ws.add_argument("--operator-org", type=str, default="", help="osdu-export: the operator's Organisation record id on the platform")
|
|
318
|
+
p_ws.add_argument("--out", type=str, default=None, help="osdu-export: the folder to write the manifest and files into")
|
|
312
319
|
p_ws.add_argument("--depth-km", type=float, default=6.0, help="associate: the hypocentral depth the location is made under, km (declared)")
|
|
313
320
|
p_ws.add_argument("--rms-tol", type=float, default=0.15, help="associate: the RMS residual an event must fit within, s")
|
|
314
321
|
p_ws.add_argument("--wells", type=str, nargs="+", default=None, help="add-site: well ids of this workspace")
|
|
@@ -355,6 +362,7 @@ def main(argv=None) -> int:
|
|
|
355
362
|
p_sv.add_argument("--workers", type=int, default=1, help="jobs run at once")
|
|
356
363
|
p_sv.add_argument("--no-scheduler", action="store_true", help="do not run scheduled jobs from this process")
|
|
357
364
|
p_sv.add_argument("--behind-proxy", action="store_true", help="a reverse proxy terminates TLS in front: trust X-Forwarded-For/-Proto, mark the cookie Secure (deploy/ has nginx and Caddy examples)")
|
|
365
|
+
p_sv.add_argument("--no-browser", action="store_true", help="do not open the control panel in a browser once the service is listening (a scheduled start, a restart, a server with no desktop)")
|
|
358
366
|
|
|
359
367
|
p_hk = sub.add_parser("housekeeping", help="rotate the append-only logs, prune finished job folders and old live recordings (dry run unless --apply)")
|
|
360
368
|
p_hk.add_argument("--workspace", type=str, required=True)
|
|
@@ -389,6 +397,8 @@ def main(argv=None) -> int:
|
|
|
389
397
|
p_w0.add_argument("--seed", type=int, default=1)
|
|
390
398
|
p_w0.add_argument("--connect", type=str, default=None, help="host:port - instead of listening, connect to a listening tap and push frames")
|
|
391
399
|
|
|
400
|
+
p_osdu = sub.add_parser("osdu", help="the OSDU-shaped export: the self-test on a labelled site")
|
|
401
|
+
p_osdu.add_argument("--action", choices=["selftest"], default="selftest")
|
|
392
402
|
p_sra = sub.add_parser("sra", help="the Seismicity Response Area packet: the self-test on a labelled scene")
|
|
393
403
|
p_sra.add_argument("--action", choices=["selftest"], default="selftest")
|
|
394
404
|
p_sra.add_argument("--json", action="store_true")
|
|
@@ -1486,6 +1496,14 @@ def main(argv=None) -> int:
|
|
|
1486
1496
|
return 0
|
|
1487
1497
|
print(f"notifications: {'configured' if n.cfg else 'not configured'}" + (f" - {len(n.cfg['channels'])} channel(s), {len(n.cfg['rules'])} rule(s), quiet {n.cfg['quiet_s']} s" if n.cfg else " (gea notify --example)"))
|
|
1488
1498
|
return 0
|
|
1499
|
+
elif a.cmd == "osdu":
|
|
1500
|
+
from . import osdu as _O
|
|
1501
|
+
r = _O.selftest()
|
|
1502
|
+
print(f"osdu selftest [{r['label']}]: {r['status']}")
|
|
1503
|
+
for k, v in r["checks"].items():
|
|
1504
|
+
print(f" {'ok ' if v else 'BAD'} {k}")
|
|
1505
|
+
print(_O.report_text(r["summary"]))
|
|
1506
|
+
return 0 if r["status"] == "OK" else 1
|
|
1489
1507
|
elif a.cmd == "sra":
|
|
1490
1508
|
from . import sra as _SRA
|
|
1491
1509
|
r = _SRA.selftest()
|
|
@@ -1545,6 +1563,10 @@ def main(argv=None) -> int:
|
|
|
1545
1563
|
print(" Ctrl+C stops it; every action is in records/audit.jsonl, every start and stop in records/runlog.jsonl")
|
|
1546
1564
|
print(" the control panel's Stop and Restart end this run with a stated code: 0 stop, 86 start me again -")
|
|
1547
1565
|
print(" the launcher reads it, and on anything but 86 it hands the window to a PowerShell prompt, never a Python one")
|
|
1566
|
+
print(" this window is the server and has nothing more to load: the control panel is the page in the browser,")
|
|
1567
|
+
print(" and what happens there (the page opening, sign-ins, jobs, stops and restarts) is printed below as it happens")
|
|
1568
|
+
svc.console = True
|
|
1569
|
+
svc.open_browser = not a.no_browser
|
|
1548
1570
|
return svc.serve_forever()
|
|
1549
1571
|
elif a.cmd == "users":
|
|
1550
1572
|
import getpass
|
|
@@ -1723,6 +1745,14 @@ def main(argv=None) -> int:
|
|
|
1723
1745
|
print(f" {sid}: {x['status']}, {x['picks']} pick(s)")
|
|
1724
1746
|
print(_assoc_text(r["association"], r["catalogue"]))
|
|
1725
1747
|
print(" written:", os.path.join(ws.path, "reports", "sites", a.site, "association.json")); return 0
|
|
1748
|
+
elif a.action == "osdu-export":
|
|
1749
|
+
from .osdu import report_text as _osdu_text
|
|
1750
|
+
if not a.site:
|
|
1751
|
+
raise SystemExit("osdu-export needs --site <id>")
|
|
1752
|
+
r = ws.osdu_export(a.site, partition=a.partition, acl_owners=a.acl_owner, acl_viewers=a.acl_viewer, legal_tags=a.legal_tag,
|
|
1753
|
+
countries=a.country, operator_org_id=a.operator_org, out_dir=a.out, actor=a.actor)
|
|
1754
|
+
print(_osdu_text(r)); v = r["validate"]
|
|
1755
|
+
print(f" structure: {'ok' if v['ok'] else 'PROBLEMS'} ({v['records']} record(s))" + ('' if v['ok'] else '; ' + '; '.join(v['problems'][:5]))); return 0
|
|
1726
1756
|
elif a.action == "seismic-dataset":
|
|
1727
1757
|
r = ws.write_seismic_dataset_report(actor=a.actor)
|
|
1728
1758
|
inv = r["inventory"]
|
|
@@ -3390,12 +3390,13 @@ def section_aq_sar_and_audit(tmp: str) -> None:
|
|
|
3390
3390
|
# AQ4 - the page and the help
|
|
3391
3391
|
page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
|
|
3392
3392
|
ok("function sarPanelHtml" in page_src and "function sarDraw" in page_src and "id=\"sarScreen\"" in page_src and "/api/seismic/sar/run" in page_src
|
|
3393
|
+
and "VIEWS.sar = " in page_src and "['#/sar', 'SAR panel']" in page_src and H.VIEW_TOPIC.get("sar") == "seismic"
|
|
3393
3394
|
and "SIMULATION_SELF_TEST" in page_src and "film.label" in page_src and "not a measurement of any ground" in page_src
|
|
3394
3395
|
and "VIEWS.audit = " in page_src and "['#/audit', 'Audit / Update']" in page_src and "/api/update/program" in page_src and "/api/update/data" in page_src
|
|
3395
3396
|
and "Download CSV" in page_src and 'href="#/audit"' in page_src.split("VIEWS.admin = ")[1].split("VIEWS.")[0]
|
|
3396
3397
|
and H.VIEW_TOPIC.get("audit") == "audit-update" and any(t["topic"] == "audit-update" for t in H.topics()) and not H.check("audit-update")
|
|
3397
3398
|
and "sar-film" in (pkg / "help" / "seismic.md").read_text(encoding="utf-8") and "never a film" in (pkg / "help" / "seismic.md").read_text(encoding="utf-8"),
|
|
3398
|
-
"AQ4 the Seismic page carries the SAR panel (the controls, Run the scene as a job, Play/Pause/Stop/speed/scrub, the four-pane screen with the stamp on every frame); "
|
|
3399
|
+
"AQ4 the Seismic page carries the SAR panel (the controls, Run the scene as a job, Play/Pause/Stop/speed/scrub, the four-pane screen with the stamp on every frame) and the panel has a page and a navigation entry of its own, because at the foot of the Seismic page it was reported as nowhere to be found; "
|
|
3399
3400
|
"the Audit / Update view has the program card, the data card with its two jobs, the audit log with filters and a CSV; Administration points at it; the help index "
|
|
3400
3401
|
"has the audit-update page, the view maps to it, and the seismic page names the film and what it is not")
|
|
3401
3402
|
|
|
@@ -4593,6 +4594,55 @@ def section_bb_supervisor(tmp: str) -> None:
|
|
|
4593
4594
|
"BB11 an authorised restart is logged before the server is touched, stops the run and leaves 86 as the code the launcher reads; the control "
|
|
4594
4595
|
"panel's own page carries the Stop and Restart controls, the authorisation step behind a popup, and the auto-restart switch")
|
|
4595
4596
|
|
|
4597
|
+
# -- the console answers (0.11.0) -------------------------------------------------------
|
|
4598
|
+
# a server that answers in silence looks, from the window it was started in, exactly like one that is
|
|
4599
|
+
# still loading. An operator waited hours at a console that had been serving the page all along.
|
|
4600
|
+
svc2 = Service(wsp, host="127.0.0.1", port=0, scheduler=False)
|
|
4601
|
+
lines: list = []
|
|
4602
|
+
svc2._console_line = lambda m: lines.append(m)
|
|
4603
|
+
svc2.console = True
|
|
4604
|
+
svc2.open_browser = False
|
|
4605
|
+
base2 = svc2.url.rstrip("/")
|
|
4606
|
+
th2 = _th.Thread(target=svc2.serve_forever, daemon=True); th2.start()
|
|
4607
|
+
time.sleep(0.6)
|
|
4608
|
+
cj2 = http.cookiejar.CookieJar(); opener2 = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(cj2))
|
|
4609
|
+
|
|
4610
|
+
def call2(method, path, body=None):
|
|
4611
|
+
req = urllib.request.Request(base2 + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
|
|
4612
|
+
req.add_header("Content-Type", "application/json")
|
|
4613
|
+
if method == "POST":
|
|
4614
|
+
req.add_header("X-GEA-Action", "1")
|
|
4615
|
+
try:
|
|
4616
|
+
with opener2.open(req, timeout=60) as r:
|
|
4617
|
+
return r.status, (json.loads(r.read()) if path.startswith("/api/") else r.read())
|
|
4618
|
+
except urllib.error.HTTPError as e:
|
|
4619
|
+
return e.code, json.loads(e.read())
|
|
4620
|
+
|
|
4621
|
+
call2("GET", "/"); call2("GET", "/") # the second fetch from the same address is not a second line
|
|
4622
|
+
call2("POST", "/api/login", {"name": "adm", "password": "wrong-pass-999"})
|
|
4623
|
+
call2("POST", "/api/login", {"name": "adm", "password": "admin-pass-123"})
|
|
4624
|
+
call2("POST", "/api/control/restart", {"authorize": True})
|
|
4625
|
+
th2.join(timeout=30)
|
|
4626
|
+
joined = "\n".join(lines)
|
|
4627
|
+
ok(svc2.ws.on_audit is not None and svc2.app.console is not None
|
|
4628
|
+
and sum(1 for m in lines if m.startswith("listening at")) == 1
|
|
4629
|
+
and sum(1 for m in lines if m.startswith("control panel opened in a browser")) == 1
|
|
4630
|
+
and "sign-in refused for 'adm'" in joined and "signed in: adm (admin)" in joined
|
|
4631
|
+
and "restart requested by adm" in joined and not th2.is_alive(),
|
|
4632
|
+
"BB12 the serving console says what happens as it happens - the page being opened (once per address), a sign-in refused, a sign-in, a "
|
|
4633
|
+
"stop or restart requested - because a server that answers in silence looks, from the window it was started in, like one that is still "
|
|
4634
|
+
"loading; the audit file is written first and the console line is only a courtesy to whoever is watching")
|
|
4635
|
+
main_src = (pkg / "__main__.py").read_text(encoding="utf-8")
|
|
4636
|
+
ok('"--no-browser", action="store_true"' in main_src
|
|
4637
|
+
and "svc.open_browser = not a.no_browser" in main_src and "svc.console = True" in main_src
|
|
4638
|
+
and hasattr(Service, "_open_browser_later") and Service(wsp, host="127.0.0.1", port=0, scheduler=False).open_browser is False
|
|
4639
|
+
and (cmd is None or ("%GEA_BROWSER%" in cmd and "timeout /t 4" not in cmd and 'if "%1"=="--no-browser" set GEA_BROWSER=--no-browser' in cmd
|
|
4640
|
+
and "set GEA_BROWSER=--no-browser" in cmd))
|
|
4641
|
+
and (sh is None or ("$browser" in sh and 'browser="--no-browser"' in sh)),
|
|
4642
|
+
"BB13 `gea serve` opens the control panel in the browser itself once its port is listening, and the launchers no longer race it with a "
|
|
4643
|
+
"browser of their own - opened first, it showed a failure page from the second before the server was up; a scheduled start passes "
|
|
4644
|
+
"--no-browser through, a restart from the panel does not open a second page, and the service run in-process by this gate opens nothing")
|
|
4645
|
+
|
|
4596
4646
|
|
|
4597
4647
|
def section_bc_sra(tmp: str) -> None:
|
|
4598
4648
|
"""Section BC - the Seismicity Response Area packet. The Railroad Commission's operator-led response plans
|
|
@@ -4831,6 +4881,90 @@ def section_bd_association(tmp: str) -> None:
|
|
|
4831
4881
|
"runs the labelled scene from the command line")
|
|
4832
4882
|
|
|
4833
4883
|
|
|
4884
|
+
def section_be_osdu(tmp: str) -> None:
|
|
4885
|
+
"""Section BE - the OSDU-shaped export: the manifest a large operator's data platform loads, built to the
|
|
4886
|
+
published well-known schemas from what the site holds, with both coordinate sets on every position,
|
|
4887
|
+
the operator's declarations required rather than filled in, and every gap named."""
|
|
4888
|
+
import csv as _csv
|
|
4889
|
+
import subprocess as _sp
|
|
4890
|
+
from datetime import datetime as _dt, timedelta as _td, timezone as _tz
|
|
4891
|
+
from . import osdu as O
|
|
4892
|
+
from .workspace import Workspace
|
|
4893
|
+
d = Path(tmp, "be"); d.mkdir()
|
|
4894
|
+
|
|
4895
|
+
r = O.selftest(str(d / "self"))
|
|
4896
|
+
ok(r["status"] == "OK" and all(r["checks"].values()) and r["label"] == "SIMULATION_SELF_TEST" and r["validate"]["ok"],
|
|
4897
|
+
"BE1 the self-test: a Manifest 1.0.0 with Well and Wellbore 1.0.0, WellLog 1.1.0 in the time domain with a curve per channel over a "
|
|
4898
|
+
"File.Generic dataset carrying the file's size and SHA-256, a seismic station as a generic component with its records as datasets; a NAD27 "
|
|
4899
|
+
"position carries both coordinate sets with the 45 m shift written out; a position on an unknown datum gets no WGS 84 coordinates and is "
|
|
4900
|
+
"named; a catalogue well with no file is named; the manifest validates; and without the operator's partition, ACL and legal tag it is "
|
|
4901
|
+
"NOT LOADABLE with the four names listed")
|
|
4902
|
+
|
|
4903
|
+
# -- the position discipline, record by record ------------------------------------------
|
|
4904
|
+
ctx = O.Context("opendes", ["o@x"], ["v@x"], ["tag"])
|
|
4905
|
+
sl = O.spatial_location(31.96, -102.24, "NAD83", ctx)
|
|
4906
|
+
sl27 = O.spatial_location(31.96, -102.24, "NAD27", ctx)
|
|
4907
|
+
slu = O.spatial_location(31.96, -102.24, None, ctx)
|
|
4908
|
+
w84 = sl["Wgs84Coordinates"]["features"][0]["geometry"]["coordinates"]
|
|
4909
|
+
w27 = sl27["Wgs84Coordinates"]["features"][0]["geometry"]["coordinates"]
|
|
4910
|
+
ok(sl["AsIngestedCoordinates"]["CoordinateReferenceSystemID"] == "opendes:reference-data--CoordinateReferenceSystem:Geographic2D:EPSG::4269:"
|
|
4911
|
+
and w84 == [-102.24, 31.96] and w27 != [-102.24, 31.96] and abs(w27[0] + 102.24) < 0.001 and abs(w27[1] - 31.96) < 0.001
|
|
4912
|
+
and "shift 45" in sl27["AppliedOperations"][0] and "Wgs84Coordinates" not in slu and slu["_gap"] and "unknown" in slu["AppliedOperations"][0]
|
|
4913
|
+
and slu["QualitativeSpatialAccuracyTypeID"].endswith(":Unverifiable:"),
|
|
4914
|
+
"BE2 every position goes out twice, as given on its own datum with the EPSG code of that datum, and on WGS 84 with the operation between "
|
|
4915
|
+
"them written into AppliedOperations - NAD83 passes through unchanged, NAD27 moves 45 m and says so, and an unknown datum gets no WGS 84 "
|
|
4916
|
+
"point at all, marked Unverifiable, because a platform that indexed it would place the well tens of metres wrong")
|
|
4917
|
+
|
|
4918
|
+
# -- the structural validation catches a broken manifest ---------------------------------
|
|
4919
|
+
man = json.load(open(Path(d, "self", "osdu_full", "manifest.json"), encoding="utf-8"))
|
|
4920
|
+
broken = json.loads(json.dumps(man))
|
|
4921
|
+
broken["Data"]["WorkProductComponents"][0]["data"]["Datasets"] = ["surrogate-key:file-nowhere"]
|
|
4922
|
+
del broken["MasterData"][0]["legal"]
|
|
4923
|
+
broken["MasterData"][1]["kind"] = "Wellbore"
|
|
4924
|
+
v = O.validate(broken)
|
|
4925
|
+
ok(not v["ok"] and len(v["problems"]) >= 3 and any("not in this manifest" in p for p in v["problems"]) and any("no legal" in p for p in v["problems"])
|
|
4926
|
+
and any("osdu:wks:" in p for p in v["problems"]),
|
|
4927
|
+
"BE3 the validation makes the platform loader's first checks before the platform does: a component naming a dataset the manifest does not "
|
|
4928
|
+
"carry, a record with no legal block, and a kind not in the osdu:wks:<group>--<Type>:<version> form are each named")
|
|
4929
|
+
|
|
4930
|
+
# -- through the workspace and the command line ------------------------------------------
|
|
4931
|
+
t0 = _dt(2026, 3, 1, tzinfo=_tz.utc)
|
|
4932
|
+
hist = d / "swd.csv"
|
|
4933
|
+
with open(hist, "w", newline="") as f:
|
|
4934
|
+
w = _csv.writer(f); w.writerow(["timestamp", "P_surf_psi", "Q_bpm"])
|
|
4935
|
+
for i in range(2 * 144):
|
|
4936
|
+
w.writerow([(t0 + _td(seconds=600 * i)).strftime("%Y-%m-%dT%H:%M:%SZ"), "1500.0", "5.0"])
|
|
4937
|
+
ws = Workspace.create(str(d / "ws"), "Pad 3", actor="tester")
|
|
4938
|
+
w1 = ws.add_well_file(str(hist), display="SWD 1", actor="tester", station_md_ft=9800.0)
|
|
4939
|
+
ws.set_well(w1["id"], surface={"lat": 31.96, "lon": -102.24, "datum": "NAD27"}, disposal={"api_number": "42-329-12345", "uic_number": "123456"}, actor="tester")
|
|
4940
|
+
w2 = ws.add_well_catalog("volve_f12_f14_production_excerpt", "15/9-F-12", 10000.0, actor="tester")
|
|
4941
|
+
ws.add_site("OSDU block", wells=[w1["id"], w2["id"]], client="Acme", actor="tester")
|
|
4942
|
+
run = lambda *a: _sp.run([sys.executable, "-m", "gea", "workspace", "--path", ws.path, "--actor", "tester", *a], capture_output=True, text=True)
|
|
4943
|
+
r1 = run("--action", "osdu-export", "--site", "OSDU-block")
|
|
4944
|
+
r2 = run("--action", "osdu-export", "--site", "OSDU-block", "--partition", "opendes", "--acl-owner", "data.default.owners@opendes.example.com",
|
|
4945
|
+
"--acl-viewer", "data.default.viewers@opendes.example.com", "--legal-tag", "opendes-public-usa", "--operator-org", "opendes:master-data--Organisation:Acme:")
|
|
4946
|
+
out = Path(ws.path, "reports", "sites", "OSDU-block", "osdu")
|
|
4947
|
+
man2 = json.load(open(out / "manifest.json", encoding="utf-8"))
|
|
4948
|
+
summ = json.load(open(out / "export_summary.json", encoding="utf-8"))
|
|
4949
|
+
well = next(m for m in man2["MasterData"] if m["kind"] == O.KINDS["well"] and m["data"]["FacilityID"] == "42-329-12345")
|
|
4950
|
+
log = next(c for c in man2["Data"]["WorkProductComponents"] if c["kind"] == O.KINDS["welllog"])
|
|
4951
|
+
audit = Path(ws.path, "records", "audit.jsonl").read_text(encoding="utf-8")
|
|
4952
|
+
r3 = _sp.run([sys.executable, "-m", "gea", "osdu"], capture_output=True, text=True)
|
|
4953
|
+
ok(r1.returncode == 0 and "NOT LOADABLE" in r1.stdout and "--partition" in r1.stdout
|
|
4954
|
+
and r2.returncode == 0 and "[LOADABLE]" in r2.stdout and "structure: ok" in r2.stdout and summ["status"] == "LOADABLE"
|
|
4955
|
+
and well["legal"]["legaltags"] == ["opendes-public-usa"] and well["data"]["CurrentOperatorID"] == "opendes:master-data--Organisation:Acme:"
|
|
4956
|
+
and well["data"]["VerticalMeasurements"][0]["VerticalMeasurement"] == 9800.0 and "Wgs84Coordinates" in well["data"]["SpatialLocation"]
|
|
4957
|
+
and log["data"]["ZeroTime"] == "2026-03-01T00:00:00Z" and log["data"]["SamplingInterval"] == 600.0
|
|
4958
|
+
and [c["Mnemonic"] for c in log["data"]["Curves"]] == ["TIME", "P_surf_psi", "Q_bpm"]
|
|
4959
|
+
and (out / "files" / "wells" / w1["id"] / "swd.csv").is_file()
|
|
4960
|
+
and any(w2["id"] in g and "no file" in g for g in summ["gaps"]) and "site.osdu_export" in audit
|
|
4961
|
+
and r3.returncode == 0 and "SIMULATION_SELF_TEST" in r3.stdout,
|
|
4962
|
+
"BE4 `--action osdu-export` writes the site's manifest and copies its files beside it: without the operator's declarations it says NOT "
|
|
4963
|
+
"LOADABLE and which flags are missing; with them the well goes out as Well and Wellbore with its API and UIC, its gauge station as a "
|
|
4964
|
+
"vertical measurement, its position on both datums; its record as a WellLog in the time domain over the file; a catalogue well with no "
|
|
4965
|
+
"file is a named gap; the structure validates; every export is audited; `gea osdu` runs the self-test from the command line")
|
|
4966
|
+
|
|
4967
|
+
|
|
4834
4968
|
def main() -> int:
|
|
4835
4969
|
print("GEA-Program - ACCEPTANCE SUITE (the product gate)")
|
|
4836
4970
|
# a handle a job subprocess still holds at the end must not turn a finished gate into a traceback on Windows:
|
|
@@ -4890,6 +5024,7 @@ def main() -> int:
|
|
|
4890
5024
|
section_bb_supervisor(tmp)
|
|
4891
5025
|
section_bc_sra(tmp)
|
|
4892
5026
|
section_bd_association(tmp)
|
|
5027
|
+
section_be_osdu(tmp)
|
|
4893
5028
|
if _FAILS:
|
|
4894
5029
|
print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
|
|
4895
5030
|
for f in _FAILS:
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# The OSDU-shaped export
|
|
2
|
+
|
|
3
|
+
> The site as the Manifest a large operator's OSDU data platform loads, built to the published well-known schemas, with every file beside it.
|
|
4
|
+
|
|
5
|
+
**The command**: `gea workspace --path C:\site --action osdu-export --site <id> --partition <partition> --acl-owner <group> --acl-viewer <group> --legal-tag <tag> [--country US] [--operator-org <partition>:master-data--Organisation:<id>:] [--out <folder>]`. The partition, the ACL groups and the legal tag are the platform's and yours; without them the manifest is still written and marked NOT LOADABLE with the missing names. `gea osdu` runs the self-test on a labelled site.
|
|
6
|
+
|
|
7
|
+
**What it writes**: `reports/sites/<site>/osdu/manifest.json` - `osdu:wks:Manifest:1.0.0` with MasterData (each well as `master-data--Well:1.0.0` and `master-data--Wellbore:1.0.0`, its API and UIC numbers as name aliases, the gauge station as a vertical measurement), Data (the site as the WorkProduct; each well's record as `work-product-component--WellLog:1.1.0` in the time domain with ZeroTime, the sampling interval and a curve per channel; each seismic station as a generic component with its position) and Datasets (`dataset--File.Generic:1.0.0` for every file, with its size and SHA-256); `files/` beside it with the files themselves; `export_summary.json` with the counts, the gaps and whether it is loadable. Every export is in `records/audit.jsonl`.
|
|
8
|
+
|
|
9
|
+
**The number to check**: `[LOADABLE]` or `[NOT LOADABLE]` on the first line, and `structure: ok (<n> record(s))` - the platform loader's first checks made here first: every record has its id, kind, ACL, legal block and data; every dataset a component names is in the manifest; every wellbore's well is in MasterData; the work product lists every component.
|
|
10
|
+
|
|
11
|
+
**What this page will not call a measurement**: a WGS 84 position for a point whose datum is unknown - every position goes out twice, as given on its own datum with that datum's EPSG code, and on WGS 84 with the operation between them written into AppliedOperations; a point on an unknown datum gets no WGS 84 coordinates at all, because a platform that indexed it would place the well tens of metres wrong. A loadable manifest without the operator's partition, ACL and legal tag - they are never filled in. A seismic trace component - the seismic trace schema was not verified against a published example when this export was written, and a kind not read here is not a kind written here; stations go out as generic components with their records as datasets.
|
|
12
|
+
|
|
13
|
+
Related: `gea help sites`, `gea help sra`, `gea help data-in`.
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> The workspace folder, the four roles and what each cannot do, the audit log.
|
|
4
4
|
|
|
5
|
-
**The command**: `gea workspace --path C:\site --action init --name "Pad 3"`; `gea serve --workspace C:\site` (loopback by default; `--behind-proxy` with a TLS proxy in front, see `deploy/README.md`); `gea users --workspace C:\site --action add --name ... --role admin` (the password from `GEA_PASSWORD`, never the command line). `gea workspace --path C:\site --action rename --name "Pad 3"` sets the site's name as every report prints it.
|
|
5
|
+
**The command**: `gea workspace --path C:\site --action init --name "Pad 3"`; `gea serve --workspace C:\site` (loopback by default; it opens the control panel in your browser once it is listening, `--no-browser` for a scheduled start, and the window it runs in prints what happens on the page - sign-ins, jobs, stops - as it happens; `--behind-proxy` with a TLS proxy in front, see `deploy/README.md`); `gea users --workspace C:\site --action add --name ... --role admin` (the password from `GEA_PASSWORD`, never the command line). `gea workspace --path C:\site --action rename --name "Pad 3"` sets the site's name as every report prints it.
|
|
6
6
|
|
|
7
7
|
**What it writes**: `workspace.json`, `wells/<id>/{source,records}`, `config/` (every configuration versioned, diffed, reversible), `monitor/`, `reports/`, `jobs/<id>/{job.json,log.txt}`, `records/audit.jsonl` (append-only, every action with the actor and the SHA-256 of its inputs), `users.json` (salted PBKDF2-SHA256, never a password).
|
|
8
8
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> Install, the first run, and what the program will not claim.
|
|
4
4
|
|
|
5
|
-
**The command**: `python -m pip install "gea-program[live]"` then `gea quickstart` (a real catalogue well through every report, then the strata survey on a public hole). A site: `gea workspace --path C:\site --action init --name "Pad 3"` and `gea serve --workspace C:\site`,
|
|
5
|
+
**The command**: `python -m pip install "gea-program[live]"` then `gea quickstart` (a real catalogue well through every report, then the strata survey on a public hole). A site: `gea workspace --path C:\site --action init --name "Pad 3"` and `gea serve --workspace C:\site`, which opens http://127.0.0.1:8765/ in your browser (the serve window is the server, not the panel: it stays open and prints what happens on the page).
|
|
6
6
|
|
|
7
7
|
**What it writes**: `gea_quickstart/index.html` with every report beside it; a site writes under its workspace folder (`reports/`, `records/`, `jobs/`).
|
|
8
8
|
|
|
@@ -39,6 +39,7 @@ INDEX: List[tuple] = [
|
|
|
39
39
|
('files', 'Files', 'import and export roots, detection by content, the evidence pack'),
|
|
40
40
|
('notifications', 'Notifications', 'rules, channels, the delivery log'),
|
|
41
41
|
('sra', 'The Seismicity Response Area', 'the packet an operator inside an SRA puts in front of the Commission'),
|
|
42
|
+
('osdu', 'The OSDU-shaped export', 'the site as the manifest an operator\'s data platform loads'),
|
|
42
43
|
('doctor', 'Which code is running', 'gea doctor and the serve start-up gate'),
|
|
43
44
|
('audit-update', 'Audit / Update', 'the whole audit log with filters, the program against PyPI, every report against its source'),
|
|
44
45
|
('upkeep', 'Upkeep', 'housekeeping, sessions, the TLS proxy, the load test'),
|
|
@@ -49,7 +50,7 @@ REQUIRED_LINES = ('**The command**', '**What it writes**', '**The number to chec
|
|
|
49
50
|
VIEW_TOPIC: Dict[str, str] = {
|
|
50
51
|
'home': 'start', 'wells': 'data-in', 'well': 'drift', 'live': 'patches', 'patch': 'patches', 'files': 'files', 'alarms': 'alarms',
|
|
51
52
|
'approvals': 'well-tests', 'config': 'site', 'reports': 'drift', 'verify': 'start', 'survey': 'data-in', 'jobs': 'site',
|
|
52
|
-
'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sites': 'sites', 'audit': 'audit-update',
|
|
53
|
+
'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'audit': 'audit-update',
|
|
53
54
|
}
|
|
54
55
|
|
|
55
56
|
|