// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "DetectorSettings.h" #include "JFJochException.h" #include "Definitions.h" #define check_max(param, val, max) if ((val) > (max)) throw JFJochException(JFJochExceptionCategory::InputParameterAboveMax, param) #define check_min(param, val, min) if ((val) < (min)) throw JFJochException(JFJochExceptionCategory::InputParameterBelowMin, param) DetectorSettings &DetectorSettings::InternalGeneratorEnable(bool input) { internal_fpga_packet_generator = input; return *this; } DetectorSettings &DetectorSettings::InternalGeneratorImages(int64_t input) { check_min("Internal packet generator images", input, 1); check_max("Internal packet generator images", input, 64); internal_fpga_packet_generator_images = input; return *this; } DetectorSettings &DetectorSettings::StorageCells(int64_t input) { check_min("Storage cell number", input, 1); check_max("Storage cell number", input, 16); storage_cells = input; return *this; } DetectorSettings &DetectorSettings::StorageCellStart(int64_t input) { check_min("Start storage cell", input, 0); check_max("Start storage cell", input, 15); storage_cell_start = input; return *this; } DetectorSettings &DetectorSettings::StorageCellDelay(const std::chrono::nanoseconds &input) { check_min("Storage cell delay [ns]", input.count(), MIN_STORAGE_CELL_DELAY_IN_NS); storage_cell_delay = input; return *this; } DetectorSettings &DetectorSettings::DetectorDelay(const std::chrono::nanoseconds &input) { check_min("Detector delay (us)", input.count(), 0); detector_delay = input; return *this; } DetectorSettings &DetectorSettings::PedestalG0Frames(int64_t input) { check_min("Pedestal G0 frames", input, 0); pedestal_g0_frames = input; return *this; } DetectorSettings &DetectorSettings::PedestalG1Frames(int64_t input) { check_min("Pedestal G1 frames", input, 0); pedestal_g1_frames = input; return *this; } DetectorSettings &DetectorSettings::PedestalG2Frames(int64_t input) { check_min("Pedestal G2 frames", input, 0); pedestal_g2_frames = input; return *this; } DetectorSettings &DetectorSettings::UseGainHG0(bool input) { use_gain_hg0 = input; return *this; } DetectorSettings &DetectorSettings::FixGainG1(bool input) { fix_gain_g1 = input; return *this; } DetectorSettings &DetectorSettings::FrameTime(const std::chrono::microseconds &input) { frame_time = input; count_time = {}; return *this; } DetectorSettings &DetectorSettings::FrameTime(const std::chrono::microseconds &in_frame_time, const std::chrono::microseconds &in_count_time) { check_min("Count time (us)", in_count_time.count(), MIN_COUNT_TIME_IN_US); frame_time = in_frame_time; count_time = in_count_time; return *this; } bool DetectorSettings::IsInternalGeneratorEnable() const { return internal_fpga_packet_generator; } int64_t DetectorSettings::GetInternalGeneratorImages() const { return internal_fpga_packet_generator_images; } int64_t DetectorSettings::GetStorageCells() const { return storage_cells; } int64_t DetectorSettings::GetStorageCellStart() const { return storage_cell_start; } std::chrono::nanoseconds DetectorSettings::GetStorageCellDelay() const { return storage_cell_delay; } std::chrono::nanoseconds DetectorSettings::GetDetectorDelay() const { return detector_delay; } int64_t DetectorSettings::GetPedestalG0Frames() const { return pedestal_g0_frames; } int64_t DetectorSettings::GetPedestalG1Frames() const { return pedestal_g1_frames; } int64_t DetectorSettings::GetPedestalG2Frames() const { return pedestal_g2_frames; } bool DetectorSettings::IsUseGainHG0() const { return use_gain_hg0; } bool DetectorSettings::IsFixGainG1() const { return fix_gain_g1; } std::chrono::microseconds DetectorSettings::GetFrameTime() const { return frame_time; } std::optional DetectorSettings::GetCountTime() const { return count_time; } DetectorSettings &DetectorSettings::FrameTime(const std::chrono::microseconds &input, const std::optional &in_count_time) { if (!in_count_time.has_value() || (in_count_time.value().count() == 0)) return this->FrameTime(input); else return this->FrameTime(input, in_count_time.value()); } uint32_t DetectorSettings::GetPedestalMinImageCount() const { return pedestal_min_image_count; } DetectorSettings &DetectorSettings::PedestalMinImageCount(uint32_t input) { check_min("Pedestal window size", input, 32); pedestal_min_image_count = input; return *this; } std::optional DetectorSettings::GetEigerThreshold_keV() const { return eiger_threshold_keV; } DetectorSettings &DetectorSettings::EigerThreshold_keV(const std::optional &input) { check_min("EIGER Threshold (keV)", input, 1.0); check_max("EIGER Threshold (keV)", input, 100.0); eiger_threshold_keV = input; return *this; } DetectorSettings &DetectorSettings::Timing(DetectorTiming input) { switch(input) { case DetectorTiming::Auto: case DetectorTiming::Trigger: case DetectorTiming::Burst: case DetectorTiming::Gated: timing = input; break; default: // Handle invalid input, e.g., throw an exception, log an error, set a default value, etc. throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Invalid DetectorTiming value"); } return *this; } DetectorTiming DetectorSettings::GetTiming() const { return timing; } std::chrono::microseconds DetectorSettings::GetFrameTimePedestalG1G2() const { return frame_time_pedestalG1G2; } std::optional DetectorSettings::GetEigerBitDepth() const { return eiger_bitwidth; } DetectorSettings &DetectorSettings::EigerBitDepth(const std::optional &input) { if (input.has_value() && !((input.value() == 8) || (input.value() == 16) || (input.value() == 32))) { throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "EIGER bitwidth can be only 8, 16 or 32"); } eiger_bitwidth = input; return *this; } bool DetectorSettings::NeedsJUNGFRAURecalibration(const DetectorSettings &other) const { return this->fix_gain_g1 != other.fix_gain_g1 || this->use_gain_hg0 != other.use_gain_hg0 || this->frame_time != other.frame_time || this->count_time != other.count_time || this->pedestal_g0_frames != other.pedestal_g0_frames || this->pedestal_g1_frames != other.pedestal_g1_frames || this->pedestal_g2_frames != other.pedestal_g2_frames || this->pedestal_min_image_count != other.pedestal_min_image_count || this->storage_cells != other.storage_cells || this->storage_cell_start != other.storage_cell_start || this->storage_cell_delay != other.storage_cell_delay || this->internal_fpga_packet_generator != other.internal_fpga_packet_generator; }