Files
Jungfraujoch/broker/JFJochStateMachine.h
2024-06-20 11:26:40 +02:00

204 lines
6.5 KiB
C++

// Copyright (2019-2023) Paul Scherrer Institute
#ifndef JUNGFRAUJOCH_JFJOCHSTATEMACHINE_H
#define JUNGFRAUJOCH_JFJOCHSTATEMACHINE_H
#include <string>
#include <mutex>
#include <future>
#include <optional>
#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<float> progress;
std::optional<float> indexing_rate;
};
struct DetectorListElement {
std::string description;
int64_t nmodules;
int64_t width;
int64_t height;
};
struct DetectorList {
std::vector<DetectorListElement> 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<float> collection_efficiency;
std::optional<float> compression_ratio;
bool cancelled;
int64_t max_receive_delay;
std::optional<float> indexing_rate;
int64_t detector_width;
int64_t detector_height;
int64_t detector_pixel_depth;
std::optional<float> bkg_estimate;
std::optional<std::pair<float, float>> beam_center_drift_pxl;
std::string unit_cell;
};
struct DetectorSettings {
int64_t frame_time_us;
std::optional<int64_t> count_time_us;
int64_t storage_cell_count;
bool use_internal_packet_generator;
bool collect_raw_data;
bool use_gain_hg0;
bool fixed_gain_g1;
std::optional<int64_t> pedestal_g0_frames;
std::optional<int64_t> pedestal_g1_frames;
std::optional<int64_t> pedestal_g2_frames;
std::optional<int64_t> storage_cell_delay_ns;
std::optional<int64_t> detector_delay_ns;
std::optional<int64_t> internal_packet_generator_images;
};
struct RadialIntegrationSettings {
bool solid_angle_correction;
std::optional<float> polarization_factor;
float high_q_recipA;
float low_q_recipA;
float q_spacing;
};
class JFJochStateMachine {
Logger &logger;
JFJochServices &services;
mutable std::mutex m;
std::condition_variable c;
// mutex m is protecting:
DiffractionExperiment experiment;
volatile JFJochState state = JFJochState::Inactive;
volatile bool cancel_sequence = false;
std::unique_ptr<JFCalibration> calibration;
PixelMask pixel_mask;
std::vector<JFModuleGainCalibration> gain_calibration;
std::vector<DetectorSetup> detector_setup;
int64_t current_detector_setup;
std::future<void> measurement;
mutable std::mutex calibration_statistics_mutex;
std::vector<JFCalibrationModuleStatistics> calibration_statistics;
mutable std::mutex last_receiver_output_mutex;
std::optional<MeasurementStatistics> measurement_statistics;
void SetFullMeasurementOutput(const JFJochServicesOutput &output);
void ClearMeasurementStatistics();
void ClearAndSetMeasurementStatistics();
mutable std::mutex data_processing_settings_mutex;
SpotFindingSettings data_processing_settings;
// Private functions assume that lock m is acquired
void MeasurementThread();
void PedestalThread(std::unique_lock<std::mutex> ul);
void InitializeThread(std::unique_lock<std::mutex> 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<std::string> CheckError();
void TakePedestalInternalAll(std::unique_lock<std::mutex> &ul);
void TakePedestalInternalG0(std::unique_lock<std::mutex> &ul);
void TakePedestalInternalG1(std::unique_lock<std::mutex> &ul, int32_t storage_cell = 0);
void TakePedestalInternalG2(std::unique_lock<std::mutex> &ul, int32_t storage_cell = 0);
public:
JFJochStateMachine(JFJochServices &in_services, Logger &logger);
~JFJochStateMachine();
void Initialize();
void Pedestal();
void Deactivate();
void Start(const DatasetSettings& settings);
void WaitTillMeasurementDone();
JFJochState WaitTillMeasurementDone(std::chrono::milliseconds timeout);
void Trigger();
void Cancel();
void SetCalibrationStatistics(const std::vector<JFCalibrationModuleStatistics> &input);
DetectorSettings GetDetectorSettings() const;
void LoadDetectorSettings(const DetectorSettings& settings);
// return by value to ensure thread safety
std::optional<MeasurementStatistics> GetMeasurementStatistics() const;
std::vector<JFCalibrationModuleStatistics> 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<DetectorStatus> GetDetectorStatus() const;
void SetRadialIntegrationSettings(const RadialIntegrationSettings& settings);
RadialIntegrationSettings 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<ROIBox>& input);
void SetCircleROI(const std::vector<ROICircle>& input);
std::vector<ROIBox> GetBoxROI() const;
std::vector<ROICircle> GetCircleROI() const;
std::vector<uint64_t> GetXFELPulseID() const;
std::vector<uint64_t> GetXFELEventCode() const;
std::string GetFullPixelMaskTIFF() const;
std::string GetUserPixelMaskTIFF() const;
void SetUserPixelMask(const std::string &v);
};
#endif //JUNGFRAUJOCH_JFJOCHSTATEMACHINE_H