// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #ifndef JUNGFRAUJOCH_JFJOCHSTATEMACHINE_H #define JUNGFRAUJOCH_JFJOCHSTATEMACHINE_H #include #include #include #include #include "../common/DiffractionExperiment.h" #include "../jungfrau/JFCalibration.h" #include "../common/Logger.h" #include "JFJochServices.h" #include "../common/ROIMap.h" enum class JFJochState {Inactive, Idle, Measuring, Error, Busy, Pedestal}; struct BrokerStatus { JFJochState broker_state; std::optional progress; }; struct DetectorListElement { std::string description; std::string serial_number; std::string base_ipv4_addr; int64_t udp_interface_count; int64_t nmodules; int64_t width; int64_t height; }; struct DetectorList { std::vector detector; int64_t current_id; }; struct MeasurementStatistics { std::string file_prefix; std::string experiment_group; int64_t run_number; int64_t images_expected; int64_t images_collected; int64_t images_sent; int64_t images_skipped; int64_t max_image_number_sent; std::optional collection_efficiency; std::optional compression_ratio; bool cancelled; int64_t max_receive_delay; std::optional indexing_rate; int64_t detector_width; int64_t detector_height; int64_t detector_pixel_depth; std::optional bkg_estimate; std::optional> beam_center_drift_pxl; std::string unit_cell; }; class JFJochStateMachine { Logger &logger; JFJochServices &services; mutable std::mutex experiment_detector_settings_mutex; DiffractionExperiment experiment; mutable std::mutex m; std::condition_variable c; // mutex m is protecting: volatile JFJochState state = JFJochState::Inactive; volatile bool cancel_sequence = false; std::unique_ptr calibration; PixelMask pixel_mask; std::vector gain_calibration; std::vector detector_setup; int64_t current_detector_setup; std::future measurement; mutable std::mutex calibration_statistics_mutex; std::vector calibration_statistics; mutable std::mutex data_processing_settings_mutex; SpotFindingSettings data_processing_settings; mutable std::mutex pixel_mask_statistics_mutex; PixelMaskStatistics pixel_mask_statistics; void UpdatePixelMaskStatistics(const PixelMaskStatistics &input); // Private functions assume that lock m is acquired void MeasurementThread(); void PedestalThread(std::unique_lock ul); void InitializeThread(std::unique_lock ul); bool ImportPedestalG1G2(const JFJochReceiverOutput &receiver_output, size_t gain_level, size_t storage_cell = 0); bool ImportPedestalG0(const JFJochReceiverOutput &receiver_output); bool IsRunning() const; // Is state Busy/Pedestal/Measure std::optional CheckError(); void TakePedestalInternalAll(std::unique_lock &ul); void TakePedestalInternalG0(std::unique_lock &ul); void TakePedestalInternalG1(std::unique_lock &ul, int32_t storage_cell = 0); void TakePedestalInternalG2(std::unique_lock &ul, int32_t storage_cell = 0); void ImportDetectorSettings(const DetectorSettings& input); public: JFJochStateMachine(JFJochServices &in_services, Logger &logger); ~JFJochStateMachine(); void Initialize(); void Pedestal(); void Deactivate(); void Start(const DatasetSettings& settings); JFJochState WaitTillMeasurementDone(); JFJochState WaitTillMeasurementDone(std::chrono::milliseconds timeout); void Trigger(); void Cancel(); void SetCalibrationStatistics(const std::vector &input); DetectorSettings GetDetectorSettings() const; void LoadDetectorSettings(const DetectorSettings& settings); InstrumentMetadata GetInstrumentMetadata() const; void LoadInstrumentMetadata(const InstrumentMetadata& settings); ImageFormatSettings GetImageFormatSettings() const; void LoadImageFormatSettings(const ImageFormatSettings& settings); void RawImageFormatSettings(); void ConvImageFormatSettings(); // return by value to ensure thread safety std::optional GetMeasurementStatistics() const; std::vector GetCalibrationStatistics() const; BrokerStatus GetStatus() const; MultiLinePlot GetPlots(const PlotRequest &request) const; void SetSpotFindingSettings(const SpotFindingSettings& settings); SpotFindingSettings GetSpotFindingSettings() const; JFJochState GetState() const; void AddDetectorSetup(const DetectorSetup& setup); DetectorList GetDetectorsList() const; void SelectDetector(int64_t id); std::optional GetDetectorStatus() const; void SetRadialIntegrationSettings(const AzimuthalIntegrationSettings& settings); AzimuthalIntegrationSettings GetRadialIntegrationSettings() const; std::string GetPreviewJPEG(const PreviewJPEGSettings& settings) const; std::string GetPreviewTIFF(bool calibration) const; std::string GetPedestalTIFF(size_t gain_level, size_t sc) const; void LoadInternalGeneratorImage(const void *data, size_t size, uint64_t image_number); void LoadInternalGeneratorImageTIFF(const std::string &s, uint64_t image_number); // Not thread safe - only for configuration in serial context DiffractionExperiment& NotThreadSafe_Experiment(); // Function for debug only - UNSAFE for real operation void DebugOnly_SetState(JFJochState state); void SetBoxROI(const std::vector& input); void SetCircleROI(const std::vector& input); std::vector GetBoxROI() const; std::vector GetCircleROI() const; std::vector GetXFELPulseID() const; std::vector GetXFELEventCode() const; std::string GetFullPixelMaskTIFF() const; std::string GetUserPixelMaskTIFF() const; std::vector GetFullPixelMask() const; std::vector GetUserPixelMask() const; void SetUserPixelMask(const std::vector &v); std::vector GetDeviceStatus() const; void SetPreviewSocketSettings(const ZMQPreviewSettings &input); ZMQPreviewSettings GetPreviewSocketSettings(); void SetMetadataSocketSettings(const ZMQMetadataSettings &input); ZMQMetadataSettings GetMetadataSocketSettings(); PixelMaskStatistics GetPixelMaskStatistics() const; }; #endif //JUNGFRAUJOCH_JFJOCHSTATEMACHINE_H