Files
Jungfraujoch/broker/JFJochServices.cpp

176 lines
5.7 KiB
C++

// Copyright (2019-2022) Paul Scherrer Institute
// SPDX-License-Identifier: GPL-3.0-or-later
#include "JFJochServices.h"
#include "../common/JFJochException.h"
uint64_t current_time_ms() {
auto curr_time = std::chrono::system_clock::now();
return std::chrono::duration_cast<std::chrono::milliseconds>(curr_time.time_since_epoch()).count();
}
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 ((experiment.GetImageNum() > 0) && (!experiment.GetFilePrefix().empty())) {
logger.Info(" ... writer start");
writer.Start(writer_zmq_addr, 0);
writer_running = true;
} else
writer_running = false;
logger.Info(" ... receiver start");
if (experiment.GetDetectorMode() == DetectorMode::Conversion)
receiver.Start(experiment, &calibration);
else
receiver.Start(experiment, nullptr);
if (!experiment.IsUsingInternalPacketGen()) {
logger.Info(" ... detector start");
detector.Start(experiment);
}
logger.Info(" Done!");
}
void JFJochServices::Off() {
detector.Off();
}
void JFJochServices::On(const DiffractionExperiment &x) {
logger.Info("Detector on");
JFJochProtoBuf::DetectorConfig config = x.DetectorConfig(receiver.GetNetworkConfig());
detector.On(config);
logger.Info(" ... done");
}
JFJochProtoBuf::BrokerFullStatus JFJochServices::Stop(const JFCalibration &calibration) {
JFJochProtoBuf::BrokerFullStatus ret;
std::unique_ptr<JFJochException> exception;
try {
logger.Info("Wait for receiver done");
*ret.mutable_receiver() = receiver.Stop();
logger.Info(" ... Receiver efficiency: {} % Max delay: {} Compression ratio {}x",
static_cast<int>(ret.receiver().efficiency()*100.0),
ret.receiver().max_receive_delay(),
static_cast<int>(std::round(ret.receiver().compressed_ratio())));
if (ret.receiver().efficiency() < 1.0) {
for (int i = 0; i < ret.receiver().device_statistics_size(); i++) {
for (int j = 0; j < ret.receiver().device_statistics(i).packets_received_per_module_size(); j++) {
logger.Info(" ... Device: {} Module: {} Packets received: {}", i, j,
ret.receiver().device_statistics(i).packets_received_per_module(j));
}
}
}
} catch (const JFJochException &e) {
logger.Error(" ... finished with error {}",e.what());
exception = std::make_unique<JFJochException>(e);
}
logger.Info("Receiver finished with success");
if (writer_running) {
logger.Info("Stopping writer");
try {
auto stats = writer.Stop();
logger.Info(" ... finished with success");
for (int i = 0; i < stats.size(); i++) {
*ret.add_writer() = stats[i];
logger.Info("Writer {}: Images = {} Throughput = {:.0f} MB/s Frame rate = {:.0f} Hz",
i, stats[i].nimages(), stats[i].performance_mbs(), stats[i].performance_hz());
}
} catch (JFJochException &e) {
logger.Error(" ... finished with error {}",e.what());
exception = std::make_unique<JFJochException>(e);
}
}
logger.Info("Stopping detector");
try {
detector.Stop();
logger.Info(" ... done");
} catch (JFJochException &e) {
logger.Error(" ... finished with error {}",e.what());
exception = std::make_unique<JFJochException>(e);
}
if (exception)
throw JFJochException(*exception);
return ret;
}
void JFJochServices::Abort() {
// Abort should try to achieve the best outcome possible
// but it OK if things fail (for example lost connection)
try {
receiver.Abort();
} catch (const std::exception &e) {
logger.Error(e.what());
}
}
void JFJochServices::Cancel() {
detector.Stop();
receiver.Cancel();
}
JFJochServices &JFJochServices::Receiver(const std::string &addr) {
receiver.Connect(addr);
logger.Info("Using receiver service with gRPC " + addr);
return *this;
}
JFJochServices &JFJochServices::Writer(const std::string &addr, const std::string &zmq_push_addr) {
writer.AddClient(addr);
writer_zmq_addr.push_back(zmq_push_addr);
logger.Info("Using writer service with gRPC {} listening for images from ZeroMQ {}", addr, zmq_push_addr);
return *this;
}
JFJochServices &JFJochServices::Detector(const std::string &addr) {
detector.Connect(addr);
logger.Info("Using detector service with gRPC {}", addr);
return *this;
}
JFJochProtoBuf::ReceiverStatus JFJochServices::GetReceiverStatus() {
return receiver.GetStatus();
}
JFJochProtoBuf::Plot JFJochServices::GetPlots(const JFJochProtoBuf::PlotRequest &request) {
try {
return receiver.GetPlots(request);
} catch (...) {
return JFJochProtoBuf::Plot();
}
}
JFJochProtoBuf::RadialIntegrationProfiles JFJochServices::GetRadialIntegrationProfiles() {
try {
return receiver.GetRadialIntegrationProfiles();
} catch (...) {
return JFJochProtoBuf::RadialIntegrationProfiles();
}
}
void JFJochServices::SetDataProcessingSettings(const JFJochProtoBuf::DataProcessingSettings &settings) {
receiver.SetDataProcessingSettings(settings);
}
JFJochProtoBuf::PreviewFrame JFJochServices::GetPreviewFrame() {
return receiver.GetPreviewFrame();
}
void JFJochServices::Trigger() {
detector.Trigger();
}
size_t JFJochServices::WriterZMQCount() const {
return writer_zmq_addr.size();
}