Skip to content

Commit

Permalink
Merge pull request #419 from dowdlelt/doc_improvements
Browse files Browse the repository at this point in the history
[DOC] Improving clarity of docs and figures

It is beautiful. Thanks team capybara
  • Loading branch information
dowdlelt authored Nov 8, 2019
2 parents f7aa600 + 33e4675 commit 9f62169
Show file tree
Hide file tree
Showing 13 changed files with 562 additions and 255 deletions.
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -104,4 +104,4 @@ ENV/
.mypy_cache/

# vscode
.vscode
.vscode
Binary file added docs/_static/physics_kundu_2017_TE_dependence.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
135 changes: 103 additions & 32 deletions docs/approach.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
Processing pipeline details
===========================
The tedana pipeline
===================

``tedana`` works by decomposing multi-echo BOLD data via PCA and ICA.
``tedana`` works by decomposing multi-echo BOLD data via priniciple component analysis (PCA)
and independent component analysis (ICA).
The resulting components are then analyzed to determine whether they are
TE-dependent or -independent.
TE-dependent components are classified as BOLD, while TE-independent components
Expand All @@ -23,7 +24,7 @@ Multi-echo data
```````````````

Here are the echo-specific time series for a single voxel in an example
resting-state scan with 5 echoes.
resting-state scan with 8 echoes.

.. image:: /_static/a01_echo_timeseries.png

Expand All @@ -45,6 +46,10 @@ 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.

`Adaptive mask code`_

.. _Adaptive mask code: https://tedana.readthedocs.io/en/latest/generated/tedana.utils.make_adaptive_mask.html#tedana.utils.make_adaptive_mask

.. note::
``tedana`` allows users to provide their own mask.
The adaptive mask will be computed on this explicit mask, and may reduce
Expand All @@ -62,23 +67,39 @@ value for that voxel in the adaptive mask.
Monoexponential decay model fit
```````````````````````````````
The next step is to fit a monoexponential decay model to the data in order to
estimate voxel-wise :math:`T_{2}^*` and :math:`S_0`.
estimate voxel-wise :math:`T_{2}^*` and :math:`S_0`.
:math:`S_0` corresponds to the total signal in each voxel before decay and can reflect coil sensivity.
:math:`T_{2}^*` corresponds to the rate at which a voxel decays over time, which
is related to signal dropout and BOLD sensitivity.
Estimates of the parameters are saved as **t2sv.nii.gz** and **s0v.nii.gz**.

While :math:`T_{2}^*` and :math:`S_0` in fact fluctuate over time, estimating
them on a volume-by-volume basis with only a small number of echoes is not
feasible (i.e., the estimates would be extremely noisy).
As such, we estimate average :math:`T_{2}^*` and :math:`S_0` maps and use those
throughout the workflow.

In order to make it easier to fit the decay model to the data, ``tedana``
transforms the data.
transforms the data by default.
The BOLD data are transformed as :math:`log(|S|+1)`, where :math:`S` is the BOLD signal.
The echo times are also multiplied by -1.

`Decay model fit code`_

.. _Decay model fit code: https://tedana.readthedocs.io/en/latest/generated/tedana.decay.fit_decay.html#tedana.decay.fit_decay


.. note::
It is now possible to do a nonlinear monoexponential fit to the original, untransformed
data values by specifiying ``--fittype curvefit``.
This method is slightly more computationally demanding but may obtain more
accurate fits.

.. image:: /_static/a04_echo_log_value_distributions.png

