def test_speed(self):
        guard_len = 5
        awgn_len = 200
        frame_period = 3000 * 2
        pseq_lvl2_len = len(random_sequence.maximum_length_sequence(13 *
                                                                    8))  #13*4
        pseq_len = [13, 199]
        nrepeats0 = 1

        dc_offset = 2.0
        cfo = -0.45 / pseq_len[0]

        pypparams = preamble_utils.generate_preamble_type2(
            pseq_len, pseq_lvl2_len, nrepeats0)
        pyfparams = preamble_utils.frame_params(pypparams, guard_len, awgn_len,
                                                frame_period)
        pparams = generate_hier_preamble(pseq_len, pseq_lvl2_len, nrepeats0)
        fparams = specmonitor.PyFrameParams(pparams, guard_len, awgn_len,
                                            frame_period)
        sframer = preamble_utils.SignalFramer(pyfparams)
        pydetec = preamble_utils.PreambleDetectorType2(pyfparams,
                                                       pseq_len[0] * 8, 0.045,
                                                       0.045)
        detec = preamble_utils.PyHierPreambleDetector(fparams, pseq_len[0] * 8,
                                                      0.045, 0.045)

        x = np.zeros(int(pyfparams.frame_period * 1.5), np.complex64)
        Nruns = 5
        for i in range(Nruns):
            y, section_ranges = sframer.frame_signal(x, 1)
            x_with_hist = detec.x_hist_buffer + y.tolist()
            detec.work(y)
            pydetec.work(y)
            assert_consistency(self, pydetec, detec.detec, pypparams, pparams,
                               x_with_hist)
def generate_hier_preamble(pseq_len_list, pseq_lvl2_len, num_repeats=1):
    assert len(pseq_len_list) == 2
    pseq_list = [
        random_sequence.zadoffchu_noDC_sequence(p, 1, 0) for p in pseq_len_list
    ]
    lvl2_code = random_sequence.maximum_length_sequence(pseq_lvl2_len)
    lvl2_many = np.array([])
    for i in range(num_repeats):
        lvl2_many = np.append(lvl2_many, lvl2_code)
    pseq_list_coef = preamble_utils.set_schmidl_sequence(lvl2_many)
    pseq_list_coef = np.append(pseq_list_coef, 1)
    pseq_len_seq = [0] * (pseq_lvl2_len * num_repeats + 1) + [1]
    return specmonitor.PyPreambleParams(pseq_list, pseq_len_seq,
                                        pseq_list_coef)
    def test_array_values(self):
        guard_len = 5
        awgn_len = 10
        frame_period = 5000
        nrepeats0 = 3
        pseq_len = [5, 31]
        pseq_lvl2_len = len(random_sequence.maximum_length_sequence(3))  #13*4

        # generation of python-version of preamble detector
        pypparams = preamble_utils.generate_preamble_type2(
            pseq_len, pseq_lvl2_len, nrepeats0)
        pyfparams = preamble_utils.frame_params(pypparams, guard_len, awgn_len,
                                                frame_period)
        pydetec = preamble_utils.PreambleDetectorType2(pyfparams,
                                                       pseq_len[0] * 8)
        sframer = preamble_utils.SignalFramer(pyfparams)
        L0 = pydetec.L0

        # generation of the C++ version
        pparams = generate_hier_preamble(pseq_len, pseq_lvl2_len, nrepeats0)
        fparams = specmonitor.PyFrameParams(pparams, guard_len, awgn_len,
                                            frame_period)
        detec = specmonitor.hier_preamble_detector(fparams, pseq_len[0] * 8)

        # initialization asserts
        x_hlen = pydetec.x_h.hist_len
        xdc_mavg_hlen = pydetec.xdc_mavg_h.hist_len
        xnodc_hlen = pydetec.xnodc_h.hist_len
        xschmidl_nodc_hlen = pydetec.xschmidl_nodc.hist_len
        xcorr_nodc_hlen = pydetec.xcorr_nodc.hist_len
        xcrossautocorr_nodc_hlen = pydetec.xcrossautocorr_nodc.hist_len

        xlen = pyfparams.section_duration() + guard_len * 2
        x = np.zeros(xlen, np.complex64)
        y, section_ranges = sframer.frame_signal(x, 1)
        x = list([complex(yy) for yy in y])  #list(range(10000))
        x_with_hist = list(np.zeros(x_hlen)) + x

        detec.work(x_with_hist)
        pydetec.work(np.array(x))

        assert_consistency(self, pydetec, detec, pypparams, pparams,
                           x_with_hist)
