diff --git a/doc/manipulating_images/manipulating_images.rst b/doc/manipulating_images/manipulating_images.rst index 0f716d0643..eeb675e0aa 100644 --- a/doc/manipulating_images/manipulating_images.rst +++ b/doc/manipulating_images/manipulating_images.rst @@ -149,7 +149,7 @@ Relevant functions: * compute a mask from EPI images: :func:`nilearn.masking.compute_epi_mask` * compute a grey-matter mask using the MNI template: - :func:`nilearn.masking.compute_gray_matter_mask`. + :func:`nilearn.masking.compute_brain_mask`. * compute a mask from images with a flat background: :func:`nilearn.masking.compute_background_mask` * compute for multiple sessions/subjects: @@ -170,8 +170,8 @@ can be computed from the data: the brain stands out of a constant background. This is typically the case when working on statistic maps output after a brain extraction - :func:`nilearn.masking.compute_epi_mask` for EPI images -- :func:`nilearn.masking.compute_gray_matter_mask` to compute a - gray-matter mask using the MNI template. +- :func:`nilearn.masking.compute_brain_mask` to compute a + whole-brain mask using the MNI template. .. literalinclude:: ../../examples/01_plotting/plot_visualization.py diff --git a/doc/modules/reference.rst b/doc/modules/reference.rst index 37fa6663ca..1b0821cdb8 100644 --- a/doc/modules/reference.rst +++ b/doc/modules/reference.rst @@ -243,7 +243,7 @@ the :ref:`user guide ` for more information and usage examples. compute_epi_mask compute_multi_epi_mask - compute_gray_matter_mask + compute_brain_mask compute_multi_gray_matter_mask compute_background_mask compute_multi_background_mask diff --git a/doc/whats_new.rst b/doc/whats_new.rst index f794466774..01d9fc7451 100644 --- a/doc/whats_new.rst +++ b/doc/whats_new.rst @@ -21,6 +21,10 @@ Fixes ----- - :class:`nilearn.input_data.NiftiLabelsMasker` no longer ignores its `mask_img` +- :func:`nilearn.masking.compute_brain_mask` has been replaced by + `:func: nilearn.masking.compute_gray_matter_mask`. Features remained the same but + some corrections regarding its description were made in the docstring. + 0.6.2 ====== diff --git a/nilearn/decomposition/base.py b/nilearn/decomposition/base.py index 63e2773e96..1533ed3060 100644 --- a/nilearn/decomposition/base.py +++ b/nilearn/decomposition/base.py @@ -286,7 +286,7 @@ class BaseDecomposition(BaseEstimator, CacheMixin, TransformerMixin): brain mask for your data's field of view. Depending on this value, the mask will be computed from masking.compute_background_mask, masking.compute_epi_mask or - masking.compute_gray_matter_mask. Default is 'epi'. + masking.compute_brain_mask. Default is 'epi'. mask_args: dict, optional If mask is None, these are additional parameters passed to diff --git a/nilearn/decomposition/canica.py b/nilearn/decomposition/canica.py index 8fbe707985..37ea1a7c48 100644 --- a/nilearn/decomposition/canica.py +++ b/nilearn/decomposition/canica.py @@ -91,7 +91,7 @@ class CanICA(MultiPCA): brain mask for your data's field of view. Depending on this value, the mask will be computed from masking.compute_background_mask, masking.compute_epi_mask or - masking.compute_gray_matter_mask. Default is 'epi'. + masking.compute_brain_mask. Default is 'epi'. mask_args: dict, optional If mask is None, these are additional parameters passed to diff --git a/nilearn/decomposition/dict_learning.py b/nilearn/decomposition/dict_learning.py index e2784b24c0..a347b7b277 100644 --- a/nilearn/decomposition/dict_learning.py +++ b/nilearn/decomposition/dict_learning.py @@ -121,7 +121,7 @@ class DictLearning(BaseDecomposition): brain mask for your data's field of view. Depending on this value, the mask will be computed from masking.compute_background_mask, masking.compute_epi_mask or - masking.compute_gray_matter_mask. Default is 'epi'. + masking.compute_brain_mask. Default is 'epi'. mask_args: dict, optional If mask is None, these are additional parameters passed to diff --git a/nilearn/decomposition/multi_pca.py b/nilearn/decomposition/multi_pca.py index 2627190187..1c69e6addb 100644 --- a/nilearn/decomposition/multi_pca.py +++ b/nilearn/decomposition/multi_pca.py @@ -47,7 +47,7 @@ class MultiPCA(BaseDecomposition): brain mask for your data's field of view. Depending on this value, the mask will be computed from masking.compute_background_mask, masking.compute_epi_mask or - masking.compute_gray_matter_mask. Default is 'epi'. + masking.compute_brain_mask. Default is 'epi'. mask_args: dict, optional If mask is None, these are additional parameters passed to diff --git a/nilearn/input_data/multi_nifti_masker.py b/nilearn/input_data/multi_nifti_masker.py index dcd0077d49..289a1f74cb 100644 --- a/nilearn/input_data/multi_nifti_masker.py +++ b/nilearn/input_data/multi_nifti_masker.py @@ -81,7 +81,7 @@ class MultiNiftiMasker(NiftiMasker, CacheMixin): brain mask for your data's field of view. Depending on this value, the mask will be computed from masking.compute_background_mask, masking.compute_epi_mask or - masking.compute_gray_matter_mask. Default is 'background'. + masking.compute_brain_mask. Default is 'background'. mask_args : dict, optional If mask is None, these are additional parameters passed to diff --git a/nilearn/input_data/nifti_masker.py b/nilearn/input_data/nifti_masker.py index 6588de91fa..d3491fbcc1 100644 --- a/nilearn/input_data/nifti_masker.py +++ b/nilearn/input_data/nifti_masker.py @@ -134,7 +134,7 @@ class NiftiMasker(BaseMasker, CacheMixin, ReportMixin): brain mask for your data's field of view. Depending on this value, the mask will be computed from masking.compute_background_mask, masking.compute_epi_mask or - masking.compute_gray_matter_mask. Default is 'background'. + masking.compute_brain_mask. Default is 'background'. mask_args : dict, optional If mask is None, these are additional parameters passed to @@ -317,7 +317,7 @@ def fit(self, imgs=None, y=None): elif self.mask_strategy == 'epi': compute_mask = masking.compute_epi_mask elif self.mask_strategy == 'template': - compute_mask = masking.compute_gray_matter_mask + compute_mask = masking.compute_brain_mask else: raise ValueError("Unknown value of mask_strategy '%s'. " "Acceptable values are 'background', " diff --git a/nilearn/input_data/tests/test_nifti_masker.py b/nilearn/input_data/tests/test_nifti_masker.py index 6518527934..c57dcd8b61 100644 --- a/nilearn/input_data/tests/test_nifti_masker.py +++ b/nilearn/input_data/tests/test_nifti_masker.py @@ -314,7 +314,7 @@ def test_compute_epi_mask(): get_data(mask4)[3:12, 3:12]) -def test_compute_gray_matter_mask(): +def test_compute_brain_mask(): # Check masker for template masking strategy img = np.random.rand(9, 9, 5) diff --git a/nilearn/masking.py b/nilearn/masking.py index bf202e0fd0..c4c8ab36c3 100644 --- a/nilearn/masking.py +++ b/nilearn/masking.py @@ -10,6 +10,7 @@ from scipy import ndimage from joblib import Parallel, delayed +from sklearn.utils import deprecated from . import _utils from .image import new_img_like from ._utils.cache_mixin import cache @@ -519,6 +520,9 @@ def compute_multi_background_mask(data_imgs, border_size=2, upper_cutoff=0.85, return mask +@deprecated("Function 'compute_gray_matter_mask' has been renamed to " + "'compute_brain_mask' and " + "'compute_gray_matter_mask' will be removed in release 0.9.") def compute_gray_matter_mask(target_img, threshold=.5, connected=True, opening=2, memory=None, verbose=0): @@ -528,20 +532,20 @@ def compute_gray_matter_mask(target_img, threshold=.5, Parameters ---------- - target_img: Niimg-like object + target_img : Niimg-like object See http://nilearn.github.io/manipulating_images/input_output.html Images used to compute the mask. 3D and 4D images are accepted. Only the shape and affine of target_img will be used here. - threshold: float, optional + threshold : float, optional The value under which the MNI template is cut off. Default value is 0.5 - connected: bool, optional + connected : bool, optional if connected is True, only the largest connected component is kept. Default is True - opening: bool or int, optional + opening : bool or int, optional if opening is True, a morphological opening is performed, to keep only large structures. If opening is an integer `n`, it is performed via `n` erosions. @@ -550,18 +554,64 @@ def compute_gray_matter_mask(target_img, threshold=.5, to 1 opening operation of order `n` followed by a closing operator of order `n`. - memory: instance of joblib.Memory or str + memory : instance of joblib.Memory or str Used to cache the function call. - verbose: int, optional + verbose : int, optional Controls the amount of verbosity: higher numbers give more messages Returns ------- - mask: nibabel.Nifti1Image + mask : nibabel.Nifti1Image The brain mask (3D image) """ + return compute_brain_mask(target_img=target_img, threshold=threshold, + connected=connected, opening=opening, + memory=memory, verbose=verbose) + + +def compute_brain_mask(target_img, threshold=.5, connected=True, + opening=2, memory=None, verbose=0): + """Compute the whole-brain mask. This mask is calculated through the + resampling of the MNI152 template mask onto the target image. + + Parameters + ---------- + target_img : Niimg-like object + See http://nilearn.github.io/manipulating_images/input_output.html + Images used to compute the mask. 3D and 4D images are accepted. + Only the shape and affine of target_img will be used here. + + threshold : float, optional + The value under which the MNI template is cut off. + Default value is 0.5 + + connected : bool, optional + if connected is True, only the largest connected component is kept. + Default is True + + opening : bool or int, optional + if opening is True, a morphological opening is performed, to keep + only large structures. + If opening is an integer `n`, it is performed via `n` erosions. + After estimation of the largest connected constituent, 2`n` closing + operations are performed followed by `n` erosions. This corresponds + to 1 opening operation of order `n` followed by a closing operator + of order `n`. + + memory : instance of joblib.Memory or str + Used to cache the function call. + + verbose : int, optional + Controls the amount of verbosity: higher numbers give + more messages + + Returns + ------- + mask : nibabel.Nifti1Image + The whole-brain mask (3D image) + """ if verbose > 0: print("Template mask computation") @@ -643,7 +693,7 @@ def compute_multi_gray_matter_mask(target_imgs, threshold=.5, See also -------- - nilearn.masking.compute_gray_matter_mask + nilearn.masking.compute_brain_mask """ if len(target_imgs) == 0: raise TypeError('An empty object - %r - was passed instead of an ' @@ -654,7 +704,7 @@ def compute_multi_gray_matter_mask(target_imgs, threshold=.5, for _ in imgs_generator: pass - mask = compute_gray_matter_mask(target_imgs[0], threshold=threshold, + mask = compute_brain_mask(target_imgs[0], threshold=threshold, connected=connected, opening=opening, memory=memory, verbose=verbose) return mask diff --git a/nilearn/regions/parcellations.py b/nilearn/regions/parcellations.py index f940a99ff5..18ad418c04 100644 --- a/nilearn/regions/parcellations.py +++ b/nilearn/regions/parcellations.py @@ -187,7 +187,7 @@ class Parcellations(MultiPCA): brain mask for your data's field of view. Depending on this value, the mask will be computed from masking.compute_background_mask, masking.compute_epi_mask or - masking.compute_gray_matter_mask. Default is 'epi'. + masking.compute_brain_mask. Default is 'epi'. mask_args: dict, optional If mask is None, these are additional parameters passed to diff --git a/nilearn/tests/test_masking.py b/nilearn/tests/test_masking.py index a144de41cc..26e33516a0 100644 --- a/nilearn/tests/test_masking.py +++ b/nilearn/tests/test_masking.py @@ -5,9 +5,9 @@ import warnings import numpy as np import pytest +import sklearn from numpy.testing import assert_array_equal -import pytest from sklearn.utils import check_random_state from nibabel import Nifti1Image @@ -15,7 +15,7 @@ from nilearn import masking from nilearn.image import get_data from nilearn.masking import (compute_epi_mask, compute_multi_epi_mask, - compute_background_mask, compute_gray_matter_mask, + compute_background_mask, compute_brain_mask, compute_multi_gray_matter_mask, unmask, _unmask_3d, _unmask_4d, intersect_masks, MaskWarning, _extrapolate_out_mask, _unmask_from_to_3d_array) @@ -99,10 +99,10 @@ def test_compute_background_mask(): assert isinstance(w[0].message, masking.MaskWarning) -def test_compute_gray_matter_mask(): +def test_compute_brain_mask(): image = Nifti1Image(np.ones((9, 9, 9)), np.eye(4)) - mask = compute_gray_matter_mask(image, threshold=-1) + mask = compute_brain_mask(image, threshold=-1) mask1 = np.zeros((9, 9, 9)) mask1[2:-2, 2:-2, 2:-2] = 1 @@ -110,18 +110,29 @@ def test_compute_gray_matter_mask(): # Check that we get a useful warning for empty masks with pytest.warns(masking.MaskWarning): - compute_gray_matter_mask(image, threshold=1) + compute_brain_mask(image, threshold=1) # Check that masks obtained from same FOV are the same img1 = Nifti1Image(np.full((9, 9, 9), np.random.rand()), np.eye(4)) img2 = Nifti1Image(np.full((9, 9, 9), np.random.rand()), np.eye(4)) - mask_img1 = compute_gray_matter_mask(img1) - mask_img2 = compute_gray_matter_mask(img2) + mask_img1 = compute_brain_mask(img1) + mask_img2 = compute_brain_mask(img2) np.testing.assert_array_equal(get_data(mask_img1), get_data(mask_img2)) +def test_deprecation_warning_compute_gray_matter_mask(): + img = Nifti1Image(np.ones((9, 9, 9)), np.eye(4)) + if distutils.version.LooseVersion(sklearn.__version__) < '0.22': + with pytest.deprecated_call(): + masking.compute_gray_matter_mask(img) + else: + with pytest.warns(FutureWarning, + match="renamed to 'compute_brain_mask'"): + masking.compute_gray_matter_mask(img) + + def test_apply_mask(): """ Test smoothing of timeseries extraction """