A simple line can then be fit to the transformed data with linear regression.
For the sake of this introduction, we can assume that the example voxel has
good signal in all five echoes (i.e., the adaptive mask has a value of 5 at
good signal in all eight echoes (i.e., the adaptive mask has a value of 8 at
this voxel), so the line is fit to all available data.

.. note::
Expand Down Expand Up @@ -128,13 +149,21 @@ For the example voxel, the resulting weights are:
:width: 400 px
:align: center

These normalized weights are then used to compute a weighted average that takes advantage
of the higher signal in earlier echoes and the heigher sensitivty at later echoes.
The distribution of values for the optimally combined data lands somewhere
between the distributions for other echoes.

.. image:: /_static/a09_optimal_combination_value_distributions.png

The time series for the optimally combined data also looks like a combination
of the other echoes (which it is).
of the other echoes (which it is).
This optimally combined data is written out as **ts_OC.nii.gz**

`Optimal combination code`_

.. _Optimal combination code: https://tedana.readthedocs.io/en/latest/generated/tedana.combine.make_optcom.html#tedana.combine.make_optcom


.. image:: /_static/a10_optimal_combination_timeseries.png

Expand All @@ -149,14 +178,30 @@ of the other echoes (which it is).
We do, however, make it accessible as an alternative combination method
in the t2smap workflow.

Denoising
`````````
The next step is an attempt to remove noise from the data.
This process can be
broadly seperated into three steps: **decomposition**, **metric calculation** and
**component selection**.
Decomposition reduces the dimensionality of the
optimally combined data using `Principal Components Analysis (PCA)`_ and then an `Independent Components Analysis (ICA)`_.
Metrics which highlights the
TE-dependence or indepence are derived from these components.
Component selection
uses these metrics in order to identify components that should be kept in the data
or discarded.
Unwanted components are then removed from the optimally combined data
to produce the denoised data output.

TEDPCA
``````
The next step is to dimensionally reduce the data with TE-dependent principal
components analysis (PCA).
The goal of this step is to make it easier for the later ICA decomposition to converge.
Dimensionality reduction is a common step prior to ICA.
TEDPCA applies PCA to the optimally combined data in order to decompose it into component maps and
time series.
time series (saved as **mepca_mix.1D**).
Here we can see time series for some example components (we don't really care about the maps):

.. image:: /_static/a11_pca_component_timeseries.png
Expand All @@ -165,48 +210,58 @@ These components are subjected to component selection, the specifics of which
vary according to algorithm.

In the simplest approach, ``tedana`` uses Minka’s MLE to estimate the
dimensionality of the data, which disregards low-variance components.
dimensionality of the data, which disregards low-variance components (the `mle` option in for `--tedpca`).

A more complicated approach involves applying a decision tree to identify and
A more complicated approach involves applying a decision tree (similar to the
decision tree described in the TEDICA section below) to identify and
discard PCA components which, in addition to not explaining much variance,
are also not significantly TE-dependent (i.e., have low Kappa) or
TE-independent (i.e., have low Rho).

.. note::
This process (also performed in TEDICA) can be broadly separated into three
steps: decomposition, metric calculation, and component selection.
Decomposition identifies components in the data.
Metric calculation derives relevant summary statistics for each component.
Component selection uses the summary statistics to identify components that
should be kept or discarded.
TE-independent (i.e., have low Rho).
These approaches can be accessed using either the `kundu` or `kundu_stabilize`
options for the `--tedpca` flag.
For a more thorough explanation of this approach, consider the supplemental information
in `Kundu et al (2013)`_

After component selection is performed, the retained components and their
associated betas are used to reconstruct the optimally combined data, resulting
in a dimensionally reduced version of the dataset.
in a dimensionally reduced version of the dataset which is then used in the `TEDICA` step.

.. image:: /_static/a12_pca_reduced_data.png

`TEDPCA code`_

.. _TEDPCA code: https://tedana.readthedocs.io/en/latest/generated/tedana.decomposition.tedpca.html#tedana.decomposition.tedpca


TEDICA
``````
Next, ``tedana`` applies TE-dependent independent components analysis (ICA) in
order to identify and remove TE-independent (i.e., non-BOLD noise) components.
The dimensionally reduced optimally combined data are first subjected to ICA in
order to fit a mixing matrix to the whitened data.
order to fit a mixing matrix to the whitened data.
This generates a number of
independent timeseries (saved as **meica_mix.1D**), as well as beta maps which show
the spatial loading of these components on the brain (**betas_OC.nii.gz**).

.. image:: /_static/a13_ica_component_timeseries.png

Linear regression is used to fit the component time series to each voxel in each
echo from the original, echo-specific data.
This way, low-variance information (originally discarded by TEDPCA) is retained
in the data, but is ignored by the TEDICA process.
This results in echo- and voxel-specific betas for each of the components.

TE-dependence (:math:`R_2`) and TE-independence (:math:`S_0`) models can then
of the original, echo-specific data.
This results in echo- and voxel-specific
betas for each of the components.
The beta values from the linear regression
can be used to determine how the fluctutations (in each component timeseries) change
across the echo times.

TE-dependence (:math:`R_2` or :math:`1/T_{2}^*`) and TE-independence (:math:`S_0`) models can then
be fit to these betas.
For more information on how these models are estimated, see :ref:`dependence models`.
These models allow calculation of F-statistics for the :math:`R_2` and :math:`S_0`
models (referred to as :math:`\kappa` and :math:`\rho`, respectively).

The grey lines show how beta values (Parameter Estimates) change over time. Refer the the
`physics section`_ :math:`{\Delta}{S_0}` for more information about the :math:`S_0` and :math:`T_2^*` models.

.. image:: /_static/a14_te_dependence_models_component_0.png

.. image:: /_static/a14_te_dependence_models_component_1.png
Expand All @@ -215,11 +270,20 @@ models (referred to as :math:`\kappa` and :math:`\rho`, respectively).

A decision tree is applied to :math:`\kappa`, :math:`\rho`, and other metrics in order to
classify ICA components as TE-dependent (BOLD signal), TE-independent
(non-BOLD noise), or neither (to be ignored).
(non-BOLD noise), or neither (to be ignored).
These classifications are saved in
`comp_table_ica.txt`.
The actual decision tree is dependent on the component selection algorithm employed.
``tedana`` includes two options: `kundu_v2_5` (which uses hardcoded thresholds
applied to each of the metrics) and `kundu_v3_2` (which trains a classifier to
select components).
``tedana`` includes the option `kundu` (which uses hardcoded thresholds
applied to each of the metrics).

Components that are classified as noise are projected out of the optimally combined data,
yielding a denoised timeseries, which is saved as `dn_ts_OC.nii.gz`.

`TEDICA code`_

.. _TEDICA code: https://tedana.readthedocs.io/en/latest/generated/tedana.decomposition.tedica.html#tedana.decomposition.tedica


.. image:: /_static/a15_denoised_data_timeseries.png

Expand All @@ -237,8 +301,15 @@ regression (GSR), T1c-GSR, anatomical CompCor, Go Decomposition (GODEC), and
robust PCA.
Currently, ``tedana`` implements GSR and T1c-GSR.

`Global signal control code`_

.. _Global signal control code: https://tedana.readthedocs.io/en/latest/generated/tedana.gscontrol.gscontrol_mmix.html#tedana.gscontrol.gscontrol_mmix

.. image:: /_static/a16_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
.. _Poser et al., 2006: https://onlinelibrary.wiley.com/doi/full/10.1002/mrm.20900

.. _physics section: https://tedana.readthedocs.io/en/latest/multi_echo.html
.. _Kundu et al (2013): https://www.ncbi.nlm.nih.gov/pubmed/24038744
3 changes: 2 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@
'sphinx.ext.todo',
'numpydoc',
'sphinx.ext.ifconfig',
'sphinx.ext.linkcode']
'sphinx.ext.linkcode',
'matplotlib.sphinxext.plot_directive']

import sphinx
from distutils.version import LooseVersion
Expand Down
Loading

0 comments on commit 9f62169

Please sign in to comment.