Skip to content

Commit 1d2f047

Browse files
committed
[DOC] Reviving kim
1 parent ad2fa8e commit 1d2f047

File tree

1 file changed

+122
-59
lines changed

1 file changed

+122
-59
lines changed

examples/examples/real/mik.py

Lines changed: 122 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,18 @@
55
#
66
# %%
77
# List of relative paths used during the workshop
8+
import numpy as np
9+
import pandas as pd
810
import pooch
911

12+
from subsurface.core.geological_formats import Collars, Survey, BoreholeSet
13+
from subsurface.core.geological_formats.boreholes._combine_trajectories import MergeOptions
14+
from subsurface.core.reader_helpers.readers_data import GenericReaderFilesHelper
15+
from subsurface.core.structs.base_structures.base_structures_enum import SpecialCellCase
16+
from subsurface.modules.reader.wells.read_borehole_interface import read_collar, read_survey, read_lith
17+
import subsurface as ss
18+
from subsurface.modules.visualization import to_pyvista_points, pv_plot, to_pyvista_line, init_plotter
19+
1020
path_to_well_png = '../../common/basics/data/wells.png'
1121
path_to_checkpoint_1 = '../../common/basics/checkpoints/checkpoint1.pickle'
1222
path_to_checkpoint_2 = '../../common/basics/checkpoints/checkpoint2.pickle'
@@ -29,73 +39,108 @@
2939
# %% md
3040
# Now we can use `subsurface` function to help us reading csv files into pandas dataframes that the package can understand. Since the combination of styles data is provided can highly vary from project to project, `subsurface` provides some *helpers* functions to parse different combination of .csv
3141
# %%
32-
reading_collars = ReaderFilesHelper(
33-
file_or_buffer=raw_borehole_data_csv,
34-
index_col="name",
35-
usecols=['x', 'y', 'altitude', "name"]
36-
)
3742

38-
reading_collars
39-
# %%
40-
from dataclasses import asdict
43+
collar_df: pd.DataFrame = read_collar(
44+
GenericReaderFilesHelper(
45+
file_or_buffer=raw_borehole_data_csv,
46+
index_col="name",
47+
usecols=['x', 'y', 'altitude', "name"],
48+
columns_map={
49+
"name": "id", # ? Index name is not mapped
50+
"X": "x",
51+
"Y": "y",
52+
"altitude": "z"
53+
}
54+
)
55+
)
56+
# TODO: df to unstruct
57+
unstruc: ss.UnstructuredData = ss.UnstructuredData.from_array(
58+
vertex=collar_df[["x", "y", "z"]].values,
59+
cells=SpecialCellCase.POINTS
60+
)
61+
points = ss.PointSet(data=unstruc)
62+
collars: Collars = Collars(
63+
ids=collar_df.index.to_list(),
64+
collar_loc=points
65+
)
4166

42-
asdict(reading_collars)
43-
# %%
44-
collar = read_collar(reading_collars)
67+
s = to_pyvista_points(collars.collar_loc)
68+
pv_plot([s], image_2d=True)
4569

