con un clic
segy-operations
// Use when working with SEG-Y seismic data files - reading, writing, visualization, or manipulation operations.
// Use when working with SEG-Y seismic data files - reading, writing, visualization, or manipulation operations.
| name | segy-operations |
| description | Use when working with SEG-Y seismic data files - reading, writing, visualization, or manipulation operations. |
Read, manipulate, and write SEG-Y seismic data using segyio library.
Handle seismic data operations across all oil & gas pipeline skills. Provides code patterns for reading SEG-Y files, extracting headers, visualization, and writing output.
Primary source: Equinor segyio-notebooks
Key notebooks:
notebooks/basic/01_basic_tutorial.ipynb - Complete workflownotebooks/basic/02_segy_quicklook.ipynb - Header analysisnotebooks/basic/03_basic_segy_editing.ipynb - Trace manipulationnotebooks/pylops/01_seismic_inversion.ipynb - Inversion workflowLibrary: segyio
pip install segyio numpy pandas matplotlib
import segyio
import numpy as np
# Open file
with segyio.open('seismic.sgy', 'r') as segyfile:
# Read as 3D cube
data = segyio.tools.cube(segyfile)
print(f"Shape: {data.shape}") # (inlines, crosslines, samples)
# Access inline
inline_100 = segyfile.iline[100]
# Access crossline
crossline_200 = segyfile.xline[200]
# Access specific trace
trace_50 = segyfile.trace[50]
import segyio
import pandas as pd
with segyio.open('seismic.sgy', 'r') as segyfile:
# Binary header
binary_header = segyfile.bin
# Trace headers
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, # usually scaled
'cdp_y': trace_header[segyio.su.cdp_y] / 10,
'samples': trace_header[segyio.su.ns],
})
df = pd.DataFrame(headers)
print(df.head())
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
time_slice = data[:, :, 100] # sample index 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)
import segyio
from scipy.signal import resample
# Resample or cut traces
with segyio.open('input.sgy', 'r') as src:
# Cut to specific sample range
data = segyio.tools.cube(src)
cut_data = data[:, :, 100:500] # samples 100-500
# Or resample
resampled = resample(data, 500, axis=2) # resample to 500 samples
import segyio
import numpy as np
# Create new SEG-Y from numpy array
with segyio.open('template.sgy', 'r') as src:
# Use source as template for headers
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
# Write new file
data = np.random.randn(100, 120, 500) # example data
with segyio.open('output.sgy', 'w', spec) as dst:
dst.trace = data.reshape(-1, data.shape[-1])
# Copy headers from source if needed
with segyio.open('template.sgy', 'r') as src:
dst.header = src.header
import segyio
with segyio.open('similarity.sgy', 'r') as segyfile:
similarity = segyio.tools.cube(segyfile)
# Convert similarity to discontinuity (fault indicator)
# Low similarity = high discontinuity = likely fault
discontinuity = 1 - similarity
# Threshold to create fault mask
fault_mask = (discontinuity > 0.6).astype(float)
# Write fault volume
# (use write pattern from above)
Used by:
oil-gas-pipelines/exploration - Seismic interpretationoil-gas-pipelines/reservoir-production - Horizon picking, attribute analysis# Try strict=False for non-standard files
with segyio.open('file.sgy', 'r', strict=False) as segyfile:
data = segyio.tools.cube(segyfile)
# Check file structure
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}")
If user requests:
petropowers:oil-gas-delegationpetropowers:oil-gas-delegationpetropowers:oil-gas-delegation| 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) |
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 (Open Subsurface Data Universe) uses cloud-native formats for seismic data:
Conversion Workflow:
| Schema | Purpose |
|---|---|
| SeismicBinGrid | Survey geometry |
| SeismicTraceData | Individual seismic traces |
| SeismicLineGeometry2D | 2D seismic lines |
| SeismicLineGeometry3D | 3D seismic surveys |
import requests
# Get storage instructions
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 file to provided URL
upload_url = storage_resp.json()["storageLocation"]["signedUrl"]
with open("seismic.sgy", "rb") as f:
requests.put(upload_url, data=f.read())
# Register dataset
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"]
}
}
)
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=2)
# Example usage
manifest = create_seismic_manifest(
survey_id="survey-2024-001",
segy_file="seismic_001.sgy",
legal_tags={"legaltags": ["my-legal-tag"], "otherRelevantDataCountries": ["US"]}
)
If user requests:
petropowers:oil-gas-delegationpetropowers:oil-gas-delegationYou MUST use this before any creative work - creating features, building components, adding functionality, or modifying behavior. Explores user intent, requirements and design before implementation.
Generate realistic synthetic oil & gas data (LAS well logs, SEG-Y seismic, core photos, time-series) with proper physical constraints for testing, demos, and training.
Use when starting any conversation - establishes how to find and use skills, requiring Skill tool invocation before ANY response including clarifying questions
Pre-flight check that determines if brainstorming is required before any action. Invoke this FIRST for any request involving creative or generative work.
Meta-skill that detects software tasks and routes them to appropriate petropowers skills.
Use when you have a written implementation plan to execute in a separate session with review checkpoints