def test2():
    """
    In this test we check if we are able to synchronize with one preamble after breaking the input signal into parts
    in the stream.
    """
    print 'test2: Test sync with one preamble when I break my input'

    guard_len = 5
    awgn_len = 75
    frame_period = 2000
    lvl2_seq_diff = random_sequence.maximum_length_sequence(13)
    lvl2_diff_len = len(lvl2_seq_diff)
    lvl2_len = lvl2_diff_len + 1
    small_pseq_len = 13

    dc_offset = 1.5
    cfo = 0.42 / small_pseq_len
    amp = 1.5

    pparams = preamble_utils.generate_preamble_type2([small_pseq_len, 61],
                                                     lvl2_diff_len)
    fparams = preamble_utils.frame_params(pparams, guard_len, awgn_len,
                                          frame_period)
    sframer = preamble_utils.SignalFramer(fparams)
    thres = [0.12, 0.09]

    xlen = fparams.section_duration() + guard_len * 2
    x = (np.random.randn(xlen) + np.random.randn(xlen) * 1j) * 0.1 / np.sqrt(2)
    y, section_ranges = sframer.frame_signal(x, 1)
    y = preamble_utils.apply_cfo(y, cfo) * amp + dc_offset * np.exp(
        1j * np.random.rand() * 2 * np.pi)

    def test_partitioning(toffset, partition_part):
        pdetec = preamble_utils.PreambleDetectorType2(fparams,
                                                      thres1=thres[0],
                                                      thres2=thres[1])
        pdetec2 = preamble_utils.PreambleDetectorType2(fparams,
                                                       thres1=thres[0],
                                                       thres2=thres[1])
        assert pdetec.lvl2_len == lvl2_len
        assert np.array_equal(
            np.real(pdetec.lvl2_seq_diff),
            lvl2_seq_diff)  # assert the diff is equal to the MLS

        y_with_offset = np.append(np.zeros(toffset, dtype=y.dtype), y)
        pdetec.work(y_with_offset)
        x_h = pdetec.x_h.data()
        xschmidl = pdetec.xschmidl_nodc.data()
        xschmidl_filt = pdetec.xschmidl_filt_nodc.data()
        xcorr_filt = pdetec.xcorr_filt_nodc.data()
        xcrossautocorr = pdetec.xcrossautocorr_nodc.data()
        # detector_transform_visualizations(pdetec,awgn_len,cfo)

        pdetec2.work(y_with_offset[0:partition_part])
        x_h2 = np.array(pdetec2.x_h.data())
        xschmidl2 = np.array(pdetec2.xschmidl_nodc.data())
        xschmidl_filt2 = np.array(pdetec2.xschmidl_filt_nodc.data())
        xcorr_filt2 = np.array(pdetec2.xcorr_filt_nodc.data())
        xcrossautocorr2 = np.array(pdetec2.xcrossautocorr_nodc.data())
        pdetec2.work(y_with_offset[partition_part::])
        # detector_transform_visualizations(pdetec2,None)
        x_h2 = np.append(x_h2, pdetec2.x_h[0::])
        xschmidl2 = np.append(xschmidl2, pdetec2.xschmidl_nodc[0::])
        xschmidl_filt2 = np.append(xschmidl_filt2,
                                   pdetec2.xschmidl_filt_nodc[0::])
        xcorr_filt2 = np.append(xcorr_filt2, pdetec2.xcorr_filt_nodc[0::])
        xcrossautocorr2 = np.array(pdetec2.xcrossautocorr_nodc[0::])

        assert pdetec2.nread == pdetec.nread
        tlast = pdetec.nread

        def assert_aligned(x, x2):
            siz = min(x.size, x2.size)
            assert np.max(
                np.abs(x[x.size - siz::] - x2[x2.size - siz::])) < 1.0e-6

        assert_aligned(x_h2, x_h)
        assert_aligned(xschmidl2, xschmidl)
        assert_aligned(xschmidl_filt2, xschmidl_filt)
        assert_aligned(xcorr_filt2, xcorr_filt)

        # def plot_taligned(x,fmt='-'):
        #     t = np.arange(tlast-x.size,tlast)
        #     plt.plot(t,x,fmt)

        # plot_taligned(np.abs(xschmidl_filt),'r')
        # plot_taligned(np.abs(xschmidl_filt2),'rx')
        # plot_taligned(np.abs(xcorr_filt)**2,'b')
        # plot_taligned(np.abs(xcorr_filt2)**2,'bx')
        # t = np.arange(pdetec.nread-xcrossautocorr.size,pdetec.nread)
        # plt.plot(t,np.abs(xcrossautocorr),'x-')
        # t = np.arange(pdetec2.nread-xcrossautocorr2.size,pdetec2.nread)
        # plt.plot(t,np.abs(xcrossautocorr2),'.--')
        # plt.show()

        assert len(pdetec.peaks) == 1 and len(pdetec2.peaks) == 1
        p = pdetec2.peaks[0]
        assert p.tidx == fparams.awgn_len + toffset and pdetec.peaks[
            0].is_equal(p)
        assert p.awgn_mag2_nodc < 0.000001
        assert np.abs(p.preamble_mag2 - amp**2) < 1.0e-6
        assert np.abs(p.cfo - cfo) < 1.0e-4
        # print p.xcorr,amp**2
        # assert np.abs(p.xcorr-amp**2)<0.05
        assert p.xautocorr / amp**2 > 0.95
        # detector_transform_visualizations(pdetec)

        # print 'min idx:',preamble_utils.min_idx

    for toffset in range(0, y.size):
        for partition in [
                y.size / 16, y.size / 8, y.size / 4, y.size / 2, y.size * 3 / 4
        ]:
            test_partitioning(toffset, partition)
