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.
Files changed (45) hide show
  1. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/PKG-INFO +1 -1
  2. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/base.py +62 -3
  3. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/pyproject.toml +1 -1
  4. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/LICENSE +0 -0
  5. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/README.md +0 -0
  6. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/__init__.py +0 -0
  7. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/block_model.py +0 -0
  8. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/config/__init__.py +0 -0
  9. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/config/config_read.py +0 -0
  10. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/config/flowsheet_example.yaml +0 -0
  11. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/config/mc_config.yml +0 -0
  12. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/data/downloader.py +0 -0
  13. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/data/register.csv +0 -0
  14. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/__init__.py +0 -0
  15. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/datasets.py +0 -0
  16. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/downloader.py +0 -0
  17. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/register.csv +0 -0
  18. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/datasets/sample_data.py +0 -0
  19. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/extras.py +0 -0
  20. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/__init__.py +0 -0
  21. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/flowsheet.py +0 -0
  22. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/loader.py +0 -0
  23. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/operation.py +0 -0
  24. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/flowsheet/stream.py +0 -0
  25. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/interval_sample.py +0 -0
  26. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/io.py +0 -0
  27. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/plot.py +0 -0
  28. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/profile.py +0 -0
  29. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/sample.py +0 -0
  30. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/__init__.py +0 -0
  31. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/amenability.py +0 -0
  32. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/block_model_converter.py +0 -0
  33. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/components.py +0 -0
  34. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/data.py +0 -0
  35. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/interp.py +0 -0
  36. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/layout.py +0 -0
  37. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/moisture.py +0 -0
  38. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/pandas.py +0 -0
  39. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/parallel.py +0 -0
  40. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/partition.py +0 -0
  41. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/sampling.py +0 -0
  42. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/size.py +0 -0
  43. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/timer.py +0 -0
  44. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/utils/viz.py +0 -0
  45. {geometallurgy-0.4.7 → geometallurgy-0.4.8}/elphick/geomet/validate.py.hide +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: geometallurgy
3
- Version: 0.4.7
3
+ Version: 0.4.8
4
4
  Summary: Tools for the geometallurgist
5
5
  Home-page: https://github.com/elphick/geometallurgy
6
6
  Author: Greg
@@ -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, Any
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.7"
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