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

[ENH] Automatically use Nilearn's EPI mask when no explicit mask is provided #226

Merged
merged 7 commits into from
Mar 4, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions docs/approach.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,16 @@ number of echoes with "good" signal. When :math:`T_{2}^*` and :math:`S_{0}` are
calculated below, each voxel's values are only calculated from the first :math:`n`
echoes, where :math:`n` is the value for that voxel in the adaptive mask.

.. note::
``tedana`` allows users to provide their own mask. The adaptive mask will
be computed on this explicit mask, and may reduce it further based on the
data.
If a mask is not provided, ``tedana`` runs `nilearn.masking.compute_epi_mask`_
on the first echo's data to derive a mask prior to adaptive masking.
The workflow does this because the adaptive mask generation function
sometimes identifies almost the entire bounding box as "brain", and
``compute_epi_mask`` restricts analysis to a more reasonable area.

.. image:: /_static/03_adaptive_mask.png
:width: 600 px
:align: center
Expand Down Expand Up @@ -211,4 +221,5 @@ robust PCA.

.. image:: /_static/16_t1c_denoised_data_timeseries.png

.. _nilearn.masking.compute_epi_mask: https://nilearn.github.io/modules/generated/nilearn.masking.compute_epi_mask.html
.. _Power et al. (2018): http://www.pnas.org/content/early/2018/02/07/1720985115.short
18 changes: 13 additions & 5 deletions tedana/workflows/tedana.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
import numpy as np
import pandas as pd
from scipy import stats
from nilearn.masking import compute_epi_mask

from tedana.workflows.parser_utils import is_valid_file
from tedana import decay, combine, decomposition, io, model, selection, utils
Expand Down Expand Up @@ -60,9 +61,12 @@ def _get_parser():
dest='mask',
metavar='FILE',
type=lambda x: is_valid_file(parser, x),
help=('Binary mask of voxels to include in TE '
'Dependent ANAlysis. Must be in the same '
'space as `data`.'),
help=("Binary mask of voxels to include in TE "
"Dependent ANAlysis. Must be in the same "
"space as `data`. If an explicit mask is not "
"provided, then Nilearn's compute_epi_mask "
"function will be used to derive a mask "
"from the first echo's data."),
default=None)
optional.add_argument('--mix',
dest='mixm',
Expand Down Expand Up @@ -187,7 +191,9 @@ def tedana_workflow(data, tes, mask=None, mixm=None, ctab=None, manacc=None,
List of echo times associated with data in milliseconds.
mask : :obj:`str`, optional
Binary mask of voxels to include in TE Dependent ANAlysis. Must be
spatially aligned with `data`.
spatially aligned with `data`. If an explicit mask is not provided,
then Nilearn's compute_epi_mask function will be used to derive a mask
from the first echo's data.
mixm : :obj:`str`, optional
File containing mixing matrix. If not provided, ME-PCA and ME-ICA are
done.
Expand Down Expand Up @@ -293,7 +299,9 @@ def tedana_workflow(data, tes, mask=None, mixm=None, ctab=None, manacc=None,
raise IOError('Argument "ctab" must be an existing file.')

if mask is None:
LGR.info('Computing adaptive mask')
LGR.info('Computing EPI mask from first echo')
first_echo_img = io.new_nii_like(ref_img, catd[:, 0, :])
mask = compute_epi_mask(first_echo_img)
else:
# TODO: add affine check
LGR.info('Using user-defined mask')
Expand Down