Source code for processing.rereference

"""Re-referencing Module."""

import numpy as np
import pandas as pd

from py_neuromodulation.utils.types import NMPreprocessor


[docs] class ReReferencer(NMPreprocessor): def __init__( self, sfreq: float, channels: pd.DataFrame, ) -> None: """Initialize real-time rereference information. Parameters ---------- sfreq : float Sampling frequency. Is not used, only kept for compatibility. channels : Pandas DataFrame Dataframe containing information about rereferencing, as specified in channels.csv. Raises: ValueError: rereferencing using undefined channel ValueError: rereferencing to same channel """ self.ref_matrix: np.ndarray | None channels = channels[channels["used"] == 1].reset_index(drop=True) # (channels_used,) = np.where((channels.used == 1)) ch_names = channels["name"].tolist() # no re-referencing is being performed when there is a single channel present only if channels.shape[0] in (0, 1): self.ref_matrix = None return ch_types = channels["type"] refs = channels["rereference"] type_map = {} for ch_type in ch_types.unique(): type_map[ch_type] = np.where( (ch_types == ch_type) & (channels["status"] == "good") )[0] ref_matrix = np.zeros((len(channels), len(channels))) for ind in range(len(channels)): ref_matrix[ind, ind] = 1 # if ind not in channels_used: # continue ref = refs[ind] if ref.lower() == "none" or pd.isnull(ref): ref_idx = None continue if ref.lower() == "average": ch_type = ch_types[ind] ref_idx = type_map[ch_type][type_map[ch_type] != ind] else: ref_idx = [] ref_channels = ref.split("&") for ref_chan in ref_channels: if ref_chan not in ch_names: raise ValueError( "One or more of the reference channels are not" " part of the recording channels. First missing" f" channel: {ref_chan}." ) if ref_chan == ch_names[ind]: raise ValueError( "You cannot rereference to the same channel." f" Channel: {ref_chan}." ) ref_idx.append(ch_names.index(ref_chan)) ref_matrix[ind, ref_idx] = -1 / len(ref_idx) self.ref_matrix = ref_matrix
[docs] def process(self, data: np.ndarray) -> np.ndarray: """Rereference data according to the initialized ReReferencer class. Args: data (numpy ndarray) : shape(n_channels, n_samples) - data to be rereferenced. Returns: reref_data (numpy ndarray): shape(n_channels, n_samples) - rereferenced data """ if self.ref_matrix is not None: return self.ref_matrix @ data else: return data