Skip to content

Commit 743ac62

Browse files
committed
- [ENH] Revive orientations from surface points in a light way
1 parent 57a9633 commit 743ac62

File tree

3 files changed

+29
-161
lines changed

3 files changed

+29
-161
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from ._orientations_generator import select_nearest_surfaces_points
1+
from ._orientations_generator import select_nearest_surfaces_points, NearestSurfacePointsSearcher

gempy_plugins/orientations_generator/_orientations_generator.py

Lines changed: 2 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ class NearestSurfacePointsSearcher(enum.Enum):
1212

1313

1414
def select_nearest_surfaces_points(surface_points_xyz: np.ndarray, searchcrit: Optional[int|float] = 3,
15-
search_type: NearestSurfacePointsSearcher = NearestSurfacePointsSearcher.KNN
15+
search_type: NearestSurfacePointsSearcher = NearestSurfacePointsSearcher.KNN
1616
) -> np.ndarray:
1717
match search_type:
1818
case NearestSurfacePointsSearcher.KNN:
@@ -26,121 +26,4 @@ def select_nearest_surfaces_points(surface_points_xyz: np.ndarray, searchcrit: O
2626
case _:
2727
raise ValueError(f"Invalid search type: {search_type}")
2828

29-
return neighbours_surfaces
30-
31-
32-
def _select_nearest_surfaces_points(geo_model, surface_points, searchcrit):
33-
"""
34-
Find the neighbour points of the same surface
35-
by given radius (radius-search) or fix number (knn).
36-
37-
Parameters
38-
----------
39-
geo_model : geo_model
40-
GemPy-model.
41-
surface_points: Pandas-dataframe
42-
Contains the dataframe of the (point-)data from the GemPy-model.
43-
searchcrit : int or float
44-
if is int: uses knn-search.
45-
if is float: uses radius-search.
46-
"""
47-
48-
# extract surface names
49-
surfaces = np.unique(surface_points['surface'])
50-
neighbours = []
51-
# for each surface
52-
if isinstance(searchcrit, int): # in case knn-search
53-
searchcrit = searchcrit + 1 # because the point itself is also found
54-
for s in range(surfaces.size):
55-
# extract point-ids
56-
i_surfaces = surface_points['surface'] == surfaces[s]
57-
# extract point coordinates
58-
p_surfaces = surface_points[i_surfaces][['X', 'Y', 'Z']]
59-
# create search-tree
60-
Tree = NearestNeighbors(n_neighbors=searchcrit)
61-
# add data to tree
62-
Tree.fit(p_surfaces)
63-
# find neighbours
64-
neighbours_surfaces = Tree.kneighbors(p_surfaces, n_neighbors=searchcrit,
65-
return_distance=False)
66-
# add neighbours with initial index to total list
67-
for n in neighbours_surfaces:
68-
neighbours.append(p_surfaces.index[n])
69-
else: # in case radius-search
70-
for s in range(surfaces.size):
71-
# extract point-ids
72-
i_surfaces = surface_points['surface'] == surfaces[s]
73-
# extract point coordinates
74-
p_surfaces = surface_points[i_surfaces][['X', 'Y', 'Z']]
75-
# create search-tree
76-
Tree = NearestNeighbors(radius=searchcrit)
77-
# add data to tree
78-
Tree.fit(p_surfaces)
79-
# find neighbours (attention: relativ index!)
80-
neighbours_surfaces = Tree.radius_neighbors(p_surfaces,
81-
radius=searchcrit,
82-
return_distance=False)
83-
# add neighbours with initial index to total list
84-
for n in neighbours_surfaces:
85-
neighbours.append(p_surfaces.index[n])
86-
return neighbours
87-
88-
89-
def set_orientation_from_neighbours(geo_model, neighbours):
90-
"""
91-
Calculates the orientation of one point with its neighbour points
92-
of the same surface.
93-
Parameters
94-
----------
95-
geo_model : geo_model
96-
GemPy-model.
97-
neighbours : Int64Index
98-
point-neighbours-id, first id is the point itself.
99-
"""
100-
101-
# compute normal vector for the point
102-
if neighbours.size > 2:
103-
# extract point coordinates
104-
coo = geo_model._surface_points.df.loc[neighbours][['X', 'Y', 'Z']]
105-
# calculates covariance matrix
106-
cov = np.cov(coo.T)
107-
# calculate normalized normal vector
108-
normvec = normalize(np.cross(cov[0].T, cov[1].T).reshape(1, -1))[0]
109-
# check orientation of normal vector (has to be oriented to sky)
110-
if normvec[2] < 0:
111-
normvec = normvec * (-1)
112-
# append to the GemPy-model
113-
geo_model.add_orientations(geo_model._surface_points.df['X'][neighbours[0]],
114-
geo_model._surface_points.df['Y'][neighbours[0]],
115-
geo_model._surface_points.df['Z'][neighbours[0]],
116-
geo_model._surface_points.df['surface'][neighbours[0]],
117-
normvec.tolist())
118-
# if computation is impossible set normal vector to default orientation
119-
else:
120-
print("orientation calculation of point" + str(neighbours[0]) + "is impossible")
121-
print("-> default vector is set [0,0,1]")
122-
geo_model.add_orientations(geo_model._surface_points.df['X'][neighbours[0]],
123-
geo_model._surface_points.df['Y'][neighbours[0]],
124-
geo_model._surface_points.df['Z'][neighbours[0]],
125-
geo_model._surface_points.df['surface'][neighbours[0]],
126-
orientation=[0, 0, 1])
127-
return geo_model._orientations
128-
129-
130-
def set_orientation_from_neighbours_all(geo_model, neighbours):
131-
"""
132-
Calculates the orientations for all points with given neighbours.
133-
Parameters
134-
----------
135-
geo_model : geo_model
136-
GemPy-model.
137-
neighbours : list of Int64Index
138-
point-neighbours-IDs, the first id is the id of the point
139-
for which the orientation is calculated.
140-
"""
141-
142-
# compute normal vector for the points
143-
for n in neighbours:
144-
set_orientation_from_neighbours(geo_model, n)
145-
146-
return geo_model._orientations
29+
return neighbours_surfaces
Lines changed: 26 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,9 @@
11
import gempy as gp
2-
import numpy as np
32
import os
43

5-
from orientations_generator import select_nearest_surfaces_points
6-
from orientations_generator._orientations_generator import NearestSurfacePointsSearcher
4+
from orientations_generator import select_nearest_surfaces_points, NearestSurfacePointsSearcher
75

86
input_path = os.path.dirname(__file__) + '/../../examples/data'
9-
107
data_path = os.path.abspath('data')
118

129

@@ -26,7 +23,9 @@ def _model_factory():
2623
def test_set_orientations():
2724
geo_data = _model_factory()
2825

29-
orientations: gp.data.OrientationsTable = gp.create_orientations_from_surface_points(geo_data.surface_points)
26+
orientations: gp.data.OrientationsTable = gp.create_orientations_from_surface_points_coords(
27+
xyz_coords=geo_data.surface_points
28+
)
3029

3130
gp.add_orientations(
3231
geo_model=geo_data,
@@ -43,16 +42,14 @@ def test_select_nearest_surface_points():
4342
geo_model = _model_factory()
4443
print(geo_model)
4544

46-
# TODO: This is to select the surface points we want to use to calculate the orientations
47-
4845
element: gp.data.StructuralElement = geo_model.structural_frame.get_element_by_name("fault")
4946

5047
# find neighbours
5148
knn = select_nearest_surfaces_points(
5249
surface_points_xyz=element.surface_points.xyz,
5350
searchcrit=3
5451
)
55-
52+
5653
radius = select_nearest_surfaces_points(
5754
surface_points_xyz=element.surface_points.xyz,
5855
searchcrit=200.,
@@ -63,42 +60,30 @@ def test_select_nearest_surface_points():
6360

6461

6562
def test_set_orientation_from_neighbours():
66-
67-
68-
69-
70-
# find neighbours
71-
neighbours = gp.select_nearest_surfaces_points(geo_data, fault_poi, 5)
72-
# calculate one fault orientation
73-
gp.set_orientation_from_neighbours(geo_data, neighbours[1])
74-
# find the calculated orientation
75-
test = geo_data._orientations.df.sort_index().iloc[-1][['dip', 'azimuth']].values
76-
77-
# calculate reference
78-
reference = [90 - np.arctan(0.5) / np.pi * 180, 90]
79-
80-
assert np.array_equal(reference, test)
81-
82-
83-
def test_set_orientation_from_neighbours_all():
84-
data_path = 'https://raw.githubusercontent.com/cgre-aachen/gempy_data/master/'
85-
path_to_data = data_path + "/data/input_data/jan_models/"
63+
geo_model = _model_factory()
8664

87-
geo_data = gp.create_data_legacy('fault', extent=[0, 1000, 0, 1000, 0, 1000],
88-
resolution=[50, 50, 50],
89-
path_o=path_to_data + "model5_orientations.csv",
90-
path_i=path_to_data + "model5_surface_points.csv")
65+
print(geo_model)
9166

92-
# count orientations before orientation calculation
93-
length_pre = geo_data._orientations.df.shape[0]
67+
element: gp.data.StructuralElement = geo_model.structural_frame.get_element_by_name("fault")
9468

9569
# find neighbours
96-
neighbours = gp.select_nearest_surfaces_points(geo_data, geo_data._surface_points.df, 2)
97-
# calculate all fault orientations
98-
gp.set_orientation_from_neighbours_all(geo_data, neighbours)
70+
knn = select_nearest_surfaces_points(
71+
surface_points_xyz=element.surface_points.xyz,
72+
searchcrit=3
73+
)
9974

100-
# count orientations after orientation calculation
101-
length_after = geo_data._orientations.df.shape[0]
75+
orientations: gp.data.OrientationsTable = gp.create_orientations_from_surface_points_coords(
76+
xyz_coords=geo_model.surface_points.xyz,
77+
subset=knn
78+
)
10279

103-
assert np.array_equal(geo_data._surface_points.df.shape[0],
104-
length_after - length_pre)
80+
gp.add_orientations(
81+
geo_model=geo_model,
82+
x=orientations.data['X'],
83+
y=orientations.data['Y'],
84+
z=orientations.data['Z'],
85+
pole_vector=orientations.grads,
86+
elements_names=geo_model.structural_frame.elements_names[0],
87+
)
88+
89+
return knn

0 commit comments

Comments
 (0)