Source code for brainvisa.tools.spm_run

# -*- 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