gea-program 0.20.0__tar.gz → 0.22.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 (255) hide show
  1. {gea_program-0.20.0 → gea_program-0.22.0}/PKG-INFO +49 -2
  2. {gea_program-0.20.0 → gea_program-0.22.0}/README.md +48 -1
  3. {gea_program-0.20.0 → gea_program-0.22.0}/gea/__init__.py +1 -1
  4. {gea_program-0.20.0 → gea_program-0.22.0}/gea/__main__.py +132 -4
  5. {gea_program-0.20.0 → gea_program-0.22.0}/gea/acceptance_tests.py +501 -0
  6. {gea_program-0.20.0 → gea_program-0.22.0}/gea/client_reports.py +49 -0
  7. gea_program-0.22.0/gea/elevation.py +60 -0
  8. gea_program-0.22.0/gea/help/interval.md +11 -0
  9. gea_program-0.22.0/gea/help/structure.md +11 -0
  10. {gea_program-0.20.0 → gea_program-0.22.0}/gea/helplib.py +2 -0
  11. gea_program-0.22.0/gea/interval.py +250 -0
  12. {gea_program-0.20.0 → gea_program-0.22.0}/gea/service.py +102 -0
  13. gea_program-0.22.0/gea/shapefile.py +398 -0
  14. gea_program-0.22.0/gea/structure.py +342 -0
  15. {gea_program-0.20.0 → gea_program-0.22.0}/gea/web/app.html +63 -0
  16. {gea_program-0.20.0 → gea_program-0.22.0}/gea/workspace.py +230 -4
  17. {gea_program-0.20.0 → gea_program-0.22.0}/gea_program.egg-info/PKG-INFO +49 -2
  18. {gea_program-0.20.0 → gea_program-0.22.0}/gea_program.egg-info/SOURCES.txt +6 -0
  19. {gea_program-0.20.0 → gea_program-0.22.0}/pyproject.toml +1 -1
  20. {gea_program-0.20.0 → gea_program-0.22.0}/LICENSE +0 -0
  21. {gea_program-0.20.0 → gea_program-0.22.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
  22. {gea_program-0.20.0 → gea_program-0.22.0}/gea/accuracy_statement.py +0 -0
  23. {gea_program-0.20.0 → gea_program-0.22.0}/gea/alarm_engine.py +0 -0
  24. {gea_program-0.20.0 → gea_program-0.22.0}/gea/backup.py +0 -0
  25. {gea_program-0.20.0 → gea_program-0.22.0}/gea/bench.py +0 -0
  26. {gea_program-0.20.0 → gea_program-0.22.0}/gea/blind_harness.py +0 -0
  27. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
  28. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
  29. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
  30. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
  31. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
  32. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
  33. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
  34. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
  35. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
  36. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
  37. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
  38. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
  39. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
  40. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
  41. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
  42. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
  43. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
  44. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
  45. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
  46. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
  47. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
  48. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
  49. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
  50. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
  51. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
  52. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
  53. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
  54. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
  55. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
  56. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
  57. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
  58. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
  59. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
  60. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
  61. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
  62. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
  63. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
  64. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
  65. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
  66. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
  67. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
  68. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
  69. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
  70. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
  71. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
  72. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
  73. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
  74. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
  75. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
  76. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
  77. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
  78. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
  79. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
  80. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
  81. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
  82. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
  83. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
  84. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
  85. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
  86. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
  87. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
  88. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
  89. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
  90. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
  91. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
  92. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
  93. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
  94. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/med_160_sapropels.txt +0 -0
  95. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
  96. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
  97. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
  98. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
  99. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
  100. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
  101. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
  102. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
  103. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
  104. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
  105. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
  106. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
  107. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
  108. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
  109. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
  110. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
  111. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
  112. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
  113. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
  114. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
  115. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
  116. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
  117. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
  118. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
  119. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
  120. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
  121. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
  122. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
  123. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
  124. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
  125. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
  126. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
  127. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
  128. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
  129. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
  130. {gea_program-0.20.0 → gea_program-0.22.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
  131. {gea_program-0.20.0 → gea_program-0.22.0}/gea/certificates.py +0 -0
  132. {gea_program-0.20.0 → gea_program-0.22.0}/gea/cli.py +0 -0
  133. {gea_program-0.20.0 → gea_program-0.22.0}/gea/config_versioning.py +0 -0
  134. {gea_program-0.20.0 → gea_program-0.22.0}/gea/conformance.py +0 -0
  135. {gea_program-0.20.0 → gea_program-0.22.0}/gea/correlation.py +0 -0
  136. {gea_program-0.20.0 → gea_program-0.22.0}/gea/dashboard.py +0 -0
  137. {gea_program-0.20.0 → gea_program-0.22.0}/gea/deviation.py +0 -0
  138. {gea_program-0.20.0 → gea_program-0.22.0}/gea/doctor.py +0 -0
  139. {gea_program-0.20.0 → gea_program-0.22.0}/gea/downhole_engine.py +0 -0
  140. {gea_program-0.20.0 → gea_program-0.22.0}/gea/drift_monitor.py +0 -0
  141. {gea_program-0.20.0 → gea_program-0.22.0}/gea/earth_model.py +0 -0
  142. {gea_program-0.20.0 → gea_program-0.22.0}/gea/etp.py +0 -0
  143. {gea_program-0.20.0 → gea_program-0.22.0}/gea/etp12_schemas.json +0 -0
  144. {gea_program-0.20.0 → gea_program-0.22.0}/gea/example_register_map.json +0 -0
  145. {gea_program-0.20.0 → gea_program-0.22.0}/gea/fat_sat.py +0 -0
  146. {gea_program-0.20.0 → gea_program-0.22.0}/gea/files.py +0 -0
  147. {gea_program-0.20.0 → gea_program-0.22.0}/gea/follower.py +0 -0
  148. {gea_program-0.20.0 → gea_program-0.22.0}/gea/forward_model.py +0 -0
  149. {gea_program-0.20.0 → gea_program-0.22.0}/gea/gamma.py +0 -0
  150. {gea_program-0.20.0 → gea_program-0.22.0}/gea/gauge_aging.py +0 -0
  151. {gea_program-0.20.0 → gea_program-0.22.0}/gea/gauge_specs.py +0 -0
  152. {gea_program-0.20.0 → gea_program-0.22.0}/gea/geodesy.py +0 -0
  153. {gea_program-0.20.0 → gea_program-0.22.0}/gea/gravity_reference.py +0 -0
  154. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/TESTER_GUIDE.md +0 -0
  155. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/alarms.md +0 -0
  156. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/audit-update.md +0 -0
  157. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/backup.md +0 -0
  158. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/conformance.md +0 -0
  159. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/data-in.md +0 -0
  160. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/doctor.md +0 -0
  161. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/drift.md +0 -0
  162. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/etp.md +0 -0
  163. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/files.md +0 -0
  164. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/instruments.md +0 -0
  165. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/month-end.md +0 -0
  166. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/notifications.md +0 -0
  167. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/osdu.md +0 -0
  168. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/patches.md +0 -0
  169. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/ppdm.md +0 -0
  170. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/quakeml.md +0 -0
  171. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/quality.md +0 -0
  172. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/seedlink.md +0 -0
  173. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/seismic.md +0 -0
  174. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/site.md +0 -0
  175. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/sites.md +0 -0
  176. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/soak.md +0 -0
  177. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/sra.md +0 -0
  178. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/start.md +0 -0
  179. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/transients.md +0 -0
  180. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/upkeep.md +0 -0
  181. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/vibration.md +0 -0
  182. {gea_program-0.20.0 → gea_program-0.22.0}/gea/help/well-tests.md +0 -0
  183. {gea_program-0.20.0 → gea_program-0.22.0}/gea/housekeeping.py +0 -0
  184. {gea_program-0.20.0 → gea_program-0.22.0}/gea/inverse_engine.py +0 -0
  185. {gea_program-0.20.0 → gea_program-0.22.0}/gea/jobs.py +0 -0
  186. {gea_program-0.20.0 → gea_program-0.22.0}/gea/live_ports.py +0 -0
  187. {gea_program-0.20.0 → gea_program-0.22.0}/gea/loadtest.py +0 -0
  188. {gea_program-0.20.0 → gea_program-0.22.0}/gea/matplotlib_demo.py +0 -0
  189. {gea_program-0.20.0 → gea_program-0.22.0}/gea/modbus.py +0 -0
  190. {gea_program-0.20.0 → gea_program-0.22.0}/gea/model_card.py +0 -0
  191. {gea_program-0.20.0 → gea_program-0.22.0}/gea/month_end.py +0 -0
  192. {gea_program-0.20.0 → gea_program-0.22.0}/gea/mqtt_port.py +0 -0
  193. {gea_program-0.20.0 → gea_program-0.22.0}/gea/notify.py +0 -0
  194. {gea_program-0.20.0 → gea_program-0.22.0}/gea/opcua_port.py +0 -0
  195. {gea_program-0.20.0 → gea_program-0.22.0}/gea/operator_app.py +0 -0
  196. {gea_program-0.20.0 → gea_program-0.22.0}/gea/osdu.py +0 -0
  197. {gea_program-0.20.0 → gea_program-0.22.0}/gea/patches.py +0 -0
  198. {gea_program-0.20.0 → gea_program-0.22.0}/gea/permits.py +0 -0
  199. {gea_program-0.20.0 → gea_program-0.22.0}/gea/ports.py +0 -0
  200. {gea_program-0.20.0 → gea_program-0.22.0}/gea/ppdm.py +0 -0
  201. {gea_program-0.20.0 → gea_program-0.22.0}/gea/profile_catalog.py +0 -0
  202. {gea_program-0.20.0 → gea_program-0.22.0}/gea/project.py +0 -0
  203. {gea_program-0.20.0 → gea_program-0.22.0}/gea/qt6_downhole_app.py +0 -0
  204. {gea_program-0.20.0 → gea_program-0.22.0}/gea/quakeml.py +0 -0
  205. {gea_program-0.20.0 → gea_program-0.22.0}/gea/reconciler.py +0 -0
  206. {gea_program-0.20.0 → gea_program-0.22.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
  207. {gea_program-0.20.0 → gea_program-0.22.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
  208. {gea_program-0.20.0 → gea_program-0.22.0}/gea/reference/libmseed_steim.provenance.json +0 -0
  209. {gea_program-0.20.0 → gea_program-0.22.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
  210. {gea_program-0.20.0 → gea_program-0.22.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
  211. {gea_program-0.20.0 → gea_program-0.22.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
  212. {gea_program-0.20.0 → gea_program-0.22.0}/gea/rock_inventory.py +0 -0
  213. {gea_program-0.20.0 → gea_program-0.22.0}/gea/sample_record.py +0 -0
  214. {gea_program-0.20.0 → gea_program-0.22.0}/gea/sample_well_profile.csv +0 -0
  215. {gea_program-0.20.0 → gea_program-0.22.0}/gea/sbom.py +0 -0
  216. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seedlink.py +0 -0
  217. {gea_program-0.20.0 → gea_program-0.22.0}/gea/segy.py +0 -0
  218. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic.py +0 -0
  219. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_array.py +0 -0
  220. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_assoc.py +0 -0
  221. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_detect.py +0 -0
  222. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_film.py +0 -0
  223. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_harmonic.py +0 -0
  224. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_qc.py +0 -0
  225. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_response.py +0 -0
  226. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_signature.py +0 -0
  227. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_track.py +0 -0
  228. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_uncertainty.py +0 -0
  229. {gea_program-0.20.0 → gea_program-0.22.0}/gea/seismic_unlisted.py +0 -0
  230. {gea_program-0.20.0 → gea_program-0.22.0}/gea/sensor_swap.py +0 -0
  231. {gea_program-0.20.0 → gea_program-0.22.0}/gea/service_life.py +0 -0
  232. {gea_program-0.20.0 → gea_program-0.22.0}/gea/shell.py +0 -0
  233. {gea_program-0.20.0 → gea_program-0.22.0}/gea/shut_in.py +0 -0
  234. {gea_program-0.20.0 → gea_program-0.22.0}/gea/sla_report.py +0 -0
  235. {gea_program-0.20.0 → gea_program-0.22.0}/gea/soak.py +0 -0
  236. {gea_program-0.20.0 → gea_program-0.22.0}/gea/sra.py +0 -0
  237. {gea_program-0.20.0 → gea_program-0.22.0}/gea/store_forward.py +0 -0
  238. {gea_program-0.20.0 → gea_program-0.22.0}/gea/strata_join.py +0 -0
  239. {gea_program-0.20.0 → gea_program-0.22.0}/gea/supervisor.py +0 -0
  240. {gea_program-0.20.0 → gea_program-0.22.0}/gea/survey_cmd.py +0 -0
  241. {gea_program-0.20.0 → gea_program-0.22.0}/gea/survey_view.py +0 -0
  242. {gea_program-0.20.0 → gea_program-0.22.0}/gea/telemetry.py +0 -0
  243. {gea_program-0.20.0 → gea_program-0.22.0}/gea/tool_library.py +0 -0
  244. {gea_program-0.20.0 → gea_program-0.22.0}/gea/transient.py +0 -0
  245. {gea_program-0.20.0 → gea_program-0.22.0}/gea/vibration.py +0 -0
  246. {gea_program-0.20.0 → gea_program-0.22.0}/gea/well_assembler.py +0 -0
  247. {gea_program-0.20.0 → gea_program-0.22.0}/gea/well_test_validation.py +0 -0
  248. {gea_program-0.20.0 → gea_program-0.22.0}/gea/wits0.py +0 -0
  249. {gea_program-0.20.0 → gea_program-0.22.0}/gea/witsml.py +0 -0
  250. {gea_program-0.20.0 → gea_program-0.22.0}/gea_program.egg-info/dependency_links.txt +0 -0
  251. {gea_program-0.20.0 → gea_program-0.22.0}/gea_program.egg-info/entry_points.txt +0 -0
  252. {gea_program-0.20.0 → gea_program-0.22.0}/gea_program.egg-info/requires.txt +0 -0
  253. {gea_program-0.20.0 → gea_program-0.22.0}/gea_program.egg-info/top_level.txt +0 -0
  254. {gea_program-0.20.0 → gea_program-0.22.0}/setup.cfg +0 -0
  255. {gea_program-0.20.0 → gea_program-0.22.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.20.0
3
+ Version: 0.22.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 (347 checks)
128
+ gea accept # the product gate (353 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,53 @@ 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 interval against the mapped tops
652
+
653
+ Where does the injection sit in the geology? The operator declares the
654
+ disposal interval - top and base, true vertical depth, and the reference
655
+ elevation the depths are measured from with what it is (kelly bushing, ground,
656
+ derrick floor) and where it came from: `gea workspace --action set-well --well
657
+ <id> --top-interval-ft 9850 --base-interval-ft 10400 --depth-ref TVD
658
+ --ref-elev-ft 2962 --ref-elev-datum KB --ref-elev-source "completion report"`
659
+ (`--elev-3dep` fetches the ground elevation from the USGS 3DEP point service
660
+ instead, stored with its raster and named as the ground). A contours layer is
661
+ told what it maps (`add-layer ... --formation-name Wolfcamp --role
662
+ top|isopach|base`). `--action interval --well <id>` then converts the interval
663
+ to subsea with the arithmetic printed and sets it beside each formation-top
664
+ bracket at the well: ABOVE the mapped top, BELOW it, or NOT RESOLVED where
665
+ the bracket overlaps the interval; a formation with a top and an isopach gets
666
+ a base bracket by arithmetic the report shows, and the declared depth tier
667
+ (shallow or deep by the base the SRA names) is CONSISTENT with the map,
668
+ INCONSISTENT, or NOT RESOLVED. The SRA packet's section 2c carries it and
669
+ section 2d sets the catalogue's events against the mapped faults - the
670
+ nearest trace to each epicentre, the counts within 1, 2 and 5 km, proximity
671
+ never called attribution. `gea help interval`.
672
+
673
+ ### Mapped structure
674
+
675
+ The first geological statement the program makes about a well. A structure
676
+ layer - a shapefile of mapped faults and folds, a public map (USGS, a state
677
+ survey, BEG/TexNet) or the operator's own - is read as the specification
678
+ lays the format out (`gea/shapefile.py`, no dependency: the .shp by its .shx
679
+ index, the .dbf attributes, the .prj coordinate system; geographic NAD83 or
680
+ WGS84 taken as is, the Texas State Plane NAD83 zones unprojected, anything
681
+ else refused by name) and kept in the workspace with every part hashed:
682
+ `gea workspace --action add-layer --name ... --layer structure.zip
683
+ --citation ...` (`--member <name>` names one shapefile in a zip holding
684
+ several; `gea structure --layer <zip> --list` lists them). Each layer is
685
+ kept by kind and read for what it is: faults and folds (`--action structure
686
+ --well <id>` prints the nearest mapped fault and the nearest fold by
687
+ distance along the ellipsoid and bearing, and what else the map holds within
688
+ the radius), formation-top contours (which two the position lies between,
689
+ read and not interpolated, or on one), basin and play polygons (which one
690
+ the position is inside), picked wells (the nearest picks with their values).
691
+ A position outside the layer's extent is OUTSIDE LAYER EXTENT, which is not
692
+ "no faults". Proven on the USGS PP 1708 Appalachian structure layer and the
693
+ EIA Permian Basin set. On the well page, in the SRA packet's
694
+ section 2b for every well inside the area, and from `gea structure --layer
695
+ <file> --lat --lon` for any position. A distance to a mapped trace is a fact
696
+ of the map at the map's scale, not a hazard judgement. `gea help structure`.
697
+
651
698
  ### WITSML 2.x over ETP
652
699
 
653
700
  The newer rigs and stores do not poll: Energistics ETP v1.2 is a WebSocket
@@ -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 (347 checks)
89
+ gea accept # the product gate (353 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,53 @@ 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 interval against the mapped tops
613
+
614
+ Where does the injection sit in the geology? The operator declares the
615
+ disposal interval - top and base, true vertical depth, and the reference
616
+ elevation the depths are measured from with what it is (kelly bushing, ground,
617
+ derrick floor) and where it came from: `gea workspace --action set-well --well
618
+ <id> --top-interval-ft 9850 --base-interval-ft 10400 --depth-ref TVD
619
+ --ref-elev-ft 2962 --ref-elev-datum KB --ref-elev-source "completion report"`
620
+ (`--elev-3dep` fetches the ground elevation from the USGS 3DEP point service
621
+ instead, stored with its raster and named as the ground). A contours layer is
622
+ told what it maps (`add-layer ... --formation-name Wolfcamp --role
623
+ top|isopach|base`). `--action interval --well <id>` then converts the interval
624
+ to subsea with the arithmetic printed and sets it beside each formation-top
625
+ bracket at the well: ABOVE the mapped top, BELOW it, or NOT RESOLVED where
626
+ the bracket overlaps the interval; a formation with a top and an isopach gets
627
+ a base bracket by arithmetic the report shows, and the declared depth tier
628
+ (shallow or deep by the base the SRA names) is CONSISTENT with the map,
629
+ INCONSISTENT, or NOT RESOLVED. The SRA packet's section 2c carries it and
630
+ section 2d sets the catalogue's events against the mapped faults - the
631
+ nearest trace to each epicentre, the counts within 1, 2 and 5 km, proximity
632
+ never called attribution. `gea help interval`.
633
+
634
+ ### Mapped structure
635
+
636
+ The first geological statement the program makes about a well. A structure
637
+ layer - a shapefile of mapped faults and folds, a public map (USGS, a state
638
+ survey, BEG/TexNet) or the operator's own - is read as the specification
639
+ lays the format out (`gea/shapefile.py`, no dependency: the .shp by its .shx
640
+ index, the .dbf attributes, the .prj coordinate system; geographic NAD83 or
641
+ WGS84 taken as is, the Texas State Plane NAD83 zones unprojected, anything
642
+ else refused by name) and kept in the workspace with every part hashed:
643
+ `gea workspace --action add-layer --name ... --layer structure.zip
644
+ --citation ...` (`--member <name>` names one shapefile in a zip holding
645
+ several; `gea structure --layer <zip> --list` lists them). Each layer is
646
+ kept by kind and read for what it is: faults and folds (`--action structure
647
+ --well <id>` prints the nearest mapped fault and the nearest fold by
648
+ distance along the ellipsoid and bearing, and what else the map holds within
649
+ the radius), formation-top contours (which two the position lies between,
650
+ read and not interpolated, or on one), basin and play polygons (which one
651
+ the position is inside), picked wells (the nearest picks with their values).
652
+ A position outside the layer's extent is OUTSIDE LAYER EXTENT, which is not
653
+ "no faults". Proven on the USGS PP 1708 Appalachian structure layer and the
654
+ EIA Permian Basin set. On the well page, in the SRA packet's
655
+ section 2b for every well inside the area, and from `gea structure --layer
656
+ <file> --lat --lon` for any position. A distance to a mapped trace is a fact
657
+ of the map at the map's scale, not a hazard judgement. `gea help structure`.
658
+
612
659
  ### WITSML 2.x over ETP
613
660
 
614
661
  The newer rigs and stores do not poll: Energistics ETP v1.2 is a WebSocket
@@ -123,7 +123,7 @@ from .profile_catalog import (
123
123
  read_pangaea_txt,
124
124
  )
125
125
 
126
- __version__ = "0.20.0"
126
+ __version__ = "0.22.0"
127
127
  __all__ = [
128
128
  "aging_rate", "rate_psi_yr", "accuracy_psi",
129
129
  "Sensor", "SimulatorConfig", "DownholeEngine",
@@ -285,7 +285,7 @@ def main(argv=None) -> int:
285
285
  "add-seismic", "refresh-seismic", "remove-seismic", "sar-film", "refresh-all", "add-track", "refresh-track", "remove-track",
286
286
  "seismic-dataset", "seismic-field", "add-site", "sites", "site-report", "remove-site", "rename",
287
287
  "set-well", "sra-define", "sra-report", "associate", "osdu-export", "quakeml-export", "well-identity", "vibration-report",
288
- "add-live-station", "live-fold", "live-run", "month-end"])
288
+ "add-live-station", "live-fold", "live-run", "month-end", "add-layer", "layers", "remove-layer", "structure", "interval"])
289
289
  p_ws.add_argument("--stations", type=str, nargs="+", default=None, help="add-track: two or more array station ids of this workspace")
290
290
  p_ws.add_argument("--site", type=str, default=None, help="site-report/remove-site: the site id")
291
291
  p_ws.add_argument("--api", type=str, default=None, help="set-well: the API number")
@@ -299,7 +299,7 @@ def main(argv=None) -> int:
299
299
  p_ws.add_argument("--channel-bhp", type=str, default=None, help="set-well: the downhole gauge channel (probe method)")
300
300
  p_ws.add_argument("--top-interval-ft", type=float, default=None, help="set-well: top of the disposal interval, ft (calculated method)")
301
301
  p_ws.add_argument("--gradient-psi-ft", type=float, default=None, help="set-well: fluid gradient, psi/ft (calculated method)")
302
- p_ws.add_argument("--radius-km", type=float, default=None, help="sra-define: the area's radius in km (Gardendale: 9.08)")
302
+ p_ws.add_argument("--radius-km", type=float, default=None, help="sra-define: the area's radius in km (Gardendale: 9.08); structure: how far around the well to look (default 50)")
303
303
  p_ws.add_argument("--plan-date", type=str, default=None, help="sra-define: the plan date, YYYY-MM-DD")
304
304
  p_ws.add_argument("--threshold-m", type=float, default=3.5, help="sra-define: the magnitude the plan is written against (3.5)")
305
305
  p_ws.add_argument("--goal-months", type=int, default=18, help="sra-define: months without a threshold event that meet the goal (18)")
@@ -359,6 +359,18 @@ def main(argv=None) -> int:
359
359
  p_ws.add_argument("--seedlink-config", type=str, default=None, help="add-live-station: the SeedLink config JSON (gea seedlink --write-example-config)")
360
360
  p_ws.add_argument("--include-open", action="store_true", help="live-fold: fold the current day's files too (they are still being written)")
361
361
  p_ws.add_argument("--seconds", type=float, default=None, help="live-run: how long to run (default: until Ctrl+C)")
362
+ p_ws.add_argument("--layer", type=str, default=None, help="add-layer: the shapefile (zip, folder or .shp); remove-layer: the layer id")
363
+ p_ws.add_argument("--member", type=str, default=None, help="add-layer: which shapefile inside a zip or folder that holds several (gea structure --layer <zip> --list)")
364
+ p_ws.add_argument("--citation", type=str, default="", help="add-layer: where the map came from, in the site's words")
365
+ p_ws.add_argument("--formation-name", type=str, default=None, help="add-layer: the formation a contours layer maps (Wolfcamp)")
366
+ p_ws.add_argument("--role", type=str, choices=["top", "isopach", "base"], default=None, help="add-layer: what the contours are of that formation: its top elevation, its thickness, or its base")
367
+ p_ws.add_argument("--base-interval-ft", type=float, default=None, help="set-well: base of the disposal interval, ft")
368
+ p_ws.add_argument("--depth-ref", type=str, choices=["TVD", "MD"], default=None, help="set-well: the interval depths are true vertical (TVD) or measured (MD) depth")
369
+ p_ws.add_argument("--ref-elev-ft", type=float, default=None, help="set-well: the reference elevation the depths are measured from, ft above sea level")
370
+ p_ws.add_argument("--ref-elev-datum", type=str, choices=["KB", "GL", "DF"], default=None, help="set-well: what that elevation is: kelly bushing, ground level, derrick floor")
371
+ p_ws.add_argument("--ref-elev-source", type=str, default=None, help="set-well: where the elevation came from (completion report, survey plat)")
372
+ p_ws.add_argument("--elev-3dep", action="store_true", help="set-well: fetch the GROUND elevation at the surface position from the USGS 3DEP point service and store it as the reference (datum GL, source stated)")
373
+ p_ws.add_argument("--epqs-url", type=str, default=None, help="set-well --elev-3dep / gea elevation: the EPQS endpoint (default the USGS one)")
362
374
  p_ws.add_argument("--period", type=str, default="previous", help="month-end: the month, YYYY-MM, or 'previous' (the last closed month)")
363
375
  p_ws.add_argument("--no-refresh", action="store_true", help="month-end: collect the reports as they stand without refreshing first")
364
376
  p_ws.add_argument("--name", type=str, default=None, help="init: site name; add-*: display name")
@@ -392,6 +404,18 @@ def main(argv=None) -> int:
392
404
  p_hk.add_argument("--actor", type=str, default="housekeeping")
393
405
  p_hk.add_argument("--json", action="store_true")
394
406
 
407
+ p_el = sub.add_parser("elevation", help="the ground elevation of a position from the USGS 3DEP point service: --lat --lon (the ground, NAVD88; not the kelly bushing)")
408
+ p_el.add_argument("--lat", type=float, required=True); p_el.add_argument("--lon", type=float, required=True)
409
+ p_el.add_argument("--url", type=str, default=None, help="the EPQS endpoint (default the USGS one)")
410
+ p_el.add_argument("--json", action="store_true")
411
+ p_st = sub.add_parser("structure", help="the nearest mapped fault and fold to a position, from a shapefile: --layer <zip|folder|.shp> --lat --lon; --info describes the layer")
412
+ p_st.add_argument("--layer", type=str, required=True)
413
+ p_st.add_argument("--lat", type=float, default=None); p_st.add_argument("--lon", type=float, default=None)
414
+ p_st.add_argument("--radius-km", type=float, default=50.0)
415
+ p_st.add_argument("--member", type=str, default=None, help="which shapefile inside a zip or folder that holds several")
416
+ p_st.add_argument("--list", action="store_true", help="list the shapefiles a zip or folder holds and exit")
417
+ p_st.add_argument("--info", action="store_true", help="describe the layer (coordinate system, extent, types, metadata) and exit")
418
+ p_st.add_argument("--json", action="store_true")
395
419
  p_sk = sub.add_parser("soak", help="the patches through link outages for hours, measured: N WITS0 patches, an ETP patch and a SeedLink station through relays that are cut on a schedule; the Soak Report")
396
420
  p_sk.add_argument("--hours", type=float, default=None, help="how long (72 for the go-live soak); or --seconds")
397
421
  p_sk.add_argument("--seconds", type=float, default=None)
@@ -928,6 +952,55 @@ def main(argv=None) -> int:
928
952
  for x in r['records_removed'][:20]:
929
953
  print(f" record {x['well_id']}/{x['file']} {x['age_days']} d")
930
954
  return 0
955
+ elif a.cmd == "elevation":
956
+ from .elevation import EPQS_URL, epqs
957
+ r = epqs(a.lat, a.lon, url=a.url or EPQS_URL)
958
+ if a.json:
959
+ print(json.dumps(r, indent=1)); return 0 if r["status"] == "OK" else 1
960
+ if r["status"] != "OK":
961
+ print(f"elevation: {r['status']} - {r.get('detail', '')}", file=sys.stderr); return 1
962
+ print(f"ground elevation at {a.lat}, {a.lon}: {r['elev_ft']:,.2f} ft ({r['vertical_datum']})")
963
+ print(f" source: {r['source']}")
964
+ return 0
965
+ elif a.cmd == "structure":
966
+ import json as _json
967
+ from . import shapefile as _SF
968
+ from . import structure as _ST
969
+ if a.list:
970
+ ms = _SF.members(a.layer)
971
+ print("\n".join(ms) if ms else f"no shapefile in {a.layer}")
972
+ return 0 if ms else 1
973
+ try:
974
+ L = _SF.read(a.layer, member=a.member)
975
+ except (ValueError, OSError) as e:
976
+ raise SystemExit(f"structure: {e}")
977
+ ta, na = _ST.guess_attrs(L)
978
+ kind = _ST.layer_kind(L)
979
+ if a.info or a.lat is None or a.lon is None:
980
+ md = L.source.get("metadata", {})
981
+ info = {"name": L.name, "kind": kind, "shape_type": L.shape_type, "crs": {k: v for k, v in L.crs.items() if k != "wkt"}, "bbox": list(L.bbox), "n_features": L.n,
982
+ "fields": L.fields, "type_attr": ta, "name_attr": na, "value_attr": _ST.guess_value_attr(L) if kind == "contours" else None,
983
+ "type_counts": dict(list(L.counts(ta).items())[:20]) if ta else {}, "metadata": md}
984
+ if a.json:
985
+ print(_json.dumps(info, indent=1))
986
+ else:
987
+ print(f"{L.name} ({kind}): {L.n} {L.shape_type} features; {L.crs['kind']} {L.crs.get('datum') or ''}; extent lon {L.bbox[0]:.3f}..{L.bbox[2]:.3f} lat {L.bbox[1]:.3f}..{L.bbox[3]:.3f}")
988
+ print(f" fields: {', '.join(f['name'] + ' (' + f['type'] + ')' for f in L.fields)}; type attribute {ta!r}, name attribute {na!r}")
989
+ for k, v in list(info["type_counts"].items())[:12]:
990
+ print(f" {v:7d} {k}")
991
+ if md.get("titles"):
992
+ print(f" source: {'; '.join(md['titles'][:2])}" + (f" ({md['pubdates'][0]})" if md.get("pubdates") else ""))
993
+ if a.lat is None or a.lon is None:
994
+ return 0
995
+ r = _ST.describe(L, a.lat, a.lon, a.radius_km, ta, na)
996
+ if a.json:
997
+ print(_json.dumps(r, indent=1, default=str))
998
+ else:
999
+ for line in _ST.lines(r):
1000
+ print(line)
1001
+ for h in r.get("within", [])[:10]:
1002
+ print(f" {h['distance_km']:8.2f} km {h['bearing_deg']:5.0f} deg {h['kind']:5s} {h['type']} {h['name']}")
1003
+ return 0 if r["status"] == "OK" else 1
931
1004
  elif a.cmd == "soak":
932
1005
  import json as _json
933
1006
  from .soak import run as _soak
@@ -1903,13 +1976,28 @@ def main(argv=None) -> int:
1903
1976
  elif a.action == "set-well":
1904
1977
  if not a.well:
1905
1978
  raise SystemExit("set-well needs --well <id>")
1906
- surface = {"lat": a.lat, "lon": a.lon, "datum": a.datum} if (a.lat is not None or a.lon is not None) else None
1979
+ surface = {"lat": a.lat, "lon": a.lon, "datum": a.datum} if (a.lat is not None or a.lon is not None) else {}
1980
+ if a.elev_3dep:
1981
+ from .elevation import EPQS_URL, as_reference, epqs
1982
+ w0 = ws.well(a.well)
1983
+ pos = {"lat": a.lat, "lon": a.lon} if a.lat is not None else (w0.get("surface") or {})
1984
+ if pos.get("lat") is None:
1985
+ raise SystemExit("--elev-3dep needs the surface position (give --lat --lon --datum, or declare it first)")
1986
+ r = epqs(float(pos["lat"]), float(pos["lon"]), url=a.epqs_url or EPQS_URL)
1987
+ if r["status"] != "OK":
1988
+ raise SystemExit(f"3DEP: {r['status']} - {r.get('detail', '')} ({r['url']})")
1989
+ surface["elevation"] = as_reference(r)
1990
+ print(f"3DEP ground elevation {r['elev_ft']:,.2f} ft ({r['source']})")
1991
+ elif a.ref_elev_ft is not None or a.ref_elev_datum or a.ref_elev_source:
1992
+ surface["elevation"] = {"ft": a.ref_elev_ft, "datum": a.ref_elev_datum, "source": a.ref_elev_source}
1907
1993
  disposal = {k: v for k, v in {"api_number": a.api, "uic_number": a.uic, "depth_tier": a.depth_tier, "formation_basis": a.formation,
1908
1994
  "channel_pressure": a.channel_pressure, "channel_rate": a.channel_rate, "rate_unit": a.rate_unit,
1909
1995
  "bhp_method": a.bhp_method, "channel_bhp": a.channel_bhp, "top_interval_ft": a.top_interval_ft,
1996
+ "base_interval_ft": a.base_interval_ft, "depth_reference": a.depth_ref,
1910
1997
  "gradient_psi_ft": a.gradient_psi_ft}.items() if v is not None}
1911
1998
  if not surface and not disposal:
1912
- raise SystemExit("set-well: nothing to declare (give --lat/--lon, or any of --api --uic --depth-tier --channel-pressure ...)")
1999
+ raise SystemExit("set-well: nothing to declare (give --lat/--lon, --ref-elev-ft, or any of --api --uic --depth-tier --top-interval-ft ...)")
2000
+ surface = surface or None
1913
2001
  w = ws.set_well(a.well, surface=surface, disposal=disposal or None, actor=a.actor)
1914
2002
  print(f"well {a.well}: surface {w.get('surface')}; disposal {w.get('disposal')}"); return 0
1915
2003
  elif a.action == "sra-define":
@@ -1968,6 +2056,46 @@ def main(argv=None) -> int:
1968
2056
  raise SystemExit("well-identity needs --well <id>")
1969
2057
  r = ws.well_identity(a.well)
1970
2058
  print(_ppdm_text(r)); return 0
2059
+ elif a.action == "add-layer":
2060
+ if not a.layer or not a.name:
2061
+ raise SystemExit("add-layer needs --name <display> and --layer <shapefile zip | folder | .shp>")
2062
+ L = ws.add_layer(a.layer, a.name, actor=a.actor, citation=a.citation, member=a.member, formation=a.formation_name, role=a.role)
2063
+ tc = ", ".join(f"{k} {v}" for k, v in list(L["type_counts"].items())[:6])
2064
+ print(f"layer {L['id']} ({L['kind']}): {L['n_features']} {L['shape_type']} features, {L['crs']['kind']} {L['crs'].get('datum') or ''}, extent lon {L['bbox'][0]:.3f}..{L['bbox'][2]:.3f} lat {L['bbox'][1]:.3f}..{L['bbox'][3]:.3f}"
2065
+ + (f"; contour value {L['value_attr']}" if L.get('value_attr') else ''))
2066
+ print(f" types: {tc}" + (" ..." if len(L["type_counts"]) > 6 else ""))
2067
+ md = L.get("metadata") or {}
2068
+ if md.get("titles"):
2069
+ print(f" source: {'; '.join(md['titles'][:2])}" + (f" ({md['pubdates'][0]})" if md.get("pubdates") else ""))
2070
+ return 0
2071
+ elif a.action == "layers":
2072
+ for L in ws.layers():
2073
+ print(f"{L['id']:28s} {L.get('kind', 'structure'):10s} {L['n_features']:7d} {L['shape_type']:9s} {L['crs']['kind']} {L['crs'].get('datum') or '':6s} {L['display']}")
2074
+ if not ws.layers():
2075
+ print("no structure layer - add one with --action add-layer --name ... --layer <shapefile zip>")
2076
+ return 0
2077
+ elif a.action == "remove-layer":
2078
+ if not a.layer:
2079
+ raise SystemExit("remove-layer needs --layer <id>")
2080
+ ws.remove_layer(a.layer, actor=a.actor); print(f"removed layer {a.layer} (folder kept, renamed)"); return 0
2081
+ elif a.action == "structure":
2082
+ if not a.well:
2083
+ raise SystemExit("structure needs --well <id>")
2084
+ r = ws.well_structure(a.well, a.radius_km if a.radius_km is not None else 50.0, actor=a.actor)
2085
+ print(f"structure {a.well}: {r['status']}" + (f" - {r['note']}" if r.get("note") else ""))
2086
+ for L in r["layers"]:
2087
+ print(f" [{L.get('layer_display') or L['layer']}]")
2088
+ for line in L["lines"]:
2089
+ print(" " + line)
2090
+ return 0 if r["status"] == "OK" else 1
2091
+ elif a.action == "interval":
2092
+ if not a.well:
2093
+ raise SystemExit("interval needs --well <id>")
2094
+ r = ws.well_interval(a.well, a.radius_km if a.radius_km is not None else 50.0, actor=a.actor)
2095
+ print(f"interval {a.well}: {r['status']}")
2096
+ for line in r["lines"]:
2097
+ print(" " + line)
2098
+ return 0 if r["status"] == "OK" else 1
1971
2099
  elif a.action == "month-end":
1972
2100
  from .month_end import report_text as _me_text
1973
2101
  r = ws.month_end(a.period, actor=a.actor, refresh=not a.no_refresh, catalog_csv=a.catalog)