46-
collar
4770
# %%
4871
# Your code here:
49-
survey = read_survey(
50-
ReaderFilesHelper(
72+
survey_df: pd.DataFrame = read_survey(
73+
GenericReaderFilesHelper(
5174
file_or_buffer=raw_borehole_data_csv,
5275
index_col="name",
5376
usecols=["name", "md"]
5477
)
5578
)
5679

80+
survey: Survey = Survey.from_df(survey_df)
81+
5782
survey
83+
5884
# %%
5985
# Your code here:
6086
lith = read_lith(
61-
ReaderFilesHelper(
87+
GenericReaderFilesHelper(
6288
file_or_buffer=raw_borehole_data_csv,
6389
usecols=['name', 'top', 'base', 'formation'],
64-
columns_map={'top' : 'top',
65-
'base' : 'base',
66-
'formation': 'component lith',
67-
}
90+
columns_map={
91+
'top': 'top',
92+
'base': 'base',
93+
'formation': 'component lith',
94+
}
6895
)
6996
)
7097

98+
survey.update_survey_with_lith(lith)
99+
71100
lith
72101

73-
# %% md
74-
# ### Welly
75-
#
76-
# Welly is a family of classes to facilitate the loading, processing, and analysis of subsurface wells and well data, such as striplogs, formation tops, well log curves, and synthetic seismograms.
77-
#
78-
# We are using welly to convert pandas data frames into classes to manipulate well data. The final goal is to extract 3D coordinates and properties for multiple wells.
79-
#
80-
# The class `WellyToSubsurfaceHelper` contains the methods to create a `welly` project and export it to a `subsurface` data class.
81-
# %%
82-
wts = sb.reader.wells.WellyToSubsurfaceHelper(collar_df=collar, survey_df=survey, lith_df=lith)
83-
# %% md
84-
# In the field p is stored a welly project (https://github.com/agile-geoscience/welly/blob/master/tutorial/04_Project.ipynb)and we can use it to explore and visualize properties of each well.
85-
# %%
86-
wts.p
87-
# %%
88-
stripLog = wts.p[0].data['lith']
89-
stripLog
90-
# %%
91-
stripLog.plot()
92-
plt.gcf()
102+
borehole_set = BoreholeSet(
103+
collars=collars,
104+
survey=survey,
105+
merge_option=MergeOptions.INTERSECT
106+
)
107+
93108
# %%
94-
welly_well = wts.p[0].data["lith_log"]
95-
welly_well
96-
# %% md
97-
# ## Welly to Subsurface
98-
#
109+
110+
s = to_pyvista_line(
111+
line_set=borehole_set.combined_trajectory,
112+
active_scalar="lith_ids",
113+
radius=40
114+
)
115+
116+
p = init_plotter()
117+
import matplotlib.pyplot as plt
118+
119+
boring_cmap = plt.get_cmap(name="viridis", lut=14)
120+
p.add_mesh(s, cmap=boring_cmap)
121+
122+
collar_mesh = to_pyvista_points(collars.collar_loc)
123+
p.add_mesh(collar_mesh, render_points_as_spheres=True)
124+
p.add_point_labels(
125+
points=collars.collar_loc.points,
126+
labels=collars.ids,
127+
point_size=10,
128+
shape_opacity=0.5,
129+
font_size=12,
130+
bold=True
131+
)
132+
133+
if plot3D:=False:
134+
p.show()
135+
else:
136+
img = p.show(screenshot=True)
137+
img = p.last_image
138+
fig = plt.imshow(img)
139+
plt.axis('off')
140+
plt.show(block=False)
141+
p.close()
142+
143+
# %% m
99144
# Welly is a very powerful tool to inspect well data but it was not design for 3D. However they have a method to export XYZ coordinates of each of the well that we can take advanatage of to create a `subsurface.UnstructuredData` object. This object is one of the core data class of `subsurface` and we will use it from now on to keep working in 3D.
100145
# %%
101146
formations = ["topo", "etchegoin", "macoma", "chanac", "mclure",
@@ -104,20 +149,25 @@
104149
"cretaceous",
105150
"basement", "null"]
106151

107-
unstruct = sb.reader.wells.welly_to_subsurface(wts, table=[Component({'lith': l}) for l in formations])
152+
153+
# %%
154+
155+
borehole_set.get_bottom_coords_for_each_lith()
156+
foo = borehole_set._merge_vertex_data_arrays_to_dataframe()
157+
well_id_mapper: dict[str, int] = borehole_set.survey.id_to_well_id
158+
# mapp well_id column to well_name
159+
fos is greato["well_name"] = foo["well_id"].map(well_id_mapper)
160+
161+
pass
162+
# %%
163+
# unstruct = sb.reader.wells.welly_to_subsurface(wts, table=[Component({'lith': l}) for l in formations])
164+
unstrc = w
108165
unstruct.data
109166
# %% md
110167
# At each core `UstructuredData` is a wrapper of a `xarray.Dataset`. Although slightly flexible, any `UnstructuredData` will contain 4 `xarray.DataArray` objects containing vertex, cells, cell attributes and vertex attibutes. This is the minimum amount of information necessary to work in 3D.
111168
# %% md
112169
# From an `UnstructuredData` we can construct *elements*. *elements* are a higher level construct and includes the definion of type of geometric representation - e.g. points, lines, surfaces, etc. For the case of borehole we will use LineSets. *elements* have a very close relation to `vtk` data structures what enables easily to plot the data using `pyvista`
113170
# %%
114-
element = sb.LineSet(unstruct)
115-
pyvista_mesh = sb.visualization.to_pyvista_line(element, radius=50)
116-
117-
# Plot default LITH
118-
interactive_plot = sb.visualization.pv_plot([pyvista_mesh], background_plotter=True)
119-
# %%
120-
plot_pyvista_to_notebook(interactive_plot)
121171
# %% md
122172
# ## Finding the boreholes bases
123173
#
@@ -145,17 +195,30 @@
145195
interface_points
146196
# %%
147197
# Creating a new UnstructuredData
148-
interf_us = sb.UnstructuredData.from_array(vertex=interface_points.values, cells="points",
198+
interf_us = ss.UnstructuredData.from_array(vertex=interface_points.values, cells="points",
149199
cells_attr=vals_prop_change.to_pandas())
150200
interf_us
151201
# %% md
152202
# This new `UnstructuredData` object instead containing data that represent lines, contain point data at the bottom of each unit. We can plot it very similar as before:
153203
# %%
154-
element = sb.PointSet(interf_us)
155-
pyvista_mesh = sb.visualization.to_pyvista_points(element)
156-
interactive_plot.add_mesh(pyvista_mesh)
157-
# %%
158-
plot_pyvista_to_notebook(interactive_plot)
204+
element = ss.PointSet(interf_us)
205+
pyvista_mesh = ss.visualization.to_pyvista_points(element)
206+
207+
p = init_plotter()
208+
import matplotlib.pyplot as plt
209+
210+
p.add_mesh(collar_mesh, render_points_as_spheres=True)
211+
p.add_point_labels(
212+
points=collars.collar_loc.points,
213+
labels=collars.ids,
214+
point_size=10,
215+
shape_opacity=0.5,
216+
font_size=12,
217+
bold=True
218+
)
219+
p.show()
220+
221+
159222
# %% md
160223
# ## GemPy: Initialize model
161224
#
@@ -387,4 +450,4 @@ def get_interface_coord_from_surfaces(surface_names: list, verbose=False):
387450
#
388451
# ![Terranigma_Logotype_black.png](attachment:200622_Terranigma_Logotype_black.png)
389452
#
390-
#
453+
#

0 commit comments

Comments
 (0)