Understanding NiftiMasker and mask computation

In this example, the NiftiMasker is used to automatically compute a mask.

  • The default strategy is based on the background.

  • Another option is to use a template.

  • For raw EPI, as in resting-state or movie watching time series, we need to use the ‘epi’ strategy of the NiftiMasker.

In addition, we show here how to tweak the different parameters of the underlying routine that extract masks from EPI compute_epi_mask.

Warning

If you are using Nilearn with a version older than 0.9.0, then you should either upgrade your version or import maskers from the input_data module instead of the maskers module.

That is, you should manually replace in the following example all occurrences of:

from nilearn.maskers import NiftiMasker

with:

from nilearn.input_data import NiftiMasker

Computing a mask from the background

The default strategy to compute a mask, like the NiftiMasker, is to try to detect the background.

With data that has already been masked this should work well, as it relies on a homogeneous background

Fetch the dataset

We fetch do some basic visualization of the image we will be using.

from nilearn.datasets import fetch_miyawaki2008
from nilearn.image import mean_img
from nilearn.plotting import plot_epi, show

miyawaki_dataset = fetch_miyawaki2008()
print(
    "First functional nifti image (4D) is located "
    f"at: {miyawaki_dataset.func[0]}"
)

miyawaki_filename = miyawaki_dataset.func[0]
miyawaki_mean_img = mean_img(miyawaki_filename)

plot_epi(miyawaki_mean_img, title="Mean EPI image")

show()
plot mask computation
[fetch_miyawaki2008] Dataset found in /home/runner/nilearn_data/miyawaki2008
First functional nifti image (4D) is located at: /home/runner/nilearn_data/miyawaki2008/func/data_figure_run01.nii.gz
/home/runner/work/nilearn/nilearn/examples/06_manipulating_images/plot_mask_computation.py:54: UserWarning: You are using the 'agg' matplotlib backend that is non-interactive.
No figure will be plotted when calling matplotlib.pyplot.show() or nilearn.plotting.show().
You can fix this by installing a different backend: for example via
        pip install PyQt6
  show()

A NiftiMasker with the default strategy

Let’s use the NiftiMasker with its defaults parameters.

from nilearn.maskers import NiftiMasker

masker = NiftiMasker(verbose=1)

Note

When viewing an Nilearn estimator in a notebook (or more generally on an HTML page like here) you get an expandable ‘Parameters’ section where the parameters that have different values from their default are highlighted in orange. If you are using a version of scikit-learn >= 1.8.0 you will also get access to the ‘docstring’ description of each parameter.

