예제 #1
0
    def test_spike_objects(self):
        dimension = 40
        offset = sp.zeros((dimension, 1))
        offset[0] = 4
        cluster1 = self.rand.randn(dimension, 10)
        cluster2 = self.rand.randn(dimension, 100) + offset
        cluster3 = self.rand.randn(dimension, 500) - offset
        clusterList1 = [cluster1[:, i] for i in xrange(sp.size(cluster1, 1))]
        clusterList2 = [cluster2[:, i] for i in xrange(sp.size(cluster2, 1))]
        clusterList3 = [cluster3[:, i] for i in xrange(sp.size(cluster3, 1))]
        mean1 = sp.zeros(dimension)
        mean2 = offset.flatten()
        mean3 = -mean2

        total, pair = qa.overlap_fp_fn(
            {
                1: clusterList1,
                2: clusterList2,
                3: clusterList3
            },
            means={
                1: mean1,
                2: mean2,
                3: mean3
            },
            covariances={
                1: sp.eye(dimension),
                2: sp.eye(dimension),
                3: sp.eye(dimension)
            })

        # Replacing some arrays with Spike objects
        mean2 = neo.Spike(waveform=mean2.reshape(-1, 4) / 1000.0 * pq.mV)
        mean3 = neo.Spike(waveform=mean3.reshape(-1, 4) / 1e6 * pq.V)
        newClusterList = []
        for s in clusterList1:
            newClusterList.append(
                neo.Spike(waveform=s.reshape(-1, 4) / 1000.0 * pq.mV))

        total_s, pair_s = qa.overlap_fp_fn(
            {
                1: newClusterList,
                2: clusterList2,
                3: clusterList3
            },
            means={
                1: mean1,
                2: mean2,
                3: mean3
            },
            covariances='white')

        # Results should be identical for arrays and Spike objects
        for i in total.keys():
            self.assertAlmostEqual(total[i][0], total_s[i][0])
            self.assertAlmostEqual(total[i][1], total_s[i][1])
            for j in pair[i].keys():
                self.assertAlmostEqual(pair[i][j][0], pair_s[i][j][0])
                self.assertAlmostEqual(pair[i][j][1], pair_s[i][j][1])
예제 #2
0
 def test_spikes(self):
     trains = {}
     trains[0] = [
         neo.Spike(0 * pq.ms, waveform=[[-1, -2], [1, 2]] * pq.mV),
         neo.Spike(0 * pq.ms, waveform=[[-1, -2], [1, 2]] * pq.mV)
     ]
     trains[1] = trains[0]
     means = {}
     means[0] = neo.Spike(0 * pq.ms, waveform=[[-1, -1], [1, 1]] * pq.mV)
     exp = qa.variance_explained(trains, means)
     self.assertAlmostEqual(exp[1][0], 1)
     self.assertAlmostEqual(exp[1][0], 1)
     self.assertAlmostEqual(exp[0][0], 1)
     self.assertAlmostEqual(exp[0][1], 0.75)
예제 #3
0
def spike_train_to_spikes(spike_train, include_waveforms=True):
    """ Return a list of spikes for a spike train.

    Note that while the created spikes have references to the same segment and
    unit as the spike train, the relationships in the other direction are
    not automatically created (the spikes are not attached to the unit or
    segment). Other properties like annotations are not copied or referenced
    in the created spikes.

    :param spike_train: A spike train from which the :class:`neo.core.Spike`
        objects are constructed.
    :type spike_train: :class:`neo.core.SpikeTrain`
    :param bool include_waveforms: Determines if the ``waveforms`` property is
        converted to the spike waveforms. If ``waveforms`` is None, this
        parameter has no effect.
    :returns: A list of :class:`neo.core.Spike` objects, one for every
        spike in ``spike_train``.
    :rtype: list
    """
    waves = None
    if include_waveforms:
        waves = spike_train.waveforms

    spikes = []
    for i, t in enumerate(spike_train):
        s = neo.Spike(t,
                      sampling_rate=spike_train.sampling_rate,
                      left_sweep=spike_train.left_sweep)
        if waves is not None:
            s.waveform = waves[i, :, :]
        s.unit = spike_train.unit
        s.segment = spike_train.segment
        spikes.append(s)

    return spikes
