diff --git a/raster/r.surf.random/main.c b/raster/r.surf.random/main.c index fc4a9ea4c96..a657ba00498 100644 --- a/raster/r.surf.random/main.c +++ b/raster/r.surf.random/main.c @@ -67,9 +67,12 @@ int main(int argc, char *argv[]) struct Option *out; struct Option *min; struct Option *max; + struct Option *seed; struct Flag *i_flag; double min_value; double max_value; + long seed_value; + char *seedptr; struct History history; char title[64]; @@ -97,6 +100,14 @@ int main(int argc, char *argv[]) max->type = TYPE_DOUBLE; max->answer = "100"; + seed = G_define_option(); + seed->key = "seed"; + seed->type = TYPE_INTEGER; + seed->required = NO; + seed->label = _("Seed for random number generator"); + seed->description = _("The same seed can be used to obtain same results" + " or random seed can be generated by other means."); + i_flag = G_define_flag(); i_flag->key = 'i'; i_flag->description = _("Create an integer raster map"); @@ -107,6 +118,19 @@ int main(int argc, char *argv[]) min_value = atof(min->answer); max_value = atof(max->answer); + if (seed->answer) { + seed_value = strtol(seed->answer, &seedptr, 10); + G_srand48(seed_value); + G_verbose_message(_("Read random seed from %s option: %ld"), seed->key, + seed_value); + } + else { + /* default as it used to be */ + seed_value = G_srand48_auto(); + G_verbose_message(_("Autogenerated random seed set to: %ld"), + seed_value); + } + /* We disallow max=5.5 for integer output since there are unclear * expectations on what it should do. */ if (i_flag->answer) { diff --git a/raster/r.surf.random/randsurf.c b/raster/r.surf.random/randsurf.c index a5214b26e4f..ca3a13ec20e 100644 --- a/raster/r.surf.random/randsurf.c +++ b/raster/r.surf.random/randsurf.c @@ -21,10 +21,6 @@ int randsurf(char *out, double min, double max, int int_map) /* open raster maps. */ int row_count, col_count; - /****** INITIALISE RANDOM NUMBER GENERATOR ******/ - /* You can set GRASS_RANDOM_SEED for repeatability */ - G_srand48_auto(); - /****** OPEN CELL FILES AND GET CELL DETAILS ******/ fd_out = Rast_open_new(out, int_map ? CELL_TYPE : DCELL_TYPE); diff --git a/raster/r.surf.random/testsuite/test_min_max.py b/raster/r.surf.random/testsuite/test_min_max.py index 6a7319ef69e..063f7965771 100644 --- a/raster/r.surf.random/testsuite/test_min_max.py +++ b/raster/r.surf.random/testsuite/test_min_max.py @@ -14,8 +14,6 @@ for details. """ -import os - import grass.script as gs from grass.gunittest.case import TestCase @@ -37,12 +35,9 @@ class MinMaxTestCase(TestCase): @classmethod def setUpClass(cls): """Ensures expected computational region""" - os.environ["GRASS_RANDOM_SEED"] = "42" # modifying region just for this script cls.use_temp_region() - # Only 100,000,000 seem to resonably (not 100%) ensure that all values - # are generated, so exceeding of ranges actually shows up. - cls.runModule("g.region", rows=10000, cols=10000) + cls.runModule("g.region", rows=10, cols=10) @classmethod def tearDownClass(cls): @@ -57,10 +52,9 @@ def test_min_max_double(self): """Check to see if double output has the expected range""" min_value = -3.3 max_value = 5.8 - # arbitrary, but with more cells, we expect higher precision precision = 0.00001 self.assertModule( - "r.surf.random", min=min_value, max=max_value, output=self.output + "r.surf.random", min=min_value, max=max_value, output=self.output, seed=42 ) self.assertRasterExists(self.output, msg="Output was not created") self.assertRasterMinMax( @@ -71,7 +65,7 @@ def test_min_max_double(self): ) self.assertRasterFitsInfo( raster=self.output, - reference=dict(min=min_value, max=max_value), + reference=dict(min=-3.20423, max=5.68621), precision=precision, msg="Output min and max too far from parameters", ) @@ -84,7 +78,12 @@ def test_min_max_int(self): max_value = 13 precision = 0 self.assertModule( - "r.surf.random", min=min_value, max=max_value, output=self.output, flags="i" + "r.surf.random", + min=min_value, + max=max_value, + output=self.output, + seed=42, + flags="i", ) self.assertRasterExists(self.output, msg="Output was not created") self.assertRasterMinMax( @@ -105,7 +104,12 @@ def test_double_params_with_int(self): min_value = -3.3 max_value = 5.8 self.assertModuleFail( - "r.surf.random", min=min_value, max=max_value, output=self.output, flags="i" + "r.surf.random", + min=min_value, + max=max_value, + output=self.output, + seed=42, + flags="i", ) def test_min_greater_than_max(self): @@ -113,6 +117,14 @@ def test_min_greater_than_max(self): min_value = 10 max_value = 5.8 self.assertModuleFail( + "r.surf.random", min=min_value, max=max_value, output=self.output, seed=42 + ) + + def test_auto_seed(self): + """Check if random seed is generated without seed""" + min_value = -3.3 + max_value = 5.8 + self.assertModule( "r.surf.random", min=min_value, max=max_value, output=self.output )