geometallurgy 0.4.7__tar.gz → 0.4.8__tar.gz
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.
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/PKG-INFO +1 -1
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/base.py +62 -3
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/pyproject.toml +1 -1
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/LICENSE +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/README.md +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/__init__.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/block_model.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/config/__init__.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/config/config_read.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/config/flowsheet_example.yaml +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/config/mc_config.yml +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/data/downloader.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/data/register.csv +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/__init__.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/datasets.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/downloader.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/register.csv +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/sample_data.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/extras.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/__init__.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/flowsheet.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/loader.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/operation.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/stream.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/interval_sample.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/io.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/plot.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/profile.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/sample.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/__init__.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/amenability.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/block_model_converter.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/components.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/data.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/interp.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/layout.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/moisture.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/pandas.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/parallel.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/partition.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/sampling.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/size.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/timer.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/viz.py +0 -0
- {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/validate.py.hide +0 -0
|
@@ -4,10 +4,12 @@ import logging
|
|
|
4
4
|
import re
|
|
5
5
|
from abc import ABC
|
|
6
6
|
from pathlib import Path
|
|
7
|
-
from typing import Optional, Union, Literal, TypeVar, TYPE_CHECKING
|
|
7
|
+
from typing import Optional, Union, Literal, TypeVar, TYPE_CHECKING
|
|
8
8
|
|
|
9
9
|
import numpy as np
|
|
10
10
|
import pandas as pd
|
|
11
|
+
import plotly.express as px
|
|
12
|
+
import plotly.graph_objects as go
|
|
11
13
|
|
|
12
14
|
from elphick.geomet.config import read_yaml
|
|
13
15
|
from elphick.geomet.utils.components import get_components, is_compositional
|
|
@@ -17,8 +19,6 @@ from elphick.geomet.utils.sampling import random_int
|
|
|
17
19
|
from elphick.geomet.utils.timer import log_timer
|
|
18
20
|
from .config.config_read import get_column_config
|
|
19
21
|
from .plot import parallel_plot, comparison_plot
|
|
20
|
-
import plotly.express as px
|
|
21
|
-
import plotly.graph_objects as go
|
|
22
22
|
|
|
23
23
|
if TYPE_CHECKING:
|
|
24
24
|
from elphick.geomet.flowsheet.stream import Stream
|
|
@@ -138,6 +138,22 @@ class MassComposition(ABC):
|
|
|
138
138
|
# Recalculate the aggregate whenever the data changes
|
|
139
139
|
self.aggregate = self.weight_average()
|
|
140
140
|
|
|
141
|
+
def get_mass_data(self, include_moisture: bool = True) -> pd.DataFrame:
|
|
142
|
+
"""Get the mass data
|
|
143
|
+
|
|
144
|
+
Args:
|
|
145
|
+
include_moisture: If True (and moisture is in scope), include the moisture mass column
|
|
146
|
+
|
|
147
|
+
Returns:
|
|
148
|
+
|
|
149
|
+
"""
|
|
150
|
+
if include_moisture and self.moisture_in_scope:
|
|
151
|
+
moisture_mass = self._mass_data[self.mass_wet_var] - self._mass_data[self.mass_dry_var]
|
|
152
|
+
mass_data: pd.DataFrame = self._mass_data.copy()
|
|
153
|
+
mass_data.insert(loc=2, column=self.moisture_column, value=moisture_mass)
|
|
154
|
+
return mass_data
|
|
155
|
+
return self._mass_data
|
|
156
|
+
|
|
141
157
|
@property
|
|
142
158
|
def aggregate(self) -> pd.DataFrame:
|
|
143
159
|
if self._aggregate is None and self._mass_data is not None:
|
|
@@ -235,6 +251,49 @@ class MassComposition(ABC):
|
|
|
235
251
|
|
|
236
252
|
return self
|
|
237
253
|
|
|
254
|
+
def clip_recovery(self, other: MC, recovery_bounds: tuple[float, float] = (0.01, 0.99),
|
|
255
|
+
allow_moisture_coercion: bool = True) -> MC:
|
|
256
|
+
"""Clip the recovery to the specified bounds and recalculate the estimate.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
other: The other MassComposition object, from which the recovery of self is calculated.
|
|
260
|
+
recovery_bounds: The bounds for the recovery between 0.0 and 1.0
|
|
261
|
+
allow_moisture_coercion: if True, allow the wet mass to be modified to maintain the moisture (in the
|
|
262
|
+
case that dry mass is clipped to manage recovery)
|
|
263
|
+
|
|
264
|
+
Returns:
|
|
265
|
+
The MassComposition object with the recovery clipped to the bounds.
|
|
266
|
+
"""
|
|
267
|
+
recovery: pd.DataFrame = (self.get_mass_data(include_moisture=False) /
|
|
268
|
+
other.get_mass_data(include_moisture=False))
|
|
269
|
+
|
|
270
|
+
# Limit the recovery to the bounds
|
|
271
|
+
before_clip = recovery.copy()
|
|
272
|
+
recovery = recovery.clip(lower=recovery_bounds[0], upper=recovery_bounds[1]).fillna(0.0)
|
|
273
|
+
|
|
274
|
+
# Check if any records were affected
|
|
275
|
+
affected_indexes = set(recovery.index[np.any(before_clip != recovery, axis=1)])
|
|
276
|
+
if affected_indexes:
|
|
277
|
+
# Recalculate the estimate from the bound recovery
|
|
278
|
+
new_mass: pd.DataFrame = recovery * other.get_mass_data(include_moisture=False)[recovery.columns]
|
|
279
|
+
|
|
280
|
+
if self.moisture_in_scope and allow_moisture_coercion:
|
|
281
|
+
# Calculate the moisture from the new mass
|
|
282
|
+
new_mass[self.mass_wet_var] = solve_mass_moisture(mass_dry=new_mass[self.mass_dry_var],
|
|
283
|
+
moisture=self.data[self.moisture_column])
|
|
284
|
+
|
|
285
|
+
# Log the top 50 records affected by the recovery coercion
|
|
286
|
+
affected_indexes_list = sorted(affected_indexes)[:50]
|
|
287
|
+
self._logger.info(f"Recovery coercion affected {len(affected_indexes)} records. "
|
|
288
|
+
f"Affected indexes (first 50): {affected_indexes_list}")
|
|
289
|
+
|
|
290
|
+
# Update the mass data of self
|
|
291
|
+
self.update_mass_data(new_mass)
|
|
292
|
+
else:
|
|
293
|
+
self._logger.info("Recovery coercion did not affect any records.")
|
|
294
|
+
|
|
295
|
+
return self
|
|
296
|
+
|
|
238
297
|
def set_moisture(self, moisture: Union[pd.Series, float, int], mass_to_adjust: Literal['wet', 'dry'] = 'wet') -> MC:
|
|
239
298
|
"""Set the moisture to the specified value
|
|
240
299
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "geometallurgy"
|
|
3
3
|
packages = [{ include = "elphick/geomet" }]
|
|
4
|
-
version = "0.4.
|
|
4
|
+
version = "0.4.8"
|
|
5
5
|
description = "Tools for the geometallurgist"
|
|
6
6
|
authors = ["Greg <11791585+elphick@users.noreply.github.com>"]
|
|
7
7
|
repository = "https://github.com/elphick/geometallurgy"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|