Skip to content

Commit 99de68f

Browse files
committed
[ENH] Improve handling and visualization of structural elements
Improved the implementation for handling structural elements by differentiating the original data from its copy and providing appropriate error messages if data is not found. Additionally, changes were made to visualization of structural elements, including adding color specifications and implementing a 3D plot of the geological model.
1 parent bcc07ad commit 99de68f

File tree

4 files changed

+59
-26
lines changed

4 files changed

+59
-26
lines changed

gempy/API/initialization_API.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,9 @@ def structural_elements_from_borehole_set(
101101
component_lith: dict[Hashable, np.ndarray] = borehole_set.get_top_coords_for_each_lith()
102102

103103
for name, properties in elements_dict.items():
104-
top_coordinates = component_lith.get(properties['top_lith'])
104+
top_coordinates = component_lith.get(properties['id'])
105105
if top_coordinates is None:
106-
raise ValueError(f"Top lithology {properties['top_lith']} not found in borehole set.")
106+
raise ValueError(f"Top lithology {properties['id']} not found in borehole set.")
107107

108108
element = StructuralElement(
109109
name=name,
@@ -119,6 +119,9 @@ def structural_elements_from_borehole_set(
119119
orientations=OrientationsTable(np.zeros(0, dtype=OrientationsTable.dt))
120120
)
121121
elements.append(element)
122+
# Reverse the list to have the oldest rocks at the bottom
123+
elements.reverse()
124+
122125
return elements
123126

124127

gempy/core/data/geo_model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ def solutions(self, value):
161161
@property
162162
def surface_points_copy(self):
163163
"""This is a copy! Returns a SurfacePointsTable for all surface points across the structural elements"""
164-
surface_points_table = self.structural_frame.surface_points
164+
surface_points_table = self.structural_frame.surface_points_copy
165165
if self.transform is not None:
166166
surface_points_table.model_transform = self.transform
167167
return surface_points_table
@@ -178,7 +178,7 @@ def surface_points(self, value):
178178
@property
179179
def orientations_copy(self) -> OrientationsTable:
180180
"""This is a copy! Returns a OrientationsTable for all orientations across the structural elements"""
181-
orientations_table = self.structural_frame.orientations
181+
orientations_table = self.structural_frame.orientations_copy
182182
if self.transform is not None:
183183
orientations_table.model_transform = self.transform
184184
return orientations_table

gempy/core/data/structural_frame.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,11 +329,16 @@ def elements_ids(self) -> np.ndarray:
329329
return np.arange(len(self.structural_elements)) + 1
330330

331331
@property
332-
def surface_points(self) -> SurfacePointsTable:
332+
def surface_points_copy(self) -> SurfacePointsTable:
333333
"""Returns a SurfacePointsTable for all surface points across the structural elements. This is a copy!"""
334334
all_data: np.ndarray = np.concatenate([element.surface_points.data for element in self.structural_elements])
335335
return SurfacePointsTable(data=all_data, name_id_map=self.element_name_id_map)
336336

337+
@property
338+
def surface_points(self):
339+
raise AttributeError("This property can only be set, not read. You can access the copy with `surface_points_copy` or"
340+
"the original on the individual structural elements.")
341+
337342
@surface_points.setter
338343
def surface_points(self, modified_surface_points: SurfacePointsTable) -> None:
339344
"""Distributes the modified surface points back to the structural elements."""
@@ -344,11 +349,16 @@ def surface_points(self, modified_surface_points: SurfacePointsTable) -> None:
344349
start += length
345350

346351
@property
347-
def orientations(self) -> OrientationsTable:
352+
def orientations_copy(self) -> OrientationsTable:
348353
"""Returns an OrientationsTable for all orientations across the structural elements."""
349354
all_data: np.ndarray = np.concatenate([element.orientations.data for element in self.structural_elements])
350355
return OrientationsTable(data=all_data)
351356

357+
@property
358+
def orientations(self) -> OrientationsTable:
359+
raise AttributeError("This property can only be set, not read. You can access the copy with `orientations_copy` or"
360+
"the original on the individual structural elements.")
361+
352362
@orientations.setter
353363
def orientations(self, modified_orientations: OrientationsTable) -> None:
354364
"""Distributes the modified orientations back to the structural elements."""

test/test_modules/test_pile/test_stratigraphic_pile.py

Lines changed: 40 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,10 @@
99
from subsurface.core.geological_formats.boreholes.survey import Survey
1010
from subsurface.core.reader_helpers.readers_data import GenericReaderFilesHelper
1111
from subsurface.modules.reader.wells.read_borehole_interface import read_lith, read_survey, read_collar
12-
from subsurface.modules.visualization import to_pyvista_line, pv_plot
12+
from subsurface.modules.visualization import to_pyvista_line, pv_plot, to_pyvista_points
1313

1414
import gempy as gp
15+
import gempy_viewer as gpv
1516

1617

1718
# @pytest.mark.skip(reason="Not implemented yet")
@@ -64,7 +65,8 @@ def borehole_set(self):
6465

6566
return borehole_set
6667

67-
def test_structural_elements(self, borehole_set: BoreholeSet):
68+
# TODO: Rename this to test structural elements from borehole set
69+
def test_structural_elements_from_borehole_set(self, borehole_set: BoreholeSet):
6870
from subsurface import LineSet
6971
borehole_trajectory: LineSet = borehole_set.combined_trajectory
7072
if PLOT := False:
@@ -78,16 +80,29 @@ def test_structural_elements(self, borehole_set: BoreholeSet):
7880
elements = gp.structural_elements_from_borehole_set(
7981
borehole_set=borehole_set,
8082
elements_dict={
81-
# "Pleistozen": {"id": 10_000, "color": "#f9f97f", "top_lith": 10_000},
82-
# "Kreide": {"id": 30_000, "color": "#a6d84a", "top_lith": 30_000},
83-
# "Trias": {"id": 50_000, "color": "#a4469f", "top_lith": 50_000},
84-
# "Perm": {"id": 60_000, "color": "#f4a142", "top_lith": 60_000},
85-
"Rotliegend": {"id": 62_000, "color": "#bb825b", "top_lith": 62_000},
86-
# "Devon": {"id": 80_000, "color": "#969594", "top_lith": 80_000}
83+
"Buntsandstein" : {
84+
"id" : 53_300,
85+
"color": "#983999"
86+
},
87+
"Werra-Anhydrit" : {
88+
"id" : 61_730,
89+
"color": "#00923f"
90+
},
91+
"Kupfershiefer" : {
92+
"id" : 61_760,
93+
"color": "#da251d"
94+
},
95+
"Zechsteinkonglomerat": {
96+
"id" : 61_770,
97+
"color": "#f8c300"
98+
},
99+
"Rotliegend" : {
100+
"id" : 62_000,
101+
"color": "#bb825b"
102+
}
87103
}
88104
)
89-
90-
105+
91106
group = gp.data.StructuralGroup(
92107
name="Stratigraphic Pile",
93108
elements=elements,
@@ -99,11 +114,9 @@ def test_structural_elements(self, borehole_set: BoreholeSet):
99114
)
100115
print(group)
101116

102-
103-
component_lith = borehole_set.get_top_coords_for_each_lith()
104-
rotliegend_xyz = component_lith[62_000]
105-
extent_from_data = rotliegend_xyz.min(axis=0), rotliegend_xyz.max(axis=0)
106-
117+
all_surface_points_coords: gp.data.SurfacePointsTable = structural_frame.surface_points_copy
118+
extent_from_data = all_surface_points_coords.xyz.min(axis=0), all_surface_points_coords.xyz.max(axis=0)
119+
107120
geo_model = gp.data.GeoModel(
108121
name="Stratigraphic Pile",
109122
structural_frame=structural_frame,
@@ -117,9 +130,16 @@ def test_structural_elements(self, borehole_set: BoreholeSet):
117130
mesh_extraction=True,
118131
number_octree_levels=3,
119132
),
120-
121133
)
122-
123-
import gempy_viewer as gpv
124-
gpv.plot_3d(geo_model)
125-
pass
134+
gempy_plot = gpv.plot_3d(
135+
model=geo_model,
136+
# ve=10,
137+
kwargs_pyvista_bounds={
138+
'show_xlabels': False,
139+
'show_ylabels': False,
140+
# 'show_zlabels': True,
141+
},
142+
show=True,
143+
image=True
144+
)
145+

0 commit comments

Comments
 (0)