AnalysisSettings had begun collecting per-method parameters - the calibrant was already in it, and the grid thresholds were about to be. That makes the structure every method reads grow whenever any one method gains a knob, and it puts a field in front of readers for whom it means nothing. So: AnalysisSettings keeps what all methods share, which for now is the mode, and each method gets a class of its own bound the same way. GridScanAnalysisSettings holds the protein-score threshold, the minimum cells per crystal, the decisive single-cell score, the maximum crystals reported and the indexing switch. CalibrationSettings holds the calibrant and the ring source. Both sit on DiffractionExperiment outside the per-run dataset member, both have an Import/Get pair, and both have their own endpoint - /config/grid_scan_analysis and /config/calibration - which is how every other settings group in this API is already reached. Grid indexing is no longer fixed in the stages table. It was turned off there on cost grounds, and that reasoning does not hold: a raster runs at up to 100 Hz, which the FFT indexer keeps up with, and a fixed-target serial experiment with a known cell wants ffbidx on every cell, where a raster that indexes is most of the measurement. So it is a setting, and DEFAULTS ON. It is additive rather than a change of answer - blobs are still found on the protein score, so indexing alters nothing about which cells are called crystals and only adds what was found in them, including the per-cell lattice count, which is the cheapest multi-lattice or cracked-crystal signal there is. That makes indexing the one stage a mode does not decide. AnalysisModeStages still carries a value for it, but only as the setting's default, and DiffractionExperiment::GetAnalysisStages - which is what every gate reads - substitutes the configured one. The table row is marked so nobody reads it as the mode's answer. The calibration knobs stay coupled to the mode but the rule now lives with them: CalibrationSettings::ApplyToAzimuthalIntegration moves azimuthal integration onto the CPU and supplies sectors where fewer than four were asked for, carrying the reason with it - the FPGA integration core holds 2048 bins in total, so 32 sectors leave 64 q bins, which cannot locate a ring. Stated there because it will otherwise read as an FPGA defect to be fixed back onto that path, and it is not one: the core is sized for a detector at full rate, and a calibration exposure is a few images at a few Hz. Both imports apply it, so the order the mode and the calibration settings are set in does not matter. CalibrationMethod moves from image_analysis/geom_refinement/PowderCalibration.h into common/CalibrationSettings.h, which that header now includes. One enum, so the setting and the code consuming it are not two vocabularies; every existing user sees it unchanged. The grid thresholds have one home and it is this class. The raster work owns AnalyzeGridScan's parameter surface and carries PROTEIN_SCORE_THRESHOLD_DEFAULT / MIN_BLOB_CELLS_DEFAULT beside that header today; the header here states the signature that replaces them, so the two do not become competing defaults. The beam size deliberately stays a separate argument to AnalyzeGridScan: it is measured, not configured. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N
1468 lines
65 KiB
C++
1468 lines
65 KiB
C++
// SPDX-FileCopyrightText: 2024 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
|
// SPDX-License-Identifier: GPL-3.0-only
|
|
|
|
#include "../common/JFJochMath.h"
|
|
#include "../common/GitInfo.h"
|
|
#include "OpenAPIConvert.h"
|
|
|
|
// From https://en.cppreference.com/w/cpp/string/byte/tolower
|
|
std::string str_tolower(std::string s) {
|
|
std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c){ return std::tolower(c); });
|
|
return s;
|
|
}
|
|
|
|
SpotFindingSettings Convert(const org::openapitools::server::model::Spot_finding_settings &input) {
|
|
SpotFindingSettings ret{};
|
|
ret.signal_to_noise_threshold = input.getSignalToNoiseThreshold();
|
|
ret.photon_count_threshold = input.getPhotonCountThreshold();
|
|
ret.min_pix_per_spot = input.getMinPixPerSpot();
|
|
ret.max_pix_per_spot = input.getMaxPixPerSpot();
|
|
// Both limits are optional and unset means "no limit at that end". A value of 0 has meant the same
|
|
// thing since rc.161 and clients still send it that way, so fold it into the unset case here - the
|
|
// analysis code then has exactly one spelling for "no limit" and no zero to special-case.
|
|
if (input.highResolutionLimitIsSet() && input.getHighResolutionLimit() > 0)
|
|
ret.high_resolution_limit = input.getHighResolutionLimit();
|
|
if (input.lowResolutionLimitIsSet() && input.getLowResolutionLimit() > 0)
|
|
ret.low_resolution_limit = input.getLowResolutionLimit();
|
|
ret.enable = input.isEnable();
|
|
ret.indexing = input.isIndexing();
|
|
ret.quick_integration = input.isQuickIntegration();
|
|
ret.cutoff_spot_count_low_res = input.getHighResolutionLimitForSpotCountLowRes();
|
|
ret.ice_ring_width_Q_recipA = input.getIceRingWidthQRecipA();
|
|
if (input.highResGapQRecipAIsSet())
|
|
ret.high_res_gap_Q_recipA = input.getHighResGapQRecipA();
|
|
if (input.adaptiveThresholdIsSet())
|
|
ret.adaptive_threshold = input.isAdaptiveThreshold();
|
|
if (input.falsePixelsPerFrameIsSet())
|
|
ret.false_pixels_per_frame = input.getFalsePixelsPerFrame();
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Spot_finding_settings Convert(const SpotFindingSettings &input) {
|
|
org::openapitools::server::model::Spot_finding_settings ret;
|
|
ret.setSignalToNoiseThreshold(input.signal_to_noise_threshold);
|
|
ret.setPhotonCountThreshold(input.photon_count_threshold);
|
|
ret.setMinPixPerSpot(input.min_pix_per_spot.value_or(2));
|
|
ret.setMaxPixPerSpot(input.max_pix_per_spot);
|
|
if (input.high_resolution_limit.has_value())
|
|
ret.setHighResolutionLimit(input.high_resolution_limit.value());
|
|
if (input.low_resolution_limit.has_value())
|
|
ret.setLowResolutionLimit(input.low_resolution_limit.value());
|
|
ret.setEnable(input.enable);
|
|
ret.setIndexing(input.indexing);
|
|
ret.setHighResolutionLimitForSpotCountLowRes(input.cutoff_spot_count_low_res);
|
|
ret.setQuickIntegration(input.quick_integration);
|
|
ret.setIceRingWidthQRecipA(input.ice_ring_width_Q_recipA);
|
|
if (input.high_res_gap_Q_recipA.has_value())
|
|
ret.setHighResGapQRecipA(input.high_res_gap_Q_recipA.value());
|
|
ret.setAdaptiveThreshold(input.adaptive_threshold);
|
|
ret.setFalsePixelsPerFrame(input.false_pixels_per_frame);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Measurement_statistics Convert(const MeasurementStatistics &input) {
|
|
org::openapitools::server::model::Measurement_statistics ret{};
|
|
|
|
if (!input.file_prefix.empty())
|
|
ret.setFilePrefix(input.file_prefix);
|
|
|
|
ret.setExperimentGroup(input.experiment_group);
|
|
ret.setImagesExpected(input.images_expected);
|
|
ret.setImagesCollected(input.images_collected);
|
|
ret.setImagesSent(input.images_sent);
|
|
ret.setImagesDiscardedLossyCompression(input.images_skipped);
|
|
ret.setMaxImageNumberSent(input.max_image_number_sent);
|
|
if (input.collection_efficiency)
|
|
ret.setCollectionEfficiency(input.collection_efficiency.value());
|
|
if (input.compression_ratio)
|
|
ret.setCompressionRatio(input.compression_ratio.value());
|
|
|
|
ret.setCancelled(input.cancelled);
|
|
if (input.max_receive_delay)
|
|
ret.setMaxReceiverDelay(input.max_receive_delay.value());
|
|
|
|
ret.setDetectorWidth(input.detector_width);
|
|
ret.setDetectorHeight(input.detector_height);
|
|
ret.setDetectorPixelDepth(input.detector_pixel_depth);
|
|
|
|
if (input.roi_beam_npixel)
|
|
ret.setRoiBeamPixels(input.roi_beam_npixel.value());
|
|
if (input.roi_beam_sum)
|
|
ret.setRoiBeamSum(input.roi_beam_sum.value());
|
|
|
|
if (input.error_pixels)
|
|
ret.setErrorPixels(input.error_pixels.value());
|
|
if (input.saturated_pixels)
|
|
ret.setSaturatedPixels(input.saturated_pixels.value());
|
|
|
|
if (input.indexing_rate)
|
|
ret.setIndexingRate(input.indexing_rate.value());
|
|
|
|
if (input.bkg_estimate)
|
|
ret.setBkgEstimate(input.bkg_estimate.value());
|
|
ret.setUnitCell(input.unit_cell);
|
|
ret.setRunNumber(input.run_number);
|
|
if (input.images_written)
|
|
ret.setImagesWritten(input.images_written.value());
|
|
return ret;
|
|
}
|
|
|
|
DetectorTiming Convert(const org::openapitools::server::model::Detector_timing& input) {
|
|
switch (input.getValue()) {
|
|
case org::openapitools::server::model::Detector_timing::eDetector_timing::AUTO:
|
|
return DetectorTiming::Auto;
|
|
case org::openapitools::server::model::Detector_timing::eDetector_timing::TRIGGER:
|
|
return DetectorTiming::Trigger;
|
|
case org::openapitools::server::model::Detector_timing::eDetector_timing::BURST:
|
|
return DetectorTiming::Burst;
|
|
case org::openapitools::server::model::Detector_timing::eDetector_timing::GATED:
|
|
return DetectorTiming::Gated;
|
|
default:
|
|
case org::openapitools::server::model::Detector_timing::eDetector_timing::INVALID_VALUE_OPENAPI_GENERATED:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "invalid input");
|
|
}
|
|
}
|
|
|
|
org::openapitools::server::model::Detector_timing Convert(DetectorTiming input) {
|
|
org::openapitools::server::model::Detector_timing val;
|
|
switch (input) {
|
|
|
|
case DetectorTiming::Auto:
|
|
val.setValue(org::openapitools::server::model::Detector_timing::eDetector_timing::AUTO);
|
|
break;
|
|
case DetectorTiming::Trigger:
|
|
val.setValue(org::openapitools::server::model::Detector_timing::eDetector_timing::TRIGGER);
|
|
break;
|
|
case DetectorTiming::Burst:
|
|
val.setValue(org::openapitools::server::model::Detector_timing::eDetector_timing::BURST);
|
|
break;
|
|
case DetectorTiming::Gated:
|
|
val.setValue(org::openapitools::server::model::Detector_timing::eDetector_timing::GATED);
|
|
break;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "invalid input");
|
|
}
|
|
return val;
|
|
}
|
|
|
|
DetectorSettings Convert(const org::openapitools::server::model::Detector_settings &input) {
|
|
DetectorSettings ret{};
|
|
|
|
if (input.countTimeUsIsSet())
|
|
ret.FrameTime(std::chrono::microseconds(input.getFrameTimeUs()),
|
|
std::chrono::microseconds(input.getCountTimeUs()));
|
|
else
|
|
ret.FrameTime(std::chrono::microseconds(input.getFrameTimeUs()));
|
|
|
|
ret.InternalGeneratorEnable(input.isInternalFrameGenerator());
|
|
ret.InternalGeneratorImages(input.getInternalFrameGeneratorImages());
|
|
ret.DetectorDelay(std::chrono::nanoseconds(input.getDetectorTriggerDelayNs()));
|
|
|
|
ret.StorageCells(input.getJungfrauStorageCellCount());
|
|
ret.StorageCellDelay(std::chrono::nanoseconds(input.getJungfrauStorageCellDelayNs()));
|
|
|
|
ret.FixGainG1(input.isJungfrauFixedGainG1());
|
|
ret.UseGainHG0(input.isJungfrauUseGainHg0());
|
|
|
|
ret.PedestalG0Frames(input.getJungfrauPedestalG0Frames());
|
|
ret.PedestalG1Frames(input.getJungfrauPedestalG1Frames());
|
|
ret.PedestalG2Frames(input.getJungfrauPedestalG2Frames());
|
|
ret.PedestalMinImageCount(input.getJungfrauPedestalMinImageCount());
|
|
|
|
if (input.eigerBitDepthIsSet())
|
|
ret.EigerBitDepth(input.getEigerBitDepth());
|
|
|
|
if (input.eigerThresholdKeVIsSet())
|
|
ret.EigerThreshold_keV(input.getEigerThresholdKeV());
|
|
|
|
if (input.timingIsSet())
|
|
ret.Timing(Convert(input.getTiming()));
|
|
else
|
|
ret.Timing(DetectorTiming::Trigger);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Detector_settings Convert(const DetectorSettings &input) {
|
|
org::openapitools::server::model::Detector_settings ret{};
|
|
|
|
ret.setFrameTimeUs(std::chrono::round<std::chrono::microseconds>(
|
|
std::chrono::duration<float>(input.GetFrameTime())).count());
|
|
if (input.GetCountTime().has_value())
|
|
ret.setCountTimeUs(std::chrono::round<std::chrono::microseconds>(
|
|
std::chrono::duration<float>(input.GetCountTime().value())
|
|
).count());
|
|
ret.setDetectorTriggerDelayNs(input.GetDetectorDelay().count());
|
|
ret.setInternalFrameGeneratorImages(input.GetInternalGeneratorImages());
|
|
ret.setInternalFrameGenerator(input.IsInternalGeneratorEnable());
|
|
|
|
ret.setJungfrauStorageCellCount(input.GetStorageCells());
|
|
ret.setJungfrauFixedGainG1(input.IsFixGainG1());
|
|
ret.setJungfrauUseGainHg0(input.IsUseGainHG0());
|
|
|
|
ret.setJungfrauPedestalG0Frames(input.GetPedestalG0Frames());
|
|
ret.setJungfrauPedestalG1Frames(input.GetPedestalG1Frames());
|
|
ret.setJungfrauPedestalG2Frames(input.GetPedestalG2Frames());
|
|
ret.setJungfrauPedestalMinImageCount(input.GetPedestalMinImageCount());
|
|
|
|
ret.setJungfrauStorageCellDelayNs(input.GetStorageCellDelay().count());
|
|
if (input.GetEigerThreshold_keV().has_value())
|
|
ret.setEigerThresholdKeV(input.GetEigerThreshold_keV().value());
|
|
if (input.GetEigerBitDepth().has_value())
|
|
ret.setEigerBitDepth(input.GetEigerBitDepth().value());
|
|
|
|
ret.setTiming(Convert(input.GetTiming()));
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Broker_status Convert(const BrokerStatus& input) {
|
|
org::openapitools::server::model::Broker_status ret;
|
|
|
|
switch (input.state) {
|
|
case JFJochState::Inactive:
|
|
ret.setState("Inactive");
|
|
break;
|
|
case JFJochState::Idle:
|
|
ret.setState("Idle");
|
|
break;
|
|
case JFJochState::Measuring:
|
|
ret.setState("Measuring");
|
|
break;
|
|
case JFJochState::Error:
|
|
ret.setState("Error");
|
|
break;
|
|
case JFJochState::Busy:
|
|
ret.setState("Busy");
|
|
break;
|
|
case JFJochState::Calibration:
|
|
ret.setState("Pedestal");
|
|
break;
|
|
}
|
|
|
|
if (input.message.has_value())
|
|
ret.setMessage(input.message.value());
|
|
|
|
switch (input.message_severity) {
|
|
case BrokerStatus::MessageSeverity::Info:
|
|
ret.setMessageSeverity("info");
|
|
break;
|
|
case BrokerStatus::MessageSeverity::Success:
|
|
ret.setMessageSeverity("success");
|
|
break;
|
|
case BrokerStatus::MessageSeverity::Warning:
|
|
ret.setMessageSeverity("warning");
|
|
break;
|
|
default:
|
|
ret.setMessageSeverity("error");
|
|
break;
|
|
}
|
|
if (input.progress.has_value())
|
|
ret.setProgress(input.progress.value());
|
|
|
|
ret.setGpuCount(input.gpu_count);
|
|
ret.setBrokerVersion(input.broker_version);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Calibration_statistics_inner Convert(const JFCalibrationModuleStatistics& input) {
|
|
org::openapitools::server::model::Calibration_statistics_inner output;
|
|
|
|
output.setModuleNumber(input.module_number);
|
|
output.setMaskedPixels(input.bad_pixels);
|
|
output.setStorageCellNumber(input.storage_cell_number);
|
|
output.setGainG0Mean(input.gain_g0_mean);
|
|
output.setGainG1Mean(input.gain_g1_mean);
|
|
output.setGainG2Mean(input.gain_g2_mean);
|
|
output.setPedestalG0Mean(input.pedestal_g0_mean);
|
|
output.setPedestalG1Mean(input.pedestal_g1_mean);
|
|
output.setPedestalG2Mean(input.pedestal_g2_mean);
|
|
|
|
return output;
|
|
}
|
|
|
|
std::vector<org::openapitools::server::model::Calibration_statistics_inner> Convert(const std::vector<JFCalibrationModuleStatistics>& input) {
|
|
std::vector<org::openapitools::server::model::Calibration_statistics_inner> ret;
|
|
for (const auto &i: input)
|
|
ret.push_back(Convert(i));
|
|
return ret;
|
|
}
|
|
|
|
|
|
org::openapitools::server::model::Instrument_metadata Convert(const InstrumentMetadata& input) {
|
|
org::openapitools::server::model::Instrument_metadata output;
|
|
output.setInstrumentName(input.GetInstrumentName());
|
|
output.setSourceName(input.GetSourceName());
|
|
output.setSourceType(input.GetSourceType());
|
|
output.setPulsedSource(input.IsPulsedSource());
|
|
output.setElectronSource(input.IsElectronSource());
|
|
return output;
|
|
}
|
|
|
|
InstrumentMetadata Convert(const org::openapitools::server::model::Instrument_metadata &input) {
|
|
InstrumentMetadata output;
|
|
output.InstrumentName(input.getInstrumentName())
|
|
.SourceName(input.getSourceName())
|
|
.SourceType(input.getSourceType())
|
|
.PulsedSource(input.isPulsedSource())
|
|
.ElectronSource(input.isElectronSource());
|
|
return output;
|
|
}
|
|
|
|
|
|
org::openapitools::server::model::Detector_state Convert(DetectorState input) {
|
|
org::openapitools::server::model::Detector_state ret;
|
|
switch (input) {
|
|
case DetectorState::IDLE:
|
|
ret.setValue(org::openapitools::server::model::Detector_state::eDetector_state::IDLE);
|
|
break;
|
|
case DetectorState::ERROR:
|
|
ret.setValue(org::openapitools::server::model::Detector_state::eDetector_state::ERROR);
|
|
break;
|
|
case DetectorState::BUSY:
|
|
ret.setValue(org::openapitools::server::model::Detector_state::eDetector_state::BUSY);
|
|
break;
|
|
case DetectorState::WAITING:
|
|
ret.setValue(org::openapitools::server::model::Detector_state::eDetector_state::WAITING);
|
|
break;
|
|
default:
|
|
case DetectorState::NOT_CONNECTED:
|
|
ret.setValue(org::openapitools::server::model::Detector_state::eDetector_state::NOT_CONNECTED);
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Detector_power_state Convert(DetectorPowerState input) {
|
|
org::openapitools::server::model::Detector_power_state ret;
|
|
switch (input) {
|
|
case DetectorPowerState::ON:
|
|
ret.setValue(org::openapitools::server::model::Detector_power_state::eDetector_power_state::POWERON);
|
|
break;
|
|
case DetectorPowerState::PARTIAL:
|
|
ret.setValue(org::openapitools::server::model::Detector_power_state::eDetector_power_state::PARTIAL);
|
|
break;
|
|
default:
|
|
case DetectorPowerState::OFF:
|
|
ret.setValue(org::openapitools::server::model::Detector_power_state::eDetector_power_state::POWEROFF);
|
|
break;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Detector_status Convert(const DetectorStatus &input) {
|
|
org::openapitools::server::model::Detector_status output;
|
|
output.setServerVersion(input.detector_server_version);
|
|
output.setNumberOfTriggersLeft(input.remaining_triggers);
|
|
output.setFpgaTempDegC(input.temperature_fpga_degC);
|
|
output.setHighVoltageV(input.high_voltage_V);
|
|
output.setPowerchip(Convert(input.power_state));
|
|
output.setState(Convert(input.detector_state));
|
|
return output;
|
|
}
|
|
|
|
org::openapitools::server::model::Detector_type Convert(const DetectorType &input) {
|
|
org::openapitools::server::model::Detector_type dt;
|
|
switch (input) {
|
|
case DetectorType::EIGER:
|
|
dt.setValue(org::openapitools::server::model::Detector_type::eDetector_type::EIGER);
|
|
break;
|
|
case DetectorType::JUNGFRAU:
|
|
dt.setValue(org::openapitools::server::model::Detector_type::eDetector_type::JUNGFRAU);
|
|
break;
|
|
case DetectorType::DECTRIS:
|
|
dt.setValue(org::openapitools::server::model::Detector_type::eDetector_type::DECTRIS);
|
|
break;
|
|
}
|
|
return dt;
|
|
}
|
|
|
|
org::openapitools::server::model::Detector_list Convert(const DetectorList &input) {
|
|
org::openapitools::server::model::Detector_list ret;
|
|
std::vector<org::openapitools::server::model::Detector_list_element> dets;
|
|
for (int i = 0; i < input.detector.size(); i++) {
|
|
org::openapitools::server::model::Detector_list_element d;
|
|
d.setId(i);
|
|
d.setDescription(input.detector[i].description);
|
|
d.setNmodules(input.detector[i].nmodules);
|
|
d.setHeight(input.detector[i].height);
|
|
d.setWidth(input.detector[i].width);
|
|
d.setSerialNumber(input.detector[i].serial_number);
|
|
d.setBaseIpv4Addr(input.detector[i].base_ipv4_addr);
|
|
d.setUdpInterfaceCount(input.detector[i].udp_interface_count);
|
|
d.setMinFrameTimeNs(input.detector[i].min_frame_time.count());
|
|
d.setMinCountTimeNs(input.detector[i].min_count_time.count());
|
|
d.setReadoutTimeNs(input.detector[i].readout_time.count());
|
|
d.setPixelSizeMm(input.detector[i].pixel_size_mm);
|
|
d.setType(Convert(input.detector[i].detector_type));
|
|
dets.emplace_back(std::move(d));
|
|
}
|
|
ret.setDetectors(dets);
|
|
ret.setCurrentId(input.current_id);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Plots Convert(const MultiLinePlot& input) {
|
|
std::vector<org::openapitools::server::model::Plot> tmp(input.GetPlots().size());
|
|
for (int i = 0; i < input.GetPlots().size(); i++) {
|
|
tmp[i].setTitle(input.GetPlots()[i].title);
|
|
tmp[i].setX(input.GetPlots()[i].x);
|
|
tmp[i].setY(input.GetPlots()[i].y);
|
|
tmp[i].setZ(input.GetPlots()[i].z);
|
|
}
|
|
|
|
org::openapitools::server::model::Plots output;
|
|
output.setPlot(tmp);
|
|
|
|
org::openapitools::server::model::Plot_unit_x unit;
|
|
switch (input.GetUnits()) {
|
|
case MultiLinePlotUnits::ImageNumber:
|
|
unit.setValue(org::openapitools::server::model::Plot_unit_x::ePlot_unit_x::IMAGE_NUMBER);
|
|
break;
|
|
case MultiLinePlotUnits::Angle_deg:
|
|
unit.setValue(org::openapitools::server::model::Plot_unit_x::ePlot_unit_x::ANGLE_DEG);
|
|
break;
|
|
case MultiLinePlotUnits::Q_recipA:
|
|
unit.setValue(org::openapitools::server::model::Plot_unit_x::ePlot_unit_x::Q_RECIPA);
|
|
break;
|
|
case MultiLinePlotUnits::ADU:
|
|
unit.setValue(org::openapitools::server::model::Plot_unit_x::ePlot_unit_x::ADU);
|
|
break;
|
|
case MultiLinePlotUnits::d_A:
|
|
unit.setValue(org::openapitools::server::model::Plot_unit_x::ePlot_unit_x::D_A);
|
|
break;
|
|
case MultiLinePlotUnits::Grid_um:
|
|
unit.setValue(org::openapitools::server::model::Plot_unit_x::ePlot_unit_x::GRID_UM);
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
output.setUnitX(unit);
|
|
|
|
if (input.GetSizeX().has_value())
|
|
output.setSizeX(input.GetSizeX().value());
|
|
|
|
if (input.GetSizeY().has_value())
|
|
output.setSizeY(input.GetSizeY().value());
|
|
|
|
return output;
|
|
}
|
|
|
|
AzimuthalIntegrationSettings Convert(const org::openapitools::server::model::Azim_int_settings& input) {
|
|
AzimuthalIntegrationSettings ret{};
|
|
ret.SolidAngleCorrection(input.isSolidAngleCorr());
|
|
ret.PolarizationCorrection(input.isPolarizationCorr());
|
|
ret.QSpacing_recipA(input.getQSpacing());
|
|
ret.QRange_recipA(input.getLowQRecipA(),
|
|
input.highQRecipAIsSet() ? std::optional<float>(input.getHighQRecipA())
|
|
: std::nullopt);
|
|
ret.AzimuthalBinCount(input.getAzimuthalBins());
|
|
ret.ForceCPUinFPGAWorkflow(input.isForceCpu());
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Azim_int_settings Convert(const AzimuthalIntegrationSettings& settings) {
|
|
org::openapitools::server::model::Azim_int_settings ret{};
|
|
ret.setSolidAngleCorr(settings.IsSolidAngleCorrection());
|
|
ret.setPolarizationCorr(settings.IsPolarizationCorrection());
|
|
if (const auto high_q = settings.GetRequestedHighQ_recipA())
|
|
ret.setHighQRecipA(high_q.value());
|
|
ret.setLowQRecipA(settings.GetLowQ_recipA());
|
|
ret.setQSpacing(settings.GetQSpacing_recipA());
|
|
ret.setAzimuthalBins(settings.GetAzimuthalBinCount());
|
|
ret.setForceCpu(settings.IsForceCPUinFPGAWorkflow());
|
|
return ret;
|
|
}
|
|
|
|
ROIDefinition Convert(const org::openapitools::server::model::Roi_definitions& input) {
|
|
ROIDefinition output{};
|
|
for (const auto &i: input.getBox().getRois())
|
|
output.boxes.emplace_back(ROIBox(i.getName(), i.getMinXPxl(), i.getMaxXPxl(), i.getMinYPxl(), i.getMaxYPxl()));
|
|
for (const auto &i: input.getCircle().getRois())
|
|
output.circles.emplace_back(ROICircle(i.getName(), i.getCenterXPxl(), i.getCenterYPxl(), i.getRadiusPxl()));
|
|
for (const auto &i: input.getAzim().getRois()) {
|
|
// A sector needs both bounds; if only one is given, treat it as a full ring.
|
|
float phi_min = 0, phi_max = 0;
|
|
if (i.phiMinDegIsSet() && i.phiMaxDegIsSet()) {
|
|
phi_min = i.getPhiMinDeg();
|
|
phi_max = i.getPhiMaxDeg();
|
|
}
|
|
output.azimuthal.emplace_back(ROIAzimuthal(i.getName(),
|
|
(i.getQMaxRecipA() == 0.0) ? 0.0 : 2.0f * PI / i.getQMaxRecipA(),
|
|
(i.getQMinRecipA() == 0.0) ? 0.0 : 2.0f * PI / i.getQMinRecipA(),
|
|
phi_min, phi_max));
|
|
}
|
|
return output;
|
|
}
|
|
|
|
org::openapitools::server::model::Roi_circle_list Convert(const std::vector<ROICircle> &input) {
|
|
org::openapitools::server::model::Roi_circle_list ret{};
|
|
std::vector<org::openapitools::server::model::Roi_circle> tmp;
|
|
for (const auto &i: input) {
|
|
org::openapitools::server::model::Roi_circle elem;
|
|
elem.setName(i.GetName());
|
|
elem.setCenterXPxl(i.GetX());
|
|
elem.setCenterYPxl(i.GetY());
|
|
elem.setRadiusPxl(i.GetRadius_pxl());
|
|
tmp.emplace_back(elem);
|
|
}
|
|
ret.setRois(tmp);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Roi_azim_list Convert(const std::vector<ROIAzimuthal> &input) {
|
|
org::openapitools::server::model::Roi_azim_list ret{};
|
|
std::vector<org::openapitools::server::model::Roi_azimuthal> tmp;
|
|
for (const auto &i: input) {
|
|
org::openapitools::server::model::Roi_azimuthal elem;
|
|
elem.setName(i.GetName());
|
|
elem.setQMinRecipA(i.GetQMin_recipA());
|
|
elem.setQMaxRecipA(i.GetQMax_recipA());
|
|
if (i.HasPhi()) {
|
|
elem.setPhiMinDeg(i.GetPhiMin_deg());
|
|
elem.setPhiMaxDeg(i.GetPhiMax_deg());
|
|
}
|
|
tmp.emplace_back(elem);
|
|
}
|
|
ret.setRois(tmp);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Roi_box_list Convert(const std::vector<ROIBox> &input) {
|
|
org::openapitools::server::model::Roi_box_list ret{};
|
|
std::vector<org::openapitools::server::model::Roi_box> tmp;
|
|
for (const auto &i: input) {
|
|
org::openapitools::server::model::Roi_box elem;
|
|
elem.setName(i.GetName());
|
|
elem.setMinXPxl(i.GetXMin());
|
|
elem.setMaxXPxl(i.GetXMax());
|
|
elem.setMinYPxl(i.GetYMin());
|
|
elem.setMaxYPxl(i.GetYMax());
|
|
tmp.emplace_back(elem);
|
|
}
|
|
ret.setRois(tmp);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Roi_definitions Convert(const ROIDefinition &input) {
|
|
org::openapitools::server::model::Roi_definitions ret{};
|
|
ret.setCircle(Convert(input.circles));
|
|
ret.setBox(Convert(input.boxes));
|
|
ret.setAzim(Convert(input.azimuthal));
|
|
return ret;
|
|
}
|
|
|
|
ImageFormatSettings Convert(const org::openapitools::server::model::Image_format_settings& input) {
|
|
ImageFormatSettings ret{};
|
|
ret.GeometryTransformed(input.isGeometryTransform());
|
|
ret.AutoSummation(input.isSummation());
|
|
ret.JungfrauConversion(input.isJungfrauConversion());
|
|
ret.MaskChipEdges(input.isMaskChipEdges());
|
|
ret.MaskModuleEdges(input.isMaskModuleEdges());
|
|
ret.ApplyPixelMask(input.isApplyMask());
|
|
ret.PedestalG0RMSLimit(input.getJungfrauPedestalG0RmsLimit());
|
|
ret.MaskPixelsWithoutG0(input.isJungfrauMaskPixelsWithoutG0());
|
|
if (input.signedOutputIsSet())
|
|
ret.PixelSigned(input.isSignedOutput());
|
|
if (input.jungfrauConversionFactorKeVIsSet())
|
|
ret.JungfrauConvFactor_keV(input.getJungfrauConversionFactorKeV());
|
|
if (input.bitDepthImageIsSet())
|
|
ret.BitDepthImage(input.getBitDepthImage());
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Image_format_settings Convert(const ImageFormatSettings& input) {
|
|
org::openapitools::server::model::Image_format_settings ret{};
|
|
ret.setGeometryTransform(input.IsGeometryTransformed());
|
|
ret.setSummation(input.IsAutoSummation());
|
|
ret.setJungfrauConversion(input.IsJungfrauConversion());
|
|
ret.setMaskChipEdges(input.IsMaskChipEdges());
|
|
ret.setMaskModuleEdges(input.IsMaskModuleEdges());
|
|
ret.setApplyMask(input.IsApplyPixelMask());
|
|
ret.setJungfrauMaskPixelsWithoutG0(input.IsMaskPixelsWithoutG0());
|
|
ret.setJungfrauPedestalG0RmsLimit(input.GetPedestalG0RMSLimit());
|
|
if (input.IsPixelSigned().has_value())
|
|
ret.setSignedOutput(input.IsPixelSigned().value());
|
|
if (input.GetJungfrauConvFactor_keV().has_value())
|
|
ret.setJungfrauConversionFactorKeV(input.GetJungfrauConvFactor_keV().value());
|
|
if (input.GetBitDepthImage().has_value())
|
|
ret.setBitDepthImage(input.GetBitDepthImage().value());
|
|
return ret;
|
|
}
|
|
|
|
Coord ConvertOpenAPI(const std::vector<float> &input) {
|
|
if (input.size() != 3)
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Wrong size of Coord array");
|
|
return {input[0], input[1], input[2]};
|
|
}
|
|
|
|
GoniometerAxis Convert(const org::openapitools::server::model::Rotation_axis& input) {
|
|
std::optional<Coord> helical;
|
|
if (input.helicalStepUmIsSet())
|
|
helical = ConvertOpenAPI(input.getHelicalStepUm());
|
|
|
|
GoniometerAxis axis{input.getName(), input.getStart(), input.getStep(),
|
|
ConvertOpenAPI(input.getVector()), helical};
|
|
if (input.screeningWedgeDegIsSet())
|
|
axis.ScreeningWedge(input.getScreeningWedgeDeg());
|
|
return axis;
|
|
}
|
|
|
|
GridScanSettings Convert(const org::openapitools::server::model::Grid_scan& input) {
|
|
return {input.getNFast(), input.getStepXUm(), input.getStepYUm(), input.isSnake(), input.isVertical()};
|
|
}
|
|
|
|
DatasetSettings Convert(const org::openapitools::server::model::Dataset_settings& input) {
|
|
DatasetSettings ret;
|
|
|
|
ret.ImagesPerTrigger(input.getImagesPerTrigger());
|
|
ret.NumTriggers(input.getNtrigger());
|
|
|
|
if (input.runNumberIsSet())
|
|
ret.RunNumber(input.getRunNumber());
|
|
if (input.runNameIsSet())
|
|
ret.RunName(input.getRunName());
|
|
|
|
ret.ExperimentGroup(input.getExperimentGroup());
|
|
|
|
if (input.imageTimeUsIsSet())
|
|
ret.ImageTime(std::chrono::microseconds(input.getImageTimeUs()));
|
|
ret.BeamX_pxl(input.getBeamXPxl());
|
|
ret.BeamY_pxl(input.getBeamYPxl());
|
|
ret.DetectorDistance_mm(input.getDetectorDistanceMm());
|
|
ret.PhotonEnergy_keV(input.getIncidentEnergyKeV());
|
|
|
|
ret.FilePrefix(input.getFilePrefix());
|
|
|
|
if (!input.compressionIsSet())
|
|
ret.Compression(CompressionAlgorithm::BSHUF_LZ4);
|
|
else {
|
|
std::string compr = str_tolower(input.getCompression());
|
|
if (compr == "bslz4")
|
|
ret.Compression(CompressionAlgorithm::BSHUF_LZ4);
|
|
else if (compr == "bszstd")
|
|
ret.Compression(CompressionAlgorithm::BSHUF_ZSTD);
|
|
else if (compr == "bszstd_rle")
|
|
ret.Compression(CompressionAlgorithm::BSHUF_ZSTD_RLE);
|
|
else if (compr == "bszstd_rlehuf")
|
|
ret.Compression(CompressionAlgorithm::BSHUF_ZSTD_RLE_HUFF);
|
|
else if (compr == "none")
|
|
ret.Compression(CompressionAlgorithm::NO_COMPRESSION);
|
|
else
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown compression");
|
|
}
|
|
if (input.poissonCompressionIsSet())
|
|
ret.LossyCompressionPoisson(input.getPoissonCompression());
|
|
|
|
if (input.unitCellIsSet())
|
|
ret.SetUnitCell(UnitCell{
|
|
.a = input.getUnitCell().getA(),
|
|
.b = input.getUnitCell().getB(),
|
|
.c = input.getUnitCell().getC(),
|
|
.alpha = input.getUnitCell().getAlpha(),
|
|
.beta = input.getUnitCell().getBeta(),
|
|
.gamma = input.getUnitCell().getGamma()
|
|
});
|
|
|
|
if (input.totalFluxIsSet())
|
|
ret.TotalFlux(input.getTotalFlux());
|
|
if (input.beamSizeXUmIsSet())
|
|
ret.BeamSizeX_um(input.getBeamSizeXUm());
|
|
if (input.beamSizeYUmIsSet())
|
|
ret.BeamSizeY_um(input.getBeamSizeYUm());
|
|
if (input.transmissionIsSet())
|
|
ret.AttenuatorTransmission(input.getTransmission());
|
|
// Not alternatives: a grid scan is often collected at a given head position, so an axis and a
|
|
// grid can both be set. This used to drop the grid scan silently whenever an axis was present.
|
|
if (input.goniometerIsSet())
|
|
ret.Goniometer(Convert(input.getGoniometer()));
|
|
if (input.gridScanIsSet())
|
|
ret.GridScan(Convert(input.getGridScan()));
|
|
|
|
if (input.spaceGroupNumberIsSet())
|
|
ret.SpaceGroupNumber(input.getSpaceGroupNumber());
|
|
ret.SampleName(input.getSampleName());
|
|
ret.HeaderAppendix(input.getHeaderAppendix());
|
|
ret.ImageAppendix(input.getImageAppendix());
|
|
if (input.imagesPerFileIsSet())
|
|
ret.ImagesPerFile(input.getImagesPerFile());
|
|
|
|
if (input.dataReductionFactorSerialmxIsSet())
|
|
ret.LossyCompressionSerialMX(input.getDataReductionFactorSerialmx());
|
|
|
|
if (input.pixelValueLowThresholdIsSet())
|
|
ret.PixelValueLowThreshold(input.getPixelValueLowThreshold());
|
|
|
|
if (input.saveCalibrationIsSet())
|
|
ret.SaveCalibration(input.isSaveCalibration());
|
|
|
|
ret.WriteNXmxHDF5Master(input.isWriteNxmxHdf5Master());
|
|
|
|
if (input.polarizationFactorIsSet())
|
|
ret.PolarizationFactor(input.getPolarizationFactor());
|
|
|
|
ret.PoniRot1_rad(input.getPoniRot1Rad());
|
|
ret.PoniRot2_rad(input.getPoniRot2Rad());
|
|
ret.PoniRot3_rad(input.getPoniRot3Rad());
|
|
|
|
if (input.ringCurrentMAIsSet())
|
|
ret.RingCurrent_mA(input.getRingCurrentMA());
|
|
if (input.sampleTemperatureKIsSet())
|
|
ret.SampleTemperature_K(input.getSampleTemperatureK());
|
|
|
|
ret.SpotFindingEnable(input.isSpotFinding());
|
|
ret.MaxSpotCount(input.getMaxSpotCount());
|
|
|
|
ret.DetectIceRings(input.isDetectIceRings());
|
|
|
|
if (input.xrayFluorescenceSpectrumIsSet()) {
|
|
auto fl = input.getXrayFluorescenceSpectrum();
|
|
ret.FluorescenceSpectrum({fl.getEnergyEV(), fl.getData()});
|
|
}
|
|
|
|
if (input.smargonIsSet()) {
|
|
auto sm = input.getSmargon();
|
|
SmargonPosition smargon;
|
|
smargon.phi_deg = sm.getPhiDeg();
|
|
smargon.chi_deg = sm.getChiDeg();
|
|
if (sm.phiAxisIsSet())
|
|
smargon.phi_axis = ConvertOpenAPI(sm.getPhiAxis());
|
|
if (sm.chiAxisIsSet())
|
|
smargon.chi_axis = ConvertOpenAPI(sm.getChiAxis());
|
|
ret.Smargon(smargon);
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
std::vector<org::openapitools::server::model::Fpga_status_inner> Convert(const std::vector<DeviceStatus> &input) {
|
|
std::vector<org::openapitools::server::model::Fpga_status_inner> ret;
|
|
for (const auto &d: input) {
|
|
org::openapitools::server::model::Fpga_status_inner tmp;
|
|
tmp.setPciDevId(d.device_number);
|
|
tmp.setSerialNumber(d.serial_number);
|
|
tmp.setFwVersion(d.fpga_firmware_version);
|
|
tmp.setBaseMacAddr(MacAddressToStr(d.fpga_default_mac_addr));
|
|
tmp.setPacketsSls(d.packets_sls);
|
|
tmp.setPacketsUdp(d.packets_udp);
|
|
tmp.setEthLinkCount(d.eth_link_count);
|
|
tmp.setEthLinkStatus(d.eth_link_status);
|
|
tmp.setFpgaTempC(static_cast<float>(d.fpga_temp_C));
|
|
tmp.setHbmTempC(static_cast<float>(d.hbm_0_temp_C));
|
|
tmp.setPowerUsageW(static_cast<float>(d.fpga_pcie_12V_I_mA * d.fpga_pcie_12V_V_mV + d.fpga_pcie_3p3V_I_mA
|
|
* d.fpga_pcie_3p3V_V_mV) / (1000.0f * 1000.0f));
|
|
tmp.setIdle(d.idle);
|
|
tmp.setPcieLinkSpeed(d.pcie_link_speed);
|
|
tmp.setPcieLinkWidth(d.pcie_link_width);
|
|
ret.emplace_back(std::move(tmp));
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
ZMQPreviewSettings Convert(const org::openapitools::server::model::Zeromq_preview_settings &input) {
|
|
ZMQPreviewSettings ret;
|
|
if (input.isEnabled())
|
|
ret.period = std::chrono::milliseconds(input.getPeriodMs());
|
|
else
|
|
ret.period = {};
|
|
ret.address = "";
|
|
return ret;
|
|
}
|
|
|
|
ZMQMetadataSettings Convert(const org::openapitools::server::model::Zeromq_metadata_settings &input) {
|
|
ZMQMetadataSettings ret;
|
|
if (input.isEnabled())
|
|
ret.period = std::chrono::milliseconds(input.getPeriodMs());
|
|
else
|
|
ret.period = {};
|
|
ret.address = "";
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Zeromq_preview_settings Convert(const ZMQPreviewSettings &settings) {
|
|
org::openapitools::server::model::Zeromq_preview_settings ret;
|
|
ret.setEnabled(settings.period.has_value());
|
|
if (settings.period.has_value())
|
|
ret.setPeriodMs(std::chrono::round<std::chrono::milliseconds>(settings.period.value()).count());
|
|
ret.setSocketAddress(settings.address);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Zeromq_metadata_settings Convert(const ZMQMetadataSettings &settings) {
|
|
org::openapitools::server::model::Zeromq_metadata_settings ret;
|
|
ret.setEnabled(settings.period.has_value());
|
|
if (settings.period.has_value())
|
|
ret.setPeriodMs(std::chrono::round<std::chrono::milliseconds>(settings.period.value()).count());
|
|
ret.setSocketAddress(settings.address);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Pixel_mask_statistics Convert(const PixelMaskStatistics& input) {
|
|
org::openapitools::server::model::Pixel_mask_statistics ret;
|
|
ret.setUserMask(input.user_mask);
|
|
ret.setWrongGain(input.error_pixel);
|
|
ret.setTooHighPedestalRms(input.noisy_pixel);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Image_buffer_status Convert(const ImageBufferStatus& input) {
|
|
org::openapitools::server::model::Image_buffer_status ret;
|
|
ret.setAvailableSlots(input.available_slots);
|
|
ret.setTotalSlots(input.total_slots);
|
|
ret.setImageNumbers(input.images_in_the_buffer);
|
|
ret.setMaxImageNumber(input.max_image_number);
|
|
ret.setMinImageNumber(input.min_image_number);
|
|
ret.setInPreparationSlots(input.preparation_slots);
|
|
ret.setInSendingSlots(input.sending_slots);
|
|
|
|
if (input.current_counter.has_value())
|
|
ret.setCurrentCounter(input.current_counter.value());
|
|
return ret;
|
|
}
|
|
|
|
ImageBufferStatus Convert(const org::openapitools::server::model::Image_buffer_status& input) {
|
|
ImageBufferStatus ret;
|
|
ret.available_slots = input.getAvailableSlots();
|
|
ret.total_slots = input.getTotalSlots();
|
|
ret.images_in_the_buffer = input.getImageNumbers();
|
|
ret.max_image_number = input.getMaxImageNumber();
|
|
ret.min_image_number = input.getMinImageNumber();
|
|
ret.sending_slots = input.getInSendingSlots();
|
|
ret.preparation_slots = input.getInPreparationSlots();
|
|
|
|
if (input.currentCounterIsSet())
|
|
ret.current_counter = input.getCurrentCounter();
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::File_writer_settings Convert(const FileWriterSettings& input) {
|
|
org::openapitools::server::model::File_writer_settings ret;
|
|
ret.setFormat(Convert(input.GetFileFormat()));
|
|
ret.setOverwrite(input.IsOverwriteExistingFiles());
|
|
return ret;
|
|
}
|
|
|
|
FileWriterSettings Convert(const org::openapitools::server::model::File_writer_settings &input) {
|
|
FileWriterSettings ret;
|
|
ret.OverwriteExistingFiles(input.isOverwrite());
|
|
ret.FileFormat(Convert(input.getFormat()));
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::File_writer_format Convert(FileWriterFormat input) {
|
|
org::openapitools::server::model::File_writer_format ret;
|
|
switch (input) {
|
|
case FileWriterFormat::DataOnly:
|
|
ret.setValue(org::openapitools::server::model::File_writer_format::eFile_writer_format::NXMXONLYDATA);
|
|
break;
|
|
case FileWriterFormat::NXmxLegacy:
|
|
ret.setValue(org::openapitools::server::model::File_writer_format::eFile_writer_format::NXMXLEGACY);
|
|
break;
|
|
case FileWriterFormat::NXmxVDS:
|
|
ret.setValue(org::openapitools::server::model::File_writer_format::eFile_writer_format::NXMXVDS);
|
|
break;
|
|
case FileWriterFormat::NXmxIntegrated:
|
|
ret.setValue(org::openapitools::server::model::File_writer_format::eFile_writer_format::NXMXINTEGRATED);
|
|
break;
|
|
case FileWriterFormat::NoFile:
|
|
ret.setValue(org::openapitools::server::model::File_writer_format::eFile_writer_format::NOFILEWRITTEN);
|
|
break;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown file writer format enum value");
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
FileWriterFormat Convert(const org::openapitools::server::model::File_writer_format& input) {
|
|
switch (input.getValue()) {
|
|
case org::openapitools::server::model::File_writer_format::eFile_writer_format::NXMXONLYDATA:
|
|
return FileWriterFormat::DataOnly;
|
|
case org::openapitools::server::model::File_writer_format::eFile_writer_format::NXMXLEGACY:
|
|
return FileWriterFormat::NXmxLegacy;
|
|
case org::openapitools::server::model::File_writer_format::eFile_writer_format::NXMXVDS:
|
|
return FileWriterFormat::NXmxVDS;
|
|
case org::openapitools::server::model::File_writer_format::eFile_writer_format::NXMXINTEGRATED:
|
|
return FileWriterFormat::NXmxIntegrated;
|
|
case org::openapitools::server::model::File_writer_format::eFile_writer_format::CBF:
|
|
case org::openapitools::server::model::File_writer_format::eFile_writer_format::TIFF:
|
|
// Deprecated, kept in the OpenAPI enum for back compatibility only - only HDF5 is written now.
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"CBF and TIFF file formats are no longer supported");
|
|
case org::openapitools::server::model::File_writer_format::eFile_writer_format::NOFILEWRITTEN:
|
|
return FileWriterFormat::NoFile;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Unknown file writer format enum value");
|
|
}
|
|
}
|
|
|
|
PlotType ConvertPlotType(const std::optional<std::string>& input) {
|
|
if (!input.has_value())
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Plot type is compulsory paramater");
|
|
if (input == "bkg_estimate") return PlotType::BkgEstimate;
|
|
if (input == "spindle_blind_fraction") return PlotType::SpindleBlindFraction;
|
|
if (input == "ice_ring_score") return PlotType::IceRingScore;
|
|
if (input == "azint") return PlotType::AzInt;
|
|
if (input == "azint_1d") return PlotType::AzInt1D;
|
|
if (input == "spot_count") return PlotType::SpotCount;
|
|
if (input == "spot_count_low_res") return PlotType::SpotCountLowRes;
|
|
if (input == "spot_count_indexed") return PlotType::SpotCountIndexed;
|
|
if (input == "spot_count_ice") return PlotType::SpotCountIceRing;
|
|
if (input == "indexing_rate") return PlotType::IndexingRate;
|
|
if (input == "indexing_unit_cell_length") return PlotType::IndexingUnitCellLength;
|
|
if (input == "profile_radius") return PlotType::ProfileRadius;
|
|
if (input == "mosaicity") return PlotType::Mosaicity;
|
|
if (input == "b_factor") return PlotType::BFactor;
|
|
if (input == "indexing_unit_cell_angle") return PlotType::IndexingUnitCellAngle;
|
|
if (input == "error_pixels") return PlotType::ErrorPixels;
|
|
if (input == "strong_pixels") return PlotType::StrongPixels;
|
|
if (input == "saturated_pixels") return PlotType::SaturatedPixels;
|
|
if (input == "image_collection_efficiency") return PlotType::ImageCollectionEfficiency;
|
|
if (input == "receiver_delay") return PlotType::ReceiverDelay;
|
|
if (input == "receiver_free_send_buf") return PlotType::ReceiverFreeSendBuf;
|
|
if (input == "roi_sum") return PlotType::ROISum;
|
|
if (input == "roi_mean") return PlotType::ROIMean;
|
|
if (input == "roi_max_count") return PlotType::ROIMaxCount;
|
|
if (input == "roi_pixels") return PlotType::ROIPixels;
|
|
if (input == "roi_weighted_x") return PlotType::ROIWeightedX;
|
|
if (input == "roi_weighted_y") return PlotType::ROIWeightedY;
|
|
if (input == "packets_received") return PlotType::PacketsReceived;
|
|
if (input == "max_pixel_value") return PlotType::MaxValue;
|
|
if (input == "resolution_estimate") return PlotType::ResolutionEstimate;
|
|
if (input == "pixel_sum") return PlotType::PixelSum;
|
|
if (input == "processing_time") return PlotType::ImageProcessingTime;
|
|
if (input == "beam_center_x") return PlotType::RefinementBeamX;
|
|
if (input == "beam_center_y") return PlotType::RefinementBeamY;
|
|
if (input == "integrated_reflections") return PlotType::IntegratedReflections;
|
|
if (input == "image_scale_factor") return PlotType::ImageScaleFactor;
|
|
if (input == "image_scale_cc") return PlotType::ImageScaleCC;
|
|
if (input == "compression_ratio") return PlotType::CompressionRatio;
|
|
if (input == "indexing_lattice_count") return PlotType::IndexingLatticeCount;
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Plot type not recognized");
|
|
}
|
|
|
|
ColorScaleEnum ConvertColorScale(const std::optional<std::string> &input) {
|
|
std::string color = input.value_or("indigo");
|
|
|
|
if (color == "viridis")
|
|
return ColorScaleEnum::Viridis;
|
|
if (color == "bw")
|
|
return ColorScaleEnum::BW;
|
|
if (color == "wb")
|
|
return ColorScaleEnum::WB;
|
|
if (color == "green")
|
|
return ColorScaleEnum::Green;
|
|
if (color == "heat")
|
|
return ColorScaleEnum::Heat;
|
|
if (color == "indigo")
|
|
return ColorScaleEnum::Indigo;
|
|
if (color == "magma")
|
|
return ColorScaleEnum::Magma;
|
|
if (color == "inferno")
|
|
return ColorScaleEnum::Inferno;
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Color scale unknown");
|
|
}
|
|
|
|
IndexingSettings Convert(const org::openapitools::server::model::Indexing_settings &input) {
|
|
IndexingSettings ret;
|
|
switch (input.getAlgorithm().getValue()) {
|
|
case org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::FFT:
|
|
ret.Algorithm(IndexingAlgorithmEnum::FFT);
|
|
break;
|
|
case org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::FFTW:
|
|
ret.Algorithm(IndexingAlgorithmEnum::FFTW);
|
|
break;
|
|
case org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::NONE:
|
|
ret.Algorithm(IndexingAlgorithmEnum::None);
|
|
break;
|
|
case org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::FFBIDX:
|
|
ret.Algorithm(IndexingAlgorithmEnum::FFBIDX);
|
|
break;
|
|
case org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::AUTO:
|
|
ret.Algorithm(IndexingAlgorithmEnum::Auto);
|
|
break;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown indexing algorithm");
|
|
}
|
|
|
|
switch (input.getGeomRefinementAlgorithm().getValue()) {
|
|
case org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::INVALID_VALUE_OPENAPI_GENERATED:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown refinement algorithm");
|
|
break;
|
|
case org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::BEAMCENTER:
|
|
ret.GeomRefinementAlgorithm(GeomRefinementAlgorithmEnum::BeamCenter);
|
|
break;
|
|
case org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::ORIENTATIONONLY:
|
|
ret.GeomRefinementAlgorithm(GeomRefinementAlgorithmEnum::OrientationOnly);
|
|
break;
|
|
case org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::FLEX:
|
|
ret.GeomRefinementAlgorithm(GeomRefinementAlgorithmEnum::Flex);
|
|
break;
|
|
case org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::NONE:
|
|
ret.GeomRefinementAlgorithm(GeomRefinementAlgorithmEnum::None);
|
|
break;
|
|
}
|
|
|
|
ret.FFT_HighResolution_A(input.getFftHighResolutionA());
|
|
ret.FFT_MaxUnitCell_A(input.getFftMaxUnitCellA());
|
|
ret.FFT_MinUnitCell_A(input.getFftMinUnitCellA());
|
|
ret.FFT_NumVectors(input.getFftNumVectors());
|
|
ret.Tolerance(input.getTolerance());
|
|
ret.IndexingThreads(input.getThreadCount());
|
|
ret.UnitCellDistTolerance(input.getUnitCellDistTolerance());
|
|
ret.ViableCellMinSpots(input.getViableCellMinSpots());
|
|
ret.IndexIceRings(input.isIndexIceRings());
|
|
ret.RotationIndexing(input.isRotationIndexing());
|
|
ret.RotationIndexingAngularStride_deg(input.getRotationIndexingAngularStrideDeg());
|
|
ret.RotationIndexingMinAngularRange_deg(input.getRotationIndexingMinAngularRangeDeg());
|
|
ret.BlockingBehavior(input.isBlocking());
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Indexing_settings Convert(const IndexingSettings &input) {
|
|
org::openapitools::server::model::Indexing_settings ret;
|
|
|
|
ret.setFftHighResolutionA(input.GetFFT_HighResolution_A());
|
|
ret.setFftMinUnitCellA(input.GetFFT_MinUnitCell_A());
|
|
ret.setFftMaxUnitCellA(input.GetFFT_MaxUnitCell_A());
|
|
ret.setFftNumVectors(input.GetFFT_NumVectors());
|
|
ret.setTolerance(input.GetTolerance());
|
|
ret.setThreadCount(input.GetIndexingThreads());
|
|
ret.setUnitCellDistTolerance(input.GetUnitCellDistTolerance());
|
|
ret.setViableCellMinSpots(input.GetViableCellMinSpots());
|
|
ret.setRotationIndexing(input.GetRotationIndexing());
|
|
ret.setRotationIndexingAngularStrideDeg(input.GetRotationIndexingAngularStride_deg());
|
|
ret.setRotationIndexingMinAngularRangeDeg(input.GetRotationIndexingMinAngularRange_deg());
|
|
ret.setBlocking(input.GetBlockingBehavior());
|
|
|
|
org::openapitools::server::model::Geom_refinement_algorithm refinement;
|
|
switch (input.GetGeomRefinementAlgorithm()) {
|
|
|
|
case GeomRefinementAlgorithmEnum::None:
|
|
refinement.setValue(org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::NONE);
|
|
break;
|
|
case GeomRefinementAlgorithmEnum::BeamCenter:
|
|
refinement.setValue(org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::BEAMCENTER);
|
|
break;
|
|
case GeomRefinementAlgorithmEnum::OrientationOnly:
|
|
refinement.setValue(org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::ORIENTATIONONLY);
|
|
break;
|
|
case GeomRefinementAlgorithmEnum::Flex:
|
|
refinement.setValue(org::openapitools::server::model::Geom_refinement_algorithm::eGeom_refinement_algorithm::FLEX);
|
|
break;
|
|
}
|
|
|
|
ret.setGeomRefinementAlgorithm(refinement);
|
|
|
|
org::openapitools::server::model::Indexing_algorithm tmp;
|
|
switch (input.GetAlgorithm()) {
|
|
case IndexingAlgorithmEnum::Auto:
|
|
tmp.setValue(org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::AUTO);
|
|
break;
|
|
case IndexingAlgorithmEnum::FFBIDX:
|
|
tmp.setValue(org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::FFBIDX);
|
|
break;
|
|
case IndexingAlgorithmEnum::FFT:
|
|
tmp.setValue(org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::FFT);
|
|
break;
|
|
case IndexingAlgorithmEnum::FFTW:
|
|
tmp.setValue(org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::FFTW);
|
|
break;
|
|
case IndexingAlgorithmEnum::None:
|
|
tmp.setValue(org::openapitools::server::model::Indexing_algorithm::eIndexing_algorithm::NONE);
|
|
break;
|
|
}
|
|
ret.setAlgorithm(tmp);
|
|
ret.setIndexIceRings(input.GetIndexIceRings());
|
|
return ret;
|
|
}
|
|
|
|
BraggIntegrationSettings Convert(const org::openapitools::server::model::Bragg_integration_settings &input) {
|
|
BraggIntegrationSettings ret;
|
|
switch (input.getIntegrationModel().getValue()) {
|
|
case org::openapitools::server::model::Integration_model::eIntegration_model::PROFILEGAUSSIAN:
|
|
ret.Integrator(IntegratorMode::ProfileGaussian);
|
|
break;
|
|
case org::openapitools::server::model::Integration_model::eIntegration_model::PROFILEEMPIRICAL:
|
|
ret.Integrator(IntegratorMode::ProfileEmpirical);
|
|
break;
|
|
case org::openapitools::server::model::Integration_model::eIntegration_model::BOXSUM:
|
|
ret.Integrator(IntegratorMode::BoxSum);
|
|
break;
|
|
default:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown integration model");
|
|
}
|
|
// Always a concrete number online, never "derive it from the crystal": the generated model holds
|
|
// the schema's default when the request omits the field, so an absent max_hkl arrives here as that
|
|
// default rather than as an absent value. Deriving per crystal would make a live acquisition's
|
|
// per-image cost depend on whichever sample is mounted.
|
|
ret.MaxHKL(input.getMaxHkl());
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Bragg_integration_settings Convert(const BraggIntegrationSettings &input) {
|
|
org::openapitools::server::model::Bragg_integration_settings ret;
|
|
org::openapitools::server::model::Integration_model tmp;
|
|
switch (input.GetIntegrator()) {
|
|
case IntegratorMode::ProfileGaussian:
|
|
tmp.setValue(org::openapitools::server::model::Integration_model::eIntegration_model::PROFILEGAUSSIAN);
|
|
break;
|
|
case IntegratorMode::ProfileEmpirical:
|
|
tmp.setValue(org::openapitools::server::model::Integration_model::eIntegration_model::PROFILEEMPIRICAL);
|
|
break;
|
|
case IntegratorMode::BoxSum:
|
|
tmp.setValue(org::openapitools::server::model::Integration_model::eIntegration_model::BOXSUM);
|
|
break;
|
|
}
|
|
ret.setIntegrationModel(tmp);
|
|
if (const auto max_hkl = input.GetMaxHKL())
|
|
ret.setMaxHkl(*max_hkl);
|
|
return ret;
|
|
}
|
|
|
|
AnalysisSettings Convert(const org::openapitools::server::model::Analysis_settings &input) {
|
|
AnalysisSettings ret;
|
|
// No default: the compiler must object here when a mode is added to the API, rather than let the
|
|
// new value fall through to whatever the last branch was. MXRotation is not in the API at all -
|
|
// jfjoch_broker has no rotation analysis path - so there is no case for it.
|
|
switch (input.getMode().getValue()) {
|
|
case org::openapitools::server::model::Analysis_mode::eAnalysis_mode::INVALID_VALUE_OPENAPI_GENERATED:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown analysis mode");
|
|
case org::openapitools::server::model::Analysis_mode::eAnalysis_mode::NONE:
|
|
ret.Mode(AnalysisMode::None);
|
|
break;
|
|
case org::openapitools::server::model::Analysis_mode::eAnalysis_mode::MXSTILLS:
|
|
ret.Mode(AnalysisMode::MXStills);
|
|
break;
|
|
case org::openapitools::server::model::Analysis_mode::eAnalysis_mode::AZINT:
|
|
ret.Mode(AnalysisMode::Azint);
|
|
break;
|
|
case org::openapitools::server::model::Analysis_mode::eAnalysis_mode::GRID:
|
|
ret.Mode(AnalysisMode::Grid);
|
|
break;
|
|
case org::openapitools::server::model::Analysis_mode::eAnalysis_mode::POWDERCALIBRATION:
|
|
ret.Mode(AnalysisMode::PowderCalibration);
|
|
break;
|
|
}
|
|
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Analysis_settings Convert(const AnalysisSettings &input) {
|
|
org::openapitools::server::model::Analysis_settings ret;
|
|
org::openapitools::server::model::Analysis_mode tmp;
|
|
switch (input.GetMode()) {
|
|
case AnalysisMode::None:
|
|
tmp.setValue(org::openapitools::server::model::Analysis_mode::eAnalysis_mode::NONE);
|
|
break;
|
|
case AnalysisMode::MXStills:
|
|
tmp.setValue(org::openapitools::server::model::Analysis_mode::eAnalysis_mode::MXSTILLS);
|
|
break;
|
|
case AnalysisMode::Azint:
|
|
tmp.setValue(org::openapitools::server::model::Analysis_mode::eAnalysis_mode::AZINT);
|
|
break;
|
|
case AnalysisMode::Grid:
|
|
tmp.setValue(org::openapitools::server::model::Analysis_mode::eAnalysis_mode::GRID);
|
|
break;
|
|
case AnalysisMode::PowderCalibration:
|
|
tmp.setValue(org::openapitools::server::model::Analysis_mode::eAnalysis_mode::POWDERCALIBRATION);
|
|
break;
|
|
case AnalysisMode::MXRotation:
|
|
// Unreachable through the API: the setter refuses it, so it can never be stored. Reported
|
|
// rather than silently rewritten to stills, which would be the broker claiming to run an
|
|
// analysis it does not have.
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
|
|
"Rotation MX analysis cannot be reported by this API");
|
|
}
|
|
ret.setMode(tmp);
|
|
return ret;
|
|
}
|
|
|
|
GridScanAnalysisSettings Convert(const org::openapitools::server::model::Grid_scan_analysis_settings &input) {
|
|
GridScanAnalysisSettings ret;
|
|
ret.ProteinScoreThreshold(input.getProteinScoreThreshold());
|
|
ret.MinBlobCells(input.getMinBlobCells());
|
|
ret.DecisiveSingleCellScore(input.getDecisiveSingleCellScore());
|
|
ret.MaxCrystals(input.getMaxCrystals());
|
|
ret.Indexing(input.isIndexing());
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Grid_scan_analysis_settings Convert(const GridScanAnalysisSettings &input) {
|
|
org::openapitools::server::model::Grid_scan_analysis_settings ret;
|
|
ret.setProteinScoreThreshold(input.GetProteinScoreThreshold());
|
|
ret.setMinBlobCells(input.GetMinBlobCells());
|
|
ret.setDecisiveSingleCellScore(input.GetDecisiveSingleCellScore());
|
|
ret.setMaxCrystals(input.GetMaxCrystals());
|
|
ret.setIndexing(input.IsIndexing());
|
|
return ret;
|
|
}
|
|
|
|
CalibrationSettings Convert(const org::openapitools::server::model::Calibration_settings &input) {
|
|
CalibrationSettings ret;
|
|
// No default: the compiler must object here when a source is added to the API.
|
|
switch (input.getMethod().getValue()) {
|
|
case org::openapitools::server::model::Calibration_method::eCalibration_method::INVALID_VALUE_OPENAPI_GENERATED:
|
|
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown calibration method");
|
|
case org::openapitools::server::model::Calibration_method::eCalibration_method::RINGS:
|
|
ret.Method(CalibrationMethod::Rings);
|
|
break;
|
|
case org::openapitools::server::model::Calibration_method::eCalibration_method::SPOTS:
|
|
ret.Method(CalibrationMethod::Spots);
|
|
break;
|
|
}
|
|
|
|
if (input.calibrantIsSet())
|
|
ret.Calibrant(input.getCalibrant());
|
|
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Calibration_settings Convert(const CalibrationSettings &input) {
|
|
org::openapitools::server::model::Calibration_settings ret;
|
|
org::openapitools::server::model::Calibration_method tmp;
|
|
switch (input.GetMethod()) {
|
|
case CalibrationMethod::Rings:
|
|
tmp.setValue(org::openapitools::server::model::Calibration_method::eCalibration_method::RINGS);
|
|
break;
|
|
case CalibrationMethod::Spots:
|
|
tmp.setValue(org::openapitools::server::model::Calibration_method::eCalibration_method::SPOTS);
|
|
break;
|
|
}
|
|
ret.setMethod(tmp);
|
|
if (!input.GetCalibrant().empty())
|
|
ret.setCalibrant(input.GetCalibrant());
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Powder_calibration_output Convert(const CalibrationResult &input) {
|
|
org::openapitools::server::model::Powder_calibration_output ret;
|
|
const auto &g = input.geometry;
|
|
|
|
// The geometry under this API's own property names, so it can be PUT back without translating a
|
|
// field. Same content as the <prefix>.json rugnux writes (WriteCalibrationJson).
|
|
org::openapitools::server::model::Dataset_settings settings;
|
|
settings.setBeamXPxl(g.GetBeamX_pxl());
|
|
settings.setBeamYPxl(g.GetBeamY_pxl());
|
|
settings.setDetectorDistanceMm(g.GetDetectorDistance_mm());
|
|
settings.setIncidentEnergyKeV(WVL_1A_IN_KEV / g.GetWavelength_A());
|
|
// The rotations go in together or not at all: omitting them would state a FLAT detector, since the
|
|
// schema's default is 0.0, rather than leave the tilt unstated.
|
|
if (g.GetPoniRot1_rad() != 0.0f || g.GetPoniRot2_rad() != 0.0f || g.GetPoniRot3_rad() != 0.0f) {
|
|
settings.setPoniRot1Rad(g.GetPoniRot1_rad());
|
|
settings.setPoniRot2Rad(g.GetPoniRot2_rad());
|
|
settings.setPoniRot3Rad(g.GetPoniRot3_rad());
|
|
}
|
|
ret.setDatasetSettings(settings);
|
|
|
|
org::openapitools::server::model::Powder_calibration_quality quality;
|
|
// The verdict first: a caller that reads nothing else must still not mistake a non-fit for a fit.
|
|
quality.setConverged(input.converged);
|
|
if (!input.converged)
|
|
quality.setNotConvergedReason(input.reason);
|
|
quality.setRingPoints(input.ring_points);
|
|
quality.setRmsRadialPxl(input.rms_radial_pxl);
|
|
quality.setBeamSigmaPxl(input.beam_sigma_pxl);
|
|
// Where the beam actually lands, which is not the PONI above once the detector is tilted.
|
|
const auto [direct_x, direct_y] = g.GetDirectBeam_pxl();
|
|
quality.setDirectBeamXPxl(direct_x);
|
|
quality.setDirectBeamYPxl(direct_y);
|
|
quality.setHeaderDistanceMm(input.header_distance_mm);
|
|
quality.setTiltRefined(input.tilt_refined);
|
|
quality.setTiltSignificance(input.tilt_significance);
|
|
if (input.seed_distance_mm > 0.0f)
|
|
quality.setRingSeedDistanceMm(input.seed_distance_mm);
|
|
|
|
if (input.uncertainty.valid) {
|
|
org::openapitools::server::model::Powder_calibration_fit_sigma sigma;
|
|
sigma.setBeamXPxl(input.uncertainty.sigma_beam_x_pxl);
|
|
sigma.setBeamYPxl(input.uncertainty.sigma_beam_y_pxl);
|
|
sigma.setDetectorDistanceMm(input.uncertainty.sigma_distance_mm);
|
|
if (input.uncertainty.sigma_rot1_rad > 0.0 || input.uncertainty.sigma_rot2_rad > 0.0) {
|
|
sigma.setPoniRot1Rad(input.uncertainty.sigma_rot1_rad);
|
|
sigma.setPoniRot2Rad(input.uncertainty.sigma_rot2_rad);
|
|
sigma.setCorrelationBeamXRot1(input.uncertainty.corr_beam_x_rot1);
|
|
sigma.setCorrelationBeamYRot2(input.uncertainty.corr_beam_y_rot2);
|
|
}
|
|
quality.setFitSigma(sigma);
|
|
}
|
|
|
|
if (input.spots_geometry) {
|
|
org::openapitools::server::model::Powder_calibration_spot_check cross;
|
|
cross.setBeamXPxl(input.spots_geometry->GetBeamX_pxl());
|
|
cross.setBeamYPxl(input.spots_geometry->GetBeamY_pxl());
|
|
cross.setDetectorDistanceMm(input.spots_geometry->GetDetectorDistance_mm());
|
|
cross.setDisagreementPxl(input.spots_disagreement_pxl);
|
|
quality.setSpotCrossCheck(cross);
|
|
}
|
|
|
|
ret.setCalibration(quality);
|
|
ret.setJfjochVersion(jfjoch_version());
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Grid_scan_crystal Convert(const GridScanCrystal &input) {
|
|
org::openapitools::server::model::Grid_scan_crystal ret;
|
|
ret.setNx(input.nx);
|
|
ret.setNy(input.ny);
|
|
ret.setXUm(input.x_um);
|
|
ret.setYUm(input.y_um);
|
|
ret.setImageNumber(input.image_number);
|
|
ret.setMajorUm(input.major_um);
|
|
ret.setMinorUm(input.minor_um);
|
|
ret.setAngleDeg(input.angle_deg);
|
|
ret.setScore(input.score);
|
|
ret.setIceScore(input.ice_score);
|
|
ret.setResA(input.res_A);
|
|
ret.setNImages(input.n_images);
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Scan_result Convert(const ScanResult& input) {
|
|
org::openapitools::server::model::Scan_result ret;
|
|
ret.setFilePrefix(input.file_prefix);
|
|
std::vector<org::openapitools::server::model::Scan_result_images_inner> v;
|
|
for (const auto &i : input.images) {
|
|
org::openapitools::server::model::Scan_result_images_inner tmp;
|
|
tmp.setEfficiency(i.collection_efficiency);
|
|
tmp.setNumber(i.number);
|
|
if (i.x.has_value())
|
|
tmp.setNx(i.x.value());
|
|
if (i.y.has_value())
|
|
tmp.setNy(i.y.value());
|
|
|
|
if (i.bkg.has_value())
|
|
tmp.setBkg(i.bkg.value());
|
|
if (i.spindle_blind.has_value())
|
|
tmp.setSpindleBlind(i.spindle_blind.value());
|
|
|
|
if (i.angle_deg.has_value())
|
|
tmp.setAngle(i.angle_deg.value());
|
|
if (i.pixel_sum.has_value())
|
|
tmp.setPixelSum(i.pixel_sum.value());
|
|
if (i.max_viable_pixel.has_value())
|
|
tmp.setMax(i.max_viable_pixel.value());
|
|
if (i.sat_pixels.has_value())
|
|
tmp.setSat(i.sat_pixels.value());
|
|
if (i.spot_count.has_value())
|
|
tmp.setSpots(i.spot_count.value());
|
|
if (i.spot_count_ice.has_value())
|
|
tmp.setSpotsIce(i.spot_count_ice.value());
|
|
if (i.ice_ring_score.has_value())
|
|
tmp.setIce(i.ice_ring_score.value());
|
|
if (i.spot_count_low_res.has_value())
|
|
tmp.setSpotsLowRes(i.spot_count_low_res.value());
|
|
if (i.spot_count_indexed.has_value())
|
|
tmp.setSpotsIndexed(i.spot_count_indexed.value());
|
|
if (i.indexing_solution.has_value())
|
|
tmp.setIndex(i.indexing_solution.value());
|
|
if (i.profile_radius.has_value())
|
|
tmp.setPr(i.profile_radius.value());
|
|
if (i.b_factor.has_value())
|
|
tmp.setB(i.b_factor.value());
|
|
if (i.uc.has_value()) {
|
|
org::openapitools::server::model::Unit_cell uc;
|
|
uc.setA(i.uc->a);
|
|
uc.setB(i.uc->b);
|
|
uc.setC(i.uc->c);
|
|
uc.setAlpha(i.uc->alpha);
|
|
uc.setBeta(i.uc->beta);
|
|
uc.setGamma(i.uc->gamma);
|
|
tmp.setUc(uc);
|
|
}
|
|
if (i.indexed_lattice_count.has_value())
|
|
tmp.setLattCount(i.indexed_lattice_count.value());
|
|
if (i.xfel_pulse_id.has_value())
|
|
tmp.setXfelPulseid(i.xfel_pulse_id.value());
|
|
if (i.res.has_value())
|
|
tmp.setRes(i.res.value());
|
|
v.emplace_back(std::move(tmp));
|
|
}
|
|
ret.setImages(v);
|
|
if (input.rotation_lattice) {
|
|
ret.setRotationCrystalLattice(input.rotation_lattice->GetVector());
|
|
org::openapitools::server::model::Unit_cell uc;
|
|
auto i_uc = input.rotation_lattice->GetUnitCell();
|
|
|
|
uc.setA(i_uc.a);
|
|
uc.setB(i_uc.b);
|
|
uc.setC(i_uc.c);
|
|
uc.setAlpha(i_uc.alpha);
|
|
uc.setBeta(i_uc.beta);
|
|
uc.setGamma(i_uc.gamma);
|
|
ret.setRotationUnitCell(uc);
|
|
}
|
|
if (input.rotation_crystal_system && input.rotation_centering)
|
|
ret.setRotationBravais(BravaisSymbol(*input.rotation_crystal_system, *input.rotation_centering));
|
|
|
|
// The two mode-specific payloads. Optional and independent, exactly as the rotation_* members
|
|
// above are: present when that mode ran, absent otherwise.
|
|
if (input.grid) {
|
|
org::openapitools::server::model::Grid_scan_result grid;
|
|
std::vector<org::openapitools::server::model::Grid_scan_crystal> crystals;
|
|
for (const auto &c : input.grid->crystals)
|
|
crystals.emplace_back(Convert(c));
|
|
grid.setCrystals(crystals);
|
|
grid.setBeamSizeXUm(input.grid->beam_size_x_um);
|
|
grid.setBeamSizeYUm(input.grid->beam_size_y_um);
|
|
ret.setGrid(grid);
|
|
}
|
|
if (input.calibration)
|
|
ret.setCalibration(Convert(input.calibration.value()));
|
|
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Dark_mask_settings Convert(const DarkMaskSettings &input) {
|
|
org::openapitools::server::model::Dark_mask_settings ret{};
|
|
ret.setDetectorThresholdKeV(input.GetThreshold_keV());
|
|
ret.setFrameTimeUs(std::chrono::round<std::chrono::microseconds>(
|
|
std::chrono::duration<float>(input.GetFrameTime())
|
|
).count());
|
|
ret.setMaxFramesWithSignal(input.GetMaxFramesWithCounts());
|
|
ret.setMaxAllowedPixelCount(input.GetMaxCounts());
|
|
ret.setNumberOfFrames(input.GetNumberOfFrames());
|
|
return ret;
|
|
}
|
|
|
|
DarkMaskSettings Convert(const org::openapitools::server::model::Dark_mask_settings &input) {
|
|
DarkMaskSettings ret{};
|
|
ret.FrameTime(std::chrono::microseconds(input.getFrameTimeUs()))
|
|
.NumberOfFrames(input.getNumberOfFrames())
|
|
.MaxCounts(input.getMaxAllowedPixelCount())
|
|
.MaxFramesWithCounts(input.getMaxFramesWithSignal())
|
|
.Threshold_keV(input.getDetectorThresholdKeV());
|
|
return ret;
|
|
}
|
|
|
|
org::openapitools::server::model::Image_pusher_status Convert(const ImagePusherStatus& input) {
|
|
org::openapitools::server::model::Image_pusher_status ret;
|
|
ret.setAddr(input.address);
|
|
ret.setConnectedWriters(input.connected_writers);
|
|
org::openapitools::server::model::Image_pusher_type tmp;
|
|
switch (input.pusher_type) {
|
|
case ImagePusherType::HDF5:
|
|
tmp.setValue(org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::HDF5);
|
|
break;
|
|
case ImagePusherType::CBOR:
|
|
tmp.setValue(org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::CBOR);
|
|
break;
|
|
case ImagePusherType::TCP:
|
|
tmp.setValue(org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::TCP);
|
|
break;
|
|
case ImagePusherType::ZMQ:
|
|
tmp.setValue(org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::ZEROMQ);
|
|
break;
|
|
default:
|
|
tmp.setValue(org::openapitools::server::model::Image_pusher_type::eImage_pusher_type::NONE);
|
|
break;
|
|
}
|
|
ret.setPusherType(tmp);
|
|
if (input.images_written)
|
|
ret.setImagesWritten(input.images_written.value());
|
|
if (input.images_write_error)
|
|
ret.setImagesWriteError(input.images_write_error.value());
|
|
ret.setWriterFifoUtilization(input.writer_fifo_utilization);
|
|
return ret;
|
|
} |