Files
Jungfraujoch/tests/FPGASpotFindingUnitTest.cpp

110 lines
3.3 KiB
C++

// Copyright (2019-2023) Paul Scherrer Institute
#include <iostream>
#include <catch2/catch.hpp>
#include "../fpga/hls/hls_jfjoch.h"
#include "../fpga/hls/spot_finder.h"
TEST_CASE("Pack32_Unpack32","[FPGA][SpotFinder]") {
ap_int<16> value[32];
for (int i = 0; i < 32; i++)
value[i] = i;
ap_int<512> packed = pack32(value);
ap_int<16> restore[32];
unpack32(packed, restore);
for (int i = 0; i < 32; i++) {
REQUIRE(value[i] == restore[i]);
}
}
TEST_CASE("Pack32_Unpack32_36","[FPGA][SpotFinder]") {
ap_int<36> value[32];
for (int i = 0; i < 32; i++)
value[i] = i;
ap_int<36*32> packed = pack32(value);
ap_int<36> restore[32];
unpack32(packed, restore);
for (int i = 0; i < 32; i++) {
REQUIRE(value[i] == restore[i]);
}
}
TEST_CASE("FPGA_calc_sum","[FPGA][SpotFinder]") {
ap_int<16> old_value[32];
ap_int<16> new_value[32];
ap_int<SUM_BITWIDTH> new_sum[32];
ap_int<SUM2_BITWIDTH> new_sum2[32];
for (int i = 0; i < 32; i++) {
old_value[i] = i;
new_value[i] = 2;
}
ap_uint<SUM_BITWIDTH*32> diff_sum;
ap_uint<SUM2_BITWIDTH*32> diff_sum2;
calc_sum(diff_sum, pack32(old_value), pack32(new_value));
calc_sum2(diff_sum2, pack32(old_value), pack32(new_value));
unpack32(diff_sum, new_sum);
unpack32(diff_sum2, new_sum2);
for (int i = 0; i < 32; i++) {
REQUIRE(new_sum[i] == 2-i);
REQUIRE(new_sum2[i] == 4-i*i);
}
}
TEST_CASE("FPGA_update_sum" , "[FPGA][SpotFinder]") {
ap_int<SUM2_BITWIDTH> arr_val1[32], arr_val2[32], arr_out[32];
for (int i = 0; i < 32; i++) {
arr_val1[i] = 5 * i;
arr_val2[i] = 3 * i + 2;
}
ap_uint<SUM2_BITWIDTH*32> val1 = pack32(arr_val1);
ap_uint<SUM2_BITWIDTH*32> val2 = pack32(arr_val2);
update_sum<SUM2_BITWIDTH>(val1, val2);
unpack32(val1, arr_out);
for (int i = 0; i < 32; i++)
REQUIRE(arr_out[i] == 8 * i + 2);
}
bool Isigma_cpu(double val, double sum, double sum2, float threshold) {
double mean = sum / ((2*FPGA_NBX+1) * (2*FPGA_NBX+1));
double mean2 = sum2 / ((2*FPGA_NBX+1) * (2*FPGA_NBX+1));
double variance = mean2 - mean * mean;
double sigma = sqrt(variance);
double i_over_sigma = (val - mean) / sigma;
return (i_over_sigma > threshold);
}
bool Isigma_fpga(ap_int<16> val, ap_int<SUM_BITWIDTH> sum, ap_uint<SUM2_BITWIDTH> sum2, float threshold) {
return check_threshold(val, sum, sum2, fpga_strong_pixel_threshold(threshold), -1);
}
TEST_CASE("FPGA_spot_check_threshold","[FPGA][SpotFinder]") {
std::vector<float> threshold_values = {1.0, 3.0, 6.0};
for (auto threshold: threshold_values) {
uint32_t uniform_val = 10;
uint32_t diff = 0;
for (int16_t val = -100; val < INT16_MAX; val++) {
uint32_t sum = val + ((2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1) - 1) * uniform_val;
uint32_t sum2 = val * val + ((2 * FPGA_NBX + 1) * (2 * FPGA_NBX + 1) - 1) * uniform_val * uniform_val;
bool cpu = Isigma_cpu(val, sum, sum2, threshold);
bool fpga = Isigma_fpga(val, sum, sum2, threshold);
if (cpu != fpga) {
std::cout << "WRONG!!! " << threshold << " " << val << " " << sum << " " << sum2 << " CPU: " << cpu << " FPGA: " << fpga << std::endl;
diff++;
}
}
REQUIRE(diff == 0);
}
}