The library is imported as segysak and the loaded xarray
objects are compatible with numpy and matplotlib.
The cropped volume from the Volve field in the North Sea (made available by Equinor) is used for this example, and
all the examples and data in this documentation are available from the examples
folder of the
Github respository.
import matplotlib.pyplot as plt
import pathlib
V3D_path = pathlib.Path("data/volve10r12-full-twt-sub3d.sgy")
print("3D", V3D_path, V3D_path.exists())
3D data/volve10r12-full-twt-sub3d.sgy True
Scan SEG-Y headers¶
A basic operation would be to check the text header included in the SEG-Y file. The get_segy_texthead
function accounts for common encoding issues and returns the header as a text string. It is important to check the text header if you are unfamiliar with your data, it may provide important information about the contents/location of trace header values which are needed by SEGY-SAK to successfully load your data into a xarray.Dataset
.
from segysak.segy import get_segy_texthead
get_segy_texthead(V3D_path)
Text Header
C 1 SEGY OUTPUT FROM Petrel 2017.2 Saturday, June 06 2020 10:15:00
C 2 Name: ST10010ZDC12-PZ-PSDM-KIRCH-FULL-T.MIG_FIN.POST_STACK.3D.JS-017534 ÝCro
C 3
C 4 First inline: 10090 Last inline: 10150
C 5 First xline: 2150 Last xline: 2351
C 6 CRS: ED50-UTM31 ("MENTOR:ED50-UTM31:European 1950 Based UTM, Zone 31 North,
C 7 X min: 433955.09 max: 436589.56 delta: 2634.47
C 8 Y min: 6477439.46 max: 6478790.23 delta: 1350.77
C 9 Time min: -3402.00 max: -2.00 delta: 3400.00
C10 Lat min: 58.25'52.8804"N max: 58.26'37.9493"N delta: 0.00'45.0689"
C11 Long min: 1.52'7.1906"E max: 1.54'50.9616"E delta: 0.02'43.7710"
C12 Trace min: -3400.00 max: -4.00 delta: 3396.00
C13 Seismic (template) min: -58.55 max: 54.55 delta: 113.10
C14 Amplitude (data) min: -58.55 max: 54.55 delta: 113.10
C15 Trace sample format: IEEE floating point
C16 Coordinate scale factor: 100.00000
C17
C18 Binary header locations:
C19 Sample interval : bytes 17-18
C20 Number of samples per trace : bytes 21-22
C21 Trace date format : bytes 25-26
C22
C23 Trace header locations:
C24 Inline number : bytes 5-8
C25 Xline number : bytes 21-24
C26 Coordinate scale factor : bytes 71-72
C27 X coordinate : bytes 73-76
C28 Y coordinate : bytes 77-80
C29 Trace start time/depth : bytes 109-110
C30 Number of samples per trace : bytes 115-116
C31 Sample interval : bytes 117-118
C32
C33
C34
C35
C36
C37
C38
C39
C40 END EBCDIC
If you need to investigate the trace header data more deeply, then segy_header_scan can be used to report basic statistics of each byte position for a limited number of traces.
segy_header_scan returns a pandas.DataFrame
. To see the full DataFrame use the pandas
option_context manager.
from segysak.segy import segy_header_scan
import pandas as pd
scan = segy_header_scan(V3D_path)
with pd.option_context("display.max_rows", 100, "display.max_columns", 10):
# drop byte locations where the mean is zero, these are likely empty.
display(scan)
byte_loc | count | mean | std | min | 25% | 50% | 75% | max | |
---|---|---|---|---|---|---|---|---|---|
TRACE_SEQUENCE_LINE | 1 | 1000.0 | 1.005400e+02 | 57.831072 | 1.0 | 5.075000e+01 | 100.5 | 1.502500e+02 | 202.0 |
TRACE_SEQUENCE_FILE | 5 | 1000.0 | 1.009198e+04 | 1.407687 | 10090.0 | 1.009100e+04 | 10092.0 | 1.009300e+04 | 10094.0 |
FieldRecord | 9 | 1000.0 | 1.009198e+04 | 1.407687 | 10090.0 | 1.009100e+04 | 10092.0 | 1.009300e+04 | 10094.0 |
TraceNumber | 13 | 1000.0 | 1.005400e+02 | 57.831072 | 1.0 | 5.075000e+01 | 100.5 | 1.502500e+02 | 202.0 |
EnergySourcePoint | 17 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
CDP | 21 | 1000.0 | 2.249540e+03 | 57.831072 | 2150.0 | 2.199750e+03 | 2249.5 | 2.299250e+03 | 2351.0 |
CDP_TRACE | 25 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
TraceIdentificationCode | 29 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
NSummedTraces | 31 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
NStackedTraces | 33 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
DataUse | 35 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
offset | 37 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
ReceiverGroupElevation | 41 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceSurfaceElevation | 45 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceDepth | 49 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
ReceiverDatumElevation | 53 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceDatumElevation | 57 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceWaterDepth | 61 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
GroupWaterDepth | 65 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
ElevationScalar | 69 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
SourceGroupScalar | 71 | 1000.0 | -1.000000e+02 | 0.000000 | -100.0 | -1.000000e+02 | -100.0 | -1.000000e+02 | -100.0 |
SourceX | 73 | 1000.0 | 4.351992e+07 | 70152.496037 | 43396267.0 | 4.345933e+07 | 43519976.5 | 4.358062e+07 | 43641261.0 |
SourceY | 77 | 1000.0 | 6.477772e+08 | 17532.885301 | 647744704.0 | 6.477622e+08 | 647777222.0 | 6.477923e+08 | 647809133.0 |
GroupX | 81 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
GroupY | 85 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
CoordinateUnits | 89 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
WeatheringVelocity | 91 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SubWeatheringVelocity | 93 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceUpholeTime | 95 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
GroupUpholeTime | 97 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceStaticCorrection | 99 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
GroupStaticCorrection | 101 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TotalStaticApplied | 103 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
LagTimeA | 105 | 1000.0 | 4.000000e+00 | 0.000000 | 4.0 | 4.000000e+00 | 4.0 | 4.000000e+00 | 4.0 |
LagTimeB | 107 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
DelayRecordingTime | 109 | 1000.0 | 4.000000e+00 | 0.000000 | 4.0 | 4.000000e+00 | 4.0 | 4.000000e+00 | 4.0 |
MuteTimeStart | 111 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
MuteTimeEND | 113 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TRACE_SAMPLE_COUNT | 115 | 1000.0 | 8.500000e+02 | 0.000000 | 850.0 | 8.500000e+02 | 850.0 | 8.500000e+02 | 850.0 |
TRACE_SAMPLE_INTERVAL | 117 | 1000.0 | 4.000000e+03 | 0.000000 | 4000.0 | 4.000000e+03 | 4000.0 | 4.000000e+03 | 4000.0 |
GainType | 119 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
InstrumentGainConstant | 121 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
InstrumentInitialGain | 123 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
Correlated | 125 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
SweepFrequencyStart | 127 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SweepFrequencyEnd | 129 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SweepLength | 131 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SweepType | 133 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
SweepTraceTaperLengthStart | 135 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SweepTraceTaperLengthEnd | 137 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TaperType | 139 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
AliasFilterFrequency | 141 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
AliasFilterSlope | 143 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
NotchFilterFrequency | 145 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
NotchFilterSlope | 147 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
LowCutFrequency | 149 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
HighCutFrequency | 151 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
LowCutSlope | 153 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
HighCutSlope | 155 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
YearDataRecorded | 157 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
DayOfYear | 159 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
HourOfDay | 161 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
MinuteOfHour | 163 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SecondOfMinute | 165 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TimeBaseCode | 167 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
TraceWeightingFactor | 169 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
GeophoneGroupNumberRoll1 | 171 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
GeophoneGroupNumberFirstTraceOrigField | 173 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
GeophoneGroupNumberLastTraceOrigField | 175 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
GapSize | 177 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
OverTravel | 179 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
CDP_X | 181 | 1000.0 | 4.351992e+07 | 70152.496037 | 43396267.0 | 4.345933e+07 | 43519976.5 | 4.358062e+07 | 43641261.0 |
CDP_Y | 185 | 1000.0 | 6.477772e+08 | 17532.885301 | 647744704.0 | 6.477622e+08 | 647777222.0 | 6.477923e+08 | 647809133.0 |
INLINE_3D | 189 | 1000.0 | 1.009198e+04 | 1.407687 | 10090.0 | 1.009100e+04 | 10092.0 | 1.009300e+04 | 10094.0 |
CROSSLINE_3D | 193 | 1000.0 | 2.249540e+03 | 57.831072 | 2150.0 | 2.199750e+03 | 2249.5 | 2.299250e+03 | 2351.0 |
ShotPoint | 197 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
ShotPointScalar | 201 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TraceValueMeasurementUnit | 203 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TransductionConstantMantissa | 205 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TransductionConstantPower | 209 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TransductionUnit | 211 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
TraceIdentifier | 213 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
ScalarTraceHeader | 215 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceType | 217 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceEnergyDirectionMantissa | 219 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceEnergyDirectionExponent | 223 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceMeasurementMantissa | 225 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceMeasurementExponent | 229 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
SourceMeasurementUnit | 231 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
UnassignedInt1 | 233 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
UnassignedInt2 | 237 | 1000.0 | 0.000000e+00 | 0.000000 | 0.0 | 0.000000e+00 | 0.0 | 0.000000e+00 | 0.0 |
The header report can also be reduced by filtering blank byte locations. Here we use the standard deviation std
to filter away blank values which can help us to understand the composition of the data.
For instance, key values like trace UTM coordinates are located in bytes 73 for X & 77 for Y. We can also see the byte positions of the local grid for INLINE_3D in byte 189 and for CROSSLINE_3D in byte 193.
scan[scan["mean"] > 0]
byte_loc | count | mean | std | min | 25% | 50% | 75% | max | |
---|---|---|---|---|---|---|---|---|---|
TRACE_SEQUENCE_LINE | 1 | 1000.0 | 1.005400e+02 | 57.831072 | 1.0 | 5.075000e+01 | 100.5 | 1.502500e+02 | 202.0 |
TRACE_SEQUENCE_FILE | 5 | 1000.0 | 1.009198e+04 | 1.407687 | 10090.0 | 1.009100e+04 | 10092.0 | 1.009300e+04 | 10094.0 |
FieldRecord | 9 | 1000.0 | 1.009198e+04 | 1.407687 | 10090.0 | 1.009100e+04 | 10092.0 | 1.009300e+04 | 10094.0 |
TraceNumber | 13 | 1000.0 | 1.005400e+02 | 57.831072 | 1.0 | 5.075000e+01 | 100.5 | 1.502500e+02 | 202.0 |
CDP | 21 | 1000.0 | 2.249540e+03 | 57.831072 | 2150.0 | 2.199750e+03 | 2249.5 | 2.299250e+03 | 2351.0 |
CDP_TRACE | 25 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
TraceIdentificationCode | 29 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
DataUse | 35 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
ElevationScalar | 69 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
SourceX | 73 | 1000.0 | 4.351992e+07 | 70152.496037 | 43396267.0 | 4.345933e+07 | 43519976.5 | 4.358062e+07 | 43641261.0 |
SourceY | 77 | 1000.0 | 6.477772e+08 | 17532.885301 | 647744704.0 | 6.477622e+08 | 647777222.0 | 6.477923e+08 | 647809133.0 |
CoordinateUnits | 89 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
LagTimeA | 105 | 1000.0 | 4.000000e+00 | 0.000000 | 4.0 | 4.000000e+00 | 4.0 | 4.000000e+00 | 4.0 |
DelayRecordingTime | 109 | 1000.0 | 4.000000e+00 | 0.000000 | 4.0 | 4.000000e+00 | 4.0 | 4.000000e+00 | 4.0 |
TRACE_SAMPLE_COUNT | 115 | 1000.0 | 8.500000e+02 | 0.000000 | 850.0 | 8.500000e+02 | 850.0 | 8.500000e+02 | 850.0 |
TRACE_SAMPLE_INTERVAL | 117 | 1000.0 | 4.000000e+03 | 0.000000 | 4000.0 | 4.000000e+03 | 4000.0 | 4.000000e+03 | 4000.0 |
Correlated | 125 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
SweepType | 133 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
TaperType | 139 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
TimeBaseCode | 167 | 1000.0 | 1.000000e+00 | 0.000000 | 1.0 | 1.000000e+00 | 1.0 | 1.000000e+00 | 1.0 |
CDP_X | 181 | 1000.0 | 4.351992e+07 | 70152.496037 | 43396267.0 | 4.345933e+07 | 43519976.5 | 4.358062e+07 | 43641261.0 |
CDP_Y | 185 | 1000.0 | 6.477772e+08 | 17532.885301 | 647744704.0 | 6.477622e+08 | 647777222.0 | 6.477923e+08 | 647809133.0 |
INLINE_3D | 189 | 1000.0 | 1.009198e+04 | 1.407687 | 10090.0 | 1.009100e+04 | 10092.0 | 1.009300e+04 | 10094.0 |
CROSSLINE_3D | 193 | 1000.0 | 2.249540e+03 | 57.831072 | 2150.0 | 2.199750e+03 | 2249.5 | 2.299250e+03 | 2351.0 |
To retreive the raw header content (values) use segy_header_scrape
. Setting partial_scan=None
will return the
full dataframe of trace header information.
from segysak.segy import segy_header_scrape
scrape = segy_header_scrape(V3D_path, partial_scan=1000)
scrape
TRACE_SEQUENCE_LINE | TRACE_SEQUENCE_FILE | FieldRecord | TraceNumber | EnergySourcePoint | CDP | CDP_TRACE | TraceIdentificationCode | NSummedTraces | NStackedTraces | ... | TraceIdentifier | ScalarTraceHeader | SourceType | SourceEnergyDirectionMantissa | SourceEnergyDirectionExponent | SourceMeasurementMantissa | SourceMeasurementExponent | SourceMeasurementUnit | UnassignedInt1 | UnassignedInt2 | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | 10090 | 10090 | 1 | 0 | 2150 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1 | 2 | 10090 | 10090 | 2 | 0 | 2151 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
2 | 3 | 10090 | 10090 | 3 | 0 | 2152 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
3 | 4 | 10090 | 10090 | 4 | 0 | 2153 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
4 | 5 | 10090 | 10090 | 5 | 0 | 2154 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
995 | 188 | 10094 | 10094 | 188 | 0 | 2337 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
996 | 189 | 10094 | 10094 | 189 | 0 | 2338 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
997 | 190 | 10094 | 10094 | 190 | 0 | 2339 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
998 | 191 | 10094 | 10094 | 191 | 0 | 2340 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
999 | 192 | 10094 | 10094 | 192 | 0 | 2341 | 1 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
1000 rows × 91 columns
Load SEG-Y data¶
All SEG-Y (2D, 2D gathers, 3D & 3D gathers) are ingested into xarray.Dataset
using the Xarray SEGY engine provided by
segysak. The engine recognizes the '.segy' and .sgy' extensions automatically when passed to
xr.open_dataset(). It is important to provide the
dim_bytes_fieldsand if required the
extra_bytes_fields` variables.
dim_byte_fields
specifies the byte locations which determine the orthogonal geometry of your data. This could be CDP for 2D data,
iline and xline for 3D data, or iline, xline and offset for pre-stack gathers over 3D data. UTM coordinates are not usually valid dimensions,
because if a survey is rotated relative to the UTM grid, you do not get orthogonal dimensions.
UTM coordinates and other trace header information you require can be loaded via the extra_bytes_fields
argument.
Note that the keys you use to label byte fields will be the keys of the dimensions and variables loaded into the dataset.
Since v0.5 of SEGY-SAK, the vertical dimension is always labelled as
samples
.
import xarray as xr
V3D = xr.open_dataset(
V3D_path,
dim_byte_fields={"iline": 189, "xline": 193},
extra_byte_fields={"cdp_x": 73, "cdp_y": 77},
)
V3D
<xarray.Dataset> Size: 42MB Dimensions: (iline: 61, xline: 202, samples: 850) Coordinates: * iline (iline) int16 122B 10090 10091 10092 10093 ... 10148 10149 10150 * xline (xline) int16 404B 2150 2151 2152 2153 2154 ... 2348 2349 2350 2351 * samples (samples) float32 3kB 4.0 8.0 12.0 ... 3.392e+03 3.396e+03 3.4e+03 Data variables: cdp_x (iline, xline) int32 49kB ... cdp_y (iline, xline) int32 49kB ... data (iline, xline, samples) float32 42MB ... Attributes: seisnc: {"coord_scalar": -100.0, "coord_scaled": false}
Visualising data¶
xarray
objects use smart label based indexing techniques to retreive subsets of data. More
details on xarray
techniques for segysak are covered in the examples, but this demonstrates
a general syntax for selecting data by label with xarray
. Plotting is done by matploblib
and
xarray
selections can be passed to normal matplotlib.pyplot
functions.
fig, ax1 = plt.subplots(ncols=1, figsize=(15, 8))
iline_sel = 10093
V3D.data.transpose("samples", "iline", "xline", transpose_coords=True).sel(
iline=iline_sel
).plot(yincrease=False, cmap="seismic_r")
plt.grid("grey")
plt.ylabel("TWT")
plt.xlabel("XLINE")
Text(0.5, 0, 'XLINE')
Saving data to NetCDF4¶
SEGYSAK now loads data in a way that is compatable with the standard to_netcdf
method of an xarray.Dataset
. To output data to NetCDF4, simply specify the output file and Xarray should take care of the rest. If you have a particularly large SEG-Y file, that will not fit into memory, then you may need to chunk the dataset first prior to output. This will ensure lazy loading and output of data.
V3D.to_netcdf("data/V3D.nc")
# Here the seismic volume to process one INLINE at a time to the NetCDF4 file.
V3D.chunk({"iline": 1, "xline": -1, "samples": -1}).to_netcdf("data/V3D_chks.nc")
Saving data to SEG-Y¶
To return data to SEG-Y after modification use the seisio
accessor provided by SEGY-SAK. Unlike the to_netcdf
method. Additional arguments are required by to_segy
to successfuly write a SEG-Y file with appropriate header information. At a minimum, this should include byte locations for each dimension in the Dataset, but additional variables can be written to trace headers as required.
V3D.seisio.to_segy(
"data/V3D-out.segy",
trace_header_map={"cdp_x": 73, "cdp_y": 77},
iline=189,
xline=193,
)