Skip to content

Commit 8a5d3b4

Browse files
authored
Merge pull request #246 from markspec/245-trace-density-error
Add QC for SEG-Y ingestion based on trace density.
2 parents 21451a8 + 21fb2d8 commit 8a5d3b4

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

src/mdio/converters/segy.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
from __future__ import annotations
55

6+
import logging
67
from datetime import datetime
78
from datetime import timezone
89
from importlib import metadata
@@ -25,6 +26,8 @@
2526
from mdio.segy.utilities import get_grid_plan
2627

2728

29+
logger = logging.getLogger(__name__)
30+
2831
try:
2932
API_VERSION = metadata.version("multidimio")
3033
except metadata.PackageNotFoundError:
@@ -52,6 +55,50 @@ def parse_index_types(
5255
return parsed_types
5356

5457

58+
def grid_density_qc(grid: Grid, num_traces: int) -> None:
59+
"""QC for sensible Grid density.
60+
61+
Basic qc of the grid to check density and provide warning/exception
62+
when indexing is problematic to provide user with insights to the use.
63+
If trace density on the specified grid is less than 50% a warning is
64+
logged. If denisty is less than 1% an exception is raised.
65+
66+
Args:
67+
grid: The grid instance to check.
68+
num_traces: Expected number of traces.
69+
70+
Raises:
71+
GridTraceCountError: When the grid is too sparse.
72+
"""
73+
grid_traces = np.prod(grid.shape[:-1], dtype=np.uint64) # Exclude sample
74+
dims = {k: v for k, v in zip(grid.dim_names, grid.shape)} # noqa: B905
75+
76+
logger.debug(f"Dimensions: {dims}")
77+
logger.debug(f"num_traces = {num_traces}")
78+
79+
# Extreme case where the grid is very sparse (usually user error)
80+
if grid_traces > 10 * num_traces:
81+
for dim_name in grid.dim_names:
82+
dim_min = grid.get_min(dim_name)
83+
dim_max = grid.get_max(dim_name)
84+
logger.warning(f"{dim_name} min: {dim_min} max: {dim_max}")
85+
86+
msg = (
87+
f"Grid shape: {grid.shape} but SEG-Y tracecount: {num_traces}. "
88+
"This grid is very sparse and most likely user error with indexing."
89+
)
90+
raise GridTraceCountError(msg)
91+
92+
# Warning if we have above 50% sparsity.
93+
if grid_traces > 2 * num_traces:
94+
msg = (
95+
f"Proposed ingestion grid is sparse. Ingestion grid: {dims}. "
96+
f"SEG-Y trace count:{num_traces}, grid trace count: {grid_traces}."
97+
)
98+
99+
logger.warning(msg)
100+
101+
55102
def segy_to_mdio(
56103
segy_path: str,
57104
mdio_path_or_buffer: str,
@@ -262,6 +309,9 @@ def segy_to_mdio(
262309

263310
# Make grid and build global live trace mask
264311
grid = Grid(dims=dimensions)
312+
313+
grid_density_qc(grid, num_traces)
314+
265315
grid.build_map(index_headers)
266316

267317
# Check grid validity by comparing trace numbers

0 commit comments

Comments
 (0)