Example #1
0
    def write_raw(self, dataset):
        """ Append a Psychic DataSet to the BDF file. No conversion between physical and digital values are performed. """
        assert len(self.n_samples_per_record) > 0 and self.n_samples_per_record[0] > 0, "Number of samples per record not set!"
        assert dataset.nfeatures == self.n_channels-1, 'Number of channels in dataset does not respond to the number of channels set in the header'
        assert dataset.labels.shape[0] == 1, 'Dimensions of labels must be (samples x 1).idst is used as STATUS channel'

        if not self.header_written:
            self.write_header()

        # Prepend any data left in the buffer from the previous write
        if self.samples_left_in_record is not None:
            dataset = psychic.concatenate([self.samples_left_in_record, dataset], merge_possible_labels=True)
            self.samples_left_in_record = None

        num_channels, num_samples = dataset.data.shape
        for i in range(0, num_samples, self.n_samples_per_record[0]):
            if i+self.n_samples_per_record[0] <= num_samples:
                # Convert data to 24 bit little endian, two's complement
                data = int24_to_le(dataset.data[:, i:i+self.n_samples_per_record[0]])
                self.f.write(data)

                # Bit 20 is used as overflow detection, this code keeps it fixed at '1' (no overflow) 
                status = int24_to_le(dataset.y[i:i+self.n_samples_per_record[0]].astype(np.int) | (1<<19))
                self.f.write(status)

                self.records_written += 1
            else:
                # Store any data left, it will be written the next time write() is called
                self.samples_left_in_record = dataset[i:]

        self.f.flush()
Example #2
0
    def read_all(self):
        '''
        Read all remaining records. Returns a `:class:psychic.DataSet:`

        Returns
        -------
        d : :class:`psychic.DataSet`:
            The records, concatenated into a :class:`psychic.DataSet`:
             - ``d.data`` will be the [channels x samples] EEG data
             - ``d.labels`` will contain the status channel
             - ``d.feat_lab`` will contain the channel names
             - ``d.ids`` will contain timestamps for each sample
             - ``d.data`` will be the [channels x samples] EEG data
             - ``d.labels`` will contain the status channel
             - ``d.feat_lab`` will contain the channel names
             - ``d.ids`` will contain timestamps for each sample
        '''
        records = list(self.read())
        return psychic.concatenate(records, merge_possible_labels=True)