Esempio n. 1
0
    def test_spike_later_than_hilbert(self):
        # This is a spike clearly outside the bounds
        st = SpikeTrain([1, 250],
                        units='s',
                        t_start=-1 * pq.s,
                        t_stop=300 * pq.s)
        phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase(
            elephant.signal_processing.hilbert(self.anasig0),
            st,
            interpolate=False)
        self.assertEqual(len(phases_noint[0]), 1)

        # This is a spike right on the border (length of the signal is 100s,
        # spike sits at t=100s). However, by definition of intervals in
        # Elephant (left borders inclusive, right borders exclusive), this
        # spike is not to be considered.
        st = SpikeTrain([1, 100],
                        units='s',
                        t_start=-1 * pq.s,
                        t_stop=200 * pq.s)
        phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase(
            elephant.signal_processing.hilbert(self.anasig0),
            st,
            interpolate=False)
        self.assertEqual(len(phases_noint[0]), 1)
Esempio n. 2
0
def default_data(block=None, n_chidx=1, n_units=1):

    # generate new block if none provided, otherwise attach to provided block
    if block is None:
        block = Block()

    for id in range(n_chidx):
        sorting_hash = elephant.spike_sorting.SpikeSorter.get_sorting_hash({
            'channel_index':
            id,
            'random annotation':
            np.random.randint(0, 10**10)
        })
        chidx = ChannelIndex([], sorting_hash=sorting_hash)
        chidx.block = block
        block.channel_indexes.append(chidx)

    for chidx in block.channel_indexes:
        for id in range(n_units):
            unit = Unit(unit_id=id)
            chidx.units.append(unit)
            unit.channel_index = chidx

            for st_id in range(id):
                st = SpikeTrain(np.random.uniform(0, st_id, 1) * pq.s,
                                t_start=0 * pq.s,
                                t_stop=st_id * pq.s,
                                spiketrain_id=st_id)
                unit.spiketrains.append(st)
                st.unit = unit

    block.create_relationship()
    return block
Esempio n. 3
0
    def test_write_read_single_spike(self):
        block1 = Block()
        seg = Segment('segment1')
        spiketrain1 = SpikeTrain([1] * pq.s,
                                 t_stop=10 * pq.s,
                                 sampling_rate=1 * pq.Hz)
        spiketrain1.annotate(yep='yop')
        block1.segments.append(seg)
        seg.spiketrains.append(spiketrain1)

        # write block
        filename = self.get_local_path('matlabiotestfile.mat')
        io1 = self.ioclass(filename)
        io1.write_block(block1)

        # read block
        io2 = self.ioclass(filename)
        block2 = io2.read_block()

        self.assertEqual(block1.segments[0].spiketrains[0],
                         block2.segments[0].spiketrains[0])

        # test annotations
        spiketrain2 = block2.segments[0].spiketrains[0]
        assert 'yep' in spiketrain2.annotations
        assert spiketrain2.annotations['yep'] == 'yop'
Esempio n. 4
0
 def setUp(self):
     self.asiga0 = AnalogSignal(np.array(
         [np.sin(np.arange(0, 20 * math.pi, 0.1))]).T,
                                units='mV',
                                sampling_rate=10 / ms)
     self.asiga1 = AnalogSignal(np.array([
         np.sin(np.arange(0, 20 * math.pi, 0.1)),
         np.cos(np.arange(0, 20 * math.pi, 0.1))
     ]).T,
                                units='mV',
                                sampling_rate=10 / ms)
     self.asiga2 = AnalogSignal(np.array([
         np.sin(np.arange(0, 20 * math.pi, 0.1)),
         np.cos(np.arange(0, 20 * math.pi, 0.1)),
         np.tan(np.arange(0, 20 * math.pi, 0.1))
     ]).T,
                                units='mV',
                                sampling_rate=10 / ms)
     self.st0 = SpikeTrain(
         [9 * math.pi, 10 * math.pi, 11 * math.pi, 12 * math.pi],
         units='ms',
         t_stop=self.asiga0.t_stop)
     self.lst = [
         SpikeTrain([9 * math.pi, 10 * math.pi, 11 * math.pi, 12 * math.pi],
                    units='ms',
                    t_stop=self.asiga1.t_stop),
         SpikeTrain([30, 35, 40], units='ms', t_stop=self.asiga1.t_stop)
     ]
Esempio n. 5
0
    def setUp(self):
        # standard testsignals
        tlen0 = 100 * pq.s
        f0 = 20. * pq.Hz
        fs0 = 1 * pq.ms
        t0 = np.arange(
            0, tlen0.rescale(pq.s).magnitude,
            fs0.rescale(pq.s).magnitude) * pq.s
        self.anasig0 = AnalogSignal(
            np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0)
        self.st0 = SpikeTrain(
            np.arange(0, tlen0.rescale(pq.ms).magnitude, 50) * pq.ms,
            t_start=0 * pq.ms, t_stop=tlen0)
        self.bst0 = BinnedSpikeTrain(self.st0, binsize=fs0)

        # shortened analogsignals
        self.anasig1 = self.anasig0.time_slice(1 * pq.s, None)
        self.anasig2 = self.anasig0.time_slice(None, 99 * pq.s)

        # increased sampling frequency
        fs1 = 0.1 * pq.ms
        self.anasig3 = AnalogSignal(
            np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs1)
        self.bst1 = BinnedSpikeTrain(
            self.st0.time_slice(self.anasig3.t_start, self.anasig3.t_stop),
            binsize=fs1)

        # analogsignal containing multiple traces
        self.anasig4 = AnalogSignal(
            np.array([
                np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
                np.sin(4 * np.pi * (f0 * t0).simplified.magnitude)]).
            transpose(),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0)

        # shortened spike train
        self.st3 = SpikeTrain(
            np.arange(
                (tlen0.rescale(pq.ms).magnitude * .25),
                (tlen0.rescale(pq.ms).magnitude * .75), 50) * pq.ms,
            t_start=0 * pq.ms, t_stop=tlen0)
        self.bst3 = BinnedSpikeTrain(self.st3, binsize=fs0)

        self.st4 = SpikeTrain(np.arange(
            (tlen0.rescale(pq.ms).magnitude * .25),
            (tlen0.rescale(pq.ms).magnitude * .75), 50) * pq.ms,
            t_start=5 * fs0, t_stop=tlen0 - 5 * fs0)
        self.bst4 = BinnedSpikeTrain(self.st4, binsize=fs0)

        # spike train with incompatible binsize
        self.bst5 = BinnedSpikeTrain(self.st3, binsize=fs0 * 2.)

        # spike train with same binsize as the analog signal, but with
        # bin edges not aligned to the time axis of the analog signal
        self.bst6 = BinnedSpikeTrain(
            self.st3, binsize=fs0, t_start=4.5 * fs0, t_stop=tlen0 - 4.5 * fs0)
