geometallurgy 0.4.12__py3-none-any.whl → 0.4.14__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.
- elphick/geomet/block_model.py +55 -94
- elphick/geomet/extras.py +5 -5
- {geometallurgy-0.4.12.dist-info → geometallurgy-0.4.14.dist-info}/METADATA +6 -5
- {geometallurgy-0.4.12.dist-info → geometallurgy-0.4.14.dist-info}/RECORD +7 -7
- {geometallurgy-0.4.12.dist-info → geometallurgy-0.4.14.dist-info}/LICENSE +0 -0
- {geometallurgy-0.4.12.dist-info → geometallurgy-0.4.14.dist-info}/WHEEL +0 -0
- {geometallurgy-0.4.12.dist-info → geometallurgy-0.4.14.dist-info}/entry_points.txt +0 -0
elphick/geomet/block_model.py
CHANGED
|
@@ -10,7 +10,6 @@ from scipy import stats
|
|
|
10
10
|
from elphick.geomet import extras
|
|
11
11
|
from elphick.geomet.base import MassComposition
|
|
12
12
|
from elphick.geomet.extras import BlockmodelExtras
|
|
13
|
-
from elphick.geomet.utils.block_model_converter import volume_to_vtk
|
|
14
13
|
from elphick.geomet.utils.timer import log_timer
|
|
15
14
|
|
|
16
15
|
if TYPE_CHECKING:
|
|
@@ -21,8 +20,8 @@ if TYPE_CHECKING:
|
|
|
21
20
|
def import_extras(func):
|
|
22
21
|
@wraps(func)
|
|
23
22
|
def wrapper(*args, **kwargs):
|
|
24
|
-
|
|
25
|
-
extras_instance = BlockmodelExtras(
|
|
23
|
+
omfpandas, omfvista, pv = extras.import_blockmodel_packages()
|
|
24
|
+
extras_instance = BlockmodelExtras(omfpandas, omfvista, pv)
|
|
26
25
|
return func(*args, imports=extras_instance, **kwargs)
|
|
27
26
|
|
|
28
27
|
return wrapper
|
|
@@ -66,105 +65,67 @@ class BlockModel(MassComposition):
|
|
|
66
65
|
@classmethod
|
|
67
66
|
@import_extras
|
|
68
67
|
def from_omf(cls, omf_filepath: Path, imports,
|
|
69
|
-
|
|
70
|
-
columns: Optional[list[str]] = None
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
else:
|
|
86
|
-
omf_bm = block_model_candidates[0]
|
|
87
|
-
|
|
88
|
-
origin = np.array(project.origin)
|
|
89
|
-
bm = volume_to_vtk(omf_bm, origin=origin, columns=columns)
|
|
90
|
-
|
|
91
|
-
# Create DataFrame
|
|
92
|
-
df = pd.DataFrame(bm.cell_centers().points, columns=['x', 'y', 'z'])
|
|
93
|
-
|
|
94
|
-
# set the index to the cell centroids
|
|
95
|
-
df.set_index(['x', 'y', 'z'], drop=True, inplace=True)
|
|
68
|
+
element_name: Optional[str] = None,
|
|
69
|
+
columns: Optional[list[str]] = None,
|
|
70
|
+
query: Optional[str] = None,
|
|
71
|
+
density: float = 2.5) -> 'BlockModel':
|
|
72
|
+
"""Create a BlockModel from an OMF file.
|
|
73
|
+
|
|
74
|
+
Args:
|
|
75
|
+
omf_filepath: Path to the OMF file.
|
|
76
|
+
imports: internally used to import the necessary packages.
|
|
77
|
+
element_name: The name of the element in the OMF file.
|
|
78
|
+
columns: The columns to extract from the OMF file.
|
|
79
|
+
query: The query to filter the DataFrame.
|
|
80
|
+
density: The density of the material in g/cm3, used to calculate DMT (Dry Mass Tonnes). A workaround.
|
|
81
|
+
|
|
82
|
+
Returns:
|
|
83
|
+
BlockModel: The BlockModel instance.
|
|
96
84
|
|
|
97
|
-
|
|
98
|
-
for d, t in zip(['dx', 'dy', 'dz'], ['tensor_u', 'tensor_v', 'tensor_w']):
|
|
99
|
-
# todo: fix - wrong shape
|
|
100
|
-
df[d] = eval(f"omf_bm.geometry.{t}")
|
|
101
|
-
df.set_index(['dx', 'dy', 'dz'], append=True, inplace=True)
|
|
85
|
+
"""
|
|
102
86
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
87
|
+
omfpr: imports.omfpandas.OMFPandasReader = imports.omfpandas.OMFPandasReader(filepath=omf_filepath)
|
|
88
|
+
blocks: pd.DataFrame = omfpr.read_blockmodel(blockmodel_name=element_name, attributes=columns,
|
|
89
|
+
query=query)
|
|
106
90
|
|
|
107
|
-
#
|
|
108
|
-
df['DMT'] = 2000
|
|
109
|
-
moisture_in_scope = False
|
|
91
|
+
# get the block volume
|
|
110
92
|
|
|
111
|
-
|
|
93
|
+
volume: Union[float, np.ndarray[float]]
|
|
94
|
+
from omfpandas.blockmodel import OMFBlockModel
|
|
95
|
+
from omfpandas.blockmodels.convert_blockmodel import df_to_blockmodel
|
|
96
|
+
from omfpandas.blockmodels.geometry import Geometry
|
|
97
|
+
geom: Geometry = OMFBlockModel(df_to_blockmodel(blocks, blockmodel_name=element_name)).geometry
|
|
112
98
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
# Create a VolumeElement instance for the block model
|
|
120
|
-
block_model = imports.omf.VolumeElement(name=name, description=description,
|
|
121
|
-
geometry=imports.omf.VolumeGridGeometry())
|
|
122
|
-
|
|
123
|
-
# Set the geometry of the block model
|
|
124
|
-
block_model.geometry.origin = self.data.index.get_level_values('x').min(), \
|
|
125
|
-
self.data.index.get_level_values('y').min(), \
|
|
126
|
-
self.data.index.get_level_values('z').min()
|
|
127
|
-
|
|
128
|
-
# Set the axis directions
|
|
129
|
-
block_model.geometry.axis_u = [1, 0, 0] # Set the u-axis to point along the x-axis
|
|
130
|
-
block_model.geometry.axis_v = [0, 1, 0] # Set the v-axis to point along the y-axis
|
|
131
|
-
block_model.geometry.axis_w = [0, 0, 1] # Set the w-axis to point along the z-axis
|
|
132
|
-
|
|
133
|
-
# Set the tensor locations and dimensions
|
|
134
|
-
if 'dx' not in self.data.index.names:
|
|
135
|
-
# Calculate the dimensions of the cells
|
|
136
|
-
x_dims = np.diff(self.data.index.get_level_values('x').unique())
|
|
137
|
-
y_dims = np.diff(self.data.index.get_level_values('y').unique())
|
|
138
|
-
z_dims = np.diff(self.data.index.get_level_values('z').unique())
|
|
139
|
-
|
|
140
|
-
# Append an extra value to the end of the dimensions arrays
|
|
141
|
-
x_dims = np.append(x_dims, x_dims[-1])
|
|
142
|
-
y_dims = np.append(y_dims, y_dims[-1])
|
|
143
|
-
z_dims = np.append(z_dims, z_dims[-1])
|
|
144
|
-
|
|
145
|
-
# Assign the dimensions to the tensor attributes
|
|
146
|
-
block_model.geometry.tensor_u = x_dims
|
|
147
|
-
block_model.geometry.tensor_v = y_dims
|
|
148
|
-
block_model.geometry.tensor_w = z_dims
|
|
99
|
+
if geom.__class__.__name__ == 'RegularGeometry':
|
|
100
|
+
volume = geom.block_size[0] * geom.block_size[1] * geom.block_size[2]
|
|
101
|
+
elif geom.__class__.__name__ == 'TensorGeometry':
|
|
102
|
+
# TODO: Implement the volume calculation for TensorGeometry - this is a placeholder.
|
|
103
|
+
volume = geom.block_sizes[0][0] * geom.block_sizes[0][1] * geom.block_sizes[0][2]
|
|
149
104
|
else:
|
|
150
|
-
|
|
151
|
-
block_model.geometry.tensor_v = self.data.index.get_level_values('dy').unique().tolist()
|
|
152
|
-
block_model.geometry.tensor_w = self.data.index.get_level_values('dz').unique().tolist()
|
|
153
|
-
|
|
154
|
-
# Sort the blocks by their x, y, and z coordinates
|
|
155
|
-
blocks: pd.DataFrame = self.data.sort_index()
|
|
105
|
+
raise ValueError(f"Geometry type '{geom.__class__.__name__}' not supported.")
|
|
156
106
|
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
107
|
+
if density is not None:
|
|
108
|
+
blocks['mass_dry'] = volume * density
|
|
109
|
+
moisture_in_scope = False
|
|
160
110
|
|
|
161
|
-
|
|
162
|
-
project.elements = [block_model]
|
|
111
|
+
return cls(data=blocks, name=element_name, mass_dry_var='mass_dry', moisture_in_scope=moisture_in_scope)
|
|
163
112
|
|
|
164
|
-
|
|
113
|
+
@import_extras
|
|
114
|
+
def to_omf(self, omf_filepath: Path, imports, element_name: str = 'Block Model',
|
|
115
|
+
description: str = 'A block model'):
|
|
116
|
+
"""Write the BlockModel to an OMF file.
|
|
117
|
+
|
|
118
|
+
Args:
|
|
119
|
+
omf_filepath: Path to the OMF file.
|
|
120
|
+
imports: internally used to import the necessary packages.
|
|
121
|
+
element_name: The name of the element in the OMF file.
|
|
122
|
+
description: Description of the block model.
|
|
123
|
+
"""
|
|
124
|
+
# Create an OMFPandasWriter instance
|
|
125
|
+
writer = imports.omfpandas.OMFPandasWriter(filepath=omf_filepath)
|
|
165
126
|
|
|
166
|
-
# Write the
|
|
167
|
-
|
|
127
|
+
# Write the block model to the OMF file
|
|
128
|
+
writer.write_blockmodel(blockmodel_name=element_name, description=description, dataframe=self.data)
|
|
168
129
|
|
|
169
130
|
@log_timer
|
|
170
131
|
def get_blocks(self) -> Union['pv.StructuredGrid', 'pv.UnstructuredGrid']:
|
|
@@ -235,7 +196,7 @@ class BlockModel(MassComposition):
|
|
|
235
196
|
def create_structured_grid(self, imports) -> 'pv.StructuredGrid':
|
|
236
197
|
|
|
237
198
|
# Get the unique x, y, z coordinates (centroids)
|
|
238
|
-
data = self.data
|
|
199
|
+
data = self.data.sort_values(['z', 'y', 'x']) # ensure the data is sorted F-style
|
|
239
200
|
x_centroids = data.index.get_level_values('x').unique()
|
|
240
201
|
y_centroids = data.index.get_level_values('y').unique()
|
|
241
202
|
z_centroids = data.index.get_level_values('z').unique()
|
|
@@ -274,7 +235,7 @@ class BlockModel(MassComposition):
|
|
|
274
235
|
"""
|
|
275
236
|
|
|
276
237
|
# Get the x, y, z coordinates and cell dimensions
|
|
277
|
-
blocks = self.data.reset_index().sort_values(['z', 'y', 'x'])
|
|
238
|
+
blocks = self.data.reset_index().sort_values(['z', 'y', 'x']) # ensure the data is sorted F-style
|
|
278
239
|
# if no dims are passed, estimate them
|
|
279
240
|
if 'dx' not in blocks.columns:
|
|
280
241
|
dx, dy, dz = self.common_block_size()
|
elphick/geomet/extras.py
CHANGED
|
@@ -3,8 +3,8 @@ _blockmodel_imports = None
|
|
|
3
3
|
|
|
4
4
|
# Define the Extras class to encapsulate the imported modules
|
|
5
5
|
class BlockmodelExtras:
|
|
6
|
-
def __init__(self,
|
|
7
|
-
self.
|
|
6
|
+
def __init__(self, omfpandas, omfvista, pv):
|
|
7
|
+
self.omfpandas = omfpandas
|
|
8
8
|
self.omfvista = omfvista
|
|
9
9
|
self.pv = pv
|
|
10
10
|
|
|
@@ -15,7 +15,7 @@ def import_blockmodel_packages():
|
|
|
15
15
|
|
|
16
16
|
# Optional imports
|
|
17
17
|
try:
|
|
18
|
-
import
|
|
18
|
+
import omfpandas
|
|
19
19
|
import omfvista
|
|
20
20
|
import pyvista as pv
|
|
21
21
|
from pyvista import CellType
|
|
@@ -25,10 +25,10 @@ def import_blockmodel_packages():
|
|
|
25
25
|
|
|
26
26
|
if _blockmodel_imports is None:
|
|
27
27
|
try:
|
|
28
|
-
import
|
|
28
|
+
import omfpandas
|
|
29
29
|
import omfvista
|
|
30
30
|
import pyvista as pv
|
|
31
|
-
_blockmodel_imports = (
|
|
31
|
+
_blockmodel_imports = (omfpandas, omfvista, pv)
|
|
32
32
|
except ImportError:
|
|
33
33
|
raise ImportError("Failed to import blockmodel related packages. "
|
|
34
34
|
"Consider executing: 'poetry install --extras blockmodel'")
|
|
@@ -1,26 +1,27 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: geometallurgy
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.14
|
|
4
4
|
Summary: Tools for the geometallurgist
|
|
5
5
|
Home-page: https://github.com/elphick/geometallurgy
|
|
6
6
|
Author: Greg
|
|
7
7
|
Author-email: 11791585+elphick@users.noreply.github.com
|
|
8
|
-
Requires-Python: >=3.
|
|
8
|
+
Requires-Python: >=3.10,<3.13
|
|
9
9
|
Classifier: Programming Language :: Python :: 3
|
|
10
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
11
10
|
Classifier: Programming Language :: Python :: 3.10
|
|
12
11
|
Classifier: Programming Language :: Python :: 3.11
|
|
13
12
|
Provides-Extra: all
|
|
14
13
|
Provides-Extra: blockmodel
|
|
15
|
-
Provides-Extra:
|
|
14
|
+
Provides-Extra: spatial
|
|
16
15
|
Provides-Extra: validation
|
|
17
|
-
Requires-Dist: folium (>=0.16.0,<0.17.0) ; extra == "
|
|
16
|
+
Requires-Dist: folium (>=0.16.0,<0.17.0) ; extra == "spatial"
|
|
17
|
+
Requires-Dist: omfpandas (>=0.8.1,<0.9.0) ; extra == "blockmodel"
|
|
18
18
|
Requires-Dist: omfvista (>=0.3.0) ; extra == "blockmodel"
|
|
19
19
|
Requires-Dist: pandas (>=1.0)
|
|
20
20
|
Requires-Dist: pandera[io] (>=0.19.3,<0.21.0) ; extra == "validation"
|
|
21
21
|
Requires-Dist: periodictable (>=1.7.0,<2.0.0)
|
|
22
22
|
Requires-Dist: plotly (>=5.22.0,<6.0.0)
|
|
23
23
|
Requires-Dist: pyarrow (>=16.1.0,<18.0.0)
|
|
24
|
+
Requires-Dist: rioxarray (>=0.18.2,<0.19.0) ; extra == "spatial"
|
|
24
25
|
Project-URL: Documentation, https://elphick.github.io/geometallurgy
|
|
25
26
|
Project-URL: Repository, https://github.com/elphick/geometallurgy
|
|
26
27
|
Description-Content-Type: text/markdown
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
elphick/geomet/__init__.py,sha256=gcaArz-agLsm_Tf9KNvmGznw4Jml2QTjj_CxKUC1Ejg,274
|
|
2
2
|
elphick/geomet/base.py,sha256=vp0C7DEAAUDGhTdQ8_Hz9WmqZRjNGn7m5CqEGy3L_98,50603
|
|
3
|
-
elphick/geomet/block_model.py,sha256=
|
|
3
|
+
elphick/geomet/block_model.py,sha256=E-krPZfjQVIjTgxdDgp0RbvDTJJLFJbUMELE6dh7Jlk,12937
|
|
4
4
|
elphick/geomet/config/__init__.py,sha256=F94hbxN3KzSaljbElIGVhdEwX0FKmHxST4jJ7rNohxY,35
|
|
5
5
|
elphick/geomet/config/config_read.py,sha256=frRwfRwUXpgxwMNCiBVFUw1-yPbBHs3h2KjmzXImvxY,1396
|
|
6
6
|
elphick/geomet/config/flowsheet_example_partition.yaml,sha256=85vrhOotQHhaKkYN-0QQA7ed03EMRkyaKZc-GtXMKro,716
|
|
@@ -13,7 +13,7 @@ elphick/geomet/datasets/datasets.py,sha256=RUqQWXZTWEA3R4S5RRdjwlosQZFy2PaMX8x32
|
|
|
13
13
|
elphick/geomet/datasets/downloader.py,sha256=JXHQfwQYbe1X-tIfajx4kGbqkcWh0U2k5R03ur2J6E4,1622
|
|
14
14
|
elphick/geomet/datasets/register.csv,sha256=-N3F6L0097C-I79axINi_ewFAxiqbT_SOSW3-XtPkI4,3046
|
|
15
15
|
elphick/geomet/datasets/sample_data.py,sha256=jt5DWxdMmPbZGDuon2s8Q2wlX3cEegB0dSmRKF4pz4I,7684
|
|
16
|
-
elphick/geomet/extras.py,sha256=
|
|
16
|
+
elphick/geomet/extras.py,sha256=UMkAYp72X-30ckaZ-2ENffUUZ7k7JBTdtgsVdgxxYAk,1164
|
|
17
17
|
elphick/geomet/flowsheet/__init__.py,sha256=-lxSLPZNQfiLXKZ2qqS5XbbhrZA2ABi3ppx0LaHnNEI,33
|
|
18
18
|
elphick/geomet/flowsheet/flowsheet.py,sha256=__kgowBIyWfvXcdPWCFihoEUdOqTj7KszSbKGF1AkBo,52032
|
|
19
19
|
elphick/geomet/flowsheet/loader.py,sha256=8nd9Vqbg1de35iuoc4mdRFxrUsIBZed0ivXIAu80jBk,4756
|
|
@@ -41,8 +41,8 @@ elphick/geomet/utils/size.py,sha256=EmV_sv2bOImQN3s7TWCniU_y83HNJEPtZH7fMMkYTcc,
|
|
|
41
41
|
elphick/geomet/utils/timer.py,sha256=8WNKLFcINRsZ3IsKtOIZ77YbKtqczyOOTEWY9h9Uxxw,3112
|
|
42
42
|
elphick/geomet/utils/viz.py,sha256=M0CnfDXBHtYb8aak1Sfz6XLvRSmkzX3ybIDllEmDR8A,1718
|
|
43
43
|
elphick/geomet/validate.py.hide,sha256=qAWJlgq0jp19UakVV0dEU_AsqV_JctUn1QTHn8cCRw0,6738
|
|
44
|
-
geometallurgy-0.4.
|
|
45
|
-
geometallurgy-0.4.
|
|
46
|
-
geometallurgy-0.4.
|
|
47
|
-
geometallurgy-0.4.
|
|
48
|
-
geometallurgy-0.4.
|
|
44
|
+
geometallurgy-0.4.14.dist-info/LICENSE,sha256=GrSVdcGtNbGvAYC_tIjLHBrIVPyg-Ksfe7ZGr087yCI,1069
|
|
45
|
+
geometallurgy-0.4.14.dist-info/METADATA,sha256=9BuaS4pfeVHbV7H6822vaZ2nKUgGgEJ3qbgjREwlzLQ,4476
|
|
46
|
+
geometallurgy-0.4.14.dist-info/WHEEL,sha256=WGfLGfLX43Ei_YORXSnT54hxFygu34kMpcQdmgmEwCQ,88
|
|
47
|
+
geometallurgy-0.4.14.dist-info/entry_points.txt,sha256=aQI-8kmaba_c9ZGOFkJgWl0MWBke5BQLNyPSVcbS7EU,58
|
|
48
|
+
geometallurgy-0.4.14.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|