gea-program 0.6.0__tar.gz → 0.8.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 (228) hide show
  1. {gea_program-0.6.0/gea_program.egg-info → gea_program-0.8.0}/PKG-INFO +164 -11
  2. {gea_program-0.6.0 → gea_program-0.8.0}/README.md +163 -10
  3. {gea_program-0.6.0 → gea_program-0.8.0}/gea/__init__.py +1 -1
  4. {gea_program-0.6.0 → gea_program-0.8.0}/gea/__main__.py +569 -11
  5. {gea_program-0.6.0 → gea_program-0.8.0}/gea/acceptance_tests.py +1325 -7
  6. {gea_program-0.6.0 → gea_program-0.8.0}/gea/cli.py +18 -12
  7. {gea_program-0.6.0 → gea_program-0.8.0}/gea/client_reports.py +469 -6
  8. {gea_program-0.6.0 → gea_program-0.8.0}/gea/doctor.py +134 -6
  9. gea_program-0.8.0/gea/geodesy.py +536 -0
  10. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/TESTER_GUIDE.md +1 -1
  11. gea_program-0.8.0/gea/help/audit-update.md +13 -0
  12. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/doctor.md +7 -0
  13. gea_program-0.8.0/gea/help/seismic.md +13 -0
  14. gea_program-0.8.0/gea/help/site.md +53 -0
  15. gea_program-0.8.0/gea/help/sites.md +13 -0
  16. {gea_program-0.6.0 → gea_program-0.8.0}/gea/helplib.py +3 -1
  17. {gea_program-0.6.0 → gea_program-0.8.0}/gea/jobs.py +11 -4
  18. {gea_program-0.6.0 → gea_program-0.8.0}/gea/operator_app.py +12 -3
  19. gea_program-0.8.0/gea/permits.py +296 -0
  20. {gea_program-0.6.0 → gea_program-0.8.0}/gea/seismic_array.py +23 -7
  21. {gea_program-0.6.0 → gea_program-0.8.0}/gea/seismic_detect.py +20 -6
  22. gea_program-0.8.0/gea/seismic_film.py +303 -0
  23. gea_program-0.8.0/gea/seismic_harmonic.py +889 -0
  24. gea_program-0.8.0/gea/seismic_qc.py +517 -0
  25. gea_program-0.8.0/gea/seismic_signature.py +557 -0
  26. gea_program-0.8.0/gea/seismic_track.py +470 -0
  27. gea_program-0.8.0/gea/seismic_uncertainty.py +294 -0
  28. gea_program-0.8.0/gea/seismic_unlisted.py +303 -0
  29. {gea_program-0.6.0 → gea_program-0.8.0}/gea/service.py +235 -10
  30. gea_program-0.8.0/gea/supervisor.py +256 -0
  31. {gea_program-0.6.0 → gea_program-0.8.0}/gea/web/app.html +370 -5
  32. gea_program-0.8.0/gea/workspace.py +1271 -0
  33. {gea_program-0.6.0 → gea_program-0.8.0/gea_program.egg-info}/PKG-INFO +164 -11
  34. {gea_program-0.6.0 → gea_program-0.8.0}/gea_program.egg-info/SOURCES.txt +12 -0
  35. {gea_program-0.6.0 → gea_program-0.8.0}/pyproject.toml +1 -1
  36. gea_program-0.6.0/gea/help/seismic.md +0 -13
  37. gea_program-0.6.0/gea/help/site.md +0 -15
  38. gea_program-0.6.0/gea/workspace.py +0 -547
  39. {gea_program-0.6.0 → gea_program-0.8.0}/LICENSE +0 -0
  40. {gea_program-0.6.0 → gea_program-0.8.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
  41. {gea_program-0.6.0 → gea_program-0.8.0}/gea/accuracy_statement.py +0 -0
  42. {gea_program-0.6.0 → gea_program-0.8.0}/gea/alarm_engine.py +0 -0
  43. {gea_program-0.6.0 → gea_program-0.8.0}/gea/bench.py +0 -0
  44. {gea_program-0.6.0 → gea_program-0.8.0}/gea/blind_harness.py +0 -0
  45. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
  46. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
  47. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
  48. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
  49. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
  50. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
  51. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
  52. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
  53. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
  54. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
  55. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
  56. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
  57. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
  58. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
  59. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
  60. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
  61. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
  62. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
  63. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
  64. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
  65. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
  66. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
  67. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
  68. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
  69. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
  70. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
  71. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
  72. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
  73. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
  74. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
  75. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
  76. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
  77. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
  78. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
  79. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
  80. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
  81. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
  82. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
  83. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
  84. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
  85. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
  86. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
  87. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
  88. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
  89. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
  90. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
  91. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
  92. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
  93. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
  94. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
  95. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
  96. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
  97. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
  98. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
  99. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
  100. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
  101. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
  102. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
  103. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
  104. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
  105. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
  106. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
  107. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
  108. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
  109. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
  110. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
  111. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
  112. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/med_160_sapropels.txt +0 -0
  113. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
  114. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
  115. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
  116. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
  117. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
  118. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
  119. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
  120. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
  121. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
  122. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
  123. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
  124. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
  125. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
  126. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
  127. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
  128. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
  129. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
  130. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
  131. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
  132. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
  133. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
  134. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
  135. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
  136. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
  137. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
  138. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
  139. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
  140. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
  141. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
  142. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
  143. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
  144. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
  145. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
  146. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
  147. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
  148. {gea_program-0.6.0 → gea_program-0.8.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
  149. {gea_program-0.6.0 → gea_program-0.8.0}/gea/certificates.py +0 -0
  150. {gea_program-0.6.0 → gea_program-0.8.0}/gea/config_versioning.py +0 -0
  151. {gea_program-0.6.0 → gea_program-0.8.0}/gea/correlation.py +0 -0
  152. {gea_program-0.6.0 → gea_program-0.8.0}/gea/dashboard.py +0 -0
  153. {gea_program-0.6.0 → gea_program-0.8.0}/gea/deviation.py +0 -0
  154. {gea_program-0.6.0 → gea_program-0.8.0}/gea/downhole_engine.py +0 -0
  155. {gea_program-0.6.0 → gea_program-0.8.0}/gea/drift_monitor.py +0 -0
  156. {gea_program-0.6.0 → gea_program-0.8.0}/gea/earth_model.py +0 -0
  157. {gea_program-0.6.0 → gea_program-0.8.0}/gea/example_register_map.json +0 -0
  158. {gea_program-0.6.0 → gea_program-0.8.0}/gea/fat_sat.py +0 -0
  159. {gea_program-0.6.0 → gea_program-0.8.0}/gea/files.py +0 -0
  160. {gea_program-0.6.0 → gea_program-0.8.0}/gea/follower.py +0 -0
  161. {gea_program-0.6.0 → gea_program-0.8.0}/gea/forward_model.py +0 -0
  162. {gea_program-0.6.0 → gea_program-0.8.0}/gea/gamma.py +0 -0
  163. {gea_program-0.6.0 → gea_program-0.8.0}/gea/gauge_aging.py +0 -0
  164. {gea_program-0.6.0 → gea_program-0.8.0}/gea/gauge_specs.py +0 -0
  165. {gea_program-0.6.0 → gea_program-0.8.0}/gea/gravity_reference.py +0 -0
  166. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/alarms.md +0 -0
  167. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/data-in.md +0 -0
  168. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/drift.md +0 -0
  169. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/files.md +0 -0
  170. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/instruments.md +0 -0
  171. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/notifications.md +0 -0
  172. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/patches.md +0 -0
  173. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/quality.md +0 -0
  174. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/start.md +0 -0
  175. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/transients.md +0 -0
  176. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/upkeep.md +0 -0
  177. {gea_program-0.6.0 → gea_program-0.8.0}/gea/help/well-tests.md +0 -0
  178. {gea_program-0.6.0 → gea_program-0.8.0}/gea/housekeeping.py +0 -0
  179. {gea_program-0.6.0 → gea_program-0.8.0}/gea/inverse_engine.py +0 -0
  180. {gea_program-0.6.0 → gea_program-0.8.0}/gea/live_ports.py +0 -0
  181. {gea_program-0.6.0 → gea_program-0.8.0}/gea/loadtest.py +0 -0
  182. {gea_program-0.6.0 → gea_program-0.8.0}/gea/matplotlib_demo.py +0 -0
  183. {gea_program-0.6.0 → gea_program-0.8.0}/gea/modbus.py +0 -0
  184. {gea_program-0.6.0 → gea_program-0.8.0}/gea/model_card.py +0 -0
  185. {gea_program-0.6.0 → gea_program-0.8.0}/gea/mqtt_port.py +0 -0
  186. {gea_program-0.6.0 → gea_program-0.8.0}/gea/notify.py +0 -0
  187. {gea_program-0.6.0 → gea_program-0.8.0}/gea/opcua_port.py +0 -0
  188. {gea_program-0.6.0 → gea_program-0.8.0}/gea/patches.py +0 -0
  189. {gea_program-0.6.0 → gea_program-0.8.0}/gea/ports.py +0 -0
  190. {gea_program-0.6.0 → gea_program-0.8.0}/gea/profile_catalog.py +0 -0
  191. {gea_program-0.6.0 → gea_program-0.8.0}/gea/project.py +0 -0
  192. {gea_program-0.6.0 → gea_program-0.8.0}/gea/qt6_downhole_app.py +0 -0
  193. {gea_program-0.6.0 → gea_program-0.8.0}/gea/reconciler.py +0 -0
  194. {gea_program-0.6.0 → gea_program-0.8.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
  195. {gea_program-0.6.0 → gea_program-0.8.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
  196. {gea_program-0.6.0 → gea_program-0.8.0}/gea/reference/libmseed_steim.provenance.json +0 -0
  197. {gea_program-0.6.0 → gea_program-0.8.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
  198. {gea_program-0.6.0 → gea_program-0.8.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
  199. {gea_program-0.6.0 → gea_program-0.8.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
  200. {gea_program-0.6.0 → gea_program-0.8.0}/gea/rock_inventory.py +0 -0
  201. {gea_program-0.6.0 → gea_program-0.8.0}/gea/sample_record.py +0 -0
  202. {gea_program-0.6.0 → gea_program-0.8.0}/gea/sample_well_profile.csv +0 -0
  203. {gea_program-0.6.0 → gea_program-0.8.0}/gea/sbom.py +0 -0
  204. {gea_program-0.6.0 → gea_program-0.8.0}/gea/segy.py +0 -0
  205. {gea_program-0.6.0 → gea_program-0.8.0}/gea/seismic.py +0 -0
  206. {gea_program-0.6.0 → gea_program-0.8.0}/gea/seismic_response.py +0 -0
  207. {gea_program-0.6.0 → gea_program-0.8.0}/gea/sensor_swap.py +0 -0
  208. {gea_program-0.6.0 → gea_program-0.8.0}/gea/service_life.py +0 -0
  209. {gea_program-0.6.0 → gea_program-0.8.0}/gea/shell.py +0 -0
  210. {gea_program-0.6.0 → gea_program-0.8.0}/gea/shut_in.py +0 -0
  211. {gea_program-0.6.0 → gea_program-0.8.0}/gea/sla_report.py +0 -0
  212. {gea_program-0.6.0 → gea_program-0.8.0}/gea/store_forward.py +0 -0
  213. {gea_program-0.6.0 → gea_program-0.8.0}/gea/strata_join.py +0 -0
  214. {gea_program-0.6.0 → gea_program-0.8.0}/gea/survey_cmd.py +0 -0
  215. {gea_program-0.6.0 → gea_program-0.8.0}/gea/survey_view.py +0 -0
  216. {gea_program-0.6.0 → gea_program-0.8.0}/gea/telemetry.py +0 -0
  217. {gea_program-0.6.0 → gea_program-0.8.0}/gea/tool_library.py +0 -0
  218. {gea_program-0.6.0 → gea_program-0.8.0}/gea/transient.py +0 -0
  219. {gea_program-0.6.0 → gea_program-0.8.0}/gea/well_assembler.py +0 -0
  220. {gea_program-0.6.0 → gea_program-0.8.0}/gea/well_test_validation.py +0 -0
  221. {gea_program-0.6.0 → gea_program-0.8.0}/gea/wits0.py +0 -0
  222. {gea_program-0.6.0 → gea_program-0.8.0}/gea/witsml.py +0 -0
  223. {gea_program-0.6.0 → gea_program-0.8.0}/gea_program.egg-info/dependency_links.txt +0 -0
  224. {gea_program-0.6.0 → gea_program-0.8.0}/gea_program.egg-info/entry_points.txt +0 -0
  225. {gea_program-0.6.0 → gea_program-0.8.0}/gea_program.egg-info/requires.txt +0 -0
  226. {gea_program-0.6.0 → gea_program-0.8.0}/gea_program.egg-info/top_level.txt +0 -0
  227. {gea_program-0.6.0 → gea_program-0.8.0}/setup.cfg +0 -0
  228. {gea_program-0.6.0 → gea_program-0.8.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.6.0
3
+ Version: 0.8.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
@@ -110,7 +110,10 @@ reaches a client document. Nothing unmeasured is ever reported as met.
110
110
  leg lives on the dashboard: a Seismic page where a station or an array is
111
111
  added by upload with its rigs list and station file, refreshed as a job,
112
112
  and read - spectrum, lines, verdicts, bearing - with its Seismic Station
113
- Report under Reports. See *The second leg*.
113
+ Report under Reports; and the SAR panel on that page, a control panel and a
114
+ screen that plays the leg's arithmetic forward in time on the labelled
115
+ synthetic scene (`seismic_film.py`), every frame stamped SIMULATION_SELF_TEST.
116
+ See *The second leg*.
114
117
 
115
118
  ## Quick start
116
119
 
@@ -122,8 +125,8 @@ gea dashboard --catalog-well volve_f12_f14_production_excerpt:15/9-F-12:10000 --
122
125
  gea client-report --report accuracy --out client_report
123
126
  gea model-cards --out model_cards
124
127
  gea sbom --out sbom
125
- gea accept # the product gate (258 checks)
126
- gea help drift # the help library, by the job (15 pages; the same text is on every dashboard page)
128
+ gea accept # the product gate (302 checks)
129
+ gea help drift # the help library, by the job (16 pages; the same text is on every dashboard page)
127
130
  gea guide # the click-by-click tester guide (docs/TESTER_GUIDE.md)
128
131
  gea gui # the desktop window (pip install "gea-program[desktop]")
129
132
  gea workspace --path C:\site --action init --name "Pad 3" # a site folder
@@ -149,12 +152,12 @@ site session is reproduced offline and how the mapping logic is tested.
149
152
  ```
150
153
  pip install "gea-program[live]" # asyncua, paho-mqtt, pymodbus, pyserial (or one extra at a time)
151
154
  gea wits0 --write-example-config wits0.json # drill floor: transport tcp | listen | serial; item codes -> tags, units
152
- gea wits0-sim --port 5001 # a WITS0 sender to rehearse with (no rig needed)
153
- gea wits0 --config wits0.json --seconds 60 --record floor/session.jsonl --out floor --stream-csv floor/stream.csv
155
+ gea wits0-sim --port 5001 # a WITS0 sender to rehearse with (no rig needed) - run it in a SECOND window and leave it running
156
+ gea wits0 --config wits0.json --seconds 60 --record floor/session.jsonl --out floor --stream-csv floor/stream.csv # in the first window, while the sender runs
154
157
  gea witsml --write-example-config witsml.json # a WITSML 1.4.1 store: url, uids, mnemonics -> tags; credentials by env name
155
- gea witsml --config witsml.json --seconds 60 --out store
158
+ gea witsml --config witsml.json --seconds 60 --out store # needs a real store: the example url is a placeholder until you edit it
156
159
  gea opcua --write-example-config opcua.json # edit: endpoint, security, credential env names, nodes
157
- gea opcua --config opcua.json --seconds 60 --record opc/session.jsonl --out opc --stream-csv opc/stream.csv
160
+ gea opcua --config opcua.json --seconds 60 --record opc/session.jsonl --out opc --stream-csv opc/stream.csv # needs a real OPC UA server, likewise
158
161
  gea mqtt --write-example-config mqtt.json # edit: broker, TLS, credential env names, topics
159
162
  gea mqtt --config mqtt.json --replay mq/session.jsonl --out mq_replay # no broker needed
160
163
  gea ingest --file floor/stream.csv # a stream CSV feeds the historian port like any other
@@ -251,10 +254,10 @@ text: JSON, JSON lines, CSV, Markdown, HTML.
251
254
 
252
255
  ### The help library
253
256
 
254
- `gea help` lists fifteen pages indexed by the job a reader arrives with -
257
+ `gea help` lists sixteen pages indexed by the job a reader arrives with -
255
258
  start, bring data in, quality rules, drift, well tests, alarms and the month,
256
259
  the site, instruments, shut-ins and build-ups, seismic (the second leg),
257
- patches, files, notifications, which code is running, upkeep. Each page carries four lines and stops: the
260
+ patches, files, notifications, which code is running, audit / update, upkeep. Each page carries four lines and stops: the
258
261
  command, what it writes, the one number to check, and what the page will not
259
262
  call a measurement. The pages ship inside the package (`gea/help/`), and the
260
263
  same text is what `/api/help` serves and what the dashboard shows under every
@@ -394,6 +397,155 @@ a rig not on the list, and any quantity in physical units until a station's
394
397
  response has been applied and named. `--action selftest` runs the test on a
395
398
  synthetic scene and labels its output SIMULATION_SELF_TEST.
396
399
 
400
+ The SAR panel at the foot of the Seismic page is the control panel and the
401
+ screen. "Run the scene" is `gea workspace --action sar-film` as a job: the
402
+ labelled synthetic array scene, one frame per window, written under
403
+ `reports/seismic/SIMULATION/`. The screen plays it - the trace, the
404
+ spectrogram column arriving, the beam power map on the slowness grid swinging
405
+ onto the working rig, the map with the bearing and the array's tolerance
406
+ wedge against the rigs where the scene put them, the tally per rig, and at
407
+ the end the array detectability test's verdict on the whole scene, the same
408
+ function a real record goes through. Every frame carries SIMULATION_SELF_TEST
409
+ and the line "not a measurement of any ground"; a real record is refreshed on
410
+ its station and the page shows what it earned, never a film. `gea seismic
411
+ --action sar-film --out film.json` writes the same film from the command line.
412
+
413
+ ### Tracks - the time dimension
414
+
415
+ The array step gives one bearing for one window. `seismic_track.py` runs it
416
+ window after window: a bearing history per array (a bearing with the array's
417
+ own tolerance where the beam was coherent, a gap where it was not, change
418
+ points where the bearing moved beyond the tolerance), a position history from
419
+ two or more arrays crossed window by window (a position only where two or
420
+ more arrays were coherent, the bearings crossed at 15 degrees or more and the
421
+ point lies in front of every array - every other window a gap with its
422
+ reason), and the track: the principal line through the longest continuous
423
+ segment of positions, with its heading, length and rate, the ellipses beside
424
+ every point, and segments listed apart where positions jump farther than
425
+ their ellipses allow (a coherent background crossing in a quiet hour is not
426
+ the rig an hour later). The verdict against ground truth - the lateral's
427
+ surveyed points or a permit's surface hole with its date, interpolated to
428
+ each position's time - is TRACKED, PARTIAL, NOT_TRACKED or INSUFFICIENT, with
429
+ the fraction and the heading difference printed. The labelled scene behind
430
+ `--action track-selftest` is a bit advancing along a straight lateral past
431
+ two arrays. On a site a track is two or more array stations and an optional
432
+ truth CSV, refreshed as a job into the Seismic Track Report; the track view
433
+ shows the map with every position's ellipse, a slider through time and the
434
+ bearings over time, and the SAR panel's second scene plays the same thing
435
+ forward with the track drawn as it is earned.
436
+
437
+ Ground truth from a permit export: `gea permits --file export.csv --out
438
+ rigs.csv --within LAT LON KM` finds the columns of a regulator's query (an
439
+ identifier, a surface position, a spud or approval date) by name, with a
440
+ mapping file when the guesses are wrong, and writes the rigs CSV the tests
441
+ read beside an import note that says which columns were used, how many rows
442
+ were dropped and why, and how many end dates it assumed (a permit rarely says
443
+ when drilling stopped). The Seismic page's add form takes a permit export in
444
+ place of the rigs CSV and keeps both.
445
+
446
+ ### Several rigs at once
447
+
448
+ One bearing is one direction for every machine in the band, so when two rigs
449
+ work together the crossing of whole-band bearings means nothing. That is the
450
+ wall between "a rig" and "a field", and `seismic_signature.py` is the step
451
+ through it. While a rig works alone, the bins that stand above the local
452
+ floor in its windows and not in the quiet ones are kept as its signature -
453
+ the same lines the detectability test already prints. In the windows where
454
+ several rigs work together, the cross-spectral matrix is sliced to one rig's
455
+ lines and beamed, which gives a bearing per rig in the same window; a
456
+ machinery line arriving as one plane wave is coherent in its own bin even
457
+ when the band as a whole is noise, which is why it works.
458
+
459
+ What it refuses is as much of the method as what it claims. A rig that never
460
+ worked alone has no signature and gets no bearing. Two rigs whose lines fall
461
+ within the spectral resolution of each other are NOT_SEPARABLE, both of them,
462
+ rather than handed a bearing each. A rig whose own lines all sit above the
463
+ array's spatial Nyquist is ALIASED: the measured beam has another peak within
464
+ a tenth of the height of the one found, the geometry cannot say which is the
465
+ source, and the peaks it cannot separate are listed instead of a direction.
466
+ Run through two arrays, every rig that both pointed at in the same window
467
+ gets its own positions, ellipses and track, and a track whose extent is
468
+ inside its own ellipses says `NOT_RESOLVED` instead of reporting the heading
469
+ of a scatter as a direction of travel. `gea seismic --action signatures |
470
+ multi-beam | multi-bearings | multi-track | signature-selftest |
471
+ field-selftest`; on a site, an array station with a rigs list learns the
472
+ signatures at every refresh and a track carries a track per rig beside the
473
+ whole-band one.
474
+
475
+ ### The machine behind the lines
476
+
477
+ A signature as a list of frequencies is a list of facts about bins. A pump at
478
+ 1.7 strokes per second is one fact about a machine, and it puts energy at
479
+ 1.7, 3.4, 5.1 and 8.5 Hz. `seismic_harmonic.py` searches every line divided
480
+ by every order for the comb that explains the most of them, normalises it to
481
+ the largest spacing the orders found allow - a comb of every second tooth is
482
+ that comb at twice the spacing, and the larger one claims less - and reports
483
+ the fundamental as a rate per minute. That is a far stronger claim than the
484
+ same lines listed separately, and the module says how strong: `by chance` is
485
+ how often this record's line density puts that many lines on a comb by
486
+ accident, and a family above the ceiling is set aside rather than reported.
487
+ Fewer than three lines is not a family, because any two lines define a comb;
488
+ two spacings that explain the same lines equally well are AMBIGUOUS; and a
489
+ fundamental whose half would fall below the analysed band is flagged, because
490
+ the machine may be running at half that rate with only its even harmonics in
491
+ view.
492
+
493
+ The other half is time. A pump's rate follows the work: a line at 1.40 Hz
494
+ walks to 1.85 Hz over a tour, no single bin stands above its floor in enough
495
+ windows, and the rig all but disappears from its own signature - which is the
496
+ defect this band exists to fix. Every line is followed window to window by
497
+ nearest neighbour within a drift ceiling, each peak refined inside its bin by
498
+ a parabola so a walk smaller than the bin width can be read, and each track
499
+ carries STEADY, DRIFTING or INTERMITTENT with its drift in Hz per hour. A
500
+ drift no larger than the bin width is not called a drift. The walk is also an
501
+ observable in its own right: `rate_history` reads the rate over the record,
502
+ and a rate that moves is the machine's load changing, not a different
503
+ machine.
504
+
505
+ Both halves meet in attribution. A track belongs to a source when it passes
506
+ within tolerance of a line that source was learned on - or when it stands in
507
+ a small whole-number ratio, in a window they share, to a track that source
508
+ already claims, which is how a harmonic the fixed bins missed comes back to
509
+ its machine wherever it has walked to. A line two sources could both claim is
510
+ given to neither. A line no listed source claims is listed as exactly that:
511
+ something is making it and the program was not told what.
512
+
513
+ And it closes the loop on ground truth. Every verdict in the leg rested on
514
+ the rigs CSV's working window - the detectability test, the array test and the
515
+ track all believed it. `activity_from_signature` measures it instead: the
516
+ fraction of a source's own lines standing above their floor, window by
517
+ window, each line looked for within a fraction of its own frequency of where
518
+ it was learned, because a harmonic walks as far as its order. The spells it
519
+ finds sit beside the declared ones with AGREES or DIFFERS and the counts both
520
+ ways. A permit date is a permission, not a drilling log, so a disagreement is
521
+ a finding and not an error - and which of the two is right is not decided
522
+ here.
523
+
524
+ `gea seismic --action harmonics | harmonic-selftest`; on a site every station
525
+ refresh does all of it - a single sensor as well as an array, using its own
526
+ detectability test's lines per source when there is no array to learn from,
527
+ so one geophone can still say when each rig was working - and the Seismic
528
+ Station Report and the station page carry the section, with the tracks drawn
529
+ against time.
530
+
531
+ ### Audit / Update
532
+
533
+ The Audit / Update tab holds three things. The whole audit log
534
+ (`records/audit.jsonl`) with filters by who, by action and since a date, and
535
+ a CSV download - Administration keeps the last hundred lines and points here.
536
+ The program card: the running version and code path, the newest release on
537
+ PyPI (`current`, `behind`, or `PyPI not reachable` when the machine is
538
+ offline), which extras are installed here, and links to PyPI, the releases
539
+ with the install kits, and the CHANGELOG; "Update the program from PyPI"
540
+ (admin) is `gea update` as a job - pip --upgrade from the same Python, after
541
+ which the service must be restarted; the program never restarts itself, and
542
+ an offline kit is updated by installing the newer kit. The data card: every
543
+ report against its source - `current` or `stale` when the source changed
544
+ after the report was written - and "Update every report from its source"
545
+ (operator), which is `gea workspace --action refresh-all` as a job: the
546
+ dashboard for every well, then every seismic station, errors collected and
547
+ listed, never hidden.
548
+
397
549
  ### Before a site goes live
398
550
 
399
551
  `deploy/README.md` is the checklist: keep the service on the loopback
@@ -446,7 +598,8 @@ docs/report_samples/ one rendered example of every client report, from this bui
446
598
  docs/ TESTER_GUIDE.md, REQUIREMENTS_MATRIX.md (the scope-of-work mirror that shaped the reports), examples/ (port configs),
447
599
  SESSION_LOG.md (the working record, session by session),
448
600
  commercial/ (pilot proposal, bench readiness, commercial use), HISTORY.md (the ship-by-ship record)
449
- tools/ standalone_check.py (the self-contained guard; run by ci and ship.ps1), build_installer.py (the kit)
601
+ tools/ standalone_check.py (the self-contained guard; run by ci and ship.ps1), build_installer.py (the kit),
602
+ render_report_samples.py (docs/report_samples), seismic_reader_check.py (the reader against libmseed)
450
603
  CHANGELOG.md per-release summary (a tag ships only with its section); SHIP_LOG.md is written by ship.ps1
451
604
  tests/ pytest wrapper around the acceptance suite and the standalone check
452
605
  ```
@@ -71,7 +71,10 @@ reaches a client document. Nothing unmeasured is ever reported as met.
71
71
  leg lives on the dashboard: a Seismic page where a station or an array is
72
72
  added by upload with its rigs list and station file, refreshed as a job,
73
73
  and read - spectrum, lines, verdicts, bearing - with its Seismic Station
74
- Report under Reports. See *The second leg*.
74
+ Report under Reports; and the SAR panel on that page, a control panel and a
75
+ screen that plays the leg's arithmetic forward in time on the labelled
76
+ synthetic scene (`seismic_film.py`), every frame stamped SIMULATION_SELF_TEST.
77
+ See *The second leg*.
75
78
 
76
79
  ## Quick start
77
80
 
@@ -83,8 +86,8 @@ gea dashboard --catalog-well volve_f12_f14_production_excerpt:15/9-F-12:10000 --
83
86
  gea client-report --report accuracy --out client_report
84
87
  gea model-cards --out model_cards
85
88
  gea sbom --out sbom
86
- gea accept # the product gate (258 checks)
87
- gea help drift # the help library, by the job (15 pages; the same text is on every dashboard page)
89
+ gea accept # the product gate (302 checks)
90
+ gea help drift # the help library, by the job (16 pages; the same text is on every dashboard page)
88
91
  gea guide # the click-by-click tester guide (docs/TESTER_GUIDE.md)
89
92
  gea gui # the desktop window (pip install "gea-program[desktop]")
90
93
  gea workspace --path C:\site --action init --name "Pad 3" # a site folder
@@ -110,12 +113,12 @@ site session is reproduced offline and how the mapping logic is tested.
110
113
  ```
111
114
  pip install "gea-program[live]" # asyncua, paho-mqtt, pymodbus, pyserial (or one extra at a time)
112
115
  gea wits0 --write-example-config wits0.json # drill floor: transport tcp | listen | serial; item codes -> tags, units
113
- gea wits0-sim --port 5001 # a WITS0 sender to rehearse with (no rig needed)
114
- gea wits0 --config wits0.json --seconds 60 --record floor/session.jsonl --out floor --stream-csv floor/stream.csv
116
+ gea wits0-sim --port 5001 # a WITS0 sender to rehearse with (no rig needed) - run it in a SECOND window and leave it running
117
+ gea wits0 --config wits0.json --seconds 60 --record floor/session.jsonl --out floor --stream-csv floor/stream.csv # in the first window, while the sender runs
115
118
  gea witsml --write-example-config witsml.json # a WITSML 1.4.1 store: url, uids, mnemonics -> tags; credentials by env name
116
- gea witsml --config witsml.json --seconds 60 --out store
119
+ gea witsml --config witsml.json --seconds 60 --out store # needs a real store: the example url is a placeholder until you edit it
117
120
  gea opcua --write-example-config opcua.json # edit: endpoint, security, credential env names, nodes
118
- gea opcua --config opcua.json --seconds 60 --record opc/session.jsonl --out opc --stream-csv opc/stream.csv
121
+ gea opcua --config opcua.json --seconds 60 --record opc/session.jsonl --out opc --stream-csv opc/stream.csv # needs a real OPC UA server, likewise
119
122
  gea mqtt --write-example-config mqtt.json # edit: broker, TLS, credential env names, topics
120
123
  gea mqtt --config mqtt.json --replay mq/session.jsonl --out mq_replay # no broker needed
121
124
  gea ingest --file floor/stream.csv # a stream CSV feeds the historian port like any other
@@ -212,10 +215,10 @@ text: JSON, JSON lines, CSV, Markdown, HTML.
212
215
 
213
216
  ### The help library
214
217
 
215
- `gea help` lists fifteen pages indexed by the job a reader arrives with -
218
+ `gea help` lists sixteen pages indexed by the job a reader arrives with -
216
219
  start, bring data in, quality rules, drift, well tests, alarms and the month,
217
220
  the site, instruments, shut-ins and build-ups, seismic (the second leg),
218
- patches, files, notifications, which code is running, upkeep. Each page carries four lines and stops: the
221
+ patches, files, notifications, which code is running, audit / update, upkeep. Each page carries four lines and stops: the
219
222
  command, what it writes, the one number to check, and what the page will not
220
223
  call a measurement. The pages ship inside the package (`gea/help/`), and the
221
224
  same text is what `/api/help` serves and what the dashboard shows under every
@@ -355,6 +358,155 @@ a rig not on the list, and any quantity in physical units until a station's
355
358
  response has been applied and named. `--action selftest` runs the test on a
356
359
  synthetic scene and labels its output SIMULATION_SELF_TEST.
357
360
 
361
+ The SAR panel at the foot of the Seismic page is the control panel and the
362
+ screen. "Run the scene" is `gea workspace --action sar-film` as a job: the
363
+ labelled synthetic array scene, one frame per window, written under
364
+ `reports/seismic/SIMULATION/`. The screen plays it - the trace, the
365
+ spectrogram column arriving, the beam power map on the slowness grid swinging
366
+ onto the working rig, the map with the bearing and the array's tolerance
367
+ wedge against the rigs where the scene put them, the tally per rig, and at
368
+ the end the array detectability test's verdict on the whole scene, the same
369
+ function a real record goes through. Every frame carries SIMULATION_SELF_TEST
370
+ and the line "not a measurement of any ground"; a real record is refreshed on
371
+ its station and the page shows what it earned, never a film. `gea seismic
372
+ --action sar-film --out film.json` writes the same film from the command line.
373
+
374
+ ### Tracks - the time dimension
375
+
376
+ The array step gives one bearing for one window. `seismic_track.py` runs it
377
+ window after window: a bearing history per array (a bearing with the array's
378
+ own tolerance where the beam was coherent, a gap where it was not, change
379
+ points where the bearing moved beyond the tolerance), a position history from
380
+ two or more arrays crossed window by window (a position only where two or
381
+ more arrays were coherent, the bearings crossed at 15 degrees or more and the
382
+ point lies in front of every array - every other window a gap with its
383
+ reason), and the track: the principal line through the longest continuous
384
+ segment of positions, with its heading, length and rate, the ellipses beside
385
+ every point, and segments listed apart where positions jump farther than
386
+ their ellipses allow (a coherent background crossing in a quiet hour is not
387
+ the rig an hour later). The verdict against ground truth - the lateral's
388
+ surveyed points or a permit's surface hole with its date, interpolated to
389
+ each position's time - is TRACKED, PARTIAL, NOT_TRACKED or INSUFFICIENT, with
390
+ the fraction and the heading difference printed. The labelled scene behind
391
+ `--action track-selftest` is a bit advancing along a straight lateral past
392
+ two arrays. On a site a track is two or more array stations and an optional
393
+ truth CSV, refreshed as a job into the Seismic Track Report; the track view
394
+ shows the map with every position's ellipse, a slider through time and the
395
+ bearings over time, and the SAR panel's second scene plays the same thing
396
+ forward with the track drawn as it is earned.
397
+
398
+ Ground truth from a permit export: `gea permits --file export.csv --out
399
+ rigs.csv --within LAT LON KM` finds the columns of a regulator's query (an
400
+ identifier, a surface position, a spud or approval date) by name, with a
401
+ mapping file when the guesses are wrong, and writes the rigs CSV the tests
402
+ read beside an import note that says which columns were used, how many rows
403
+ were dropped and why, and how many end dates it assumed (a permit rarely says
404
+ when drilling stopped). The Seismic page's add form takes a permit export in
405
+ place of the rigs CSV and keeps both.
406
+
407
+ ### Several rigs at once
408
+
409
+ One bearing is one direction for every machine in the band, so when two rigs
410
+ work together the crossing of whole-band bearings means nothing. That is the
411
+ wall between "a rig" and "a field", and `seismic_signature.py` is the step
412
+ through it. While a rig works alone, the bins that stand above the local
413
+ floor in its windows and not in the quiet ones are kept as its signature -
414
+ the same lines the detectability test already prints. In the windows where
415
+ several rigs work together, the cross-spectral matrix is sliced to one rig's
416
+ lines and beamed, which gives a bearing per rig in the same window; a
417
+ machinery line arriving as one plane wave is coherent in its own bin even
418
+ when the band as a whole is noise, which is why it works.
419
+
420
+ What it refuses is as much of the method as what it claims. A rig that never
421
+ worked alone has no signature and gets no bearing. Two rigs whose lines fall
422
+ within the spectral resolution of each other are NOT_SEPARABLE, both of them,
423
+ rather than handed a bearing each. A rig whose own lines all sit above the
424
+ array's spatial Nyquist is ALIASED: the measured beam has another peak within
425
+ a tenth of the height of the one found, the geometry cannot say which is the
426
+ source, and the peaks it cannot separate are listed instead of a direction.
427
+ Run through two arrays, every rig that both pointed at in the same window
428
+ gets its own positions, ellipses and track, and a track whose extent is
429
+ inside its own ellipses says `NOT_RESOLVED` instead of reporting the heading
430
+ of a scatter as a direction of travel. `gea seismic --action signatures |
431
+ multi-beam | multi-bearings | multi-track | signature-selftest |
432
+ field-selftest`; on a site, an array station with a rigs list learns the
433
+ signatures at every refresh and a track carries a track per rig beside the
434
+ whole-band one.
435
+
436
+ ### The machine behind the lines
437
+
438
+ A signature as a list of frequencies is a list of facts about bins. A pump at
439
+ 1.7 strokes per second is one fact about a machine, and it puts energy at
440
+ 1.7, 3.4, 5.1 and 8.5 Hz. `seismic_harmonic.py` searches every line divided
441
+ by every order for the comb that explains the most of them, normalises it to
442
+ the largest spacing the orders found allow - a comb of every second tooth is
443
+ that comb at twice the spacing, and the larger one claims less - and reports
444
+ the fundamental as a rate per minute. That is a far stronger claim than the
445
+ same lines listed separately, and the module says how strong: `by chance` is
446
+ how often this record's line density puts that many lines on a comb by
447
+ accident, and a family above the ceiling is set aside rather than reported.
448
+ Fewer than three lines is not a family, because any two lines define a comb;
449
+ two spacings that explain the same lines equally well are AMBIGUOUS; and a
450
+ fundamental whose half would fall below the analysed band is flagged, because
451
+ the machine may be running at half that rate with only its even harmonics in
452
+ view.
453
+
454
+ The other half is time. A pump's rate follows the work: a line at 1.40 Hz
455
+ walks to 1.85 Hz over a tour, no single bin stands above its floor in enough
456
+ windows, and the rig all but disappears from its own signature - which is the
457
+ defect this band exists to fix. Every line is followed window to window by
458
+ nearest neighbour within a drift ceiling, each peak refined inside its bin by
459
+ a parabola so a walk smaller than the bin width can be read, and each track
460
+ carries STEADY, DRIFTING or INTERMITTENT with its drift in Hz per hour. A
461
+ drift no larger than the bin width is not called a drift. The walk is also an
462
+ observable in its own right: `rate_history` reads the rate over the record,
463
+ and a rate that moves is the machine's load changing, not a different
464
+ machine.
465
+
466
+ Both halves meet in attribution. A track belongs to a source when it passes
467
+ within tolerance of a line that source was learned on - or when it stands in
468
+ a small whole-number ratio, in a window they share, to a track that source
469
+ already claims, which is how a harmonic the fixed bins missed comes back to
470
+ its machine wherever it has walked to. A line two sources could both claim is
471
+ given to neither. A line no listed source claims is listed as exactly that:
472
+ something is making it and the program was not told what.
473
+
474
+ And it closes the loop on ground truth. Every verdict in the leg rested on
475
+ the rigs CSV's working window - the detectability test, the array test and the
476
+ track all believed it. `activity_from_signature` measures it instead: the
477
+ fraction of a source's own lines standing above their floor, window by
478
+ window, each line looked for within a fraction of its own frequency of where
479
+ it was learned, because a harmonic walks as far as its order. The spells it
480
+ finds sit beside the declared ones with AGREES or DIFFERS and the counts both
481
+ ways. A permit date is a permission, not a drilling log, so a disagreement is
482
+ a finding and not an error - and which of the two is right is not decided
483
+ here.
484
+
485
+ `gea seismic --action harmonics | harmonic-selftest`; on a site every station
486
+ refresh does all of it - a single sensor as well as an array, using its own
487
+ detectability test's lines per source when there is no array to learn from,
488
+ so one geophone can still say when each rig was working - and the Seismic
489
+ Station Report and the station page carry the section, with the tracks drawn
490
+ against time.
491
+
492
+ ### Audit / Update
493
+
494
+ The Audit / Update tab holds three things. The whole audit log
495
+ (`records/audit.jsonl`) with filters by who, by action and since a date, and
496
+ a CSV download - Administration keeps the last hundred lines and points here.
497
+ The program card: the running version and code path, the newest release on
498
+ PyPI (`current`, `behind`, or `PyPI not reachable` when the machine is
499
+ offline), which extras are installed here, and links to PyPI, the releases
500
+ with the install kits, and the CHANGELOG; "Update the program from PyPI"
501
+ (admin) is `gea update` as a job - pip --upgrade from the same Python, after
502
+ which the service must be restarted; the program never restarts itself, and
503
+ an offline kit is updated by installing the newer kit. The data card: every
504
+ report against its source - `current` or `stale` when the source changed
505
+ after the report was written - and "Update every report from its source"
506
+ (operator), which is `gea workspace --action refresh-all` as a job: the
507
+ dashboard for every well, then every seismic station, errors collected and
508
+ listed, never hidden.
509
+
358
510
  ### Before a site goes live
359
511
 
360
512
  `deploy/README.md` is the checklist: keep the service on the loopback
@@ -407,7 +559,8 @@ docs/report_samples/ one rendered example of every client report, from this bui
407
559
  docs/ TESTER_GUIDE.md, REQUIREMENTS_MATRIX.md (the scope-of-work mirror that shaped the reports), examples/ (port configs),
408
560
  SESSION_LOG.md (the working record, session by session),
409
561
  commercial/ (pilot proposal, bench readiness, commercial use), HISTORY.md (the ship-by-ship record)
410
- tools/ standalone_check.py (the self-contained guard; run by ci and ship.ps1), build_installer.py (the kit)
562
+ tools/ standalone_check.py (the self-contained guard; run by ci and ship.ps1), build_installer.py (the kit),
563
+ render_report_samples.py (docs/report_samples), seismic_reader_check.py (the reader against libmseed)
411
564
  CHANGELOG.md per-release summary (a tag ships only with its section); SHIP_LOG.md is written by ship.ps1
412
565
  tests/ pytest wrapper around the acceptance suite and the standalone check
413
566
  ```
@@ -122,7 +122,7 @@ from .profile_catalog import (
122
122
  read_pangaea_txt,
123
123
  )
124
124
 
125
- __version__ = "0.6.0"
125
+ __version__ = "0.8.0"
126
126
  __all__ = [
127
127
  "aging_rate", "rate_psi_yr", "accuracy_psi",
128
128
  "Sensor", "SimulatorConfig", "DownholeEngine",