Skip to content

Commit ef7ca0d

Browse files
RuslanRuslan
Ruslan
authored and
Ruslan
committed
Added saving in SEGY2d3d and utils for 3d prediction
1 parent 29020cd commit ef7ca0d

File tree

5 files changed

+654
-55
lines changed

5 files changed

+654
-55
lines changed

__init__.py

Whitespace-only changes.

custom_blocks.py

Lines changed: 60 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import streamlit as st
2+
import numpy as np
23
from PIL import Image
3-
from utils import img_to_html_custom, img_to_bytes
4+
from utils import img_to_html_custom, img_to_bytes, save_to_numpy, save_to_segy_2d, save_to_segy_3d
5+
from data_classes import Numpy3D
46
import os
57

68

@@ -18,7 +20,6 @@ def footer():
1820

1921
def sidebar():
2022
with st.sidebar:
21-
col1, col2 = st.columns(2)
2223
st.markdown("""
2324
- **Seismic Type:** {}
2425
- **Seismic Name:** {}
@@ -33,3 +34,60 @@ def sidebar():
3334
3435
""")
3536

37+
def crop_and_load_volume(data, converted_to_numpy3d, cropped_info):
38+
with st.form("Cropping"):
39+
col1, col2, col3 = st.columns(3)
40+
inlines_indx = col1.slider( 'Select a range for Inlines',
41+
0, data.get_n_ilines()-1, (0, data.get_n_ilines()))
42+
43+
xlines_indx = col2.slider( 'Select a range for Xlines',
44+
0, data.get_n_xlines()-1, (0, data.get_n_xlines()))
45+
46+
zslice_indx = col3.slider( 'Select a range for Zslice',
47+
0, data.get_n_zslices()-1, (0, data.get_n_zslices()))
48+
49+
# Every form must have a submit button.
50+
submitted = st.form_submit_button("Submit")
51+
if submitted:
52+
cropped_info = np.array([[inlines_indx[0], inlines_indx[1]], \
53+
[xlines_indx[0], xlines_indx[1]], \
54+
[zslice_indx[0], zslice_indx[1]]])
55+
np_data = data.cropped_numpy(inlines_indx[0], inlines_indx[1], \
56+
xlines_indx[0], xlines_indx[1],\
57+
zslice_indx[0], zslice_indx[1])
58+
converted_to_numpy3d = Numpy3D(np_data)
59+
col1, col2, col3 = st.columns(3)
60+
col1.info(f"Number of Inlines [{inlines_indx[1]-inlines_indx[0]}]")
61+
col2.info(f"Number of Xlines [{xlines_indx[1] - xlines_indx[0]}]")
62+
col3.info(f"Time [{zslice_indx[1]-zslice_indx[0]}]")
63+
st.success('Volume is loaded')
64+
return converted_to_numpy3d, cropped_info
65+
66+
def save_data_form(session_state, seismic, numpy_data, status):
67+
with st.form("save_data"):
68+
col1, col2, col3 = st.columns(3)
69+
path = col1.text_input("Path to Folder")
70+
file_name = col2.text_input("File Name")
71+
file_format = col3.radio( "What format? ", ('SEGY', 'NUMPY_SUBSET'))
72+
submitted = st.form_submit_button("Save")
73+
if submitted:
74+
if file_format == "SEGY":
75+
if seismic.get_str_format() == "SEGY":
76+
if seismic.get_str_dim() == "2D":
77+
save_to_segy_2d(seismic, path+file_name, numpy_data, session_state)
78+
else:
79+
save_to_segy_3d(seismic, path+file_name, numpy_data, session_state)
80+
status = "Saving SEGY complete"
81+
else:
82+
status = "Error: you can not save a SEGY file since the initial seismic was not SEGY."
83+
else:
84+
save_to_numpy(path+file_name, numpy_data)
85+
status = "Saving NUMPY complete"
86+
# option = st.radio( "Option", ('Save subset', 'Save in original dimensions - It will create the volume in RAM. Are you sure?'))
87+
# if st.form_submit_button("Save "):
88+
# if option == 'Save subset':
89+
# status = None
90+
# save_to_numpy(path+file_name, numpy_data)
91+
# else:
92+
# status = "Save in original dimensions"
93+
return status

data_classes.py

Lines changed: 127 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from abc import ABC, abstractmethod
2+
from unittest import result
23
import segyio
34
import numpy as np
45
import random
@@ -47,19 +48,21 @@ def get_sample_rate(self):
4748

4849
@abstractmethod
4950
def get_vm(self):
50-
return self.vm
51-
52-
51+
pass
5352

5453
class SegyIO3D(SeismicData):
5554

5655
def __init__(self, file_name, iline_byte=189, xline_byte=193):
56+
super().__init__()
5757
self._segyfile = segyio.open(file_name, iline=int(iline_byte), xline=int(xline_byte))
5858

5959
# get statistics for visualization
6060
n_slices = 10
6161
seis = [self.get_iline(random.randint(0, self.get_n_ilines()-1)) for i in range(n_slices)]
6262
self.vm = np.percentile(seis, 95)
63+
self.file_name = file_name
64+
self.iline_byte = iline_byte
65+
self.xline_byte = xline_byte
6366

6467
def __del__(self):
6568
self._segyfile.close()
@@ -93,9 +96,43 @@ def get_sample_rate(self):
9396
def get_vm(self):
9497
return self.vm
9598

