subsurface-terra 2025.1.0rc15__py3-none-any.whl → 2025.1.0rc16__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.
Files changed (81) hide show
  1. subsurface/__init__.py +31 -31
  2. subsurface/_version.py +34 -21
  3. subsurface/api/__init__.py +13 -13
  4. subsurface/api/interfaces/__init__.py +3 -3
  5. subsurface/api/interfaces/stream.py +136 -136
  6. subsurface/api/reader/read_wells.py +78 -78
  7. subsurface/core/geological_formats/boreholes/_combine_trajectories.py +117 -117
  8. subsurface/core/geological_formats/boreholes/_map_attrs_to_survey.py +236 -234
  9. subsurface/core/geological_formats/boreholes/_survey_to_unstruct.py +163 -163
  10. subsurface/core/geological_formats/boreholes/boreholes.py +140 -140
  11. subsurface/core/geological_formats/boreholes/collars.py +26 -26
  12. subsurface/core/geological_formats/boreholes/survey.py +86 -86
  13. subsurface/core/geological_formats/fault.py +47 -47
  14. subsurface/core/reader_helpers/reader_unstruct.py +11 -11
  15. subsurface/core/reader_helpers/readers_data.py +130 -130
  16. subsurface/core/reader_helpers/readers_wells.py +13 -13
  17. subsurface/core/structs/__init__.py +3 -3
  18. subsurface/core/structs/base_structures/__init__.py +2 -2
  19. subsurface/core/structs/base_structures/_liquid_earth_mesh.py +121 -121
  20. subsurface/core/structs/base_structures/_unstructured_data_constructor.py +70 -70
  21. subsurface/core/structs/base_structures/base_structures_enum.py +6 -6
  22. subsurface/core/structs/base_structures/structured_data.py +282 -282
  23. subsurface/core/structs/base_structures/unstructured_data.py +319 -319
  24. subsurface/core/structs/structured_elements/octree_mesh.py +10 -10
  25. subsurface/core/structs/structured_elements/structured_grid.py +59 -59
  26. subsurface/core/structs/structured_elements/structured_mesh.py +9 -9
  27. subsurface/core/structs/unstructured_elements/__init__.py +3 -3
  28. subsurface/core/structs/unstructured_elements/line_set.py +72 -72
  29. subsurface/core/structs/unstructured_elements/point_set.py +43 -43
  30. subsurface/core/structs/unstructured_elements/tetrahedron_mesh.py +35 -35
  31. subsurface/core/structs/unstructured_elements/triangular_surface.py +62 -62
  32. subsurface/core/utils/utils_core.py +38 -38
  33. subsurface/modules/reader/__init__.py +13 -13
  34. subsurface/modules/reader/faults/faults.py +80 -80
  35. subsurface/modules/reader/from_binary.py +46 -46
  36. subsurface/modules/reader/mesh/_GOCAD_mesh.py +82 -82
  37. subsurface/modules/reader/mesh/_trimesh_reader.py +447 -447
  38. subsurface/modules/reader/mesh/csv_mesh_reader.py +53 -53
  39. subsurface/modules/reader/mesh/dxf_reader.py +177 -177
  40. subsurface/modules/reader/mesh/glb_reader.py +30 -30
  41. subsurface/modules/reader/mesh/mx_reader.py +232 -232
  42. subsurface/modules/reader/mesh/obj_reader.py +53 -53
  43. subsurface/modules/reader/mesh/omf_mesh_reader.py +43 -43
  44. subsurface/modules/reader/mesh/surface_reader.py +56 -56
  45. subsurface/modules/reader/mesh/surfaces_api.py +41 -41
  46. subsurface/modules/reader/profiles/__init__.py +3 -3
  47. subsurface/modules/reader/profiles/profiles_core.py +197 -197
  48. subsurface/modules/reader/read_netcdf.py +38 -38
  49. subsurface/modules/reader/topography/__init__.py +7 -7
  50. subsurface/modules/reader/topography/topo_core.py +100 -100
  51. subsurface/modules/reader/volume/read_grav3d.py +478 -428
  52. subsurface/modules/reader/volume/read_volume.py +327 -230
  53. subsurface/modules/reader/volume/segy_reader.py +105 -105
  54. subsurface/modules/reader/volume/seismic.py +173 -173
  55. subsurface/modules/reader/volume/volume_utils.py +43 -43
  56. subsurface/modules/reader/wells/DEP/__init__.py +43 -43
  57. subsurface/modules/reader/wells/DEP/_well_files_reader.py +167 -167
  58. subsurface/modules/reader/wells/DEP/_wells_api.py +61 -61
  59. subsurface/modules/reader/wells/DEP/_welly_reader.py +180 -180
  60. subsurface/modules/reader/wells/DEP/pandas_to_welly.py +212 -212
  61. subsurface/modules/reader/wells/_read_to_df.py +57 -57
  62. subsurface/modules/reader/wells/read_borehole_interface.py +148 -148
  63. subsurface/modules/reader/wells/wells_utils.py +68 -68
  64. subsurface/modules/tools/mocking_aux.py +104 -104
  65. subsurface/modules/visualization/__init__.py +2 -2
  66. subsurface/modules/visualization/to_pyvista.py +320 -320
  67. subsurface/modules/writer/to_binary.py +12 -12
  68. subsurface/modules/writer/to_rex/common.py +78 -78
  69. subsurface/modules/writer/to_rex/data_struct.py +74 -74
  70. subsurface/modules/writer/to_rex/gempy_to_rexfile.py +791 -791
  71. subsurface/modules/writer/to_rex/material_encoder.py +44 -44
  72. subsurface/modules/writer/to_rex/mesh_encoder.py +152 -152
  73. subsurface/modules/writer/to_rex/to_rex.py +115 -115
  74. subsurface/modules/writer/to_rex/utils.py +15 -15
  75. subsurface/optional_requirements.py +116 -116
  76. {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc16.dist-info}/METADATA +194 -194
  77. subsurface_terra-2025.1.0rc16.dist-info/RECORD +98 -0
  78. {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc16.dist-info}/WHEEL +1 -1
  79. {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc16.dist-info}/licenses/LICENSE +203 -203
  80. subsurface_terra-2025.1.0rc15.dist-info/RECORD +0 -98
  81. {subsurface_terra-2025.1.0rc15.dist-info → subsurface_terra-2025.1.0rc16.dist-info}/top_level.txt +0 -0
