|
@@ -51,7 +51,11 @@ |
|
|
from processing.core.outputs import OutputRaster |
|
|
from processing.core.outputs import OutputHTML |
|
|
from processing.core.outputs import OutputFile |
|
|
from processing.core.outputs import OutputDirectory |
|
|
from processing.core.outputs import OutputString |
|
|
from processing.core.outputs import OutputNumber |
|
|
from processing.tools.system import isWindows |
|
|
from processing.tools.system import setTempOutput |
|
|
from processing.script.WrongScriptException import WrongScriptException |
|
|
from RUtils import RUtils |
|
|
|
|
@@ -60,6 +64,7 @@ class RAlgorithm(GeoAlgorithm): |
|
|
|
|
|
R_CONSOLE_OUTPUT = 'R_CONSOLE_OUTPUT' |
|
|
RPLOTS = 'RPLOTS' |
|
|
R_OUTPUT_VALUES = 'R_OUTPUT_VALUES' |
|
|
|
|
|
def getCopy(self): |
|
|
newone = RAlgorithm(self.descriptionFile) |
|
@@ -97,6 +102,7 @@ def parseDescription(self, lines): |
|
|
self.commands = [] |
|
|
self.showPlots = False |
|
|
self.showConsoleOutput = False |
|
|
self.saveOutputValues = False |
|
|
self.useRasterPackage = True |
|
|
self.passFileNames = False |
|
|
self.verboseCommands = [] |
|
@@ -106,7 +112,7 @@ def parseDescription(self, lines): |
|
|
if line.startswith('##'): |
|
|
try: |
|
|
self.processParameterLine(line) |
|
|
except Exception: |
|
|
except Exception as e: |
|
|
raise WrongScriptException( |
|
|
self.tr('Could not load R script: %s.\n Problem with line %s' % (self.descriptionFile, line))) |
|
|
elif line.startswith('>'): |
|
@@ -269,8 +275,24 @@ def processOutputParameterToken(self, token): |
|
|
out = OutputVector() |
|
|
elif token.lower().strip().startswith('table'): |
|
|
out = OutputTable() |
|
|
elif token.lower().strip().startswith('file'): |
|
|
out = OutputFile() |
|
|
else: |
|
|
if token.lower().strip().startswith('file'): |
|
|
out = OutputFile() |
|
|
ext = token.strip()[len('file') + 1:] |
|
|
if ext: |
|
|
out.ext = ext |
|
|
elif token.lower().strip().startswith('directory'): |
|
|
out = OutputDirectory() |
|
|
elif token.lower().strip().startswith('number'): |
|
|
out = OutputNumber() |
|
|
elif token.lower().strip().startswith('string'): |
|
|
out = OutputString() |
|
|
|
|
|
if not self.saveOutputValues and out: |
|
|
outVal = OutputFile(RAlgorithm.R_OUTPUT_VALUES, self.tr('R Output values'), ext='txt') |
|
|
outVal.hidden = True |
|
|
self.addOutput(outVal) |
|
|
self.saveOutputValues = True |
|
|
|
|
|
return out |
|
|
|
|
@@ -288,6 +310,10 @@ def processAlgorithm(self, progress): |
|
|
progress.setCommand(line) |
|
|
ProcessingLog.addToLog(ProcessingLog.LOG_INFO, loglines) |
|
|
RUtils.executeRAlgorithm(self, progress) |
|
|
if self.saveOutputValues: |
|
|
with open(self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES), 'r') as f: |
|
|
lines = [line.strip() for line in f] |
|
|
self.parseOutputValues(iter(lines)) |
|
|
if self.showPlots: |
|
|
htmlfilename = self.getOutputValue(RAlgorithm.RPLOTS) |
|
|
f = open(htmlfilename, 'w') |
|
@@ -299,6 +325,37 @@ def processAlgorithm(self, progress): |
|
|
f.write(RUtils.getConsoleOutput()) |
|
|
f.close() |
|
|
|
|
|
def parseOutputValues(self, lines): |
|
|
if not self.saveOutputValues: |
|
|
return |
|
|
|
|
|
out = None |
|
|
ender = 0 |
|
|
line = lines.next().strip('\n').strip('\r') |
|
|
while ender < 10: |
|
|
if line.startswith('##'): |
|
|
name = line.replace('#', '') |
|
|
out = self.getOutputFromName(name) |
|
|
else: |
|
|
if line == '': |
|
|
ender += 1 |
|
|
else: |
|
|
ender = 0 |
|
|
if out: |
|
|
if isinstance(out, OutputNumber): |
|
|
out.setValue(float(line) if '.' in line else int(line)) |
|
|
elif isinstance(out, OutputString): |
|
|
if not out.value: |
|
|
out.setValue(line) |
|
|
else: |
|
|
out.value += '\n\r' + line |
|
|
else: |
|
|
out.setValue(line) |
|
|
try: |
|
|
line = lines.next().strip('\n').strip('\r') |
|
|
except: |
|
|
break |
|
|
|
|
|
def getFullSetOfRCommands(self): |
|
|
commands = [] |
|
|
commands += self.getImportCommands() |
|
@@ -309,6 +366,15 @@ def getFullSetOfRCommands(self): |
|
|
|
|
|
def getExportCommands(self): |
|
|
commands = [] |
|
|
|
|
|
# Output Values |
|
|
outputDataFile = None |
|
|
if self.saveOutputValues: |
|
|
outputDataFile = self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES) |
|
|
if not outputDataFile: |
|
|
setTempOutput(self.getOutputFromName(RAlgorithm.R_OUTPUT_VALUES), self) |
|
|
outputDataFile = self.getOutputValue(RAlgorithm.R_OUTPUT_VALUES) |
|
|
|
|
|
for out in self.outputs: |
|
|
if isinstance(out, OutputRaster): |
|
|
value = out.value |
|
@@ -334,6 +400,9 @@ def getExportCommands(self): |
|
|
value = out.value |
|
|
value = value.replace('\\', '/') |
|
|
commands.append('write.csv(' + out.name + ',"' + value + '")') |
|
|
elif out.name != RAlgorithm.R_OUTPUT_VALUES: |
|
|
commands.append('cat("##' + out.name + '",file="' + outputDataFile + '",sep="\n",append=TRUE)') |
|
|
commands.append('cat(' + out.name + ',file="' + outputDataFile + '",sep="\n",append=TRUE)') |
|
|
|
|
|
if self.showPlots: |
|
|
commands.append('dev.off()') |
|
@@ -358,6 +427,7 @@ def getImportCommands(self): |
|
|
commands.append('library("raster")') |
|
|
commands.append('library("rgdal")') |
|
|
|
|
|
# Add parameters |
|
|
for param in self.parameters: |
|
|
if isinstance(param, ParameterRaster): |
|
|
if param.value is None: |
|
@@ -476,6 +546,13 @@ def getImportCommands(self): |
|
|
s += ')\n' |
|
|
commands.append(s) |
|
|
|
|
|
# Set outputs |
|
|
for out in self.outputs: |
|
|
if isinstance(out, OutputFile) or isinstance(out, OutputDirectory): |
|
|
if not out.value: |
|
|
setTempOutput(out, self) |
|
|
commands.append(out.name + ' = "' + out.value + '"') |
|
|
|
|
|
if self.showPlots: |
|
|
htmlfilename = self.getOutputValue(RAlgorithm.RPLOTS) |
|
|
self.plotsFilename = htmlfilename + '.png' |
|
|