I have been struggling for the last couple days to get some nipype interfaces to run some SPM functions that I will be using to do a Python implementation of Martin Havlicek’s cubature Kalman Filter for deconvolving hemodynamic functions.
In short, my goal right now is to call the spm_hdm_priors function from Python so I can use the outputs to describe the priors on the HDM. I have been able to get some code to work, but its kind of a “hacky” implementation, where I use the interface to disp my SPM outputs in the MCR session, and then parse stdout for the matrix files (shown below).
from nipype.interfaces.base import BaseInterface, BaseInterfaceInputSpec, TraitedSpec, traits, File
from nipype.interfaces.matlab import MatlabCommand
import os
class SPMHdmPriorsInputSpec(BaseInterfaceInputSpec):
num_inputs = traits.Int(desc='Number of inputs', mandatory=True)
num_priors = traits.Int(desc='Number of priors', mandatory=True)
output_dir = traits.Directory(desc='Output directory', exists=True, mandatory=True)
class SPMHdmPriorsOutputSpec(TraitedSpec):
priors = traits.List(desc='List of output priors')
class SPMHdmPriors(BaseInterface):
input_spec = SPMHdmPriorsInputSpec
output_spec = SPMHdmPriorsOutputSpec
def _list_outputs(self, stdout):
stdout = stdout.split('\n')[-2:]
pE = np.array(stdout[0].strip('[]').split(';'), dtype=np.float32)
pC = np.array(stdout[1].strip('[]').replace(';', ' ').split(), dtype=np.float32).reshape(7, 7)
return {'pE': pE, 'pC': pC}
def aggregate_outputs(self, runtime):
return self._list_outputs(self._results.runtime.stdout)
def _run_interface(self, runtime):
# Call MATLAB SPM function spm_hdm_priors
mcr_path = '/Applications/MATLAB/MATLAB_Runtime/R2022b/' # Replace with the actual path to the MATLAB Common Runtime
matlab_script = """
addpath('/Users/cjohnson44/spm12_standalone//');
num_inputs = {num_inputs};
num_priors = {num_priors};
[pE, pC] = spm_hdm_priors(num_inputs, num_priors);
disp(mat2str(pE));
disp(mat2str(pC));
""".format(num_inputs=1, num_priors=3, mcr_path=mcr_path)
matlab_cmd = MatlabCommand(script=matlab_script, mfile=True)
self._results = matlab_cmd.run()
return runtime
priors_eng = SPMHdmPriors()
priors_eng.inputs.num_inputs = 1
priors_eng.inputs.num_priors = 3
priors_eng.inputs.output_dir = '/Users/cjohnson44/Documents/workdir'
outs = priors_eng.run()
I would really prefer to be able to transfer these files directly to Python (using the Traits package?), but have not been able to find any methods that don’t involve writing to disk or stdout.