1543 lines
55 KiB
C++
1543 lines
55 KiB
C++
// Copyright (2019-2023) Paul Scherrer Institute
|
|
|
|
#include <catch2/catch.hpp>
|
|
#include <random>
|
|
|
|
#include "../jungfrau/JFPedestalCalc.h"
|
|
#include "../acquisition_device/HLSSimulatedDevice.h"
|
|
#include "FPGAUnitTest.h"
|
|
|
|
using namespace std::literals::chrono_literals;
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 4;
|
|
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
test.SetInternalGeneratorFrame();
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.OutputStream().size() == 1);
|
|
|
|
|
|
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
for (int image = 0; image < 4; image++) {
|
|
for (int m = 0; m < nmodules; m++) {
|
|
auto imageBuf = (uint16_t *) test.GetDeviceOutput(image, m)->pixels;
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
|
REQUIRE(imageBuf[i] == i % 65536);
|
|
}
|
|
}
|
|
REQUIRE(test.GetExpectedDescriptorsPerModule() == 5);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_custom_frame", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 32;
|
|
const size_t nframes = 2;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
std::vector<uint16_t> test_frame(nmodules*RAW_MODULE_SIZE);
|
|
|
|
std::mt19937 g1(1387);
|
|
std::uniform_int_distribution<uint16_t> dist(0, 65535);
|
|
|
|
for (auto &i: test_frame)
|
|
i = dist(g1);
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nframes).PedestalG0Frames(0);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
test.SetInternalGeneratorFrame(test_frame);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.OutputStream().size() == 1);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 128 * nmodules * nframes * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
for (int image = 0; image < nframes; image++) {
|
|
for (int m = 0; m < nmodules; m++) {
|
|
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++) {
|
|
REQUIRE(imageBuf[i] == test_frame[m * RAW_MODULE_SIZE + i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_raw", "[FPGA][Full]") {
|
|
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
|
|
|
|
for (int i = 0; i < 20; i++) {
|
|
LoadBinaryFile("../../tests/test_data/mod5_raw" + std::to_string(i)+".bin", raw_frames.data() + i * RAW_MODULE_SIZE, RAW_MODULE_SIZE);
|
|
}
|
|
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
uint16_t data[4096];
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.PedestalG0Frames(0).ImagesPerTrigger(5).NumTriggers(1);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
test.CreatePackets(x, 1, 5, 0, raw_frames.data(), true);
|
|
test.CreateFinalPacket(x);
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 5 * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
uint64_t diffs = 0;
|
|
for (int image = 0; image < 5; image++) {
|
|
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
|
|
if (raw_frames[image*RAW_MODULE_SIZE+j] != ((uint16_t *) test.GetDeviceOutput(image, 0)->pixels)[j]) {
|
|
diffs++;
|
|
std::cout << raw_frames[image*RAW_MODULE_SIZE+j] << " " << ((uint16_t *) test.GetDeviceOutput(image, 0)->pixels)[j] << std::endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
REQUIRE(diffs == 0);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_cancel", "[FPGA][Full]") {
|
|
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[4096];
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.PedestalG0Frames(0).ImagesPerTrigger(5).NumTriggers(1);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
test.Cancel();
|
|
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 0);
|
|
}
|
|
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_cancel_conversion", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[4096];
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).ImagesPerTrigger(5).NumTriggers(1);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
test.Cancel();
|
|
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 0);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_delay", "[FPGA][Full]") {
|
|
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
|
|
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[4096];
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
test.CreatePacketJF(x, 1, 0, 0, data, false);
|
|
test.CreatePacketJF(x, 1, 0, 1, data, false);
|
|
test.CreatePacketJF(x, 1, 0, 2, data, false);
|
|
test.CreatePacketJF(x, 1, 0, 3, data, false);
|
|
|
|
test.CreatePacketJF(x, 2, 0, 0, data, false);
|
|
test.CreatePacketJF(x, 2, 0, 1, data, false);
|
|
test.CreatePacketJF(x, 2, 0, 2, data, false);
|
|
test.CreatePacketJF(x, 2, 0, 3, data, false);
|
|
|
|
test.CreatePacketJF(x, 3, 0, 0, data, false);
|
|
test.CreatePacketJF(x, 3, 0, 1, data, false);
|
|
test.CreatePacketJF(x, 3, 0, 2, data, false);
|
|
test.CreatePacketJF(x, 3, 0, 3, data, false);
|
|
|
|
test.CreateFinalPacket(x);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.Counters().CalculateDelay(0) == 2);
|
|
REQUIRE(test.Counters().CalculateDelay(0, 0) == 2);
|
|
REQUIRE(test.Counters().CalculateDelay(1) == 1);
|
|
REQUIRE(test.Counters().CalculateDelay(1, 0) == 1);
|
|
REQUIRE(test.Counters().CalculateDelay(2) == 0);
|
|
REQUIRE(test.Counters().CalculateDelay(2, 0) == 0);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_lost_frame_raw", "[FPGA][Full]") {
|
|
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
|
|
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[4096];
|
|
|
|
for (int i = 0; i < 4096; i++) data[i] = i;
|
|
x.Mode(DetectorMode::Raw);
|
|
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
test.CreatePacketJF(x, 1, 0, 0, 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() == JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
REQUIRE(test.GetDeviceOutput(0,0)->pixels[0] == 0);
|
|
REQUIRE(test.GetDeviceOutput(0,0)->pixels[1] == 1);
|
|
REQUIRE(test.GetDeviceOutput(0,0)->pixels[4095] == 4095);
|
|
REQUIRE(test.GetDeviceOutput(0,1)->pixels[0] == -1);
|
|
REQUIRE(test.GetDeviceOutput(0,1)->pixels[RAW_MODULE_SIZE-1] == -1);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_lost_frame_conversion", "[FPGA][Full]") {
|
|
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
|
|
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[4096];
|
|
|
|
for (int i = 0; i < 4096; i++) data[i] = i;
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
test.CreatePacketJF(x, 1, 0, 0, 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() == JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
REQUIRE(test.GetDeviceOutput(0,1)->pixels[0] == PIXEL_OUT_LOST);
|
|
REQUIRE(test.GetDeviceOutput(0,1)->pixels[RAW_MODULE_SIZE-1] == PIXEL_OUT_LOST);
|
|
REQUIRE(test.GetDeviceOutput(1,0)->pixels[0] == PIXEL_OUT_LOST);
|
|
REQUIRE(test.GetDeviceOutput(2,1)->pixels[556] == PIXEL_OUT_LOST);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_single_packet", "[FPGA][Full]") {
|
|
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
|
|
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[4096];
|
|
uint16_t wrong[4096];
|
|
|
|
for (int i = 0; i < 4096; i++) {
|
|
data[i] = (7 * i + 534 + 5 * i * i) % UINT16_MAX;
|
|
wrong[i] = UINT16_MAX;
|
|
}
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
test.CreatePacketJF(x, 1, 0, 0, data, false);
|
|
test.CreatePacketJF(x, 1, 64, 0, data, false);
|
|
test.CreatePacketJF(x, 1, 0, 2, data, false);
|
|
|
|
test.CreatePacketJF(x, 1, 2, 3, data, false);
|
|
test.CreatePacketJF(x, 1, 3, 3, data, false);
|
|
|
|
test.CreatePacketJF(x, 1, 1, 3, data, false);
|
|
test.CreatePacketJF(x, 1, 0, 3, data, false);
|
|
test.CreatePacketJF(x, 1, 64, 3, data, false);
|
|
|
|
test.CreatePacketJF(x, 1, 5, 0, data, false);
|
|
test.CreatePacketJF(x, 1, 4, 0, data, false);
|
|
|
|
test.CreatePacketJF(x, 1, 67, 1, data, false);
|
|
test.CreatePacketJF(x, 1, 66, 1, data, false);
|
|
test.CreatePacketJF(x, 1, 68, 1, data, false);
|
|
|
|
test.CreatePacketJF(x, 3, 1, 0, data, false);
|
|
test.CreatePacketJF(x, 2, 1, 0, data, false);
|
|
|
|
test.CreatePacketJF(x, 4, 1, 0, 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() == 15 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels, data, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels + 1 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels + 2 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels + 3 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels + 4 * JUNGFRAU_PACKET_SIZE_BYTES/2, data, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels + 5 * JUNGFRAU_PACKET_SIZE_BYTES/2, data, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels + 6 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,0)->pixels + 64 * JUNGFRAU_PACKET_SIZE_BYTES/2, data, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,1)->pixels + 67 * JUNGFRAU_PACKET_SIZE_BYTES/2, data, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
REQUIRE(memcmp(test.GetDeviceOutput(0,1)->pixels + 65 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 15 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
}
|
|
|
|
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);
|
|
|
|
JFModulePedestal pedestal_g0(0), pedestal_g1(14500), pedestal_g2(14500);
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
data[i] = i % UINT16_MAX;
|
|
}
|
|
|
|
std::vector<double> energy_values = {6.0, 12.4, 17.7, 5, 4.5, 3.7};
|
|
|
|
const uint16_t nmodules = 1;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
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));
|
|
|
|
JFCalibration c_in(x);
|
|
c_in.Pedestal(0,0) = pedestal_g0;
|
|
c_in.Pedestal(0,1) = pedestal_g1;
|
|
c_in.Pedestal(0,2) = pedestal_g2;
|
|
for (int i = 0; i < x.GetModulesNum(); i++)
|
|
c_in.GainCalibration(i) = gain_from_file;
|
|
|
|
test.InitializeCalibration(x, c_in);
|
|
test.CreatePackets(x, 1, 1, 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);
|
|
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
double mean_error = CheckConversion(x, c_in, data.data(), test.GetDeviceOutput(0,0)->pixels);
|
|
|
|
REQUIRE(mean_error < 0.5);
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
JFModulePedestal pedestal_g0(0), pedestal_g1(14500), pedestal_g2(14500);
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
data[i] = i % UINT16_MAX;
|
|
}
|
|
|
|
std::vector<double> energy_values = {6.0, 12.4, 17.7, 5, 4.5, 3.7};
|
|
|
|
const uint16_t nmodules = 1;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
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));
|
|
|
|
JFCalibration c_in(x);
|
|
c_in.Pedestal(0,0) = pedestal_g0;
|
|
c_in.Pedestal(0,1) = pedestal_g1;
|
|
c_in.Pedestal(0,2) = pedestal_g2;
|
|
for (int i = 0; i < x.GetModulesNum(); i++)
|
|
c_in.GainCalibration(i) = gain_from_file;
|
|
|
|
test.InitializeCalibration(x, c_in);
|
|
test.CreatePackets(x, 1, 1, 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);
|
|
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
double mean_error = CheckConversion(x, c_in, data.data(), (int32_t *) test.GetDeviceOutput(0,0)->pixels);
|
|
|
|
REQUIRE(mean_error < 0.5);
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
JFModulePedestal pedestal_g0(0), pedestal_g1(14500), pedestal_g2(14500);
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
data[i] = i % UINT16_MAX;
|
|
}
|
|
|
|
std::vector<double> energy_values = {6.0, 12.4, 17.7, 5, 4.5, 3.7};
|
|
|
|
const uint16_t nmodules = 1;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
auto gain_from_file = GainCalibrationFromTestFile();
|
|
|
|
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));
|
|
|
|
JFCalibration c_in(x);
|
|
c_in.Pedestal(0,0) = pedestal_g0;
|
|
c_in.Pedestal(0,1) = pedestal_g1;
|
|
c_in.Pedestal(0,2) = pedestal_g2;
|
|
for (int i = 0; i < x.GetModulesNum(); i++)
|
|
c_in.GainCalibration(i) = gain_from_file;
|
|
|
|
test.InitializeCalibration(x, c_in);
|
|
for (int i = 0; i < nsummation; i++)
|
|
test.CreatePackets(x, i+1, 1, 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);
|
|
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);
|
|
|
|
REQUIRE(mean_error < 2.0);
|
|
}
|
|
}
|
|
|
|
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);
|
|
|
|
JFModulePedestal pedestal_g0(0), pedestal_g1(14500), pedestal_g2(14500);
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
data[i] = i % UINT16_MAX;
|
|
}
|
|
|
|
std::vector<double> energy_values = {6.0, 12.4, 17.7, 5, 4.5, 3.7};
|
|
|
|
const uint16_t nmodules = 1;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
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));
|
|
|
|
JFCalibration c_in(x);
|
|
c_in.Pedestal(0,0) = pedestal_g0;
|
|
c_in.Pedestal(0,1) = pedestal_g1;
|
|
c_in.Pedestal(0,2) = pedestal_g2;
|
|
for (int i = 0; i < x.GetModulesNum(); i++)
|
|
c_in.GainCalibration(i) = gain_from_file;
|
|
|
|
test.InitializeCalibration(x, c_in);
|
|
test.CreatePackets(x, 1, 1, 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);
|
|
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
double mean_error = CheckConversion(x, c_in, data.data(), (uint16_t *) test.GetDeviceOutput(0,0)->pixels);
|
|
|
|
REQUIRE(mean_error < 0.5);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_convert_full_range", "[FPGA][Full]") {
|
|
double energy = 6.0;
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules, 2, 8, 36, true)));
|
|
|
|
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
|
JFModulePedestal pedestal_g0, pedestal_g1, pedestal_g2;
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
pedestal_g0.GetPedestal()[i] = 0 + (i / 65536) * 1000 + 100 * (i % 5);
|
|
pedestal_g1.GetPedestal()[i] = 14500 - (i / 65536) * 1000 + 100 * (i % 3);
|
|
pedestal_g2.GetPedestal()[i] = 14500 - + (i / 65536) * 1000;
|
|
}
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
data[i] = i % RAW_MODULE_SIZE;
|
|
}
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).UseInternalPacketGenerator(true).PhotonEnergy_keV(energy);
|
|
REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy));
|
|
|
|
auto gain_from_file = GainCalibrationFromTestFile();
|
|
|
|
JFCalibration c(x);
|
|
for (int i = 0; i < x.GetModulesNum(); i++) {
|
|
c.Pedestal(i, 0) = pedestal_g0;
|
|
c.Pedestal(i, 1) = pedestal_g1;
|
|
c.Pedestal(i, 2) = pedestal_g2;
|
|
c.GainCalibration(i) = gain_from_file;
|
|
}
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
test.SetInternalGeneratorFrame();
|
|
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == nmodules * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
double mean_error = CheckConversion(x, c, data.data(), test.GetDeviceOutput(0,0)->pixels);
|
|
|
|
REQUIRE(mean_error < 0.5);
|
|
}
|
|
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_convert_full_range_adu_histo", "[FPGA][Full]") {
|
|
double energy = 6.0;
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules, 2, 8, 36, true)));
|
|
|
|
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
|
JFModulePedestal pedestal_g0, pedestal_g1, pedestal_g2;
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
pedestal_g0.GetPedestal()[i] = 0 + (i / 65536) * 1000 + 100 * (i % 5);
|
|
pedestal_g1.GetPedestal()[i] = 14500 - (i / 65536) * 1000 + 100 * (i % 3);
|
|
pedestal_g2.GetPedestal()[i] = 14500 - + (i / 65536) * 1000;
|
|
}
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
data[i] = i % RAW_MODULE_SIZE;
|
|
}
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).UseInternalPacketGenerator(true).PhotonEnergy_keV(energy);
|
|
REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy));
|
|
|
|
auto gain_from_file = GainCalibrationFromTestFile();
|
|
|
|
JFCalibration c(x);
|
|
for (int i = 0; i < x.GetModulesNum(); i++) {
|
|
c.Pedestal(i, 0) = pedestal_g0;
|
|
c.Pedestal(i, 1) = pedestal_g1;
|
|
c.Pedestal(i, 2) = pedestal_g2;
|
|
c.GainCalibration(i) = gain_from_file;
|
|
}
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
test.SetInternalGeneratorFrame();
|
|
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == nmodules * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
uint32_t err = 0;
|
|
const uint32_t *adu_histogram = test.GetDeviceOutput(0, 0)->adu_histogram;
|
|
for (int i = 0; i < ADU_HISTO_BIN_COUNT; i++) {
|
|
if(adu_histogram[i] != RAW_MODULE_SIZE / ADU_HISTO_BIN_COUNT)
|
|
err++;
|
|
}
|
|
REQUIRE(err == 0);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_apply_pixel_mask", "[FPGA][Full]") {
|
|
double energy = 6.0;
|
|
|
|
const uint16_t nmodules = 1;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
JFModulePedestal pedestal_g0, pedestal_g1, pedestal_g2;
|
|
std::vector<double> gain(3 * RAW_MODULE_SIZE);
|
|
|
|
std::vector<uint16_t> test_frame(RAW_MODULE_SIZE);
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
test_frame[i] = 5000 | ((i > 128*1024) ? 16384:0) | ((i > 256*1024) ? 32768 : 0);
|
|
}
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
pedestal_g0.GetPedestal()[i] = 3000;
|
|
pedestal_g1.GetPedestal()[i] = 14000;
|
|
pedestal_g2.GetPedestal()[i] = 15000;
|
|
}
|
|
pedestal_g0.GetPedestalMask()[0] = 1;
|
|
pedestal_g1.GetPedestalMask()[1] = 1;
|
|
pedestal_g2.GetPedestalMask()[2] = 1;
|
|
|
|
pedestal_g0.GetPedestalMask()[128*1024+1] = 1;
|
|
pedestal_g1.GetPedestalMask()[128*1024+2] = 1;
|
|
pedestal_g2.GetPedestalMask()[128*1024+3] = 1;
|
|
|
|
pedestal_g0.GetPedestalMask()[256*1024+1] = 1;
|
|
pedestal_g1.GetPedestalMask()[256*1024+2] = 1;
|
|
pedestal_g2.GetPedestalMask()[256*1024+3] = 1;
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).UseInternalPacketGenerator(true).PhotonEnergy_keV(energy)
|
|
.ApplyPixelMaskInFPGA(true);
|
|
REQUIRE(x.GetPhotonEnergy_keV() == Approx(energy));
|
|
|
|
JFCalibration c(x);
|
|
c.Pedestal(0,0) = pedestal_g0;
|
|
c.Pedestal(0,1) = pedestal_g1;
|
|
c.Pedestal(0,2) = pedestal_g2;
|
|
c.Mask(3) = UINT32_MAX;
|
|
c.Mask(128*1024+3) = UINT32_MAX;
|
|
c.Mask(256*1024+3) = UINT32_MAX;
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
test.SetInternalGeneratorFrameForAllModules(test_frame);
|
|
|
|
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
size_t err = 0;
|
|
auto frame = test.GetDeviceOutput(0,0)->pixels;
|
|
auto mask = c.CalculateMask(x);
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
if (mask[i] && (frame[i] != INT16_MIN))
|
|
err++;
|
|
if (!mask[i] && (frame[i] == INT16_MIN))
|
|
err++;
|
|
}
|
|
REQUIRE(err == 0);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_2_trigger_convert", "[FPGA][Full]") {
|
|
std::vector<float> pedestal_g0(RAW_MODULE_SIZE), pedestal_g1(RAW_MODULE_SIZE), pedestal_g2(RAW_MODULE_SIZE);
|
|
|
|
LoadBinaryFile("../../tests/test_data/mod5_pedeG0.bin", pedestal_g0.data(), RAW_MODULE_SIZE);
|
|
LoadBinaryFile("../../tests/test_data/mod5_pedeG1.bin", pedestal_g1.data(), RAW_MODULE_SIZE);
|
|
LoadBinaryFile("../../tests/test_data/mod5_pedeG2.bin", pedestal_g2.data(), RAW_MODULE_SIZE);
|
|
|
|
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
|
|
std::vector<float> conv_frames(RAW_MODULE_SIZE*20);
|
|
|
|
for (int i = 0; i < 20; i++) {
|
|
LoadBinaryFile("../../tests/test_data/mod5_raw" + std::to_string(i)+".bin", raw_frames.data() + i * RAW_MODULE_SIZE, RAW_MODULE_SIZE);
|
|
LoadBinaryFile("../../tests/test_data/mod5_conv" + std::to_string(i)+".bin", conv_frames.data() + i * RAW_MODULE_SIZE, RAW_MODULE_SIZE);
|
|
}
|
|
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[4096];
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(2).ImagesPerTrigger(5);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
JFCalibration c(x);
|
|
REQUIRE_NOTHROW(c.Pedestal(0, 0).LoadPedestal(pedestal_g0));
|
|
REQUIRE_NOTHROW(c.Pedestal(0, 1).LoadPedestal(pedestal_g1));
|
|
REQUIRE_NOTHROW(c.Pedestal(0, 2).LoadPedestal(pedestal_g2));
|
|
REQUIRE_NOTHROW(c.GainCalibration(0) = GainCalibrationFromTestFile());
|
|
|
|
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
|
|
|
|
// send some frames without trigger (to be ignored)
|
|
test.CreatePackets(x, 1, 10, 0, raw_frames.data(), true);
|
|
test.CreateFinalPacket(x);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
|
|
REQUIRE(!test.Counters().IsAcquisitionFinished());
|
|
|
|
test.WaitForActionComplete();
|
|
|
|
REQUIRE(test.Counters().IsAcquisitionFinished());
|
|
|
|
// address properly aligned
|
|
REQUIRE((uint64_t) test.GetDeviceOutput(0,0)->pixels % 128 == 0);
|
|
|
|
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
|
|
REQUIRE(test.Counters().GetCurrFrameNumber(0) == 9);
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived()== 128 * 10 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
double mean_error = 0.0;
|
|
for (int image = 0; image < 10; image++) {
|
|
auto img = test.GetDeviceOutput(image, 0)->pixels;
|
|
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
|
|
if ((img[j] < 30000) && (img[j] > -30000)) {
|
|
float diff = (conv_frames[image * RAW_MODULE_SIZE + j] - (float) img[j]);
|
|
mean_error += diff * diff;
|
|
}
|
|
}
|
|
}
|
|
|
|
mean_error = sqrt(mean_error/ (10*RAW_MODULE_SIZE));
|
|
std::cout << "Mean error " << mean_error << std::endl;
|
|
REQUIRE(mean_error < 0.30);
|
|
}
|
|
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_detect_last_frame", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 4;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[4096];
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(2).ImagesPerTrigger(5);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
test.CreatePacketJF(x, 15, 0, 0, data, true);
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE(!test.Counters().IsAcquisitionFinished());
|
|
|
|
test.WaitForActionComplete();
|
|
|
|
REQUIRE(test.Counters().IsAcquisitionFinished());
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_check_wrong_packet_size", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 1;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
uint16_t data[8192];
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(5);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
// send some frames with wrong size or tuser=1
|
|
test.CreatePacketJF(x, 1, 0, 0, data, true, 0);
|
|
test.CreatePacketJF(x, 1, 1, 0, data, true, -1);
|
|
test.CreatePacketJF(x, 1, 2, 0, data, true, 2);
|
|
test.CreatePacketJF(x, 1, 3, 0, data, true, 0);
|
|
test.CreatePacketJF(x, 1, 4, 0, data, true, -5);
|
|
test.CreatePacketJF(x, 1, 5, 0, data, true, 0, 1);
|
|
test.CreatePacketJF(x, 1, 6, 0, data, true, 0);
|
|
test.CreatePacketJF(x, 1, 7, 0, data, true, 0);
|
|
test.CreatePacketJF(x, 1, 8, 0, data, true, 7);
|
|
test.CreatePacketJF(x, 1, 9, 0, data, true, 100);
|
|
test.CreatePacketJF(x, 1, 10, 0, data, true, 2);
|
|
test.CreatePacketJF(x, 1, 11, 0, data, true, 0);
|
|
test.CreatePacketJF(x, 1, 12, 0, data, true, -80);
|
|
test.CreatePacketJF(x, 1, 13, 0, data, true, 100);
|
|
test.CreatePacketJF(x, 1, 118, 0, data, true, 0);
|
|
|
|
test.CreateFinalPacket(x);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
|
|
REQUIRE(!test.Counters().IsAcquisitionFinished());
|
|
|
|
test.WaitForActionComplete();
|
|
|
|
REQUIRE(test.Counters().IsAcquisitionFinished());
|
|
|
|
REQUIRE(test.GetBytesReceived() == 6 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
}
|
|
|
|
TEST_CASE("HLS_DataCollectionFSM","[OpenCAPI]") {
|
|
DataCollectionConfig act_reg;
|
|
|
|
STREAM_512 raw0;
|
|
STREAM_512 raw1;
|
|
|
|
hls::stream<axis_addr> addr0;
|
|
hls::stream<axis_addr> addr1;
|
|
|
|
ap_uint<1> run_data_collection = 0;
|
|
ap_uint<1> cancel_data_collection = 0;
|
|
ap_uint<1> idle_data_collection;
|
|
uint32_t save_data_collection_counter;
|
|
act_reg.mode = MODE_CONV;
|
|
|
|
// state = WAIT_FOR_START
|
|
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
REQUIRE(idle_data_collection == 1);
|
|
REQUIRE(addr1.empty());
|
|
REQUIRE(raw1.empty());
|
|
|
|
run_data_collection = 1;
|
|
|
|
// state = WAIT_FOR_START
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
REQUIRE(idle_data_collection == 0);
|
|
REQUIRE(addr1.empty());
|
|
REQUIRE(raw1.empty());
|
|
|
|
// state = WAIT_FOR_START_LOW
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
REQUIRE(idle_data_collection == 0);
|
|
REQUIRE(addr1.empty());
|
|
REQUIRE(raw1.empty());
|
|
|
|
// state = WAIT_FOR_START_LOW
|
|
|
|
run_data_collection = 0;
|
|
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
REQUIRE(idle_data_collection == 0);
|
|
REQUIRE(addr1.empty());
|
|
REQUIRE(raw1.empty());
|
|
|
|
// state = START
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
|
|
REQUIRE(idle_data_collection == 0);
|
|
REQUIRE(raw1.size() == 1);
|
|
|
|
// state = INIT
|
|
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
|
|
REQUIRE(idle_data_collection == 0);
|
|
REQUIRE(raw1.size() == 1);
|
|
|
|
// state = INIT
|
|
|
|
cancel_data_collection = 1;
|
|
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
|
|
REQUIRE(idle_data_collection == 0);
|
|
REQUIRE(raw1.size() == 1);
|
|
|
|
// state = LAST
|
|
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
|
|
REQUIRE(idle_data_collection == 0);
|
|
REQUIRE(addr1.size() == 1);
|
|
REQUIRE(raw1.size() == 2);
|
|
|
|
// state = WAIT_FOR_START
|
|
|
|
data_collection_fsm(raw0, raw1,
|
|
addr0, addr1,
|
|
run_data_collection,
|
|
cancel_data_collection,
|
|
idle_data_collection,
|
|
act_reg.mode,
|
|
act_reg.one_over_energy,
|
|
act_reg.nframes,
|
|
act_reg.nmodules,
|
|
act_reg.nstorage_cells,
|
|
act_reg.nsummation);
|
|
|
|
REQUIRE(idle_data_collection == 1);
|
|
REQUIRE(addr1.size() == 1);
|
|
REQUIRE(raw1.size() == 2);
|
|
|
|
auto packet = raw1.read();
|
|
REQUIRE(packet.last == 0);
|
|
REQUIRE(packet.dest == 0);
|
|
|
|
packet = raw1.read();
|
|
REQUIRE(packet.last);
|
|
REQUIRE(packet.dest == 0);
|
|
|
|
auto addr = addr1.read();
|
|
REQUIRE(addr.last);
|
|
}
|
|
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_15_storage_cell_convert_G0", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 2;
|
|
const uint16_t ntrigger = 2;
|
|
const uint16_t nstoragecells = 15;
|
|
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(ntrigger).ImagesPerTrigger(nstoragecells).UseInternalPacketGenerator(true)
|
|
.PhotonEnergy_keV(10.0).StorageCells(nstoragecells);
|
|
|
|
REQUIRE(x.GetImageNum() == ntrigger * nstoragecells);
|
|
|
|
HLSSimulatedDevice test(0, ntrigger * nstoragecells);
|
|
|
|
std::vector<double> tmp(3 * RAW_MODULE_SIZE, 50);
|
|
JFModuleGainCalibration gain(tmp);
|
|
|
|
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
|
for (auto &i: data)
|
|
i = 16000;
|
|
REQUIRE_NOTHROW(test.SetInternalGeneratorFrameForAllModules(data));
|
|
|
|
JFCalibration c(x);
|
|
for (int i = 0; i < nstoragecells; i++) {
|
|
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
|
|
c.Pedestal(0, 0, i).GetPedestal()[j] = (15 - i) * 500;
|
|
c.Pedestal(1, 0, i).GetPedestal()[j] = i * 1000;
|
|
}
|
|
}
|
|
c.GainCalibration(0) = gain;
|
|
c.GainCalibration(1) = gain;
|
|
|
|
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == ntrigger * nmodules * nstoragecells * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
for (int i = 0; i < ntrigger * nstoragecells; i++) {
|
|
REQUIRE(test.GetDeviceOutput(i, 0)->pixels[511 * 764] == 32 - 15 + (i % nstoragecells));
|
|
REQUIRE(test.GetDeviceOutput(i, 1)->pixels[200 * 145] == 32 - 2 * (i % nstoragecells));
|
|
}
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_8_storage_cell_convert_G0", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 2;
|
|
const uint16_t ntrigger = 2;
|
|
const uint16_t nstoragecells = 8;
|
|
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(ntrigger).ImagesPerTrigger(nstoragecells).UseInternalPacketGenerator(true)
|
|
.PhotonEnergy_keV(10.0).StorageCells(nstoragecells);
|
|
|
|
REQUIRE(x.GetImageNum() == ntrigger * nstoragecells);
|
|
|
|
HLSSimulatedDevice test(0, ntrigger * nstoragecells);
|
|
|
|
std::vector<double> tmp(3 * RAW_MODULE_SIZE, 50);
|
|
JFModuleGainCalibration gain(tmp);
|
|
|
|
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
|
for (auto &i: data)
|
|
i = 16000;
|
|
REQUIRE_NOTHROW(test.SetInternalGeneratorFrameForAllModules(data));
|
|
|
|
JFCalibration c(x);
|
|
for (int i = 0; i < nstoragecells; i++) {
|
|
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
|
|
c.Pedestal(0, 0, i).GetPedestal()[j] = (15 - i) * 500;
|
|
c.Pedestal(1, 0, i).GetPedestal()[j] = i * 1000;
|
|
}
|
|
}
|
|
c.GainCalibration(0) = gain;
|
|
c.GainCalibration(1) = gain;
|
|
|
|
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == ntrigger * nmodules * nstoragecells * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
for (int i = 0; i < ntrigger * nstoragecells; i++) {
|
|
REQUIRE(test.GetDeviceOutput(i, 0)->pixels[511 * 764] == 32 - 15 + (i % nstoragecells));
|
|
REQUIRE(test.GetDeviceOutput(i, 1)->pixels[200 * 145] == 32 - 2 * (i % nstoragecells));
|
|
}
|
|
}
|
|
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_16_storage_cell_convert_G0", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 2;
|
|
const uint16_t ntrigger = 4;
|
|
const uint16_t nstoragecells = 16;
|
|
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(ntrigger).ImagesPerTrigger(nstoragecells).UseInternalPacketGenerator(true)
|
|
.PhotonEnergy_keV(10.0).StorageCells(nstoragecells);
|
|
|
|
REQUIRE(x.GetImageNum() == ntrigger * nstoragecells);
|
|
|
|
HLSSimulatedDevice test(0, ntrigger * nstoragecells);
|
|
std::vector<double> tmp(3 * RAW_MODULE_SIZE, 50);
|
|
JFModuleGainCalibration gain(tmp);
|
|
|
|
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
|
for (auto &i: data)
|
|
i = 16000;
|
|
REQUIRE_NOTHROW(test.SetInternalGeneratorFrameForAllModules(data));
|
|
|
|
JFCalibration c(x);
|
|
for (int i = 0; i < nstoragecells; i++) {
|
|
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
|
|
c.Pedestal(0, 0, i).GetPedestal()[j] = (15 - i) * 500;
|
|
c.Pedestal(1, 0, i).GetPedestal()[j] = i * 1000;
|
|
}
|
|
}
|
|
c.GainCalibration(0) = gain;
|
|
c.GainCalibration(1) = gain;
|
|
|
|
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == ntrigger * nmodules * nstoragecells * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
for (int i = 0; i < ntrigger * nstoragecells; i++) {
|
|
REQUIRE(test.GetDeviceOutput(i, 0)->pixels[511 * 764] == 32 - 15 + (i % nstoragecells));
|
|
REQUIRE(test.GetDeviceOutput(i, 1)->pixels[200 * 145] == 32 - 2 * (i % nstoragecells));
|
|
}
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_storage_cell_convert_G1", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 2;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Conversion);
|
|
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(16).UseInternalPacketGenerator(true)
|
|
.PhotonEnergy_keV(10.0).StorageCells(16);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
std::vector<uint16_t> data(RAW_MODULE_SIZE);
|
|
for (auto &i: data)
|
|
i = 16384 | 10;
|
|
REQUIRE_NOTHROW(test.SetInternalGeneratorFrameForAllModules(data));
|
|
|
|
JFCalibration c(x);
|
|
for (int i = 0; i < 16; i++) {
|
|
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
|
|
c.Pedestal(0, 1, i).GetPedestal()[j] = (17 - i) * 10;
|
|
c.Pedestal(1, 1, i).GetPedestal()[j] = i * 20;
|
|
}
|
|
}
|
|
|
|
std::vector<double> tmp(3 * RAW_MODULE_SIZE, -1);
|
|
JFModuleGainCalibration gain(tmp);
|
|
c.GainCalibration(0) = gain;
|
|
c.GainCalibration(1) = gain;
|
|
|
|
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE_NOTHROW(test.OutputStream().read());
|
|
REQUIRE(test.OutputStream().size() == 0);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 32*128*JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
for (int i = 0; i < 16; i++) {
|
|
REQUIRE(test.GetDeviceOutput(i, 0)->pixels[511 * 764] == 17 - (i % 16) - 1);
|
|
REQUIRE(test.GetDeviceOutput(i, 1)->pixels[200 * 145] == 2 * (i % 16) - 1);
|
|
}
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_integration", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 4;
|
|
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
std::vector<uint16_t> frame(RAW_MODULE_SIZE);
|
|
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++)
|
|
frame[i] = 32754;
|
|
|
|
test.SetInternalGeneratorFrameForAllModules(frame);
|
|
|
|
std::vector<uint16_t> integration_map(nmodules * RAW_MODULE_SIZE, 54);
|
|
for (int i = 0; i < RAW_MODULE_SIZE/2; i++) {
|
|
integration_map[2 * i] = 0;
|
|
integration_map[2 * i + 1] = FPGA_INTEGRATION_BIN_COUNT - 1;
|
|
}
|
|
|
|
integration_map[RAW_MODULE_SIZE - 1] = FPGA_INTEGRATION_BIN_COUNT;
|
|
test.InitializeIntegrationMap(x, integration_map);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.OutputStream().size() == 1);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
|
|
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 == 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 == 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 == 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 == 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 == Approx(32754 * (RAW_MODULE_SIZE)));
|
|
CHECK(integration_result[54].count == RAW_MODULE_SIZE);
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_count_threshold", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 4;
|
|
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
std::vector<uint16_t> frame(RAW_MODULE_SIZE, 0);
|
|
frame [ 0] = 11;
|
|
frame [123*1024 + 578] = 10;
|
|
frame [121*1024 + 800] = 12;
|
|
frame [ 89*1024 + 300] = 8;
|
|
frame [300*1024 + 0] = 9;
|
|
|
|
test.SetInternalGeneratorFrameForAllModules(frame);
|
|
|
|
test.SetSpotFinderParameters(10, 0.0);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.OutputStream().size() == 1);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
|
|
REQUIRE(memcmp(imageBuf, frame.data(), RAW_MODULE_SIZE * sizeof(uint16_t)) == 0);
|
|
|
|
auto spot_finder_result = test.GetDeviceOutput(0, 0)->spot_finding_result;
|
|
REQUIRE (spot_finder_result.strong_pixel_count == 3);
|
|
REQUIRE (spot_finder_result.snr_threshold == 0);
|
|
REQUIRE (spot_finder_result.count_threshold == 10);
|
|
REQUIRE (spot_finder_result.strong_pixel[0] == (1<<0));
|
|
REQUIRE (spot_finder_result.strong_pixel[(123*1024 + 578) / 8] == (1<<2)); // 578 % 8 == 2
|
|
REQUIRE (spot_finder_result.strong_pixel[(121*1024 + 800) / 8] == (1<<0)); // 800 % 8 == 0
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_snr_threshold", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 4;
|
|
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
|
|
std::vector<uint16_t> frame(RAW_MODULE_SIZE);
|
|
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
|
|
frame[i] = ((i / RAW_MODULE_COLS) + (i % RAW_MODULE_COLS)) % 2;
|
|
}
|
|
// Mean = 0.5
|
|
// Std. dev. = 0.5
|
|
// Threshold = 10 * std. dev. - 6 is minimum count
|
|
|
|
frame [ 0] = 8;
|
|
frame [123*1024 + 578] = 5;
|
|
frame [121*1024 + 800] = 4;
|
|
frame [ 89*1024 + 300] = 7;
|
|
frame [300*1024 + 0] = 3;
|
|
|
|
test.SetInternalGeneratorFrameForAllModules(frame);
|
|
|
|
test.SetSpotFinderParameters(0, 10);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.OutputStream().size() == 1);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
|
|
REQUIRE(memcmp(imageBuf, frame.data(), RAW_MODULE_SIZE * sizeof(uint16_t)) == 0);
|
|
|
|
auto spot_finder_result = test.GetDeviceOutput(0, 0)->spot_finding_result;
|
|
REQUIRE (spot_finder_result.strong_pixel_count == 2);
|
|
REQUIRE (spot_finder_result.snr_threshold == 10 * 4);
|
|
REQUIRE (spot_finder_result.count_threshold == 0);
|
|
REQUIRE (spot_finder_result.strong_pixel[0] == (1<<0));
|
|
REQUIRE (spot_finder_result.strong_pixel[(89*1024 + 300) / 8] == (1<<4)); // 300 % 8 == 4
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_32bit", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 1;
|
|
const size_t nframes = 2;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
std::vector<uint16_t> test_frame(nmodules*RAW_MODULE_SIZE);
|
|
|
|
std::mt19937 g1(1387);
|
|
std::uniform_int_distribution<uint16_t> dist(0, UINT16_MAX);
|
|
|
|
for (auto &i: test_frame)
|
|
i = dist(g1);
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nframes).PedestalG0Frames(0).FPGAOutputMode(FPGAPixelOutput::Int32);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
test.SetInternalGeneratorFrame(test_frame);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.OutputStream().size() == 1);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 128 * nmodules * nframes * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
auto test_frame_unsigned = (uint16_t *) test_frame.data();
|
|
|
|
for (int image = 0; image < nframes; image++) {
|
|
for (int m = 0; m < nmodules; m++) {
|
|
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++) {
|
|
REQUIRE(imageBuf[i] == test_frame_unsigned[m * RAW_MODULE_SIZE + i]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
TEST_CASE("HLS_C_Simulation_internal_packet_generator_summation", "[FPGA][Full]") {
|
|
const uint16_t nmodules = 1;
|
|
const size_t nframes = 16;
|
|
const size_t nsummation = 16;
|
|
DiffractionExperiment x((DetectorGeometry(nmodules)));
|
|
|
|
std::vector<uint16_t> test_frame(nmodules*RAW_MODULE_SIZE);
|
|
|
|
std::mt19937 g1(1387);
|
|
std::uniform_int_distribution<uint16_t> dist(0, 65535);
|
|
|
|
for (auto &i: test_frame)
|
|
i = dist(g1);
|
|
|
|
x.Mode(DetectorMode::Raw);
|
|
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nframes).PedestalG0Frames(0).Summation(nsummation);
|
|
|
|
HLSSimulatedDevice test(0, 64);
|
|
test.SetInternalGeneratorFrame(test_frame);
|
|
|
|
REQUIRE_NOTHROW(test.StartAction(x));
|
|
REQUIRE_NOTHROW(test.WaitForActionComplete());
|
|
|
|
REQUIRE(test.OutputStream().size() == 1);
|
|
|
|
REQUIRE(test.GetBytesReceived() == 128 * nmodules * nframes * nsummation * JUNGFRAU_PACKET_SIZE_BYTES);
|
|
|
|
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.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++) {
|
|
REQUIRE(imageBuf[i] == test_frame_signed[m * RAW_MODULE_SIZE + i] * nsummation);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#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);
|
|
}
|
|
}
|