Source code for bciflow.modules.fe.nonlinearenergy
'''
Description
-----------
This module implements the Nonlinear Energy feature extractor, which estimates the energy
of EEG signals using a nonlinear transformation. This feature is useful for capturing
nonlinear dynamics and transient events in brain activity, making it suitable for tasks
like seizure detection or event-related potential (ERP) analysis.
The Nonlinear Energy is calculated as the sum of the squared amplitude of the signal
minus the product of adjacent samples.
Class
------------
'''
import numpy as np
[docs]
class nonlinearenergy():
'''
Attributes
----------
flating : bool
If True, the output data is returned in a flattened format (default is False).
'''
def __init__(self, flating: bool = False):
''' Initializes the class.
Parameters
----------
flating : bool, optional
If True, the output data is returned in a flattened format (default is False).
Returns
-------
None
'''
if type(flating) != bool:
raise ValueError ("Has to be a boolean type value")
else:
self.flating = flating
[docs]
def fit(self, eegdata):
'''
This method does nothing, as the Nonlinear Energy feature extractor does not require training.
Parameters
----------
eegdata : dict
The input data.
Returns
-------
self
'''
if type(eegdata) != dict:
raise ValueError ("Has to be a dict type")
return self
[docs]
def transform(self, eegdata) -> dict:
'''
This method computes the Nonlinear Energy for each trial, band, and channel in the input data.
The result is stored in the dictionary under the key 'X'.
Parameters
----------
eegdata : dict
The input data.
Returns
-------
output : dict
The transformed data.
'''
if type(eegdata) != dict:
raise ValueError ("Has to be a dict type")
X = eegdata['X'].copy()
many_trials = len(X.shape) == 4
if not many_trials:
X = X[np.newaxis, :, :, :]
output = []
trials_, bands_, channels_, times_ = X.shape
for trial_ in range(trials_):
output.append([])
for band_ in range(bands_):
output[trial_].append([])
for channel_ in range(channels_):
diff = X[trial_, band_, channel_, 1:-1]**2 - (X[trial_, band_, channel_, 2:] * X[trial_, band_, channel_, :-2])
output[trial_][band_].append(np.sum(diff))
output = np.array(output)
if self.flating:
output = output.reshape(output.shape[0], -1)
if not many_trials:
output = output[0]
eegdata['X'] = output
return eegdata
[docs]
def fit_transform(self, eegdata) -> dict:
'''
This method combines fitting and transforming into a single step. It returns a
dictionary with the transformed data.
Parameters
----------
eegdata : dict
The input data.
Returns
-------
output : dict
The transformed data.
'''
return self.fit(eegdata).transform(eegdata)