From 30e775d8a2eec59a2a9b6ab6d26eacea4fa9f473 Mon Sep 17 00:00:00 2001 From: leonarski_f Date: Sun, 31 Mar 2024 23:08:19 +0200 Subject: [PATCH] Improve plotting --- acquisition_device/AcquisitionDevice.cpp | 10 + acquisition_device/AcquisitionDevice.h | 1 + acquisition_device/HLSSimulatedDevice.cpp | 35 +- broker/JFJochBrokerHttp.cpp | 156 +++++--- broker/JFJochBrokerHttp.h | 18 +- broker/JFJochServices.cpp | 23 +- broker/JFJochServices.h | 6 +- broker/JFJochStateMachine.cpp | 48 ++- broker/JFJochStateMachine.h | 14 +- broker/gen/api/DefaultApi.cpp | 192 +++++++++- broker/gen/api/DefaultApi.h | 74 +++- broker/gen/model/Dataset_settings.cpp | 30 +- broker/gen/model/Dataset_settings.h | 10 - .../gen/model/Dataset_settings_unit_cell.cpp | 101 ++++- broker/gen/model/Plot.cpp | 16 +- broker/gen/model/Plot.h | 8 + broker/gen/model/Plots.cpp | 140 +++++++ ...dial_integration_plots_inner.h => Plots.h} | 35 +- broker/gen/model/Preview_settings.cpp | 31 +- broker/gen/model/Preview_settings.h | 9 + .../model/Radial_integration_plots_inner.cpp | 104 ------ broker/gen/model/Roi_box.cpp | 217 +++++++++++ broker/gen/model/Roi_box.h | 105 ++++++ broker/gen/model/Roi_box_list.cpp | 131 +++++++ broker/gen/model/Roi_box_list.h | 80 ++++ broker/gen/model/Roi_circle.cpp | 161 ++++++++ broker/gen/model/Roi_circle.h | 98 +++++ broker/gen/model/Roi_circle_list.cpp | 116 ++++++ broker/gen/model/Roi_circle_list.h | 78 ++++ broker/jfjoch_api.yaml | 344 ++++++++++++++---- broker/redoc-static.html | 94 +++-- common/ADUHistogram.cpp | 12 +- common/ADUHistogram.h | 2 +- common/CMakeLists.txt | 8 + common/DatasetSettings.cpp | 22 +- common/DatasetSettings.h | 3 - common/DiffractionExperiment.cpp | 59 ++- common/DiffractionExperiment.h | 14 +- common/Histogram.h | 26 +- common/Plot.h | 17 +- common/ROIBox.cpp | 44 +++ common/ROIBox.h | 22 ++ common/ROICircle.cpp | 42 +++ common/ROICircle.h | 20 + common/ROIElement.cpp | 10 + common/ROIElement.h | 20 + common/ROIMask.cpp | 67 ++++ common/ROIMask.h | 38 ++ common/RawToConvertedGeometry.h | 25 +- common/StatusVector.h | 74 +++- export_images/PreviewImage.cpp | 26 +- export_images/PreviewImage.h | 3 + fpga/hls/frame_summation.cpp | 37 +- fpga/hls/frame_summation_tb.cpp | 12 +- fpga/hls/frame_summation_tb_2.cpp | 12 +- fpga/hls/hls_jfjoch.h | 12 +- fpga/hls/jf_conversion.cpp | 40 +- fpga/include/jfjoch_fpga.h | 7 +- frame_serialize/CBORStream2Deserializer.cpp | 72 ++-- frame_serialize/CBORStream2Deserializer.h | 2 + frame_serialize/CBORStream2Serializer.cpp | 46 ++- frame_serialize/JFJochMessages.h | 20 +- frontend_ui/package-lock.json | 20 + frontend_ui/package.json | 1 + frontend_ui/src/App.tsx | 30 +- .../src/components/DataProcessingPlot.tsx | 92 +++-- .../src/components/DataProcessingPlots.tsx | 21 +- .../src/components/DetectorSelection.tsx | 2 - .../src/components/DetectorSettings.tsx | 1 - frontend_ui/src/components/PlotWrapper.js | 30 -- frontend_ui/src/components/PreviewImage.tsx | 7 +- .../src/components/PreviewImageSettings.tsx | 16 +- frontend_ui/src/components/ROI.tsx | 260 +++++++++++++ .../RadialIntegrationProfilePlots.tsx | 75 ---- frontend_ui/src/components/handleErrors.ts | 1 - frontend_ui/src/openapi/index.ts | 6 +- .../src/openapi/models/dataset_settings.ts | 9 - frontend_ui/src/openapi/models/plot.ts | 1 + .../{radial_integration_plots.ts => plots.ts} | 9 +- .../src/openapi/models/preview_settings.ts | 4 + frontend_ui/src/openapi/models/roi_box.ts | 31 ++ .../src/openapi/models/roi_box_list.ts | 14 + frontend_ui/src/openapi/models/roi_circle.ts | 27 ++ .../src/openapi/models/roi_circle_list.ts | 14 + .../src/openapi/services/DefaultService.ts | 216 ++++++++--- .../AzimuthalIntegrationProfile.cpp | 13 +- image_analysis/AzimuthalIntegrationProfile.h | 4 +- image_analysis/CMakeLists.txt | 6 +- image_analysis/CPUSpotFinder.cpp | 64 ++++ image_analysis/CPUSpotFinder.h | 14 + image_analysis/MXAnalyzer.cpp | 65 ++++ image_analysis/MXAnalyzer.h | 30 ++ image_analysis/fast-feedback-indexer | 2 +- jungfrau/JFConversionFloatingPoint.cpp | 6 +- jungfrau/JFConversionFloatingPoint.h | 1 + receiver/CMakeLists.txt | 4 +- receiver/FrameTransformation.cpp | 39 -- receiver/FrameTransformation.h | 1 - receiver/ImageMetadata.cpp | 36 +- receiver/ImageMetadata.h | 6 +- receiver/JFJochReceiver.cpp | 70 +--- receiver/JFJochReceiver.h | 8 +- receiver/JFJochReceiverPlots.cpp | 145 +++++--- receiver/JFJochReceiverPlots.h | 21 +- receiver/JFJochReceiverService.cpp | 25 +- receiver/JFJochReceiverService.h | 8 +- receiver/LossyFilter.cpp | 24 ++ receiver/LossyFilter.h | 28 ++ tests/AzimuthalIntegrationTest.cpp | 20 +- tests/CBORTest.cpp | 62 +++- tests/CMakeLists.txt | 2 + tests/DiffractionExperimentTest.cpp | 86 +++++ tests/FrameTransformationTest.cpp | 108 ------ tests/HistogramTest.cpp | 40 +- tests/JFJochReceiverProcessingTest.cpp | 90 +++++ tests/JPEGTest.cpp | 52 +++ tests/LossyFilterTest.cpp | 71 ++++ tests/ROIMaskTest.cpp | 91 +++++ tests/StatusVectorTest.cpp | 120 +++++- tools/AzimIntDataset.cpp | 19 +- tools/CMakeLists.txt | 3 + tools/jfjoch_spot_finding_test.cpp | 219 +++++++++++ 122 files changed, 4640 insertions(+), 1149 deletions(-) create mode 100644 broker/gen/model/Plots.cpp rename broker/gen/model/{Radial_integration_plots_inner.h => Plots.h} (62%) delete mode 100644 broker/gen/model/Radial_integration_plots_inner.cpp create mode 100644 broker/gen/model/Roi_box.cpp create mode 100644 broker/gen/model/Roi_box.h create mode 100644 broker/gen/model/Roi_box_list.cpp create mode 100644 broker/gen/model/Roi_box_list.h create mode 100644 broker/gen/model/Roi_circle.cpp create mode 100644 broker/gen/model/Roi_circle.h create mode 100644 broker/gen/model/Roi_circle_list.cpp create mode 100644 broker/gen/model/Roi_circle_list.h create mode 100644 common/ROIBox.cpp create mode 100644 common/ROIBox.h create mode 100644 common/ROICircle.cpp create mode 100644 common/ROICircle.h create mode 100644 common/ROIElement.cpp create mode 100644 common/ROIElement.h create mode 100644 common/ROIMask.cpp create mode 100644 common/ROIMask.h delete mode 100644 frontend_ui/src/components/PlotWrapper.js create mode 100644 frontend_ui/src/components/ROI.tsx delete mode 100644 frontend_ui/src/components/RadialIntegrationProfilePlots.tsx rename frontend_ui/src/openapi/models/{radial_integration_plots.ts => plots.ts} (66%) create mode 100644 frontend_ui/src/openapi/models/roi_box.ts create mode 100644 frontend_ui/src/openapi/models/roi_box_list.ts create mode 100644 frontend_ui/src/openapi/models/roi_circle.ts create mode 100644 frontend_ui/src/openapi/models/roi_circle_list.ts create mode 100644 image_analysis/CPUSpotFinder.cpp create mode 100644 image_analysis/CPUSpotFinder.h create mode 100644 image_analysis/MXAnalyzer.cpp create mode 100644 image_analysis/MXAnalyzer.h create mode 100644 receiver/LossyFilter.cpp create mode 100644 receiver/LossyFilter.h create mode 100644 tests/LossyFilterTest.cpp create mode 100644 tests/ROIMaskTest.cpp create mode 100644 tools/jfjoch_spot_finding_test.cpp diff --git a/acquisition_device/AcquisitionDevice.cpp b/acquisition_device/AcquisitionDevice.cpp index 4a61dba6..d9e8ed7c 100644 --- a/acquisition_device/AcquisitionDevice.cpp +++ b/acquisition_device/AcquisitionDevice.cpp @@ -186,6 +186,16 @@ void AcquisitionDevice::InitializeSpotFinderResolutionMap(const float *data, siz void AcquisitionDevice::InitializeROIMap(const uint16_t *map, size_t module_number) {} +void AcquisitionDevice::InitializeROIMap(const DiffractionExperiment& experiment) { + std::vector tmp(RAW_MODULE_SIZE); + auto offset = experiment.GetFirstModuleOfDataStream(data_stream); + size_t modules = experiment.GetModulesNum(data_stream); + for (int m = 0; m < modules; m++) { + experiment.ExportROIMask(tmp.data(), offset + m); + InitializeROIMap(tmp.data(), m); + } +} + void AcquisitionDevice::MapBuffersStandard(size_t c2h_buffer_count, int16_t numa_node) { try { for (int i = 0; i < c2h_buffer_count; i++) diff --git a/acquisition_device/AcquisitionDevice.h b/acquisition_device/AcquisitionDevice.h index 842b5f61..8c49541e 100644 --- a/acquisition_device/AcquisitionDevice.h +++ b/acquisition_device/AcquisitionDevice.h @@ -97,6 +97,7 @@ public: virtual void InitializeIntegrationMap(const uint16_t *map, const float *weights, size_t module_number); virtual void InitializeSpotFinderResolutionMap(const float *data, size_t module_number); virtual void InitializeROIMap(const uint16_t *map, size_t module_number); + void InitializeROIMap(const DiffractionExperiment &experiment); const AcquisitionCounters& Counters() const; diff --git a/acquisition_device/HLSSimulatedDevice.cpp b/acquisition_device/HLSSimulatedDevice.cpp index fb6c5a36..3433498e 100644 --- a/acquisition_device/HLSSimulatedDevice.cpp +++ b/acquisition_device/HLSSimulatedDevice.cpp @@ -278,6 +278,7 @@ void HLSSimulatedDevice::HLSMainThread() { STREAM_768 stream_768_2; STREAM_768 stream_768_3; STREAM_768 stream_768_4; + STREAM_768 stream_768_5; STREAM_512 data_0; hls::stream, 2> data_1; @@ -290,7 +291,6 @@ void HLSSimulatedDevice::HLSMainThread() { STREAM_512 data_8; STREAM_512 data_9; STREAM_512 data_10; - STREAM_576 data_11; STREAM_512 data_12; STREAM_512 data_13; @@ -480,7 +480,7 @@ void HLSSimulatedDevice::HLSMainThread() { hls_cores.emplace_back([&] { eiger_reorder(data_8, data_9, axi_compl[5], axi_compl[6]);}); // 6. Apply pedestal & gain corrections - hls_cores.emplace_back([&] { jf_conversion(data_9, data_11, + hls_cores.emplace_back([&] { jf_conversion(data_9, stream_768_0, axi_compl[6], axi_compl[7], hbm.data(), hbm.data(), @@ -497,10 +497,10 @@ void HLSSimulatedDevice::HLSMainThread() { hbm_if_size); }); // 7. Frame summation - hls_cores.emplace_back([&] { frame_summation(data_11, stream_768_0, axi_compl[7], axi_compl[8], frame_summation_idle);}); + hls_cores.emplace_back([&] { frame_summation(stream_768_0, stream_768_1, axi_compl[7], axi_compl[8], frame_summation_idle);}); // 8. Integration of pixels - hls_cores.emplace_back([&] { integration(stream_768_0, stream_768_1, integration_result_0, axi_compl[8], axi_compl[9], + hls_cores.emplace_back([&] { integration(stream_768_1, stream_768_2, integration_result_0, axi_compl[8], axi_compl[9], hbm.data(), hbm.data(), hbm.data(), hbm.data(), integration_idle, hbm_if_size);}); hls_cores.emplace_back([&] { axis_64_to_512(integration_result_0, integration_result_1);}); @@ -512,8 +512,8 @@ void HLSSimulatedDevice::HLSMainThread() { ap_uint<32> min_pix_per_spot = spot_finder_parameters.min_pix_per_spot; hls_cores.emplace_back([&] { - spot_finder_mask(stream_768_1, - stream_768_2, + spot_finder_mask(stream_768_2, + stream_768_3, spot_finder_mask_0, axi_compl[9], axi_compl[10], @@ -526,7 +526,7 @@ void HLSSimulatedDevice::HLSMainThread() { }); hls_cores.emplace_back([&] { - spot_finder(stream_768_2, spot_finder_mask_0, stream_768_3, spot_finder_result_0, tmp_count_threshold, tmp_snr_threshold); + spot_finder(stream_768_3, spot_finder_mask_0, stream_768_4, spot_finder_result_0, tmp_count_threshold, tmp_snr_threshold); logger_hls.Info("spot_finder done"); }); @@ -546,8 +546,8 @@ void HLSSimulatedDevice::HLSMainThread() { }); hls_cores.emplace_back([&] { - roi_calc(stream_768_3, - stream_768_4, + roi_calc(stream_768_4, + stream_768_5, roi_calc_result_0, axi_compl[10], axi_compl[11], @@ -558,7 +558,7 @@ void HLSSimulatedDevice::HLSMainThread() { }); // 10. Reduce/extend 24-bit stream - hls_cores.emplace_back([&] { stream_24bit_conv(stream_768_4, data_12, stream_conv_idle);}); + hls_cores.emplace_back([&] { stream_24bit_conv(stream_768_5, data_12, stream_conv_idle);}); // 11. Prepare data to write to host memory hls_cores.emplace_back([&] { @@ -618,8 +618,7 @@ void HLSSimulatedDevice::HLSMainThread() { if (!data_10.empty()) throw std::runtime_error("data_10 queue not empty"); - if (!data_11.empty()) - throw std::runtime_error("data_11 queue not empty"); + if (!data_12.empty()) throw std::runtime_error("data_12 queue not empty"); @@ -633,13 +632,19 @@ void HLSSimulatedDevice::HLSMainThread() { } if (!stream_768_0.empty()) - throw std::runtime_error("Stream_768_0 queue not empty"); + throw std::runtime_error("stream_768_0 queue not empty"); if (!stream_768_1.empty()) - throw std::runtime_error("Stream_768_1 queue not empty"); + throw std::runtime_error("stream_768_1 queue not empty"); if (!stream_768_2.empty()) - throw std::runtime_error("Stream_768_2 queue not empty"); + throw std::runtime_error("stream_768_2 queue not empty"); + + if (!stream_768_3.empty()) + throw std::runtime_error("stream_768_3 queue not empty"); + + if (!stream_768_4.empty()) + throw std::runtime_error("stream_768_4 queue not empty"); if (!hbm_handles.empty()) throw std::runtime_error("Handles queue not empty"); diff --git a/broker/JFJochBrokerHttp.cpp b/broker/JFJochBrokerHttp.cpp index 825c6394..ff842e13 100644 --- a/broker/JFJochBrokerHttp.cpp +++ b/broker/JFJochBrokerHttp.cpp @@ -222,17 +222,16 @@ inline org::openapitools::server::model::Detector_list Convert(const DetectorLis return ret; } -inline org::openapitools::server::model::Plot Convert(const Plot& input) { - org::openapitools::server::model::Plot output; - output.setX(input.x); - output.setY(input.y); - return output; -} +inline org::openapitools::server::model::Plots Convert(const MultiLinePlot& input) { + std::vector tmp(input.size()); + for (int i = 0; i < input.size(); i++) { + tmp[i].setTitle(input[i].title); + tmp[i].setX(input[i].x); + tmp[i].setY(input[i].y); + } -inline org::openapitools::server::model::Radial_integration_plots_inner Convert(const RadialIntegrationProfileStruct& input) { - org::openapitools::server::model::Radial_integration_plots_inner output; - output.setTitle(input.title); - output.setPlot(Convert(input.plot)); + org::openapitools::server::model::Plots output; + output.setPlot(tmp); return output; } @@ -267,11 +266,58 @@ inline org::openapitools::server::model::Rad_int_settings Convert(const RadialIn return ret; } +inline std::vector Convert(const org::openapitools::server::model::Roi_box_list& input) { + std::vector ret; + for (const auto &i: input.getRois()) + ret.emplace_back(ROIBox(i.getName(), i.getMinXPxl(), i.getMaxXPxl(), i.getMinYPxl(), i.getMaxYPxl())); + return ret; +} + +inline std::vector Convert(const org::openapitools::server::model::Roi_circle_list& input) { + std::vector ret; + for (const auto &i: input.getRois()) + ret.emplace_back(ROICircle(i.getName(), i.getCenterXPxl(), i.getCenterYPxl(), i.getRadiusPxl())); + return ret; +} + +inline org::openapitools::server::model::Roi_circle_list Convert(const std::vector &input) { + org::openapitools::server::model::Roi_circle_list ret{}; + std::vector 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; +} + + +inline org::openapitools::server::model::Roi_box_list Convert(const std::vector &input) { + org::openapitools::server::model::Roi_box_list ret{}; + std::vector 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; +} + inline PreviewJPEGSettings Convert(const org::openapitools::server::model::Preview_settings& input) { PreviewJPEGSettings ret{}; ret.show_spots = input.isShowSpots(); ret.jpeg_quality = input.getJpegQuality(); ret.saturation_value = input.getSaturation(); + ret.show_roi = input.isShowRoi(); return ret; } @@ -280,6 +326,7 @@ inline org::openapitools::server::model::Preview_settings Convert(const PreviewJ ret.setJpegQuality(settings.jpeg_quality); ret.setSaturation(settings.saturation_value); ret.setShowSpots(settings.show_spots); + ret.setShowRoi(settings.show_roi); return ret; } @@ -358,14 +405,6 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s } } - if (input.roiSumAreaIsSet()) { - ret.ROISummation(ROIRectangle{ - .x_min = static_cast(input.getRoiSumArea().getXMin()), - .x_max = static_cast(input.getRoiSumArea().getXMax()), - .y_min = static_cast(input.getRoiSumArea().getYMin()), - .y_max = static_cast(input.getRoiSumArea().getYMax()) - }); - } ret.SpaceGroupNumber(input.getSpaceGroupNumber()); ret.SampleName(input.getSampleName()); ret.HeaderAppendix(input.getHeaderAppendix()); @@ -493,15 +532,6 @@ void JFJochBrokerHttp::config_spot_finding_put( response.send(Pistache::Http::Code::Ok); } -void JFJochBrokerHttp::plot_saturated_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, - Pistache::Http::ResponseWriter &response) { - PlotRequest req{.type = PlotType::SaturatedPixels, .binning = 0}; - if (plotRequest.binningIsSet()) - req.binning = plotRequest.getBinning(); - auto plot = state_machine.GetPlots(req); - ProcessOutput(Convert(plot), response); -} - void JFJochBrokerHttp::plot_bkg_estimate_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) { PlotRequest req{.type = PlotType::BkgEstimate, .binning = 0}; @@ -534,19 +564,9 @@ void JFJochBrokerHttp::plot_rad_int_get(Pistache::Http::ResponseWriter &response } void JFJochBrokerHttp::plot_rad_int_per_file_get(Pistache::Http::ResponseWriter &response) { - auto rad_int = state_machine.GetRadialIntegrationProfiles(); - nlohmann::json j; - - for (const auto &i: rad_int.profiles) { - auto output = Convert(i); - std::stringstream s; - assert(output.validate(s)); - - nlohmann::json j_elem; - to_json(j_elem, output); - j.push_back(j_elem); - } - response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json)); + PlotRequest req{.type = PlotType::RadIntPerFile}; + auto plot = state_machine.GetPlots(req); + ProcessOutput(Convert(plot), response); } void JFJochBrokerHttp::plot_spot_count_post(const org::openapitools::server::model::Plot_request &plotRequest, @@ -735,4 +755,58 @@ void JFJochBrokerHttp::config_internal_generator_image_put(const Pistache::Rest: state_machine.LoadInternalGeneratorImage(request.body().data(), request.body().size(), image_number); logger.Info("Internal generator image #{} loaded", image_number); response.send(Pistache::Http::Code::Ok); -} \ No newline at end of file +} + +void JFJochBrokerHttp::roi_box_get(Pistache::Http::ResponseWriter &response) { + ProcessOutput(Convert(state_machine.GetBoxROI()), response); +} + +void JFJochBrokerHttp::roi_box_put(const org::openapitools::server::model::Roi_box_list &roiBoxList, + Pistache::Http::ResponseWriter &response) { + state_machine.SetBoxROI(Convert(roiBoxList)); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::roi_circle_get(Pistache::Http::ResponseWriter &response) { + ProcessOutput(Convert(state_machine.GetCircleROI()), response); +} + +void JFJochBrokerHttp::roi_circle_put(const org::openapitools::server::model::Roi_circle_list &roiCircleList, + Pistache::Http::ResponseWriter &response) { + state_machine.SetCircleROI(Convert(roiCircleList)); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::xfel_event_code_get(Pistache::Http::ResponseWriter &response) { + auto array = state_machine.GetXFELEventCode(); + if (array.empty()) + response.send(Pistache::Http::Code::Not_Found); + nlohmann::json j = array; + response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json)); +} + +void JFJochBrokerHttp::xfel_pulse_id_get(Pistache::Http::ResponseWriter &response) { + auto array = state_machine.GetXFELPulseID(); + if (array.empty()) + response.send(Pistache::Http::Code::Not_Found); + nlohmann::json j = array; + response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json)); +} + +void JFJochBrokerHttp::plot_roi_max_count_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) { + PlotRequest req{.type = PlotType::ROIMaxCount, .binning = 0}; + if (plotRequest.binningIsSet()) + req.binning = plotRequest.getBinning(); + auto plot = state_machine.GetPlots(req); + ProcessOutput(Convert(plot), response); +} + +void JFJochBrokerHttp::plot_roi_valid_pixels_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) { + PlotRequest req{.type = PlotType::ROIPixels, .binning = 0}; + if (plotRequest.binningIsSet()) + req.binning = plotRequest.getBinning(); + auto plot = state_machine.GetPlots(req); + ProcessOutput(Convert(plot), response); +} diff --git a/broker/JFJochBrokerHttp.h b/broker/JFJochBrokerHttp.h index b638ecc6..65c6b453 100644 --- a/broker/JFJochBrokerHttp.h +++ b/broker/JFJochBrokerHttp.h @@ -43,8 +43,6 @@ class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi { void plot_roi_sum_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) override; - void plot_saturated_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, - Pistache::Http::ResponseWriter &response) override; void plot_error_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) override; void plot_strong_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, @@ -71,6 +69,12 @@ class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi { void plot_spot_count_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) override; + void plot_roi_max_count_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) override; + + void plot_roi_valid_pixels_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) override; + void plot_resolution_estimate_histogram_get(Pistache::Http::ResponseWriter &response) override; void statistics_calibration_get(Pistache::Http::ResponseWriter &response) override; @@ -104,9 +108,19 @@ class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi { void preview_jpeg_settings_put(const org::openapitools::server::model::Preview_settings &previewSettings, Pistache::Http::ResponseWriter &response) override; + void roi_box_get(Pistache::Http::ResponseWriter &response) override; + void roi_box_put(const org::openapitools::server::model::Roi_box_list &roiBoxList, + Pistache::Http::ResponseWriter &response) override; + void roi_circle_get(Pistache::Http::ResponseWriter &response) override; + void roi_circle_put(const org::openapitools::server::model::Roi_circle_list &roiCircleList, + Pistache::Http::ResponseWriter &response) override; + void config_internal_generator_image_put(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter &response) override; + void xfel_event_code_get(Pistache::Http::ResponseWriter &response) override; + void xfel_pulse_id_get(Pistache::Http::ResponseWriter &response) override; + void GetStaticFile(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); std::pair handleOperationException(const std::exception &ex) const noexcept override; diff --git a/broker/JFJochServices.cpp b/broker/JFJochServices.cpp index 335e20ff..9c408216 100644 --- a/broker/JFJochServices.cpp +++ b/broker/JFJochServices.cpp @@ -116,7 +116,7 @@ std::optional JFJochServices::GetReceiverStatus() { return receiver->GetStatus(); } -Plot JFJochServices::GetPlots(const PlotRequest &request) { +MultiLinePlot JFJochServices::GetPlots(const PlotRequest &request) { if (receiver == nullptr) return {}; @@ -127,17 +127,6 @@ Plot JFJochServices::GetPlots(const PlotRequest &request) { } } -RadialIntegrationProfiles JFJochServices::GetRadialIntegrationProfiles() { - if (receiver == nullptr) - return {}; - - try { - return receiver->GetRadialIntegrationProfiles(); - } catch (...) { - return {}; - } -} - void JFJochServices::SetSpotFindingSettings(const SpotFindingSettings &settings) { if (receiver) receiver->SetSpotFindingSettings(settings); @@ -180,3 +169,13 @@ void JFJochServices::LoadInternalGeneratorImage(const DiffractionExperiment &exp if (receiver) receiver->LoadInternalGeneratorImage(experiment, image, image_number); } + +void JFJochServices::GetXFELPulseID(std::vector &v) const { + if (receiver) + receiver->GetXFELPulseID(v); +} + +void JFJochServices::GetXFELEventCode(std::vector &v) const { + if (receiver) + receiver->GetXFELPulseID(v); +} diff --git a/broker/JFJochServices.h b/broker/JFJochServices.h index c749d0cc..b0389261 100644 --- a/broker/JFJochServices.h +++ b/broker/JFJochServices.h @@ -32,8 +32,7 @@ public: const std::vector &image, uint64_t image_number); std::optional GetReceiverStatus(); - Plot GetPlots(const PlotRequest &request); - RadialIntegrationProfiles GetRadialIntegrationProfiles(); + MultiLinePlot GetPlots(const PlotRequest &request); void SetSpotFindingSettings(const SpotFindingSettings &settings); JFJochServices& Receiver(JFJochReceiverService *input); @@ -42,6 +41,9 @@ public: std::string GetPreviewJPEG(const PreviewJPEGSettings &settings) const; std::string GetPreviewTIFF(bool calibration) const; + + void GetXFELPulseID(std::vector &v) const; + void GetXFELEventCode(std::vector &v) const; }; diff --git a/broker/JFJochStateMachine.cpp b/broker/JFJochStateMachine.cpp index 68527c91..07f5b35f 100644 --- a/broker/JFJochStateMachine.cpp +++ b/broker/JFJochStateMachine.cpp @@ -263,6 +263,7 @@ void JFJochStateMachine::Initialize() { logger.Info("Initialize"); state = JFJochState::Busy; + ClearMeasurementStatistics(); measurement = std::async(std::launch::async, &JFJochStateMachine::InitializeThread, this, std::move(ul)); } @@ -494,6 +495,7 @@ void JFJochStateMachine::LoadDetectorSettings(const DetectorSettings &settings) ApplyDetectorSettings(experiment, settings); break; case JFJochState::Idle: + state = JFJochState::Busy; ApplyDetectorSettings(experiment, settings); measurement = std::async(std::launch::async, &JFJochStateMachine::PedestalThread, this, std::move(ul)); break; @@ -523,14 +525,10 @@ BrokerStatus JFJochStateMachine::GetStatus() const { return ret; } -Plot JFJochStateMachine::GetPlots(const PlotRequest &request) const { +MultiLinePlot JFJochStateMachine::GetPlots(const PlotRequest &request) const { return services.GetPlots(request); } -RadialIntegrationProfiles JFJochStateMachine::GetRadialIntegrationProfiles() const { - return services.GetRadialIntegrationProfiles(); -} - void JFJochStateMachine::SetSpotFindingSettings(const SpotFindingSettings &settings) { std::unique_lock ul(data_processing_settings_mutex); DiffractionExperiment::CheckDataProcessingSettings(settings); @@ -690,3 +688,43 @@ void JFJochStateMachine::LoadInternalGeneratorImage(const void *data, size_t siz services.LoadInternalGeneratorImage(experiment, image, image_number); } + +void JFJochStateMachine::SetBoxROI(const std::vector &input) { + std::unique_lock ul(m); + + if (IsRunning()) + throw WrongDAQStateException ("ROI can be modified only when detector is not running"); + + experiment.ROI().SetROIBox(input); +} + +void JFJochStateMachine::SetCircleROI(const std::vector &input) { + std::unique_lock ul(m); + + if (IsRunning()) + throw WrongDAQStateException ("ROI can be modified only when detector is not running"); + + experiment.ROI().SetROICircle(input); +} + +std::vector JFJochStateMachine::GetBoxROI() const { + std::unique_lock ul(m); + return experiment.ROI().GetROIBox(); +} + +std::vector JFJochStateMachine::GetCircleROI() const { + std::unique_lock ul(m); + return experiment.ROI().GetROICircle(); +} + +std::vector JFJochStateMachine::GetXFELPulseID() const { + std::vector ret; + services.GetXFELPulseID(ret); + return ret; +} + +std::vector JFJochStateMachine::GetXFELEventCode() const { + std::vector ret; + services.GetXFELEventCode(ret); + return ret; +} diff --git a/broker/JFJochStateMachine.h b/broker/JFJochStateMachine.h index 4b9e4014..4e7287af 100644 --- a/broker/JFJochStateMachine.h +++ b/broker/JFJochStateMachine.h @@ -13,6 +13,7 @@ #include "../common/Logger.h" #include "JFJochServices.h" +#include "../common/ROIMask.h" enum class JFJochState {Inactive, Idle, Measuring, Error, Busy, Pedestal}; @@ -125,7 +126,6 @@ class JFJochStateMachine { bool ImportPedestalG0(const JFJochReceiverOutput &receiver_output); bool IsRunning() const; // Is state Busy/Pedestal/Measure std::optional CheckError(); - void TakePedestalInternalAll(std::unique_lock &ul); void TakePedestalInternalG0(std::unique_lock &ul); void TakePedestalInternalG1(std::unique_lock &ul, int32_t storage_cell = 0); @@ -154,8 +154,7 @@ public: std::vector GetCalibrationStatistics() const; BrokerStatus GetStatus() const; - Plot GetPlots(const PlotRequest &request) const; - RadialIntegrationProfiles GetRadialIntegrationProfiles() const; + MultiLinePlot GetPlots(const PlotRequest &request) const; void SetSpotFindingSettings(const SpotFindingSettings& settings); SpotFindingSettings GetSpotFindingSettings() const; @@ -182,6 +181,15 @@ public: // Function for debug only - UNSAFE for real operation void DebugOnly_SetState(JFJochState state); + + void SetBoxROI(const std::vector& input); + void SetCircleROI(const std::vector& input); + + std::vector GetBoxROI() const; + std::vector GetCircleROI() const; + + std::vector GetXFELPulseID() const; + std::vector GetXFELEventCode() const; }; diff --git a/broker/gen/api/DefaultApi.cpp b/broker/gen/api/DefaultApi.cpp index de8cd8dd..308ffb02 100644 --- a/broker/gen/api/DefaultApi.cpp +++ b/broker/gen/api/DefaultApi.cpp @@ -56,8 +56,9 @@ void DefaultApi::setupRoutes() { Routes::Get(*router, base + "/plot/rad_int_per_file", Routes::bind(&DefaultApi::plot_rad_int_per_file_get_handler, this)); Routes::Post(*router, base + "/plot/receiver_delay", Routes::bind(&DefaultApi::plot_receiver_delay_post_handler, this)); Routes::Get(*router, base + "/plot/resolution_estimate_histogram", Routes::bind(&DefaultApi::plot_resolution_estimate_histogram_get_handler, this)); + Routes::Post(*router, base + "/plot/roi_max_count", Routes::bind(&DefaultApi::plot_roi_max_count_post_handler, this)); Routes::Post(*router, base + "/plot/roi_sum", Routes::bind(&DefaultApi::plot_roi_sum_post_handler, this)); - Routes::Post(*router, base + "/plot/saturated_pixel", Routes::bind(&DefaultApi::plot_saturated_pixel_post_handler, this)); + Routes::Post(*router, base + "/plot/roi_valid_pixels", Routes::bind(&DefaultApi::plot_roi_valid_pixels_post_handler, this)); Routes::Post(*router, base + "/plot/spot_count", Routes::bind(&DefaultApi::plot_spot_count_post_handler, this)); Routes::Post(*router, base + "/plot/strong_pixel", Routes::bind(&DefaultApi::plot_strong_pixel_post_handler, this)); Routes::Get(*router, base + "/preview/calibration.tiff", Routes::bind(&DefaultApi::preview_calibration_tiff_get_handler, this)); @@ -65,12 +66,18 @@ void DefaultApi::setupRoutes() { Routes::Get(*router, base + "/preview/image.tiff", Routes::bind(&DefaultApi::preview_image_tiff_get_handler, this)); Routes::Get(*router, base + "/preview/jpeg_settings", Routes::bind(&DefaultApi::preview_jpeg_settings_get_handler, this)); Routes::Put(*router, base + "/preview/jpeg_settings", Routes::bind(&DefaultApi::preview_jpeg_settings_put_handler, this)); + Routes::Get(*router, base + "/roi/box", Routes::bind(&DefaultApi::roi_box_get_handler, this)); + Routes::Put(*router, base + "/roi/box", Routes::bind(&DefaultApi::roi_box_put_handler, this)); + Routes::Get(*router, base + "/roi/circle", Routes::bind(&DefaultApi::roi_circle_get_handler, this)); + Routes::Put(*router, base + "/roi/circle", Routes::bind(&DefaultApi::roi_circle_put_handler, this)); Routes::Post(*router, base + "/start", Routes::bind(&DefaultApi::start_post_handler, this)); Routes::Get(*router, base + "/statistics/calibration", Routes::bind(&DefaultApi::statistics_calibration_get_handler, this)); Routes::Get(*router, base + "/statistics/data_collection", Routes::bind(&DefaultApi::statistics_data_collection_get_handler, this)); Routes::Get(*router, base + "/status", Routes::bind(&DefaultApi::status_get_handler, this)); Routes::Post(*router, base + "/trigger", Routes::bind(&DefaultApi::trigger_post_handler, this)); Routes::Post(*router, base + "/wait_till_done", Routes::bind(&DefaultApi::wait_till_done_post_handler, this)); + Routes::Get(*router, base + "/xfel/event_code", Routes::bind(&DefaultApi::xfel_event_code_get_handler, this)); + Routes::Get(*router, base + "/xfel/pulse_id", Routes::bind(&DefaultApi::xfel_pulse_id_get_handler, this)); // Default handler, called when a route is not found router->addCustomHandler(Routes::bind(&DefaultApi::default_api_default_handler, this)); @@ -669,6 +676,39 @@ void DefaultApi::plot_resolution_estimate_histogram_get_handler(const Pistache:: response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); } +} +void DefaultApi::plot_roi_max_count_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + try { + + + // Getting the body param + + Plot_request plotRequest; + + try { + nlohmann::json::parse(request.body()).get_to(plotRequest); + plotRequest.validate(); + } catch (std::exception &e) { + const std::pair errorInfo = this->handleParsingException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + try { + this->plot_roi_max_count_post(plotRequest, response); + } catch (Pistache::Http::HttpError &e) { + response.send(static_cast(e.code()), e.what()); + return; + } catch (std::exception &e) { + const std::pair errorInfo = this->handleOperationException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + } catch (std::exception &e) { + response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); + } + } void DefaultApi::plot_roi_sum_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { try { @@ -703,7 +743,7 @@ void DefaultApi::plot_roi_sum_post_handler(const Pistache::Rest::Request &reques } } -void DefaultApi::plot_saturated_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { +void DefaultApi::plot_roi_valid_pixels_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { try { @@ -721,7 +761,7 @@ void DefaultApi::plot_saturated_pixel_post_handler(const Pistache::Rest::Request } try { - this->plot_saturated_pixel_post(plotRequest, response); + this->plot_roi_valid_pixels_post(plotRequest, response); } catch (Pistache::Http::HttpError &e) { response.send(static_cast(e.code()), e.what()); return; @@ -914,6 +954,112 @@ void DefaultApi::preview_jpeg_settings_put_handler(const Pistache::Rest::Request response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); } +} +void DefaultApi::roi_box_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->roi_box_get(response); + } catch (Pistache::Http::HttpError &e) { + response.send(static_cast(e.code()), e.what()); + return; + } catch (std::exception &e) { + const std::pair errorInfo = this->handleOperationException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + } catch (std::exception &e) { + response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); + } + +} +void DefaultApi::roi_box_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + try { + + + // Getting the body param + + Roi_box_list roiBoxList; + + try { + nlohmann::json::parse(request.body()).get_to(roiBoxList); + roiBoxList.validate(); + } catch (std::exception &e) { + const std::pair errorInfo = this->handleParsingException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + try { + this->roi_box_put(roiBoxList, response); + } catch (Pistache::Http::HttpError &e) { + response.send(static_cast(e.code()), e.what()); + return; + } catch (std::exception &e) { + const std::pair errorInfo = this->handleOperationException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + } catch (std::exception &e) { + response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); + } + +} +void DefaultApi::roi_circle_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->roi_circle_get(response); + } catch (Pistache::Http::HttpError &e) { + response.send(static_cast(e.code()), e.what()); + return; + } catch (std::exception &e) { + const std::pair errorInfo = this->handleOperationException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + } catch (std::exception &e) { + response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); + } + +} +void DefaultApi::roi_circle_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + try { + + + // Getting the body param + + Roi_circle_list roiCircleList; + + try { + nlohmann::json::parse(request.body()).get_to(roiCircleList); + roiCircleList.validate(); + } catch (std::exception &e) { + const std::pair errorInfo = this->handleParsingException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + try { + this->roi_circle_put(roiCircleList, response); + } catch (Pistache::Http::HttpError &e) { + response.send(static_cast(e.code()), e.what()); + return; + } catch (std::exception &e) { + const std::pair errorInfo = this->handleOperationException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + } catch (std::exception &e) { + response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); + } + } void DefaultApi::start_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { try { @@ -1047,6 +1193,46 @@ void DefaultApi::wait_till_done_post_handler(const Pistache::Rest::Request &, Pi response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); } +} +void DefaultApi::xfel_event_code_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->xfel_event_code_get(response); + } catch (Pistache::Http::HttpError &e) { + response.send(static_cast(e.code()), e.what()); + return; + } catch (std::exception &e) { + const std::pair errorInfo = this->handleOperationException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + } catch (std::exception &e) { + response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); + } + +} +void DefaultApi::xfel_pulse_id_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->xfel_pulse_id_get(response); + } catch (Pistache::Http::HttpError &e) { + response.send(static_cast(e.code()), e.what()); + return; + } catch (std::exception &e) { + const std::pair errorInfo = this->handleOperationException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + } catch (std::exception &e) { + response.send(Pistache::Http::Code::Internal_Server_Error, e.what()); + } + } void DefaultApi::default_api_default_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { diff --git a/broker/gen/api/DefaultApi.h b/broker/gen/api/DefaultApi.h index 14f3cc2b..ad597c7a 100644 --- a/broker/gen/api/DefaultApi.h +++ b/broker/gen/api/DefaultApi.h @@ -35,11 +35,12 @@ #include "Detector_status.h" #include "Error_message.h" #include "Measurement_statistics.h" -#include "Plot.h" #include "Plot_request.h" +#include "Plots.h" #include "Preview_settings.h" #include "Rad_int_settings.h" -#include "Radial_integration_plots_inner.h" +#include "Roi_box_list.h" +#include "Roi_circle_list.h" #include "Spot_finding_settings.h" #include @@ -80,8 +81,9 @@ private: void plot_rad_int_per_file_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void plot_receiver_delay_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void plot_resolution_estimate_histogram_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void plot_roi_max_count_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void plot_roi_sum_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); - void plot_saturated_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void plot_roi_valid_pixels_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void plot_spot_count_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void plot_strong_pixel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void preview_calibration_tiff_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); @@ -89,12 +91,18 @@ private: void preview_image_tiff_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void preview_jpeg_settings_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void preview_jpeg_settings_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void roi_box_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void roi_box_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void roi_circle_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void roi_circle_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void start_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void statistics_calibration_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void statistics_data_collection_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void status_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void trigger_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void wait_till_done_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void xfel_event_code_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void xfel_pulse_id_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); void default_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); const std::shared_ptr router; @@ -227,7 +235,7 @@ private: /// Generate error pixels plot /// /// - /// Count of error pixels per image; binning is configurable + /// Count of error (mean) and saturated (mean/max) pixels per image; binning is configurable /// /// (optional) virtual void plot_error_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0; @@ -284,6 +292,14 @@ private: /// virtual void plot_resolution_estimate_histogram_get(Pistache::Http::ResponseWriter &response) = 0; /// + /// Generate plot of ROI max count + /// + /// + /// Max count of ROI per image; binning is configurable + /// + /// (optional) + virtual void plot_roi_max_count_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0; + /// /// Generate ROI sum plot /// /// @@ -292,13 +308,13 @@ private: /// (optional) virtual void plot_roi_sum_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0; /// - /// Generate saturated pixels plot + /// Generate plot of ROI valid pixels /// /// - /// Count of saturated pixels per image; binning is configurable + /// Number of pixels within a ROI area; pixels with special values (overload, bad pixel) are excluded; multipixels are counted just once; binning is configurable /// /// (optional) - virtual void plot_saturated_pixel_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0; + virtual void plot_roi_valid_pixels_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0; /// /// Generate spot count plot /// @@ -352,6 +368,36 @@ private: /// (optional) virtual void preview_jpeg_settings_put(const org::openapitools::server::model::Preview_settings &previewSettings, Pistache::Http::ResponseWriter &response) = 0; /// + /// Get box ROIs + /// + /// + /// + /// + virtual void roi_box_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Upload box ROIs + /// + /// + /// + /// + /// (optional) + virtual void roi_box_put(const org::openapitools::server::model::Roi_box_list &roiBoxList, Pistache::Http::ResponseWriter &response) = 0; + /// + /// Get circular ROI + /// + /// + /// + /// + virtual void roi_circle_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Upload circular ROI + /// + /// + /// + /// + /// (optional) + virtual void roi_circle_put(const org::openapitools::server::model::Roi_circle_list &roiCircleList, Pistache::Http::ResponseWriter &response) = 0; + /// /// Start detector /// /// @@ -394,6 +440,20 @@ private: /// Block execution of external script till initialization, data collection or pedestal is finished. Running this command does not affect (cancel) running data collection, it is only to ensure synchronous execution of other software. To not block web server for a long period of time, the procedure is provided with a timeout of 5 seconds. /// virtual void wait_till_done_post(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Return XFEL event codes for the current data acquisition + /// + /// + /// Return array of XFEL event codes + /// + virtual void xfel_event_code_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Return XFEL pulse IDs for the current data acquisition + /// + /// + /// Return array of XFEL pulse IDs - (-1) if image not recorded + /// + virtual void xfel_pulse_id_get(Pistache::Http::ResponseWriter &response) = 0; }; diff --git a/broker/gen/model/Dataset_settings.cpp b/broker/gen/model/Dataset_settings.cpp index 09db600d..9502252d 100644 --- a/broker/gen/model/Dataset_settings.cpp +++ b/broker/gen/model/Dataset_settings.cpp @@ -55,7 +55,6 @@ Dataset_settings::Dataset_settings() m_Image_appendixIsSet = false; m_Photon_energy_multiplier = 1.0f; m_Photon_energy_multiplierIsSet = false; - m_Roi_sum_areaIsSet = false; m_Unit_cellIsSet = false; } @@ -225,7 +224,7 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP } } - + return success; } @@ -295,9 +294,6 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const ((!photonEnergyMultiplierIsSet() && !rhs.photonEnergyMultiplierIsSet()) || (photonEnergyMultiplierIsSet() && rhs.photonEnergyMultiplierIsSet() && getPhotonEnergyMultiplier() == rhs.getPhotonEnergyMultiplier())) && - ((!roiSumAreaIsSet() && !rhs.roiSumAreaIsSet()) || (roiSumAreaIsSet() && rhs.roiSumAreaIsSet() && getRoiSumArea() == rhs.getRoiSumArea())) && - - ((!unitCellIsSet() && !rhs.unitCellIsSet()) || (unitCellIsSet() && rhs.unitCellIsSet() && getUnitCell() == rhs.getUnitCell())) ; @@ -346,8 +342,6 @@ void to_json(nlohmann::json& j, const Dataset_settings& o) j["image_appendix"] = o.m_Image_appendix; if(o.photonEnergyMultiplierIsSet()) j["photon_energy_multiplier"] = o.m_Photon_energy_multiplier; - if(o.roiSumAreaIsSet()) - j["roi_sum_area"] = o.m_Roi_sum_area; if(o.unitCellIsSet()) j["unit_cell"] = o.m_Unit_cell; @@ -435,11 +429,6 @@ void from_json(const nlohmann::json& j, Dataset_settings& o) j.at("photon_energy_multiplier").get_to(o.m_Photon_energy_multiplier); o.m_Photon_energy_multiplierIsSet = true; } - if(j.find("roi_sum_area") != j.end()) - { - j.at("roi_sum_area").get_to(o.m_Roi_sum_area); - o.m_Roi_sum_areaIsSet = true; - } if(j.find("unit_cell") != j.end()) { j.at("unit_cell").get_to(o.m_Unit_cell); @@ -743,23 +732,6 @@ void Dataset_settings::unsetPhoton_energy_multiplier() { m_Photon_energy_multiplierIsSet = false; } -org::openapitools::server::model::Dataset_settings_roi_sum_area Dataset_settings::getRoiSumArea() const -{ - return m_Roi_sum_area; -} -void Dataset_settings::setRoiSumArea(org::openapitools::server::model::Dataset_settings_roi_sum_area const& value) -{ - m_Roi_sum_area = value; - m_Roi_sum_areaIsSet = true; -} -bool Dataset_settings::roiSumAreaIsSet() const -{ - return m_Roi_sum_areaIsSet; -} -void Dataset_settings::unsetRoi_sum_area() -{ - m_Roi_sum_areaIsSet = false; -} org::openapitools::server::model::Dataset_settings_unit_cell Dataset_settings::getUnitCell() const { return m_Unit_cell; diff --git a/broker/gen/model/Dataset_settings.h b/broker/gen/model/Dataset_settings.h index b9209f45..697071fc 100644 --- a/broker/gen/model/Dataset_settings.h +++ b/broker/gen/model/Dataset_settings.h @@ -21,7 +21,6 @@ #include "Rotation_axis.h" #include -#include "Dataset_settings_roi_sum_area.h" #include "Dataset_settings_unit_cell.h" #include @@ -194,13 +193,6 @@ public: /// /// /// - org::openapitools::server::model::Dataset_settings_roi_sum_area getRoiSumArea() const; - void setRoiSumArea(org::openapitools::server::model::Dataset_settings_roi_sum_area const& value); - bool roiSumAreaIsSet() const; - void unsetRoi_sum_area(); - /// - /// - /// org::openapitools::server::model::Dataset_settings_unit_cell getUnitCell() const; void setUnitCell(org::openapitools::server::model::Dataset_settings_unit_cell const& value); bool unitCellIsSet() const; @@ -249,8 +241,6 @@ protected: bool m_Image_appendixIsSet; float m_Photon_energy_multiplier; bool m_Photon_energy_multiplierIsSet; - org::openapitools::server::model::Dataset_settings_roi_sum_area m_Roi_sum_area; - bool m_Roi_sum_areaIsSet; org::openapitools::server::model::Dataset_settings_unit_cell m_Unit_cell; bool m_Unit_cellIsSet; diff --git a/broker/gen/model/Dataset_settings_unit_cell.cpp b/broker/gen/model/Dataset_settings_unit_cell.cpp index b051bb7c..88247e89 100644 --- a/broker/gen/model/Dataset_settings_unit_cell.cpp +++ b/broker/gen/model/Dataset_settings_unit_cell.cpp @@ -49,7 +49,106 @@ bool Dataset_settings_unit_cell::validate(std::stringstream& msg, const std::str bool success = true; const std::string _pathPrefix = pathPrefix.empty() ? "Dataset_settings_unit_cell" : pathPrefix; - + + + /* a */ { + const float& value = m_a; + const std::string currentValuePath = _pathPrefix + ".A"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* b */ { + const float& value = m_b; + const std::string currentValuePath = _pathPrefix + ".B"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* c */ { + const float& value = m_c; + const std::string currentValuePath = _pathPrefix + ".C"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Alpha */ { + const float& value = m_Alpha; + const std::string currentValuePath = _pathPrefix + ".alpha"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + if (value > static_cast(360)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 360;"; + } + + } + + + /* Beta */ { + const float& value = m_Beta; + const std::string currentValuePath = _pathPrefix + ".beta"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + if (value > static_cast(360)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 360;"; + } + + } + + + /* Gamma */ { + const float& value = m_Gamma; + const std::string currentValuePath = _pathPrefix + ".gamma"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + if (value > static_cast(360)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 360;"; + } + + } + return success; } diff --git a/broker/gen/model/Plot.cpp b/broker/gen/model/Plot.cpp index 67a241b8..72cc47b6 100644 --- a/broker/gen/model/Plot.cpp +++ b/broker/gen/model/Plot.cpp @@ -21,6 +21,7 @@ namespace org::openapitools::server::model Plot::Plot() { + m_Title = ""; } @@ -43,7 +44,7 @@ bool Plot::validate(std::stringstream& msg, const std::string& pathPrefix) const bool success = true; const std::string _pathPrefix = pathPrefix.empty() ? "Plot" : pathPrefix; - + /* x */ { const std::vector& value = m_x; @@ -94,6 +95,9 @@ bool Plot::operator==(const Plot& rhs) const return + (getTitle() == rhs.getTitle()) + && + (getX() == rhs.getX()) && @@ -111,6 +115,7 @@ bool Plot::operator!=(const Plot& rhs) const void to_json(nlohmann::json& j, const Plot& o) { j = nlohmann::json(); + j["title"] = o.m_Title; j["x"] = o.m_x; j["y"] = o.m_y; @@ -118,11 +123,20 @@ void to_json(nlohmann::json& j, const Plot& o) void from_json(const nlohmann::json& j, Plot& o) { + j.at("title").get_to(o.m_Title); j.at("x").get_to(o.m_x); j.at("y").get_to(o.m_y); } +std::string Plot::getTitle() const +{ + return m_Title; +} +void Plot::setTitle(std::string const& value) +{ + m_Title = value; +} std::vector Plot::getX() const { return m_x; diff --git a/broker/gen/model/Plot.h b/broker/gen/model/Plot.h index 67d2a77d..b0899da4 100644 --- a/broker/gen/model/Plot.h +++ b/broker/gen/model/Plot.h @@ -19,6 +19,7 @@ #define Plot_H_ +#include #include #include @@ -58,6 +59,11 @@ public: ///////////////////////////////////////////// /// Plot members + /// + /// + /// + std::string getTitle() const; + void setTitle(std::string const& value); /// /// /// @@ -72,6 +78,8 @@ public: friend void to_json(nlohmann::json& j, const Plot& o); friend void from_json(const nlohmann::json& j, Plot& o); protected: + std::string m_Title; + std::vector m_x; std::vector m_y; diff --git a/broker/gen/model/Plots.cpp b/broker/gen/model/Plots.cpp new file mode 100644 index 00000000..a94d2e4e --- /dev/null +++ b/broker/gen/model/Plots.cpp @@ -0,0 +1,140 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Plots.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Plots::Plots() +{ + m_Title = ""; + m_TitleIsSet = false; + +} + +void Plots::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Plots::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Plots::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Plots" : pathPrefix; + + + + /* Plot */ { + const std::vector& value = m_Plot; + const std::string currentValuePath = _pathPrefix + ".plot"; + + + { // Recursive validation of array elements + const std::string oldValuePath = currentValuePath; + int i = 0; + for (const org::openapitools::server::model::Plot& value : value) + { + const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]"; + + success = value.validate(msg, currentValuePath + ".plot") && success; + + i++; + } + } + + } + + return success; +} + +bool Plots::operator==(const Plots& rhs) const +{ + return + + + + ((!titleIsSet() && !rhs.titleIsSet()) || (titleIsSet() && rhs.titleIsSet() && getTitle() == rhs.getTitle())) && + + (getPlot() == rhs.getPlot()) + + + ; +} + +bool Plots::operator!=(const Plots& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Plots& o) +{ + j = nlohmann::json(); + if(o.titleIsSet()) + j["title"] = o.m_Title; + j["plot"] = o.m_Plot; + +} + +void from_json(const nlohmann::json& j, Plots& o) +{ + if(j.find("title") != j.end()) + { + j.at("title").get_to(o.m_Title); + o.m_TitleIsSet = true; + } + j.at("plot").get_to(o.m_Plot); + +} + +std::string Plots::getTitle() const +{ + return m_Title; +} +void Plots::setTitle(std::string const& value) +{ + m_Title = value; + m_TitleIsSet = true; +} +bool Plots::titleIsSet() const +{ + return m_TitleIsSet; +} +void Plots::unsetTitle() +{ + m_TitleIsSet = false; +} +std::vector Plots::getPlot() const +{ + return m_Plot; +} +void Plots::setPlot(std::vector const& value) +{ + m_Plot = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Radial_integration_plots_inner.h b/broker/gen/model/Plots.h similarity index 62% rename from broker/gen/model/Radial_integration_plots_inner.h rename to broker/gen/model/Plots.h index 546cce4d..7a79bce2 100644 --- a/broker/gen/model/Radial_integration_plots_inner.h +++ b/broker/gen/model/Plots.h @@ -10,17 +10,18 @@ * Do not edit the class manually. */ /* - * Radial_integration_plots_inner.h + * Plots.h * * */ -#ifndef Radial_integration_plots_inner_H_ -#define Radial_integration_plots_inner_H_ +#ifndef Plots_H_ +#define Plots_H_ #include "Plot.h" #include +#include #include namespace org::openapitools::server::model @@ -29,11 +30,11 @@ namespace org::openapitools::server::model /// /// /// -class Radial_integration_plots_inner +class Plots { public: - Radial_integration_plots_inner(); - virtual ~Radial_integration_plots_inner() = default; + Plots(); + virtual ~Plots() = default; /// @@ -53,33 +54,35 @@ public: /// bool validate(std::stringstream& msg, const std::string& pathPrefix) const; - bool operator==(const Radial_integration_plots_inner& rhs) const; - bool operator!=(const Radial_integration_plots_inner& rhs) const; + bool operator==(const Plots& rhs) const; + bool operator!=(const Plots& rhs) const; ///////////////////////////////////////////// - /// Radial_integration_plots_inner members + /// Plots members /// /// /// std::string getTitle() const; void setTitle(std::string const& value); + bool titleIsSet() const; + void unsetTitle(); /// /// /// - org::openapitools::server::model::Plot getPlot() const; - void setPlot(org::openapitools::server::model::Plot const& value); + std::vector getPlot() const; + void setPlot(std::vector const& value); - friend void to_json(nlohmann::json& j, const Radial_integration_plots_inner& o); - friend void from_json(const nlohmann::json& j, Radial_integration_plots_inner& o); + friend void to_json(nlohmann::json& j, const Plots& o); + friend void from_json(const nlohmann::json& j, Plots& o); protected: std::string m_Title; - - org::openapitools::server::model::Plot m_Plot; + bool m_TitleIsSet; + std::vector m_Plot; }; } // namespace org::openapitools::server::model -#endif /* Radial_integration_plots_inner_H_ */ +#endif /* Plots_H_ */ diff --git a/broker/gen/model/Preview_settings.cpp b/broker/gen/model/Preview_settings.cpp index 226bb4b1..8fbeed75 100644 --- a/broker/gen/model/Preview_settings.cpp +++ b/broker/gen/model/Preview_settings.cpp @@ -24,6 +24,8 @@ Preview_settings::Preview_settings() m_Saturation = 0L; m_Show_spots = true; m_Show_spotsIsSet = false; + m_Show_roi = false; + m_Show_roiIsSet = false; m_Jpeg_quality = 0L; m_Jpeg_qualityIsSet = false; @@ -67,7 +69,7 @@ bool Preview_settings::validate(std::stringstream& msg, const std::string& pathP } } - + if (jpegQualityIsSet()) { const int64_t& value = m_Jpeg_quality; @@ -102,6 +104,9 @@ bool Preview_settings::operator==(const Preview_settings& rhs) const ((!showSpotsIsSet() && !rhs.showSpotsIsSet()) || (showSpotsIsSet() && rhs.showSpotsIsSet() && isShowSpots() == rhs.isShowSpots())) && + ((!showRoiIsSet() && !rhs.showRoiIsSet()) || (showRoiIsSet() && rhs.showRoiIsSet() && isShowRoi() == rhs.isShowRoi())) && + + ((!jpegQualityIsSet() && !rhs.jpegQualityIsSet()) || (jpegQualityIsSet() && rhs.jpegQualityIsSet() && getJpegQuality() == rhs.getJpegQuality())) ; @@ -118,6 +123,8 @@ void to_json(nlohmann::json& j, const Preview_settings& o) j["saturation"] = o.m_Saturation; if(o.showSpotsIsSet()) j["show_spots"] = o.m_Show_spots; + if(o.showRoiIsSet()) + j["show_roi"] = o.m_Show_roi; if(o.jpegQualityIsSet()) j["jpeg_quality"] = o.m_Jpeg_quality; @@ -131,6 +138,11 @@ void from_json(const nlohmann::json& j, Preview_settings& o) j.at("show_spots").get_to(o.m_Show_spots); o.m_Show_spotsIsSet = true; } + if(j.find("show_roi") != j.end()) + { + j.at("show_roi").get_to(o.m_Show_roi); + o.m_Show_roiIsSet = true; + } if(j.find("jpeg_quality") != j.end()) { j.at("jpeg_quality").get_to(o.m_Jpeg_quality); @@ -164,6 +176,23 @@ void Preview_settings::unsetShow_spots() { m_Show_spotsIsSet = false; } +bool Preview_settings::isShowRoi() const +{ + return m_Show_roi; +} +void Preview_settings::setShowRoi(bool const value) +{ + m_Show_roi = value; + m_Show_roiIsSet = true; +} +bool Preview_settings::showRoiIsSet() const +{ + return m_Show_roiIsSet; +} +void Preview_settings::unsetShow_roi() +{ + m_Show_roiIsSet = false; +} int64_t Preview_settings::getJpegQuality() const { return m_Jpeg_quality; diff --git a/broker/gen/model/Preview_settings.h b/broker/gen/model/Preview_settings.h index de443621..ab0a6806 100644 --- a/broker/gen/model/Preview_settings.h +++ b/broker/gen/model/Preview_settings.h @@ -70,6 +70,13 @@ public: bool showSpotsIsSet() const; void unsetShow_spots(); /// + /// Show ROI areas on the image + /// + bool isShowRoi() const; + void setShowRoi(bool const value); + bool showRoiIsSet() const; + void unsetShow_roi(); + /// /// Quality of JPEG image (100 - highest; 0 - lowest) /// int64_t getJpegQuality() const; @@ -84,6 +91,8 @@ protected: bool m_Show_spots; bool m_Show_spotsIsSet; + bool m_Show_roi; + bool m_Show_roiIsSet; int64_t m_Jpeg_quality; bool m_Jpeg_qualityIsSet; diff --git a/broker/gen/model/Radial_integration_plots_inner.cpp b/broker/gen/model/Radial_integration_plots_inner.cpp deleted file mode 100644 index 860aae1c..00000000 --- a/broker/gen/model/Radial_integration_plots_inner.cpp +++ /dev/null @@ -1,104 +0,0 @@ -/** -* Jungfraujoch -* Jungfraujoch Broker Web API -* -* The version of the OpenAPI document: 1.0.1 -* -* -* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). -* https://openapi-generator.tech -* Do not edit the class manually. -*/ - - -#include "Radial_integration_plots_inner.h" -#include "Helpers.h" - -#include - -namespace org::openapitools::server::model -{ - -Radial_integration_plots_inner::Radial_integration_plots_inner() -{ - m_Title = ""; - -} - -void Radial_integration_plots_inner::validate() const -{ - std::stringstream msg; - if (!validate(msg)) - { - throw org::openapitools::server::helpers::ValidationException(msg.str()); - } -} - -bool Radial_integration_plots_inner::validate(std::stringstream& msg) const -{ - return validate(msg, ""); -} - -bool Radial_integration_plots_inner::validate(std::stringstream& msg, const std::string& pathPrefix) const -{ - bool success = true; - const std::string _pathPrefix = pathPrefix.empty() ? "Radial_integration_plots_inner" : pathPrefix; - - - return success; -} - -bool Radial_integration_plots_inner::operator==(const Radial_integration_plots_inner& rhs) const -{ - return - - - (getTitle() == rhs.getTitle()) - && - - (getPlot() == rhs.getPlot()) - - - ; -} - -bool Radial_integration_plots_inner::operator!=(const Radial_integration_plots_inner& rhs) const -{ - return !(*this == rhs); -} - -void to_json(nlohmann::json& j, const Radial_integration_plots_inner& o) -{ - j = nlohmann::json(); - j["title"] = o.m_Title; - j["plot"] = o.m_Plot; - -} - -void from_json(const nlohmann::json& j, Radial_integration_plots_inner& o) -{ - j.at("title").get_to(o.m_Title); - j.at("plot").get_to(o.m_Plot); - -} - -std::string Radial_integration_plots_inner::getTitle() const -{ - return m_Title; -} -void Radial_integration_plots_inner::setTitle(std::string const& value) -{ - m_Title = value; -} -org::openapitools::server::model::Plot Radial_integration_plots_inner::getPlot() const -{ - return m_Plot; -} -void Radial_integration_plots_inner::setPlot(org::openapitools::server::model::Plot const& value) -{ - m_Plot = value; -} - - -} // namespace org::openapitools::server::model - diff --git a/broker/gen/model/Roi_box.cpp b/broker/gen/model/Roi_box.cpp new file mode 100644 index 00000000..d1ae2970 --- /dev/null +++ b/broker/gen/model/Roi_box.cpp @@ -0,0 +1,217 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Roi_box.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Roi_box::Roi_box() +{ + m_Name = ""; + m_Min_x_pxl = 0L; + m_Max_x_pxl = 0L; + m_Min_y_pxl = 0L; + m_Max_y_pxl = 0L; + +} + +void Roi_box::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Roi_box::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Roi_box::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Roi_box" : pathPrefix; + + + + /* Name */ { + const std::string& value = m_Name; + const std::string currentValuePath = _pathPrefix + ".name"; + + + if (value.length() < 1) + { + success = false; + msg << currentValuePath << ": must be at least 1 characters long;"; + } + + } + + + /* Min_x_pxl */ { + const int64_t& value = m_Min_x_pxl; + const std::string currentValuePath = _pathPrefix + ".minXPxl"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Max_x_pxl */ { + const int64_t& value = m_Max_x_pxl; + const std::string currentValuePath = _pathPrefix + ".maxXPxl"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Min_y_pxl */ { + const int64_t& value = m_Min_y_pxl; + const std::string currentValuePath = _pathPrefix + ".minYPxl"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Max_y_pxl */ { + const int64_t& value = m_Max_y_pxl; + const std::string currentValuePath = _pathPrefix + ".maxYPxl"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + return success; +} + +bool Roi_box::operator==(const Roi_box& rhs) const +{ + return + + + (getName() == rhs.getName()) + && + + (getMinXPxl() == rhs.getMinXPxl()) + && + + (getMaxXPxl() == rhs.getMaxXPxl()) + && + + (getMinYPxl() == rhs.getMinYPxl()) + && + + (getMaxYPxl() == rhs.getMaxYPxl()) + + + ; +} + +bool Roi_box::operator!=(const Roi_box& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Roi_box& o) +{ + j = nlohmann::json(); + j["name"] = o.m_Name; + j["min_x_pxl"] = o.m_Min_x_pxl; + j["max_x_pxl"] = o.m_Max_x_pxl; + j["min_y_pxl"] = o.m_Min_y_pxl; + j["max_y_pxl"] = o.m_Max_y_pxl; + +} + +void from_json(const nlohmann::json& j, Roi_box& o) +{ + j.at("name").get_to(o.m_Name); + j.at("min_x_pxl").get_to(o.m_Min_x_pxl); + j.at("max_x_pxl").get_to(o.m_Max_x_pxl); + j.at("min_y_pxl").get_to(o.m_Min_y_pxl); + j.at("max_y_pxl").get_to(o.m_Max_y_pxl); + +} + +std::string Roi_box::getName() const +{ + return m_Name; +} +void Roi_box::setName(std::string const& value) +{ + m_Name = value; +} +int64_t Roi_box::getMinXPxl() const +{ + return m_Min_x_pxl; +} +void Roi_box::setMinXPxl(int64_t const value) +{ + m_Min_x_pxl = value; +} +int64_t Roi_box::getMaxXPxl() const +{ + return m_Max_x_pxl; +} +void Roi_box::setMaxXPxl(int64_t const value) +{ + m_Max_x_pxl = value; +} +int64_t Roi_box::getMinYPxl() const +{ + return m_Min_y_pxl; +} +void Roi_box::setMinYPxl(int64_t const value) +{ + m_Min_y_pxl = value; +} +int64_t Roi_box::getMaxYPxl() const +{ + return m_Max_y_pxl; +} +void Roi_box::setMaxYPxl(int64_t const value) +{ + m_Max_y_pxl = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Roi_box.h b/broker/gen/model/Roi_box.h new file mode 100644 index 00000000..dbfd8f30 --- /dev/null +++ b/broker/gen/model/Roi_box.h @@ -0,0 +1,105 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Roi_box.h + * + * Box ROI + */ + +#ifndef Roi_box_H_ +#define Roi_box_H_ + + +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// Box ROI +/// +class Roi_box +{ +public: + Roi_box(); + virtual ~Roi_box() = default; + + + /// + /// Validate the current data in the model. Throws a ValidationException on failure. + /// + void validate() const; + + /// + /// Validate the current data in the model. Returns false on error and writes an error + /// message into the given stringstream. + /// + bool validate(std::stringstream& msg) const; + + /// + /// Helper overload for validate. Used when one model stores another model and calls it's validate. + /// Not meant to be called outside that case. + /// + bool validate(std::stringstream& msg, const std::string& pathPrefix) const; + + bool operator==(const Roi_box& rhs) const; + bool operator!=(const Roi_box& rhs) const; + + ///////////////////////////////////////////// + /// Roi_box members + + /// + /// Name for the ROI; used in the plots + /// + std::string getName() const; + void setName(std::string const& value); + /// + /// Lower bound (inclusive) in X coordinate for the box + /// + int64_t getMinXPxl() const; + void setMinXPxl(int64_t const value); + /// + /// Upper bound (inclusive) in X coordinate for the box + /// + int64_t getMaxXPxl() const; + void setMaxXPxl(int64_t const value); + /// + /// Lower bound (inclusive) in Y coordinate for the box + /// + int64_t getMinYPxl() const; + void setMinYPxl(int64_t const value); + /// + /// Upper bound (inclusive) in Y coordinate for the box + /// + int64_t getMaxYPxl() const; + void setMaxYPxl(int64_t const value); + + friend void to_json(nlohmann::json& j, const Roi_box& o); + friend void from_json(const nlohmann::json& j, Roi_box& o); +protected: + std::string m_Name; + + int64_t m_Min_x_pxl; + + int64_t m_Max_x_pxl; + + int64_t m_Min_y_pxl; + + int64_t m_Max_y_pxl; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Roi_box_H_ */ diff --git a/broker/gen/model/Roi_box_list.cpp b/broker/gen/model/Roi_box_list.cpp new file mode 100644 index 00000000..51ec78ae --- /dev/null +++ b/broker/gen/model/Roi_box_list.cpp @@ -0,0 +1,131 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Roi_box_list.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Roi_box_list::Roi_box_list() +{ + m_RoisIsSet = false; + +} + +void Roi_box_list::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Roi_box_list::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Roi_box_list::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Roi_box_list" : pathPrefix; + + + if (roisIsSet()) + { + const std::vector& value = m_Rois; + const std::string currentValuePath = _pathPrefix + ".rois"; + + + if (value.size() > 32) + { + success = false; + msg << currentValuePath << ": must have at most 32 elements;"; + } + { // Recursive validation of array elements + const std::string oldValuePath = currentValuePath; + int i = 0; + for (const org::openapitools::server::model::Roi_box& value : value) + { + const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]"; + + success = value.validate(msg, currentValuePath + ".rois") && success; + + i++; + } + } + + } + + return success; +} + +bool Roi_box_list::operator==(const Roi_box_list& rhs) const +{ + return + + + + ((!roisIsSet() && !rhs.roisIsSet()) || (roisIsSet() && rhs.roisIsSet() && getRois() == rhs.getRois())) + + ; +} + +bool Roi_box_list::operator!=(const Roi_box_list& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Roi_box_list& o) +{ + j = nlohmann::json(); + if(o.roisIsSet() || !o.m_Rois.empty()) + j["rois"] = o.m_Rois; + +} + +void from_json(const nlohmann::json& j, Roi_box_list& o) +{ + if(j.find("rois") != j.end()) + { + j.at("rois").get_to(o.m_Rois); + o.m_RoisIsSet = true; + } + +} + +std::vector Roi_box_list::getRois() const +{ + return m_Rois; +} +void Roi_box_list::setRois(std::vector const& value) +{ + m_Rois = value; + m_RoisIsSet = true; +} +bool Roi_box_list::roisIsSet() const +{ + return m_RoisIsSet; +} +void Roi_box_list::unsetRois() +{ + m_RoisIsSet = false; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Roi_box_list.h b/broker/gen/model/Roi_box_list.h new file mode 100644 index 00000000..714dc69f --- /dev/null +++ b/broker/gen/model/Roi_box_list.h @@ -0,0 +1,80 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Roi_box_list.h + * + * List of box ROIs + */ + +#ifndef Roi_box_list_H_ +#define Roi_box_list_H_ + + +#include +#include "Roi_box.h" +#include + +namespace org::openapitools::server::model +{ + +/// +/// List of box ROIs +/// +class Roi_box_list +{ +public: + Roi_box_list(); + virtual ~Roi_box_list() = default; + + + /// + /// Validate the current data in the model. Throws a ValidationException on failure. + /// + void validate() const; + + /// + /// Validate the current data in the model. Returns false on error and writes an error + /// message into the given stringstream. + /// + bool validate(std::stringstream& msg) const; + + /// + /// Helper overload for validate. Used when one model stores another model and calls it's validate. + /// Not meant to be called outside that case. + /// + bool validate(std::stringstream& msg, const std::string& pathPrefix) const; + + bool operator==(const Roi_box_list& rhs) const; + bool operator!=(const Roi_box_list& rhs) const; + + ///////////////////////////////////////////// + /// Roi_box_list members + + /// + /// + /// + std::vector getRois() const; + void setRois(std::vector const& value); + bool roisIsSet() const; + void unsetRois(); + + friend void to_json(nlohmann::json& j, const Roi_box_list& o); + friend void from_json(const nlohmann::json& j, Roi_box_list& o); +protected: + std::vector m_Rois; + bool m_RoisIsSet; + +}; + +} // namespace org::openapitools::server::model + +#endif /* Roi_box_list_H_ */ diff --git a/broker/gen/model/Roi_circle.cpp b/broker/gen/model/Roi_circle.cpp new file mode 100644 index 00000000..7b7c4902 --- /dev/null +++ b/broker/gen/model/Roi_circle.cpp @@ -0,0 +1,161 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Roi_circle.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Roi_circle::Roi_circle() +{ + m_Name = ""; + m_Center_x_pxl = 0.0f; + m_Center_y_pxl = 0.0f; + m_Radius_pxl = 0.0f; + +} + +void Roi_circle::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Roi_circle::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Roi_circle::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Roi_circle" : pathPrefix; + + + + /* Name */ { + const std::string& value = m_Name; + const std::string currentValuePath = _pathPrefix + ".name"; + + + if (value.length() < 1) + { + success = false; + msg << currentValuePath << ": must be at least 1 characters long;"; + } + + } + + + /* Radius_pxl */ { + const float& value = m_Radius_pxl; + const std::string currentValuePath = _pathPrefix + ".radiusPxl"; + + + if (value <= static_cast(0.0)) + { + success = false; + msg << currentValuePath << ": must be greater than 0.0;"; + } + + } + + return success; +} + +bool Roi_circle::operator==(const Roi_circle& rhs) const +{ + return + + + (getName() == rhs.getName()) + && + + (getCenterXPxl() == rhs.getCenterXPxl()) + && + + (getCenterYPxl() == rhs.getCenterYPxl()) + && + + (getRadiusPxl() == rhs.getRadiusPxl()) + + + ; +} + +bool Roi_circle::operator!=(const Roi_circle& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Roi_circle& o) +{ + j = nlohmann::json(); + j["name"] = o.m_Name; + j["center_x_pxl"] = o.m_Center_x_pxl; + j["center_y_pxl"] = o.m_Center_y_pxl; + j["radius_pxl"] = o.m_Radius_pxl; + +} + +void from_json(const nlohmann::json& j, Roi_circle& o) +{ + j.at("name").get_to(o.m_Name); + j.at("center_x_pxl").get_to(o.m_Center_x_pxl); + j.at("center_y_pxl").get_to(o.m_Center_y_pxl); + j.at("radius_pxl").get_to(o.m_Radius_pxl); + +} + +std::string Roi_circle::getName() const +{ + return m_Name; +} +void Roi_circle::setName(std::string const& value) +{ + m_Name = value; +} +float Roi_circle::getCenterXPxl() const +{ + return m_Center_x_pxl; +} +void Roi_circle::setCenterXPxl(float const value) +{ + m_Center_x_pxl = value; +} +float Roi_circle::getCenterYPxl() const +{ + return m_Center_y_pxl; +} +void Roi_circle::setCenterYPxl(float const value) +{ + m_Center_y_pxl = value; +} +float Roi_circle::getRadiusPxl() const +{ + return m_Radius_pxl; +} +void Roi_circle::setRadiusPxl(float const value) +{ + m_Radius_pxl = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Roi_circle.h b/broker/gen/model/Roi_circle.h new file mode 100644 index 00000000..6c33e5e0 --- /dev/null +++ b/broker/gen/model/Roi_circle.h @@ -0,0 +1,98 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Roi_circle.h + * + * Circular ROI + */ + +#ifndef Roi_circle_H_ +#define Roi_circle_H_ + + +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// Circular ROI +/// +class Roi_circle +{ +public: + Roi_circle(); + virtual ~Roi_circle() = default; + + + /// + /// Validate the current data in the model. Throws a ValidationException on failure. + /// + void validate() const; + + /// + /// Validate the current data in the model. Returns false on error and writes an error + /// message into the given stringstream. + /// + bool validate(std::stringstream& msg) const; + + /// + /// Helper overload for validate. Used when one model stores another model and calls it's validate. + /// Not meant to be called outside that case. + /// + bool validate(std::stringstream& msg, const std::string& pathPrefix) const; + + bool operator==(const Roi_circle& rhs) const; + bool operator!=(const Roi_circle& rhs) const; + + ///////////////////////////////////////////// + /// Roi_circle members + + /// + /// Name for the ROI; used in the plots + /// + std::string getName() const; + void setName(std::string const& value); + /// + /// X coordinate of center of the circle [pixels] + /// + float getCenterXPxl() const; + void setCenterXPxl(float const value); + /// + /// Y coordinate of center of the circle [pixels] + /// + float getCenterYPxl() const; + void setCenterYPxl(float const value); + /// + /// Radius of the circle [pixels] + /// + float getRadiusPxl() const; + void setRadiusPxl(float const value); + + friend void to_json(nlohmann::json& j, const Roi_circle& o); + friend void from_json(const nlohmann::json& j, Roi_circle& o); +protected: + std::string m_Name; + + float m_Center_x_pxl; + + float m_Center_y_pxl; + + float m_Radius_pxl; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Roi_circle_H_ */ diff --git a/broker/gen/model/Roi_circle_list.cpp b/broker/gen/model/Roi_circle_list.cpp new file mode 100644 index 00000000..4028505d --- /dev/null +++ b/broker/gen/model/Roi_circle_list.cpp @@ -0,0 +1,116 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Roi_circle_list.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Roi_circle_list::Roi_circle_list() +{ + +} + +void Roi_circle_list::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Roi_circle_list::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Roi_circle_list::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Roi_circle_list" : pathPrefix; + + + + /* Rois */ { + const std::vector& value = m_Rois; + const std::string currentValuePath = _pathPrefix + ".rois"; + + + if (value.size() > 32) + { + success = false; + msg << currentValuePath << ": must have at most 32 elements;"; + } + { // Recursive validation of array elements + const std::string oldValuePath = currentValuePath; + int i = 0; + for (const org::openapitools::server::model::Roi_circle& value : value) + { + const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]"; + + success = value.validate(msg, currentValuePath + ".rois") && success; + + i++; + } + } + + } + + return success; +} + +bool Roi_circle_list::operator==(const Roi_circle_list& rhs) const +{ + return + + + (getRois() == rhs.getRois()) + + + ; +} + +bool Roi_circle_list::operator!=(const Roi_circle_list& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Roi_circle_list& o) +{ + j = nlohmann::json(); + j["rois"] = o.m_Rois; + +} + +void from_json(const nlohmann::json& j, Roi_circle_list& o) +{ + j.at("rois").get_to(o.m_Rois); + +} + +std::vector Roi_circle_list::getRois() const +{ + return m_Rois; +} +void Roi_circle_list::setRois(std::vector const& value) +{ + m_Rois = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Roi_circle_list.h b/broker/gen/model/Roi_circle_list.h new file mode 100644 index 00000000..96cf0db1 --- /dev/null +++ b/broker/gen/model/Roi_circle_list.h @@ -0,0 +1,78 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.1 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Roi_circle_list.h + * + * List of circular ROIs + */ + +#ifndef Roi_circle_list_H_ +#define Roi_circle_list_H_ + + +#include "Roi_circle.h" +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// List of circular ROIs +/// +class Roi_circle_list +{ +public: + Roi_circle_list(); + virtual ~Roi_circle_list() = default; + + + /// + /// Validate the current data in the model. Throws a ValidationException on failure. + /// + void validate() const; + + /// + /// Validate the current data in the model. Returns false on error and writes an error + /// message into the given stringstream. + /// + bool validate(std::stringstream& msg) const; + + /// + /// Helper overload for validate. Used when one model stores another model and calls it's validate. + /// Not meant to be called outside that case. + /// + bool validate(std::stringstream& msg, const std::string& pathPrefix) const; + + bool operator==(const Roi_circle_list& rhs) const; + bool operator!=(const Roi_circle_list& rhs) const; + + ///////////////////////////////////////////// + /// Roi_circle_list members + + /// + /// + /// + std::vector getRois() const; + void setRois(std::vector const& value); + + friend void to_json(nlohmann::json& j, const Roi_circle_list& o); + friend void from_json(const nlohmann::json& j, Roi_circle_list& o); +protected: + std::vector m_Rois; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Roi_circle_list_H_ */ diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml index 31c55719..572ead97 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -164,31 +164,6 @@ components: minimum: 0.015625 maximum: 4.0 description: For JUNGFRAU conversion it is possible to multiply energy by a given factor to get fractional/multiplied photon counts - roi_sum_area: - type: object - description: Rectangle for ROI summation - required: - - x_min - - x_max - - y_min - - y_max - properties: - x_min: - type: integer - format: int64 - example: 12 - x_max: - type: integer - format: int64 - example: 14 - y_min: - type: integer - format: int64 - example: 25 - y_max: - type: integer - format: int64 - example: 32 unit_cell: type: object description: Units of angstrom and degree @@ -204,26 +179,35 @@ components: type: number format: float example: 37 + minimum: 0 b: type: number format: float example: 37 + minimum: 0 c: type: number format: float example: 78 + minimum: 0 alpha: type: number format: float example: 90 + minimum: 0 + maximum: 360 beta: type: number format: float example: 90 + minimum: 0 + maximum: 360 gamma: type: number format: float example: 90 + minimum: 0 + maximum: 360 detector_status: type: object @@ -515,8 +499,12 @@ components: required: - x - y + - title description: x and y coordinates for plotting, it is OK to assume that both arrays have the same size; layout is optimized for Plotly properties: + title: + type: string + default: "" x: type: array items: @@ -527,18 +515,17 @@ components: items: type: number format: float - radial_integration_plots: - type: array - items: - type: object - required: - - title - - plot - properties: - title: - type: string - plot: - $ref: "#/components/schemas/plot" + plots: + type: object + required: + - plot + properties: + title: + type: string + plot: + type: array + items: + $ref: '#/components/schemas/plot' calibration_statistics: type: array items: @@ -597,6 +584,10 @@ components: type: boolean default: true description: "Show spot finding results on the image" + show_roi: + type: boolean + default: false + description: "Show ROI areas on the image" jpeg_quality: type: integer description: "Quality of JPEG image (100 - highest; 0 - lowest)" @@ -618,7 +609,87 @@ components: type: string description: "Enumerate field for automated analysis" enum: ["WrongDAQState", "Other"] - + roi_circle: + type: object + description: "Circular ROI" + required: + - name + - center_x_pxl + - center_y_pxl + - radius_pxl + properties: + name: + type: string + minLength: 1 + description: "Name for the ROI; used in the plots" + center_x_pxl: + type: number + format: float + description: "X coordinate of center of the circle [pixels]" + center_y_pxl: + type: number + format: float + description: "Y coordinate of center of the circle [pixels]" + radius_pxl: + type: number + format: float + minimum: 0.0 + exclusiveMinimum: true + description: "Radius of the circle [pixels]" + roi_box: + type: object + description: "Box ROI" + required: + - name + - min_x_pxl + - max_x_pxl + - min_y_pxl + - max_y_pxl + properties: + name: + type: string + minLength: 1 + description: "Name for the ROI; used in the plots" + min_x_pxl: + type: integer + format: int64 + description: "Lower bound (inclusive) in X coordinate for the box" + minimum: 0 + max_x_pxl: + type: integer + format: int64 + description: "Upper bound (inclusive) in X coordinate for the box" + minimum: 0 + min_y_pxl: + type: integer + format: int64 + description: "Lower bound (inclusive) in Y coordinate for the box" + minimum: 0 + max_y_pxl: + type: integer + format: int64 + description: "Upper bound (inclusive) in Y coordinate for the box" + minimum: 0 + roi_circle_list: + type: object + description: "List of circular ROIs" + required: + - rois + properties: + rois: + type: array + maxItems: 32 + items: + $ref: "#/components/schemas/roi_circle" + roi_box_list: + type: object + description: "List of box ROIs" + properties: + rois: + type: array + maxItems: 32 + items: + $ref: "#/components/schemas/roi_box" paths: /initialize: post: @@ -935,6 +1006,39 @@ paths: application/json: schema: $ref: '#/components/schemas/broker_status' + /xfel/pulse_id: + get: + summary: Return XFEL pulse IDs for the current data acquisition + description: Return array of XFEL pulse IDs - (-1) if image not recorded + responses: + "200": + description: "Pulse ID collected" + content: + application/json: + schema: + type: array + items: + type: integer + format: int64 + "404": + description: "Not in XFEL mode or no acquisition recorded" + /xfel/event_code: + get: + summary: Return XFEL event codes for the current data acquisition + description: Return array of XFEL event codes + responses: + "200": + description: "Event codes collected" + content: + application/json: + schema: + type: array + items: + type: integer + format: int64 + "404": + description: "Not in XFEL mode or no acquisition recorded" + /detector/status: get: summary: Get detector status @@ -955,7 +1059,72 @@ paths: schema: type: string description: Exception error - + /roi/box: + get: + summary: Get box ROIs + responses: + "200": + description: "OK" + content: + application/json: + schema: + $ref: '#/components/schemas/roi_box_list' + put: + summary: Upload box ROIs + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/roi_box_list" + responses: + "200": + description: Everything OK + "400": + description: Input parsing or validation error + content: + text/plain: + schema: + type: string + description: Exception error + "500": + description: Error within Jungfraujoch code - see output message. + content: + application/json: + schema: + $ref: '#/components/schemas/error_message' + /roi/circle: + get: + summary: Get circular ROI + responses: + "200": + description: "OK" + content: + application/json: + schema: + $ref: '#/components/schemas/roi_circle_list' + put: + summary: Upload circular ROI + requestBody: + content: + application/json: + schema: + $ref: "#/components/schemas/roi_circle_list" + responses: + "200": + description: Everything OK + "400": + description: Input parsing or validation error + content: + text/plain: + schema: + type: string + description: Exception error + "500": + description: Error within Jungfraujoch code - see output message. + content: + application/json: + schema: + $ref: '#/components/schemas/error_message' /plot/bkg_estimate: post: summary: Generate background estimate plot @@ -971,7 +1140,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' "400": description: Input parsing or validation error content: @@ -994,7 +1163,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' "400": description: Input parsing or validation error content: @@ -1017,30 +1186,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' - "400": - description: Input parsing or validation error - content: - text/plain: - schema: - type: string - description: Exception error - /plot/saturated_pixel: - post: - summary: Generate saturated pixels plot - description: Count of saturated pixels per image; binning is configurable - requestBody: - content: - application/json: - schema: - $ref: '#/components/schemas/plot_request' - responses: - "200": - description: Everything OK - content: - application/json: - schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' "400": description: Input parsing or validation error content: @@ -1051,7 +1197,7 @@ paths: /plot/error_pixel: post: summary: Generate error pixels plot - description: Count of error pixels per image; binning is configurable + description: Count of error (mean) and saturated (mean/max) pixels per image; binning is configurable requestBody: content: application/json: @@ -1063,7 +1209,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' "400": description: Input parsing or validation error content: @@ -1086,7 +1232,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' "400": description: Input parsing or validation error content: @@ -1109,7 +1255,53 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' + "400": + description: Input parsing or validation error + content: + text/plain: + schema: + type: string + description: Exception error + /plot/roi_max_count: + post: + summary: Generate plot of ROI max count + description: Max count of ROI per image; binning is configurable + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/plot_request' + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/plots' + "400": + description: Input parsing or validation error + content: + text/plain: + schema: + type: string + description: Exception error + /plot/roi_valid_pixels: + post: + summary: Generate plot of ROI valid pixels + description: Number of pixels within a ROI area; pixels with special values (overload, bad pixel) are excluded; multipixels are counted just once; binning is configurable + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/plot_request' + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/plots' "400": description: Input parsing or validation error content: @@ -1132,7 +1324,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' "400": description: Input parsing or validation error content: @@ -1155,7 +1347,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' "400": description: Input parsing or validation error content: @@ -1173,7 +1365,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' /plot/resolution_estimate_histogram: get: summary: Generate resolution estimate histogram @@ -1184,7 +1376,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' /plot/rad_int: get: summary: Generate radial integration profile @@ -1195,7 +1387,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/plot' + $ref: '#/components/schemas/plots' /plot/rad_int_per_file: get: summary: Generate radial integration profiles per file @@ -1206,7 +1398,7 @@ paths: content: application/json: schema: - $ref: '#/components/schemas/radial_integration_plots' + $ref: '#/components/schemas/plots' /statistics/data_collection: get: summary: Get data collection statistics @@ -1306,4 +1498,4 @@ paths: type: string format: binary "404": - description: No preview image recorded so far \ No newline at end of file + description: No preview image recorded so far diff --git a/broker/redoc-static.html b/broker/redoc-static.html index 537b5d12..b472e899 100644 --- a/broker/redoc-static.html +++ b/broker/redoc-static.html @@ -341,7 +341,7 @@ data-styled.g137[id="sc-cMdfCE"]{content:"dvQijr,"}/*!sc*/ -

Image appendix, added as user_data to image message

photon_energy_multiplier
number <float> [ 0.015625 .. 4 ]
Default: 1

For JUNGFRAU conversion it is possible to multiply energy by a given factor to get fractional/multiplied photon counts

-
object

Rectangle for ROI summation

object

Units of angstrom and degree

Responses

Request samples

Content type
application/json
{
  • "images_per_trigger": 1,
  • "ntrigger": 1,
  • "summation": 1,
  • "beam_x_pxl": 0.1,
  • "beam_y_pxl": 0.1,
  • "detector_distance_mm": 0.1,
  • "photon_energy_keV": 0.1,
  • "file_prefix": "",
  • "data_file_count": 1,
  • "space_group_number": 0,
  • "sample_name": "string",
  • "save_calibration": false,
  • "fpga_output": "auto",
  • "compression": "bslz4",
  • "total_flux": 0.1,
  • "transmission": 1,
  • "omega": {
    },
  • "header_appendix": "string",
  • "image_appendix": "string",
  • "photon_energy_multiplier": 1,
  • "roi_sum_area": {
    },
  • "unit_cell": {
    }
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Wait for acquisition done

Request samples

Content type
application/json
{
  • "images_per_trigger": 1,
  • "ntrigger": 1,
  • "summation": 1,
  • "beam_x_pxl": 0.1,
  • "beam_y_pxl": 0.1,
  • "detector_distance_mm": 0.1,
  • "photon_energy_keV": 0.1,
  • "file_prefix": "",
  • "data_file_count": 1,
  • "space_group_number": 0,
  • "sample_name": "string",
  • "save_calibration": false,
  • "fpga_output": "auto",
  • "compression": "bslz4",
  • "total_flux": 0.1,
  • "transmission": 1,
  • "omega": {
    },
  • "header_appendix": "string",
  • "image_appendix": "string",
  • "photon_energy_multiplier": 1,
  • "unit_cell": {
    }
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Wait for acquisition done

Block execution of external script till initialization, data collection or pedestal is finished. @@ -593,7 +591,19 @@ Changing detector will set detector to Inactive state and will requ " class="sc-iKOmoZ sc-cCzLxZ WVNwY VEBGS">

Status of the data acquisition

Responses

Response samples

Content type
application/json
{
  • "state": "Inactive",
  • "progress": 1,
  • "indexing_rate": 0.1
}

Get detector status

Response samples

Content type
application/json
{
  • "state": "Inactive",
  • "progress": 1,
  • "indexing_rate": 0.1
}

Return XFEL pulse IDs for the current data acquisition

Return array of XFEL pulse IDs - (-1) if image not recorded

+

Responses

Response samples

Content type
application/json
[
  • 0
]

Return XFEL event codes for the current data acquisition

Return array of XFEL event codes

+

Responses

Response samples

Content type
application/json
[
  • 0
]

Get detector status

Status of the JUNGFRAU detector

Responses

Response samples

Content type
application/json
{
  • "state": "Idle",
  • "powerchip": "On",
  • "server_version": "string",
  • "number_of_triggers_left": 0,
  • "fpga_temp_degC": [
    ],
  • "high_voltage_V": [
    ]
}

Generate background estimate plot

Response samples

Content type
application/json
{
  • "state": "Idle",
  • "powerchip": "On",
  • "server_version": "string",
  • "number_of_triggers_left": 0,
  • "fpga_temp_degC": [
    ],
  • "high_voltage_V": [
    ]
}

Get box ROIs

Responses

Response samples

Content type
application/json
{
  • "rois": [
    ]
}

Upload box ROIs

Request Body schema: application/json
Array of objects (roi_box) <= 32 items

Responses

Request samples

Content type
application/json
{
  • "rois": [
    ]
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Get circular ROI

Responses

Response samples

Content type
application/json
{
  • "rois": [
    ]
}

Upload circular ROI

Request Body schema: application/json
required
Array of objects (roi_circle) <= 32 items

Responses

Request samples

Content type
application/json
{
  • "rois": [
    ]
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Generate background estimate plot

Mean intensity for d = 3 - 5 A per image; binning is configurable

Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate spot count plot

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate spot count plot

Number of spots per image; binning is configurable

Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate indexing rate plot

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate indexing rate plot

Image indexing rate; binning is configurable

Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate saturated pixels plot

Count of saturated pixels per image; binning is configurable

+

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate error pixels plot

Count of error (mean) and saturated (mean/max) pixels per image; binning is configurable

Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate error pixels plot

Count of error pixels per image; binning is configurable

-
Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate strong pixels plot

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate strong pixels plot

Count of strong pixels per image (from spot finding); binning is configurable

Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate ROI sum plot

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate ROI sum plot

Sum of ROI rectangle per image; binning is configurable

Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate receiver delay plot

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate plot of ROI max count

Max count of ROI per image; binning is configurable

+
Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate plot of ROI valid pixels

Number of pixels within a ROI area; pixels with special values (overload, bad pixel) are excluded; multipixels are counted just once; binning is configurable

+
Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate receiver delay plot

Amount of frames the receiver is behind the FPGA for each image - used for internal debugging; binning is configurable

Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate image collection efficiency plot

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate image collection efficiency plot

Ratio of collected and expected packets per image; binning is configurable

Request Body schema: application/json
binning
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate indexing rate per file

Request samples

Content type
application/json
{
  • "binning": 0
}

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate indexing rate per file

Indexing rate per each of data files; useful for example for time resolved data

Responses

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate resolution estimate histogram

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate resolution estimate histogram

Generate histogram of crystal resolutions from 1.0 to 5.0 A based on ML model

Responses

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate radial integration profile

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate radial integration profile

Generate average radial integration profile

Responses

Response samples

Content type
application/json
{
  • "x": [
    ],
  • "y": [
    ]
}

Generate radial integration profiles per file

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Generate radial integration profiles per file

Radial integration plots for both the whole dataset and per file; useful for time-resolved measurements

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get data collection statistics

Response samples

Content type
application/json
{
  • "title": "string",
  • "plot": [
    ]
}

Get data collection statistics

Results of the last data collection

Responses

Response samples

Content type
application/json
{
  • "file_prefix": "string",
  • "images_expected": 0,
  • "images_collected": 0,
  • "images_sent": 0,
  • "max_image_number_sent": 0,
  • "collection_efficiency": 1,
  • "compression_ratio": 5.3,
  • "cancelled": true,
  • "max_receiver_delay": 0,
  • "indexing_rate": 0.1,
  • "detector_width": 0,
  • "detector_height": 0,
  • "detector_pixel_depth": 2,
  • "bkg_estimate": 0.1
}

Get calibration statistics

Response samples

Content type
application/json
{
  • "file_prefix": "string",
  • "images_expected": 0,
  • "images_collected": 0,
  • "images_sent": 0,
  • "max_image_number_sent": 0,
  • "collection_efficiency": 1,
  • "compression_ratio": 5.3,
  • "cancelled": true,
  • "max_receiver_delay": 0,
  • "indexing_rate": 0.1,
  • "detector_width": 0,
  • "detector_height": 0,
  • "detector_pixel_depth": 2,
  • "bkg_estimate": 0.1
}

Get calibration statistics

Statistics are provided for each module/storage cell separately

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get last preview image in JPEG format

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get last preview image in JPEG format

Responses

show_spots
boolean
Default: true

Show spot finding results on the image

+
show_roi
boolean
Default: false

Show ROI areas on the image

jpeg_quality
integer <int64> [ 0 .. 100 ]

Quality of JPEG image (100 - highest; 0 - lowest)

Responses

Request samples

Content type
application/json
{
  • "saturation": 65535,
  • "show_spots": true,
  • "jpeg_quality": 100
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Get JPEG rendering configuration

Request samples

Content type
application/json
{
  • "saturation": 65535,
  • "show_spots": true,
  • "show_roi": false,
  • "jpeg_quality": 100
}

Response samples

Content type
application/json
{
  • "msg": "Detector in wrong state",
  • "reason": "WrongDAQState"
}

Get JPEG rendering configuration

Can be done anytime

Responses

Response samples

Content type
application/json
{
  • "saturation": 65535,
  • "show_spots": true,
  • "jpeg_quality": 100
}

Get last preview image in TIFF format

Responses

Response samples

Content type
application/json
{
  • "saturation": 65535,
  • "show_spots": true,
  • "show_roi": false,
  • "jpeg_quality": 100
}

Get last preview image in TIFF format

Responses