@@ -1,59 +1,59 @@
1
- import numpy as np
2
- from ..base_structures import StructuredData
3
-
4
-
5
- class StructuredGrid:
6
- # TODO check structured_data has three coordinates
7
- """Container for curvilinear mesh grids.
8
-
9
- This is analogous to PyVista's StructuredGrid class or discretize's
10
- CurviMesh class.
11
-
12
- """
13
-
14
- def __init__(self, structured_data: StructuredData):
15
- self.ds = structured_data
16
-
17
- @property
18
- def cartesian_dimensions(self):
19
- return len(self.cartesian_coords_names)
20
-
21
- @property
22
- def cartesian_coords_names(self):
23
- coord_names = np.array(['X', 'Y', 'Z', 'x', 'y', 'z'])
24
- return coord_names[np.isin(coord_names, self.ds.data.dims)]
25
-
26
- @property
27
- def coord(self):
28
- return self.ds.data.coords
29
-
30
- @property
31
- def meshgrid_3d(self):
32
- cart_coord = [self.coord[i] for i in self.cartesian_coords_names]
33
- grid_3d = np.meshgrid(*cart_coord, indexing='ij')
34
- return grid_3d
35
-
36
- @property
37
- def active_attributes(self) -> np.ndarray:
38
- return self.ds.data[self.ds.active_data_array_name].values
39
-
40
- def meshgrid_2d(self, attribute_name_coord_name: str = None) -> list:
41
- """
42
-
43
- Args:
44
- attribute_name_coord_name(str): Name of the xarray.Dataset coord that
45
- will be used for the z direction. This must be 2d
46
-
47
- Returns:
48
-
49
- """
50
- grid_2d_: tuple = np.meshgrid(self.coord['x'], self.coord['y'])
51
- grid_2d = list(grid_2d_)
52
- if attribute_name_coord_name is not None:
53
- z_coord = self.ds.data[attribute_name_coord_name].values.T
54
- if z_coord.ndim != 2:
55
- raise AttributeError('The attribute must be a 2D array')
56
-
57
- grid_2d.append(z_coord)
58
-
59
- return grid_2d
1
+ import numpy as np
2
+ from ..base_structures import StructuredData
3
+
4
+
5
+ class StructuredGrid:
6
+ # TODO check structured_data has three coordinates
7
+ """Container for curvilinear mesh grids.
8
+
9
+ This is analogous to PyVista's StructuredGrid class or discretize's
10
+ CurviMesh class.
11
+
12
+ """
13
+
14
+ def __init__(self, structured_data: StructuredData):
15
+ self.ds = structured_data
16
+
17
+ @property
18
+ def cartesian_dimensions(self):
19
+ return len(self.cartesian_coords_names)
20
+
21
+ @property
22
+ def cartesian_coords_names(self):
23
+ coord_names = np.array(['X', 'Y', 'Z', 'x', 'y', 'z'])
24
+ return coord_names[np.isin(coord_names, self.ds.data.dims)]
25
+
26
+ @property
27
+ def coord(self):
28
+ return self.ds.data.coords
29
+
30
+ @property
31
+ def meshgrid_3d(self):
32
+ cart_coord = [self.coord[i] for i in self.cartesian_coords_names]
33
+ grid_3d = np.meshgrid(*cart_coord, indexing='ij')
34
+ return grid_3d
35
+
36
+ @property
37
+ def active_attributes(self) -> np.ndarray:
38
+ return self.ds.data[self.ds.active_data_array_name].values
39
+
40
+ def meshgrid_2d(self, attribute_name_coord_name: str = None) -> list:
41
+ """
42
+
43
+ Args:
44
+ attribute_name_coord_name(str): Name of the xarray.Dataset coord that
45
+ will be used for the z direction. This must be 2d
46
+
47
+ Returns:
48
+
49
+ """
50
+ grid_2d_: tuple = np.meshgrid(self.coord['x'], self.coord['y'])
51
+ grid_2d = list(grid_2d_)
52
+ if attribute_name_coord_name is not None:
53
+ z_coord = self.ds.data[attribute_name_coord_name].values.T
54
+ if z_coord.ndim != 2:
55
+ raise AttributeError('The attribute must be a 2D array')
56
+
57
+ grid_2d.append(z_coord)
58
+
59
+ return grid_2d
@@ -1,9 +1,9 @@
1
- from subsurface import StructuredData
2
-
3
-
4
- class StructuredSurface:
5
- def __init__(self, structured_data: StructuredData):
6
- # TODO check structured_data has two coordinates
7
- self.ds = structured_data
8
-
9
- # Add pyvista methods of gridded data
1
+ from subsurface import StructuredData
2
+
3
+
4
+ class StructuredSurface:
5
+ def __init__(self, structured_data: StructuredData):
6
+ # TODO check structured_data has two coordinates
7
+ self.ds = structured_data
8
+
9
+ # Add pyvista methods of gridded data
@@ -1,4 +1,4 @@
1
- from .triangular_surface import TriSurf
2
- from .line_set import LineSet
3
- from .point_set import PointSet
1
+ from .triangular_surface import TriSurf
2
+ from .line_set import LineSet
3
+ from .point_set import PointSet
4
4
  from .tetrahedron_mesh import TetraMesh