Esempio n. 6
0
 def test_one_spiketrain_empty(self):
     '''Test for one empty SpikeTrain, but existing spikes in other'''
     st = [SpikeTrain(
         [9 * math.pi, 10 * math.pi, 11 * math.pi, 12 * math.pi], 
         units='ms', t_stop=self.asiga1.t_stop), 
         SpikeTrain([], units='ms', t_stop=self.asiga1.t_stop)]
     STA = sta.spike_triggered_average(self.asiga1, st, (-1 * ms, 1 * ms))
     cmp_array = AnalogSignalArray(np.array([np.zeros(20, dtype=float)]).T,
         units='mV', sampling_rate=10 / ms)
     cmp_array = cmp_array / 0.
     cmp_array.t_start = -1 * ms
     assert_array_equal(STA[:, 1], cmp_array[:, 0])
Esempio n. 7
0
    def __init__(self, spk_trains, t_starts=None, t_stops=None):
        """Create a Spikes instance."""

        # Create empty instance.
        self.spk_trains = None
        self.t_starts = None
        self.t_stops = None

        # Init t_starts and t_stops.
        # Below deals with single values, including None.
        n_trs = len(spk_trains)
        if not util.is_iterable(t_starts):
            t_starts = n_trs * [t_starts]
        if not util.is_iterable(t_stops):
            t_stops = n_trs * [t_stops]

        # Convert into Pandas Series for speed and more functionality.
        self.t_starts = pd.Series(t_starts)
        self.t_stops = pd.Series(t_stops)

        # Create list of Neo SpikeTrain objects.
        self.spk_trains = pd.Series(index=np.arange(n_trs), dtype=object)
        for i in self.spk_trains.index:

            # Remove spikes outside of time window.
            t_start, t_stop = self.t_starts[i], self.t_stops[i]
            spk_tr = util.values_in_window(spk_trains[i], t_start, t_stop)
            self.spk_trains[i] = SpikeTrain(spk_tr,
                                            t_start=t_start,
                                            t_stop=t_stop)
Esempio n. 8
0
 def test_one_spiketrain_empty(self):
     """Test for one empty SpikeTrain, but existing spikes in other"""
     st = [SpikeTrain(
         [9 * math.pi, 10 * math.pi, 11 * math.pi, 12 * math.pi],
         units='ms', t_stop=self.asiga1.t_stop),
         SpikeTrain([], units='ms', t_stop=self.asiga1.t_stop)]
     with warnings.catch_warnings():
         warnings.simplefilter("ignore")
         """
         Ignore the RuntimeWarning: invalid value encountered in true_divide
         new_signal = f(other, *args) for the empty SpikeTrain.
         """
         STA = sta.spike_triggered_average(self.asiga1,
                                           spiketrains=st,
                                           window=(-1 * ms, 1 * ms))
     assert np.isnan(STA.magnitude[:, 1]).all()
Esempio n. 9
0
 def test_spike_earlier_than_analogsignal(self):
     st = SpikeTrain([-1 * math.pi, 2 * math.pi],
                     units='ms',
                     t_start=-2 * math.pi,
                     t_stop=20 * math.pi)
     self.assertRaises(ValueError, sta.spike_triggered_average, self.asiga0,
                       st, (-2 * ms, 2 * ms))
Esempio n. 10
0
 def test_usage_of_spikes(self):
     st = SpikeTrain([16.5 * math.pi, 17.5 * math.pi,
         18.5 * math.pi, 19.5 * math.pi], units='ms', t_stop=20 * math.pi)
     STA = sta.spike_triggered_average(
         self.asiga0, st, (-math.pi * ms, math.pi * ms))
     self.assertEqual(STA.annotations['used_spikes'], 3)
     self.assertEqual(STA.annotations['unused_spikes'], 1)
Esempio n. 11
0
def _pool_spiketrains(trains, extremes='inner'):
    """
    Pool spikes from any number of spike trains into a unique spike train.

    Parameters
    ----------
    trains: list
        list of spike trains to merge

    extremes: str, optional
        Only spikes of a and b in the specified extremes are considered.
        * 'inner': pool all spikes from min(a.t_start b.t_start) to
           max(a.t_stop, b.t_stop)
        * 'outer': pool all spikes from max(a.tstart_ b.t_start) to
           min(a.t_stop, b.t_stop)
        Default: 'inner'

    Output
    ------
    neo.SpikeTrain containing all spikes in trains falling in the
    specified extremes
    """

    merge_trains = trains[0]
    for t in trains[1:]:
        merge_trains = _pool_two_spiketrains(
            merge_trains, t, extremes=extremes)
    t_start, t_stop = merge_trains.t_start, merge_trains.t_stop
    merge_trains = sorted(merge_trains)
    merge_trains = np.squeeze(merge_trains)
    merge_trains = SpikeTrain(
        merge_trains, t_stop=t_stop, t_start=t_start, units=trains[0].units)
    return merge_trains
Esempio n. 12
0
 def setUp(self):
     tlen0 = 100 * pq.s
     f0 = 20. * pq.Hz
     fs0 = 1 * pq.ms
     t0 = np.arange(
         0, tlen0.rescale(pq.s).magnitude,
         fs0.rescale(pq.s).magnitude) * pq.s
     self.anasig0 = AnalogSignal(
         np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
         units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0)
     self.st0 = SpikeTrain(
         np.arange(50, tlen0.rescale(pq.ms).magnitude - 50, 50) * pq.ms,
         t_start=0 * pq.ms, t_stop=tlen0)
     self.st1 = SpikeTrain(
         [100., 100.1, 100.2, 100.3, 100.9, 101.] * pq.ms,
         t_start=0 * pq.ms, t_stop=tlen0)
