// Copyright (2019-2023) Paul Scherrer Institute #include #include "../common/DiffractionExperiment.h" #include "../compression/JFJochCompressor.h" #include "../common/NetworkAddressConvert.h" using namespace std::literals::chrono_literals; TEST_CASE("DiffractionExperiment_FilePath","[DiffractionExperiment]") { DiffractionExperiment x; REQUIRE_NOTHROW(x.FilePrefix("x")); REQUIRE(x.GetFilePrefix() == "x"); // trailing / needs to be ignored REQUIRE_THROWS(x.FilePrefix("/x")); REQUIRE_THROWS(x.FilePrefix("../x")); REQUIRE_THROWS(x.FilePrefix("x/../y")); x.Mode(DetectorMode::PedestalG0); REQUIRE(x.GetFilePrefix() == "x"); x.Mode(DetectorMode::PedestalG1); REQUIRE(x.GetFilePrefix() == "x"); x.Mode(DetectorMode::PedestalG2); REQUIRE(x.GetFilePrefix() == "x"); REQUIRE_NOTHROW(x.FilePrefix("x6_master.h5")); REQUIRE(x.GetFilePrefix() == "x6"); REQUIRE_NOTHROW(x.FilePrefix("long_name/directory/file_master.h5")); REQUIRE(x.GetFilePrefix() == "long_name/directory/file"); REQUIRE_NOTHROW(x.FilePrefix("_master.h5")); REQUIRE(x.GetFilePrefix() == "_master.h5"); } TEST_CASE("DiffractionExperiment_Compression","[DiffractionExperiment]") { DiffractionExperiment x; // Compression x.Compression(CompressionAlgorithm::BSHUF_LZ4); REQUIRE(x.GetCompressionAlgorithm() == CompressionAlgorithm::BSHUF_LZ4); x.Compression(CompressionAlgorithm::BSHUF_ZSTD); REQUIRE(x.GetCompressionAlgorithm() == CompressionAlgorithm::BSHUF_ZSTD); x.Compression(CompressionAlgorithm::BSHUF_ZSTD_RLE); REQUIRE(x.GetCompressionAlgorithm() == CompressionAlgorithm::BSHUF_ZSTD_RLE); x.Compression(CompressionAlgorithm::NO_COMPRESSION); REQUIRE(x.GetCompressionAlgorithm() == CompressionAlgorithm::NO_COMPRESSION); } //TODO: Update /* TEST_CASE("DiffractionExperiment_Timing","[DiffractionExperiment]") { DiffractionExperiment x; x.Mode(DetectorMode::Conversion); // Timing and frame count x.PedestalG0Frames(1000).ImagesPerTrigger(1000).NumTriggers(1).FrameTime(1000us).FPGA; // Frame count analysis REQUIRE(x.GetFrameNum() == 1000); REQUIRE(x.GetFrameTime().count() == 1000); REQUIRE(x.GetPixelDepth() == 2); REQUIRE(x.GetOverflow() == INT16_MAX); REQUIRE(x.GetUnderflow() == INT16_MIN); REQUIRE(x.GetFrameNumPerTrigger() == 1000); x.PedestalG0Frames(1000).PedestalG1Frames(2000).PedestalG2Frames(3000).NumTriggers(1) .ImagesPerTrigger(1000).FrameTime(1000us).Summation(6); REQUIRE(x.GetImageNum() == 1000); REQUIRE(x.GetImageNumPerTrigger() == 1000); REQUIRE(x.GetFrameNum() == 6000); REQUIRE(x.GetFrameTime().count() == 1000); REQUIRE(x.GetFrameCountTime().count() == 1000 - READOUT_TIME_IN_US); REQUIRE(x.GetSummation() == 6); REQUIRE(x.GetImageTime().count() == 6*1000); REQUIRE(x.GetImageCountTime().count() == 6 * (1000 - READOUT_TIME_IN_US)); REQUIRE(x.GetFrameNumPerTrigger() == 6000); REQUIRE(x.GetPedestalG0Frames() == 1000); REQUIRE(x.GetPedestalG1Frames() == 2000); REQUIRE(x.GetPedestalG2Frames() == 3000); REQUIRE(x.GetPixelDepth() == 4); REQUIRE(x.GetOverflow() == INT32_MAX); REQUIRE(x.GetUnderflow() == INT32_MIN); x.NumTriggers(2); REQUIRE(x.GetFrameNum() == 12000); REQUIRE(x.GetNumTriggers() == 2); REQUIRE(x.GetImageNum() == 2000); REQUIRE(x.GetImageNumPerTrigger() == 1000); REQUIRE(x.GetFrameNumPerTrigger() == 6000); x.Mode(DetectorMode::Raw); REQUIRE(x.GetSummation() == 1); REQUIRE(x.GetFrameNum() == 2000); REQUIRE(x.GetImageNum() == 2000); REQUIRE(x.GetImageNumPerTrigger() == 1000); x.Mode(DetectorMode::PedestalG0); REQUIRE(x.GetFrameTime().count() == 1000); REQUIRE(x.GetDetectorMode() == DetectorMode::PedestalG0); REQUIRE(x.GetFrameNum() == 1000); REQUIRE(x.GetSummation() == 1); REQUIRE(x.GetImageNumPerTrigger() == 0); x.Mode(DetectorMode::PedestalG1); REQUIRE(x.GetDetectorMode() == DetectorMode::PedestalG1); REQUIRE(x.GetFrameNum() == 2000); REQUIRE(x.GetFrameTime().count() == 10000); REQUIRE(x.GetSummation() == 1); x.PedestalG1G2FrameTime(8345us); x.Mode(DetectorMode::PedestalG2); REQUIRE(x.GetDetectorMode() == DetectorMode::PedestalG2); REQUIRE(x.GetFrameNum() == 3000); REQUIRE(x.GetFrameTime().count() == 8345); REQUIRE(x.GetSummation() == 1); } */ TEST_CASE("DiffractionExperiment_UnitCell","[DiffractionExperiment]") { DiffractionExperiment x; REQUIRE(!x.GetUnitCell()); UnitCell cell{ .a = 10, .b = 20, .c = 30, .alpha = 90, .beta = 95, .gamma = 89 }; REQUIRE_NOTHROW(x.SetUnitCell(cell)); REQUIRE(x.GetUnitCell()); REQUIRE(x.GetUnitCell()->c == 30); REQUIRE_NOTHROW(x.SetUnitCell({})); REQUIRE(!x.GetUnitCell()); REQUIRE_NOTHROW(x.SetUnitCell(cell)); REQUIRE(x.GetUnitCell()); UnitCell cell_with_zero_angle{ .a = 10, .b = 20, .c = 30, .alpha = 90, .beta = 0, .gamma = 89 }; REQUIRE_NOTHROW(x.SetUnitCell(cell_with_zero_angle)); REQUIRE(!x.GetUnitCell()); UnitCell cell_with_zero_dist{ .a = 10, .b = 20, .c = 0, .alpha = 90, .beta = 90, .gamma = 89 }; REQUIRE_NOTHROW(x.SetUnitCell(cell_with_zero_dist)); REQUIRE(!x.GetUnitCell()); UnitCell cell_with_nonsense{ .a = 10, .b = 20, .c = 30, .alpha = 90, .beta = -90, .gamma = 89 }; REQUIRE_THROWS(x.SetUnitCell(cell_with_nonsense)); } TEST_CASE("IPv4AddressToStr","") { REQUIRE(IPv4AddressToStr(0x0f32010a) == "10.1.50.15"); } TEST_CASE("IPv4AddressFromStr","") { REQUIRE(IPv4AddressFromStr("10.1.50.15") == 0x0f32010a); REQUIRE_THROWS(IPv4AddressFromStr("256.257.0.1")); REQUIRE_THROWS(IPv4AddressFromStr("ff.ff.ff.1")); } TEST_CASE("MacAddressToStr","") { REQUIRE(MacAddressToStr(0xF1EEDDCCBBAA) == "aa:bb:cc:dd:ee:f1"); REQUIRE(MacAddressToStr(0x0000DDCCBB00) == "00:bb:cc:dd:00:00"); } TEST_CASE("MacAddressFromStr","") { REQUIRE(MacAddressFromStr("aa:bb:cc:dd:ee:f1") == 0xF1EEDDCCBBAA); REQUIRE(MacAddressFromStr("11:22:33:44:55:66") == 0x665544332211); REQUIRE_THROWS(MacAddressFromStr("11:22:33:44:55:66:77")); REQUIRE_THROWS(MacAddressFromStr("11:22:33:44:55")); REQUIRE_THROWS(MacAddressFromStr("456:22:33:44:55")); REQUIRE_THROWS(MacAddressFromStr("xy:22:33:44:55")); } TEST_CASE("DiffractionExperiment_DataStreams","[DiffractionExperiment]") { DiffractionExperiment x(DetectorGeometry(18)); // 9M x.DataStreams(4); REQUIRE(x.GetModulesNum() == 18); REQUIRE(x.GetDataStreamsNum() == 4); REQUIRE(x.GetModulesNum(0) == 5); REQUIRE(x.GetModulesNum(1) == 5); REQUIRE(x.GetModulesNum(2) == 4); REQUIRE(x.GetModulesNum(3) == 4); REQUIRE_THROWS(x.GetModulesNum(4)); x.DataStreams(2); REQUIRE(x.GetModulesNum() == 18); REQUIRE(x.GetDataStreamsNum() == 2); REQUIRE(x.GetModulesNum(0) == 9); REQUIRE(x.GetModulesNum(1) == 9); REQUIRE_THROWS(x.GetModulesNum(2)); x = DiffractionExperiment(DetectorGeometry(2)); x.DataStreams(2); REQUIRE(x.GetModulesNum() == 2); REQUIRE(x.GetDataStreamsNum() == 2); REQUIRE(x.GetModulesNum(0) == 1); REQUIRE(x.GetModulesNum(1) == 1); x.DataStreams(5); REQUIRE(x.GetModulesNum() == 2); REQUIRE(x.GetDataStreamsNum() == 2); REQUIRE(x.GetModulesNum(0) == 1); REQUIRE(x.GetModulesNum(1) == 1); } TEST_CASE("DiffractionExperiment_DetectorGeometry","[DiffractionExperiment]") { DiffractionExperiment x(DetectorGeometry(18)); // 9M configuration #1 - via constructor x.Mode(DetectorMode::Conversion); x.DataStreams(4); REQUIRE(x.GetDataStreamsNum() == 4); REQUIRE(x.GetXPixelsNum() == 1030); REQUIRE(x.GetYPixelsNum() == 514 * 18); REQUIRE(x.GetModulesNum() == 18); REQUIRE(x.GetModulesNum(0) == 5); REQUIRE(x.GetModulesNum(2) == 4); REQUIRE(x.GetFirstModuleOfDataStream(0) == 0); REQUIRE(x.GetFirstModuleOfDataStream(1) == 5); REQUIRE(x.GetFirstModuleOfDataStream(2) == 10); REQUIRE(x.GetFirstModuleOfDataStream(3) == 14); REQUIRE(x.GetPixelsNum() == 18 * 514 * 1030); x.Mode(DetectorMode::Raw); REQUIRE(x.GetPixelsNum() == 18 * 512 * 1024); REQUIRE(x.GetXPixelsNum() == 1024); REQUIRE(x.GetYPixelsNum() == 512 * 18); x.Mode(DetectorMode::Conversion); x = DiffractionExperiment(DetectorGeometry(18, 2)); // 9M configuration #2 REQUIRE(x.GetPixelsNum() == 1030 * 514 * 18); REQUIRE(x.GetXPixelsNum() == 1030 * 2); REQUIRE(x.GetYPixelsNum() == 514 * 18 / 2); REQUIRE(x.GetPixel0OfModule(0) == 16 * CONVERTED_MODULE_SIZE + 513 * CONVERTED_MODULE_COLS * 2); REQUIRE(x.GetPixel0OfModule(1) == 16 * CONVERTED_MODULE_SIZE + 513 * CONVERTED_MODULE_COLS * 2 + CONVERTED_MODULE_COLS); REQUIRE(x.GetPixel0OfModule(12) == 4 * CONVERTED_MODULE_SIZE + 513 * CONVERTED_MODULE_COLS * 2); REQUIRE(x.GetPixel0OfModule(13) == 4 * CONVERTED_MODULE_SIZE + 513 * CONVERTED_MODULE_COLS * 2 + CONVERTED_MODULE_COLS); REQUIRE(x.GetPixel0OfModule(14) == 2 * CONVERTED_MODULE_SIZE + 513 * CONVERTED_MODULE_COLS * 2); REQUIRE(x.GetPixel0OfModule(15) == 2 * CONVERTED_MODULE_SIZE + 513 * CONVERTED_MODULE_COLS * 2 + CONVERTED_MODULE_COLS); REQUIRE(x.GetPixel0OfModule(16) == 0 * CONVERTED_MODULE_SIZE + 513 * CONVERTED_MODULE_COLS * 2); REQUIRE(x.GetPixel0OfModule(17) == 0 * CONVERTED_MODULE_SIZE + 513 * CONVERTED_MODULE_COLS * 2 + CONVERTED_MODULE_COLS); REQUIRE_THROWS(x.GetPixel0OfModule(18)); x.Mode(DetectorMode::Raw); REQUIRE(x.GetPixelsNum() == 1024 * 512 * 18); REQUIRE(x.GetXPixelsNum() == 1024); REQUIRE(x.GetYPixelsNum() == 512 * 18); REQUIRE(x.GetPixel0OfModule(15) == 15 * RAW_MODULE_SIZE); } TEST_CASE("DiffractionExperiment_DetectorGeometry_gaps","[DiffractionExperiment]") { const size_t gap_x = 8; const size_t gap_y = 36; DiffractionExperiment x(DetectorGeometry(18, 2, gap_x, gap_y, false)); x.Mode(DetectorMode::Conversion); x.DataStreams(4); REQUIRE(x.GetDataStreamsNum() == 4); REQUIRE(x.GetPixelsNum() == (1030 * 2 + gap_x) * (514 * 9 + (9-1) * gap_y) ); REQUIRE(x.GetXPixelsNum() == 1030 * 2 + gap_x); REQUIRE(x.GetYPixelsNum() == 514 * 9 + (9-1) * gap_y); REQUIRE(x.GetModulesNum() == 18); REQUIRE(x.GetModulesNum(0) == 5); REQUIRE(x.GetModulesNum(2) == 4); REQUIRE(x.GetFirstModuleOfDataStream(0) == 0); REQUIRE(x.GetFirstModuleOfDataStream(1) == 5); REQUIRE(x.GetFirstModuleOfDataStream(2) == 10); REQUIRE(x.GetFirstModuleOfDataStream(3) == 14); REQUIRE(x.GetPixel0OfModule(0) == (2*1030 + gap_x) * (514 + gap_y) * (0/2)); REQUIRE(x.GetPixel0OfModule(4) == (2*1030 + gap_x) * (514 + gap_y) * (4/2)); REQUIRE(x.GetPixel0OfModule(8) == (2*1030 + gap_x) * (514 + gap_y) * (8/2)); REQUIRE(x.GetPixel0OfModule(14) == (2*1030 + gap_x) * (514 + gap_y) * (14/2)); REQUIRE(x.GetPixel0OfModule(0) == (2*1030 + gap_x) * 0 * (514 + gap_y)); REQUIRE(x.GetPixel0OfModule(1) == (2*1030 + gap_x) * 0 * (514 + gap_y) + 1030 + gap_x); REQUIRE(x.GetPixel0OfModule(16) == (2*1030 + gap_x) * 8 * (514 + gap_y)); REQUIRE(x.GetPixel0OfModule(17) == (2*1030 + gap_x) * 8 * (514 + gap_y) + 1030 + gap_x); } TEST_CASE("DiffractionExperiment_DetectorGeometry_gaps_mirror_y","[DiffractionExperiment]") { const size_t gap_x = 8; const size_t gap_y = 36; DiffractionExperiment x(DetectorGeometry(20, 2, gap_x, gap_y, true)); x.Mode(DetectorMode::Conversion); REQUIRE(x.GetPixel0OfModule(0) == (2*1030+gap_x) * 513 + (2*1030 + gap_x) * 9 * (514 + gap_y)); REQUIRE(x.GetPixel0OfModule(1) == (2*1030+gap_x) * 513 + (2*1030 + gap_x) * 9 * (514 + gap_y) + 1030 + gap_x); REQUIRE(x.GetPixel0OfModule(14) == (2*1030+gap_x) * 513 + (2*1030 + gap_x) * 2 * (514 + gap_y)); REQUIRE(x.GetPixel0OfModule(15) == (2*1030+gap_x) * 513 + (2*1030 + gap_x) * 2 * (514 + gap_y) + 1030 + gap_x); REQUIRE(x.GetPixel0OfModule(16) == (2*1030+gap_x) * 513 + (2*1030 + gap_x) * 1 * (514 + gap_y)); REQUIRE(x.GetPixel0OfModule(17) == (2*1030+gap_x) * 513 + (2*1030 + gap_x) * 1 * (514 + gap_y) + 1030 + gap_x); REQUIRE(x.GetPixel0OfModule(18) == (2*1030+gap_x) * 513 + (2*1030 + gap_x) * 0 * (514 + gap_y)); REQUIRE(x.GetPixel0OfModule(19) == (2*1030+gap_x) * 513 + (2*1030 + gap_x) * 0 * (514 + gap_y) + 1030 + gap_x); REQUIRE_THROWS(x.GetPixel0OfModule(20)); } TEST_CASE("DiffractionExperiment_Metadata","[DiffractionExperiment]") { DiffractionExperiment x; x.PhotonEnergy_keV(6.0); REQUIRE(x.GetPhotonEnergy_keV() == 6.0); REQUIRE(x.GetWavelength_A() == Catch::Approx(12.39854 / 6.0)); x.DetectorDistance_mm(30.0).BeamX_pxl(1200).BeamY_pxl(1000).FrameTime(900us); REQUIRE(x.GetBeamX_pxl() == Catch::Approx(1200)); REQUIRE(x.GetBeamY_pxl() == Catch::Approx(1000)); REQUIRE(x.GetDetectorDistance_mm() == Catch::Approx(30.0)); REQUIRE_THROWS(x.PedestalG0Frames(-1)); REQUIRE_THROWS(x.PedestalG1Frames(-1)); REQUIRE_THROWS(x.PedestalG2Frames(-1)); } TEST_CASE("DiffractionExperiment_ZMQPreview", "[DiffractionExperiment]") { DiffractionExperiment x; x.ZMQPreviewPeriod(0ms); REQUIRE(x.GetZMQPreviewPeriod().has_value()); REQUIRE(x.GetZMQPreviewPeriod().value().count() == 0); x.ZMQPreviewPeriod({}); REQUIRE(!x.GetZMQPreviewPeriod().has_value()); x.ZMQPreviewPeriod(1s); REQUIRE(x.GetZMQPreviewPeriod() == std::chrono::milliseconds(1000)); REQUIRE_THROWS(x.ZMQPreviewPeriod(-5ms)); x.Mode(DetectorMode::PedestalG0); REQUIRE(!x.GetZMQPreviewPeriod().has_value()); x.Mode(DetectorMode::PedestalG1); REQUIRE(!x.GetZMQPreviewPeriod().has_value()); x.Mode(DetectorMode::PedestalG2); REQUIRE(!x.GetZMQPreviewPeriod().has_value()); } TEST_CASE("DiffractionExperiment_SpaceGroup", "[DiffractionExperiment]") { DiffractionExperiment x; REQUIRE_THROWS(x.SpaceGroupNumber(-1)); REQUIRE_THROWS(x.SpaceGroupNumber(500)); REQUIRE_NOTHROW(x.SpaceGroupNumber(0)); REQUIRE_NOTHROW(x.SpaceGroupNumber(200)); REQUIRE(x.GetSpaceGroupNumber() == 200); } TEST_CASE("DiffractionExperiment_SampleName", "[DiffractionExperiment]") { DiffractionExperiment x; REQUIRE_NOTHROW(x.SampleName("")); REQUIRE(x.GetSampleName().empty()); REQUIRE_NOTHROW(x.SampleName("lyso1")); REQUIRE(x.GetSampleName() == "lyso1"); } TEST_CASE("DiffractionExperiment_SaveCalibration", "[DiffractionExperiment]") { DiffractionExperiment x; x.ImagesPerTrigger(2).NumTriggers(2); REQUIRE(!x.GetSaveCalibration()); x.ImagesPerTrigger(1).NumTriggers(5); REQUIRE(x.GetSaveCalibration()); x.ImagesPerTrigger(5).NumTriggers(1); REQUIRE(x.GetSaveCalibration()); x.Mode(DetectorMode::PedestalG0); REQUIRE(!x.GetSaveCalibration()); } TEST_CASE("DiffractionExperiment_FrameCountTime","[DiffractionExperiment]") { DiffractionExperiment x; REQUIRE_NOTHROW(x.FrameTime(1000us, 3us)); REQUIRE_NOTHROW(x.FrameTime(1000us)); REQUIRE(x.GetFrameCountTime() == 1000us - std::chrono::microseconds(READOUT_TIME_IN_US)); REQUIRE_NOTHROW(x.FrameTime(2000us)); REQUIRE_THROWS(x.FrameTime(2500us)); REQUIRE_THROWS(x.FrameTime(10000us, 2100us)); REQUIRE_NOTHROW(x.FrameTime(10000us, 10us)); } //TODO: Update /* TEST_CASE("DiffractionExperiment_FrameCountTime","[DiffractionExperiment]") { DiffractionExperiment x; x.FrameTime(std::chrono::microseconds(1200)); REQUIRE(x.GetFrameTime() == std::chrono::microseconds(1200)); REQUIRE(x.GetFrameCountTime() == std::chrono::microseconds(1200 - READOUT_TIME_IN_US)); REQUIRE(x.GetImageTime() == std::chrono::microseconds(1200)); REQUIRE(x.GetImageCountTime() == std::chrono::microseconds(1200 - READOUT_TIME_IN_US)); x.FrameTime(std::chrono::microseconds(1200), std::chrono::microseconds(567)); REQUIRE(x.GetFrameTime() == std::chrono::microseconds(1200)); REQUIRE(x.GetFrameCountTime() == std::chrono::microseconds(567)); x.Summation(7); REQUIRE(x.GetFrameTime() == std::chrono::microseconds(1200)); REQUIRE(x.GetFrameCountTime() == std::chrono::microseconds(567)); REQUIRE(x.GetImageTime() == std::chrono::microseconds(7*1200)); REQUIRE(x.GetImageCountTime() == std::chrono::microseconds(7*567)); } */ TEST_CASE("DiffractionExperiment_InternalPacketGenerator", "[DiffractionExperiment]") { DiffractionExperiment x; x.NumTriggers(50).ImagesPerTrigger(20); REQUIRE(x.GetNumTriggers() == 50); // Default is false REQUIRE(!x.IsUsingInternalPacketGen()); x.UseInternalPacketGenerator(true); REQUIRE(x.IsUsingInternalPacketGen()); REQUIRE(x.GetNumTriggers() == 50); REQUIRE(x.GetFrameNum() == 50*20); } TEST_CASE("DiffractionExperiment_CopyConstructor", "[DiffractionExperiment]") { DiffractionExperiment a = DiffractionExperiment().Mode(DetectorMode::Raw); a.BeamX_pxl(150); REQUIRE(a.GetBeamX_pxl() == 150.0); REQUIRE(a.GetDetectorMode() == DetectorMode::Raw); DiffractionExperiment b(a); REQUIRE(b.GetBeamX_pxl() == 150.0); b.BeamX_pxl(100); REQUIRE(a.GetBeamX_pxl() == 150.0); REQUIRE(b.GetBeamX_pxl() == 100.0); REQUIRE(b.GetDetectorMode() == DetectorMode::Raw); DiffractionExperiment c = b; REQUIRE (c.GetBeamX_pxl() == 100.0); c.BeamX_pxl(10); REQUIRE (a.GetBeamX_pxl() == 150.0); REQUIRE (b.GetBeamX_pxl() == 100.0); REQUIRE (c.GetBeamX_pxl() == 10.0); } TEST_CASE("DiffractionExperiment_RadialIntegration_LowQ","[DiffractionExperiment]") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36)); REQUIRE_THROWS(x.LowQForAzimInt_recipA(0)); REQUIRE_THROWS(x.LowQForAzimInt_recipA(-1)); REQUIRE_THROWS(x.LowQForAzimInt_recipA(50)); x.LowQForAzimInt_recipA(4); REQUIRE(x.GetLowQForAzimInt_recipA() == Catch::Approx(4)); REQUIRE_THROWS(x.LowResForAzimInt_A(0)); REQUIRE_THROWS(x.LowResForAzimInt_A(-1)); x.LowResForAzimInt_A(5.0); REQUIRE(x.GetLowQForAzimInt_recipA() == Catch::Approx(2 * M_PI / 5.0)); DiffractionExperiment y(x); REQUIRE(y.GetLowQForAzimInt_recipA() == Catch::Approx(2 * M_PI / 5.0)); } TEST_CASE("DiffractionExperiment_RadialIntegration_HighQ","[DiffractionExperiment]") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36)); REQUIRE_THROWS(x.HighQForAzimInt_recipA(0)); REQUIRE_THROWS(x.HighQForAzimInt_recipA(-1)); REQUIRE_THROWS(x.HighQForAzimInt_recipA(50)); x.HighQForAzimInt_recipA(8); REQUIRE(x.GetHighQForAzimInt_recipA() == Catch::Approx(8.0)); REQUIRE_THROWS(x.HighResForAzimInt_A(0)); REQUIRE_THROWS(x.HighResForAzimInt_A(-1)); x.HighResForAzimInt_A(3.0); REQUIRE(x.GetHighQForAzimInt_recipA() == Catch::Approx(2 * M_PI / 3.0)); DiffractionExperiment y(x); REQUIRE(y.GetHighQForAzimInt_recipA() == Catch::Approx(2 * M_PI / 3.0)); } TEST_CASE("DiffractionExperiment_RadialIntegration_QSpacing","[DiffractionExperiment]") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36)); x.QSpacingForAzimInt_recipA(0.456); REQUIRE(x.GetQSpacingForAzimInt_recipA() == Catch::Approx(0.456)); DiffractionExperiment y(x); REQUIRE(y.GetQSpacingForAzimInt_recipA() == Catch::Approx(0.456)); } TEST_CASE("DiffractionExperiment_StorageCells","[DiffractionExperiment]") { const int64_t num_triggers = 20; DiffractionExperiment x; x.FrameTime(std::chrono::milliseconds(1)).ImagesPerTrigger(5).NumTriggers(num_triggers); REQUIRE(x.GetNumTriggers() == num_triggers); REQUIRE_NOTHROW(x.StorageCells(5)); REQUIRE(x.GetStorageCellNumber() == 5); REQUIRE_THROWS(x.StorageCells(0)); REQUIRE_THROWS(x.StorageCells(-1)); REQUIRE_THROWS(x.StorageCells(32)); REQUIRE_NOTHROW(x.StorageCells(3)); REQUIRE(x.GetStorageCellNumber() == 3); REQUIRE_NOTHROW(x.StorageCells(15)); REQUIRE(x.GetStorageCellNumber() == 15); REQUIRE_NOTHROW(x.StorageCells(4)); REQUIRE(x.GetStorageCellNumber() == 4); REQUIRE_NOTHROW(x.StorageCells(8)); REQUIRE(x.GetStorageCellNumber() == 8); x.StorageCells(16); REQUIRE(x.GetStorageCellNumber() == 16); REQUIRE(x.GetFrameNumPerTrigger() == x.GetStorageCellNumber()); REQUIRE(x.GetImageNum() == x.GetStorageCellNumber() * num_triggers); REQUIRE(x.GetFrameNum() == x.GetStorageCellNumber() * num_triggers); x.UseInternalPacketGenerator(true); REQUIRE(x.GetFrameNumPerTrigger() == x.GetStorageCellNumber()); REQUIRE(x.GetImageNum() == x.GetStorageCellNumber() * num_triggers); REQUIRE(x.GetFrameNum() == x.GetStorageCellNumber() * num_triggers); } TEST_CASE("DiffractionExperiment_StorageCells_Pedestal","[DiffractionExperiment]") { DiffractionExperiment x; x.PedestalG0Frames(1456).PedestalG1Frames(323).PedestalG2Frames(456).StorageCells(16); x.Mode(DetectorMode::PedestalG0); REQUIRE(x.GetStorageCellNumber() == 16); REQUIRE(x.GetNumTriggers() == 1); REQUIRE(x.GetFrameNumPerTrigger() == 1456*16); REQUIRE(x.GetFrameNum() == 1456 * 16); x.Mode(DetectorMode::PedestalG1); REQUIRE(x.GetStorageCellNumber() == 2); REQUIRE(x.GetNumTriggers() == 1); REQUIRE(x.GetFrameNumPerTrigger() == 2 * 323); REQUIRE(x.GetFrameNum() == 323 * 2); x.StorageCells(8); x.Mode(DetectorMode::PedestalG2); REQUIRE(x.GetStorageCellNumber() == 2); REQUIRE(x.GetNumTriggers() == 1); REQUIRE(x.GetFrameNumPerTrigger() == 2 * 456); } TEST_CASE("DiffractionExperiment_StorageCells_Pedestal_FixedG1","[DiffractionExperiment]") { DiffractionExperiment x; x.PedestalG0Frames(1456).PedestalG1Frames(323).PedestalG2Frames(456).StorageCells(15).FixedGainG1(true); x.Mode(DetectorMode::PedestalG1); REQUIRE(x.GetStorageCellNumber() == 15); REQUIRE(x.GetNumTriggers() == 1); REQUIRE(x.GetFrameNumPerTrigger() == 15 * 323); REQUIRE(x.GetFrameNum() == 323 * 15); } TEST_CASE("DiffractionExperiment_ImageTime","[DiffractionExperiment]") { DiffractionExperiment x(DetectorSetup(3, DetectorType::JUNGFRAU)); DatasetSettings s; x.FrameTime(583us); s.ImageTime(583us * 4); x.ImportDatasetSettings(s); REQUIRE(x.GetSummation() == 4); s.ImageTime({}); x.ImportDatasetSettings(s); REQUIRE(x.GetSummation() == 1); s.ImageTime(585us); REQUIRE_THROWS(x.ImportDatasetSettings(s)); } TEST_CASE("DiffractionExperiment_ImageTime_EIGER","[DiffractionExperiment]") { DiffractionExperiment x(DetectorSetup(3, DetectorType::EIGER)); DatasetSettings s; x.FrameTime(583us); s.ImageTime(5ms); x.ImportDatasetSettings(s); REQUIRE(x.GetSummation() == 1); REQUIRE(x.GetFrameTime() == 5ms); REQUIRE(x.GetFrameCountTime() == 4980us); REQUIRE(x.GetByteDepthReadout() == 4); s.ImageTime({}); REQUIRE_NOTHROW(x.ImportDatasetSettings(s)); REQUIRE(x.GetSummation() == 1); REQUIRE(x.GetFrameTime() == 583us); REQUIRE(x.GetFrameCountTime() == 563us); REQUIRE(x.GetByteDepthReadout() == 2); s.ImageTime(200us); REQUIRE_THROWS(x.ImportDatasetSettings(s)); s.ImageTime(250us); REQUIRE_NOTHROW(x.ImportDatasetSettings(s)); REQUIRE(x.GetSummation() == 1); REQUIRE(x.GetByteDepthReadout() == 1); } TEST_CASE("DiffractionExperiment_PulsedSource","[DiffractionExperiment]") { DiffractionExperiment x; REQUIRE(!x.IsPulsedSource()); // default must be off x.ImagesPerTrigger(50).NumTriggers(100).Mode(DetectorMode::Conversion).PedestalG0Frames(1000) .PedestalG1Frames(200).PedestalG2Frames(100); x.PulsedSource(true); REQUIRE(x.GetFrameNumPerTrigger() == 1); REQUIRE(x.GetImageNum() == 100); x.Summation(10); REQUIRE(x.GetFrameNumPerTrigger() == 1); REQUIRE(x.GetNumTriggers() == 100 * 10); REQUIRE(x.GetFrameNum() == 100 * 10); REQUIRE(x.GetImageNum() == 100); x.Mode(DetectorMode::Raw); REQUIRE(x.GetSummation() == 1); REQUIRE(x.GetFrameNumPerTrigger() == 1); REQUIRE(x.GetNumTriggers() == 100); REQUIRE(x.GetFrameNum() == 100); REQUIRE(x.GetImageNum() == 100); x.Mode(DetectorMode::PedestalG0); REQUIRE(x.GetImageNum() == 0); REQUIRE(x.GetFrameNumPerTrigger() == 1000); REQUIRE(x.GetNumTriggers() == 1); x.Mode(DetectorMode::PedestalG1); REQUIRE(x.GetImageNum() == 0); REQUIRE(x.GetFrameNumPerTrigger() == 200); REQUIRE(x.GetNumTriggers() == 1); x.Mode(DetectorMode::PedestalG2); REQUIRE(x.GetImageNum() == 0); REQUIRE(x.GetFrameNumPerTrigger() == 100); REQUIRE(x.GetNumTriggers() == 1); } TEST_CASE("DiffractionExperiment_DefaultDataProcessingSettings","[DiffractionExperiment]") { REQUIRE_NOTHROW(DiffractionExperiment::CheckDataProcessingSettings( DiffractionExperiment::DefaultDataProcessingSettings())); } TEST_CASE("DiffractionExperiment_FPGA_PixelSigned_JUNGFRAU","[DiffractionExperiment]") { DiffractionExperiment x(DetectorSetup(DetectorGeometry(4), DetectorType::JUNGFRAU)); x.Mode(DetectorMode::Conversion).PixelSigned({}); REQUIRE(x.IsPixelSigned()); x.Mode(DetectorMode::Raw).PixelSigned({}); REQUIRE(!x.IsPixelSigned()); x.Mode(DetectorMode::Conversion).PixelSigned(false); REQUIRE(!x.IsPixelSigned()); x.Mode(DetectorMode::Raw).PixelSigned(true); REQUIRE(x.IsPixelSigned()); } TEST_CASE("DiffractionExperiment_FPGA_PixelSigned_EIGER","[DiffractionExperiment]") { DiffractionExperiment x(DetectorSetup(DetectorGeometry(4), DetectorType::EIGER)); x.Mode(DetectorMode::Conversion).PixelSigned({}); REQUIRE(!x.IsPixelSigned()); x.Mode(DetectorMode::Raw).PixelSigned({}); REQUIRE(!x.IsPixelSigned()); x.Mode(DetectorMode::Conversion).PixelSigned(false); REQUIRE(!x.IsPixelSigned()); x.Mode(DetectorMode::Raw).PixelSigned(true); REQUIRE(x.IsPixelSigned()); } TEST_CASE("DiffractionExperiment_Summation","[DiffractionExperiment]") { DiffractionExperiment x; REQUIRE_THROWS(x.Summation(0)); REQUIRE_THROWS(x.Summation(-1)); REQUIRE_NOTHROW(x.Summation(1)); REQUIRE(x.GetByteDepthImage() == 2); REQUIRE(x.GetSummation() == 1); REQUIRE(x.GetFPGASummation() == 1); REQUIRE_NOTHROW(x.Summation(2)); REQUIRE(x.GetSummation() == 2); REQUIRE(x.GetFPGASummation() == 2); REQUIRE(x.GetByteDepthImage() == 2); REQUIRE_NOTHROW(x.Summation(3)); REQUIRE(x.GetByteDepthImage() == 4); REQUIRE(x.GetSummation() == 3); REQUIRE(x.GetFPGASummation() == 3); x.BitDepthImage(16); REQUIRE(x.GetByteDepthImage() == 2); x.BitDepthImage(32); REQUIRE(x.GetByteDepthImage() == 4); x.BitDepthImage(16); REQUIRE_NOTHROW(x.Summation(500)); CHECK(x.GetByteDepthImage() == 4); CHECK(x.GetSummation() == 500); CHECK(x.GetFPGASummation() == 1); CHECK(x.IsCPUSummation()); } TEST_CASE("DiffractionExperiment_DetectorModuleHostname","[DiffractionExperiment]") { std::vector h = {"mx1", "mx2", "mx3"}; DiffractionExperiment x(DetectorSetup(3, DetectorType::JUNGFRAU, "X", h)); std::vector net_cfg; net_cfg.push_back(AcquisitionDeviceNetConfig{ .mac_addr = "00:00:00:00:00:00", .ipv4_addr = "10.10.50.1", .udp_port = 1234}); net_cfg.push_back(AcquisitionDeviceNetConfig{ .mac_addr = "00:00:00:00:00:01", .ipv4_addr = "10.10.50.2", .udp_port = 1234}); std::vector h_out; REQUIRE_NOTHROW(h_out = x.GetDetectorModuleHostname()); REQUIRE(h == h_out); auto det_cfg = x.GetDetectorModuleConfig(net_cfg); REQUIRE(det_cfg.size() == x.GetModulesNum()); } TEST_CASE("DiffractionExperiment_GetImageFillValue","") { DiffractionExperiment x; x.BitDepthImage(32).PixelSigned(true); REQUIRE(x.GetImageFillValue() == INT32_MIN); REQUIRE(x.GetOverflow() == INT32_MAX); REQUIRE(x.GetUnderflow() == INT32_MIN); x.BitDepthImage(32).PixelSigned(false); REQUIRE(x.GetImageFillValue() == UINT32_MAX); REQUIRE(x.GetOverflow() == UINT32_MAX); REQUIRE(x.GetUnderflow() == -1); x.BitDepthImage(8).PixelSigned(true); REQUIRE(x.GetImageFillValue() == INT8_MIN); REQUIRE(x.GetOverflow() == INT8_MAX); REQUIRE(x.GetUnderflow() == INT8_MIN); x.BitDepthImage(8).PixelSigned(false); REQUIRE(x.GetImageFillValue() == UINT8_MAX); REQUIRE(x.GetOverflow() == UINT8_MAX); REQUIRE(x.GetUnderflow() == -1); } TEST_CASE("DiffractionExperiment_Appendix","") { DiffractionExperiment x; StartMessage message; x.FillMessage(message); REQUIRE(message.user_data == nlohmann::json()); REQUIRE(x.GetImageAppendix() == nlohmann::json()); REQUIRE(x.GetHeaderAppendix() == nlohmann::json()); x.ImageAppendix("ImageAppendix").HeaderAppendix("HeaderAppendix"); x.FillMessage(message); REQUIRE(x.GetImageAppendix() == "ImageAppendix"); REQUIRE(x.GetHeaderAppendix() == "HeaderAppendix"); REQUIRE(message.user_data == "HeaderAppendix"); } TEST_CASE("DiffractionExperiment_OmegaRotationAxis","[DiffractionExperiment]") { DiffractionExperiment x; x.RotationAxis(Coord{-1, 0, 0}); REQUIRE(x.GetRotationAxis().x == -1); REQUIRE(x.GetRotationAxis().y == 0); REQUIRE_THROWS(x.RotationAxis(Coord{0,0,0})); } TEST_CASE("DiffractionExperiment_OmegaStep","[DiffractionExperiment]") { DiffractionExperiment x; StartMessage msg; x.FillMessage(msg); REQUIRE(!x.GetGoniometer()); REQUIRE(!msg.goniometer); DatasetSettings d; d.Goniometer(GoniometerAxis{ .name = "omega", .increment = 75.0f, .start = 20.0f }); x.ImportDatasetSettings(d); x.FillMessage(msg); REQUIRE(x.GetGoniometer().has_value()); REQUIRE(msg.goniometer); REQUIRE(msg.goniometer->name == "omega"); REQUIRE(msg.goniometer->increment == 75.0f); REQUIRE(msg.goniometer->start == 20.0f); } TEST_CASE("DiffractionExperiment_ConversionOnFPGA","[DiffractionExperiment]") { DiffractionExperiment x; x.Mode(DetectorMode::Conversion); REQUIRE(x.IsJungfrauConvPhotonCnt()); // conversion on FPGA must be default true! x.Mode(DetectorMode::Raw); REQUIRE(!x.IsJungfrauConvPhotonCnt()); // conversion on FPGA off for raw mode x.Mode(DetectorMode::PedestalG0); REQUIRE(!x.IsJungfrauConvPhotonCnt()); // conversion on FPGA off for pedestal modes x.Mode(DetectorMode::PedestalG1); REQUIRE(!x.IsJungfrauConvPhotonCnt()); // conversion on FPGA off for pedestal modes x.Mode(DetectorMode::PedestalG2); REQUIRE(!x.IsJungfrauConvPhotonCnt()); // conversion on FPGA off for pedestal modes x.Mode(DetectorMode::Conversion).JungfrauConvPhotonCnt(false); REQUIRE(!x.IsJungfrauConvPhotonCnt()); // conversion on FPGA turned explicitly off x.Mode(DetectorMode::Conversion).JungfrauConvPhotonCnt(true); REQUIRE(x.IsJungfrauConvPhotonCnt()); // conversion on FPGA back on } TEST_CASE("DiffractionExperiment_EIGER","[DiffractionExperiment]") { DiffractionExperiment x(DetectorSetup(DetectorGeometry(4), DetectorType::EIGER)); x.Mode(DetectorMode::Conversion); REQUIRE(!x.IsJungfrauConvPhotonCnt()); REQUIRE(!x.IsPixelSigned()); x.ImagesPerTrigger(245).NumTriggers(100); REQUIRE(!x.GetSaveCalibration()); } TEST_CASE("DiffractionExperiment_JungfrauConversionFactor","[DiffractionExperiment]") { DiffractionExperiment x(DetectorSetup(DetectorGeometry(4))); x.Mode(DetectorMode::Conversion).PhotonEnergy_keV(16.0); REQUIRE(!x.GetJungfrauConversionFactor_keV().has_value()); REQUIRE(x.GetPhotonEnergy_keV() == 16.0f); REQUIRE(x.GetPhotonEnergyForConversion_keV() == 16.0f); x.JungfrauConversionFactor_keV(0.25f); REQUIRE(x.GetJungfrauConversionFactor_keV().has_value()); REQUIRE(x.GetJungfrauConversionFactor_keV() == 0.25f); REQUIRE(x.GetPhotonEnergy_keV() == 16.0f); REQUIRE(x.GetPhotonEnergyForConversion_keV() == 0.25f); } TEST_CASE("DiffractionExperiment_SeriesID","[DiffractionExperiment]") { DiffractionExperiment x; REQUIRE(x.GetRunNumber() == 0); x.IncrementRunNumber(); REQUIRE(x.GetRunNumber() == 1); DatasetSettings d; d.RunNumber(25).RunName("run1"); x.ImportDatasetSettings(d); REQUIRE(x.GetRunNumber() == 25); REQUIRE(x.GetRunName() == "run1"); d.RunNumber({}).RunName({}).FilePrefix("file1"); x.ImportDatasetSettings(d); REQUIRE(x.GetRunNumber() == 1); REQUIRE(x.GetRunName() == "1:file1"); } TEST_CASE("DiffractionExperiment_GetDefaultPlotBinning", "[DiffractionExperiment]") { DiffractionExperiment x; x.FrameTime(std::chrono::milliseconds(1)); x.ImagesPerTrigger(5000); CHECK(x.GetDefaultPlotBinning() == 500); // 500 x 1 us = 500 us x.Summation(2).ImagesPerTrigger(2500); CHECK(x.GetDefaultPlotBinning() == 250); // 250 x 2 us = 500 us x.ImagesPerTrigger(2499); CHECK(x.GetDefaultPlotBinning() == 1); x.ImagesPerTrigger(1); CHECK(x.GetDefaultPlotBinning() == 1); } TEST_CASE("DiffractionExperiment_ImportDataset_TooManyFrames", "[DiffractionExperiment]") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36, true)); x.ImagesPerTrigger(345).NumTriggers(17); DatasetSettings dataset; dataset.ImagesPerTrigger(100000).NumTriggers(100000); REQUIRE_THROWS(x.ImportDatasetSettings(dataset)); REQUIRE(x.GetImageNum() == 345 * 17); } TEST_CASE("DiffractionExperiment_AutoSummation", "[DiffractionExperiment]") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36, true)); x.Summation(4).AutoSummation(true); x.Mode(DetectorMode::Conversion).StorageCells(1); x.AutoSummation(true); REQUIRE(x.GetSummation() == 4); x.Mode(DetectorMode::Raw).StorageCells(1); x.AutoSummation(true); REQUIRE(x.GetSummation() == 4); x.Mode(DetectorMode::PedestalG0).StorageCells(1); x.AutoSummation(true); REQUIRE(x.GetSummation() == 1); x.Mode(DetectorMode::Conversion).StorageCells(2); x.AutoSummation(true); REQUIRE(x.GetSummation() == 1); x.Mode(DetectorMode::Conversion).StorageCells(1); x.AutoSummation(false); REQUIRE(x.GetSummation() == 1); x.Mode(DetectorMode::Raw).StorageCells(1); x.AutoSummation(false); REQUIRE(x.GetSummation() == 1); } TEST_CASE("DiffractionExperiment_ExportROIMask", "[DiffractionExperiment]") { DiffractionExperiment x(DetectorGeometry(8, 2, 8, 36, true)); x.Mode(DetectorMode::Conversion); x.ROI().SetROIBox({ ROIBox("roi0", 800 , 800, 0, 4), ROIBox("roi1", 0 , 1, 2162, 2163) }); CHECK(x.ROI().GetROIMap()[800] == 0); CHECK(x.ROI().GetROIMap()[801] == UINT16_MAX); CHECK(x.ROI().GetROIMap()[2162 * x.GetXPixelsNum() + 1] == 1); std::vector tmp(RAW_MODULE_SIZE, 899); x.ExportROIMap(tmp.data(), 0); CHECK(tmp[0] == 1); CHECK(tmp[1] == 1); CHECK(tmp[2] == UINT16_MAX); CHECK(tmp[RAW_MODULE_SIZE-1] == UINT16_MAX); x.ExportROIMap(tmp.data(), 6); CHECK(tmp[0] == UINT16_MAX); CHECK(tmp[511 * RAW_MODULE_COLS + 800-6] == 0); CHECK(tmp[509 * RAW_MODULE_COLS + 800-6] == 0); CHECK(tmp[507 * RAW_MODULE_COLS + 800-6] == 0); CHECK(tmp[506 * RAW_MODULE_COLS + 800-6] == UINT16_MAX); x.ExportROIMap(tmp.data(), 3); size_t diff = 0; for (int i = 0; i < RAW_MODULE_SIZE; i++) { if (tmp[i] != UINT16_MAX) diff++; } CHECK(diff == 0); }