Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CAT12 OSError: No command "matlab" found on host. #518

Open
JohannesWiesner opened this issue Mar 6, 2023 · 15 comments
Open

CAT12 OSError: No command "matlab" found on host. #518

JohannesWiesner opened this issue Mar 6, 2023 · 15 comments

Comments

@JohannesWiesner
Copy link

When installing CAT12+MATLAB-MCR and then running a little test script, I get the following error:

(csp) root@5904d25de750:/code# python test_cat12.py 
Traceback (most recent call last):
  File "/code/test_cat12.py", line 4, in <module>
    c.run()
  File "/opt/miniconda-latest/envs/csp/lib/python3.11/site-packages/nipype/interfaces/base/core.py", line 398, in run
    runtime = self._run_interface(runtime)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/miniconda-latest/envs/csp/lib/python3.11/site-packages/nipype/interfaces/spm/base.py", line 387, in _run_interface
    results = self.mlab.run()
              ^^^^^^^^^^^^^^^
  File "/opt/miniconda-latest/envs/csp/lib/python3.11/site-packages/nipype/interfaces/base/core.py", line 398, in run
    runtime = self._run_interface(runtime)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/miniconda-latest/envs/csp/lib/python3.11/site-packages/nipype/interfaces/matlab.py", line 156, in _run_interface
    runtime = super(MatlabCommand, self)._run_interface(runtime)
              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/opt/miniconda-latest/envs/csp/lib/python3.11/site-packages/nipype/interfaces/base/core.py", line 753, in _run_interface
    raise IOError(
OSError: No command "matlab" found on host 5904d25de750. Please check that the corresponding package is installed.
(csp) root@5904d25de750:/code# 

This is the script to produce the Dockerfile:

generate_docker() {
    docker run -i --rm repronim/neurodocker:0.9.4 generate docker \
        --base-image neurodebian:stretch-non-free \
        --pkg-manager apt \
        --install opts="--quiet" \
            gcc \
            g++ \
            octave \
        --matlabmcr version=2017b \
        --cat12 version=r1933_R2017b \
        --copy $yaml_file /tmp/ \
        --miniconda \
            version=latest \
            yaml_file=/tmp/$yaml_file \
            env_name=csp \
        --run 'mkdir /code && chmod 777 /code && chmod a+s /code' \
        --run 'mkdir /data && chmod 777 /data && chmod a+s /data' \
        --run 'mkdir /cache && chmod 777 /cache && chmod a+s /cache' \
        --run 'mkdir /output && chmod 777 /output && chmod a+s /output' \
        --run 'mkdir ~root/.jupyter' \
        --run 'echo c.NotebookApp.ip = \"0.0.0.0\" > ~root/.jupyter/jupyter_notebook_config.py' \
        --run 'echo c.NotebookApp.allow_root=True >> ~root/.jupyter/jupyter_notebook_config.py' \
        --run 'echo source activate csp >> ~root/.bashrc' \
        --workdir '/code'
}

And this is the little test script (taken from the nipype docs):

from nipype.interfaces.cat12 import CAT12SANLMDenoising
c = CAT12SANLMDenoising()
c.inputs.in_files = '/data/anatomical.nii'
c.run()

However, when installing SPM12 and also running the corresponding test script everything works fine:

generate_docker() {
    docker run -i --rm repronim/neurodocker:0.9.4 generate docker \
        --base-image neurodebian:stretch-non-free \
        --pkg-manager apt \
        --install opts="--quiet" \
            gcc \
            g++ \
            octave \
        --spm12 version=r7771 \
        --copy $yaml_file /tmp/ \
        --miniconda \
            version=latest \
            yaml_file=/tmp/$yaml_file \
            env_name=csp \
        --run 'mkdir /code && chmod 777 /code && chmod a+s /code' \
        --run 'mkdir /data && chmod 777 /data && chmod a+s /data' \
        --run 'mkdir /cache && chmod 777 /cache && chmod a+s /cache' \
        --run 'mkdir /output && chmod 777 /output && chmod a+s /output' \
        --run 'mkdir ~root/.jupyter' \
        --run 'echo c.NotebookApp.ip = \"0.0.0.0\" > ~root/.jupyter/jupyter_notebook_config.py' \
        --run 'echo c.NotebookApp.allow_root=True >> ~root/.jupyter/jupyter_notebook_config.py' \
        --run 'echo source activate csp >> ~root/.bashrc' \
        --workdir '/code'
}
from nipype.interfaces.spm import Smooth
smooth = Smooth()
smooth.inputs.in_files = '/data/functional.nii'
smooth.inputs.fwhm = 6
smooth.run()
@JohannesWiesner
Copy link
Author

My current hypothesis is, that CAT12 doesn't work with the root-user. Will check it out by creating a separate script with a non-root user.

@JohannesWiesner
Copy link
Author

We checked it, and it also doesn't work when switching to a non-root user.

generate_docker() {
    docker run -i --rm repronim/neurodocker:0.9.4 generate docker \
        --base-image neurodebian:stretch-non-free \
        --pkg-manager apt \
        --install opts="--quiet" \
            gcc \
            g++ \
            octave \
        --matlabmcr version=2017b \
        --cat12 version=r1933_R2017b \
        --copy $yaml_file /tmp/ \
        --miniconda \
            version=latest \
            yaml_file=/tmp/$yaml_file \
            env_name=csp \
        --user csp \
        --run 'mkdir /home/csp/data && chmod -R a+rwx /home/csp/data' \
        --run 'mkdir /home/csp/output && chmod -R a+rwx /home/csp/output' \
        --run 'mkdir /home/csp/code && chmod -R a+rwx /home/csp/code' \
        --run 'mkdir /home/csp/cache && chmod -R a+rwx /home/csp/cache' \
        --run 'mkdir /home/csp/.jupyter && echo c.NotebookApp.ip = \"0.0.0.0\" > home/csp/.jupyter/jupyter_notebook_config.py' \
        --run 'echo source activate csp >> /home/csp/.bashrc' \
        --workdir /home/csp/code
}

and then:

from nipype.interfaces.cat12 import CAT12SANLMDenoising
c = CAT12SANLMDenoising()
c.inputs.in_files = '/home/csp/data/anatomical.nii'
c.run()

gives the same error.

@JohannesWiesner
Copy link
Author

Additional checks:

According to the docs nipype.interfaces.cat12.CAT12SANLMDenoising is a subclass of nipype.interfaces.spm.SPMCommand. This class in turn has an attribute nipype.interfaces.spm.SPMCommand._matlab_cmd. When using the "SPM-Version" I get:

from nipype.interfaces import spm
spm_instance = spm.SPMCommand()
spm_instance._matlab_cmd
'/opt/spm12-r7771/run_spm12.sh /opt/matlab-compiler-runtime-2010a/v713 script'

which looks good. However, with the "CAT12"-Version, this attribute is empty.

@stebo85
Copy link
Collaborator

stebo85 commented Mar 10, 2023

Dear @JohannesWiesner,

It looks like you got the matlab path incorrectly specified.

For the www.neurodesk.org project we build CAT12 like this: https://github.com/NeuroDesk/neurocontainers/blob/master/recipes/cat12/build.sh

Then using CAT12 from nipype works like this:

import nipype.interfaces.spm as spm

matlab_cmd = '/opt/cat12/run_spm12.sh /opt/mcr/v93/ script'
spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True)

