237 lines
9.7 KiB
C++
237 lines
9.7 KiB
C++
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#include "JFJochBrokerParser.h"
|
|
#include "../common/NetworkAddressConvert.h"
|
|
#include "../image_pusher/ZMQStream2Pusher.h"
|
|
#include "../image_pusher/CBORFilePusher.h"
|
|
#include "../image_pusher/HDF5FilePusher.h"
|
|
#include "OpenAPIConvert.h"
|
|
#include "Detector_type.h"
|
|
#include "../image_pusher/NonePusher.h"
|
|
|
|
DetectorGeometryModular ParseStandardDetectorGeometry(const org::openapitools::server::model::Detector &j) {
|
|
auto s = j.getStandardGeometry();
|
|
return DetectorGeometryModular(s.getNmodules(), s.getModulesInRow(), s.getGapX(), s.getGapY(), false);
|
|
}
|
|
|
|
DetectorModuleGeometry::Direction Convert(const org::openapitools::server::model::Detector_module_direction& d) {
|
|
switch (d.getValue()) {
|
|
case org::openapitools::server::model::Detector_module_direction::eDetector_module_direction::XP:
|
|
return DetectorModuleGeometry::Direction::Xpos;
|
|
case org::openapitools::server::model::Detector_module_direction::eDetector_module_direction::XN:
|
|
return DetectorModuleGeometry::Direction::Xneg;
|
|
case org::openapitools::server::model::Detector_module_direction::eDetector_module_direction::YP:
|
|
return DetectorModuleGeometry::Direction::Ypos;
|
|
case org::openapitools::server::model::Detector_module_direction::eDetector_module_direction::YN:
|
|
return DetectorModuleGeometry::Direction::Yneg;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "invalid detector direction");
|
|
}
|
|
}
|
|
|
|
DetectorType Convert(const org::openapitools::server::model::Detector_type &d) {
|
|
switch (d.getValue()) {
|
|
case org::openapitools::server::model::Detector_type::eDetector_type::EIGER:
|
|
return DetectorType::EIGER;
|
|
case org::openapitools::server::model::Detector_type::eDetector_type::JUNGFRAU:
|
|
return DetectorType::JUNGFRAU;
|
|
case org::openapitools::server::model::Detector_type::eDetector_type::DECTRIS:
|
|
return DetectorType::DECTRIS;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "invalid detector type");
|
|
}
|
|
}
|
|
|
|
DetectorGeometryModular ParseCustomDetectorGeometry(const org::openapitools::server::model::Detector &j) {
|
|
std::vector<DetectorModuleGeometry> modules;
|
|
for (const auto &iter: j.getCustomGeometry()) {
|
|
auto fast = Convert(iter.getFastAxis());
|
|
auto slow = Convert(iter.getSlowAxis());
|
|
modules.emplace_back(iter.getX0(), iter.getY0(), fast, slow);
|
|
}
|
|
return DetectorGeometryModular(modules, false);
|
|
}
|
|
|
|
|
|
DetectorGeometryModular ParseDetectorGeometry(const org::openapitools::server::model::Detector &d) {
|
|
if (d.standardGeometryIsSet() && d.customGeometryIsSet())
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Need to set EITHER standard or custom geometry");
|
|
|
|
if (d.standardGeometryIsSet())
|
|
return ParseStandardDetectorGeometry(d);
|
|
else if (d.customGeometryIsSet())
|
|
return ParseCustomDetectorGeometry(d);
|
|
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Need to set EITHER standard or custom geometry");
|
|
}
|
|
|
|
DetectorSetup ParseDetectorSetup(const org::openapitools::server::model::Detector &d) {
|
|
DetectorType detector_type = Convert(d.getType());
|
|
|
|
if (detector_type == DetectorType::DECTRIS) {
|
|
std::string hostname;
|
|
if (d.getHostname().size() > 1)
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"DECTRIS detector requires single hostname (or none)");
|
|
else if (d.getHostname().size() == 1)
|
|
hostname = d.getHostname()[0];
|
|
|
|
DetectorSetup setup = DetDECTRIS(1,1, d.getDescription(), hostname);
|
|
|
|
if (d.roiModeIsSet())
|
|
setup.DECTRISROI(d.getRoiMode());
|
|
|
|
return setup;
|
|
}
|
|
|
|
DetectorGeometryModular geom = ParseDetectorGeometry(d);
|
|
if (d.isMirrorY())
|
|
geom.VerticalFlip();
|
|
|
|
DetectorSetup setup(geom, detector_type, d.getDescription(), d.getHostname());
|
|
|
|
auto calib = d.getCalibrationFile();
|
|
if (!calib.empty()) {
|
|
switch (detector_type) {
|
|
case DetectorType::EIGER:
|
|
setup.SetTrimFiles(calib);
|
|
break;
|
|
case DetectorType::JUNGFRAU:
|
|
setup.LoadGain(calib);
|
|
break;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Detector type not supported");
|
|
}
|
|
}
|
|
|
|
switch (detector_type) {
|
|
case DetectorType::EIGER:
|
|
case DetectorType::JUNGFRAU:
|
|
setup.PixelSize_um(75.0f);
|
|
break;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Detector type not supported");
|
|
}
|
|
if (d.highVoltageVIsSet())
|
|
setup.HighVoltage(d.getHighVoltageV());
|
|
|
|
setup.UDPInterfaceCount(d.getUdpInterfaceCount())
|
|
.SensorThickness_um(d.getSensorThicknessUm())
|
|
// .PixelSize_um(GET_FLOAT(j, "pixel_size_um", 75.0f))
|
|
.SensorMaterial(d.getSensorMaterial())
|
|
.SerialNumber(d.getSerialNumber())
|
|
.ModuleSync(d.isModuleSync());
|
|
|
|
if (d.readoutTimeUsIsSet())
|
|
setup.ReadOutTime(std::chrono::microseconds(d.getReadoutTimeUs()));
|
|
|
|
if (d.baseDataIpv4AddressIsSet())
|
|
setup.BaseIPv4Addr(d.getBaseDataIpv4Address());
|
|
if (d.txDelayIsSet())
|
|
setup.TxDelay(d.getTxDelay());
|
|
|
|
if (d.minimumCountTimeUsIsSet())
|
|
setup.MinCountTime(std::chrono::microseconds(d.getMinimumCountTimeUs()));
|
|
|
|
if (d.minimumFrameTimeUsIsSet())
|
|
setup.MinFrameTime(std::chrono::microseconds(d.getMinimumFrameTimeUs()));
|
|
|
|
if (d.defaultSettingsIsSet())
|
|
setup.DefaultSettings(Convert(d.getDefaultSettings()));
|
|
|
|
if (d.tempThresoldDegCIsSet())
|
|
setup.TempThreshold_degC(d.getTempThresoldDegC());
|
|
|
|
return setup;
|
|
}
|
|
|
|
void ParseFacilityConfiguration(const org::openapitools::server::model::Jfjoch_settings &j, DiffractionExperiment &experiment) {
|
|
if (j.instrumentIsSet())
|
|
experiment.ImportInstrumentMetadata(Convert(j.getInstrument()));
|
|
|
|
if (j.fileWriterIsSet())
|
|
experiment.ImportFileWriterSettings(Convert(j.getFileWriter()));
|
|
|
|
if (j.detectorSettingsIsSet())
|
|
experiment.ImportDetectorSettings(Convert(j.getDetectorSettings()));
|
|
|
|
if (j.azimIntIsSet())
|
|
experiment.ImportAzimuthalIntegrationSettings(Convert(j.getAzimInt()));
|
|
|
|
if (j.imageFormatIsSet())
|
|
experiment.ImportImageFormatSettings(Convert(j.getImageFormat()));
|
|
|
|
if (j.indexingIsSet())
|
|
experiment.ImportIndexingSettings(Convert(j.getIndexing()));
|
|
}
|
|
|
|
std::unique_ptr<ImagePusher> ParseZMQImagePusher(const org::openapitools::server::model::Jfjoch_settings &j) {
|
|
if (!j.zeromqIsSet())
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "ZeroMQ settings must be provided");
|
|
|
|
std::optional<int32_t> send_buffer_size;
|
|
if (j.getZeromq().sendBufferSizeIsSet())
|
|
send_buffer_size = j.getZeromq().getSendBufferSize();
|
|
|
|
std::optional<int32_t> send_watermark;
|
|
if (j.getZeromq().sendWatermarkIsSet())
|
|
send_watermark = j.getZeromq().getSendWatermark();
|
|
|
|
auto tmp = std::make_unique<ZMQStream2Pusher>(j.getZeromq().getImageSocket(),
|
|
send_watermark,
|
|
send_buffer_size);
|
|
|
|
if (j.getZeromq().writerNotificationSocketIsSet())
|
|
tmp->WriterNotificationSocket(j.getZeromq().getWriterNotificationSocket());
|
|
return std::move(tmp);
|
|
}
|
|
|
|
std::unique_ptr<ImagePusher> ParseImagePusher(const org::openapitools::server::model::Jfjoch_settings &j) {
|
|
switch (j.getImagePusher().getValue()) {
|
|
case org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::ZEROMQ:
|
|
return ParseZMQImagePusher(j);
|
|
case org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::HDF5:
|
|
return std::make_unique<HDF5FilePusher>();
|
|
case org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::NONE:
|
|
return std::make_unique<NonePusher>();
|
|
case org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::CBOR:
|
|
return std::make_unique<CBORFilePusher>();
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Invalid value");
|
|
}
|
|
}
|
|
|
|
void ParseAcquisitionDeviceGroup(const org::openapitools::server::model::Jfjoch_settings &input,
|
|
AcquisitionDeviceGroup &aq_devices) {
|
|
if (!input.pcieIsSet())
|
|
aq_devices.AddHLSDevice(256);
|
|
else for (auto &p: input.getPcie()) {
|
|
std::optional<uint32_t> ipv4_addr = {};
|
|
if (p.ipv4IsSet())
|
|
ipv4_addr = IPv4AddressFromStr(p.getIpv4());
|
|
aq_devices.AddPCIeDevice(p.getBlk(), ipv4_addr);
|
|
}
|
|
}
|
|
|
|
void ParseReceiverSettings(const org::openapitools::server::model::Jfjoch_settings &input, JFJochReceiverService &service) {
|
|
std::string numa_policy = input.getNumaPolicy();
|
|
if (!numa_policy.empty())
|
|
service.NUMAPolicy(numa_policy);
|
|
|
|
// Using default in case
|
|
service.NumThreads(input.getReceiverThreads());
|
|
|
|
if (input.zeromqPreviewIsSet()) {
|
|
service.PreviewSocket(input.getZeromqPreview().getSocketAddress());
|
|
service.PreviewSocketSettings(Convert(input.getZeromqPreview()));
|
|
}
|
|
|
|
if (input.zeromqMetadataIsSet()) {
|
|
service.MetadataSocket(input.getZeromqMetadata().getSocketAddress());
|
|
service.MetadataSocketSettings(Convert(input.getZeromqMetadata()));
|
|
}
|
|
}
|