Esempio n. 13
0
def _cpp_hom_stat(A, t_stop, rate, t_start=0 * ms):
    """
    Generate a Compound Poisson Process (CPP) with amplitude distribution
    A and heterogeneous firing rates r=r[0], r[1], ..., r[-1].

    Parameters
    ----------
    A : numpy.ndarray
        Amplitude distribution. A[j] represents the probability of a
        synchronous event of size j.
        The sum over all entries of A must be equal to one.
    t_stop : quantities.Quantity
        The end time of the output spike trains
    rate : quantities.Quantity
        Average rate of each spike train generated
    t_start : quantities.Quantity, optional
        The start time of the output spike trains
        Default: 0 ms

    Output
    ------
    List of n neo.SpikeTrains, having average firing rate r and correlated
    such to form a CPP with amplitude distribution a
    """

    # Generate mother process and associated spike labels
    mother = _mother_proc_cpp_stat(
        A=A, t_stop=t_stop, rate=rate, t_start=t_start)
    labels = _sample_int_from_pdf(A, len(mother))

    N = len(A) - 1  # Number of trains in output

    try:  # Faster but more memory-consuming approach
        M = len(mother)  # number of spikes in the mother process
        spike_matrix = np.zeros((N, M), dtype=bool)
        # for each spike, take its label l
        for spike_id, l in enumerate(labels):
            # choose l random trains
            train_ids = random.sample(range(N), l)
            # and set the spike matrix for that train
            for train_id in train_ids:
                spike_matrix[train_id, spike_id] = True  # and spike to True

        times = [[] for i in range(N)]
        for train_id, row in enumerate(spike_matrix):
            times[train_id] = mother[row].view(Quantity)

    except MemoryError:  # Slower (~2x) but less memory-consuming approach
        print('memory case')
        times = [[] for i in range(N)]
        for t, l in zip(mother, labels):
            train_ids = random.sample(range(N), l)
            for train_id in train_ids:
                times[train_id].append(t)

    trains = [SpikeTrain(
        times=t, t_start=t_start, t_stop=t_stop) for t in times]

    return trains
Esempio n. 14
0
    def setUp(self):
        # standard testsignals
        tlen0 = 100 * pq.s
        f0 = 20. * pq.Hz
        fs0 = 1 * pq.ms
        t0 = np.arange(
            0, tlen0.rescale(pq.s).magnitude,
            fs0.rescale(pq.s).magnitude) * pq.s
        self.anasig0 = AnalogSignal(
            np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0)
        self.st0 = SpikeTrain(
            np.arange(0, tlen0.rescale(pq.ms).magnitude, 50) * pq.ms,
            t_start=0 * pq.ms, t_stop=tlen0)
        self.bst0 = BinnedSpikeTrain(self.st0, binsize=fs0)

        # shortened analogsignals
        self.anasig1 = self.anasig0.time_slice(1 * pq.s, None)
        self.anasig2 = self.anasig0.time_slice(None, 99 * pq.s)

        # increased sampling frequency
        fs1 = 0.1 * pq.ms
        self.anasig3 = AnalogSignal(
            np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs1)
        self.bst1 = BinnedSpikeTrain(
            self.st0.time_slice(self.anasig3.t_start, self.anasig3.t_stop),
            binsize=fs1)

        # analogsignal containing multiple traces
        self.anasig4 = AnalogSignal(
            np.array([
                np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
                np.sin(4 * np.pi * (f0 * t0).simplified.magnitude)]).
            transpose(),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0)

        # shortened spike train
        self.st3 = SpikeTrain(
            np.arange(
                (tlen0.rescale(pq.ms).magnitude * .25),
                (tlen0.rescale(pq.ms).magnitude * .75), 50) * pq.ms,
            t_start=0 * pq.ms, t_stop=tlen0)
        self.bst3 = BinnedSpikeTrain(self.st3, binsize=fs0)

        self.st4 = SpikeTrain(np.arange(
            (tlen0.rescale(pq.ms).magnitude * .25),
            (tlen0.rescale(pq.ms).magnitude * .75), 50) * pq.ms,
            t_start=5 * fs0, t_stop=tlen0 - 5 * fs0)
        self.bst4 = BinnedSpikeTrain(self.st4, binsize=fs0)

        # spike train with incompatible binsize
        self.bst5 = BinnedSpikeTrain(self.st3, binsize=fs0 * 2.)

        # spike train with same binsize as the analog signal, but with
        # bin edges not aligned to the time axis of the analog signal
        self.bst6 = BinnedSpikeTrain(
            self.st3, binsize=fs0, t_start=4.5 * fs0, t_stop=tlen0 - 4.5 * fs0)
Esempio n. 15
0
def get_instantaneous_FR(spiketrain,
                         sampling_period,
                         t_start=0.,
                         t_stop=5000.):
    from elephant.statistics import instantaneous_rate as ir_fnc
    from neo import SpikeTrain
    from quantities import ms

    spiketrain = SpikeTrain(spiketrain, t_stop, units='ms', t_start=t_start)
    return ir_fnc(spiketrain, sampling_period * ms, kernel='auto')
