gea-program 0.23.0__tar.gz → 0.25.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.
Files changed (266) hide show
  1. {gea_program-0.23.0/gea_program.egg-info → gea_program-0.25.0}/PKG-INFO +33 -2
  2. {gea_program-0.23.0 → gea_program-0.25.0}/README.md +32 -1
  3. {gea_program-0.23.0 → gea_program-0.25.0}/gea/__init__.py +1 -1
  4. {gea_program-0.23.0 → gea_program-0.25.0}/gea/__main__.py +184 -5
  5. {gea_program-0.23.0 → gea_program-0.25.0}/gea/acceptance_tests.py +300 -0
  6. gea_program-0.25.0/gea/catalog_register.py +146 -0
  7. gea_program-0.25.0/gea/dlis.py +624 -0
  8. {gea_program-0.23.0 → gea_program-0.25.0}/gea/files.py +18 -2
  9. gea_program-0.25.0/gea/friction_priors.py +133 -0
  10. gea_program-0.25.0/gea/help/catalog.md +11 -0
  11. gea_program-0.25.0/gea/help/dlis.md +11 -0
  12. gea_program-0.25.0/gea/help/historian.md +11 -0
  13. {gea_program-0.23.0 → gea_program-0.25.0}/gea/helplib.py +3 -0
  14. {gea_program-0.23.0 → gea_program-0.25.0}/gea/model_card.py +4 -2
  15. {gea_program-0.23.0 → gea_program-0.25.0}/gea/patches.py +35 -5
  16. gea_program-0.25.0/gea/piwebapi.py +366 -0
  17. {gea_program-0.23.0 → gea_program-0.25.0}/gea/ports.py +4 -0
  18. {gea_program-0.23.0 → gea_program-0.25.0}/gea/rock_inventory.py +26 -0
  19. {gea_program-0.23.0 → gea_program-0.25.0}/gea/service.py +3 -3
  20. {gea_program-0.23.0 → gea_program-0.25.0}/gea/survey_cmd.py +21 -3
  21. {gea_program-0.23.0 → gea_program-0.25.0}/gea/web/app.html +1 -1
  22. {gea_program-0.23.0 → gea_program-0.25.0}/gea/workspace.py +1 -1
  23. {gea_program-0.23.0 → gea_program-0.25.0/gea_program.egg-info}/PKG-INFO +33 -2
  24. {gea_program-0.23.0 → gea_program-0.25.0}/gea_program.egg-info/SOURCES.txt +7 -0
  25. {gea_program-0.23.0 → gea_program-0.25.0}/pyproject.toml +1 -1
  26. {gea_program-0.23.0 → gea_program-0.25.0}/LICENSE +0 -0
  27. {gea_program-0.23.0 → gea_program-0.25.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
  28. {gea_program-0.23.0 → gea_program-0.25.0}/gea/accuracy_statement.py +0 -0
  29. {gea_program-0.23.0 → gea_program-0.25.0}/gea/alarm_engine.py +0 -0
  30. {gea_program-0.23.0 → gea_program-0.25.0}/gea/backup.py +0 -0
  31. {gea_program-0.23.0 → gea_program-0.25.0}/gea/bench.py +0 -0
  32. {gea_program-0.23.0 → gea_program-0.25.0}/gea/blind_harness.py +0 -0
  33. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
  34. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
  35. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
  36. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
  37. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
  38. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
  39. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
  40. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
  41. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
  42. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
  43. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
  44. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
  45. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
  46. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
  47. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
  48. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
  49. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
  50. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
  51. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
  52. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
  53. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
  54. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
  55. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
  56. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
  57. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
  58. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
  59. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
  60. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
  61. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
  62. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
  63. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
  64. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
  65. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
  66. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
  67. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
  68. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
  69. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
  70. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
  71. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
  72. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
  73. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
  74. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
  75. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
  76. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
  77. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
  78. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
  79. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
  80. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
  81. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
  82. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
  83. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
  84. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
  85. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
  86. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
  87. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
  88. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
  89. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
  90. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
  91. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
  92. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
  93. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
  94. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
  95. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
  96. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
  97. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
  98. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
  99. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
  100. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/med_160_sapropels.txt +0 -0
  101. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
  102. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
  103. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
  104. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
  105. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
  106. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
  107. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
  108. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
  109. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
  110. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
  111. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
  112. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
  113. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
  114. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
  115. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
  116. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
  117. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
  118. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
  119. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
  120. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
  121. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
  122. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
  123. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
  124. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
  125. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
  126. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
  127. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
  128. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
  129. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
  130. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
  131. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
  132. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
  133. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
  134. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
  135. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
  136. {gea_program-0.23.0 → gea_program-0.25.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
  137. {gea_program-0.23.0 → gea_program-0.25.0}/gea/certificates.py +0 -0
  138. {gea_program-0.23.0 → gea_program-0.25.0}/gea/cli.py +0 -0
  139. {gea_program-0.23.0 → gea_program-0.25.0}/gea/client_reports.py +0 -0
  140. {gea_program-0.23.0 → gea_program-0.25.0}/gea/config_versioning.py +0 -0
  141. {gea_program-0.23.0 → gea_program-0.25.0}/gea/conformance.py +0 -0
  142. {gea_program-0.23.0 → gea_program-0.25.0}/gea/correlation.py +0 -0
  143. {gea_program-0.23.0 → gea_program-0.25.0}/gea/dashboard.py +0 -0
  144. {gea_program-0.23.0 → gea_program-0.25.0}/gea/deviation.py +0 -0
  145. {gea_program-0.23.0 → gea_program-0.25.0}/gea/dnp3.py +0 -0
  146. {gea_program-0.23.0 → gea_program-0.25.0}/gea/doctor.py +0 -0
  147. {gea_program-0.23.0 → gea_program-0.25.0}/gea/downhole_engine.py +0 -0
  148. {gea_program-0.23.0 → gea_program-0.25.0}/gea/drift_monitor.py +0 -0
  149. {gea_program-0.23.0 → gea_program-0.25.0}/gea/earth_model.py +0 -0
  150. {gea_program-0.23.0 → gea_program-0.25.0}/gea/elevation.py +0 -0
  151. {gea_program-0.23.0 → gea_program-0.25.0}/gea/etp.py +0 -0
  152. {gea_program-0.23.0 → gea_program-0.25.0}/gea/etp12_schemas.json +0 -0
  153. {gea_program-0.23.0 → gea_program-0.25.0}/gea/example_register_map.json +0 -0
  154. {gea_program-0.23.0 → gea_program-0.25.0}/gea/fat_sat.py +0 -0
  155. {gea_program-0.23.0 → gea_program-0.25.0}/gea/follower.py +0 -0
  156. {gea_program-0.23.0 → gea_program-0.25.0}/gea/forward_model.py +0 -0
  157. {gea_program-0.23.0 → gea_program-0.25.0}/gea/gamma.py +0 -0
  158. {gea_program-0.23.0 → gea_program-0.25.0}/gea/gauge_aging.py +0 -0
  159. {gea_program-0.23.0 → gea_program-0.25.0}/gea/gauge_specs.py +0 -0
  160. {gea_program-0.23.0 → gea_program-0.25.0}/gea/geodesy.py +0 -0
  161. {gea_program-0.23.0 → gea_program-0.25.0}/gea/gravity_reference.py +0 -0
  162. {gea_program-0.23.0 → gea_program-0.25.0}/gea/hartip.py +0 -0
  163. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/TESTER_GUIDE.md +0 -0
  164. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/alarms.md +0 -0
  165. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/audit-update.md +0 -0
  166. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/backup.md +0 -0
  167. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/conformance.md +0 -0
  168. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/data-in.md +0 -0
  169. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/doctor.md +0 -0
  170. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/drift.md +0 -0
  171. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/etp.md +0 -0
  172. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/field-ports.md +0 -0
  173. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/files.md +0 -0
  174. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/instruments.md +0 -0
  175. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/interval.md +0 -0
  176. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/month-end.md +0 -0
  177. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/notifications.md +0 -0
  178. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/osdu.md +0 -0
  179. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/patches.md +0 -0
  180. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/ppdm.md +0 -0
  181. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/quakeml.md +0 -0
  182. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/quality.md +0 -0
  183. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/seedlink.md +0 -0
  184. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/seismic.md +0 -0
  185. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/site.md +0 -0
  186. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/sites.md +0 -0
  187. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/soak.md +0 -0
  188. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/sra.md +0 -0
  189. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/start.md +0 -0
  190. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/structure.md +0 -0
  191. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/transients.md +0 -0
  192. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/upkeep.md +0 -0
  193. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/vibration.md +0 -0
  194. {gea_program-0.23.0 → gea_program-0.25.0}/gea/help/well-tests.md +0 -0
  195. {gea_program-0.23.0 → gea_program-0.25.0}/gea/housekeeping.py +0 -0
  196. {gea_program-0.23.0 → gea_program-0.25.0}/gea/interval.py +0 -0
  197. {gea_program-0.23.0 → gea_program-0.25.0}/gea/inverse_engine.py +0 -0
  198. {gea_program-0.23.0 → gea_program-0.25.0}/gea/jobs.py +0 -0
  199. {gea_program-0.23.0 → gea_program-0.25.0}/gea/live_ports.py +0 -0
  200. {gea_program-0.23.0 → gea_program-0.25.0}/gea/loadtest.py +0 -0
  201. {gea_program-0.23.0 → gea_program-0.25.0}/gea/matplotlib_demo.py +0 -0
  202. {gea_program-0.23.0 → gea_program-0.25.0}/gea/modbus.py +0 -0
  203. {gea_program-0.23.0 → gea_program-0.25.0}/gea/modbus_rtu.py +0 -0
  204. {gea_program-0.23.0 → gea_program-0.25.0}/gea/month_end.py +0 -0
  205. {gea_program-0.23.0 → gea_program-0.25.0}/gea/mqtt_port.py +0 -0
  206. {gea_program-0.23.0 → gea_program-0.25.0}/gea/notify.py +0 -0
  207. {gea_program-0.23.0 → gea_program-0.25.0}/gea/opcua_port.py +0 -0
  208. {gea_program-0.23.0 → gea_program-0.25.0}/gea/operator_app.py +0 -0
  209. {gea_program-0.23.0 → gea_program-0.25.0}/gea/osdu.py +0 -0
  210. {gea_program-0.23.0 → gea_program-0.25.0}/gea/permits.py +0 -0
  211. {gea_program-0.23.0 → gea_program-0.25.0}/gea/ppdm.py +0 -0
  212. {gea_program-0.23.0 → gea_program-0.25.0}/gea/profile_catalog.py +0 -0
  213. {gea_program-0.23.0 → gea_program-0.25.0}/gea/project.py +0 -0
  214. {gea_program-0.23.0 → gea_program-0.25.0}/gea/qt6_downhole_app.py +0 -0
  215. {gea_program-0.23.0 → gea_program-0.25.0}/gea/quakeml.py +0 -0
  216. {gea_program-0.23.0 → gea_program-0.25.0}/gea/reconciler.py +0 -0
  217. {gea_program-0.23.0 → gea_program-0.25.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
  218. {gea_program-0.23.0 → gea_program-0.25.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
  219. {gea_program-0.23.0 → gea_program-0.25.0}/gea/reference/libmseed_steim.provenance.json +0 -0
  220. {gea_program-0.23.0 → gea_program-0.25.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
  221. {gea_program-0.23.0 → gea_program-0.25.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
  222. {gea_program-0.23.0 → gea_program-0.25.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
  223. {gea_program-0.23.0 → gea_program-0.25.0}/gea/sample_record.py +0 -0
  224. {gea_program-0.23.0 → gea_program-0.25.0}/gea/sample_well_profile.csv +0 -0
  225. {gea_program-0.23.0 → gea_program-0.25.0}/gea/sbom.py +0 -0
  226. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seedlink.py +0 -0
  227. {gea_program-0.23.0 → gea_program-0.25.0}/gea/segy.py +0 -0
  228. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic.py +0 -0
  229. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_array.py +0 -0
  230. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_assoc.py +0 -0
  231. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_detect.py +0 -0
  232. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_film.py +0 -0
  233. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_harmonic.py +0 -0
  234. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_qc.py +0 -0
  235. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_response.py +0 -0
  236. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_signature.py +0 -0
  237. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_track.py +0 -0
  238. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_uncertainty.py +0 -0
  239. {gea_program-0.23.0 → gea_program-0.25.0}/gea/seismic_unlisted.py +0 -0
  240. {gea_program-0.23.0 → gea_program-0.25.0}/gea/sensor_swap.py +0 -0
  241. {gea_program-0.23.0 → gea_program-0.25.0}/gea/service_life.py +0 -0
  242. {gea_program-0.23.0 → gea_program-0.25.0}/gea/shapefile.py +0 -0
  243. {gea_program-0.23.0 → gea_program-0.25.0}/gea/shell.py +0 -0
  244. {gea_program-0.23.0 → gea_program-0.25.0}/gea/shut_in.py +0 -0
  245. {gea_program-0.23.0 → gea_program-0.25.0}/gea/sla_report.py +0 -0
  246. {gea_program-0.23.0 → gea_program-0.25.0}/gea/soak.py +0 -0
  247. {gea_program-0.23.0 → gea_program-0.25.0}/gea/sra.py +0 -0
  248. {gea_program-0.23.0 → gea_program-0.25.0}/gea/store_forward.py +0 -0
  249. {gea_program-0.23.0 → gea_program-0.25.0}/gea/strata_join.py +0 -0
  250. {gea_program-0.23.0 → gea_program-0.25.0}/gea/structure.py +0 -0
  251. {gea_program-0.23.0 → gea_program-0.25.0}/gea/supervisor.py +0 -0
  252. {gea_program-0.23.0 → gea_program-0.25.0}/gea/survey_view.py +0 -0
  253. {gea_program-0.23.0 → gea_program-0.25.0}/gea/telemetry.py +0 -0
  254. {gea_program-0.23.0 → gea_program-0.25.0}/gea/tool_library.py +0 -0
  255. {gea_program-0.23.0 → gea_program-0.25.0}/gea/transient.py +0 -0
  256. {gea_program-0.23.0 → gea_program-0.25.0}/gea/vibration.py +0 -0
  257. {gea_program-0.23.0 → gea_program-0.25.0}/gea/well_assembler.py +0 -0
  258. {gea_program-0.23.0 → gea_program-0.25.0}/gea/well_test_validation.py +0 -0
  259. {gea_program-0.23.0 → gea_program-0.25.0}/gea/wits0.py +0 -0
  260. {gea_program-0.23.0 → gea_program-0.25.0}/gea/witsml.py +0 -0
  261. {gea_program-0.23.0 → gea_program-0.25.0}/gea_program.egg-info/dependency_links.txt +0 -0
  262. {gea_program-0.23.0 → gea_program-0.25.0}/gea_program.egg-info/entry_points.txt +0 -0
  263. {gea_program-0.23.0 → gea_program-0.25.0}/gea_program.egg-info/requires.txt +0 -0
  264. {gea_program-0.23.0 → gea_program-0.25.0}/gea_program.egg-info/top_level.txt +0 -0
  265. {gea_program-0.23.0 → gea_program-0.25.0}/setup.cfg +0 -0
  266. {gea_program-0.23.0 → gea_program-0.25.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.23.0
3
+ Version: 0.25.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,7 +125,7 @@ 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 (356 checks)
128
+ gea accept # the product gate (362 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]")
@@ -648,6 +648,37 @@ against it; `gea seedlink --config ... --hello` prints what a server says of
648
648
  itself; `gea help seedlink`. A TexNet station is served by EarthScope at
649
649
  `rtserve.iris.washington.edu:18000`, network `TX`.
650
650
 
651
+ ### The catalogue accounted for
652
+
653
+ `gea catalog --list` is the register of the 52 shipped public datasets: for
654
+ each, what in this program reads it, or CARRIED, NO BAND with the reason;
655
+ the gate holds the register to the code both ways and reads every entry.
656
+ `gea survey --catalog <entry>` runs the strata survey on any catalogue log
657
+ with its provenance; `gea catalog --friction` reads seven laboratory
658
+ datasets on natural fault and sediment samples as the measured friction
659
+ envelope (0.21-0.90 on 70 measurements, none from the Permian) against
660
+ Byerlee's 0.6; `gea catalog --core` checks the published sandstone range
661
+ against the Volve core (65 of 70 plugs inside), an evaluation on the rock
662
+ inventory model card. `gea help catalog`.
663
+
664
+ ### The log as delivered, and the historian
665
+
666
+ A well log arrives as DLIS (API RP66 V1); `gea/dlis.py` reads the container
667
+ as the standard lays it out, with no dependency - the storage unit label,
668
+ visible records, logical record segments and trailers, the sets of objects
669
+ with every representation code, the frames and channels, the frame data -
670
+ and hands the strata survey the same stream the LAS port does: `gea dlis
671
+ --file log.dlis --info` describes it, `--to-las` exports a frame, `gea survey
672
+ --file log.dlis` reads it directly, and the Files page detects it by its
673
+ label. Encrypted records are skipped and named, never decrypted or guessed.
674
+ Proven on a real Schlumberger station log (104 channels, two frames, 3,252
675
+ records in a tenth of a second). The operator's gauge history in a PI System
676
+ comes out through PI Web API (`gea piwebapi`, protocol `piwebapi` on the
677
+ Patch panel): GET only, the archive between two times with its paging
678
+ followed, every value with the archive's timestamp and flags, credentials
679
+ from environment variables the map names. `gea help dlis`, `gea help
680
+ historian`.
681
+
651
682
  ### The field ports
652
683
 
653
684
  The three links a gauge panel on a pad actually offers, each read-only in
@@ -86,7 +86,7 @@ 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 (356 checks)
89
+ gea accept # the product gate (362 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]")
@@ -609,6 +609,37 @@ against it; `gea seedlink --config ... --hello` prints what a server says of
609
609
  itself; `gea help seedlink`. A TexNet station is served by EarthScope at
610
610
  `rtserve.iris.washington.edu:18000`, network `TX`.
611
611
 
612
+ ### The catalogue accounted for
613
+
614
+ `gea catalog --list` is the register of the 52 shipped public datasets: for
615
+ each, what in this program reads it, or CARRIED, NO BAND with the reason;
616
+ the gate holds the register to the code both ways and reads every entry.
617
+ `gea survey --catalog <entry>` runs the strata survey on any catalogue log
618
+ with its provenance; `gea catalog --friction` reads seven laboratory
619
+ datasets on natural fault and sediment samples as the measured friction
620
+ envelope (0.21-0.90 on 70 measurements, none from the Permian) against
621
+ Byerlee's 0.6; `gea catalog --core` checks the published sandstone range
622
+ against the Volve core (65 of 70 plugs inside), an evaluation on the rock
623
+ inventory model card. `gea help catalog`.
624
+
625
+ ### The log as delivered, and the historian
626
+
627
+ A well log arrives as DLIS (API RP66 V1); `gea/dlis.py` reads the container
628
+ as the standard lays it out, with no dependency - the storage unit label,
629
+ visible records, logical record segments and trailers, the sets of objects
630
+ with every representation code, the frames and channels, the frame data -
631
+ and hands the strata survey the same stream the LAS port does: `gea dlis
632
+ --file log.dlis --info` describes it, `--to-las` exports a frame, `gea survey
633
+ --file log.dlis` reads it directly, and the Files page detects it by its
634
+ label. Encrypted records are skipped and named, never decrypted or guessed.
635
+ Proven on a real Schlumberger station log (104 channels, two frames, 3,252
636
+ records in a tenth of a second). The operator's gauge history in a PI System
637
+ comes out through PI Web API (`gea piwebapi`, protocol `piwebapi` on the
638
+ Patch panel): GET only, the archive between two times with its paging
639
+ followed, every value with the archive's timestamp and flags, credentials
640
+ from environment variables the map names. `gea help dlis`, `gea help
641
+ historian`.
642
+
612
643
  ### The field ports
613
644
 
614
645
  The three links a gauge panel on a pad actually offers, each read-only in
@@ -123,7 +123,7 @@ from .profile_catalog import (
123
123
  read_pangaea_txt,
124
124
  )
125
125
 
126
- __version__ = "0.23.0"
126
+ __version__ = "0.25.0"
127
127
  __all__ = [
128
128
  "aging_rate", "rate_psi_yr", "accuracy_psi",
129
129
  "Sensor", "SimulatorConfig", "DownholeEngine",
@@ -278,6 +278,26 @@ def main(argv=None) -> int:
278
278
  p_lp.add_argument("--stream-csv", type=str, default=None, help="also write a historian-style CSV the other commands ingest")
279
279
  p_lp.add_argument("--selftest", action="store_true", help="etp: the codec round-trip and a session against the simulated store on the loopback")
280
280
 
281
+ p_cat = sub.add_parser("catalog", help="the shipped catalogue: --list every entry with what reads it; --unused the carried ones; --check reads every entry; --friction the measured friction envelope; --core the core check; --entry X --info | --stream-csv")
282
+ p_cat.add_argument("--list", action="store_true"); p_cat.add_argument("--unused", action="store_true"); p_cat.add_argument("--check", action="store_true")
283
+ p_cat.add_argument("--friction", action="store_true"); p_cat.add_argument("--core", action="store_true")
284
+ p_cat.add_argument("--entry", type=str, default=None); p_cat.add_argument("--info", action="store_true"); p_cat.add_argument("--stream-csv", type=str, default=None)
285
+ p_cat.add_argument("--json", action="store_true")
286
+ p_dl = sub.add_parser("dlis", help="a DLIS (RP66 V1) well log: --info describes it (origin, channels, frames, what was skipped); --frame --out writes the frame as a historian-style CSV; --to-las writes LAS 2.0")
287
+ p_dl.add_argument("--file", type=str, required=True)
288
+ p_dl.add_argument("--info", action="store_true")
289
+ p_dl.add_argument("--frame", type=str, default=None, help="the frame to read when the file holds several")
290
+ p_dl.add_argument("--out", type=str, default=None, help="write the frame's channels as CSV (index first)")
291
+ p_dl.add_argument("--to-las", type=str, default=None, help="write the frame as a LAS 2.0 file")
292
+ p_dl.add_argument("--json", action="store_true")
293
+ p_pi = sub.add_parser("piwebapi", help="the PI Web API historian pull, read-only: --config (base_url, auth by environment variable names, tags with paths); --selftest against the stand-in")
294
+ p_pi.add_argument("--config", type=str, default=None)
295
+ p_pi.add_argument("--write-example-config", type=str, default=None)
296
+ p_pi.add_argument("--out", type=str, default=None, help="write the records CSV here")
297
+ p_pi.add_argument("--stream-csv", type=str, default=None)
298
+ p_pi.add_argument("--seconds", type=float, default=None, help="ignored: a pull is one request per tag (kept so the live tap's call shape is the same)")
299
+ p_pi.add_argument("--record", type=str, default=None, help="write the pull's summary as one JSON line here")
300
+ p_pi.add_argument("--selftest", action="store_true")
281
301
  for name, helptxt in (("modbus-rtu", "Modbus RTU port, read-only: the serial line (pyserial) or RTU over TCP; functions 03/04 only; the stand-in slave with --selftest"),
282
302
  ("dnp3", "DNP3 (IEEE 1815) master, read-only: integrity and event polls over TCP; analog inputs, binaries, counters with flags and event times; the stand-in outstation with --selftest"),
283
303
  ("hartip", "HART-IP client, read-only: session, command 0, 3 and 9; the variables with their unit codes and status; the stand-in device with --selftest")):
@@ -671,8 +691,10 @@ def main(argv=None) -> int:
671
691
  p_fl.add_argument("--station-md", type=float, default=None)
672
692
  p_fl.add_argument("--actor", type=str, default="cli")
673
693
 
674
- p_sy = sub.add_parser("survey", help="a LAS file in, one strata report out (--demo: the bundled public KTB excerpt); --out writes report.txt + survey.json")
675
- p_sy.add_argument("--file", type=str, default=None, help="LAS 2.0 file")
694
+ p_sy = sub.add_parser("survey", help="a LAS or DLIS file in, one strata report out (--demo: the bundled public KTB excerpt); --out writes report.txt + survey.json")
695
+ p_sy.add_argument("--file", type=str, default=None, help="LAS 2.0 or DLIS (RP66 V1) file")
696
+ p_sy.add_argument("--frame", type=str, default=None, help="DLIS: the frame to read when the file holds several (gea dlis --file X --info lists them)")
697
+ p_sy.add_argument("--catalog", type=str, default=None, help="a catalogue LAS entry instead of a file (gea catalog --list names them)")
676
698
  p_sy.add_argument("--demo", action="store_true")
677
699
  p_sy.add_argument("--family", type=str, default="continental_crystalline", help="prior family for the estimator")
678
700
  p_sy.add_argument("--lat", type=float, default=None)
@@ -807,9 +829,9 @@ def main(argv=None) -> int:
807
829
  elif a.cmd == "survey":
808
830
  import json as _json
809
831
  from .survey_cmd import run_survey
810
- if not (a.file or a.demo):
811
- raise SystemExit("survey needs --file <LAS> or --demo")
812
- txt, machine = run_survey(path=a.file, demo=a.demo, family=a.family, lat=a.lat, elev=a.elev)
832
+ if not (a.file or a.demo or a.catalog):
833
+ raise SystemExit("survey needs --file <LAS or DLIS>, --catalog <entry> or --demo")
834
+ txt, machine = run_survey(path=a.file, demo=a.demo, family=a.family, lat=a.lat, elev=a.elev, frame=a.frame, catalog=a.catalog)
813
835
  print(txt)
814
836
  if a.out:
815
837
  os.makedirs(a.out, exist_ok=True)
@@ -2282,6 +2304,163 @@ def main(argv=None) -> int:
2282
2304
  stop.set()
2283
2305
  print("etp-sim: stopped")
2284
2306
  return 0
2307
+ elif a.cmd == "catalog":
2308
+ import json as _json
2309
+ from . import catalog_register as _CR
2310
+ if a.friction:
2311
+ from . import friction_priors as _FP
2312
+ print(_json.dumps({"measured": _FP.measured(), "envelope": _FP.envelope()}, indent=1, default=str) if a.json else _FP.text()); return 0
2313
+ if a.core:
2314
+ from .rock_inventory import core_check
2315
+ c = core_check()
2316
+ print(_json.dumps(c, indent=1) if a.json else (f"core check ({c.get('entry')}): {c.get('how')}\n grain density {c['grain_density']['min']}-{c['grain_density']['max']} g/cc, porosity "
2317
+ f"{c['porosity_frac']['min']:.3f}-{c['porosity_frac']['max']:.3f}, bulk {c['bulk_density']['min']}-{c['bulk_density']['max']} g/cc; {c['outside']} plug(s) outside the range\n source: {c['source']} [{c['license']}]" if c.get('status') == 'OK' else str(c)))
2318
+ return 0
2319
+ if a.check:
2320
+ rows = _CR.check_all()
2321
+ bad = [r for r in rows if not r["ok"]]
2322
+ for r in rows:
2323
+ print(f" {'ok ' if r['ok'] else 'BAD'} {r['entry']:<40s} {r['shape']}")
2324
+ print(f"catalog: {len(rows) - len(bad)} of {len(rows)} entries read through their own readers" + (f"; {len(bad)} did not" if bad else ""))
2325
+ return 0 if not bad else 1
2326
+ if a.entry:
2327
+ from .profile_catalog import CATALOG as _CAT
2328
+ e = _CAT.get(a.entry)
2329
+ if e is None:
2330
+ raise SystemExit(f"catalog: no entry {a.entry!r} (gea catalog --list)")
2331
+ if a.stream_csv:
2332
+ st = e.stream()
2333
+ import csv as _csv
2334
+ with open(a.stream_csv, "w", newline="", encoding="utf-8") as f:
2335
+ wr = _csv.writer(f)
2336
+ wr.writerow([st.index_kind] + list(st.channels)); wr.writerow([""] + [st.channels[c].unit for c in st.channels])
2337
+ for i in range(len(st.index)):
2338
+ wr.writerow([float(st.index[i])] + ["" if st.channels[c].values[i] != st.channels[c].values[i] else float(st.channels[c].values[i]) for c in st.channels])
2339
+ print(f"{a.entry}: {len(st.index)} rows x {len(st.channels)} channels -> {a.stream_csv}")
2340
+ reg = next(r for r in _CR.register() if r["entry"] == a.entry)
2341
+ if a.json:
2342
+ print(_json.dumps({"register": reg, "provenance": e.provenance}, indent=1, default=str))
2343
+ else:
2344
+ print(f"{a.entry}: {reg['kind']} ({reg['tier']}), {reg['file']} {reg['bytes']:,} bytes, {reg['status']}")
2345
+ for u in reg["used_by"]:
2346
+ print(" used by:", u)
2347
+ for k in ("well", "source_database", "source_url", "license", "fetch_date", "coverage", "purpose"):
2348
+ if e.provenance.get(k):
2349
+ print(f" {k}: {str(e.provenance[k])[:300]}")
2350
+ print(" reads as:", _CR.check_entry(e)["shape"])
2351
+ return 0
2352
+ rows = _CR.register()
2353
+ if a.json:
2354
+ print(_json.dumps({"entries": rows, "audit": _CR.audit()}, indent=1, default=str)); return 0
2355
+ print(_CR.text(rows, unused_only=a.unused))
2356
+ if a.unused:
2357
+ print(f"\n {_CR.NO_BAND_REASON}")
2358
+ return 0
2359
+ elif a.cmd == "dlis":
2360
+ import json as _json
2361
+ from .dlis import DlisError, DlisFile, read as _read_dlis
2362
+ try:
2363
+ if a.info or not (a.out or a.to_las):
2364
+ with open(a.file, "rb") as f:
2365
+ info = DlisFile(f.read(), os.path.basename(a.file)).describe()
2366
+ if a.json:
2367
+ print(_json.dumps(info, indent=1, default=str)); return 0
2368
+ o = info["origin"]
2369
+ print(f"dlis: {a.file}")
2370
+ print(f" storage set: {info['storage_unit']['storage_set_id']}; file {info['file_header'].get('ID', '').strip()} seq {info['file_header'].get('SEQUENCE-NUMBER', '').strip()}")
2371
+ print(f" well: {o.get('WELL-NAME', '').strip() or '?'} field: {o.get('FIELD-NAME', '').strip() or '?'} company: {o.get('COMPANY', '').strip() or '?'} producer: {o.get('PRODUCER-NAME', '').strip() or '?'} created: {o.get('CREATION-TIME', '?')}")
2372
+ print(f" {info['n_records']} logical records; sets: " + ", ".join(f"{t}{'(' + n + ')' if n else ''} x{k}" for t, n, k in info["eflr_sets"]))
2373
+ if info.get("encrypted_records"):
2374
+ print(" encrypted records skipped: " + ", ".join(f"{k} x{n}" for k, n in info["encrypted_records"].items()))
2375
+ for u in info["unparsed"]:
2376
+ print(" not parsed: " + u)
2377
+ print(f" {len(info['channels'])} channels:")
2378
+ for c in info["channels"]:
2379
+ print(f" {c['name']:<12s} {c['units']:<10s} {c['code']:<7s} dim {c['dimension']} {c['long_name']}")
2380
+ for fr in info["frames"]:
2381
+ print(f" frame {fr['name']}: index {fr['index_type']} {fr['direction']}, spacing {fr['spacing']} {fr['spacing_units']}, {fr['index_min']}..{fr['index_max']}; {len(fr['channels'])} channels: {', '.join(fr['channels'][:12])}{' ...' if len(fr['channels']) > 12 else ''}")
2382
+ return 0
2383
+ st = _read_dlis(a.file, frame=a.frame)
2384
+ except (DlisError, OSError) as e:
2385
+ raise SystemExit(f"dlis: {e}")
2386
+ print(f"dlis: frame {st.meta['frame']}: {len(st.index)} rows, index {st.meta['index_channel']} ({st.meta['index_units']}) {float(st.index[0]):g}..{float(st.index[-1]):g}, {len(st.channels)} channels"
2387
+ + (f"; {st.meta['notes']}" if st.meta.get("notes") else ""))
2388
+ if a.out:
2389
+ import csv as _csv
2390
+ with open(a.out, "w", newline="", encoding="utf-8") as f:
2391
+ w = _csv.writer(f)
2392
+ w.writerow([st.meta["index_channel"]] + list(st.channels))
2393
+ w.writerow([st.meta["index_units"]] + [st.channels[c].unit for c in st.channels])
2394
+ for i in range(len(st.index)):
2395
+ w.writerow([float(st.index[i])] + ["" if st.channels[c].values[i] != st.channels[c].values[i] else float(st.channels[c].values[i]) for c in st.channels])
2396
+ print(" csv:", a.out)
2397
+ if a.to_las:
2398
+ with open(a.to_las, "w", encoding="utf-8") as f:
2399
+ f.write("~VERSION INFORMATION\n VERS. 2.0 : CWLS LOG ASCII STANDARD - VERSION 2.0\n WRAP. NO : ONE LINE PER DEPTH STEP\n")
2400
+ f.write("~WELL INFORMATION\n")
2401
+ f.write(f" STRT.{st.meta['index_units']:<6s} {float(st.index[0]):.4f} : START\n STOP.{st.meta['index_units']:<6s} {float(st.index[-1]):.4f} : STOP\n")
2402
+ f.write(f" STEP.{st.meta['index_units']:<6s} {(float(st.index[1]) - float(st.index[0])) if len(st.index) > 1 else 0.0:.4f} : STEP\n NULL. -999.25 : NULL VALUE\n")
2403
+ f.write(f" WELL. {st.meta.get('WELL-NAME', '').strip()} : WELL\n FLD . {st.meta.get('FIELD-NAME', '').strip()} : FIELD\n COMP. {st.meta.get('COMPANY', '').strip()} : COMPANY\n SRVC. {st.meta.get('PRODUCER-NAME', '').strip()} : SERVICE COMPANY\n")
2404
+ f.write(f" SRC . DLIS {os.path.basename(a.file)} frame {st.meta['frame']} : SOURCE (gea dlis --to-las)\n")
2405
+ f.write("~CURVE INFORMATION\n")
2406
+ f.write(f" {st.meta['index_channel']:<8s}.{st.meta['index_units']:<8s} : INDEX\n")
2407
+ for c in st.channels:
2408
+ f.write(f" {c:<8s}.{st.channels[c].unit:<8s} : {c}\n")
2409
+ f.write("~A\n")
2410
+ for i in range(len(st.index)):
2411
+ f.write(f"{float(st.index[i]):.4f}" + "".join(f" {(-999.25 if st.channels[c].values[i] != st.channels[c].values[i] else float(st.channels[c].values[i])):.4f}" for c in st.channels) + "\n")
2412
+ print(" las:", a.to_las)
2413
+ return 0
2414
+ elif a.cmd == "piwebapi":
2415
+ import json as _json
2416
+ from .live_ports import records_to_stream, summarize, write_records_csv
2417
+ from . import piwebapi as _PI
2418
+ if a.selftest:
2419
+ r = _PI.selftest()
2420
+ print(f"piwebapi selftest: {'OK' if r['ok'] else 'FAILED'}")
2421
+ for k, v in r.items():
2422
+ if k != "ok":
2423
+ print(f" {'ok ' if v else 'BAD'} {k}")
2424
+ return 0 if r["ok"] else 1
2425
+ if a.write_example_config:
2426
+ with open(a.write_example_config, "w", encoding="utf-8") as f:
2427
+ _json.dump(_PI.EXAMPLE_CONFIG, f, indent=1)
2428
+ print("config:", a.write_example_config); return 0
2429
+ if not a.config:
2430
+ raise SystemExit("piwebapi needs --config (or --write-example-config to start one)")
2431
+ cfg = _PI.load_config(a.config)
2432
+ sim_h = None
2433
+ try:
2434
+ if cfg.get("base_url") == "sim":
2435
+ sim = _PI.SimServer(); sim_h, port_ = sim.serve(); cfg = {**cfg, "base_url": f"http://127.0.0.1:{port_}/piwebapi", "auth": "none"}
2436
+ try:
2437
+ port = _PI.PiPort(cfg)
2438
+ r = port.pull()
2439
+ except (_PI.PiError, ValueError) as e:
2440
+ raise SystemExit(f"piwebapi: {e}")
2441
+ finally:
2442
+ if sim_h is not None:
2443
+ sim_h.close()
2444
+ recs = port.records
2445
+ print(f"piwebapi: {_json.dumps(port.summary(), default=str)}")
2446
+ print(_json.dumps(summarize(recs), indent=1))
2447
+ if a.record:
2448
+ with open(a.record, "w", encoding="utf-8") as f:
2449
+ f.write(_json.dumps({"pull": r, "summary": port.summary()}, default=str) + "\n")
2450
+ if a.out:
2451
+ print(" records:", write_records_csv(recs, a.out))
2452
+ if a.stream_csv and recs:
2453
+ st = records_to_stream(recs, name="piwebapi")
2454
+ import csv as _csv
2455
+ from datetime import datetime as _dt, timedelta as _td
2456
+ t0 = _dt.fromisoformat(st.meta["start_time"])
2457
+ with open(a.stream_csv, "w", newline="", encoding="utf-8") as f:
2458
+ w = _csv.writer(f)
2459
+ w.writerow(["timestamp"] + list(st.channels))
2460
+ for i, t in enumerate(st.index):
2461
+ w.writerow([(t0 + _td(seconds=float(t))).isoformat()] + ["" if st.channels[c].values[i] != st.channels[c].values[i] else round(float(st.channels[c].values[i]), 4) for c in st.channels])
2462
+ print(" stream:", a.stream_csv)
2463
+ return 0 if not port.faults else 1
2285
2464
  elif a.cmd in ("modbus-rtu", "dnp3", "hartip"):
2286
2465
  import json as _json
2287
2466
  from .live_ports import records_to_stream, summarize, write_records_csv