import nipype.interfaces.cat12 as cat12

cat = cat12.CAT12Segment(in_files='/neurodesktop-storage/sub-01_ses-01_7T_T1w_defaced.nii')
cat.run() 

@JohannesWiesner
Copy link
Author

@stebo85 :

It looks like you got the matlab path incorrectly specified.

But this should all happen automatically right? Because for SPM12 it is not necessary to specify the paths beforehand? Or have I misunderstood something? Besides it does not seem to work in this case (put a file anatomical.nii into /data beforehand):

generate_docker() {
    docker run -i --rm repronim/neurodocker:0.9.4 generate docker \
        --base-image neurodebian:stretch-non-free \
        --pkg-manager apt \
        --install opts="--quiet" \
            gcc \
            g++ \
            octave \
        --matlabmcr version=2017b \
        --cat12 version=r1933_R2017b \
        --copy $yaml_file /tmp/ \
        --miniconda \
            version=latest \
            yaml_file=/tmp/$yaml_file \
            env_name=csp \
        --user csp \
        --run 'mkdir /home/csp/data && chmod -R a+rwx /home/csp/data' \
        --run 'mkdir /home/csp/output && chmod -R a+rwx /home/csp/output' \
        --run 'mkdir /home/csp/code && chmod -R a+rwx /home/csp/code' \
        --run 'mkdir /home/csp/cache && chmod -R a+rwx /home/csp/cache' \
        --run 'mkdir /home/csp/.jupyter && echo c.NotebookApp.ip = \"0.0.0.0\" > home/csp/.jupyter/jupyter_notebook_config.py' \
        --run 'echo source activate csp >> /home/csp/.bashrc' \
        --workdir /home/csp/code
}

