Creating a New SEG-Y¶
Altay Sansal
May 07, 2024
2 min read
In this tutorial, we create a new SEG-Y file from spec.
Let’s start by importing some modules we will be using.
from segy.factory import SegyFactory
from segy.standards.rev1 import rev1_segy
We will take the default SEG-Y Revision 1 specification.
The SegyFactory
takes the spec, number of samples, and sample interval as inputs.
By using its creation functions, we can make the encoded (ready to write to disk)
bytes for file headers (text header and binary header).
SAMPLE_INTERVAL = 4000 # in microseconds
SAMPLES_PER_TRACE = 101
factory = SegyFactory(
rev1_segy, sample_interval=SAMPLE_INTERVAL, samples_per_trace=SAMPLES_PER_TRACE
)
txt = factory.create_textual_header()
bin_ = factory.create_binary_header()
Let’s create 15 traces and populate their values. Headers by default will be populated
by sample rate and number of samples. We will set some fake headers. We will also fill
in the trace samples with trace_no
+ sample_index
.
TRACE_COUNT = 15
headers = factory.create_trace_header_template(size=TRACE_COUNT)
samples = factory.create_trace_sample_template(size=TRACE_COUNT)
for trace_idx in range(TRACE_COUNT):
headers[trace_idx]["trace_seq_file"] = trace_idx + 1
headers[trace_idx]["x_coordinate"] = 1_000
headers[trace_idx]["y_coordinate"] = 10_000 + trace_idx * 50
headers[trace_idx]["inline_no"] = 10
headers[trace_idx]["crossline_no"] = 100 + trace_idx
samples[trace_idx] = range(SAMPLES_PER_TRACE) # sample index
samples[trace_idx] += trace_idx # trace no
Now we can create the encoded binary values for traces (ready to write).
traces = factory.create_traces(samples=samples, headers=headers)
We can now compose a binary SEG-Y file from pieces.
We create a new my_segy.sgy
file and write the pieces we built.
from pathlib import Path
with Path("my_segy.sgy").open(mode="wb") as fp:
fp.write(txt)
fp.write(bin_)
fp.write(traces)
Opening New SEG-Y¶
Now we can open it with SegyFile
.
Note that our factory correctly populated the revision number in the header so the spec is automatically inferred!
from segy.file import SegyFile
file = SegyFile("my_segy.sgy")
print(file.text_header)
C01 File written by the open-source segy library.
C02
C03 Website: https://segy.readthedocs.io
C04 Source: https://github.com/TGSAI/segy
C05
C06
C07
C08
C09
C10
C11
C12
C13
C14
C15
C16
C17
C18
C19
C20
C21
C22
C23
C24
C25
C26
C27
C28
C29
C30
C31
C32
C33
C34
C35
C36
C37
C38
C39
C40 END TEXTUAL HEADER
file.binary_header.to_dataframe()
job_id | line_no | reel_no | data_traces_ensemble | aux_traces_ensemble | sample_interval | sample_interval_orig | samples_per_trace | samples_per_trace_orig | data_sample_format | ... | correlated_traces | binary_gain | amp_recovery_method | measurement_system | impulse_signal_polarity | vibratory_polarity | seg_y_revision | fixed_length_trace_flag | extended_textual_headers | additional_trace_headers | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 0 | 0 | 0 | 0 | 0 | 4000 | 4000 | 101 | 101 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 256 | 0 | 0 | 0 |
1 rows × 31 columns
file.sample[:]
array([[ 0., 1., 2., ..., 98., 99., 100.],
[ 1., 2., 3., ..., 99., 100., 101.],
[ 2., 3., 4., ..., 100., 101., 102.],
...,
[ 12., 13., 14., ..., 110., 111., 112.],
[ 13., 14., 15., ..., 111., 112., 113.],
[ 14., 15., 16., ..., 112., 113., 114.]], dtype=float32)
show_fields = [
"trace_seq_file",
"x_coordinate",
"y_coordinate",
"inline_no",
"crossline_no",
]
file.header[:][show_fields].to_dataframe()
trace_seq_file | x_coordinate | y_coordinate | inline_no | crossline_no | |
---|---|---|---|---|---|
0 | 1 | 1000 | 10000 | 10 | 100 |
1 | 2 | 1000 | 10050 | 10 | 101 |
2 | 3 | 1000 | 10100 | 10 | 102 |
3 | 4 | 1000 | 10150 | 10 | 103 |
4 | 5 | 1000 | 10200 | 10 | 104 |
5 | 6 | 1000 | 10250 | 10 | 105 |
6 | 7 | 1000 | 10300 | 10 | 106 |
7 | 8 | 1000 | 10350 | 10 | 107 |
8 | 9 | 1000 | 10400 | 10 | 108 |
9 | 10 | 1000 | 10450 | 10 | 109 |
10 | 11 | 1000 | 10500 | 10 | 110 |
11 | 12 | 1000 | 10550 | 10 | 111 |
12 | 13 | 1000 | 10600 | 10 | 112 |
13 | 14 | 1000 | 10650 | 10 | 113 |
14 | 15 | 1000 | 10700 | 10 | 114 |