예제 #1
0
def test_events_to_epochs(events, rel_start, rel_stop):
    words = events[events.type == 'WORD']

    epochs = events_to_epochs(words, rel_start, rel_stop, 1000)
    assert len(epochs) == 156
    for epoch in epochs:
        assert epoch[1] - epoch[0] == rel_stop - rel_start
예제 #2
0
def test_events_to_epochs_simple():
    offsets = [100, 200]  # in samples
    events = pd.DataFrame({"eegoffset": offsets})
    rate = 1000  # in samples / s
    rel_start = -10  # in ms
    rel_stop = 10  # in ms

    epochs = events_to_epochs(events, rel_start, rel_stop, rate)

    assert epochs[0][0] == 90
    assert epochs[0][1] == 110
    assert epochs[1][0] == 190
    assert epochs[1][1] == 210
예제 #3
0
    def test_split_eeg_reader(self, rhino_root):
        basename, sample_rate, dtype, filename = self.get_meta(
            'R1111M', 'FR1', 0, rhino_root)

        events = pd.DataFrame({"eegoffset": list(range(0, 500, 100))})
        rel_start, rel_stop = 0, 200
        epochs = convert.events_to_epochs(events, rel_start, rel_stop,
                                          sample_rate)

        eeg_reader = SplitEEGReader(filename, dtype, epochs, None)
        ts, contacts = eeg_reader.read()

        assert ts.shape == (len(epochs), 100, 100)
        assert len(contacts) == 100
예제 #4
0
    def test_split_eeg_reader_missing_contacts(self, rhino_root):
        basename, sample_rate, dtype, filename = self.get_meta(
            'R1006P', 'FR2', 0, rhino_root)

        events = pd.DataFrame({"eegoffset": list(range(0, 500, 100))})
        rel_start, rel_stop = 0, 200
        epochs = convert.events_to_epochs(events, rel_start, rel_stop,
                                          sample_rate)

        eeg_reader = SplitEEGReader(filename, dtype, epochs, None, False)
        ts, contacts = eeg_reader.read()

        assert ts.shape == (len(epochs), 123, 102)
        assert 1 not in contacts
        assert 98 not in contacts
        assert 99 not in contacts
        assert 100 not in contacts
        assert len(contacts) == 123
예제 #5
0
    def test_ramulator_hdf5_reader_rhino(self, subject, experiment, session,
                                         rhino_root):
        basename, sample_rate, dtype, filename = self.get_meta(
            subject, experiment, session, rhino_root)

        events = pd.DataFrame({"eegoffset": list(range(0, 500, 100))})
        rel_start, rel_stop = 0, 200
        epochs = convert.events_to_epochs(events, rel_start, rel_stop,
                                          sample_rate)

        eeg_reader = RamulatorHDF5Reader(filename, dtype, epochs, None)
        ts, contacts = eeg_reader.read()

        num_channels = len(
            CMLReader(subject, experiment, session,
                      rootdir=rhino_root).load('pairs'))

        time_steps = 200
        assert ts.shape == (len(epochs), num_channels, time_steps)