and then:

import nipype.interfaces.spm as spm
from nipype.interfaces.cat12 import CAT12SANLMDenoising

matlab_cmd = '/opt/CAT12-r1933_R2/run_spm12.sh /opt/MCR-2017b/v93/ script'
spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True)
c = CAT12SANLMDenoising()
c.inputs.in_files = '/data/anatomical.nii'
c.run()

I get OSError: No command "/opt/CAT12-r1933_R2/run_spm12.sh" although the script is definitely at this location

@kaczmarj
Copy link
Collaborator

is /opt/CAT12-r1933_R2/run_spm12.sh executable? what does ls -l /opt/CAT12-r1933_R2/run_spm12.sh say?

@stebo85
Copy link
Collaborator

stebo85 commented Mar 31, 2023

Dear @JohannesWiesner ,

I tried reproducing your problem and I built the container exactly like you. I think the problem might be a typo in your matlab_cmd:

import nipype.interfaces.spm as spm
from nipype.interfaces.cat12 import CAT12SANLMDenoising

matlab_cmd = '/opt/CAT12-r1933_R2017b/run_spm12.sh /opt/MCR-2017b/v93/ script'
spm.SPMCommand.set_mlab_paths(matlab_cmd=matlab_cmd, use_mcr=True)
c = CAT12SANLMDenoising()
c.inputs.in_files = '/data/anatomical.nii'
c.run()

This is working for me :)

@kaczmarj
Copy link
Collaborator

thanks @stebo85 !

@JohannesWiesner
Copy link
Author

@stebo85 You're right, sorry for the typo! The script works fine now :) However, I still don't get why this manual configuration has to be done? I checked the .yml files for SPM12 and CAT12 and it seems that for SPM12 MATLABCMD and a few other global variables are already specified in the installation instructions which might explain that the steps above are necessary to do for CAT12 but not for SPM12. Wouldn't it make sense to harmonize the .yml files?

@stebo85
Copy link
Collaborator

stebo85 commented Apr 3, 2023

Good idea - I wasn't aware that you can set this in the yaml file. Can you test it for CAT12 and send a pull request?

@JohannesWiesner
Copy link
Author

Maybe the original idea of this was that CAT12 would always be installed together with SPM12 and therefore it would be unnecessary to specify the same environmental variables twice? Maybe @kaczmarj remembers what lead to this design decision? As the simultaneous installation of SPM12+CAT12 in one container is not possible currently (see #510) it could make more sense to follow a modular approach so that CAT12 and SPM12 can be installed individually (with the long-term goal to make it possible to install them both in one container).

Can you test it for CAT12 and send a pull request?

I could try but it's a steep learning curve for me, I don't really understand what's going on when the env: part get's specified for both spm12.yaml and cat12.yaml

@kaczmarj
Copy link
Collaborator

kaczmarj commented Apr 4, 2023

Maybe the original idea of this was that CAT12 would always be installed together with SPM12 and therefore it would be unnecessary to specify the same environmental variables twice? Maybe @kaczmarj remembers what lead to this design decision?

this was a long time ago, but i believe you are correct @JohannesWiesner .

I don't really understand what's going on when the env: part get's specified for both spm12.yaml and cat12.yaml

if the environment variable names for spm12 and cat12 overlap, then the environment variables will be overwritten by whatever is installed last.

@github-actions
Copy link
Contributor

This issue is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Aug 23, 2023
@github-actions
Copy link
Contributor

github-actions bot commented Sep 6, 2023

This issue was closed because it has been inactive for 14 days since being marked as stale.

@github-actions github-actions bot closed this as not planned Won't fix, can't repro, duplicate, stale Sep 6, 2023
@Remi-Gau Remi-Gau reopened this Sep 6, 2023
@github-actions github-actions bot removed the stale label Sep 7, 2023
Copy link
Contributor

github-actions bot commented Nov 6, 2023

This issue is stale because it has been open for 30 days with no activity.

@github-actions github-actions bot added the stale label Nov 6, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants