// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-or-later #include "TestImagePusher.h" #include "../tests/FPGAUnitTest.h" #include "JFJochCompressor.h" #include "../compression/JFJochDecompress.h" #include "../frame_serialize/JFJochFrameDeserializer.h" TestImagePusher::TestImagePusher(int64_t image_number) { image_id = image_number; } void TestImagePusher::StartDataCollection(const StartMessage& message) { std::unique_lock ul(m); if (is_running) correct_sequence = false; else is_running = true; } void TestImagePusher::EndDataCollection(const EndMessage& message) { std::unique_lock ul(m); if (!is_running) correct_sequence = false; else is_running = false; } void TestImagePusher::SendImage(const uint8_t *image_data, size_t image_size, int64_t image_number) { std::unique_lock ul(m); frame_counter++; if (image_number == image_id) { JFJochFrameDeserializer deserializer; deserializer.Process(image_data, image_size); auto image_array = deserializer.GetDataMessage(); receiver_generated_image.resize(image_array.image.size); memcpy(receiver_generated_image.data(), image_array.image.data, image_array.image.size); } } void TestImagePusher::SendImage(const uint8_t *image_data, size_t image_size, int64_t image_number, std::binary_semaphore *sempahore) { std::unique_lock ul(m); frame_counter++; if (image_number == image_id) { JFJochFrameDeserializer deserializer; deserializer.Process(image_data, image_size); auto image_array = deserializer.GetDataMessage(); receiver_generated_image.resize(image_array.image.size); memcpy(receiver_generated_image.data(), image_array.image.data, image_array.image.size); } sempahore->release(); } bool TestImagePusher::CheckSequence() const { std::unique_lock ul(m); return correct_sequence; } const std::vector &TestImagePusher::GetImage() const { std::unique_lock ul(m); return receiver_generated_image; } size_t TestImagePusher::GetCounter() const { std::unique_lock ul(m); return frame_counter; } bool TestImagePusher::CheckImage(const DiffractionExperiment &x, const std::vector &raw_reference_image, const JFCalibration &calibration, Logger &logger) { bool no_errors = true; if (receiver_generated_image.empty()) { logger.Error("Image empty"); no_errors = false; } else { std::vector decompressed_image; // Image decompression try { JFJochDecompress(decompressed_image, x.GetCompressionAlgorithmEnum(), receiver_generated_image, x.GetPixelsNum()); } catch (const JFJochException &e) { logger.Error(e.what()); no_errors = false; } if (no_errors) { // Check output if (x.GetDetectorMode() == DetectorMode::Conversion) { size_t storage_cell = 0; if (x.GetStorageCellNumber() > 1) storage_cell = image_id % x.GetStorageCellNumber(); double result = CheckConversionWithGeomTransform(x, calibration, raw_reference_image.data(), decompressed_image.data(), storage_cell); if (x.GetBinning2x2() && (result > 1.5)) { logger.Error("Mean conversion error ({}) larger than threshold", result); no_errors = false; } else if (!x.GetBinning2x2() && (result > 0.5)) { logger.Error("Mean conversion error ({}) larger than threshold", result); no_errors = false; } else logger.Info("Mean conversion error: {}", result); } else if (x.GetDetectorMode() == DetectorMode::Raw) { if (memcmp(raw_reference_image.data(), decompressed_image.data(), sizeof(uint16_t) * x.GetPixelsNum()) != 0) { logger.Error("Raw data mismatch"); no_errors = false; } } } } return no_errors; }