Skip to content

Commit acd3575

Browse files
authoredMay 16, 2017
Merge pull request #4545 from rldhont/release-2_14-processing-rscripts-outputs
[BUGFIX][Processing] R scripts do not have enough outputs
2 parents 6feed19 + b830eab commit acd3575

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
@@ -51,7 +51,11 @@
5151
from processing.core.outputs import OutputRaster
5252
from processing.core.outputs import OutputHTML
5353
from processing.core.outputs import OutputFile
54+
from processing.core.outputs import OutputDirectory
55+
from processing.core.outputs import OutputString
56+
from processing.core.outputs import OutputNumber
5457
from processing.tools.system import isWindows
58+
from processing.tools.system import setTempOutput
5559
from processing.script.WrongScriptException import WrongScriptException
5660
from RUtils import RUtils
5761

@@ -60,6 +64,7 @@ class RAlgorithm(GeoAlgorithm):
6064

6165
R_CONSOLE_OUTPUT = 'R_CONSOLE_OUTPUT'
6266
RPLOTS = 'RPLOTS'
67+
R_OUTPUT_VALUES = 'R_OUTPUT_VALUES'
6368

6469
def getCopy(self):
6570
newone = RAlgorithm(self.descriptionFile)
@@ -97,6 +102,7 @@ def parseDescription(self, lines):
97102
self.commands = []
98103
self.showPlots = False
99104
self.showConsoleOutput = False
105+
self.saveOutputValues = False
100106
self.useRasterPackage = True
101107
self.passFileNames = False
102108
self.verboseCommands = []
@@ -106,7 +112,7 @@ def parseDescription(self, lines):
106112
if line.startswith('##'):
107113
try:
108114
self.processParameterLine(line)
109-
except Exception:
115+
except Exception as e:
110116
raise WrongScriptException(
111117
self.tr('Could not load R script: %s.\n Problem with line %s' % (self.descriptionFile, line)))
112118
elif line.startswith('>'):
@@ -269,8 +275,24 @@ def processOutputParameterToken(self, token):
269275
out = OutputVector()
270276
elif token.lower().strip().startswith('table'):
271277
out = OutputTable()
272-
elif token.lower().strip().startswith('file'):
273-
out = OutputFile()
278+
else:
279+
if token.lower().strip().startswith('file'):
280+
out = OutputFile()
281+
ext = token.strip()[len('file') + 1:]
282+
if ext:
283+
out.ext = ext
284+
elif token.lower().strip().startswith('directory'):
285+
out = OutputDirectory()
286+
elif token.lower().strip().startswith('number'):
287+
out = OutputNumber()
288+
elif token.lower().strip().startswith('string'):
289+
out = OutputString()
290+
291+
if not self.saveOutputValues and out:
292+
outVal = OutputFile(RAlgorithm.R_OUTPUT_VALUES, self.tr('R Output values'), ext='txt')
293+
outVal.hidden = True
294+
self.addOutput(outVal)
295+
self.saveOutputValues = True
274296

275297
return out
276298

@@ -288,6 +310,10 @@ def processAlgorithm(self, progress):
288310
progress.setCommand(line)
289311
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines)
290312
RUtils.executeRAlgorithm(self, progress)
313+
if self.saveOutputValues:
314+
with open(self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES), 'r') as f:
315+
lines = [line.strip() for line in f]
316+
self.parseOutputValues(iter(lines))
291317
if self.showPlots:
292318
htmlfilename = self.getOutputValue(RAlgorithm.RPLOTS)
293319
f = open(htmlfilename, 'w')
@@ -299,6 +325,37 @@ def processAlgorithm(self, progress):
299325
f.write(RUtils.getConsoleOutput())
300326
f.close()
301327

328+
def parseOutputValues(self, lines):
329+
if not self.saveOutputValues:
330+
return
331+
332+
out = None
333+
ender = 0
334+
line = lines.next().strip('\n').strip('\r')
335+
while ender < 10:
336+
if line.startswith('##'):
337+
name = line.replace('#', '')
338+
out = self.getOutputFromName(name)
339+
else:
340+
if line == '':
341+
ender += 1
342+
else:
343+
ender = 0
344+
if out:
345+
if isinstance(out, OutputNumber):
346+
out.setValue(float(line) if '.' in line else int(line))
347+
elif isinstance(out, OutputString):
348+
if not out.value:
349+
out.setValue(line)
350+
else:
351+
out.value += '\n\r' + line
352+
else:
353+
out.setValue(line)
354+
try:
355+
line = lines.next().strip('\n').strip('\r')
356+
except:
357+
break
358+
302359
def getFullSetOfRCommands(self):
303360
commands = []
304361
commands += self.getImportCommands()
@@ -309,6 +366,15 @@ def getFullSetOfRCommands(self):
309366

310367
def getExportCommands(self):
311368
commands = []
369+
370+
# Output Values
371+
outputDataFile = None
372+
if self.saveOutputValues:
373+
outputDataFile = self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES)
374+
if not outputDataFile:
375+
setTempOutput(self.getOutputFromName(RAlgorithm.R_OUTPUT_VALUES), self)
376+
outputDataFile = self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES)
377+
312378
for out in self.outputs:
313379
if isinstance(out, OutputRaster):
314380
value = out.value
@@ -334,6 +400,9 @@ def getExportCommands(self):
334400
value = out.value
335401
value = value.replace('\\', '/')
336402
commands.append('write.csv(' + out.name + ',"' + value + '")')
403+
elif out.name != RAlgorithm.R_OUTPUT_VALUES:
404+
commands.append('cat("##' + out.name + '",file="' + outputDataFile + '",sep="\n",append=TRUE)')
405+
commands.append('cat(' + out.name + ',file="' + outputDataFile + '",sep="\n",append=TRUE)')
337406

338407
if self.showPlots:
339408
commands.append('dev.off()')
@@ -358,6 +427,7 @@ def getImportCommands(self):
358427
commands.append('library("raster")')
359428
commands.append('library("rgdal")')
360429

430+
# Add parameters
361431
for param in self.parameters:
362432
if isinstance(param, ParameterRaster):
363433
if param.value is None:
@@ -476,6 +546,13 @@ def getImportCommands(self):
476546
s += ')\n'
477547
commands.append(s)
478548

549+
# Set outputs
550+
for out in self.outputs:
551+
if isinstance(out, OutputFile) or isinstance(out, OutputDirectory):
552+
if not out.value:
553+
setTempOutput(out, self)
554+
commands.append(out.name + ' = "' + out.value + '"')
555+
479556
if self.showPlots:
480557
htmlfilename = self.getOutputValue(RAlgorithm.RPLOTS)
481558
self.plotsFilename = htmlfilename + '.png'

0 commit comments

Comments
 (0)
Please sign in to comment.