// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute // 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(), j.isMirrorY()); } 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 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, j.isMirrorY()); } 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); 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())); if (j.darkMaskIsSet()) experiment.ImportDarkMaskSettings(Convert(j.getDarkMask())); } std::unique_ptr ParseZMQImagePusher(const org::openapitools::server::model::Jfjoch_settings &j) { if (!j.zeromqIsSet()) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "ZeroMQ settings must be provided"); std::optional send_buffer_size; if (j.getZeromq().sendBufferSizeIsSet()) send_buffer_size = j.getZeromq().getSendBufferSize(); std::optional send_watermark; if (j.getZeromq().sendWatermarkIsSet()) send_watermark = j.getZeromq().getSendWatermark(); auto tmp = std::make_unique(j.getZeromq().getImageSocket(), send_watermark, send_buffer_size); if (j.getZeromq().writerNotificationSocketIsSet()) tmp->WriterNotificationSocket(j.getZeromq().getWriterNotificationSocket()); return std::move(tmp); } std::unique_ptr 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(); case org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::NONE: return std::make_unique(); case org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::CBOR: return std::make_unique(); 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 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())); } }