// Copyright (2019-2023) Paul Scherrer Institute #include "JFJochServices.h" #include "../common/JFJochException.h" JFJochServices::JFJochServices(Logger &in_logger) : logger(in_logger) {} void JFJochServices::Start(const DiffractionExperiment& experiment, const JFCalibration &calibration) { logger.Info("Measurement start for: {}", experiment.GetFilePrefix()); if (receiver != nullptr) { logger.Info(" ... receiver start"); if (experiment.GetDetectorMode() == DetectorMode::Conversion) receiver->Start(experiment, &calibration); else receiver->Start(experiment, nullptr); if (detector && !experiment.IsUsingInternalPacketGen()) { logger.Info(" ... detector start"); detector->Start(experiment); } } logger.Info(" Done!"); } void JFJochServices::Off() { if (detector) detector->Deactivate(); } void JFJochServices::On(const DiffractionExperiment &x) { if (x.IsUsingInternalPacketGen() || (receiver == nullptr)) { detector.reset(); } else { logger.Info("Detector on"); if (!detector) detector = std::make_unique(); detector->Initialize(x, receiver->GetNetworkConfig()); logger.Info(" ... done"); } } JFJochServicesOutput JFJochServices::Stop() { JFJochServicesOutput ret; std::unique_ptr exception; if (receiver != nullptr) { try { if (detector) { logger.Info("Wait for detector done"); DetectorState state = detector->GetState(); while ((state == DetectorState::WAITING) || (state == DetectorState::BUSY)) { // check detector state every 5 ms std::this_thread::sleep_for(std::chrono::milliseconds(5)); state = detector->GetState(); } if (state == DetectorState::ERROR) { logger.Error(" ... detector in error state"); receiver->Cancel(false); } else if (state == DetectorState::IDLE) { receiver->Cancel(true); // cancel silently } } logger.Info("Wait for receiver done"); ret.receiver_output = receiver->Stop(); if (ret.receiver_output.status.compressed_ratio) logger.Info(" ... Receiver efficiency: {} % Max delay: {} Compression ratio {}x", static_cast(ret.receiver_output.efficiency * 100.0), ret.receiver_output.status.max_receive_delay, static_cast(std::round(ret.receiver_output.status.compressed_ratio.value()))); else logger.Info(" ... Receiver efficiency: {} % Max delay: {}", static_cast(ret.receiver_output.efficiency * 100.0), ret.receiver_output.status.max_receive_delay); if (ret.receiver_output.efficiency < 1.0) { for (int i = 0; i < ret.receiver_output.received_packets.size(); i++) { if (ret.receiver_output.received_packets[i] != ret.receiver_output.expected_packets[i]) logger.Info(" ... Module: {} Packets received: {} out of {}", i, ret.receiver_output.received_packets[i], ret.receiver_output.expected_packets[i]); } } } catch (const JFJochException &e) { logger.Error(" ... finished with error {}", e.what()); exception = std::make_unique(e); } logger.Info("Receiver finished with success"); } else { logger.Info("No receiver - sleeping for 30 seconds"); std::this_thread::sleep_for(std::chrono::seconds(30)); logger.Info("Sleep done"); } if (exception) throw JFJochException(*exception); return ret; } void JFJochServices::Cancel() { if (receiver != nullptr) { if (detector) detector->Stop(); receiver->Cancel(false); } } JFJochServices &JFJochServices::Receiver(JFJochReceiverService *input) { receiver = input; return *this; } std::optional JFJochServices::GetReceiverStatus() { if (receiver == nullptr) return {}; return receiver->GetStatus(); } MultiLinePlot JFJochServices::GetPlots(const PlotRequest &request) { if (receiver == nullptr) return {}; try { return receiver->GetDataProcessingPlot(request); } catch (...) { return {}; } } void JFJochServices::SetSpotFindingSettings(const SpotFindingSettings &settings) { if (receiver) receiver->SetSpotFindingSettings(settings); } void JFJochServices::Trigger() { if (detector && (receiver != nullptr)) detector->Trigger(); } std::optional JFJochServices::GetDetectorStatus() const { if (detector) return detector->GetStatus(); else return {}; } std::string JFJochServices::GetPreviewJPEG(const PreviewJPEGSettings &settings) const { if (receiver != nullptr) return receiver->GetJPEG(settings); else return {}; } std::string JFJochServices::GetPreviewTIFF(bool calibration) const { if (receiver != nullptr) return receiver->GetTIFF(calibration); else return ""; } void JFJochServices::ConfigureDetector(const DiffractionExperiment &experiment) { if (detector) detector->Configure(experiment); } void JFJochServices::LoadInternalGeneratorImage(const DiffractionExperiment &experiment, const std::vector &image, uint64_t image_number) { if (receiver) receiver->LoadInternalGeneratorImage(experiment, image, image_number); } void JFJochServices::GetXFELPulseID(std::vector &v) const { if (receiver) receiver->GetXFELPulseID(v); } void JFJochServices::GetXFELEventCode(std::vector &v) const { if (receiver) receiver->GetXFELPulseID(v); }