Skip to content

Commit

Permalink
[DOC] Add docstring to fit_loglinear (#646)
Browse files Browse the repository at this point in the history
* Add docstring for fit_loglinear.

* Fix fit_decay docstring.

* Improve fit_monoexponential docstring.
  • Loading branch information
tsalo committed Jan 15, 2021
1 parent 5369e1d commit 4ecdf4b
Showing 1 changed file with 49 additions and 16 deletions.
65 changes: 49 additions & 16 deletions tedana/decay.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,20 @@ def fit_monoexponential(data_cat, echo_times, adaptive_mask):
----------
data_cat : (S x E x T) :obj:`numpy.ndarray`
Multi-echo data.
echo_times
echo_times : (E,) array_like
Echo times in milliseconds.
adaptive_mask
adaptive_mask : (S,) :obj:`numpy.ndarray`
Array where each value indicates the number of echoes with good signal
for that voxel.
Returns
-------
t2s_limited, s0_limited, t2s_full, s0_full
t2s_limited, s0_limited, t2s_full, s0_full : (S,) :obj:`numpy.ndarray`
T2* and S0 estimate maps.
Notes
-----
This method is slower, but more accurate, than the log-linear approach.
"""
RepLGR.info("A monoexponential model was fit to the data at each voxel "
"using nonlinear model fitting in order to estimate T2* and S0 "
Expand Down Expand Up @@ -156,7 +161,42 @@ def fit_monoexponential(data_cat, echo_times, adaptive_mask):


def fit_loglinear(data_cat, echo_times, adaptive_mask, report=True):
"""
"""Fit monoexponential decay model with log-linear regression.
The monoexponential decay function is fitted to all values for a given
voxel across TRs, per TE, to estimate voxel-wise :math:`S_0` and :math:`T_2^*`.
At a given voxel, only those echoes with "good signal", as indicated by the
value of the voxel in the adaptive mask, are used.
Therefore, for a voxel with an adaptive mask value of five, the first five
echoes would be used to estimate T2* and S0.
Parameters
----------
data_cat : (S x E x T) :obj:`numpy.ndarray`
Multi-echo data. S is samples, E is echoes, and T is timepoints.
echo_times : (E,) array_like
Echo times in milliseconds.
adaptive_mask : (S,) :obj:`numpy.ndarray`
Array where each value indicates the number of echoes with good signal
for that voxel.
report : :obj:`bool`, optional
Whether to log a description of this step or not. Default is True.
Returns
-------
t2s_limited, s0_limited, t2s_full, s0_full: (S,) :obj:`numpy.ndarray`
T2* and S0 estimate maps.
Notes
-----
The approach used in this function involves transforming the raw signal values
(:math:`log(|data| + 1)`) and then fitting a line to the transformed data using
ordinary least squares.
This results in two parameter estimates: one for the slope and one for the intercept.
The slope estimate is inverted (i.e., 1 / slope) to get :math:`T_2^*`,
while the intercept estimate is exponentiated (i.e., e^intercept) to get :math:`S_0`.
This method is faster, but less accurate, than the nonlinear approach.
"""
if report:
RepLGR.info("A monoexponential model was fit to the data at each voxel "
Expand Down Expand Up @@ -254,18 +294,11 @@ def fit_decay(data, tes, mask, adaptive_mask, fittype):
Notes
-----
1. Fit monoexponential decay function to all values for a given voxel
across TRs, per TE, to estimate voxel-wise :math:`S_0` and
:math:`T_2^*`:
.. math::
S(TE) = S_0 * exp(-R_2^* * TE)
T_2^* = 1 / R_2^*
2. Replace infinite values in :math:`T_2^*` map with 500 and NaN values
in :math:`S_0` map with 0.
3. Generate limited :math:`T_2^*` and :math:`S_0` maps by doing something.
This function replaces infinite values in the :math:`T_2^*` map with 500 and
:math:`T_2^*` values less than or equal to zero with 1.
Additionally, very small :math:`T_2^*` values above zero are replaced with a floor
value to prevent zero-division errors later on in the workflow.
It also replaces NaN values in the :math:`S_0` map with 0.
"""
if data.shape[1] != len(tes):
raise ValueError('Second dimension of data ({0}) does not match number '
Expand Down

0 comments on commit 4ecdf4b

Please sign in to comment.