def threshold_detection(signal, threshold=0.0 * mV, sign='above'):
    """
    Returns the times when the analog signal crosses a threshold.
    Usually used for extracting spike times from a membrane potential.
    Adapted from version in NeuroTools.

    Parameters
    ----------
    signal : neo AnalogSignal object
        'signal' is an analog signal.
    threshold : A quantity, e.g. in mV
        'threshold' contains a value that must be reached
        for an event to be detected. Default: 0.0 * mV.
    sign : 'above' or 'below'
        'sign' determines whether to count thresholding crossings
        that cross above or below the threshold.
    format : None or 'raw'
        Whether to return as SpikeTrain (None)
        or as a plain array of times ('raw').

    Returns
    -------
    result_st : neo SpikeTrain object
        'result_st' contains the spike times of each of the events (spikes)
        extracted from the signal.
    """

    assert threshold is not None, "A threshold must be provided"

    if sign is 'above':
        cutout = np.where(signal > threshold)[0]
    elif sign in 'below':
        cutout = np.where(signal < threshold)[0]

    if len(cutout) <= 0:
        events_base = np.zeros(0)
    else:
        take = np.where(np.diff(cutout) > 1)[0] + 1
        take = np.append(0, take)

        time = signal.times
        events = time[cutout][take]

        events_base = events.magnitude
        if events_base is None:
            # This occurs in some Python 3 builds due to some
            # bug in quantities.
            events_base = np.array([event.magnitude
                                    for event in events])  # Workaround

    result_st = SpikeTrain(events_base,
                           units=signal.times.units,
                           t_start=signal.t_start,
                           t_stop=signal.t_stop)
    return result_st
Esempio n. 17
0
 def test_regression_269(self):
     # This is a spike train on a 30KHz sampling, one spike at 1s, one just
     # before the end of the signal
     cu = pq.CompoundUnit("1/30000.*s")
     st = SpikeTrain(
         [30000., (self.anasig0.t_stop - 1 * pq.s).rescale(cu).magnitude],
         units=pq.CompoundUnit("1/30000.*s"),
         t_start=-1 * pq.s, t_stop=300 * pq.s)
     phases_noint, _, _ = elephant.phase_analysis.spike_triggered_phase(
         elephant.signal_processing.hilbert(self.anasig0),
         st,
         interpolate=False)
     self.assertEqual(len(phases_noint[0]), 2)
Esempio n. 18
0
    def test_victor_purpura_matlab_comparison_int(self):

        repo_path =\
            r"unittest/spike_train_dissimilarity/victor_purpura_distance/data"

        files_to_download = [
            ("times_int.npy", "aa1411c04da3f58d8b8913ae2f935057"),
            ("matlab_results_int.npy", "7edd32e50edde12dc1ef4aa5f57f70fb")
        ]

        for filename, checksum in files_to_download:
            download_datasets(repo_path=f"{repo_path}/{filename}",
                              checksum=checksum)

        times_int = np.load(ELEPHANT_TMP_DIR / 'times_int.npy')
        mat_res_int = np.load(ELEPHANT_TMP_DIR / 'matlab_results_int.npy')

        r_int = SpikeTrain(times_int[0],
                           units='ms',
                           t_start=0,
                           t_stop=1000 * ms)
        s_int = SpikeTrain(times_int[1],
                           units='ms',
                           t_start=0,
                           t_stop=1000 * ms)
        t_int = SpikeTrain(times_int[2],
                           units='ms',
                           t_start=0,
                           t_stop=1000 * ms)

        vic_pur_result_int = stds.victor_purpura_distance(
            [r_int, s_int, t_int],
            cost_factor=1.0 / ms,
            kernel=None,
            sort=True,
            algorithm='intuitive')

        assert_array_equal(vic_pur_result_int, mat_res_int)
Esempio n. 19
0
    def test_victor_purpura_matlab_comparison_float(self):

        repo_path =\
            r"unittest/spike_train_dissimilarity/victor_purpura_distance/data"

        files_to_download = [
            ("times_float.npy", "ed1ff4d2c0eeed4a2b50a456803656be"),
            ("matlab_results_float.npy", "a17f049e7ad0ddf7ca812e86fdb92646")
        ]

        for filename, checksum in files_to_download:
            download_datasets(repo_path=f"{repo_path}/{filename}",
                              checksum=checksum)

        times_float = np.load(ELEPHANT_TMP_DIR / 'times_float.npy')
        mat_res_float = np.load(ELEPHANT_TMP_DIR / 'matlab_results_float.npy')

        r_float = SpikeTrain(times_float[0],
                             units='ms',
                             t_start=0,
                             t_stop=1000 * ms)
        s_float = SpikeTrain(times_float[1],
                             units='ms',
                             t_start=0,
                             t_stop=1000 * ms)
        t_float = SpikeTrain(times_float[2],
                             units='ms',
                             t_start=0,
                             t_stop=1000 * ms)

        vic_pur_result_float = stds.victor_purpura_distance(
            [r_float, s_float, t_float],
            cost_factor=1.0 / ms,
            kernel=None,
            sort=True,
            algorithm='intuitive')

        assert_array_almost_equal(vic_pur_result_float, mat_res_float)
Esempio n. 20
0
 def test_all_spiketrains_empty(self):
     st = SpikeTrain([], units='ms', t_stop=self.asiga1.t_stop)
     with warnings.catch_warnings(record=True) as w:
         # Cause all warnings to always be triggered.
         warnings.simplefilter("always")
         # Trigger warnings.
         STA = sta.spike_triggered_average(
             self.asiga1, st, (-1 * ms, 1 * ms))
         self.assertEqual("No spike at all was either found or used "
                          "for averaging", str(w[-1].message))
         nan_array = np.empty(20)
         nan_array.fill(np.nan)
         cmp_array = AnalogSignal(np.array([nan_array, nan_array]).T,
                                  units='mV', sampling_rate=10 / ms)
         assert_array_equal(STA.magnitude, cmp_array.magnitude)
Esempio n. 21
0
 def test_spike_triggered_average_with_n_spikes_on_constant_function(self):
     """Signal should average to the input"""
     const = 13.8
     x = const * np.ones(201)
     asiga = AnalogSignal(
         np.array([x]).T, units='mV', sampling_rate=10 / ms)
     st = SpikeTrain([3, 5.6, 7, 7.1, 16, 16.3], units='ms', t_stop=20)
     window_starttime = -2 * ms
     window_endtime = 2 * ms
     STA = sta.spike_triggered_average(
         asiga, st, (window_starttime, window_endtime))
     a = int(((window_endtime - window_starttime) *
              asiga.sampling_rate).simplified)
     cutout = asiga[0: a]
     cutout.t_start = window_starttime
     assert_array_almost_equal(STA, cutout, 12)
Esempio n. 22
0
 def test_only_one_spike(self):
     """The output should be the same as the input"""
     x = np.arange(0, 20, 0.1)
     y = x**2
     sr = 10 / ms
     z = AnalogSignal(np.array([y]).T, units='mV', sampling_rate=sr)
     spiketime = 8 * ms
     spiketime_in_ms = int((spiketime / ms).simplified)
     st = SpikeTrain([spiketime_in_ms], units='ms', t_stop=20)
     window_starttime = -3 * ms
     window_endtime = 5 * ms
     STA = sta.spike_triggered_average(
         z, st, (window_starttime, window_endtime))
     cutout = z[int(((spiketime + window_starttime) * sr).simplified):
                int(((spiketime + window_endtime) * sr).simplified)]
     cutout.t_start = window_starttime
     assert_array_equal(STA, cutout)
Esempio n. 23
0
def _pool_two_spiketrains(a, b, extremes='inner'):
    """
    Pool the spikes of two spike trains a and b into a unique spike train.

    Parameters
    ----------
    a, b : neo.SpikeTrains
        Spike trains to be pooled

    extremes: str, optional
        Only spikes of a and b in the specified extremes are considered.
        * 'inner': pool all spikes from max(a.tstart_ b.t_start) to
           min(a.t_stop, b.t_stop)
        * 'outer': pool all spikes from min(a.tstart_ b.t_start) to
           max(a.t_stop, b.t_stop)
        Default: 'inner'

    Output
    ------
    neo.SpikeTrain containing all spikes in a and b falling in the
    specified extremes
    """

    unit = a.units
    times_a_dimless = list(a.view(Quantity).magnitude)
    times_b_dimless = list(b.rescale(unit).view(Quantity).magnitude)
    times = (times_a_dimless + times_b_dimless) * unit

    if extremes == 'outer':
        t_start = min(a.t_start, b.t_start)
        t_stop = max(a.t_stop, b.t_stop)
    elif extremes == 'inner':
        t_start = max(a.t_start, b.t_start)
        t_stop = min(a.t_stop, b.t_stop)
        times = times[times > t_start]
        times = times[times < t_stop]

    else:
        raise ValueError('extremes (%s) can only be "inner" or "outer"' %
                         extremes)
    pooled_train = SpikeTrain(times=sorted(times.magnitude),
                              units=unit,
                              t_start=t_start,
                              t_stop=t_stop)
    return pooled_train
    def test_write_read_single_spike(self):
        block1 = Block()
        seg = Segment('segment1')
        spiketrain = SpikeTrain([1] * pq.s, t_stop=10 * pq.s, sampling_rate=1 * pq.Hz)
        block1.segments.append(seg)
        seg.spiketrains.append(spiketrain)

        # write block
        filename = BaseTestIO.get_filename_path(self, 'matlabiotestfile.mat')
        io1 = self.ioclass(filename)
        io1.write_block(block1)

        # read block
        io2 = self.ioclass(filename)
        block2 = io2.read_block()

        self.assertEqual(block1.segments[0].spiketrains[0],
                         block2.segments[0].spiketrains[0])
Esempio n. 25
0
    def setUp(self):
        # standard testsignals
        tlen0 = 100 * pq.s
        f0 = 20. * pq.Hz
        fs0 = 1 * pq.ms
        t0 = np.arange(
            0, tlen0.rescale(pq.s).magnitude,
            fs0.rescale(pq.s).magnitude) * pq.s
        self.anasig0 = AnalogSignal(
            np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0)
        self.st0 = SpikeTrain(
            np.arange(0, tlen0.rescale(pq.ms).magnitude, 50) * pq.ms,
            t_start=0 * pq.ms, t_stop=tlen0)
        self.bst0 = BinnedSpikeTrain(self.st0, bin_size=fs0)

        def test_old_scipy_version(self):
            self.assertRaises(AttributeError, sta.spike_field_coherence,
                              self.anasig0, self.bst0)
Esempio n. 26
0
def _homogeneous_process(interval_generator, args, mean_rate, t_start, t_stop,
                         as_array):
    """
    Returns a spike train whose spikes are a realization of a random process
    generated by the function `interval_generator` with the given rate,
    starting at time `t_start` and stopping `time t_stop`.
    """
    def rescale(x):
        return (x / mean_rate.units).rescale(t_stop.units)

    n = int(((t_stop - t_start) * mean_rate).simplified)
    number = np.ceil(n + 3 * np.sqrt(n))
    if number < 100:
        number = min(5 + np.ceil(2 * n), 100)
    assert number > 4  # if positive, number cannot be less than 5
    isi = rescale(interval_generator(*args, size=int(number)))
    spikes = np.cumsum(isi)
    spikes += t_start

    i = spikes.searchsorted(t_stop)
    if i == len(spikes):
        # ISI buffer overrun
        extra_spikes = []
        t_last = spikes[-1] + rescale(interval_generator(*args, size=1))[0]
        while t_last < t_stop:
            extra_spikes.append(t_last)
            t_last = t_last + rescale(interval_generator(*args, size=1))[0]
        # np.concatenate does not conserve units
        spikes = Quantity(np.concatenate((spikes, extra_spikes)).magnitude,
                          units=spikes.units)
    else:
        spikes = spikes[:i]

    if as_array:
        spikes = spikes.magnitude
    else:
        spikes = SpikeTrain(spikes,
                            t_start=t_start,
                            t_stop=t_stop,
                            units=spikes.units)

    return spikes
Esempio n. 27
0
    def get_spikes(self, trs=None, t1s=None, t2s=None, ref_ts=None):
        """Return spike times of given trials within time windows."""

        # Init trials and time limits.
        trs = self.init_trials(trs)
        t1s, t2s, ref_ts = self.init_time_limits(t1s, t2s, ref_ts)

        # Assamble time-windowed spike trains.
        spk_trains = pd.Series(index=trs, dtype=object)
        for itr in trs:
            # Select spikes between t1 and t2 during selected trials, and
            # convert them into new SpikeTrain list, with time limits set.
            t1, t2, tr = t1s[itr], t2s[itr], ref_ts[itr]
            spk_tr = util.values_in_window(self.spk_trains[itr], t1, t2)
            spk_tr, t1, t2 = spk_tr - tr, t1 - tr, t2 - tr  # align to reference time
            # Need to check range once again to deal with rounding errors.
            spk_tr = util.values_in_window(spk_tr, t1, t2)
            spk_trains[itr] = SpikeTrain(spk_tr, t_start=t1, t_stop=t2)

        return spk_trains
Esempio n. 28
0
def calc_corellation(spike_times, spike_ids, num, duration, bin_x=None):
    # Create randomly shuffled indices
    neuron_indices = np.arange(num)
    np.random.shuffle(neuron_indices)

    # Loop through indices
    spike_trains = []
    for n in neuron_indices:
        # Extract spike times
        neuron_spike_times = spike_times[spike_ids == n]

        # If there are any spikes
        if len(neuron_spike_times) > 0:
            # Add neo SpikeTrain object
            spike_trains.append(
                SpikeTrain(neuron_spike_times * ms,
                           t_start=1 * s,
                           t_stop=10 * s))

            # If we have found our 200 spike trains, stop
            if len(spike_trains) == 200:
                break

    # Check that 200 spike trains containing spikes could be found
    assert len(spike_trains) == 200

    # Bin spikes using bins corresponding to 2ms refractory period
    binned_spike_trains = BinnedSpikeTrain(spike_trains, binsize=2.0 * ms)

    # Calculate correlation matrix
    correlation = corrcoef(binned_spike_trains)

    # Take lower triangle of matrix (minus diagonal)
    correlation_non_disjoint = correlation[np.tril_indices_from(correlation,
                                                                k=-1)]

    # Calculate histogram
    return calc_histogram(correlation_non_disjoint, 0.002, bin_x)
Esempio n. 29
0
        event = Event(name="Seg {} :: Event".format(idx),
                      times=event_times,
                      labels=["A", "B", "C", "D", "E"])
        seg.events.append(event)

        epoch_times = tstart + np.cumsum(np.array([0,1,2])) * pq.ms
        epoch = Epoch(name="Seg {} :: Epoch".format(idx),
                      times=epoch_times,
                      durations=np.array([0,1,2])*pq.ms,
                      labels=["A+", "B+", "C+"])
        seg.epochs.append(epoch)

        tstart = 10 *pq.s
        st_times = tstart + np.cumsum(np.arange(0,1,0.1)) * pq.s
        tstop = max(event_times[-1], epoch_times[-1], st_times[-1]) + 1 * pq.s
        st = SpikeTrain(name="Seg {} :: SpikeTrain".format(idx),
                        times=st_times, t_start=tstart, t_stop=tstop)
        wf = np.random.random((len(st_times), nchannels, 30)) * pq.mV
        st.waveforms = wf
        st.sampling_rate = sampling_rate

        seg.spiketrains.append(st)

        unit = Unit(name="unit-{}".format(idx))
        print(unit)
        unit.spiketrains.append(st)
        chx.units.append(unit)
# Write the Block to file using the NixIO
# Any existing file will be overwritten
fname = "test_case.nix"
io = NixIO(fname, "ow")
io.write_block(block1)
Esempio n. 30
0
class sfc_TestCase_new_scipy(unittest.TestCase):

    def setUp(self):
        # standard testsignals
        tlen0 = 100 * pq.s
        f0 = 20. * pq.Hz
        fs0 = 1 * pq.ms
        t0 = np.arange(
            0, tlen0.rescale(pq.s).magnitude,
            fs0.rescale(pq.s).magnitude) * pq.s
        self.anasig0 = AnalogSignal(
            np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0)
        self.st0 = SpikeTrain(
            np.arange(0, tlen0.rescale(pq.ms).magnitude, 50) * pq.ms,
            t_start=0 * pq.ms, t_stop=tlen0)
        self.bst0 = BinnedSpikeTrain(self.st0, binsize=fs0)

        # shortened analogsignals
        self.anasig1 = self.anasig0.time_slice(1 * pq.s, None)
        self.anasig2 = self.anasig0.time_slice(None, 99 * pq.s)

        # increased sampling frequency
        fs1 = 0.1 * pq.ms
        self.anasig3 = AnalogSignal(
            np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs1)
        self.bst1 = BinnedSpikeTrain(
            self.st0.time_slice(self.anasig3.t_start, self.anasig3.t_stop),
            binsize=fs1)

        # analogsignal containing multiple traces
        self.anasig4 = AnalogSignal(
            np.array([
                np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
                np.sin(4 * np.pi * (f0 * t0).simplified.magnitude)]).
            transpose(),
            units=pq.mV, t_start=0 * pq.ms, sampling_period=fs0)

        # shortened spike train
        self.st3 = SpikeTrain(
            np.arange(
                (tlen0.rescale(pq.ms).magnitude * .25),
                (tlen0.rescale(pq.ms).magnitude * .75), 50) * pq.ms,
            t_start=0 * pq.ms, t_stop=tlen0)
        self.bst3 = BinnedSpikeTrain(self.st3, binsize=fs0)

        self.st4 = SpikeTrain(np.arange(
            (tlen0.rescale(pq.ms).magnitude * .25),
            (tlen0.rescale(pq.ms).magnitude * .75), 50) * pq.ms,
            t_start=5 * fs0, t_stop=tlen0 - 5 * fs0)
        self.bst4 = BinnedSpikeTrain(self.st4, binsize=fs0)

        # spike train with incompatible binsize
        self.bst5 = BinnedSpikeTrain(self.st3, binsize=fs0 * 2.)

        # spike train with same binsize as the analog signal, but with
        # bin edges not aligned to the time axis of the analog signal
        self.bst6 = BinnedSpikeTrain(
            self.st3, binsize=fs0, t_start=4.5 * fs0, t_stop=tlen0 - 4.5 * fs0)

    # =========================================================================
    # Tests for correct input handling
    # =========================================================================

    def test_wrong_input_type(self):
        self.assertRaises(TypeError,
                          sta.spike_field_coherence,
                          np.array([1, 2, 3]), self.bst0)
        self.assertRaises(TypeError,
                          sta.spike_field_coherence,
                          self.anasig0, [1, 2, 3])
        self.assertRaises(ValueError,
                          sta.spike_field_coherence,
                          self.anasig0.duplicate_with_new_array([]), self.bst0)

    def test_start_stop_times_out_of_range(self):
        self.assertRaises(ValueError,
                          sta.spike_field_coherence,
                          self.anasig1, self.bst0)

        self.assertRaises(ValueError,
                          sta.spike_field_coherence,
                          self.anasig2, self.bst0)

    def test_non_matching_input_binning(self):
        self.assertRaises(ValueError,
                          sta.spike_field_coherence,
                          self.anasig0, self.bst1)

    def test_incompatible_spiketrain_analogsignal(self):
        # These spike trains have incompatible binning (binsize or alignment to
        # time axis of analog signal)
        self.assertRaises(ValueError,
                          sta.spike_field_coherence,
                          self.anasig0, self.bst5)
        self.assertRaises(ValueError,
                          sta.spike_field_coherence,
                          self.anasig0, self.bst6)

    def test_signal_dimensions(self):
        # single analogsignal trace and single spike train
        s_single, f_single = sta.spike_field_coherence(self.anasig0, self.bst0)

        self.assertEqual(len(f_single.shape), 1)
        self.assertEqual(len(s_single.shape), 2)

        # multiple analogsignal traces and single spike train
        s_multi, f_multi = sta.spike_field_coherence(self.anasig4, self.bst0)

        self.assertEqual(len(f_multi.shape), 1)
        self.assertEqual(len(s_multi.shape), 2)

        # frequencies are identical since same sampling frequency was used
        # in both cases and data length is the same
        assert_array_equal(f_single, f_multi)
        # coherences of s_single and first signal in s_multi are identical,
        # since first analogsignal trace in anasig4 is same as in anasig0
        assert_array_equal(s_single[:, 0], s_multi[:, 0])

    def test_non_binned_spiketrain_input(self):
        s, f = sta.spike_field_coherence(self.anasig0, self.st0)

        f_ind = np.where(f >= 19.)[0][0]
        max_ind = np.argmax(s[1:]) + 1

        self.assertEqual(f_ind, max_ind)
        self.assertAlmostEqual(s[f_ind], 1., delta=0.01)

    # =========================================================================
    # Tests for correct return values
    # =========================================================================

    def test_spike_field_coherence_perfect_coherence(self):
        # check for detection of 20Hz peak in anasig0/bst0
        s, f = sta.spike_field_coherence(
            self.anasig0, self.bst0, window='boxcar')

        f_ind = np.where(f >= 19.)[0][0]
        max_ind = np.argmax(s[1:]) + 1

        self.assertEqual(f_ind, max_ind)
        self.assertAlmostEqual(s[f_ind], 1., delta=0.01)

    def test_output_frequencies(self):
        nfft = 256
        _, f = sta.spike_field_coherence(self.anasig3, self.bst1, nfft=nfft)

        # check number of frequency samples
        self.assertEqual(len(f), nfft / 2 + 1)

        # check values of frequency samples
        assert_array_almost_equal(
            f, np.linspace(
                0, self.anasig3.sampling_rate.rescale('Hz').magnitude / 2,
                nfft / 2 + 1) * pq.Hz)

    def test_short_spiketrain(self):
        # this spike train has the same length as anasig0
        s1, f1 = sta.spike_field_coherence(
            self.anasig0, self.bst3, window='boxcar')

        # this spike train has the same spikes as above, but is shorter than
        # anasig0
        s2, f2 = sta.spike_field_coherence(
            self.anasig0, self.bst4, window='boxcar')

        # the results above should be the same, nevertheless
        assert_array_equal(s1.magnitude, s2.magnitude)
        assert_array_equal(f1.magnitude, f2.magnitude)