def variance_explained(spikes, means=None, noise=None):
    """ Returns the fraction of variance in each channel that is explained
    by the means.

    Values below 0 or above 1 for large data sizes indicate
    that some assumptions were incorrect (e.g. about channel noise) and
    the results should not be trusted.

    :param dict spikes: Dictionary, indexed by unit, of
        :class:`neo.core.SpikeTrain` objects (where the ``waveforms``
        member includes the spike waveforms) or lists of
        :class:`neo.core.Spike` objects.
    :param dict means: Dictionary, indexed by unit, of lists of
        spike waveforms as :class:`neo.core.Spike` objects or numpy arrays.
        Means for units that are not in this dictionary will be estimated
        using the spikes.
        Default: None - means will be estimated from given spikes.
    :type noise: Quantity 1D
    :param noise: The known noise levels (as variance) per channel of the
        original data. This should be estimated from the signal periods
        that do not contain spikes, otherwise the explained variance
        could be overestimated. If None, the estimate of explained variance
        is done without regard for noise.
        Default: None
    :return dict: A dictionary of arrays, both indexed by unit. If ``noise``
        is ``None``, the  dictionary contains
        the fraction of explained variance per channel without taking noise
        into account. If ``noise`` is given, it contains the fraction of
        variance per channel explained by the means and given noise level
        together.
    """
    ret = {}
    if means is None:
        means = {}
    for u, spks in spikes.iteritems():
        train = spks
        if not isinstance(train, neo.SpikeTrain):
            train = spikes_to_spike_train(spks)
        if u in means and means[u].waveform.shape[0] == train.waveforms.shape[
                1]:
            spike = means[u]
        else:
            spike = neo.Spike(0)
            spike.waveform = sp.mean(train.waveforms, axis=0)

        orig = sp.mean(sp.var(train.waveforms, axis=1), axis=0)
        waves = train.waveforms - spike.waveform
        new = sp.mean(sp.var(waves, axis=1), axis=0)

        if noise is not None:
            ret[u] = sp.asarray(1 - (new - noise) / orig)
        else:
            ret[u] = sp.asarray(1 - new / orig)

    return ret
예제 #5
0
    def create_hierarchy(cls, many_to_many):
        b = neo.Block()

        for ns in range(cls.SEGMENTS):
            b.segments.append(neo.Segment())

        channels = []
        if many_to_many:
            channels = [
                neo.RecordingChannel(name='Shared %d' % i,
                                     index=i + cls.CHANNELS)
                for i in range(cls.CHANNELS / 2)
            ]

        for ng in range(cls.CHANNEL_GROUPS):
            rcg = neo.RecordingChannelGroup()
            for nu in range(cls.UNITS):
                unit = neo.Unit()
                for ns in range(cls.SEGMENTS):
                    spike = neo.Spike(0 * pq.s)
                    unit.spikes.append(spike)
                    b.segments[ns].spikes.append(spike)

                    st = neo.SpikeTrain([] * pq.s, 0 * pq.s)
                    unit.spiketrains.append(st)
                    b.segments[ns].spiketrains.append(st)

                rcg.units.append(unit)

            if not many_to_many:
                for nc in range(cls.CHANNELS):
                    rc = neo.RecordingChannel(name='Single %d' % nc, index=nc)
                    rc.recordingchannelgroups.append(rcg)
                    rcg.recordingchannels.append(rc)
            else:
                for nc in range(cls.CHANNELS):
                    if nc % 2 == 0:
                        rc = neo.RecordingChannel(name='Single %d' % (nc / 2),
                                                  index=nc / 2)
                    else:
                        rc = channels[nc / 2]
                    rc.recordingchannelgroups.append(rcg)
                    rcg.recordingchannels.append(rc)
            rcg.channel_indexes = sp.array(
                [c.index for c in rcg.recordingchannels])
            rcg.channel_names = sp.array(
                [c.name for c in rcg.recordingchannels])

            b.recordingchannelgroups.append(rcg)

        try:
            neo.io.tools.create_many_to_one_relationship(b)
        except AttributeError:
            b.create_many_to_one_relationship()
        return b
예제 #6
0
 def test_trains(self):
     trains = {}
     trains[0] = neo.SpikeTrain(
         sp.zeros(2) * pq.ms,
         0 * pq.ms,
         waveforms=[[[-1, -2], [1, 2]], [[-1, -2], [1, 2]]] * pq.mV)
     trains[1] = trains[0]
     means = {}
     means[1] = neo.Spike(0 * pq.ms, waveform=[[-1, -1], [1, 1]] * pq.mV)
     exp = qa.variance_explained(trains, means)
     self.assertAlmostEqual(exp[0][0], 1)
     self.assertAlmostEqual(exp[0][0], 1)
     self.assertAlmostEqual(exp[1][0], 1)
     self.assertAlmostEqual(exp[1][1], 0.75)
