subsurface-terra 2025.1.0rc15__py3-none-any.whl → 2025.1.0rc17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- subsurface/__init__.py +31 -31
- subsurface/_version.py +34 -21
- subsurface/api/__init__.py +13 -13
- subsurface/api/interfaces/__init__.py +3 -3
- subsurface/api/interfaces/stream.py +136 -136
- subsurface/api/reader/read_wells.py +78 -78
- subsurface/core/geological_formats/boreholes/_combine_trajectories.py +117 -117
- subsurface/core/geological_formats/boreholes/_map_attrs_to_survey.py +236 -234
- subsurface/core/geological_formats/boreholes/_survey_to_unstruct.py +163 -163
- subsurface/core/geological_formats/boreholes/boreholes.py +140 -140
- subsurface/core/geological_formats/boreholes/collars.py +26 -26
- subsurface/core/geological_formats/boreholes/survey.py +86 -86
- subsurface/core/geological_formats/fault.py +47 -47
- subsurface/core/reader_helpers/reader_unstruct.py +11 -11
- subsurface/core/reader_helpers/readers_data.py +130 -130
- subsurface/core/reader_helpers/readers_wells.py +13 -13
- subsurface/core/structs/__init__.py +3 -3
- subsurface/core/structs/base_structures/__init__.py +2 -2
- subsurface/core/structs/base_structures/_aux.py +69 -0
- subsurface/core/structs/base_structures/_liquid_earth_mesh.py +121 -121
- subsurface/core/structs/base_structures/_unstructured_data_constructor.py +70 -70
- subsurface/core/structs/base_structures/base_structures_enum.py +6 -6
- subsurface/core/structs/base_structures/structured_data.py +282 -282
- subsurface/core/structs/base_structures/unstructured_data.py +338 -319
- subsurface/core/structs/structured_elements/octree_mesh.py +10 -10
- subsurface/core/structs/structured_elements/structured_grid.py +59 -59
- subsurface/core/structs/structured_elements/structured_mesh.py +9 -9
- subsurface/core/structs/unstructured_elements/__init__.py +3 -3
- subsurface/core/structs/unstructured_elements/line_set.py +72 -72
- subsurface/core/structs/unstructured_elements/point_set.py +43 -43
- subsurface/core/structs/unstructured_elements/tetrahedron_mesh.py +35 -35
- subsurface/core/structs/unstructured_elements/triangular_surface.py +62 -62
- subsurface/core/utils/utils_core.py +38 -38
- subsurface/modules/reader/__init__.py +13 -13
- subsurface/modules/reader/faults/faults.py +80 -80
- subsurface/modules/reader/from_binary.py +46 -46
- subsurface/modules/reader/mesh/_GOCAD_mesh.py +82 -82
- subsurface/modules/reader/mesh/_trimesh_reader.py +447 -447
- subsurface/modules/reader/mesh/csv_mesh_reader.py +53 -53
- subsurface/modules/reader/mesh/dxf_reader.py +177 -177
- subsurface/modules/reader/mesh/glb_reader.py +30 -30
- subsurface/modules/reader/mesh/mx_reader.py +232 -232
- subsurface/modules/reader/mesh/obj_reader.py +53 -53
- subsurface/modules/reader/mesh/omf_mesh_reader.py +43 -43
- subsurface/modules/reader/mesh/surface_reader.py +56 -56
- subsurface/modules/reader/mesh/surfaces_api.py +41 -41
- subsurface/modules/reader/profiles/__init__.py +3 -3
- subsurface/modules/reader/profiles/profiles_core.py +197 -197
- subsurface/modules/reader/read_netcdf.py +38 -38
- subsurface/modules/reader/topography/__init__.py +7 -7
- subsurface/modules/reader/topography/topo_core.py +100 -100
- subsurface/modules/reader/volume/read_grav3d.py +447 -428
- subsurface/modules/reader/volume/read_volume.py +327 -230
- subsurface/modules/reader/volume/segy_reader.py +105 -105
- subsurface/modules/reader/volume/seismic.py +173 -173
- subsurface/modules/reader/volume/volume_utils.py +43 -43
- subsurface/modules/reader/wells/DEP/__init__.py +43 -43
- subsurface/modules/reader/wells/DEP/_well_files_reader.py +167 -167
- subsurface/modules/reader/wells/DEP/_wells_api.py +61 -61
- subsurface/modules/reader/wells/DEP/_welly_reader.py +180 -180
- subsurface/modules/reader/wells/DEP/pandas_to_welly.py +212 -212
- subsurface/modules/reader/wells/_read_to_df.py +57 -57
- subsurface/modules/reader/wells/read_borehole_interface.py +148 -148
- subsurface/modules/reader/wells/wells_utils.py +68 -68
- subsurface/modules/tools/mocking_aux.py +104 -104
- subsurface/modules/visualization/__init__.py +2 -2
- subsurface/modules/visualization/to_pyvista.py +320 -320
- subsurface/modules/writer/to_binary.py +12 -12
- subsurface/modules/writer/to_rex/common.py +78 -78
- subsurface/modules/writer/to_rex/data_struct.py +74 -74
- subsurface/modules/writer/to_rex/gempy_to_rexfile.py +791 -791
- subsurface/modules/writer/to_rex/material_encoder.py +44 -44
- subsurface/modules/writer/to_rex/mesh_encoder.py +152 -152
- subsurface/modules/writer/to_rex/to_rex.py +115 -115
- subsurface/modules/writer/to_rex/utils.py +15 -15
- subsurface/optional_requirements.py +116 -116
- {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc17.dist-info}/METADATA +194 -194
- subsurface_terra-2025.1.0rc17.dist-info/RECORD +99 -0
- {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc17.dist-info}/WHEEL +1 -1
- {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc17.dist-info}/licenses/LICENSE +203 -203
- subsurface_terra-2025.1.0rc15.dist-info/RECORD +0 -98
- {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc17.dist-info}/top_level.txt +0 -0
|
@@ -1,180 +1,180 @@
|
|
|
1
|
-
import glob
|
|
2
|
-
from typing import List
|
|
3
|
-
|
|
4
|
-
import warnings
|
|
5
|
-
|
|
6
|
-
from pandas import DataFrame
|
|
7
|
-
|
|
8
|
-
from subsurface import optional_requirements
|
|
9
|
-
from subsurface.reader.wells.pandas_to_welly import WellyToSubsurfaceHelper
|
|
10
|
-
import numpy as np
|
|
11
|
-
|
|
12
|
-
from subsurface.structs.base_structures import UnstructuredData
|
|
13
|
-
|
|
14
|
-
welly = optional_requirements.require_welly()
|
|
15
|
-
striplog = optional_requirements.require_striplog()
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
def welly_to_subsurface(
|
|
19
|
-
wts: WellyToSubsurfaceHelper,
|
|
20
|
-
elev=True,
|
|
21
|
-
n_vertex_per_well=50,
|
|
22
|
-
convert_lith=True,
|
|
23
|
-
table: List[striplog.Component] = None,
|
|
24
|
-
**kwargs) -> UnstructuredData:
|
|
25
|
-
"""Method to convert well data to `subsurface.UnstructuredData`
|
|
26
|
-
|
|
27
|
-
Args:
|
|
28
|
-
elev (bool): In general the (x, y, z) array of positions will have
|
|
29
|
-
z as TVD, which is positive down. If `elev` is True, positive
|
|
30
|
-
will be upwards.
|
|
31
|
-
n_vertex_per_well (int): Number of vertex used to describe the geometry of the
|
|
32
|
-
well.
|
|
33
|
-
return_element (bool): if True return a `subsurface.LineSet` instead
|
|
34
|
-
convert_lith (bool): if True convert lith from stiplog to curve
|
|
35
|
-
table (List[Striplog.Component]): List of components to map lithologies
|
|
36
|
-
to value.
|
|
37
|
-
**kwargs:
|
|
38
|
-
`Well.location.trajectory` kwargs
|
|
39
|
-
|
|
40
|
-
Returns:
|
|
41
|
-
|
|
42
|
-
"""
|
|
43
|
-
vertex = np.zeros((0, 3))
|
|
44
|
-
cells = np.zeros((0, 2), dtype=int)
|
|
45
|
-
|
|
46
|
-
last_index = 0
|
|
47
|
-
missed_wells = []
|
|
48
|
-
|
|
49
|
-
for w in wts.p.get_wells():
|
|
50
|
-
if well_without_valid_survey(w, missed_wells): continue
|
|
51
|
-
|
|
52
|
-
cells, vertex, last_index = vertex_and_cells_from_welly_trajectory(
|
|
53
|
-
cells, elev, kwargs, last_index, n_vertex_per_well, vertex, w)
|
|
54
|
-
|
|
55
|
-
change_curve_basis_to_n_vertex_per_well_inplace(n_vertex_per_well, w, wts)
|
|
56
|
-
|
|
57
|
-
# Convert striplog into Curve
|
|
58
|
-
if convert_lith is True:
|
|
59
|
-
if 'lith' in w.data:
|
|
60
|
-
if table is None: table = wts.lith_component_table
|
|
61
|
-
w.data['lith_log'] = striplog_to_curve_log(n_vertex_per_well, table, w, wts)
|
|
62
|
-
else:
|
|
63
|
-
w.data["lith_log"] = welly.Curve(-1 * np.ones(n_vertex_per_well - 1, dtype=int))
|
|
64
|
-
|
|
65
|
-
if w.data["lith_log"].shape[0] != n_vertex_per_well - 1:
|
|
66
|
-
raise ValueError("Cell_attr does not match cells")
|
|
67
|
-
|
|
68
|
-
try:
|
|
69
|
-
df = wts.p.df()
|
|
70
|
-
except ValueError as e:
|
|
71
|
-
if 'objects passed' in str(e):
|
|
72
|
-
df = None
|
|
73
|
-
else:
|
|
74
|
-
raise ValueError
|
|
75
|
-
|
|
76
|
-
print('The following boreholes failed being processed: ', missed_wells)
|
|
77
|
-
|
|
78
|
-
unstructured_data = UnstructuredData.from_array(vertex, cells, df)
|
|
79
|
-
return unstructured_data
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
def striplog_to_curve_log(n_vertex_per_well, table, w: welly.Well, wts: WellyToSubsurfaceHelper) -> welly.Curve:
|
|
83
|
-
start, stop, step_size = wts._calculate_basis_parameters(w, n_vertex_per_well - 1)
|
|
84
|
-
s_log, basis, _table = w.data['lith'].to_log(step_size, start, stop, table=table, return_meta=True)
|
|
85
|
-
return welly.Curve(s_log, basis)
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
def change_curve_basis_to_n_vertex_per_well_inplace(n_points, w, wts):
|
|
89
|
-
start, stop, step_size = wts._calculate_basis_parameters(w, n_points)
|
|
90
|
-
basis = np.arange(start, stop, step_size)
|
|
91
|
-
w.unify_basis(keys=None, basis=basis)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
def vertex_and_cells_from_welly_trajectory(
|
|
95
|
-
cells: np.ndarray, elev: bool,
|
|
96
|
-
welly_trajectory_kwargs: dict,
|
|
97
|
-
last_index: int, n_vertex_for_well: int,
|
|
98
|
-
vertex: np.ndarray, w: welly.Well):
|
|
99
|
-
try:
|
|
100
|
-
datum = w.location.datum
|
|
101
|
-
except AttributeError:
|
|
102
|
-
datum = None
|
|
103
|
-
|
|
104
|
-
xyz = w.location.trajectory(datum=datum, elev=elev, points=n_vertex_for_well, **welly_trajectory_kwargs) # w.location.position
|
|
105
|
-
# Make sure deviation is there
|
|
106
|
-
a = np.arange(0 + last_index, xyz.shape[0] - 1 + last_index, dtype=np.int_)
|
|
107
|
-
b = np.arange(1 + last_index, xyz.shape[0] + last_index, dtype=np.int_)
|
|
108
|
-
cells_b = np.vstack([a, b]).T
|
|
109
|
-
|
|
110
|
-
vertex = np.vstack((vertex, xyz))
|
|
111
|
-
cells = np.vstack((cells, cells_b))
|
|
112
|
-
last_index += xyz.shape[0]
|
|
113
|
-
|
|
114
|
-
return cells, vertex, last_index
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
def well_without_valid_survey(w: welly.Well, missed_wells: List[str]):
|
|
118
|
-
well_without_position = w.location.position is None
|
|
119
|
-
if well_without_position:
|
|
120
|
-
warnings.warn(f'At least one of the wells do not have '
|
|
121
|
-
'assigned a survey. Borehole name: {w.name}')
|
|
122
|
-
missed_wells.append(w.name)
|
|
123
|
-
return well_without_position
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
def _create_welly_well_from_las(well_name: str, las_folder: str):
|
|
127
|
-
"""
|
|
128
|
-
Add well from welly las file.
|
|
129
|
-
|
|
130
|
-
Args:
|
|
131
|
-
well_name (str): Well name
|
|
132
|
-
las_folder (str): Path to las file
|
|
133
|
-
|
|
134
|
-
Returns:
|
|
135
|
-
|
|
136
|
-
"""
|
|
137
|
-
|
|
138
|
-
def _create_well(uwi: str = 'dummy_uwi'):
|
|
139
|
-
w = welly.Well()
|
|
140
|
-
w.location.uwi = well_name
|
|
141
|
-
w.location.name = well_name
|
|
142
|
-
|
|
143
|
-
return w
|
|
144
|
-
|
|
145
|
-
well = _create_well(well_name)
|
|
146
|
-
return add_curves_from_las(well, las_folder)
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
def add_curves_from_las(w: welly.Well, las_folder: str) -> welly.Well:
|
|
150
|
-
""" Add curves from las file. """
|
|
151
|
-
|
|
152
|
-
def _read_curves_to_welly_object(well: welly.Well, curve_path: str = '.') -> welly.Well:
|
|
153
|
-
las_files = glob.glob(curve_path + '*.las')
|
|
154
|
-
# throw error if no las files found
|
|
155
|
-
if len(las_files) == 0:
|
|
156
|
-
raise Exception('No las files found in ' + curve_path)
|
|
157
|
-
|
|
158
|
-
for curve in las_files:
|
|
159
|
-
well.add_curves_from_las(curve)
|
|
160
|
-
return well
|
|
161
|
-
|
|
162
|
-
_read_curves_to_welly_object(w, curve_path=las_folder)
|
|
163
|
-
|
|
164
|
-
w_df = w.df()
|
|
165
|
-
deviation_df = _make_deviation_df(w_df, inclination_header='IMG_INCL', azimuth_header='IMG_AZ')
|
|
166
|
-
w.location.add_deviation(deviation_df)
|
|
167
|
-
return w
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
def _make_deviation_df(well_df: DataFrame, inclination_header: str, azimuth_header: str,
|
|
171
|
-
depth_header: str = '', depth_index=True):
|
|
172
|
-
if depth_index:
|
|
173
|
-
deviation_data = well_df[[inclination_header, azimuth_header]].to_numpy()
|
|
174
|
-
deviation_index = well_df.index.to_numpy()
|
|
175
|
-
deviation_complete = np.insert(deviation_data, 0, deviation_index, axis=1)
|
|
176
|
-
deviation_complete = deviation_complete[~np.isnan(deviation_complete).any(axis=1), :]
|
|
177
|
-
else:
|
|
178
|
-
deviation_complete = well_df[[depth_header, inclination_header, azimuth_header]].to_numpy()
|
|
179
|
-
deviation_complete = deviation_complete[~np.isnan(deviation_complete).any(axis=1), :]
|
|
180
|
-
return deviation_complete
|
|
1
|
+
import glob
|
|
2
|
+
from typing import List
|
|
3
|
+
|
|
4
|
+
import warnings
|
|
5
|
+
|
|
6
|
+
from pandas import DataFrame
|
|
7
|
+
|
|
8
|
+
from subsurface import optional_requirements
|
|
9
|
+
from subsurface.reader.wells.pandas_to_welly import WellyToSubsurfaceHelper
|
|
10
|
+
import numpy as np
|
|
11
|
+
|
|
12
|
+
from subsurface.structs.base_structures import UnstructuredData
|
|
13
|
+
|
|
14
|
+
welly = optional_requirements.require_welly()
|
|
15
|
+
striplog = optional_requirements.require_striplog()
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def welly_to_subsurface(
|
|
19
|
+
wts: WellyToSubsurfaceHelper,
|
|
20
|
+
elev=True,
|
|
21
|
+
n_vertex_per_well=50,
|
|
22
|
+
convert_lith=True,
|
|
23
|
+
table: List[striplog.Component] = None,
|
|
24
|
+
**kwargs) -> UnstructuredData:
|
|
25
|
+
"""Method to convert well data to `subsurface.UnstructuredData`
|
|
26
|
+
|
|
27
|
+
Args:
|
|
28
|
+
elev (bool): In general the (x, y, z) array of positions will have
|
|
29
|
+
z as TVD, which is positive down. If `elev` is True, positive
|
|
30
|
+
will be upwards.
|
|
31
|
+
n_vertex_per_well (int): Number of vertex used to describe the geometry of the
|
|
32
|
+
well.
|
|
33
|
+
return_element (bool): if True return a `subsurface.LineSet` instead
|
|
34
|
+
convert_lith (bool): if True convert lith from stiplog to curve
|
|
35
|
+
table (List[Striplog.Component]): List of components to map lithologies
|
|
36
|
+
to value.
|
|
37
|
+
**kwargs:
|
|
38
|
+
`Well.location.trajectory` kwargs
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
|
|
42
|
+
"""
|
|
43
|
+
vertex = np.zeros((0, 3))
|
|
44
|
+
cells = np.zeros((0, 2), dtype=int)
|
|
45
|
+
|
|
46
|
+
last_index = 0
|
|
47
|
+
missed_wells = []
|
|
48
|
+
|
|
49
|
+
for w in wts.p.get_wells():
|
|
50
|
+
if well_without_valid_survey(w, missed_wells): continue
|
|
51
|
+
|
|
52
|
+
cells, vertex, last_index = vertex_and_cells_from_welly_trajectory(
|
|
53
|
+
cells, elev, kwargs, last_index, n_vertex_per_well, vertex, w)
|
|
54
|
+
|
|
55
|
+
change_curve_basis_to_n_vertex_per_well_inplace(n_vertex_per_well, w, wts)
|
|
56
|
+
|
|
57
|
+
# Convert striplog into Curve
|
|
58
|
+
if convert_lith is True:
|
|
59
|
+
if 'lith' in w.data:
|
|
60
|
+
if table is None: table = wts.lith_component_table
|
|
61
|
+
w.data['lith_log'] = striplog_to_curve_log(n_vertex_per_well, table, w, wts)
|
|
62
|
+
else:
|
|
63
|
+
w.data["lith_log"] = welly.Curve(-1 * np.ones(n_vertex_per_well - 1, dtype=int))
|
|
64
|
+
|
|
65
|
+
if w.data["lith_log"].shape[0] != n_vertex_per_well - 1:
|
|
66
|
+
raise ValueError("Cell_attr does not match cells")
|
|
67
|
+
|
|
68
|
+
try:
|
|
69
|
+
df = wts.p.df()
|
|
70
|
+
except ValueError as e:
|
|
71
|
+
if 'objects passed' in str(e):
|
|
72
|
+
df = None
|
|
73
|
+
else:
|
|
74
|
+
raise ValueError
|
|
75
|
+
|
|
76
|
+
print('The following boreholes failed being processed: ', missed_wells)
|
|
77
|
+
|
|
78
|
+
unstructured_data = UnstructuredData.from_array(vertex, cells, df)
|
|
79
|
+
return unstructured_data
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def striplog_to_curve_log(n_vertex_per_well, table, w: welly.Well, wts: WellyToSubsurfaceHelper) -> welly.Curve:
|
|
83
|
+
start, stop, step_size = wts._calculate_basis_parameters(w, n_vertex_per_well - 1)
|
|
84
|
+
s_log, basis, _table = w.data['lith'].to_log(step_size, start, stop, table=table, return_meta=True)
|
|
85
|
+
return welly.Curve(s_log, basis)
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def change_curve_basis_to_n_vertex_per_well_inplace(n_points, w, wts):
|
|
89
|
+
start, stop, step_size = wts._calculate_basis_parameters(w, n_points)
|
|
90
|
+
basis = np.arange(start, stop, step_size)
|
|
91
|
+
w.unify_basis(keys=None, basis=basis)
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def vertex_and_cells_from_welly_trajectory(
|
|
95
|
+
cells: np.ndarray, elev: bool,
|
|
96
|
+
welly_trajectory_kwargs: dict,
|
|
97
|
+
last_index: int, n_vertex_for_well: int,
|
|
98
|
+
vertex: np.ndarray, w: welly.Well):
|
|
99
|
+
try:
|
|
100
|
+
datum = w.location.datum
|
|
101
|
+
except AttributeError:
|
|
102
|
+
datum = None
|
|
103
|
+
|
|
104
|
+
xyz = w.location.trajectory(datum=datum, elev=elev, points=n_vertex_for_well, **welly_trajectory_kwargs) # w.location.position
|
|
105
|
+
# Make sure deviation is there
|
|
106
|
+
a = np.arange(0 + last_index, xyz.shape[0] - 1 + last_index, dtype=np.int_)
|
|
107
|
+
b = np.arange(1 + last_index, xyz.shape[0] + last_index, dtype=np.int_)
|
|
108
|
+
cells_b = np.vstack([a, b]).T
|
|
109
|
+
|
|
110
|
+
vertex = np.vstack((vertex, xyz))
|
|
111
|
+
cells = np.vstack((cells, cells_b))
|
|
112
|
+
last_index += xyz.shape[0]
|
|
113
|
+
|
|
114
|
+
return cells, vertex, last_index
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def well_without_valid_survey(w: welly.Well, missed_wells: List[str]):
|
|
118
|
+
well_without_position = w.location.position is None
|
|
119
|
+
if well_without_position:
|
|
120
|
+
warnings.warn(f'At least one of the wells do not have '
|
|
121
|
+
'assigned a survey. Borehole name: {w.name}')
|
|
122
|
+
missed_wells.append(w.name)
|
|
123
|
+
return well_without_position
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
def _create_welly_well_from_las(well_name: str, las_folder: str):
|
|
127
|
+
"""
|
|
128
|
+
Add well from welly las file.
|
|
129
|
+
|
|
130
|
+
Args:
|
|
131
|
+
well_name (str): Well name
|
|
132
|
+
las_folder (str): Path to las file
|
|
133
|
+
|
|
134
|
+
Returns:
|
|
135
|
+
|
|
136
|
+
"""
|
|
137
|
+
|
|
138
|
+
def _create_well(uwi: str = 'dummy_uwi'):
|
|
139
|
+
w = welly.Well()
|
|
140
|
+
w.location.uwi = well_name
|
|
141
|
+
w.location.name = well_name
|
|
142
|
+
|
|
143
|
+
return w
|
|
144
|
+
|
|
145
|
+
well = _create_well(well_name)
|
|
146
|
+
return add_curves_from_las(well, las_folder)
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
def add_curves_from_las(w: welly.Well, las_folder: str) -> welly.Well:
|
|
150
|
+
""" Add curves from las file. """
|
|
151
|
+
|
|
152
|
+
def _read_curves_to_welly_object(well: welly.Well, curve_path: str = '.') -> welly.Well:
|
|
153
|
+
las_files = glob.glob(curve_path + '*.las')
|
|
154
|
+
# throw error if no las files found
|
|
155
|
+
if len(las_files) == 0:
|
|
156
|
+
raise Exception('No las files found in ' + curve_path)
|
|
157
|
+
|
|
158
|
+
for curve in las_files:
|
|
159
|
+
well.add_curves_from_las(curve)
|
|
160
|
+
return well
|
|
161
|
+
|
|
162
|
+
_read_curves_to_welly_object(w, curve_path=las_folder)
|
|
163
|
+
|
|
164
|
+
w_df = w.df()
|
|
165
|
+
deviation_df = _make_deviation_df(w_df, inclination_header='IMG_INCL', azimuth_header='IMG_AZ')
|
|
166
|
+
w.location.add_deviation(deviation_df)
|
|
167
|
+
return w
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def _make_deviation_df(well_df: DataFrame, inclination_header: str, azimuth_header: str,
|
|
171
|
+
depth_header: str = '', depth_index=True):
|
|
172
|
+
if depth_index:
|
|
173
|
+
deviation_data = well_df[[inclination_header, azimuth_header]].to_numpy()
|
|
174
|
+
deviation_index = well_df.index.to_numpy()
|
|
175
|
+
deviation_complete = np.insert(deviation_data, 0, deviation_index, axis=1)
|
|
176
|
+
deviation_complete = deviation_complete[~np.isnan(deviation_complete).any(axis=1), :]
|
|
177
|
+
else:
|
|
178
|
+
deviation_complete = well_df[[depth_header, inclination_header, azimuth_header]].to_numpy()
|
|
179
|
+
deviation_complete = deviation_complete[~np.isnan(deviation_complete).any(axis=1), :]
|
|
180
|
+
return deviation_complete
|