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

[DOC] Add docstrings for some bigger private functions in load_confounds. #3863

Merged
merged 11 commits into from
Aug 10, 2023
137 changes: 119 additions & 18 deletions nilearn/interfaces/fmriprep/load_confounds.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,19 @@


def _check_strategy(strategy):
"""Ensure the denoising strategies are valid."""
"""Ensure the denoising strategies combinations are valid.

Parameters
----------
strategy : :obj:`tuple` or :obj:`list` of :obj:`str`.
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

Raises
------
ValueError
If any of the confounds specified in the strategy are not supported,
or the combination of the strategies are not valid.
"""
if (not isinstance(strategy, tuple)) and (not isinstance(strategy, list)):
raise ValueError(
"strategy needs to be a tuple or list of strings"
Expand Down Expand Up @@ -110,7 +122,8 @@ def load_confounds(

Parameters
----------
img_files : path to processed image files, optionally as a list.
img_files : :obj:`str`, path to processed image files, \
optionally as a :obj:`list` of :obj:`str`.
htwangtw marked this conversation as resolved.
Show resolved Hide resolved
Processed nii.gz/dtseries.nii/func.gii file reside in a
:term:`fMRIPrep` generated functional derivative directory (i.e.The
associated confound files should be in the same directory as the image
Expand All @@ -122,7 +135,7 @@ def load_confounds(
- `func.gii`: list of a pair of paths to files, optionally as a list
of lists.

strategy : tuple or list of strings.
strategy : :obj:`tuple` or :obj:`list` of :obj:`str`.
Default ("motion", "high_pass", "wm_csf")
The type of noise components to include.

Expand Down Expand Up @@ -157,7 +170,7 @@ def load_confounds(
Non-steady-state volumes will always be checked. There's no need to
supply this component to the strategy.

motion : {'basic', 'power2', 'derivatives', 'full'}
motion : :obj:`str`, {'basic', 'power2', 'derivatives', 'full'}
htwangtw marked this conversation as resolved.
Show resolved Hide resolved
Type of confounds extracted from head motion estimates.

- "basic" translation/rotation (6 parameters)
Expand All @@ -166,7 +179,7 @@ def load_confounds(
- "full" translation/rotation + derivatives + quadratic terms + power2d
derivatives (24 parameters)

wm_csf : {'basic', 'power2', 'derivatives', 'full'}
wm_csf : :obj:`str`, {'basic', 'power2', 'derivatives', 'full'}
htwangtw marked this conversation as resolved.
Show resolved Hide resolved
Type of confounds extracted from masks of white matter and
cerebrospinal fluids.

Expand All @@ -176,7 +189,7 @@ def load_confounds(
- "full" averages + derivatives + quadratic terms + power2d derivatives
(8 parameters)

global_signal : {'basic', 'power2', 'derivatives', 'full'}
global_signal : :obj:`str`, {'basic', 'power2', 'derivatives', 'full'}
htwangtw marked this conversation as resolved.
Show resolved Hide resolved
Type of confounds extracted from the global signal.

- "basic" just the global signal (1 parameter)
Expand All @@ -185,25 +198,25 @@ def load_confounds(
- "full" global signal + derivatives + quadratic terms + power2d
derivatives (4 parameters)

scrub : int, default 5
scrub : :obj:`int`, default 5
After accounting for time frames with excessive motion, further remove
segments shorter than the given number. The default value is 5
ymzayek marked this conversation as resolved.
Show resolved Hide resolved
(referred as full scrubbing in :footcite:`Power2014`). When the value
is 0, temove time frames based on excessive framewise displacement and
DVARS only. One-hot encoding vectors are added as regressors for each
scrubbed frame.

fd_threshold : float, default 0.2
fd_threshold : :obj:`float`, default 0.2
Framewise displacement threshold for scrub (default = 0.2 mm)
htwangtw marked this conversation as resolved.
Show resolved Hide resolved

std_dvars_threshold : float, default 3
std_dvars_threshold : :obj:`float`, default 3
ymzayek marked this conversation as resolved.
Show resolved Hide resolved
Standardized DVARS threshold for scrub (default = 3).
DVARs is defined as root mean squared intensity difference of volume N
to volume N+1 :footcite:`Power2012`. D referring to temporal derivative
of timecourses, VARS referring to root mean squared variance over
voxels.

compcor : {'anat_combined', 'anat_separated', 'temporal',\
compcor : :obj:`str`, {'anat_combined', 'anat_separated', 'temporal',\
'temporal_anat_combined', 'temporal_anat_separated'}
ymzayek marked this conversation as resolved.
Show resolved Hide resolved

.. warning::
Expand All @@ -221,20 +234,20 @@ def load_confounds(
- "temporal_anat_separated" components of "temporal" and
"anat_separated"

n_compcor : "all" or int, default "all"
n_compcor : :obj:`str` "all" or :obj:`int`, default "all"
htwangtw marked this conversation as resolved.
Show resolved Hide resolved
The number of noise components to be extracted.
For acompcor_combined=False, and/or compcor="full", this is the number
of components per mask.
"all": select all components (50% variance explained by
:term:`fMRIPrep` defaults)

ica_aroma : {'full', 'basic'}
ica_aroma : :obj:`str`, {'full', 'basic'}
ymzayek marked this conversation as resolved.
Show resolved Hide resolved

- "full": use :term:`fMRIPrep` output
`~desc-smoothAROMAnonaggr_bold.nii.gz`.
- "basic": use noise independent components only.

demean : boolean, default True
demean : :obj:`bool`, default True
If True, the confounds are standardized to a zero mean (over time).
When using :class:`nilearn.maskers.NiftiMasker` with default
parameters, the recommended option is True.
Expand All @@ -245,12 +258,14 @@ def load_confounds(

Returns
-------
confounds : pandas.DataFrame, or list of
confounds : :class:`pandas.DataFrame`, or :obj:`list` of \
:class:`pandas.DataFrame`
A reduced version of :term:`fMRIPrep` confounds based on selected
strategy and flags.
The columns contains the labels of the regressors.

sample_mask : None, numpy.ndarray, or list of
sample_mask : None, :class:`numpy.ndarray` or, :obj:`list` of \
:class:`numpy.ndarray` or None
When no volumns require removal, the value is None.
Otherwise, shape: (number of scans - number of volumes removed, )
The index of the niimgs along time/fourth dimension for valid volumes
Expand Down Expand Up @@ -315,7 +330,33 @@ def load_confounds(
def _load_confounds_for_single_image_file(
image_file, strategy, demean, **kwargs
):
"""Load confounds for a single image file."""
"""Load confounds for a single image file.

Parameters
----------
image_file : :obj:`str`
Path to processed image file.

strategy : :obj:`tuple` or :obj:`list` of :obj:`str`.
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

demean : :obj:`bool`, default True
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

kwargs : :obj:`dict`
Extra relevant parameters for the given `strategy`.
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

Returns
-------
sample_mask : None, :class:`numpy.ndarray` or, :obj:`list` of \
:class:`numpy.ndarray` or None
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

confounds : :class:`pandas.DataFrame`, or :obj:`list` of \
:class:`pandas.DataFrame`
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.
"""
# Check for ica_aroma in strategy, this will change the required image_file
flag_full_aroma = ("ica_aroma" in strategy) and (
kwargs.get("ica_aroma") == "full"
Expand All @@ -338,7 +379,37 @@ def _load_confounds_for_single_image_file(
def _load_single_confounds_file(
confounds_file, strategy, demean=True, confounds_json_file=None, **kwargs
):
"""Load and extract specified confounds from the confounds file."""
"""Load and extract specified confounds from the confounds file.

Parameters
----------
confounds_file : :obj:`str`
Path to confounds file.

strategy : :obj:`tuple` or :obj:`list` of :obj:`str`.
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

demean : :obj:`bool`, default True
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

confounds_json_file : :obj:`str`, default None
Path to confounds json file.

kwargs : :obj:`dict`
Extra relevant parameters for the given `strategy`.
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

Returns
-------
confounds : :class:`pandas.DataFrame`
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

Raises
------
ValueError
If any of the confounds specified in the strategy are not found in the
confounds file or confounds json file.
"""
flag_acompcor = ("compcor" in strategy) and (
"anat" in kwargs.get("compcor")
)
Expand Down Expand Up @@ -375,7 +446,37 @@ def _load_single_confounds_file(


def _load_noise_component(confounds_raw, component, missing, **kargs):
"""Load confound of a single noise component."""
"""Load confound of a single noise component.

Parameters
----------
confounds_raw : :class:`pandas.DataFrame`
The confounds loaded from the confounds file.

component : :obj:`str`
The noise component to be loaded. The item from the strategy list.

missing : :obj:`dict`
A dictionary of missing confounds and noise component keywords.

kargs : :obj:`dict`
Extra relevant parameters for the given `component`.
See :func:`nilearn.interfaces.fmriprep.load_confounds` for details.

Returns
-------
loaded_confounds : :class:`pandas.DataFrame`
The confounds loaded from the confounds file for the given component.

missing : :obj:`dict`
A dictionary of missing confounds and noise component keywords.

Raises
------
MissingConfound
If any of the confounds specified in the strategy are not found in the
confounds file or confounds json file.
"""
try:
need_params = component_parameters.get(component)
if need_params:
Expand Down
107 changes: 101 additions & 6 deletions nilearn/interfaces/fmriprep/load_confounds_compcor.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,24 @@


def _find_compcor(confounds_json, compcor, n_compcor):
"""Build list for the number of compcor components."""
"""Build list for the number of compcor components.

Parameters
----------
confounds_json : dict
Dictionary of confounds from the confounds.json file.
compcor : str
Compcor strategy to use. Options are "temporal_anat", "temporal",
"anat", or "combined".
n_compcor : int or str
Number of compcor components to retain. If "all", all components
are retained.

Returns
-------
collector : list
List of compcor components to retain.
"""
prefix_set, anat_mask = _check_compcor_method(compcor)

collector = []
Expand Down Expand Up @@ -38,7 +55,22 @@ def _find_compcor(confounds_json, compcor, n_compcor):


def _select_compcor(compcor_cols, n_compcor):
"""Retain a specified number of compcor components."""
"""Retain a specified number of compcor components.

Parameters
----------
compcor_cols : list
List of compcor components column names filtered by user
selected CompCor strategy.
n_compcor : int or str
Remi-Gau marked this conversation as resolved.
Show resolved Hide resolved
Number of compcor components to retain. If "all", all components
are retained.

Returns
-------
compcor_cols : list
List of compcor components column names to retain.
"""
# only select if not "all", or less components are requested than there
# actually is
if (n_compcor != "all") and (n_compcor < len(compcor_cols)):
Expand All @@ -47,7 +79,21 @@ def _select_compcor(compcor_cols, n_compcor):


def _check_compcor_method(compcor):
"""Load compcor options and check if method is acceptable."""
"""Load compcor options and check if method is acceptable.

Parameters
----------
compcor : str
htwangtw marked this conversation as resolved.
Show resolved Hide resolved
Compcor strategy to use. Options are "temporal_anat", "temporal",
"anat", or "combined".

Returns
-------
prefix_set : list
List of prefixes to use for compcor components.
anat_mask : list
List of anatomical masks to use for acompcor.
"""
compcor_type = compcor.split("_")
if len(compcor_type) > 1:
compcor_type = "_".join(compcor_type[:-1])
Expand All @@ -63,7 +109,26 @@ def _check_compcor_method(compcor):


def _acompcor_mask(confounds_json, anat_mask, compcor_cols_filt, n_compcor):
"""Filter according to acompcor mask(s) and select top components."""
"""Filter according to acompcor mask(s) and select top components.

Parameters
----------
confounds_json : dict
htwangtw marked this conversation as resolved.
Show resolved Hide resolved
Dictionary of confounds from the confounds.json file.
anat_mask : list
List of anatomical masks to use for acompcor.
compcor_cols_filt : list
List of compcor components column names filtered by user
selected CompCor strategy.
n_compcor : int or str
Number of compcor components to retain. If "all", all components
are retained.

Returns
-------
collector : list
List of compcor components column names to retain.
"""
collector = []
for mask in anat_mask:
cols = _json_mask(compcor_cols_filt, confounds_json, mask)
Expand All @@ -73,7 +138,24 @@ def _acompcor_mask(confounds_json, anat_mask, compcor_cols_filt, n_compcor):


def _json_mask(compcor_cols_filt, confounds_json, mask):
"""Extract anat compcor components from a given mask."""
"""Extract anat compcor components with a given mask.

Parameters
----------
compcor_cols_filt : list
List of compcor components column names filtered by user
selected CompCor strategy.
confounds_json : dict
bthirion marked this conversation as resolved.
Show resolved Hide resolved
Dictionary of confounds from the confounds.json file.
mask : str
Remi-Gau marked this conversation as resolved.
Show resolved Hide resolved
Mask to use for acompcor.

Returns
-------
compcor_cols_filt : list
List of compcor components column names filtered by type of
acompcor mask.
"""
return [
compcor_col
for compcor_col in compcor_cols_filt
Expand All @@ -82,7 +164,20 @@ def _json_mask(compcor_cols_filt, confounds_json, mask):


def _prefix_confound_filter(prefix, all_compcor_name):
"""Get confound columns by prefix and acompcor mask."""
"""Get confound columns by prefix and acompcor mask.

Parameters
----------
prefix : str
Prefix to use for compcor components.
all_compcor_name : list
List of all compcor components column names.

Returns
-------
compcor_cols_filt : list
List of compcor components column names filtered by prefix.
"""
compcor_cols_filt = []
for nn in range(len(all_compcor_name)):
nn_str = str(nn).zfill(2)
Expand Down