예제 #7
0
    def test_remove_spiketrain(self):
        unit = neo.Unit()
        segment = neo.Segment()

        s = neo.Spike(0 * pq.s)
        unit.spikes.append(s)
        segment.spikes.append(s)
        s.unit = unit
        s.segment = segment

        st = neo.SpikeTrain([] * pq.s, 0 * pq.s)
        unit.spiketrains.append(st)
        segment.spiketrains.append(st)
        st.unit = unit
        st.segment = segment

        tools.remove_from_hierarchy(st)
        self.assertTrue(s in unit.spikes)
        self.assertTrue(s in segment.spikes)
        self.assertFalse(st in unit.spiketrains)
        self.assertFalse(st in segment.spiketrains)
예제 #8
0
def extract_spikes(train, signals, length, align_time):
    """ Extract spikes with waveforms from analog signals using a spike train. 
    Spikes that are too close to the beginning or end of the shortest signal
    to be fully extracted are ignored.

    :type train: :class:`neo.core.SpikeTrain`
    :param train: The spike times.
    :param sequence signals: A sequence of :class:`neo.core.AnalogSignal`
        objects from which the spikes are extracted. The waveforms of
        the returned spikes are extracted from these signals in the
        same order they are given.
    :type length: Quantity scalar
    :param length: The length of the waveform to extract as time scalar.
    :type align_time: Quantity scalar
    :param align_time: The alignment time of the spike times as time scalar.
        This is the time delta from the start of the extracted waveform
        to the exact time of the spike.
    :returns: A list of :class:`neo.core.Spike` objects, one for each
        time point in ``train``. All returned spikes include their
        ``waveform`` property.
    :rtype: list
    """
    if not signals:
        raise ValueError('No signals to extract spikes from')
    ref = signals[0]
    for s in signals[1:]:
        if ref.sampling_rate != s.sampling_rate:
            raise ValueError(
                'All signals for spike extraction need the same sampling rate')

    wave_unit = signals[0].units
    srate = signals[0].sampling_rate
    end = min(s.shape[0] for s in signals)

    aligned_train = train - align_time
    cut_samples = int((length * srate).simplified)

    st = sp.asarray((aligned_train * srate).simplified)

    # Find extraction epochs
    st_ok = (st >= 0) * (st < end - cut_samples)
    epochs = sp.vstack((st[st_ok], st[st_ok] + cut_samples)).T.astype(sp.int64)

    nspikes = epochs.shape[0]
    if not nspikes:
        return []

    # Create data
    data = sp.vstack([sp.asarray(s.rescale(wave_unit)) for s in signals])
    nc = len(signals)

    spikes = []
    for s in xrange(nspikes):
        waveform = sp.zeros((cut_samples, nc))
        for c in xrange(nc):
            waveform[:, c] = \
                data[c, epochs[s, 0]:epochs[s, 1]]
        spikes.append(neo.Spike(train[st_ok][s], waveform=waveform * wave_unit,
                                sampling_rate=srate))

    return spikes
예제 #9
0
import ipdb

ss = session.create(location="http://predata.g-node.org", username="******", password="******")
blk = neo.Block(name='testBlock1')
for ind1 in range(3):

    seg = neo.Segment(name='testSegment' + str(ind1), index=ind1)
    seg.block = blk

    for ind2 in range(3):
        sp = neo.SpikeTrain(name='SpikeTrain' + str(ind2), times=np.random.rand(10) * qu.s, t_stop=1.2)
        sp.segment = seg
        seg.spiketrains.append(sp)

    for ind2 in range(3):
        sp = neo.Spike(name='Spike' + str(ind2), time=np.random.rand() * qu.s)
        sp.segment = seg
        seg.spikes.append(sp)

    for ind2 in range(3):
        irr = neo.IrregularlySampledSignal(name='IrregularlySampled' + str(ind2), times=np.random.rand(10) * qu.s,
                                           signal=np.random.rand(10) * qu.mV)
        irr.segment = seg
        seg.irregularlysampledsignals.append(irr)

    for ind2 in range(3):
        an = neo.AnalogSignal(name='AnalogSignal' + str(ind2), signal=np.random.rand(10) * qu.mV,
                              sampling_rate=10 * qu.Hz)
        an.segment = seg
        seg.analogsignals.append(an)