def unit_test1():
    """
    This test checks if the generated preamble params and frame params make sense
    """
    print 'UnitTest1:frame generation'

    guard_len = 5
    awgn_len = 50
    frame_period = 1000
    lvl2_seq_diff = random_sequence.maximum_length_sequence(7)
    lvl2_diff_len = len(lvl2_seq_diff)

    pparams = preamble_utils.generate_preamble_type2([5, 61], lvl2_diff_len)
    fparams = preamble_utils.frame_params(pparams, guard_len, awgn_len,
                                          frame_period)
    sframer = preamble_utils.SignalFramer(fparams)

    # check if frame params make sense
    assert pparams.length() == pparams.preamble.size
    assert np.abs(np.mean(np.abs(pparams.pseq_list_norm[1])**2) - 1) < 1.0e-6
    assert np.array_equal(
        np.real(
            preamble_utils.get_schmidl_sequence(pparams.pseq_list_coef[0:-1])),
        lvl2_seq_diff)

    assert fparams.section_duration() == (frame_period - 4 * guard_len -
                                          awgn_len - pparams.length())
    assert fparams.guarded_section_duration(
    ) == fparams.guarded_section_interval(
    )[1] - fparams.guarded_section_interval()[0]
    assert fparams.section_duration(
    ) + 2 * guard_len == fparams.guarded_section_duration()
    assert fparams.section_interval()[1] - fparams.section_interval(
    )[0] == fparams.section_duration()

    # check if the SignalFramer produces stuff that makes sense
    num_sections = 10
    x = np.ones(num_sections * fparams.section_duration() + guard_len * 2,
                np.complex64)
    y, section_ranges = sframer.frame_signal(x, num_sections)

    # plt.plot(np.abs(y))
    # plt.show()

    assert y.size == (num_sections * fparams.frame_period
                      )  # check if the size matches
    assert len(
        section_ranges) == num_sections  # check if section_ranges makes sense
    assert all(
        (s[1] - s[0]) == fparams.section_duration() for s in section_ranges)
    assert np.sum([np.sum(np.abs(y[s[0]:s[1]] - 1)) for s in section_ranges
                   ]) == 0  # check if sections are equal to 1
    tmp = guard_len * 2 + pparams.length()
    assert np.sum([
        np.sum(np.abs(y[s[0] - tmp - awgn_len:s[0] - tmp]))
        for s in section_ranges
    ]) == 0
    preamble = pparams.preamble
    assert np.sum([
        np.sum(np.abs(y[s[0] - tmp:s[0] - tmp + pparams.length()] - preamble))
        for s in section_ranges
    ]) == 0
