# -*- coding: utf-8 -*-
from __future__ import print_function
from __future__ import absolute_import
from brainvisa.validation import ValidationError
import distutils.spawn
import os
import sys
[docs]class Spm8_error(RuntimeError):
pass
[docs]class Spm8Standalone_error(RuntimeError):
pass
[docs]class SpmConfigError(RuntimeError):
pass
def getSpm8Path(configuration):
if(configuration.SPM.spm8_path is not None and configuration.SPM.spm8_path != ''):
return configuration.SPM.spm8_path
elif(configuration.SPM.spm8_standalone_path is not None and configuration.SPM.spm8_standalone_path != ''):
return configuration.SPM.spm8_standalone_path
else:
return None
#------------------------------------------------------------------------------
# spm8_standalone :
#* does not generate spm_2012Oct03.ps file for result job
#* can NOT execute spm_write_filtered command
#* has not VBM toolboxe
#-> so first, try spm8, but if not in configuration, use spm8Standalone
#------------------------------------------------------------------------------
def validation(configuration):
try:
return validationSpm8(configuration)
except Exception as Spm8_error:
try:
validationSpm8Standalone(configuration)
except Exception as Spm8Standalone_error:
raise Spm8_error
raise Spm8Standalone_error
def validationSpm8Standalone(configuration):
if((not configuration.SPM.spm8_standalone_command
or not (configuration.SPM.spm8_standalone_mcr_path or (sys.platform == "win32")))) \
and not distutils.spawn.find_executable(
configuration.matlab.executable):
raise ValidationError('SPM or matlab is not found')
return True
def validationSpm8(configuration):
if(not distutils.spawn.find_executable(configuration.matlab.executable)):
# print("Matlab executable is not found")
raise ValidationError('Matlab is not found')
if(not configuration.SPM.spm8_path):
# print("SPM8 path is not found")
raise ValidationError('SPM is not found')
return True
#------------------------------------------------------------------------------
# try spm8Standalone, but if not working, use spm8 Matlab. Read note on
# top of this file
[docs]def run(context, configuration, jobPath, cmd=None, useMatlabFirst=False, isMatlabMandatory=False):
'''Run a SPM job using SPM8 standalone or SMP8 Matlab version, trying them
alternatively, with a specifiable priority
'''
firstException = None
spmRunResult = None
isSpmRunFailed = False
if useMatlabFirst or isMatlabMandatory:
spmRunResult, firstException = tryToRunSpm8(
context, configuration, jobPath, cmd)
isSpmRunFailed = spmRunResult != 0 or firstException != None
if ((isSpmRunFailed or not useMatlabFirst) and not isMatlabMandatory):
spmRunResult, e = tryToRunSpm8Standalone(
context, configuration, jobPath)
if not firstException:
firstException = e
isSpmRunFailed = spmRunResult != 0 or firstException != None
if (isSpmRunFailed and not useMatlabFirst):
spmRunResult, e = tryToRunSpm8(
context, configuration, jobPath, cmd)
isSpmRunOK = spmRunResult == 0 and e == None
if isSpmRunOK:
firstException = None
if firstException is not None:
raise firstException
return spmRunResult
def tryToRunSpm8(context, configuration, jobPath, cmd):
hasexception = None
result = None
try:
result = runSpm8(context, configuration, jobPath, cmd)
print('spm_run.run, matlab version result:', result)
except Exception as e:
print('Exception in sun_spm.runSpm8:', e)
hasexception = e
return result, hasexception
def tryToRunSpm8Standalone(context, configuration, jobPath):
hasexception = None
result = None
try:
result = runSpm8Standalone(context, configuration, jobPath)
print('spm_run.run, standalone version result:', result)
except Exception as e:
print('Exception in run_spm.runSpm8Standalone:', e)
hasexception = e
return result, hasexception
def runSpm8Standalone(context, configuration, matfilePath):
if configuration.SPM.spm8_standalone_command is None or \
len(configuration.SPM.spm8_standalone_command) == 0:
raise SpmConfigError('SPM8 standalone is not configured')
context.write(
_t_('Using SPM8 standalone version (compiled, Matlab not needed)'))
mexe = configuration.SPM.spm8_standalone_command
cmd = [mexe, configuration.SPM.spm8_standalone_mcr_path,
'run', matfilePath]
# it's possible to use 'script' instead of 'run'
context.write('running SPM command:', cmd)
result = context.system(*cmd, cwd=os.path.dirname(matfilePath))
return result
def runSpm8(context, configuration, jobPath, spmCmd=None):
if configuration.SPM.spm8_path is None or configuration.SPM.spm8_path == '':
raise SpmConfigError('SPM8/Matlab is not configured')
matlabBatchPath = str(jobPath).replace('_job', '')
if matlabBatchPath == str(jobPath):
matlabBatchPath = str(jobPath).replace('.m', '_batch.m')
matlabBatchFile = open(matlabBatchPath, 'w')
context.write("matlabBatchPath", matlabBatchPath)
matlabBatchFile.write("try\n")
matlabBatchFile.write(
" addpath('" + configuration.SPM.spm8_path + "');\n")
matlabBatchFile.write(" spm('pet');\n")
matlabBatchFile.write(" jobid = cfg_util('initjob', '%s');\n" % jobPath)
matlabBatchFile.write(" cfg_util('run', jobid);\n")
if(spmCmd is not None):
matlabBatchFile.write(' ' + spmCmd + "\n")
matlabBatchFile.write("catch\n")
matlabBatchFile.write(" disp('error running SPM');\n")
matlabBatchFile.write(" exit(1);\n")
matlabBatchFile.write("end\n")
matlabBatchFile.write("exit\n")
matlabBatchFile.close()
try:
result = runMatblatBatch(context, configuration, matlabBatchPath)
finally:
os.unlink(matlabBatchPath)
return result
def runMatblatBatch(context, configuration, matlabBatchPath,
removeCmdOption=None):
curDir = matlabBatchPath[:matlabBatchPath.rindex('/')]
# execution batch file
# momoTODO check if mexe is None when no matlab then raise error or
# exception
mexe = distutils.spawn.find_executable(configuration.matlab.executable)
matlabCmd = os.path.basename(matlabBatchPath)[
:os.path.basename(matlabBatchPath).rindex('.')] # remove extension
matlabOptions = configuration.matlab.options
if(removeCmdOption is not None):
matlabOptions = matlabOptions.replace(removeCmdOption, '')
cmd = [mexe] + matlabOptions.split() + ['-r', matlabCmd]
context.write('Running matlab command:', cmd)
result = context.system(*cmd, cwd=curDir)
return result