yirgacheffe 1.7.0__tar.gz → 1.7.2__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.

Potentially problematic release.


This version of yirgacheffe might be problematic. Click here for more details.

Files changed (56) hide show
  1. {yirgacheffe-1.7.0/yirgacheffe.egg-info → yirgacheffe-1.7.2}/PKG-INFO +1 -1
  2. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/pyproject.toml +1 -1
  3. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_openers.py +22 -0
  4. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_operators.py +46 -34
  5. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_pickle.py +2 -3
  6. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_raster.py +10 -1
  7. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_vectors.py +5 -1
  8. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/_core.py +2 -2
  9. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/base.py +6 -1
  10. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/group.py +8 -8
  11. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/vectors.py +5 -1
  12. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/operators.py +8 -4
  13. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2/yirgacheffe.egg-info}/PKG-INFO +1 -1
  14. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/LICENSE +0 -0
  15. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/MANIFEST.in +0 -0
  16. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/README.md +0 -0
  17. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/setup.cfg +0 -0
  18. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_area.py +0 -0
  19. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_auto_windowing.py +0 -0
  20. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_base.py +0 -0
  21. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_constants.py +0 -0
  22. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_datatypes.py +0 -0
  23. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_group.py +0 -0
  24. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_h3layer.py +0 -0
  25. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_intersection.py +0 -0
  26. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_multiband.py +0 -0
  27. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_nodata.py +0 -0
  28. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_optimisation.py +0 -0
  29. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_parallel_operators.py +0 -0
  30. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_projection.py +0 -0
  31. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_rescaling.py +0 -0
  32. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_rounding.py +0 -0
  33. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_save_with_window.py +0 -0
  34. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_sum_with_window.py +0 -0
  35. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_uniform_area_layer.py +0 -0
  36. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_union.py +0 -0
  37. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/tests/test_window.py +0 -0
  38. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/__init__.py +0 -0
  39. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/_backends/__init__.py +0 -0
  40. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/_backends/enumeration.py +0 -0
  41. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/_backends/mlx.py +0 -0
  42. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/_backends/numpy.py +0 -0
  43. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/constants.py +0 -0
  44. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/__init__.py +0 -0
  45. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/area.py +0 -0
  46. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/constant.py +0 -0
  47. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/h3layer.py +0 -0
  48. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/rasters.py +0 -0
  49. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/layers/rescaled.py +0 -0
  50. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/rounding.py +0 -0
  51. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe/window.py +0 -0
  52. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe.egg-info/SOURCES.txt +0 -0
  53. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe.egg-info/dependency_links.txt +0 -0
  54. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe.egg-info/entry_points.txt +0 -0
  55. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe.egg-info/requires.txt +0 -0
  56. {yirgacheffe-1.7.0 → yirgacheffe-1.7.2}/yirgacheffe.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yirgacheffe
3
- Version: 1.7.0
3
+ Version: 1.7.2
4
4
  Summary: Abstraction of gdal datasets for doing basic math operations
5
5
  Author-email: Michael Dales <mwd24@cam.ac.uk>
6
6
  License-Expression: ISC
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "yirgacheffe"
9
- version = "1.7.0"
9
+ version = "1.7.2"
10
10
  description = "Abstraction of gdal datasets for doing basic math operations"
11
11
  readme = "README.md"
12
12
  authors = [{ name = "Michael Dales", email = "mwd24@cam.ac.uk" }]
@@ -191,3 +191,25 @@ def test_open_two_raster_areas_side_by_side(tiled):
191
191
  with yg.read_raster(path1) as raster1:
192
192
  with yg.read_raster(path2) as raster2:
193
193
  assert group.sum() == raster1.sum() + raster2.sum()
194
+
195
+ @pytest.mark.parametrize("tiled", [False, True])
196
+ def test_open_two_raster_by_glob(tiled):
197
+ with tempfile.TemporaryDirectory() as tempdir:
198
+ temppath = Path(tempdir)
199
+ path1 = temppath / "test1.tif"
200
+ area1 = Area(-10, 10, 10, -10)
201
+ dataset1 = gdal_dataset_of_region(area1, 0.2, filename=path1)
202
+ dataset1.Close()
203
+
204
+ path2 = temppath / "test2.tif"
205
+ area2 = Area(10, 10, 30, -10)
206
+ dataset2 = gdal_dataset_of_region(area2, 0.2, filename=path2)
207
+ dataset2.Close()
208
+
209
+ with yg.read_rasters(temppath.glob("*.tif"), tiled=tiled) as group:
210
+ assert group.area == Area(-10, 10, 30, -10)
211
+ assert group.window == Window(0, 0, 200, 100)
212
+
213
+ with yg.read_raster(path1) as raster1:
214
+ with yg.read_raster(path2) as raster2:
215
+ assert group.sum() == raster1.sum() + raster2.sum()
@@ -1472,42 +1472,54 @@ def test_to_geotiff_single_thread_and_sum() -> None:
1472
1472
  assert (expected == actual).all()
