Example #1
0
def align(trials, window, offsets):
    sample_rate = utils.get_samplerate(trials)
    w = np.arange(int(window[0]*sample_rate), int(sample_rate))
    feat_lab = [ trials.feat_lab[0],
                    (w / float(sample_rate)).tolist()]
    feat_shape = (trials.feat_shape[0], len(w))

    data = np.zeros(feat_shape + (trials.ninstances,))
    for i,t in enumerate(offsets):
        t -= window[0]
        data[:,:,i] = trials.data[:,int(t*sample_rate)+w,i]

    trials_aligned = DataSet(data=data, feat_lab=feat_lab, default=trials)

    return trials_aligned
Example #2
0
def slice(d, markers_to_class, offsets):
    '''
    Slice function, used to extract fixed-length segments (called trials) of
    EEG from a recording. Opposite of :func:`psychic.concatenate_trials`.
    Segments are sliced based on the onset of some event code.

    Given for example an EEG recording which contains two marker codes:

    1. Left finger tapping
    2. Right finger tapping

    Trials can be extracted in the following manner:

    >>> import psychic
    >>> d = psychic.load_bdf(psychic.find_data_path('priming-short.bdf'))
    >>> mdict = {1:'related', 2:'unrelated'}
    >>> sample_rate = psychic.get_samplerate(d)
    >>> begin = int(-0.2 * sample_rate)
    >>> end = int(1.0 * sample_rate)
    >>> trials = psychic.slice(d, mdict, (begin, end))
    >>> print trials
    DataSet with 208 instances, 12280 features [40x307], 2 classes: [104, 104], extras: []
     
    Parameters
    ----------
    markers_to_class : dict
        A dictionary containing as keys the event codes to use as onset of the
        trial and as values a class label for the resulting trials. For example
        ``{1:'left finger tapping', 2:'right finger tapping'}``
    offsets : tuple
        Indicates the time (start, end), relative to the onset of marker, to
        extract as trial. Values are given in samples.

    Returns
    -------
    d : :class:`DataSet`
        The extracted segments:

        - ``d.data``: [channels x samples x trials]
        - ``d.labels``: [classes x trials]
        - ``d.ids``: Timestamps indicating the marker onsets
        - ``d.cl_lab``: The class labels as specified in the
          ``markers_to_class`` dictionary
        - ``d.feat_lab``: Feature labels for the axes [channels (strings),
          time in seconds (floats)]
    '''
    assert len(d.feat_shape) == 1, 'Data must be continuous EEG.'
    assert d.labels.shape[0] == 1 and d.labels.dtype == np.int, ('Labels are'
        'the wrong format. It must be an integer marker stream.')
    start_off, end_off = offsets
    data, labels, ids = [], [], []
    
    cl_lab = sorted(set(markers_to_class.values()))
    events, events_i, events_d = markers.markers_to_events(d.labels.flat)
    for (mark, cl) in markers_to_class.items():
        cl_i = cl_lab.index(cl)
        for i in events_i[events==mark]: # fails if there is *ONE* event
            (start, end) = i + start_off, i + end_off
            if start < 0 or end > d.ninstances:
                logging.getLogger('psychic.utils.slice').warning(
                    'Cannot extract slice [%d, %d] for class %s'
                    % (start, end, cl))
                continue
            dslice = d[start:end]
            data.append(dslice.data)
            labels.append(cl_i)
            ids.append(d.ids[:,i])
    
    event_time = np.arange(start_off, end_off) / float(utils.get_samplerate(d))
    feat_lab = [d.feat_lab[0], event_time.tolist()]

    if len(data) == 0:
        data = np.zeros(d.feat_shape + (len(event_time),0))
        labels = np.zeros((len(cl_lab),0))
        ids = np.zeros((1,0))
    else:
        data = np.concatenate([x[...,np.newaxis] for x in data], axis=2)
        labels = helpers.to_one_of_n(labels, class_rows=range(len(cl_lab)))
        ids = np.atleast_2d(np.vstack(ids).T)

    feat_dim_lab = ['channels', 'time']

    d = DataSet(
        data=data,
        labels=labels,
        ids=ids,
        cl_lab=cl_lab, 
        feat_lab=feat_lab, 
        feat_dim_lab=feat_dim_lab,
        default=d
    )
    return d.sorted()