|
2 | 2 |
|
3 | 3 | from __future__ import annotations |
4 | 4 |
|
5 | | -import numpy as np |
6 | 5 | from typing import TYPE_CHECKING |
7 | | -from segy.transforms import ByteSwapTransform |
8 | | -from segy.transforms import IbmFloatTransform |
9 | 6 |
|
10 | 7 | if TYPE_CHECKING: |
| 8 | + import numpy as np |
11 | 9 | from segy.file import SegyFile |
12 | | - from segy.indexing import HeaderIndexer |
13 | | - from segy.transforms import Transform, TransformPipeline, ByteSwapTransform, IbmFloatTransform |
| 10 | + from segy.transforms import Transform, ByteSwapTransform, IbmFloatTransform |
14 | 11 | from numpy.typing import NDArray |
15 | 12 |
|
16 | 13 | def _reverse_single_transform(data: NDArray, transform: Transform) -> NDArray: |
17 | | - """Reverse a single transform operation. |
18 | | -
|
19 | | - Args: |
20 | | - data: The data to reverse transform |
21 | | - transform: The transform to reverse |
22 | | -
|
23 | | - Returns: |
24 | | - Data with the transform reversed |
25 | | - """ |
26 | | - # Import here to avoid circular imports |
27 | | - from segy.transforms import get_endianness |
| 14 | + """Reverse a single transform operation.""" |
28 | 15 | from segy.schema import Endianness |
29 | 16 |
|
30 | 17 | if isinstance(transform, ByteSwapTransform): |
31 | | - # For byte swap, we need to reverse the endianness conversion |
32 | | - # If the transform was converting to little-endian, we need to convert back to big-endian |
33 | | - |
34 | | - # If transform was converting TO little-endian, we need to convert TO big-endian |
| 18 | + # Reverse the endianness conversion |
35 | 19 | # TODO: I don't think this is correct |
36 | 20 | if transform.target_order == Endianness.LITTLE: |
37 | 21 | reverse_target = Endianness.BIG |
38 | 22 | else: |
39 | 23 | reverse_target = Endianness.LITTLE |
40 | 24 |
|
41 | 25 | reverse_transform = ByteSwapTransform(reverse_target) |
42 | | - result = reverse_transform.apply(data) |
43 | | - |
44 | | - return result |
| 26 | + return reverse_transform.apply(data) |
45 | 27 |
|
46 | 28 | elif isinstance(transform, IbmFloatTransform): |
47 | | - # Reverse IBM float conversion by swapping direction |
| 29 | + # Reverse IBM float conversion |
48 | 30 | reverse_direction = "to_ibm" if transform.direction == "to_ieee" else "to_ieee" |
49 | 31 | reverse_transform = IbmFloatTransform(reverse_direction, transform.keys) |
50 | 32 | return reverse_transform.apply(data) |
51 | 33 |
|
52 | 34 | else: |
53 | 35 | # For unknown transforms, return data unchanged |
54 | | - # This maintains compatibility if new transforms are added |
55 | 36 | return data |
56 | 37 |
|
57 | 38 | def get_header_raw_and_transformed( |
58 | 39 | segy_file: SegyFile, |
59 | | - indices: int | list[int] | np.ndarray | slice |
| 40 | + indices: int | list[int] | NDArray | slice |
60 | 41 | ) -> tuple[NDArray, NDArray, NDArray]: |
61 | | - """Convenience function to get both raw and transformed header data. |
62 | | -
|
63 | | - This is a drop-in replacement that provides the functionality you requested |
64 | | - without modifying the segy package. |
| 42 | + """Get both raw and transformed header data. |
65 | 43 |
|
66 | 44 | Args: |
67 | 45 | segy_file: The SegyFile instance |
68 | 46 | indices: Which headers to retrieve |
69 | 47 |
|
70 | 48 | Returns: |
71 | | - Tuple of (raw_headers, transformed_headers) |
72 | | -
|
73 | | - Example: |
74 | | - from header_raw_transformed_accessor import get_header_raw_and_transformed |
75 | | -
|
76 | | - # Single header |
77 | | - raw_hdr, transformed_hdr = get_header_raw_and_transformed(segy_file, 0) |
78 | | -
|
79 | | - # Multiple headers |
80 | | - raw_hdrs, transformed_hdrs = get_header_raw_and_transformed(segy_file, [0, 1, 2]) |
81 | | -
|
82 | | - # Slice of headers |
83 | | - raw_hdrs, transformed_hdrs = get_header_raw_and_transformed(segy_file, slice(0, 10)) |
| 49 | + Tuple of (raw_headers, transformed_headers, traces) |
84 | 50 | """ |
85 | 51 |
|
86 | 52 | traces = segy_file.trace[indices] |
87 | | - |
88 | 53 | transformed_headers = traces.header |
89 | 54 |
|
90 | | - # Reverse the transforms on the already-loaded transformed data |
91 | | - # This eliminates the second disk read entirely! |
| 55 | + # Reverse transforms to get raw data |
92 | 56 | raw_headers = _reverse_transforms(transformed_headers, segy_file.header.transform_pipeline) |
93 | 57 |
|
94 | 58 | return raw_headers, transformed_headers, traces |
95 | 59 |
|
96 | 60 | def _reverse_transforms(transformed_data: NDArray, transform_pipeline) -> NDArray: |
97 | | - """Reverse the transform pipeline to get raw data from transformed data. |
98 | | -
|
99 | | - Args: |
100 | | - transformed_data: Data that has been processed through the transform pipeline |
101 | | - transform_pipeline: The transform pipeline to reverse |
102 | | -
|
103 | | - Returns: |
104 | | - Raw data equivalent to what was read directly from filesystem |
105 | | - """ |
106 | | - # Start with the transformed data |
| 61 | + """Reverse the transform pipeline to get raw data.""" |
107 | 62 | raw_data = transformed_data.copy() if hasattr(transformed_data, 'copy') else transformed_data |
108 | 63 |
|
109 | | - # Apply transforms in reverse order with reversed operations |
| 64 | + # Apply transforms in reverse order |
110 | 65 | for transform in reversed(transform_pipeline.transforms): |
111 | 66 | raw_data = _reverse_single_transform(raw_data, transform) |
112 | 67 |
|
|
0 commit comments