Source code for pycartool.io.sef

# -*- coding: utf-8 -*-
# Authors: Tanguy Vivier <tanguy.viv@gmail.com>
#          Victor Férat <victor.ferat@live.fr>
#
# License: BSD (3-clause)
import struct
import time
import datetime as dt
import numpy as np
import mne
from mne.io import RawArray
from mne import create_info


[docs]def read_sef(path): """ Reads file with format .sef, and returns a mne.io.Raw object containing the data. Parameters ---------- path : str The path of the sef file. Returns ------- raw : mne.io.RawArray RawArray containing the EEG signals. """ f = open(path, 'rb') # Read fixed part of the headerà version = f.read(4).decode('utf-8') if version != 'SE01': priint(f'Version : {version} not supported') raise ValueError() n_channels, = struct.unpack('I', f.read(4)) num_aux_electrodes, = struct.unpack('I', f.read(4)) num_time_frames, = struct.unpack('I', f.read(4)) sfreq, = struct.unpack('f', f.read(4)) year, = struct.unpack('H', f.read(2)) month, = struct.unpack('H', f.read(2)) day, = struct.unpack('H', f.read(2)) hour, = struct.unpack('H', f.read(2)) minute, = struct.unpack('H', f.read(2)) second, = struct.unpack('H', f.read(2)) millisecond, = struct.unpack('H', f.read(2)) # Read variable part of the header ch_names = [] for _ in range(n_channels): name = [char for char in f.read(8).split(b'\x00') if char != b''][0] ch_names.append(name.decode('utf-8')) # Read data buffer = np.frombuffer( f.read(n_channels * num_time_frames * 8), dtype=np.float32, count=n_channels * num_time_frames) data = np.reshape(buffer, (num_time_frames, n_channels)) # Create infos description = 'Imported with Pycartool' try: record_time = dt.datetime(year, month, day, hour, minute, second).timetuple() meas_date = (time.mktime(record_time), millisecond) except Exception as e: print('Cannot read recording date from file...') print(e) meas_date = None ch_types = ['eeg' for i in range(n_channels)] infos = create_info(ch_names=ch_names, sfreq=sfreq, ch_types=ch_types) infos['description'] = description infos['meas_date'] = meas_date raw = RawArray(np.transpose(data), infos) return (raw)
[docs]def write_sef(path, raw): """Export a raw mne file to a sef file. Parameters ---------- path : str Filename of the exported dataset. raw : instance of mne.io.Raw The raw data to export. """ n_channels = len(raw.info['ch_names']) num_freq_frames = raw.n_times info = raw.info sfreq = info['sfreq'] num_aux_electrodes = n_channels - len(mne.pick_types(info, meg=False, eeg=True, exclude=[''])) f = open(path, 'wb') f.write('SE01'.encode('utf-8')) f.write(struct.pack('I', n_channels)) f.write(struct.pack('I', num_aux_electrodes)) f.write(struct.pack('I', num_freq_frames)) f.write(struct.pack('f', sfreq)) f.write(struct.pack('H', 0)) f.write(struct.pack('H', 0)) f.write(struct.pack('H', 0)) f.write(struct.pack('H', 0)) f.write(struct.pack('H', 0)) f.write(struct.pack('H', 0)) f.write(struct.pack('H', 0)) ch_names = info['ch_names'] for k in range(n_channels): ch_name = ch_names[k] ch_name = ch_name.ljust(8) f.write(ch_name.encode('utf-8')) data = raw.get_data().astype(np.float32) data = np.reshape(data, n_channels * num_freq_frames, order='F') data.tofile(f) f.close()