Source code for mne_nirs.signal_enhancement._short_channel_correction

# Authors: Robert Luke <mail@robertluke.net>
#
# License: BSD (3-clause)

import numpy as np
from mne import pick_types
from mne.io import BaseRaw
from mne.preprocessing.nirs import source_detector_distances
from mne.utils import _validate_type
from scipy import linalg


[docs] def short_channel_regression(raw, max_dist=0.01): """ Systemic correction regression based on nearest short channel. Method as described by NIRx and based on :footcite:`fabbri2004optical`, :footcite:`saager2005direct`, and :footcite:`scholkmann2014measuring`. Parameters ---------- raw : instance of Raw Raw instance containing optical density data. max_dist : number Channels less than this distance are considered short (m). Returns ------- raw : instance of Raw The modified raw instance. References ---------- .. footbibliography:: """ raw = raw.copy().load_data() _validate_type(raw, BaseRaw, "raw") picks_od = pick_types(raw.info, fnirs="fnirs_od") if len(picks_od) == 0: raise RuntimeError("Data must be optical density.") distances = source_detector_distances(raw.info) picks_short = picks_od[distances[picks_od] < max_dist] picks_long = picks_od[distances[picks_od] > max_dist] if len(picks_short) == 0: raise RuntimeError("No short channels present.") if len(picks_long) == 0: raise RuntimeError("No long channels present.") for pick in picks_long: short_idx = _find_nearest_short(raw, pick, picks_short) A_l = raw.get_data(pick).ravel() A_s = raw.get_data(short_idx).ravel() # Eqn 27 Scholkmann et al 2014 alfa = np.dot(A_s, A_l) / np.dot(A_s, A_s) # Eqn 26 Scholkmann et al 2014 raw._data[pick] = A_l - alfa * A_s return raw
def _find_nearest_short(raw, pick, short_picks): """Return index of closest short channel. Parameters ---------- raw : instance of Raw Haemoglobin data. pick : integer Index of channel of interest. short_picks : list of integers Indices of short channels. Returns ------- pick : integer Index of short channel that is closest to pick. Note this index is relative to raw, and is from the subset provided in short_picks. """ dist = [ linalg.norm(raw.info["chs"][pick]["loc"][:3] - raw.info["chs"][p_sh]["loc"][:3]) for p_sh in short_picks ] return short_picks[np.argmin(dist)]