Files
Jungfraujoch/tests/FPGAIntegrationTest.cpp
leonarski_fandClaude Opus 5.5 637d2c09cc pixel_sum on the CPU and GPU path, under the device mask, and read back from HDF5
pixel_sum existed only on the FPGA path, so a DECTRIS master file carried an all-zero
/entry/image/pixel_sum. The CPU and GPU image preprocessors now compute it in the pass that takes the
minimum and maximum, as a signed 64-bit sum, and MXAnalysisWithoutFPGA reports it: Lite, live stills,
live rotation and rugnux. On the simulated card it equals the card's own sum, for 16-bit and for
summed 32-bit frames.

The sum excludes error and saturated pixels and the device mask (detector and calibration). The hot
pixels and the beam-stop shadow a run finds on its own frames do not change it, though they stay masked
in the image and in the other statistics, so the number does not depend on what a run decided. Those
two have bits of their own (PixelMask::RunMaskBits); the byte-per-pixel mask keeps the difference, 1 for
the device mask and 2 for the run's alone, and the CPU preprocessor gets a packed mask of the second.
Live stills reports this sum of the assembled image in place of the card's, and with the run's mask out
of it the two agree on the test frames.

Frames a live rotation run does not reach stay 0 in the master file, as before, and have no dataset in
the data files. The reader now reads pixel_sum into the dataset and the per-image message; a file
without it opens as before.

(ported from rc184-2 15af14357)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK
2026-11-08 20:08:56 +01:00

2847 lines
102 KiB
C++

// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include <catch2/catch_all.hpp>
#include <random>
#include "../jungfrau/JFPedestalCalc.h"
#include "../acquisition_device/HLSSimulatedDevice.h"
#include "../image_analysis/image_preprocessing/ImagePreprocessorCPU.h"
#ifdef JFJOCH_USE_CUDA
#include "../image_analysis/image_preprocessing/ImagePreprocessorBufferGPU.h"
#include "../image_analysis/image_preprocessing/ImagePreprocessorGPU.h"
#endif
#include "CheckImageOutput.h"
using namespace std::literals::chrono_literals;
TEST_CASE("HLS_C_Simulation_internal_packet_generator", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0);
HLSSimulatedDevice test(0, 64);
std::vector<uint16_t> ref_data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
ref_data[i] = i % 65536;
for (int m = 0; m < nmodules; m++)
test.SetInternalGeneratorFrame(ref_data.data(), m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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() == DMA_DESCRIPTORS_PER_MODULE);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_data_stream", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.DataStreams(4);
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0);
HLSSimulatedDevice test(3, 64);
std::vector<uint16_t> ref_data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
ref_data[i] = i % 65536;
test.SetInternalGeneratorFrame(ref_data.data(), 0);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
auto imageBuf = (uint16_t *) test.GetDeviceOutput(image, 0)->pixels;
for (int i = 0; i < RAW_MODULE_SIZE; i++)
REQUIRE(imageBuf[i] == i % 65536);
}
REQUIRE(test.GetExpectedDescriptorsPerModule() == DMA_DESCRIPTORS_PER_MODULE);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_custom_frame", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 32;
const size_t nframes = 2;
DiffractionExperiment x(DetJF(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.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nframes).PedestalG0Frames(0);
HLSSimulatedDevice test(0, 128);
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(test_frame.data() + RAW_MODULE_SIZE * m, m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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.pulse_id == INT_PKT_GEN_BUNCHID + image);
REQUIRE(test.GetDeviceOutput(image, m)->module_statistics.exptime == INT_PKT_GEN_EXPTTIME);
REQUIRE(test.GetDeviceOutput(image, m)->module_statistics.detector_type == SLS_DETECTOR_TYPE_JUNGFRAU);
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]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE);
LoadBinaryFile("../../tests/test_data/mod5_raw0.bin", raw_frames.data(), RAW_MODULE_SIZE);
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
x.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(1).NumTriggers(1);
HLSSimulatedDevice test(0, 64);
test.CreateJFPackets(x, 1, 1, 0, raw_frames.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
uint64_t diffs = 0;
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
if (raw_frames[j] != ((uint16_t *) test.GetDeviceOutput(0, 0)->pixels)[j]) {
diffs++;
std::cout << raw_frames[j] << " " << ((uint16_t *) test.GetDeviceOutput(0, 0)->pixels)[j] << std::endl;
}
}
REQUIRE(diffs == 0);
}
TEST_CASE("HLS_C_Simulation_check_missing_modules", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
const uint64_t nframes = AcquisitionCounters::ThresholdFramesLost + 5;
std::vector<uint16_t> raw_frames(nframes * RAW_MODULE_SIZE, 0);
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(nframes).NumTriggers(1);
HLSSimulatedDevice test(0, nframes + 2);
test.CreateJFPackets(x, 1, nframes, 0, raw_frames.data());
test.CreateJFPackets(x, 1, 3, 1, raw_frames.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.Counters().GetSlowestFrameNumber() == 5 - 1);
REQUIRE(test.Counters().GetBufferHandle(0,0) != AcquisitionCounters::HandleNotFound);
REQUIRE(test.Counters().GetBufferHandle(0,1) == AcquisitionCounters::HandleNotFound);
REQUIRE(test.Counters().GetBufferHandle(0,2) == AcquisitionCounters::HandleNotFound);
REQUIRE(test.GetBytesReceived() == nframes * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
}
TEST_CASE("HLS_C_Simulation_check_cancel", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
x.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(test.GetBytesReceived() == 0);
}
TEST_CASE("HLS_C_Simulation_check_cancel_conversion", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
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(test.GetBytesReceived() == 0);
}
TEST_CASE("HLS_C_Simulation_check_delay", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
x.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
HLSSimulatedDevice test(0, 64);
test.CreateJFPacket(x, 1, 0, 0, data);
test.CreateJFPacket(x, 1, 0, 1, data);
test.CreateJFPacket(x, 1, 0, 2, data);
test.CreateJFPacket(x, 1, 0, 3, data);
test.CreateJFPacket(x, 2, 0, 0, data);
test.CreateJFPacket(x, 2, 0, 1, data);
test.CreateJFPacket(x, 2, 0, 2, data);
test.CreateJFPacket(x, 2, 0, 3, data);
test.CreateJFPacket(x, 3, 0, 0, data);
test.CreateJFPacket(x, 3, 0, 1, data);
test.CreateJFPacket(x, 3, 0, 2, data);
test.CreateJFPacket(x, 3, 0, 3, data);
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]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
for (int i = 0; i < 4096; i++) data[i] = i;
x.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
HLSSimulatedDevice test(0, 64);
test.CreateJFPacket(x, 1, 0, 0, data);
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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_THROWS(test.GetDeviceOutput(0,1));
REQUIRE_THROWS(test.GetDeviceOutput(0,1));
}
TEST_CASE("HLS_C_Simulation_check_lost_frame_conversion", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
for (int i = 0; i < 4096; i++) data[i] = i;
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
HLSSimulatedDevice test(0, 64);
test.CreateJFPacket(x, 1, 0, 0, data);
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == JUNGFRAU_PACKET_SIZE_BYTES);
REQUIRE_THROWS(test.GetDeviceOutput(0,1));
REQUIRE_THROWS(test.GetDeviceOutput(0,1));
REQUIRE_THROWS(test.GetDeviceOutput(1,0));
REQUIRE_THROWS(test.GetDeviceOutput(2,1));
}
TEST_CASE("HLS_C_Simulation_check_single_packet_raw", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(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.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
HLSSimulatedDevice test(0, 64);
test.CreateJFPacket(x, 1, 0, 0, data);
test.CreateJFPacket(x, 1, 64, 0, data);
test.CreateJFPacket(x, 1, 0, 2, data);
test.CreateJFPacket(x, 1, 2, 3, data);
test.CreateJFPacket(x, 1, 3, 3, data);
test.CreateJFPacket(x, 1, 1, 3, data);
test.CreateJFPacket(x, 1, 0, 3, data);
test.CreateJFPacket(x, 1, 64, 3, data);
test.CreateJFPacket(x, 1, 5, 0, data);
test.CreateJFPacket(x, 1, 4, 0, data);
test.CreateJFPacket(x, 1, 67, 1, data);
test.CreateJFPacket(x, 1, 66, 1, data);
test.CreateJFPacket(x, 1, 68, 1, data);
test.CreateJFPacket(x, 3, 1, 0, data);
test.CreateJFPacket(x, 2, 1, 0, data);
test.CreateJFPacket(x, 4, 1, 0, data);
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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.GetDeviceOutput(0,0)->module_statistics.detector_type == SLS_DETECTOR_TYPE_JUNGFRAU);
}
TEST_CASE("HLS_C_Simulation_check_single_packet_conv", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> raw_frames(RAW_MODULE_SIZE*20);
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
int16_t wrong[4096];
for (int i = 0; i < 4096; i++) {
data[i] = (7 * i + 534 + 5 * i * i) % UINT16_MAX;
wrong[i] = INT16_MIN;
}
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
HLSSimulatedDevice test(0, 64);
auto gain_from_file = GainCalibrationFromTestFile();
JFModulePedestal pedestal_g0(1000), pedestal_g1(14500), pedestal_g2(14500);
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.CreateJFPacket(x, 1, 0, 0, data);
test.CreateJFPacket(x, 1, 64, 0, data);
test.CreateJFPacket(x, 1, 67, 1, data);
test.CreateJFPacket(x, 1, 66, 1, data);
test.CreateJFPacket(x, 1, 68, 1, data);
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 5 * JUNGFRAU_PACKET_SIZE_BYTES);
CHECK(memcmp(test.GetDeviceOutput(0,0)->pixels + 0 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) != 0);
CHECK(memcmp(test.GetDeviceOutput(0,0)->pixels + 1 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
CHECK(memcmp(test.GetDeviceOutput(0,0)->pixels + 2 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
CHECK(memcmp(test.GetDeviceOutput(0,0)->pixels + 3 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
CHECK(memcmp(test.GetDeviceOutput(0,0)->pixels + 6 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
CHECK(memcmp(test.GetDeviceOutput(0,0)->pixels + 64 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) != 0);
CHECK(memcmp(test.GetDeviceOutput(0,1)->pixels + 65 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) == 0);
CHECK(memcmp(test.GetDeviceOutput(0,1)->pixels + 66 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) != 0);
CHECK(memcmp(test.GetDeviceOutput(0,1)->pixels + 67 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) != 0);
CHECK(memcmp(test.GetDeviceOutput(0,1)->pixels + 68 * JUNGFRAU_PACKET_SIZE_BYTES/2, wrong, JUNGFRAU_PACKET_SIZE_BYTES) != 0);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.detector_type == SLS_DETECTOR_TYPE_JUNGFRAU);
}
TEST_CASE("HLS_C_Simulation_check_convert_full_range", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
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(DetJF(nmodules));
HLSSimulatedDevice test(0, 64);
auto gain_from_file = GainCalibrationFromTestFile();
for (const auto energy : energy_values) {
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).IncidentEnergy_keV(energy);
x.GeometryTransformation(false);
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(x, c_in, data.data(), test.GetDeviceOutput(0, 0)->pixels);
logger.Info("Error of {:.2f} for photon energy {} keV", mean_error, energy);
REQUIRE(mean_error < 0.5);
}
}
TEST_CASE("HLS_C_Simulation_check_convert_full_range_HG0", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> data(RAW_MODULE_SIZE);
std::vector<double> gain(3 * RAW_MODULE_SIZE);
JFModulePedestal pedestal_g0(1000), pedestal_g1(14500), pedestal_g2(14500);
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
data[i] = i % 0x4000; // only generate gain 0
}
std::vector<double> energy_values = {6.0, 12.4, 17.7, 5, 4.5, 3.7, 2.0, 1.0, 0.5, 0.1};
const uint16_t nmodules = 1;
DiffractionExperiment x(DetJF(nmodules));
x.UsingGainHG0(true);
HLSSimulatedDevice test(0, 64);
auto gain_from_file = GainCalibrationFromTestFile();
logger.Info("With HG0");
for (const auto energy : energy_values) {
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).IncidentEnergy_keV(energy);
x.GeometryTransformation(false);
REQUIRE(x.IsUsingGainHG0());
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(x, c_in, data.data(), test.GetDeviceOutput(0, 0)->pixels);
logger.Info(" std. dev. of {:.2f} for photon energy {} keV", mean_error, energy);
REQUIRE(mean_error < 0.5);
}
logger.Info("Without HG0");
x.UsingGainHG0(false);
for (const auto energy : energy_values) {
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).IncidentEnergy_keV(energy);
x.GeometryTransformation(false);
REQUIRE(!x.IsUsingGainHG0());
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(x, c_in, data.data(), test.GetDeviceOutput(0, 0)->pixels);
logger.Info(" std. dev. of {:.2f} for photon energy {} keV", mean_error, energy);
REQUIRE(mean_error < 0.5);
}
}
TEST_CASE("HLS_C_Simulation_check_convert_full_range_fixedG1", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> data(RAW_MODULE_SIZE);
std::vector<double> gain(3 * RAW_MODULE_SIZE);
JFModulePedestal pedestal_g0(1000), pedestal_g1(1500), pedestal_g2(14500);
std::vector<double> energy_values = {6.0, 12.4, 17.7, 5, 4.5, 3.7, 2.0, 1.0};
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
data[i] = i % UINT16_MAX;
}
const uint16_t nmodules = 1;
DiffractionExperiment x(DetJF(nmodules));
x.FixedGainG1(true);
HLSSimulatedDevice test(0, 64);
auto gain_from_file = GainCalibrationFromTestFile();
for (const auto energy : energy_values) {
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).IncidentEnergy_keV(energy).GeometryTransformation(false);
REQUIRE(x.IsFixedGainG1());
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(x, c_in, data.data(), test.GetDeviceOutput(0, 0)->pixels);
logger.Info(" std. dev. of {:.2f} for photon energy {} keV", mean_error, energy);
REQUIRE(mean_error < 0.5);
}
}
TEST_CASE("HLS_C_Simulation_check_convert_full_range_I32", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
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, 3.0};
const uint16_t nmodules = 1;
DiffractionExperiment x(DetJF(nmodules));
HLSSimulatedDevice test(0, 64);
auto gain_from_file = GainCalibrationFromTestFile();
for (const auto energy : energy_values) {
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).IncidentEnergy_keV(energy)
.PixelSigned(true).BitDepthImage(32).GeometryTransformation(false);
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(x, c_in, data.data(), (int32_t *) test.GetDeviceOutput(0, 0)->pixels);
logger.Info("Error of {:.2f} for photon energy {} keV", mean_error, energy);
REQUIRE(mean_error < 0.5);
}
}
TEST_CASE("HLS_C_Simulation_check_convert_full_range_sum4", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
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(DetJF(nmodules));
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).IncidentEnergy_keV(energy).Summation(nsummation)
.GeometryTransformation(false);
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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.CreateJFPackets(x, i + 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * nsummation * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(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(Catch::getResultCapture().getCurrentTestName());
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(DetJF(nmodules));
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).IncidentEnergy_keV(energy)
.PixelSigned(false).BitDepthImage(16).GeometryTransformation(false);
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(x, c_in, data.data(), (uint16_t *) test.GetDeviceOutput(0, 0)->pixels);
REQUIRE(mean_error < 0.5);
}
}
TEST_CASE("HLS_C_Simulation_check_poisson_full_range", "[FPGA][Full]") {
// This test is not 100% representable!
// At the moment it is not possible to include "hls_math.h" in jfjoch_test
// So hls::sqrt is actually implemented as round(sqrt())
// This can be only handled by HLS test bench
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
data[i] = i % UINT16_MAX;
}
const uint16_t nmodules = 1;
for (int sqrtmult: {1, 2,4,8}) {
DiffractionExperiment x(DetJF(nmodules));
x.Raw().PixelSigned(true).BitDepthImage(16);
HLSSimulatedDevice test(0, 64);
x.NumTriggers(1).ImagesPerTrigger(1).LossyCompressionPoisson(sqrtmult);
test.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto data_signed = (int16_t *) data.data();
uint64_t diff = 0;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
uint64_t expected_value = 0;
if (data_signed[i] == INT16_MAX)
expected_value = INT16_MAX;
else if (data_signed[i] == INT16_MIN)
expected_value = INT16_MIN;
else if (data_signed[i] >= 0)
expected_value = std::lround(std::sqrt(data_signed[i]) * sqrtmult);
if (expected_value != test.GetDeviceOutput(0, 0)->pixels[i])
diff++;
}
REQUIRE(diff == 0);
}
}
TEST_CASE("HLS_C_Simulation_check_threshold_full_range", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
data[i] = i % UINT16_MAX;
}
const uint16_t nmodules = 1;
for (int threshold: {1, 2, 4, 8}) {
DiffractionExperiment x(DetJF(nmodules));
x.Raw().PixelSigned(true).BitDepthImage(16);
HLSSimulatedDevice test(0, 64);
x.NumTriggers(1).ImagesPerTrigger(1).PixelValueLowThreshold(threshold);
test.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto data_signed = (int16_t *) data.data();
uint64_t diff = 0;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
uint64_t expected_value = data_signed[i];
if (data_signed[i] == INT16_MAX)
expected_value = INT16_MAX;
else if (data_signed[i] == INT16_MIN)
expected_value = INT16_MIN;
else if (data_signed[i] < threshold)
expected_value = 0;
if (expected_value != test.GetDeviceOutput(0, 0)->pixels[i]) {
std::cout << data_signed[i] << " " << expected_value << " " << threshold << std::endl;
diff++;
}
}
REQUIRE(diff == 0);
}
}
TEST_CASE("HLS_C_Simulation_check_convert_full_range_poisson", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
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(DetJF(nmodules));
x.LossyCompressionPoisson(2);
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).IncidentEnergy_keV(energy)
.PixelSigned(false).BitDepthImage(16).GeometryTransformation(false);
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(x, c_in, data.data(), (uint16_t *) test.GetDeviceOutput(0, 0)->pixels);
REQUIRE(mean_error < 0.5);
}
}
TEST_CASE("HLS_C_Simulation_no_conversion_U16", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
data[i] = i % UINT16_MAX;
data[5456] = UINT16_MAX;
data[211] = UINT16_MAX;
const uint16_t nmodules = 1;
DiffractionExperiment x(DetJF(nmodules));
x.JungfrauConvPhotonCnt(false);
HLSSimulatedDevice test(0, 64);
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PixelSigned(false).BitDepthImage(16);
test.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto output = (uint16_t *) test.GetDeviceOutput(0, 0)->pixels;
size_t err = 0;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
CHECK(data[i] == output[i]);
}
REQUIRE(err == 0);
}
TEST_CASE("HLS_C_Simulation_no_conversion_U32", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
data[i] = i % UINT16_MAX;
data[5456] = UINT16_MAX;
data[211] = UINT16_MAX;
const uint16_t nmodules = 1;
DiffractionExperiment x(DetJF(nmodules));
x.JungfrauConvPhotonCnt(false);
HLSSimulatedDevice test(0, 64);
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PixelSigned(false).BitDepthImage(32);
test.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto output = (uint32_t *) test.GetDeviceOutput(0, 0)->pixels;
size_t err = 0;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
if (data[i] == UINT16_MAX) {
CHECK(output[i] == UINT32_MAX);
} else if (data[i] != output[i]) err++;
}
REQUIRE(err == 0);
}
TEST_CASE("HLS_C_Simulation_no_conversion_I32", "[FPGA][Full]") {
Logger logger("HLS_C_Simulation_no_conversion_I32");
std::vector<uint16_t> data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
data[i] = i % UINT16_MAX;
data[5456] = UINT16_MAX;
data[211] = UINT16_MAX;
const uint16_t nmodules = 1;
DiffractionExperiment x(DetJF(nmodules));
x.JungfrauConvPhotonCnt(false);
HLSSimulatedDevice test(0, 64);
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).PixelSigned(true).BitDepthImage(32);
test.CreateJFPackets(x, 1, 1, 0, data.data());
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
CHECK(test.GetBytesReceived() == 128 * JUNGFRAU_PACKET_SIZE_BYTES);
auto data16_signed = (int16_t *) data.data();
auto output = (int32_t *) test.GetDeviceOutput(0, 0)->pixels;
size_t err = 0;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
if (data16_signed[i] == INT16_MAX) {
CHECK(output[i] == INT32_MAX);
} else if (data16_signed[i] == INT16_MIN) {
CHECK(output[i] == INT32_MIN);
} else if (data16_signed[i] != output[i]) err++;
}
REQUIRE(err == 0);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_convert_full_range", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
double energy = 6.0;
const uint16_t nmodules = 1;
DiffractionExperiment x(DetJF(nmodules));
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.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).UseInternalPacketGenerator(true).IncidentEnergy_keV(energy)
.GeometryTransformation(false);
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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);
std::vector<uint16_t> ref_data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
ref_data[i] = i % 65536;
for (int m = 0; m < nmodules; m++)
test.SetInternalGeneratorFrame(ref_data.data(), m);
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == nmodules * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = CheckImageOutput(x, c, data.data(), test.GetDeviceOutput(0, 0)->pixels);
REQUIRE(mean_error < 0.5);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_mask", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
double energy = 6.0;
const uint16_t nmodules = 2;
DiffractionExperiment x(DetJF(nmodules));
std::vector<uint16_t> data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
data[i] = i % 7;
x.Raw();
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).UseInternalPacketGenerator(true).IncidentEnergy_keV(energy)
.GeometryTransformation(false).PixelSigned(true).ApplyPixelMask(true);
REQUIRE(x.GetIncidentEnergy_keV() == Catch::Approx(energy));
HLSSimulatedDevice test(0, 64);
std::vector<uint32_t> module_pixel_mask(RAW_MODULE_SIZE);
module_pixel_mask[456*49+6] = 1;
module_pixel_mask[0] = 128;
module_pixel_mask[RAW_MODULE_SIZE - 1] = 16384;
for (int m = 0; m < nmodules; m++)
test.SetInternalGeneratorFrame(data.data(), m);
REQUIRE_NOTHROW(test.InitializePixelMask(module_pixel_mask.data(), 1));
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == nmodules * 128 * JUNGFRAU_PACKET_SIZE_BYTES);
CHECK(test.GetDeviceOutput(0, 0)->pixels[0] == 0);
CHECK(test.GetDeviceOutput(0, 0)->pixels[1] == 1);
CHECK(test.GetDeviceOutput(0, 0)->pixels[456*49+5] == 5);
CHECK(test.GetDeviceOutput(0, 0)->pixels[456*49+6] == 6);
CHECK(test.GetDeviceOutput(0, 0)->pixels[456*49+7] == 0);
CHECK(test.GetDeviceOutput(0, 0)->pixels[RAW_MODULE_SIZE - 1] == (RAW_MODULE_SIZE - 1) % 7);
CHECK(test.GetDeviceOutput(0, 1)->pixels[0] == INT16_MIN);
CHECK(test.GetDeviceOutput(0, 1)->pixels[1] == 1);
CHECK(test.GetDeviceOutput(0, 1)->pixels[456*49+5] == 5);
CHECK(test.GetDeviceOutput(0, 1)->pixels[456*49+6] == INT16_MIN);
CHECK(test.GetDeviceOutput(0, 1)->pixels[456*49+7] == 0);
CHECK(test.GetDeviceOutput(0, 1)->pixels[RAW_MODULE_SIZE - 1] == INT16_MIN);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_convert_full_range_adu_histo", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
double energy = 6.0;
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(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.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1).UseInternalPacketGenerator(true).IncidentEnergy_keV(energy);
REQUIRE(x.GetIncidentEnergy_keV() == Catch::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);
std::vector<uint16_t> ref_data(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
ref_data[i] = i % 65536;
for (int m = 0; m < nmodules; m++)
test.SetInternalGeneratorFrame(ref_data.data(), m);
REQUIRE_NOTHROW(test.InitializeCalibration(x, c));
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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_check_2_trigger_convert", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
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);
std::vector<float> conv_frames(RAW_MODULE_SIZE);
LoadBinaryFile("../../tests/test_data/mod5_raw0.bin", raw_frames.data(), RAW_MODULE_SIZE);
LoadBinaryFile("../../tests/test_data/mod5_conv0.bin", conv_frames.data(), RAW_MODULE_SIZE);
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(1);
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.CreateJFPackets(x, 1, 1, 0, raw_frames.data());
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) == 0);
REQUIRE(test.GetBytesReceived()== 128 * JUNGFRAU_PACKET_SIZE_BYTES);
double mean_error = 0.0;
auto img = test.GetDeviceOutput(0, 0)->pixels;
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
if ((img[j] < 30000) && (img[j] > -30000)) {
float diff = (conv_frames[j] - (float) img[j]);
mean_error += diff * diff;
}
}
mean_error = sqrt(mean_error/ (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]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[4096];
x.PedestalG0Frames(0).NumTriggers(2).ImagesPerTrigger(5);
HLSSimulatedDevice test(0, 64);
test.CreateJFPacket(x, 15, 0, 0, data);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE(!test.Counters().IsAcquisitionFinished());
test.WaitForActionComplete();
REQUIRE(test.Counters().IsAcquisitionFinished());
}
TEST_CASE("HLS_C_Simulation_check_wrong_packet_size", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 1;
DiffractionExperiment x(DetJF(nmodules));
uint16_t data[8192];
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(5);
HLSSimulatedDevice test(0, 64);
// send some frames with wrong size or tuser=1
test.CreateJFPacket(x, 1, 0, 0, data, 0);
test.CreateJFPacket(x, 1, 1, 0, data, -1);
test.CreateJFPacket(x, 1, 2, 0, data, 2);
test.CreateJFPacket(x, 1, 3, 0, data, 0);
test.CreateJFPacket(x, 1, 4, 0, data, -5);
test.CreateJFPacket(x, 1, 5, 0, data, 0, 1);
test.CreateJFPacket(x, 1, 6, 0, data, 0);
test.CreateJFPacket(x, 1, 7, 0, data, 0);
test.CreateJFPacket(x, 1, 8, 0, data, 7);
test.CreateJFPacket(x, 1, 9, 0, data, 100);
test.CreateJFPacket(x, 1, 10, 0, data, 2);
test.CreateJFPacket(x, 1, 11, 0, data, 0);
test.CreateJFPacket(x, 1, 12, 0, data, -80);
test.CreateJFPacket(x, 1, 13, 0, data, 100);
test.CreateJFPacket(x, 1, 118, 0, data, 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_C_Simulation_internal_packet_generator_15_storage_cell_convert_G0", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 2;
const uint16_t ntrigger = 2;
const uint16_t nstoragecells = 15;
DiffractionExperiment x(DetJF(nmodules));
x.PedestalG0Frames(0).NumTriggers(ntrigger).ImagesPerTrigger(nstoragecells).UseInternalPacketGenerator(true)
.IncidentEnergy_keV(10.0).StorageCells(nstoragecells);
REQUIRE(x.GetImageNum() == ntrigger * nstoragecells);
HLSSimulatedDevice test(0, ntrigger * nstoragecells * nmodules + 32);
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;
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(data.data(), m);
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(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]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 2;
const uint16_t ntrigger = 2;
const uint16_t nstoragecells = 8;
DiffractionExperiment x(DetJF(nmodules));
x.PedestalG0Frames(0).NumTriggers(ntrigger).ImagesPerTrigger(nstoragecells).UseInternalPacketGenerator(true)
.IncidentEnergy_keV(10.0).StorageCells(nstoragecells);
REQUIRE(x.GetImageNum() == ntrigger * nstoragecells);
HLSSimulatedDevice test(0, ntrigger * nstoragecells * nmodules + 64);
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;
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(data.data(), m);
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(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]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 2;
const uint16_t ntrigger = 4;
const uint16_t nstoragecells = 16;
DiffractionExperiment x(DetJF(nmodules));
x.PedestalG0Frames(0).NumTriggers(ntrigger).ImagesPerTrigger(nstoragecells).UseInternalPacketGenerator(true)
.IncidentEnergy_keV(10.0).StorageCells(nstoragecells);
REQUIRE(x.GetImageNum() == ntrigger * nstoragecells);
HLSSimulatedDevice test(0, ntrigger * nstoragecells * nmodules + 128);
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;
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(data.data(), m);
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(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]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 2;
DiffractionExperiment x(DetJF(nmodules));
x.PedestalG0Frames(0).NumTriggers(1).ImagesPerTrigger(16).UseInternalPacketGenerator(true)
.IncidentEnergy_keV(10.0).StorageCells(16);
HLSSimulatedDevice test(0, 64);
std::vector<uint16_t> data(RAW_MODULE_SIZE);
for (auto &i: data)
i = 16384 | 10;
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(data.data(), m);
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);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
tmp[i] = DEFAULT_G0_FACTOR;
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(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]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.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;
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(frame.data(), m);
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;
}
std::vector<float> weights(nmodules * RAW_MODULE_SIZE, 1.0);
integration_map[RAW_MODULE_SIZE - 1] = FPGA_INTEGRATION_BIN_COUNT;
test.InitializeIntegrationMap(x, integration_map, weights);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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 == Catch::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 == Catch::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 == Catch::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 == Catch::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 == Catch::Approx(32754 * (RAW_MODULE_SIZE)));
CHECK(integration_result[54].count == RAW_MODULE_SIZE);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_integration_mask", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0).ApplyPixelMask(false);
HLSSimulatedDevice test(0, 64);
std::vector<uint32_t> mask(RAW_MODULE_SIZE, 0);
mask[0] = 4;
std::vector<uint16_t> frame(RAW_MODULE_SIZE, 0);
frame[0] = 2;
frame[1] = 3;
for (int m = 0; m < x.GetModulesNum(); m++) {
test.SetInternalGeneratorFrame(frame.data(), m);
test.InitializePixelMask(mask.data(), m);
}
std::vector<uint16_t> integration_map(nmodules * RAW_MODULE_SIZE, 1);
std::vector<float> weights(nmodules * RAW_MODULE_SIZE, 1.0);
integration_map[0] = 0;
integration_map[1] = 0;
test.InitializeIntegrationMap(x, integration_map, weights);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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 == 3);
CHECK(integration_result[0].count == 1);
CHECK(integration_result[1].sum == 0);
CHECK(integration_result[1].count == RAW_MODULE_SIZE - 2);
}
bool spot_finder_output_contains(const SpotFindingResult& output, uint32_t number) {
size_t byte = number / 8;
size_t bit = number % 8;
return ((output.strong_pixel[byte] & (1 << bit)) != 0);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_count_threshold", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
HLSSimulatedDevice test(0, 64);
std::vector<float> d_map(RAW_MODULE_SIZE, 3.0);
std::vector<uint16_t> frame(RAW_MODULE_SIZE, 0);
frame [ 1*1024 + 1] = 11;
frame [123*1024 + 578] = 10;
frame [121*1024 + 800] = 12;
frame [ 89*1024 + 300] = 8;
frame [300*1024 + 0] = 9;
for (int m = 0; m < x.GetModulesNum(); m++) {
test.SetInternalGeneratorFrame(frame.data(), m);
test.InitializeSpotFinderResolutionMap(d_map.data(), m);
}
SpotFindingSettings parameters{
.signal_to_noise_threshold = 0.0,
.photon_count_threshold = 9,
.min_pix_per_spot = 1,
.high_resolution_limit = 2.5,
.low_resolution_limit = 3.1
};
test.SetSpotFinderParameters(parameters);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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 == 9);
CHECK (spot_finder_output_contains(spot_finder_result, 1*1024 + 1));
CHECK (spot_finder_output_contains(spot_finder_result, 123*1024 + 578));
CHECK (spot_finder_output_contains(spot_finder_result, 121*1024 + 800));
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_mask", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
x.ApplyPixelMask(false);
HLSSimulatedDevice test(0, 64);
std::vector<uint32_t> mask(RAW_MODULE_SIZE, 0);
mask[325*1024 + 463] = 4;
std::vector<uint16_t> frame(RAW_MODULE_SIZE, 0);
// Module boundary
frame [ 0*1024 + 0] = 50;
frame [ 5*1024 + 0] = 50;
frame [ 0*1024 + 5] = 50;
frame [ 511*1024 + 5] = 50;
// Chip boundary
frame [ 345*1024 + 1023] = 50;
frame [ 346*1024 + 255] = 50;
frame [ 347*1024 + 256] = 50;
frame [ 348*1024 + 511] = 50;
frame [ 349*1024 + 512] = 50;
frame [ 350*1024 + 767] = 50;
frame [ 351*1024 + 768] = 50;
frame [ 255*1024 + 234] = 50;
frame [ 256*1024 + 876] = 50;
// "Normal" pixel
frame [ 320*1024 + 400] = 50;
// Masked pixel
frame [ 325*1024 + 463] = 50;
std::vector<float> d_map(RAW_MODULE_SIZE, 3.0);
for (int m = 0; m < x.GetModulesNum(); m++) {
test.SetInternalGeneratorFrame(frame.data(), m);
test.InitializeSpotFinderResolutionMap(d_map.data(), m);
test.InitializePixelMask(mask.data(), m);
}
SpotFindingSettings parameters{
.signal_to_noise_threshold = 0.0,
.photon_count_threshold = 45,
.min_pix_per_spot = 1,
.high_resolution_limit = 2.0,
.low_resolution_limit = 4.0
};
test.SetSpotFinderParameters(parameters);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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 == 1);
REQUIRE (spot_finder_result.snr_threshold == 0);
REQUIRE (spot_finder_result.count_threshold == 45);
CHECK (spot_finder_output_contains(spot_finder_result, 320*1024 + 400));
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_overload", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0).PixelSigned(true);
HLSSimulatedDevice test(0, 64);
std::vector<int16_t> frame(RAW_MODULE_SIZE, 0);
frame [ 132*1024 + 133] = INT16_MAX;
frame [ 0*1024 + 500] = INT16_MIN;
frame [ 255*1024 + 234] = INT16_MAX;
frame [ 300*1024 + 234] = INT16_MAX;
std::vector<float> d_map(RAW_MODULE_SIZE, 3.0);
d_map[ 132*1024 + 133] = 0.0;
for (int m = 0; m < x.GetModulesNum(); m++) {
test.SetInternalGeneratorFrame((uint16_t *) frame.data(), m);
test.InitializeSpotFinderResolutionMap(d_map.data(), m);
}
SpotFindingSettings parameters{
.signal_to_noise_threshold = 5.0,
.photon_count_threshold = 45,
.min_pix_per_spot = 1,
.high_resolution_limit = 2.0,
.low_resolution_limit = 4.0
};
test.SetSpotFinderParameters(parameters);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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 == 1);
REQUIRE (spot_finder_result.snr_threshold == 5.0);
REQUIRE (spot_finder_result.count_threshold == 45);
CHECK (spot_finder_output_contains(spot_finder_result, 300*1024 + 234));
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_min_pix_per_spot", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
HLSSimulatedDevice test(0, 64);
std::vector<float> d_map(RAW_MODULE_SIZE, 3.0);
std::vector<uint16_t> frame(RAW_MODULE_SIZE, 0);
frame [1*1024 + 1] = 11;
frame [1*1024 + 2] = 10;
frame [5*1024 + 7] = 12;
frame [6*1024 + 7] = 12;
frame [ 89*1024+154] = 12;
frame [ 99*1024+200] = 12;
frame [100*1024+200] = 11;
frame [100*1024+201] = 10;
frame [101*1024+200] = 12;
frame [RAW_MODULE_SIZE - 1 - 1024] = 20;
for (int m = 0; m < x.GetModulesNum(); m++) {
test.InitializeSpotFinderResolutionMap(d_map.data(), m);
test.SetInternalGeneratorFrame(frame.data(), m);
}
SpotFindingSettings parameters{
.signal_to_noise_threshold = 0.0,
.photon_count_threshold = 9,
.min_pix_per_spot = 2,
.high_resolution_limit = 2.0,
.low_resolution_limit = 4.0
};
test.SetSpotFinderParameters(parameters);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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 == 8);
REQUIRE (spot_finder_result.snr_threshold == 0);
REQUIRE (spot_finder_result.count_threshold == 9);
CHECK (spot_finder_output_contains(spot_finder_result, 1*1024 + 1));
CHECK (spot_finder_output_contains(spot_finder_result, 1*1024 + 2));
CHECK (spot_finder_output_contains(spot_finder_result, 5*1024 + 7));
CHECK (!spot_finder_output_contains(spot_finder_result, RAW_MODULE_SIZE-1-1024));
CHECK (!spot_finder_output_contains(spot_finder_result, 89*1024+154));
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_d_min_max", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
HLSSimulatedDevice test(0, 64);
std::vector<float> d_map(RAW_MODULE_SIZE, 0.0);
d_map[1024+1] = 2.5;
d_map[1024+2] = 4.0;
d_map[1024+3] = 1.0;
d_map[1024+4] = 1.5;
std::vector<uint16_t> frame(RAW_MODULE_SIZE, 0);
frame [1024+1] = 11;
frame [1024+2] = 10;
frame [1024+3] = 12;
frame [1024+4] = 12;
test.InitializeSpotFinderResolutionMap(d_map.data(), 0);
for (int m = 0; m < x.GetModulesNum(); m++) {
test.SetInternalGeneratorFrame(frame.data(), m);
test.InitializeSpotFinderResolutionMap(d_map.data(), m);
}
SpotFindingSettings parameters{
.signal_to_noise_threshold = 0.0,
.photon_count_threshold = 9,
.min_pix_per_spot = 1,
.high_resolution_limit = 1.25,
.low_resolution_limit = 3.0
};
test.SetSpotFinderParameters(parameters);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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 == 0);
REQUIRE (spot_finder_result.count_threshold == 9);
CHECK (spot_finder_output_contains(spot_finder_result, 1024+1));
CHECK (spot_finder_output_contains(spot_finder_result, 1024+4));
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_spot_finder_snr_threshold", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0);
HLSSimulatedDevice test(0, 64);
std::vector<float> d_map(RAW_MODULE_SIZE, 3.0);
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 [ 1*1024 + 1] = 8;
frame [123*1024 + 578] = 5;
frame [121*1024 + 800] = 4;
frame [ 89*1024 + 300] = 7;
frame [300*1024 + 5] = 3;
for (int m = 0; m < x.GetModulesNum(); m++) {
test.SetInternalGeneratorFrame(frame.data(), m);
test.InitializeSpotFinderResolutionMap(d_map.data(), m);
}
SpotFindingSettings parameters{
.signal_to_noise_threshold = 10.0,
.photon_count_threshold = 0,
.min_pix_per_spot = 1,
.high_resolution_limit = 2.0,
.low_resolution_limit = 3.1
};
test.SetSpotFinderParameters(parameters);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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.0);
REQUIRE (spot_finder_result.count_threshold == 0);
REQUIRE (spot_finder_output_contains(spot_finder_result, 1*1024+1));
REQUIRE (spot_finder_output_contains(spot_finder_result, 89*1024 + 300));
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_pixel_threshold_summation", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0).Summation(4)
.PixelValueLowThreshold(4).AutoSummation(true).PixelSigned(true)
.PixelValueHighThreshold(500);
HLSSimulatedDevice test(0, 64);
std::vector<uint16_t> frame(RAW_MODULE_SIZE, 0);
frame [1024+1] = 1;
frame [1024+2] = 3;
frame [1024+3] = 4;
frame [1024+4] = 5;
frame [1024+5] = 100;
frame [1024+6] = 501;
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(frame.data(), m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 4 * 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
REQUIRE(imageBuf[1024+1] == 0);
REQUIRE(imageBuf[1024+2] == 0);
REQUIRE(imageBuf[1024+3] == 4*4);
REQUIRE(imageBuf[1024+4] == 4*5);
REQUIRE(imageBuf[1024+5] == 4*100);
REQUIRE(imageBuf[1024+6] == INT16_MAX);
CHECK(test.GetDeviceOutput(0, 0)->module_statistics.pixel_sum == 4 * (4+5+100));
CHECK(test.GetDeviceOutput(0,0)->module_statistics.max_value == 4*100);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_summation_mask", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0).Summation(4)
.AutoSummation(true).ApplyPixelMask(true).BitDepthImage(16).PixelSigned(true);
HLSSimulatedDevice test(0, 64);
std::vector<int16_t> frame(RAW_MODULE_SIZE, 0);
frame [1024+1] = 1;
frame [1024+2] = 3;
frame [1024+3] = 4;
frame [1024+4] = 5;
frame [1024+5] = 100;
frame [1024+6] = -20;
std::vector<uint32_t> pixel_mask(RAW_MODULE_SIZE, 0);
pixel_mask[1024+2] = 1;
std::vector<uint16_t> roi_map(RAW_MODULE_SIZE, 0);
roi_map[1024+1] = 1;
roi_map[1024+2] = 2;
roi_map[1024+5] = 4;
for (int m = 0; m < x.GetModulesNum(); m++) {
test.InitializePixelMask(pixel_mask.data(), m);
test.SetInternalGeneratorFrame((uint16_t *) frame.data(), m);
test.InitializeROIMap(roi_map.data(), m);
}
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 4 * 128 * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
REQUIRE(imageBuf[1024+1] == 4 * 1);
REQUIRE(imageBuf[1024+2] == INT16_MIN);
REQUIRE(imageBuf[1024+3] == 4*4);
REQUIRE(imageBuf[1024+4] == 4*5);
REQUIRE(imageBuf[1024+5] == 4*100);
REQUIRE(imageBuf[1024+6] == -4*20);
CHECK(test.GetDeviceOutput(0, 0)->module_statistics.pixel_sum == 4 * (1+4+5+100-20));
CHECK(test.GetDeviceOutput(0,0)->module_statistics.max_value == 4*100);
CHECK(test.GetDeviceOutput(0, 0)->module_statistics.min_value == -4 * 20);
CHECK(test.GetDeviceOutput(0, 0)->roi_counts[0].good_pixels == 1);
CHECK(test.GetDeviceOutput(0, 0)->roi_counts[1].good_pixels == 0);
CHECK(test.GetDeviceOutput(0, 0)->roi_counts[2].good_pixels == 1);
CHECK(test.GetDeviceOutput(0, 0)->roi_counts[2].sum == 4*100);
CHECK(test.GetDeviceOutput(0, 0)->roi_counts[3].good_pixels == 0);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_32bit", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 1;
const size_t nframes = 2;
DiffractionExperiment x(DetJF(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 - 1);
for (auto &i: test_frame)
i = dist(g1);
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nframes).PedestalG0Frames(0).PixelSigned(false).BitDepthImage(32);
HLSSimulatedDevice test(0, 64);
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(test_frame.data() + m * RAW_MODULE_SIZE, m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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 == 512);
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.packet_mask[2] == UINT64_MAX);
CHECK(test.GetDeviceOutput(image, m)->module_statistics.packet_mask[3] == UINT64_MAX);
CHECK(test.GetDeviceOutput(image, m)->module_statistics.timestamp == INT_PKT_GEN_EXPTTIME * image);
CHECK(test.GetDeviceOutput(image, m)->module_statistics.pulse_id == INT_PKT_GEN_BUNCHID + image);
CHECK(test.GetDeviceOutput(image, m)->module_statistics.exptime == INT_PKT_GEN_EXPTTIME);
auto imageBuf = (uint32_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]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 1;
const size_t nframes = 16;
const size_t nsummation = 16;
DiffractionExperiment x(DetJF(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.UseInternalPacketGenerator(true).ImagesPerTrigger(nframes).PedestalG0Frames(0).Summation(nsummation)
.JungfrauConvPhotonCnt(false).PixelSigned(true).BitDepthImage(32);
HLSSimulatedDevice test(0, 64);
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(test_frame.data() + m * RAW_MODULE_SIZE, m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 128 * nmodules * nframes * nsummation * JUNGFRAU_PACKET_SIZE_BYTES);
auto test_frame_signed = (int16_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.pulse_id == 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++) {
if (test_frame_signed[m * RAW_MODULE_SIZE + i] == INT16_MAX)
CHECK(imageBuf[i] == INT32_MAX);
else if (test_frame_signed[m * RAW_MODULE_SIZE + i] == INT16_MIN)
CHECK(imageBuf[i] == INT32_MIN);
else
REQUIRE(imageBuf[i] == test_frame_signed[m * RAW_MODULE_SIZE + i] * nsummation);
}
}
}
}
TEST_CASE("HLS_C_Simulation_count_sat_and_err_pixels", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 3;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0).PixelSigned(true);
HLSSimulatedDevice test(0, 64);
std::vector<int16_t> v(RAW_MODULE_SIZE, 0);
v[567] = INT16_MAX;
v[RAW_MODULE_COLS * 511 + 255] = INT16_MAX;
v[RAW_MODULE_COLS * 250 + 233] = INT16_MIN;
v[0] = INT16_MIN;
v[RAW_MODULE_SIZE-1] = INT16_MIN;
v[23] = 23;
v[24] = -24;
v[25] = 27;
v[1500] = -25;
v[1501] = 30;
v[1502] = INT16_MIN + 25;
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame((uint16_t *) v.data(), m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
for (int m = 0; m < nmodules; m++) {
CHECK(test.GetDeviceOutput(image, m)->module_statistics.saturated_pixels == 2);
CHECK(test.GetDeviceOutput(image, m)->module_statistics.err_pixels == 3);
CHECK(test.GetDeviceOutput(image, m)->module_statistics.max_value == 30);
CHECK(test.GetDeviceOutput(image, m)->module_statistics.min_value == INT16_MIN + 25);
}
}
}
TEST_CASE("HLS_C_Simulation_pixel_count_mask", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 3;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0).PixelSigned(true);
x.ApplyPixelMask(false);
HLSSimulatedDevice test(0, 64);
std::vector<uint32_t> pixel_mask(RAW_MODULE_SIZE, 0);
pixel_mask[0] = 2;
pixel_mask[1] = 4;
pixel_mask[2] = 1<<30;
test.InitializePixelMask(pixel_mask.data(), 1);
std::vector<int16_t> v(RAW_MODULE_SIZE, 0);
v[0] = INT16_MAX;
v[1] = INT16_MIN;
v[2] = 35;
v[3] = 234;
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame((uint16_t *) v.data(), m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
CHECK(test.GetDeviceOutput(image, 1)->module_statistics.saturated_pixels == 0);
CHECK(test.GetDeviceOutput(image, 1)->module_statistics.err_pixels == 0);
CHECK(test.GetDeviceOutput(image, 1)->module_statistics.max_value == 234);
CHECK(test.GetDeviceOutput(image, 1)->module_statistics.min_value == 0);
CHECK(test.GetDeviceOutput(image, 1)->module_statistics.masked_pixels == 3);
CHECK(test.GetDeviceOutput(image, 1)->module_statistics.pixel_sum == 234);
CHECK(test.GetDeviceOutput(image, 1)->pixels[2] == 35);
CHECK(test.GetDeviceOutput(image, 0)->module_statistics.saturated_pixels == 1);
CHECK(test.GetDeviceOutput(image, 0)->module_statistics.err_pixels == 1);
CHECK(test.GetDeviceOutput(image, 0)->module_statistics.max_value == 234);
CHECK(test.GetDeviceOutput(image, 0)->module_statistics.min_value == 0);
CHECK(test.GetDeviceOutput(image, 0)->module_statistics.masked_pixels == 0);
CHECK(test.GetDeviceOutput(image, 0)->module_statistics.pixel_sum == 35 + 234);
}
}
TEST_CASE("HLS_C_Simulation_count_pixel_sum", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 3;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0).PixelSigned(true);
HLSSimulatedDevice test(0, 64);
std::vector<int16_t> v_0(RAW_MODULE_SIZE, 123);
std::vector<int16_t> v_1(RAW_MODULE_SIZE, 34);
v_1[0] = INT16_MAX;
v_1[1] = INT16_MIN;
v_1[2] = 0;
v_1[RAW_MODULE_SIZE-1] = -1234;
std::vector<int16_t> v_2(RAW_MODULE_SIZE, -23);
test.SetInternalGeneratorFrame((uint16_t *) v_0.data(), 0);
test.SetInternalGeneratorFrame((uint16_t *) v_1.data(), 1);
test.SetInternalGeneratorFrame((uint16_t *) v_2.data(), 2);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
CHECK(test.GetDeviceOutput(image, 0)->module_statistics.pixel_sum == 123 * RAW_MODULE_SIZE);
CHECK(test.GetDeviceOutput(image, 1)->module_statistics.pixel_sum == 34 * (RAW_MODULE_SIZE - 4) - 1234);
CHECK(test.GetDeviceOutput(image, 2)->module_statistics.pixel_sum == -23 * RAW_MODULE_SIZE);
}
}
TEST_CASE("HLS_C_Simulation_check_bunchid", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint64_t bunchid = 0xAAAAAAAA87345600;
const uint16_t nmodules = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(3).NumTriggers(1);
HLSSimulatedDevice test(0, 64);
test.CreateXfelBunchIDPacket(bunchid, 0);
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 0);
REQUIRE(test.GetDataCollectionStatus().current_pulseid == bunchid);
}
TEST_CASE("HLS_C_Simulation_check_raw_eiger", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> raw_frame(RAW_MODULE_SIZE);
std::vector<uint16_t> raw_frame_eiger(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
raw_frame[i] = i % (UINT16_MAX - 11);
RawToEigerInput<4>(raw_frame_eiger.data(), raw_frame.data());
const uint16_t nmodules = 1;
DetectorSetup detector(DetEIGER(nmodules));
DiffractionExperiment x(detector);
x.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(1).NumTriggers(1);
HLSSimulatedDevice test(0, 64);
// bottom half module is reversed
for (int i = 0; i < 64; i++)
test.CreateEIGERPacket(x, 1, i, 0, 0, 0, raw_frame_eiger.data() + 2048 * (2 * i));
for (int i = 0; i < 64; i++)
test.CreateEIGERPacket(x, 1, i, 0, 1, 0, raw_frame_eiger.data() + 2048 * (1 + 2 * i));
for (int i = 0; i < 64; i++)
test.CreateEIGERPacket(x, 1, i, 0, 0, 1, raw_frame_eiger.data() + 2048 * (128 + 2 * i));
for (int i = 0; i < 64; i++)
test.CreateEIGERPacket(x, 1, i, 0, 1, 1, raw_frame_eiger.data() + 2048 * (129 + 2 * i));
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE(test.GetBytesReceived() == 256 * 4096);
uint64_t diffs = 0;
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
if (raw_frame[j] != ((uint16_t *) test.GetDeviceOutput(0, 0)->pixels)[j])
diffs++;
}
REQUIRE(diffs == 0);
}
TEST_CASE("HLS_C_Simulation_check_raw_eiger_8bit", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint8_t> raw_frame(RAW_MODULE_SIZE);
std::vector<uint8_t> raw_frame_eiger(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
raw_frame[i] = i;
const uint16_t nmodules = 1;
DetectorSetup detector(DetEIGER(nmodules));
RawToEigerInput<8>(raw_frame_eiger.data(), raw_frame.data());
DiffractionExperiment x(detector);
x.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(1).NumTriggers(1).EigerBitDepth(8).BitDepthImage(8);
REQUIRE(x.GetByteDepthImage() == 1);
HLSSimulatedDevice test(0, 64);
// bottom half module is reversed
for (int i = 0; i < 32; i++)
test.CreateEIGERPacket(x, 1, i, 0, 0, 0, reinterpret_cast<uint16_t *>(raw_frame_eiger.data() + 4096 * (2 * i)));
for (int i = 0; i < 32; i++)
test.CreateEIGERPacket(x, 1, i, 0, 1, 0, reinterpret_cast<uint16_t *>(raw_frame_eiger.data() + 4096 * (2 * i + 1)));
for (int i = 0; i < 32; i++)
test.CreateEIGERPacket(x, 1, i, 0, 0, 1, reinterpret_cast<uint16_t *>(raw_frame_eiger.data() + 4096 * (2 * i + 64)));
for (int i = 0; i < 32; i++)
test.CreateEIGERPacket(x, 1, i, 0, 1, 1, reinterpret_cast<uint16_t *>(raw_frame_eiger.data() + 4096 * (2 * i + 65)));
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE(test.GetBytesReceived() == 128 * 4096);
auto out = (uint8_t *) test.GetDeviceOutput(0, 0)->pixels;
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[0] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[1] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[2] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[3] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[4] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[5] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[6] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[7] == UINT64_MAX);
uint64_t diffs = 0;
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
if (raw_frame[j] != out[j])
diffs++;
}
REQUIRE(diffs == 0);
}
TEST_CASE("HLS_C_Simulation_check_raw_eiger_32bit", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint32_t> raw_frame(RAW_MODULE_SIZE);
std::vector<uint32_t> raw_frame_eiger(RAW_MODULE_SIZE);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
raw_frame[i] = i;
const uint16_t nmodules = 1;
DetectorSetup detector(DetEIGER(nmodules));
RawToEigerInput<2>(raw_frame_eiger.data(), raw_frame.data());
DiffractionExperiment x(detector);
x.Raw();
x.PedestalG0Frames(0).ImagesPerTrigger(1).NumTriggers(1).EigerBitDepth(32).BitDepthImage(32);
REQUIRE(x.GetByteDepthImage() == 4);
HLSSimulatedDevice test(0, 64);
// bottom half module is reversed
for (int i = 0; i < 128; i++)
test.CreateEIGERPacket(x, 1, i, 0, 0, 0, reinterpret_cast<uint16_t *>(raw_frame_eiger.data() + 1024 * (2 * i)));
for (int i = 0; i < 128; i++)
test.CreateEIGERPacket(x, 1, i, 0, 1, 0, reinterpret_cast<uint16_t *>(raw_frame_eiger.data() + 1024 * (2 * i + 1)));
for (int i = 0; i < 128; i++)
test.CreateEIGERPacket(x, 1, i, 0, 0, 1, reinterpret_cast<uint16_t *>(raw_frame_eiger.data() + 1024 * (2 * i + 256)));
for (int i = 0; i < 128; i++)
test.CreateEIGERPacket(x, 1, i, 0, 1, 1, reinterpret_cast<uint16_t *>(raw_frame_eiger.data() + 1024 * (2 * i + 257)));
test.CreateFinalPacket(x);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.Counters().GetSlowestFrameNumber() == 0);
REQUIRE(test.GetBytesReceived() == 512 * 4096);
auto out = (uint32_t *) test.GetDeviceOutput(0, 0)->pixels;
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[0] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[1] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[2] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[3] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[4] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[5] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[6] == UINT64_MAX);
CHECK(test.GetDeviceOutput(0,0)->module_statistics.packet_mask[7] == UINT64_MAX);
uint64_t diffs = 0;
for (int j = 0; j < RAW_MODULE_SIZE; j++) {
if (raw_frame[j] != out[j])
diffs++;
}
REQUIRE(diffs == 0);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_eiger", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint16_t> raw_frame(RAW_MODULE_SIZE), raw_frame_eiger(RAW_MODULE_SIZE);
std::mt19937 g1(1387);
std::uniform_int_distribution<uint16_t> dist(0, 65535);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
raw_frame[i] = dist(g1);
RawToEigerInput<4>(raw_frame_eiger.data(), raw_frame.data());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetEIGER(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0);
HLSSimulatedDevice test(0, 64);
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(raw_frame_eiger.data(), m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
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] == raw_frame[i]);
}
}
REQUIRE(test.GetExpectedDescriptorsPerModule() == DMA_DESCRIPTORS_PER_MODULE);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_eiger_8bit", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
std::vector<uint8_t> raw_frame(RAW_MODULE_SIZE*2), raw_frame_eiger(RAW_MODULE_SIZE*2);
std::mt19937 g1(1387);
std::uniform_int_distribution<uint16_t> dist(0, 254);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
raw_frame[i] = dist(g1);
RawToEigerInput<8>(raw_frame_eiger.data(), raw_frame.data());
const uint16_t nmodules = 4;
DiffractionExperiment x(DetEIGER(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0);
x.EigerBitDepth(8);
REQUIRE(x.GetBitDepthReadout() == 8);
REQUIRE(x.GetByteDepthImage() == 2);
HLSSimulatedDevice test(0, 64);
for (int m = 0; m < x.GetModulesNum(); m++)
test.SetInternalGeneratorFrame(reinterpret_cast<uint16_t *>(raw_frame_eiger.data()), m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 2 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
for (int m = 0; m < nmodules; m++) {
auto imageBuf = test.GetDeviceOutput(image, m)->pixels;
size_t diff = 0;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
if(imageBuf[i] != raw_frame.data()[i]) diff++;
}
REQUIRE(diff == 0);
}
}
REQUIRE(test.GetExpectedDescriptorsPerModule() == DMA_DESCRIPTORS_PER_MODULE);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_eiger_32bit", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
std::vector<uint32_t> raw_frame(RAW_MODULE_SIZE), raw_frame_eiger(RAW_MODULE_SIZE);
std::mt19937 g1(1387);
std::uniform_int_distribution<uint32_t> dist(0, 4*UINT16_MAX);
for (int i = 0; i < RAW_MODULE_SIZE; i++)
raw_frame[i] = dist(g1);
RawToEigerInput<2>(raw_frame_eiger.data(), raw_frame.data());
DiffractionExperiment x(DetEIGER(nmodules));
x.UseInternalPacketGenerator(true).ImagesPerTrigger(4).PedestalG0Frames(0);
x.EigerBitDepth(32);
HLSSimulatedDevice test(0, 64);
for (int m = 0; m < x.GetModulesNum(); m++) {
test.SetInternalGeneratorFrame(reinterpret_cast<uint16_t *>(raw_frame_eiger.data()),
2 * m);
test.SetInternalGeneratorFrame(reinterpret_cast<uint16_t *>(raw_frame_eiger.data()) + RAW_MODULE_SIZE,
2 * m + 1);
}
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 512 * nmodules * 2 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
for (int m = 0; m < nmodules; m++) {
auto imageBuf = reinterpret_cast<const uint32_t *>(test.GetDeviceOutput(image, m)->pixels);
size_t diff = 0;
for (int i = 0; i < RAW_MODULE_SIZE; i++) {
if(imageBuf[i] != raw_frame.data()[i]) diff++;
}
REQUIRE(diff == 0);
}
}
REQUIRE(test.GetExpectedDescriptorsPerModule() == DMA_DESCRIPTORS_PER_MODULE);
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_roi_calc", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
const size_t nimages = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nimages).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] = 135;
frame[12+RAW_MODULE_COLS*3] = 83;
frame[13+RAW_MODULE_COLS*3] = 95;
frame[12+RAW_MODULE_COLS*4] = 13;
frame[13+RAW_MODULE_COLS*4] = 125;
frame[812+RAW_MODULE_COLS*303] = 83;
frame[813+RAW_MODULE_COLS*303] = 95;
frame[812+RAW_MODULE_COLS*304] = 13;
frame[813+RAW_MODULE_COLS*304] = 125;
std::vector<uint16_t> roi_map(RAW_MODULE_SIZE, 0);
roi_map[12+RAW_MODULE_COLS*3] = 1;
roi_map[13+RAW_MODULE_COLS*3] = 1;
roi_map[12+RAW_MODULE_COLS*4] = 1;
roi_map[13+RAW_MODULE_COLS*4] = 1;
roi_map[812+RAW_MODULE_COLS*303] = (1<<5);
roi_map[813+RAW_MODULE_COLS*303] = (1<<5);
roi_map[812+RAW_MODULE_COLS*304] = (1<<5);
roi_map[813+RAW_MODULE_COLS*304] = (1<<5);
for (int m = 0; m < x.GetModulesNum(); m++) {
test.SetInternalGeneratorFrame(frame.data(), m);
test.InitializeROIMap(roi_map.data(), m);
}
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 128 * nimages * nmodules * JUNGFRAU_PACKET_SIZE_BYTES);
auto imageBuf = test.GetDeviceOutput(0, 0)->pixels;
REQUIRE(memcmp(imageBuf, frame.data(), RAW_MODULE_SIZE * sizeof(uint16_t)) == 0);
for (int i = 0; i < x.GetImageNum(); i++) {
for (int m = 0; m < x.GetModulesNum(); m++) {
CHECK (test.GetDeviceOutput(i, m)->roi_counts[0].sum == 83 + 95 + 13 + 125);
CHECK (test.GetDeviceOutput(i, m)->roi_counts[0].sum2 == 83 * 83 + 95 * 95 + 13 * 13 + 125 * 125);
CHECK (test.GetDeviceOutput(i, m)->roi_counts[0].sum_x_weighted == Catch::Approx(83 * 12 + 95 * 13 + 13 * 12 + 125 * 13));
CHECK (test.GetDeviceOutput(i, m)->roi_counts[0].sum_y_weighted == Catch::Approx(83 * 3 + 95 * 3 + 13 * 4 + 125 * 4));
CHECK (test.GetDeviceOutput(i, m)->roi_counts[0].max_value == 125);
CHECK (test.GetDeviceOutput(i, m)->roi_counts[0].good_pixels == 4);
CHECK (test.GetDeviceOutput(i, m)->roi_counts[5].sum_x_weighted == Catch::Approx(83 * (812+6) + 95 * (813+6) + 13 * (812+6) + 125 * (813+6)));
CHECK (test.GetDeviceOutput(i, m)->roi_counts[5].sum_y_weighted == Catch::Approx(83 * (303+2) + 95 * (303+2) + 13 * (304+2) + 125 * (304+2)));
}
}
}
TEST_CASE("HLS_C_Simulation_internal_packet_generator_4_images", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
const uint16_t nmodules = 4;
const uint16_t nimages = 4;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(nimages).PedestalG0Frames(0).InternalPacketGeneratorImages(nimages);
HLSSimulatedDevice test(0, 64);
std::vector<uint16_t> ref_data(RAW_MODULE_SIZE*nimages*nmodules);
for (int i = 0; i < ref_data.size(); i++)
ref_data[i] = (7 * i + 5) % 65521;
for (int m = 0; m < nmodules*nimages; m++)
test.SetInternalGeneratorFrame(ref_data.data() + RAW_MODULE_SIZE * m, m);
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
REQUIRE(test.GetBytesReceived() == 128 * nmodules * 4 * JUNGFRAU_PACKET_SIZE_BYTES);
for (int image = 0; image < 4; image++) {
for (int m = 0; m < nmodules; m++) {
std::cout << image << " " << m << std::endl;
auto imageBuf = (uint16_t *) test.GetDeviceOutput(image, m)->pixels;
for (int i = 0; i < RAW_MODULE_SIZE; i++)
REQUIRE(imageBuf[i] == ref_data[i + (image * nmodules + m) * RAW_MODULE_SIZE]);
}
}
}
TEST_CASE("HLSSimulatedDevice_InternalGeneratorMemory", "[FPGA]") {
// 64 module frames in the card memory; the generator takes 63 at most
DiffractionExperiment x(DetJF(2));
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).NumTriggers(1);
HLSSimulatedDevice hls_device(0, 64);
x.InternalPacketGeneratorImages(31);
REQUIRE_NOTHROW(hls_device.PrepareAction(x));
x.InternalPacketGeneratorImages(32);
REQUIRE_THROWS(hls_device.PrepareAction(x));
std::vector<uint16_t> frame(RAW_MODULE_SIZE);
REQUIRE_NOTHROW(hls_device.SetInternalGeneratorFrame(frame.data(), 62));
REQUIRE_THROWS(hls_device.SetInternalGeneratorFrame(frame.data(), 63));
}
// The claim behind ImageStatistics::pixel_sum: the preprocessors, reading the frame the card wrote, give the
// card's own sum over the same pixels.
namespace {
template<class T>
void CheckPixelSumParity(int64_t nsummation, CompressedImageMode mode) {
const uint16_t nmodules = 2;
DiffractionExperiment x(DetJF(nmodules));
x.Raw();
x.UseInternalPacketGenerator(true).ImagesPerTrigger(1).PedestalG0Frames(0).Summation(nsummation)
.AutoSummation(true).ApplyPixelMask(true).BitDepthImage(8 * sizeof(T)).PixelSigned(true);
std::mt19937 rng(5);
std::vector<int16_t> frame(RAW_MODULE_SIZE);
for (auto &v: frame)
v = static_cast<int16_t>(static_cast<int>(rng() % 401) - 200);
frame[1024 + 1] = 2000;
frame[1024 + 2] = -1500;
frame[1024 + 3] = INT16_MAX;
frame[1024 + 4] = INT16_MIN;
frame[1024 + 5] = 1234;
std::vector<uint32_t> module_mask(RAW_MODULE_SIZE, 0);
module_mask[1024 + 5] = 1;
module_mask[1024 + 6] = 1;
HLSSimulatedDevice test(0, 64);
std::vector<uint32_t> user_mask;
for (int m = 0; m < x.GetModulesNum(); m++) {
test.InitializePixelMask(module_mask.data(), m);
test.SetInternalGeneratorFrame((uint16_t *) frame.data(), m);
user_mask.insert(user_mask.end(), module_mask.begin(), module_mask.end());
}
REQUIRE_NOTHROW(test.StartAction(x));
REQUIRE_NOTHROW(test.WaitForActionComplete());
std::vector<T> image(nmodules * RAW_MODULE_SIZE);
int64_t card_sum = 0;
for (int m = 0; m < nmodules; m++) {
const auto *output = test.GetDeviceOutput(0, m);
memcpy(image.data() + m * RAW_MODULE_SIZE, output->pixels, RAW_MODULE_SIZE * sizeof(T));
card_sum += output->module_statistics.pixel_sum;
}
CHECK(card_sum != 0);
// The modules one under the other, as a detector without a card delivers its image.
DiffractionExperiment x_image(DetDECTRIS(RAW_MODULE_COLS, nmodules * RAW_MODULE_LINES, "Test", {})
.BitDepthImage(8 * sizeof(T)));
x_image.PixelSigned(true);
PixelMask mask(x_image);
mask.LoadUserMask(x_image, user_mask);
const auto input = reinterpret_cast<const uint8_t *>(image.data());
ImagePreprocessorCPU cpu(x_image, mask);
ImagePreprocessorBuffer cpu_buffer(x_image.GetPixelsNum());
CHECK(cpu.Analyze(cpu_buffer, input, mode).pixel_sum == card_sum);
#ifdef JFJOCH_USE_CUDA
if (get_gpu_count() > 0) {
ImagePreprocessorGPU gpu(x_image, mask, std::make_shared<CudaStream>(), /*copy_image_to_host=*/false);
ImagePreprocessorBufferGPU gpu_buffer(x_image.GetPixelsNum());
CHECK(gpu.Analyze(gpu_buffer, input, mode).pixel_sum == card_sum);
}
#endif
}
}
TEST_CASE("HLS_C_Simulation_pixel_sum_matches_preprocessor", "[FPGA][Full]") {
Logger logger(Catch::getResultCapture().getCurrentTestName());
CheckPixelSumParity<int16_t>(1, CompressedImageMode::Int16);
CheckPixelSumParity<int32_t>(4, CompressedImageMode::Int32);
}