[GRASS-SVN] r61475 - in grass/branches/releasebranch_7_0: gui/wxpython/modules lib/init lib/python/script raster/r.mapcalc temporal/t.rast.neighbors
svn_grass at osgeo.org
svn_grass at osgeo.org
Thu Jul 31 05:08:48 PDT 2014
Author: neteler
Date: 2014-07-31 05:08:48 -0700 (Thu, 31 Jul 2014)
New Revision: 61475
Modified:
grass/branches/releasebranch_7_0/gui/wxpython/modules/mcalc_builder.py
grass/branches/releasebranch_7_0/lib/init/variables.html
grass/branches/releasebranch_7_0/lib/python/script/raster.py
grass/branches/releasebranch_7_0/raster/r.mapcalc/evaluate.c
grass/branches/releasebranch_7_0/raster/r.mapcalc/globals.h
grass/branches/releasebranch_7_0/raster/r.mapcalc/main.c
grass/branches/releasebranch_7_0/raster/r.mapcalc/map.c
grass/branches/releasebranch_7_0/raster/r.mapcalc/r.mapcalc.html
grass/branches/releasebranch_7_0/raster/r.mapcalc/r3.mapcalc.html
grass/branches/releasebranch_7_0/raster/r.mapcalc/xrand.c
grass/branches/releasebranch_7_0/temporal/t.rast.neighbors/t.rast.neighbors.html
Log:
r.mapcalc: Replace GRASS_RND_SEED with seed= option and -s flag, Use lib/gis PRNG, Store seed in history (r61353); wxGUI/mapcalc: seed handling added to the interface (r61354); GRASS_RND_SEED replaced by seed= (r61358); Add seed= parameter to grass.script.mapcalc() (r61388); python: Add env= parameter to mapcalc, mapcalc_start, raster_what (r61428)
Modified: grass/branches/releasebranch_7_0/gui/wxpython/modules/mcalc_builder.py
===================================================================
--- grass/branches/releasebranch_7_0/gui/wxpython/modules/mcalc_builder.py 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/gui/wxpython/modules/mcalc_builder.py 2014-07-31 12:08:48 UTC (rev 61475)
@@ -28,6 +28,7 @@
from core.utils import _
from gui_core.gselect import Select
from gui_core.forms import GUI
+from gui_core.widgets import IntegerValidator
from core.settings import UserSettings
class MapCalcFrame(wx.Frame):
@@ -230,7 +231,18 @@
self.overwrite = wx.CheckBox(parent = self.panel, id = wx.ID_ANY,
label=_("Allow output files to overwrite existing files"))
self.overwrite.SetValue(UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))
+
+ self.randomSeed = wx.CheckBox(parent=self.panel,
+ label=_("Generate random seed for rand()"))
+ self.randomSeedStaticText = wx.StaticText(parent=self.panel, label=_("Seed:"))
+ self.randomSeedText = wx.TextCtrl(parent=self.panel, size=(100, -1),
+ validator=IntegerValidator())
+ self.randomSeedText.SetToolTipString(_("Integer seed for rand() function"))
+ self.randomSeed.SetValue(True)
+ self.randomSeedStaticText.Disable()
+ self.randomSeedText.Disable()
+
self.addbox = wx.CheckBox(parent=self.panel,
label=_('Add created raster map into layer tree'), style = wx.NO_BORDER)
self.addbox.SetValue(UserSettings.Get(group='cmd', key='addNewLayer', subkey='enabled'))
@@ -258,6 +270,9 @@
self.newmaptxt.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
self.text_mcalc.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
self.overwrite.Bind(wx.EVT_CHECKBOX, self.OnUpdateStatusBar)
+ self.randomSeed.Bind(wx.EVT_CHECKBOX, self.OnUpdateStatusBar)
+ self.randomSeed.Bind(wx.EVT_CHECKBOX, self.OnSeedFlag)
+ self.randomSeedText.Bind(wx.EVT_TEXT, self.OnUpdateStatusBar)
self._layout()
@@ -379,7 +394,17 @@
border = 5)
sizer.Add(item = buttonSizer4, proportion = 0,
flag = wx.ALIGN_RIGHT | wx.ALL, border = 3)
-
+
+ randomSizer = wx.BoxSizer(wx.HORIZONTAL)
+ randomSizer.Add(item=self.randomSeed, proportion=0,
+ flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border=20)
+ randomSizer.Add(item=self.randomSeedStaticText, proportion=0,
+ flag=wx.RIGHT | wx.ALIGN_CENTER_VERTICAL, border=5)
+ randomSizer.Add(item=self.randomSeedText, proportion=0)
+ sizer.Add(item=randomSizer, proportion=0,
+ flag=wx.LEFT | wx.RIGHT,
+ border=5)
+
sizer.Add(item = self.overwrite, proportion = 0,
flag = wx.LEFT | wx.RIGHT,
border = 5)
@@ -458,6 +483,13 @@
self.SetStatusText(command)
event.Skip()
+ def OnSeedFlag(self, event):
+ checked = self.randomSeed.IsChecked()
+ self.randomSeedText.Enable(not checked)
+ self.randomSeedStaticText.Enable(not checked)
+
+ event.Skip()
+
def _getCommand(self):
"""Returns entire command as string."""
expr = self.text_mcalc.GetValue().strip().replace("\n", " ")
@@ -467,10 +499,17 @@
overwrite = ''
if self.overwrite.IsChecked():
overwrite = ' --overwrite'
- return '{cmd} "{new} = {expr}"{overwrite}'.format(cmd=cmd, expr=expr,
- new=self.newmaptxt.GetValue(),
- overwrite=overwrite)
+ seed_flag = seed = ''
+ if re.search(pattern="rand *\(.+\)", string=expr):
+ if self.randomSeed.IsChecked():
+ seed_flag = ' -s'
+ else:
+ seed = " seed={val}".format(val=self.randomSeedText.GetValue().strip())
+ return ('{cmd} "{new} = {expr}"{seed}{seed_flag}{overwrite}'
+ .format(cmd=cmd, expr=expr, new=self.newmaptxt.GetValue(),
+ seed_flag=seed_flag, seed=seed, overwrite=overwrite))
+
def _addSomething(self, what):
"""!Inserts operators, map names, and functions into text area
"""
@@ -520,11 +559,23 @@
message = _("You must enter an expression "
"to create a new raster map."))
return
-
+
+ seed_flag = seed = None
+ if re.search(pattern="rand *\(.+\)", string=expr):
+ if self.randomSeed.IsChecked():
+ seed_flag = '-s'
+ else:
+ seed = self.randomSeedText.GetValue().strip()
if self.log:
- cmd = [self.cmd, str('expression=%s = %s' % (name, expr))]
+ cmd = [self.cmd]
+ if seed_flag:
+ cmd.append('-s')
+ if seed:
+ cmd.append("seed={val}".format(val=seed))
if self.overwrite.IsChecked():
cmd.append('--overwrite')
+ cmd.append(str('expression=%s = %s' % (name, expr)))
+
self.log.RunCmd(cmd, onDone = self.OnDone)
self.parent.Raise()
else:
@@ -532,10 +583,16 @@
overwrite = True
else:
overwrite = False
+ params = dict(expression="%s=%s" % (name, expr),
+ overwrite=overwrite)
+ if seed_flag:
+ params['flags'] = 's'
+ if seed:
+ params['seed'] = seed
+
RunCommand(self.cmd,
- expression = "%s=%s" % (name, expr),
- overwrite = overwrite)
-
+ **params)
+
def OnDone(self, cmd, returncode):
"""!Add create map to the layer tree
Modified: grass/branches/releasebranch_7_0/lib/init/variables.html
===================================================================
--- grass/branches/releasebranch_7_0/lib/init/variables.html 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/lib/init/variables.html 2014-07-31 12:08:48 UTC (rev 61475)
@@ -201,11 +201,6 @@
<dd>[used during install process for generating man pages]<br>
set Perl with path.</dd>
- <dt>GRASS_RND_SEED</dt>
- <dd>set random seed
- for <em><a href="r.mapcalc.html">r.mapcalc</a></em> rand()
- function.</dd>
-
<dt>GRASS_SKIP_MAPSET_OWNER_CHECK</dt>
<dd>By default it is not possible to work with MAPSETs that are
not owned by current user. Setting this variable to any non-empty value
Modified: grass/branches/releasebranch_7_0/lib/python/script/raster.py
===================================================================
--- grass/branches/releasebranch_7_0/lib/python/script/raster.py 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/lib/python/script/raster.py 2014-07-31 12:08:48 UTC (rev 61475)
@@ -25,6 +25,7 @@
import os
import string
import types
+import time
from core import *
@@ -86,26 +87,37 @@
# interface to r.mapcalc
-def mapcalc(exp, quiet = False, verbose = False, overwrite = False, **kwargs):
+def mapcalc(exp, quiet = False, verbose = False, overwrite = False,
+ seed = None, env = None, **kwargs):
"""!Interface to r.mapcalc.
@param exp expression
@param quiet True to run quietly (<tt>--q</tt>)
@param verbose True to run verbosely (<tt>--v</tt>)
@param overwrite True to enable overwriting the output (<tt>--o</tt>)
+ @param seed an integer used to seed the random-number generator for the rand() function,
+ or 'auto' to generate a random seed
+ @param env dictionary of environment variables for child process
@param kwargs
"""
+
+ if seed == 'auto':
+ seed = hash((os.getpid(), time.time())) % (2**32)
+
t = string.Template(exp)
e = t.substitute(**kwargs)
if write_command('r.mapcalc', file = '-', stdin = e,
+ env = env,
+ seed = seed,
quiet = quiet,
verbose = verbose,
overwrite = overwrite) != 0:
fatal(_("An error occurred while running r.mapcalc"))
-def mapcalc_start(exp, quiet = False, verbose = False, overwrite = False, **kwargs):
+def mapcalc_start(exp, quiet = False, verbose = False, overwrite = False,
+ seed = None, env = None, **kwargs):
"""!Interface to r.mapcalc, doesn't wait for it to finish, returns Popen object.
\code
@@ -124,14 +136,23 @@
@param quiet True to run quietly (<tt>--q</tt>)
@param verbose True to run verbosely (<tt>--v</tt>)
@param overwrite True to enable overwriting the output (<tt>--o</tt>)
+ @param seed an integer used to seed the random-number generator for the rand() function,
+ or 'auto' to generate a random seed
+ @param env dictionary of environment variables for child process
@param kwargs
@return Popen object
"""
+
+ if seed == 'auto':
+ seed = hash((os.getpid(), time.time())) % (2**32)
+
t = string.Template(exp)
e = t.substitute(**kwargs)
p = feed_command('r.mapcalc', file = '-',
+ env = env,
+ seed = seed,
quiet = quiet,
verbose = verbose,
overwrite = overwrite)
@@ -140,7 +161,7 @@
return p
# interface to r.what
-def raster_what(map, coord):
+def raster_what(map, coord, env = None):
"""!TODO"""
if type(map) in (types.StringType, types.UnicodeType):
map_list = [map]
@@ -158,14 +179,13 @@
# separator '|' not included in command
# because | is causing problems on Windows
# change separator?
- cmdParams = dict(quiet = True,
- flags = 'rf',
- map = ','.join(map_list),
- coordinates = ','.join(coord_list),
- null = _("No data"))
-
ret = read_command('r.what',
- **cmdParams)
+ flags = 'rf',
+ map = ','.join(map_list),
+ coordinates = ','.join(coord_list),
+ null = _("No data"),
+ quiet = True,
+ env = env)
data = list()
if not ret:
return data
Modified: grass/branches/releasebranch_7_0/raster/r.mapcalc/evaluate.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.mapcalc/evaluate.c 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/raster/r.mapcalc/evaluate.c 2014-07-31 12:08:48 UTC (rev 61475)
@@ -254,26 +254,6 @@
}
}
-static void setup_rand(void)
-{
- /* Read PRNG seed from environment variable if available */
- /* GRASS_RND_SEED */
- const char *random_seed = getenv("GRASS_RND_SEED");
- long seed_value;
-
- if (!random_seed)
- return;
-
- seed_value = atol(random_seed);
- G_debug(3, "Read random seed from environment: %ld", seed_value);
-
-#if defined(HAVE_DRAND48)
- srand48(seed_value);
-#else
- srand((unsigned int)seed_value);
-#endif
-}
-
void execute(expr_list * ee)
{
int verbose = isatty(2);
@@ -281,7 +261,6 @@
int count, n;
setup_region();
- setup_rand();
exprs = ee;
G_add_error_handler(error_handler, NULL);
Modified: grass/branches/releasebranch_7_0/raster/r.mapcalc/globals.h
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.mapcalc/globals.h 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/raster/r.mapcalc/globals.h 2014-07-31 12:08:48 UTC (rev 61475)
@@ -6,6 +6,8 @@
extern volatile int floating_point_exception_occurred;
extern int overflow_occurred;
extern int overwrite_flag;
+extern long seed_value;
+extern long seeded;
extern int current_depth, current_row;
extern int depths, rows, columns;
Modified: grass/branches/releasebranch_7_0/raster/r.mapcalc/main.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.mapcalc/main.c 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/raster/r.mapcalc/main.c 2014-07-31 12:08:48 UTC (rev 61475)
@@ -31,6 +31,9 @@
volatile int floating_point_exception;
volatile int floating_point_exception_occurred;
+long seed_value;
+long seeded;
+
/****************************************************************************/
static expr_list *result;
@@ -102,7 +105,8 @@
int main(int argc, char **argv)
{
struct GModule *module;
- struct Option *expr, *file;
+ struct Option *expr, *file, *seed;
+ struct Flag *random;
int all_ok;
G_gisinit(argv[0]);
@@ -126,6 +130,16 @@
file->description = _("File containing expression(s) to evaluate");
file->guisection = _("Expression");
+ seed = G_define_option();
+ seed->key = "seed";
+ seed->type = TYPE_INTEGER;
+ seed->required = NO;
+ seed->description = _("Seed for rand() function");
+
+ random = G_define_flag();
+ random->key = 's';
+ random->description = _("Generate random seed (result is non-deterministic)");
+
if (argc == 1)
{
char **p = G_malloc(3 * sizeof(char *));
@@ -144,6 +158,10 @@
if (expr->answer && file->answer)
G_fatal_error(_("file= and expression= are mutually exclusive"));
+ if (seed->answer && random->answer)
+ G_fatal_error(_("%s= and -%c are mutually exclusive"),
+ seed->key, random->key);
+
if (expr->answer)
result = parse_string(expr->answer);
else if (file->answer)
@@ -154,6 +172,19 @@
if (!result)
G_fatal_error(_("parse error"));
+ if (seed->answer) {
+ seed_value = atol(seed->answer);
+ G_srand48(seed_value);
+ seeded = 1;
+ G_debug(3, "Read random seed from seed=: %ld", seed_value);
+ }
+
+ if (random->answer) {
+ seed_value = G_srand48_auto();
+ seeded = 1;
+ G_debug(3, "Generated random seed (-s): %ld", seed_value);
+ }
+
pre_exec();
execute(result);
post_exec();
Modified: grass/branches/releasebranch_7_0/raster/r.mapcalc/map.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.mapcalc/map.c 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/raster/r.mapcalc/map.c 2014-07-31 12:08:48 UTC (rev 61475)
@@ -740,6 +740,12 @@
len -= n;
}
+ if (seeded) {
+ char buf[RECORD_LEN];
+ sprintf(buf, "random seed = %ld", seed_value);
+ Rast_append_history(&hist, buf);
+ }
+
Rast_write_history(dst, &hist);
G_free(expr);
Modified: grass/branches/releasebranch_7_0/raster/r.mapcalc/r.mapcalc.html
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.mapcalc/r.mapcalc.html 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/raster/r.mapcalc/r.mapcalc.html 2014-07-31 12:08:48 UTC (rev 61475)
@@ -609,8 +609,20 @@
(map) must be changed.
<h3>Random number generator initialization</h3>
-<p>The environment variable GRASS_RND_SEED is read to initialize the
-random number generator.
+<p>The pseudo-random number generator used by the rand() function can
+be initialised to a specific value using the <em>seed</em> option.
+This can be used to replicate a previous calculation.
+<p>Alternatively, it can be initialised from the system time and the
+PID using the <em>-r</em> flag. This should result in a different seed
+being used each time.
+<p>In either case, the seed will be written to the map's history, and
+can be seen using <em>r.info</em>.
+<p>If you want other people to be able to verify your results, it's
+preferable to use the <em>seed</em> option to supply a seed which is
+either specified in the script or generated from a determenistic process
+such as a pseudo-random number generator given an explicit seed.
+<p>Note that the rand() function will generate a fatal error if neither
+the <em>seed</em> option nor the <em>-s</em> flag are given.
<h2>EXAMPLES</h2>
To compute the average of two raster map layers
Modified: grass/branches/releasebranch_7_0/raster/r.mapcalc/r3.mapcalc.html
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.mapcalc/r3.mapcalc.html 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/raster/r.mapcalc/r3.mapcalc.html 2014-07-31 12:08:48 UTC (rev 61475)
@@ -470,8 +470,20 @@
See <em><a href="r.mask.html">r.mask</a></em> for details.
<h3>Random number generator initialization</h3>
-<p>The environment variable GRASS_RND_SEED is read to initialize the
-random number generator.
+<p>The pseudo-random number generator used by the rand() function can
+be initialised to a specific value using the <em>seed</em> option.
+This can be used to replicate a previous calculation.
+<p>Alternatively, it can be initialised from the system time and the
+PID using the <em>-r</em> flag. This should result in a different seed
+being used each time.
+<p>In either case, the seed will be written to the map's history, and
+can be seen using <em>r.info</em>.
+<p>If you want other people to be able to verify your results, it's
+preferable to use the <em>seed</em> option to supply a seed which is
+either specified in the script or generated from a determenistic process
+such as a pseudo-random number generator given an explicit seed.
+<p>Note that the rand() function will generate a fatal error if neither
+the <em>seed</em> option nor the <em>-s</em> flag are given.
<h2>EXAMPLES</h2>
To compute the average of two 3D grids
Modified: grass/branches/releasebranch_7_0/raster/r.mapcalc/xrand.c
===================================================================
--- grass/branches/releasebranch_7_0/raster/r.mapcalc/xrand.c 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/raster/r.mapcalc/xrand.c 2014-07-31 12:08:48 UTC (rev 61475)
@@ -12,11 +12,6 @@
rand(lo,hi) random values between a and b
****************************************************************/
-#if !defined(HAVE_DRAND48)
-#define drand48() ((double)rand()/((double)RAND_MAX + 1))
-#define mrand48() ((long)rand())
-#endif
-
int f_rand(int argc, const int *argt, void **args)
{
int i;
@@ -34,7 +29,7 @@
CELL *arg2 = args[2];
for (i = 0; i < columns; i++) {
- unsigned long x = (unsigned long)mrand48();
+ unsigned long x = (unsigned long)G_mrand48();
int lo = arg1[i];
int hi = arg2[i];
@@ -55,7 +50,7 @@
FCELL *arg2 = args[2];
for (i = 0; i < columns; i++) {
- double x = drand48();
+ double x = G_drand48();
FCELL lo = arg1[i];
FCELL hi = arg2[i];
@@ -76,7 +71,7 @@
DCELL *arg2 = args[2];
for (i = 0; i < columns; i++) {
- double x = drand48();
+ double x = G_drand48();
DCELL lo = arg1[i];
DCELL hi = arg2[i];
Modified: grass/branches/releasebranch_7_0/temporal/t.rast.neighbors/t.rast.neighbors.html
===================================================================
--- grass/branches/releasebranch_7_0/temporal/t.rast.neighbors/t.rast.neighbors.html 2014-07-31 11:48:14 UTC (rev 61474)
+++ grass/branches/releasebranch_7_0/temporal/t.rast.neighbors/t.rast.neighbors.html 2014-07-31 12:08:48 UTC (rev 61475)
@@ -34,8 +34,7 @@
count=1
for map in ${MAPS} ; do
- export GRASS_RND_SEED=${count}
- r.mapcalc --o expr="${map} = rand(0, 550)"
+ r.mapcalc --o expr="${map} = rand(0, 550)" seed=${count}
echo ${map} >> map_list.txt
count=$((count+1))
done
More information about the grass-commit
mailing list