99+
def get_file_name(self):
100+
return self.file_name
101+
102+
def cropped_numpy(self, min_il, max_il, min_xl, max_xl, min_z, max_z):
103+
""" Reads cropped seismic and returns numpy array
104+
105+
Args:
106+
min_il (_type_): min inline
107+
max_il (_type_): max inline
108+
min_xl (_type_): min crossline
109+
max_xl (_type_): max crossline
110+
min_z (_type_): min timeslice
111+
max_z (_type_): max timeslice
112+
"""
113+
assert max_il>min_il, f"max_il must be greater than {min_il}, got: {max_il}"
114+
assert max_xl>min_xl, f"max_il must be greater than {min_xl}, got: {max_xl}"
115+
assert max_z>min_z, f"max_il must be greater than {min_z}, got: {max_z}"
116+
117+
return np.array([self.get_iline(i)[min_xl:max_xl, min_z:max_z] for i in range(min_il, max_il)])
118+
119+
def get_xline_byte(self):
120+
return self.xline_byte
121+
122+
def get_iline_byte(self):
123+
return self.iline_byte
124+
125+
def get_str_format(self):
126+
return "SEGY"
127+
128+
def get_str_dim(self):
129+
return "2D"
130+
131+
96132
class SegyIO2D(SeismicData):
97133

98134
def __init__(self, file_name):
135+
super().__init__()
99136
seismic_type = "2D"
100137
try:
101138
with segyio.open(file_name, strict=True) as segyfile:
@@ -108,10 +145,15 @@ def __init__(self, file_name):
108145
self._data = np.stack(list((_.copy() for _ in segyfile.trace[:])))
109146
self._dt = segyio.tools.dt(segyfile)
110147
self.vm = np.percentile(self._data, 95)
148+
self.file_name = file_name
149+
111150

112151
def __del__(self):
113152
pass
114153

154+
def get_file_name(self):
155+
return self.file_name
156+
115157
def get_iline(self):
116158
return self._data.T
117159

@@ -124,11 +166,11 @@ def get_zslice(self,):
124166

125167
# get total number of ilines
126168
def get_n_ilines(self):
127-
return self._data.shape[0]
169+
pass
128170

129171
# get total number of xlines
130172
def get_n_xlines(self):
131-
pass
173+
return self._data.shape[0]
132174

133175
# get total number of zslices
134176
def get_n_zslices(self):
@@ -144,10 +186,24 @@ def make_axis_devisable_by(self, factor):
144186
xlim = self._data.shape[0]//int(factor)*int(factor)
145187
ylim = self._data.shape[1]//int(factor)*int(factor)
146188
self._data = self._data[:xlim, :ylim]
189+
190+
def get_xline_byte(self):
191+
return self.xline_byte
192+
193+
def get_iline_byte(self):
194+
return self.iline_byte
195+
196+
def get_str_format(self):
197+
return "SEGY"
198+
199+
def get_str_dim(self):
200+
return "2D"
201+
147202

148203
class Numpy2D(SeismicData):
149204

150205
def __init__(self, file_name):
206+
super().__init__()
151207
self._data = np.load(file_name)
152208

153209
# get statistics for visualization
@@ -167,11 +223,11 @@ def get_zslice(self):
167223
pass
168224

169225
def get_n_ilines(self):
170-
return self._data.shape[0]
226+
pass
171227

172228
# get total number of xlines
173229
def get_n_xlines(self):
174-
pass
230+
return self._data.shape[0]
175231

176232
def get_n_zslices(self):
177233
return self._data.shape[1]
@@ -185,4 +241,67 @@ def get_vm(self):
185241
def make_axis_devisable_by(self, factor):
186242
xlim = self._data.shape[0]//int(factor)*int(factor)
187243
ylim = self._data.shape[1]//int(factor)*int(factor)
188-
self._data = self._data[:xlim, :ylim]
244+
self._data = self._data[:xlim, :ylim]
245+
246+
def get_str_format(self):
247+
return "NUMPY"
248+
249+
def get_str_dim(self):
250+
return "2D"
251+
252+
class Numpy3D(SeismicData):
253+
254+
def __init__(self, data):
255+
super().__init__()
256+
if isinstance(data, str):
257+
self._data = np.load(data)
258+
elif isinstance(data, np.ndarray):
259+
self._data = data
260+
261+
# get statistics for visualization
262+
if self._data is not None:
263+
n_slices = 10
264+
seis = [self.get_iline(random.randint(0, self.get_n_ilines()-1)) for i in range(n_slices)]
265+
self.vm = np.percentile(seis, 95)
266+
267+
def __del__(self):
268+
pass
269+
270+
def get_iline(self, indx):
271+
return self._data[indx,:,:]
272+
273+
def get_xline(self, indx):
274+
return self._data[:,indx,:]
275+
276+
def get_zslice(self, indx):
277+
return self._data[:,:,indx]
278+
279+
def get_n_ilines(self):
280+
return self._data.shape[0]
281+
282+
# get total number of xlines
283+
def get_n_xlines(self):
284+
return self._data.shape[1]
285+
286+
def get_n_zslices(self):
287+
return self._data.shape[2]
288+
289+
def get_sample_rate(self):
290+
return 1000
291+
292+
def get_vm(self):
293+
return self.vm
294+
295+
def get_cube(self):
296+
return self._data
297+
298+
def make_axis_devisable_by(self, factor):
299+
xlim = self._data.shape[0]//int(factor)*int(factor)
300+
ylim = self._data.shape[1]//int(factor)*int(factor)
301+
self._data = self._data[:xlim, :ylim, :]
302+
303+
def get_str_format(self):
304+
return "NUMPY"
305+
306+
def get_str_dim(self):
307+
return "3D"

0 commit comments

Comments
 (0)