// Copyright (2019-2023) Paul Scherrer Institute #include #include "../broker/JFJochStateMachine.h" using namespace std::literals::chrono_literals; TEST_CASE("JFJochStateMachine_States") { Logger logger("JFJochStateMachine_States"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.AddDetectorSetup(DetectorGeometry(4)); DatasetSettings setup; setup.ntrigger = 1; setup.detector_distance_mm = 100; setup.file_prefix = "integration_test"; setup.images_per_trigger = 5; setup.photon_energy_keV = 12.4; setup.data_file_count = 5; JFJochState state; REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Inactive); REQUIRE_THROWS(state_machine.Start(setup)); REQUIRE_THROWS(state_machine.Pedestal()); REQUIRE_NOTHROW(state_machine.Initialize()); REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Idle); REQUIRE_NOTHROW(state_machine.Deactivate()); REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Inactive); } TEST_CASE("JFJochStateMachine_State_Pedestal") { Logger logger("JFJochStateMachine_State_Pedestal"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.AddDetectorSetup(DetectorGeometry(4)); DatasetSettings setup; setup.ntrigger = 1; setup.detector_distance_mm = 100; setup.file_prefix = "integration_test"; setup.images_per_trigger = 5; setup.photon_energy_keV = 12.4; setup.data_file_count = 5; state_machine.DebugOnly_SetState(JFJochState::Pedestal); JFJochState state; REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Pedestal); REQUIRE_THROWS(state_machine.Start(setup)); REQUIRE_THROWS(state_machine.Pedestal()); REQUIRE_THROWS(state_machine.Initialize()); REQUIRE(state_machine.WaitTillMeasurementDone(std::chrono::milliseconds(1)) == JFJochState::Pedestal); DetectorSettings settings{}; settings.frame_time_us = 500; settings.storage_cell_count = 16; REQUIRE_THROWS(state_machine.LoadDetectorSettings(settings)); } TEST_CASE("JFJochStateMachine_State_Measure") { Logger logger("JFJochStateMachine_State_Measure"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.AddDetectorSetup(DetectorGeometry(4)); DatasetSettings setup; setup.ntrigger = 1; setup.detector_distance_mm = 100; setup.file_prefix = "integration_test"; setup.images_per_trigger = 5; setup.photon_energy_keV = 12.4; setup.data_file_count = 5; state_machine.DebugOnly_SetState(JFJochState::Measuring); JFJochState state; REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Measuring); REQUIRE_THROWS(state_machine.Start(setup)); REQUIRE_THROWS(state_machine.Pedestal()); REQUIRE_THROWS(state_machine.Initialize()); REQUIRE(state_machine.WaitTillMeasurementDone(std::chrono::milliseconds(1)) == JFJochState::Measuring); DetectorSettings settings{}; settings.frame_time_us = 500; settings.storage_cell_count = 16; REQUIRE_THROWS(state_machine.LoadDetectorSettings(settings)); } TEST_CASE("JFJochStateMachine_State_Error") { Logger logger("JFJochStateMachine_State_Error"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.AddDetectorSetup(DetectorGeometry(4)); DatasetSettings setup; setup.ntrigger = 1; setup.detector_distance_mm = 100; setup.file_prefix = "integration_test"; setup.images_per_trigger = 5; setup.photon_energy_keV = 12.4; setup.data_file_count = 5; state_machine.DebugOnly_SetState(JFJochState::Error); JFJochState state; REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Error); REQUIRE_THROWS(state_machine.Start(setup)); REQUIRE_THROWS(state_machine.Pedestal()); REQUIRE(state_machine.WaitTillMeasurementDone(std::chrono::milliseconds(1)) == JFJochState::Error); DetectorSettings settings{}; settings.frame_time_us = 500; settings.storage_cell_count = 16; REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE_NOTHROW(state_machine.Initialize()); REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Idle); } TEST_CASE("JFJochStateMachine_Setup") { Logger logger("JJFJochStateMachine_Setup"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); DetectorSettings settings{}, settings_save{}; settings.pedestal_g1_frames = -15; settings.pedestal_g0_frames = 2378; REQUIRE_THROWS(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG0Frames() != 2378); settings.pedestal_g2_frames = 2800; settings.pedestal_g1_frames = 3000; settings.pedestal_g0_frames = 2378; settings.storage_cell_count = 16; settings.frame_time_us = 600; settings.count_time_us = 247; REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG0Frames() == 2378); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG1Frames() == 3000); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG2Frames() == 2800); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellNumber() == 16); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameTime() == std::chrono::microseconds(600)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameCountTime() == std::chrono::microseconds(247)); REQUIRE_NOTHROW(settings_save = state_machine.GetDetectorSettings()); REQUIRE(settings_save.storage_cell_count == 16); REQUIRE(settings_save.count_time_us == 247); } TEST_CASE("JFJochStateMachine_NoDetectorSetup") { Logger logger("JFJochStateMachine_NoDetectorSetup"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); REQUIRE_THROWS(state_machine.Initialize()); REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); } TEST_CASE("JFJochStateMachine_AddDetectorSetup") { Logger logger("JFJochStateMachine_AddDetectorSetup"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); DetectorSetup setup = DetectorGeometry(4); state_machine.AddDetectorSetup(setup); REQUIRE_NOTHROW(state_machine.Initialize()); REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); } TEST_CASE("JFJochStateMachine_AddDetectorSetup_Gain") { Logger logger("JFJochStateMachine_AddDetectorSetup_Gain"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); DetectorSetup setup = DetectorGeometry(4); setup.LoadGain({"../../tests/test_data/gainMaps_M049.bin", "../../tests/test_data/gainMaps_M049.bin", "../../tests/test_data/gainMaps_M049.bin", "../../tests/test_data/gainMaps_M049.bin"}); state_machine.AddDetectorSetup(setup); REQUIRE_NOTHROW(state_machine.Initialize()); REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); } TEST_CASE("JFJochStateMachine_StorageCells") { Logger logger("JFJochBrokerService_StorageCells"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.AddDetectorSetup(DetectorGeometry(4)); DetectorSettings settings{}; settings.frame_time_us = 500; settings.storage_cell_count = 16; REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellNumber() == 16); REQUIRE_NOTHROW(state_machine.Initialize()); REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); } TEST_CASE("JFJochStateMachine_AddDetectorSetup_Multiple") { Logger logger("JFJochBrokerService_StorageCells"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); REQUIRE_NOTHROW(state_machine.AddDetectorSetup(DetectorSetup(DetectorGeometry(4), "Det1", {"mx1", "mx2", "mx3", "mx4"}))); REQUIRE_NOTHROW(state_machine.AddDetectorSetup(DetectorSetup(DetectorGeometry(2), "Det2", {"mx1", "mx2"}))); REQUIRE_NOTHROW(state_machine.AddDetectorSetup(DetectorSetup(DetectorGeometry(1), "Det3", {"mx1"}))); auto dl = state_machine.GetDetectorsList(); REQUIRE(dl.detector.size() == 3); REQUIRE(dl.detector[0].description == "Det1"); REQUIRE(dl.detector[0].nmodules == 4); REQUIRE(dl.detector[1].description == "Det2"); REQUIRE(dl.detector[1].nmodules == 2); REQUIRE(dl.detector[2].description == "Det3"); REQUIRE(dl.detector[2].nmodules == 1); REQUIRE_NOTHROW(state_machine.Initialize()); REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); REQUIRE(state_machine.NotThreadSafe_Experiment().GetModulesNum() == 4); REQUIRE(state_machine.GetState() == JFJochState::Idle); REQUIRE_THROWS(state_machine.SelectDetector(7)); REQUIRE(state_machine.GetState() == JFJochState::Idle); REQUIRE_NOTHROW(state_machine.SelectDetector(2)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetModulesNum() == 1); REQUIRE(state_machine.NotThreadSafe_Experiment().GetDetectorDescription() == "Det3"); REQUIRE(state_machine.GetState() == JFJochState::Inactive); } TEST_CASE("JFJochStateMachine_LoadDatasetSettings", "[DiffractionExperiment]") { DiffractionExperiment x; x.ImagesPerTrigger(567).BeamY_pxl(324).Compression(CompressionAlgorithm::BSHUF_ZSTD); DatasetSettings settings{}; settings.images_per_trigger = 234; settings.ntrigger = 56; settings.beam_x_pxl = 23.4; settings.beam_y_pxl = 123.4; settings.photon_energy_keV = WVL_1A_IN_KEV; settings.detector_distance_mm = 57.6; settings.data_file_count = 5; settings.space_group_number = 45; settings.sample_name = "lyso1"; settings.summation = 36; settings.fpga_pixel_output = FPGAPixelOutput::Int16; settings.compression = CompressionAlgorithm::BSHUF_LZ4; REQUIRE_NOTHROW(LoadDatasetSettings(x,settings)); REQUIRE(x.GetImageNumPerTrigger() == 234); REQUIRE(x.GetBeamX_pxl() == Approx(23.4)); REQUIRE(x.GetBeamY_pxl() == Approx(123.4)); REQUIRE(x.GetSpaceGroupNumber() == 45); REQUIRE(x.GetCompressionAlgorithm() == CompressionAlgorithm::BSHUF_LZ4); REQUIRE(x.GetSampleName() == "lyso1"); REQUIRE(x.GetDataFileCount() == 5); REQUIRE(x.GetDetectorDistance_mm() == Approx(57.6)); REQUIRE(x.GetSummation() == 36); REQUIRE(x.GetFPGAOutputMode() == FPGAPixelOutput::Int16); } TEST_CASE("JFJochStateMachine_LoadDatasetSettings_Invalid", "[DiffractionExperiment]") { DiffractionExperiment x; x.ImagesPerTrigger(567).BeamY_pxl(324).Compression(CompressionAlgorithm::BSHUF_ZSTD); DatasetSettings settings{}; settings.images_per_trigger = -1; settings.ntrigger = 56; settings.beam_x_pxl = 23.4; settings.beam_y_pxl = 123.4; settings.photon_energy_keV = WVL_1A_IN_KEV; settings.detector_distance_mm = 57.6; settings.data_file_count = 5; settings.space_group_number = 45; settings.sample_name = "lyso1"; REQUIRE_THROWS(LoadDatasetSettings(x, settings)); REQUIRE(x.GetImageNumPerTrigger() == 567); REQUIRE(x.GetBeamY_pxl() == Approx(324)); REQUIRE(x.GetSpaceGroupNumber() == 0); } TEST_CASE("JFJochStateMachine_SetDetectorSettings", "[DiffractionExperiment]") { Logger logger("JFJochStateMachine_SetDetectorSettings"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.NotThreadSafe_Experiment().PedestalG0Frames(456).PedestalG1Frames(1234).PedestalG2Frames(123).StorageCellDelay(2500ns); DetectorSettings settings{}; settings.frame_time_us = 600; settings.count_time_us = 400; settings.storage_cell_count = 8; settings.use_internal_packet_generator = true; settings.collect_raw_data = true; settings.pedestal_g0_frames = 5000; settings.pedestal_g1_frames = 100; settings.pedestal_g2_frames = 150; REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameTime().count() == 600); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameCountTime().count() == 400); REQUIRE(state_machine.NotThreadSafe_Experiment().IsUsingInternalPacketGen()); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellNumber() == 8); REQUIRE(state_machine.NotThreadSafe_Experiment().GetDetectorMode() == DetectorMode::Raw); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG0Frames() == 5000); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG1Frames() == 100); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG2Frames() == 150); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellDelay().count() == 2500); } TEST_CASE("JFJochStateMachine_SetDetectorSettings_StorageCellDelay", "[DiffractionExperiment]") { Logger logger("JFJochStateMachine_SetDetectorSettings_StorageCellDelay"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.NotThreadSafe_Experiment().PedestalG0Frames(456).PedestalG1Frames(1234).PedestalG2Frames(123).StorageCellDelay(5000ns); DetectorSettings settings{}; settings.frame_time_us = 600; settings.count_time_us = 400; settings.storage_cell_count = 8; settings.use_internal_packet_generator = true; settings.collect_raw_data = true; settings.storage_cell_delay_ns = 7000; REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellDelay().count() == 7000); } TEST_CASE("JFJochStateMachine_SetDetectorSettings_invalid", "[DiffractionExperiment]") { Logger logger("JFJochStateMachine_SetDetectorSettings_invalid"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.NotThreadSafe_Experiment().PedestalG0Frames(456).PedestalG1Frames(1234).PedestalG2Frames(123) .FrameTime(525us).Mode(DetectorMode::Conversion); DetectorSettings settings{}; settings.frame_time_us = 600; settings.count_time_us = 800; settings.storage_cell_count = 16; settings.use_internal_packet_generator = true; settings.collect_raw_data = true; settings.pedestal_g0_frames = 5000; settings.pedestal_g1_frames = 100; settings.pedestal_g2_frames = 150; REQUIRE_THROWS(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameTime().count() == 525); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameCountTime().count() == 525 - READOUT_TIME_IN_US); REQUIRE(!state_machine.NotThreadSafe_Experiment().IsUsingInternalPacketGen()); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellNumber() == 1); REQUIRE(state_machine.NotThreadSafe_Experiment().GetDetectorMode() == DetectorMode::Conversion); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG0Frames() == 456); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG1Frames() == 1234); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG2Frames() == 123); } TEST_CASE("JFJochStateMachine_SetDetectorSettings_inferred", "[DiffractionExperiment]") { Logger logger("JFJochStateMachine_SetDetectorSettings_inferred"); JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); state_machine.NotThreadSafe_Experiment().PedestalG0Frames(456).PedestalG1Frames(1234).PedestalG2Frames(123); DetectorSettings settings{}; settings.frame_time_us = 600; settings.storage_cell_count = 1; REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameTime().count() == 600); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameCountTime().count() == 600 - READOUT_TIME_IN_US); REQUIRE(!state_machine.NotThreadSafe_Experiment().IsUsingInternalPacketGen()); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellNumber() == 1); REQUIRE(state_machine.NotThreadSafe_Experiment().GetDetectorMode() == DetectorMode::Conversion); }