Files
Jungfraujoch/tests/DiffractionExperimentTest.cpp
2024-03-31 23:08:19 +02:00

885 lines
30 KiB
C++

// Copyright (2019-2023) Paul Scherrer Institute
#define CATCH_CONFIG_MAIN
#include <catch2/catch.hpp>
#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_Raw","[DiffractionExperiment]") {
DiffractionExperiment x;
for (auto i: {DetectorMode::Raw, DetectorMode::PedestalG0, DetectorMode::PedestalG1, DetectorMode::PedestalG2}) {
x.Mode(i).Compression(CompressionAlgorithm::BSHUF_ZSTD);
REQUIRE(x.GetCompressionAlgorithm() == CompressionAlgorithm::NO_COMPRESSION);
}
}
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("DiffractionExperiment_IPv4Address","[DiffractionExperiment]") {
DiffractionExperiment x(DetectorGeometry(12));
x.Mode(DetectorMode::Conversion);
uint32_t ndatastreams = 3;
x.DataStreams(ndatastreams);
REQUIRE_NOTHROW(x.IPv4BaseAddr("64.1.124.1"));
REQUIRE(x.GetSrcIPv4Address(0, 0) == IPv4AddressFromStr("64.1.124.1"));
REQUIRE(x.GetSrcIPv4Address(0, 6) == IPv4AddressFromStr("64.1.124.7"));
REQUIRE(x.GetSrcIPv4Address(2, 6) == IPv4AddressFromStr("64.1.124.23"));
}
TEST_CASE("DiffractionExperiment_IPv4Address_1_UDP_Interface","[DiffractionExperiment]") {
DetectorSetup detector(DetectorGeometry(4));
detector.UDPInterfaceCount(1);
DiffractionExperiment x(detector);
x.Mode(DetectorMode::Conversion);
x.DataStreams(2);
REQUIRE_NOTHROW(x.IPv4BaseAddr("64.1.124.1"));
REQUIRE(x.GetSrcIPv4Address(0, 0) == IPv4AddressFromStr("64.1.124.1"));
REQUIRE(x.GetSrcIPv4Address(0, 1) == IPv4AddressFromStr("64.1.124.2"));
REQUIRE(x.GetSrcIPv4Address(1, 1) == IPv4AddressFromStr("64.1.124.4"));
REQUIRE_THROWS(x.GetSrcIPv4Address(0, 2));
REQUIRE_THROWS(x.GetSrcIPv4Address(2, 0));
}
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() == Approx(12.39854 / 6.0));
x.DetectorDistance_mm(30.0).BeamX_pxl(1200).BeamY_pxl(1000).FrameTime(900us);
REQUIRE(x.GetBeamX_pxl() == Approx(1200));
REQUIRE(x.GetBeamY_pxl() == Approx(1000));
REQUIRE(x.GetDetectorDistance_mm() == Approx(30.0));
REQUIRE_THROWS(x.PedestalG0Frames(-1));
REQUIRE_THROWS(x.PedestalG1Frames(-1));
REQUIRE_THROWS(x.PedestalG2Frames(-1));
}
TEST_CASE("DiffractionExperiment_Preview", "[DiffractionExperiment]") {
DiffractionExperiment x;
std::map<size_t, uint32_t> map, map2;
x.ImagesPerTrigger(10000).FrameTime(1ms);
x.PreviewPeriod(0ms);
REQUIRE(x.GetPreviewPeriod().count() == 0);
x.PreviewPeriod(1s);
REQUIRE(x.GetPreviewPeriod() == std::chrono::milliseconds(1000));
REQUIRE_THROWS(x.PreviewPeriod(-5ms));
x.Mode(DetectorMode::Raw);
REQUIRE(x.GetPreviewPeriod().count() == 0);
x.Mode(DetectorMode::PedestalG0);
REQUIRE(x.GetPreviewPeriod().count() == 0);
x.Mode(DetectorMode::PedestalG1);
REQUIRE(x.GetPreviewPeriod().count() == 0);
x.Mode(DetectorMode::PedestalG2);
REQUIRE(x.GetPreviewPeriod().count() == 0);
}
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");
}
//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() == Approx(4));
REQUIRE_THROWS(x.LowResForAzimInt_A(0));
REQUIRE_THROWS(x.LowResForAzimInt_A(-1));
x.LowResForAzimInt_A(5.0);
REQUIRE(x.GetLowQForAzimInt_recipA() == Approx(2 * M_PI / 5.0));
DiffractionExperiment y(x);
REQUIRE(y.GetLowQForAzimInt_recipA() == 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() == Approx(8.0));
REQUIRE_THROWS(x.HighResForAzimInt_A(0));
REQUIRE_THROWS(x.HighResForAzimInt_A(-1));
x.HighResForAzimInt_A(3.0);
REQUIRE(x.GetHighQForAzimInt_recipA() == Approx(2 * M_PI / 3.0));
DiffractionExperiment y(x);
REQUIRE(y.GetHighQForAzimInt_recipA() == 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() == Approx(0.456));
DiffractionExperiment y(x);
REQUIRE(y.GetQSpacingForAzimInt_recipA() == 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.GetImageNumPerTrigger() == 5);
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.GetImageNumPerTrigger() == x.GetStorageCellNumber());
REQUIRE(x.GetFrameNumPerTrigger() == x.GetStorageCellNumber());
REQUIRE(x.GetImageNum() == x.GetStorageCellNumber() * num_triggers);
REQUIRE(x.GetFrameNum() == x.GetStorageCellNumber() * num_triggers);
x.UseInternalPacketGenerator(true);
REQUIRE(x.GetImageNumPerTrigger() == x.GetStorageCellNumber());
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() == 1456);
REQUIRE(x.GetFrameNumPerTrigger() == 16);
REQUIRE(x.GetFrameNum() == 1456 * 16);
x.Mode(DetectorMode::PedestalG1);
REQUIRE(x.GetStorageCellNumber() == 2);
REQUIRE(x.GetNumTriggers() == 323);
REQUIRE(x.GetFrameNumPerTrigger() == 2);
REQUIRE(x.GetFrameNum() == 323 * 2);
x.StorageCells(8);
x.Mode(DetectorMode::PedestalG2);
REQUIRE(x.GetStorageCellNumber() == 2);
REQUIRE(x.GetNumTriggers() == 456);
REQUIRE(x.GetFrameNumPerTrigger() == 2);
}
TEST_CASE("DiffractionExperiment_PulsedSource","[DiffractionExperiment]") {
DiffractionExperiment x;
REQUIRE(!x.IsPulsedSource()); // default must be off
x.ImagesPerTrigger(50).NumTriggers(100).Mode(DetectorMode::Raw).PedestalG0Frames(1000)
.PedestalG1Frames(200).PedestalG2Frames(100);
REQUIRE(x.GetImageNumPerTrigger() == 50);
x.PulsedSource(true);
REQUIRE(x.GetImageNumPerTrigger() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 1);
x.Summation(10);
REQUIRE(x.GetImageNumPerTrigger() == 1);
REQUIRE(x.GetFrameNumPerTrigger() == 10);
x.Mode(DetectorMode::PedestalG0);
REQUIRE(x.GetImageNumPerTrigger() == 0);
REQUIRE(x.GetFrameNumPerTrigger() == 1);
REQUIRE(x.GetNumTriggers() == 1000);
x.Mode(DetectorMode::PedestalG1);
REQUIRE(x.GetImageNumPerTrigger() == 0);
REQUIRE(x.GetFrameNumPerTrigger() == 1);
REQUIRE(x.GetNumTriggers() == 200);
x.Mode(DetectorMode::PedestalG2);
REQUIRE(x.GetImageNumPerTrigger() == 0);
REQUIRE(x.GetFrameNumPerTrigger() == 1);
REQUIRE(x.GetNumTriggers() == 100);
}
TEST_CASE("DiffractionExperiment_DefaultDataProcessingSettings","[DiffractionExperiment]") {
REQUIRE_NOTHROW(DiffractionExperiment::CheckDataProcessingSettings(
DiffractionExperiment::DefaultDataProcessingSettings()));
}
TEST_CASE("DiffractionExperiment_FPGA_Summation_output","[DiffractionExperiment]") {
DiffractionExperiment x;
REQUIRE_THROWS(x.Summation(0));
REQUIRE_THROWS(x.Summation(-1));
REQUIRE_THROWS(x.Summation(MAX_FPGA_SUMMATION + 1));
x.FPGAOutputMode(FPGAPixelOutput::Auto);
REQUIRE_NOTHROW(x.Summation(1));
REQUIRE(x.IsPixelSigned());
REQUIRE(x.GetPixelDepth() == 2);
REQUIRE(x.GetSummation() == 1);
REQUIRE_NOTHROW(x.Summation(3));
REQUIRE(x.IsPixelSigned());
REQUIRE(x.GetPixelDepth() == 4);
REQUIRE(x.GetSummation() == 3);
x.FPGAOutputMode(FPGAPixelOutput::Int16);
REQUIRE(x.GetPixelDepth() == 2);
REQUIRE(x.IsPixelSigned());
x.FPGAOutputMode(FPGAPixelOutput::Int32);
REQUIRE(x.GetPixelDepth() == 4);
REQUIRE(x.IsPixelSigned());
x.FPGAOutputMode(FPGAPixelOutput::Uint16);
REQUIRE(x.GetPixelDepth() == 2);
REQUIRE(!x.IsPixelSigned());
x.FPGAOutputMode(FPGAPixelOutput::Uint32);
REQUIRE(x.GetPixelDepth() == 4);
REQUIRE(!x.IsPixelSigned());
}
TEST_CASE("DiffractionExperiment_DetectorModuleHostname","[DiffractionExperiment]") {
std::vector<std::string> h = {"mx1", "mx2", "mx3"};
DiffractionExperiment x(DetectorSetup(3, DetectorType::JUNGFRAU, "X", h));
std::vector<AcquisitionDeviceNetConfig> 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<std::string> 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_Appendix","") {
DiffractionExperiment x;
StartMessage message;
x.FillMessage(message);
REQUIRE(message.user_data == "");
REQUIRE(x.GetImageAppendix() == "");
REQUIRE(x.GetHeaderAppendix() == "");
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.DefaultOmegaAxis({0,-1,0});
REQUIRE(x.GetDefaultOmegaAxis().x == 0);
REQUIRE(x.GetDefaultOmegaAxis().y == -1);
x.OmegaAxis();
REQUIRE(x.GetOmegaAxis().x == 0);
REQUIRE(x.GetOmegaAxis().y == -1);
x.OmegaAxis({-1, 0, 0});
REQUIRE(x.GetOmegaAxis().x == -1);
REQUIRE(x.GetOmegaAxis().y == 0);
REQUIRE_THROWS(x.DefaultOmegaAxis({0,0,0}));
REQUIRE_THROWS(x.OmegaAxis({0,0,0}));
}
TEST_CASE("DiffractionExperiment_OmegaStep","[DiffractionExperiment]") {
DiffractionExperiment x;
StartMessage msg;
x.OmegaStep(std::optional<float>());
x.FillMessage(msg);
REQUIRE(!x.GetOmegaStep());
REQUIRE(msg.omega.increment == 0.0f);
x.OmegaStep(0.0);
REQUIRE(!x.GetOmegaStep());
x.FillMessage(msg);
REQUIRE(msg.omega.increment == 0.0f);
x.OmegaStep(1.0);
x.FillMessage(msg);
REQUIRE(x.GetOmegaStep());
REQUIRE(msg.omega.increment == 1.0f);
}
TEST_CASE("DiffractionExperiment_ConversionOnFPGA","[DiffractionExperiment]") {
DiffractionExperiment x;
x.Mode(DetectorMode::Conversion);
REQUIRE(x.IsConversionOnFPGA()); // conversion on FPGA must be default true!
x.Mode(DetectorMode::Raw);
REQUIRE(!x.IsConversionOnFPGA()); // conversion on FPGA off for raw mode
x.Mode(DetectorMode::PedestalG0);
REQUIRE(!x.IsConversionOnFPGA()); // conversion on FPGA off for pedestal modes
x.Mode(DetectorMode::PedestalG1);
REQUIRE(!x.IsConversionOnFPGA()); // conversion on FPGA off for pedestal modes
x.Mode(DetectorMode::PedestalG2);
REQUIRE(!x.IsConversionOnFPGA()); // conversion on FPGA off for pedestal modes
x.Mode(DetectorMode::Conversion).ConversionOnFPGA(false);
REQUIRE(!x.IsConversionOnFPGA()); // conversion on FPGA turned explicitly off
x.Mode(DetectorMode::Conversion).ConversionOnFPGA(true);
REQUIRE(x.IsConversionOnFPGA()); // conversion on FPGA back on
}
TEST_CASE("DiffractionExperiment_EIGER","[DiffractionExperiment]") {
DiffractionExperiment x(DetectorSetup(DetectorGeometry(4), DetectorType::EIGER));
x.Mode(DetectorMode::Conversion).FPGAOutputMode(FPGAPixelOutput::Auto);
REQUIRE(!x.IsConversionOnFPGA());
REQUIRE(!x.IsPixelSigned());
REQUIRE(x.GetPhotonEnergyMultiplier() == 1.0f);
}
TEST_CASE("DiffractionExperiment_PhotonEnergyMultiplayer","[DiffractionExperiment]") {
DiffractionExperiment x(DetectorSetup(DetectorGeometry(4)));
x.Mode(DetectorMode::Conversion).PhotonEnergy_keV(16.0);
REQUIRE(x.GetPhotonEnergyMultiplier() == 1.0f);
REQUIRE(x.GetPhotonEnergy_keV() == 16.0f);
REQUIRE(x.GetPhotonEnergyForConversion_keV() == 16.0f);
x.PhotonEnergyMultiplayer(0.25f);
REQUIRE(x.GetPhotonEnergyMultiplier() == 0.25f);
REQUIRE(x.GetPhotonEnergy_keV() == 16.0f);
REQUIRE(x.GetPhotonEnergyForConversion_keV() == 4.0f);
x.Mode(DetectorMode::Raw);
REQUIRE(x.GetPhotonEnergyMultiplier() == 1.0f);
REQUIRE(x.GetPhotonEnergy_keV() == 16.0f);
REQUIRE(x.GetPhotonEnergyForConversion_keV() == 16.0f);
}
TEST_CASE("DiffractioExperiment_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("DiffractioExperiment_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().GetMask()[800] == 0);
CHECK(x.ROI().GetMask()[801] == UINT16_MAX);
CHECK(x.ROI().GetMask()[2162 * x.GetXPixelsNum() + 1] == 1);
std::vector<uint16_t> tmp(RAW_MODULE_SIZE, 899);
x.ExportROIMask(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.ExportROIMask(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.ExportROIMask(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);
}