77from pathlib import Path
88from multiprocessing import Manager , Process , cpu_count
99from queue import Queue
10- from typing import List , NamedTuple , Optional , Tuple
10+ from typing import NamedTuple
1111
1212import numpy as np
1313import yirgacheffe as yg
@@ -32,8 +32,11 @@ def process_tile(
3232 current : yg .layers .RasterLayer ,
3333 pnv : yg .layers .RasterLayer ,
3434 tile : TileInfo ,
35+ random_seed : int ,
3536) -> np .ndarray :
3637
38+ rng = np .random .default_rng (random_seed )
39+
3740 data = current .read_array (tile .x_position , tile .y_position , tile .width , tile .height )
3841
3942 diffs = [
@@ -61,7 +64,7 @@ def process_tile(
6164 continue
6265 required_points = min (required_points , possible_points )
6366
64- selected_locations = np . random .choice (
67+ selected_locations = rng .choice (
6568 len (valid_locations [0 ]),
6669 size = required_points ,
6770 replace = False
@@ -90,13 +93,14 @@ def process_tile_concurrently(
9093 with yg .read_raster (current_lvl1_path ) as current :
9194 with yg .read_raster (pnv_path ) as pnv :
9295 while True :
93- tile : Optional [TileInfo ] = input_queue .get ()
94- if tile is None :
96+ job : tuple [TileInfo , int ] | None = input_queue .get ()
97+ if job is None :
9598 break
99+ tile , seed = job
96100 if np .isnan (tile .crop_diff ) and np .isnan (tile .pasture_diff ):
97101 result_queue .put ((tile , None ))
98102 else :
99- data = process_tile (current , pnv , tile )
103+ data = process_tile (current , pnv , tile , seed )
100104 result_queue .put ((tile , data .tobytes ()))
101105
102106 result_queue .put (None )
@@ -105,7 +109,7 @@ def build_tile_list(
105109 current_lvl1_path : Path ,
106110 crop_adjustment_path : Path ,
107111 pasture_adjustment_path : Path ,
108- ) -> List [TileInfo ]:
112+ ) -> list [TileInfo ]:
109113 tiles = []
110114 with yg .read_raster (current_lvl1_path ) as current :
111115 current_dimensions = current .window .xsize , current .window .ysize
@@ -151,7 +155,7 @@ def assemble_map(
151155 band = output ._dataset .GetRasterBand (1 ) # pylint: disable=W0212
152156
153157 while True :
154- result : Optional [ Tuple [ TileInfo ,Optional [ bytearray ]]] = result_queue .get ()
158+ result : tuple [ TileInfo ,bytearray | None ] | None = result_queue .get ()
155159 if result is None :
156160 sentinal_count -= 1
157161 if sentinal_count == 0 :
@@ -174,14 +178,18 @@ def pipeline_source(
174178 pasture_adjustment_path : Path ,
175179 source_queue : Queue ,
176180 sentinal_count : int ,
181+ random_seed : int ,
177182) -> None :
183+ rng = np .random .default_rng (random_seed )
184+
178185 tiles = build_tile_list (
179186 current_lvl1_path ,
180187 crop_adjustment_path ,
181188 pasture_adjustment_path ,
182189 )
183- for tile in tiles :
184- source_queue .put (tile )
190+ seeds = rng .integers (2 ** 63 , size = len (tiles ))
191+ for tile , seed in zip (tiles , seeds ):
192+ source_queue .put ((tile , seed ))
185193 for _ in range (sentinal_count ):
186194 source_queue .put (None )
187195
@@ -190,6 +198,7 @@ def make_food_current_map(
190198 pnv_path : Path ,
191199 crop_adjustment_path : Path ,
192200 pasture_adjustment_path : Path ,
201+ random_seed : int ,
193202 output_path : Path ,
194203 processes_count : int ,
195204) -> None :
@@ -210,7 +219,7 @@ def make_food_current_map(
210219 pnv_path ,
211220 source_queue ,
212221 result_queue ,
213- )) for index in range (processes_count )]
222+ )) for _ in range (processes_count )]
214223 for worker_process in workers :
215224 worker_process .start ()
216225
@@ -220,6 +229,7 @@ def make_food_current_map(
220229 pasture_adjustment_path ,
221230 source_queue ,
222231 processes_count ,
232+ random_seed ,
223233 ))
224234 source_worker .start ()
225235
@@ -273,6 +283,13 @@ def main() -> None:
273283 help = "Path of adjustment for pasture diff" ,
274284 dest = "pasture_adjustment_path" ,
275285 )
286+ parser .add_argument (
287+ "--seed" ,
288+ type = int ,
289+ required = True ,
290+ help = "Seed the random number generator" ,
291+ dest = "seed" ,
292+ )
276293 parser .add_argument (
277294 '--output' ,
278295 type = Path ,
@@ -295,6 +312,7 @@ def main() -> None:
295312 args .pnv_path ,
296313 args .crop_adjustment_path ,
297314 args .pasture_adjustment_path ,
315+ args .seed ,
298316 args .output_path ,
299317 args .processes_count ,
300318 )
0 commit comments