class BBCIDataset(object):
"""
Loader class for files created by saving BBCI files in matlab (make
sure to save with '-v7.3' in matlab, see
https://de.mathworks.com/help/matlab/import_export/mat-file-versions.html#buk6i87 )
Parameters
----------
filename: str
load_sensor_names: list of str, optional
Also speeds up loading if you only load some sensors.
None means load all sensors.
Copyright Robin Schirrmeister, 2017
Altered by Vinay Jayaram, 2018
"""
def __init__(self, filename, load_sensor_names=None):
self.__dict__.update(locals())
del self.self
def load(self):
cnt = self._load_continuous_signal()
cnt = self._add_markers(cnt)
return cnt
def _load_continuous_signal(self):
wanted_chan_inds, wanted_sensor_names = self._determine_sensors()
fs = self._determine_samplingrate()
with h5py.File(self.filename, 'r') as h5file:
samples = int(h5file['nfo']['T'][0, 0])
cnt_signal_shape = (samples, len(wanted_chan_inds))
continuous_signal = np.ones(cnt_signal_shape,
dtype=np.float32) * np.nan
for chan_ind_arr, chan_ind_set in enumerate(wanted_chan_inds):
# + 1 because matlab/this hdf5-naming logic
# has 1-based indexing
# i.e ch1,ch2,....
chan_set_name = 'ch' + str(chan_ind_set + 1)
# first 0 to unpack into vector, before it is 1xN matrix
chan_signal = h5file[chan_set_name][
:].squeeze() # already load into memory
continuous_signal[:, chan_ind_arr] = chan_signal
assert not np.any(
np.isnan(continuous_signal)), "No NaNs expected in signal"
# Assume we cant know channel type here automatically
ch_types = ['eeg'] * len(wanted_chan_inds)
info = mne.create_info(ch_names=wanted_sensor_names, sfreq=fs,
ch_types=ch_types)
# Scale to volts from microvolts, (VJ 19.6.18)
continuous_signal = continuous_signal * 1e-6
cnt = mne.io.RawArray(continuous_signal.T, info)
return cnt
def _determine_sensors(self):
all_sensor_names = self.get_all_sensors(self.filename, pattern=None)
if self.load_sensor_names is None:
# if no sensor names given, take all EEG-chans
eeg_sensor_names = all_sensor_names
eeg_sensor_names = filter(lambda s: not s.startswith('BIP'),
eeg_sensor_names)
eeg_sensor_names = filter(lambda s: not s.startswith('E'),
eeg_sensor_names)
eeg_sensor_names = filter(lambda s: not s.startswith('Microphone'),
eeg_sensor_names)
eeg_sensor_names = filter(lambda s: not s.startswith('Breath'),
eeg_sensor_names)
eeg_sensor_names = filter(lambda s: not s.startswith('GSR'),
eeg_sensor_names)
eeg_sensor_names = list(eeg_sensor_names)
assert (len(eeg_sensor_names) in set(
[128, 64, 32, 16])), "check this code if you have different sensors..." # noqa
self.load_sensor_names = eeg_sensor_names
chan_inds = self._determine_chan_inds(all_sensor_names,
self.load_sensor_names)
return chan_inds, self.load_sensor_names
def _determine_samplingrate(self):
with h5py.File(self.filename, 'r') as h5file:
fs = h5file['nfo']['fs'][0, 0]
assert isinstance(fs, int) or fs.is_integer()
fs = int(fs)
return fs
@staticmethod def _determine_chan_inds(all_sensor_names, sensor_names):
assert sensor_names is not None
chan_inds = [all_sensor_names.index(s) for s in sensor_names]
assert len(chan_inds) == len(sensor_names)