Summary of what happened:
I am trying to use the SPM standalone tool with Python and the Matlab Common Runtime installation, but I am getting an error that the docstring returned by MCR was not generated by nipype
Command used (and if a helper script was used, a link to the helper script or the command generated):
from nipype.interfaces import spm
import os
os.environ['FORCE_SPMMCR'] = '1'
matlab_cmd = '/Users/cjohnson44/Documents/MATLAB/spm12/run_spm12.sh /Applications/MATLAB/MATLAB_Runtime/v97/ script'
spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True)
spm.SPMCommand().version
Version:
SPM12, Matlab Runtime R2022b
Environment (Docker, Singularity / Apptainer, custom installation):
Local conda build
Relevant log outputs (up to 20 lines):
stty: stdin isn't a terminal
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
File /opt/anaconda3/envs/matlabengine/lib/python3.10/site-packages/nipype/utils/spm_docs.py:49, in _strip_header(doc)
48 try:
---> 49 index = doc.index(hdr)
50 except ValueError as e:
ValueError: substring not found
The above exception was the direct cause of the following exception:
OSError Traceback (most recent call last)
Cell In[7], line 3
1 from nipype.interfaces import spm
2 matlab_cmd = '/Users/cjohnson44/spm12_standalone/run_spm12.sh /Applications/MATLAB/MATLAB_Runtime/R2022b/ script'
----> 3 spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True)
4 spm.SPMCommand().version
File /opt/anaconda3/envs/matlabengine/lib/python3.10/site-packages/nipype/interfaces/spm/base.py:322, in SPMCommand.set_mlab_paths(cls, matlab_cmd, paths, use_mcr)
320 cls._paths = paths
321 cls._use_mcr = use_mcr
--> 322 info_dict = Info.getinfo(matlab_cmd=matlab_cmd, paths=paths, use_mcr=use_mcr)
File /opt/anaconda3/envs/matlabengine/lib/python3.10/site-packages/nipype/interfaces/spm/base.py:238, in Info.getinfo(klass, matlab_cmd, paths, use_mcr)
235 klass._paths = paths
236 return None
--> 238 out = sd._strip_header(out.runtime.stdout)
239 out_dict = {}
240 for part in out.split("|"):
File /opt/anaconda3/envs/matlabengine/lib/python3.10/site-packages/nipype/utils/spm_docs.py:51, in _strip_header(doc)
49 index = doc.index(hdr)
50 except ValueError as e:
---> 51 raise IOError("This docstring was not generated by Nipype!\n") from e
53 index += len(hdr)
54 index += 1
OSError: This docstring was not generated by Nipype!
Dear @cjohnson44 ,
It looks like you are running this on MacOS?
Have you checked that you are using an spm12 standalone version that was compiled on Mac?
Have you checked if this is an Apple silicon system? If yes, have you tried disabling Rosetta.
In the project https://www.neurodesk.org we got SPM12 standalone to work with nipype inside a Linux system running through docker with disabled Rosetta support on apple silicon - but while experimenting with this I saw the same errors.
I hope this helps
Kind regards
Steffen
Hi Steffen,
Thank you for your reply! I am on MacOS Monterey (12.6.8) with an Intel i7 chip. The standalone spm12 can compile from the command line with the same command used in the matlab_cmd from my code above, so I am quite certain that it is the correctly compiled version for my system.
The problem seems to be with how Nipype handles the commands. I will keep looking into it and update the thread if I figure it out!
Update:
I went to the source of the error in the sd._strip_header() method and printed out the stdout (original code and change shown below:
mlab = MatlabCommand(matlab_cmd=matlab_cmd, resource_monitor=False)
mlab.inputs.mfile = False
if paths:
mlab.inputs.paths = paths
if use_mcr:
mlab.inputs.nodesktop = Undefined
mlab.inputs.nosplash = Undefined
mlab.inputs.single_comp_thread = Undefined
mlab.inputs.mfile = True
mlab.inputs.uses_mcr = True
mlab.inputs.script = """
if isempty(which('spm')),
throw(MException('SPMCheck:NotFound','SPM not in matlab path'));
end;
spm_path = spm('dir');
[name, version] = spm('ver');
fprintf(1, 'NIPYPE path:%s|name:%s|release:%s', spm_path, name, version);
exit;
"""
try:
out = mlab.run()
except (IOError, RuntimeError) as e:
......
return None
print(out.runtime.stdout) # added line here
out = sd._strip_header(out.runtime.stdout)
Running this with my original check method yields:
stty: stdin isn't a terminal
SPM12, version 7771 (standalone)
MATLAB, version 9.7.0.1737446 (R2019b) Update 9
___ ____ __ __
/ __)( _ \( \/ )
\__ \ )___/ ) ( Statistical Parametric Mapping
(___/(__) (_/\/\_) SPM12 - https://www.fil.ion.ucl.ac.uk/spm/
Executing /Users/cjohnson44/pyscript.m at 02-Jul-2024 11:20:39:
Executing /Users/cjohnson44/pyscript.m at 02-Jul-2024 11:20:39:
-----------------------------------------------------------------------------------------------------
MATLAB Version: 9.7.0.1737446 (R2019b) Update 9
MATLAB License Number: unknown
Operating System: macOS Version: 12.6.8 Build: 21G725
Java Version: Java 1.8.0_202-b08 with Oracle Corporation Java HotSpot(TM) 64-Bit Server VM mixed mode
-----------------------------------------------------------------------------------------------------
MATLAB Version 9.7 (R2019b)
FieldTrip Version unknown www.fieldtriptoolbox.org
MATLAB Compiler Version 7.1 (R2019b)
RICOH MEG Reader toolbox for MATLAB Version 1.0.2
Statistical Parametric Mapping Version 7771 (SPM12)
Yokogawa MEG Reader toolbox for MATLAB Version 1.5.1
NIPYPE path:/Users/cjohnson44/Documents/MATLAB/spm12/spm12.app/Contents/MacOS/spm12_mcr/Users/spm/spm12|name:SPM12|release:7771
stty: stdin isn't a terminal
< M A T L A B (R) >
Copyright 1984-2022 The MathWorks, Inc.
R2022b Update 5 (9.13.0.2193358) 64-bit (maci64)
February 10, 2023
To get started, type doc.
For product information, visit www.mathworks.com.
It appears that the nipype engine is actually spinning up both the SPM12 standalone, as well as a MATLAB engine. I was able to fix this issue by removing MATLAB from my PATH before starting my jupyter lab, and now all is running well!