1"""
2Understanding NiftiMasker and mask computation
3==================================================
4
5In this example, the Nifti masker is used to automatically compute a mask.
6
7* The default strategy is based on the background.
8
9* Another option is to use a template.
10
11* For raw EPI, as in resting-state or movie watching time series, we need to
12  use the 'epi' strategy of the NiftiMasker.
13
14In addition, we show here how to tweak the different parameters of the
15underlying routine that extract masks from EPI
16:func:`nilearn.masking.compute_epi_mask`.
17
18"""
19
20from nilearn.input_data import NiftiMasker
21import nilearn.image as image
22from nilearn.plotting import plot_roi, plot_epi, show
23
24###############################################################################
25# Computing a mask from the background
26###############################################################################
27#
28# The default strategy to compute a mask, eg in NiftiMasker is to try to
29# detect the background.
30#
31# With data that has already been masked, this will work well, as it lies
32# on a homogeneous background
33
34# Load Miyawaki dataset
35from nilearn import datasets
36miyawaki_dataset = datasets.fetch_miyawaki2008()
37
38# print basic information on the dataset
39print('First functional nifti image (4D) is located at: %s' %
40      miyawaki_dataset.func[0])  # 4D data
41
42miyawaki_filename = miyawaki_dataset.func[0]
43miyawaki_mean_img = image.mean_img(miyawaki_filename)
44plot_epi(miyawaki_mean_img, title='Mean EPI image')
45###############################################################################
46# A NiftiMasker with the default strategy
47masker = NiftiMasker()
48masker.fit(miyawaki_filename)
49
50# Plot the generated mask using the mask_img_ attribute
51plot_roi(masker.mask_img_, miyawaki_mean_img,
52         title="Mask from already masked data")
53
54###############################################################################
55# Plot the generated mask using the .generate_report method
56report = masker.generate_report()
57report
58
59
60###############################################################################
61# Computing a mask from raw EPI data
62###############################################################################
63#
64# From raw EPI data, there is no uniform background, and a different
65# strategy is necessary
66
67# Load movie watching based brain development fmri dataset
68dataset = datasets.fetch_development_fmri(n_subjects=1)
69epi_filename = dataset.func[0]
70
71# Restrict to 100 frames to speed up computation
72from nilearn.image import index_img
73epi_img = index_img(epi_filename, slice(0, 100))
74
75# To display the background
76mean_img = image.mean_img(epi_img)
77plot_epi(mean_img, title='Mean EPI image')
78
79###############################################################################
80# Simple mask extraction from EPI images
81# We need to specify an 'epi' mask_strategy, as this is raw EPI data
82masker = NiftiMasker(mask_strategy='epi')
83masker.fit(epi_img)
84report = masker.generate_report()
85report
86
87###############################################################################
88# Generate mask with strong opening
89#
90# We can fine-tune the outline of the mask by increasing the number of
91# opening steps (`opening=10`) using the `mask_args` argument of the
92# NiftiMasker. This effectively performs erosion and dilation
93# operations on the outer voxel layers of the mask, which can for example
94# remove remaining
95# skull parts in the image.
96masker = NiftiMasker(mask_strategy='epi', mask_args=dict(opening=10))
97masker.fit(epi_img)
98report = masker.generate_report()
99report
100
101###############################################################################
102# Generate mask with a high lower cutoff
103#
104# The NiftiMasker calls the nilearn.masking.compute_epi_mask function to
105# compute the mask from the EPI. It has two important parameters:
106# lower_cutoff and upper_cutoff. These set the grey-value bounds in which
107# the masking algorithm will search for its threshold (0 being the
108# minimum of the image and 1 the maximum). We will here increase the
109# lower cutoff to enforce selection of those voxels that appear as bright
110# in the EPI image.
111
112masker = NiftiMasker(mask_strategy='epi',
113                     mask_args=dict(upper_cutoff=.9, lower_cutoff=.8,
114                                    opening=False))
115masker.fit(epi_img)
116report = masker.generate_report()
117report
118
119###############################################################################
120# Computing the mask from the MNI template
121###############################################################################
122#
123# A mask can also be computed from the MNI template. In this case, it is
124# resampled to the target image. Three options are available:
125# 'whole-brain-template', 'gm-template', and 'wm-template' depending on whether
126# the whole-brain, gray matter, or white matter template should be used.
127
128masker = NiftiMasker(mask_strategy='whole-brain-template')
129masker.fit(epi_img)
130report = masker.generate_report()
131report
132
133###############################################################################
134# Compute and resample a mask
135###############################################################################
136#
137# NiftiMasker also allows passing parameters directly to `image.resample_img`.
138# We can specify a `target_affine`, a `target_shape`, or both.
139# For more information on these arguments,
140# see :doc:`plot_affine_transformation`.
141#
142# The NiftiMasker report allows us to see the mask before and after resampling.
143# Simply hover over the report to see the mask from the original image.
144
145import numpy as np
146
147masker = NiftiMasker(mask_strategy='epi', target_affine=np.eye(3) * 8)
148masker.fit(epi_img)
149report = masker.generate_report()
150report
151
152###############################################################################
153# After mask computation: extracting time series
154###############################################################################
155#
156# Extract time series
157
158# trended vs detrended
159trended = NiftiMasker(mask_strategy='epi')
160detrended = NiftiMasker(mask_strategy='epi', detrend=True)
161trended_data = trended.fit_transform(epi_img)
162detrended_data = detrended.fit_transform(epi_img)
163
164# The timeseries are numpy arrays, so we can manipulate them with numpy
165
166print("Trended: mean %.2f, std %.2f" %
167      (np.mean(trended_data), np.std(trended_data)))
168print("Detrended: mean %.2f, std %.2f" %
169      (np.mean(detrended_data), np.std(detrended_data)))
170
171show()
172