906 lines
36 KiB
C++
906 lines
36 KiB
C++
// Copyright (2019-2023) Paul Scherrer Institute
|
|
|
|
#include <catch2/catch.hpp>
|
|
|
|
#include "../frame_serialize/CBORStream2Serializer.h"
|
|
#include "../frame_serialize/CBORStream2Deserializer.h"
|
|
#include "../compression/JFJochCompressor.h"
|
|
#include "stream2.h"
|
|
#include "../frame_serialize/CborUtil.h"
|
|
|
|
TEST_CASE("CBORSerialize_Start", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
StartMessage message {
|
|
.data_file_count = 3,
|
|
.detector_distance = 0.0005,
|
|
.beam_center_x = 456.6,
|
|
.beam_center_y = 124.3,
|
|
.number_of_images = 34567,
|
|
.image_size_x = 456,
|
|
.image_size_y = 457,
|
|
.pixel_bit_depth = 32,
|
|
.pixel_signed = true,
|
|
.countrate_correction_enabled = true,
|
|
.incident_energy = 12400,
|
|
.incident_wavelength = 0.988,
|
|
.frame_time = 0.0001,
|
|
.count_time = 0.000098,
|
|
.saturation_value = 65534,
|
|
.error_value = 65535,
|
|
.pixel_size_x = 0.000075,
|
|
.pixel_size_y = 0.000075,
|
|
.sensor_thickness = 0.0005,
|
|
.sensor_material = "Si",
|
|
.unit_cell = UnitCell{.a = 45,.b = 37, .c = 45, .alpha = 90, .beta = 108,. gamma = 120},
|
|
.space_group_number = 154,
|
|
.max_spot_count = 250,
|
|
.storage_cell_number = 16,
|
|
.storage_cell_delay_ns = 15345,
|
|
.pixel_mask_enabled = true,
|
|
.arm_date = "abc",
|
|
.sample_name = "lyso",
|
|
.file_prefix = "lyso1/dir/file",
|
|
.channels = {"default", "sc2"},
|
|
.detector_description = "EIGER 16M",
|
|
.detector_serial_number = "123",
|
|
.series_unique_id = "bla",
|
|
.series_id = 4567,
|
|
.gain_file_names = {"abc" , "def", "/dsadasdsa/dadsadas/dsadsa/M056.bin"},
|
|
.omega = {
|
|
.increment = 0.1f,
|
|
.start = 10.0f,
|
|
.axis = {0,-1.0, 0.0}
|
|
},
|
|
.detector_translation = {0.5f, 0.0f, 0.5f},
|
|
.source_name = "Swiss Light Source",
|
|
.source_name_short = "SLS",
|
|
.instrument_name = "X06SA",
|
|
.instrument_name_short = "PXIII",
|
|
.az_int_bin_number = 35,
|
|
.summation = 567,
|
|
.az_int_bin_to_q = {0.1, 0.2, 0.3, 0.5},
|
|
.total_flux = 123,
|
|
.attenuator_transmission = 0.345,
|
|
.roi_summation_area = ROIRectangle{12,15,17,29},
|
|
.user_data = "Some random string 12345"
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeSequenceStart(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::START);
|
|
|
|
StartMessage output_message;
|
|
REQUIRE_NOTHROW(output_message = deserializer.GetStartMessage());
|
|
CHECK(output_message.data_file_count == message.data_file_count);
|
|
CHECK(output_message.detector_distance == Approx(message.detector_distance));
|
|
CHECK(output_message.beam_center_x == Approx(message.beam_center_x));
|
|
CHECK(output_message.beam_center_y == Approx(message.beam_center_y));
|
|
CHECK(output_message.number_of_images == message.number_of_images);
|
|
CHECK(output_message.image_size_x == message.image_size_x);
|
|
CHECK(output_message.image_size_y == message.image_size_y);
|
|
CHECK(output_message.pixel_bit_depth == message.pixel_bit_depth);
|
|
CHECK(output_message.incident_energy == Approx(message.incident_energy));
|
|
CHECK(output_message.incident_wavelength == Approx(message.incident_wavelength));
|
|
CHECK(output_message.frame_time == Approx(message.frame_time));
|
|
CHECK(output_message.count_time == Approx(message.count_time));
|
|
CHECK(output_message.saturation_value == message.saturation_value);
|
|
CHECK(output_message.error_value == message.error_value);
|
|
CHECK(output_message.pixel_size_x == Approx(message.pixel_size_x));
|
|
CHECK(output_message.pixel_size_y == Approx(message.pixel_size_y));
|
|
CHECK(output_message.sensor_thickness == Approx(message.sensor_thickness));
|
|
CHECK(output_message.sensor_material == message.sensor_material);
|
|
CHECK(output_message.pixel_mask_enabled == message.pixel_mask_enabled);
|
|
CHECK(output_message.space_group_number == message.space_group_number);
|
|
CHECK(output_message.arm_date == message.arm_date);
|
|
CHECK(output_message.storage_cell_number == message.storage_cell_number);
|
|
CHECK(output_message.storage_cell_delay_ns == message.storage_cell_delay_ns);
|
|
CHECK(output_message.pixel_signed == message.pixel_signed);
|
|
CHECK(output_message.sample_name == message.sample_name);
|
|
CHECK(output_message.file_prefix == message.file_prefix);
|
|
CHECK(output_message.max_spot_count == message.max_spot_count);
|
|
CHECK(output_message.channels == message.channels);
|
|
CHECK(output_message.detector_description == message.detector_description);
|
|
CHECK(output_message.detector_serial_number == message.detector_serial_number);
|
|
CHECK(output_message.series_unique_id == message.series_unique_id);
|
|
CHECK(output_message.series_id == message.series_id);
|
|
CHECK(output_message.source_name == message.source_name);
|
|
CHECK(output_message.source_name_short == message.source_name_short);
|
|
CHECK(output_message.instrument_name == message.instrument_name);
|
|
CHECK(output_message.instrument_name_short == message.instrument_name_short);
|
|
CHECK(output_message.az_int_bin_number == message.az_int_bin_number);
|
|
CHECK(output_message.summation == message.summation);
|
|
CHECK(output_message.az_int_bin_to_q == message.az_int_bin_to_q);
|
|
|
|
for (int i = 0; i < 3; i++)
|
|
CHECK(output_message.detector_translation[i] == message.detector_translation[i]);
|
|
|
|
CHECK(output_message.unit_cell);
|
|
CHECK(output_message.unit_cell->a == message.unit_cell->a);
|
|
CHECK(output_message.unit_cell->b == message.unit_cell->b);
|
|
CHECK(output_message.unit_cell->c == message.unit_cell->c);
|
|
CHECK(output_message.unit_cell->alpha == message.unit_cell->alpha);
|
|
CHECK(output_message.unit_cell->beta == message.unit_cell->beta);
|
|
CHECK(output_message.unit_cell->gamma == message.unit_cell->gamma);
|
|
|
|
CHECK(output_message.omega.increment == message.omega.increment);
|
|
CHECK(output_message.omega.start == message.omega.start);
|
|
for (int i = 0; i < 3; i++)
|
|
CHECK(output_message.omega.axis[i] == message.omega.axis[i]);
|
|
|
|
REQUIRE (output_message.total_flux);
|
|
CHECK(output_message.total_flux.value() == message.total_flux.value());
|
|
REQUIRE (output_message.attenuator_transmission);
|
|
CHECK(output_message.attenuator_transmission.value() == message.attenuator_transmission.value());
|
|
CHECK(output_message.user_data == message.user_data);
|
|
REQUIRE(output_message.roi_summation_area);
|
|
CHECK(output_message.roi_summation_area->x_min == message.roi_summation_area->x_min);
|
|
CHECK(output_message.roi_summation_area->x_max == message.roi_summation_area->x_max);
|
|
CHECK(output_message.roi_summation_area->y_min == message.roi_summation_area->y_min);
|
|
CHECK(output_message.roi_summation_area->y_max == message.roi_summation_area->y_max);
|
|
CHECK(output_message.gain_file_names == message.gain_file_names);
|
|
CHECK(output_message.countrate_correction_enabled == message.countrate_correction_enabled);
|
|
CHECK(output_message.flatfield_enabled == message.flatfield_enabled);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Start_PixelMask", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<uint32_t> mask(456*457, 15);
|
|
|
|
CompressedImage image_mask {
|
|
.data = reinterpret_cast<uint8_t *>(mask.data()),
|
|
.size = 456 * 457 * sizeof(uint32_t),
|
|
.xpixel = 456,
|
|
.ypixel = 457,
|
|
.pixel_depth_bytes = 4,
|
|
.pixel_is_signed = false,
|
|
.pixel_is_float = false,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "sc0"
|
|
};
|
|
|
|
StartMessage message {};
|
|
|
|
message.AddPixelMask(image_mask);
|
|
REQUIRE_NOTHROW(serializer.SerializeSequenceStart(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::START);
|
|
|
|
StartMessage output_message;
|
|
REQUIRE_NOTHROW(output_message = deserializer.GetStartMessage());
|
|
REQUIRE(output_message.pixel_mask.size() == 1);
|
|
CHECK(!output_message.pixel_mask[0].pixel_is_float);
|
|
CHECK(output_message.pixel_mask[0].xpixel == 456);
|
|
CHECK(output_message.pixel_mask[0].ypixel == 457);
|
|
CHECK(output_message.pixel_mask[0].channel == "sc0");
|
|
CHECK(output_message.pixel_mask[0].algorithm == CompressionAlgorithm::NO_COMPRESSION);
|
|
CHECK(memcmp(output_message.pixel_mask[0].data, mask.data(), mask.size() * sizeof(float)) == 0);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Start_Calibration", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<float> calib1(256);
|
|
std::vector<float> calib2(256);
|
|
|
|
for (int i = 0; i < 256; i++) {
|
|
calib1[i] = i * 34.567;
|
|
calib2[i] = i * 76.33456;
|
|
}
|
|
|
|
CompressedImage image1 {
|
|
.data = reinterpret_cast<uint8_t *>(calib1.data()),
|
|
.size = 16 * 16 * sizeof(float),
|
|
.xpixel = 16,
|
|
.ypixel = 16,
|
|
.pixel_depth_bytes = 4,
|
|
.pixel_is_signed = true,
|
|
.pixel_is_float = true,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "calib1"
|
|
};
|
|
|
|
CompressedImage image2 {
|
|
.data = reinterpret_cast<uint8_t *>(calib2.data()),
|
|
.size = 16 * 16 * sizeof(float),
|
|
.xpixel = 16,
|
|
.ypixel = 16,
|
|
.pixel_depth_bytes = 4,
|
|
.pixel_is_signed = true,
|
|
.pixel_is_float = true,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "calib2"
|
|
};
|
|
|
|
StartMessage message {};
|
|
|
|
message.AddCalibration(image2);
|
|
message.AddCalibration(image1);
|
|
REQUIRE_NOTHROW(serializer.SerializeSequenceStart(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::START);
|
|
|
|
StartMessage output_message;
|
|
REQUIRE_NOTHROW(output_message = deserializer.GetStartMessage());
|
|
REQUIRE(output_message.calibration.size() == 2);
|
|
CHECK(output_message.calibration[0].pixel_is_float);
|
|
CHECK(output_message.calibration[1].pixel_is_float);
|
|
CHECK(output_message.calibration[0].xpixel == 16);
|
|
CHECK(output_message.calibration[0].ypixel == 16);
|
|
CHECK(output_message.calibration[1].xpixel == 16);
|
|
CHECK(output_message.calibration[1].ypixel == 16);
|
|
CHECK(output_message.calibration[0].channel == "calib2");
|
|
CHECK(output_message.calibration[1].channel == "calib1");
|
|
CHECK(memcmp(output_message.calibration[0].data, calib2.data(), 256 * sizeof(float)) == 0);
|
|
CHECK(memcmp(output_message.calibration[1].data, calib1.data(), 256 * sizeof(float)) == 0);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_End", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
EndMessage message {
|
|
.max_image_number = 57789,
|
|
.images_collected_count = 50000,
|
|
.images_sent_to_write_count = 40000,
|
|
.max_receiver_delay = 3456,
|
|
.efficiency = 0.99,
|
|
.write_master_file = true,
|
|
.end_date = "ccc",
|
|
.series_unique_id = "bla5",
|
|
.series_id = 45676782
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeSequenceEnd(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::END);
|
|
|
|
EndMessage output_message{};
|
|
REQUIRE_NOTHROW(output_message = deserializer.GetEndMessage());
|
|
REQUIRE(output_message.max_receiver_delay == message.max_receiver_delay);
|
|
REQUIRE(output_message.max_image_number == message.max_image_number);
|
|
REQUIRE(output_message.images_collected_count == message.images_collected_count);
|
|
REQUIRE(output_message.images_sent_to_write_count == message.images_sent_to_write_count);
|
|
REQUIRE(output_message.efficiency);
|
|
REQUIRE(output_message.efficiency == Approx(message.efficiency.value()));
|
|
REQUIRE(output_message.end_date == message.end_date);
|
|
REQUIRE(output_message.write_master_file.value() == message.write_master_file.value());
|
|
REQUIRE(output_message.series_id == message.series_id);
|
|
REQUIRE(output_message.series_unique_id == message.series_unique_id);
|
|
REQUIRE(output_message.az_int_result.empty());
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_End_RadIntResult", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
EndMessage message {
|
|
.max_image_number = 57789,
|
|
.max_receiver_delay = 3456,
|
|
.efficiency = 0.99,
|
|
.write_master_file = true,
|
|
.end_date = "ccc",
|
|
.series_unique_id = "bla5",
|
|
.series_id = 45676782
|
|
};
|
|
|
|
message.az_int_result["avg"] = {11.0, 12.0, 13.0};
|
|
message.az_int_result["file0"] = {56.0, 75.0, 34.0};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeSequenceEnd(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::END);
|
|
|
|
EndMessage output_message{};
|
|
REQUIRE_NOTHROW(output_message = deserializer.GetEndMessage());
|
|
REQUIRE(output_message.az_int_result.size() == 2);
|
|
REQUIRE(output_message.az_int_result.contains("avg"));
|
|
REQUIRE(output_message.az_int_result.contains("file0"));
|
|
CHECK(message.az_int_result["avg"] == output_message.az_int_result["avg"]);
|
|
CHECK(message.az_int_result["file0"] == output_message.az_int_result["file0"]);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_End_ADUHistogram", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
EndMessage message {
|
|
.max_image_number = 57789,
|
|
.max_receiver_delay = 3456,
|
|
.efficiency = 0.99,
|
|
.write_master_file = true,
|
|
.end_date = "ccc",
|
|
.series_unique_id = "bla5",
|
|
.series_id = 45676782,
|
|
.adu_histogram_bin_width = 55
|
|
};
|
|
|
|
message.adu_histogram["avg"] = {11, 12, 13};
|
|
message.adu_histogram["file0"] = {56, 75, 34};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeSequenceEnd(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::END);
|
|
|
|
EndMessage output_message{};
|
|
REQUIRE_NOTHROW(output_message = deserializer.GetEndMessage());
|
|
REQUIRE(output_message.adu_histogram.size() == 2);
|
|
REQUIRE(output_message.adu_histogram.contains("avg"));
|
|
REQUIRE(output_message.adu_histogram.contains("file0"));
|
|
CHECK(message.adu_histogram["avg"] == output_message.adu_histogram["avg"]);
|
|
CHECK(message.adu_histogram["file0"] == output_message.adu_histogram["file0"]);
|
|
CHECK(message.adu_histogram_bin_width == output_message.adu_histogram_bin_width);
|
|
}
|
|
|
|
|
|
TEST_CASE("CBORSerialize_Image", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<SpotToSave> spots;
|
|
|
|
std::vector<uint8_t> test(1024);
|
|
for (int i = 0; i < test.size(); i++)
|
|
test[i] = (i * 253 + 56) % 256;
|
|
|
|
CompressedImage image {
|
|
.data = test.data(),
|
|
.size = 1024,
|
|
.xpixel = 256,
|
|
.ypixel = 2,
|
|
.pixel_depth_bytes = 2,
|
|
.pixel_is_signed = true,
|
|
.pixel_is_float = false,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "default"
|
|
};
|
|
|
|
DataMessage message {
|
|
.number = 456,
|
|
.image = image,
|
|
.image_collection_efficiency = 0.11,
|
|
.spots = spots,
|
|
.bkg_estimate = 12.345f,
|
|
.indexing_result = 1,
|
|
.adu_histogram = {3, 4, 5, 8},
|
|
.timestamp = 1ul<<27 | 1ul <<35,
|
|
.exptime = 1000,
|
|
.series_unique_id = "bla2",
|
|
.series_id = 4567678,
|
|
.saturated_pixel_count = 378,
|
|
.error_pixel_count = 123,
|
|
.strong_pixel_count = 1234,
|
|
.user_data = "Some random string ABCDEF",
|
|
.jf_info = UINT32_MAX,
|
|
.receiver_aq_dev_delay = 2323,
|
|
.storage_cell = 0xF,
|
|
.roi_sum = 456,
|
|
.xfel_pulse_id = UINT64_MAX - 5678,
|
|
.xfel_event_code = UINT64_MAX - 123,
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeImage(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::IMAGE);
|
|
|
|
auto image_array = deserializer.GetDataMessage();
|
|
REQUIRE(image_array.image.algorithm == CompressionAlgorithm::NO_COMPRESSION);
|
|
REQUIRE(image_array.image.xpixel == 256);
|
|
REQUIRE(image_array.image.ypixel == 2);
|
|
REQUIRE(image_array.image.pixel_depth_bytes == 2);
|
|
REQUIRE(image_array.image.pixel_is_signed);
|
|
REQUIRE(!image_array.image.pixel_is_float);
|
|
REQUIRE(image_array.image.channel == "default");
|
|
REQUIRE(image_array.image.size == test.size());
|
|
REQUIRE(image_array.indexing_result == message.indexing_result);
|
|
REQUIRE(image_array.number == 456);
|
|
REQUIRE(image_array.series_id == message.series_id);
|
|
REQUIRE(image_array.series_unique_id == message.series_unique_id);
|
|
REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0);
|
|
|
|
REQUIRE(image_array.xfel_pulse_id == message.xfel_pulse_id);
|
|
REQUIRE(image_array.xfel_event_code == message.xfel_event_code);
|
|
REQUIRE(image_array.jf_info == message.jf_info);
|
|
REQUIRE(image_array.timestamp == message.timestamp);
|
|
REQUIRE(image_array.storage_cell == message.storage_cell);
|
|
REQUIRE(image_array.exptime == message.exptime);
|
|
REQUIRE(image_array.receiver_aq_dev_delay == image_array.receiver_aq_dev_delay);
|
|
REQUIRE(image_array.adu_histogram == message.adu_histogram);
|
|
REQUIRE(image_array.saturated_pixel_count == message.saturated_pixel_count);
|
|
REQUIRE(image_array.error_pixel_count == message.error_pixel_count);
|
|
REQUIRE(image_array.strong_pixel_count == message.strong_pixel_count);
|
|
REQUIRE(image_array.bkg_estimate == message.bkg_estimate);
|
|
REQUIRE(image_array.image_collection_efficiency == message.image_collection_efficiency);
|
|
REQUIRE(image_array.user_data == message.user_data);
|
|
REQUIRE(image_array.roi_sum == message.roi_sum);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Image_2", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<SpotToSave> spots;
|
|
|
|
std::vector<uint8_t> test(512*1024);
|
|
for (int i = 0; i < test.size(); i++)
|
|
test[i] = (i * 253 + 56) % 256;
|
|
|
|
CompressedImage image {
|
|
.data = test.data(),
|
|
.size = 1024 * 512,
|
|
.xpixel = 1024,
|
|
.ypixel = 512,
|
|
.pixel_depth_bytes = 1,
|
|
.pixel_is_signed = false,
|
|
.pixel_is_float = false,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "default"
|
|
};
|
|
|
|
DataMessage message {
|
|
.number = 480,
|
|
.image = image,
|
|
.spots = spots,
|
|
.indexing_result = 3
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeImage(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::IMAGE);
|
|
|
|
auto image_array = deserializer.GetDataMessage();
|
|
REQUIRE(image_array.image.algorithm == CompressionAlgorithm::NO_COMPRESSION);
|
|
REQUIRE(image_array.image.xpixel == 1024);
|
|
REQUIRE(image_array.image.ypixel == 512);
|
|
REQUIRE(image_array.image.pixel_depth_bytes == 1);
|
|
REQUIRE(!image_array.image.pixel_is_signed);
|
|
REQUIRE(!image_array.image.pixel_is_float);
|
|
REQUIRE(image_array.image.channel == "default");
|
|
REQUIRE(image_array.image.size == test.size());
|
|
REQUIRE(image_array.indexing_result == message.indexing_result);
|
|
REQUIRE(image_array.number == 480);
|
|
REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Image_Float", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<SpotToSave> spots;
|
|
|
|
std::vector<float> test(512*1024);
|
|
for (int i = 0; i < test.size(); i++)
|
|
test[i] = i * 0.1f;
|
|
|
|
CompressedImage image {
|
|
.data = reinterpret_cast<uint8_t *>(test.data()),
|
|
.size = 1024 * 512 * sizeof(float),
|
|
.xpixel = 1024,
|
|
.ypixel = 512,
|
|
.pixel_depth_bytes = 4,
|
|
.pixel_is_signed = true,
|
|
.pixel_is_float = true,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "default"
|
|
};
|
|
|
|
DataMessage message {
|
|
.number = 480,
|
|
.image = image,
|
|
.spots = spots,
|
|
.indexing_result = 3
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeImage(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::IMAGE);
|
|
|
|
auto image_array = deserializer.GetDataMessage();
|
|
REQUIRE(image_array.image.algorithm == CompressionAlgorithm::NO_COMPRESSION);
|
|
REQUIRE(image_array.image.xpixel == 1024);
|
|
REQUIRE(image_array.image.ypixel == 512);
|
|
REQUIRE(image_array.image.pixel_is_float);
|
|
REQUIRE(image_array.image.pixel_depth_bytes == 4);
|
|
REQUIRE(image_array.image.pixel_is_signed);
|
|
REQUIRE(image_array.image.channel == "default");
|
|
REQUIRE(image_array.image.size == test.size() * sizeof(float));
|
|
REQUIRE(image_array.indexing_result == message.indexing_result);
|
|
REQUIRE(image_array.number == 480);
|
|
REQUIRE(memcmp(image_array.image.data, test.data(), test.size() * sizeof(float)) == 0);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Image_Compressed", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<SpotToSave> spots;
|
|
|
|
std::vector<uint8_t> test(512);
|
|
for (int i = 0; i < test.size(); i++)
|
|
test[i] = (i * 253 + 56) % 256;
|
|
|
|
CompressedImage image {
|
|
.data = test.data(),
|
|
.size = 512,
|
|
.xpixel = 256,
|
|
.ypixel = 2,
|
|
.pixel_depth_bytes = 4,
|
|
.pixel_is_signed = true,
|
|
.pixel_is_float = false,
|
|
.algorithm = CompressionAlgorithm::BSHUF_LZ4,
|
|
.channel = "default"
|
|
};
|
|
|
|
DataMessage message {
|
|
.number = 456,
|
|
.image = image,
|
|
.spots = spots
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeImage(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::IMAGE);
|
|
|
|
auto image_array = deserializer.GetDataMessage();
|
|
REQUIRE(image_array.image.algorithm == CompressionAlgorithm::BSHUF_LZ4);
|
|
REQUIRE(image_array.image.xpixel == 256);
|
|
REQUIRE(image_array.image.ypixel == 2);
|
|
REQUIRE(image_array.image.pixel_depth_bytes == 4);
|
|
REQUIRE(!image_array.image.pixel_is_float);
|
|
REQUIRE(image_array.image.channel == "default");
|
|
REQUIRE(image_array.image.size == test.size());
|
|
REQUIRE(image_array.image.pixel_is_signed == true);
|
|
REQUIRE(image_array.number == 456);
|
|
REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Image_Rad_Int_Profile", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8 * 1024 * 1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<uint8_t> test(1024);
|
|
for (int i = 0; i < test.size(); i++)
|
|
test[i] = (i * 253 + 56) % 256;
|
|
|
|
CompressedImage image{
|
|
.data = test.data(),
|
|
.size = 1024,
|
|
.xpixel = 256,
|
|
.ypixel = 2,
|
|
.pixel_depth_bytes = 2,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "default"
|
|
};
|
|
|
|
DataMessage message{
|
|
.number = 789,
|
|
.image = image,
|
|
.az_int_profile = {4.0, 5.0, 7.0, 12.0, 13.25, 0.125}
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeImage(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::IMAGE);
|
|
|
|
auto image_array = deserializer.GetDataMessage();
|
|
REQUIRE(image_array.number == 789);
|
|
|
|
REQUIRE(image_array.image.size == test.size());
|
|
REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0);
|
|
REQUIRE(image_array.az_int_profile == message.az_int_profile);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Image_Spots", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<SpotToSave> spots;
|
|
spots.push_back(SpotToSave{.x = 7, .y = 8, .intensity = 34, .indexed = false});
|
|
spots.push_back(SpotToSave{.x = 37, .y = 48, .intensity = 123, .indexed = true});
|
|
|
|
std::vector<uint8_t> test(1024);
|
|
for (int i = 0; i < test.size(); i++)
|
|
test[i] = (i * 253 + 56) % 256;
|
|
|
|
CompressedImage image {
|
|
.data = test.data(),
|
|
.size = 1024,
|
|
.xpixel = 256,
|
|
.ypixel = 2,
|
|
.pixel_depth_bytes = 2,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "default"
|
|
};
|
|
|
|
DataMessage message {
|
|
.number = 789,
|
|
.image = image,
|
|
.spots = spots
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeImage(message));
|
|
|
|
CBORStream2Deserializer deserializer;
|
|
REQUIRE_NOTHROW(deserializer.Process(buffer.data(), serializer.GetBufferSize()));
|
|
REQUIRE(deserializer.GetType() == CBORStream2Deserializer::Type::IMAGE);
|
|
|
|
auto image_array = deserializer.GetDataMessage();
|
|
REQUIRE(image_array.number == 789);
|
|
|
|
REQUIRE(image_array.image.size == test.size());
|
|
REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0);
|
|
REQUIRE(image_array.spots.size() == 2);
|
|
|
|
REQUIRE(image_array.spots[0].intensity == 34);
|
|
REQUIRE(!image_array.spots[0].indexed);
|
|
|
|
REQUIRE(image_array.spots[1].x == 37);
|
|
REQUIRE(image_array.spots[1].y == 48);
|
|
REQUIRE(image_array.spots[1].intensity == 123);
|
|
|
|
REQUIRE(image_array.spots[1].indexed);
|
|
}
|
|
|
|
inline bool CmpString(const char *str1, const std::string& str2) {
|
|
return (strncmp(str1, str2.c_str(), str2.size()) == 0);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Start_stream2", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<uint32_t> mask(456*457, 15);
|
|
|
|
CompressedImage image_mask {
|
|
.data = reinterpret_cast<uint8_t *>(mask.data()),
|
|
.size = 456 * 457 * sizeof(uint32_t),
|
|
.xpixel = 456,
|
|
.ypixel = 457,
|
|
.pixel_depth_bytes = 4,
|
|
.pixel_is_signed = false,
|
|
.pixel_is_float = false,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "sc0"
|
|
};
|
|
|
|
StartMessage message {
|
|
.data_file_count = 3,
|
|
.detector_distance = 0.0005,
|
|
.beam_center_x = 456.6,
|
|
.beam_center_y = 124.3,
|
|
.number_of_images = 34567,
|
|
.image_size_x = 456,
|
|
.image_size_y = 457,
|
|
.pixel_bit_depth = 32,
|
|
.pixel_signed = true,
|
|
.incident_energy = 12400,
|
|
.incident_wavelength = 0.988,
|
|
.frame_time = 0.0001,
|
|
.count_time = 0.000098,
|
|
.saturation_value = 65535,
|
|
.pixel_size_x = 0.000075,
|
|
.pixel_size_y = 0.000075,
|
|
.sensor_thickness = 0.0005,
|
|
.sensor_material = "Si",
|
|
.unit_cell = UnitCell{.a = 45,.b = 37, .c = 45, .alpha = 90, .beta = 108,. gamma = 120},
|
|
.space_group_number = 154,
|
|
.max_spot_count = 250,
|
|
.storage_cell_number = 16,
|
|
.pixel_mask_enabled = true,
|
|
.arm_date = "abc",
|
|
.sample_name = "lyso",
|
|
.file_prefix = "lyso1/dir/file",
|
|
.channels = {"default", "sc2"},
|
|
.detector_description = "EIGER 16M",
|
|
.detector_serial_number = "123",
|
|
.series_unique_id = "bla",
|
|
.series_id = 4567,
|
|
.omega = {
|
|
.increment = 0.1f,
|
|
.start = 10.0f
|
|
},
|
|
.detector_translation = {0.5f, 0.0f, 0.5f},
|
|
.source_name = "Swiss Light Source",
|
|
.source_name_short = "SLS",
|
|
.instrument_name = "X06SA",
|
|
.instrument_name_short = "PXIII",
|
|
.az_int_bin_number = 35,
|
|
.summation = 567
|
|
};
|
|
|
|
message.AddPixelMask(image_mask);
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeSequenceStart(message));
|
|
|
|
stream2_msg *msg;
|
|
|
|
auto ret = stream2_parse_msg(buffer.data(), serializer.GetBufferSize(), &msg);
|
|
REQUIRE(ret == STREAM2_OK);
|
|
CHECK(msg->type == STREAM2_MSG_START);
|
|
auto msg2 = (stream2_start_msg *) msg;
|
|
|
|
CHECK(msg2->beam_center_x == message.beam_center_x);
|
|
CHECK(msg2->beam_center_y == message.beam_center_y);
|
|
CHECK(msg2->image_size_x == message.image_size_x);
|
|
CHECK(msg2->image_size_y == message.image_size_y);
|
|
CHECK(msg2->series_id == message.series_id);
|
|
CHECK(CmpString(msg2->series_unique_id, message.series_unique_id));
|
|
CHECK(CmpString(msg2->detector_description, message.detector_description));
|
|
CHECK(CmpString(msg2->arm_date, message.arm_date));
|
|
CHECK(msg2->number_of_images == message.number_of_images);
|
|
CHECK(msg2->frame_time == message.frame_time);
|
|
CHECK(msg2->count_time == message.count_time);
|
|
|
|
CHECK(msg2->pixel_mask_enabled == message.pixel_mask_enabled);
|
|
CHECK(msg2->pixel_mask.len == 1);
|
|
CHECK(CmpString(msg2->pixel_mask.ptr[0].channel, "sc0"));
|
|
CHECK(msg2->pixel_mask.ptr[0].pixel_mask.dim[0] == 457);
|
|
CHECK(msg2->pixel_mask.ptr[0].pixel_mask.dim[1] == 456);
|
|
CHECK(msg2->pixel_mask.ptr[0].pixel_mask.array.data.len == 456 * 457 * sizeof(uint32_t));
|
|
CHECK(memcmp(msg2->pixel_mask.ptr[0].pixel_mask.array.data.ptr, mask.data(), 456 * 457 * sizeof(uint32_t)) == 0);
|
|
CHECK(msg2->pixel_mask.ptr[0].pixel_mask.array.tag == TagUnsignedInt32BitLE);
|
|
stream2_free_msg(msg);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_End_stream2", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
EndMessage message {
|
|
.max_image_number = 57789,
|
|
.max_receiver_delay = 3456,
|
|
.efficiency = 0.99,
|
|
.write_master_file = true,
|
|
.end_date = "ccc",
|
|
.series_unique_id = "bla5",
|
|
.series_id = 45676782
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeSequenceEnd(message));
|
|
|
|
stream2_msg *msg;
|
|
|
|
auto ret = stream2_parse_msg(buffer.data(), serializer.GetBufferSize(), &msg);
|
|
REQUIRE(ret == STREAM2_OK);
|
|
CHECK(msg->type == STREAM2_MSG_END);
|
|
auto msg2 = (stream2_end_msg *) msg;
|
|
|
|
CHECK(msg2->series_id == message.series_id);
|
|
CHECK(CmpString(msg2->series_unique_id, message.series_unique_id));
|
|
|
|
stream2_free_msg(msg);
|
|
}
|
|
|
|
|
|
TEST_CASE("CBORSerialize_Image_compressed_stream2", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<SpotToSave> spots;
|
|
|
|
std::vector<uint16_t> test(512*1024);
|
|
for (int i = 0; i < test.size(); i++)
|
|
test[i] = (i * 253 + 56) % 256;
|
|
std::vector<uint8_t> compressed_test(512*1024*4);
|
|
|
|
JFJochBitShuffleCompressor compressor(CompressionAlgorithm::BSHUF_LZ4);
|
|
|
|
size_t compressed_size = compressor.Compress(compressed_test.data(), test);
|
|
|
|
CompressedImage image {
|
|
.data = compressed_test.data(),
|
|
.size = compressed_size,
|
|
.xpixel = 1024,
|
|
.ypixel = 512,
|
|
.pixel_depth_bytes = 2,
|
|
.pixel_is_signed = false,
|
|
.pixel_is_float = false,
|
|
.algorithm = CompressionAlgorithm::BSHUF_LZ4,
|
|
.channel = "default"
|
|
};
|
|
|
|
DataMessage message {
|
|
.number = 456,
|
|
.image = image,
|
|
.spots = spots
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeImage(message));
|
|
|
|
stream2_msg *msg;
|
|
|
|
auto ret = stream2_parse_msg(buffer.data(), serializer.GetBufferSize(), &msg);
|
|
REQUIRE(ret == STREAM2_OK);
|
|
CHECK(msg->type == STREAM2_MSG_IMAGE);
|
|
auto msg2 = (stream2_image_msg *) msg;
|
|
CHECK(msg2->image_id == message.number);
|
|
CHECK(msg2->data.len == 1);
|
|
CHECK(CmpString(msg2->data.ptr[0].channel, "default"));
|
|
CHECK(msg2->data.ptr[0].data.dim[0] == 512);
|
|
CHECK(msg2->data.ptr[0].data.dim[1] == 1024);
|
|
CHECK(CmpString(msg2->data.ptr[0].data.array.data.compression.algorithm, "bslz4"));
|
|
CHECK(msg2->data.ptr[0].data.array.data.compression.elem_size == 2);
|
|
CHECK(msg2->data.ptr[0].data.array.data.compression.orig_size == 1024 * 512 * 2);
|
|
REQUIRE(msg2->data.ptr[0].data.array.data.len == compressed_size);
|
|
CHECK(memcmp(msg2->data.ptr[0].data.array.data.ptr, compressed_test.data(), compressed_size) == 0);
|
|
CHECK(msg2->data.ptr[0].data.array.tag == TagUnsignedInt16BitLE);
|
|
CHECK(msg2->series_id == message.series_id);
|
|
CHECK(CmpString(msg2->series_unique_id, message.series_unique_id));
|
|
stream2_free_msg(msg);
|
|
}
|
|
|
|
TEST_CASE("CBORSerialize_Image_uncompressed_stream2", "[CBOR]") {
|
|
std::vector<uint8_t> buffer(8*1024*1024);
|
|
CBORStream2Serializer serializer(buffer.data(), buffer.size());
|
|
|
|
std::vector<SpotToSave> spots;
|
|
|
|
std::vector<uint8_t> test(512*1024);
|
|
for (int i = 0; i < test.size(); i++)
|
|
test[i] = (i * 253 + 56) % 256;
|
|
|
|
CompressedImage image {
|
|
.data = test.data(),
|
|
.size = 1024 * 512,
|
|
.xpixel = 1024,
|
|
.ypixel = 512,
|
|
.pixel_depth_bytes = 1,
|
|
.pixel_is_signed = false,
|
|
.pixel_is_float = false,
|
|
.algorithm = CompressionAlgorithm::NO_COMPRESSION,
|
|
.channel = "default"
|
|
};
|
|
|
|
DataMessage message {
|
|
.number = 456,
|
|
.image = image,
|
|
.spots = spots
|
|
};
|
|
|
|
REQUIRE_NOTHROW(serializer.SerializeImage(message));
|
|
|
|
stream2_msg *msg;
|
|
|
|
auto ret = stream2_parse_msg(buffer.data(), serializer.GetBufferSize(), &msg);
|
|
REQUIRE(ret == STREAM2_OK);
|
|
CHECK(msg->type == STREAM2_MSG_IMAGE);
|
|
auto msg2 = (stream2_image_msg *) msg;
|
|
CHECK(msg2->image_id == message.number);
|
|
CHECK(msg2->data.len == 1);
|
|
CHECK(CmpString(msg2->data.ptr->channel, "default"));
|
|
CHECK(msg2->data.ptr[0].data.array.data.compression.algorithm == nullptr);
|
|
REQUIRE(msg2->data.ptr[0].data.array.data.len == 512*1024);
|
|
CHECK(memcmp(msg2->data.ptr[0].data.array.data.ptr, test.data(), 512*1024) == 0);
|
|
CHECK(msg2->data.ptr[0].data.array.tag == TagUnsignedInt8Bit);
|
|
CHECK(msg2->series_id == message.series_id);
|
|
CHECK(CmpString(msg2->series_unique_id, message.series_unique_id));
|
|
stream2_free_msg(msg);
|
|
}
|
|
|