@@ -1,72 +1,72 @@
1
- import numpy as np
2
- import pandas as pd
3
-
4
- from ..base_structures import UnstructuredData
5
-
6
-
7
- class LineSet:
8
- """PointSet with line cells.
9
-
10
- This dataset defines cell connectivity between points to create
11
- line segments.
12
-
13
- Args:
14
- data (UnstructuredData): Base object for unstructured data.
15
-
16
- data.cells represent the indices of the end points for each
17
- line segment in the mesh. Each column corresponds to a line
18
- segment. If not specified, the vertices are connected in order,
19
- equivalent to ``segments=[[0, 1], [1, 2], [2, 3], ...]``
20
-
21
- radius (float): Thickness of the line set
22
- """
23
-
24
- def __init__(self, data: UnstructuredData, radius: float = 1):
25
-
26
- self.data: UnstructuredData = data
27
- self.radius = radius
28
-
29
- if data.cells is None or data.cells.shape[1] < 2:
30
- self.generate_default_cells()
31
-
32
- elif data.cells.shape[1] != 2:
33
- raise AttributeError('data.cells must be of the format'
34
- 'NDArray[(Any, 2), IntX]')
35
-
36
- # TODO: these must all be integer dtypes!
37
-
38
- def get_first_index_per_well(self, attr_hole_id: str):
39
- """ Method to get the first index of each well in the LineSet
40
-
41
- Returns:
42
- np.ndarray[(Any,), IntX]
43
-
44
- """
45
- import xarray as xr
46
- dataset: xr.Dataset = self.data.data
47
- dataframe: pd.DataFrame = self.data.attributes
48
- array = dataframe[attr_hole_id].values
49
-
50
- first_index = np.where(array[:-1] != array[1:])[0]
51
- return first_index
52
-
53
-
54
- def generate_default_cells(self):
55
- """ Method to generate cells based on the order of the vertex. This
56
- only works if the LineSet only represents one single line
57
-
58
- Returns:
59
- np.ndarray[(Any, 2), IntX]
60
-
61
- """
62
- a = np.arange(0, self.data.n_points - 1, dtype=np.int_)
63
- b = np.arange(1, self.data.n_points, dtype=np.int_)
64
- return np.vstack([a, b]).T
65
-
66
- @property
67
- def segments(self):
68
- return self.data.cells
69
-
70
- @property
71
- def n_segments(self):
72
- return self.segments.shape[0]
1
+ import numpy as np
2
+ import pandas as pd
3
+
4
+ from ..base_structures import UnstructuredData
5
+
6
+
7
+ class LineSet:
8
+ """PointSet with line cells.
9
+
10
+ This dataset defines cell connectivity between points to create
11
+ line segments.
12
+
13
+ Args:
14
+ data (UnstructuredData): Base object for unstructured data.
15
+
16
+ data.cells represent the indices of the end points for each
17
+ line segment in the mesh. Each column corresponds to a line
18
+ segment. If not specified, the vertices are connected in order,
19
+ equivalent to ``segments=[[0, 1], [1, 2], [2, 3], ...]``
20
+
21
+ radius (float): Thickness of the line set
22
+ """
23
+
24
+ def __init__(self, data: UnstructuredData, radius: float = 1):
25
+
26
+ self.data: UnstructuredData = data
27
+ self.radius = radius
28
+
29
+ if data.cells is None or data.cells.shape[1] < 2:
30
+ self.generate_default_cells()
31
+
32
+ elif data.cells.shape[1] != 2:
33
+ raise AttributeError('data.cells must be of the format'
34
+ 'NDArray[(Any, 2), IntX]')
35
+
36
+ # TODO: these must all be integer dtypes!
37
+
38
+ def get_first_index_per_well(self, attr_hole_id: str):
39
+ """ Method to get the first index of each well in the LineSet
40
+
41
+ Returns:
42
+ np.ndarray[(Any,), IntX]
43
+
44
+ """
45
+ import xarray as xr
46
+ dataset: xr.Dataset = self.data.data
47
+ dataframe: pd.DataFrame = self.data.attributes
48
+ array = dataframe[attr_hole_id].values
49
+
50
+ first_index = np.where(array[:-1] != array[1:])[0]
51
+ return first_index
52
+
53
+
54
+ def generate_default_cells(self):
55
+ """ Method to generate cells based on the order of the vertex. This
56
+ only works if the LineSet only represents one single line
57
+
58
+ Returns:
59
+ np.ndarray[(Any, 2), IntX]
60
+
61
+ """
62
+ a = np.arange(0, self.data.n_points - 1, dtype=np.int_)
63
+ b = np.arange(1, self.data.n_points, dtype=np.int_)
64
+ return np.vstack([a, b]).T
65
+
66
+ @property
67
+ def segments(self):
68
+ return self.data.cells
69
+
70
+ @property
71
+ def n_segments(self):
72
+ return self.segments.shape[0]
@@ -1,43 +1,43 @@
1
- from dataclasses import dataclass
2
-
3
- from ..base_structures import UnstructuredData
4
-
5
-
6
- @dataclass
7
- class PointSet:
8
- """Class for pointset based data structures.
9
-
10
- This class uses UnstructuredData.vertex as cloud of points and the
11
- associated attributes. UnstructuredData.cells are not used.
12
-
13
- Args:
14
- data (UnstructuredData): Base object for unstructured data.
15
-
16
- """
17
- data: UnstructuredData
18
-
19
- def __init__(self, data: UnstructuredData):
20
- if data.cells.shape[1] > 1:
21
- raise AttributeError('data.cells must be of the format'
22
- 'NDArray[(Any, 0), IntX] or NDArray[(Any, 1), IntX]')
23
-
24
- self.data = data
25
-
26
- @property
27
- def points(self) -> "np.ndarray":
28
- """Fetch the points/vertices dataframe."""
29
- return self.data.vertex
30
-
31
- @property
32
- def n_points(self):
33
- return self.data.vertex.shape[0]
34
-
35
- @property
36
- def point_data(self):
37
- """Fetch the scalar data associated with the vertices."""
38
- return self.data.attributes
39
-
40
- @property
41
- def point_data_dict(self):
42
- """Fetch the point data as a dictionary of numpy arrays."""
43
- return self.data.attributes_to_dict
1
+ from dataclasses import dataclass
2
+
3
+ from ..base_structures import UnstructuredData
4
+
5
+
6
+ @dataclass
7
+ class PointSet:
8
+ """Class for pointset based data structures.
9
+
10
+ This class uses UnstructuredData.vertex as cloud of points and the
11
+ associated attributes. UnstructuredData.cells are not used.
12
+
13
+ Args:
14
+ data (UnstructuredData): Base object for unstructured data.
15
+
16
+ """
17
+ data: UnstructuredData
18
+
19
+ def __init__(self, data: UnstructuredData):
20
+ if data.cells.shape[1] > 1:
21
+ raise AttributeError('data.cells must be of the format'
22
+ 'NDArray[(Any, 0), IntX] or NDArray[(Any, 1), IntX]')
23
+
24
+ self.data = data
25
+
26
+ @property
27
+ def points(self) -> "np.ndarray":
28
+ """Fetch the points/vertices dataframe."""
29
+ return self.data.vertex
30
+
31
+ @property
32
+ def n_points(self):
33
+ return self.data.vertex.shape[0]
34
+
35
+ @property
36
+ def point_data(self):
37
+ """Fetch the scalar data associated with the vertices."""
38
+ return self.data.attributes
39
+
40
+ @property
41
+ def point_data_dict(self):
42
+ """Fetch the point data as a dictionary of numpy arrays."""
43
+ return self.data.attributes_to_dict
@@ -1,35 +1,35 @@
1
- from ..base_structures import UnstructuredData
2
-
3
-
4
- class TetraMesh:
5
- """PointSet with tetrahedron cells.
6
-
7
- This dataset defines cell connectivity between points to create
8
- tetrahedrons. This is volumetric.
9
-
10
- Args:
11
-
12
- data (UnstructuredData): Base object for unstructured data.
13
-
14
- data.cells represent the indices of the points for each
15
- tetrahedron in the mesh. Each column corresponds to a tetrahedron.
16
- Every tetrahedron is defined by the four points; where the first
17
- three (0,1,2) are the base of the tetrahedron which, using the
18
- right hand rule, forms a triangle whose normal points in the
19
- direction of the fourth point.
20
-
21
- """
22
-
23
- def __init__(self, data: UnstructuredData):
24
- if data.cells.shape[1] != 4:
25
- raise AttributeError('data.cells must be of the format'
26
- 'NDArray[(Any, 4), IntX]')
27
- self.data = data
28
-
29
- @property
30
- def tetrahedrals(self):
31
- return self.data.cells
32
-
33
- @property
34
- def n_tetrahedrals(self):
35
- return self.tetrahedrals.shape[0]
1
+ from ..base_structures import UnstructuredData
2
+
3
+
4
+ class TetraMesh:
5
+ """PointSet with tetrahedron cells.
6
+
7
+ This dataset defines cell connectivity between points to create
8
+ tetrahedrons. This is volumetric.
9
+
10
+ Args:
11
+
12
+ data (UnstructuredData): Base object for unstructured data.
13
+
14
+ data.cells represent the indices of the points for each
15
+ tetrahedron in the mesh. Each column corresponds to a tetrahedron.
16
+ Every tetrahedron is defined by the four points; where the first
17
+ three (0,1,2) are the base of the tetrahedron which, using the
18
+ right hand rule, forms a triangle whose normal points in the
19
+ direction of the fourth point.
20
+
21
+ """
22
+
23
+ def __init__(self, data: UnstructuredData):
24
+ if data.cells.shape[1] != 4:
25
+ raise AttributeError('data.cells must be of the format'
26
+ 'NDArray[(Any, 4), IntX]')
27
+ self.data = data
28
+
29
+ @property
30
+ def tetrahedrals(self):
31
+ return self.data.cells
32
+
33
+ @property
34
+ def n_tetrahedrals(self):
35
+ return self.tetrahedrals.shape[0]
@@ -1,62 +1,62 @@
1
- from ..base_structures import UnstructuredData, StructuredData
2
-
3
-
4
- class TriSurf:
5
- """PointSet with triangle cells.
6
-
7
- This dataset defines cell/element connectivity between points to create
8
- triangulated surface.
9
-
10
- Uses UnstructuredData.cells for the face connectivity.
11
-
12
- Args:
13
- mesh (UnstructuredData): Base object for unstructured data.
14
- data.cells represent the point indices for each triangle
15
- in the mesh. Each column corresponds to a triangle edge.
16
- texture (StructuredData): 2D StructuredData with data to be mapped
17
- on the mesh
18
-
19
- Keyword Args:
20
- texture_origin : tuple(float)
21
- Length 3 iterable of floats defining the XYZ coordinates of the
22
- BOTTOM LEFT CORNER of the plane
23
-
24
- texture_point_u : tuple(float)
25
- Length 3 iterable of floats defining the XYZ coordinates of the
26
- BOTTOM RIGHT CORNER of the plane
27
-
28
- texture_point_v : tuple(float)
29
- Length 3 iterable of floats defining the XYZ coordinates of the
30
- TOP LEFT CORNER of the plane
31
- """
32
-
33
- def __init__(self,
34
- mesh: UnstructuredData,
35
- texture: StructuredData = None,
36
- **kwargs
37
- ):
38
- if mesh.cells.shape[1] != 3:
39
- raise AttributeError('data.cells must be of the format'
40
- 'NDArray[(Any, 3), IntX]')
41
-
42
- self.mesh: UnstructuredData = mesh
43
- self.texture: StructuredData = texture
44
- self.texture_origin = kwargs.get('texture_origin', None)
45
- self.texture_point_u = kwargs.get('texture_point_u', None)
46
- self.texture_point_v = kwargs.get('texture_point_v', None)
47
-
48
- @property
49
- def has_texture_data_without_uv(self):
50
- return self.texture is not None and self.texture_origin is not None and self.texture_point_u is not None and self.texture_point_v is not None
51
-
52
- @property
53
- def has_texture_data_with_uv(self):
54
- return 'u' in self.mesh.points_attributes and 'v' in self.mesh.points_attributes
55
-
56
- @property
57
- def triangles(self):
58
- return self.mesh.cells
59
-
60
- @property
61
- def n_triangles(self):
62
- return self.mesh.cells.shape[0]
1
+ from ..base_structures import UnstructuredData, StructuredData
2
+
3
+
4
+ class TriSurf:
5
+ """PointSet with triangle cells.
6
+
7
+ This dataset defines cell/element connectivity between points to create
8
+ triangulated surface.
9
+
10
+ Uses UnstructuredData.cells for the face connectivity.
11
+
12
+ Args:
13
+ mesh (UnstructuredData): Base object for unstructured data.
14
+ data.cells represent the point indices for each triangle
15
+ in the mesh. Each column corresponds to a triangle edge.
16
+ texture (StructuredData): 2D StructuredData with data to be mapped
17
+ on the mesh
18
+
19
+ Keyword Args:
20
+ texture_origin : tuple(float)
21
+ Length 3 iterable of floats defining the XYZ coordinates of the
22
+ BOTTOM LEFT CORNER of the plane
23
+
24
+ texture_point_u : tuple(float)
25
+ Length 3 iterable of floats defining the XYZ coordinates of the
26
+ BOTTOM RIGHT CORNER of the plane
27
+
28
+ texture_point_v : tuple(float)
29
+ Length 3 iterable of floats defining the XYZ coordinates of the
30
+ TOP LEFT CORNER of the plane
31
+ """
32
+
33
+ def __init__(self,
34
+ mesh: UnstructuredData,
35
+ texture: StructuredData = None,
36
+ **kwargs
37
+ ):
38
+ if mesh.cells.shape[1] != 3:
39
+ raise AttributeError('data.cells must be of the format'
40
+ 'NDArray[(Any, 3), IntX]')
41
+
42
+ self.mesh: UnstructuredData = mesh
43
+ self.texture: StructuredData = texture
44
+ self.texture_origin = kwargs.get('texture_origin', None)
45
+ self.texture_point_u = kwargs.get('texture_point_u', None)
46
+ self.texture_point_v = kwargs.get('texture_point_v', None)
47
+
48
+ @property
49
+ def has_texture_data_without_uv(self):
50
+ return self.texture is not None and self.texture_origin is not None and self.texture_point_u is not None and self.texture_point_v is not None
51
+
52
+ @property
53
+ def has_texture_data_with_uv(self):
54
+ return 'u' in self.mesh.points_attributes and 'v' in self.mesh.points_attributes
55
+
56
+ @property
57
+ def triangles(self):
58
+ return self.mesh.cells
59
+
60
+ @property
61
+ def n_triangles(self):
62
+ return self.mesh.cells.shape[0]
@@ -1,38 +1,38 @@
1
- from typing import Union
2
-
3
- from pathlib import Path
4
-
5
- from ..structs import StructuredData, UnstructuredData
6
-
7
-
8
- def get_extension(path):
9
- try:
10
- p = Path(path)
11
- return p.suffix
12
- except TypeError:
13
- return False
14
-
15
-
16
- def replace_outliers(base_data: Union[StructuredData, UnstructuredData], dim=0, perc=0.99, replace_for=None):
17
- """@Edoardo Guerreiro https://stackoverflow.com/questions/60816533/
18
- is-there-a-built-in-function-in-xarray-to-remove-outliers-from-a-dataset"""
19
-
20
- data = base_data.data
21
- # calculate percentile
22
- threshold = data[dim].quantile(perc)
23
-
24
- # find outliers and replace them with max among remaining values
25
- mask = data[dim].where(abs(data[dim]) <= threshold)
26
- if replace_for == 'max':
27
- max_value = mask.max().values
28
- # .where replace outliers with nan
29
- mask = mask.fillna(max_value)
30
- elif replace_for == 'min':
31
- min_value = mask.min().values
32
- # .where replace outliers with nan
33
- mask = mask.fillna(min_value)
34
-
35
- print(mask)
36
- data[dim] = mask
37
-
38
- return data
1
+ from typing import Union
2
+
3
+ from pathlib import Path
4
+
5
+ from ..structs import StructuredData, UnstructuredData
6
+
7
+
8
+ def get_extension(path):
9
+ try:
10
+ p = Path(path)
11
+ return p.suffix
12
+ except TypeError:
13
+ return False
14
+
15
+
16
+ def replace_outliers(base_data: Union[StructuredData, UnstructuredData], dim=0, perc=0.99, replace_for=None):
17
+ """@Edoardo Guerreiro https://stackoverflow.com/questions/60816533/
18
+ is-there-a-built-in-function-in-xarray-to-remove-outliers-from-a-dataset"""
19
+
20
+ data = base_data.data
21
+ # calculate percentile
22
+ threshold = data[dim].quantile(perc)
23
+
24
+ # find outliers and replace them with max among remaining values
25
+ mask = data[dim].where(abs(data[dim]) <= threshold)
26
+ if replace_for == 'max':
27
+ max_value = mask.max().values
28
+ # .where replace outliers with nan
29
+ mask = mask.fillna(max_value)
30
+ elif replace_for == 'min':
31
+ min_value = mask.min().values
32
+ # .where replace outliers with nan
33
+ mask = mask.fillna(min_value)
34
+
35
+ print(mask)
36
+ data[dim] = mask
37
+
38
+ return data