| name | segy-operations |
| description | Use when working with SEG-Y seismic data files - reading, writing, visualization, or manipulation operations. |
Skill: SEG-Y Operations
Read, manipulate, and write SEG-Y seismic data using segyio library.
Purpose
Handle seismic data operations across all oil & gas pipeline skills. Provides code patterns for reading SEG-Y files, extracting headers, visualization, and writing output.
Reference Materials
Primary source: Equinor segyio-notebooks
Key notebooks:
notebooks/basic/01_basic_tutorial.ipynb - Complete workflow
notebooks/basic/02_segy_quicklook.ipynb - Header analysis
notebooks/basic/03_basic_segy_editing.ipynb - Trace manipulation
notebooks/pylops/01_seismic_inversion.ipynb - Inversion workflow
Library: segyio
Dependencies
pip install segyio numpy pandas matplotlib
Capabilities
1. Read SEG-Y Files
import segyio
import numpy as np
with segyio.open('seismic.sgy', 'r') as segyfile:
data = segyio.tools.cube(segyfile)
print(f"Shape: {data.shape}")
inline_100 = segyfile.iline[100]
crossline_200 = segyfile.xline[200]
trace_50 = segyfile.trace[50]
2. Extract Headers to DataFrame
import segyio
import pandas as pd
with segyio.open('seismic.sgy', 'r') as segyfile:
binary_header = segyfile.bin
headers = []
for i, trace_header in enumerate(segyfile.header):
headers.append({
'trace_number': i,
'iline': trace_header[segyio.su.iline],
'xline': trace_header[segyio.su.xline],
'cdp_x': trace_header[segyio.su.cdp_x] / 10,
'cdp_y': trace_header[segyio.su.cdp_y] / 10,
'samples': trace_header[segyio.su.ns],
})
df = pd.DataFrame(headers)
print(df.head())
3. Visualize Seismic Data
import segyio
import numpy as np
import matplotlib.pyplot as plt
with segyio.open('seismic.sgy', 'r') as segyfile:
data = segyio.tools.cube(segyfile)
time_slice = data[:, :, 100]
plt.figure(figsize=(12, 8))
plt.imshow(time_slice.T, cmap='seismic', aspect='auto')
plt.colorbar(label='Amplitude')
plt.title('Time Slice at Sample 100')
plt.xlabel('Crossline')
plt.ylabel('Inline')
plt.savefig('time_slice.png', dpi=150)
4. Manipulate Trace Length
import segyio
from scipy.signal import resample
with segyio.open('input.sgy', 'r') as src:
data = segyio.tools.cube(src)
cut_data = data[:, :, 100:500]
resampled = resample(data, 500, axis=2)
5. Write SEG-Y Files
import segyio
import numpy as np
with segyio.open('template.sgy', 'r') as src:
spec = segyio.spec()
spec.format = src.format
spec.sorting = src.sorting
spec.iline = src.header.iline
spec.xline = src.header.xline
spec.samples = src.samples
spec.ilines = src.ilines
spec.xlines = src.xlines
data = np.random.randn(100, 120, 500)
with segyio.open('output.sgy', 'w', spec) as dst:
dst.trace = data.reshape(-1, data.shape[-1])
with segyio.open('template.sgy', 'r') as src:
dst.header = src.header
6. Create Fault Volume from Similarity
import segyio
with segyio.open('similarity.sgy', 'r') as segyfile:
similarity = segyio.tools.cube(segyfile)
discontinuity = 1 - similarity
fault_mask = (discontinuity > 0.6).astype(float)
Workflow Integration
Used by:
oil-gas-pipelines/exploration - Seismic interpretation
oil-gas-pipelines/reservoir-production - Horizon picking, attribute analysis
Common Issues
File won't open
with segyio.open('file.sgy', 'r', strict=False) as segyfile:
data = segyio.tools.cube(segyfile)
Wrong dimensions
with segyio.open('file.sgy', 'r') as segyfile:
print(f"Inlines: {segyfile.ilines}")
print(f"Crosslines: {segyfile.xlines}")
print(f"Samples: {len(segyfile.samples)}")
print(f"Sorting: {segyfile.sorting}")
Software Tasks
If user requests:
- Seismic visualization web app → invoke
petropowers:oil-gas-delegation
- SEG-Y database system → invoke
petropowers:oil-gas-delegation
- Automated SEG-Y processing pipeline → invoke
petropowers:oil-gas-delegation
Quick Reference
| Operation | Code |
|---|
| Open file | segyio.open('file.sgy', 'r') |
| Read cube | segyio.tools.cube(segyfile) |
| Get inline | segyfile.iline[inline_number] |
| Get trace header | segyfile.header[trace_number] |
| Write file | segyio.open('file.sgy', 'w', spec) |
Example Session
User: "What's the amplitude range in this SEG-Y file?"
Agent:
import segyio
import numpy as np
with segyio.open('seismic.sgy', 'r') as segyfile:
data = segyio.tools.cube(segyfile)
print(f"Amplitude range: {data.min():.2f} to {data.max():.2f}")
print(f"Mean: {data.mean():.2f}, Std: {data.std():.2f}")
Output:
Amplitude range: -32768.00 to 32767.00
Mean: 12.34, Std: 4567.89
OSDU Integration
SEG-Y to VDS/ZGY Conversion
OSDU (Open Subsurface Data Universe) uses cloud-native formats for seismic data:
- VDS (Voxel Data Service) - Cloud-optimized seismic format for random access
- ZGY - Compressed seismic format for visualization
Conversion Workflow:
- Upload SEG-Y file to OSDU (via Dataset Service)
- Trigger SegYToVDS DAG conversion workflow
- VDS file stored in cloud storage
- Access via Seismic DMS (Data Management Service)
OSDU Schemas for Seismic
| Schema | Purpose |
|---|
| SeismicBinGrid | Survey geometry |
| SeismicTraceData | Individual seismic traces |
| SeismicLineGeometry2D | 2D seismic lines |
| SeismicLineGeometry3D | 3D seismic surveys |
OSDU Dataset Service API
import requests
storage_resp = requests.post(
"https://api.osdu.com/api/dataset/v1/storageInstructions",
headers={
"Authorization": "Bearer <token>",
"data-partition-id": "mypartition"
},
json={
"kind": "osdu:wks:dataset--File.Seismic:1.0.0",
"dataContentType": "application/x-segy"
}
)
upload_url = storage_resp.json()["storageLocation"]["signedUrl"]
with open("seismic.sgy", "rb") as f:
requests.put(upload_url, data=f.read())
register_resp = requests.post(
"https://api.osdu.com/api/dataset/v1/register",
headers={
"Authorization": "Bearer <token>",
"data-partition-id": "mypartition"
},
json={
"id": "dataset--File.Seismic:1654321",
"kind": "osdu:wks:dataset--File.Seismic:1.0.0",
"ancestry": {
"parents": ["work-product--SeismicTraceData:12345"]
}
}
)
Create OSDU Manifest for Seismic
import json
from datetime import datetime
def create_seismic_manifest(survey_id, segy_file, legal_tags):
"""Create OSDU manifest for 3D seismic survey"""
manifest = {
"kind": "osdu:wks:Manifest:1.0.0",
"ReferenceData": [],
"MasterData": [],
"Data": {
"WorkProduct": {
"kind": "osdu:wks:work-product--SeismicTraceData:1.0.0",
"id": f"work-product--SeismicTraceData:{survey_id}",
"legal": legal_tags,
"data": {
"Name": f"Seismic Survey {survey_id}",
"Description": "3D seismic data",
"CreationDateTime": datetime.utcnow().isoformat(),
"DatasetIDs": [f"dataset--File.Seismic:{segy_file}"],
"ExtensionProperties": {}
}
},
"Datasets": [{
"kind": "osdu:wks:dataset--File.Seismic:1.0.0",
"id": f"dataset--File.Seismic:{segy_file}",
"data": {
"Name": segy_file,
"DataContentType": "application/x-segy"
}
}]
}
}
return json.dumps(manifest, indent=)
manifest = create_seismic_manifest(
survey_id=,
segy_file=,
legal_tags={: [], : []}
)
From SEG-Y to OSDU Workflow
- Quality check SEG-Y file using segyio (see Capabilities section above)
- Create OSDU manifest with SeismicBinGrid and SeismicLineGeometry3D schemas
- Upload SEG-Y to cloud storage via Dataset Service
- Trigger SegYToVDS DAG for conversion to VDS format
- Access VDS via Seismic DMS API
OSDU Reference Documentation
Software Tasks
If user requests:
- OSDU data ingestion pipeline → invoke
petropowers:oil-gas-delegation
- Seismic visualization web app → invoke
petropowers:oil-gas-delegation
- OSDU schema validation → stay in domain skill (validate against OSDU schemas)