NiftiMasker(verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.


[NiftiMasker.fit] Loading data from
'/home/runner/nilearn_data/miyawaki2008/func/data_figure_run01.nii.gz'
[NiftiMasker.fit] Computing mask
[NiftiMasker.fit] Resampling mask
[NiftiMasker.fit] Finished fit
NiftiMasker(verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.


Note

You can also note that after fitting, the HTML representation of the estimator looks different than before before fitting.

NiftiMasker(verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.


Visualize the mask

We can quickly get an idea about the estimated mask for this functional image by plotting the mask.

We get the estimated mask from the mask_img_ attribute of the masker: the final _ of this attribute name means it was generated by the fit method.

We can then plot it using the plot_roi function with the mean functional image as background.

from nilearn.plotting import plot_roi

plot_roi(
    masker.mask_img_, miyawaki_mean_img, title="Mask from already masked data"
)

# display the image
show()
plot mask computation
/home/runner/work/nilearn/nilearn/examples/06_manipulating_images/plot_mask_computation.py:104: UserWarning: You are using the 'agg' matplotlib backend that is non-interactive.
No figure will be plotted when calling matplotlib.pyplot.show() or nilearn.plotting.show().
You can fix this by installing a different backend: for example via
        pip install PyQt6
  show()

View the generated mask

More information can be obtained about the masker and its mask by generating a masker report. This can be done using the generate_report method.

Note

The generated report can be:

  • displayed in a Notebook,

  • opened in a browser using the .open_in_browser() method,

  • or saved to a file using the .save_as_html(output_filepath) method.

NiftiMasker Applying a mask to extract time-series from Niimg-like objects. NiftiMasker is useful when preprocessing (detrending, standardization, resampling, etc.) of in-mask :term:`voxels` is necessary. Use case: working with time series of :term:`resting-state` or task maps.

No image provided.

This report shows the input Nifti image overlaid with the outlines of the mask (in green). We recommend to inspect the report for the overlap between the mask and its input image.

The mask includes 5438 voxels (4.4 %) of the image.

NiftiMasker(verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

This report was generated based on information provided at instantiation and fit time. Note that the masker can potentially perform resampling at transform time.



Computing a mask from raw EPI data

From raw EPI data, there is no uniform background, and a different strategy is necessary

Fetch the dataset

Here we getch the movie watching based brain development fMRI dataset and once again do some basic visualization of the data.

Here we only work with the first 100 volumes of the image to speed up computation.

from nilearn.datasets import fetch_development_fmri
from nilearn.image import index_img

dataset = fetch_development_fmri(n_subjects=1)
epi_filename = dataset.func[0]

epi_img = index_img(epi_filename, slice(0, 100))

mean_func_img = mean_img(epi_img)

plot_epi(mean_func_img, title="Mean EPI image")

show()
plot mask computation
[fetch_development_fmri] Dataset found in
/home/runner/nilearn_data/development_fmri
[fetch_development_fmri] Dataset found in
/home/runner/nilearn_data/development_fmri/development_fmri
[fetch_development_fmri] Dataset found in
/home/runner/nilearn_data/development_fmri/development_fmri
/home/runner/work/nilearn/nilearn/examples/06_manipulating_images/plot_mask_computation.py:151: UserWarning: You are using the 'agg' matplotlib backend that is non-interactive.
No figure will be plotted when calling matplotlib.pyplot.show() or nilearn.plotting.show().
You can fix this by installing a different backend: for example via
        pip install PyQt6
  show()

Simple mask extraction from EPI images

We need to specify an 'epi' mask_strategy, as this is raw EPI data

masker = NiftiMasker(mask_strategy="epi", verbose=1)
masker.fit(epi_img)
report = masker.generate_report()
report
[NiftiMasker.fit] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.fit] Computing mask
[NiftiMasker.fit] Resampling mask
[NiftiMasker.fit] Finished fit

NiftiMasker Applying a mask to extract time-series from Niimg-like objects. NiftiMasker is useful when preprocessing (detrending, standardization, resampling, etc.) of in-mask :term:`voxels` is necessary. Use case: working with time series of :term:`resting-state` or task maps.

No image provided.

This report shows the input Nifti image overlaid with the outlines of the mask (in green). We recommend to inspect the report for the overlap between the mask and its input image.

The mask includes 24428 voxels (16.6 %) of the image.

NiftiMasker(mask_strategy='epi', verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

This report was generated based on information provided at instantiation and fit time. Note that the masker can potentially perform resampling at transform time.



Generate mask with strong opening

We can fine-tune the outline of the mask by increasing the number of opening steps (opening=10) using the mask_args argument of the NiftiMasker. This effectively performs erosion and dilation operations on the outer voxel layers of the mask, which can for example remove remaining skull parts in the image.

masker = NiftiMasker(mask_strategy="epi", mask_args={"opening": 10}, verbose=1)
masker.fit(epi_img)
report = masker.generate_report()
report
[NiftiMasker.fit] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.fit] Computing mask
[NiftiMasker.fit] Resampling mask
[NiftiMasker.fit] Finished fit

NiftiMasker Applying a mask to extract time-series from Niimg-like objects. NiftiMasker is useful when preprocessing (detrending, standardization, resampling, etc.) of in-mask :term:`voxels` is necessary. Use case: working with time series of :term:`resting-state` or task maps.

No image provided.

This report shows the input Nifti image overlaid with the outlines of the mask (in green). We recommend to inspect the report for the overlap between the mask and its input image.

The mask includes 11617 voxels (7.9 %) of the image.

NiftiMasker(mask_args={'opening': 10}, mask_strategy='epi', verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

This report was generated based on information provided at instantiation and fit time. Note that the masker can potentially perform resampling at transform time.



Generate mask with a high lower cutoff

The NiftiMasker calls the nilearn.masking.compute_epi_mask function to compute the mask from the EPI. It has two important parameters: lower_cutoff and upper_cutoff. These set the grey-value bounds in which the masking algorithm will search for its threshold (0 being the minimum of the image and 1 the maximum). We will here increase the lower cutoff to enforce selection of those voxels that appear as bright in the EPI image.

masker = NiftiMasker(
    mask_strategy="epi",
    mask_args={"upper_cutoff": 0.9, "lower_cutoff": 0.8, "opening": False},
    verbose=1,
)
masker.fit(epi_img)
report = masker.generate_report()
report
[NiftiMasker.fit] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.fit] Computing mask
[NiftiMasker.fit] Resampling mask
[NiftiMasker.fit] Finished fit

NiftiMasker Applying a mask to extract time-series from Niimg-like objects. NiftiMasker is useful when preprocessing (detrending, standardization, resampling, etc.) of in-mask :term:`voxels` is necessary. Use case: working with time series of :term:`resting-state` or task maps.

No image provided.

This report shows the input Nifti image overlaid with the outlines of the mask (in green). We recommend to inspect the report for the overlap between the mask and its input image.

The mask includes 24809 voxels (16.8 %) of the image.

NiftiMasker(mask_args={'lower_cutoff': 0.8, 'opening': False,
                       'upper_cutoff': 0.9},
            mask_strategy='epi', verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

This report was generated based on information provided at instantiation and fit time. Note that the masker can potentially perform resampling at transform time.



Computing the mask from the MNI template

A mask can also be computed from the MNI template. In this case, it is resampled to the target image. Three options are available: 'whole-brain-template', 'gm-template', and 'wm-template' depending on whether the whole-brain, gray matter, or white matter template should be used.

masker = NiftiMasker(mask_strategy="whole-brain-template", verbose=1)
masker.fit(epi_img)
report = masker.generate_report()
report
[NiftiMasker.fit] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.fit] Computing mask
[NiftiMasker.fit] Resampling mask
[NiftiMasker.fit] Finished fit

NiftiMasker Applying a mask to extract time-series from Niimg-like objects. NiftiMasker is useful when preprocessing (detrending, standardization, resampling, etc.) of in-mask :term:`voxels` is necessary. Use case: working with time series of :term:`resting-state` or task maps.

No image provided.

This report shows the input Nifti image overlaid with the outlines of the mask (in green). We recommend to inspect the report for the overlap between the mask and its input image.

The mask includes 21781 voxels (14.8 %) of the image.

NiftiMasker(mask_strategy='whole-brain-template', verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

This report was generated based on information provided at instantiation and fit time. Note that the masker can potentially perform resampling at transform time.



Compute and resample a mask

NiftiMasker also allows passing parameters directly to resample_img. We can specify a target_affine, a target_shape, or both. For more information on these arguments, see Visualization of affine resamplings.

The NiftiMasker report allows us to see the mask before and after resampling. Simply hover over the report to see the mask from the original image.

import numpy as np

masker = NiftiMasker(
    mask_strategy="epi", target_affine=np.eye(3) * 8, verbose=1
)
masker.fit(epi_img)
report = masker.generate_report()
report
[NiftiMasker.fit] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.fit] Computing mask
[NiftiMasker.fit] Resampling mask
[NiftiMasker.fit] Finished fit

NiftiMasker Applying a mask to extract time-series from Niimg-like objects. NiftiMasker is useful when preprocessing (detrending, standardization, resampling, etc.) of in-mask :term:`voxels` is necessary. Use case: working with time series of :term:`resting-state` or task maps.

No image provided.
No overlay found.

This report shows the input Nifti image overlaid with the outlines of the mask (in green). We recommend to inspect the report for the overlap between the mask and its input image. To see the input Nifti image before resampling, hover over the displayed image.

The mask includes 3040 voxels (15.0 %) of the image.

NiftiMasker(mask_strategy='epi',
            target_affine=array([[8., 0., 0.],
       [0., 8., 0.],
       [0., 0., 8.]]),
            verbose=1)
In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.

This report was generated based on information provided at instantiation and fit time. Note that the masker can potentially perform resampling at transform time.



After mask computation: extracting time series

We extract time series detrended and non-detrended.

trended_data = NiftiMasker(mask_strategy="epi", verbose=1).fit_transform(
    epi_img
)
detrended_data = NiftiMasker(
    mask_strategy="epi", detrend=True, verbose=1
).fit_transform(epi_img)
[NiftiMasker.wrapped] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.wrapped] Computing mask
[NiftiMasker.wrapped] Resampling mask
[NiftiMasker.wrapped] Finished fit
[NiftiMasker.wrapped] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.wrapped] Extracting region signals
[NiftiMasker.wrapped] Cleaning extracted signals
[NiftiMasker.wrapped] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.wrapped] Computing mask
[NiftiMasker.wrapped] Resampling mask
[NiftiMasker.wrapped] Finished fit
[NiftiMasker.wrapped] Loading data from <nibabel.nifti1.Nifti1Image object at
0x7f7f3ee62110>
[NiftiMasker.wrapped] Extracting region signals
[NiftiMasker.wrapped] Cleaning extracted signals

Once extracted, the timeseries are numpy arrays, so we can manipulate them with numpy

print(
    f"Trended: mean {np.mean(trended_data):.2f}, "
    f"std {np.std(trended_data):.2f}"
)
print(
    f"Detrended: mean {np.mean(detrended_data):.2f}, "
    f"std {np.std(detrended_data):.2f}"
)
Trended: mean 552.82, std 168.28
Detrended: mean -0.00, std 5.88

Total running time of the script: (0 minutes 19.998 seconds)

Estimated memory usage: 479 MB

Gallery generated by Sphinx-Gallery