gea-program 0.51.0__tar.gz → 0.52.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 (358) hide show
  1. {gea_program-0.51.0 → gea_program-0.52.0}/PKG-INFO +16 -1
  2. {gea_program-0.51.0 → gea_program-0.52.0}/README.md +15 -0
  3. {gea_program-0.51.0 → gea_program-0.52.0}/gea/__init__.py +1 -1
  4. {gea_program-0.51.0 → gea_program-0.52.0}/gea/__main__.py +53 -0
  5. {gea_program-0.51.0 → gea_program-0.52.0}/gea/acceptance_tests.py +189 -0
  6. {gea_program-0.51.0 → gea_program-0.52.0}/gea/dossier.py +14 -3
  7. gea_program-0.52.0/gea/help/pore-pressure.md +17 -0
  8. {gea_program-0.51.0 → gea_program-0.52.0}/gea/helplib.py +2 -1
  9. gea_program-0.52.0/gea/pore_pressure.py +682 -0
  10. gea_program-0.52.0/gea/reference/l0701_sonic_gr.las.gz +0 -0
  11. gea_program-0.52.0/gea/reference/l0701_sonic_gr.provenance.json +14 -0
  12. {gea_program-0.51.0 → gea_program-0.52.0}/gea/service.py +20 -0
  13. {gea_program-0.51.0 → gea_program-0.52.0}/gea/web/app.html +67 -1
  14. {gea_program-0.51.0 → gea_program-0.52.0}/gea_program.egg-info/PKG-INFO +16 -1
  15. {gea_program-0.51.0 → gea_program-0.52.0}/gea_program.egg-info/SOURCES.txt +4 -0
  16. {gea_program-0.51.0 → gea_program-0.52.0}/pyproject.toml +1 -1
  17. {gea_program-0.51.0 → gea_program-0.52.0}/LICENSE +0 -0
  18. {gea_program-0.51.0 → gea_program-0.52.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
  19. {gea_program-0.51.0 → gea_program-0.52.0}/gea/accuracy_statement.py +0 -0
  20. {gea_program-0.51.0 → gea_program-0.52.0}/gea/alarm_engine.py +0 -0
  21. {gea_program-0.51.0 → gea_program-0.52.0}/gea/alerts.py +0 -0
  22. {gea_program-0.51.0 → gea_program-0.52.0}/gea/backup.py +0 -0
  23. {gea_program-0.51.0 → gea_program-0.52.0}/gea/bench.py +0 -0
  24. {gea_program-0.51.0 → gea_program-0.52.0}/gea/blind_harness.py +0 -0
  25. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
  26. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
  27. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
  28. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
  29. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
  30. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
  31. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
  32. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
  33. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
  34. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
  35. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
  36. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
  37. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
  38. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
  39. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
  40. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
  41. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
  42. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
  43. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
  44. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
  45. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
  46. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
  47. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
  48. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
  49. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
  50. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
  51. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
  52. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
  53. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
  54. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
  55. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
  56. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
  57. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
  58. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
  59. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
  60. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
  61. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
  62. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
  63. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
  64. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
  65. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
  66. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
  67. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
  68. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
  69. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
  70. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
  71. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
  72. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
  73. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
  74. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
  75. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
  76. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
  77. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
  78. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
  79. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
  80. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
  81. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
  82. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
  83. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
  84. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
  85. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
  86. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
  87. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
  88. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
  89. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
  90. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
  91. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
  92. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/med_160_sapropels.txt +0 -0
  93. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
  94. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
  95. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
  96. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
  97. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
  98. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
  99. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
  100. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
  101. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
  102. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
  103. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
  104. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
  105. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
  106. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
  107. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
  108. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
  109. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
  110. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
  111. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
  112. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
  113. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
  114. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
  115. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
  116. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
  117. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
  118. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
  119. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
  120. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
  121. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
  122. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
  123. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
  124. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
  125. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
  126. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
  127. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
  128. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
  129. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog_map.py +0 -0
  130. {gea_program-0.51.0 → gea_program-0.52.0}/gea/catalog_register.py +0 -0
  131. {gea_program-0.51.0 → gea_program-0.52.0}/gea/certificates.py +0 -0
  132. {gea_program-0.51.0 → gea_program-0.52.0}/gea/cli.py +0 -0
  133. {gea_program-0.51.0 → gea_program-0.52.0}/gea/client_reports.py +0 -0
  134. {gea_program-0.51.0 → gea_program-0.52.0}/gea/collision.py +0 -0
  135. {gea_program-0.51.0 → gea_program-0.52.0}/gea/config_versioning.py +0 -0
  136. {gea_program-0.51.0 → gea_program-0.52.0}/gea/conformance.py +0 -0
  137. {gea_program-0.51.0 → gea_program-0.52.0}/gea/control_room.py +0 -0
  138. {gea_program-0.51.0 → gea_program-0.52.0}/gea/correlation.py +0 -0
  139. {gea_program-0.51.0 → gea_program-0.52.0}/gea/dashboard.py +0 -0
  140. {gea_program-0.51.0 → gea_program-0.52.0}/gea/declarations.py +0 -0
  141. {gea_program-0.51.0 → gea_program-0.52.0}/gea/deviation.py +0 -0
  142. {gea_program-0.51.0 → gea_program-0.52.0}/gea/dlis.py +0 -0
  143. {gea_program-0.51.0 → gea_program-0.52.0}/gea/dnp3.py +0 -0
  144. {gea_program-0.51.0 → gea_program-0.52.0}/gea/doctor.py +0 -0
  145. {gea_program-0.51.0 → gea_program-0.52.0}/gea/dossier_verify.py +0 -0
  146. {gea_program-0.51.0 → gea_program-0.52.0}/gea/downhole_engine.py +0 -0
  147. {gea_program-0.51.0 → gea_program-0.52.0}/gea/drift_monitor.py +0 -0
  148. {gea_program-0.51.0 → gea_program-0.52.0}/gea/drill_string.py +0 -0
  149. {gea_program-0.51.0 → gea_program-0.52.0}/gea/earth_model.py +0 -0
  150. {gea_program-0.51.0 → gea_program-0.52.0}/gea/economics.py +0 -0
  151. {gea_program-0.51.0 → gea_program-0.52.0}/gea/ed25519.py +0 -0
  152. {gea_program-0.51.0 → gea_program-0.52.0}/gea/edr.py +0 -0
  153. {gea_program-0.51.0 → gea_program-0.52.0}/gea/elevation.py +0 -0
  154. {gea_program-0.51.0 → gea_program-0.52.0}/gea/etp.py +0 -0
  155. {gea_program-0.51.0 → gea_program-0.52.0}/gea/etp12_schemas.json +0 -0
  156. {gea_program-0.51.0 → gea_program-0.52.0}/gea/example_register_map.json +0 -0
  157. {gea_program-0.51.0 → gea_program-0.52.0}/gea/fat_sat.py +0 -0
  158. {gea_program-0.51.0 → gea_program-0.52.0}/gea/files.py +0 -0
  159. {gea_program-0.51.0 → gea_program-0.52.0}/gea/fixtures/README.md +0 -0
  160. {gea_program-0.51.0 → gea_program-0.52.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
  161. {gea_program-0.51.0 → gea_program-0.52.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
  162. {gea_program-0.51.0 → gea_program-0.52.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
  163. {gea_program-0.51.0 → gea_program-0.52.0}/gea/fixtures/ne_110m_coastline.json +0 -0
  164. {gea_program-0.51.0 → gea_program-0.52.0}/gea/follower.py +0 -0
  165. {gea_program-0.51.0 → gea_program-0.52.0}/gea/forward_model.py +0 -0
  166. {gea_program-0.51.0 → gea_program-0.52.0}/gea/frac_hits.py +0 -0
  167. {gea_program-0.51.0 → gea_program-0.52.0}/gea/friction_priors.py +0 -0
  168. {gea_program-0.51.0 → gea_program-0.52.0}/gea/gamma.py +0 -0
  169. {gea_program-0.51.0 → gea_program-0.52.0}/gea/gauge_aging.py +0 -0
  170. {gea_program-0.51.0 → gea_program-0.52.0}/gea/gauge_specs.py +0 -0
  171. {gea_program-0.51.0 → gea_program-0.52.0}/gea/geodesy.py +0 -0
  172. {gea_program-0.51.0 → gea_program-0.52.0}/gea/geomag.py +0 -0
  173. {gea_program-0.51.0 → gea_program-0.52.0}/gea/gravity_reference.py +0 -0
  174. {gea_program-0.51.0 → gea_program-0.52.0}/gea/hartip.py +0 -0
  175. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/TESTER_GUIDE.md +0 -0
  176. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/alarms.md +0 -0
  177. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/alerts.md +0 -0
  178. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/audit-update.md +0 -0
  179. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/backup.md +0 -0
  180. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/catalog.md +0 -0
  181. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/charts.md +0 -0
  182. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/collision.md +0 -0
  183. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/conformance.md +0 -0
  184. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/control-room.md +0 -0
  185. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/data-in.md +0 -0
  186. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/declare.md +0 -0
  187. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/dlis.md +0 -0
  188. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/doctor.md +0 -0
  189. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/dossier.md +0 -0
  190. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/drift.md +0 -0
  191. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/drillstring.md +0 -0
  192. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/economics.md +0 -0
  193. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/edr.md +0 -0
  194. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/etp.md +0 -0
  195. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/field-ports.md +0 -0
  196. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/files.md +0 -0
  197. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/frac-hits.md +0 -0
  198. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/historian.md +0 -0
  199. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/instruments.md +0 -0
  200. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/interval.md +0 -0
  201. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/invoice-check.md +0 -0
  202. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/map.md +0 -0
  203. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/month-end.md +0 -0
  204. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/notifications.md +0 -0
  205. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/opseis.md +0 -0
  206. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/osdu.md +0 -0
  207. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/pad-summary.md +0 -0
  208. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/patches.md +0 -0
  209. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/penetrator.md +0 -0
  210. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/plan.md +0 -0
  211. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/ppdm.md +0 -0
  212. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/quakeml.md +0 -0
  213. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/quality.md +0 -0
  214. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/report-history.md +0 -0
  215. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/rig-time.md +0 -0
  216. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/seedlink.md +0 -0
  217. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/seismic.md +0 -0
  218. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/setup.md +0 -0
  219. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/simulation.md +0 -0
  220. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/site.md +0 -0
  221. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/sites.md +0 -0
  222. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/slip.md +0 -0
  223. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/soak.md +0 -0
  224. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/sra.md +0 -0
  225. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/start.md +0 -0
  226. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/structure.md +0 -0
  227. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/tools.md +0 -0
  228. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/transients.md +0 -0
  229. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/upkeep.md +0 -0
  230. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/vibration.md +0 -0
  231. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/well-report.md +0 -0
  232. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/well-tests.md +0 -0
  233. {gea_program-0.51.0 → gea_program-0.52.0}/gea/help/well3d.md +0 -0
  234. {gea_program-0.51.0 → gea_program-0.52.0}/gea/housekeeping.py +0 -0
  235. {gea_program-0.51.0 → gea_program-0.52.0}/gea/interval.py +0 -0
  236. {gea_program-0.51.0 → gea_program-0.52.0}/gea/inverse_engine.py +0 -0
  237. {gea_program-0.51.0 → gea_program-0.52.0}/gea/invoice_check.py +0 -0
  238. {gea_program-0.51.0 → gea_program-0.52.0}/gea/jobs.py +0 -0
  239. {gea_program-0.51.0 → gea_program-0.52.0}/gea/live_ports.py +0 -0
  240. {gea_program-0.51.0 → gea_program-0.52.0}/gea/loadtest.py +0 -0
  241. {gea_program-0.51.0 → gea_program-0.52.0}/gea/matplotlib_demo.py +0 -0
  242. {gea_program-0.51.0 → gea_program-0.52.0}/gea/modbus.py +0 -0
  243. {gea_program-0.51.0 → gea_program-0.52.0}/gea/modbus_rtu.py +0 -0
  244. {gea_program-0.51.0 → gea_program-0.52.0}/gea/model_card.py +0 -0
  245. {gea_program-0.51.0 → gea_program-0.52.0}/gea/month_end.py +0 -0
  246. {gea_program-0.51.0 → gea_program-0.52.0}/gea/mqtt_port.py +0 -0
  247. {gea_program-0.51.0 → gea_program-0.52.0}/gea/notify.py +0 -0
  248. {gea_program-0.51.0 → gea_program-0.52.0}/gea/op_seismicity.py +0 -0
  249. {gea_program-0.51.0 → gea_program-0.52.0}/gea/opcua_port.py +0 -0
  250. {gea_program-0.51.0 → gea_program-0.52.0}/gea/operator_app.py +0 -0
  251. {gea_program-0.51.0 → gea_program-0.52.0}/gea/osdu.py +0 -0
  252. {gea_program-0.51.0 → gea_program-0.52.0}/gea/pad_summary.py +0 -0
  253. {gea_program-0.51.0 → gea_program-0.52.0}/gea/patches.py +0 -0
  254. {gea_program-0.51.0 → gea_program-0.52.0}/gea/pdf_report.py +0 -0
  255. {gea_program-0.51.0 → gea_program-0.52.0}/gea/penetrator.py +0 -0
  256. {gea_program-0.51.0 → gea_program-0.52.0}/gea/permits.py +0 -0
  257. {gea_program-0.51.0 → gea_program-0.52.0}/gea/piwebapi.py +0 -0
  258. {gea_program-0.51.0 → gea_program-0.52.0}/gea/ports.py +0 -0
  259. {gea_program-0.51.0 → gea_program-0.52.0}/gea/ppdm.py +0 -0
  260. {gea_program-0.51.0 → gea_program-0.52.0}/gea/profile_catalog.py +0 -0
  261. {gea_program-0.51.0 → gea_program-0.52.0}/gea/project.py +0 -0
  262. {gea_program-0.51.0 → gea_program-0.52.0}/gea/qt6_downhole_app.py +0 -0
  263. {gea_program-0.51.0 → gea_program-0.52.0}/gea/quakeml.py +0 -0
  264. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reconciler.py +0 -0
  265. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
  266. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
  267. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/WMM2025.COF +0 -0
  268. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
  269. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/eia_prices.provenance.json +0 -0
  270. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
  271. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/iscwsa_rev4_example.json +0 -0
  272. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/iscwsa_rev5_example.json +0 -0
  273. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/libmseed_steim.provenance.json +0 -0
  274. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
  275. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
  276. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
  277. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/mahoning_example.json +0 -0
  278. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/mud_motor_specs.json +0 -0
  279. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/owsg_tool_models.json +0 -0
  280. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/penetrator_ratings.json +0 -0
  281. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/seismicity_protocols.json +0 -0
  282. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/tool_sources.json +0 -0
  283. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/us_outline.json +0 -0
  284. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/us_outline.provenance.json +0 -0
  285. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_3d.provenance.json +0 -0
  286. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
  287. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
  288. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
  289. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_surfaces.json.gz +0 -0
  290. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
  291. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
  292. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
  293. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
  294. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
  295. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
  296. {gea_program-0.51.0 → gea_program-0.52.0}/gea/reference/volve_well_picks.csv.gz +0 -0
  297. {gea_program-0.51.0 → gea_program-0.52.0}/gea/report_history.py +0 -0
  298. {gea_program-0.51.0 → gea_program-0.52.0}/gea/rig_state.py +0 -0
  299. {gea_program-0.51.0 → gea_program-0.52.0}/gea/rock_inventory.py +0 -0
  300. {gea_program-0.51.0 → gea_program-0.52.0}/gea/sample_record.py +0 -0
  301. {gea_program-0.51.0 → gea_program-0.52.0}/gea/sample_well_profile.csv +0 -0
  302. {gea_program-0.51.0 → gea_program-0.52.0}/gea/sbom.py +0 -0
  303. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seedlink.py +0 -0
  304. {gea_program-0.51.0 → gea_program-0.52.0}/gea/segy.py +0 -0
  305. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic.py +0 -0
  306. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_array.py +0 -0
  307. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_assoc.py +0 -0
  308. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_detect.py +0 -0
  309. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_film.py +0 -0
  310. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_harmonic.py +0 -0
  311. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_qc.py +0 -0
  312. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_response.py +0 -0
  313. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_signature.py +0 -0
  314. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_track.py +0 -0
  315. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_uncertainty.py +0 -0
  316. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_unlisted.py +0 -0
  317. {gea_program-0.51.0 → gea_program-0.52.0}/gea/seismic_watch.py +0 -0
  318. {gea_program-0.51.0 → gea_program-0.52.0}/gea/sensor_swap.py +0 -0
  319. {gea_program-0.51.0 → gea_program-0.52.0}/gea/series_cache.py +0 -0
  320. {gea_program-0.51.0 → gea_program-0.52.0}/gea/service_life.py +0 -0
  321. {gea_program-0.51.0 → gea_program-0.52.0}/gea/setup_checklist.py +0 -0
  322. {gea_program-0.51.0 → gea_program-0.52.0}/gea/shapefile.py +0 -0
  323. {gea_program-0.51.0 → gea_program-0.52.0}/gea/shell.py +0 -0
  324. {gea_program-0.51.0 → gea_program-0.52.0}/gea/shut_in.py +0 -0
  325. {gea_program-0.51.0 → gea_program-0.52.0}/gea/simulation.py +0 -0
  326. {gea_program-0.51.0 → gea_program-0.52.0}/gea/site_map.py +0 -0
  327. {gea_program-0.51.0 → gea_program-0.52.0}/gea/sla_report.py +0 -0
  328. {gea_program-0.51.0 → gea_program-0.52.0}/gea/slip.py +0 -0
  329. {gea_program-0.51.0 → gea_program-0.52.0}/gea/soak.py +0 -0
  330. {gea_program-0.51.0 → gea_program-0.52.0}/gea/sra.py +0 -0
  331. {gea_program-0.51.0 → gea_program-0.52.0}/gea/store_forward.py +0 -0
  332. {gea_program-0.51.0 → gea_program-0.52.0}/gea/strata_join.py +0 -0
  333. {gea_program-0.51.0 → gea_program-0.52.0}/gea/structure.py +0 -0
  334. {gea_program-0.51.0 → gea_program-0.52.0}/gea/supervisor.py +0 -0
  335. {gea_program-0.51.0 → gea_program-0.52.0}/gea/survey_cmd.py +0 -0
  336. {gea_program-0.51.0 → gea_program-0.52.0}/gea/survey_view.py +0 -0
  337. {gea_program-0.51.0 → gea_program-0.52.0}/gea/telemetry.py +0 -0
  338. {gea_program-0.51.0 → gea_program-0.52.0}/gea/tool_catalog.py +0 -0
  339. {gea_program-0.51.0 → gea_program-0.52.0}/gea/tool_library.py +0 -0
  340. {gea_program-0.51.0 → gea_program-0.52.0}/gea/tool_taxonomy.py +0 -0
  341. {gea_program-0.51.0 → gea_program-0.52.0}/gea/transient.py +0 -0
  342. {gea_program-0.51.0 → gea_program-0.52.0}/gea/vibration.py +0 -0
  343. {gea_program-0.51.0 → gea_program-0.52.0}/gea/well3d.py +0 -0
  344. {gea_program-0.51.0 → gea_program-0.52.0}/gea/well_assembler.py +0 -0
  345. {gea_program-0.51.0 → gea_program-0.52.0}/gea/well_report.py +0 -0
  346. {gea_program-0.51.0 → gea_program-0.52.0}/gea/well_test_validation.py +0 -0
  347. {gea_program-0.51.0 → gea_program-0.52.0}/gea/wellplan.py +0 -0
  348. {gea_program-0.51.0 → gea_program-0.52.0}/gea/wellpos.py +0 -0
  349. {gea_program-0.51.0 → gea_program-0.52.0}/gea/wits0.py +0 -0
  350. {gea_program-0.51.0 → gea_program-0.52.0}/gea/witsml.py +0 -0
  351. {gea_program-0.51.0 → gea_program-0.52.0}/gea/workspace.py +0 -0
  352. {gea_program-0.51.0 → gea_program-0.52.0}/gea/xlsx_read.py +0 -0
  353. {gea_program-0.51.0 → gea_program-0.52.0}/gea_program.egg-info/dependency_links.txt +0 -0
  354. {gea_program-0.51.0 → gea_program-0.52.0}/gea_program.egg-info/entry_points.txt +0 -0
  355. {gea_program-0.51.0 → gea_program-0.52.0}/gea_program.egg-info/requires.txt +0 -0
  356. {gea_program-0.51.0 → gea_program-0.52.0}/gea_program.egg-info/top_level.txt +0 -0
  357. {gea_program-0.51.0 → gea_program-0.52.0}/setup.cfg +0 -0
  358. {gea_program-0.51.0 → gea_program-0.52.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.51.0
3
+ Version: 0.52.0
4
4
  Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
5
5
  Author: Daniel T. Murphy
6
6
  License: MPL-2.0
@@ -648,6 +648,21 @@ 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
+ ### Pore pressure
652
+
653
+ The mud-weight window from a well's logs or its drilling record. The
654
+ overburden from the density log (or Gardner's density from the sonic); the
655
+ shale's normal compaction trend over an interval the operator declares
656
+ normally pressured; the pore pressure by Eaton's method from the sonic, the
657
+ deep resistivity or the corrected d-exponent computed from the drilling
658
+ record; the fracture gradient by Eaton's relation and the Hubbert-Willis
659
+ minimum - all as equivalent mud weights against true vertical depth, with
660
+ formation tests, kicks and leak-off tests beside them, the Eaton exponent
661
+ that fits the tests, and the mud weight used flagged where it falls outside
662
+ the window. The Dutch offshore well L07-01 (NLOG open data) is the worked
663
+ example. The **Pore pressure** tab, `gea pore-pressure`,
664
+ `gea help pore-pressure`.
665
+
651
666
  ### Frac hits
652
667
 
653
668
  What each fracturing stage did to the pressure in the wells around it. A
@@ -609,6 +609,21 @@ 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
+ ### Pore pressure
613
+
614
+ The mud-weight window from a well's logs or its drilling record. The
615
+ overburden from the density log (or Gardner's density from the sonic); the
616
+ shale's normal compaction trend over an interval the operator declares
617
+ normally pressured; the pore pressure by Eaton's method from the sonic, the
618
+ deep resistivity or the corrected d-exponent computed from the drilling
619
+ record; the fracture gradient by Eaton's relation and the Hubbert-Willis
620
+ minimum - all as equivalent mud weights against true vertical depth, with
621
+ formation tests, kicks and leak-off tests beside them, the Eaton exponent
622
+ that fits the tests, and the mud weight used flagged where it falls outside
623
+ the window. The Dutch offshore well L07-01 (NLOG open data) is the worked
624
+ example. The **Pore pressure** tab, `gea pore-pressure`,
625
+ `gea help pore-pressure`.
626
+
612
627
  ### Frac hits
613
628
 
614
629
  What each fracturing stage did to the pressure in the wells around it. A
@@ -123,7 +123,7 @@ from .profile_catalog import (
123
123
  read_pangaea_txt,
124
124
  )
125
125
 
126
- __version__ = "0.51.0"
126
+ __version__ = "0.52.0"
127
127
  __all__ = [
128
128
  "aging_rate", "rate_psi_yr", "accuracy_psi",
129
129
  "Sensor", "SimulatorConfig", "DownholeEngine",
@@ -622,6 +622,22 @@ def main(argv=None) -> int:
622
622
  p_pl.add_argument("--actor", type=str, default="cli")
623
623
  p_pl.add_argument("--json", action="store_true")
624
624
 
625
+ p_pp = sub.add_parser("pore-pressure", help="the mud-weight window: overburden, pore pressure by Eaton from the sonic, the resistivity or the d-exponent, and the fracture gradient")
626
+ p_pp.add_argument("--workspace", type=str, default=None)
627
+ p_pp.add_argument("--well", type=str, default=None)
628
+ p_pp.add_argument("--example", action="store_true", help="the worked example (L07-01, public data)")
629
+ p_pp.add_argument("--indicator", type=str, default=None, help="auto, sonic, resistivity or dexponent")
630
+ for k_, h_ in (("exponent", "Eaton's exponent"), ("nct-top", "top of the normally pressured interval, m TVD"), ("nct-bottom", "its bottom, m TVD"),
631
+ ("gr-cutoff", "the shale cut-off, gAPI"), ("normal-gradient", "the normal pore gradient, psi/ft"), ("poisson", "Poisson's ratio"),
632
+ ("density-above", "the mean density above the logs, g/cm3"), ("water-depth", "the water depth, m"), ("air-gap", "the air gap, m"),
633
+ ("bit", "the bit size for the d-exponent, in")):
634
+ p_pp.add_argument("--" + k_, type=str, default=None, help=h_)
635
+ p_pp.add_argument("--measure", type=str, default=None, help="add a measurement DEPTH_M,VALUE[,psi|ppg[,pore|kick|lot|fit[,tvd|md]]]")
636
+ p_pp.add_argument("--source", type=str, default="", help="where the values came from")
637
+ p_pp.add_argument("--write", action="store_true", help="write the report")
638
+ p_pp.add_argument("--actor", type=str, default="cli")
639
+ p_pp.add_argument("--json", action="store_true")
640
+
625
641
  p_fh = sub.add_parser("frac-hits", help="what each fracturing stage did to the pressure in the wells around it: none, poroelastic, mixed or a frac hit, the first response and the volume pumped by then")
626
642
  p_fh.add_argument("--workspace", type=str, required=True)
627
643
  p_fh.add_argument("--well", type=str, default=None, help="the treatment well (with --stages or --remove) or the monitored well (with --channel)")
@@ -2456,6 +2472,43 @@ def main(argv=None) -> int:
2456
2472
  raise SystemExit(f"collision: {e.args[0] if e.args else e}")
2457
2473
  print(_json.dumps({k: v for k, v in r.items()}, default=str) if a.json else _CO.text(r))
2458
2474
  return 0
2475
+ elif a.cmd == "pore-pressure":
2476
+ import json as _json
2477
+ from . import pore_pressure as _PPF
2478
+ from .cli import _safe_stdout
2479
+ from .workspace import Workspace, WorkspaceError
2480
+ _safe_stdout()
2481
+ try:
2482
+ ws = Workspace(a.workspace) if a.workspace else None
2483
+ scene = "example" if (a.example or ws is None) else "workspace"
2484
+ keys = {"exponent": a.exponent, "nct_top_m": a.nct_top, "nct_bottom_m": a.nct_bottom, "gr_cutoff": a.gr_cutoff,
2485
+ "normal_gradient_psi_ft": a.normal_gradient, "poisson": a.poisson, "density_above_gcc": a.density_above,
2486
+ "water_depth_m": a.water_depth, "air_gap_m": a.air_gap, "bit_in": a.bit, "indicator": a.indicator}
2487
+ if ws is not None and (any(v is not None for v in keys.values()) or a.measure):
2488
+ if not a.well:
2489
+ raise ValueError("--well is needed")
2490
+ if a.measure:
2491
+ p_ = [x.strip() for x in a.measure.split(",")]
2492
+ r_ = _PPF.add_measurement(ws, a.actor, a.well, p_[0], p_[1], p_[2] if len(p_) > 2 else "psi", p_[3] if len(p_) > 3 else "pore",
2493
+ p_[4] if len(p_) > 4 else "tvd", a.source)
2494
+ print(f"measurement kept for {a.well}: {r_['kind']} {r_['value']:g} {r_['unit']} at {r_['depth_m']:g} m {r_['depth_kind'].upper()}")
2495
+ return 0
2496
+ c_ = _PPF.set_well(ws, a.actor, a.well, a.source, **{k: v for k, v in keys.items() if v is not None})
2497
+ print(f"{a.well}: {c_['indicator']}, exponent {c_['exponent'] or 'Eaton'}, trend {c_['nct_top_m']} to {c_['nct_bottom_m']} m, normal {c_['normal_gradient_psi_ft']:g} psi/ft, Poisson {c_['poisson']:g}")
2498
+ return 0
2499
+ if a.write:
2500
+ if ws is None:
2501
+ raise ValueError("--write needs --workspace")
2502
+ r_ = _PPF.write_report(ws, __version__, a.well, a.actor, scene)
2503
+ print(f"wrote {r_['report_id']}: {r_['paths']['html']}")
2504
+ if r_['paths'].get('pdf'):
2505
+ print(f" printable: {r_['paths']['pdf']}")
2506
+ return 0
2507
+ r = _PPF.page(ws, scene, a.well)
2508
+ except (KeyError, ValueError, OSError, WorkspaceError) as e:
2509
+ raise SystemExit(f"pore-pressure: {e.args[0] if e.args else e}")
2510
+ print(_json.dumps(r, default=str) if a.json else _PPF.text(r))
2511
+ return 0
2459
2512
  elif a.cmd == "frac-hits":
2460
2513
  import json as _json
2461
2514
  from . import frac_hits as _FH
@@ -11717,6 +11717,194 @@ def section_ct_frac_hits(tmp: str) -> None:
11717
11717
  + (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
11718
11718
 
11719
11719
 
11720
+ def section_cu_pore_pressure(tmp: str) -> None:
11721
+ """Section CU - pore pressure and fracture gradient: the arithmetic (overburden, Gardner, Eaton, the d-exponent and
11722
+ its correction, Eaton's and Hubbert-Willis's fracture gradients) by hand; a depth log and a drilling record built so
11723
+ Eaton's method must return a known overpressure, read back by the sonic, the resistivity and the corrected
11724
+ d-exponent; measurements and the fitted exponent; the worked example; the API, the CLI, the report, the dossier,
11725
+ the tab and the help."""
11726
+ import gzip
11727
+ import hashlib as _hl
11728
+ import http.cookiejar
11729
+ import math as _m
11730
+ import subprocess as _sp
11731
+ import urllib.request
11732
+ import urllib.error
11733
+ import zipfile as _zf
11734
+ import numpy as _np
11735
+ from . import __version__ as _ver
11736
+ from . import dossier as DZ
11737
+ from . import helplib as H
11738
+ from . import pore_pressure as PPF
11739
+ from .workspace import Workspace
11740
+ from .service import Service, Users
11741
+ pkg = Path(__file__).parent
11742
+ d = Path(tmp, "porepressure"); d.mkdir()
11743
+
11744
+ # -- CU1 the arithmetic by hand ------------------------------------------------------------------------------------------
11745
+ dd = float(PPF.dexponent([30.0], [100.0], [20000.0], 8.5)[0])
11746
+ d_hand = _m.log10(30.0 / 6000.0) / _m.log10(12.0 * 20000.0 / 8.5e6)
11747
+ dc_ = float(PPF.dc([d_hand], 8.95, [10.0])[0])
11748
+ ob = PPF.overburden_psi(_np.array([1000.0, 2000.0]), _np.array([2.3, 2.3]), 0.0, 0.0, 1.03, 2.3)
11749
+ ob_sea = PPF.overburden_psi(_np.array([137.0, 1137.0]), _np.array([2.0, 2.0]), 100.0, 37.0, 1.03, 2.0)
11750
+ psi_hand = lambda rho, h: rho * 1000.0 * 9.80665 * h / 6894.757293168
11751
+ S_, Ph_ = 10000.0, 4650.0
11752
+ pp_s = float(PPF.eaton(S_, Ph_, 120.0, 100.0, 3.0, -1)) # sonic slower than its trend: overpressure
11753
+ pp_r = float(PPF.eaton(S_, Ph_, 0.8, 1.0, 1.2, 1)) # resistivity below its trend: overpressure
11754
+ c1 = {
11755
+ "dexp": abs(dd - d_hand) < 1e-12 and abs(d_hand - 1.48529) < 1e-4 and abs(dc_ - d_hand * 0.895) < 1e-12 and _np.isnan(PPF.dexponent([0.0], [100.0], [20000.0], 8.5)[0]),
11756
+ "overburden": abs(ob[0] - psi_hand(2.3, 1000.0)) < 1e-6 and abs(ob[1] - psi_hand(2.3, 2000.0)) < 1e-6
11757
+ and abs(ob_sea[0] - psi_hand(1.03, 100.0)) < 1e-6 and abs(ob_sea[1] - psi_hand(1.03, 100.0) - psi_hand(2.0, 1000.0)) < 1e-6,
11758
+ "gardner": abs(float(PPF.gardner(_np.array([100.0]))[0]) - 0.23 * 10000.0 ** 0.25) < 1e-12,
11759
+ "eaton": abs(pp_s - (S_ - (S_ - Ph_) * (100.0 / 120.0) ** 3)) < 1e-9 and pp_s > Ph_ and abs(pp_r - (S_ - (S_ - Ph_) * 0.8 ** 1.2)) < 1e-9
11760
+ and abs(float(PPF.eaton(S_, Ph_, 100.0, 100.0, 3.0, -1)) - Ph_) < 1e-9,
11761
+ "fracture": abs(float(PPF.eaton_fg(S_, 6000.0, 0.25)) - float(PPF.hubbert_willis(S_, 6000.0))) < 1e-9
11762
+ and abs(float(PPF.eaton_fg(S_, 6000.0, 0.4)) - (0.4 / 0.6 * 4000.0 + 6000.0)) < 1e-9,
11763
+ "ppg": abs(float(PPF.ppg(5200.0, 10000.0 * 0.3048)) - 10.0) < 1e-9,
11764
+ }
11765
+ failed1 = [k for k, v in c1.items() if not v]
11766
+ ok(not failed1,
11767
+ "CU1 the arithmetic by hand: Jorden and Shirley's d-exponent (1.4853 for 30 ft/h, 100 rpm, 20 klbf on an 8-1/2 in bit) and "
11768
+ "Rehm and McClendon's correction; the overburden of rock alone and of sea then rock below an air gap; Gardner's density; "
11769
+ "Eaton's ratio for the sonic and the resistivity, returning hydrostatic on the trend; Eaton's fracture gradient equal to "
11770
+ "Hubbert-Willis's at a Poisson's ratio of 0.25; an equivalent mud weight"
11771
+ + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
11772
+
11773
+ # -- CU2 the labelled log and drilling record --------------------------------------------------------------------------
11774
+ f = PPF.selftest_files(str(d))
11775
+ wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
11776
+ wl = ws.add_well_file(f["las"], display="LOG-1", actor="tester")["id"]
11777
+ we = ws.add_well_file(f["edr"], display="EDR-1", actor="tester")["id"]
11778
+
11779
+ def err_of(wid):
11780
+ x = PPF.page(ws, "workspace", wid)["result"]
11781
+ c = x["curves"]
11782
+ z = _np.array(c["tvd_m"], float)
11783
+ pp = _np.array([_np.nan if v is None else v for v in c["pp_psi"]], float)
11784
+ Pt = PPF.truth(z)[2]
11785
+ away = (_np.abs(z - 2200.0) > 10.0) & (_np.abs(z - 2600.0) > 10.0) & _np.isfinite(pp)
11786
+ return x, float(_np.max(_np.abs(pp[away] - Pt[away]) / Pt[away])), int(away.sum())
11787
+ PPF.set_well(ws, "tester", wl, "labelled log (test)", indicator="sonic", nct_top_m=600, nct_bottom_m=2100, smooth_m=5, density_above_gcc=2.3)
11788
+ xs, es, ns = err_of(wl)
11789
+ PPF.set_well(ws, "tester", wl, "labelled log (test)", indicator="resistivity")
11790
+ xr, er, nr = err_of(wl)
11791
+ no_bit = PPF.page(ws, "workspace", we)["detail"]
11792
+ PPF.set_well(ws, "tester", we, "labelled record (test)", bit_in=8.5, nct_top_m=1050, nct_bottom_m=2100, smooth_m=6, density_above_gcc=2.3)
11793
+ xd, ed, nd = err_of(we)
11794
+ c2 = {
11795
+ "sonic": es < 0.002 and ns > 300 and abs(xs["trend"]["a"] - 2.25) < 1e-4 and abs(xs["trend"]["b_per_m"] + 1.2e-4) < 1e-8
11796
+ and xs["overpressure_from_tvd_m"] is not None and abs(xs["overpressure_from_tvd_m"] - 2200.0) <= 5.0 and abs(xs["overburden_td_psi"] - float(PPF.truth(_np.array([3500.0]))[0][0])) < 1.0,
11797
+ "resistivity": er < 0.002 and nr > 300 and xr["indicator"] == "resistivity" and abs(xr["trend"]["b_per_m"] - 1.5e-4) < 1e-8,
11798
+ "dexponent": "bit size" in no_bit and ed < 0.002 and nd > 300 and xd["indicator"] == "dexponent" and "Mud Weight In" in xd["how"] and abs(xd["trend"]["b_per_m"] - 1.0e-4) < 2e-6,
11799
+ "mud_flag": any(fl["what"] == "the mud weight below the pore pressure" and abs(fl["from_tvd_m"] - 2200.0) < 6 and abs(fl["to_tvd_m"] - 2600.0) < 6 for fl in xd["flags"]),
11800
+ }
11801
+ failed2 = [k for k, v in c2.items() if not v]
11802
+ ok(not failed2,
11803
+ "CU2 a depth log and a drilling record built so that Eaton's method must find a pore pressure 40 % of the way from "
11804
+ "hydrostatic to the overburden between 2,200 and 2,600 m: read back by the sonic, the resistivity and the corrected "
11805
+ "d-exponent to within 0.2 % away from the zone's edges, the trends recovered as built, the overburden to the psi; the "
11806
+ "d-exponent refused without a bit size; the 9.5 ppg mud flagged below the pore pressure across the zone"
11807
+ + (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
11808
+
11809
+ # -- CU3 measurements, the fitted exponent, refusals and the worked example ----------------------------------------------
11810
+ PPF.set_well(ws, "tester", wl, "labelled log (test)", indicator="sonic")
11811
+ pt = float(PPF.truth(_np.array([2400.0]))[2][0])
11812
+ PPF.add_measurement(ws, "tester", wl, 2400.0, round(pt, 1), "psi", "pore", "tvd", "MDT (test)")
11813
+ PPF.add_measurement(ws, "tester", wl, 1500.0, 16.2, "ppg", "lot", "tvd", "LOT (test)")
11814
+ xm = PPF.page(ws, "workspace", wl)["result"]
11815
+ refused = 0
11816
+ for kw in ({"poisson": 0.6}, {"normal_gradient_psi_ft": 0.3}, {"nct_top_m": 2000, "nct_bottom_m": 1000}, {"indicator": "magic"}, {"exponent": 2.0}):
11817
+ try:
11818
+ PPF.set_well(ws, "tester", wl, "" if "exponent" in kw else "x", **kw)
11819
+ except ValueError:
11820
+ refused += 1
11821
+ for args in ((wl, -5, 100), (wl, 1000, 100, "bar"), (wl, 1000, 100, "psi", "dst"), (wl, 1000, 100, "psi", "pore", "tvd", "")):
11822
+ try:
11823
+ PPF.add_measurement(ws, "tester", args[0], args[1], args[2], *(args[3:5] or ()), **({"depth_kind": args[5], "source": args[6]} if len(args) > 6 else {"source": "s"}))
11824
+ except ValueError:
11825
+ refused += 1
11826
+ ex = PPF.example()
11827
+ raw = gzip.open(pkg / "reference" / "l0701_sonic_gr.las.gz").read()
11828
+ prov = json.loads((pkg / "reference" / "l0701_sonic_gr.provenance.json").read_text(encoding="utf-8"))
11829
+ c3 = {
11830
+ "measured": len(xm["measured"]) == 2 and abs(xm["measured"][0]["computed_psi"] - pt) < 0.005 * pt and xm["fit_exponent"] is not None and abs(xm["fit_exponent"] - 3.0) < 0.06
11831
+ and abs(xm["measured"][1]["psi"] - 16.2 * 0.052 * 1500.0 / 0.3048) < 0.1 and xm["measured"][1]["kind"] == "lot",
11832
+ "refused": refused == 9,
11833
+ "example": ex["indicator"] == "sonic" and ex["channel"] == "DT" and ex["trend"]["points"] > 5000 and 18.0 < ex["overburden_td_ppg"] < 21.0
11834
+ and "Gardner from the sonic" in ex["density_from"] and "density log" in ex["density_from"] and ex["max_pp_ppg"] is not None and "NLOG" in ex["attribution"],
11835
+ "provenance": _hl.sha256(raw).hexdigest() == prov["sha256_uncompressed"] and _hl.sha256((pkg / "reference" / "l0701_sonic_gr.las.gz").read_bytes()).hexdigest() == prov["sha256"],
11836
+ }
11837
+ failed3 = [k for k, v in c3.items() if not v]
11838
+ ok(not failed3,
11839
+ "CU3 a formation test drawn beside the curve it confirms (to half a percent) and the Eaton exponent fitted to it (3); a "
11840
+ "leak-off test in ppg turned to psi at its depth; a Poisson's ratio, a normal gradient, a trend interval or an indicator "
11841
+ "out of range, a value without its source, and a measurement without a depth, a unit, a kind or a source refused; the "
11842
+ "worked example L07-01 read from its sonic with the overburden from its density log and Gardner's, the file as hashed"
11843
+ + (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
11844
+
11845
+ # -- CU4 the API, the CLI, the report, the dossier, the tab and the help -------------------------------------------------
11846
+ Users(str(Path(wsp, "users.json"))).add("v", "viewer-pass-1", "viewer"); Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
11847
+ svc = Service(wsp, port=0, scheduler=False).start()
11848
+ base_url = svc.url.rstrip("/")
11849
+
11850
+ def opener(name, pw_):
11851
+ o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
11852
+ rq = urllib.request.Request(base_url + "/api/login", method="POST", data=json.dumps({"name": name, "password": pw_}).encode())
11853
+ rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1"); o.open(rq, timeout=30)
11854
+ return o
11855
+
11856
+ def call(o, method, path, body=None):
11857
+ rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
11858
+ if method == "POST":
11859
+ rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
11860
+ try:
11861
+ with o.open(rq, timeout=120) as rr_:
11862
+ return rr_.status, json.loads(rr_.read())
11863
+ except urllib.error.HTTPError as e:
11864
+ return e.code, json.loads(e.read())
11865
+ try:
11866
+ V, O = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
11867
+ s_vg, vg = call(V, "GET", "/api/pore-pressure?well=" + wl)
11868
+ s_ve, ve = call(V, "GET", "/api/pore-pressure?scene=example")
11869
+ s_vs, _ = call(V, "POST", "/api/pore-pressure/settings", {"well_id": wl, "poisson": 0.3, "source": "x"})
11870
+ s_os, os_ = call(O, "POST", "/api/pore-pressure/settings", {"well_id": wl, "poisson": "0.3", "source": "frac gradient study (test)"})
11871
+ s_ob, _ = call(O, "POST", "/api/pore-pressure/settings", {"well_id": wl, "poisson": 0.7, "source": "x"})
11872
+ s_om, _ = call(O, "POST", "/api/pore-pressure/measure", {"well_id": wl, "depth_m": 3000, "value": 9.0, "unit": "ppg", "kind": "kick", "source": "kick (test)"})
11873
+ s_bm, _ = call(O, "POST", "/api/pore-pressure/measure", {"well_id": wl, "depth_m": 3000, "value": 9.0, "unit": "ppg", "kind": "kick", "source": ""})
11874
+ s_ur, _ = call(O, "POST", "/api/pore-pressure/unmeasure", {"well_id": wl, "index": 2})
11875
+ s_u2, _ = call(O, "POST", "/api/pore-pressure/unmeasure", {"well_id": wl, "index": 9})
11876
+ s_vw, _ = call(V, "POST", "/api/pore-pressure/write", {"well_id": wl})
11877
+ s_ow, ow = call(O, "POST", "/api/pore-pressure/write", {"well_id": wl})
11878
+ finally:
11879
+ svc.stop()
11880
+ cli_x = _sp.run([sys.executable, "-m", "gea", "pore-pressure", "--example"], capture_output=True, text=True, cwd=str(pkg.parent))
11881
+ cli_s = _sp.run([sys.executable, "-m", "gea", "pore-pressure", "--workspace", wsp, "--well", wl, "--gr-cutoff", "90", "--source", "shale cut-off (test)"], capture_output=True, text=True, cwd=str(pkg.parent))
11882
+ cli_m = _sp.run([sys.executable, "-m", "gea", "pore-pressure", "--workspace", wsp, "--well", wl, "--measure", "2500,13.0,ppg,pore,tvd", "--source", "RFT (test)"], capture_output=True, text=True, cwd=str(pkg.parent))
11883
+ cli_t = _sp.run([sys.executable, "-m", "gea", "pore-pressure", "--workspace", wsp, "--well", wl], capture_output=True, text=True, cwd=str(pkg.parent))
11884
+ dz = DZ.build(ws, "tester", _ver, None)
11885
+ names = _zf.ZipFile(Path(ws.reports_dir, dz["path"])).namelist()
11886
+ audit = Path(ws.audit_path).read_text(encoding="utf-8")
11887
+ page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
11888
+ c4 = {
11889
+ "api": s_vg == 200 and vg["result"]["indicator"] == "sonic" and s_ve == 200 and ve["result"]["well"] == "L07-01" and s_vs == 403 and s_os == 200 and os_["poisson"] == 0.3
11890
+ and s_ob == 400 and s_om == 200 and s_bm == 400 and s_ur == 200 and s_u2 == 404 and s_vw == 403 and s_ow == 200 and ow["report_id"].startswith("PPF-"),
11891
+ "cli": cli_x.returncode == 0 and "L07-01" in cli_x.stdout and cli_s.returncode == 0 and cli_m.returncode == 0 and "pore 13 ppg at 2500 m TVD" in cli_m.stdout
11892
+ and cli_t.returncode == 0 and "gamma ray >= 90" in cli_t.stdout and "the exponent that fits" in cli_t.stdout,
11893
+ "report": PR_read_ok(Path(ws.reports_dir, "wells", wl, "pore_pressure.pdf"))
11894
+ and all(x in audit for x in ("pore_pressure.settings", "pore_pressure.measurement", "pore_pressure.measurement_removed", "report.pore_pressure")),
11895
+ "dossier": "declarations/geomech/pore_pressure.json" in names and f"results/pore_pressure/{wl}.json" in names and f"results/pore_pressure/{we}.json" in names,
11896
+ "page": all(x in page_src for x in ("VIEWS.porepressure", "['#/porepressure', 'Pore pressure']", "/api/pore-pressure/settings", "ppDepthPlot", "ppTrendPlot")),
11897
+ "help": not H.check("pore-pressure") and H.VIEW_TOPIC.get("porepressure") == "pore-pressure",
11898
+ }
11899
+ failed4 = [k for k, v in c4.items() if not v]
11900
+ ok(not failed4,
11901
+ "CU4 on the API (anyone reads a well's window and the worked example; only an operator declares how a well is read - a "
11902
+ "Poisson's ratio of 0.7 refused - adds or removes a measurement - one without its source refused - or writes the report), "
11903
+ "the CLI (the example, a cut-off, a measurement, the well), the report as PDF, a signed dossier carrying the declarations "
11904
+ "and each declared well's window, the tab and the help"
11905
+ + (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
11906
+
11907
+
11720
11908
  def PR_read_ok(path) -> bool:
11721
11909
  from . import pdf_report as PR
11722
11910
  try:
@@ -11826,6 +12014,7 @@ def main() -> int:
11826
12014
  section_cr_collision(tmp)
11827
12015
  section_cs_plan_and_tools(tmp)
11828
12016
  section_ct_frac_hits(tmp)
12017
+ section_cu_pore_pressure(tmp)
11829
12018
  if _FAILS:
11830
12019
  print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
11831
12020
  for f in _FAILS:
@@ -277,7 +277,7 @@ def _gather(ws, well_id: Optional[str]) -> Dict[str, List[tuple]]:
277
277
  ('seismicity', 'catalogs.json'), ('seismicity', 'settings.json'), ('config', 'fleet.json'), ('workspace.json',),
278
278
  ('economics', 'invoices', 'terms.json'), ('economics', 'invoices', 'files.json'), ('drillstring', 'rig_time.json'),
279
279
  ('drillstring', 'casing.json'), ('wellpath', 'collision.json'), ('wellpath', 'survey_program.json'),
280
- ('completion', 'frac', 'stages.json'), ('completion', 'frac', 'settings.json')):
280
+ ('completion', 'frac', 'stages.json'), ('completion', 'frac', 'settings.json'), ('geomech', 'pore_pressure.json')):
281
281
  p = os.path.join(ws.path, *rel)
282
282
  if os.path.isfile(p):
283
283
  out_list.append((p, 'declarations/' + '/'.join(rel)))
@@ -299,8 +299,8 @@ def _gather(ws, well_id: Optional[str]) -> Dict[str, List[tuple]]:
299
299
 
300
300
  def _results(ws, well_id: Optional[str]) -> List[tuple]:
301
301
  """The invoice cross-check of each well with invoices or reports attached, the rig time of each well with a drilling
302
- record, the collision check, each surveyed well against its plan and the frac-hit check, as JSON computed when the
303
- dossier is signed (a check that cannot run is left out, and says why)."""
302
+ record, the collision check, each surveyed well against its plan, each declared well's pore pressure and the
303
+ frac-hit check, as JSON computed when the dossier is signed (a check that cannot run is left out, and says why)."""
304
304
  out = []
305
305
  wells = [well_id] if well_id else [w['id'] for w in ws.wells()]
306
306
  try:
@@ -338,6 +338,17 @@ def _results(ws, well_id: Optional[str]) -> List[tuple]:
338
338
  indent=1, sort_keys=True, default=str).encode('utf-8')))
339
339
  except Exception as e:
340
340
  out.append(('results/collision_not_run.txt', f'the collision check did not run: {type(e).__name__}: {e}\n'.encode('utf-8')))
341
+ try:
342
+ from . import pore_pressure as PPF
343
+ declared = (PPF._load(ws).get('wells') or {})
344
+ for wid in wells:
345
+ if wid in declared:
346
+ r = PPF.page(ws, 'workspace', wid).get('result')
347
+ if r:
348
+ out.append((f'results/pore_pressure/{wid}.json', json.dumps({k: v for k, v in r.items() if k != 'points'}, indent=1, sort_keys=True,
349
+ default=str).encode('utf-8')))
350
+ except Exception as e:
351
+ out.append(('results/pore_pressure_not_run.txt', f'the pore-pressure reading did not run: {type(e).__name__}: {e}\n'.encode('utf-8')))
341
352
  try:
342
353
  from . import frac_hits as FH
343
354
  if FH.stages(ws):
@@ -0,0 +1,17 @@
1
+ # Pore pressure
2
+
3
+ > The mud-weight window from a well's logs or its drilling record: the overburden; the pore pressure by Eaton's method from the sonic, the deep resistivity or the corrected d-exponent against the shale's normal compaction trend; the fracture gradient by Eaton's relation and the Hubbert-Willis minimum; measured pressures and the mud weight used beside them. The Dutch offshore well L07-01 is the worked example.
4
+
5
+ **The command**: the **Pore pressure** tab: the pressures as equivalent mud weights against true vertical depth, with the hydrostatic, the overburden, the fracture gradients, the measurements and the mud; beside it the indicator against depth on a log scale, the shale points, the trend and the interval it was fitted over; how the well is read and its measurements (the operator role); **Write the report**. From a terminal: `gea pore-pressure --workspace C:\site --well W` prints it; `--example` the worked example; `--indicator sonic --nct-top 600 --nct-bottom 2100 --gr-cutoff 75 --normal-gradient 0.465 --poisson 0.25 --density-above 2.1 --water-depth 0 --air-gap 0 --bit 8.5 --source "drilling program"` declares how it is read; `--measure 2400,5337,psi,pore,tvd --source "MDT station 14"` adds a measurement (`lot` or `fit` for a leak-off or formation-integrity test, `ppg` for an equivalent weight, `md` for a measured depth); `--write` writes the report.
6
+
7
+ **What it reads**: a well whose record is a depth log (LAS) with a sonic (DT, AC), a deep resistivity (RDEP, ILD, RT) and a gamma ray, a bulk density where there is one; or a drilling record with hole depth, rate of penetration, rotary speed and weight on bit, from which the d-exponent is computed on the drilling samples (the median every 3 m of hole), corrected by the record's mud density when it has one - the bit size must be declared. True vertical depth comes from the well's survey, else the recorder's interpolated TVD, else the well is taken as vertical.
8
+
9
+ **How it is computed**: the overburden integrates the density - the sea below the air gap, then the rock: the density log, else Gardner's density from the sonic (0.23 V^0.25), else the declared mean density above the first value. The normal compaction trend is a straight line in the logarithm of the indicator against TVD, fitted to the shale (gamma ray at or above the cut-off; the 60th percentile when none is declared) over the interval the operator declares normally pressured. Eaton's ratio gives the pore pressure: Pp = S - (S - Ph) (X/Xn)^n, sonic exponent 3.0, resistivity and d-exponent 1.2. A step read below 90 % of hydrostatic is rock faster than the shale trend and is left blank. The fracture gradient is Eaton's F = nu/(1 - nu) (S - Pp) + Pp with the declared Poisson's ratio, beside the Hubbert-Willis minimum (S - Pp)/3 + Pp. Overpressure is read where the pore pressure stays half a ppg over hydrostatic for 50 m. With formation tests declared, the Eaton exponent that best fits them is given; with a mud weight in the record, a stretch where it is below the pore pressure or above the fracture gradient is flagged.
10
+
11
+ **What it writes**: how each well is read and its measurements in `geomech\pore_pressure.json` (audit lines `pore_pressure.settings`, `pore_pressure.measurement`, `pore_pressure.measurement_removed`), the audit line `report.pore_pressure`, and the reports `reports\wells\<well>\pore_pressure.*` (or `reports\pore_pressure_example.*`; PDF, HTML, markdown, JSON).
12
+
13
+ **The number to check**: the overburden at TD against the density log integrated by hand; a formation test's pressure against the curve at its depth; the trend's slope against the shale points on the right-hand plot.
14
+
15
+ **What this page will not call a measurement**: the pore pressure where nothing was measured - it is computed from a log against its trend, and the trend is the operator's choice of a normally pressured interval. The fracture gradient - a relation with a declared Poisson's ratio, not a leak-off test. The pressure in sand and carbonate - the method reads shale.
16
+
17
+ **Sources**: Eaton, "The equation for geopressure prediction from well logs", SPE-5544 (1975); Eaton, "Fracture gradient prediction and its application in oilfield operations", JPT 21(10) (1969); Gardner, Gardner and Gregory, Geophysics 39(6) (1974); Jorden and Shirley, SPE-1407 (1966); Rehm and McClendon, SPE-3601 (1971); Hubbert and Willis, Trans. AIME 210 (1957). The worked example: well L07-01, NLOG open data.
@@ -57,6 +57,7 @@ INDEX: List[tuple] = [
57
57
  ('collision', 'Well collision checks', "every well scanned against every other, planned wells along their plans: the closest approach and the ISCWSA separation factor, the travelling cylinder, each well's position uncertainty by its survey program's ISCWSA / OWSG tool models, the field by WMM2025; the Volve template as the worked example"),
58
58
  ('plan', 'Plan vs actual', "a well against its directional plan: the distance high or low and right or left at each survey against the survey's own uncertainty, the bit projected, the one arc back to the plan and its toolface; each well's survey program by tool model"),
59
59
  ('frac-hits', 'Frac hits', "what each fracturing stage did to the pressure in the wells around it - none, poroelastic, mixed or a frac hit - the first response and the fluid pumped by then, the distance and the earthquakes beside each stage"),
60
+ ('pore-pressure', 'Pore pressure', "the mud-weight window from a well's logs or its drilling record: the overburden, the pore pressure by Eaton from the sonic, the resistivity or the d-exponent against a normal compaction trend, the fracture gradient, against measured pressures and the mud used; L07-01 as the worked example"),
60
61
  ('rig-time', 'Rig time', "what the rig did each second of the drilling record - drilling, the slips, tripping, circulating - its connections timed weight to weight, its trips by speed, and the time lost against the pad's own best quarter"),
61
62
  ('invoice-check', 'The invoice cross-check', "the drilling contractor's daywork invoice, day by day, against the daily drilling reports and the drilling record at the contract's terms: hours, rates, standby, the repair allowance, depth and footage, with the dollars each difference puts in question"),
62
63
  ('economics', 'Economics', 'each well\'s days, footage and cost by the operator\'s own declared rates, against the EIA oil and gas spot prices while it was drilled, and any series the site imports'),
@@ -89,7 +90,7 @@ REQUIRED_LINES = ('**The command**', '**What it writes**', '**The number to chec
89
90
  VIEW_TOPIC: Dict[str, str] = {
90
91
  'home': 'start', 'wells': 'data-in', 'well': 'drift', 'live': 'patches', 'patch': 'patches', 'files': 'files', 'alarms': 'alarms',
91
92
  'approvals': 'well-tests', 'config': 'site', 'reports': 'drift', 'verify': 'start', 'survey': 'data-in', 'jobs': 'site',
92
- 'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'setup': 'setup', 'map': 'map', '3d': 'well3d', 'simulation': 'simulation', 'drillstring': 'drillstring', 'completion': 'penetrator', 'opseis': 'opseis', 'economics': 'economics', 'invoices': 'invoice-check', 'rigtime': 'rig-time', 'collision': 'collision', 'plan': 'plan', 'frac': 'frac-hits', 'control': 'control-room', 'wall': 'control-room', 'audit': 'audit-update', 'tools': 'tools', 'catalog': 'catalog',
93
+ 'admin': 'site', 'prefs': 'site', 'search': 'start', 'welcome': 'start', 'seismic': 'seismic', 'seismic_station': 'seismic', 'track': 'seismic', 'sar': 'seismic', 'sites': 'sites', 'setup': 'setup', 'map': 'map', '3d': 'well3d', 'simulation': 'simulation', 'drillstring': 'drillstring', 'completion': 'penetrator', 'opseis': 'opseis', 'economics': 'economics', 'invoices': 'invoice-check', 'rigtime': 'rig-time', 'collision': 'collision', 'plan': 'plan', 'frac': 'frac-hits', 'porepressure': 'pore-pressure', 'control': 'control-room', 'wall': 'control-room', 'audit': 'audit-update', 'tools': 'tools', 'catalog': 'catalog',
93
94
  }
94
95
 
95
96