diff --git a/segpy-ext/segpy-numpy/segpy_numpy/extract.py b/segpy-ext/segpy-numpy/segpy_numpy/extract.py index d6dbc2f..1e9e3ce 100644 --- a/segpy-ext/segpy-numpy/segpy_numpy/extract.py +++ b/segpy-ext/segpy-numpy/segpy_numpy/extract.py @@ -203,27 +203,27 @@ def extract_inline_3d(reader_3d, inline_number, xline_numbers=None, sample_numbe return array -def _populate_inline_array_numbered_samples(reader, inline_number, xline_numbers, sample_numbers, array): +def _populate_inline_array_numbered_samples(reader_3d, inline_number, xline_numbers, sample_numbers, array): for xline_index, xline_number in enumerate(xline_numbers): inline_xline_number = (inline_number, xline_number) - if reader.has_trace_index(inline_xline_number): - trace_index = reader.trace_index(inline_xline_number) - num_trace_samples = reader.num_trace_samples(trace_index) + if reader_3d.has_trace_index(inline_xline_number): + trace_index = reader_3d.trace_index(inline_xline_number) + num_trace_samples = reader_3d.num_trace_samples(trace_index) trace_sample_start = sample_numbers[0] trace_sample_stop = min(sample_numbers[-1] + 1, num_trace_samples) - trace_samples = reader.trace_samples(trace_index, trace_sample_start, trace_sample_stop) + trace_samples = reader_3d.trace_samples(trace_index, trace_sample_start, trace_sample_stop) for sample_index, sample_number in enumerate(sample_numbers): array[xline_index, sample_index] = trace_samples[sample_number - trace_sample_start] -def _populate_inline_array_over_sample_range(reader, inline_number, xline_numbers, sample_numbers, array): +def _populate_inline_array_over_sample_range(reader_3d, inline_number, xline_numbers, sample_numbers, array): for xline_index, xline_number in enumerate(xline_numbers): inline_xline_number = (inline_number, xline_number) - if reader.has_trace_index(inline_xline_number): - trace_index = reader.trace_index(inline_xline_number) - num_trace_samples = reader.num_trace_samples(trace_index) + if reader_3d.has_trace_index(inline_xline_number): + trace_index = reader_3d.trace_index(inline_xline_number) + num_trace_samples = reader_3d.num_trace_samples(trace_index) trace_sample_stop = min(sample_numbers.stop, num_trace_samples) - trace_samples = reader.trace_samples(trace_index, sample_numbers.start, trace_sample_stop) + trace_samples = reader_3d.trace_samples(trace_index, sample_numbers.start, trace_sample_stop) source_slice = slice(sample_numbers.start, trace_sample_stop, sample_numbers.step) array[xline_index, :] = trace_samples[source_slice] @@ -292,31 +292,98 @@ def extract_xline_3d(reader_3d, xline_number, inline_numbers=None, sample_number return array -def _populate_xline_array_numbered_samples(reader, xline_number, inline_numbers, sample_numbers, array): +def _populate_xline_array_numbered_samples(reader_3d, xline_number, inline_numbers, sample_numbers, array): for inline_index, inline_number in enumerate(inline_numbers): inline_xline_number = (inline_number, xline_number) - if reader.has_trace_index(inline_xline_number): - trace_index = reader.trace_index(inline_xline_number) - num_trace_samples = reader.num_trace_samples(trace_index) + if reader_3d.has_trace_index(inline_xline_number): + trace_index = reader_3d.trace_index(inline_xline_number) + num_trace_samples = reader_3d.num_trace_samples(trace_index) trace_sample_start = sample_numbers[0] trace_sample_stop = min(sample_numbers[-1] + 1, num_trace_samples) - trace_samples = reader.trace_samples(trace_index, trace_sample_start, trace_sample_stop) + trace_samples = reader_3d.trace_samples(trace_index, trace_sample_start, trace_sample_stop) for sample_index, sample_number in enumerate(sample_numbers): array[inline_index, sample_index] = trace_samples[sample_number - trace_sample_start] -def _populate_xline_array_over_sample_range(reader, xline_number, inline_numbers, sample_numbers, array): +def _populate_xline_array_over_sample_range(reader_3d, xline_number, inline_numbers, sample_numbers, array): for inline_index, inline_number in enumerate(inline_numbers): inline_xline_number = (inline_number, xline_number) - if reader.has_trace_index(inline_xline_number): - trace_index = reader.trace_index(inline_xline_number) - num_trace_samples = reader.num_trace_samples(trace_index) + if reader_3d.has_trace_index(inline_xline_number): + trace_index = reader_3d.trace_index(inline_xline_number) + num_trace_samples = reader_3d.num_trace_samples(trace_index) trace_sample_stop = min(sample_numbers.stop, num_trace_samples) - trace_samples = reader.trace_samples(trace_index, sample_numbers.start, trace_sample_stop) + trace_samples = reader_3d.trace_samples(trace_index, sample_numbers.start, trace_sample_stop) source_slice = slice(sample_numbers.start, trace_sample_stop, sample_numbers.step) array[inline_index, :] = trace_samples[source_slice] +def extract_timeslice_3d(reader_3d, sample_number, inline_numbers=None, xline_numbers=None, null=None): + """Extract a single timeslice header field from all trace headers as an array. + + Args: + reader_3d: A SegYReader3D + + sample_number: The zero-based sample index. + + inline_numbers: The inline numbers for which traces are to be extracted. + This argument can be specified in three ways: + + None (the default) - All traces within the each crossline will be be extracted. + + sequence - When a sequence, such as a range or a list is provided only those traces at + inline numbers corresponding to the items in the sequence will be extracted. The + traces will always be extracted in increasing numeric order and duplicate entries + will be ignored. For example inline_numbers=range(100, 200, 2) will extract alternate + traces from inline number 100 to inline number 198 inclusive. + + slice - When a slice object is provided the slice will be applied to the sequence of all + inline numbers. For example inline_numbers=slice(100, -100) will omit the first + one hundred and the last one hundred traces, irrespective of their numbers. + + xline_numbers: The crossline numbers at which traces are to be extracted. + This argument can be specified in three ways: + + None (the default) - All traces at within each inline will be be extracted. + + sequence - When a sequence, such as a range or a list is provided only those traces at + crossline numbers corresponding to the items in the sequence will be extracted. The + traces will always be extracted in increasing numeric order and duplicate entries + will be ignored. For example xline_numbers=range(100, 200, 2) will extract alternate + traces from crossline number 100 to crossline number 198 inclusive. + + slice - When a slice object is provided the slice will be applied to the sequence of all + crossline numbers. For example xline_numbers=slice(100, -100) will omit the first + one hundred and the last one hundred traces, irrespective of their numbers. + + null: An optional null value for missing traces. The null value must be convertible + to all field value types. + + Returns: + An namedtuple object with attributes which are two-dimensional Numpy arrays. + If a null value was specified the arrays will be ndarrays, otherwise they + will be masked arrays. The attributes of the named tuple are in the same + order as the fields specified in the `fields` argument. + + Raises: + AttributeError: If the the named fields do not exist in the trace header definition. + """ + + inline_numbers = ensure_superset(reader_3d.inline_numbers(), inline_numbers) + xline_numbers = ensure_superset(reader_3d.xline_numbers(), xline_numbers) + shape = (len(inline_numbers), len(xline_numbers)) + dtype = make_dtype(reader_3d.data_sample_format) + array = _make_array(shape, dtype, null) + sample_number_stop = sample_number + 1 + + for inline_index, inline_number in enumerate(inline_numbers): + for xline_index, xline_number in enumerate(xline_numbers): + inline_xline_number = (inline_number, xline_number) + if reader_3d.has_trace_index(inline_xline_number): + trace_index = reader_3d.trace_index((inline_number, xline_number)) + trace_samples = reader_3d.trace_samples(trace_index, sample_number, sample_number_stop) + array[inline_index, xline_index] = trace_samples[0] + return array + def _make_array(shape, dtype, null=None): """Make an array""" if null is None: