예제 #1
0
def test_pop_empty_array():
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="array")
    result = tsb.pop()

    assert isinstance(result, np.ndarray)
    assert result.shape == (0, 4)
    assert result.size == 0
예제 #2
0
def test_pop_empty_uarray():
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="uarray")
    result = tsb.show(n_samples=n_samples)

    assert isinstance(result, np.ndarray)
    assert result.shape == (0, 2)
    assert result.size == 0
예제 #3
0
def test_add_arrays():
    tsb = TimeSeriesBuffer(maxlen=maxlen)

    M = 4
    data = np.random.random((N, M))
    t = data[:, 0]
    ut = data[:, 1]
    v = data[:, 2]
    uv = data[:, 3]

    # add data to buffer in different combinations
    # and check if latest element of buffer corresponds to latest element of data
    ignore = tsb.empty_unc

    # no uncertainty information
    tsb.add(time=t, val=v)
    assert tsb.buffer[-1] == (data[-1, 0], ignore, data[-1, 2], ignore)

    # typical uncertainty information
    tsb.add(time=t, val=v, val_unc=uv)
    assert tsb.buffer[-1] == (data[-1, 0], ignore, data[-1, 2], data[-1, 3])

    # full uncertainty information
    tsb.add(time=t, time_unc=ut, val=v, val_unc=uv)
    assert tsb.buffer[-1] == (data[-1, 0], data[-1, 1], data[-1, 2], data[-1,
                                                                          3])

    # untypical uncertainty information
    tsb.add(time=t, time_unc=ut, val=v)
    assert tsb.buffer[-1] == (data[-1, 0], data[-1, 1], data[-1, 2], ignore)
예제 #4
0
def test_pop_empty_uarrays():
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="uarrays")
    t, v = tsb.show(n_samples=n_samples)

    assert isinstance(t, np.ndarray)
    assert isinstance(v, np.ndarray)
    assert t.size == 0
    assert v.size == 0
예제 #5
0
def test_return_format_list():
    M = 4
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="list")
    data = np.random.random((N, M))
    tsb.add(data=data)

    result = tsb.show(n_samples=n_samples)
    assert isinstance(result, list)
    assert isinstance(result[0], tuple)
    assert isinstance(result[0][0], float)
예제 #6
0
def test_return_format_array():
    M = 4
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="array")
    data = np.random.random((N, M))
    tsb.add(data=data)

    result = tsb.show(n_samples=n_samples)
    assert isinstance(result, np.ndarray)
    assert isinstance(result[0], np.ndarray)
    assert isinstance(result[0][0], float)
예제 #7
0
def test_return_format_uarrays():
    M = 4
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="uarrays")
    data = np.random.random((N, M))
    tsb.add(data=data)

    t, v = tsb.show(n_samples=n_samples)
    assert isinstance(t, np.ndarray)
    assert isinstance(v, np.ndarray)
    assert isinstance(t[0], uncertainties.core.Variable)
    assert isinstance(v[0], uncertainties.core.Variable)
예제 #8
0
def test_return_format_arrays():
    M = 4
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="arrays")
    data = np.random.random((N, M))
    tsb.add(data=data)

    t, ut, v, uv = tsb.show(n_samples=n_samples)
    assert isinstance(t, np.ndarray)
    assert isinstance(ut, np.ndarray)
    assert isinstance(v, np.ndarray)
    assert isinstance(uv, np.ndarray)
    assert isinstance(t[0], float)
    assert isinstance(ut[0], float)
    assert isinstance(v[0], float)
    assert isinstance(uv[0], float)
예제 #9
0
def test_show_all():

    M = 4
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="array")
    data = np.random.random((N, M))
    tsb.add(data=data)

    # return some buffer elements without pop
    result = tsb.show(n_samples=-1)

    # check that show does not alter the buffer
    assert len(result) == N

    # check if newest elements are received and order is as expected
    assert np.all(result == data)
예제 #10
0
def test_add_uarray():
    tsb = TimeSeriesBuffer(maxlen=maxlen)

    M = 4
    data = np.random.random((N, M))
    udata = unumpy.uarray(data[:, [0, 2]], data[:, [1, 3]])

    # add data to buffer
    tsb.add(data=udata)

    # check if number of buffer elements increased accordingly
    assert len(tsb) == min(N, maxlen)

    # check if latest element of buffer corresponds to latest element of data
    assert tsb.buffer[-1] == tuple(data[-1, :])
예제 #11
0
def test_show_size_and_order():
    n_samples = 7

    M = 4
    tsb = TimeSeriesBuffer(maxlen=maxlen, return_type="array")
    data = np.random.random((N, M))
    tsb.add(data=data)

    # return some buffer elements without pop
    length_before_show = len(tsb)
    result = tsb.show(n_samples=n_samples)
    length_after_show = len(tsb)

    # check that show does not alter the buffer
    assert length_before_show == length_after_show

    # check if newest elements are received and order is as expected
    assert np.all(result == data[-n_samples:, :])
예제 #12
0
def test_add_array():

    # init the buffer
    tsb = TimeSeriesBuffer(maxlen=maxlen)
    counter = 0

    # fill buffer with arrays of different shape
    for M in [2, 3, 4]:
        data = np.random.random((N, M))

        # add data to buffer
        tsb.add(data=data)

        # check if number of buffer elements increased accordingly
        counter += len(data)
        assert len(tsb) == min(counter, maxlen)

        # check if latest element of buffer corresponds to latest element of data
        # (because M changes, we only check if the timestamp (index=0) matches)
        assert tsb.buffer[-1][0] == data[-1, 0]
예제 #13
0
def test_pop_size_and_order():
    n_samples = 7

    M = 4
    tsb = TimeSeriesBuffer(maxlen=maxlen)
    data = np.random.random((N, M))
    tsb.add(data=data)

    # pop some buffer elements
    length_before_pop = len(tsb)
    result = tsb.pop(n_samples=n_samples)
    length_after_pop = len(tsb)

    # check output length and buffer size after pop
    if n_samples > length_before_pop:
        assert 0 == length_after_pop
    else:
        assert length_before_pop - n_samples == length_after_pop

    # check if really oldest elements are received
    assert np.all(result == data[0:n_samples, :])
예제 #14
0
    def set_output_data(self, channel, data=None, metadata=None):
        # create storage for new output channels
        if channel not in self._output_data.keys():
            self._output_data[channel] = {
                "metadata": metadata,
                "buffer": TimeSeriesBuffer(maxlen=self._output_data_maxlen),
            }

        if metadata is not None:
            # update received metadata
            self._output_data[channel]["metadata"] = metadata

        if data is not None:
            # append received data
            self._output_data[channel]["buffer"].add(data=data)
예제 #15
0
    def _set_input_data(self, sender, data=None, metadata=None):
        # create storage for new senders
        if sender not in self._input_data.keys():
            self._input_data[sender] = {
                "metadata": metadata,
                "buffer": TimeSeriesBuffer(maxlen=self._input_data_maxlen),
            }

        if metadata is not None:
            # update received metadata
            self._input_data[sender]["metadata"] = metadata

        if data is not None:
            # append received data
            self._input_data[sender]["buffer"].add(data=data)
예제 #16
0
def test_error_on_shape_mismatch():
    tsb = TimeSeriesBuffer(maxlen=maxlen)

    M = 4
    data = np.random.random((N, M))
    t = data[:, 0]
    ut = data[:, 1]
    v = data[:, 2]
    uv = data[:, 3]

    with pytest.raises(ValueError):
        tsb.add(time=t, time_unc=ut[:-2], val=v, val_unc=uv)

    with pytest.raises(ValueError):
        tsb.add(time=t, time_unc=ut, val=v[:-2], val_unc=uv)

    with pytest.raises(ValueError):
        tsb.add(time=t, time_unc=ut, val=v, val_unc=uv[:-2])
예제 #17
0
def main():
    # basics
    buffer_length = 120
    signal = Buffer(maxlen=buffer_length, return_type="arrays")
    cycle_duration = 0.1  # seconds
    plot_counter = 0
    dwt_counter = 0
    cycle_counter = 0

    # init wavelet stuff
    ld, hd, _, _ = wavelet.filter_design("db2")
    dwt_length = 21

    # init multi level wavelet stuff
    n_levels = 4
    output_multi_level = [n_levels] + [
        level for level in list(range(1, n_levels + 1))[::-1]
    ]  # highest level twice because we store detail + approx
    output_multi_buffer_maxlen = [
        buffer_length // 2 ** level for level in output_multi_level
    ]
    output_multi = [
        Buffer(maxlen=maxlen, return_type="arrays")
        for maxlen in output_multi_buffer_maxlen
    ]  # list of buffer (different lengths to approximately cover the same timespan)
    level_states = None

    # init plot
    plt.ion()
    fig = plt.figure()
    ax = fig.subplots(nrows=1 + len(output_multi), ncols=1, sharex=True)

    # init signal plot
    ax[0].set_ylabel("$x^{(0)}$")
    ax[0].set_ylim([-2, 2])
    (sm,) = ax[0].plot(0, 0, "-k")  # signal
    (su,) = ax[0].plot(0, 0, ":k", linewidth=0.8)  # upper unc
    (sl,) = ax[0].plot(0, 0, ":k", linewidth=0.8)  # lower unc

    # init coefficient plots
    c_lines = []
    for i, (level, _ax) in enumerate(zip(output_multi_level[::-1], ax[1:])):
        if i == len(ax[1:]) - 1:
            _ax.set_ylabel("$a^{{({0})}}$".format(level))
        else:
            _ax.set_ylabel("$d^{{({0})}}$".format(level))
        _ax.set_ylim(auto=True)
        ce = _ax.errorbar(
            0, 0, yerr=0, linewidth=0, elinewidth=2, color="gray", capsize=5
        )
        cm = _ax.scatter([0], [0], c="r", s=10)  # (detail) coeffs
        c_lines.append([cm, ce])
        _ax.set_ylim([-3, 3])

    # simulate infinite stream of data
    while True:
        cycle_counter += 1

        # ti = tm.time()
        ti = cycle_counter * cycle_duration
        ui = 0.15 * (np.sin(2 * ti) + 2)
        xi = np.sin(ti) + np.random.randn() * ui

        signal.add(time=ti, val=xi, val_unc=ui)

        # run DWT every <dwt_length> iterations
        dwt_counter += 1
        if dwt_counter % dwt_length == 0:
            t, _, v, u = signal.show(dwt_length)

            # multi level dwt with uncertainty
            coeffs, Ucoeffs, _, level_states = wavelet.wave_dec_realtime(
                v, u, ld, hd, n=n_levels, level_states=level_states
            )

            # assign correct timestamps to the coefficients
            i0_old = (level_states["counter"] - len(t)) % 2 ** n_levels
            time_indices = np.arange(i0_old, i0_old + len(t))

            # save results to data structure
            for c, u, buffer, level in zip(
                coeffs, Ucoeffs, output_multi, output_multi_level
            ):
                time_indices_level = (time_indices + 1) % 2 ** level == 0
                if (
                    time_indices_level.sum() > 0
                ):  # otherwise error from time-series-buffer
                    buffer.add(time=t[time_indices_level], val=c, val_unc=u)

            dwt_counter = 0

            # set dwt length until next cycle
            dwt_length = random.choice(
                [1, 2, 10, 21]
            )  # could also be constant, e.g. dwt_length = 20
            print(dwt_length)

        # update plot every 5 iterations
        plot_counter += 1
        if (
            plot_counter % 5 == 0 and cycle_counter > buffer_length
        ):  # skip plotting at startup, when buffer is still not fully filled
            # update plot

            # get data to plot
            t_signal, _, v_signal, u_signal = signal.show(-1)

            # update signal lines
            sm.set_xdata(t_signal)
            su.set_xdata(t_signal)
            sl.set_xdata(t_signal)
            sm.set_ydata(v_signal)
            su.set_ydata(v_signal + u_signal)
            sl.set_ydata(v_signal - u_signal)
            ax[0].set_xlim([min(t_signal), max(t_signal)])

            # update dwt lines
            for buffer, _ax, c_line in zip(output_multi[::-1], ax[1:], c_lines):
                if len(buffer) > 0:  # otherwise error from time-series-buffer
                    t_coeff, _, v_coeff, u_coeff = buffer.show(-1)

                    # change the scatter
                    data = np.c_[t_coeff, v_coeff]
                    c_line[0].set_offsets(data)
                    c_line[0].set_facecolor(["r"] * len(t_coeff))

                    # change the error bars
                    c_line[1].remove()
                    c_line[1] = _ax.errorbar(
                        t_coeff,
                        v_coeff,
                        yerr=u_coeff,
                        linewidth=0,
                        elinewidth=1.5,
                        color="gray",
                        capsize=3,
                        zorder=0,
                    )
                    upper_unc = v_coeff + u_coeff
                    lower_unc = v_coeff - u_coeff

                    if v_coeff.size != 0:
                        lim = [np.min(lower_unc), np.max(upper_unc)]
                        _ax.set_ylim(lim)

            # finally update the plot itself
            fig.tight_layout()
            fig.align_ylabels(ax)
            fig.canvas.draw()
            fig.canvas.flush_events()

            # reset plot counter
            plot_counter = 0