Spaces:
Running
Running
| # Authors: The MNE-Python contributors. | |
| # License: BSD-3-Clause | |
| # Copyright the MNE-Python contributors. | |
| import calendar | |
| import datetime | |
| from os import path | |
| import numpy as np | |
| from ..._fiff.constants import FIFF | |
| from ..._fiff.meas_info import _empty_info | |
| from ..._fiff.utils import _create_chs, _find_channels, _read_segments_file | |
| from ...utils import fill_doc, logger | |
| from ..base import BaseRaw | |
| def read_raw_nicolet( | |
| input_fname, ch_type, eog=(), ecg=(), emg=(), misc=(), preload=False, verbose=None | |
| ) -> "RawNicolet": | |
| """Read Nicolet data as raw object. | |
| .. note:: This reader takes data files with the extension ``.data`` as an | |
| input. The header file with the same file name stem and an | |
| extension ``.head`` is expected to be found in the same | |
| directory. | |
| Parameters | |
| ---------- | |
| input_fname : path-like | |
| Path to the data file (ending with ``.data`` not ``.head``). | |
| ch_type : str | |
| Channel type to designate to the data channels. Supported data types | |
| include ``'eeg'``, ``'dbs'``. | |
| eog : list | tuple | ``'auto'`` | |
| Names of channels or list of indices that should be designated | |
| EOG channels. If ``'auto'``, the channel names beginning with | |
| ``EOG`` are used. Defaults to empty tuple. | |
| ecg : list or tuple | ``'auto'`` | |
| Names of channels or list of indices that should be designated | |
| ECG channels. If ``'auto'``, the channel names beginning with | |
| ``ECG`` are used. Defaults to empty tuple. | |
| emg : list or tuple | ``'auto'`` | |
| Names of channels or list of indices that should be designated | |
| EMG channels. If ``'auto'``, the channel names beginning with | |
| ``EMG`` are used. Defaults to empty tuple. | |
| misc : list or tuple | |
| Names of channels or list of indices that should be designated | |
| MISC channels. Defaults to empty tuple. | |
| %(preload)s | |
| %(verbose)s | |
| Returns | |
| ------- | |
| raw : instance of Raw | |
| A Raw object containing the data. | |
| See Also | |
| -------- | |
| mne.io.Raw : Documentation of attributes and methods. | |
| """ | |
| return RawNicolet( | |
| input_fname, | |
| ch_type, | |
| eog=eog, | |
| ecg=ecg, | |
| emg=emg, | |
| misc=misc, | |
| preload=preload, | |
| verbose=verbose, | |
| ) | |
| def _get_nicolet_info(fname, ch_type, eog, ecg, emg, misc): | |
| """Extract info from Nicolet header files.""" | |
| fname, extension = path.splitext(fname) | |
| if extension != ".data": | |
| raise ValueError(f'File name should end with .data not "{extension}".') | |
| header = fname + ".head" | |
| logger.info("Reading header...") | |
| header_info = dict() | |
| with open(header) as fid: | |
| for line in fid: | |
| var, value = line.split("=") | |
| if var == "elec_names": | |
| value = value[1:-2].split(",") # strip brackets | |
| elif var == "conversion_factor": | |
| value = float(value) | |
| elif var in ["num_channels", "rec_id", "adm_id", "pat_id", "num_samples"]: | |
| value = int(value) | |
| elif var != "start_ts": | |
| value = float(value) | |
| header_info[var] = value | |
| ch_names = header_info["elec_names"] | |
| if eog == "auto": | |
| eog = _find_channels(ch_names, "EOG") | |
| if ecg == "auto": | |
| ecg = _find_channels(ch_names, "ECG") | |
| if emg == "auto": | |
| emg = _find_channels(ch_names, "EMG") | |
| date, time = header_info["start_ts"].split() | |
| date = date.split("-") | |
| time = time.split(":") | |
| sec, msec = time[2].split(".") | |
| date = datetime.datetime( | |
| int(date[0]), | |
| int(date[1]), | |
| int(date[2]), | |
| int(time[0]), | |
| int(time[1]), | |
| int(sec), | |
| int(msec), | |
| ) | |
| info = _empty_info(header_info["sample_freq"]) | |
| info["meas_date"] = (calendar.timegm(date.utctimetuple()), 0) | |
| if ch_type == "eeg": | |
| ch_coil = FIFF.FIFFV_COIL_EEG | |
| ch_kind = FIFF.FIFFV_EEG_CH | |
| elif ch_type == "seeg": | |
| ch_coil = FIFF.FIFFV_COIL_EEG | |
| ch_kind = FIFF.FIFFV_SEEG_CH | |
| else: | |
| raise TypeError( | |
| "Channel type not recognized. Available types are 'eeg' and 'seeg'." | |
| ) | |
| cals = np.repeat(header_info["conversion_factor"] * 1e-6, len(ch_names)) | |
| info["chs"] = _create_chs(ch_names, cals, ch_coil, ch_kind, eog, ecg, emg, misc) | |
| info["highpass"] = 0.0 | |
| info["lowpass"] = info["sfreq"] / 2.0 | |
| info._unlocked = False | |
| info._update_redundant() | |
| return info, header_info | |
| class RawNicolet(BaseRaw): | |
| """Raw object from Nicolet file. | |
| Parameters | |
| ---------- | |
| input_fname : path-like | |
| Path to the Nicolet file. | |
| ch_type : str | |
| Channel type to designate to the data channels. Supported data types | |
| include ``'eeg'``, ``'seeg'``. | |
| eog : list | tuple | ``'auto'`` | |
| Names of channels or list of indices that should be designated | |
| EOG channels. If ``'auto'``, the channel names beginning with | |
| ``EOG`` are used. Defaults to empty tuple. | |
| ecg : list or tuple | ``'auto'`` | |
| Names of channels or list of indices that should be designated | |
| ECG channels. If ``'auto'``, the channel names beginning with | |
| ``ECG`` are used. Defaults to empty tuple. | |
| emg : list or tuple | ``'auto'`` | |
| Names of channels or list of indices that should be designated | |
| EMG channels. If ``'auto'``, the channel names beginning with | |
| ``EMG`` are used. Defaults to empty tuple. | |
| misc : list or tuple | |
| Names of channels or list of indices that should be designated | |
| MISC channels. Defaults to empty tuple. | |
| %(preload)s | |
| %(verbose)s | |
| See Also | |
| -------- | |
| mne.io.Raw : Documentation of attributes and methods. | |
| """ | |
| def __init__( | |
| self, | |
| input_fname, | |
| ch_type, | |
| eog=(), | |
| ecg=(), | |
| emg=(), | |
| misc=(), | |
| preload=False, | |
| verbose=None, | |
| ): | |
| input_fname = path.abspath(input_fname) | |
| info, header_info = _get_nicolet_info(input_fname, ch_type, eog, ecg, emg, misc) | |
| last_samps = [header_info["num_samples"] - 1] | |
| super().__init__( | |
| info, | |
| preload, | |
| filenames=[input_fname], | |
| raw_extras=[header_info], | |
| last_samps=last_samps, | |
| orig_format="int", | |
| verbose=verbose, | |
| ) | |
| def _read_segment_file(self, data, idx, fi, start, stop, cals, mult): | |
| """Read a chunk of raw data.""" | |
| _read_segments_file(self, data, idx, fi, start, stop, cals, mult, dtype="<i2") | |