2222from mdio .segy .checksum import is_checksum_available
2323from mdio .segy .checksum import should_calculate_checksum
2424
25+ from mdio .segy ._workers import header_scan_worker
26+
2527if TYPE_CHECKING :
2628 from segy .arrays import HeaderArray
2729
2830 from mdio .segy .file import SegyFileArguments
2931
3032default_cpus = cpu_count (logical = True )
3133
32-
33- def parse_headers ( # noqa: PLR0913
34+ def parse_headers (
3435 segy_file_kwargs : SegyFileArguments ,
3536 num_traces : int ,
3637 subset : list [str ] | None = None ,
3738 block_size : int = 10000 ,
3839 progress_bar : bool = True ,
39- calculate_checksum : bool = True ,
40- ) -> HeaderArray | tuple [HeaderArray , int ]:
40+ ) -> HeaderArray :
4141 """Read and parse given `byte_locations` from SEG-Y file.
4242
4343 Args:
@@ -46,47 +46,11 @@ def parse_headers( # noqa: PLR0913
4646 subset: List of header names to filter and keep.
4747 block_size: Number of traces to read for each block.
4848 progress_bar: Enable or disable progress bar. Default is True.
49- calculate_checksum: If True, also calculate CRC32C checksum for all trace data.
5049
5150 Returns:
52- HeaderArray if calculate_checksum is False.
53- Tuple of (HeaderArray, combined_crc32c) if calculate_checksum is True .
51+ HeaderArray. Keys are the index names, values are numpy arrays of parsed headers for the
52+ current block. Array is of type byte_type except IBM32 which is mapped to FLOAT32 .
5453 """
55- # Dynamically import the appropriate header_scan_worker based on checksum requirement
56- if should_calculate_checksum () and is_checksum_available ():
57- from mdio .segy .checksum import header_scan_worker
58- else :
59- from mdio .segy ._workers import header_scan_worker
60-
61- # Type hint for the dynamically imported function
62- header_scan_worker : Any
63- # Initialize combiner only if checksum calculation is needed and available
64- combiner : Any = None
65- if calculate_checksum :
66- if not is_checksum_available ():
67- # Checksum was requested but libraries not available - disable it
68- calculate_checksum = False
69- else :
70- # Use UPath for cloud/filesystem agnostic reading
71- path = UPath (segy_file_kwargs ["url" ])
72- raw_bytes = path .fs .read_block (
73- fn = str (path ),
74- offset = 0 ,
75- length = 3600 ,
76- )
77-
78- # Calculate trace size to determine total data length
79- # We need to open the file briefly to get the spec
80- sf = SegyFile (** segy_file_kwargs )
81- trace_header_size = sf .spec .trace .header .itemsize
82- sample_size = 4 # This will always be a 4-byte float
83- num_samples = len (sf .sample_labels )
84- trace_size = trace_header_size + (num_samples * sample_size )
85-
86- # Total length is header (3600) + trace data
87- total_len = 3600 + num_traces * trace_size
88- combiner = create_distributed_crc32c (raw_bytes , total_len )
89-
9054 trace_count = num_traces
9155 n_blocks = int (ceil (trace_count / block_size ))
9256
@@ -105,85 +69,18 @@ def parse_headers( # noqa: PLR0913
10569 # 'fork' to avoid deadlocks on cloud stores. Slower but necessary. Default on Windows.
10670 context = mp .get_context ("spawn" )
10771 with ProcessPoolExecutor (num_workers , mp_context = context ) as executor :
108- lazy_work = executor .map (
109- header_scan_worker ,
110- repeat (segy_file_kwargs ),
111- trace_ranges ,
112- repeat (subset ),
113- )
72+ lazy_work = executor .map (header_scan_worker , repeat (segy_file_kwargs ), trace_ranges , repeat (subset ))
11473
11574 if progress_bar is True :
116- desc = (
117- "Scanning SEG-Y & calculating checksum"
118- if calculate_checksum
119- else "Scanning SEG-Y for geometry attributes"
120- )
12175 lazy_work = tqdm (
12276 iterable = lazy_work ,
12377 total = n_blocks ,
124- desc = desc ,
78+ desc = "Scanning SEG-Y for geometry attributes" ,
12579 ** tqdm_kw ,
12680 )
12781
12882 # This executes the lazy work.
129- results = list (lazy_work )
130-
131- if not calculate_checksum :
132- # Merge headers and return
133- return np .concatenate (results )
134-
135- return finalize_distributed_checksum (results , combiner )
136-
137- # def _parse_headers(
138- # segy_file_kwargs: SegyFileArguments,
139- # num_traces: int,
140- # subset: list[str] | None = None,
141- # block_size: int = 10000,
142- # progress_bar: bool = True,
143- # ) -> HeaderArray:
144- # """Read and parse given `byte_locations` from SEG-Y file.
145-
146- # Args:
147- # segy_file_kwargs: SEG-Y file arguments.
148- # num_traces: Total number of traces in the SEG-Y file.
149- # subset: List of header names to filter and keep.
150- # block_size: Number of traces to read for each block.
151- # progress_bar: Enable or disable progress bar. Default is True.
152-
153- # Returns:
154- # HeaderArray. Keys are the index names, values are numpy arrays of parsed headers for the
155- # current block. Array is of type byte_type except IBM32 which is mapped to FLOAT32.
156- # """
157- # trace_count = num_traces
158- # n_blocks = int(ceil(trace_count / block_size))
159-
160- # trace_ranges = []
161- # for idx in range(n_blocks):
162- # start, stop = idx * block_size, (idx + 1) * block_size
163- # stop = min(stop, trace_count)
164-
165- # trace_ranges.append((start, stop))
166-
167- # num_cpus = int(os.getenv("MDIO__IMPORT__CPU_COUNT", default_cpus))
168- # num_workers = min(n_blocks, num_cpus)
169-
170- # tqdm_kw = {"unit": "block", "dynamic_ncols": True}
171- # # For Unix async writes with s3fs/fsspec & multiprocessing, use 'spawn' instead of default
172- # # 'fork' to avoid deadlocks on cloud stores. Slower but necessary. Default on Windows.
173- # context = mp.get_context("spawn")
174- # with ProcessPoolExecutor(num_workers, mp_context=context) as executor:
175- # lazy_work = executor.map(header_scan_worker, repeat(segy_file_kwargs), trace_ranges, repeat(subset))
176-
177- # if progress_bar is True:
178- # lazy_work = tqdm(
179- # iterable=lazy_work,
180- # total=n_blocks,
181- # desc="Scanning SEG-Y for geometry attributes",
182- # **tqdm_kw,
183- # )
184-
185- # # This executes the lazy work.
186- # headers: list[HeaderArray] = list(lazy_work)
187-
188- # # Merge blocks before return
189- # return np.concatenate(headers)
83+ headers : list [HeaderArray ] = list (lazy_work )
84+
85+ # Merge blocks before return
86+ return np .concatenate (headers )
0 commit comments