Skip to content

Commit

Permalink
Merge pull request #1254 from nipreps/docs/freesurfer-dependency
Browse files Browse the repository at this point in the history
ENH: Improve documentation and logging of *SynthStrip*'s model
  • Loading branch information
oesteban committed Apr 11, 2024
2 parents 64643a9 + 9c01f31 commit ecf26ab
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 19 deletions.
47 changes: 36 additions & 11 deletions docs/source/install.rst
Original file line number Diff line number Diff line change
Expand Up @@ -62,23 +62,48 @@ Execution system dependencies
If you are using a a `Neurodebian <http://neuro.debian.net/>`_ Linux distribution,
installation should be as easy as::

sudo apt-get install fsl afni ants
sudo apt-get install afni ants
sudo ln -sf /usr/lib/ants/N4BiasFieldCorrection /usr/local/bin/

After installation, make sure that all the necessary binaries are added to the ``$PATH`` environment
variable, for the user that will run ``mriqc``.

Please note that MRIQC requires Freesurfer's Synthstrip tool. If you already have Freesurfer installed,
you can get the requirements with: ::

wget https://github.com/freesurfer/freesurfer/blob/dev/mri_synthstrip/synthstrip.1.pt -P <path_to_your_freesurfer_dir>/models/
Otherwise, you can follow each software installation guide:
`AFNI <https://afni.nimh.nih.gov/afni/doc/howto/0>`_,
and `ANTs <http://stnava.github.io/ANTs/>`_.

.. warning::

You will get the error `The 'model' trait of a _SynthStripInputSpec instance must be a pathlike object or string representing an existing file, but a value of '<undefined>' <class 'str'> was specified.`
if you do not install the previous Freesurfer requirement.
Please note that *MRIQC* 22.0.0 and later requires Freesurfer's *SynthStrip* tool.

Otherwise, you can follow each software installation guide:
`FSL <http://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FslInstallation>`_,
`AFNI <https://afni.nimh.nih.gov/afni/doc/howto/0>`_,
and `ANTs <http://stnava.github.io/ANTs/>`_.
Please also install *FreeSurfer* (above 7.2) using `their guidelines <https://surfer.nmr.mgh.harvard.edu/fswiki/DownloadAndInstall>`__.
If your *FreeSurfer* version is older than 7.2, then you can get *MRIQC*'s requirements with::

wget https://github.com/freesurfer/freesurfer/blob/dev/mri_synthstrip/synthstrip.1.pt -P ${FREESURFER_HOME}/models/

.. danger::

You will get the following error if you do not install *SynthStrip*'s requirement::

The 'model' trait of a _SynthStripInputSpec instance must be a pathlike object or string representing an existing file, but a value of '<undefined>' <class 'str'> was specified.`

If the *SynthStrip* requirement was downloaded, please make sure your environment has defined the variable ``$FREESURFER_HOME`` and that it is pointing at the right directory::

echo $FREESURFER_HOME

If the ``$FREESURFER_HOME`` environment variable is defined, check whether the model file is available at the expected path::

$ stat $FREESURFER_HOME/models/synthstrip.1.pt
File: /opt/freesurfer/models/synthstrip.1.pt
Size: 30851709 Blocks: 60264 IO Block: 4096 regular file
Device: fd00h/64768d Inode: 12583379 Links: 1
Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root)
Access: 2024-04-09 11:13:29.091893354 +0200
Modify: 2023-01-20 09:39:54.284056264 +0100
Change: 2023-01-20 09:39:54.284056264 +0100
Birth: 2023-01-20 09:39:54.224056213 +0100

If *SynthStrip*'s model file is not present, the output will look like::

$ stat $FREESURFER_HOME/models/synthstrip.1.pt
stat: cannot statx '/opt/freesurfer/models/synthstrip.1.pt': No such file or directory
13 changes: 13 additions & 0 deletions mriqc/cli/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,19 @@ def main():
config.nipype.nprocs,
)

# Check synthstrip is properly installed
if not config.environment.synthstrip_path:
config.loggers.cli.warning(
(
'Please make sure FreeSurfer is installed and the FREESURFER_HOME '
'environment variable is defined and pointing at the right directory.'
) if config.environment.freesurfer_home is None
else (
f'FreeSurfer seems to be installed at {config.environment.freesurfer_home},'
" however SynthStrip's model is not found at the expected path."
)
)

if mriqc_wf is None:
sys.exit(os.EX_SOFTWARE)

Expand Down
11 changes: 11 additions & 0 deletions mriqc/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,13 @@
).decode().strip().split(' ')[-1]
_memory_gb = float(_mem_str) / (1024.0**3)

# Check for FreeSurfer's SynthStrip model
_fs_home = os.getenv('FREESURFER_HOME', None)
_default_model_path = Path(_fs_home) / 'models' / 'synthstrip.1.pt' if _fs_home else None

if _fs_home and not _default_model_path.exists():
_default_model_path = None


class _Config:
"""An abstract class forbidding instantiation."""
Expand Down Expand Up @@ -281,12 +288,16 @@ class environment(_Config):
"""A string representing the execution platform."""
free_mem = _free_mem_at_start
"""Free memory at start."""
freesurfer_home = _fs_home
"""Path to the *FreeSurfer* installation (from ``FREESURFER_HOME`` environment variable)."""
overcommit_policy = _oc_policy
"""Linux's kernel virtual memory overcommit policy."""
overcommit_limit = _oc_limit
"""Linux's kernel virtual memory overcommit limits."""
nipype_version = get_version('nipype')
"""Nipype's current version."""
synthstrip_path = _default_model_path
"""Path to *SynthStrip*'s model weights (requires *FreeSurfer*)."""
templateflow_version = get_version('templateflow')
"""The TemplateFlow client version installed."""
total_memory = _memory_gb
Expand Down
15 changes: 7 additions & 8 deletions mriqc/interfaces/synthstrip.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@
# https://www.nipreps.org/community/licensing/
#
"""SynthStrip interface."""
import os
from pathlib import Path

from nipype.interfaces.base import (
CommandLine,
CommandLineInputSpec,
Expand All @@ -33,11 +30,13 @@
traits,
)

_fs_home = os.getenv('FREESURFER_HOME', None)
_default_model_path = Path(_fs_home) / 'models' / 'synthstrip.1.pt' if _fs_home else Undefined
from mriqc import config

if _fs_home and not _default_model_path.exists():
_default_model_path = Undefined
_model_path = (
str(config.environment.synthstrip_path)
if config.environment.synthstrip_path is not None
else Undefined
)


class _SynthStripInputSpec(CommandLineInputSpec):
Expand All @@ -51,7 +50,7 @@ class _SynthStripInputSpec(CommandLineInputSpec):
False, usedefault=True, argstr='-g', desc='Use GPU', nohash=True
)
model = File(
str(_default_model_path),
_model_path,
usedefault=True,
exists=True,
argstr='--model %s',
Expand Down

0 comments on commit ecf26ab

Please sign in to comment.