Esempio n. 31
0
class sfc_TestCase_new_scipy(unittest.TestCase):
    def setUp(self):
        # standard testsignals
        tlen0 = 100 * pq.s
        f0 = 20. * pq.Hz
        fs0 = 1 * pq.ms
        t0 = np.arange(0,
                       tlen0.rescale(pq.s).magnitude,
                       fs0.rescale(pq.s).magnitude) * pq.s
        self.anasig0 = AnalogSignal(np.sin(2 * np.pi *
                                           (f0 * t0).simplified.magnitude),
                                    units=pq.mV,
                                    t_start=0 * pq.ms,
                                    sampling_period=fs0)
        self.st0 = SpikeTrain(np.arange(0,
                                        tlen0.rescale(pq.ms).magnitude, 50) *
                              pq.ms,
                              t_start=0 * pq.ms,
                              t_stop=tlen0)
        self.bst0 = BinnedSpikeTrain(self.st0, bin_size=fs0)

        # shortened analogsignals
        self.anasig1 = self.anasig0.time_slice(1 * pq.s, None)
        self.anasig2 = self.anasig0.time_slice(None, 99 * pq.s)

        # increased sampling frequency
        fs1 = 0.1 * pq.ms
        self.anasig3 = AnalogSignal(np.sin(2 * np.pi *
                                           (f0 * t0).simplified.magnitude),
                                    units=pq.mV,
                                    t_start=0 * pq.ms,
                                    sampling_period=fs1)
        self.bst1 = BinnedSpikeTrain(self.st0.time_slice(
            self.anasig3.t_start, self.anasig3.t_stop),
                                     bin_size=fs1)

        # analogsignal containing multiple traces
        self.anasig4 = AnalogSignal(np.array([
            np.sin(2 * np.pi * (f0 * t0).simplified.magnitude),
            np.sin(4 * np.pi * (f0 * t0).simplified.magnitude)
        ]).transpose(),
                                    units=pq.mV,
                                    t_start=0 * pq.ms,
                                    sampling_period=fs0)

        # shortened spike train
        self.st3 = SpikeTrain(np.arange(
            (tlen0.rescale(pq.ms).magnitude * .25),
            (tlen0.rescale(pq.ms).magnitude * .75), 50) * pq.ms,
                              t_start=0 * pq.ms,
                              t_stop=tlen0)
        self.bst3 = BinnedSpikeTrain(self.st3, bin_size=fs0)

        self.st4 = SpikeTrain(np.arange(
            (tlen0.rescale(pq.ms).magnitude * .25),
            (tlen0.rescale(pq.ms).magnitude * .75), 50) * pq.ms,
                              t_start=5 * fs0,
                              t_stop=tlen0 - 5 * fs0)
        self.bst4 = BinnedSpikeTrain(self.st4, bin_size=fs0)

        # spike train with incompatible bin_size
        self.bst5 = BinnedSpikeTrain(self.st3, bin_size=fs0 * 2.)

        # spike train with same bin_size as the analog signal, but with
        # bin edges not aligned to the time axis of the analog signal
        self.bst6 = BinnedSpikeTrain(self.st3,
                                     bin_size=fs0,
                                     t_start=4.5 * fs0,
                                     t_stop=tlen0 - 4.5 * fs0)

    # =========================================================================
    # Tests for correct input handling
    # =========================================================================

    def test_wrong_input_type(self):
        self.assertRaises(TypeError, sta.spike_field_coherence,
                          np.array([1, 2, 3]), self.bst0)
        self.assertRaises(TypeError, sta.spike_field_coherence, self.anasig0,
                          [1, 2, 3])
        self.assertRaises(ValueError, sta.spike_field_coherence,
                          self.anasig0.duplicate_with_new_data([]), self.bst0)

    def test_start_stop_times_out_of_range(self):
        self.assertRaises(ValueError, sta.spike_field_coherence, self.anasig1,
                          self.bst0)

        self.assertRaises(ValueError, sta.spike_field_coherence, self.anasig2,
                          self.bst0)

    def test_non_matching_input_binning(self):
        self.assertRaises(ValueError, sta.spike_field_coherence, self.anasig0,
                          self.bst1)

    def test_incompatible_spiketrain_analogsignal(self):
        # These spike trains have incompatible binning (bin_size or alignment
        # to time axis of analog signal)
        self.assertRaises(ValueError, sta.spike_field_coherence, self.anasig0,
                          self.bst5)
        self.assertRaises(ValueError, sta.spike_field_coherence, self.anasig0,
                          self.bst6)

    def test_signal_dimensions(self):
        # single analogsignal trace and single spike train
        s_single, f_single = sta.spike_field_coherence(self.anasig0, self.bst0)

        self.assertEqual(len(f_single.shape), 1)
        self.assertEqual(len(s_single.shape), 2)

        # multiple analogsignal traces and single spike train
        s_multi, f_multi = sta.spike_field_coherence(self.anasig4, self.bst0)

        self.assertEqual(len(f_multi.shape), 1)
        self.assertEqual(len(s_multi.shape), 2)

        # frequencies are identical since same sampling frequency was used
        # in both cases and data length is the same
        assert_array_equal(f_single, f_multi)
        # coherences of s_single and first signal in s_multi are identical,
        # since first analogsignal trace in anasig4 is same as in anasig0
        assert_array_equal(s_single[:, 0], s_multi[:, 0])

    def test_non_binned_spiketrain_input(self):
        s, f = sta.spike_field_coherence(self.anasig0, self.st0)

        f_ind = np.where(f >= 19.)[0][0]
        max_ind = np.argmax(s[1:]) + 1

        self.assertEqual(f_ind, max_ind)
        self.assertAlmostEqual(s[f_ind], 1., delta=0.01)

    # =========================================================================
    # Tests for correct return values
    # =========================================================================

    def test_spike_field_coherence_perfect_coherence(self):
        # check for detection of 20Hz peak in anasig0/bst0
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            """
            When the spiketrain is a vector with zero values, ignore the
            warning RuntimeWarning: invalid value encountered in true_divide
              Cxy = np.abs(Pxy)**2 / Pxx / Pyy.
            """
            s, f = sta.spike_field_coherence(self.anasig0,
                                             self.bst0,
                                             window='boxcar')

        f_ind = np.where(f >= 19.)[0][0]
        max_ind = np.argmax(s[1:]) + 1

        self.assertEqual(f_ind, max_ind)
        self.assertAlmostEqual(s[f_ind], 1., delta=0.01)

    def test_output_frequencies(self):
        nfft = 256
        _, f = sta.spike_field_coherence(self.anasig3, self.bst1, nfft=nfft)

        # check number of frequency samples
        self.assertEqual(len(f), nfft / 2 + 1)

        f_max = self.anasig3.sampling_rate.rescale('Hz').magnitude / 2
        f_ground_truth = np.linspace(start=0, stop=f_max,
                                     num=nfft // 2 + 1) * pq.Hz

        # check values of frequency samples
        assert_array_almost_equal(f, f_ground_truth)

    def test_short_spiketrain(self):
        # this spike train has the same length as anasig0
        with warnings.catch_warnings():
            warnings.simplefilter("ignore")
            """
            When the spiketrain is a vector with zero values, ignore the
            warning RuntimeWarning: invalid value encountered in true_divide
              Cxy = np.abs(Pxy)**2 / Pxx / Pyy.
            """
            s1, f1 = sta.spike_field_coherence(self.anasig0,
                                               self.bst3,
                                               window='boxcar')

            # this spike train has the same spikes as above,
            # but it's shorter than anasig0
            s2, f2 = sta.spike_field_coherence(self.anasig0,
                                               self.bst4,
                                               window='boxcar')

        # the results above should be the same, nevertheless
        assert_array_equal(s1.magnitude, s2.magnitude)
        assert_array_equal(f1.magnitude, f2.magnitude)
Esempio n. 32
0
 def test_empty_analogsignal(self):
     asiga = AnalogSignal([], units='mV', sampling_rate=10 / ms)
     st = SpikeTrain([5], units='ms', t_stop=10)
     self.assertRaises(ValueError, sta.spike_triggered_average, asiga, st,
                       (-1 * ms, 1 * ms))