예제 #6
0
    def as_timeseries(self, events: pd.DataFrame,
                      rel_start: Union[float, int],
                      rel_stop: Union[float, int]) -> EEGContainer:
        """Read the timeseries.

        Parameters
        ----------
        events
            Events to read EEG data from
        rel_start
            Relative start times in ms
        rel_stop
            Relative stop times in ms

        Returns
        -------
        A time series with shape (channels, epochs, time). By default, this
        returns data as it was physically recorded (e.g., if recorded with a
        common reference, each channel will be a contact's reading referenced
        to the common reference, a.k.a. "monopolar channels").

        Raises
        ------
        RereferencingNotPossibleError
            When rereferencing is not possible.

        """
        eegs = []

        # sanity check on the offsets

        if rel_start != 0 and rel_stop != -1 and rel_start > rel_stop:
            raise ValueError('rel_start must precede rel_stop')

        for filename in events["eegfile"].unique():
            # select subset of events for this basename
            ev = events[events["eegfile"] == filename]

            # determine experiment, session, dtype, and sample rate
            experiment = ev["experiment"].unique()[0]
            session = ev["session"].unique()[0]
            basename = os.path.basename(filename)
            finder = PathFinder(subject=self.subject,
                                experiment=experiment,
                                session=session,
                                eeg_basename=basename,
                                rootdir=self.rootdir)
            sources = EEGMetaReader.fromfile(finder.find("sources"),
                                             subject=self.subject)
            sample_rate = sources["sample_rate"]
            dtype = sources["data_format"]
            is_scalp = dtype in (".bdf", ".raw", ".mff")

            # Convert events to epochs (onset & offset times)
            if rel_start == 0 and rel_stop == -1 and len(events) == 1:
                epochs = [(0, None)]
            else:
                epochs = convert.events_to_epochs(ev, rel_start, rel_stop,
                                                  sample_rate)

            # Scalp EEG reader requires onsets, rel_start (in sec), and rel_
            # stop (in sec) to cut data into epochs
            if is_scalp:
                on_off_epochs = epochs  # The onset & offset times will still
                # be passed to the EEGContainer later
                if rel_start == 0 and rel_stop == -1 and len(events) == 1:
                    epochs = None
                else:
                    epochs = np.zeros((len(ev), 3), dtype=int)
                    epochs[:, 0] = ev["eegoffset"]
                    epochs = dict(epochs=epochs, tmin=rel_start / 1000.,
                                  tmax=rel_stop / 1000.)

            root = get_root_dir(self.rootdir)
            eeg_filename = os.path.join(root, filename.lstrip("/"))
            reader_class = self._get_reader_class(filename)
            reader = reader_class(filename=eeg_filename,
                                  dtype=dtype,
                                  epochs=epochs,
                                  scheme=self.scheme,
                                  clean=self.clean)
            # if scalp EEG, info is an MNE Info object; if iEEG, info is a list
            # of contacts
            data, info = reader.read()

            attrs = {}
            if is_scalp:
                # Pass MNE info and events as extra attributes, to be able to
                # fully reconstruct MNE Raw/Epochs objects
                attrs["mne_info"] = info
                channels = info["ch_names"]
                if epochs is not None:
                    # Crop out any events/epoch times that ran beyond the
                    # bounds of the EEG recording
                    te_pre = info["truncated_events_pre"] \
                        if info["truncated_events_pre"] > 0 else None
                    te_post = -info["truncated_events_post"] \
                        if info["truncated_events_post"] > 0 else None
                    on_off_epochs = on_off_epochs[te_pre:te_post]
                    ev = ev[te_pre:te_post]
                # Pass the onset & offset time epoch list to EEGContainer, NOT
                # the MNE-formatted epoch list
                epochs = on_off_epochs
            elif self.scheme is not None:
                data, channels = reader.rereference(data, info)
            else:
                channels = ["CH{}".format(n + 1) for n in range(data.shape[1])]

            eegs.append(
                EEGContainer(
                    data,
                    sample_rate,
                    epochs=epochs,
                    events=ev,
                    channels=channels,
                    tstart=rel_start,
                    attrs=attrs
                )
            )

        eegs = EEGContainer.concatenate(eegs)
        eegs.attrs["rereferencing_possible"] = reader.rereferencing_possible
        return eegs
예제 #7
0
    def as_timeseries(self, events: pd.DataFrame, rel_start: Union[float, int],
                      rel_stop: Union[float, int]) -> EEGContainer:
        """Read the timeseries.

        Parameters
        ----------
        events
            Events to read EEG data from
        rel_start
            Relative start times in ms
        rel_stop
            Relative stop times in ms

        Returns
        -------
        A time series with shape (channels, epochs, time). By default, this
        returns data as it was physically recorded (e.g., if recorded with a
        common reference, each channel will be a contact's reading referenced to
        the common reference, a.k.a. "monopolar channels").

        Raises
        ------
        RereferencingNotPossibleError
            When rereferencing is not possible.

        """
        eegs = []

        for filename in events["eegfile"].unique():
            # select subset of events for this basename
            ev = events[events["eegfile"] == filename]

            # determine experiment, session, dtype, and sample rate
            experiment = ev["experiment"].unique()[0]
            session = ev["session"].unique()[0]
            finder = PathFinder(subject=self.subject,
                                experiment=experiment,
                                session=session,
                                rootdir=self.rootdir)
            sources = EEGMetaReader.fromfile(finder.find("sources"),
                                             subject=self.subject)
            sample_rate = sources["sample_rate"]
            dtype = sources["data_format"]

            # convert events to epochs
            if rel_stop < 0:
                # We're trying to load to the end of the session. Only allow
                # this in cases where we're trying to load a whole session.
                if len(events) > 1:
                    raise ValueError("rel_stop must not be negative")
                epochs = [(0, None)]
            else:
                epochs = convert.events_to_epochs(ev, rel_start, rel_stop,
                                                  sample_rate)

            root = get_root_dir(self.rootdir)
            eeg_filename = os.path.join(root, filename.lstrip("/"))
            reader_class = self._get_reader_class(filename)
            reader = reader_class(filename=eeg_filename,
                                  dtype=dtype,
                                  epochs=epochs,
                                  scheme=self.scheme)
            data, contacts = reader.read()

            if self.scheme is not None:
                data, labels = reader.rereference(data, contacts)
                channels = labels
            else:
                channels = ["CH{}".format(n + 1) for n in range(data.shape[1])]

            eegs.append(
                EEGContainer(
                    data,
                    sample_rate,
                    epochs=epochs,
                    events=ev,
                    channels=channels,
                    tstart=rel_start,
                ))

        eegs = EEGContainer.concatenate(eegs)
        eegs.attrs["rereferencing_possible"] = reader.rereferencing_possible
        return eegs