[GRASS-SVN] r70370 - grass-addons/grass7/vector/v.krige

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Jan 14 06:56:59 PST 2017


Author: marisn
Date: 2017-01-14 06:56:59 -0800 (Sat, 14 Jan 2017)
New Revision: 70370

Modified:
   grass-addons/grass7/vector/v.krige/Makefile
   grass-addons/grass7/vector/v.krige/v.krige.html
   grass-addons/grass7/vector/v.krige/v.krige.py
   grass-addons/grass7/vector/v.krige/vkrige.py
Log:
Rename Sill to Psill as R code operates with partial sill not sill
Move Psill, Range and Nugget to float to match real life use cases
Fix Makefile to work with g.extension
Fix imports to finish transition to addons (fixes #3256)
+ cosmetics


Modified: grass-addons/grass7/vector/v.krige/Makefile
===================================================================
--- grass-addons/grass7/vector/v.krige/Makefile	2017-01-14 11:27:30 UTC (rev 70369)
+++ grass-addons/grass7/vector/v.krige/Makefile	2017-01-14 14:56:59 UTC (rev 70370)
@@ -2,6 +2,9 @@
 
 PGM = v.krige
 
+ETCFILES = vkrige
+
 include $(MODULE_TOPDIR)/include/Make/Script.make
+include $(MODULE_TOPDIR)/include/Make/Python.make
 
 default: script

Modified: grass-addons/grass7/vector/v.krige/v.krige.html
===================================================================
--- grass-addons/grass7/vector/v.krige/v.krige.html	2017-01-14 11:27:30 UTC (rev 70369)
+++ grass-addons/grass7/vector/v.krige/v.krige.html	2017-01-14 14:56:59 UTC (rev 70370)
@@ -17,9 +17,10 @@
 of parameters or powerful hardware. See Isaaks and Srivastava's book,
 exhaustive and clear even if a bit outdated.
 
-<p>Auto-fit variogram option will update sill, nugget, range and kappa values
+<p>Auto-fit variogram option will update partial sill, nugget, range and kappa values
 with fitted ones. Enabling the values will pass them to auto-fit and thus
 preserve from modification and thus they might differ from fitted ones.
+Sill value can be tetermined by summing partial sill with nugget.
 
 <h3>Dependencies</h3>
 
@@ -37,6 +38,7 @@
 Install the packages via R command line (or your preferred GUI):
 <div class="code"><pre>
   install.packages("rgeos", dep=T)
+  install.packages("rgdal", dep=T)
   install.packages("gstat", dep=T)
   install.packages("rgrass7", dep=T)
   install.packages("automap", dep=T)
@@ -127,7 +129,7 @@
 functions are: exponential, spherical, Gaussian, Matern, M.Stein's
 parametrisation. A wider range of models is available from gstat
 package and can be tested on the GUI via the variogram plotting. If a
-model is specified in the CLI, also sill, nugget and range values are
+model is specified in the CLI, also partial sill, nugget and range values are
 to be provided, otherwise an error is raised (see second example of
 <em>v.krige</em> command).
 
@@ -139,7 +141,7 @@
 # define variogram model, create variance map as well
 v.krige input=rand2k_elev_filt column=elevation \
         output=rand2k_elev_filt_kriging output_var=rand2k_elev_filt_kriging_var \
-        model=Mat sill=2500 nugget=0 range=1000 
+        model=Mat psill=2500 nugget=0 range=1000 
 </pre></div>
 
 Or run wxGUI, to interactively fit the variogram and explore options:

Modified: grass-addons/grass7/vector/v.krige/v.krige.py
===================================================================
--- grass-addons/grass7/vector/v.krige/v.krige.py	2017-01-14 11:27:30 UTC (rev 70369)
+++ grass-addons/grass7/vector/v.krige/v.krige.py	2017-01-14 14:56:59 UTC (rev 70370)
@@ -77,9 +77,9 @@
 #% required : no
 #%end
 #%option
-#% key: sill
+#% key: psill
 #% type: integer
-#% label: Sill value
+#% label: Partial sill value
 #% description: Automatically fixed if not set
 #% required : no
 #%end
@@ -109,6 +109,16 @@
 
 gettext.install('grasswxpy', os.path.join(os.getenv("GISBASE"), 'locale'))
 
+sys.path.append(os.path.join(os.getenv('GISBASE'), 'gui', 'wxpython'))
+
+from grass.pygrass.utils import get_lib_path
+
+path = get_lib_path("v.krige", "")
+if path is None:
+    raise ImportError(_("Not able to find the path %s directory.") % path)
+
+sys.path.append(path)
+
 # dependencies to be checked once, as they are quite time-consuming. cfr. grass.parser.
 # GRASS binding
 try:
@@ -197,11 +207,11 @@
             predictor = 'x+y'
         else:
             predictor = '1'
-        print(column + "~" + predictor)
+
         Formula = robjects.Formula(column + "~" + predictor)
         return Formula
 
-    def FitVariogram(self, formula, inputdata, sill, nugget, range, kappa, model=''):
+    def FitVariogram(self, formula, inputdata, psill, nugget, range, kappa, model=''):
         """ Fits variogram either automagically either specifying all parameters.
         Returns a list containing data and model variograms. """
 
@@ -210,8 +220,7 @@
         if model is '':
             robjects.r.require('automap')
             DottedParams = {}
-            #print (nugget.r_repr(), sill, range)
-            DottedParams['fix.values'] = robjects.r.c(nugget, range, sill)
+            DottedParams['fix.values'] = robjects.r.c(nugget, range, psill)
 
             if not isinstance(kappa, float):
                 # autofit gives strange results if kappa is NA
@@ -219,7 +228,6 @@
             else:
                 VariogramModel = robjects.r.autofitVariogram(
                     formula, inputdata, kappa=kappa, **DottedParams)
-            # print robjects.r.warnings()
             Variograms['datavariogram'] = VariogramModel.rx('exp_var')[0]
             Variograms['variogrammodel'] = VariogramModel.rx('var_model')[0]
             # obtain the model name. *Too* complicated to get the string instead of
@@ -231,7 +239,7 @@
         else:
             DataVariogram = robjects.r['variogram'](formula, inputdata)
             VariogramModel = robjects.r['fit.variogram'](DataVariogram,
-                                                         model=robjects.r.vgm(psill=sill,
+                                                         model=robjects.r.vgm(psill=psill,
                                                                               model=model,
                                                                               nugget=nugget,
                                                                               range=range,
@@ -245,7 +253,6 @@
         DottedParams = {'debug.level': -1}  # let krige() print percentage status
         if block is not '':  # @FIXME(anne): but it's a string!! and krige accepts it!!
             DottedParams['block'] = block
-        # print DottedParams
         KrigingResult = robjects.r.krige(formula, inputdata, grid, model, **DottedParams)
         return KrigingResult
 
@@ -262,7 +269,7 @@
                               map=name,
                               history='Model chosen by automatic fitting: ' + variograms['model'])
 
-    def Run(self, input, column, output, package, sill, nugget, range, kappa, logger,
+    def Run(self, input, column, output, package, psill, nugget, range, kappa, logger,
             overwrite, model, block, output_var, command, **kwargs):
         """ Wrapper for all functions above. """
 
@@ -273,7 +280,6 @@
         if self.InputData is None:
             self.InputData = self.ImportMap(input, column)
         # and from here over, InputData refers to the global variable
-        #print(robjects.r.slot(InputData, 'data').names)
         logger.message(_("Data successfully imported."))
 
         GridPredicted = self.CreateGrid(self.InputData)
@@ -288,7 +294,7 @@
             self.Variogram = self.FitVariogram(robjects.Formula(column + "~" + self.predictor),
                                                self.InputData,
                                                model=model,
-                                               sill=sill,
+                                               psill=psill,
                                                nugget=nugget,
                                                range=range,
                                                kappa=kappa)
@@ -332,7 +338,7 @@
         if not os.getenv("GRASS_WXBUNDLED"):
             from core import globalvar
             globalvar.CheckForWx()
-        from modules import vkrige as GUI
+        import vkrige as GUI
 
         import wx
 
@@ -379,12 +385,11 @@
             except ImportError as e:
                 grass.fatal(_("R package automap is missing, no variogram autofit available."))
         else:
-            if options['sill'] is '' or options['nugget'] is '' or options['range'] is '':
+            if options['psill'] is '' or options['nugget'] is '' or options['range'] is '':
                 grass.fatal(
-                    _("You have specified model, but forgot at least one of sill, nugget and range."))
+                    _("You have specified model, but forgot at least one of psill, nugget and range."))
 
         #@TODO: let GRASS remount its commandstring. Until then, keep that 4 lines below.
-        # print grass.write_command(argv)
         command = ""
         notnulloptions = {}
         for k, v in options.items():
@@ -393,12 +398,9 @@
         command = command.join("%s=%s " % (k, v) for k, v in notnulloptions.items())
 
         # re-cast integers from strings, as parser() cast everything to string.
-        for each in ("sill", "nugget", "range", "kappa"):
+        for each in ("psill", "nugget", "range", "kappa"):
             if options[each] is not '':
-                if each == "kappa":
-                    options[each] = float(options[each])
-                else:
-                    options[each] = int(options[each])
+                options[each] = float(options[each])
             else:
                 options[each] = robjects.r('''NA''')
 
@@ -410,7 +412,7 @@
                        package=options['package'],
                        model=options['model'],
                        block=options['block'],
-                       sill=options['sill'],
+                       psill=options['psill'],
                        nugget=options['nugget'],
                        range=options['range'],
                        kappa=options['kappa'],
@@ -439,15 +441,16 @@
         # ok for other OSes?
         grass.fatal(_("Python module 'Rpy2' not found. Please install it and re-run v.krige."))
 
+    if not robjects.r.require("automap", quietly=True)[0]:
+        grass.warning(_("R package \"automap\" is missing. It provides variogram autofitting functionality and thus is recomended."))
+    
     # R packages check. Will create one error message after check of all packages.
     missingPackagesList = []
-    for each in ["rgeos", "gstat", "rgrass7", "maptools"]:
+    for each in ["rgeos", "gstat", "rgrass7", "maptools", "rgdal"]:
         if not robjects.r.require(each, quietly=True)[0]:
             missingPackagesList.append(each)
     if missingPackagesList:
-        errorString = _("R package(s) ") + \
-            ", ".join(map(str, missingPackagesList)) + \
-            _(" missing. Install it/them and re-run v.krige.")
+        errorString = _("R package(s) %s missing. Install it/them and re-run v.krige.") % ", ".join(map(str, missingPackagesList))
         grass.fatal(errorString)
 
 if __name__ == '__main__':

Modified: grass-addons/grass7/vector/v.krige/vkrige.py
===================================================================
--- grass-addons/grass7/vector/v.krige/vkrige.py	2017-01-14 11:27:30 UTC (rev 70369)
+++ grass-addons/grass7/vector/v.krige/vkrige.py	2017-01-14 14:56:59 UTC (rev 70370)
@@ -14,12 +14,12 @@
 for details.
 """
 
-#@TODO move here imports related to wxGUI
+# @TODO move here imports related to wxGUI
 
 # generic imports
 import os
 import sys
-from tempfile import gettempdir
+# from tempfile import gettempdir
 import time
 import thread
 from core.utils import _
@@ -32,6 +32,7 @@
 except ImportError:
     sys.exit(_("No GRASS-python library found."))
 
+sys.path.append(os.path.join(os.getenv('GISBASE'), 'gui', 'wxpython'))
 from core import globalvar
 from gui_core import gselect
 from core import gconsole
@@ -40,7 +41,7 @@
 from gui_core.widgets import GNotebook
 from core.giface import Notification
 from gui_core.wrap import SpinCtrl
-#import help
+from core.gcmd import GError
 
 import wx
 # import wx.lib.plot as plot # for plotting the variogram.
@@ -52,7 +53,7 @@
 # Bob Moskovitz]
 maxint = 1e6
 
-#@TODO move away functions not regarding the GUI
+# @TODO move away functions not regarding the GUI
 
 
 class KrigingPanel(wx.Panel):
@@ -253,7 +254,7 @@
 
         # last action of __init__: update imput data list.
         # it's performed in the few seconds gap while user examines interface before clicking anything.
-        #@TODO: implement a splashcreen IF the maps cause a noticeable lag [markus' suggestion]
+        # @TODO: implement a splashcreen IF the maps cause a noticeable lag [markus' suggestion]
         self.InputDataMap.GetElementList()
 
     def CreatePage(self, package, Rinstance, controller):
@@ -316,9 +317,9 @@
 
     def OnRunButton(self, event):
         """Execute R analysis. """
-        #@FIXME: send data to main method instead of running it here.
+        # @FIXME: send data to main method instead of running it here.
 
-        #-1: get the selected notebook page. The user shall know that [s]he can modify settings in all
+        # -1: get the selected notebook page. The user shall know that [s]he can modify settings in all
         # pages, but only the selected one will be executed when Run is
         # pressed.
         SelectedPanel = self.RPackagesBook.GetCurrentPage()
@@ -349,7 +350,7 @@
                 "model=" + '%s' %
                 SelectedPanel.ModelChoicebox.GetStringSelection().split(" ")[0])
 
-        for i in ['Sill', 'Nugget', 'Range', 'Kappa']:
+        for i in ['Psill', 'Nugget', 'Range', 'Kappa']:
             if getattr(SelectedPanel, i + "ChextBox").IsChecked():
                 command.append(
                     i.lower() +
@@ -372,7 +373,7 @@
                 self.OutputVarianceMapName.GetValue())
 
         # give it to the output console
-        #@FIXME: it runs the command as a NEW instance. Reimports data, recalculates variogram fit..
+        # @FIXME: it runs the command as a NEW instance. Reimports data, recalculates variogram fit..
         # otherwise I can use Controller() and mimic RunCmd behaviour.
         self._gconsole.RunCmd(command)
 
@@ -475,8 +476,9 @@
             flag=wx.EXPAND | wx.ALL,
             border=parent.border)
 
-        self.ParametersList = ["Sill", "Nugget", "Range", "Kappa"]
-        MinValues = [0, 0, 1, 0.1]
+        self.ParametersList = ["Psill", "Nugget", "Range", "Kappa"]
+        MinValues = [0, 0, 0.01, 0.01]
+        InitialValues = [1, 0, 1, 0.5]
         for n in self.ParametersList:
             setattr(
                 self,
@@ -486,29 +488,18 @@
                     id=self.ParametersList.index(n),
                     label=_(
                         n + ":")))
-            # Kappa must be float
-            if n == "Kappa":
-                setattr(
+            setattr(
+                self,
+                n + "Ctrl",
+                (wx.SpinCtrlDouble(
                     self,
-                    n + "Ctrl",
-                    (wx.SpinCtrlDouble(
-                        self,
-                        id=wx.ID_ANY,
-                        min=MinValues[
-                            self.ParametersList.index(n)],
-                        max=maxint,
-                        inc=0.1,
-                        initial=0.5)))
-            else:
-                setattr(
-                    self,
-                    n + "Ctrl",
-                    (SpinCtrl(
-                        self,
-                        id=wx.ID_ANY,
-                        min=MinValues[
-                            self.ParametersList.index(n)],
-                        max=maxint)))
+                    id=wx.ID_ANY,
+                    min=MinValues[
+                        self.ParametersList.index(n)],
+                    max=maxint,
+                    inc=0.1,
+                    initial=InitialValues[
+                        self.ParametersList.index(n)])))
             getattr(self, n + "ChextBox").Bind(wx.EVT_CHECKBOX,
                                                self.UseValue,
                                                id=self.ParametersList.index(n))
@@ -521,11 +512,11 @@
                                      pos=(self.ParametersList.index(n), 1))
 
         # right side of the Variogram fitting. The plot area.
-        #Plot = wx.StaticText(self, id= wx.ID_ANY, label = "Check Plot Variogram to interactively fit model.")
-        #PlotPanel = wx.Panel(self)
-        #self.PlotArea = plot.PlotCanvas(PlotPanel)
-        #self.PlotArea.SetInitialSize(size = (250,250))
-        #self.RightSizer.Add(PlotPanel, proportion=0, flag= wx.EXPAND|wx.ALL, border=parent.border)
+        # Plot = wx.StaticText(self, id= wx.ID_ANY, label = "Check Plot Variogram to interactively fit model.")
+        # PlotPanel = wx.Panel(self)
+        # self.PlotArea = plot.PlotCanvas(PlotPanel)
+        # self.PlotArea.SetInitialSize(size = (250,250))
+        # self.RightSizer.Add(PlotPanel, proportion=0, flag= wx.EXPAND|wx.ALL, border=parent.border)
 
         self.KrigingSizer = wx.StaticBoxSizer(
             wx.StaticBox(
@@ -619,13 +610,13 @@
         ModelFactor = robjects.r.vgm()
         ModelList = robjects.r.levels(ModelFactor[1])
         self.ModelListShort = robjects.r.levels(ModelFactor[0])
-        #@FIXME: no other way to let the Python pick it up..
+        # @FIXME: no other way to let the Python pick it up..
         # and this is te wrong place where to load this list. should be at the
         # very beginning.
         self.ModelChoicebox = wx.Choice(self, id=wx.ID_ANY, choices=ModelList)
 
         # disable model parameters' widgets by default
-        for n in ["Sill", "Nugget", "Range", "Kappa"]:
+        for n in ["Psill", "Nugget", "Range", "Kappa"]:
             getattr(self, n + "Ctrl").Enable(False)
         self.ModelChoicebox.Enable(False)
 
@@ -645,7 +636,7 @@
 
     def HideOptions(self, event):
         self.ModelChoicebox.Enable(not event.IsChecked())
-        for n in ["Sill", "Nugget", "Range", "Kappa"]:
+        for n in ["Psill", "Nugget", "Range", "Kappa"]:
             if not event.IsChecked():
                 getattr(self, n + "Ctrl").Enable(True)
                 getattr(self, n + "ChextBox").SetValue(True)
@@ -655,13 +646,13 @@
                 getattr(self, n + "Ctrl").Enable(False)
                 getattr(self, n + "ChextBox").SetValue(False)
                 getattr(self, n + "ChextBox").Enable(True)
-        #@FIXME: was for n in self.ParametersSizer.GetChildren(): n.Enable(False) but doesn't work
+        # @FIXME: was for n in self.ParametersSizer.GetChildren(): n.Enable(False) but doesn't work
 
     def OnPlotButton(self, event):
         """Plots variogram with current options. """
         # BIG WARNING: smell of code duplication. Fix this asap. emminchia!
         # controller = Controller() # sed, if needed,
-        #controller = self.controller
+        # controller = self.controller
         map = self.parent.InputDataMap.GetValue()
         column = self.parent.InputDataColumn.GetValue()
 
@@ -670,12 +661,12 @@
             self.controller.InputData = self.controller.ImportMap(
                 map=map, column=column)
         # fit the variogram or pick it up
-        #~ Formula = self.controller.ComposeFormula(column = column,
-            #~ isblock = self.KrigingRadioBox.GetStringSelection() == "Block kriging")
+        # ~ Formula = self.controller.ComposeFormula(column = column,
+            # ~ isblock = self.KrigingRadioBox.GetStringSelection() == "Block kriging")
         if hasattr(
                 self, 'VariogramCheckBox') and self.VariogramCheckBox.IsChecked():
             self.model = ''
-            for each in ("Sill", "Nugget", "Range", "Kappa"):
+            for each in ("Psill", "Nugget", "Range", "Kappa"):
                 if getattr(self, each + 'ChextBox').IsChecked():
                     setattr(
                         self, each.lower(), getattr(
@@ -686,12 +677,16 @@
         else:
             self.model = self.ModelListShort[
                 self.ModelChoicebox.GetSelection()]
-            for each in ("Sill", "Nugget", "Range", "Kappa"):
+            for each in ("Psill", "Nugget", "Range", "Kappa"):
                 # @FIXME will be removed when chextboxes will be frozen
                 if getattr(self, each + 'ChextBox').IsChecked():
                     setattr(
                         self, each.lower(), getattr(
                             self, each + "Ctrl").GetValue())
+                else:
+                    GError(message=_("Variogram autofitting not enabled or R module \"automap\" is missing.\n\n" +
+                        "Parameter \"%s\" must be provided") % each, showTraceback=False)
+                    return False
 
         isblock = self.KrigingRadioBox.GetStringSelection() == "Block kriging"
         if isblock is not '':
@@ -701,7 +696,7 @@
 
         self.controller.Variogram = self.controller.FitVariogram(
             robjects.Formula(str(column) + "~" + self.predictor),
-            self.controller.InputData, model=self.model, sill=self.sill,
+            self.controller.InputData, model=self.model, psill=self.psill,
             nugget=self.nugget, range=self.range, kappa=self.kappa)
 
         ''' Fill parameters with autofitted values '''
@@ -712,9 +707,9 @@
                         i] == self.controller.Variogram['model']:
                     self.ModelChoicebox.SetSelection(i)
                     break
-            if not getattr(self, 'SillChextBox').IsChecked():
-                self.sill = self.controller.Variogram['variogrammodel'][1][1]
-                self.SillCtrl.SetValue(self.sill)
+            if not getattr(self, 'PsillChextBox').IsChecked():
+                self.psill = self.controller.Variogram['variogrammodel'][1][1]
+                self.PsillCtrl.SetValue(self.psill)
             if not getattr(self, 'NuggetChextBox').IsChecked():
                 self.nugget = self.controller.Variogram['variogrammodel'][1][0]
                 self.NuggetCtrl.SetValue(self.nugget)
@@ -748,7 +743,7 @@
 
     def __init__(self, parent, *args, **kwargs):
         RBookPanel.__init__(self, parent, *args, **kwargs)
-        #@TODO: change these two lines as soon as geoR f(x)s are integrated.
+        # @TODO: change these two lines as soon as geoR f(x)s are integrated.
         for n in self.GetChildren():
             n.Hide()
         self.Sizer.Add(



More information about the grass-commit mailing list