def test4():
    """
    In this test we plot the performance of the preamble param estimator for this SNR levels
    """
    print 'test4: Test sync against SNR'
    # np.random.seed(4)

    # preamble params
    guard_len = 5
    awgn_len = 200
    frame_period = 3000 * 2
    pseq_lvl2_len = len(random_sequence.maximum_length_sequence(13 * 8))  #13*4
    pseq_len = [13, 199]
    nrepeats0 = 1

    dc_offset = 2.0
    cfo = -0.45 / pseq_len[0]

    pparams = preamble_utils.generate_preamble_type2(pseq_len, pseq_lvl2_len,
                                                     nrepeats0)
    fparams = preamble_utils.frame_params(pparams, guard_len, awgn_len,
                                          frame_period)

    num_runs = 500
    SNRdB_range = range(-20, 21)
    FalseAlarmRate = np.zeros(len(SNRdB_range))
    Pdetec = np.zeros(len(SNRdB_range))
    amp_stats = []
    N = len(SNRdB_range)
    estim_stats = {
        'SNRdB': {
            'sum': np.zeros(N),
            'mse_sum': np.zeros(N)
        },
        'detect_count': np.zeros(len(SNRdB_range)),
        'amplitude': {
            'sum': np.zeros(N),
            'mse_sum': np.zeros(N)
        },
        'awgn_mag2': {
            'sum': np.zeros(N),
            'mse_sum': np.zeros(N)
        },
        'cfo': {
            'sum': np.zeros(N),
            'mse_sum': np.zeros(N)
        },
        'dc_offset': {
            'abs_sum': np.zeros(N),
            'mse_sum': np.zeros(N)
        }
    }

    print 'preamble duration:', pparams.preamble_len, ",", pseq_lvl2_len * pseq_len[
        0]
    for si, s in enumerate(SNRdB_range):
        amp_stats.append([0.0, 0.0, 0])
        amp = 10**(s / 20.0)
        for r in range(num_runs):
            sframer = preamble_utils.SignalFramer(fparams)
            pdetec = preamble_utils.PreambleDetectorType2(
                fparams, pseq_len[0] * 8, 0.045, 0.045)  #0.08,0.04)

            xlen = int(fparams.frame_period *
                       1.5)  #fparams.section_duration()+guard_len*2
            # print 'xlen:',guard_len*2
            x = (np.random.randn(xlen) +
                 np.random.randn(xlen) * 1j) * 0.1 / np.sqrt(2)
            y, section_ranges = sframer.frame_signal(x, 1)
            y *= amp  # the preamble has amplitude 1
            y = preamble_utils.apply_cfo(y, cfo)

            T = 1000 * 2
            toffset = 0  #np.random.randint(0,T-pparams.preamble_len+fparams.awgn_len)
            preamble_start = toffset + awgn_len
            yoffset = np.append(np.zeros(toffset, dtype=np.complex64), y)
            yoffset = np.append(yoffset,
                                np.zeros(T - toffset, dtype=np.complex64))
            awgn = (np.random.randn(yoffset.size) +
                    np.random.randn(yoffset.size) * 1j) / np.sqrt(2)
            y_pwr = amp**2
            awgn_pwr = np.mean(np.abs(awgn)**2)
            yoffset += awgn
            yawgn_nodc_pwr = np.mean(
                np.abs(yoffset[preamble_start:preamble_start +
                               fparams.preamble_params.length()])**2)
            dc_offset_with_phase = dc_offset * np.exp(
                1j * np.random.rand() * 2 * np.pi)
            yoffset += dc_offset_with_phase
            # print 'AWGN pwr [dB]:',10*np.log10(awgn_pwr)
            print 'actual SNRdB:', 10 * np.log10(y_pwr / awgn_pwr)
            # print 'amplitude:',yawgn_nodc_pwr
            # plt.plot(yoffset)
            # plt.show()

            pdetec.work(yoffset)

            test1 = False
            if len(pdetec.peaks) > 0:
                print 'peak detected at SNRdB=', s
                max_el = np.argmax([np.abs(p.xcorr) for p in pdetec.peaks])
                test1 = np.abs(pdetec.peaks[max_el].tidx -
                               (toffset + awgn_len)) < 2
                if test1:
                    p = pdetec.peaks[max_el]
                    amp_stats[si][0] += p.preamble_mag2
                    amp_stats[si][1] += (p.preamble_mag2 - amp**2)**2
                    amp_stats[si][2] += 1
                    estim_stats['amplitude']['sum'][si] += p.preamble_mag2
                    estim_stats['amplitude']['mse_sum'][si] += np.abs(
                        p.preamble_mag2 -
                        yawgn_nodc_pwr)**2  #(10**(s/10.0)+1))**2
                    estim_stats['SNRdB']['sum'][si] += p.SNRdB()
                    estim_stats['SNRdB']['mse_sum'][si] += np.abs(
                        p.SNRdB() - 10 * np.log10(y_pwr / awgn_pwr))**2
                    estim_stats['awgn_mag2']['sum'][si] += p.awgn_mag2_nodc
                    estim_stats['awgn_mag2']['mse_sum'][si] += (
                        p.awgn_mag2_nodc - awgn_pwr)**2
                    estim_stats['dc_offset']['abs_sum'][si] += np.abs(
                        p.dc_offset)
                    estim_stats['dc_offset']['mse_sum'][si] += np.abs(
                        p.dc_offset - dc_offset_with_phase)**2
                    estim_stats['cfo']['sum'][si] += p.cfo
                    estim_stats['cfo']['mse_sum'][si] += np.abs(p.cfo - cfo)**2
                    estim_stats['detect_count'][si] += 1
                print s, pdetec.peaks[0].tidx, toffset + awgn_len, test1
            num_fa = len(pdetec.peaks) - 1 if test1 else len(pdetec.peaks)
            Pdetec[si] += test1
            FalseAlarmRate[si] += num_fa
            # if test1 is False or num_fa>0:
            # detector_transform_visualizations(pdetec)
            # print 'result:',test1
    Pdetec /= float(num_runs)
    FalseAlarmRate /= float(num_runs)

    tostore = {
        'estim_stats': estim_stats,
        'Pdetec': Pdetec,
        'FalseAlarmRate': FalseAlarmRate,
        'SNRdB_range': SNRdB_range,
        'dc_offset': dc_offset,
        'cfo': cfo
    }

    with open(test4_pkl_file, 'wb') as f:
        pickle.dump(tostore, f)