def _interpolate_bads_nirs(inst, method='nearest', exclude=(), verbose=None): from scipy.spatial.distance import pdist, squareform from mne.preprocessing.nirs import _validate_nirs_info # Returns pick of all nirs and ensures channels are correctly ordered picks_nirs = _validate_nirs_info(inst.info) if len(picks_nirs) == 0: return nirs_ch_names = [inst.info['ch_names'][p] for p in picks_nirs] nirs_ch_names = [ch for ch in nirs_ch_names if ch not in exclude] bads_nirs = [ch for ch in inst.info['bads'] if ch in nirs_ch_names] if len(bads_nirs) == 0: return picks_bad = pick_channels(inst.info['ch_names'], bads_nirs, exclude=[]) bads_mask = [p in picks_bad for p in picks_nirs] chs = [inst.info['chs'][i] for i in picks_nirs] locs3d = np.array([ch['loc'][:3] for ch in chs]) _check_option('fnirs_method', method, ['nearest']) if method == 'nearest': dist = pdist(locs3d) dist = squareform(dist) for bad in picks_bad: dists_to_bad = dist[bad] # Ignore distances to self dists_to_bad[dists_to_bad == 0] = np.inf # Ignore distances to other bad channels dists_to_bad[bads_mask] = np.inf # Find closest remaining channels for same frequency closest_idx = np.argmin(dists_to_bad) + (bad % 2) inst._data[bad] = inst._data[closest_idx] inst.info['bads'] = [ch for ch in inst.info['bads'] if ch in exclude] return inst
def peak_power(raw, time_window=10, threshold=0.1, l_freq=0.7, h_freq=1.5, l_trans_bandwidth=0.3, h_trans_bandwidth=0.3, verbose=False): """ Compute peak spectral power metric for each channel and time window. As described in [1]_ and [2]_. This method provides a metric of data quality along the duration of the measurement. The user can specify the window over which the metric is computed. Parameters ---------- raw : instance of Raw The haemoglobin data. time_window : number The duration of the window over which to calculate the metric. Default is 10 seconds as in PHOEBE paper. threshold : number Values below this are marked as bad and annotated in the raw file. %(l_freq)s %(h_freq)s %(l_trans_bandwidth)s %(h_trans_bandwidth)s %(verbose)s Returns ------- raw : instance of Raw The Raw data. Optionally annotated with bad segments. scores : array (n_nirs, n_windows) Array of peak power values. times : list List of the start and end times of each window used to compute the peak spectral power. References ---------- .. [1] Pollonini L et al., “PHOEBE: a method for real time mapping of optodes-scalp coupling in functional near-infrared spectroscopy” in Biomed. Opt. Express 7, 5104-5119 (2016). .. [2] Hernandez, Samuel Montero, and Luca Pollonini. "NIRSplot: a tool for quality assessment of fNIRS scans." Optics and the Brain. Optical Society of America, 2020. """ raw = raw.copy().load_data() _validate_type(raw, BaseRaw, 'raw') if not len(pick_types(raw.info, fnirs='fnirs_od')): raise RuntimeError('Scalp coupling index ' 'should be run on optical density data.') picks = _validate_nirs_info(raw.info) filtered_data = filter_data(raw._data, raw.info['sfreq'], l_freq, h_freq, picks=picks, verbose=verbose, l_trans_bandwidth=l_trans_bandwidth, h_trans_bandwidth=h_trans_bandwidth) window_samples = int(np.ceil(time_window * raw.info['sfreq'])) n_windows = int(np.floor(len(raw) / window_samples)) scores = np.zeros((len(picks), n_windows)) times = [] for window in range(n_windows): start_sample = int(window * window_samples) end_sample = start_sample + window_samples end_sample = np.min([end_sample, len(raw) - 1]) t_start = raw.times[start_sample] t_stop = raw.times[end_sample] times.append((t_start, t_stop)) for ii in picks[::2]: c1 = filtered_data[ii][start_sample:end_sample] c2 = filtered_data[ii + 1][start_sample:end_sample] # protect against zero c1 = c1 / (np.std(c1) or 1) c2 = c2 / (np.std(c2) or 1) c = np.correlate(c1, c2, "full") c = c / (window_samples) [f, pxx] = periodogram(c, fs=raw.info['sfreq'], window='hamming') scores[ii, window] = max(pxx) scores[ii + 1, window] = max(pxx) if (threshold is not None) & (max(pxx) < threshold): raw.annotations.append(t_start, time_window, 'BAD_PeakPower', ch_names=[raw.ch_names[ii:ii + 2]]) return raw, scores, times
def _fnirs_check_bads(info): _validate_nirs_info(info)