vkrige.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. """
  2. MODULE: vkrige
  3. AUTHOR(S): Anne Ghisla <a.ghisla AT gmail.com>
  4. PURPOSE: Dedicated GUI for v.krige script.
  5. DEPENDS: R 2.x, packages gstat, maptools and spgrass6, optional: automap
  6. COPYRIGHT: (C) 2009 by the GRASS Development Team
  7. This program is free software under the GNU General Public
  8. License (>=v2). Read the file COPYING that comes with GRASS
  9. for details.
  10. """
  11. #@TODO move here imports related to wxGUI
  12. ### generic imports
  13. import os, sys
  14. from tempfile import gettempdir
  15. import time
  16. import thread
  17. from core.utils import _
  18. ### dependencies to be checked once, as they are quite
  19. ### time-consuming. cfr. grass.parser.
  20. try:
  21. import grass.script as grass
  22. except ImportError:
  23. sys.exit(_("No GRASS-python library found."))
  24. from core import globalvar
  25. from gui_core import gselect
  26. from core import gconsole
  27. from gui_core import goutput
  28. from core.settings import UserSettings
  29. from gui_core.widgets import GNotebook
  30. from core.giface import Notification
  31. #import help
  32. import wx
  33. #import wx.lib.plot as plot # for plotting the variogram.
  34. import rpy2.robjects as robjects
  35. import rpy2.rinterface as rinterface
  36. # global variables
  37. maxint = 1e6 # instead of sys.maxint, not working with SpinCtrl on 64bit [reported by Bob Moskovitz]
  38. #@TODO move away functions not regarding the GUI
  39. class KrigingPanel(wx.Panel):
  40. """Main panel. Contains all widgets except Menus and Statusbar. """
  41. def __init__(self, parent, Rinstance, controller, *args, **kwargs):
  42. wx.Panel.__init__(self, parent, *args, **kwargs)
  43. self.parent = parent
  44. self.border = 4
  45. # 1. Input data
  46. InputBoxSizer = wx.StaticBoxSizer(wx.StaticBox(self, id = wx.ID_ANY, label = _("Input Data")),
  47. orient = wx.HORIZONTAL)
  48. flexSizer = wx.FlexGridSizer(cols = 3, hgap = 5, vgap = 5)
  49. flexSizer.AddGrowableCol(1)
  50. flexSizer.Add(item = wx.StaticText(self, id = wx.ID_ANY, label = _("Point dataset:")),
  51. flag = wx.ALIGN_CENTER_VERTICAL)
  52. self.InputDataMap = gselect.VectorSelect(parent = self,
  53. ftype = 'points',
  54. updateOnPopup = False)
  55. self.InputDataMap.SetFocus()
  56. flexSizer.Add(item = self.InputDataMap, flag = wx.ALIGN_CENTER_VERTICAL)
  57. RefreshButton = wx.Button(self, id = wx.ID_REFRESH)
  58. RefreshButton.Bind(wx.EVT_BUTTON, self.OnButtonRefresh)
  59. flexSizer.Add(item = RefreshButton, flag = wx.ALIGN_CENTER_VERTICAL)
  60. flexSizer.Add(item = wx.StaticText(self, id = wx.ID_ANY, label = _("Numeric column:")),
  61. flag = wx.ALIGN_CENTER_VERTICAL)
  62. self.InputDataColumn = gselect.ColumnSelect(self, id = wx.ID_ANY)
  63. flexSizer.Add(item = self.InputDataColumn)
  64. self.InputDataMap.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnInputMapChanged)
  65. self.InputDataColumn.GetChildren()[0].Bind(wx.EVT_TEXT, self.OnInputColumnChanged)
  66. InputBoxSizer.Add(item = flexSizer)
  67. # 2. Kriging. In book pages one for each R package. Includes variogram fit.
  68. KrigingSizer = wx.StaticBoxSizer(wx.StaticBox(self, id = wx.ID_ANY, label = _("Kriging")), wx.HORIZONTAL)
  69. self.RPackagesBook = GNotebook(parent = self, style = globalvar.FNPageDStyle)
  70. for Rpackage in ["gstat"]: # , "geoR"]: #@TODO: enable it if/when it'll be implemented.
  71. self.CreatePage(package = Rpackage, Rinstance = Rinstance, controller = controller)
  72. ## Command output. From menuform module, cmdPanel class
  73. self._gconsole = gconsole.GConsole(guiparent = self)
  74. self.goutput = goutput.GConsoleWindow(parent = self, gconsole = self._gconsole, margin = False)
  75. self.goutputId = self.RPackagesBook.GetPageCount()
  76. self.outpage = self.RPackagesBook.AddPage(page = self.goutput, text = _("Command output"), name = 'output')
  77. self._gconsole.Bind(gconsole.EVT_CMD_RUN,
  78. lambda event:
  79. self._switchPageHandler(event=event, notification=Notification.MAKE_VISIBLE))
  80. self._gconsole.Bind(gconsole.EVT_CMD_DONE,
  81. lambda event:
  82. self._switchPageHandler(event=event, notification=Notification.RAISE_WINDOW))
  83. self.RPackagesBook.SetSelection(0)
  84. KrigingSizer.Add(self.RPackagesBook, proportion = 1, flag = wx.EXPAND)
  85. # 3. Output Parameters.
  86. OutputSizer = wx.StaticBoxSizer(wx.StaticBox(self, id = wx.ID_ANY, label = _("Output")), wx.HORIZONTAL)
  87. OutputParameters = wx.GridBagSizer(hgap = 5, vgap = 5)
  88. OutputParameters.Add(item = wx.StaticText(self, id = wx.ID_ANY, label = _("Name for the output raster map:")),
  89. flag = wx.ALIGN_CENTER_VERTICAL,
  90. pos = (0, 0))
  91. self.OutputMapName = gselect.Select(parent = self, id = wx.ID_ANY,
  92. type = 'raster',
  93. mapsets = [grass.gisenv()['MAPSET']])
  94. OutputParameters.Add(item = self.OutputMapName, flag = wx.EXPAND | wx.ALL,
  95. pos = (0, 1))
  96. self.VarianceRasterCheckbox = wx.CheckBox(self, id = wx.ID_ANY, label = _("Export variance map as well: "))
  97. self.VarianceRasterCheckbox.SetValue(state = True)
  98. OutputParameters.Add(item = self.VarianceRasterCheckbox,
  99. flag = wx.ALIGN_CENTER_VERTICAL,
  100. pos = (1, 0))
  101. self.OutputVarianceMapName = gselect.Select(parent = self, id = wx.ID_ANY,
  102. type = 'raster',
  103. mapsets = [grass.gisenv()['MAPSET']])
  104. self.VarianceRasterCheckbox.Bind(wx.EVT_CHECKBOX, self.OnVarianceCBChecked)
  105. OutputParameters.Add(item = self.OutputVarianceMapName, flag = wx.EXPAND | wx.ALL,
  106. pos = (1, 1))
  107. self.OverwriteCheckBox = wx.CheckBox(self, id = wx.ID_ANY,
  108. label = _("Allow output files to overwrite existing files"))
  109. self.OverwriteCheckBox.SetValue(UserSettings.Get(group='cmd', key='overwrite', subkey='enabled'))
  110. OutputParameters.Add(item = self.OverwriteCheckBox,
  111. pos = (2, 0), span = (1, 2))
  112. OutputParameters.AddGrowableCol(1)
  113. OutputSizer.Add(OutputParameters, proportion = 0, flag = wx.EXPAND | wx.ALL, border = self.border)
  114. # 4. Run Button and Quit Button
  115. ButtonSizer = wx.BoxSizer(wx.HORIZONTAL)
  116. HelpButton = wx.Button(self, id = wx.ID_HELP)
  117. HelpButton.Bind(wx.EVT_BUTTON, self.OnHelpButton)
  118. QuitButton = wx.Button(self, id = wx.ID_EXIT)
  119. QuitButton.Bind(wx.EVT_BUTTON, self.OnCloseWindow)
  120. self.RunButton = wx.Button(self, id = wx.ID_ANY, label = _("&Run")) # no stock ID for Run button..
  121. self.RunButton.Bind(wx.EVT_BUTTON, self.OnRunButton)
  122. self.RunButton.Enable(False) # disable it on loading the interface, as input map is not set
  123. ButtonSizer.Add(HelpButton, proportion = 0, flag = wx.ALIGN_LEFT | wx.ALL, border = self.border)
  124. ButtonSizer.Add(QuitButton, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = self.border)
  125. ButtonSizer.Add(self.RunButton, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = self.border)
  126. # Main Sizer. Add each child sizer as soon as it is ready.
  127. Sizer = wx.BoxSizer(wx.VERTICAL)
  128. Sizer.Add(InputBoxSizer, proportion = 0, flag = wx.EXPAND | wx.ALL, border = self.border)
  129. Sizer.Add(KrigingSizer, proportion = 1, flag = wx.EXPAND | wx.ALL, border = self.border)
  130. Sizer.Add(OutputSizer, proportion = 0, flag = wx.EXPAND | wx.ALL, border = self.border)
  131. Sizer.Add(ButtonSizer, proportion = 0, flag = wx.ALIGN_RIGHT | wx.ALL, border = self.border)
  132. self.SetSizerAndFit(Sizer)
  133. # last action of __init__: update imput data list.
  134. # it's performed in the few seconds gap while user examines interface before clicking anything.
  135. #@TODO: implement a splashcreen IF the maps cause a noticeable lag [markus' suggestion]
  136. self.InputDataMap.GetElementList()
  137. def CreatePage(self, package, Rinstance, controller):
  138. """Creates the three notebook pages, one for each R package """
  139. for package in ["gstat"]: #@TODO add here other packages when they will be implemented
  140. classobj = eval("RBook"+package+"Panel")
  141. setattr(self, "RBook"+package+"Panel", (classobj(self,
  142. id = wx.ID_ANY,
  143. Rinstance = Rinstance,
  144. controller = controller)))
  145. self.RPackagesBook.AddPage(page = getattr(self, "RBook"+package+"Panel"), text = package)
  146. def OnButtonRefresh(self, event):
  147. """Forces refresh of list of available layers. """
  148. self.InputDataMap.GetElementList()
  149. def OnCloseWindow(self, event):
  150. """Cancel button pressed"""
  151. self.parent.Close()
  152. event.Skip()
  153. def OnHelpButton(self, event):
  154. grass.run_command('g.manual', entry = 'v.krige')
  155. event.Skip()
  156. def OnInputMapChanged(self, event):
  157. """Refreshes list of columns."""
  158. MapName = event.GetString()
  159. self.InputDataColumn.InsertColumns(vector = MapName,
  160. layer = 1, excludeKey = False,
  161. type = ['integer', 'double precision'])
  162. def OnInputColumnChanged(self, event):
  163. """Fills output map name TextCtrl """
  164. MapName = self.InputDataMap.GetValue()
  165. enable = bool(self.InputDataColumn.GetValue())
  166. self.RunButton.Enable(enable)
  167. self.RBookgstatPanel.PlotButton.Enable(enable)
  168. if enable:
  169. self.OutputMapName.SetValue(MapName.split("@")[0]+"_kriging")
  170. self.OutputVarianceMapName.SetValue(MapName.split("@")[0]+"_kriging.var")
  171. else:
  172. self.OutputMapName.SetValue('')
  173. self.OutputVarianceMapName.SetValue('')
  174. def OnRunButton(self,event):
  175. """Execute R analysis. """
  176. #@FIXME: send data to main method instead of running it here.
  177. #-1: get the selected notebook page. The user shall know that [s]he can modify settings in all
  178. # pages, but only the selected one will be executed when Run is pressed.
  179. SelectedPanel = self.RPackagesBook.GetCurrentPage()
  180. if self.RPackagesBook.GetPageText(self.RPackagesBook.GetSelection()) == 'Command output':
  181. self._gconsole.WriteError("No parameters for running. Please select \"gstat\" tab, check parameters and re-run.")
  182. return False # no break invoked by above function
  183. # mount command string as it would have been written on CLI
  184. command = ["v.krige", "input=" + self.InputDataMap.GetValue(),
  185. "column=" + self.InputDataColumn.GetValue(),
  186. "output=" + self.OutputMapName.GetValue(),
  187. "package=" + '%s' % self.RPackagesBook.GetPageText(self.RPackagesBook.GetSelection())]
  188. if not hasattr(SelectedPanel, 'VariogramCheckBox') or not SelectedPanel.VariogramCheckBox.IsChecked():
  189. command.append("model=" + '%s' % SelectedPanel.ModelChoicebox.GetStringSelection().split(" ")[0])
  190. for i in ['Sill', 'Nugget', 'Range', 'Kappa']:
  191. if getattr(SelectedPanel, i+"ChextBox").IsChecked():
  192. command.append(i.lower() + "=" + '%s' % getattr(SelectedPanel, i+'Ctrl').GetValue())
  193. if SelectedPanel.KrigingRadioBox.GetStringSelection() == "Block kriging":
  194. command.append("block=" + '%s' % SelectedPanel.BlockSpinBox.GetValue())
  195. if self.OverwriteCheckBox.IsChecked():
  196. command.append("--overwrite")
  197. if self.VarianceRasterCheckbox.IsChecked():
  198. command.append("output_var=" + self.OutputVarianceMapName.GetValue())
  199. # give it to the output console
  200. #@FIXME: it runs the command as a NEW instance. Reimports data, recalculates variogram fit..
  201. #otherwise I can use Controller() and mimic RunCmd behaviour.
  202. self._gconsole.RunCmd(command)
  203. def OnVarianceCBChecked(self, event):
  204. self.OutputVarianceMapName.Enable(event.IsChecked())
  205. def _switchPageHandler(self, event, notification):
  206. self._switchPage(notification=notification)
  207. event.Skip()
  208. def _switchPage(self, notification):
  209. """Manages @c 'output' notebook page according to event notification."""
  210. if notification == Notification.HIGHLIGHT:
  211. self.RPackagesBook.HighlightPageByName('output')
  212. if notification == Notification.MAKE_VISIBLE:
  213. self.RPackagesBook.SetSelectionByName('output')
  214. if notification == Notification.RAISE_WINDOW:
  215. self.RPackagesBook.SetSelectionByName('output')
  216. self.SetFocus()
  217. self.Raise()
  218. class KrigingModule(wx.Frame):
  219. """Kriging module for GRASS GIS. Depends on R and its packages gstat and geoR. """
  220. def __init__(self, parent, Rinstance, controller, *args, **kwargs):
  221. wx.Frame.__init__(self, parent, *args, **kwargs)
  222. # setting properties and all widgettery
  223. self.SetTitle(_("Kriging Module"))
  224. self.SetIcon(wx.Icon(os.path.join(globalvar.ICONDIR, 'grass_dialog.ico'), wx.BITMAP_TYPE_ICO))
  225. self.log = Log(self)
  226. self.CreateStatusBar()
  227. self.log.message(_("Ready."))
  228. self.Panel = KrigingPanel(self, Rinstance, controller)
  229. self.SetMinSize(self.GetBestSize())
  230. self.SetSize(self.GetBestSize())
  231. class Log:
  232. """The log output is redirected to the status bar of the containing frame. """
  233. def __init__(self, parent):
  234. self.parent = parent
  235. def message(self, text_string):
  236. """Updates status bar """
  237. self.parent.SetStatusText(text_string.strip())
  238. class RBookPanel(wx.Panel):
  239. """Generic notebook page with shared widgets and empty kriging functions. """
  240. def __init__(self, parent, *args, **kwargs):
  241. wx.Panel.__init__(self, parent, *args, **kwargs)
  242. self.parent = parent
  243. self.VariogramSizer = wx.StaticBoxSizer(wx.StaticBox(self,
  244. id = wx.ID_ANY,
  245. label = _("Variogram fitting")),
  246. wx.HORIZONTAL)
  247. self.LeftSizer = wx.BoxSizer(wx.VERTICAL)
  248. self.RightSizer = wx.BoxSizer(wx.VERTICAL)
  249. self.ParametersSizer = wx.GridBagSizer(vgap = 5, hgap = 5)
  250. self.VariogramSizer.Add(self.LeftSizer, proportion = 0, flag = wx.EXPAND | wx.ALL, border = parent.border)
  251. self.VariogramSizer.Add(self.RightSizer, proportion = 0, flag = wx.EXPAND | wx.ALL, border = parent.border)
  252. # left side of Variogram fitting. The checkboxes and spinctrls.
  253. self.PlotButton = wx.Button(self, id = wx.ID_ANY, label = _("Plot/refresh variogram")) # no stock ID for Run button..
  254. self.PlotButton.Bind(wx.EVT_BUTTON, self.OnPlotButton)
  255. self.PlotButton.Enable(False) # grey it out until a suitable layer is available
  256. self.LeftSizer.Add(self.PlotButton, proportion = 0, flag = wx.ALL, border = parent.border)
  257. self.LeftSizer.Add(self.ParametersSizer, proportion = 0, flag = wx.EXPAND | wx.ALL, border = parent.border)
  258. self.ParametersList = ["Sill", "Nugget", "Range", "Kappa"]
  259. MinValues = [0,0,1,0.1]
  260. for n in self.ParametersList:
  261. setattr(self, n+"ChextBox", wx.CheckBox(self,
  262. id = self.ParametersList.index(n),
  263. label = _(n + ":")))
  264. # Kappa must be float
  265. if n == "Kappa":
  266. setattr(self, n+"Ctrl", (wx.SpinCtrlDouble(self,
  267. id = wx.ID_ANY,
  268. min = MinValues[self.ParametersList.index(n)],
  269. max = maxint,
  270. inc = 0.1,
  271. initial = 0.5)))
  272. else:
  273. setattr(self, n+"Ctrl", (wx.SpinCtrl(self,
  274. id = wx.ID_ANY,
  275. min = MinValues[self.ParametersList.index(n)],
  276. max = maxint)))
  277. getattr(self, n+"ChextBox").Bind(wx.EVT_CHECKBOX,
  278. self.UseValue,
  279. id = self.ParametersList.index(n))
  280. setattr(self, n+"Sizer", (wx.BoxSizer(wx.HORIZONTAL)))
  281. self.ParametersSizer.Add(getattr(self, n+"ChextBox"),
  282. flag = wx.ALIGN_CENTER_VERTICAL,
  283. pos = (self.ParametersList.index(n),0))
  284. self.ParametersSizer.Add(getattr(self, n+"Ctrl"),
  285. flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL,
  286. pos = (self.ParametersList.index(n),1))
  287. # right side of the Variogram fitting. The plot area.
  288. #Plot = wx.StaticText(self, id= wx.ID_ANY, label = "Check Plot Variogram to interactively fit model.")
  289. #PlotPanel = wx.Panel(self)
  290. #self.PlotArea = plot.PlotCanvas(PlotPanel)
  291. #self.PlotArea.SetInitialSize(size = (250,250))
  292. #self.RightSizer.Add(PlotPanel, proportion=0, flag= wx.EXPAND|wx.ALL, border=parent.border)
  293. self.KrigingSizer = wx.StaticBoxSizer(wx.StaticBox(self,
  294. id = wx.ID_ANY,
  295. label = _("Kriging techniques")),
  296. wx.VERTICAL)
  297. KrigingList = ["Ordinary kriging", "Block kriging"]#, "Universal kriging"] #@FIXME: i18n on the list?
  298. self.KrigingRadioBox = wx.RadioBox(self,
  299. id = wx.ID_ANY,
  300. choices = KrigingList,
  301. majorDimension = 1,
  302. style = wx.RA_SPECIFY_COLS)
  303. self.KrigingRadioBox.Bind(wx.EVT_RADIOBOX, self.HideBlockOptions)
  304. self.KrigingSizer.Add(self.KrigingRadioBox, proportion = 0, flag = wx.EXPAND | wx.ALL, border = parent.border)
  305. # block kriging parameters. Size.
  306. BlockSizer = wx.BoxSizer(wx.HORIZONTAL)
  307. BlockLabel = wx.StaticText(self, id = wx.ID_ANY, label = _("Block size:"))
  308. self.BlockSpinBox = wx.SpinCtrl(self, id = wx.ID_ANY, min = 1, max = maxint)
  309. self.BlockSpinBox.Enable(False) # default choice is Ordinary kriging so block param is disabled
  310. BlockSizer.Add(BlockLabel, flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = parent.border)
  311. BlockSizer.Add(self.BlockSpinBox, flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = parent.border)
  312. self.KrigingSizer.Add(BlockSizer, flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL, border = parent.border)
  313. self.Sizer = wx.BoxSizer(wx.VERTICAL)
  314. self.Sizer.Add(self.VariogramSizer, proportion = 0, flag = wx.EXPAND | wx.ALL, border = parent.border)
  315. self.Sizer.Add(self.KrigingSizer, proportion = 0, flag = wx.EXPAND | wx.ALL, border = parent.border)
  316. def HideBlockOptions(self, event):
  317. self.BlockSpinBox.Enable(event.GetInt() == 1)
  318. def OnPlotButton(self,event):
  319. """Plots variogram with current options. """
  320. pass
  321. def UseValue(self, event):
  322. """Enables/Disables the SpinCtrl in respect of the checkbox. """
  323. n = self.ParametersList[event.GetId()]
  324. getattr(self, n+"Ctrl").Enable(event.IsChecked())
  325. class RBookgstatPanel(RBookPanel):
  326. """Subclass of RBookPanel, with specific gstat options and kriging functions. """
  327. def __init__(self, parent, Rinstance, controller, *args, **kwargs):
  328. RBookPanel.__init__(self, parent, *args, **kwargs)
  329. # assigns Rinstance, that comes from the GUI call of v.krige.py.
  330. robjects = Rinstance
  331. self.controller = controller
  332. if robjects.r.require('automap')[0]:
  333. self.VariogramCheckBox = wx.CheckBox(self, id = wx.ID_ANY, label = _("Auto-fit variogram"))
  334. self.LeftSizer.Insert(0,
  335. self.VariogramCheckBox,
  336. proportion = 0,
  337. flag = wx.EXPAND | wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  338. border = 4)
  339. self.SetSizerAndFit(self.Sizer)
  340. self.VariogramCheckBox.Bind(wx.EVT_CHECKBOX, self.HideOptions)
  341. self.VariogramCheckBox.SetValue(state = True) # check it by default
  342. # Get list of available models. Show long name but use short one
  343. ModelFactor = robjects.r.vgm()
  344. ModelList = robjects.r.levels(ModelFactor[1])
  345. self.ModelListShort = robjects.r.levels(ModelFactor[0])
  346. #@FIXME: no other way to let the Python pick it up..
  347. # and this is te wrong place where to load this list. should be at the very beginning.
  348. self.ModelChoicebox = wx.Choice(self, id = wx.ID_ANY, choices = ModelList)
  349. # disable model parameters' widgets by default
  350. for n in ["Sill", "Nugget", "Range", "Kappa"]:
  351. getattr(self, n+"Ctrl").Enable(False)
  352. self.ModelChoicebox.Enable(False)
  353. VariogramSubSizer = wx.BoxSizer(wx.HORIZONTAL)
  354. VariogramSubSizer.Add(item = wx.StaticText(self,
  355. id = wx.ID_ANY,
  356. label = _("Model: ")),
  357. flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  358. border = 4)
  359. VariogramSubSizer.Add(item = self.ModelChoicebox,
  360. flag = wx.ALIGN_CENTER_VERTICAL | wx.ALL,
  361. border = 4)
  362. self.LeftSizer.Insert(2, item = VariogramSubSizer)
  363. self.SetSizerAndFit(self.Sizer)
  364. def HideOptions(self, event):
  365. self.ModelChoicebox.Enable(not event.IsChecked())
  366. for n in ["Sill", "Nugget", "Range", "Kappa"]:
  367. if not event.IsChecked():
  368. getattr(self, n+"Ctrl").Enable(True)
  369. getattr(self, n+ "ChextBox").SetValue(True)
  370. getattr(self, n+ "ChextBox").Enable(False) # grey it out keeping it checked.. improvable
  371. else:
  372. getattr(self, n+"Ctrl").Enable(False)
  373. getattr(self, n+ "ChextBox").SetValue(False)
  374. getattr(self, n+ "ChextBox").Enable(True)
  375. #@FIXME: was for n in self.ParametersSizer.GetChildren(): n.Enable(False) but doesn't work
  376. def OnPlotButton(self,event):
  377. """Plots variogram with current options. """
  378. ## BIG WARNING: smell of code duplication. Fix this asap. emminchia!
  379. #controller = Controller() # sed, if needed,
  380. #controller = self.controller
  381. map = self.parent.InputDataMap.GetValue()
  382. column = self.parent.InputDataColumn.GetValue()
  383. # import data or pick them up
  384. if self.controller.InputData is None:
  385. self.controller.InputData = self.controller.ImportMap(map = map,
  386. column = column)
  387. # fit the variogram or pick it up
  388. #~ Formula = self.controller.ComposeFormula(column = column,
  389. #~ isblock = self.KrigingRadioBox.GetStringSelection() == "Block kriging")
  390. if hasattr(self, 'VariogramCheckBox') and self.VariogramCheckBox.IsChecked():
  391. self.model = ''
  392. for each in ("Sill","Nugget","Range","Kappa"):
  393. if getattr(self, each+'ChextBox').IsChecked():
  394. setattr(self, each.lower(), getattr(self, each+"Ctrl").GetValue())
  395. else:
  396. setattr(self, each.lower(), robjects.r('''NA'''))
  397. else:
  398. self.model = self.ModelListShort[self.ModelChoicebox.GetSelection()]
  399. for each in ("Sill","Nugget","Range","Kappa"):
  400. if getattr(self, each+'ChextBox').IsChecked(): #@FIXME will be removed when chextboxes will be frozen
  401. setattr(self, each.lower(), getattr(self, each+"Ctrl").GetValue())
  402. isblock = self.KrigingRadioBox.GetStringSelection() == "Block kriging"
  403. if isblock is not '':
  404. self.predictor = 'x+y'
  405. else:
  406. self.predictor = '1'
  407. self.controller.Variogram = self.controller.FitVariogram(robjects.Formula(str(column) + "~" + self.predictor),
  408. self.controller.InputData,
  409. model = self.model,
  410. sill = self.sill,
  411. nugget = self.nugget,
  412. range = self.range,
  413. kappa = self.kappa)
  414. ''' Fill parameters with autofitted values '''
  415. if hasattr(self, 'VariogramCheckBox') and self.VariogramCheckBox.IsChecked():
  416. for i in range(len(self.ModelListShort)):
  417. if self.ModelListShort[i] == self.controller.Variogram['model']:
  418. self.ModelChoicebox.SetSelection(i)
  419. break
  420. if not getattr(self, 'SillChextBox').IsChecked():
  421. self.sill = self.controller.Variogram['variogrammodel'][1][1]
  422. self.SillCtrl.SetValue(self.sill)
  423. if not getattr(self, 'NuggetChextBox').IsChecked():
  424. self.nugget = self.controller.Variogram['variogrammodel'][1][0]
  425. self.NuggetCtrl.SetValue(self.nugget)
  426. if not getattr(self, 'RangeChextBox').IsChecked():
  427. self.range = self.controller.Variogram['variogrammodel'][2][1]
  428. self.RangeCtrl.SetValue(self.range)
  429. if not getattr(self, 'KappaChextBox').IsChecked():
  430. self.kappa = self.controller.Variogram['variogrammodel'][3][1]
  431. self.KappaCtrl.SetValue(self.kappa)
  432. # use R plot function, in a separate window.
  433. thread.start_new_thread(self.plot, ())
  434. def plot(self):
  435. #robjects.r.X11()
  436. #robjects.r.png("variogram.png")
  437. textplot = robjects.r.plot(self.controller.Variogram['datavariogram'],
  438. self.controller.Variogram['variogrammodel'])
  439. print textplot
  440. self.refresh()
  441. #robjects.r['dev.off']()
  442. def refresh(self):
  443. while True:
  444. rinterface.process_revents()
  445. time.sleep(0.2)
  446. class RBookgeoRPanel(RBookPanel):
  447. """Subclass of RBookPanel, with specific geoR options and kriging functions. """
  448. def __init__(self, parent, *args, **kwargs):
  449. RBookPanel.__init__(self, parent, *args, **kwargs)
  450. #@TODO: change these two lines as soon as geoR f(x)s are integrated.
  451. for n in self.GetChildren():
  452. n.Hide()
  453. self.Sizer.Add(wx.StaticText(self, id = wx.ID_ANY, label = _("Work in progress! No functionality provided.")))
  454. self.SetSizerAndFit(self.Sizer)