1473
1473
 
1474
1474
  @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
1475
- def test_to_geotiff_parallel_thread(monkeypatch) -> None:
1476
- data1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
1477
- layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
1478
-
1479
- calc = layer1 * 2
1480
-
1481
- with tempfile.TemporaryDirectory() as tempdir:
1482
- filename = os.path.join(tempdir, "test.tif")
1483
- with monkeypatch.context() as m:
1484
- m.setattr(yirgacheffe.constants, "YSTEP", 1)
1485
- calc.to_geotiff(filename, parallelism=2)
1486
-
1487
- with RasterLayer.layer_from_file(filename) as result:
1488
- expected = data1 * 2
1489
- actual = result.read_array(0, 0, 4, 2)
1490
- assert (expected == actual).all()
1475
+ @pytest.mark.parametrize("parallelism", [
1476
+ 2,
1477
+ True,
1478
+ ])
1479
+ def test_to_geotiff_parallel_thread(monkeypatch, parallelism) -> None:
1480
+ with monkeypatch.context() as m:
1481
+ m.setattr(yirgacheffe.constants, "YSTEP", 1)
1482
+ m.setattr(LayerOperation, "save", None)
1483
+ with tempfile.TemporaryDirectory() as tempdir:
1484
+ data1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
1485
+ src_filename = os.path.join("src.tif")
1486
+ dataset = gdal_dataset_with_data((0.0, 0.0), 0.02, data1, filename=src_filename)
1487
+ dataset.Close()
1488
+ with yirgacheffe.read_raster(src_filename) as layer1:
1489
+ calc = layer1 * 2
1490
+ filename = os.path.join(tempdir, "test.tif")
1491
+ calc.to_geotiff(filename, parallelism=parallelism)
1492
+
1493
+ with RasterLayer.layer_from_file(filename) as result:
1494
+ expected = data1 * 2
1495
+ actual = result.read_array(0, 0, 4, 2)
1496
+ assert (expected == actual).all()
1491
1497
 
1492
1498
  @pytest.mark.skipif(yirgacheffe._backends.BACKEND != "NUMPY", reason="Only applies for numpy")
1493
- def test_to_geotiff_parallel_thread_and_sum(monkeypatch) -> None:
1494
- data1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
1495
- layer1 = RasterLayer(gdal_dataset_with_data((0.0, 0.0), 0.02, data1))
1496
-
1497
- calc = layer1 * 2
1498
-
1499
- with tempfile.TemporaryDirectory() as tempdir:
1500
- filename = os.path.join(tempdir, "test.tif")
1501
- with monkeypatch.context() as m:
1502
- m.setattr(yirgacheffe.constants, "YSTEP", 1)
1503
- actual_sum = calc.to_geotiff(filename, and_sum=True)
1504
-
1505
- assert (data1.sum() * 2) == actual_sum
1506
-
1507
- with RasterLayer.layer_from_file(filename) as result:
1508
- expected = data1 * 2
1509
- actual = result.read_array(0, 0, 4, 2)
1510
- assert (expected == actual).all()
1499
+ @pytest.mark.parametrize("parallelism", [
1500
+ 2,
1501
+ True,
1502
+ ])
1503
+ def test_to_geotiff_parallel_thread_and_sum(monkeypatch, parallelism) -> None:
1504
+ with monkeypatch.context() as m:
1505
+ m.setattr(yirgacheffe.constants, "YSTEP", 1)
1506
+ m.setattr(LayerOperation, "save", None)
1507
+ with tempfile.TemporaryDirectory() as tempdir:
1508
+ data1 = np.array([[1, 2, 3, 4], [5, 6, 7, 8]])
1509
+ src_filename = os.path.join("src.tif")
1510
+ dataset = gdal_dataset_with_data((0.0, 0.0), 0.02, data1, filename=src_filename)
1511
+ dataset.Close()
1512
+ with yirgacheffe.read_raster(src_filename) as layer1:
1513
+ filename = os.path.join(tempdir, "test.tif")
1514
+ calc = layer1 * 2
1515
+ actual_sum = calc.to_geotiff(filename, and_sum=True, parallelism=parallelism)
1516
+
1517
+ assert (data1.sum() * 2) == actual_sum
1518
+
1519
+ with RasterLayer.layer_from_file(filename) as result:
1520
+ expected = data1 * 2
1521
+ actual = result.read_array(0, 0, 4, 2)
1522
+ assert (expected == actual).all()
1511
1523
 
