0
# Seismic Unix Compatibility
1
2
Seismic Unix field name aliases and specialized file handling for SU format compatibility. This subpackage provides familiar field names for users transitioning from Seismic Unix workflows.
3
4
## Capabilities
5
6
### SU Field Aliases
7
8
The segyio.su module provides Seismic Unix field name aliases that map to the corresponding TraceField and BinField constants, making code more readable for users familiar with SU conventions.
9
10
```python { .api }
11
import segyio.su
12
13
# Trace header field aliases (key fields)
14
segyio.su.tracl # TraceField.TRACE_SEQUENCE_LINE - Trace sequence number within line
15
segyio.su.tracr # TraceField.TRACE_SEQUENCE_FILE - Trace sequence number within file
16
segyio.su.fldr # TraceField.FieldRecord - Original field record number
17
segyio.su.tracf # TraceField.TraceNumber - Trace number within field record
18
segyio.su.ep # TraceField.EnergySourcePoint - Energy source point number
19
segyio.su.cdp # TraceField.CDP - CDP ensemble number
20
segyio.su.cdpt # TraceField.CDP_TRACE - Trace number within CDP ensemble
21
segyio.su.trid # TraceField.TraceIdentificationCode - Trace identification code
22
segyio.su.offset # TraceField.offset - Distance from source to receiver group
23
segyio.su.sx # TraceField.SourceX - Source coordinate X
24
segyio.su.sy # TraceField.SourceY - Source coordinate Y
25
segyio.su.gx # TraceField.GroupX - Group coordinate X
26
segyio.su.gy # TraceField.GroupY - Group coordinate Y
27
segyio.su.ns # TraceField.TRACE_SAMPLE_COUNT - Number of samples in trace
28
segyio.su.dt # TraceField.TRACE_SAMPLE_INTERVAL - Sample interval (microseconds)
29
segyio.su.delrt # TraceField.DelayRecordingTime - Delay recording time (ms)
30
segyio.su.cdpx # TraceField.CDP_X - CDP X coordinate
31
segyio.su.cdpy # TraceField.CDP_Y - CDP Y coordinate
32
segyio.su.iline # TraceField.INLINE_3D - Inline number (3D surveys)
33
segyio.su.xline # TraceField.CROSSLINE_3D - Crossline number (3D surveys)
34
```
35
36
**Usage Example:**
37
38
```python
39
import segyio
40
import segyio.su
41
42
# Using SU field names instead of numeric constants
43
with segyio.open('data.sgy') as f:
44
# Read trace header using SU field names
45
header = f.header[0]
46
47
# Instead of: header[189] and header[193]
48
inline = header[segyio.su.iline]
49
crossline = header[segyio.su.xline]
50
cdp_number = header[segyio.su.cdp]
51
source_x = header[segyio.su.sx]
52
group_x = header[segyio.su.gx]
53
offset_dist = header[segyio.su.offset]
54
55
print(f"Trace: IL={inline}, XL={crossline}, CDP={cdp_number}")
56
print(f"Geometry: SX={source_x}, GX={group_x}, Offset={offset_dist}")
57
58
# Sample count and interval
59
samples = header[segyio.su.ns]
60
sample_rate = header[segyio.su.dt] # microseconds
61
delay_time = header[segyio.su.delrt] # milliseconds
62
63
print(f"Timing: {samples} samples, {sample_rate/1000}ms rate, {delay_time}ms delay")
64
```
65
66
### Extended SU Field Aliases
67
68
Complete set of Seismic Unix trace header field aliases for comprehensive compatibility.
69
70
```python { .api }
71
# Additional trace header aliases
72
segyio.su.nvs # Number of vertically summed traces
73
segyio.su.nhs # Number of horizontally stacked traces
74
segyio.su.duse # Data use (production/test)
75
segyio.su.gelev # Receiver group elevation
76
segyio.su.selev # Source elevation
77
segyio.su.sdepth # Source depth below surface
78
segyio.su.gdel # Datum elevation at receiver group
79
segyio.su.sdel # Datum elevation at source
80
segyio.su.swdep # Water depth at source
81
segyio.su.gwdep # Water depth at receiver group
82
segyio.su.scalel # Elevation scalar
83
segyio.su.scalco # Coordinate scalar
84
segyio.su.counit # Coordinate units
85
segyio.su.wevel # Weathering velocity
86
segyio.su.swevel # Subweathering velocity
87
segyio.su.sut # Uphole time at source (ms)
88
segyio.su.gut # Uphole time at receiver group (ms)
89
segyio.su.sstat # Source static correction (ms)
90
segyio.su.gstat # Group static correction (ms)
91
segyio.su.tstat # Total static correction (ms)
92
segyio.su.laga # Lag time A (ms)
93
segyio.su.lagb # Lag time B (ms)
94
segyio.su.muts # Mute time start (ms)
95
segyio.su.mute # Mute time end (ms)
96
segyio.su.gain # Gain type of field instruments
97
segyio.su.igc # Instrument gain constant
98
segyio.su.igi # Instrument early or initial gain
99
segyio.su.corr # Correlated data traces
100
segyio.su.year # Year data recorded
101
segyio.su.day # Day of year
102
segyio.su.hour # Hour of day (24 hour clock)
103
segyio.su.minute # Minute of hour
104
segyio.su.sec # Second of minute
105
segyio.su.timbas # Time basis code
106
```
107
108
### Binary Header SU Aliases
109
110
Seismic Unix aliases for binary header fields.
111
112
```python { .api }
113
# Binary header field aliases
114
segyio.su.jobid # BinField.JobID - Job identification number
115
segyio.su.lino # BinField.LineNumber - Line number
116
segyio.su.reno # BinField.ReelNumber - Reel number
117
segyio.su.ntrpr # BinField.Traces - Number of data traces per ensemble
118
segyio.su.nart # BinField.AuxTraces - Number of auxiliary traces per ensemble
119
segyio.su.hdt # BinField.Interval - Sample interval in microseconds
120
segyio.su.dto # BinField.IntervalOriginal - Original sample interval
121
segyio.su.hns # BinField.Samples - Number of samples per data trace
122
segyio.su.nso # BinField.SamplesOriginal - Original number of samples
123
segyio.su.format # BinField.Format - Data sample format code
124
segyio.su.fold # BinField.EnsembleFold - Ensemble fold
125
segyio.su.tsort # BinField.SortingCode - Trace sorting code
126
segyio.su.rev # BinField.SEGYRevision - SEG Y format revision number
127
segyio.su.trflag # BinField.TraceFlag - Fixed length trace flag
128
segyio.su.exth # BinField.ExtendedHeaders - Number of extended headers
129
```
130
131
**Usage Example:**
132
133
```python
134
import segyio
135
import segyio.su
136
137
with segyio.open('data.sgy') as f:
138
# Read binary header using SU field names
139
job_id = f.bin[segyio.su.jobid]
140
line_num = f.bin[segyio.su.lino]
141
trace_count = f.bin[segyio.su.ntrpr]
142
sample_count = f.bin[segyio.su.hns]
143
sample_rate = f.bin[segyio.su.hdt]
144
data_format = f.bin[segyio.su.format]
145
146
print(f"Job {job_id}, Line {line_num}")
147
print(f"{trace_count} traces, {sample_count} samples each")
148
print(f"Sample rate: {sample_rate/1000} ms")
149
print(f"Format code: {data_format}")
150
```
151
152
### SU File Opening
153
154
Specialized file opening function for Seismic Unix format files with optimized defaults.
155
156
```python { .api }
157
def segyio.su.open(filename, mode='r', iline=189, xline=193, strict=True, ignore_geometry=False, endian='big'):
158
"""
159
Open seismic unix file with SU-specific defaults.
160
161
Parameters:
162
- filename (str): Path to SU file
163
- mode (str): File access mode ('r' or 'r+')
164
- iline (int): Inline header field, default 189
165
- xline (int): Crossline header field, default 193
166
- strict (bool): Abort if geometry cannot be inferred, default True
167
- ignore_geometry (bool): Skip geometry building, default False
168
- endian (str): File endianness, default 'big'
169
170
Returns:
171
segyio.su.sufile: Specialized SegyFile subclass with SU enhancements
172
"""
173
```
174
175
**Usage Example:**
176
177
```python
178
import segyio.su
179
180
# Open SU file with SU-specific handling
181
with segyio.su.open('data.su') as f:
182
# Access using SU field names
183
for i in range(min(10, f.tracecount)):
184
header = f.header[i]
185
186
# Common SU workflow
187
cdp = header[segyio.su.cdp]
188
offset = header[segyio.su.offset]
189
sx = header[segyio.su.sx]
190
gx = header[segyio.su.gx]
191
192
# Calculate midpoint
193
mx = (sx + gx) / 2
194
195
print(f"Trace {i}: CDP={cdp}, Offset={offset}, MX={mx}")
196
```
197
198
## SU Workflow Examples
199
200
### CDP Sorting and Analysis
201
202
```python
203
import segyio.su
204
import numpy as np
205
206
def analyze_cdp_gather(filename, target_cdp):
207
"""Analyze a specific CDP gather using SU field names."""
208
209
with segyio.su.open(filename) as f:
210
# Find all traces for target CDP
211
cdp_traces = []
212
offsets = []
213
214
for i in range(f.tracecount):
215
header = f.header[i]
216
cdp = header[segyio.su.cdp]
217
218
if cdp == target_cdp:
219
cdp_traces.append(f.trace[i])
220
offset = header[segyio.su.offset]
221
offsets.append(offset)
222
223
if not cdp_traces:
224
print(f"No traces found for CDP {target_cdp}")
225
return None
226
227
# Sort by offset
228
sorted_indices = np.argsort(offsets)
229
sorted_traces = [cdp_traces[i] for i in sorted_indices]
230
sorted_offsets = [offsets[i] for i in sorted_indices]
231
232
# Create gather array
233
gather = np.array(sorted_traces)
234
235
return {
236
'cdp': target_cdp,
237
'traces': gather,
238
'offsets': sorted_offsets,
239
'fold': len(sorted_traces)
240
}
241
242
# Usage
243
gather_info = analyze_cdp_gather('prestack.su', 1000)
244
if gather_info:
245
print(f"CDP {gather_info['cdp']}: {gather_info['fold']} traces")
246
print(f"Offset range: {min(gather_info['offsets'])} to {max(gather_info['offsets'])}")
247
```
248
249
### Source-Receiver Geometry Analysis
250
251
```python
252
import segyio.su
253
import numpy as np
254
import matplotlib.pyplot as plt
255
256
def plot_acquisition_geometry(filename, max_traces=1000):
257
"""Plot source and receiver positions using SU field names."""
258
259
sources_x, sources_y = [], []
260
receivers_x, receivers_y = [], []
261
262
with segyio.su.open(filename) as f:
263
coord_scalar = None
264
265
for i in range(min(max_traces, f.tracecount)):
266
header = f.header[i]
267
268
# Get coordinates
269
sx = header[segyio.su.sx]
270
sy = header[segyio.su.sy]
271
gx = header[segyio.su.gx]
272
gy = header[segyio.su.gy]
273
274
# Get coordinate scalar (should be same for all traces)
275
if coord_scalar is None:
276
coord_scalar = header[segyio.su.scalco]
277
278
sources_x.append(sx)
279
sources_y.append(sy)
280
receivers_x.append(gx)
281
receivers_y.append(gy)
282
283
# Apply coordinate scaling
284
if coord_scalar != 0:
285
if coord_scalar < 0:
286
scale = -1.0 / coord_scalar
287
else:
288
scale = coord_scalar
289
290
sources_x = np.array(sources_x) * scale
291
sources_y = np.array(sources_y) * scale
292
receivers_x = np.array(receivers_x) * scale
293
receivers_y = np.array(receivers_y) * scale
294
295
# Plot geometry
296
plt.figure(figsize=(12, 8))
297
plt.scatter(sources_x, sources_y, c='red', marker='*', s=20, alpha=0.6, label='Sources')
298
plt.scatter(receivers_x, receivers_y, c='blue', marker='v', s=10, alpha=0.6, label='Receivers')
299
plt.xlabel('X Coordinate')
300
plt.ylabel('Y Coordinate')
301
plt.title('Acquisition Geometry')
302
plt.legend()
303
plt.grid(True, alpha=0.3)
304
plt.axis('equal')
305
plt.show()
306
307
# Usage
308
plot_acquisition_geometry('marine_survey.su')
309
```
310
311
### Trace Attribute Extraction
312
313
```python
314
import segyio.su
315
import numpy as np
316
317
def extract_trace_attributes(filename, output_file):
318
"""Extract trace attributes using SU field names."""
319
320
attributes = []
321
322
with segyio.su.open(filename) as f:
323
for i in range(f.tracecount):
324
header = f.header[i]
325
trace = f.trace[i]
326
327
# Extract SU header attributes
328
attr = {
329
'trace_num': i,
330
'tracl': header[segyio.su.tracl],
331
'fldr': header[segyio.su.fldr],
332
'cdp': header[segyio.su.cdp],
333
'offset': header[segyio.su.offset],
334
'sx': header[segyio.su.sx],
335
'sy': header[segyio.su.sy],
336
'gx': header[segyio.su.gx],
337
'gy': header[segyio.su.gy],
338
'ns': header[segyio.su.ns],
339
'dt': header[segyio.su.dt],
340
'delrt': header[segyio.su.delrt]
341
}
342
343
# Calculate derived attributes
344
attr['midpoint_x'] = (attr['sx'] + attr['gx']) / 2
345
attr['midpoint_y'] = (attr['sy'] + attr['gy']) / 2
346
attr['azimuth'] = np.arctan2(attr['gy'] - attr['sy'],
347
attr['gx'] - attr['sx']) * 180 / np.pi
348
349
# Trace data attributes
350
attr['max_amp'] = float(trace.max())
351
attr['min_amp'] = float(trace.min())
352
attr['rms_amp'] = float(np.sqrt(np.mean(trace**2)))
353
attr['zero_crossings'] = int(np.sum(np.diff(np.sign(trace)) != 0))
354
355
attributes.append(attr)
356
357
# Save to CSV
358
import pandas as pd
359
df = pd.DataFrame(attributes)
360
df.to_csv(output_file, index=False)
361
362
return df
363
364
# Usage
365
attrs = extract_trace_attributes('survey.su', 'trace_attributes.csv')
366
print(f"Extracted attributes for {len(attrs)} traces")
367
print(attrs.describe())
368
```
369
370
## Migration from Pure SU Workflows
371
372
### Field Name Mapping
373
374
```python
375
# Traditional SU approach (numeric byte positions)
376
old_style = {
377
'inline': 189,
378
'crossline': 193,
379
'cdp': 21,
380
'offset': 37
381
}
382
383
# New SU-compatible approach
384
import segyio.su
385
new_style = {
386
'inline': segyio.su.iline,
387
'crossline': segyio.su.xline,
388
'cdp': segyio.su.cdp,
389
'offset': segyio.su.offset
390
}
391
392
# Both approaches work identically
393
with segyio.open('data.sgy') as f:
394
header = f.header[0]
395
396
# These are equivalent
397
old_cdp = header[21]
398
new_cdp = header[segyio.su.cdp]
399
400
assert old_cdp == new_cdp
401
```
402
403
### Common SU Processing Patterns
404
405
```python
406
import segyio.su
407
import numpy as np
408
409
def su_style_processing(filename):
410
"""Common SU-style processing workflow."""
411
412
with segyio.su.open(filename) as f:
413
# Print file statistics (SU segyread style)
414
print(f"File: {filename}")
415
print(f"Traces: {f.tracecount}")
416
print(f"Samples: {f.bin[segyio.su.hns]}")
417
print(f"Sample rate: {f.bin[segyio.su.hdt]/1000} ms")
418
419
# Trace loop (SU style)
420
for i in range(f.tracecount):
421
header = f.header[i]
422
trace = f.trace[i]
423
424
# Extract key SU fields
425
tracl = header[segyio.su.tracl]
426
cdp = header[segyio.su.cdp]
427
offset = header[segyio.su.offset]
428
ns = header[segyio.su.ns]
429
dt = header[segyio.su.dt]
430
431
# Apply typical SU processing
432
if offset > 5000: # Far offset processing
433
trace *= 2.0 # Gain correction
434
435
# Update trace (if file writable)
436
if not f.readonly:
437
f.trace[i] = trace
438
```