Skip to content

Commit 70a25d6

Browse files
authoredMay 17, 2017
Merge pull request #4571 from rldhont/release-2_18-processing-rscripts-outputs
[BUGFIX][Processing] R scripts do not have enough outputs
2 parents bb7f95f + 5bdd038 commit 70a25d6

File tree

1 file changed

+80
-3
lines changed

1 file changed

+80
-3
lines changed
 

‎python/plugins/processing/algs/r/RAlgorithm.py

Lines changed: 80 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,11 @@
5353
from processing.core.outputs import OutputRaster
5454
from processing.core.outputs import OutputHTML
5555
from processing.core.outputs import OutputFile
56+
from processing.core.outputs import OutputDirectory
57+
from processing.core.outputs import OutputString
58+
from processing.core.outputs import OutputNumber
5659
from processing.tools.system import isWindows
60+
from processing.tools.system import setTempOutput
5761
from processing.script.WrongScriptException import WrongScriptException
5862
from .RUtils import RUtils
5963

@@ -62,6 +66,7 @@ class RAlgorithm(GeoAlgorithm):
6266

6367
R_CONSOLE_OUTPUT = 'R_CONSOLE_OUTPUT'
6468
RPLOTS = 'RPLOTS'
69+
R_OUTPUT_VALUES = 'R_OUTPUT_VALUES'
6570

6671
def getCopy(self):
6772
newone = RAlgorithm(self.descriptionFile)
@@ -99,6 +104,7 @@ def parseDescription(self, lines):
99104
self.commands = []
100105
self.showPlots = False
101106
self.showConsoleOutput = False
107+
self.saveOutputValues = False
102108
self.useRasterPackage = True
103109
self.passFileNames = False
104110
self.verboseCommands = []
@@ -108,7 +114,7 @@ def parseDescription(self, lines):
108114
if line.startswith('##'):
109115
try:
110116
self.processParameterLine(line)
111-
except Exception:
117+
except Exception as e:
112118
raise WrongScriptException(
113119
self.tr('Could not load R script: %s.\n Problem with line %s' % (self.descriptionFile, line)))
114120
elif line.startswith('>'):
@@ -282,8 +288,24 @@ def processOutputParameterToken(self, token):
282288
out = OutputVector()
283289
elif token.lower().strip().startswith('table'):
284290
out = OutputTable()
285-
elif token.lower().strip().startswith('file'):
286-
out = OutputFile()
291+
else:
292+
if token.lower().strip().startswith('file'):
293+
out = OutputFile()
294+
ext = token.strip()[len('file') + 1:]
295+
if ext:
296+
out.ext = ext
297+
elif token.lower().strip().startswith('directory'):
298+
out = OutputDirectory()
299+
elif token.lower().strip().startswith('number'):
300+
out = OutputNumber()
301+
elif token.lower().strip().startswith('string'):
302+
out = OutputString()
303+
304+
if not self.saveOutputValues and out:
305+
outVal = OutputFile(RAlgorithm.R_OUTPUT_VALUES, self.tr('R Output values'), ext='txt')
306+
outVal.hidden = True
307+
self.addOutput(outVal)
308+
self.saveOutputValues = True
287309

288310
return out
289311

@@ -301,6 +323,10 @@ def processAlgorithm(self, progress):
301323
progress.setCommand(line)
302324
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
303325
RUtils.executeRAlgorithm(self, progress)
326+
if self.saveOutputValues:
327+
with open(self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES), 'r') as f:
328+
lines = [line.strip() for line in f]
329+
self.parseOutputValues(iter(lines))
304330
if self.showPlots:
305331
htmlfilename = self.getOutputValue(RAlgorithm.RPLOTS)
306332
f = open(htmlfilename, 'w')
@@ -312,6 +338,37 @@ def processAlgorithm(self, progress):
312338
f.write(RUtils.getConsoleOutput())
313339
f.close()
314340

341+
def parseOutputValues(self, lines):
342+
if not self.saveOutputValues:
343+
return
344+
345+
out = None
346+
ender = 0
347+
line = lines.next().strip('\n').strip('\r')
348+
while ender < 10:
349+
if line.startswith('##'):
350+
name = line.replace('#', '')
351+
out = self.getOutputFromName(name)
352+
else:
353+
if line == '':
354+
ender += 1
355+
else:
356+
ender = 0
357+
if out:
358+
if isinstance(out, OutputNumber):
359+
out.setValue(float(line) if '.' in line else int(line))
360+
elif isinstance(out, OutputString):
361+
if not out.value:
362+
out.setValue(line)
363+
else:
364+
out.value += '\n\r' + line
365+
else:
366+
out.setValue(line)
367+
try:
368+
line = lines.next().strip('\n').strip('\r')
369+
except:
370+
break
371+
315372
def getFullSetOfRCommands(self):
316373
commands = []
317374
commands += self.getImportCommands()
@@ -322,6 +379,15 @@ def getFullSetOfRCommands(self):
322379

323380
def getExportCommands(self):
324381
commands = []
382+
383+
# Output Values
384+
outputDataFile = None
385+
if self.saveOutputValues:
386+
outputDataFile = self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES)
387+
if not outputDataFile:
388+
setTempOutput(self.getOutputFromName(RAlgorithm.R_OUTPUT_VALUES), self)
389+
outputDataFile = self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES)
390+
325391
for out in self.outputs:
326392
if isinstance(out, OutputRaster):
327393
value = out.value
@@ -347,6 +413,9 @@ def getExportCommands(self):
347413
value = out.value
348414
value = value.replace('\\', '/')
349415
commands.append('write.csv(' + out.name + ',"' + value + '")')
416+
elif out.name != RAlgorithm.R_OUTPUT_VALUES:
417+
commands.append('cat("##' + out.name + '",file="' + outputDataFile + '",sep="\n",append=TRUE)')
418+
commands.append('cat(' + out.name + ',file="' + outputDataFile + '",sep="\n",append=TRUE)')
350419

351420
if self.showPlots:
352421
commands.append('dev.off()')
@@ -371,6 +440,7 @@ def getImportCommands(self):
371440
commands.append('library("raster")')
372441
commands.append('library("rgdal")')
373442

443+
# Add parameters
374444
for param in self.parameters:
375445
if isinstance(param, ParameterRaster):
376446
if param.value is None:
@@ -489,6 +559,13 @@ def getImportCommands(self):
489559
s += ')\n'
490560
commands.append(s)
491561

562+
# Set outputs
563+
for out in self.outputs:
564+
if isinstance(out, OutputFile) or isinstance(out, OutputDirectory):
565+
if not out.value:
566+
setTempOutput(out, self)
567+
commands.append(out.name + ' = "' + out.value + '"')
568+
492569
if self.showPlots:
493570
htmlfilename = self.getOutputValue(RAlgorithm.RPLOTS)
494571
self.plotsFilename = htmlfilename + '.png'

0 commit comments

Comments
 (0)