Esempio n. 1
0
def get_lock_position_from_autolock_instructions(
    spectrum, description, time_scale, initial_spectrum, final_wait_time
):
    summed = sum_up_spectrum(spectrum)
    summed_xscaled = get_diff_at_time_scale(summed, time_scale)

    description_idx = 0

    last_detected_peak = 0

    for idx, value in enumerate(summed_xscaled):
        wait_for, current_threshold = description[description_idx]

        if (
            sign(value) == sign(current_threshold)
            and abs(value) >= abs(current_threshold)
            and idx - last_detected_peak > wait_for
        ):
            description_idx += 1
            last_detected_peak = idx

            if description_idx == len(description):
                # this was the last peak!
                return idx + final_wait_time

    raise LockPositionNotFound()
Esempio n. 2
0
def test_sum_diff_calculator2():
    spectrum = pfd_spectrum(0)[0]

    delay = 60
    out_fpga = []

    def tb(dut):
        yield dut.restart.eq(0)
        yield dut.delay_value.eq(delay)
        yield dut.writing_data_now.eq(1)

        for point in spectrum:
            yield dut.input.eq(int(point))
            yield
            out = yield dut.output
            out_fpga.append(out)

    dut = SumDiffCalculator(14, 8192)
    run_simulation(dut,
                   tb(dut),
                   vcd_name="experimental_autolock_sum_diff_calculator.vcd")

    summed = sum_up_spectrum(spectrum)
    summed_xscaled = get_diff_at_time_scale(summed, delay)

    # plt.plot(out_fpga[1:])
    # plt.plot(summed_xscaled)
    # plt.show()
    assert out_fpga[1:] == summed_xscaled[:-1]
Esempio n. 3
0
def test_compare_sum_diff_calculator_implementations(debug=False):
    for iteration in (0, 1):
        if iteration == 1:
            spectrum, target_idxs = atomic_spectrum(0)
            time_scale = get_time_scale(spectrum, target_idxs)
        else:
            spectrum = [1 * i for i in range(1000)]
            time_scale = 5

        summed = sum_up_spectrum(spectrum)
        summed_xscaled = get_diff_at_time_scale(summed, time_scale)

        summed_fpga = {"summed_xscaled": [], "summed": []}

        def tb(dut):
            yield dut.request_lock.eq(1)
            yield dut.at_start.eq(1)
            yield dut.writing_data_now.eq(1)

            yield dut.at_start.eq(0)
            yield dut.time_scale.storage.eq(int(time_scale))

            for i in range(len(spectrum)):
                yield dut.input.eq(int(spectrum[i]))

                sum_diff = yield dut.sum_diff_calculator.output
                sum = yield dut.sum_diff_calculator.sum_value
                summed_fpga["summed_xscaled"].append(sum_diff)
                summed_fpga["summed"].append(sum)

                yield

        dut = RobustAutolock()
        run_simulation(
            dut,
            tb(dut),
            vcd_name="experimental_autolock_fpga_lock_position_finder.vcd")

        if debug:
            plt.plot(summed[:-FPGA_DELAY_SUMDIFF_CALCULATOR],
                     label="normal calculation")
            plt.plot(
                summed_fpga["summed"][FPGA_DELAY_SUMDIFF_CALCULATOR:],
                label="FPGA calculation",
            )
            plt.legend()
            plt.show()

            plt.plot(
                summed_xscaled[:-FPGA_DELAY_SUMDIFF_CALCULATOR],
                label="normal calculation",
            )
            plt.plot(
                summed_fpga["summed_xscaled"][FPGA_DELAY_SUMDIFF_CALCULATOR:],
                label="FPGA calculation",
            )
            plt.legend()
            plt.show()

        assert (summed[:-FPGA_DELAY_SUMDIFF_CALCULATOR] ==
                summed_fpga["summed"][FPGA_DELAY_SUMDIFF_CALCULATOR:])
        assert (summed_xscaled[:-FPGA_DELAY_SUMDIFF_CALCULATOR] ==
                summed_fpga["summed_xscaled"][FPGA_DELAY_SUMDIFF_CALCULATOR:])
Esempio n. 4
0
def calculate_autolock_instructions(spectra_with_jitter, target_idxs):
    spectra, crop_left = crop_spectra_to_same_view(spectra_with_jitter)

    target_idxs = [idx - crop_left for idx in target_idxs]

    time_scale = int(
        round(np.mean([get_time_scale(spectrum, target_idxs) for spectrum in spectra]))
    )

    print("x scale is %d" % time_scale)

    prepared_spectrum = get_diff_at_time_scale(sum_up_spectrum(spectra[0]), time_scale)
    peaks = get_all_peaks(prepared_spectrum, target_idxs)
    y_scale = peaks[0][1]

    lock_regions = [get_lock_region(spectrum, target_idxs) for spectrum in spectra]

    for tolerance_factor in [0.95, 0.9, 0.85, 0.8, 0.75, 0.7, 0.65, 0.6, 0.55, 0.5]:
        print("try out tolerance", tolerance_factor)
        peaks_filtered = [
            (peak_position, peak_height * tolerance_factor)
            for peak_position, peak_height in peaks
        ]
        # it is important to do the filtering that happens here after the previous
        # line as the previous line shrinks the values
        peaks_filtered = [
            (peak_position, peak_height)
            for peak_position, peak_height in peaks_filtered
            if abs(peak_height) > abs(y_scale * (1 - tolerance_factor))
        ]

        # now find out how much we have to wait in the end (because we detect the peak
        # too early because our threshold is too low)
        target_peak_described_height = peaks_filtered[0][1]
        target_peak_idx = get_target_peak(prepared_spectrum, target_idxs)
        current_idx = target_peak_idx
        while True:
            current_idx -= 1
            if np.abs(prepared_spectrum[current_idx]) < np.abs(
                target_peak_described_height
            ):
                break
        final_wait_time = target_peak_idx - current_idx
        print("final wait time is %d samples" % final_wait_time)

        description = []

        last_peak_position = 0
        for peak_position, peak_height in list(reversed(peaks_filtered)):
            # TODO: this .9 factor is very arbitrary.
            description.append(
                (int(0.9 * (peak_position - last_peak_position)), int(peak_height))
            )
            last_peak_position = peak_position

        # test whether description works fine for every recorded spectrum
        does_work = True
        for spectrum, lock_region in zip(spectra, lock_regions):
            try:
                lock_position = get_lock_position_from_autolock_instructions(
                    spectrum, description, time_scale, spectra[0], final_wait_time
                )
                if not lock_region[0] <= lock_position <= lock_region[1]:
                    raise LockPositionNotFound()

            except LockPositionNotFound:
                does_work = False

        if does_work:
            break
    else:
        raise UnableToFindDescription()

    if len(description) > AUTOLOCK_MAX_N_INSTRUCTIONS:
        print("warning: autolock description too long. Cropping!", len(description))
        description = description[-AUTOLOCK_MAX_N_INSTRUCTIONS:]

    print("description is", description)
    return description, final_wait_time, time_scale