1512
1524
  def test_raster_and_vector() -> None:
1513
1525
  with tempfile.TemporaryDirectory() as tempdir:
@@ -12,7 +12,6 @@ from yirgacheffe.window import Area, MapProjection, PixelScale, Window
12
12
  from yirgacheffe.layers import ConstantLayer, GroupLayer, RasterLayer, RescaledRasterLayer, \
13
13
  UniformAreaLayer, VectorLayer
14
14
  from yirgacheffe import WGS_84_PROJECTION
15
- from yirgacheffe._backends import backend
16
15
 
17
16
 
18
17
  def test_pickle_raster_layer() -> None:
@@ -97,7 +96,7 @@ def test_pickle_group_layer() -> None:
97
96
 
98
97
  group = GroupLayer.layer_from_directory(tempdir)
99
98
  expected = group.read_array(0, 0, 100, 100)
100
- assert backend.sum_op(expected) != 0 # just check there is meaningful data
99
+ assert expected.sum() != 0 # just check there is meaningful data
101
100
 
102
101
  p = pickle.dumps(group)
103
102
  restore = pickle.loads(p)
@@ -192,4 +191,4 @@ def test_pickle_rescaled_raster_layer() -> None:
192
191
  assert restore.window == Window(0, 0, 2000, 2000)
193
192
 
194
193
  expected = restore.read_array(0, 0, 100, 100)
195
- assert backend.sum_op(expected) != 0 # just check there is meaningful data
194
+ assert expected.sum() != 0 # just check there is meaningful data
@@ -5,7 +5,7 @@ import numpy as np
5
5
  import pytest
6
6
  from osgeo import gdal
7
7
 
8
- from tests.helpers import gdal_dataset_of_region, gdal_multiband_dataset_with_data
8
+ from tests.helpers import gdal_dataset_of_region, gdal_multiband_dataset_with_data, gdal_dataset_with_data
9
9
  from yirgacheffe.window import Area, PixelScale, Window
10
10
  from yirgacheffe.layers import RasterLayer, InvalidRasterBand
11
11
  from yirgacheffe.rounding import round_up_pixels
@@ -260,3 +260,12 @@ def test_multiband_raster() -> None:
260
260
  layer = layers[i]
261
261
  actual = layer.read_array(0, 0, 4, 2)
262
262
  assert (data == actual).all()
263
+
264
+ def test_read_array_is_numpy():
265
+ # This test will fail if we use say the MLX backend without casting it back to numpy
266
+ data = np.array([[1.0, 2.0, 3.0, 4.0], [5.0, 6.0, 7.0, 8.0]])
267
+ dataset = gdal_dataset_with_data((0.0, 0.0), 0.02, data)
268
+ with RasterLayer(dataset) as layer1:
269
+ actual = layer1.read_array(0, 0, 4, 2).astype(int)
270
+ expected = data.astype(int)
271
+ assert (actual == expected).all
@@ -19,7 +19,7 @@ def test_basic_vector_layer_no_filter_match() -> None:
19
19
  with RasteredVectorLayer.layer_from_file(path, "id_no = 123", PixelScale(1.0, -1.0), "WGS 84") as _layer:
20
20
  pass
21
21
 
22
- def test_basic_dyanamic_vector_layer() -> None:
22
+ def test_basic_dynamic_vector_layer() -> None:
23
23
  with tempfile.TemporaryDirectory() as tempdir:
24
24
  path = os.path.join(tempdir, "test.gpkg")
25
25
  area = Area(-10.0, 10.0, 10.0, 0.0)
@@ -31,6 +31,10 @@ def test_basic_dyanamic_vector_layer() -> None:
31
31
  assert layer.window == Window(0, 0, 20, 10)
