Skip to content

Commit

Permalink
[ENH] Automatically use Nilearn's EPI mask when no explicit mask is p…
Browse files Browse the repository at this point in the history
…rovided (#226)

* Use compute_epi_mask.

* Remove unused function ctabsel.

* Undo function removal.

* Fix issue with z-concatenated data.

* Fix test.

* *Unfix* test.

* Add rationale for using compute_epi_mask to documentation.
  • Loading branch information
tsalo authored and emdupre committed Mar 4, 2019
1 parent 27bf65a commit e44058c
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 5 deletions.
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

0 comments on commit e44058c

Please sign in to comment.