Menu

Package that provides tools for brain MRI Deep Learning pre-processing.

Source code for brainprep.connectivity

# -*- coding: utf-8 -*-
##########################################################################
# NSAp - Copyright (C) CEA, 2022
# Distributed under the terms of the CeCILL-B license, as published by
# the CEA-CNRS-INRIA. Refer to the LICENSE file or to
# http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
# for details.
##########################################################################


"""
Import pre-processed images and confounds from fMRIPrep and generate
connectivity matrices based on standard parcellations and metrics.
"""

# Imports
import os
import numpy as np
from nilearn import datasets
from nilearn import plotting
from nilearn.image import clean_img
from nilearn.maskers import NiftiLabelsMasker
from nilearn.connectome import ConnectivityMeasure
from nilearn.interfaces.fmriprep import load_confounds
from .color_utils import print_subtitle, print_result


# Define global parameters
CONNECTIVITIES = ["correlation", "partial correlation"]
ATLASES = ["schaefer"]


[docs]def func_connectivity(fmri_file, counfounds_file, mask_file, tr, outdir, low_pass=0.1, high_pass=0.01, scrub=5, fd_threshold=0.2, std_dvars_threshold=3, detrend=True, standardize=True, remove_volumes=False, fwhm=0.): """ Compute ROI-based functional connectivity from fMRIPrep pre-processing. This function applies the Yeo et al. (2011) timeseries pre-processing schema: * detrend. * low- and high-pass filters. * remove confounds. * standardize. The filtering stage is composed of: * low pass filter out high frequency signals from the data (upper than 0.1 Hz by default). fMRI signals are slow evolving processes, any high frequency signals are likely due to noise. * high pass filter out any very low frequency signals (below 0.001 Hz by default), which may be due to intrinsic scanner instabilities. The confound regressors are composed of: * 1 global signal. * 12 motion parameters + derivatives. * 8 discrete cosines transformation basis regressors to handle low-frequency signal drifts. * 2 confounds derived from white matter and cerebrospinal fluid. This is a total of 23 base confound regressor variables. According to Lindquist et al. (2018), removal of confounds will be done orthogonally to temporal filters (low- and/or high-pass filters), if both are specified. Notes ----- Connectivity extraction parameters can be changed by setting the following module global parameters: CONNECTIVITIES, ATLASES. Parameters ---------- fmri_file: str the fMRIPrep pre-processing file: **\*desc-preproc_bold.nii.gz**. counfounds_file: str the path to the fMRIPrep counfounds file: **\*desc-confounds_regressors.tsv**. mask_file: str signal is only cleaned from voxels inside the mask. It should have the same shape and affine as the ``fmri_file``: **\*desc-brain_mask.nii.gz**. tr: float the repetition time (TR) in seconds. outdir: str the destination folder. low_pass: float, default 0.1 the low-pass filter cutoff frequency in Hz. Set it to ``None`` if you dont want low-pass filtering. high_pass: float, default 0.01 the high-pass filter cutoff frequency in Hz. Set it to ``None`` if you dont want high-pass filtering. scrub: int, default 5 after accounting for time frames with excessive motion, further remove segments shorter than the given number. The default value is 5. When the value is 0, remove 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 Framewise displacement threshold for scrub. This value is typically between 0 and 1 mm. std_dvars_threshold: float, default 3 standardized DVARS threshold for scrub. DVARs is defined as root mean squared intensity difference of volume N to volume N + 1. D refers to temporal derivative of timecourses, VARS referring to root mean squared variance over voxels. detrend: bool, default True detrend data prior to confound removal. standardize: default True set this flag if you want to standardize the output signal between [0 1]. remove_volumes: bool, default False this flag determines whether contaminated volumes should be removed from the output data. fwhm: float or list, default 0. smoothing strength, expressed as as Full-Width at Half Maximum (fwhm), in millimeters. Can be a single number ``fwhm=8``, the width is identical along x, y and z or ``fwhm=0``, no smoothing is peformed. Can be three consecutive numbers, ``fwhm=[1,1.5,2.5]``, giving the fwhm along each axis. Returns ------- corrfiles: dict the connectivity matrix resulting files. """ print_subtitle("Get connectivity extraction parameters...") basename = os.path.basename(fmri_file).split(".")[0] assert basename.endswith("_bold"), basename basename = basename.replace("_bold", "_mod-bold") print("- connectivities:", "-".join(CONNECTIVITIES)) print("- atlases:", "-".join(ATLASES)) print("- fMRI volume:", fmri_file) print("- counfounds file:", counfounds_file) print("- mask file:", mask_file) print_subtitle("Get atlases...") atlasdir = os.path.join(outdir, "atlases") if not os.path.isdir(atlasdir): os.mkdir(atlasdir) data = {} for atlas_name in ATLASES: if atlas_name == "schaefer": atlas = datasets.fetch_atlas_schaefer_2018( n_rois=200, data_dir=atlasdir) elif atlass_name == "msdl": atlas = datasets.fetch_atlas_msdl(data_dir=atlasdir) else: raise ValueError("Unsupported atlas '{}'.".format(atlas)) data[atlas_name] = { "atlas_filename": atlas.maps, "atlas_labels": atlas.labels} atlas_snap = os.path.join(atlasdir, "{}.png".format(atlas_name)) if not os.path.isfile(atlas_snap): plotting.plot_roi( data[atlas_name]["atlas_filename"], title=atlas_name, cut_coords=(8, -4, 9), colorbar=True, cmap="Paired", output_file=atlas_snap) print_result(atlas_snap) print_subtitle("Get requested counfounds...") select_confounds, sample_mask = load_confounds( fmri_file, strategy=["high_pass", "motion", "wm_csf", "global_signal"], motion="derivatives", wm_csf="basic", global_signal="basic", scrub=scrub, fd_threshold=fd_threshold, std_dvars_threshold=std_dvars_threshold) if not remove_volumes: sample_mask = None print(select_confounds) print_subtitle("Clean fMRI timeseries...") clean_im = clean_img( fmri_file, standardize=standardize, detrend=detrend, confounds=select_confounds, t_r=tr, high_pass=high_pass, low_pass=low_pass, mask_img=mask_file) if np.array(fwhm).sum() > 0.0: print_subtitle("Smooth fMRI timeseries...") smooth_im = nl_img.smooth_img(clean_im, fwhm) print_subtitle("Extract average fMRI timeseries...") for atlas_name, params in data.items(): masker = NiftiLabelsMasker( labels_img=params["atlas_filename"], verbose=5) timeseries = masker.fit_transform(clean_im, sample_mask=sample_mask) params["timeseries"] = timeseries print_subtitle("Compute functional connectivity...") for metric in CONNECTIVITIES: correlation_measure = ConnectivityMeasure(kind=metric) for atlas_name, params in data.items(): correlation_matrix = correlation_measure.fit_transform( [params["timeseries"]])[0] np.fill_diagonal(correlation_matrix, 0) corr_snap = os.path.join( outdir, basename + "atlas-{}_{}.png".format( atlas_name, metric.replace(" ", ""))) display = plotting.plot_matrix( correlation_matrix, figure=(10, 8), labels=params["atlas_labels"], reorder=True, title="{}-{}".format(atlas_name, metric)) display.figure.savefig(corr_snap) print_result(corr_snap) params[metric] = correlation_matrix print_subtitle("Saving results...") corrfiles = {} for atlas_name, params in data.items(): for metric in CONNECTIVITIES: corr_file = os.path.join( outdir, basename + "atlas-{}_{}.npy".format( atlas_name, metric.replace(" ", ""))) np.save(corr_file, params[metric]) print_result(corr_file) corrfiles[metric] = corr_file return corrfiles

Follow us

© 2023, brainprep developers