// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include #include #include #include "../receiver/FrameTransformation.h" #include "../common/RawToConvertedGeometry.h" #include "../compression/JFJochDecompress.h" #include using namespace std::literals::chrono_literals; inline uint32_t read_be32(const void *ptr) { auto ptr32 = (uint32_t *) ptr; return __builtin_bswap32(ptr32[0]); } inline uint64_t read_be64(const void *ptr) { auto ptr64 = (uint64_t *) ptr; return __builtin_bswap64(ptr64[0]); } TEST_CASE("Bshuf_SSE", "[bitshuffle]") { REQUIRE (bshuf_using_SSE2() == 1); } TEST_CASE("FrameTransformation_Raw_NoCompression" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 1)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Raw); experiment.Compression(CompressionAlgorithm::NO_COMPRESSION); FrameTransformation transformation(experiment); std::mt19937 g1(1587); std::uniform_int_distribution dist; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(image.size == experiment.GetByteDepthImage() * experiment.GetPixelsNum()); auto output = (int16_t *) image.data; uint32_t diff_0 = 0; uint32_t diff_1 = 0; for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) { if (input_0[i] != output[i]) diff_0++; if (input_1[i] != output[i + nmodules*RAW_MODULE_SIZE]) diff_1++; } REQUIRE(diff_0 == 0); REQUIRE(diff_1 == 0); } TEST_CASE("FrameTransformation_Raw_NoCompression_bshuf_lz4" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 1)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Raw); experiment.Compression(CompressionAlgorithm::BSHUF_LZ4); FrameTransformation transformation(experiment); std::mt19937 g1(1587); std::uniform_int_distribution dist; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(read_be64(image.data) == experiment.GetPixelsNum() * experiment.GetByteDepthImage()); REQUIRE(read_be32(image.data+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetByteDepthImage()); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithm(), image.data, image.size, experiment.GetPixelsNum())); uint32_t diff_0 = 0; uint32_t diff_1 = 0; for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) { if (input_0[i] != output[i]) diff_0++; if (input_1[i] != output[i + nmodules*RAW_MODULE_SIZE]) diff_1++; } REQUIRE(diff_0 == 0); REQUIRE(diff_1 == 0); } TEST_CASE("FrameTransformation_Conversion_NoGeomTransformation_NoCompression" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 1)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).GeometryTransformation(false); experiment.Compression(CompressionAlgorithm::NO_COMPRESSION); FrameTransformation transformation(experiment); std::mt19937 g1(1587); std::uniform_int_distribution dist; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(image.size == experiment.GetByteDepthImage() * experiment.GetPixelsNum()); auto output = (int16_t *) image.data; uint32_t diff_0 = 0; uint32_t diff_1 = 0; for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) { if (input_0[i] != output[i]) diff_0++; if (input_1[i] != output[i + nmodules*RAW_MODULE_SIZE]) diff_1++; } REQUIRE(diff_0 == 0); REQUIRE(diff_1 == 0); } TEST_CASE("FrameTransformation_Converted_NoCompression" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Compression(CompressionAlgorithm::NO_COMPRESSION); FrameTransformation transformation(experiment); std::mt19937 g1(1687); std::uniform_int_distribution dist; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(image.size == experiment.GetByteDepthImage() * experiment.GetPixelsNum()); auto output = (int16_t *) image.data; REQUIRE(input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(input_0[511*1024+256]/2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE(input_0[256*1024+256]/4 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(input_0[311*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 0]); REQUIRE(input_0[311*1024+256] / 2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 258]); REQUIRE(input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(input_1[511*1024+256] /2 == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(input_1[(311+2*512)*1024] == output[200 * 1030 * 2 + 0]); REQUIRE(input_1[(311+2*512)*1024+512] / 2 == output[200 * 1030 * 2 + 256*2+3]); REQUIRE(input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); } TEST_CASE("FrameTransformation_Converted_bshuf_lz4" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Compression(CompressionAlgorithm::BSHUF_LZ4); FrameTransformation transformation(experiment); // Predictable random number generator std::mt19937 g1(23433); std::uniform_int_distribution distribution; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = distribution(g1); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = distribution(g1); std::vector output_compressed(experiment.GetMaxCompressedSize()); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(read_be64(image.data) == experiment.GetPixelsNum() * experiment.GetByteDepthImage()); REQUIRE(read_be32(image.data+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetByteDepthImage()); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithm(), image.data, image.size, experiment.GetPixelsNum())); REQUIRE(input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(input_0[511*1024+256]/2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE(input_0[256*1024+256]/4 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(input_0[311*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 0]); REQUIRE(input_0[311*1024+256] / 2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 258]); REQUIRE(input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(input_1[511*1024+256] /2 == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(input_1[(311+2*512)*1024] == output[200 * 1030 * 2 + 0]); REQUIRE(input_1[(311+2*512)*1024+512] / 2 == output[200 * 1030 * 2 + 256*2+3]); REQUIRE(input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); } TEST_CASE("FrameTransformation_Converted_bshuf_zstd" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Compression(CompressionAlgorithm::BSHUF_ZSTD); FrameTransformation transformation(experiment); std::mt19937 g1(1987); std::uniform_int_distribution dist; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); std::vector output_compressed(experiment.GetMaxCompressedSize()); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(read_be64(image.data) == experiment.GetPixelsNum() * experiment.GetByteDepthImage()); REQUIRE(read_be32(image.data+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetByteDepthImage()); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithm(), image.data, image.size, experiment.GetPixelsNum())); REQUIRE(input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(input_0[511*1024+256]/2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE(input_0[256*1024+256]/4 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(input_0[311*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 0]); REQUIRE(input_0[311*1024+256] / 2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 258]); REQUIRE(input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(input_1[511*1024+256] /2 == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(input_1[(311+2*512)*1024] == output[200 * 1030 * 2 + 0]); REQUIRE(input_1[(311+2*512)*1024+512] / 2 == output[200 * 1030 * 2 + 256*2+3]); REQUIRE(input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); } TEST_CASE("FrameTransformation_Converted_bshuf_zstd_rle" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Compression(CompressionAlgorithm::BSHUF_ZSTD_RLE); FrameTransformation transformation(experiment); std::mt19937 g1(1987); std::uniform_int_distribution dist; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); std::vector output_compressed(experiment.GetMaxCompressedSize()); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(read_be64(image.data) == experiment.GetPixelsNum() * experiment.GetByteDepthImage()); REQUIRE(read_be32(image.data+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetByteDepthImage()); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithm(), image.data, image.size, experiment.GetPixelsNum())); REQUIRE(input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(input_0[511*1024+256]/2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE(input_0[256*1024+256]/4 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(input_0[311*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 0]); REQUIRE(input_0[311*1024+256] / 2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 258]); REQUIRE(input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(input_1[511*1024+256] /2 == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(input_1[(311+2*512)*1024] == output[200 * 1030 * 2 + 0]); REQUIRE(input_1[(311+2*512)*1024+512] / 2 == output[200 * 1030 * 2 + 256*2+3]); REQUIRE(input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); } TEST_CASE("FrameTransformation_Converted_bshuf_zstd_32bit" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Compression(CompressionAlgorithm::BSHUF_ZSTD).BitDepthImage(32); FrameTransformation transformation(experiment); std::mt19937 g1(1987); std::uniform_int_distribution dist; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); input_0[311*1024+256] = INT32_MAX-1; input_0[311*1024+255] = INT32_MIN; std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); std::vector output_compressed(experiment.GetMaxCompressedSize()); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(read_be64(image.data) == experiment.GetPixelsNum() * experiment.GetByteDepthImage()); REQUIRE(read_be32(image.data+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetByteDepthImage()); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithm(), image.data, image.size, experiment.GetPixelsNum())); REQUIRE(input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(input_0[511*1024+256]/2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE(input_0[256*1024+256]/4 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(input_0[311*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 0]); REQUIRE(input_0[311*1024+255] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 255]); REQUIRE(input_0[311*1024+256] / 2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 258]); REQUIRE(input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(input_1[511*1024+256] /2 == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(input_1[(311+2*512)*1024] == output[200 * 1030 * 2 + 0]); REQUIRE(input_1[(311+2*512)*1024+512] / 2 == output[200 * 1030 * 2 + 256*2+3]); REQUIRE(input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); } TEST_CASE("FrameTransformation_Converted_bshuf_zstd_8bit" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Compression(CompressionAlgorithm::BSHUF_ZSTD).BitDepthImage(8); FrameTransformation transformation(experiment); std::mt19937 g1(1987); std::uniform_int_distribution dist; std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); input_0[311*1024+256] = INT8_MAX-1; input_0[311*1024+255] = INT8_MIN; std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); std::vector output_compressed(experiment.GetMaxCompressedSize()); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(read_be64(image.data) == experiment.GetPixelsNum() * experiment.GetByteDepthImage()); REQUIRE(read_be32(image.data+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetByteDepthImage()); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithm(), image.data, image.size, experiment.GetPixelsNum())); REQUIRE(input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(input_0[511*1024+256]/2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE(input_0[256*1024+256]/4 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(input_0[311*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 0]); REQUIRE(input_0[311*1024+255] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 255]); REQUIRE(input_0[311*1024+256] / 2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 258]); REQUIRE(input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(input_1[511*1024+256] /2 == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(input_1[(311+2*512)*1024] == output[200 * 1030 * 2 + 0]); REQUIRE(input_1[(311+2*512)*1024+512] / 2 == output[200 * 1030 * 2 + 256*2+3]); REQUIRE(input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); } TEST_CASE("FrameTransformation_Converted_bshuf_zstd_unsigned_16bit" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Compression(CompressionAlgorithm::BSHUF_ZSTD).PixelSigned(false); REQUIRE(!experiment.IsPixelSigned()); REQUIRE(experiment.GetByteDepthImage() == 2); FrameTransformation transformation(experiment); std::mt19937 g1(1987); std::uniform_int_distribution dist(0, UINT16_MAX - 2); std::vector input_0(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_0[i] = dist(g1); input_0[311*1024+256] = UINT16_MAX - 2; input_0[311*1024+255] = UINT16_MAX - 1; input_0[255*1024] = UINT16_MAX - 1; std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = dist(g1); std::vector output_compressed(experiment.GetMaxCompressedSize()); for (int i = 0; i < nmodules; i++) { REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data() + i * RAW_MODULE_SIZE, i, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_1.data() + i * RAW_MODULE_SIZE, i, 1)); } auto image = transformation.GetCompressedImage(); REQUIRE(read_be64(image.data) == experiment.GetPixelsNum() * experiment.GetByteDepthImage()); REQUIRE(read_be32(image.data+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetByteDepthImage()); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithm(), image.data, image.size, experiment.GetPixelsNum())); REQUIRE(input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(input_0[511*1024+256]/2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE(input_0[256*1024+256]/4 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(input_0[311*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 0]); REQUIRE(input_0[311*1024+255] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 255]); REQUIRE(input_0[311*1024+255] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 256]); REQUIRE(input_0[311*1024+256] / 2 == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 200 * 1030 * 2 + 258]); REQUIRE(input_0[255*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 257 * 1030 * 2 + 0]); REQUIRE(input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(input_1[511*1024+256] /2 == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(input_1[(311+2*512)*1024] == output[200 * 1030 * 2 + 0]); REQUIRE(input_1[(311+2*512)*1024+512] / 2 == output[200 * 1030 * 2 + 256*2+3]); REQUIRE(input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); }