32
32
  assert layer.projection == WGS_84_PROJECTION
33
33
 
34
+ # The astype here is to catch escaping MLX types...
35
+ res = layer.read_array(0, 0, 20, 20).astype(int)
36
+ assert res.sum() > 0
37
+
34
38
  def test_rastered_vector_layer() -> None:
35
39
  with tempfile.TemporaryDirectory() as tempdir:
36
40
  path = os.path.join(tempdir, "test.gpkg")
@@ -1,5 +1,5 @@
1
1
  from pathlib import Path
2
- from typing import List, Optional, Tuple, Union
2
+ from typing import Optional, Sequence, Tuple, Union
3
3
 
4
4
  from .layers.base import YirgacheffeLayer
5
5
  from .layers.group import GroupLayer, TiledGroupLayer
@@ -32,7 +32,7 @@ def read_raster(
32
32
  return RasterLayer.layer_from_file(filename, band, ignore_nodata)
33
33
 
34
34
  def read_rasters(
35
- filenames : Union[List[Path],List[str]],
35
+ filenames : Sequence[Union[Path,str]],
36
36
  tiled: bool=False
37
37
  ) -> GroupLayer:
38
38
  """Open a set of raster files (e.g., GeoTIFFs) as a single layer.
@@ -7,6 +7,7 @@ from .. import __version__
7
7
  from ..operators import DataType, LayerMathMixin
8
8
  from ..rounding import almost_equal, round_up_pixels, round_down_pixels
9
9
  from ..window import Area, MapProjection, PixelScale, Window
10
+ from .._backends import backend
10
11
 
11
12
  class YirgacheffeLayer(LayerMathMixin):
12
13
  """The common base class for the different layer types. Most still inherit from RasterLayer as deep down
@@ -310,6 +311,9 @@ class YirgacheffeLayer(LayerMathMixin):
310
311
  )
311
312
  return self._read_array_with_window(x, y, width, height, target_window)
312
313
 
314
+ def _read_array(self, x: int, y: int, width: int, height: int) -> Any:
315
+ return self._read_array_with_window(x, y, width, height, self.window)
316
+
313
317
  def read_array(self, x: int, y: int, width: int, height: int) -> Any:
314
318
  """Reads data from the layer based on the current reference window.
315
319
 
@@ -329,7 +333,8 @@ class YirgacheffeLayer(LayerMathMixin):
329
333
  Any
330
334
  An array of values from the layer.
331
335
  """
332
- return self._read_array_with_window(x, y, width, height, self.window)
336
+ res = self._read_array(x, y, width, height)
337
+ return backend.demote_array(res)
333
338
 
334
339
  def latlng_for_pixel(self, x_coord: int, y_coord: int) -> Tuple[float,float]:
335
340
  """Get geo coords for pixel. This is relative to the set view window."""
@@ -1,7 +1,7 @@
1
1
  from __future__ import annotations
2
2
  import copy
3
3
  from pathlib import Path
4
- from typing import Any, List, Optional, Union
4
+ from typing import Any, List, Optional, Sequence, Union
5
5
 
6
6
  import numpy as np
7
7
  from numpy import ma
@@ -39,14 +39,14 @@ class GroupLayer(YirgacheffeLayer):
39
39
  @classmethod
40
40
  def layer_from_files(
41
41
  cls,
42
- filenames: Union[List[Path],List[str]],
42
+ filenames: Sequence[Union[Path,str]],
43
43
  name: Optional[str] = None
44
44
  ) -> GroupLayer:
45
45
  if filenames is None:
46
46
  raise ValueError("filenames argument is None")
47
- if len(filenames) < 1:
48
- raise GroupLayerEmpty("No files found")
49
47
  rasters: List[YirgacheffeLayer] = [RasterLayer.layer_from_file(x) for x in filenames]
48
+ if len(rasters) < 1:
49
+ raise GroupLayerEmpty("No files found")
50
50
  return cls(rasters, name)
51
51
 
