Line length

Demonstration code for computing line length using LineLength().

Link to script: feature_extraction/line_length.py

import os
import numpy as np
import matplotlib.pyplot as plt

from nnsa import print_object_summary, SUPPORTED_RESULT_FILE_TYPES, read_result_from_file, assert_equal, \
    LineLength, EdfReader

plt.close('all')

Parameters.

# Print the default parameters of LineLength():
print(LineLength().default_parameters())

# Descriptions of the parameters are documented in the default_parameters() code.

# Create an instance of the LineLength class with custom parameters, overruling some defaults:
line_length = LineLength(line_length={'normalization_kind': None})

# See if the custom parameters were accepted:
print('\nCustom parameters:')
print(line_length.parameters)

Main method: line_length.

# Now that we have initialized a LineLength object with certain parameters, we can run the line_length
# method, which computes the line length:
# Create a random signal.
signal = np.random.rand(8, 10000)
fs = 250
result = line_length.line_length(signal, fs=fs)

Save the result.

# We can save the result to any supported file. To list the supported file types/extensions:
print('Supported result file types: {}'.format(SUPPORTED_RESULT_FILE_TYPES))

# E.g. save as hdf5 (the file type to save is automatically detected from the extension of the filename).
filename = 'temp_result.hdf5'
result.save_to_file(filename)

# We can reload the result back to a LineLengthResult object:
result_loaded = read_result_from_file(filename)

# Remove temporary file.
os.remove(filename)

# Verify that the loaded object is equal to the original object:
assert_equal(actual=result_loaded, desired=result)  # Will raise an AssertionError if not equal.
print('Loaded result object is equal to original object.')

The returned object is a LineLengthResult object, which is a high-level interface for manipulating/visualizing/saving the result:

print('\nSummary of result object:')
print_object_summary(result)

LineLengthResult attributes.

# The main attribute is line_length, which contains the computed line length values:
print('result.line_length: {}'.format(result.line_length))

# The median_line_length property returns the median line length across channels (ignoring nan values).
print('result.median_line_length: {}'.format(result.median_line_length))

# The channel labels corresponding to the rows of line_length:
print('result.channel_labels: {}'.format(result.channel_labels))

# The segment times corresponding to the columns of line_length:
print('result.segment_times: {}'.format(result.segment_times))

LineLengthResult methods.

# Plot the median line length across channels as function of time/segments.
result.plot(channels='median')

LineLength of EegDataset.

# Specify a file and open a reader to read the data (e.g. EdfReader to read an EDF(+) file).
filepath = 'C:/data_temp/test.edf'

# Read EEG channels in an EegDataset object.
with EdfReader(filepath) as r:
    ds = r.read_eeg_dataset(dtype=np.float32)  # We can specify the dtype, lower precision, means less memory usage.

ds_preprocessed = ds.reference('Cz').resample(fs_new=128).filter_saved_filter(filter_name='bandpassfir_a')

# We can compute the line length for multichannel EEG via the wrapper method 'line_length' of the EegDataset class.
# Specify the parameters to the LineLength class as kwargs.
result_ds = ds_preprocessed.line_length(line_length={'normalization_kind': 'sum_segments'})

plt.figure()
result_ds.plot(log_transform=True)
print(result_ds.histogram_features(ignore_nan=True))