// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-or-later #include #include #include #include "../common/FrameTransformation.h" #include "../common/RawToConvertedGeometry.h" #include "../compression/JFJochDecompress.h" using namespace std::literals::chrono_literals; 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(JFJochProtoBuf::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); std::vector output(experiment.GetPixelsNum()); 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)); } transformation.Pack(); REQUIRE(transformation.SaveCompressedImage(output.data()) == experiment.GetPixelDepth() * 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_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(JFJochProtoBuf::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); std::vector output(experiment.GetPixelsNum()); 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)); } transformation.Pack(); REQUIRE(transformation.SaveCompressedImage(output.data()) == experiment.GetPixelDepth() * 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_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(JFJochProtoBuf::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)); } size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); output_compressed.resize(compressed_size); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, 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(JFJochProtoBuf::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)); } size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); output_compressed.resize(compressed_size); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, 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_bin_2x2" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2, 0, 0, false)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Compression(JFJochProtoBuf::BSHUF_ZSTD).Binning2x2(true); 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] = (i % 1024) + (i / 1024); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = 10; 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)); } size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); output_compressed.resize(compressed_size); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, experiment.GetPixelsNum())); REQUIRE(output[0] == 0 + 1 + 1 + 2); REQUIRE(output[1] == 2 + 3 + 3 + 4); REQUIRE(output[(513/2)*(1030/2) * 2] == 510 + 511 + 511 + 512); // line 510 + 511 REQUIRE(output[(514/2)*(1030/2) * 2] == 1024 + 1025 + 1025 + 1026); // line 1024 + 1025 } 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(JFJochProtoBuf::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)); } size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); output_compressed.resize(compressed_size); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, 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_summation" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Summation(4).Compression(JFJochProtoBuf::BSHUF_ZSTD); REQUIRE(experiment.GetSummation() == 4); FrameTransformation transformation(experiment); std::mt19937 g1(15097); 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)); } 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)); } 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)); } 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)); } size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); output_compressed.resize(compressed_size); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, experiment.GetPixelsNum())); REQUIRE(4 * input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(2 * input_0[511*1024+256] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE( input_0[256*1024+256] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(4 * input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(4 * input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(4 * input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(2 * input_1[511*1024+256] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(4 * input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(4 * input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); } TEST_CASE("FrameTransformation_Converted_bshuf_zstd_summation_bin_2x2" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2, 0, 0, false)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Summation(4).Compression(JFJochProtoBuf::BSHUF_ZSTD).Binning2x2(true); REQUIRE(experiment.GetSummation() == 4); 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] = (i % 1024) + (i / 1024); std::vector input_1(nmodules*RAW_MODULE_SIZE); for (int i = 0; i < nmodules*RAW_MODULE_SIZE; i++) input_1[i] = 10; std::vector output_compressed(experiment.GetMaxCompressedSize()); for (int frame = 0; frame < experiment.GetSummation(); frame++) { 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)); } } size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); output_compressed.resize(compressed_size); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, experiment.GetPixelsNum())); REQUIRE(output[0] == 4 * (0 + 1 + 1 + 2)); REQUIRE(output[1] == 4 * (2 + 3 + 3 + 4)); REQUIRE(output[(513/2)*(1030/2) * 2] == 4 * (510 + 511 + 511 + 512)); // line 510 + 511 REQUIRE(output[(514/2)*(1030/2) * 2] == 4 * (1024 + 1025 + 1025 + 1026)); // line 1024 + 1025 } TEST_CASE("FrameTransformation_Converted_16bit_preview_summation" ,"") { const uint16_t nmodules = 1; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 1, 0, 0, false)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Summation(4).Compression(JFJochProtoBuf::BSHUF_ZSTD); REQUIRE(experiment.GetSummation() == 4); FrameTransformation transformation(experiment); std::mt19937 g1(15097); std::uniform_int_distribution dist; std::vector input_0(RAW_MODULE_SIZE, 55); input_0[0] = 10000; input_0[1] = 500; input_0[2] = INT16_MIN; input_0[3] = INT16_MAX; input_0[4] = 345; input_0[5] = 0; input_0[256*1024] = 10000; std::vector output_compressed(experiment.GetMaxCompressedSize()); REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data(), 0, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data(), 0, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data(), 0, 0)); REQUIRE_NOTHROW(transformation.ProcessModule(input_0.data(), 0, 0)); size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); output_compressed.resize(compressed_size); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, experiment.GetPixelsNum())); auto output16 = transformation.GetPreview16BitImage(); REQUIRE(output16[0] == INT16_MAX); REQUIRE(output[0] == 4 * 10000); REQUIRE(output16[1] == 4 * 500); REQUIRE(output[1] == 4 * 500); REQUIRE(output16[2] == INT16_MIN); REQUIRE(output[2] == experiment.GetUnderflow()); REQUIRE(output16[3] == INT16_MAX); REQUIRE(output[3] == experiment.GetOverflow()); REQUIRE(output16[4] == 4*345); REQUIRE(output[4] == 4*345); REQUIRE(output16[5] == 0); REQUIRE(output[5] == 0); REQUIRE(output16[1030*257] == 4 * 5000); REQUIRE(output[1030*257] == 4 * 5000); } TEST_CASE("FrameTransformation_Converted_bshuf_zstd_summation_2frames" ,"") { // Ensure that previous frame is properly cleaned with PackStandardOutput() const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Summation(4).Compression(JFJochProtoBuf::BSHUF_ZSTD); REQUIRE(experiment.GetSummation() == 4); FrameTransformation transformation(experiment); std::mt19937 g1(15097); 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)); } 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)); } size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); 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)); } 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)); } 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)); } 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)); } transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); output_compressed.resize(compressed_size); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, experiment.GetPixelsNum())); REQUIRE(4 * input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(2 * input_0[511*1024+256] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE( input_0[256*1024+256] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(4 * input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(4 * input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(4 * input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(2 * input_1[511*1024+256] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(4 * input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(4 * input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); } TEST_CASE("FrameTransformation_Converted_bshuf_zstd_summation_negatives" ,"") { const uint16_t nmodules = 4; const uint16_t ndatastreams = 2; DiffractionExperiment experiment(DetectorGeometry(ndatastreams * nmodules, 2)); experiment.DataStreams(ndatastreams); experiment.Mode(DetectorMode::Conversion).Summation(4).Compression(JFJochProtoBuf::BSHUF_ZSTD); REQUIRE(experiment.GetSummation() == 4); FrameTransformation transformation(experiment); std::mt19937 g1(12387); 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)); } 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)); } 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)); } 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)); } size_t compressed_size; transformation.Pack(); REQUIRE_NOTHROW(compressed_size = transformation.SaveCompressedImage(output_compressed.data())); REQUIRE(bshuf_read_uint64_BE(output_compressed.data()) == experiment.GetPixelsNum() * experiment.GetPixelDepth()); REQUIRE(bshuf_read_uint32_BE(output_compressed.data()+8) == JFJochBitShuffleCompressor::DefaultBlockSize * experiment.GetPixelDepth()); output_compressed.resize(compressed_size); std::vector output; REQUIRE_NOTHROW(JFJochDecompress(output, experiment.GetCompressionAlgorithmEnum(), output_compressed, experiment.GetPixelsNum())); REQUIRE(4 * input_0[511*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 0]); REQUIRE(2 * input_0[511*1024+256] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 258]); REQUIRE( input_0[256*1024+256] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 2 * 1030 * 255 + 257]); REQUIRE(4 * input_0[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030]); REQUIRE(4 * input_0[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (2 * nmodules - 2) + 1030 + 800 + 6]); REQUIRE(4 * input_1[511*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 0]); REQUIRE(2 * input_1[511*1024+256] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 258]); REQUIRE(4 * input_1[(511+512)*1024] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030]); REQUIRE(4 * input_1[(511+512)*1024 + 800] == output[CONVERTED_MODULE_SIZE * (nmodules - 2) + 1030 + 800 + 6]); }