52
52
  def __init__(
@@ -144,7 +144,7 @@ class GroupLayer(YirgacheffeLayer):
144
144
  if len(contributing_layers) == 1:
145
145
  layer, adjusted_layer_window, intersection = contributing_layers[0]
146
146
  if target_window == intersection:
147
- data = layer.read_array(
147
+ data = layer._read_array(
148
148
  intersection.xoff - adjusted_layer_window.xoff,
149
149
  intersection.yoff - adjusted_layer_window.yoff,
150
150
  intersection.xsize,
@@ -156,11 +156,11 @@ class GroupLayer(YirgacheffeLayer):
156
156
 
157
157
  result = np.zeros((ysize, xsize), dtype=float)
158
158
  for layer, adjusted_layer_window, intersection in contributing_layers:
159
- data = layer.read_array(
159
+ data = layer._read_array(
160
160
  intersection.xoff - adjusted_layer_window.xoff,
161
161
  intersection.yoff - adjusted_layer_window.yoff,
162
162
  intersection.xsize,
163
- intersection.ysize,
163
+ intersection.ysize
164
164
  )
165
165
  result_x_offset = (intersection.xoff - xoffset) - window.xoff
166
166
  result_y_offset = (intersection.yoff - yoffset) - window.yoff
@@ -269,7 +269,7 @@ class TiledGroupLayer(GroupLayer):
269
269
  intersection = Window.find_intersection_no_throw([target_window, adjusted_layer_window])
270
270
  if intersection is None:
271
271
  continue
272
- data = layer.read_array(
272
+ data = layer._read_array(
273
273
  intersection.xoff - adjusted_layer_window.xoff,
274
274
  intersection.yoff - adjusted_layer_window.yoff,
275
275
  intersection.xsize,
@@ -490,5 +490,9 @@ class VectorLayer(YirgacheffeLayer):
490
490
  def _read_array_with_window(self, _x, _y, _width, _height, _window) -> Any:
491
491
  assert NotRequired
492
492
 
493
- def read_array(self, x: int, y: int, width: int, height: int) -> Any:
493
+ def _read_array(self, x: int, y: int, width: int, height: int) -> Any:
494
494
  return self._read_array_for_area(self.area, None, x, y, width, height)
495
+
496
+ def read_array(self, x: int, y: int, width: int, height: int) -> Any:
497
+ res = self._read_array(x, y, width, height)
498
+ return backend.demote_array(res)
@@ -251,7 +251,7 @@ class LayerMathMixin:
251
251
  self,
252
252
  filename: Union[Path,str],
253
253
  and_sum: bool = False,
254
- parallelism:Optional[int]=None
254
+ parallelism:Optional[Union[int,bool]]=None
255
255
  ) -> Optional[float]:
256
256
  return LayerOperation(self).to_geotiff(filename, and_sum, parallelism)
257
257
 
@@ -899,7 +899,7 @@ class LayerOperation(LayerMathMixin):
899
899
  self,
900
900
  filename: Union[Path,str],
901
901
  and_sum: bool = False,
902
- parallelism:Optional[int]=None
902
+ parallelism:Optional[Union[int,bool]] = None
903
903
  ) -> Optional[float]:
904
904
  """Saves a calculation to a raster file, optionally also returning the sum of pixels.
905
905
 
@@ -909,8 +909,9 @@ class LayerOperation(LayerMathMixin):
909
909
  Path of the raster to save the result to.
910
910
  and_sum : bool, default=False
911
911
  If true then the function will also calculate the sum of the raster as it goes and return that value.
912
- parallelism : int, optional, default=None
913
- If passed, attempt to use multiple CPU cores up to the number provided.
912
+ parallelism : int or bool, optional, default=None
913
+ If passed, attempt to use multiple CPU cores up to the number provided, or if set to True, yirgacheffe
914
+ will pick a sensible value.
914
915
 
915
916
  Returns
916
917
  -------
@@ -932,6 +933,9 @@ class LayerOperation(LayerMathMixin):
932
933
  if parallelism is None:
933
934
  result = self.save(layer, and_sum=and_sum)
934
935
  else:
936
+ if isinstance(parallelism, bool):
937
+ # Parallel save treats None as "work it out"
938
+ parallelism = None
935
939
  result = self.parallel_save(layer, and_sum=and_sum, parallelism=parallelism)
936
940
 
937
941
  os.makedirs(target_dir, exist_ok=True)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: yirgacheffe
3
- Version: 1.7.0
3
+ Version: 1.7.2
4
4
  Summary: Abstraction of gdal datasets for doing basic math operations
5
5
  Author-email: Michael Dales <mwd24@cam.ac.uk>
6
6
  License-Expression: ISC
File without changes
File without changes
File without changes
File without changes