Extend FPGA functionality
This commit is contained in:
+116
-21
@@ -3,7 +3,6 @@
|
||||
#include <catch2/catch.hpp>
|
||||
#include <random>
|
||||
|
||||
#include <bitshuffle/bitshuffle.h>
|
||||
#include "../jungfrau/JFPedestalCalc.h"
|
||||
#include "../acquisition_device/HLSSimulatedDevice.h"
|
||||
#include "FPGAUnitTest.h"
|
||||
@@ -35,7 +34,8 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator", "[FPGA][Full]") {
|
||||
REQUIRE(imageBuf[i] == i % 65536);
|
||||
}
|
||||
}
|
||||
REQUIRE(test.GetCompletedDescriptors() == 2 * (4 + DELAY_FRAMES_STOP_AND_QUIT - 1) * nmodules);
|
||||
REQUIRE(test.GetExpectedDescriptorsPerModule() == 5);
|
||||
REQUIRE(test.GetCompletedDescriptors() == 5 * (4 + DELAY_FRAMES_STOP_AND_QUIT - 1) * nmodules);
|
||||
}
|
||||
|
||||
TEST_CASE("HLS_C_Simulation_internal_packet_generator_custom_frame", "[FPGA][Full]") {
|
||||
@@ -66,9 +66,9 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_custom_frame", "[FPGA][Ful
|
||||
|
||||
for (int image = 0; image < nframes; image++) {
|
||||
for (int m = 0; m < nmodules; m++) {
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).timestamp == INT_PKT_GEN_EXPTTIME * image);
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).bunchid == INT_PKT_GEN_BUNCHID + image);
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).exptime == INT_PKT_GEN_EXPTTIME);
|
||||
REQUIRE(test.GetDeviceOutput(image, m)->module_statistics.timestamp == INT_PKT_GEN_EXPTTIME * image);
|
||||
REQUIRE(test.GetDeviceOutput(image, m)->module_statistics.bunchid == INT_PKT_GEN_BUNCHID + image);
|
||||
REQUIRE(test.GetDeviceOutput(image, m)->module_statistics.exptime == INT_PKT_GEN_EXPTTIME);
|
||||
|
||||
auto imageBuf = (uint16_t *) test.GetDeviceOutput(image, m)->pixels;
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
@@ -340,6 +340,7 @@ TEST_CASE("HLS_C_Simulation_check_single_packet", "[FPGA][Full]") {
|
||||
}
|
||||
|
||||
TEST_CASE("HLS_C_Simulation_check_convert_full_range", "[FPGA][Full]") {
|
||||
Logger logger("HLS_C_Simulation_check_convert_full_range");
|
||||
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
||||
std::vector<double> gain(3 * RAW_MODULE_SIZE);
|
||||
|
||||
@@ -359,8 +360,8 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range", "[FPGA][Full]") {
|
||||
|
||||
auto gain_from_file = GainCalibrationFromTestFile();
|
||||
|
||||
|
||||
for (const auto energy : energy_values) {
|
||||
logger.Info("Trying with {} keV", energy);
|
||||
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PhotonEnergy_keV(energy);
|
||||
|
||||
REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy));
|
||||
@@ -381,7 +382,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range", "[FPGA][Full]") {
|
||||
|
||||
REQUIRE_NOTHROW(test.OutputStream().read());
|
||||
REQUIRE(test.OutputStream().size() == 0);
|
||||
REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
|
||||
double mean_error = CheckConversion(x, c_in, data.data(), test.GetDeviceOutput(0,0)->pixels);
|
||||
|
||||
@@ -390,6 +391,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range", "[FPGA][Full]") {
|
||||
}
|
||||
|
||||
TEST_CASE("HLS_C_Simulation_check_convert_full_range_I32", "[FPGA][Full]") {
|
||||
Logger logger("HLS_C_Simulation_check_convert_full_range_I32");
|
||||
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
||||
std::vector<double> gain(3 * RAW_MODULE_SIZE);
|
||||
|
||||
@@ -410,6 +412,8 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_I32", "[FPGA][Full]") {
|
||||
auto gain_from_file = GainCalibrationFromTestFile();
|
||||
|
||||
for (const auto energy : energy_values) {
|
||||
logger.Info("Trying with {} keV", energy);
|
||||
|
||||
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PhotonEnergy_keV(energy).FPGAOutputMode(FPGAPixelOutput::Int32);
|
||||
|
||||
REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy));
|
||||
@@ -430,7 +434,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_I32", "[FPGA][Full]") {
|
||||
|
||||
REQUIRE_NOTHROW(test.OutputStream().read());
|
||||
REQUIRE(test.OutputStream().size() == 0);
|
||||
REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
|
||||
double mean_error = CheckConversion(x, c_in, data.data(), (int32_t *) test.GetDeviceOutput(0,0)->pixels);
|
||||
|
||||
@@ -439,6 +443,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_I32", "[FPGA][Full]") {
|
||||
}
|
||||
|
||||
TEST_CASE("HLS_C_Simulation_check_convert_full_range_sum4", "[FPGA][Full]") {
|
||||
Logger logger("HLS_C_Simulation_check_convert_full_range_sum4");
|
||||
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
||||
std::vector<double> gain(3 * RAW_MODULE_SIZE);
|
||||
|
||||
@@ -461,6 +466,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_sum4", "[FPGA][Full]") {
|
||||
size_t nsummation = 4;
|
||||
|
||||
for (const auto energy : energy_values) {
|
||||
logger.Info("Trying with {} keV", energy);
|
||||
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PhotonEnergy_keV(energy).Summation(nsummation);
|
||||
|
||||
REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy));
|
||||
@@ -482,7 +488,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_sum4", "[FPGA][Full]") {
|
||||
|
||||
REQUIRE_NOTHROW(test.OutputStream().read());
|
||||
REQUIRE(test.OutputStream().size() == 0);
|
||||
REQUIRE(test.GetBytesReceived() == 128 * nsummation * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
CHECK(test.GetBytesReceived() == 128 * nsummation * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
|
||||
double mean_error = CheckConversion(x, c_in, data.data(), (int32_t *) test.GetDeviceOutput(0,0)->pixels);
|
||||
|
||||
@@ -491,6 +497,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_sum4", "[FPGA][Full]") {
|
||||
}
|
||||
|
||||
TEST_CASE("HLS_C_Simulation_check_convert_full_range_U16", "[FPGA][Full]") {
|
||||
Logger logger("HLS_C_Simulation_check_convert_full_range_U16");
|
||||
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
||||
std::vector<double> gain(3 * RAW_MODULE_SIZE);
|
||||
|
||||
@@ -511,6 +518,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_U16", "[FPGA][Full]") {
|
||||
auto gain_from_file = GainCalibrationFromTestFile();
|
||||
|
||||
for (const auto energy : energy_values) {
|
||||
logger.Info("Trying with {} keV", energy);
|
||||
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PhotonEnergy_keV(energy).FPGAOutputMode(FPGAPixelOutput::Uint16);
|
||||
|
||||
REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy));
|
||||
@@ -531,7 +539,7 @@ TEST_CASE("HLS_C_Simulation_check_convert_full_range_U16", "[FPGA][Full]") {
|
||||
|
||||
REQUIRE_NOTHROW(test.OutputStream().read());
|
||||
REQUIRE(test.OutputStream().size() == 0);
|
||||
REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
|
||||
double mean_error = CheckConversion(x, c_in, data.data(), (uint16_t *) test.GetDeviceOutput(0,0)->pixels);
|
||||
|
||||
@@ -1257,23 +1265,23 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_integration", "[FPGA][Full
|
||||
REQUIRE(memcmp(imageBuf, frame.data(), RAW_MODULE_SIZE * sizeof(uint16_t)) == 0);
|
||||
|
||||
auto integration_result = test.GetDeviceOutput(0, 0)->integration_result;
|
||||
CHECK(integration_result[0].sum == 32754LU * (RAW_MODULE_SIZE / 2) * (1LU<<24));
|
||||
CHECK(integration_result[0].sum == Approx(32754LU * (RAW_MODULE_SIZE / 2)));
|
||||
CHECK(integration_result[0].count == RAW_MODULE_SIZE / 2);
|
||||
CHECK(integration_result[1].sum == 0);
|
||||
CHECK(integration_result[1].count == 0);
|
||||
CHECK(integration_result[FPGA_INTEGRATION_BIN_COUNT - 1].sum == 32754LU * (RAW_MODULE_SIZE / 2 - 1)* (1LU<<24));
|
||||
CHECK(integration_result[FPGA_INTEGRATION_BIN_COUNT - 1].sum == Approx(32754LU * (RAW_MODULE_SIZE / 2 - 1)));
|
||||
CHECK(integration_result[FPGA_INTEGRATION_BIN_COUNT - 1].count == RAW_MODULE_SIZE / 2 - 1);
|
||||
|
||||
integration_result = test.GetDeviceOutput(0, 1)->integration_result;
|
||||
CHECK(integration_result[54].sum == 32754LU * (RAW_MODULE_SIZE) * (1LU<<24));
|
||||
CHECK(integration_result[54].sum == Approx(32754LU * (RAW_MODULE_SIZE)));
|
||||
CHECK(integration_result[54].count == RAW_MODULE_SIZE);
|
||||
|
||||
integration_result = test.GetDeviceOutput(0, 2)->integration_result;
|
||||
CHECK(integration_result[54].sum == 32754 * (RAW_MODULE_SIZE) * (1LU<<24));
|
||||
CHECK(integration_result[54].sum == Approx(32754 * (RAW_MODULE_SIZE)));
|
||||
CHECK(integration_result[54].count == RAW_MODULE_SIZE);
|
||||
|
||||
integration_result = test.GetDeviceOutput(0, 3)->integration_result;
|
||||
CHECK(integration_result[54].sum == 32754 * (RAW_MODULE_SIZE) * (1LU<<24));
|
||||
CHECK(integration_result[54].sum == Approx(32754 * (RAW_MODULE_SIZE)));
|
||||
CHECK(integration_result[54].count == RAW_MODULE_SIZE);
|
||||
}
|
||||
|
||||
@@ -1393,9 +1401,13 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_32bit", "[FPGA][Full]") {
|
||||
|
||||
for (int image = 0; image < nframes; image++) {
|
||||
for (int m = 0; m < nmodules; m++) {
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).timestamp == INT_PKT_GEN_EXPTTIME * image);
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).bunchid == INT_PKT_GEN_BUNCHID + image);
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).exptime == INT_PKT_GEN_EXPTTIME);
|
||||
CHECK(test.GetDeviceOutput(image, m)->module_statistics.frame_number == image);
|
||||
CHECK(test.GetDeviceOutput(image, m)->module_statistics.packet_count == 128);
|
||||
CHECK(test.GetDeviceOutput(image, m)->module_statistics.packet_mask[0] == UINT64_MAX);
|
||||
CHECK(test.GetDeviceOutput(image, m)->module_statistics.packet_mask[1] == UINT64_MAX);
|
||||
CHECK(test.GetDeviceOutput(image, m)->module_statistics.timestamp == INT_PKT_GEN_EXPTTIME * image);
|
||||
CHECK(test.GetDeviceOutput(image, m)->module_statistics.bunchid == INT_PKT_GEN_BUNCHID + image);
|
||||
CHECK(test.GetDeviceOutput(image, m)->module_statistics.exptime == INT_PKT_GEN_EXPTTIME);
|
||||
|
||||
auto imageBuf = (int32_t *) test.GetDeviceOutput(image, m)->pixels;
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
@@ -1435,9 +1447,9 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_summation", "[FPGA][Full]"
|
||||
auto test_frame_signed = (uint16_t *) test_frame.data();
|
||||
for (int image = 0; image < nframes; image++) {
|
||||
for (int m = 0; m < nmodules; m++) {
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).timestamp == INT_PKT_GEN_EXPTTIME * image * nsummation);
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).bunchid == INT_PKT_GEN_BUNCHID + image * nsummation);
|
||||
REQUIRE(test.Counters().GetCompletion(image, m).exptime == INT_PKT_GEN_EXPTTIME);
|
||||
REQUIRE(test.GetDeviceOutput(image, m)->module_statistics.timestamp == INT_PKT_GEN_EXPTTIME * image * nsummation);
|
||||
REQUIRE(test.GetDeviceOutput(image, m)->module_statistics.bunchid == INT_PKT_GEN_BUNCHID + image * nsummation);
|
||||
REQUIRE(test.GetDeviceOutput(image, m)->module_statistics.exptime == INT_PKT_GEN_EXPTTIME);
|
||||
|
||||
auto imageBuf = (int32_t *) test.GetDeviceOutput(image, m)->pixels;
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
@@ -1446,3 +1458,86 @@ TEST_CASE("HLS_C_Simulation_internal_packet_generator_summation", "[FPGA][Full]"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define NFRAMES_PEDESTAL_CHECK 256
|
||||
|
||||
TEST_CASE("HLS_C_Simulation_check_convert_pedestal", "[FPGA][Full]") {
|
||||
DiffractionExperiment x(DetectorGeometry(4));
|
||||
HLSSimulatedDevice test(0, NFRAMES_PEDESTAL_CHECK*4+8);
|
||||
|
||||
for (int gain = 2; gain >= 0; gain--) {
|
||||
x.ImagesPerTrigger(1).PedestalG0Frames(500).PedestalG1Frames(500).PedestalG2Frames(500).NumTriggers(1);
|
||||
|
||||
std::vector<uint16_t> data(NFRAMES_PEDESTAL_CHECK * RAW_MODULE_SIZE);
|
||||
|
||||
double mean;
|
||||
double stddev;
|
||||
|
||||
if (gain == 0) {
|
||||
x.Mode(DetectorMode::PedestalG0);
|
||||
mean = 1000.0;
|
||||
stddev = 50.0;
|
||||
} else if (gain == 1) {
|
||||
x.Mode(DetectorMode::PedestalG1);
|
||||
mean = 13000.0;
|
||||
stddev = 40.0;
|
||||
} else { // gain == 2
|
||||
x.Mode(DetectorMode::PedestalG2);
|
||||
mean = 14500.0;
|
||||
stddev = 20.0;
|
||||
}
|
||||
|
||||
// Predictable random number generator
|
||||
std::mt19937 g1(1984+gain);
|
||||
std::normal_distribution<double> distribution(mean, stddev);
|
||||
|
||||
for (int i = 0; i < NFRAMES_PEDESTAL_CHECK; i++) {
|
||||
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
|
||||
double number = distribution(g1);
|
||||
if (number < 20) number = 20;
|
||||
if (number > 16300) number = 16300;
|
||||
data[i * RAW_MODULE_SIZE + j] = number + ((gain == 1)?0x4000:0) + ((gain == 2)? 0xc000:0);
|
||||
}
|
||||
}
|
||||
|
||||
data[0 + 4096 * 45] = 0x4000 + 1; // gain_bit always 1
|
||||
data[1 + 4096 * 3] = 0x8000 + 1; // gain_bit always 2
|
||||
data[2 + 4096 * 100] = 0xc000 + 1; // gain_bit always 3
|
||||
|
||||
test.CreatePackets(x, 1, NFRAMES_PEDESTAL_CHECK, 0, data.data(), false);
|
||||
|
||||
test.CreateFinalPacket(x);
|
||||
|
||||
REQUIRE_NOTHROW(test.StartAction(x));
|
||||
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
||||
|
||||
REQUIRE_NOTHROW(test.OutputStream().read());
|
||||
REQUIRE(test.OutputStream().size() == 0);
|
||||
|
||||
REQUIRE(test.GetBytesReceived() == NFRAMES_PEDESTAL_CHECK * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
||||
|
||||
|
||||
REQUIRE(test.Counters().GetPedestalBufferHandle(0, 1) == AcquisitionCounters::HandleNotFound);
|
||||
REQUIRE(test.Counters().GetPedestalBufferHandle(0, 0) != AcquisitionCounters::HandleNotFound);
|
||||
|
||||
auto pedestal_buffer_0 = test.GetDeviceOutputPedestal(0, 0);
|
||||
REQUIRE(pedestal_buffer_0->module_statistics.packet_count == NFRAMES_PEDESTAL_CHECK);
|
||||
|
||||
JFPedestalCalc reference(x);
|
||||
for (int i = 0; i < NFRAMES_PEDESTAL_CHECK; i++)
|
||||
reference.AnalyzeImage(data.data() + i * RAW_MODULE_SIZE);
|
||||
|
||||
JFModulePedestal reference_pedestal, fpga_pedestal;
|
||||
reference.Export(reference_pedestal);
|
||||
fpga_pedestal.ImportFPGAPedestal(pedestal_buffer_0);
|
||||
|
||||
float error = 0;
|
||||
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
||||
float diff = reference_pedestal.GetPedestal()[i] - fpga_pedestal.GetPedestal()[i];
|
||||
error += diff * diff;
|
||||
}
|
||||
error = sqrtf(error / RAW_MODULE_SIZE);
|
||||
std::cout << "Pedestal G" << gain << " error: " << error << std::endl;
|
||||
REQUIRE(error < 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user