Source code for phys2denoise.metrics.responses

"""Miscellaneous utility functions for metric calculation."""
import logging

import numpy as np

from .. import references
from ..due import due

LGR = logging.getLogger(__name__)
LGR.setLevel(logging.INFO)


[docs]@due.dcite(references.SHMUELI_2007) @due.dcite(references.CHANG_CUNNINGHAM_GLOVER_2009) def crf(samplerate, time_length=32, onset=0.0, inverse=False): """ Calculate the cardiac response function using Chang, Cunningham and Glover's definition. Parameters ---------- samplerate : :obj:`float` Sampling rate of data, in seconds. time_length : :obj:`int`, optional RRF kernel length, in seconds. Default is 32. onset : :obj:`float`, optional Onset of the response, in seconds. Default is 0. inverse: `bool`, optional If True, return the additive inverse of the CRF, i.e. the iCRF. Returns ------- crf : array-like Cardiac or "heart" response function Notes ----- This cardiac response function was defined in [1]_, Appendix A. The core code for this function comes from metco2, while several of the parameters, including time_length, and onset, are modeled on nistats' HRF functions. References ---------- .. [1] C. Chang, J. P. Cunnningham & G. H. Glover, "Influence of heartrate on the BOLD signal: The cardiac response function", NeuroImage, issue 47, vol. 4, pp. 857-869, 2009. .. [2] K.Shmueli and al., “Low-frequency fluctuations in the cardiac rate as a source of variance in the resting-state fMRI BOLD signal“, NeuroImage, issue 2, vol. 38, pp.306-320, 2007. """ def _crf(t): rf = 0.6 * t**2.7 * np.exp(-t / 1.6) - 16 * ( 1 / np.sqrt(2 * np.pi * 9) ) * np.exp(-0.5 * (((t - 12) ** 2) / 9)) return rf time_stamps = np.arange(0, time_length, 1 / samplerate) time_stamps -= onset crf_arr = _crf(time_stamps) crf_arr = crf_arr / max(abs(crf_arr)) if inverse: return -crf_arr else: return crf_arr
[docs]@due.dcite(references.CHANG_CUNNINGHAM_GLOVER_2009) @due.dcite(references.CHEN_2020) def icrf(samplerate, time_length=32, onset=0.0): """ Calculate the inverse of the cardiac response function. Parameters ---------- samplerate : :obj:`float` Sampling rate of data, in seconds. time_length : :obj:`int`, optional RRF kernel length, in seconds. Default is 32. onset : :obj:`float`, optional Onset of the response, in seconds. Default is 0. inverse: `bool`, optional If True, return the additive inverse of the CRF, i.e. the iCRF. Returns ------- icrf : array-like Inverse of cardiac or "heart" response function References ---------- .. [1] C. Chang, J. P. Cunnningham & G. H. Glover, "Influence of heartrate on the BOLD signal: The cardiac response function", NeuroImage, issue 47, vol. 4, pp. 857-869, 2009. """ return crf(samplerate, time_length=32, onset=0.0, inverse=True)
[docs]@due.dcite(references.CHANG_GLOVER_2009) def rrf(samplerate, time_length=50, onset=0.0): """Calculate the respiratory response function using Chang and Glover's definition. Parameters ---------- samplerate : :obj:`float` Sampling rate of data, in seconds.. time_length : :obj:`int`, optional RRF kernel length, in seconds. Default is 50. onset : :obj:`float`, optional Onset of the response, in seconds. Default is 0. Returns ------- rrf : array-like respiratory response function Notes ----- This respiratory response function was defined in [1]_, Appendix A. The core code for this function comes from metco2, while several of the parameters, including time_length, and onset, are modeled on nistats' HRF functions. References ---------- .. [1] C. Chang & G. H. Glover, "Relationship between respiration, end-tidal CO2, and BOLD signals in resting-state fMRI," NeuroImage, issue 47, vol. 4, pp. 1381-1393, 2009. """ def _rrf(t): rf = 0.6 * t**2.1 * np.exp(-t / 1.6) - 0.0023 * t**3.54 * np.exp(-t / 4.25) return rf time_stamps = np.arange(0, time_length, 1 / samplerate) time_stamps -= onset rrf_arr = _rrf(time_stamps) rrf_arr = rrf_arr / max(abs(rrf_arr)) return rrf_arr