* Enhancements for EIGER * Writer is more flexible and capable of handling DECTRIS data
157 lines
5.2 KiB
C++
157 lines
5.2 KiB
C++
// Copyright (2019-2023) Paul Scherrer Institute
|
|
|
|
#include "JFJochReceiverService.h"
|
|
|
|
JFJochReceiverService::JFJochReceiverService(AcquisitionDeviceGroup &in_aq_devices,
|
|
Logger &in_logger, ImagePusher &pusher) :
|
|
logger(in_logger), aq_devices(in_aq_devices),
|
|
image_pusher(pusher), spot_finding_settings(DiffractionExperiment::DefaultDataProcessingSettings()) {
|
|
}
|
|
|
|
JFJochReceiverService& JFJochReceiverService::NumThreads(int64_t input) {
|
|
if (input <= 0)
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Thread number must be above zero");
|
|
nthreads = input;
|
|
return *this;
|
|
}
|
|
|
|
JFJochReceiverService& JFJochReceiverService::PreviewPublisher(ImagePusher *in_preview_writer) {
|
|
preview_publisher = in_preview_writer;
|
|
return *this;
|
|
}
|
|
|
|
JFJochReceiverService &JFJochReceiverService::NUMAPolicy(const NUMAHWPolicy &policy) {
|
|
numa_policy = policy;
|
|
return *this;
|
|
}
|
|
|
|
JFJochReceiverService &JFJochReceiverService::NUMAPolicy(const std::string &policy) {
|
|
numa_policy = NUMAHWPolicy(policy);
|
|
return *this;
|
|
}
|
|
|
|
void JFJochReceiverService::FinalizeMeasurement() {
|
|
receiver->StopReceiver();
|
|
{
|
|
std::unique_lock ul(state_mutex);
|
|
state = ReceiverState::Idle;
|
|
measurement_done.notify_all();
|
|
}
|
|
}
|
|
|
|
std::optional<JFJochReceiverStatus> JFJochReceiverService::GetStatus() {
|
|
// Need to hold mutex, as receiver might not exist here, if state is idle
|
|
std::unique_lock ul(state_mutex);
|
|
|
|
if (state == ReceiverState::Running)
|
|
return receiver->GetStatus();
|
|
else
|
|
return {};
|
|
}
|
|
|
|
void JFJochReceiverService::Start(const DiffractionExperiment &experiment, const JFCalibration *calibration) {
|
|
std::unique_lock ul_state(state_mutex); // unique lock, as it will destroy and create receiver object
|
|
if (state != ReceiverState::Idle)
|
|
throw JFJochException(JFJochExceptionCategory::WrongDAQState, "Receiver not idle, cannot start");
|
|
|
|
try {
|
|
// Thanks to properties of unique_ptr, starting new measurement will call destructor of JFJochReceiver, which will
|
|
// ensure that everything was rolled back
|
|
receiver = std::make_unique<JFJochReceiver>(experiment, calibration,
|
|
aq_devices, image_pusher,
|
|
logger, nthreads, preview_publisher, numa_policy,
|
|
spot_finding_settings);
|
|
try {
|
|
// Don't want to stop
|
|
receiver->SetSpotFindingSettings(spot_finding_settings);
|
|
|
|
} catch (...) {}
|
|
measurement = std::async(std::launch::async, &JFJochReceiverService::FinalizeMeasurement, this);
|
|
state = ReceiverState::Running;
|
|
|
|
} catch (const JFJochException &e) {
|
|
logger.ErrorException(e);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
void JFJochReceiverService::Cancel(bool silent) {
|
|
std::unique_lock ul(state_mutex);
|
|
if (state == ReceiverState::Running)
|
|
receiver->Cancel(silent);
|
|
}
|
|
|
|
JFJochReceiverOutput JFJochReceiverService::Stop() {
|
|
std::unique_lock ul(state_mutex);
|
|
|
|
measurement_done.wait(ul, [this] { return (state != ReceiverState::Running);});
|
|
|
|
if (state != ReceiverState::Idle)
|
|
throw JFJochException(JFJochExceptionCategory::WrongReceiverState, "Receiver in weird state");
|
|
|
|
try {
|
|
if (measurement.valid())
|
|
measurement.get();
|
|
} catch (JFJochException &e) {
|
|
logger.ErrorException(e);
|
|
throw;
|
|
}
|
|
|
|
if (!receiver) {
|
|
logger.Warning("Request to stop while receiver not running");
|
|
throw JFJochException(JFJochExceptionCategory::WrongReceiverState, "Receiver idle, cannot stop");
|
|
}
|
|
return receiver->GetStatistics();
|
|
}
|
|
|
|
void JFJochReceiverService::SetSpotFindingSettings(const SpotFindingSettings &settings) {
|
|
try {
|
|
std::unique_lock ul(state_mutex);
|
|
DiffractionExperiment::CheckDataProcessingSettings(settings);
|
|
spot_finding_settings = settings;
|
|
if (state != ReceiverState::Idle)
|
|
receiver->SetSpotFindingSettings(settings);
|
|
} catch (std::exception &e) {
|
|
logger.ErrorException(e);
|
|
throw;
|
|
}
|
|
}
|
|
|
|
Plot JFJochReceiverService::GetDataProcessingPlot(const PlotRequest &request) {
|
|
// Need to hold mutex, as receiver might not exist here, if state is idle
|
|
std::unique_lock ul(state_mutex);
|
|
if (receiver)
|
|
return receiver->GetPlots(request);
|
|
else
|
|
return {};
|
|
}
|
|
|
|
RadialIntegrationProfiles JFJochReceiverService::GetRadialIntegrationProfiles() {
|
|
// Need to hold mutex, as receiver might not exist here, if state is idle
|
|
std::unique_lock ul(state_mutex);
|
|
if (receiver)
|
|
return receiver->GetRadialIntegrationProfiles();
|
|
else
|
|
return {};
|
|
}
|
|
|
|
std::vector<AcquisitionDeviceNetConfig> JFJochReceiverService::GetNetworkConfig() {
|
|
return aq_devices.GetNetworkConfig();
|
|
}
|
|
|
|
std::string JFJochReceiverService::GetTIFF(bool calibration) const {
|
|
std::unique_lock ul(state_mutex);
|
|
if (receiver)
|
|
return receiver->GetTIFF(calibration);
|
|
else
|
|
return "";
|
|
}
|
|
|
|
std::string JFJochReceiverService::GetJPEG(const PreviewJPEGSettings &settings) {
|
|
std::unique_lock ul(state_mutex);
|
|
if (receiver)
|
|
return receiver->GetJPEG(settings);
|
|
else
|
|
return "";
|
|
}
|