From 0b69dfb290514bbccdea45981b1b26094f315824 Mon Sep 17 00:00:00 2001 From: leonarski_f Date: Mon, 11 Dec 2023 12:11:54 +0100 Subject: [PATCH] New REST+OpenAPI interface --- .gitlab-ci.yml | 21 +- CMakeLists.txt | 1 - README.md | 41 +- broker/CMakeLists.txt | 12 +- broker/JFJochBroker.cpp | 379 -------- broker/JFJochBroker.h | 75 -- broker/JFJochBrokerHttp.cpp | 542 +++++++++++ broker/JFJochBrokerHttp.h | 91 ++ broker/JFJochBrokerParser.cpp | 34 +- broker/JFJochBrokerParser.h | 4 +- broker/JFJochServices.cpp | 17 +- broker/JFJochServices.h | 5 +- broker/JFJochStateMachine.cpp | 257 ++--- broker/JFJochStateMachine.h | 68 +- broker/gen/api/DefaultApi.cpp | 694 ++++++++++++++ broker/gen/api/DefaultApi.h | 290 ++++++ broker/gen/model/Broker_status.cpp | 235 +++++ broker/gen/model/Broker_status.h | 104 ++ .../model/Calibration_statistics_inner.cpp | 203 ++++ .../gen/model/Calibration_statistics_inner.h | 132 +++ broker/gen/model/Data_processing_settings.cpp | 246 +++++ broker/gen/model/Data_processing_settings.h | 120 +++ broker/gen/model/Dataset_settings.cpp | 606 ++++++++++++ broker/gen/model/Dataset_settings.h | 212 +++++ .../gen/model/Dataset_settings_unit_cell.cpp | 161 ++++ broker/gen/model/Dataset_settings_unit_cell.h | 111 +++ broker/gen/model/Detector_list.cpp | 125 +++ broker/gen/model/Detector_list.h | 85 ++ .../model/Detector_list_detectors_inner.cpp | 161 ++++ .../gen/model/Detector_list_detectors_inner.h | 105 ++ broker/gen/model/Detector_selection.cpp | 91 ++ broker/gen/model/Detector_selection.h | 76 ++ broker/gen/model/Detector_settings.cpp | 398 ++++++++ broker/gen/model/Detector_settings.h | 148 +++ broker/gen/model/Error_message.cpp | 105 ++ broker/gen/model/Error_message.h | 84 ++ broker/gen/model/Helpers.cpp | 148 +++ broker/gen/model/Helpers.h | 136 +++ broker/gen/model/Measurement_statistics.cpp | 458 +++++++++ broker/gen/model/Measurement_statistics.h | 178 ++++ broker/gen/model/Plot.cpp | 145 +++ broker/gen/model/Plot.h | 84 ++ broker/gen/model/Plot_request.cpp | 106 +++ broker/gen/model/Plot_request.h | 78 ++ broker/gen/model/Rad_int_settings.cpp | 181 ++++ broker/gen/model/Rad_int_settings.h | 106 +++ .../model/Radial_integration_plots_inner.cpp | 104 ++ .../model/Radial_integration_plots_inner.h | 85 ++ broker/gen/model/Spot_finding_settings.cpp | 246 +++++ broker/gen/model/Spot_finding_settings.h | 120 +++ broker/jfjoch_api.yaml | 899 ++++++++++++++++++ broker/jfjoch_broker.cpp | 70 +- broker/redoc-static.html | 604 ++++++++++++ common/Definitions.h | 6 - common/DetectorSetup.cpp | 27 +- common/DetectorSetup.h | 9 + common/DiffractionExperiment.cpp | 60 +- common/DiffractionExperiment.h | 18 +- common/JFJochException.h | 20 +- fpga/host_library/JungfraujochDevice.cpp | 60 +- frame_serialize/CBORStream2Deserializer.cpp | 20 +- frame_serialize/CBORStream2Serializer.cpp | 24 +- frame_serialize/CborErr.h | 2 +- frame_serialize/JFJochMessages.h | 7 +- frontend_ui/README.md | 16 +- frontend_ui/package-lock.json | 278 +++++- frontend_ui/package.json | 6 +- .../src/components/BkgEstimatePlot.tsx | 11 +- frontend_ui/src/components/Calibration.tsx | 229 +++-- .../src/components/DataProcessingPlot.tsx | 81 +- .../src/components/DataProcessingPlots.tsx | 20 +- .../src/components/DataProcessingSettings.tsx | 65 +- .../src/components/DetectorSelection.tsx | 60 +- .../src/components/DetectorSettings.tsx | 69 +- .../src/components/MeasurementStatistics.tsx | 50 +- .../RadialIntegrationProfilePlots.tsx | 25 +- frontend_ui/src/components/StatusBar.tsx | 51 +- frontend_ui/src/components/handleErrors.ts | 6 - frontend_ui/src/openapi/core/ApiError.ts | 25 + .../src/openapi/core/ApiRequestOptions.ts | 17 + frontend_ui/src/openapi/core/ApiResult.ts | 11 + .../src/openapi/core/CancelablePromise.ts | 131 +++ frontend_ui/src/openapi/core/OpenAPI.ts | 32 + frontend_ui/src/openapi/core/request.ts | 320 +++++++ frontend_ui/src/openapi/index.ts | 24 + .../src/openapi/models/broker_status.ts | 26 + .../openapi/models/calibration_statistics.ts | 16 + .../src/openapi/models/dataset_settings.ts | 103 ++ .../src/openapi/models/detector_list.ts | 16 + .../src/openapi/models/detector_selection.ts | 9 + .../src/openapi/models/detector_settings.ts | 23 + .../src/openapi/models/error_message.ts | 29 + .../openapi/models/measurement_statistics.ts | 30 + frontend_ui/src/openapi/models/plot.ts | 13 + .../src/openapi/models/plot_request.ts | 9 + .../src/openapi/models/rad_int_settings.ts | 19 + .../models/radial_integration_plots.ts | 11 + .../openapi/models/spot_finding_settings.ts | 15 + .../src/openapi/services/DefaultService.ts | 470 +++++++++ grpc/CMakeLists.txt | 47 - grpc/gRPCServer_Template.h | 24 - grpc/jfjoch.proto | 227 ----- image_analysis/CMakeLists.txt | 2 +- ...essingSettings.h => SpotFindingSettings.h} | 8 +- image_analysis/StrongPixelSet.cpp | 2 +- image_analysis/StrongPixelSet.h | 4 +- python/jfjoch_grpc2http.py | 313 ------ python/jfjoch_pb2.py | 71 -- python/jfjoch_pb2_grpc.py | 627 ------------ receiver/JFJochReceiver.cpp | 27 +- receiver/JFJochReceiver.h | 8 +- receiver/JFJochReceiverService.cpp | 29 +- receiver/JFJochReceiverService.h | 7 +- receiver/JFJochReceiverTest.cpp | 4 +- tests/CBORTest.cpp | 23 +- tests/DiffractionExperimentTest.cpp | 12 +- tests/JFJochStateMachineTest.cpp | 31 +- tests/SpotAnalyzeUnitTest.cpp | 2 +- writer/HDF5NXmx.cpp | 16 +- writer/HDF5NXmx.h | 1 + 120 files changed, 11309 insertions(+), 2532 deletions(-) delete mode 100644 broker/JFJochBroker.cpp delete mode 100644 broker/JFJochBroker.h create mode 100644 broker/JFJochBrokerHttp.cpp create mode 100644 broker/JFJochBrokerHttp.h create mode 100644 broker/gen/api/DefaultApi.cpp create mode 100644 broker/gen/api/DefaultApi.h create mode 100644 broker/gen/model/Broker_status.cpp create mode 100644 broker/gen/model/Broker_status.h create mode 100644 broker/gen/model/Calibration_statistics_inner.cpp create mode 100644 broker/gen/model/Calibration_statistics_inner.h create mode 100644 broker/gen/model/Data_processing_settings.cpp create mode 100644 broker/gen/model/Data_processing_settings.h create mode 100644 broker/gen/model/Dataset_settings.cpp create mode 100644 broker/gen/model/Dataset_settings.h create mode 100644 broker/gen/model/Dataset_settings_unit_cell.cpp create mode 100644 broker/gen/model/Dataset_settings_unit_cell.h create mode 100644 broker/gen/model/Detector_list.cpp create mode 100644 broker/gen/model/Detector_list.h create mode 100644 broker/gen/model/Detector_list_detectors_inner.cpp create mode 100644 broker/gen/model/Detector_list_detectors_inner.h create mode 100644 broker/gen/model/Detector_selection.cpp create mode 100644 broker/gen/model/Detector_selection.h create mode 100644 broker/gen/model/Detector_settings.cpp create mode 100644 broker/gen/model/Detector_settings.h create mode 100644 broker/gen/model/Error_message.cpp create mode 100644 broker/gen/model/Error_message.h create mode 100644 broker/gen/model/Helpers.cpp create mode 100644 broker/gen/model/Helpers.h create mode 100644 broker/gen/model/Measurement_statistics.cpp create mode 100644 broker/gen/model/Measurement_statistics.h create mode 100644 broker/gen/model/Plot.cpp create mode 100644 broker/gen/model/Plot.h create mode 100644 broker/gen/model/Plot_request.cpp create mode 100644 broker/gen/model/Plot_request.h create mode 100644 broker/gen/model/Rad_int_settings.cpp create mode 100644 broker/gen/model/Rad_int_settings.h create mode 100644 broker/gen/model/Radial_integration_plots_inner.cpp create mode 100644 broker/gen/model/Radial_integration_plots_inner.h create mode 100644 broker/gen/model/Spot_finding_settings.cpp create mode 100644 broker/gen/model/Spot_finding_settings.h create mode 100644 broker/jfjoch_api.yaml create mode 100644 broker/redoc-static.html delete mode 100644 frontend_ui/src/components/handleErrors.ts create mode 100644 frontend_ui/src/openapi/core/ApiError.ts create mode 100644 frontend_ui/src/openapi/core/ApiRequestOptions.ts create mode 100644 frontend_ui/src/openapi/core/ApiResult.ts create mode 100644 frontend_ui/src/openapi/core/CancelablePromise.ts create mode 100644 frontend_ui/src/openapi/core/OpenAPI.ts create mode 100644 frontend_ui/src/openapi/core/request.ts create mode 100644 frontend_ui/src/openapi/index.ts create mode 100644 frontend_ui/src/openapi/models/broker_status.ts create mode 100644 frontend_ui/src/openapi/models/calibration_statistics.ts create mode 100644 frontend_ui/src/openapi/models/dataset_settings.ts create mode 100644 frontend_ui/src/openapi/models/detector_list.ts create mode 100644 frontend_ui/src/openapi/models/detector_selection.ts create mode 100644 frontend_ui/src/openapi/models/detector_settings.ts create mode 100644 frontend_ui/src/openapi/models/error_message.ts create mode 100644 frontend_ui/src/openapi/models/measurement_statistics.ts create mode 100644 frontend_ui/src/openapi/models/plot.ts create mode 100644 frontend_ui/src/openapi/models/plot_request.ts create mode 100644 frontend_ui/src/openapi/models/rad_int_settings.ts create mode 100644 frontend_ui/src/openapi/models/radial_integration_plots.ts create mode 100644 frontend_ui/src/openapi/models/spot_finding_settings.ts create mode 100644 frontend_ui/src/openapi/services/DefaultService.ts delete mode 100644 grpc/CMakeLists.txt delete mode 100644 grpc/gRPCServer_Template.h delete mode 100644 grpc/jfjoch.proto rename image_analysis/{DataProcessingSettings.h => SpotFindingSettings.h} (73%) delete mode 100644 python/jfjoch_grpc2http.py delete mode 100644 python/jfjoch_pb2.py delete mode 100644 python/jfjoch_pb2_grpc.py diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index e0a2c738..661b1797 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -92,6 +92,24 @@ build:x86:vitis_hls: - cmake .. - make hls +build:x86:frontend: + stage: build + variables: + GIT_SUBMODULE_STRATEGY: recursive + tags: + - x86 + needs: [] + script: + - cd frontend_ui + - npm install + - npm run build + - cd build + - zip ../../frontend.zip * + artifacts: + paths: + - frontend.zip + expire_in: 1 week + test:x86:gcc: stage: test timeout: 90m @@ -214,7 +232,7 @@ synthesis:vivado_pcie_100g: - vivado artifacts: paths: - - build/fpga/*.mcs + - "*.mcs" expire_in: 1 week script: - source /opt/grpc/grpc.sh @@ -223,4 +241,5 @@ synthesis:vivado_pcie_100g: - cd build - cmake .. - make action_pcie + - mv fpga/*.mcs .. needs: ["build:x86:gcc", "build:x86:vitis_hls", "test:x86:gcc"] diff --git a/CMakeLists.txt b/CMakeLists.txt index 59fb76a6..064d175c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,7 +46,6 @@ IF (JFJOCH_WRITER_ONLY) MESSAGE(STATUS "Compiling HDF5 writer only") SET(jfjoch_executables jfjoch_writer) ELSE() - ADD_SUBDIRECTORY(grpc) ADD_SUBDIRECTORY(broker) ADD_SUBDIRECTORY(etc) ADD_SUBDIRECTORY(fpga) diff --git a/README.md b/README.md index a63f5837..556480d7 100644 --- a/README.md +++ b/README.md @@ -31,7 +31,6 @@ Required: * CMake version 3.21 or newer + GNU make tool * HDF5 library version 1.10 or newer * ZeroMQ library -* Google Remote Procedure Call (gRPC) - see notes below * OpenSSL library Optional: @@ -39,7 +38,7 @@ Optional: * NUMA library * Node.js - to make frontend -provided as GIT submodules: SLS Detector Package, tinycbor (Intel), Zstandard (Facebook) and fast replacement for bitshuffle filter (DECTRIS). +provided as GIT submodules: SLS Detector Package, tinycbor (Intel), Zstandard (Facebook), Pistache webserver and fast replacement for bitshuffle filter (DECTRIS). Directly included in the repository: * JSON parser/writer from N. Lohmann - see [github.com/nlohmann/json](https://github.com/nlohmann/json) @@ -48,7 +47,6 @@ Directly included in the repository: * Bitshuffle filter from K. Masui - see [github.com/kiyo-masui/bitshuffle](https://github.com/kiyo-masui/bitshuffle) * LZ4 compression by Y.Collet - see [github.com/lz4/lz4](https://github.com/lz4/lz4) * Spdlog logging library - see [github.com/gabime/spdlog](https://github.com/gabime/spdlog) - For license check LICENSE file in respective directory ### Software components @@ -58,34 +56,6 @@ For license check LICENSE file in respective directory Configuration for the modules is given in configuration files present in `etc` directory. -### Installation of gRPC -#### RHEL/Rocky 9 -Please use Protobuf and gRPC from the Extra Packages for Enterprise Linux (EPEL) repository. -To enable EPEL, follow instructions on [the official website](https://docs.fedoraproject.org/en-US/epel/). - -#### RHEL 8 -gRPC need to be compiled before, as there is no official/semi-official repository for RHEL8. -This also applies to Protocol Buffer, which is provided in RHEL8, but version is old and incompatible with functionality needed in Jungfraujoch. -It is recommended to install gRPC in own directory (not in system path), as there is no easy way to uninstall it. -To compile gRPC: -``` -git clone https://github.com/grpc/grpc -cd grpc -git checkout v1.53.0 # This can be usually substituted by the current stable release -git submodule update --init -mkdir build -cd build -cmake -DgRPC_ZLIB_PROVIDER="package" -DCMAKE_INSTALL_PREFIX=/opt/grpc .. -make -sudo make install -``` -Currently, handling paths for gRPC and its dependencies gives sometimes troubles and few environmental variables need to be setup before compilation (assuming gRPC installed in /opt/grpc): -``` -export CMAKE_PREFIX_PATH=$CMAKE_PREFIX_PATH:/opt/grpc/lib/cmake:/opt/grpc/lib64/cmake -export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/opt/grpc/lib:/opt/grpc/lib64 -export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/opt/grpc/lib/pkgconfig:/opt/grpc/lib64/pkgconfig -``` - ### Compilation Use the following commands: @@ -118,14 +88,5 @@ Automated test routine is then accessible as `tests/CatchTest`. There are also b In addition, tests are executed to verify that datasets written by Jungfraujoch are readable with XDS Durin plugin and CrystFEL. Input files for these programs are placed in `xds_durin` and `crystfel` folders. See `.gitlab-ci.yml` for details. -## Web user interface - -### Building -To build web interface: -``` -cd frontend_ui -npm install -npm run build -``` diff --git a/broker/CMakeLists.txt b/broker/CMakeLists.txt index bb8babe8..c419de6b 100644 --- a/broker/CMakeLists.txt +++ b/broker/CMakeLists.txt @@ -1,9 +1,17 @@ +ADD_SUBDIRECTORY(pistache) + +AUX_SOURCE_DIRECTORY(gen/model MODEL_SOURCES) +ADD_LIBRARY(JFJochAPI STATIC ${MODEL_SOURCES} gen/api/DefaultApi.cpp gen/api/DefaultApi.h) + +TARGET_LINK_LIBRARIES(JFJochAPI pistache_static) +TARGET_INCLUDE_DIRECTORIES(JFJochAPI PUBLIC gen/model gen/api) + ADD_LIBRARY(JFJochBroker STATIC JFJochStateMachine.cpp JFJochStateMachine.h JFJochServices.cpp JFJochServices.h - JFJochBroker.cpp JFJochBroker.h JFJochBrokerParser.cpp JFJochBrokerParser.h) + JFJochBrokerHttp.cpp JFJochBrokerHttp.h JFJochBrokerParser.cpp JFJochBrokerParser.h) -TARGET_LINK_LIBRARIES(JFJochBroker JFJochReceiver JFJochDetector CommonFunctions JFJochProtoBuf) +TARGET_LINK_LIBRARIES(JFJochBroker JFJochReceiver JFJochDetector CommonFunctions JFJochAPI) ADD_EXECUTABLE(jfjoch_broker jfjoch_broker.cpp) TARGET_LINK_LIBRARIES(jfjoch_broker JFJochBroker) diff --git a/broker/JFJochBroker.cpp b/broker/JFJochBroker.cpp deleted file mode 100644 index c0f0925c..00000000 --- a/broker/JFJochBroker.cpp +++ /dev/null @@ -1,379 +0,0 @@ -// Copyright (2019-2023) Paul Scherrer Institute - -#include "JFJochBroker.h" - -#define GRPC_RUN(x) try { {x;} return grpc::Status::OK; } catch (const std::exception& e) { logger.ErrorException(e); return {grpc::StatusCode::ABORTED, e.what()}; } - - -inline DataProcessingSettings Convert(const JFJochProtoBuf::DataProcessingSettings &input) { - DataProcessingSettings ret; - ret.signal_to_noise_threshold = input.signal_to_noise_threshold(); - ret.photon_count_threshold = input.photon_count_threshold(); - ret.min_pix_per_spot = input.min_pix_per_spot(); - ret.max_pix_per_spot = input.max_pix_per_spot(); - ret.high_resolution_limit = input.high_resolution_limit(); - ret.low_resolution_limit = input.low_resolution_limit(); - ret.preview_indexed_only = input.preview_indexed_only(); - return ret; -} - -inline JFJochProtoBuf::DataProcessingSettings Convert(const DataProcessingSettings &input) { - JFJochProtoBuf::DataProcessingSettings ret; - ret.set_signal_to_noise_threshold(input.signal_to_noise_threshold); - ret.set_photon_count_threshold(input.photon_count_threshold); - ret.set_min_pix_per_spot(input.min_pix_per_spot); - ret.set_max_pix_per_spot(input.max_pix_per_spot); - ret.set_high_resolution_limit(input.high_resolution_limit); - ret.set_low_resolution_limit(input.low_resolution_limit); - ret.set_preview_indexed_only(input.preview_indexed_only); - return ret; -} - -inline PlotRequest Convert(const JFJochProtoBuf::PlotRequest& request) { - PlotRequest ret; - ret.binning = request.binning(); - switch (request.type()) { - case JFJochProtoBuf::BKG_ESTIMATE: - ret.type = PlotType::BkgEstimate; - break; - case JFJochProtoBuf::RAD_INT: - ret.type = PlotType::RadInt; - break; - case JFJochProtoBuf::SPOT_COUNT: - ret.type = PlotType::SpotCount; - break; - case JFJochProtoBuf::INDEXING_RATE: - ret.type = PlotType::IndexingRate; - break; - case JFJochProtoBuf::INDEXING_RATE_PER_FILE: - ret.type = PlotType::IndexingRatePerFile; - break; - default: - case JFJochProtoBuf::ADU_HISTOGRAM: - ret.type = PlotType::ADUHistorgram; - break; - } - return ret; -} - -inline JFJochProtoBuf::Plot Convert(const Plot& input) { - JFJochProtoBuf::Plot output; - if (!input.x.empty()) - *output.mutable_x() = {input.x.begin(), input.x.end()}; - if (!input.y.empty()) - *output.mutable_y() = {input.y.begin(), input.y.end()}; - return output; -} - -inline JFJochProtoBuf::RadialIntegrationProfiles Convert(const RadialIntegrationProfiles& input) { - JFJochProtoBuf::RadialIntegrationProfiles output; - for (const auto &i: input.profiles) { - auto tmp = output.add_profiles(); - tmp->set_title(i.title); - *tmp->mutable_plot() = Convert(i.plot); - } - return output; -} - -inline JFJochProtoBuf::JFCalibrationStatistics Convert(const std::vector& input) { - JFJochProtoBuf::JFCalibrationStatistics output; - for (const auto& i: input) { - auto ret = output.add_module_statistics(); - ret->set_module_number(i.module_number); - ret->set_masked_pixels(i.masked_pixels); - ret->set_storage_cell_number(i.storage_cell_number); - ret->set_gain_g0_mean(i.gain_g0_mean); - ret->set_gain_g1_mean(i.gain_g1_mean); - ret->set_gain_g2_mean(i.gain_g2_mean); - ret->set_pedestal_g0_mean(i.pedestal_g0_mean); - ret->set_pedestal_g1_mean(i.pedestal_g1_mean); - ret->set_pedestal_g2_mean(i.pedestal_g2_mean); - } - return output; -} -inline JFJochProtoBuf::BrokerStatus Convert(const BrokerStatus& input) { - JFJochProtoBuf::BrokerStatus ret; - - switch (input.broker_state) { - case JFJochState::Inactive: - ret.set_broker_state(JFJochProtoBuf::NOT_INITIALIZED); - break; - case JFJochState::Idle: - ret.set_broker_state(JFJochProtoBuf::IDLE); - break; - case JFJochState::Measuring: - ret.set_broker_state(JFJochProtoBuf::DATA_COLLECTION); - break; - case JFJochState::Error: - ret.set_broker_state(JFJochProtoBuf::ERROR); - break; - case JFJochState::Busy: - ret.set_broker_state(JFJochProtoBuf::BUSY); - break; - case JFJochState::Pedestal: - ret.set_broker_state(JFJochProtoBuf::PEDESTAL); - break; - } - - ret.set_progress(input.progress); - ret.set_indexing_rate(input.indexing_rate); - ret.set_receiver_send_buffers_avail(input.receiver_send_buffers_avail); - return ret; -} - -JFJochProtoBuf::DetectorList Convert(const DetectorList &input) { - JFJochProtoBuf::DetectorList ret; - for (const auto &i: input.detector) { - auto tmp = ret.add_detector(); - tmp->set_id(i.id); - tmp->set_nmodules(i.nmodules); - tmp->set_description(i.description); - } - ret.set_current_description(input.current_description); - ret.set_current_id(input.current_id); - return ret; -} - -JFJochProtoBuf::MeasurementStatistics Convert(const MeasurementStatistics &input) { - JFJochProtoBuf::MeasurementStatistics ret{}; - - ret.set_file_prefix(input.file_prefix); - ret.set_images_collected(input.images_collected); - ret.set_max_image_number_sent(input.max_image_number_sent); - ret.set_collection_efficiency(input.collection_efficiency); - ret.set_compression_ratio(input.compression_ratio); - - ret.set_cancelled(input.cancelled); - ret.set_max_receive_delay(input.max_receive_delay); - - ret.set_indexing_rate(input.indexing_rate); - - ret.set_detector_width(input.detector_width); - ret.set_detector_height(input.detector_height); - ret.set_detector_pixel_depth(input.detector_pixel_depth); - - ret.set_bkg_estimate(input.bkg_estimate); - - return ret; -} - -DatasetSettings Convert(const JFJochProtoBuf::DatasetSettings& input) { - DatasetSettings ret; - - ret.images_per_trigger = input.images_per_trigger(); - ret.ntrigger = input.ntrigger(); - - switch (input.fpga_pixel_output()) { - - case JFJochProtoBuf::INT16: - ret.fpga_pixel_output = FPGAPixelOutput::Int16; - break; - case JFJochProtoBuf::UINT16: - ret.fpga_pixel_output = FPGAPixelOutput::Uint16; - break; - case JFJochProtoBuf::INT32: - ret.fpga_pixel_output = FPGAPixelOutput::Int32; - break; - case JFJochProtoBuf::UINT32: - ret.fpga_pixel_output = FPGAPixelOutput::Uint32; - break; - default: - case JFJochProtoBuf::AUTO: - ret.fpga_pixel_output = FPGAPixelOutput::Auto; - break; - } - - ret.summation = input.summation(); - ret.beam_x_pxl = input.beam_x_pxl(); - ret.beam_y_pxl = input.beam_y_pxl(); - ret.detector_distance_mm = input.detector_distance_mm(); - ret.photon_energy_keV = input.photon_energy_kev(); - - ret.file_prefix = input.file_prefix(); - ret.data_file_count = input.data_file_count(); - switch (input.compression()) { - - case JFJochProtoBuf::BSHUF_LZ4: - ret.compression = CompressionAlgorithm::BSHUF_LZ4; - break; - case JFJochProtoBuf::BSHUF_ZSTD: - ret.compression = CompressionAlgorithm::BSHUF_ZSTD; - break; - case JFJochProtoBuf::BSHUF_ZSTD_RLE: - ret.compression = CompressionAlgorithm::BSHUF_ZSTD_RLE; - break; - default: - case JFJochProtoBuf::NO_COMPRESSION: - ret.compression = CompressionAlgorithm::NO_COMPRESSION; - break; - } - - - ret.sample_name = input.sample_name(); - if (input.has_unit_cell()) - ret.unit_cell = UnitCell{ - .a = input.unit_cell().a(), - .b = input.unit_cell().b(), - .c = input.unit_cell().c(), - .alpha = input.unit_cell().alpha(), - .beta = input.unit_cell().beta(), - .gamma = input.unit_cell().gamma() - }; - ret.space_group_number = input.space_group_number(); - - ret.rad_int_solid_angle_corr = input.rad_int_solid_angle_corr(); - ret.rad_int_polarization_corr = input.rad_int_polarization_corr(); - ret.rad_int_polarization_factor = input.rad_int_polarization_factor(); - - ret.save_calibration = input.save_calibration(); - return ret; -} - -DetectorSettings Convert(const JFJochProtoBuf::DetectorSettings &input) { - DetectorSettings ret{}; - - ret.frame_time_us = input.frame_time_us(); - ret.count_time_us = input.count_time_us(); - - ret.storage_cell_count = input.storage_cell_count(); - ret.use_internal_packet_generator = input.use_internal_packet_generator(); - ret.collect_raw_data = input.collect_raw_data(); - - ret.pedestal_g0_frames = input.pedestal_g0_frames(); - ret.pedestal_g1_frames = input.pedestal_g1_frames(); - ret.pedestal_g2_frames = input.pedestal_g2_frames(); - - ret.storage_cell_delay_ns = input.storage_cell_delay_ns(); - return ret; -} - -JFJochProtoBuf::DetectorSettings Convert(const DetectorSettings &input) { - JFJochProtoBuf::DetectorSettings ret{}; - - ret.set_frame_time_us(input.frame_time_us); - ret.set_count_time_us(input.count_time_us); - - ret.set_storage_cell_count(input.storage_cell_count); - ret.set_use_internal_packet_generator(input.use_internal_packet_generator); - ret.set_collect_raw_data(input.collect_raw_data); - - ret.set_pedestal_g0_frames(input.pedestal_g0_frames); - ret.set_pedestal_g1_frames(input.pedestal_g1_frames); - ret.set_pedestal_g2_frames(input.pedestal_g2_frames); - - ret.set_storage_cell_delay_ns(input.storage_cell_delay_ns); - return ret; -} - -JFJochBroker::JFJochBroker(const DiffractionExperiment &experiment) { - state_machine.NotThreadSafe_Experiment() = experiment; -} - -grpc::Status JFJochBroker::Start(grpc::ServerContext *context, const JFJochProtoBuf::DatasetSettings *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.Start(Convert(*request)) ); -} - -grpc::Status JFJochBroker::Stop(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.Stop() ); -} - -grpc::Status JFJochBroker::Pedestal(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.Pedestal() ); -} - -grpc::Status JFJochBroker::Initialize(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.Initialize() ); -} - -grpc::Status JFJochBroker::Cancel(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.Cancel() ); -} - -grpc::Status JFJochBroker::Deactivate(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.Deactivate() ); -} - -grpc::Status JFJochBroker::Trigger(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.Trigger() ); -} - -grpc::Status JFJochBroker::GetStatus(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::BrokerStatus *response) { - GRPC_RUN( *response = Convert(state_machine.GetStatus()) ); -} - -grpc::Status JFJochBroker::GetPlots(grpc::ServerContext *context, const JFJochProtoBuf::PlotRequest *request, - JFJochProtoBuf::Plot *response) { - GRPC_RUN( *response = Convert(state_machine.GetPlots(Convert(*request))) ); -} - -grpc::Status JFJochBroker::GetRadialIntegrationProfiles(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::RadialIntegrationProfiles *response) { - GRPC_RUN( *response = Convert(state_machine.GetRadialIntegrationProfiles()) ); -} - -grpc::Status JFJochBroker::GetDetectorSettings(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::DetectorSettings *response) { - GRPC_RUN( *response = Convert(state_machine.GetDetectorSettings()) ); -} - -grpc::Status JFJochBroker::GetCalibrationStatistics(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::JFCalibrationStatistics *response) { - GRPC_RUN( *response = Convert(state_machine.GetCalibrationStatistics()) ); -} - -grpc::Status JFJochBroker::PutDetectorSettings(grpc::ServerContext *context, - const JFJochProtoBuf::DetectorSettings *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.SetDetectorSettings(Convert(*request)) ); -} - -grpc::Status JFJochBroker::GetDataProcessingSettings(::grpc::ServerContext *context, const ::JFJochProtoBuf::Empty *request, - ::JFJochProtoBuf::DataProcessingSettings *response) { - GRPC_RUN( *response = Convert(state_machine.GetDataProcessingSettings()) ); -} - -grpc::Status JFJochBroker::PutDataProcessingSettings(::grpc::ServerContext *context, - const ::JFJochProtoBuf::DataProcessingSettings *request, - ::JFJochProtoBuf::Empty *response) { - GRPC_RUN( state_machine.SetDataProcessingSettings(Convert(*request)) ); -} - -grpc::Status JFJochBroker::GetMeasurementStatistics(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::MeasurementStatistics *response) { - GRPC_RUN({ - auto stat = state_machine.GetMeasurementStatistics(); - if (stat) - *response = Convert(stat.value()); - else - *response = JFJochProtoBuf::MeasurementStatistics(); - }); -} - -JFJochServices &JFJochBroker::Services() { - return services; -} - -void JFJochBroker::AddDetectorSetup(const DetectorSetup &setup) { - state_machine.AddDetectorSetup(setup); - logger.Info("Added detector {}", setup.GetDescription()); -} - -grpc::Status JFJochBroker::GetDetectorList(grpc::ServerContext *context, - const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::DetectorList *response) { - GRPC_RUN(*response = Convert(state_machine.GetDetectorsList()) ); -} - -grpc::Status JFJochBroker::SelectDetector(grpc::ServerContext *context, - const JFJochProtoBuf::DetectorSelection *request, - JFJochProtoBuf::Empty *response) { - GRPC_RUN(state_machine.SelectDetector(request->id())); -} diff --git a/broker/JFJochBroker.h b/broker/JFJochBroker.h deleted file mode 100644 index 37615af0..00000000 --- a/broker/JFJochBroker.h +++ /dev/null @@ -1,75 +0,0 @@ -// Copyright (2019-2023) Paul Scherrer Institute - -#ifndef JUNGFRAUJOCH_JFJOCHBROKER_H -#define JUNGFRAUJOCH_JFJOCHBROKER_H - -#include -#include "JFJochServices.h" -#include "JFJochStateMachine.h" - -class JFJochBroker final : public JFJochProtoBuf::gRPC_JFJochBroker::Service { - Logger logger{"JFJochBroker"}; - JFJochServices services {logger}; - JFJochStateMachine state_machine {services, logger}; -public: - JFJochBroker(const DiffractionExperiment& experiment); - void AddDetectorSetup(const DetectorSetup &setup); - JFJochServices& Services(); - - grpc::Status Start(grpc::ServerContext *context, const JFJochProtoBuf::DatasetSettings *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status Stop(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status Pedestal(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status Initialize(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status Cancel(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status Deactivate(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status Trigger(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status GetStatus(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::BrokerStatus *response) override; - - grpc::Status GetPlots(grpc::ServerContext *context, const JFJochProtoBuf::PlotRequest *request, - JFJochProtoBuf::Plot *response) override; - - grpc::Status GetRadialIntegrationProfiles(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::RadialIntegrationProfiles *response) override; - - grpc::Status GetCalibrationStatistics(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::JFCalibrationStatistics *response) override; - - grpc::Status GetDetectorSettings(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::DetectorSettings *response) override; - - grpc::Status PutDetectorSettings(grpc::ServerContext *context, const JFJochProtoBuf::DetectorSettings *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status GetDataProcessingSettings(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::DataProcessingSettings *response) override; - - grpc::Status PutDataProcessingSettings(grpc::ServerContext *context, const JFJochProtoBuf::DataProcessingSettings *request, - JFJochProtoBuf::Empty *response) override; - - grpc::Status GetMeasurementStatistics(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::MeasurementStatistics *response) override; - - grpc::Status GetDetectorList(grpc::ServerContext *context, const JFJochProtoBuf::Empty *request, - JFJochProtoBuf::DetectorList *response) override; - - grpc::Status SelectDetector(grpc::ServerContext *context, const JFJochProtoBuf::DetectorSelection *request, - JFJochProtoBuf::Empty *response) override; -}; - - -#endif //JUNGFRAUJOCH_JFJOCHBROKER_H diff --git a/broker/JFJochBrokerHttp.cpp b/broker/JFJochBrokerHttp.cpp new file mode 100644 index 00000000..a3a9a682 --- /dev/null +++ b/broker/JFJochBrokerHttp.cpp @@ -0,0 +1,542 @@ +// Copyright (2019-2023) Paul Scherrer Institute +// Using OpenAPI licensed with Apache License 2.0 + +#include +#include "JFJochBrokerHttp.h" +#include "gen/model/Error_message.h" + +// From https://en.cppreference.com/w/cpp/string/byte/tolower +inline std::string str_tolower(std::string s) { + std::transform(s.begin(), s.end(), s.begin(), [](unsigned char c){ return std::tolower(c); }); + return s; +} + +inline SpotFindingSettings Convert(const org::openapitools::server::model::Spot_finding_settings &input) { + SpotFindingSettings ret{}; + ret.signal_to_noise_threshold = input.getSignalToNoiseThreshold(); + ret.photon_count_threshold = input.getPhotonCountThreshold(); + ret.min_pix_per_spot = input.getMinPixPerSpot(); + ret.max_pix_per_spot = input.getMaxPixPerSpot(); + ret.high_resolution_limit = input.getHighResolutionLimit(); + ret.low_resolution_limit = input.getLowResolutionLimit(); + ret.preview_indexed_only = input.previewIndexedOnlyIsSet() ? input.isPreviewIndexedOnly() : false; + return ret; +} + +inline org::openapitools::server::model::Spot_finding_settings Convert(const SpotFindingSettings &input) { + org::openapitools::server::model::Spot_finding_settings ret; + ret.setSignalToNoiseThreshold(input.signal_to_noise_threshold); + ret.setPhotonCountThreshold(input.photon_count_threshold); + ret.setMinPixPerSpot(input.min_pix_per_spot); + ret.setMaxPixPerSpot(input.max_pix_per_spot); + ret.setHighResolutionLimit(input.high_resolution_limit); + ret.setLowResolutionLimit(input.low_resolution_limit); + ret.setPreviewIndexedOnly(input.preview_indexed_only); + return ret; +} + +inline org::openapitools::server::model::Measurement_statistics Convert(const MeasurementStatistics &input) { + org::openapitools::server::model::Measurement_statistics ret{}; + + ret.setFilePrefix(input.file_prefix); + ret.setImagesCollected(input.images_collected); + ret.setMaxImageNumberSent(input.max_image_number_sent); + ret.setCollectionEfficiency(input.collection_efficiency); + ret.setCompressionRatio(input.compression_ratio); + + ret.setCancelled(input.cancelled); + ret.setMaxReceiverDelay(input.max_receive_delay); + + ret.setIndexingRate(input.indexing_rate); + + ret.setDetectorWidth(input.detector_width); + ret.setDetectorHeight(input.detector_height); + ret.setDetectorPixelDepth(input.detector_pixel_depth); + + ret.setBkgEstimate(input.bkg_estimate); + + return ret; +} + +inline DetectorSettings Convert(const org::openapitools::server::model::Detector_settings &input) { + DetectorSettings ret{}; + + ret.frame_time_us = input.getFrameTimeUs(); + if (input.countTimeUsIsSet()) + ret.count_time_us = input.getCountTimeUs(); + + ret.storage_cell_count = input.getStorageCellCount(); + + ret.use_internal_packet_generator = input.isInternalFrameGenerator(); + ret.collect_raw_data = input.isCollectRawData(); + + if (input.pedestalG0FramesIsSet()) + ret.pedestal_g0_frames = input.getPedestalG0Frames(); + if (input.pedestalG1FramesIsSet()) + ret.pedestal_g1_frames = input.getPedestalG1Frames(); + if (input.pedestalG2FramesIsSet()) + ret.pedestal_g2_frames = input.getPedestalG2Frames(); + if (input.storageCellDelayNsIsSet()) + ret.storage_cell_delay_ns = input.getStorageCellDelayNs(); + + return ret; +} + +inline org::openapitools::server::model::Detector_settings Convert(const DetectorSettings &input) { + org::openapitools::server::model::Detector_settings ret{}; + + ret.setFrameTimeUs(input.frame_time_us); + ret.setCountTimeUs(input.count_time_us.value()); + + ret.setStorageCellCount(input.storage_cell_count); + ret.setInternalFrameGenerator(input.use_internal_packet_generator); + ret.setCollectRawData(input.collect_raw_data); + + ret.setPedestalG0Frames(input.pedestal_g0_frames.value()); + ret.setPedestalG1Frames(input.pedestal_g1_frames.value()); + ret.setPedestalG2Frames(input.pedestal_g2_frames.value()); + + ret.setStorageCellDelayNs(input.storage_cell_delay_ns.value()); + return ret; +} + +inline org::openapitools::server::model::Broker_status Convert(const BrokerStatus& input) { + org::openapitools::server::model::Broker_status ret; + + switch (input.broker_state) { + case JFJochState::Inactive: + ret.setState("Inactive"); + break; + case JFJochState::Idle: + ret.setState("Idle"); + break; + case JFJochState::Measuring: + ret.setState("Measuring"); + break; + case JFJochState::Error: + ret.setState("Error"); + break; + case JFJochState::Busy: + ret.setState("Busy"); + break; + case JFJochState::Pedestal: + ret.setState("Pedestal"); + break; + } + if (input.progress.has_value()) + ret.setProgress(input.progress.value()); + if (input.indexing_rate.has_value()) + ret.setIndexingRate(input.indexing_rate.value()); + if (input.receiver_send_buffers_avail.has_value()) + ret.setReceiverSendBuffersAvail(input.receiver_send_buffers_avail.value()); + return ret; +} + +inline org::openapitools::server::model::Calibration_statistics_inner Convert(const JFCalibrationModuleStatistics& input) { + org::openapitools::server::model::Calibration_statistics_inner output; + + output.setModuleNumber(input.module_number); + output.setMaskedPixels(input.masked_pixels); + output.setStorageCellNumber(input.storage_cell_number); + output.setGainG0Mean(input.gain_g0_mean); + output.setGainG1Mean(input.gain_g1_mean); + output.setGainG2Mean(input.gain_g2_mean); + output.setPedestalG0Mean(input.pedestal_g0_mean); + output.setPedestalG1Mean(input.pedestal_g1_mean); + output.setPedestalG2Mean(input.pedestal_g2_mean); + + return output; +} + +inline org::openapitools::server::model::Detector_list Convert(const DetectorList &input) { + org::openapitools::server::model::Detector_list ret; + std::vector dets; + for (int i = 0; i < input.detector.size(); i++) { + org::openapitools::server::model::Detector_list_detectors_inner d; + d.setId(i); + d.setDescription(input.detector[i].description); + d.setNmodules(input.detector[i].nmodules); + d.setHeight(input.detector[i].height); + d.setWidth(input.detector[i].width); + dets.emplace_back(std::move(d)); + } + ret.setDetectors(dets); + ret.setCurrentId(input.current_id); + 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::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)); + return output; +} + +inline PlotRequest Convert(const org::openapitools::server::model::Plot_request& request) { + PlotRequest ret{}; + if (request.binningIsSet()) + ret.binning = request.getBinning(); + else + ret.binning = 0; + return ret; +} + +inline RadialIntegrationSettings Convert(const org::openapitools::server::model::Rad_int_settings& input) { + RadialIntegrationSettings ret{}; + ret.solid_angle_correction = input.isSolidAngleCorr(); + if (input.polarizationFactorIsSet()) + ret.polarization_factor = input.getPolarizationFactor(); + ret.q_spacing = input.getQSpacing(); + ret.low_q_recipA = input.getLowQRecipA(); + ret.high_q_recipA = input.getHighQRecipA(); + return ret; +} + +inline org::openapitools::server::model::Rad_int_settings Convert(const RadialIntegrationSettings& settings) { + org::openapitools::server::model::Rad_int_settings ret{}; + ret.setSolidAngleCorr(settings.solid_angle_correction); + if (settings.polarization_factor) + ret.setPolarizationFactor(settings.polarization_factor.value()); + ret.setHighQRecipA(settings.high_q_recipA); + ret.setLowQRecipA(settings.low_q_recipA); + ret.setQSpacing(settings.q_spacing); + return ret; +} + +inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_settings& input) { + DatasetSettings ret; + + ret.images_per_trigger = input.getImagesPerTrigger(); + ret.ntrigger = input.ntriggerIsSet() ? input.getNtrigger() : 1; + + if (!input.fpgaOutputIsSet()) + ret.fpga_pixel_output = FPGAPixelOutput::Auto; + else { + std::string out = str_tolower(input.getFpgaOutput()); + if (out == "auto") + ret.fpga_pixel_output = FPGAPixelOutput::Auto; + else if (out == "int16") + ret.fpga_pixel_output = FPGAPixelOutput::Int16; + else if (out == "uint16") + ret.fpga_pixel_output = FPGAPixelOutput::Uint16; + else if (out == "int32") + ret.fpga_pixel_output = FPGAPixelOutput::Int32; + else if (out == "uint32") + ret.fpga_pixel_output = FPGAPixelOutput::Uint32; + else + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown output format"); + } + + ret.summation = input.summationIsSet() ? input.getSummation() : 1; + ret.beam_x_pxl = input.getBeamXPxl(); + ret.beam_y_pxl = input.getBeamYPxl(); + ret.detector_distance_mm = input.getDetectorDistanceMm(); + ret.photon_energy_keV = input.getPhotonEnergyKeV(); + + ret.file_prefix = input.filePrefixIsSet() ? input.getFilePrefix() : ""; + ret.data_file_count = input.dataFileCountIsSet() ? input.getDataFileCount() : 1; + + if (!input.compressionIsSet()) + ret.compression = CompressionAlgorithm::BSHUF_LZ4; + else { + std::string compr = str_tolower(input.getCompression()); + if (compr == "bslz4") + ret.compression = CompressionAlgorithm::BSHUF_LZ4; + else if (compr == "bszstd") + ret.compression = CompressionAlgorithm::BSHUF_ZSTD; + else if (compr == "bszstd_rle") + ret.compression = CompressionAlgorithm::BSHUF_ZSTD_RLE; + else if (compr == "none") + ret.compression = CompressionAlgorithm::NO_COMPRESSION; + else + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown compression"); + } + + if (input.unitCellIsSet()) + ret.unit_cell = UnitCell{ + .a = input.getUnitCell().getA(), + .b = input.getUnitCell().getB(), + .c = input.getUnitCell().getC(), + .alpha = input.getUnitCell().getAlpha(), + .beta = input.getUnitCell().getBeta(), + .gamma = input.getUnitCell().getGamma() + }; + + if (input.totalFluxIsSet()) + ret.total_flux = input.getTotalFlux(); + if (input.transmissionIsSet()) + ret.attenuator_transmission = input.getTransmission(); + + ret.space_group_number = input.spaceGroupNumberIsSet() ? input.getSpaceGroupNumber() : 0; + ret.sample_name = input.getSampleName(); + + ret.save_calibration = input.saveCalibrationIsSet() && input.isSaveCalibration(); + return ret; +} + +template +void ProcessOutput(const T& output, Pistache::Http::ResponseWriter &response) { + std::stringstream s; + assert(output.validate(s)); + + nlohmann::json j; + to_json(j, output); + response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json)); +} + +JFJochBrokerHttp::JFJochBrokerHttp(const DiffractionExperiment &experiment, std::shared_ptr &rtr) +: DefaultApi(rtr) { + Pistache::Rest::Routes::Get(*rtr, "/", Pistache::Rest::Routes::bind(&JFJochBrokerHttp::GetStaticFile, this)); + Pistache::Rest::Routes::Get(*rtr, "/frontend", Pistache::Rest::Routes::bind(&JFJochBrokerHttp::GetStaticFile, this)); + Pistache::Rest::Routes::Get(*rtr, "/frontend/*", Pistache::Rest::Routes::bind(&JFJochBrokerHttp::GetStaticFile, this)); + Pistache::Rest::Routes::Get(*rtr, "/frontend/static/js/*", Pistache::Rest::Routes::bind(&JFJochBrokerHttp::GetStaticFile, this)); + Pistache::Rest::Routes::Get(*rtr, "/frontend/static/css/*", Pistache::Rest::Routes::bind(&JFJochBrokerHttp::GetStaticFile, this)); + + state_machine.NotThreadSafe_Experiment() = experiment; + init(); +} + +void JFJochBrokerHttp::AddDetectorSetup(const DetectorSetup &setup) { + state_machine.AddDetectorSetup(setup); + logger.Info("Added detector {}", setup.GetDescription()); +} + +JFJochServices &JFJochBrokerHttp::Services() { + return services; +} + +void JFJochBrokerHttp::cancel_post(Pistache::Http::ResponseWriter &response) { + state_machine.Cancel(); +} + +void JFJochBrokerHttp::deactivate_post(Pistache::Http::ResponseWriter &response) { + state_machine.Deactivate(); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::initialize_post(Pistache::Http::ResponseWriter &response) { + state_machine.Initialize(); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::start_post(const org::openapitools::server::model::Dataset_settings &datasetSettings, + Pistache::Http::ResponseWriter &response) { + state_machine.Start(Convert(datasetSettings)); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::status_get(Pistache::Http::ResponseWriter &response) { + ProcessOutput(Convert(state_machine.GetStatus()), response); +} + +void JFJochBrokerHttp::wait_till_done_post(Pistache::Http::ResponseWriter &response) { + auto state = state_machine.WaitTillMeasurementDone(std::chrono::seconds(5)); + switch (state) { + case JFJochState::Idle: + response.send(Pistache::Http::Code::Ok); + break; + case JFJochState::Inactive: + response.send(Pistache::Http::Code::Bad_Gateway); + break; + case JFJochState::Error: + response.send(Pistache::Http::Code::Internal_Server_Error); + break; + case JFJochState::Measuring: + case JFJochState::Busy: + case JFJochState::Pedestal: + response.send(Pistache::Http::Code::Gateway_Timeout); + break; + } +} + +void JFJochBrokerHttp::trigger_post(Pistache::Http::ResponseWriter &response) { + state_machine.Trigger(); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::pedestal_post(Pistache::Http::ResponseWriter &response) { + state_machine.Pedestal(); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::config_detector_get(Pistache::Http::ResponseWriter &response) { + ProcessOutput(Convert(state_machine.GetDetectorSettings()), response); +} + +void JFJochBrokerHttp::config_detector_put(const org::openapitools::server::model::Detector_settings &detectorSettings, + Pistache::Http::ResponseWriter &response) { + state_machine.LoadDetectorSettings(Convert(detectorSettings)); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::config_rad_int_get(Pistache::Http::ResponseWriter &response) { + ProcessOutput(Convert(state_machine.GetRadialIntegrationSettings()), response); +} + +void JFJochBrokerHttp::config_rad_int_put(const org::openapitools::server::model::Rad_int_settings &radIntSettings, + Pistache::Http::ResponseWriter &response) { + state_machine.LoadRadialIntegrationSettings(Convert(radIntSettings)); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::config_select_detector_get(Pistache::Http::ResponseWriter &response) { + ProcessOutput(Convert(state_machine.GetDetectorsList()), response); +} + +void JFJochBrokerHttp::config_select_detector_put( + const org::openapitools::server::model::Detector_selection &detectorSelection, + Pistache::Http::ResponseWriter &response) { + state_machine.SelectDetector(detectorSelection.getId()); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::config_spot_finding_get(Pistache::Http::ResponseWriter &response) { + ProcessOutput(Convert(state_machine.GetSpotFindingSettings()), response); +} + +void JFJochBrokerHttp::config_spot_finding_put( + const org::openapitools::server::model::Spot_finding_settings &spotFindingSettings, + Pistache::Http::ResponseWriter &response) { + state_machine.SetSpotFindingSettings(Convert(spotFindingSettings)); + response.send(Pistache::Http::Code::Ok); +} + +void JFJochBrokerHttp::plot_adu_histogram_get(Pistache::Http::ResponseWriter &response) { + PlotRequest req{.type = PlotType::ADUHistorgram}; + 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}; + if (plotRequest.binningIsSet()) + req.binning = plotRequest.getBinning(); + auto plot = state_machine.GetPlots(req); + ProcessOutput(Convert(plot), response); +} + +void JFJochBrokerHttp::plot_indexing_rate_per_file_get(Pistache::Http::ResponseWriter &response) { + PlotRequest req{.type = PlotType::IndexingRatePerFile}; + auto plot = state_machine.GetPlots(req); + ProcessOutput(Convert(plot), response); +} + +void JFJochBrokerHttp::plot_indexing_rate_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) { + PlotRequest req{.type = PlotType::IndexingRate, .binning = 0}; + if (plotRequest.binningIsSet()) + req.binning = plotRequest.getBinning(); + auto plot = state_machine.GetPlots(req); + ProcessOutput(Convert(plot), response); + +} + +void JFJochBrokerHttp::plot_rad_int_get(Pistache::Http::ResponseWriter &response) { + PlotRequest req{.type = PlotType::RadInt}; + auto plot = state_machine.GetPlots(req); + ProcessOutput(Convert(plot), 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)); +} + +void JFJochBrokerHttp::plot_spot_count_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) { + PlotRequest req{.type = PlotType::SpotCount, .binning = 0}; + if (plotRequest.binningIsSet()) + req.binning = plotRequest.getBinning(); + auto plot = state_machine.GetPlots(req); + ProcessOutput(Convert(plot), response); +} + +void JFJochBrokerHttp::statistics_calibration_get(Pistache::Http::ResponseWriter &response) { + auto calib = state_machine.GetCalibrationStatistics(); + nlohmann::json j; + + for (const auto &i: calib) { + 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)); +} + +void JFJochBrokerHttp::statistics_data_collection_get(Pistache::Http::ResponseWriter &response) { + auto stats = state_machine.GetMeasurementStatistics(); + if (stats) { + ProcessOutput(Convert(stats.value()), response); + } else { + response.send(Pistache::Http::Code::Not_Found); + } +} + +std::pair +JFJochBrokerHttp::handleOperationException(const std::exception &ex) const noexcept { + try { + throw; + } catch (const WrongDAQStateException &e) { + org::openapitools::server::model::Error_message msg; + msg.setMsg(ex.what()); + msg.setReason("WrongDAQState"); + nlohmann::json j; + to_json(j, msg); + return std::make_pair(Pistache::Http::Code::Internal_Server_Error, j.dump()); + } catch (const std::exception &e) { + org::openapitools::server::model::Error_message msg; + msg.setMsg(ex.what()); + msg.setReason("Other"); + nlohmann::json j; + to_json(j, msg); + return std::make_pair(Pistache::Http::Code::Internal_Server_Error, j.dump()); + } +} + +void JFJochBrokerHttp::GetStaticFile(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + if (!frontend_directory.empty()) { + logger.Info("Requesting static resource {} from {}", request.resource(), frontend_directory); + if (request.resource().find("../") != std::string::npos) + response.send(Pistache::Http::Code::Forbidden); + try { + if ((request.resource() == "/") + || (request.resource() == "/frontend") + || (request.resource() == "/frontend/")) + Pistache::Http::serveFile(response, frontend_directory + "/index.html"); + else if (request.resource().substr(0, 10) == "/frontend/") + Pistache::Http::serveFile(response, frontend_directory + "/" + request.resource().substr(10)); + else response.send(Pistache::Http::Code::Not_Found); + } catch (const std::exception &e) { + logger.Error(e.what()); + response.send(Pistache::Http::Code::Not_Found); + } + } else response.send(Pistache::Http::Code::Not_Found); +} + +JFJochBrokerHttp &JFJochBrokerHttp::FrontendDirectory(const std::string &directory) { + frontend_directory = directory; + return *this; +} \ No newline at end of file diff --git a/broker/JFJochBrokerHttp.h b/broker/JFJochBrokerHttp.h new file mode 100644 index 00000000..0440166e --- /dev/null +++ b/broker/JFJochBrokerHttp.h @@ -0,0 +1,91 @@ +// Copyright (2019-2023) Paul Scherrer Institute +// Using OpenAPI licensed with Apache License 2.0 + +#ifndef JUNGFRAUJOCH_JFJOCHBROKERHTTP_H +#define JUNGFRAUJOCH_JFJOCHBROKERHTTP_H + +#include +#include +#include + +#include "../common/Logger.h" +#include "JFJochStateMachine.h" +#include "gen/api/DefaultApi.h" + +class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi { + Logger logger{"JFJochBroker"}; + JFJochServices services {logger}; + JFJochStateMachine state_machine {services, logger}; + std::string frontend_directory; + + void config_detector_get(Pistache::Http::ResponseWriter &response) override; + + void config_detector_put(const org::openapitools::server::model::Detector_settings &detectorSettings, + Pistache::Http::ResponseWriter &response) override; + + void config_rad_int_get(Pistache::Http::ResponseWriter &response) override; + + void config_rad_int_put(const org::openapitools::server::model::Rad_int_settings &radIntSettings, + Pistache::Http::ResponseWriter &response) override; + + void config_select_detector_get(Pistache::Http::ResponseWriter &response) override; + + void config_select_detector_put(const org::openapitools::server::model::Detector_selection &detectorSelection, + Pistache::Http::ResponseWriter &response) override; + + void config_spot_finding_get(Pistache::Http::ResponseWriter &response) override; + + void config_spot_finding_put(const org::openapitools::server::model::Spot_finding_settings &spotFindingSettings, + Pistache::Http::ResponseWriter &response) override; + + void plot_adu_histogram_get(Pistache::Http::ResponseWriter &response) override; + + void plot_bkg_estimate_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) override; + + void plot_indexing_rate_per_file_get(Pistache::Http::ResponseWriter &response) override; + + void plot_indexing_rate_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) override; + + void plot_rad_int_get(Pistache::Http::ResponseWriter &response) override; + + void plot_rad_int_per_file_get(Pistache::Http::ResponseWriter &response) override; + + void plot_spot_count_post(const org::openapitools::server::model::Plot_request &plotRequest, + Pistache::Http::ResponseWriter &response) override; + + void statistics_calibration_get(Pistache::Http::ResponseWriter &response) override; + + void statistics_data_collection_get(Pistache::Http::ResponseWriter &response) override; + + void cancel_post(Pistache::Http::ResponseWriter &response) override; + + void deactivate_post(Pistache::Http::ResponseWriter &response) override; + + void initialize_post(Pistache::Http::ResponseWriter &response) override; + + void start_post(const org::openapitools::server::model::Dataset_settings &datasetSettings, + Pistache::Http::ResponseWriter &response) override; + + void status_get(Pistache::Http::ResponseWriter &response) override; + + void wait_till_done_post(Pistache::Http::ResponseWriter &response) override; + void trigger_post(Pistache::Http::ResponseWriter &response) override; + void pedestal_post(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; + +public: + JFJochBrokerHttp(const DiffractionExperiment& experiment, std::shared_ptr &rtr); + void AddDetectorSetup(const DetectorSetup &setup); + JFJochServices& Services(); + + JFJochBrokerHttp& FrontendDirectory(const std::string &directory); + + ~JFJochBrokerHttp() override = default; +}; + + +#endif //JUNGFRAUJOCH_JFJOCHBROKERHTTP_H diff --git a/broker/JFJochBrokerParser.cpp b/broker/JFJochBrokerParser.cpp index 5e3c54c7..00ebdd02 100644 --- a/broker/JFJochBrokerParser.cpp +++ b/broker/JFJochBrokerParser.cpp @@ -1,7 +1,6 @@ // Copyright (2019-2023) Paul Scherrer Institute #include "JFJochBrokerParser.h" -#include "JFJochBroker.h" #include "../common/NetworkAddressConvert.h" inline bool CHECK_ARRAY(const nlohmann::json &j, const std::string& tag) { @@ -35,6 +34,19 @@ inline int64_t GET_I64(const nlohmann::json &j, const std::string& tag, int64_t return def; } +inline float GET_FLOAT(const nlohmann::json &j, const std::string& tag, float def) { + if (j.contains(tag)) { + if (!j[tag].is_number()) + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, tag + " must be float"); + try { + return j[tag].get(); + } catch (std::exception &e) { + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, tag + ": " + e.what()); + } + } else + return def; +} + inline bool GET_BOOL(const nlohmann::json &j, const std::string& tag, bool def) { if (j.contains(tag)) { if (!j[tag].is_boolean()) @@ -48,6 +60,19 @@ inline bool GET_BOOL(const nlohmann::json &j, const std::string& tag, bool def) return def; } +inline std::string GET_STR(const nlohmann::json &j, const std::string& tag, const std::string& def) { + if (j.contains(tag)) { + if (!j[tag].is_string()) + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, tag + " must be string"); + try { + return j[tag].get(); + } catch (std::exception &e) { + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, tag + ": " + e.what()); + } + } else + return def; +} + inline std::string GET_STR(const nlohmann::json &j, const std::string& tag) { if (j.contains(tag)) { if (!j[tag].is_string()) @@ -198,11 +223,14 @@ DetectorSetup ParseDetectorSetup(const nlohmann::json &j) { if (!gain_files.empty()) setup.LoadGain(gain_files); - setup.UDPInterfaceCount(GET_I64(j, "udp_interface_count", 2)); + setup.UDPInterfaceCount(GET_I64(j, "udp_interface_count", 2)) + .SensorThickness_um(GET_FLOAT(j, "sensor_thickness_um", 320.0f)) + .PixelSize_um(GET_FLOAT(j, "pixel_size_um", 75.0f)) + .SensorMaterial(GET_STR(j, "sensor_material", "Si")); return setup; } -void ParseDetectorSetup(const nlohmann::json &j, const std::string& tag, JFJochBroker& broker) { +void ParseDetectorSetup(const nlohmann::json &j, const std::string& tag, JFJochBrokerHttp& broker) { if (CHECK_ARRAY(j, tag)) { for (const auto &iter : j[tag]) broker.AddDetectorSetup(ParseDetectorSetup(iter)); diff --git a/broker/JFJochBrokerParser.h b/broker/JFJochBrokerParser.h index 2122dee6..e5b02de7 100644 --- a/broker/JFJochBrokerParser.h +++ b/broker/JFJochBrokerParser.h @@ -5,7 +5,7 @@ #include #include "../common/DiffractionExperiment.h" -#include "JFJochBroker.h" +#include "JFJochBrokerHttp.h" #include "../acquisition_device/AcquisitionDeviceGroup.h" #include "../frame_serialize/ZMQPreviewPublisher.h" @@ -13,7 +13,7 @@ DetectorGeometry ParseStandardDetectorGeometry(const nlohmann::json &j); DetectorGeometry ParseCustomDetectorGeometry(const nlohmann::json &j); DetectorGeometry ParseDetectorGeometry(const nlohmann::json &j); DetectorSetup ParseDetectorSetup(const nlohmann::json &j); -void ParseDetectorSetup(const nlohmann::json &j, const std::string& tag, JFJochBroker& broker); +void ParseDetectorSetup(const nlohmann::json &j, const std::string& tag, JFJochBrokerHttp& broker); void ParseFacilityConfiguration(const nlohmann::json &j, const std::string& tag, DiffractionExperiment &experiment); void ParseAcquisitionDeviceGroup(const nlohmann::json &input, const std::string& tag, AcquisitionDeviceGroup &aq_devices); diff --git a/broker/JFJochServices.cpp b/broker/JFJochServices.cpp index 081f6a93..a6b677e9 100644 --- a/broker/JFJochServices.cpp +++ b/broker/JFJochServices.cpp @@ -83,17 +83,6 @@ JFJochServicesOutput JFJochServices::Stop(const JFCalibration &calibration) { return ret; } -void JFJochServices::Abort() { - // Abort should try to achieve the best outcome possible - // but it is OK if things fail (for example lost connection) - try { - if (receiver != nullptr) - receiver->Abort(); - } catch (const std::exception &e) { - logger.Error(e.what()); - } -} - void JFJochServices::Cancel() { if (detector) detector->Stop(); @@ -112,7 +101,7 @@ JFJochServices &JFJochServices::Detector() { return *this; } -JFJochReceiverStatus JFJochServices::GetReceiverStatus() { +std::optional JFJochServices::GetReceiverStatus() { if (receiver == nullptr) return {}; return receiver->GetStatus(); @@ -140,9 +129,9 @@ RadialIntegrationProfiles JFJochServices::GetRadialIntegrationProfiles() { } } -void JFJochServices::SetDataProcessingSettings(const DataProcessingSettings &settings) { +void JFJochServices::SetSpotFindingSettings(const SpotFindingSettings &settings) { if (receiver) - receiver->SetDataProcessingSettings(settings); + receiver->SetSpotFindingSettings(settings); } void JFJochServices::Trigger() { diff --git a/broker/JFJochServices.h b/broker/JFJochServices.h index 8cf01cee..856c52c7 100644 --- a/broker/JFJochServices.h +++ b/broker/JFJochServices.h @@ -24,15 +24,14 @@ public: void Off(); void Start(const DiffractionExperiment& experiment, const JFCalibration &calibration); JFJochServicesOutput Stop(const JFCalibration &calibration); - void Abort(); void Cancel(); void Trigger(); - JFJochReceiverStatus GetReceiverStatus(); + std::optional GetReceiverStatus(); Plot GetPlots(const PlotRequest &request); RadialIntegrationProfiles GetRadialIntegrationProfiles(); - void SetDataProcessingSettings(const DataProcessingSettings &settings); + void SetSpotFindingSettings(const SpotFindingSettings &settings); JFJochServices& Receiver(JFJochReceiverService *input); JFJochServices& Detector(); }; diff --git a/broker/JFJochStateMachine.cpp b/broker/JFJochStateMachine.cpp index eba347a5..6f4b2955 100644 --- a/broker/JFJochStateMachine.cpp +++ b/broker/JFJochStateMachine.cpp @@ -17,10 +17,9 @@ void LoadDatasetSettings(DiffractionExperiment& experiment, const DatasetSetting experiment.PhotonEnergy_keV(settings.photon_energy_keV); experiment.FilePrefix(settings.file_prefix); experiment.DataFileCount(settings.data_file_count); - if (settings.unit_cell) - experiment.SetUnitCell(settings.unit_cell.value()); - else - experiment.SetUnitCell(); + experiment.SetUnitCell(settings.unit_cell); + experiment.AttenuatorTransmission(settings.attenuator_transmission); + experiment.TotalFlux(settings.total_flux); experiment.SpaceGroupNumber(settings.space_group_number); experiment.SampleName(settings.sample_name); experiment.Compression(settings.compression); @@ -36,12 +35,12 @@ void LoadDatasetSettings(DiffractionExperiment& experiment, const DatasetSetting } } -void LoadDetectorSettings(DiffractionExperiment& experiment, const DetectorSettings &settings) { +void ApplyDetectorSettings(DiffractionExperiment& experiment, const DetectorSettings &settings) { auto tmp = experiment; try { - if (settings.count_time_us > 0) + if (settings.count_time_us) experiment.FrameTime(std::chrono::microseconds(settings.frame_time_us), - std::chrono::microseconds(settings.count_time_us)); + std::chrono::microseconds(settings.count_time_us.value())); else experiment.FrameTime(std::chrono::microseconds(settings.frame_time_us)); @@ -53,11 +52,33 @@ void LoadDetectorSettings(DiffractionExperiment& experiment, const DetectorSetti else experiment.Mode(DetectorMode::Conversion); - experiment.PedestalG0Frames(settings.pedestal_g0_frames); - experiment.PedestalG1Frames(settings.pedestal_g1_frames); - experiment.PedestalG2Frames(settings.pedestal_g2_frames); - if (settings.storage_cell_delay_ns > 0) - experiment.StorageCellDelay(std::chrono::nanoseconds(settings.storage_cell_delay_ns)); + if (settings.pedestal_g0_frames) + experiment.PedestalG0Frames(settings.pedestal_g0_frames.value()); + if (settings.pedestal_g1_frames) + experiment.PedestalG1Frames(settings.pedestal_g1_frames.value()); + if (settings.pedestal_g2_frames) + experiment.PedestalG2Frames(settings.pedestal_g2_frames.value()); + if (settings.storage_cell_delay_ns) + experiment.StorageCellDelay(std::chrono::nanoseconds(settings.storage_cell_delay_ns.value())); + } catch (...) { + experiment = tmp; + throw; + } +} + +void ApplyRadialIntegrationSettings(DiffractionExperiment& experiment, const RadialIntegrationSettings &settings) { + auto tmp = experiment; + try { + if (settings.polarization_factor) { + experiment.ApplyPolarizationCorr(true); + experiment.PolarizationFactor(settings.polarization_factor.value()); + } else + experiment.ApplyPolarizationCorr(false); + + experiment.ApplySolidAngleCorr(settings.solid_angle_correction); + experiment.LowQForRadialInt_recipA(settings.low_q_recipA); + experiment.HighQForRadialInt_recipA(settings.high_q_recipA); + experiment.QSpacingForRadialInt_recipA(settings.q_spacing); } catch (...) { experiment = tmp; throw; @@ -71,6 +92,9 @@ data_processing_settings(DiffractionExperiment::DefaultDataProcessingSettings()) } void JFJochStateMachine::ImportPedestalG0(const JFJochReceiverOutput &receiver_output) { + if (receiver_output.pedestal_result.empty()) + return; + if (receiver_output.pedestal_result.size() != experiment.GetModulesNum() * experiment.GetStorageCellNumber()) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Mismatch in pedestal output"); @@ -84,6 +108,12 @@ void JFJochStateMachine::ImportPedestalG0(const JFJochReceiverOutput &receiver_o void JFJochStateMachine::ImportPedestal(const JFJochReceiverOutput &receiver_output, size_t gain_level, size_t storage_cell) { + if (receiver_output.pedestal_result.empty()) + return; + + if (receiver_output.pedestal_result.size() != experiment.GetModulesNum() * experiment.GetStorageCellNumber()) + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Mismatch in pedestal output"); + for (int i = 0; i < receiver_output.pedestal_result.size(); i++) calibration->Pedestal(i, gain_level, storage_cell) = receiver_output.pedestal_result[i]; SetCalibrationStatistics(calibration->GetModuleStatistics()); @@ -196,30 +226,42 @@ void JFJochStateMachine::TakePedestalInternalG2(std::unique_lock &ul void JFJochStateMachine::Initialize() { std::unique_lock ul(m); - if ((state == JFJochState::Measuring) || (state == JFJochState::Pedestal)) - throw JFJochException(JFJochExceptionCategory::WrongDAQState, "Cannot initialize during measurement"); + if (IsRunning()) + throw WrongDAQStateException ("Cannot initialize during measurement"); if (detector_setup.empty()) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Detector information not provided"); + CheckError(); // Clear error, we don't care what was it + logger.Info("Initialize"); state = JFJochState::Busy; ClearMeasurementStatistics(); - try { - services.On(experiment); - } catch (...) { - state = JFJochState::Error; - throw; - } - TakePedestalInternalAll(ul); + measurement = std::async(std::launch::async, &JFJochStateMachine::InitializeThread, this, std::move(ul)); } void JFJochStateMachine::Pedestal() { std::unique_lock ul(m); if (state != JFJochState::Idle) - throw JFJochException(JFJochExceptionCategory::WrongDAQState,"Must be idle to take pedestal"); + throw WrongDAQStateException ("Must be idle to take pedestal"); + + measurement = std::async(std::launch::async, &JFJochStateMachine::PedestalThread, this, std::move(ul)); +} + + +void JFJochStateMachine::PedestalThread(std::unique_lock ul) { + TakePedestalInternalAll(ul); +} + +void JFJochStateMachine::InitializeThread(std::unique_lock ul) { + try { + services.On(experiment); + } catch (...) { + state = JFJochState::Error; + throw; + } TakePedestalInternalAll(ul); } @@ -233,8 +275,7 @@ void JFJochStateMachine::Start(const DatasetSettings& settings) { std::unique_lock ul(m); if (state != JFJochState::Idle) - throw JFJochException(JFJochExceptionCategory::WrongDAQState, - "Must be idle to start measurement"); + throw WrongDAQStateException ("Must be idle to start measurement"); if (measurement.valid()) measurement.get(); // In case measurement was running - clear thread @@ -253,14 +294,14 @@ void JFJochStateMachine::Start(const DatasetSettings& settings) { try { state = JFJochState::Busy; - services.SetDataProcessingSettings(GetDataAnalysisSettings()); + services.SetSpotFindingSettings(GetSpotFindingSettings()); services.Start(experiment, *calibration); state = JFJochState::Measuring; - measurement = std::async(std::launch::async, &JFJochStateMachine::WaitTillMeasurementDone, this); + measurement = std::async(std::launch::async, &JFJochStateMachine::MeasurementThread, this); } catch (...) { state = JFJochState::Error; - services.Abort(); + services.Cancel(); throw; } } @@ -272,35 +313,13 @@ void JFJochStateMachine::SetDatasetDefaults(DatasetSettings &settings) { settings.ntrigger = 1; } -void JFJochStateMachine::Stop() { - std::unique_lock ul(m); +void JFJochStateMachine::WaitTillMeasurementDone() { +std::unique_lock ul(m); - if (state == JFJochState::Pedestal) - throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, - "Cannot use the function during pedestal collection"); - - c.wait(ul, [&] { return state != JFJochState::Measuring; }); - - if (!measurement.valid()) - return; // This is for unlikely condition of two parallel stops - else - measurement.get(); - - switch (state) { - case JFJochState::Inactive: - throw JFJochException(JFJochExceptionCategory::WrongDAQState,"Not initialized"); - case JFJochState::Error: - throw JFJochException(JFJochExceptionCategory::WrongDAQState,"Detector in error state"); - case JFJochState::Measuring: - case JFJochState::Busy: - case JFJochState::Pedestal: - throw JFJochException(JFJochExceptionCategory::WrongDAQState,"Detector in not expected state to end measurment"); - case JFJochState::Idle: - break; - } +c.wait(ul, [&] { return !IsRunning(); }); } -void JFJochStateMachine::WaitTillMeasurementDone() { +void JFJochStateMachine::MeasurementThread() { try { auto tmp_output = services.Stop(*calibration); SetFullMeasurementOutput(tmp_output); @@ -315,15 +334,6 @@ void JFJochStateMachine::WaitTillMeasurementDone() { c.notify_all(); } -void JFJochStateMachine::Abort() { - // This is inconsistency in naming - need to solve later - std::unique_lock ul(m); - if ((state == JFJochState::Pedestal) || (state == JFJochState::Measuring)) { - services.Abort(); - cancel_sequence = true; - } -} - void JFJochStateMachine::Cancel() { // This is inconsistency in naming - need to solve later std::unique_lock ul(m); @@ -401,17 +411,6 @@ std::optional JFJochStateMachine::GetMeasurementStatistic return measurement_statistics; } -void JFJochStateMachine::LoadMask(const std::vector &vec, uint32_t bit) { - std::unique_lock ul(m); - if (state == JFJochState::Inactive) - throw JFJochException(JFJochExceptionCategory::WrongDAQState, - "Detector not calibrated"); - if (state != JFJochState::Idle) - throw JFJochException(JFJochExceptionCategory::WrongDAQState, - "Cannot load mask if detector is not idle"); - calibration->LoadMask(experiment, vec, bit); -} - std::vector JFJochStateMachine::GetCalibrationStatistics() const { std::unique_lock ul(calibration_statistics_mutex); return calibration_statistics; @@ -438,22 +437,21 @@ DetectorSettings JFJochStateMachine::GetDetectorSettings() const { return ret; } -void JFJochStateMachine::SetDetectorSettings(const DetectorSettings &settings) { +void JFJochStateMachine::LoadDetectorSettings(const DetectorSettings &settings) { std::unique_lock ul(m); switch (state) { case JFJochState::Inactive: case JFJochState::Error: - LoadDetectorSettings(experiment, settings); + ApplyDetectorSettings(experiment, settings); break; case JFJochState::Idle: - LoadDetectorSettings(experiment, settings); - TakePedestalInternalAll(ul); + ApplyDetectorSettings(experiment, settings); + measurement = std::async(std::launch::async, &JFJochStateMachine::PedestalThread, this, std::move(ul)); break; case JFJochState::Measuring: case JFJochState::Busy: case JFJochState::Pedestal: - throw JFJochException(JFJochExceptionCategory::WrongDAQState, - "Cannot change detector set during data collection"); + throw WrongDAQStateException ("Cannot change detector settings during data collection"); } } @@ -467,9 +465,11 @@ BrokerStatus JFJochStateMachine::GetStatus() const { ret.broker_state = state; try { auto rcv_status = services.GetReceiverStatus(); - ret.progress = rcv_status.progress; - ret.indexing_rate = rcv_status.indexing_rate; - ret.receiver_send_buffers_avail = rcv_status.send_buffers_avail; + if (rcv_status) { + ret.progress = rcv_status.value().progress; + ret.indexing_rate = rcv_status.value().indexing_rate; + ret.receiver_send_buffers_avail = rcv_status.value().send_buffers_avail; + } } catch (JFJochException &e) {} // ignore exception in getting receiver status (don't really care, e.g. if receiver is down) return ret; @@ -483,19 +483,14 @@ RadialIntegrationProfiles JFJochStateMachine::GetRadialIntegrationProfiles() con return services.GetRadialIntegrationProfiles(); } -void JFJochStateMachine::SetDataProcessingSettings(const DataProcessingSettings &settings) { +void JFJochStateMachine::SetSpotFindingSettings(const SpotFindingSettings &settings) { std::unique_lock ul(data_processing_settings_mutex); DiffractionExperiment::CheckDataProcessingSettings(settings); data_processing_settings = settings; - services.SetDataProcessingSettings(settings); + services.SetSpotFindingSettings(settings); } -DataProcessingSettings JFJochStateMachine::GetDataProcessingSettings() const { - std::unique_lock ul(data_processing_settings_mutex); - return data_processing_settings; -} - -DataProcessingSettings JFJochStateMachine::GetDataAnalysisSettings() const { +SpotFindingSettings JFJochStateMachine::GetSpotFindingSettings() const { std::unique_lock ul(data_processing_settings_mutex); return data_processing_settings; } @@ -519,16 +514,16 @@ DetectorList JFJochStateMachine::GetDetectorsList() { std::unique_lock ul(m); DetectorList ret; - for (int i = 0; i < detector_setup.size(); i++) { + for (const auto & i : detector_setup) { DetectorListElement tmp; - tmp.description = detector_setup[i].GetDescription(); - tmp.nmodules = detector_setup[i].GetModulesNum(); - tmp.id = i; + tmp.description = i.GetDescription(); + tmp.nmodules = i.GetModulesNum(); + tmp.width = i.GetGeometry().GetWidth(); + tmp.height = i.GetGeometry().GetHeight(); ret.detector.emplace_back(std::move(tmp)); } ret.current_id = current_detector_setup; - ret.current_description = experiment.GetDetectorDescription(); return ret; } @@ -538,24 +533,72 @@ void JFJochStateMachine::SelectDetector(int64_t id) { if ((id < 0) || (id >= detector_setup.size())) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "Detector doesn't exist"); + if (IsRunning()) + throw WrongDAQStateException ("Cannot change detector during data collection"); + + try { + experiment.Detector(detector_setup[id]); + gain_calibration = detector_setup[id].GetGainCalibration(); + state = JFJochState::Inactive; + current_detector_setup = id; + } catch (JFJochException &e) { + logger.ErrorException(e); + state = JFJochState::Inactive; + } +} + +void JFJochStateMachine::LoadRadialIntegrationSettings(const RadialIntegrationSettings &settings) { + std::unique_lock ul(m); + + if (IsRunning()) + throw WrongDAQStateException ("Cannot change radial integration settings during data collection"); + + ApplyRadialIntegrationSettings(experiment, settings); +} + +RadialIntegrationSettings JFJochStateMachine::GetRadialIntegrationSettings() const { + RadialIntegrationSettings ret; + + if (experiment.GetApplyPolarizationCorr()) + ret.polarization_factor = experiment.GetPolarizationFactor(); + ret.solid_angle_correction = experiment.GetApplySolidAngleCorr(); + + ret.q_spacing = experiment.GetQSpacingForRadialInt_recipA(); + ret.low_q_recipA = experiment.GetLowQForRadialInt_recipA(); + ret.high_q_recipA = experiment.GetHighQForRadialInt_recipA(); + + return ret; +} + +bool JFJochStateMachine::IsRunning() const { switch (state) { case JFJochState::Inactive: case JFJochState::Error: case JFJochState::Idle: - try { - experiment.Detector(detector_setup[id]); - gain_calibration = detector_setup[id].GetGainCalibration(); - state = JFJochState::Inactive; - current_detector_setup = id; - } catch (JFJochException &e) { - logger.ErrorException(e); - state = JFJochState::Inactive; - } - break; + return false; case JFJochState::Measuring: case JFJochState::Busy: case JFJochState::Pedestal: - throw JFJochException(JFJochExceptionCategory::WrongDAQState, - "Cannot change detector during data collection"); + return true; + default: + throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "State unknown"); } } + +JFJochState JFJochStateMachine::WaitTillMeasurementDone(std::chrono::milliseconds timeout) { + std::unique_lock ul(m); + + c.wait_for(ul, timeout, [&] { return !IsRunning(); }); + + return state; +} + +std::optional JFJochStateMachine::CheckError() { + try { + if (measurement.valid()) + measurement.get(); + } catch (JFJochException &e) { + return e.what(); + } + return {}; +} \ No newline at end of file diff --git a/broker/JFJochStateMachine.h b/broker/JFJochStateMachine.h index af9927ec..c6f65502 100644 --- a/broker/JFJochStateMachine.h +++ b/broker/JFJochStateMachine.h @@ -17,22 +17,22 @@ enum class JFJochState {Inactive, Idle, Measuring, Error, Busy, Pedestal}; struct BrokerStatus { - JFJochState broker_state; - float progress; - float indexing_rate; - float receiver_send_buffers_avail; + JFJochState broker_state; + std::optional progress; + std::optional indexing_rate; + std::optional receiver_send_buffers_avail; }; struct DetectorListElement { std::string description; int64_t nmodules; - int64_t id; + int64_t width; + int64_t height; }; struct DetectorList { std::vector detector; int64_t current_id; - std::string current_description; }; struct MeasurementStatistics { @@ -75,26 +75,33 @@ struct DatasetSettings { std::optional unit_cell; int64_t space_group_number; - bool rad_int_solid_angle_corr; - bool rad_int_polarization_corr; - float rad_int_polarization_factor; - bool save_calibration; + std::optional total_flux; + std::optional attenuator_transmission; }; struct DetectorSettings { int64_t frame_time_us; - int64_t count_time_us; + std::optional count_time_us; int64_t storage_cell_count; bool use_internal_packet_generator; bool collect_raw_data; - int64_t pedestal_g0_frames; - int64_t pedestal_g1_frames; - int64_t pedestal_g2_frames; + std::optional pedestal_g0_frames; + std::optional pedestal_g1_frames; + std::optional pedestal_g2_frames; - int64_t storage_cell_delay_ns; + std::optional storage_cell_delay_ns; +}; + + +struct RadialIntegrationSettings { + bool solid_angle_correction; + std::optional polarization_factor; + float high_q_recipA; + float low_q_recipA; + float q_spacing; }; void LoadDatasetSettings(DiffractionExperiment& experiment, const DatasetSettings &settings); @@ -127,13 +134,17 @@ class JFJochStateMachine { void ClearAndSetMeasurementStatistics(); mutable std::mutex data_processing_settings_mutex; - DataProcessingSettings data_processing_settings; + SpotFindingSettings data_processing_settings; // Private functions assume that lock m is acquired void SetDatasetDefaults(DatasetSettings& settings); - void WaitTillMeasurementDone(); + void MeasurementThread(); + void PedestalThread(std::unique_lock ul); + void InitializeThread(std::unique_lock ul); void ImportPedestal(const JFJochReceiverOutput &receiver_output, size_t gain_level, size_t storage_cell = 0); void 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); @@ -147,17 +158,16 @@ public: void Pedestal(); void Deactivate(); void Start(const DatasetSettings& settings); - void Stop(); + void WaitTillMeasurementDone(); + JFJochState WaitTillMeasurementDone(std::chrono::milliseconds timeout); void Trigger(); - void Abort(); void Cancel(); - void LoadMask(const std::vector &vec, uint32_t bit); void SetCalibrationStatistics(const std::vector &input); DetectorSettings GetDetectorSettings() const; - void SetDetectorSettings(const DetectorSettings& settings); + void LoadDetectorSettings(const DetectorSettings& settings); // return by value to ensure thread safety std::optional GetMeasurementStatistics() const; @@ -167,21 +177,23 @@ public: Plot GetPlots(const PlotRequest &request) const; RadialIntegrationProfiles GetRadialIntegrationProfiles() const; - void SetDataProcessingSettings(const DataProcessingSettings& settings); - DataProcessingSettings GetDataProcessingSettings() const; - DataProcessingSettings GetDataAnalysisSettings() const; + void SetSpotFindingSettings(const SpotFindingSettings& settings); + SpotFindingSettings GetSpotFindingSettings() const; JFJochState GetState() const; + void AddDetectorSetup(const DetectorSetup& setup); + DetectorList GetDetectorsList(); + void SelectDetector(int64_t id); + + void LoadRadialIntegrationSettings(const RadialIntegrationSettings& settings); + RadialIntegrationSettings GetRadialIntegrationSettings() const; + // Not thread safe - only for configuration in serial context DiffractionExperiment& NotThreadSafe_Experiment(); // Function for debug only - UNSAFE for real operation void DebugOnly_SetState(JFJochState state); - - void AddDetectorSetup(const DetectorSetup& setup); - DetectorList GetDetectorsList(); - void SelectDetector(int64_t id); }; diff --git a/broker/gen/api/DefaultApi.cpp b/broker/gen/api/DefaultApi.cpp new file mode 100644 index 00000000..f5b03537 --- /dev/null +++ b/broker/gen/api/DefaultApi.cpp @@ -0,0 +1,694 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + +#include "DefaultApi.h" +#include "Helpers.h" + +namespace org::openapitools::server::api +{ + +using namespace org::openapitools::server::helpers; +using namespace org::openapitools::server::model; + +const std::string DefaultApi::base = ""; + +DefaultApi::DefaultApi(const std::shared_ptr& rtr) + : router(rtr) +{ +} + +void DefaultApi::init() { + setupRoutes(); +} + +void DefaultApi::setupRoutes() { + using namespace Pistache::Rest; + + Routes::Post(*router, base + "/cancel", Routes::bind(&DefaultApi::cancel_post_handler, this)); + Routes::Get(*router, base + "/config/detector", Routes::bind(&DefaultApi::config_detector_get_handler, this)); + Routes::Put(*router, base + "/config/detector", Routes::bind(&DefaultApi::config_detector_put_handler, this)); + Routes::Get(*router, base + "/config/rad_int", Routes::bind(&DefaultApi::config_rad_int_get_handler, this)); + Routes::Put(*router, base + "/config/rad_int", Routes::bind(&DefaultApi::config_rad_int_put_handler, this)); + Routes::Get(*router, base + "/config/select_detector", Routes::bind(&DefaultApi::config_select_detector_get_handler, this)); + Routes::Put(*router, base + "/config/select_detector", Routes::bind(&DefaultApi::config_select_detector_put_handler, this)); + Routes::Get(*router, base + "/config/spot_finding", Routes::bind(&DefaultApi::config_spot_finding_get_handler, this)); + Routes::Put(*router, base + "/config/spot_finding", Routes::bind(&DefaultApi::config_spot_finding_put_handler, this)); + Routes::Post(*router, base + "/deactivate", Routes::bind(&DefaultApi::deactivate_post_handler, this)); + Routes::Post(*router, base + "/initialize", Routes::bind(&DefaultApi::initialize_post_handler, this)); + Routes::Post(*router, base + "/pedestal", Routes::bind(&DefaultApi::pedestal_post_handler, this)); + Routes::Get(*router, base + "/plot/adu_histogram", Routes::bind(&DefaultApi::plot_adu_histogram_get_handler, this)); + Routes::Post(*router, base + "/plot/bkg_estimate", Routes::bind(&DefaultApi::plot_bkg_estimate_post_handler, this)); + Routes::Get(*router, base + "/plot/indexing_rate_per_file", Routes::bind(&DefaultApi::plot_indexing_rate_per_file_get_handler, this)); + Routes::Post(*router, base + "/plot/indexing_rate", Routes::bind(&DefaultApi::plot_indexing_rate_post_handler, this)); + Routes::Get(*router, base + "/plot/rad_int", Routes::bind(&DefaultApi::plot_rad_int_get_handler, this)); + 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/spot_count", Routes::bind(&DefaultApi::plot_spot_count_post_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)); + + // Default handler, called when a route is not found + router->addCustomHandler(Routes::bind(&DefaultApi::default_api_default_handler, this)); +} + +std::pair DefaultApi::handleParsingException(const std::exception& ex) const noexcept +{ + try { + throw; + } catch (nlohmann::detail::exception &e) { + return std::make_pair(Pistache::Http::Code::Bad_Request, e.what()); + } catch (org::openapitools::server::helpers::ValidationException &e) { + return std::make_pair(Pistache::Http::Code::Bad_Request, e.what()); + } catch (std::exception &e) { + return std::make_pair(Pistache::Http::Code::Internal_Server_Error, e.what()); + } +} + +std::pair DefaultApi::handleOperationException(const std::exception& ex) const noexcept +{ + return std::make_pair(Pistache::Http::Code::Internal_Server_Error, ex.what()); +} + +void DefaultApi::cancel_post_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->cancel_post(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::config_detector_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->config_detector_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::config_detector_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + try { + + + // Getting the body param + + Detector_settings detectorSettings; + + try { + nlohmann::json::parse(request.body()).get_to(detectorSettings); + detectorSettings.validate(); + } catch (std::exception &e) { + const std::pair errorInfo = this->handleParsingException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + try { + this->config_detector_put(detectorSettings, 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::config_rad_int_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->config_rad_int_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::config_rad_int_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + try { + + + // Getting the body param + + Rad_int_settings radIntSettings; + + try { + nlohmann::json::parse(request.body()).get_to(radIntSettings); + radIntSettings.validate(); + } catch (std::exception &e) { + const std::pair errorInfo = this->handleParsingException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + try { + this->config_rad_int_put(radIntSettings, 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::config_select_detector_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->config_select_detector_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::config_select_detector_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + try { + + + // Getting the body param + + Detector_selection detectorSelection; + + try { + nlohmann::json::parse(request.body()).get_to(detectorSelection); + detectorSelection.validate(); + } catch (std::exception &e) { + const std::pair errorInfo = this->handleParsingException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + try { + this->config_select_detector_put(detectorSelection, 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::config_spot_finding_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->config_spot_finding_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::config_spot_finding_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + try { + + + // Getting the body param + + Spot_finding_settings spotFindingSettings; + + try { + nlohmann::json::parse(request.body()).get_to(spotFindingSettings); + spotFindingSettings.validate(); + } catch (std::exception &e) { + const std::pair errorInfo = this->handleParsingException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + try { + this->config_spot_finding_put(spotFindingSettings, 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::deactivate_post_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->deactivate_post(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::initialize_post_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->initialize_post(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::pedestal_post_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->pedestal_post(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_adu_histogram_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->plot_adu_histogram_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::plot_bkg_estimate_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_bkg_estimate_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_indexing_rate_per_file_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->plot_indexing_rate_per_file_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::plot_indexing_rate_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_indexing_rate_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_rad_int_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->plot_rad_int_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::plot_rad_int_per_file_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->plot_rad_int_per_file_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::plot_spot_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_spot_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::start_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response) { + try { + + + // Getting the body param + + Dataset_settings datasetSettings; + + try { + nlohmann::json::parse(request.body()).get_to(datasetSettings); + datasetSettings.validate(); + } catch (std::exception &e) { + const std::pair errorInfo = this->handleParsingException(e); + response.send(errorInfo.first, errorInfo.second); + return; + } + + try { + this->start_post(datasetSettings, 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::statistics_calibration_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->statistics_calibration_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::statistics_data_collection_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->statistics_data_collection_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::status_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->status_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::trigger_post_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->trigger_post(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::wait_till_done_post_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) { + try { + + + try { + this->wait_till_done_post(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) { + response.send(Pistache::Http::Code::Not_Found, "The requested method does not exist"); +} + +} // namespace org::openapitools::server::api + diff --git a/broker/gen/api/DefaultApi.h b/broker/gen/api/DefaultApi.h new file mode 100644 index 00000000..68838c02 --- /dev/null +++ b/broker/gen/api/DefaultApi.h @@ -0,0 +1,290 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * DefaultApi.h + * + * + */ + +#ifndef DefaultApi_H_ +#define DefaultApi_H_ + + +#include +#include +#include + +#include +#include + +#include "Broker_status.h" +#include "Calibration_statistics_inner.h" +#include "Dataset_settings.h" +#include "Detector_list.h" +#include "Detector_selection.h" +#include "Detector_settings.h" +#include "Error_message.h" +#include "Measurement_statistics.h" +#include "Plot.h" +#include "Plot_request.h" +#include "Rad_int_settings.h" +#include "Radial_integration_plots_inner.h" +#include "Spot_finding_settings.h" +#include + +namespace org::openapitools::server::api +{ + +class DefaultApi { +public: + explicit DefaultApi(const std::shared_ptr& rtr); + virtual ~DefaultApi() = default; + void init(); + + static const std::string base; + +private: + void setupRoutes(); + + void cancel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void config_detector_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void config_detector_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void config_rad_int_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void config_rad_int_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void config_select_detector_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void config_select_detector_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void config_spot_finding_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void config_spot_finding_put_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void deactivate_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void initialize_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void pedestal_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void plot_adu_histogram_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void plot_bkg_estimate_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void plot_indexing_rate_per_file_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void plot_indexing_rate_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void plot_rad_int_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + void plot_rad_int_per_file_get_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 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 default_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response); + + const std::shared_ptr router; + + /// + /// Helper function to handle unexpected Exceptions during Parameter parsing and validation. + /// May be overridden to return custom error formats. This is called inside a catch block. + /// Important: When overriding, do not call `throw ex;`, but instead use `throw;`. + /// + virtual std::pair handleParsingException(const std::exception& ex) const noexcept; + + /// + /// Helper function to handle unexpected Exceptions during processing of the request in handler functions. + /// May be overridden to return custom error formats. This is called inside a catch block. + /// Important: When overriding, do not call `throw ex;`, but instead use `throw;`. + /// + virtual std::pair handleOperationException(const std::exception& ex) const noexcept; + + /// + /// Cancel running data collection + /// + /// + /// Command will inform FPGA network card to stop pedestal or data collection at the current stage. Any frame that is currently being processed by CPU will be finished and sent to writer. Given the command is making sure to gracefully stop data acquisition and detector, it might take some time to switch back after command finished to `Idle` state. If data collection is not running, the command has no effect. + /// + virtual void cancel_post(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Get detector configuration + /// + /// + /// Can be done anytime + /// + virtual void config_detector_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Change detector configuration + /// + /// + /// Detector settings are ones that have effect on calibration, i.e., pedestal has to be collected again after changing these settings. This can only be done when detector is `Idle`, `Error` or `Inactive` states. If detector is in `Idle` state , pedestal procedure will be executed automatically - there must be no X-rays on the detector during the operation. If detector is in `Inactive` or `Error` states, new settings will be saved, but no calibration will be executed. + /// + /// (optional) + virtual void config_detector_put(const org::openapitools::server::model::Detector_settings &detectorSettings, Pistache::Http::ResponseWriter &response) = 0; + /// + /// Get data processing configuration + /// + /// + /// Can be done anytime + /// + virtual void config_rad_int_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Configure radial integration + /// + /// + /// Can be done when detector is Inactive or Idle + /// + /// (optional) + virtual void config_rad_int_put(const org::openapitools::server::model::Rad_int_settings &radIntSettings, Pistache::Http::ResponseWriter &response) = 0; + /// + /// List available detectors + /// + /// + /// Configured detectors that can be selected by used + /// + virtual void config_select_detector_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Select detector + /// + /// + /// Jungfraujoch allows to control multiple detectors and/or region-of-interests. The command allows to choose one detector from the list (ID has to be consistent with one provided by GET response). Changing detector will set detector to `Inactive` state and will require reinitialization. + /// + /// (optional) + virtual void config_select_detector_put(const org::openapitools::server::model::Detector_selection &detectorSelection, Pistache::Http::ResponseWriter &response) = 0; + /// + /// Get data processing configuration + /// + /// + /// Can be done anytime + /// + virtual void config_spot_finding_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Configure spot finding + /// + /// + /// Can be done anytime, also while data collection is running + /// + /// (optional) + virtual void config_spot_finding_put(const org::openapitools::server::model::Spot_finding_settings &spotFindingSettings, Pistache::Http::ResponseWriter &response) = 0; + /// + /// Prepare detector to turn off + /// + /// + /// Should be in `Idle` or `Error` state. Command deactivates data acquisition and turns off detector high voltage and ASIC. Should be used always before turning off power from the detector. + /// + virtual void deactivate_post(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Initialize detector and data acquisition + /// + /// + /// Should be used in two cases: - Detector is in `Inactive` state - Detector is in `Error` state X-ray shutter must be closed. This operation will reconfigure network interface of the detector. During operation of the detector it is recommended to use the `POST /pedestal` operation instead. If storage cells are used, the execution time might be few minutes. This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + /// + virtual void initialize_post(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Collect dark current for the detector + /// + /// + /// Updates calibration of the JUNGFRAU detector. Must be in `Idle` state. X-ray shutter must be closed. Recommended to run once per hour for long integration times (> 100 us). This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + /// + virtual void pedestal_post(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Generate ADU histogram + /// + /// + /// ADU histogram for all images within current data collection + /// + virtual void plot_adu_histogram_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Generate background estimate plot + /// + /// + /// Mean intensity for d = 3 - 5 A per image; binning is configurable + /// + /// (optional) + virtual void plot_bkg_estimate_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0; + /// + /// Generate indexing rate per file + /// + /// + /// Indexing rate per each of data files; useful for example for time resolved data + /// + virtual void plot_indexing_rate_per_file_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Generate indexing rate plot + /// + /// + /// Image indexing rate; binning is configurable + /// + /// (optional) + virtual void plot_indexing_rate_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0; + /// + /// Generate radial integration profile + /// + /// + /// Generate average radial integration profile + /// + virtual void plot_rad_int_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Generate radial integration profiles per file + /// + /// + /// Radial integration plots for both the whole dataset and per file; useful for time-resolved measurements + /// + virtual void plot_rad_int_per_file_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Generate spot count plot + /// + /// + /// Number of spots per image; binning is configurable + /// + /// (optional) + virtual void plot_spot_count_post(const org::openapitools::server::model::Plot_request &plotRequest, Pistache::Http::ResponseWriter &response) = 0; + /// + /// Start detector + /// + /// + /// Start data acquisition. Detector must be in `Idle` state. Doesn't run calibration procedure. This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + /// + /// (optional) + virtual void start_post(const org::openapitools::server::model::Dataset_settings &datasetSettings, Pistache::Http::ResponseWriter &response) = 0; + /// + /// Get calibration statistics + /// + /// + /// Statistics are provided for each module/storage cell separately + /// + virtual void statistics_calibration_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Get data collection statistics + /// + /// + /// Results of the last data collection + /// + virtual void statistics_data_collection_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Get Jungfraujoch status + /// + /// + /// Status of the data acquisition + /// + virtual void status_get(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Send soft trigger to the detector + /// + /// + /// Generate soft trigger + /// + virtual void trigger_post(Pistache::Http::ResponseWriter &response) = 0; + /// + /// Wait for acquisition done + /// + /// + /// 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; + +}; + +} // namespace org::openapitools::server::api + +#endif /* DefaultApi_H_ */ + diff --git a/broker/gen/model/Broker_status.cpp b/broker/gen/model/Broker_status.cpp new file mode 100644 index 00000000..e45c04b8 --- /dev/null +++ b/broker/gen/model/Broker_status.cpp @@ -0,0 +1,235 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Broker_status.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Broker_status::Broker_status() +{ + m_State = ""; + m_Progress = 0.0f; + m_ProgressIsSet = false; + m_Indexing_rate = 0.0f; + m_Indexing_rateIsSet = false; + m_Receiver_send_buffers_avail = 0.0f; + m_Receiver_send_buffers_availIsSet = false; + +} + +void Broker_status::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Broker_status::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Broker_status::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Broker_status" : pathPrefix; + + + if (progressIsSet()) + { + const float& value = m_Progress; + const std::string currentValuePath = _pathPrefix + ".progress"; + + + if (value < static_cast(0.0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0.0;"; + } + if (value > static_cast(1.0)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 1.0;"; + } + + } + + if (indexingRateIsSet()) + { + const float& value = m_Indexing_rate; + const std::string currentValuePath = _pathPrefix + ".indexingRate"; + + + if (value < static_cast(0.0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0.0;"; + } + if (value > static_cast(1.0)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 1.0;"; + } + + } + + if (receiverSendBuffersAvailIsSet()) + { + const float& value = m_Receiver_send_buffers_avail; + const std::string currentValuePath = _pathPrefix + ".receiverSendBuffersAvail"; + + + if (value < static_cast(0.0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0.0;"; + } + if (value > static_cast(1.0)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 1.0;"; + } + + } + + return success; +} + +bool Broker_status::operator==(const Broker_status& rhs) const +{ + return + + + (getState() == rhs.getState()) + && + + + ((!progressIsSet() && !rhs.progressIsSet()) || (progressIsSet() && rhs.progressIsSet() && getProgress() == rhs.getProgress())) && + + + ((!indexingRateIsSet() && !rhs.indexingRateIsSet()) || (indexingRateIsSet() && rhs.indexingRateIsSet() && getIndexingRate() == rhs.getIndexingRate())) && + + + ((!receiverSendBuffersAvailIsSet() && !rhs.receiverSendBuffersAvailIsSet()) || (receiverSendBuffersAvailIsSet() && rhs.receiverSendBuffersAvailIsSet() && getReceiverSendBuffersAvail() == rhs.getReceiverSendBuffersAvail())) + + ; +} + +bool Broker_status::operator!=(const Broker_status& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Broker_status& o) +{ + j = nlohmann::json(); + j["state"] = o.m_State; + if(o.progressIsSet()) + j["progress"] = o.m_Progress; + if(o.indexingRateIsSet()) + j["indexing_rate"] = o.m_Indexing_rate; + if(o.receiverSendBuffersAvailIsSet()) + j["receiver_send_buffers_avail"] = o.m_Receiver_send_buffers_avail; + +} + +void from_json(const nlohmann::json& j, Broker_status& o) +{ + j.at("state").get_to(o.m_State); + if(j.find("progress") != j.end()) + { + j.at("progress").get_to(o.m_Progress); + o.m_ProgressIsSet = true; + } + if(j.find("indexing_rate") != j.end()) + { + j.at("indexing_rate").get_to(o.m_Indexing_rate); + o.m_Indexing_rateIsSet = true; + } + if(j.find("receiver_send_buffers_avail") != j.end()) + { + j.at("receiver_send_buffers_avail").get_to(o.m_Receiver_send_buffers_avail); + o.m_Receiver_send_buffers_availIsSet = true; + } + +} + +std::string Broker_status::getState() const +{ + return m_State; +} +void Broker_status::setState(std::string const& value) +{ + m_State = value; +} +float Broker_status::getProgress() const +{ + return m_Progress; +} +void Broker_status::setProgress(float const value) +{ + m_Progress = value; + m_ProgressIsSet = true; +} +bool Broker_status::progressIsSet() const +{ + return m_ProgressIsSet; +} +void Broker_status::unsetProgress() +{ + m_ProgressIsSet = false; +} +float Broker_status::getIndexingRate() const +{ + return m_Indexing_rate; +} +void Broker_status::setIndexingRate(float const value) +{ + m_Indexing_rate = value; + m_Indexing_rateIsSet = true; +} +bool Broker_status::indexingRateIsSet() const +{ + return m_Indexing_rateIsSet; +} +void Broker_status::unsetIndexing_rate() +{ + m_Indexing_rateIsSet = false; +} +float Broker_status::getReceiverSendBuffersAvail() const +{ + return m_Receiver_send_buffers_avail; +} +void Broker_status::setReceiverSendBuffersAvail(float const value) +{ + m_Receiver_send_buffers_avail = value; + m_Receiver_send_buffers_availIsSet = true; +} +bool Broker_status::receiverSendBuffersAvailIsSet() const +{ + return m_Receiver_send_buffers_availIsSet; +} +void Broker_status::unsetReceiver_send_buffers_avail() +{ + m_Receiver_send_buffers_availIsSet = false; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Broker_status.h b/broker/gen/model/Broker_status.h new file mode 100644 index 00000000..d901f459 --- /dev/null +++ b/broker/gen/model/Broker_status.h @@ -0,0 +1,104 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Broker_status.h + * + * + */ + +#ifndef Broker_status_H_ +#define Broker_status_H_ + + +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Broker_status +{ +public: + Broker_status(); + virtual ~Broker_status() = 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 Broker_status& rhs) const; + bool operator!=(const Broker_status& rhs) const; + + ///////////////////////////////////////////// + /// Broker_status members + + /// + /// + /// + std::string getState() const; + void setState(std::string const& value); + /// + /// + /// + float getProgress() const; + void setProgress(float const value); + bool progressIsSet() const; + void unsetProgress(); + /// + /// + /// + float getIndexingRate() const; + void setIndexingRate(float const value); + bool indexingRateIsSet() const; + void unsetIndexing_rate(); + /// + /// + /// + float getReceiverSendBuffersAvail() const; + void setReceiverSendBuffersAvail(float const value); + bool receiverSendBuffersAvailIsSet() const; + void unsetReceiver_send_buffers_avail(); + + friend void to_json(nlohmann::json& j, const Broker_status& o); + friend void from_json(const nlohmann::json& j, Broker_status& o); +protected: + std::string m_State; + + float m_Progress; + bool m_ProgressIsSet; + float m_Indexing_rate; + bool m_Indexing_rateIsSet; + float m_Receiver_send_buffers_avail; + bool m_Receiver_send_buffers_availIsSet; + +}; + +} // namespace org::openapitools::server::model + +#endif /* Broker_status_H_ */ diff --git a/broker/gen/model/Calibration_statistics_inner.cpp b/broker/gen/model/Calibration_statistics_inner.cpp new file mode 100644 index 00000000..1e250376 --- /dev/null +++ b/broker/gen/model/Calibration_statistics_inner.cpp @@ -0,0 +1,203 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Calibration_statistics_inner.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Calibration_statistics_inner::Calibration_statistics_inner() +{ + m_Module_number = 0L; + m_Storage_cell_number = 0L; + m_Pedestal_g0_mean = 0.0f; + m_Pedestal_g1_mean = 0.0f; + m_Pedestal_g2_mean = 0.0f; + m_Gain_g0_mean = 0.0f; + m_Gain_g1_mean = 0.0f; + m_Gain_g2_mean = 0.0f; + m_Masked_pixels = 0L; + +} + +void Calibration_statistics_inner::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Calibration_statistics_inner::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Calibration_statistics_inner::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Calibration_statistics_inner" : pathPrefix; + + + return success; +} + +bool Calibration_statistics_inner::operator==(const Calibration_statistics_inner& rhs) const +{ + return + + + (getModuleNumber() == rhs.getModuleNumber()) + && + + (getStorageCellNumber() == rhs.getStorageCellNumber()) + && + + (getPedestalG0Mean() == rhs.getPedestalG0Mean()) + && + + (getPedestalG1Mean() == rhs.getPedestalG1Mean()) + && + + (getPedestalG2Mean() == rhs.getPedestalG2Mean()) + && + + (getGainG0Mean() == rhs.getGainG0Mean()) + && + + (getGainG1Mean() == rhs.getGainG1Mean()) + && + + (getGainG2Mean() == rhs.getGainG2Mean()) + && + + (getMaskedPixels() == rhs.getMaskedPixels()) + + + ; +} + +bool Calibration_statistics_inner::operator!=(const Calibration_statistics_inner& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Calibration_statistics_inner& o) +{ + j = nlohmann::json(); + j["module_number"] = o.m_Module_number; + j["storage_cell_number"] = o.m_Storage_cell_number; + j["pedestal_g0_mean"] = o.m_Pedestal_g0_mean; + j["pedestal_g1_mean"] = o.m_Pedestal_g1_mean; + j["pedestal_g2_mean"] = o.m_Pedestal_g2_mean; + j["gain_g0_mean"] = o.m_Gain_g0_mean; + j["gain_g1_mean"] = o.m_Gain_g1_mean; + j["gain_g2_mean"] = o.m_Gain_g2_mean; + j["masked_pixels"] = o.m_Masked_pixels; + +} + +void from_json(const nlohmann::json& j, Calibration_statistics_inner& o) +{ + j.at("module_number").get_to(o.m_Module_number); + j.at("storage_cell_number").get_to(o.m_Storage_cell_number); + j.at("pedestal_g0_mean").get_to(o.m_Pedestal_g0_mean); + j.at("pedestal_g1_mean").get_to(o.m_Pedestal_g1_mean); + j.at("pedestal_g2_mean").get_to(o.m_Pedestal_g2_mean); + j.at("gain_g0_mean").get_to(o.m_Gain_g0_mean); + j.at("gain_g1_mean").get_to(o.m_Gain_g1_mean); + j.at("gain_g2_mean").get_to(o.m_Gain_g2_mean); + j.at("masked_pixels").get_to(o.m_Masked_pixels); + +} + +int64_t Calibration_statistics_inner::getModuleNumber() const +{ + return m_Module_number; +} +void Calibration_statistics_inner::setModuleNumber(int64_t const value) +{ + m_Module_number = value; +} +int64_t Calibration_statistics_inner::getStorageCellNumber() const +{ + return m_Storage_cell_number; +} +void Calibration_statistics_inner::setStorageCellNumber(int64_t const value) +{ + m_Storage_cell_number = value; +} +float Calibration_statistics_inner::getPedestalG0Mean() const +{ + return m_Pedestal_g0_mean; +} +void Calibration_statistics_inner::setPedestalG0Mean(float const value) +{ + m_Pedestal_g0_mean = value; +} +float Calibration_statistics_inner::getPedestalG1Mean() const +{ + return m_Pedestal_g1_mean; +} +void Calibration_statistics_inner::setPedestalG1Mean(float const value) +{ + m_Pedestal_g1_mean = value; +} +float Calibration_statistics_inner::getPedestalG2Mean() const +{ + return m_Pedestal_g2_mean; +} +void Calibration_statistics_inner::setPedestalG2Mean(float const value) +{ + m_Pedestal_g2_mean = value; +} +float Calibration_statistics_inner::getGainG0Mean() const +{ + return m_Gain_g0_mean; +} +void Calibration_statistics_inner::setGainG0Mean(float const value) +{ + m_Gain_g0_mean = value; +} +float Calibration_statistics_inner::getGainG1Mean() const +{ + return m_Gain_g1_mean; +} +void Calibration_statistics_inner::setGainG1Mean(float const value) +{ + m_Gain_g1_mean = value; +} +float Calibration_statistics_inner::getGainG2Mean() const +{ + return m_Gain_g2_mean; +} +void Calibration_statistics_inner::setGainG2Mean(float const value) +{ + m_Gain_g2_mean = value; +} +int64_t Calibration_statistics_inner::getMaskedPixels() const +{ + return m_Masked_pixels; +} +void Calibration_statistics_inner::setMaskedPixels(int64_t const value) +{ + m_Masked_pixels = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Calibration_statistics_inner.h b/broker/gen/model/Calibration_statistics_inner.h new file mode 100644 index 00000000..0b9dfa96 --- /dev/null +++ b/broker/gen/model/Calibration_statistics_inner.h @@ -0,0 +1,132 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Calibration_statistics_inner.h + * + * + */ + +#ifndef Calibration_statistics_inner_H_ +#define Calibration_statistics_inner_H_ + + +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Calibration_statistics_inner +{ +public: + Calibration_statistics_inner(); + virtual ~Calibration_statistics_inner() = 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 Calibration_statistics_inner& rhs) const; + bool operator!=(const Calibration_statistics_inner& rhs) const; + + ///////////////////////////////////////////// + /// Calibration_statistics_inner members + + /// + /// + /// + int64_t getModuleNumber() const; + void setModuleNumber(int64_t const value); + /// + /// + /// + int64_t getStorageCellNumber() const; + void setStorageCellNumber(int64_t const value); + /// + /// + /// + float getPedestalG0Mean() const; + void setPedestalG0Mean(float const value); + /// + /// + /// + float getPedestalG1Mean() const; + void setPedestalG1Mean(float const value); + /// + /// + /// + float getPedestalG2Mean() const; + void setPedestalG2Mean(float const value); + /// + /// + /// + float getGainG0Mean() const; + void setGainG0Mean(float const value); + /// + /// + /// + float getGainG1Mean() const; + void setGainG1Mean(float const value); + /// + /// + /// + float getGainG2Mean() const; + void setGainG2Mean(float const value); + /// + /// + /// + int64_t getMaskedPixels() const; + void setMaskedPixels(int64_t const value); + + friend void to_json(nlohmann::json& j, const Calibration_statistics_inner& o); + friend void from_json(const nlohmann::json& j, Calibration_statistics_inner& o); +protected: + int64_t m_Module_number; + + int64_t m_Storage_cell_number; + + float m_Pedestal_g0_mean; + + float m_Pedestal_g1_mean; + + float m_Pedestal_g2_mean; + + float m_Gain_g0_mean; + + float m_Gain_g1_mean; + + float m_Gain_g2_mean; + + int64_t m_Masked_pixels; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Calibration_statistics_inner_H_ */ diff --git a/broker/gen/model/Data_processing_settings.cpp b/broker/gen/model/Data_processing_settings.cpp new file mode 100644 index 00000000..60c5ae3c --- /dev/null +++ b/broker/gen/model/Data_processing_settings.cpp @@ -0,0 +1,246 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Data_processing_settings.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Data_processing_settings::Data_processing_settings() +{ + m_Signal_to_noise_threshold = 0.0f; + m_Photon_count_threshold = 0L; + m_Min_pix_per_spot = 0L; + m_Max_pix_per_spot = 0L; + m_High_resolution_limit = 0.0f; + m_Low_resolution_limit = 0.0f; + m_Preview_indexed_only = false; + m_Preview_indexed_onlyIsSet = false; + +} + +void Data_processing_settings::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Data_processing_settings::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Data_processing_settings::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Data_processing_settings" : pathPrefix; + + + + /* Signal_to_noise_threshold */ { + const float& value = m_Signal_to_noise_threshold; + const std::string currentValuePath = _pathPrefix + ".signalToNoiseThreshold"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Photon_count_threshold */ { + const int64_t& value = m_Photon_count_threshold; + const std::string currentValuePath = _pathPrefix + ".photonCountThreshold"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Min_pix_per_spot */ { + const int64_t& value = m_Min_pix_per_spot; + const std::string currentValuePath = _pathPrefix + ".minPixPerSpot"; + + + if (value < 1ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + + } + + + /* Max_pix_per_spot */ { + const int64_t& value = m_Max_pix_per_spot; + const std::string currentValuePath = _pathPrefix + ".maxPixPerSpot"; + + + if (value < 1ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + + } + + return success; +} + +bool Data_processing_settings::operator==(const Data_processing_settings& rhs) const +{ + return + + + (getSignalToNoiseThreshold() == rhs.getSignalToNoiseThreshold()) + && + + (getPhotonCountThreshold() == rhs.getPhotonCountThreshold()) + && + + (getMinPixPerSpot() == rhs.getMinPixPerSpot()) + && + + (getMaxPixPerSpot() == rhs.getMaxPixPerSpot()) + && + + (getHighResolutionLimit() == rhs.getHighResolutionLimit()) + && + + (getLowResolutionLimit() == rhs.getLowResolutionLimit()) + && + + + ((!previewIndexedOnlyIsSet() && !rhs.previewIndexedOnlyIsSet()) || (previewIndexedOnlyIsSet() && rhs.previewIndexedOnlyIsSet() && isPreviewIndexedOnly() == rhs.isPreviewIndexedOnly())) + + ; +} + +bool Data_processing_settings::operator!=(const Data_processing_settings& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Data_processing_settings& o) +{ + j = nlohmann::json(); + j["signal_to_noise_threshold"] = o.m_Signal_to_noise_threshold; + j["photon_count_threshold"] = o.m_Photon_count_threshold; + j["min_pix_per_spot"] = o.m_Min_pix_per_spot; + j["max_pix_per_spot"] = o.m_Max_pix_per_spot; + j["high_resolution_limit"] = o.m_High_resolution_limit; + j["low_resolution_limit"] = o.m_Low_resolution_limit; + if(o.previewIndexedOnlyIsSet()) + j["preview_indexed_only"] = o.m_Preview_indexed_only; + +} + +void from_json(const nlohmann::json& j, Data_processing_settings& o) +{ + j.at("signal_to_noise_threshold").get_to(o.m_Signal_to_noise_threshold); + j.at("photon_count_threshold").get_to(o.m_Photon_count_threshold); + j.at("min_pix_per_spot").get_to(o.m_Min_pix_per_spot); + j.at("max_pix_per_spot").get_to(o.m_Max_pix_per_spot); + j.at("high_resolution_limit").get_to(o.m_High_resolution_limit); + j.at("low_resolution_limit").get_to(o.m_Low_resolution_limit); + if(j.find("preview_indexed_only") != j.end()) + { + j.at("preview_indexed_only").get_to(o.m_Preview_indexed_only); + o.m_Preview_indexed_onlyIsSet = true; + } + +} + +float Data_processing_settings::getSignalToNoiseThreshold() const +{ + return m_Signal_to_noise_threshold; +} +void Data_processing_settings::setSignalToNoiseThreshold(float const value) +{ + m_Signal_to_noise_threshold = value; +} +int64_t Data_processing_settings::getPhotonCountThreshold() const +{ + return m_Photon_count_threshold; +} +void Data_processing_settings::setPhotonCountThreshold(int64_t const value) +{ + m_Photon_count_threshold = value; +} +int64_t Data_processing_settings::getMinPixPerSpot() const +{ + return m_Min_pix_per_spot; +} +void Data_processing_settings::setMinPixPerSpot(int64_t const value) +{ + m_Min_pix_per_spot = value; +} +int64_t Data_processing_settings::getMaxPixPerSpot() const +{ + return m_Max_pix_per_spot; +} +void Data_processing_settings::setMaxPixPerSpot(int64_t const value) +{ + m_Max_pix_per_spot = value; +} +float Data_processing_settings::getHighResolutionLimit() const +{ + return m_High_resolution_limit; +} +void Data_processing_settings::setHighResolutionLimit(float const value) +{ + m_High_resolution_limit = value; +} +float Data_processing_settings::getLowResolutionLimit() const +{ + return m_Low_resolution_limit; +} +void Data_processing_settings::setLowResolutionLimit(float const value) +{ + m_Low_resolution_limit = value; +} +bool Data_processing_settings::isPreviewIndexedOnly() const +{ + return m_Preview_indexed_only; +} +void Data_processing_settings::setPreviewIndexedOnly(bool const value) +{ + m_Preview_indexed_only = value; + m_Preview_indexed_onlyIsSet = true; +} +bool Data_processing_settings::previewIndexedOnlyIsSet() const +{ + return m_Preview_indexed_onlyIsSet; +} +void Data_processing_settings::unsetPreview_indexed_only() +{ + m_Preview_indexed_onlyIsSet = false; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Data_processing_settings.h b/broker/gen/model/Data_processing_settings.h new file mode 100644 index 00000000..0e4a847c --- /dev/null +++ b/broker/gen/model/Data_processing_settings.h @@ -0,0 +1,120 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Data_processing_settings.h + * + * + */ + +#ifndef Data_processing_settings_H_ +#define Data_processing_settings_H_ + + +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Data_processing_settings +{ +public: + Data_processing_settings(); + virtual ~Data_processing_settings() = 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 Data_processing_settings& rhs) const; + bool operator!=(const Data_processing_settings& rhs) const; + + ///////////////////////////////////////////// + /// Data_processing_settings members + + /// + /// + /// + float getSignalToNoiseThreshold() const; + void setSignalToNoiseThreshold(float const value); + /// + /// + /// + int64_t getPhotonCountThreshold() const; + void setPhotonCountThreshold(int64_t const value); + /// + /// + /// + int64_t getMinPixPerSpot() const; + void setMinPixPerSpot(int64_t const value); + /// + /// + /// + int64_t getMaxPixPerSpot() const; + void setMaxPixPerSpot(int64_t const value); + /// + /// + /// + float getHighResolutionLimit() const; + void setHighResolutionLimit(float const value); + /// + /// + /// + float getLowResolutionLimit() const; + void setLowResolutionLimit(float const value); + /// + /// + /// + bool isPreviewIndexedOnly() const; + void setPreviewIndexedOnly(bool const value); + bool previewIndexedOnlyIsSet() const; + void unsetPreview_indexed_only(); + + friend void to_json(nlohmann::json& j, const Data_processing_settings& o); + friend void from_json(const nlohmann::json& j, Data_processing_settings& o); +protected: + float m_Signal_to_noise_threshold; + + int64_t m_Photon_count_threshold; + + int64_t m_Min_pix_per_spot; + + int64_t m_Max_pix_per_spot; + + float m_High_resolution_limit; + + float m_Low_resolution_limit; + + bool m_Preview_indexed_only; + bool m_Preview_indexed_onlyIsSet; + +}; + +} // namespace org::openapitools::server::model + +#endif /* Data_processing_settings_H_ */ diff --git a/broker/gen/model/Dataset_settings.cpp b/broker/gen/model/Dataset_settings.cpp new file mode 100644 index 00000000..002835af --- /dev/null +++ b/broker/gen/model/Dataset_settings.cpp @@ -0,0 +1,606 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Dataset_settings.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Dataset_settings::Dataset_settings() +{ + m_Images_per_trigger = 0L; + m_Ntrigger = 1L; + m_NtriggerIsSet = false; + m_Summation = 1L; + m_SummationIsSet = false; + m_Beam_x_pxl = 0.0f; + m_Beam_y_pxl = 0.0f; + m_Detector_distance_mm = 0.0f; + m_Photon_energy_keV = 0.0f; + m_File_prefix = ""; + m_File_prefixIsSet = false; + m_Data_file_count = 1L; + m_Data_file_countIsSet = false; + m_Space_group_number = 0L; + m_Space_group_numberIsSet = false; + m_Sample_name = ""; + m_Save_calibration = false; + m_Save_calibrationIsSet = false; + m_Fpga_output = "auto"; + m_Fpga_outputIsSet = false; + m_Compression = "bslz4"; + m_CompressionIsSet = false; + m_Total_flux = 0.0f; + m_Total_fluxIsSet = false; + m_Transmission = 0.0f; + m_TransmissionIsSet = false; + m_Unit_cellIsSet = false; + +} + +void Dataset_settings::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Dataset_settings::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Dataset_settings" : pathPrefix; + + + + /* Images_per_trigger */ { + const int64_t& value = m_Images_per_trigger; + const std::string currentValuePath = _pathPrefix + ".imagesPerTrigger"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + if (ntriggerIsSet()) + { + const int64_t& value = m_Ntrigger; + const std::string currentValuePath = _pathPrefix + ".ntrigger"; + + + if (value < 1ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + + } + + if (summationIsSet()) + { + const int64_t& value = m_Summation; + const std::string currentValuePath = _pathPrefix + ".summation"; + + + if (value < 1ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + if (value > 256ll) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 256;"; + } + + } + + + /* Detector_distance_mm */ { + const float& value = m_Detector_distance_mm; + const std::string currentValuePath = _pathPrefix + ".detectorDistanceMm"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Photon_energy_keV */ { + const float& value = m_Photon_energy_keV; + const std::string currentValuePath = _pathPrefix + ".photonEnergyKeV"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + if (dataFileCountIsSet()) + { + const int64_t& value = m_Data_file_count; + const std::string currentValuePath = _pathPrefix + ".dataFileCount"; + + + if (value < 1ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + + } + + if (spaceGroupNumberIsSet()) + { + const int64_t& value = m_Space_group_number; + const std::string currentValuePath = _pathPrefix + ".spaceGroupNumber"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + if (value > 194ll) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 194;"; + } + + } + + if (transmissionIsSet()) + { + const float& value = m_Transmission; + const std::string currentValuePath = _pathPrefix + ".transmission"; + + + if (value < static_cast(0.0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0.0;"; + } + if (value > static_cast(1.0)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 1.0;"; + } + + } + + return success; +} + +bool Dataset_settings::operator==(const Dataset_settings& rhs) const +{ + return + + + (getImagesPerTrigger() == rhs.getImagesPerTrigger()) + && + + + ((!ntriggerIsSet() && !rhs.ntriggerIsSet()) || (ntriggerIsSet() && rhs.ntriggerIsSet() && getNtrigger() == rhs.getNtrigger())) && + + + ((!summationIsSet() && !rhs.summationIsSet()) || (summationIsSet() && rhs.summationIsSet() && getSummation() == rhs.getSummation())) && + + (getBeamXPxl() == rhs.getBeamXPxl()) + && + + (getBeamYPxl() == rhs.getBeamYPxl()) + && + + (getDetectorDistanceMm() == rhs.getDetectorDistanceMm()) + && + + (getPhotonEnergyKeV() == rhs.getPhotonEnergyKeV()) + && + + + ((!filePrefixIsSet() && !rhs.filePrefixIsSet()) || (filePrefixIsSet() && rhs.filePrefixIsSet() && getFilePrefix() == rhs.getFilePrefix())) && + + + ((!dataFileCountIsSet() && !rhs.dataFileCountIsSet()) || (dataFileCountIsSet() && rhs.dataFileCountIsSet() && getDataFileCount() == rhs.getDataFileCount())) && + + + ((!spaceGroupNumberIsSet() && !rhs.spaceGroupNumberIsSet()) || (spaceGroupNumberIsSet() && rhs.spaceGroupNumberIsSet() && getSpaceGroupNumber() == rhs.getSpaceGroupNumber())) && + + (getSampleName() == rhs.getSampleName()) + && + + + ((!saveCalibrationIsSet() && !rhs.saveCalibrationIsSet()) || (saveCalibrationIsSet() && rhs.saveCalibrationIsSet() && isSaveCalibration() == rhs.isSaveCalibration())) && + + + ((!fpgaOutputIsSet() && !rhs.fpgaOutputIsSet()) || (fpgaOutputIsSet() && rhs.fpgaOutputIsSet() && getFpgaOutput() == rhs.getFpgaOutput())) && + + + ((!compressionIsSet() && !rhs.compressionIsSet()) || (compressionIsSet() && rhs.compressionIsSet() && getCompression() == rhs.getCompression())) && + + + ((!totalFluxIsSet() && !rhs.totalFluxIsSet()) || (totalFluxIsSet() && rhs.totalFluxIsSet() && getTotalFlux() == rhs.getTotalFlux())) && + + + ((!transmissionIsSet() && !rhs.transmissionIsSet()) || (transmissionIsSet() && rhs.transmissionIsSet() && getTransmission() == rhs.getTransmission())) && + + + ((!unitCellIsSet() && !rhs.unitCellIsSet()) || (unitCellIsSet() && rhs.unitCellIsSet() && getUnitCell() == rhs.getUnitCell())) + + ; +} + +bool Dataset_settings::operator!=(const Dataset_settings& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Dataset_settings& o) +{ + j = nlohmann::json(); + j["images_per_trigger"] = o.m_Images_per_trigger; + if(o.ntriggerIsSet()) + j["ntrigger"] = o.m_Ntrigger; + if(o.summationIsSet()) + j["summation"] = o.m_Summation; + j["beam_x_pxl"] = o.m_Beam_x_pxl; + j["beam_y_pxl"] = o.m_Beam_y_pxl; + j["detector_distance_mm"] = o.m_Detector_distance_mm; + j["photon_energy_keV"] = o.m_Photon_energy_keV; + if(o.filePrefixIsSet()) + j["file_prefix"] = o.m_File_prefix; + if(o.dataFileCountIsSet()) + j["data_file_count"] = o.m_Data_file_count; + if(o.spaceGroupNumberIsSet()) + j["space_group_number"] = o.m_Space_group_number; + j["sample_name"] = o.m_Sample_name; + if(o.saveCalibrationIsSet()) + j["save_calibration"] = o.m_Save_calibration; + if(o.fpgaOutputIsSet()) + j["fpga_output"] = o.m_Fpga_output; + if(o.compressionIsSet()) + j["compression"] = o.m_Compression; + if(o.totalFluxIsSet()) + j["total_flux"] = o.m_Total_flux; + if(o.transmissionIsSet()) + j["transmission"] = o.m_Transmission; + if(o.unitCellIsSet()) + j["unit_cell"] = o.m_Unit_cell; + +} + +void from_json(const nlohmann::json& j, Dataset_settings& o) +{ + j.at("images_per_trigger").get_to(o.m_Images_per_trigger); + if(j.find("ntrigger") != j.end()) + { + j.at("ntrigger").get_to(o.m_Ntrigger); + o.m_NtriggerIsSet = true; + } + if(j.find("summation") != j.end()) + { + j.at("summation").get_to(o.m_Summation); + o.m_SummationIsSet = true; + } + j.at("beam_x_pxl").get_to(o.m_Beam_x_pxl); + j.at("beam_y_pxl").get_to(o.m_Beam_y_pxl); + j.at("detector_distance_mm").get_to(o.m_Detector_distance_mm); + j.at("photon_energy_keV").get_to(o.m_Photon_energy_keV); + if(j.find("file_prefix") != j.end()) + { + j.at("file_prefix").get_to(o.m_File_prefix); + o.m_File_prefixIsSet = true; + } + if(j.find("data_file_count") != j.end()) + { + j.at("data_file_count").get_to(o.m_Data_file_count); + o.m_Data_file_countIsSet = true; + } + if(j.find("space_group_number") != j.end()) + { + j.at("space_group_number").get_to(o.m_Space_group_number); + o.m_Space_group_numberIsSet = true; + } + j.at("sample_name").get_to(o.m_Sample_name); + if(j.find("save_calibration") != j.end()) + { + j.at("save_calibration").get_to(o.m_Save_calibration); + o.m_Save_calibrationIsSet = true; + } + if(j.find("fpga_output") != j.end()) + { + j.at("fpga_output").get_to(o.m_Fpga_output); + o.m_Fpga_outputIsSet = true; + } + if(j.find("compression") != j.end()) + { + j.at("compression").get_to(o.m_Compression); + o.m_CompressionIsSet = true; + } + if(j.find("total_flux") != j.end()) + { + j.at("total_flux").get_to(o.m_Total_flux); + o.m_Total_fluxIsSet = true; + } + if(j.find("transmission") != j.end()) + { + j.at("transmission").get_to(o.m_Transmission); + o.m_TransmissionIsSet = true; + } + if(j.find("unit_cell") != j.end()) + { + j.at("unit_cell").get_to(o.m_Unit_cell); + o.m_Unit_cellIsSet = true; + } + +} + +int64_t Dataset_settings::getImagesPerTrigger() const +{ + return m_Images_per_trigger; +} +void Dataset_settings::setImagesPerTrigger(int64_t const value) +{ + m_Images_per_trigger = value; +} +int64_t Dataset_settings::getNtrigger() const +{ + return m_Ntrigger; +} +void Dataset_settings::setNtrigger(int64_t const value) +{ + m_Ntrigger = value; + m_NtriggerIsSet = true; +} +bool Dataset_settings::ntriggerIsSet() const +{ + return m_NtriggerIsSet; +} +void Dataset_settings::unsetNtrigger() +{ + m_NtriggerIsSet = false; +} +int64_t Dataset_settings::getSummation() const +{ + return m_Summation; +} +void Dataset_settings::setSummation(int64_t const value) +{ + m_Summation = value; + m_SummationIsSet = true; +} +bool Dataset_settings::summationIsSet() const +{ + return m_SummationIsSet; +} +void Dataset_settings::unsetSummation() +{ + m_SummationIsSet = false; +} +float Dataset_settings::getBeamXPxl() const +{ + return m_Beam_x_pxl; +} +void Dataset_settings::setBeamXPxl(float const value) +{ + m_Beam_x_pxl = value; +} +float Dataset_settings::getBeamYPxl() const +{ + return m_Beam_y_pxl; +} +void Dataset_settings::setBeamYPxl(float const value) +{ + m_Beam_y_pxl = value; +} +float Dataset_settings::getDetectorDistanceMm() const +{ + return m_Detector_distance_mm; +} +void Dataset_settings::setDetectorDistanceMm(float const value) +{ + m_Detector_distance_mm = value; +} +float Dataset_settings::getPhotonEnergyKeV() const +{ + return m_Photon_energy_keV; +} +void Dataset_settings::setPhotonEnergyKeV(float const value) +{ + m_Photon_energy_keV = value; +} +std::string Dataset_settings::getFilePrefix() const +{ + return m_File_prefix; +} +void Dataset_settings::setFilePrefix(std::string const& value) +{ + m_File_prefix = value; + m_File_prefixIsSet = true; +} +bool Dataset_settings::filePrefixIsSet() const +{ + return m_File_prefixIsSet; +} +void Dataset_settings::unsetFile_prefix() +{ + m_File_prefixIsSet = false; +} +int64_t Dataset_settings::getDataFileCount() const +{ + return m_Data_file_count; +} +void Dataset_settings::setDataFileCount(int64_t const value) +{ + m_Data_file_count = value; + m_Data_file_countIsSet = true; +} +bool Dataset_settings::dataFileCountIsSet() const +{ + return m_Data_file_countIsSet; +} +void Dataset_settings::unsetData_file_count() +{ + m_Data_file_countIsSet = false; +} +int64_t Dataset_settings::getSpaceGroupNumber() const +{ + return m_Space_group_number; +} +void Dataset_settings::setSpaceGroupNumber(int64_t const value) +{ + m_Space_group_number = value; + m_Space_group_numberIsSet = true; +} +bool Dataset_settings::spaceGroupNumberIsSet() const +{ + return m_Space_group_numberIsSet; +} +void Dataset_settings::unsetSpace_group_number() +{ + m_Space_group_numberIsSet = false; +} +std::string Dataset_settings::getSampleName() const +{ + return m_Sample_name; +} +void Dataset_settings::setSampleName(std::string const& value) +{ + m_Sample_name = value; +} +bool Dataset_settings::isSaveCalibration() const +{ + return m_Save_calibration; +} +void Dataset_settings::setSaveCalibration(bool const value) +{ + m_Save_calibration = value; + m_Save_calibrationIsSet = true; +} +bool Dataset_settings::saveCalibrationIsSet() const +{ + return m_Save_calibrationIsSet; +} +void Dataset_settings::unsetSave_calibration() +{ + m_Save_calibrationIsSet = false; +} +std::string Dataset_settings::getFpgaOutput() const +{ + return m_Fpga_output; +} +void Dataset_settings::setFpgaOutput(std::string const& value) +{ + m_Fpga_output = value; + m_Fpga_outputIsSet = true; +} +bool Dataset_settings::fpgaOutputIsSet() const +{ + return m_Fpga_outputIsSet; +} +void Dataset_settings::unsetFpga_output() +{ + m_Fpga_outputIsSet = false; +} +std::string Dataset_settings::getCompression() const +{ + return m_Compression; +} +void Dataset_settings::setCompression(std::string const& value) +{ + m_Compression = value; + m_CompressionIsSet = true; +} +bool Dataset_settings::compressionIsSet() const +{ + return m_CompressionIsSet; +} +void Dataset_settings::unsetCompression() +{ + m_CompressionIsSet = false; +} +float Dataset_settings::getTotalFlux() const +{ + return m_Total_flux; +} +void Dataset_settings::setTotalFlux(float const value) +{ + m_Total_flux = value; + m_Total_fluxIsSet = true; +} +bool Dataset_settings::totalFluxIsSet() const +{ + return m_Total_fluxIsSet; +} +void Dataset_settings::unsetTotal_flux() +{ + m_Total_fluxIsSet = false; +} +float Dataset_settings::getTransmission() const +{ + return m_Transmission; +} +void Dataset_settings::setTransmission(float const value) +{ + m_Transmission = value; + m_TransmissionIsSet = true; +} +bool Dataset_settings::transmissionIsSet() const +{ + return m_TransmissionIsSet; +} +void Dataset_settings::unsetTransmission() +{ + m_TransmissionIsSet = false; +} +org::openapitools::server::model::Dataset_settings_unit_cell Dataset_settings::getUnitCell() const +{ + return m_Unit_cell; +} +void Dataset_settings::setUnitCell(org::openapitools::server::model::Dataset_settings_unit_cell const& value) +{ + m_Unit_cell = value; + m_Unit_cellIsSet = true; +} +bool Dataset_settings::unitCellIsSet() const +{ + return m_Unit_cellIsSet; +} +void Dataset_settings::unsetUnit_cell() +{ + m_Unit_cellIsSet = false; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Dataset_settings.h b/broker/gen/model/Dataset_settings.h new file mode 100644 index 00000000..2542232e --- /dev/null +++ b/broker/gen/model/Dataset_settings.h @@ -0,0 +1,212 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Dataset_settings.h + * + * + */ + +#ifndef Dataset_settings_H_ +#define Dataset_settings_H_ + + +#include +#include "Dataset_settings_unit_cell.h" +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Dataset_settings +{ +public: + Dataset_settings(); + virtual ~Dataset_settings() = 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 Dataset_settings& rhs) const; + bool operator!=(const Dataset_settings& rhs) const; + + ///////////////////////////////////////////// + /// Dataset_settings members + + /// + /// + /// + int64_t getImagesPerTrigger() const; + void setImagesPerTrigger(int64_t const value); + /// + /// + /// + int64_t getNtrigger() const; + void setNtrigger(int64_t const value); + bool ntriggerIsSet() const; + void unsetNtrigger(); + /// + /// + /// + int64_t getSummation() const; + void setSummation(int64_t const value); + bool summationIsSet() const; + void unsetSummation(); + /// + /// /entry/detector/beam_center_x in NXmx Beam center in X direction [pixels] + /// + float getBeamXPxl() const; + void setBeamXPxl(float const value); + /// + /// /entry/detector/beam_center_y in NXmx Beam center in X direction [pixels] + /// + float getBeamYPxl() const; + void setBeamYPxl(float const value); + /// + /// /entry/detector/distance in NXmx Detector distance [mm] + /// + float getDetectorDistanceMm() const; + void setDetectorDistanceMm(float const value); + /// + /// Used to calculate /entry/beam/incident_wavelength in NXmx Incident photon energy in keV + /// + float getPhotonEnergyKeV() const; + void setPhotonEnergyKeV(float const value); + /// + /// Prefix for filenames. If left empty, no file will be saved. + /// + std::string getFilePrefix() const; + void setFilePrefix(std::string const& value); + bool filePrefixIsSet() const; + void unsetFile_prefix(); + /// + /// Number of round-robin data files + /// + int64_t getDataFileCount() const; + void setDataFileCount(int64_t const value); + bool dataFileCountIsSet() const; + void unsetData_file_count(); + /// + /// + /// + int64_t getSpaceGroupNumber() const; + void setSpaceGroupNumber(int64_t const value); + bool spaceGroupNumberIsSet() const; + void unsetSpace_group_number(); + /// + /// /entry/sample/name in NXmx Sample name + /// + std::string getSampleName() const; + void setSampleName(std::string const& value); + /// + /// Save pedestal together with the dataset + /// + bool isSaveCalibration() const; + void setSaveCalibration(bool const value); + bool saveCalibrationIsSet() const; + void unsetSave_calibration(); + /// + /// FPGA output data type + /// + std::string getFpgaOutput() const; + void setFpgaOutput(std::string const& value); + bool fpgaOutputIsSet() const; + void unsetFpga_output(); + /// + /// + /// + std::string getCompression() const; + void setCompression(std::string const& value); + bool compressionIsSet() const; + void unsetCompression(); + /// + /// /entry/beam/total_flux in NXmx Flux incident on beam plane in photons per second. In other words this is the flux integrated over area. [photons/s] + /// + float getTotalFlux() const; + void setTotalFlux(float const value); + bool totalFluxIsSet() const; + void unsetTotal_flux(); + /// + /// /entry/instrument/attenuator/attenuator_transmission Transmission of attenuator (filter) [no units] + /// + float getTransmission() const; + void setTransmission(float const value); + bool transmissionIsSet() const; + void unsetTransmission(); + /// + /// + /// + 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; + void unsetUnit_cell(); + + friend void to_json(nlohmann::json& j, const Dataset_settings& o); + friend void from_json(const nlohmann::json& j, Dataset_settings& o); +protected: + int64_t m_Images_per_trigger; + + int64_t m_Ntrigger; + bool m_NtriggerIsSet; + int64_t m_Summation; + bool m_SummationIsSet; + float m_Beam_x_pxl; + + float m_Beam_y_pxl; + + float m_Detector_distance_mm; + + float m_Photon_energy_keV; + + std::string m_File_prefix; + bool m_File_prefixIsSet; + int64_t m_Data_file_count; + bool m_Data_file_countIsSet; + int64_t m_Space_group_number; + bool m_Space_group_numberIsSet; + std::string m_Sample_name; + + bool m_Save_calibration; + bool m_Save_calibrationIsSet; + std::string m_Fpga_output; + bool m_Fpga_outputIsSet; + std::string m_Compression; + bool m_CompressionIsSet; + float m_Total_flux; + bool m_Total_fluxIsSet; + float m_Transmission; + bool m_TransmissionIsSet; + org::openapitools::server::model::Dataset_settings_unit_cell m_Unit_cell; + bool m_Unit_cellIsSet; + +}; + +} // namespace org::openapitools::server::model + +#endif /* Dataset_settings_H_ */ diff --git a/broker/gen/model/Dataset_settings_unit_cell.cpp b/broker/gen/model/Dataset_settings_unit_cell.cpp new file mode 100644 index 00000000..14633d8d --- /dev/null +++ b/broker/gen/model/Dataset_settings_unit_cell.cpp @@ -0,0 +1,161 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Dataset_settings_unit_cell.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Dataset_settings_unit_cell::Dataset_settings_unit_cell() +{ + m_a = 0.0f; + m_b = 0.0f; + m_c = 0.0f; + m_Alpha = 0.0f; + m_Beta = 0.0f; + m_Gamma = 0.0f; + +} + +void Dataset_settings_unit_cell::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Dataset_settings_unit_cell::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Dataset_settings_unit_cell::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Dataset_settings_unit_cell" : pathPrefix; + + + return success; +} + +bool Dataset_settings_unit_cell::operator==(const Dataset_settings_unit_cell& rhs) const +{ + return + + + (getA() == rhs.getA()) + && + + (getB() == rhs.getB()) + && + + (getC() == rhs.getC()) + && + + (getAlpha() == rhs.getAlpha()) + && + + (getBeta() == rhs.getBeta()) + && + + (getGamma() == rhs.getGamma()) + + + ; +} + +bool Dataset_settings_unit_cell::operator!=(const Dataset_settings_unit_cell& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Dataset_settings_unit_cell& o) +{ + j = nlohmann::json(); + j["a"] = o.m_a; + j["b"] = o.m_b; + j["c"] = o.m_c; + j["alpha"] = o.m_Alpha; + j["beta"] = o.m_Beta; + j["gamma"] = o.m_Gamma; + +} + +void from_json(const nlohmann::json& j, Dataset_settings_unit_cell& o) +{ + j.at("a").get_to(o.m_a); + j.at("b").get_to(o.m_b); + j.at("c").get_to(o.m_c); + j.at("alpha").get_to(o.m_Alpha); + j.at("beta").get_to(o.m_Beta); + j.at("gamma").get_to(o.m_Gamma); + +} + +float Dataset_settings_unit_cell::getA() const +{ + return m_a; +} +void Dataset_settings_unit_cell::setA(float const value) +{ + m_a = value; +} +float Dataset_settings_unit_cell::getB() const +{ + return m_b; +} +void Dataset_settings_unit_cell::setB(float const value) +{ + m_b = value; +} +float Dataset_settings_unit_cell::getC() const +{ + return m_c; +} +void Dataset_settings_unit_cell::setC(float const value) +{ + m_c = value; +} +float Dataset_settings_unit_cell::getAlpha() const +{ + return m_Alpha; +} +void Dataset_settings_unit_cell::setAlpha(float const value) +{ + m_Alpha = value; +} +float Dataset_settings_unit_cell::getBeta() const +{ + return m_Beta; +} +void Dataset_settings_unit_cell::setBeta(float const value) +{ + m_Beta = value; +} +float Dataset_settings_unit_cell::getGamma() const +{ + return m_Gamma; +} +void Dataset_settings_unit_cell::setGamma(float const value) +{ + m_Gamma = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Dataset_settings_unit_cell.h b/broker/gen/model/Dataset_settings_unit_cell.h new file mode 100644 index 00000000..47c3db25 --- /dev/null +++ b/broker/gen/model/Dataset_settings_unit_cell.h @@ -0,0 +1,111 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Dataset_settings_unit_cell.h + * + * Units of angstrom and degree + */ + +#ifndef Dataset_settings_unit_cell_H_ +#define Dataset_settings_unit_cell_H_ + + +#include + +namespace org::openapitools::server::model +{ + +/// +/// Units of angstrom and degree +/// +class Dataset_settings_unit_cell +{ +public: + Dataset_settings_unit_cell(); + virtual ~Dataset_settings_unit_cell() = 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 Dataset_settings_unit_cell& rhs) const; + bool operator!=(const Dataset_settings_unit_cell& rhs) const; + + ///////////////////////////////////////////// + /// Dataset_settings_unit_cell members + + /// + /// + /// + float getA() const; + void setA(float const value); + /// + /// + /// + float getB() const; + void setB(float const value); + /// + /// + /// + float getC() const; + void setC(float const value); + /// + /// + /// + float getAlpha() const; + void setAlpha(float const value); + /// + /// + /// + float getBeta() const; + void setBeta(float const value); + /// + /// + /// + float getGamma() const; + void setGamma(float const value); + + friend void to_json(nlohmann::json& j, const Dataset_settings_unit_cell& o); + friend void from_json(const nlohmann::json& j, Dataset_settings_unit_cell& o); +protected: + float m_a; + + float m_b; + + float m_c; + + float m_Alpha; + + float m_Beta; + + float m_Gamma; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Dataset_settings_unit_cell_H_ */ diff --git a/broker/gen/model/Detector_list.cpp b/broker/gen/model/Detector_list.cpp new file mode 100644 index 00000000..1ba6a3b8 --- /dev/null +++ b/broker/gen/model/Detector_list.cpp @@ -0,0 +1,125 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Detector_list.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Detector_list::Detector_list() +{ + m_Current_id = 0L; + +} + +void Detector_list::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Detector_list::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Detector_list::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Detector_list" : pathPrefix; + + + + /* Detectors */ { + const std::vector& value = m_Detectors; + const std::string currentValuePath = _pathPrefix + ".detectors"; + + + { // Recursive validation of array elements + const std::string oldValuePath = currentValuePath; + int i = 0; + for (const org::openapitools::server::model::Detector_list_detectors_inner& value : value) + { + const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]"; + + success = value.validate(msg, currentValuePath + ".detectors") && success; + + i++; + } + } + + } + + return success; +} + +bool Detector_list::operator==(const Detector_list& rhs) const +{ + return + + + (getDetectors() == rhs.getDetectors()) + && + + (getCurrentId() == rhs.getCurrentId()) + + + ; +} + +bool Detector_list::operator!=(const Detector_list& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Detector_list& o) +{ + j = nlohmann::json(); + j["detectors"] = o.m_Detectors; + j["current_id"] = o.m_Current_id; + +} + +void from_json(const nlohmann::json& j, Detector_list& o) +{ + j.at("detectors").get_to(o.m_Detectors); + j.at("current_id").get_to(o.m_Current_id); + +} + +std::vector Detector_list::getDetectors() const +{ + return m_Detectors; +} +void Detector_list::setDetectors(std::vector const& value) +{ + m_Detectors = value; +} +int64_t Detector_list::getCurrentId() const +{ + return m_Current_id; +} +void Detector_list::setCurrentId(int64_t const value) +{ + m_Current_id = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Detector_list.h b/broker/gen/model/Detector_list.h new file mode 100644 index 00000000..cb1b7a39 --- /dev/null +++ b/broker/gen/model/Detector_list.h @@ -0,0 +1,85 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Detector_list.h + * + * + */ + +#ifndef Detector_list_H_ +#define Detector_list_H_ + + +#include "Detector_list_detectors_inner.h" +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Detector_list +{ +public: + Detector_list(); + virtual ~Detector_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 Detector_list& rhs) const; + bool operator!=(const Detector_list& rhs) const; + + ///////////////////////////////////////////// + /// Detector_list members + + /// + /// + /// + std::vector getDetectors() const; + void setDetectors(std::vector const& value); + /// + /// + /// + int64_t getCurrentId() const; + void setCurrentId(int64_t const value); + + friend void to_json(nlohmann::json& j, const Detector_list& o); + friend void from_json(const nlohmann::json& j, Detector_list& o); +protected: + std::vector m_Detectors; + + int64_t m_Current_id; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Detector_list_H_ */ diff --git a/broker/gen/model/Detector_list_detectors_inner.cpp b/broker/gen/model/Detector_list_detectors_inner.cpp new file mode 100644 index 00000000..99e184c3 --- /dev/null +++ b/broker/gen/model/Detector_list_detectors_inner.cpp @@ -0,0 +1,161 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Detector_list_detectors_inner.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Detector_list_detectors_inner::Detector_list_detectors_inner() +{ + m_Id = 0L; + m_Description = ""; + m_Nmodules = 0L; + m_Width = 0L; + m_Height = 0L; + +} + +void Detector_list_detectors_inner::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Detector_list_detectors_inner::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Detector_list_detectors_inner::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Detector_list_detectors_inner" : pathPrefix; + + + + /* Id */ { + const int64_t& value = m_Id; + const std::string currentValuePath = _pathPrefix + ".id"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + return success; +} + +bool Detector_list_detectors_inner::operator==(const Detector_list_detectors_inner& rhs) const +{ + return + + + (getId() == rhs.getId()) + && + + (getDescription() == rhs.getDescription()) + && + + (getNmodules() == rhs.getNmodules()) + && + + (getWidth() == rhs.getWidth()) + && + + (getHeight() == rhs.getHeight()) + + + ; +} + +bool Detector_list_detectors_inner::operator!=(const Detector_list_detectors_inner& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Detector_list_detectors_inner& o) +{ + j = nlohmann::json(); + j["id"] = o.m_Id; + j["description"] = o.m_Description; + j["nmodules"] = o.m_Nmodules; + j["width"] = o.m_Width; + j["height"] = o.m_Height; + +} + +void from_json(const nlohmann::json& j, Detector_list_detectors_inner& o) +{ + j.at("id").get_to(o.m_Id); + j.at("description").get_to(o.m_Description); + j.at("nmodules").get_to(o.m_Nmodules); + j.at("width").get_to(o.m_Width); + j.at("height").get_to(o.m_Height); + +} + +int64_t Detector_list_detectors_inner::getId() const +{ + return m_Id; +} +void Detector_list_detectors_inner::setId(int64_t const value) +{ + m_Id = value; +} +std::string Detector_list_detectors_inner::getDescription() const +{ + return m_Description; +} +void Detector_list_detectors_inner::setDescription(std::string const& value) +{ + m_Description = value; +} +int64_t Detector_list_detectors_inner::getNmodules() const +{ + return m_Nmodules; +} +void Detector_list_detectors_inner::setNmodules(int64_t const value) +{ + m_Nmodules = value; +} +int64_t Detector_list_detectors_inner::getWidth() const +{ + return m_Width; +} +void Detector_list_detectors_inner::setWidth(int64_t const value) +{ + m_Width = value; +} +int64_t Detector_list_detectors_inner::getHeight() const +{ + return m_Height; +} +void Detector_list_detectors_inner::setHeight(int64_t const value) +{ + m_Height = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Detector_list_detectors_inner.h b/broker/gen/model/Detector_list_detectors_inner.h new file mode 100644 index 00000000..f9278166 --- /dev/null +++ b/broker/gen/model/Detector_list_detectors_inner.h @@ -0,0 +1,105 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Detector_list_detectors_inner.h + * + * + */ + +#ifndef Detector_list_detectors_inner_H_ +#define Detector_list_detectors_inner_H_ + + +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Detector_list_detectors_inner +{ +public: + Detector_list_detectors_inner(); + virtual ~Detector_list_detectors_inner() = 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 Detector_list_detectors_inner& rhs) const; + bool operator!=(const Detector_list_detectors_inner& rhs) const; + + ///////////////////////////////////////////// + /// Detector_list_detectors_inner members + + /// + /// + /// + int64_t getId() const; + void setId(int64_t const value); + /// + /// + /// + std::string getDescription() const; + void setDescription(std::string const& value); + /// + /// + /// + int64_t getNmodules() const; + void setNmodules(int64_t const value); + /// + /// + /// + int64_t getWidth() const; + void setWidth(int64_t const value); + /// + /// + /// + int64_t getHeight() const; + void setHeight(int64_t const value); + + friend void to_json(nlohmann::json& j, const Detector_list_detectors_inner& o); + friend void from_json(const nlohmann::json& j, Detector_list_detectors_inner& o); +protected: + int64_t m_Id; + + std::string m_Description; + + int64_t m_Nmodules; + + int64_t m_Width; + + int64_t m_Height; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Detector_list_detectors_inner_H_ */ diff --git a/broker/gen/model/Detector_selection.cpp b/broker/gen/model/Detector_selection.cpp new file mode 100644 index 00000000..048d72a7 --- /dev/null +++ b/broker/gen/model/Detector_selection.cpp @@ -0,0 +1,91 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Detector_selection.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Detector_selection::Detector_selection() +{ + m_Id = 0L; + +} + +void Detector_selection::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Detector_selection::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Detector_selection::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Detector_selection" : pathPrefix; + + + return success; +} + +bool Detector_selection::operator==(const Detector_selection& rhs) const +{ + return + + + (getId() == rhs.getId()) + + + ; +} + +bool Detector_selection::operator!=(const Detector_selection& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Detector_selection& o) +{ + j = nlohmann::json(); + j["id"] = o.m_Id; + +} + +void from_json(const nlohmann::json& j, Detector_selection& o) +{ + j.at("id").get_to(o.m_Id); + +} + +int64_t Detector_selection::getId() const +{ + return m_Id; +} +void Detector_selection::setId(int64_t const value) +{ + m_Id = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Detector_selection.h b/broker/gen/model/Detector_selection.h new file mode 100644 index 00000000..93b71da6 --- /dev/null +++ b/broker/gen/model/Detector_selection.h @@ -0,0 +1,76 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Detector_selection.h + * + * + */ + +#ifndef Detector_selection_H_ +#define Detector_selection_H_ + + +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Detector_selection +{ +public: + Detector_selection(); + virtual ~Detector_selection() = 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 Detector_selection& rhs) const; + bool operator!=(const Detector_selection& rhs) const; + + ///////////////////////////////////////////// + /// Detector_selection members + + /// + /// + /// + int64_t getId() const; + void setId(int64_t const value); + + friend void to_json(nlohmann::json& j, const Detector_selection& o); + friend void from_json(const nlohmann::json& j, Detector_selection& o); +protected: + int64_t m_Id; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Detector_selection_H_ */ diff --git a/broker/gen/model/Detector_settings.cpp b/broker/gen/model/Detector_settings.cpp new file mode 100644 index 00000000..84a8b967 --- /dev/null +++ b/broker/gen/model/Detector_settings.cpp @@ -0,0 +1,398 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Detector_settings.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Detector_settings::Detector_settings() +{ + m_Frame_time_us = 0L; + m_Count_time_us = 0L; + m_Count_time_usIsSet = false; + m_Storage_cell_count = 1L; + m_Storage_cell_countIsSet = false; + m_Internal_frame_generator = false; + m_Internal_frame_generatorIsSet = false; + m_Collect_raw_data = false; + m_Collect_raw_dataIsSet = false; + m_Pedestal_g0_frames = 0L; + m_Pedestal_g0_framesIsSet = false; + m_Pedestal_g1_frames = 0L; + m_Pedestal_g1_framesIsSet = false; + m_Pedestal_g2_frames = 0L; + m_Pedestal_g2_framesIsSet = false; + m_Storage_cell_delay_ns = 0L; + m_Storage_cell_delay_nsIsSet = false; + +} + +void Detector_settings::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Detector_settings::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Detector_settings::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Detector_settings" : pathPrefix; + + + + /* Frame_time_us */ { + const int64_t& value = m_Frame_time_us; + const std::string currentValuePath = _pathPrefix + ".frameTimeUs"; + + + if (value < 450ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 450;"; + } + + } + + if (storageCellCountIsSet()) + { + const int64_t& value = m_Storage_cell_count; + const std::string currentValuePath = _pathPrefix + ".storageCellCount"; + + + if (value < 1ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + if (value > 16ll) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 16;"; + } + + } + + if (pedestalG0FramesIsSet()) + { + const int64_t& value = m_Pedestal_g0_frames; + const std::string currentValuePath = _pathPrefix + ".pedestalG0Frames"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + if (pedestalG1FramesIsSet()) + { + const int64_t& value = m_Pedestal_g1_frames; + const std::string currentValuePath = _pathPrefix + ".pedestalG1Frames"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + if (pedestalG2FramesIsSet()) + { + const int64_t& value = m_Pedestal_g2_frames; + const std::string currentValuePath = _pathPrefix + ".pedestalG2Frames"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + return success; +} + +bool Detector_settings::operator==(const Detector_settings& rhs) const +{ + return + + + (getFrameTimeUs() == rhs.getFrameTimeUs()) + && + + + ((!countTimeUsIsSet() && !rhs.countTimeUsIsSet()) || (countTimeUsIsSet() && rhs.countTimeUsIsSet() && getCountTimeUs() == rhs.getCountTimeUs())) && + + + ((!storageCellCountIsSet() && !rhs.storageCellCountIsSet()) || (storageCellCountIsSet() && rhs.storageCellCountIsSet() && getStorageCellCount() == rhs.getStorageCellCount())) && + + + ((!internalFrameGeneratorIsSet() && !rhs.internalFrameGeneratorIsSet()) || (internalFrameGeneratorIsSet() && rhs.internalFrameGeneratorIsSet() && isInternalFrameGenerator() == rhs.isInternalFrameGenerator())) && + + + ((!collectRawDataIsSet() && !rhs.collectRawDataIsSet()) || (collectRawDataIsSet() && rhs.collectRawDataIsSet() && isCollectRawData() == rhs.isCollectRawData())) && + + + ((!pedestalG0FramesIsSet() && !rhs.pedestalG0FramesIsSet()) || (pedestalG0FramesIsSet() && rhs.pedestalG0FramesIsSet() && getPedestalG0Frames() == rhs.getPedestalG0Frames())) && + + + ((!pedestalG1FramesIsSet() && !rhs.pedestalG1FramesIsSet()) || (pedestalG1FramesIsSet() && rhs.pedestalG1FramesIsSet() && getPedestalG1Frames() == rhs.getPedestalG1Frames())) && + + + ((!pedestalG2FramesIsSet() && !rhs.pedestalG2FramesIsSet()) || (pedestalG2FramesIsSet() && rhs.pedestalG2FramesIsSet() && getPedestalG2Frames() == rhs.getPedestalG2Frames())) && + + + ((!storageCellDelayNsIsSet() && !rhs.storageCellDelayNsIsSet()) || (storageCellDelayNsIsSet() && rhs.storageCellDelayNsIsSet() && getStorageCellDelayNs() == rhs.getStorageCellDelayNs())) + + ; +} + +bool Detector_settings::operator!=(const Detector_settings& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Detector_settings& o) +{ + j = nlohmann::json(); + j["frame_time_us"] = o.m_Frame_time_us; + if(o.countTimeUsIsSet()) + j["count_time_us"] = o.m_Count_time_us; + if(o.storageCellCountIsSet()) + j["storage_cell_count"] = o.m_Storage_cell_count; + if(o.internalFrameGeneratorIsSet()) + j["internal_frame_generator"] = o.m_Internal_frame_generator; + if(o.collectRawDataIsSet()) + j["collect_raw_data"] = o.m_Collect_raw_data; + if(o.pedestalG0FramesIsSet()) + j["pedestal_g0_frames"] = o.m_Pedestal_g0_frames; + if(o.pedestalG1FramesIsSet()) + j["pedestal_g1_frames"] = o.m_Pedestal_g1_frames; + if(o.pedestalG2FramesIsSet()) + j["pedestal_g2_frames"] = o.m_Pedestal_g2_frames; + if(o.storageCellDelayNsIsSet()) + j["storage_cell_delay_ns"] = o.m_Storage_cell_delay_ns; + +} + +void from_json(const nlohmann::json& j, Detector_settings& o) +{ + j.at("frame_time_us").get_to(o.m_Frame_time_us); + if(j.find("count_time_us") != j.end()) + { + j.at("count_time_us").get_to(o.m_Count_time_us); + o.m_Count_time_usIsSet = true; + } + if(j.find("storage_cell_count") != j.end()) + { + j.at("storage_cell_count").get_to(o.m_Storage_cell_count); + o.m_Storage_cell_countIsSet = true; + } + if(j.find("internal_frame_generator") != j.end()) + { + j.at("internal_frame_generator").get_to(o.m_Internal_frame_generator); + o.m_Internal_frame_generatorIsSet = true; + } + if(j.find("collect_raw_data") != j.end()) + { + j.at("collect_raw_data").get_to(o.m_Collect_raw_data); + o.m_Collect_raw_dataIsSet = true; + } + if(j.find("pedestal_g0_frames") != j.end()) + { + j.at("pedestal_g0_frames").get_to(o.m_Pedestal_g0_frames); + o.m_Pedestal_g0_framesIsSet = true; + } + if(j.find("pedestal_g1_frames") != j.end()) + { + j.at("pedestal_g1_frames").get_to(o.m_Pedestal_g1_frames); + o.m_Pedestal_g1_framesIsSet = true; + } + if(j.find("pedestal_g2_frames") != j.end()) + { + j.at("pedestal_g2_frames").get_to(o.m_Pedestal_g2_frames); + o.m_Pedestal_g2_framesIsSet = true; + } + if(j.find("storage_cell_delay_ns") != j.end()) + { + j.at("storage_cell_delay_ns").get_to(o.m_Storage_cell_delay_ns); + o.m_Storage_cell_delay_nsIsSet = true; + } + +} + +int64_t Detector_settings::getFrameTimeUs() const +{ + return m_Frame_time_us; +} +void Detector_settings::setFrameTimeUs(int64_t const value) +{ + m_Frame_time_us = value; +} +int64_t Detector_settings::getCountTimeUs() const +{ + return m_Count_time_us; +} +void Detector_settings::setCountTimeUs(int64_t const value) +{ + m_Count_time_us = value; + m_Count_time_usIsSet = true; +} +bool Detector_settings::countTimeUsIsSet() const +{ + return m_Count_time_usIsSet; +} +void Detector_settings::unsetCount_time_us() +{ + m_Count_time_usIsSet = false; +} +int64_t Detector_settings::getStorageCellCount() const +{ + return m_Storage_cell_count; +} +void Detector_settings::setStorageCellCount(int64_t const value) +{ + m_Storage_cell_count = value; + m_Storage_cell_countIsSet = true; +} +bool Detector_settings::storageCellCountIsSet() const +{ + return m_Storage_cell_countIsSet; +} +void Detector_settings::unsetStorage_cell_count() +{ + m_Storage_cell_countIsSet = false; +} +bool Detector_settings::isInternalFrameGenerator() const +{ + return m_Internal_frame_generator; +} +void Detector_settings::setInternalFrameGenerator(bool const value) +{ + m_Internal_frame_generator = value; + m_Internal_frame_generatorIsSet = true; +} +bool Detector_settings::internalFrameGeneratorIsSet() const +{ + return m_Internal_frame_generatorIsSet; +} +void Detector_settings::unsetInternal_frame_generator() +{ + m_Internal_frame_generatorIsSet = false; +} +bool Detector_settings::isCollectRawData() const +{ + return m_Collect_raw_data; +} +void Detector_settings::setCollectRawData(bool const value) +{ + m_Collect_raw_data = value; + m_Collect_raw_dataIsSet = true; +} +bool Detector_settings::collectRawDataIsSet() const +{ + return m_Collect_raw_dataIsSet; +} +void Detector_settings::unsetCollect_raw_data() +{ + m_Collect_raw_dataIsSet = false; +} +int64_t Detector_settings::getPedestalG0Frames() const +{ + return m_Pedestal_g0_frames; +} +void Detector_settings::setPedestalG0Frames(int64_t const value) +{ + m_Pedestal_g0_frames = value; + m_Pedestal_g0_framesIsSet = true; +} +bool Detector_settings::pedestalG0FramesIsSet() const +{ + return m_Pedestal_g0_framesIsSet; +} +void Detector_settings::unsetPedestal_g0_frames() +{ + m_Pedestal_g0_framesIsSet = false; +} +int64_t Detector_settings::getPedestalG1Frames() const +{ + return m_Pedestal_g1_frames; +} +void Detector_settings::setPedestalG1Frames(int64_t const value) +{ + m_Pedestal_g1_frames = value; + m_Pedestal_g1_framesIsSet = true; +} +bool Detector_settings::pedestalG1FramesIsSet() const +{ + return m_Pedestal_g1_framesIsSet; +} +void Detector_settings::unsetPedestal_g1_frames() +{ + m_Pedestal_g1_framesIsSet = false; +} +int64_t Detector_settings::getPedestalG2Frames() const +{ + return m_Pedestal_g2_frames; +} +void Detector_settings::setPedestalG2Frames(int64_t const value) +{ + m_Pedestal_g2_frames = value; + m_Pedestal_g2_framesIsSet = true; +} +bool Detector_settings::pedestalG2FramesIsSet() const +{ + return m_Pedestal_g2_framesIsSet; +} +void Detector_settings::unsetPedestal_g2_frames() +{ + m_Pedestal_g2_framesIsSet = false; +} +int64_t Detector_settings::getStorageCellDelayNs() const +{ + return m_Storage_cell_delay_ns; +} +void Detector_settings::setStorageCellDelayNs(int64_t const value) +{ + m_Storage_cell_delay_ns = value; + m_Storage_cell_delay_nsIsSet = true; +} +bool Detector_settings::storageCellDelayNsIsSet() const +{ + return m_Storage_cell_delay_nsIsSet; +} +void Detector_settings::unsetStorage_cell_delay_ns() +{ + m_Storage_cell_delay_nsIsSet = false; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Detector_settings.h b/broker/gen/model/Detector_settings.h new file mode 100644 index 00000000..4e789cbb --- /dev/null +++ b/broker/gen/model/Detector_settings.h @@ -0,0 +1,148 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Detector_settings.h + * + * + */ + +#ifndef Detector_settings_H_ +#define Detector_settings_H_ + + +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Detector_settings +{ +public: + Detector_settings(); + virtual ~Detector_settings() = 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 Detector_settings& rhs) const; + bool operator!=(const Detector_settings& rhs) const; + + ///////////////////////////////////////////// + /// Detector_settings members + + /// + /// Interval between consecutive frames. + /// + int64_t getFrameTimeUs() const; + void setFrameTimeUs(int64_t const value); + /// + /// Integration time of the detector. If not provided count time will be set to maximum value for a given frame time. + /// + int64_t getCountTimeUs() const; + void setCountTimeUs(int64_t const value); + bool countTimeUsIsSet() const; + void unsetCount_time_us(); + /// + /// + /// + int64_t getStorageCellCount() const; + void setStorageCellCount(int64_t const value); + bool storageCellCountIsSet() const; + void unsetStorage_cell_count(); + /// + /// + /// + bool isInternalFrameGenerator() const; + void setInternalFrameGenerator(bool const value); + bool internalFrameGeneratorIsSet() const; + void unsetInternal_frame_generator(); + /// + /// + /// + bool isCollectRawData() const; + void setCollectRawData(bool const value); + bool collectRawDataIsSet() const; + void unsetCollect_raw_data(); + /// + /// + /// + int64_t getPedestalG0Frames() const; + void setPedestalG0Frames(int64_t const value); + bool pedestalG0FramesIsSet() const; + void unsetPedestal_g0_frames(); + /// + /// + /// + int64_t getPedestalG1Frames() const; + void setPedestalG1Frames(int64_t const value); + bool pedestalG1FramesIsSet() const; + void unsetPedestal_g1_frames(); + /// + /// + /// + int64_t getPedestalG2Frames() const; + void setPedestalG2Frames(int64_t const value); + bool pedestalG2FramesIsSet() const; + void unsetPedestal_g2_frames(); + /// + /// + /// + int64_t getStorageCellDelayNs() const; + void setStorageCellDelayNs(int64_t const value); + bool storageCellDelayNsIsSet() const; + void unsetStorage_cell_delay_ns(); + + friend void to_json(nlohmann::json& j, const Detector_settings& o); + friend void from_json(const nlohmann::json& j, Detector_settings& o); +protected: + int64_t m_Frame_time_us; + + int64_t m_Count_time_us; + bool m_Count_time_usIsSet; + int64_t m_Storage_cell_count; + bool m_Storage_cell_countIsSet; + bool m_Internal_frame_generator; + bool m_Internal_frame_generatorIsSet; + bool m_Collect_raw_data; + bool m_Collect_raw_dataIsSet; + int64_t m_Pedestal_g0_frames; + bool m_Pedestal_g0_framesIsSet; + int64_t m_Pedestal_g1_frames; + bool m_Pedestal_g1_framesIsSet; + int64_t m_Pedestal_g2_frames; + bool m_Pedestal_g2_framesIsSet; + int64_t m_Storage_cell_delay_ns; + bool m_Storage_cell_delay_nsIsSet; + +}; + +} // namespace org::openapitools::server::model + +#endif /* Detector_settings_H_ */ diff --git a/broker/gen/model/Error_message.cpp b/broker/gen/model/Error_message.cpp new file mode 100644 index 00000000..116f35d1 --- /dev/null +++ b/broker/gen/model/Error_message.cpp @@ -0,0 +1,105 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Error_message.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Error_message::Error_message() +{ + m_Msg = ""; + m_Reason = ""; + +} + +void Error_message::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Error_message::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Error_message::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Error_message" : pathPrefix; + + + return success; +} + +bool Error_message::operator==(const Error_message& rhs) const +{ + return + + + (getMsg() == rhs.getMsg()) + && + + (getReason() == rhs.getReason()) + + + ; +} + +bool Error_message::operator!=(const Error_message& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Error_message& o) +{ + j = nlohmann::json(); + j["msg"] = o.m_Msg; + j["reason"] = o.m_Reason; + +} + +void from_json(const nlohmann::json& j, Error_message& o) +{ + j.at("msg").get_to(o.m_Msg); + j.at("reason").get_to(o.m_Reason); + +} + +std::string Error_message::getMsg() const +{ + return m_Msg; +} +void Error_message::setMsg(std::string const& value) +{ + m_Msg = value; +} +std::string Error_message::getReason() const +{ + return m_Reason; +} +void Error_message::setReason(std::string const& value) +{ + m_Reason = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Error_message.h b/broker/gen/model/Error_message.h new file mode 100644 index 00000000..cf5d29f7 --- /dev/null +++ b/broker/gen/model/Error_message.h @@ -0,0 +1,84 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Error_message.h + * + * + */ + +#ifndef Error_message_H_ +#define Error_message_H_ + + +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Error_message +{ +public: + Error_message(); + virtual ~Error_message() = 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 Error_message& rhs) const; + bool operator!=(const Error_message& rhs) const; + + ///////////////////////////////////////////// + /// Error_message members + + /// + /// Human readable message + /// + std::string getMsg() const; + void setMsg(std::string const& value); + /// + /// Enumerate field for automated analysis + /// + std::string getReason() const; + void setReason(std::string const& value); + + friend void to_json(nlohmann::json& j, const Error_message& o); + friend void from_json(const nlohmann::json& j, Error_message& o); +protected: + std::string m_Msg; + + std::string m_Reason; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Error_message_H_ */ diff --git a/broker/gen/model/Helpers.cpp b/broker/gen/model/Helpers.cpp new file mode 100644 index 00000000..a6b7658e --- /dev/null +++ b/broker/gen/model/Helpers.cpp @@ -0,0 +1,148 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +#include "Helpers.h" +#include + +namespace org::openapitools::server::helpers +{ + +const std::regex regexRfc3339_date(R"(^(\d{4})\-(\d{2})\-(\d{2})$)"); +const std::regex regexRfc3339_date_time( + R"(^(\d{4})\-(\d{2})\-(\d{2})[Tt](\d{2}):(\d{2}):(\d{2})(\.\d+)?([Zz]|([\+\-])(\d{2}):(\d{2}))$)" +); + + +namespace +{ + // Determine if given year is a leap year + // See RFC 3339, Appendix C https://tools.ietf.org/html/rfc3339#appendix-C + bool isLeapYear(const uint16_t year) { + return (year % 4 == 0) && ((year % 100 != 0) || (year % 400 == 0)); + } + + bool validateDateValues(const uint16_t year, const uint16_t month, const uint16_t day) { + return !( + (month == 0 || month > 12) + || (day == 0) + || (month == 2 && day > (28 + (isLeapYear(year) ? 1 : 0))) + || (month <= 7 && day > (30 + month % 2)) + || (month >= 8 && day > (31 - month % 2)) + ); + } + + bool validateTimeValues(const uint16_t hours, const uint16_t minutes, const uint16_t seconds) { + return (hours <= 23) && (minutes <= 59) && (seconds <= 60); + } +} + +bool validateRfc3339_date(const std::string& str) { + std::smatch match; + const bool found = std::regex_search(str, match, regexRfc3339_date); + return found && validateDateValues(static_cast(std::stoi(match[1])), + static_cast(std::stoi(match[2])), + static_cast(std::stoi(match[3]))); +} + +bool validateRfc3339_date_time(const std::string& str) { + std::smatch match; + const bool found = std::regex_search(str, match, regexRfc3339_date_time); + return found + && validateDateValues(static_cast(std::stoi(match[1])), + static_cast(std::stoi(match[2])), + static_cast(std::stoi(match[3]))) + && validateTimeValues(static_cast(std::stoi(match[4])), + static_cast(std::stoi(match[5])), + static_cast(std::stoi(match[6]))); +} + +std::string toStringValue(const std::string &value){ + return std::string(value); +} + +std::string toStringValue(const int32_t value){ + return std::to_string(value); +} + +std::string toStringValue(const int64_t value){ + return std::to_string(value); +} + +std::string toStringValue(const bool value){ + return value ? std::string("true") : std::string("false"); +} + +std::string toStringValue(const float value){ + return std::to_string(value); +} + +std::string toStringValue(const double value){ + return std::to_string(value); +} + +bool fromStringValue(const std::string &inStr, std::string &value){ + value = std::string(inStr); + return true; +} + +bool fromStringValue(const std::string &inStr, int32_t &value){ + try { + value = std::stoi( inStr ); + } + catch (const std::invalid_argument&) { + return false; + } + return true; +} + +bool fromStringValue(const std::string &inStr, int64_t &value){ + try { + value = std::stol( inStr ); + } + catch (const std::invalid_argument&) { + return false; + } + return true; +} + +bool fromStringValue(const std::string &inStr, bool &value){ + if (inStr == "true") { + value = true; + return true; + } + if (inStr == "false") { + value = false; + return true; + } + return false; +} + +bool fromStringValue(const std::string &inStr, float &value){ + try { + value = std::stof( inStr ); + } + catch (const std::invalid_argument&) { + return false; + } + return true; +} + +bool fromStringValue(const std::string &inStr, double &value){ + try { + value = std::stod( inStr ); + } + catch (const std::invalid_argument&) { + return false; + } + return true; +} + +} // namespace org::openapitools::server::helpers diff --git a/broker/gen/model/Helpers.h b/broker/gen/model/Helpers.h new file mode 100644 index 00000000..7d3e98db --- /dev/null +++ b/broker/gen/model/Helpers.h @@ -0,0 +1,136 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Helpers.h + * + * This is the helper class for models and primitives + */ + +#ifndef Helpers_H_ +#define Helpers_H_ + +#include +#include +#include +#include +#include + +namespace org::openapitools::server::helpers +{ + + class ValidationException : public std::runtime_error + { + public: + explicit ValidationException(const std::string& what) + : std::runtime_error(what) + { } + ~ValidationException() override = default; + }; + + /// + /// Validate a string against the full-date definition of RFC 3339, section 5.6. + /// + bool validateRfc3339_date(const std::string& str); + + /// + /// Validate a string against the date-time definition of RFC 3339, section 5.6. + /// + bool validateRfc3339_date_time(const std::string& str); + + namespace sfinae_helpers + { + struct NoType {}; + template NoType operator==(const T1&, const T2&); + + template class EqualsOperatorAvailable + { + public: + enum + { + value = !std::is_same< decltype(std::declval() == std::declval()), NoType >::value + }; + }; + } // namespace sfinae_helpers + + + /// + /// Determine if the given vector only has unique elements. T must provide the == operator. + /// + template + bool hasOnlyUniqueItems(const std::vector& vec) + { + static_assert(sfinae_helpers::EqualsOperatorAvailable::value, + "hasOnlyUniqueItems cannot be called, passed template type does not provide == operator."); + if (vec.size() <= 1) + { + return true; + } + // Compare every element of vec to every other element of vec. + // This isn't an elegant way to do this, since it's O(n^2), + // but it's the best solution working only with the == operator. + // This could be greatly improved if our models provided a valid hash + // and/or the < operator + for (size_t i = 0; i < vec.size() - 1; i++) + { + for (size_t j = i + 1; j < vec.size(); j++) + { + if (vec[i] == vec[j]) + { + return false; + } + } + } + return true; + } + + std::string toStringValue(const std::string &value); + std::string toStringValue(const int32_t value); + std::string toStringValue(const int64_t value); + std::string toStringValue(const bool value); + std::string toStringValue(const float value); + std::string toStringValue(const double value); + + bool fromStringValue(const std::string &inStr, std::string &value); + bool fromStringValue(const std::string &inStr, int32_t &value); + bool fromStringValue(const std::string &inStr, int64_t &value); + bool fromStringValue(const std::string &inStr, bool &value); + bool fromStringValue(const std::string &inStr, float &value); + bool fromStringValue(const std::string &inStr, double &value); + template + bool fromStringValue(const std::vector &inStr, std::vector &value){ + try{ + for(auto & item : inStr){ + T itemValue; + if(fromStringValue(item, itemValue)){ + value.push_back(itemValue); + } + } + } + catch(...){ + return false; + } + return value.size() > 0; + } + template + bool fromStringValue(const std::string &inStr, std::vector &value, char separator = ','){ + std::vector inStrings; + std::istringstream f(inStr); + std::string s; + while (std::getline(f, s, separator)) { + inStrings.push_back(s); + } + return fromStringValue(inStrings, value); + } + +} // namespace org::openapitools::server::helpers + +#endif // Helpers_H_ diff --git a/broker/gen/model/Measurement_statistics.cpp b/broker/gen/model/Measurement_statistics.cpp new file mode 100644 index 00000000..5b49009d --- /dev/null +++ b/broker/gen/model/Measurement_statistics.cpp @@ -0,0 +1,458 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Measurement_statistics.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Measurement_statistics::Measurement_statistics() +{ + m_File_prefix = ""; + m_File_prefixIsSet = false; + m_Images_collected = 0L; + m_Images_collectedIsSet = false; + m_Max_image_number_sent = 0L; + m_Max_image_number_sentIsSet = false; + m_Collection_efficiency = 0.0f; + m_Collection_efficiencyIsSet = false; + m_Compression_ratio = 0.0f; + m_Compression_ratioIsSet = false; + m_Cancelled = false; + m_CancelledIsSet = false; + m_Max_receiver_delay = 0L; + m_Max_receiver_delayIsSet = false; + m_Indexing_rate = 0.0f; + m_Indexing_rateIsSet = false; + m_Detector_width = 0L; + m_Detector_widthIsSet = false; + m_Detector_height = 0L; + m_Detector_heightIsSet = false; + m_Detector_pixel_depth = 0L; + m_Detector_pixel_depthIsSet = false; + m_Bkg_estimate = 0.0f; + m_Bkg_estimateIsSet = false; + +} + +void Measurement_statistics::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Measurement_statistics::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Measurement_statistics::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Measurement_statistics" : pathPrefix; + + + if (collectionEfficiencyIsSet()) + { + const float& value = m_Collection_efficiency; + const std::string currentValuePath = _pathPrefix + ".collectionEfficiency"; + + + if (value < static_cast(0.0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0.0;"; + } + if (value > static_cast(1.0)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 1.0;"; + } + + } + + if (compressionRatioIsSet()) + { + const float& value = m_Compression_ratio; + const std::string currentValuePath = _pathPrefix + ".compressionRatio"; + + + if (value < static_cast(0.0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0.0;"; + } + + } + + return success; +} + +bool Measurement_statistics::operator==(const Measurement_statistics& rhs) const +{ + return + + + + ((!filePrefixIsSet() && !rhs.filePrefixIsSet()) || (filePrefixIsSet() && rhs.filePrefixIsSet() && getFilePrefix() == rhs.getFilePrefix())) && + + + ((!imagesCollectedIsSet() && !rhs.imagesCollectedIsSet()) || (imagesCollectedIsSet() && rhs.imagesCollectedIsSet() && getImagesCollected() == rhs.getImagesCollected())) && + + + ((!maxImageNumberSentIsSet() && !rhs.maxImageNumberSentIsSet()) || (maxImageNumberSentIsSet() && rhs.maxImageNumberSentIsSet() && getMaxImageNumberSent() == rhs.getMaxImageNumberSent())) && + + + ((!collectionEfficiencyIsSet() && !rhs.collectionEfficiencyIsSet()) || (collectionEfficiencyIsSet() && rhs.collectionEfficiencyIsSet() && getCollectionEfficiency() == rhs.getCollectionEfficiency())) && + + + ((!compressionRatioIsSet() && !rhs.compressionRatioIsSet()) || (compressionRatioIsSet() && rhs.compressionRatioIsSet() && getCompressionRatio() == rhs.getCompressionRatio())) && + + + ((!cancelledIsSet() && !rhs.cancelledIsSet()) || (cancelledIsSet() && rhs.cancelledIsSet() && isCancelled() == rhs.isCancelled())) && + + + ((!maxReceiverDelayIsSet() && !rhs.maxReceiverDelayIsSet()) || (maxReceiverDelayIsSet() && rhs.maxReceiverDelayIsSet() && getMaxReceiverDelay() == rhs.getMaxReceiverDelay())) && + + + ((!indexingRateIsSet() && !rhs.indexingRateIsSet()) || (indexingRateIsSet() && rhs.indexingRateIsSet() && getIndexingRate() == rhs.getIndexingRate())) && + + + ((!detectorWidthIsSet() && !rhs.detectorWidthIsSet()) || (detectorWidthIsSet() && rhs.detectorWidthIsSet() && getDetectorWidth() == rhs.getDetectorWidth())) && + + + ((!detectorHeightIsSet() && !rhs.detectorHeightIsSet()) || (detectorHeightIsSet() && rhs.detectorHeightIsSet() && getDetectorHeight() == rhs.getDetectorHeight())) && + + + ((!detectorPixelDepthIsSet() && !rhs.detectorPixelDepthIsSet()) || (detectorPixelDepthIsSet() && rhs.detectorPixelDepthIsSet() && getDetectorPixelDepth() == rhs.getDetectorPixelDepth())) && + + + ((!bkgEstimateIsSet() && !rhs.bkgEstimateIsSet()) || (bkgEstimateIsSet() && rhs.bkgEstimateIsSet() && getBkgEstimate() == rhs.getBkgEstimate())) + + ; +} + +bool Measurement_statistics::operator!=(const Measurement_statistics& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Measurement_statistics& o) +{ + j = nlohmann::json(); + if(o.filePrefixIsSet()) + j["file_prefix"] = o.m_File_prefix; + if(o.imagesCollectedIsSet()) + j["images_collected"] = o.m_Images_collected; + if(o.maxImageNumberSentIsSet()) + j["max_image_number_sent"] = o.m_Max_image_number_sent; + if(o.collectionEfficiencyIsSet()) + j["collection_efficiency"] = o.m_Collection_efficiency; + if(o.compressionRatioIsSet()) + j["compression_ratio"] = o.m_Compression_ratio; + if(o.cancelledIsSet()) + j["cancelled"] = o.m_Cancelled; + if(o.maxReceiverDelayIsSet()) + j["max_receiver_delay"] = o.m_Max_receiver_delay; + if(o.indexingRateIsSet()) + j["indexing_rate"] = o.m_Indexing_rate; + if(o.detectorWidthIsSet()) + j["detector_width"] = o.m_Detector_width; + if(o.detectorHeightIsSet()) + j["detector_height"] = o.m_Detector_height; + if(o.detectorPixelDepthIsSet()) + j["detector_pixel_depth"] = o.m_Detector_pixel_depth; + if(o.bkgEstimateIsSet()) + j["bkg_estimate"] = o.m_Bkg_estimate; + +} + +void from_json(const nlohmann::json& j, Measurement_statistics& o) +{ + if(j.find("file_prefix") != j.end()) + { + j.at("file_prefix").get_to(o.m_File_prefix); + o.m_File_prefixIsSet = true; + } + if(j.find("images_collected") != j.end()) + { + j.at("images_collected").get_to(o.m_Images_collected); + o.m_Images_collectedIsSet = true; + } + if(j.find("max_image_number_sent") != j.end()) + { + j.at("max_image_number_sent").get_to(o.m_Max_image_number_sent); + o.m_Max_image_number_sentIsSet = true; + } + if(j.find("collection_efficiency") != j.end()) + { + j.at("collection_efficiency").get_to(o.m_Collection_efficiency); + o.m_Collection_efficiencyIsSet = true; + } + if(j.find("compression_ratio") != j.end()) + { + j.at("compression_ratio").get_to(o.m_Compression_ratio); + o.m_Compression_ratioIsSet = true; + } + if(j.find("cancelled") != j.end()) + { + j.at("cancelled").get_to(o.m_Cancelled); + o.m_CancelledIsSet = true; + } + if(j.find("max_receiver_delay") != j.end()) + { + j.at("max_receiver_delay").get_to(o.m_Max_receiver_delay); + o.m_Max_receiver_delayIsSet = true; + } + if(j.find("indexing_rate") != j.end()) + { + j.at("indexing_rate").get_to(o.m_Indexing_rate); + o.m_Indexing_rateIsSet = true; + } + if(j.find("detector_width") != j.end()) + { + j.at("detector_width").get_to(o.m_Detector_width); + o.m_Detector_widthIsSet = true; + } + if(j.find("detector_height") != j.end()) + { + j.at("detector_height").get_to(o.m_Detector_height); + o.m_Detector_heightIsSet = true; + } + if(j.find("detector_pixel_depth") != j.end()) + { + j.at("detector_pixel_depth").get_to(o.m_Detector_pixel_depth); + o.m_Detector_pixel_depthIsSet = true; + } + if(j.find("bkg_estimate") != j.end()) + { + j.at("bkg_estimate").get_to(o.m_Bkg_estimate); + o.m_Bkg_estimateIsSet = true; + } + +} + +std::string Measurement_statistics::getFilePrefix() const +{ + return m_File_prefix; +} +void Measurement_statistics::setFilePrefix(std::string const& value) +{ + m_File_prefix = value; + m_File_prefixIsSet = true; +} +bool Measurement_statistics::filePrefixIsSet() const +{ + return m_File_prefixIsSet; +} +void Measurement_statistics::unsetFile_prefix() +{ + m_File_prefixIsSet = false; +} +int64_t Measurement_statistics::getImagesCollected() const +{ + return m_Images_collected; +} +void Measurement_statistics::setImagesCollected(int64_t const value) +{ + m_Images_collected = value; + m_Images_collectedIsSet = true; +} +bool Measurement_statistics::imagesCollectedIsSet() const +{ + return m_Images_collectedIsSet; +} +void Measurement_statistics::unsetImages_collected() +{ + m_Images_collectedIsSet = false; +} +int64_t Measurement_statistics::getMaxImageNumberSent() const +{ + return m_Max_image_number_sent; +} +void Measurement_statistics::setMaxImageNumberSent(int64_t const value) +{ + m_Max_image_number_sent = value; + m_Max_image_number_sentIsSet = true; +} +bool Measurement_statistics::maxImageNumberSentIsSet() const +{ + return m_Max_image_number_sentIsSet; +} +void Measurement_statistics::unsetMax_image_number_sent() +{ + m_Max_image_number_sentIsSet = false; +} +float Measurement_statistics::getCollectionEfficiency() const +{ + return m_Collection_efficiency; +} +void Measurement_statistics::setCollectionEfficiency(float const value) +{ + m_Collection_efficiency = value; + m_Collection_efficiencyIsSet = true; +} +bool Measurement_statistics::collectionEfficiencyIsSet() const +{ + return m_Collection_efficiencyIsSet; +} +void Measurement_statistics::unsetCollection_efficiency() +{ + m_Collection_efficiencyIsSet = false; +} +float Measurement_statistics::getCompressionRatio() const +{ + return m_Compression_ratio; +} +void Measurement_statistics::setCompressionRatio(float const value) +{ + m_Compression_ratio = value; + m_Compression_ratioIsSet = true; +} +bool Measurement_statistics::compressionRatioIsSet() const +{ + return m_Compression_ratioIsSet; +} +void Measurement_statistics::unsetCompression_ratio() +{ + m_Compression_ratioIsSet = false; +} +bool Measurement_statistics::isCancelled() const +{ + return m_Cancelled; +} +void Measurement_statistics::setCancelled(bool const value) +{ + m_Cancelled = value; + m_CancelledIsSet = true; +} +bool Measurement_statistics::cancelledIsSet() const +{ + return m_CancelledIsSet; +} +void Measurement_statistics::unsetCancelled() +{ + m_CancelledIsSet = false; +} +int64_t Measurement_statistics::getMaxReceiverDelay() const +{ + return m_Max_receiver_delay; +} +void Measurement_statistics::setMaxReceiverDelay(int64_t const value) +{ + m_Max_receiver_delay = value; + m_Max_receiver_delayIsSet = true; +} +bool Measurement_statistics::maxReceiverDelayIsSet() const +{ + return m_Max_receiver_delayIsSet; +} +void Measurement_statistics::unsetMax_receiver_delay() +{ + m_Max_receiver_delayIsSet = false; +} +float Measurement_statistics::getIndexingRate() const +{ + return m_Indexing_rate; +} +void Measurement_statistics::setIndexingRate(float const value) +{ + m_Indexing_rate = value; + m_Indexing_rateIsSet = true; +} +bool Measurement_statistics::indexingRateIsSet() const +{ + return m_Indexing_rateIsSet; +} +void Measurement_statistics::unsetIndexing_rate() +{ + m_Indexing_rateIsSet = false; +} +int64_t Measurement_statistics::getDetectorWidth() const +{ + return m_Detector_width; +} +void Measurement_statistics::setDetectorWidth(int64_t const value) +{ + m_Detector_width = value; + m_Detector_widthIsSet = true; +} +bool Measurement_statistics::detectorWidthIsSet() const +{ + return m_Detector_widthIsSet; +} +void Measurement_statistics::unsetDetector_width() +{ + m_Detector_widthIsSet = false; +} +int64_t Measurement_statistics::getDetectorHeight() const +{ + return m_Detector_height; +} +void Measurement_statistics::setDetectorHeight(int64_t const value) +{ + m_Detector_height = value; + m_Detector_heightIsSet = true; +} +bool Measurement_statistics::detectorHeightIsSet() const +{ + return m_Detector_heightIsSet; +} +void Measurement_statistics::unsetDetector_height() +{ + m_Detector_heightIsSet = false; +} +int64_t Measurement_statistics::getDetectorPixelDepth() const +{ + return m_Detector_pixel_depth; +} +void Measurement_statistics::setDetectorPixelDepth(int64_t const value) +{ + m_Detector_pixel_depth = value; + m_Detector_pixel_depthIsSet = true; +} +bool Measurement_statistics::detectorPixelDepthIsSet() const +{ + return m_Detector_pixel_depthIsSet; +} +void Measurement_statistics::unsetDetector_pixel_depth() +{ + m_Detector_pixel_depthIsSet = false; +} +float Measurement_statistics::getBkgEstimate() const +{ + return m_Bkg_estimate; +} +void Measurement_statistics::setBkgEstimate(float const value) +{ + m_Bkg_estimate = value; + m_Bkg_estimateIsSet = true; +} +bool Measurement_statistics::bkgEstimateIsSet() const +{ + return m_Bkg_estimateIsSet; +} +void Measurement_statistics::unsetBkg_estimate() +{ + m_Bkg_estimateIsSet = false; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Measurement_statistics.h b/broker/gen/model/Measurement_statistics.h new file mode 100644 index 00000000..3c63aa4a --- /dev/null +++ b/broker/gen/model/Measurement_statistics.h @@ -0,0 +1,178 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Measurement_statistics.h + * + * + */ + +#ifndef Measurement_statistics_H_ +#define Measurement_statistics_H_ + + +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Measurement_statistics +{ +public: + Measurement_statistics(); + virtual ~Measurement_statistics() = 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 Measurement_statistics& rhs) const; + bool operator!=(const Measurement_statistics& rhs) const; + + ///////////////////////////////////////////// + /// Measurement_statistics members + + /// + /// + /// + std::string getFilePrefix() const; + void setFilePrefix(std::string const& value); + bool filePrefixIsSet() const; + void unsetFile_prefix(); + /// + /// + /// + int64_t getImagesCollected() const; + void setImagesCollected(int64_t const value); + bool imagesCollectedIsSet() const; + void unsetImages_collected(); + /// + /// + /// + int64_t getMaxImageNumberSent() const; + void setMaxImageNumberSent(int64_t const value); + bool maxImageNumberSentIsSet() const; + void unsetMax_image_number_sent(); + /// + /// + /// + float getCollectionEfficiency() const; + void setCollectionEfficiency(float const value); + bool collectionEfficiencyIsSet() const; + void unsetCollection_efficiency(); + /// + /// + /// + float getCompressionRatio() const; + void setCompressionRatio(float const value); + bool compressionRatioIsSet() const; + void unsetCompression_ratio(); + /// + /// + /// + bool isCancelled() const; + void setCancelled(bool const value); + bool cancelledIsSet() const; + void unsetCancelled(); + /// + /// + /// + int64_t getMaxReceiverDelay() const; + void setMaxReceiverDelay(int64_t const value); + bool maxReceiverDelayIsSet() const; + void unsetMax_receiver_delay(); + /// + /// + /// + float getIndexingRate() const; + void setIndexingRate(float const value); + bool indexingRateIsSet() const; + void unsetIndexing_rate(); + /// + /// + /// + int64_t getDetectorWidth() const; + void setDetectorWidth(int64_t const value); + bool detectorWidthIsSet() const; + void unsetDetector_width(); + /// + /// + /// + int64_t getDetectorHeight() const; + void setDetectorHeight(int64_t const value); + bool detectorHeightIsSet() const; + void unsetDetector_height(); + /// + /// + /// + int64_t getDetectorPixelDepth() const; + void setDetectorPixelDepth(int64_t const value); + bool detectorPixelDepthIsSet() const; + void unsetDetector_pixel_depth(); + /// + /// + /// + float getBkgEstimate() const; + void setBkgEstimate(float const value); + bool bkgEstimateIsSet() const; + void unsetBkg_estimate(); + + friend void to_json(nlohmann::json& j, const Measurement_statistics& o); + friend void from_json(const nlohmann::json& j, Measurement_statistics& o); +protected: + std::string m_File_prefix; + bool m_File_prefixIsSet; + int64_t m_Images_collected; + bool m_Images_collectedIsSet; + int64_t m_Max_image_number_sent; + bool m_Max_image_number_sentIsSet; + float m_Collection_efficiency; + bool m_Collection_efficiencyIsSet; + float m_Compression_ratio; + bool m_Compression_ratioIsSet; + bool m_Cancelled; + bool m_CancelledIsSet; + int64_t m_Max_receiver_delay; + bool m_Max_receiver_delayIsSet; + float m_Indexing_rate; + bool m_Indexing_rateIsSet; + int64_t m_Detector_width; + bool m_Detector_widthIsSet; + int64_t m_Detector_height; + bool m_Detector_heightIsSet; + int64_t m_Detector_pixel_depth; + bool m_Detector_pixel_depthIsSet; + float m_Bkg_estimate; + bool m_Bkg_estimateIsSet; + +}; + +} // namespace org::openapitools::server::model + +#endif /* Measurement_statistics_H_ */ diff --git a/broker/gen/model/Plot.cpp b/broker/gen/model/Plot.cpp new file mode 100644 index 00000000..a7681a8c --- /dev/null +++ b/broker/gen/model/Plot.cpp @@ -0,0 +1,145 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Plot.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Plot::Plot() +{ + +} + +void Plot::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Plot::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +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; + const std::string currentValuePath = _pathPrefix + ".X"; + + + { // Recursive validation of array elements + const std::string oldValuePath = currentValuePath; + int i = 0; + for (const float& value : value) + { + const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]"; + + + + i++; + } + } + + } + + + /* y */ { + const std::vector& value = m_y; + const std::string currentValuePath = _pathPrefix + ".Y"; + + + { // Recursive validation of array elements + const std::string oldValuePath = currentValuePath; + int i = 0; + for (const float& value : value) + { + const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]"; + + + + i++; + } + } + + } + + return success; +} + +bool Plot::operator==(const Plot& rhs) const +{ + return + + + (getX() == rhs.getX()) + && + + (getY() == rhs.getY()) + + + ; +} + +bool Plot::operator!=(const Plot& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Plot& o) +{ + j = nlohmann::json(); + j["x"] = o.m_x; + j["y"] = o.m_y; + +} + +void from_json(const nlohmann::json& j, Plot& o) +{ + j.at("x").get_to(o.m_x); + j.at("y").get_to(o.m_y); + +} + +std::vector Plot::getX() const +{ + return m_x; +} +void Plot::setX(std::vector const value) +{ + m_x = value; +} +std::vector Plot::getY() const +{ + return m_y; +} +void Plot::setY(std::vector const value) +{ + m_y = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Plot.h b/broker/gen/model/Plot.h new file mode 100644 index 00000000..fb55d6db --- /dev/null +++ b/broker/gen/model/Plot.h @@ -0,0 +1,84 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Plot.h + * + * x and y coordinates for plotting, it is OK to assume that both arrays have the same size; layout is optimized for Plotly + */ + +#ifndef Plot_H_ +#define Plot_H_ + + +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// x and y coordinates for plotting, it is OK to assume that both arrays have the same size; layout is optimized for Plotly +/// +class Plot +{ +public: + Plot(); + virtual ~Plot() = 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 Plot& rhs) const; + bool operator!=(const Plot& rhs) const; + + ///////////////////////////////////////////// + /// Plot members + + /// + /// + /// + std::vector getX() const; + void setX(std::vector const value); + /// + /// + /// + std::vector getY() const; + void setY(std::vector const value); + + friend void to_json(nlohmann::json& j, const Plot& o); + friend void from_json(const nlohmann::json& j, Plot& o); +protected: + std::vector m_x; + + std::vector m_y; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Plot_H_ */ diff --git a/broker/gen/model/Plot_request.cpp b/broker/gen/model/Plot_request.cpp new file mode 100644 index 00000000..689be18d --- /dev/null +++ b/broker/gen/model/Plot_request.cpp @@ -0,0 +1,106 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Plot_request.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Plot_request::Plot_request() +{ + m_Binning = 0L; + m_BinningIsSet = false; + +} + +void Plot_request::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Plot_request::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Plot_request::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Plot_request" : pathPrefix; + + + return success; +} + +bool Plot_request::operator==(const Plot_request& rhs) const +{ + return + + + + ((!binningIsSet() && !rhs.binningIsSet()) || (binningIsSet() && rhs.binningIsSet() && getBinning() == rhs.getBinning())) + + ; +} + +bool Plot_request::operator!=(const Plot_request& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Plot_request& o) +{ + j = nlohmann::json(); + if(o.binningIsSet()) + j["binning"] = o.m_Binning; + +} + +void from_json(const nlohmann::json& j, Plot_request& o) +{ + if(j.find("binning") != j.end()) + { + j.at("binning").get_to(o.m_Binning); + o.m_BinningIsSet = true; + } + +} + +int64_t Plot_request::getBinning() const +{ + return m_Binning; +} +void Plot_request::setBinning(int64_t const value) +{ + m_Binning = value; + m_BinningIsSet = true; +} +bool Plot_request::binningIsSet() const +{ + return m_BinningIsSet; +} +void Plot_request::unsetBinning() +{ + m_BinningIsSet = false; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Plot_request.h b/broker/gen/model/Plot_request.h new file mode 100644 index 00000000..d6cce77d --- /dev/null +++ b/broker/gen/model/Plot_request.h @@ -0,0 +1,78 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Plot_request.h + * + * + */ + +#ifndef Plot_request_H_ +#define Plot_request_H_ + + +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Plot_request +{ +public: + Plot_request(); + virtual ~Plot_request() = 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 Plot_request& rhs) const; + bool operator!=(const Plot_request& rhs) const; + + ///////////////////////////////////////////// + /// Plot_request members + + /// + /// + /// + int64_t getBinning() const; + void setBinning(int64_t const value); + bool binningIsSet() const; + void unsetBinning(); + + friend void to_json(nlohmann::json& j, const Plot_request& o); + friend void from_json(const nlohmann::json& j, Plot_request& o); +protected: + int64_t m_Binning; + bool m_BinningIsSet; + +}; + +} // namespace org::openapitools::server::model + +#endif /* Plot_request_H_ */ diff --git a/broker/gen/model/Rad_int_settings.cpp b/broker/gen/model/Rad_int_settings.cpp new file mode 100644 index 00000000..3e963a7e --- /dev/null +++ b/broker/gen/model/Rad_int_settings.cpp @@ -0,0 +1,181 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Rad_int_settings.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Rad_int_settings::Rad_int_settings() +{ + m_Polarization_factor = 0.0f; + m_Polarization_factorIsSet = false; + m_Solid_angle_corr = true; + m_High_q_recipA = 0.0f; + m_Low_q_recipA = 0.0f; + m_Q_spacing = 0.0f; + +} + +void Rad_int_settings::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Rad_int_settings::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Rad_int_settings::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Rad_int_settings" : pathPrefix; + + + if (polarizationFactorIsSet()) + { + const float& value = m_Polarization_factor; + const std::string currentValuePath = _pathPrefix + ".polarizationFactor"; + + + if (value < static_cast(-1.0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to -1.0;"; + } + if (value > static_cast(1.0)) + { + success = false; + msg << currentValuePath << ": must be less than or equal to 1.0;"; + } + + } + + return success; +} + +bool Rad_int_settings::operator==(const Rad_int_settings& rhs) const +{ + return + + + + ((!polarizationFactorIsSet() && !rhs.polarizationFactorIsSet()) || (polarizationFactorIsSet() && rhs.polarizationFactorIsSet() && getPolarizationFactor() == rhs.getPolarizationFactor())) && + + (isSolidAngleCorr() == rhs.isSolidAngleCorr()) + && + + (getHighQRecipA() == rhs.getHighQRecipA()) + && + + (getLowQRecipA() == rhs.getLowQRecipA()) + && + + (getQSpacing() == rhs.getQSpacing()) + + + ; +} + +bool Rad_int_settings::operator!=(const Rad_int_settings& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Rad_int_settings& o) +{ + j = nlohmann::json(); + if(o.polarizationFactorIsSet()) + j["polarization_factor"] = o.m_Polarization_factor; + j["solid_angle_corr"] = o.m_Solid_angle_corr; + j["high_q_recipA"] = o.m_High_q_recipA; + j["low_q_recipA"] = o.m_Low_q_recipA; + j["q_spacing"] = o.m_Q_spacing; + +} + +void from_json(const nlohmann::json& j, Rad_int_settings& o) +{ + if(j.find("polarization_factor") != j.end()) + { + j.at("polarization_factor").get_to(o.m_Polarization_factor); + o.m_Polarization_factorIsSet = true; + } + j.at("solid_angle_corr").get_to(o.m_Solid_angle_corr); + j.at("high_q_recipA").get_to(o.m_High_q_recipA); + j.at("low_q_recipA").get_to(o.m_Low_q_recipA); + j.at("q_spacing").get_to(o.m_Q_spacing); + +} + +float Rad_int_settings::getPolarizationFactor() const +{ + return m_Polarization_factor; +} +void Rad_int_settings::setPolarizationFactor(float const value) +{ + m_Polarization_factor = value; + m_Polarization_factorIsSet = true; +} +bool Rad_int_settings::polarizationFactorIsSet() const +{ + return m_Polarization_factorIsSet; +} +void Rad_int_settings::unsetPolarization_factor() +{ + m_Polarization_factorIsSet = false; +} +bool Rad_int_settings::isSolidAngleCorr() const +{ + return m_Solid_angle_corr; +} +void Rad_int_settings::setSolidAngleCorr(bool const value) +{ + m_Solid_angle_corr = value; +} +float Rad_int_settings::getHighQRecipA() const +{ + return m_High_q_recipA; +} +void Rad_int_settings::setHighQRecipA(float const value) +{ + m_High_q_recipA = value; +} +float Rad_int_settings::getLowQRecipA() const +{ + return m_Low_q_recipA; +} +void Rad_int_settings::setLowQRecipA(float const value) +{ + m_Low_q_recipA = value; +} +float Rad_int_settings::getQSpacing() const +{ + return m_Q_spacing; +} +void Rad_int_settings::setQSpacing(float const value) +{ + m_Q_spacing = value; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Rad_int_settings.h b/broker/gen/model/Rad_int_settings.h new file mode 100644 index 00000000..6f70ab75 --- /dev/null +++ b/broker/gen/model/Rad_int_settings.h @@ -0,0 +1,106 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Rad_int_settings.h + * + * + */ + +#ifndef Rad_int_settings_H_ +#define Rad_int_settings_H_ + + +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Rad_int_settings +{ +public: + Rad_int_settings(); + virtual ~Rad_int_settings() = 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 Rad_int_settings& rhs) const; + bool operator!=(const Rad_int_settings& rhs) const; + + ///////////////////////////////////////////// + /// Rad_int_settings members + + /// + /// If polarization factor is provided, than polarization correction is enabled. + /// + float getPolarizationFactor() const; + void setPolarizationFactor(float const value); + bool polarizationFactorIsSet() const; + void unsetPolarization_factor(); + /// + /// Apply solid angle correction for radial integration + /// + bool isSolidAngleCorr() const; + void setSolidAngleCorr(bool const value); + /// + /// + /// + float getHighQRecipA() const; + void setHighQRecipA(float const value); + /// + /// + /// + float getLowQRecipA() const; + void setLowQRecipA(float const value); + /// + /// + /// + float getQSpacing() const; + void setQSpacing(float const value); + + friend void to_json(nlohmann::json& j, const Rad_int_settings& o); + friend void from_json(const nlohmann::json& j, Rad_int_settings& o); +protected: + float m_Polarization_factor; + bool m_Polarization_factorIsSet; + bool m_Solid_angle_corr; + + float m_High_q_recipA; + + float m_Low_q_recipA; + + float m_Q_spacing; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Rad_int_settings_H_ */ diff --git a/broker/gen/model/Radial_integration_plots_inner.cpp b/broker/gen/model/Radial_integration_plots_inner.cpp new file mode 100644 index 00000000..28151e1d --- /dev/null +++ b/broker/gen/model/Radial_integration_plots_inner.cpp @@ -0,0 +1,104 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* 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/Radial_integration_plots_inner.h b/broker/gen/model/Radial_integration_plots_inner.h new file mode 100644 index 00000000..edbc7705 --- /dev/null +++ b/broker/gen/model/Radial_integration_plots_inner.h @@ -0,0 +1,85 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Radial_integration_plots_inner.h + * + * + */ + +#ifndef Radial_integration_plots_inner_H_ +#define Radial_integration_plots_inner_H_ + + +#include "Plot.h" +#include +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Radial_integration_plots_inner +{ +public: + Radial_integration_plots_inner(); + virtual ~Radial_integration_plots_inner() = 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 Radial_integration_plots_inner& rhs) const; + bool operator!=(const Radial_integration_plots_inner& rhs) const; + + ///////////////////////////////////////////// + /// Radial_integration_plots_inner members + + /// + /// + /// + std::string getTitle() const; + void setTitle(std::string const& value); + /// + /// + /// + org::openapitools::server::model::Plot getPlot() const; + void setPlot(org::openapitools::server::model::Plot 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); +protected: + std::string m_Title; + + org::openapitools::server::model::Plot m_Plot; + + +}; + +} // namespace org::openapitools::server::model + +#endif /* Radial_integration_plots_inner_H_ */ diff --git a/broker/gen/model/Spot_finding_settings.cpp b/broker/gen/model/Spot_finding_settings.cpp new file mode 100644 index 00000000..ac23cb80 --- /dev/null +++ b/broker/gen/model/Spot_finding_settings.cpp @@ -0,0 +1,246 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ + + +#include "Spot_finding_settings.h" +#include "Helpers.h" + +#include + +namespace org::openapitools::server::model +{ + +Spot_finding_settings::Spot_finding_settings() +{ + m_Signal_to_noise_threshold = 0.0f; + m_Photon_count_threshold = 0L; + m_Min_pix_per_spot = 0L; + m_Max_pix_per_spot = 0L; + m_High_resolution_limit = 0.0f; + m_Low_resolution_limit = 0.0f; + m_Preview_indexed_only = false; + m_Preview_indexed_onlyIsSet = false; + +} + +void Spot_finding_settings::validate() const +{ + std::stringstream msg; + if (!validate(msg)) + { + throw org::openapitools::server::helpers::ValidationException(msg.str()); + } +} + +bool Spot_finding_settings::validate(std::stringstream& msg) const +{ + return validate(msg, ""); +} + +bool Spot_finding_settings::validate(std::stringstream& msg, const std::string& pathPrefix) const +{ + bool success = true; + const std::string _pathPrefix = pathPrefix.empty() ? "Spot_finding_settings" : pathPrefix; + + + + /* Signal_to_noise_threshold */ { + const float& value = m_Signal_to_noise_threshold; + const std::string currentValuePath = _pathPrefix + ".signalToNoiseThreshold"; + + + if (value < static_cast(0)) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Photon_count_threshold */ { + const int64_t& value = m_Photon_count_threshold; + const std::string currentValuePath = _pathPrefix + ".photonCountThreshold"; + + + if (value < 0ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 0;"; + } + + } + + + /* Min_pix_per_spot */ { + const int64_t& value = m_Min_pix_per_spot; + const std::string currentValuePath = _pathPrefix + ".minPixPerSpot"; + + + if (value < 1ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + + } + + + /* Max_pix_per_spot */ { + const int64_t& value = m_Max_pix_per_spot; + const std::string currentValuePath = _pathPrefix + ".maxPixPerSpot"; + + + if (value < 1ll) + { + success = false; + msg << currentValuePath << ": must be greater than or equal to 1;"; + } + + } + + return success; +} + +bool Spot_finding_settings::operator==(const Spot_finding_settings& rhs) const +{ + return + + + (getSignalToNoiseThreshold() == rhs.getSignalToNoiseThreshold()) + && + + (getPhotonCountThreshold() == rhs.getPhotonCountThreshold()) + && + + (getMinPixPerSpot() == rhs.getMinPixPerSpot()) + && + + (getMaxPixPerSpot() == rhs.getMaxPixPerSpot()) + && + + (getHighResolutionLimit() == rhs.getHighResolutionLimit()) + && + + (getLowResolutionLimit() == rhs.getLowResolutionLimit()) + && + + + ((!previewIndexedOnlyIsSet() && !rhs.previewIndexedOnlyIsSet()) || (previewIndexedOnlyIsSet() && rhs.previewIndexedOnlyIsSet() && isPreviewIndexedOnly() == rhs.isPreviewIndexedOnly())) + + ; +} + +bool Spot_finding_settings::operator!=(const Spot_finding_settings& rhs) const +{ + return !(*this == rhs); +} + +void to_json(nlohmann::json& j, const Spot_finding_settings& o) +{ + j = nlohmann::json(); + j["signal_to_noise_threshold"] = o.m_Signal_to_noise_threshold; + j["photon_count_threshold"] = o.m_Photon_count_threshold; + j["min_pix_per_spot"] = o.m_Min_pix_per_spot; + j["max_pix_per_spot"] = o.m_Max_pix_per_spot; + j["high_resolution_limit"] = o.m_High_resolution_limit; + j["low_resolution_limit"] = o.m_Low_resolution_limit; + if(o.previewIndexedOnlyIsSet()) + j["preview_indexed_only"] = o.m_Preview_indexed_only; + +} + +void from_json(const nlohmann::json& j, Spot_finding_settings& o) +{ + j.at("signal_to_noise_threshold").get_to(o.m_Signal_to_noise_threshold); + j.at("photon_count_threshold").get_to(o.m_Photon_count_threshold); + j.at("min_pix_per_spot").get_to(o.m_Min_pix_per_spot); + j.at("max_pix_per_spot").get_to(o.m_Max_pix_per_spot); + j.at("high_resolution_limit").get_to(o.m_High_resolution_limit); + j.at("low_resolution_limit").get_to(o.m_Low_resolution_limit); + if(j.find("preview_indexed_only") != j.end()) + { + j.at("preview_indexed_only").get_to(o.m_Preview_indexed_only); + o.m_Preview_indexed_onlyIsSet = true; + } + +} + +float Spot_finding_settings::getSignalToNoiseThreshold() const +{ + return m_Signal_to_noise_threshold; +} +void Spot_finding_settings::setSignalToNoiseThreshold(float const value) +{ + m_Signal_to_noise_threshold = value; +} +int64_t Spot_finding_settings::getPhotonCountThreshold() const +{ + return m_Photon_count_threshold; +} +void Spot_finding_settings::setPhotonCountThreshold(int64_t const value) +{ + m_Photon_count_threshold = value; +} +int64_t Spot_finding_settings::getMinPixPerSpot() const +{ + return m_Min_pix_per_spot; +} +void Spot_finding_settings::setMinPixPerSpot(int64_t const value) +{ + m_Min_pix_per_spot = value; +} +int64_t Spot_finding_settings::getMaxPixPerSpot() const +{ + return m_Max_pix_per_spot; +} +void Spot_finding_settings::setMaxPixPerSpot(int64_t const value) +{ + m_Max_pix_per_spot = value; +} +float Spot_finding_settings::getHighResolutionLimit() const +{ + return m_High_resolution_limit; +} +void Spot_finding_settings::setHighResolutionLimit(float const value) +{ + m_High_resolution_limit = value; +} +float Spot_finding_settings::getLowResolutionLimit() const +{ + return m_Low_resolution_limit; +} +void Spot_finding_settings::setLowResolutionLimit(float const value) +{ + m_Low_resolution_limit = value; +} +bool Spot_finding_settings::isPreviewIndexedOnly() const +{ + return m_Preview_indexed_only; +} +void Spot_finding_settings::setPreviewIndexedOnly(bool const value) +{ + m_Preview_indexed_only = value; + m_Preview_indexed_onlyIsSet = true; +} +bool Spot_finding_settings::previewIndexedOnlyIsSet() const +{ + return m_Preview_indexed_onlyIsSet; +} +void Spot_finding_settings::unsetPreview_indexed_only() +{ + m_Preview_indexed_onlyIsSet = false; +} + + +} // namespace org::openapitools::server::model + diff --git a/broker/gen/model/Spot_finding_settings.h b/broker/gen/model/Spot_finding_settings.h new file mode 100644 index 00000000..9e1e3519 --- /dev/null +++ b/broker/gen/model/Spot_finding_settings.h @@ -0,0 +1,120 @@ +/** +* Jungfraujoch +* Jungfraujoch Broker Web API +* +* The version of the OpenAPI document: 1.0.0 +* +* +* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech). +* https://openapi-generator.tech +* Do not edit the class manually. +*/ +/* + * Spot_finding_settings.h + * + * + */ + +#ifndef Spot_finding_settings_H_ +#define Spot_finding_settings_H_ + + +#include + +namespace org::openapitools::server::model +{ + +/// +/// +/// +class Spot_finding_settings +{ +public: + Spot_finding_settings(); + virtual ~Spot_finding_settings() = 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 Spot_finding_settings& rhs) const; + bool operator!=(const Spot_finding_settings& rhs) const; + + ///////////////////////////////////////////// + /// Spot_finding_settings members + + /// + /// + /// + float getSignalToNoiseThreshold() const; + void setSignalToNoiseThreshold(float const value); + /// + /// + /// + int64_t getPhotonCountThreshold() const; + void setPhotonCountThreshold(int64_t const value); + /// + /// + /// + int64_t getMinPixPerSpot() const; + void setMinPixPerSpot(int64_t const value); + /// + /// + /// + int64_t getMaxPixPerSpot() const; + void setMaxPixPerSpot(int64_t const value); + /// + /// + /// + float getHighResolutionLimit() const; + void setHighResolutionLimit(float const value); + /// + /// + /// + float getLowResolutionLimit() const; + void setLowResolutionLimit(float const value); + /// + /// + /// + bool isPreviewIndexedOnly() const; + void setPreviewIndexedOnly(bool const value); + bool previewIndexedOnlyIsSet() const; + void unsetPreview_indexed_only(); + + friend void to_json(nlohmann::json& j, const Spot_finding_settings& o); + friend void from_json(const nlohmann::json& j, Spot_finding_settings& o); +protected: + float m_Signal_to_noise_threshold; + + int64_t m_Photon_count_threshold; + + int64_t m_Min_pix_per_spot; + + int64_t m_Max_pix_per_spot; + + float m_High_resolution_limit; + + float m_Low_resolution_limit; + + bool m_Preview_indexed_only; + bool m_Preview_indexed_onlyIsSet; + +}; + +} // namespace org::openapitools::server::model + +#endif /* Spot_finding_settings_H_ */ diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml new file mode 100644 index 00000000..bfbbee68 --- /dev/null +++ b/broker/jfjoch_api.yaml @@ -0,0 +1,899 @@ +openapi: 3.0.3 +info: + title: Jungfraujoch + description: Jungfraujoch Broker Web API + version: 1.0.0 +components: + schemas: + dataset_settings: + type: object + required: + - images_per_trigger + - beam_x_pxl + - beam_y_pxl + - detector_distance_mm + - photon_energy_keV + - sample_name + properties: + images_per_trigger: + type: integer + format: int64 + minimum: 0 + ntrigger: + type: integer + format: int64 + default: 1 + minimum: 1 + summation: + type: integer + format: int64 + minimum: 1 + maximum: 256 + default: 1 + beam_x_pxl: + type: number + format: float + description: | + /entry/detector/beam_center_x in NXmx + Beam center in X direction [pixels] + beam_y_pxl: + type: number + format: float + description: | + /entry/detector/beam_center_y in NXmx + Beam center in X direction [pixels] + detector_distance_mm: + type: number + format: float + minimum: 0 + description: + /entry/detector/distance in NXmx + Detector distance [mm] + photon_energy_keV: + type: number + format: float + minimum: 0 + description: | + Used to calculate /entry/beam/incident_wavelength in NXmx + Incident photon energy in keV + file_prefix: + type: string + default: "" + description: Prefix for filenames. If left empty, no file will be saved. + data_file_count: + type: integer + format: int64 + minimum: 1 + default: 1 + description: Number of round-robin data files + space_group_number: + type: integer + format: int64 + minimum: 0 + default: 0 + maximum: 194 + sample_name: + type: string + description: | + /entry/sample/name in NXmx + Sample name + save_calibration: + type: boolean + default: false + description: Save pedestal together with the dataset + fpga_output: + type: string + enum: [ + "auto", + "int32", + "int16", + "uint32", + "uint16" + ] + default: "auto" + description: FPGA output data type + compression: + type: string + enum: [ + "bslz4", + "bszstd", + "bszstd_rle", + "none" + ] + default: "bslz4" + total_flux: + type: number + format: float + description: | + /entry/beam/total_flux in NXmx + Flux incident on beam plane in photons per second. In other words this is the flux integrated over area. [photons/s] + transmission: + type: number + format: float + minimum: 0.0 + maximum: 1.0 + description: | + /entry/instrument/attenuator/attenuator_transmission + Transmission of attenuator (filter) [no units] + unit_cell: + type: object + description: Units of angstrom and degree + required: + - a + - b + - c + - alpha + - beta + - gamma + properties: + a: + type: number + format: float + example: 37 + b: + type: number + format: float + example: 37 + c: + type: number + format: float + example: 78 + alpha: + type: number + format: float + example: 90 + beta: + type: number + format: float + example: 90 + gamma: + type: number + format: float + example: 90 + + detector_settings: + type: object + required: + - frame_time_us + properties: + frame_time_us: + type: integer + description: Interval between consecutive frames. + format: int64 + minimum: 450 + count_time_us: + type: integer + description: Integration time of the detector. If not provided count time will be set to maximum value for a given frame time. + format: int64 + storage_cell_count: + type: integer + format: int64 + default: 1 + minimum: 1 + maximum: 16 + internal_frame_generator: + type: boolean + default: false + collect_raw_data: + type: boolean + default: false + pedestal_g0_frames: + type: integer + format: int64 + minimum: 0 + pedestal_g1_frames: + type: integer + format: int64 + minimum: 0 + pedestal_g2_frames: + type: integer + format: int64 + minimum: 0 + storage_cell_delay_ns: + type: integer + format: int64 + spot_finding_settings: + type: object + required: + - signal_to_noise_threshold + - photon_count_threshold + - max_pix_per_spot + - min_pix_per_spot + - high_resolution_limit + - low_resolution_limit + properties: + signal_to_noise_threshold: + type: number + format: float + minimum: 0 + photon_count_threshold: + type: integer + format: int64 + minimum: 0 + min_pix_per_spot: + type: integer + format: int64 + minimum: 1 + max_pix_per_spot: + type: integer + format: int64 + minimum: 1 + high_resolution_limit: + type: number + format: float + low_resolution_limit: + type: number + format: float + preview_indexed_only: + type: boolean + default: false + rad_int_settings: + type: object + required: + - solid_angle_corr + - high_q_recipA + - low_q_recipA + - q_spacing + properties: + polarization_factor: + type: number + description: If polarization factor is provided, than polarization correction is enabled. + format: float + minimum: -1.0 + maximum: 1.0 + solid_angle_corr: + type: boolean + description: Apply solid angle correction for radial integration + default: true + high_q_recipA: + type: number + format: float + low_q_recipA: + type: number + format: float + q_spacing: + type: number + format: float + detector_list: + type: object + required: + - detectors + - current_id + properties: + detectors: + type: array + items: + type: object + required: + - id + - nmodules + - description + - width + - height + properties: + id: + type: integer + format: int64 + minimum: 0 + description: + type: string + example: "JUNGFRAU 4 Mpixel" + nmodules: + type: integer + format: int64 + example: 18 + width: + type: integer + format: int64 + example: 2068 + height: + type: integer + format: int64 + example: 2164 + current_id: + type: integer + format: int64 + example: 0 + detector_selection: + type: object + required: + - id + properties: + id: + type: integer + format: int64 + example: 1 + measurement_statistics: + type: object + properties: + file_prefix: + type: string + images_collected: + type: integer + format: int64 + max_image_number_sent: + type: integer + format: int64 + collection_efficiency: + type: number + format: float + example: 1.0 + minimum: 0.0 + maximum: 1.0 + compression_ratio: + type: number + format: float + example: 5.3 + minimum: 0.0 + cancelled: + type: boolean + max_receiver_delay: + type: integer + format: int64 + indexing_rate: + type: number + format: float + detector_width: + type: integer + format: int64 + detector_height: + type: integer + format: int64 + detector_pixel_depth: + type: integer + format: int64 + enum: + - 2 + - 4 + bkg_estimate: + type: number + format: float + broker_status: + type: object + required: + - state + properties: + state: + type: string + enum: + - Inactive + - Idle + - Busy + - Measuring + - Pedestal + - Error + progress: + type: number + format: float + example: 1.0 + minimum: 0.0 + maximum: 1.0 + indexing_rate: + type: number + format: float + example: 0.10 + minimum: 0.0 + maximum: 1.0 + receiver_send_buffers_avail: + type: number + format: float + example: 0.8 + minimum: 0.0 + maximum: 1.0 + plot_request: + type: object + properties: + binning: + type: integer + format: int64 + plot: + type: object + required: + - x + - y + 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: + x: + type: array + items: + type: number + format: float + y: + type: array + 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" + calibration_statistics: + type: array + items: + required: + - module_number + - storage_cell_number + - pedestal_g0_mean + - pedestal_g1_mean + - pedestal_g2_mean + - gain_g0_mean + - gain_g1_mean + - gain_g2_mean + - masked_pixels + type: object + properties: + module_number: + type: integer + format: int64 + storage_cell_number: + type: integer + format: int64 + pedestal_g0_mean: + type: number + format: float + pedestal_g1_mean: + type: number + format: float + pedestal_g2_mean: + type: number + format: float + gain_g0_mean: + type: number + format: float + gain_g1_mean: + type: number + format: float + gain_g2_mean: + type: number + format: float + masked_pixels: + type: integer + format: int64 + error_message: + type: object + required: + - msg + - reason + properties: + msg: + type: string + description: "Human readable message" + example: "Detector in wrong state" + reason: + type: string + description: "Enumerate field for automated analysis" + enum: + - WrongDAQState + - Other + + +paths: + /initialize: + post: + summary: Initialize detector and data acquisition + description: | + Should be used in two cases: + - Detector is in `Inactive` state + - Detector is in `Error` state + X-ray shutter must be closed. + This operation will reconfigure network interface of the detector. + During operation of the detector it is recommended to use the `POST /pedestal` operation instead. + If storage cells are used, the execution time might be few minutes. + + This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + responses: + "200": + description: Initialization started + "500": + description: Error within Jungfraujoch code - see output message. + content: + application/json: + schema: + $ref: '#/components/schemas/error_message' + + /pedestal: + post: + summary: Collect dark current for the detector + description: | + Updates calibration of the JUNGFRAU detector. Must be in `Idle` state. + + X-ray shutter must be closed. Recommended to run once per hour for long integration times (> 100 us). + + This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + responses: + "200": + description: Everything OK + "500": + description: Error within Jungfraujoch code - see output message. + content: + application/json: + schema: + $ref: '#/components/schemas/error_message' + + /start: + post: + summary: Start detector + description: | + Start data acquisition. + Detector must be in `Idle` state. + Doesn't run calibration procedure. + This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/dataset_settings' + 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' + /wait_till_done: + post: + summary: Wait for acquisition done + description: | + 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. + responses: + "200": + description: Detector in `Idle` state, another data collection can start immediately + "500": + description: Error within Jungfraujoch code - see output message. + content: + application/json: + schema: + $ref: '#/components/schemas/error_message' + "504": + description: 5 second timeout reached, need to restart operation + + /trigger: + post: + summary: Send soft trigger to the detector + description: Generate soft trigger + responses: + "200": + description: Trigger sent + + /cancel: + post: + summary: Cancel running data collection + description: | + Command will inform FPGA network card to stop pedestal or data collection at the current stage. + Any frame that is currently being processed by CPU will be finished and sent to writer. + Given the command is making sure to gracefully stop data acquisition and detector, it might take some time to switch back after command finished to `Idle` state. + + If data collection is not running, the command has no effect. + responses: + "200": + description: Cancel request sent to FPGAs (or ignored, as data collection is not running) + + /deactivate: + post: + summary: Prepare detector to turn off + description: | + Should be in `Idle` or `Error` state. + Command deactivates data acquisition and turns off detector high voltage and ASIC. + Should be used always before turning off power from the detector. + responses: + "200": + description: Detector ready to turn off + "500": + description: Error within Jungfraujoch code - see output message. + content: + application/json: + schema: + $ref: '#/components/schemas/error_message' + + /config/detector: + put: + summary: Change detector configuration + description: | + Detector settings are ones that have effect on calibration, i.e., pedestal has to be collected again after changing these settings. + This can only be done when detector is `Idle`, `Error` or `Inactive` states. + If detector is in `Idle` state , pedestal procedure will be executed automatically - there must be no X-rays on the detector during the operation. + If detector is in `Inactive` or `Error` states, new settings will be saved, but no calibration will be executed. + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/detector_settings' + 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' + get: + summary: Get detector configuration + description: Can be done anytime + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/detector_settings' + + /config/spot_finding: + put: + summary: Configure spot finding + description: Can be done anytime, also while data collection is running + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/spot_finding_settings' + responses: + "200": + description: Everything OK + "400": + description: Input parsing or validation error + content: + text/plain: + schema: + type: string + description: Exception error + get: + summary: Get data processing configuration + description: Can be done anytime + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/spot_finding_settings' + /config/rad_int: + put: + summary: Configure radial integration + description: Can be done when detector is Inactive or Idle + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/rad_int_settings' + 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' + get: + summary: Get data processing configuration + description: Can be done anytime + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/rad_int_settings' + + /config/select_detector: + put: + summary: Select detector + description: | + Jungfraujoch allows to control multiple detectors and/or region-of-interests. + The command allows to choose one detector from the list (ID has to be consistent with one provided by GET response). + Changing detector will set detector to `Inactive` state and will require reinitialization. + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/detector_selection' + 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' + get: + summary: List available detectors + description: Configured detectors that can be selected by used + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/detector_list' + /status: + get: + summary: Get Jungfraujoch status + description: Status of the data acquisition + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/broker_status' + /plot/bkg_estimate: + post: + summary: Generate background estimate plot + description: Mean intensity for d = 3 - 5 A 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' + "400": + description: Input parsing or validation error + content: + text/plain: + schema: + type: string + description: Exception error + /plot/spot_count: + post: + summary: Generate spot count plot + description: Number of spots 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' + "400": + description: Input parsing or validation error + content: + text/plain: + schema: + type: string + description: Exception error + /plot/indexing_rate: + post: + summary: Generate indexing rate plot + description: Image indexing rate; 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' + "400": + description: Input parsing or validation error + content: + text/plain: + schema: + type: string + description: Exception error + /plot/adu_histogram: + get: + summary: Generate ADU histogram + description: ADU histogram for all images within current data collection + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/plot' + /plot/indexing_rate_per_file: + get: + summary: Generate indexing rate per file + description: Indexing rate per each of data files; useful for example for time resolved data + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/plot' + /plot/rad_int: + get: + summary: Generate radial integration profile + description: Generate average radial integration profile + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/plot' + /plot/rad_int_per_file: + get: + summary: Generate radial integration profiles per file + description: Radial integration plots for both the whole dataset and per file; useful for time-resolved measurements + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/radial_integration_plots' + /statistics/data_collection: + get: + summary: Get data collection statistics + description: Results of the last data collection + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/measurement_statistics' + "404": + description: No data collection performed so far + + /statistics/calibration: + get: + summary: Get calibration statistics + description: Statistics are provided for each module/storage cell separately + responses: + "200": + description: Everything OK + content: + application/json: + schema: + $ref: '#/components/schemas/calibration_statistics' diff --git a/broker/jfjoch_broker.cpp b/broker/jfjoch_broker.cpp index 9659b070..8149912a 100644 --- a/broker/jfjoch_broker.cpp +++ b/broker/jfjoch_broker.cpp @@ -1,25 +1,57 @@ // Copyright (2019-2023) Paul Scherrer Institute +// Using OpenAPI licensed with Apache License 2.0 +#include +#include #include #include #include "../common/Logger.h" #include "../common/NetworkAddressConvert.h" -#include "JFJochBroker.h" -#include "../grpc/gRPCServer_Template.h" +#include "JFJochBrokerHttp.h" #include "JFJochBrokerParser.h" #include "../frame_serialize/ZMQStream2Pusher.h" +static Pistache::Http::Endpoint *httpEndpoint; + +static void sigHandler [[noreturn]] (int sig){ + switch(sig){ + case SIGINT: + case SIGQUIT: + case SIGTERM: + case SIGHUP: + default: + httpEndpoint->shutdown(); + break; + } + exit(0); +} + +static void setUpUnixSignals(std::vector quitSignals) { + sigset_t blocking_mask; + sigemptyset(&blocking_mask); + for (auto sig : quitSignals) + sigaddset(&blocking_mask, sig); + + struct sigaction sa; + sa.sa_handler = sigHandler; + sa.sa_mask = blocking_mask; + sa.sa_flags = 0; + + for (auto sig : quitSignals) + sigaction(sig, &sa, nullptr); +} + int main (int argc, char **argv) { if (argc > 3) { - std::cout << "Usage ./jfjoch_broker { {}}" << std::endl; + std::cout << "Usage ./jfjoch_broker {}" << std::endl; exit(EXIT_FAILURE); } - uint16_t grpc_port = 5232; - if (argc >= 3) grpc_port = atoi(argv[2]); + uint16_t http_port = 5232; + if (argc >= 3) http_port = atoi(argv[2]); Logger logger("jfjoch_broker"); @@ -32,6 +64,9 @@ int main (int argc, char **argv) { logger.Error("JSON Parsing exception: " + std::string(e.what())); exit(EXIT_FAILURE); } + } else { + logger.Error("Must provide JSON configuration file"); + exit(EXIT_FAILURE); } std::unique_ptr receiver; @@ -66,17 +101,30 @@ int main (int argc, char **argv) { ParseFacilityConfiguration(input, "cfg", experiment); - JFJochBroker broker(experiment); + Pistache::Address addr(Pistache::Ipv4::any(), Pistache::Port(http_port)); + + httpEndpoint = new Pistache::Http::Endpoint((addr)); + + std::vector sigs{SIGQUIT, SIGINT, SIGTERM, SIGHUP}; + setUpUnixSignals(sigs); + + auto router = std::make_shared(); + + auto opts = Pistache::Http::Endpoint::options().threads(8); + opts.flags(Pistache::Tcp::Options::ReuseAddr); + httpEndpoint->init(opts); + + JFJochBrokerHttp broker(experiment, router); + broker.FrontendDirectory(input["frontend_directory"]); ParseDetectorSetup(input, "detectors", broker); if (receiver) broker.Services().Receiver(receiver.get()); - broker.Services().Detector(); + // broker.Services().Detector(); - std::string grpc_addr = "0.0.0.0:" + std::to_string(grpc_port); + httpEndpoint->setHandler(router->handler()); + httpEndpoint->serve(); - auto server = gRPCServer(grpc_addr, broker); - logger.Info("gRPC configuration listening on address " + grpc_addr); - server->Wait(); + httpEndpoint->shutdown(); } \ No newline at end of file diff --git a/broker/redoc-static.html b/broker/redoc-static.html new file mode 100644 index 00000000..6ca64223 --- /dev/null +++ b/broker/redoc-static.html @@ -0,0 +1,604 @@ + + + + + + Jungfraujoch + + + + + + + + + +

Jungfraujoch (1.0.0)

Download OpenAPI specification:Download

Jungfraujoch Broker Web API

+

Initialize detector and data acquisition

Should be used in two cases:

+
    +
  • Detector is in Inactive state
  • +
  • Detector is in Error state +X-ray shutter must be closed. +This operation will reconfigure network interface of the detector. +During operation of the detector it is recommended to use the POST /pedestal operation instead. +If storage cells are used, the execution time might be few minutes.
  • +
+

This is async function - one needs to use POST /wait_till_done to ensure operation is done.

+

Responses

Response samples

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

Collect dark current for the detector

Updates calibration of the JUNGFRAU detector. Must be in Idle state.

+

X-ray shutter must be closed. Recommended to run once per hour for long integration times (> 100 us).

+

This is async function - one needs to use POST /wait_till_done to ensure operation is done.

+

Responses

Response samples

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

Start detector

Start data acquisition. +Detector must be in Idle state. +Doesn't run calibration procedure. +This is async function - one needs to use POST /wait_till_done to ensure operation is done.

+
Request Body schema: application/json
images_per_trigger
required
integer <int64> >= 0
ntrigger
integer <int64> >= 1
Default: 1
summation
integer <int64> [ 1 .. 256 ]
Default: 1
beam_x_pxl
required
number <float>

/entry/detector/beam_center_x in NXmx +Beam center in X direction [pixels]

+
beam_y_pxl
required
number <float>

/entry/detector/beam_center_y in NXmx +Beam center in X direction [pixels]

+
detector_distance_mm
required
number <float> >= 0

/entry/detector/distance in NXmx Detector distance [mm]

+
photon_energy_keV
required
number <float> >= 0

Used to calculate /entry/beam/incident_wavelength in NXmx +Incident photon energy in keV

+
file_prefix
string
Default: ""

Prefix for filenames. If left empty, no file will be saved.

+
data_file_count
integer <int64> >= 1
Default: 1

Number of round-robin data files

+
space_group_number
integer <int64> [ 0 .. 194 ]
Default: 0
sample_name
required
string

/entry/sample/name in NXmx +Sample name

+
save_calibration
boolean
Default: false

Save pedestal together with the dataset

+
fpga_output
string
Default: "auto"
Enum: "auto" "int32" "int16" "uint32" "uint16"

FPGA output data type

+
compression
string
Default: "bslz4"
Enum: "bslz4" "bszstd" "bszstd_rle" "none"
total_flux
number <float>

/entry/beam/total_flux in NXmx +Flux incident on beam plane in photons per second. In other words this is the flux integrated over area. [photons/s]

+
transmission
number <float> [ 0 .. 1 ]

/entry/instrument/attenuator/attenuator_transmission +Transmission of attenuator (filter) [no units]

+
object

Units of angstrom and degree

+

Responses

Request samples

Content type
application/json
{
  • "images_per_trigger": 0,
  • "ntrigger": 1,
  • "summation": 1,
  • "beam_x_pxl": 0,
  • "beam_y_pxl": 0,
  • "detector_distance_mm": 0,
  • "photon_energy_keV": 0,
  • "file_prefix": "",
  • "data_file_count": 1,
  • "space_group_number": 0,
  • "sample_name": "string",
  • "save_calibration": false,
  • "fpga_output": "auto",
  • "compression": "bslz4",
  • "total_flux": 0,
  • "transmission": 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. +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.

+

Responses

Response samples

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

Send soft trigger to the detector

Generate soft trigger

+

Responses

Cancel running data collection

Command will inform FPGA network card to stop pedestal or data collection at the current stage. +Any frame that is currently being processed by CPU will be finished and sent to writer. +Given the command is making sure to gracefully stop data acquisition and detector, it might take some time to switch back after command finished to Idle state.

+

If data collection is not running, the command has no effect.

+

Responses

Prepare detector to turn off

Should be in Idle or Error state. +Command deactivates data acquisition and turns off detector high voltage and ASIC. +Should be used always before turning off power from the detector.

+

Responses

Response samples

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

Change detector configuration

Detector settings are ones that have effect on calibration, i.e., pedestal has to be collected again after changing these settings. +This can only be done when detector is Idle, Error or Inactive states. +If detector is in Idle state , pedestal procedure will be executed automatically - there must be no X-rays on the detector during the operation. +If detector is in Inactive or Error states, new settings will be saved, but no calibration will be executed.

+
Request Body schema: application/json
frame_time_us
required
integer <int64> >= 450

Interval between consecutive frames.

+
count_time_us
integer <int64>

Integration time of the detector. If not provided count time will be set to maximum value for a given frame time.

+
storage_cell_count
integer <int64> [ 1 .. 16 ]
Default: 1
internal_frame_generator
boolean
Default: false
collect_raw_data
boolean
Default: false
pedestal_g0_frames
integer <int64> >= 0
pedestal_g1_frames
integer <int64> >= 0
pedestal_g2_frames
integer <int64> >= 0
storage_cell_delay_ns
integer <int64>

Responses

Request samples

Content type
application/json
{
  • "frame_time_us": 450,
  • "count_time_us": 0,
  • "storage_cell_count": 1,
  • "internal_frame_generator": false,
  • "collect_raw_data": false,
  • "pedestal_g0_frames": 0,
  • "pedestal_g1_frames": 0,
  • "pedestal_g2_frames": 0,
  • "storage_cell_delay_ns": 0
}

Response samples

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

Get detector configuration

Can be done anytime

+

Responses

Response samples

Content type
application/json
{
  • "frame_time_us": 450,
  • "count_time_us": 0,
  • "storage_cell_count": 1,
  • "internal_frame_generator": false,
  • "collect_raw_data": false,
  • "pedestal_g0_frames": 0,
  • "pedestal_g1_frames": 0,
  • "pedestal_g2_frames": 0,
  • "storage_cell_delay_ns": 0
}

Configure spot finding

Can be done anytime, also while data collection is running

+
Request Body schema: application/json
signal_to_noise_threshold
required
number <float> >= 0
photon_count_threshold
required
integer <int64> >= 0
min_pix_per_spot
required
integer <int64> >= 1
max_pix_per_spot
required
integer <int64> >= 1
high_resolution_limit
required
number <float>
low_resolution_limit
required
number <float>
preview_indexed_only
boolean
Default: false

Responses

Request samples

Content type
application/json
{
  • "signal_to_noise_threshold": 0,
  • "photon_count_threshold": 0,
  • "min_pix_per_spot": 1,
  • "max_pix_per_spot": 1,
  • "high_resolution_limit": 0,
  • "low_resolution_limit": 0,
  • "preview_indexed_only": false
}

Get data processing configuration

Can be done anytime

+

Responses

Response samples

Content type
application/json
{
  • "signal_to_noise_threshold": 0,
  • "photon_count_threshold": 0,
  • "min_pix_per_spot": 1,
  • "max_pix_per_spot": 1,
  • "high_resolution_limit": 0,
  • "low_resolution_limit": 0,
  • "preview_indexed_only": false
}

Configure radial integration

Can be done when detector is Inactive or Idle

+
Request Body schema: application/json
polarization_factor
number <float> [ -1 .. 1 ]

If polarization factor is provided, than polarization correction is enabled.

+
solid_angle_corr
required
boolean
Default: true

Apply solid angle correction for radial integration

+
high_q_recipA
required
number <float>
low_q_recipA
required
number <float>
q_spacing
required
number <float>

Responses

Request samples

Content type
application/json
{
  • "polarization_factor": -1,
  • "solid_angle_corr": true,
  • "high_q_recipA": 0,
  • "low_q_recipA": 0,
  • "q_spacing": 0
}

Response samples

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

Get data processing configuration

Can be done anytime

+

Responses

Response samples

Content type
application/json
{
  • "polarization_factor": -1,
  • "solid_angle_corr": true,
  • "high_q_recipA": 0,
  • "low_q_recipA": 0,
  • "q_spacing": 0
}

Select detector

Jungfraujoch allows to control multiple detectors and/or region-of-interests. +The command allows to choose one detector from the list (ID has to be consistent with one provided by GET response). +Changing detector will set detector to Inactive state and will require reinitialization.

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

Responses

Request samples

Content type
application/json
{
  • "id": 1
}

Response samples

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

List available detectors

Configured detectors that can be selected by used

+

Responses

Response samples

Content type
application/json
{
  • "detectors": [
    ],
  • "current_id": 0
}

Get Jungfraujoch status

Status of the data acquisition

+

Responses

Response samples

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

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

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

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 ADU histogram

ADU histogram for all images within current data collection

+

Responses

Response samples

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

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 radial integration profile

Generate average radial integration profile

+

Responses

Response samples

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

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

Results of the last data collection

+

Responses

Response samples

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

Get calibration statistics

Statistics are provided for each module/storage cell separately

+

Responses

Response samples

Content type
application/json
[
  • {
    }
]
+ + + + diff --git a/common/Definitions.h b/common/Definitions.h index 48614287..8f4a1344 100644 --- a/common/Definitions.h +++ b/common/Definitions.h @@ -24,7 +24,6 @@ #define MIN_STORAGE_CELL_DELAY_IN_NS 2100 #define READOUT_TIME_IN_US 20 -#define GRPC_MAX_MESSAGE_SIZE (2*1000L*1000L*1000L) #define MIN_ENERGY 0.1 #define MAX_ENERGY 25.0 @@ -33,11 +32,6 @@ #define FRAME_TIME_PEDE_G1G2_IN_US (10*1000) -#define SENSOR_THICKNESS_IN_UM 320.0 -#define PIXEL_SIZE_IN_UM 75.0 -#define PIXEL_SIZE_IN_MM (PIXEL_SIZE_IN_UM/1000.0) -#define SENSOR_MATERIAL "Si" - #define GAIN_G0_MULTIPLIER 32 #define GAIN_G1_MULTIPLIER (-1) #define GAIN_G2_MULTIPLIER (-1) diff --git a/common/DetectorSetup.cpp b/common/DetectorSetup.cpp index c7d9783d..1ad2c85e 100644 --- a/common/DetectorSetup.cpp +++ b/common/DetectorSetup.cpp @@ -32,7 +32,15 @@ std::string DetectorSetup::GetDescription() const { } float DetectorSetup::GetPixelSize_mm() const { - return PIXEL_SIZE_IN_MM; + return pixel_size_um / 1000.0f; +} + +std::string DetectorSetup::GetSensorMaterial() const { + return sensor_material; +} + +float DetectorSetup::GetSensorThickness_um() const { + return sensor_thickness_um; } void DetectorSetup::LoadGain(const std::vector &filenames) { @@ -57,4 +65,19 @@ const std::vector &DetectorSetup::GetGainCalibration() int64_t DetectorSetup::GetUDPInterfaceCount() const { return udp_interface_count; -} \ No newline at end of file +} + +DetectorSetup &DetectorSetup::SensorMaterial(const std::string &input) { + sensor_material = input; + return *this; +} + +DetectorSetup &DetectorSetup::SensorThickness_um(float input) { + sensor_thickness_um = input; + return *this; +} + +DetectorSetup &DetectorSetup::PixelSize_um(float input) { + pixel_size_um = input; + return *this; +} diff --git a/common/DetectorSetup.h b/common/DetectorSetup.h index 21ef2c9e..62760153 100644 --- a/common/DetectorSetup.h +++ b/common/DetectorSetup.h @@ -12,6 +12,9 @@ class DetectorSetup { std::vector det_modules_hostname; std::vector gain_calibration; int64_t udp_interface_count = 2; + float pixel_size_um = 75.0f; + std::string sensor_material = "Si"; + float sensor_thickness_um = 320.0f; public: DetectorSetup(const DetectorGeometry& geom); DetectorSetup(const DetectorGeometry& geom, @@ -21,11 +24,17 @@ public: void LoadGain(const std::vector &filenames); DetectorSetup& UDPInterfaceCount(int64_t input); + DetectorSetup& SensorMaterial(const std::string &input); + DetectorSetup& SensorThickness_um(float input); + DetectorSetup& PixelSize_um(float input); + [[nodiscard]] const DetectorGeometry& GetGeometry() const; [[nodiscard]] const std::vector& GetDetectorModuleHostname() const; [[nodiscard]] uint64_t GetModulesNum() const; [[nodiscard]] std::string GetDescription() const; [[nodiscard]] float GetPixelSize_mm() const; + [[nodiscard]] float GetSensorThickness_um() const; + [[nodiscard]] std::string GetSensorMaterial() const; [[nodiscard]] const std::vector &GetGainCalibration() const; [[nodiscard]] int64_t GetUDPInterfaceCount() const; }; diff --git a/common/DiffractionExperiment.cpp b/common/DiffractionExperiment.cpp index f185537c..6c57d068 100644 --- a/common/DiffractionExperiment.cpp +++ b/common/DiffractionExperiment.cpp @@ -257,16 +257,11 @@ DiffractionExperiment& DiffractionExperiment::QSpacingForRadialInt_recipA(float return *this; } -DiffractionExperiment &DiffractionExperiment::SetUnitCell(const UnitCell &cell) { +DiffractionExperiment &DiffractionExperiment::SetUnitCell(const std::optional &cell) { dataset.unit_cell = cell; return *this; } -DiffractionExperiment &DiffractionExperiment::SetUnitCell() { - dataset.unit_cell.reset(); - return *this; -} - DiffractionExperiment &DiffractionExperiment::PreviewPeriod(std::chrono::microseconds input) { check_min("Preview image generation period", input.count(), 0); preview_period = input; @@ -639,15 +634,8 @@ bool DiffractionExperiment::GetMaskChipEdges() const { return mask_chip_edges; } -UnitCell DiffractionExperiment::GetUnitCell() const { - if (dataset.unit_cell.has_value()) - return dataset.unit_cell.value(); - else - throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Cannot return empty unit cell"); -} - -bool DiffractionExperiment::HasUnitCell() const { - return dataset.unit_cell.has_value(); +std::optional DiffractionExperiment::GetUnitCell() const { + return dataset.unit_cell; } Coord DiffractionExperiment::LabCoord(float detector_x, float detector_y) const { @@ -697,7 +685,7 @@ std::string DiffractionExperiment::GetSampleName() const { return dataset.sample_name; } -void DiffractionExperiment::CheckDataProcessingSettings(const DataProcessingSettings &settings) { +void DiffractionExperiment::CheckDataProcessingSettings(const SpotFindingSettings &settings) { check_min("Signal to noise threshold", settings.signal_to_noise_threshold, 1); check_min("Photon count threshold", settings.photon_count_threshold, 0); check_min("Minimum pixels per spot", settings.min_pix_per_spot, 1); @@ -715,8 +703,8 @@ void DiffractionExperiment::CheckDataProcessingSettings(const DataProcessingSett } } -DataProcessingSettings DiffractionExperiment::DefaultDataProcessingSettings() { - DataProcessingSettings ret{}; +SpotFindingSettings DiffractionExperiment::DefaultDataProcessingSettings() { + SpotFindingSettings ret{}; ret.signal_to_noise_threshold = 3; ret.photon_count_threshold = 16; ret.min_pix_per_spot = 1; @@ -740,8 +728,8 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const { message.number_of_images = GetImageNum(); message.pixel_size_x = GetPixelSize_mm() * 1e-3f; message.pixel_size_y = GetPixelSize_mm() * 1e-3f; - message.sensor_material = SENSOR_MATERIAL; - message.sensor_thickness = SENSOR_THICKNESS_IN_UM * 1e-6f; + message.sensor_material = detector.GetSensorMaterial(); + message.sensor_thickness = detector.GetSensorThickness_um() * 1e-6f; message.compression_algorithm = GetCompressionAlgorithm(); message.compression_block_size = JFJochBitShuffleCompressor::DefaultBlockSize; message.pixel_bit_depth = GetPixelDepth() * 8; @@ -754,17 +742,9 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const { message.pixel_mask_enabled = GetApplyPixelMaskInFPGA(); message.detector_description = GetDetectorDescription(); message.space_group_number = GetSpaceGroupNumber(); - if (HasUnitCell()) { - auto uc = GetUnitCell(); - message.unit_cell[0] = uc.a; - message.unit_cell[1] = uc.b; - message.unit_cell[2] = uc.c; - message.unit_cell[3] = uc.alpha; - message.unit_cell[4] = uc.beta; - message.unit_cell[5] = uc.gamma; - } else { - message.unit_cell[0] = 0.0; - } + message.unit_cell = GetUnitCell(); + message.total_flux = GetTotalFlux(); + message.attenuator_transmission = GetAttenuatorTransmission(); message.detector_translation[0] = 0.0f; message.detector_translation[1] = 0.0f; @@ -975,3 +955,21 @@ float DiffractionExperiment::GetLowQForBkgEstimate_recipA() const { float DiffractionExperiment::GetHighQForBkgEstimate_recipA() const { return 2 * static_cast(M_PI) / 3.0; } + +DiffractionExperiment &DiffractionExperiment::AttenuatorTransmission(const std::optional &input) { + dataset.attenuator_transmission = input; + return *this; +} + +DiffractionExperiment &DiffractionExperiment::TotalFlux(const std::optional &input) { + dataset.total_flux = input; + return *this; +} + +std::optional DiffractionExperiment::GetAttenuatorTransmission() const { + return dataset.attenuator_transmission; +} + +std::optional DiffractionExperiment::GetTotalFlux() const { + return dataset.total_flux; +} diff --git a/common/DiffractionExperiment.h b/common/DiffractionExperiment.h index df30f7e7..219d33c7 100644 --- a/common/DiffractionExperiment.h +++ b/common/DiffractionExperiment.h @@ -14,7 +14,7 @@ #include "Definitions.h" #include "../frame_serialize/JFJochMessages.h" #include "DetectorSetup.h" -#include "../image_analysis/DataProcessingSettings.h" +#include "../image_analysis/SpotFindingSettings.h" enum class DetectorMode { Conversion, Raw, PedestalG0, PedestalG1, PedestalG2 @@ -110,6 +110,8 @@ class DiffractionExperiment { float rad_int_polarization_factor; bool save_calibration; + std::optional total_flux; + std::optional attenuator_transmission; } dataset; constexpr static const int64_t max_spot_count = 100; @@ -147,8 +149,7 @@ public: DiffractionExperiment& IPv4BaseAddr(std::string input); DiffractionExperiment& MaskModuleEdges(bool input); DiffractionExperiment& MaskChipEdges(bool input); - DiffractionExperiment& SetUnitCell(const UnitCell &cell); - DiffractionExperiment& SetUnitCell(); + DiffractionExperiment& SetUnitCell(const std::optional &cell); DiffractionExperiment& LowResForRadialInt_A(float input); DiffractionExperiment& HighResForRadialInt_A(float input); @@ -166,11 +167,13 @@ public: DiffractionExperiment& InstrumentName(std::string input); DiffractionExperiment& InstrumentNameShort(std::string input); DiffractionExperiment& ApplyPixelMaskInFPGA(bool input); + DiffractionExperiment& AttenuatorTransmission(const std::optional &input); + DiffractionExperiment& TotalFlux(const std::optional &input); void FillMessage(StartMessage &message) const; - static void CheckDataProcessingSettings(const DataProcessingSettings& settings); - static DataProcessingSettings DefaultDataProcessingSettings(); + static void CheckDataProcessingSettings(const SpotFindingSettings& settings); + static SpotFindingSettings DefaultDataProcessingSettings(); DetectorMode GetDetectorMode() const; int64_t GetPixelDepth() const; @@ -239,8 +242,7 @@ public: bool GetMaskModuleEdges() const; bool GetMaskChipEdges() const; - UnitCell GetUnitCell() const; - bool HasUnitCell() const; + std::optional GetUnitCell() const; Coord LabCoord(float detector_x, float detector_y) const; @@ -288,6 +290,8 @@ public: int64_t GetUDPInterfaceCount() const; std::vector GetDetectorModuleConfig(const std::vector& net_config) const; + std::optional GetAttenuatorTransmission() const; + std::optional GetTotalFlux() const; }; inline int64_t CalculateStride(const std::chrono::microseconds &frame_time, const std::chrono::microseconds &preview_time) { diff --git a/common/JFJochException.h b/common/JFJochException.h index d57f005a..91bb6706 100644 --- a/common/JFJochException.h +++ b/common/JFJochException.h @@ -3,6 +3,7 @@ #ifndef SLSEXCEPTION_H #define SLSEXCEPTION_H +#include #include #include @@ -18,6 +19,7 @@ HDF5, IBVerbs, RESTCommandUnknown, WrongDAQState, +WrongReceiverState, Detector, MemAllocFailed, AcquisitionDeviceError, @@ -44,6 +46,7 @@ CommunicationError }; class JFJochException : public std::exception { +protected: std::string msg; JFJochExceptionCategory category; static std::string DecodeCategory(JFJochExceptionCategory category) { @@ -121,9 +124,7 @@ class JFJochException : public std::exception { } } public: - JFJochException() = default; - - JFJochException(JFJochExceptionCategory in_val, const std::string &description, int optional = 0) noexcept : + JFJochException(JFJochExceptionCategory in_val, const std::string &description) noexcept : category(in_val) { try { msg = DecodeCategory(category) + " (" + description + ")"; @@ -142,4 +143,17 @@ public: } }; +class WrongDAQStateException : public JFJochException { +public: + explicit WrongDAQStateException(const std::string &description) + : JFJochException(JFJochExceptionCategory::WrongDAQState, description) {} +}; + +class PCIeDeviceException : public JFJochException { +public: + explicit PCIeDeviceException(const std::string &description) + : JFJochException(JFJochExceptionCategory::PCIeError, description) { + msg += " (" + std::string(strerror(errno)) + ")"; + } +}; #endif //SLSEXCEPTION_H diff --git a/fpga/host_library/JungfraujochDevice.cpp b/fpga/host_library/JungfraujochDevice.cpp index e83b4ada..aebdf522 100644 --- a/fpga/host_library/JungfraujochDevice.cpp +++ b/fpga/host_library/JungfraujochDevice.cpp @@ -30,50 +30,50 @@ JungfraujochDevice::~JungfraujochDevice() { void JungfraujochDevice::Start() { if (ioctl(fd, IOCTL_JFJOCH_START) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed starting action", errno); + throw PCIeDeviceException("Failed starting action"); } void JungfraujochDevice::Cancel() { if (ioctl(fd, IOCTL_JFJOCH_CANCEL) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed setting cancel bit", errno); + throw PCIeDeviceException("Failed setting cancel bit"); } void JungfraujochDevice::End() { if (ioctl(fd, IOCTL_JFJOCH_END) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed ending action", errno); + throw PCIeDeviceException("Failed ending action"); } bool JungfraujochDevice::IsIdle() const { uint32_t tmp; if (ioctl(fd, IOCTL_JFJOCH_ISIDLE, &tmp) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed checking if idle", errno); + throw PCIeDeviceException("Failed checking if idle"); return tmp; } DataCollectionStatus JungfraujochDevice::GetDataCollectionStatus() const { DataCollectionStatus ret{}; if (ioctl(fd, IOCTL_JFJOCH_STATUS, &ret) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed reading status", errno); + throw PCIeDeviceException("Failed reading status"); return ret; } DataCollectionConfig JungfraujochDevice::GetConfig() const { DataCollectionConfig ret{}; if (ioctl(fd, IOCTL_JFJOCH_READ_CONFIG, &ret) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed reading config", errno); + throw PCIeDeviceException("Failed reading config"); return ret; } DeviceStatus JungfraujochDevice::GetDeviceStatus() const { DeviceStatus ret{}; if (ioctl(fd, IOCTL_JFJOCH_GET_DEV_STATUS, &ret) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed reading env. data", errno); + throw PCIeDeviceException("Failed reading env. data"); return ret; } void JungfraujochDevice::ClearNetworkCounters() { if (ioctl(fd, IOCTL_JFJOCH_CLR_CNTRS) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed clearing network counters", errno); + throw PCIeDeviceException("Failed clearing network counters"); } void JungfraujochDevice::Reset() { @@ -83,20 +83,20 @@ void JungfraujochDevice::Reset() { uint32_t JungfraujochDevice::GetNumaNode() const { int32_t tmp; if (ioctl(fd, IOCTL_JFJOCH_NUMA, &tmp) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed reading NUMA node", errno); + throw PCIeDeviceException("Failed reading NUMA node"); return tmp; } uint32_t JungfraujochDevice::GetCompletedDescriptors() const { uint32_t ret = 0; if (ioctl(fd, IOCTL_JFJOCH_C2H_DMA_DESC, &ret) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed geting C2H completed descriptor count", errno); + throw PCIeDeviceException("Failed geting C2H completed descriptor count"); return ret; } void JungfraujochDevice::SetConfig(const DataCollectionConfig &config) { if (ioctl(fd, IOCTL_JFJOCH_SET_CONFIG, &config) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed writing config", errno); + throw PCIeDeviceException("Failed writing config"); } bool JungfraujochDevice::ReadWorkCompletion(uint32_t output[16]) { @@ -104,7 +104,7 @@ bool JungfraujochDevice::ReadWorkCompletion(uint32_t output[16]) { if (tmp != 0) { if (errno == EAGAIN) return false; - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed receiving work completion", errno); + throw PCIeDeviceException("Failed receiving work completion"); } return true; } @@ -114,7 +114,7 @@ bool JungfraujochDevice::SendWorkRequest(uint32_t id) { if (tmp != 0) { if (errno == EAGAIN) return false; - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed sending work request", errno); + throw PCIeDeviceException("Failed sending work request"); } return true; } @@ -122,55 +122,55 @@ bool JungfraujochDevice::SendWorkRequest(uint32_t id) { uint32_t JungfraujochDevice::GetBufferCount() const { uint32_t tmp; if (ioctl(fd, IOCTL_JFJOCH_BUF_COUNT, &tmp) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed getting buffer count", errno); + throw PCIeDeviceException("Failed getting buffer count"); return tmp; } void JungfraujochDevice::SetMACAddress(uint64_t addr) { if (ioctl(fd, IOCTL_JFJOCH_SET_MAC, &addr) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed setting MAC address", errno); + throw PCIeDeviceException("Failed setting MAC address"); } uint64_t JungfraujochDevice::GetMACAddress() const { uint64_t tmp; if (ioctl(fd, IOCTL_JFJOCH_GET_MAC, &tmp) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed getting MAC address", errno); + throw PCIeDeviceException("Failed getting MAC address"); return tmp; } void JungfraujochDevice::SetDefaultMACAddress() { if (ioctl(fd, IOCTL_JFJOCH_DEFAULT_MAC) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed setting default MAC", errno); + throw PCIeDeviceException("Failed setting default MAC"); } uint32_t JungfraujochDevice::GetIPv4Address() const { uint32_t tmp; if (ioctl(fd, IOCTL_JFJOCH_GET_IPV4, &tmp) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed getting IPv4 address", errno); + throw PCIeDeviceException("Failed getting IPv4 address"); return tmp; } void JungfraujochDevice::SetIPv4Address(uint32_t input) { if (ioctl(fd, IOCTL_JFJOCH_SET_IPV4, &input) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed setting IPv4 address", errno); + throw PCIeDeviceException("Failed setting IPv4 address"); } void JungfraujochDevice::RunFrameGenerator(const FrameGeneratorConfig &config) { if (ioctl(fd, IOCTL_JFJOCH_RUN_FRAME_GEN, &config) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed starting frame generator", errno); + throw PCIeDeviceException("Failed starting frame generator"); } void JungfraujochDevice::WriteRegister(uint32_t addr, uint32_t val) { RegisterConfig config{.addr = addr, .val = val}; if (ioctl(fd, IOCTL_JFJOCH_WRITE_REGISTER, &config) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed writing to register", errno); + throw PCIeDeviceException("Failed writing to register"); } uint32_t JungfraujochDevice::ReadRegister(uint32_t addr) const { RegisterConfig config; config.addr = addr; if (ioctl(fd, IOCTL_JFJOCH_READ_REGISTER, &config) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed reading register", errno); + throw PCIeDeviceException("Failed reading register"); return config.val; } @@ -180,7 +180,7 @@ void JungfraujochDevice::LoadCalibration(uint32_t modules, uint32_t storage_cell .nstorage_cells = storage_cells }; if (ioctl(fd, IOCTL_JFJOCH_LOAD_CALIB, &config) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed uploading calibration", errno); + throw PCIeDeviceException("Failed uploading calibration"); } void JungfraujochDevice::LoadInternalGeneratorFrame(uint32_t modules) { @@ -188,7 +188,7 @@ void JungfraujochDevice::LoadInternalGeneratorFrame(uint32_t modules) { .nmodules = modules }; if (ioctl(fd, IOCTL_JFJOCH_LOAD_INT_GEN, &config) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed uploading internal generator frame", errno); + throw PCIeDeviceException("Failed uploading internal generator frame"); } void JungfraujochDevice::LoadIntegrationMap(uint32_t modules) { @@ -196,7 +196,7 @@ void JungfraujochDevice::LoadIntegrationMap(uint32_t modules) { .nmodules = modules, }; if (ioctl(fd, IOCTL_JFJOCH_LOAD_INT_MAP, &config) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed uploading integration map", errno); + throw PCIeDeviceException("Failed uploading integration map"); } uint16_t *JungfraujochDevice::MapKernelBuffer(uint32_t id) { @@ -205,27 +205,27 @@ uint16_t *JungfraujochDevice::MapKernelBuffer(uint32_t id) { fd, FPGA_BUFFER_LOCATION_SIZE * id); if (tmp == nullptr) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Mmap of kernel buffer error", errno); + throw PCIeDeviceException("Mmap of kernel buffer error"); return tmp; } void JungfraujochDevice::SetSpotFinderParameters(const SpotFinderParameters& params) { if (ioctl(fd, IOCTL_JFJOCH_SPOT_FINDER_PAR, ¶ms) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed settings spot finder parameters", errno); + throw PCIeDeviceException("Failed settings spot finder parameters"); } uint32_t JungfraujochDevice::GetDataSource() { uint32_t tmp; if (ioctl(fd, IOCTL_JFJOCH_GET_DATA_SOURCE, &tmp) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed getting data source", errno); + throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed getting data source"); return tmp; } void JungfraujochDevice::SetDataSource(uint32_t id) { if (id >= 4) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Data source is 2-bit variable", errno); + throw JFJochException(JFJochExceptionCategory::PCIeError, "Data source is 2-bit variable"); if (ioctl(fd, IOCTL_JFJOCH_SET_DATA_SOURCE, &id) != 0) - throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed setting data source", errno); + throw JFJochException(JFJochExceptionCategory::PCIeError, "Failed setting data source"); } \ No newline at end of file diff --git a/frame_serialize/CBORStream2Deserializer.cpp b/frame_serialize/CBORStream2Deserializer.cpp index 70f01b0a..3c9a16de 100644 --- a/frame_serialize/CBORStream2Deserializer.cpp +++ b/frame_serialize/CBORStream2Deserializer.cpp @@ -507,27 +507,31 @@ void CBORStream2Deserializer::ProcessChannels(CborValue &value) { } void CBORStream2Deserializer::ProcessUnitCellElement(CborValue &value) { + UnitCell unit_cell{}; + CborValue map_value; cborErr(cbor_value_enter_container(&value, &map_value)); while (! cbor_value_at_end(&map_value)) { auto key = GetCBORString(map_value); if (key == "a") - start_message.unit_cell[0] = GetCBORFloat(map_value); + unit_cell.a = GetCBORFloat(map_value); else if (key == "b") - start_message.unit_cell[1] = GetCBORFloat(map_value); + unit_cell.b = GetCBORFloat(map_value); else if (key == "c") - start_message.unit_cell[2] = GetCBORFloat(map_value); + unit_cell.c = GetCBORFloat(map_value); else if (key == "alpha") - start_message.unit_cell[3] = GetCBORFloat(map_value); + unit_cell.alpha = GetCBORFloat(map_value); else if (key == "beta") - start_message.unit_cell[4] = GetCBORFloat(map_value); + unit_cell.beta = GetCBORFloat(map_value); else if (key == "gamma") - start_message.unit_cell[5] = GetCBORFloat(map_value); + unit_cell.gamma = GetCBORFloat(map_value); else cbor_value_advance(&map_value); } cborErr(cbor_value_leave_container(&value, &map_value)); + + start_message.unit_cell = unit_cell; } void CBORStream2Deserializer::ProcessStartMessageUserDataElement(CborValue &value) { @@ -580,6 +584,10 @@ void CBORStream2Deserializer::ProcessStartMessageUserDataElement(CborValue &valu start_message.storage_cell_number = GetCBORUInt(map_value); else if (key == "storage_cell_delay") start_message.storage_cell_delay_ns = GetRational(map_value).first; + else if (key == "total_flux") + start_message.total_flux = GetCBORFloat(map_value); + else if (key == "attenuator_transmission") + start_message.attenuator_transmission = GetCBORFloat(map_value); else if (key == "compression_algorithm") { auto tmp = GetCBORString(map_value); if (tmp == "bslz4") diff --git a/frame_serialize/CBORStream2Serializer.cpp b/frame_serialize/CBORStream2Serializer.cpp index c0730d7e..07a8b318 100644 --- a/frame_serialize/CBORStream2Serializer.cpp +++ b/frame_serialize/CBORStream2Serializer.cpp @@ -236,17 +236,17 @@ inline void CBOR_ENC_CHANNELS(CborEncoder &encoder, const char* key, const std:: cborErr(cbor_encoder_close_container(&encoder, &arrayEncoder)); } -inline void CBOR_ENC_UNIT_CELL(CborEncoder &encoder, const char* key, const float val[6]) { +inline void CBOR_ENC_UNIT_CELL(CborEncoder &encoder, const char* key, const UnitCell &val) { CborEncoder mapEncoder; cborErr(cbor_encode_text_stringz(&encoder, key)); cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 6)); - CBOR_ENC(mapEncoder, "a", val[0]); - CBOR_ENC(mapEncoder, "b", val[1]); - CBOR_ENC(mapEncoder, "c", val[2]); - CBOR_ENC(mapEncoder, "alpha", val[3]); - CBOR_ENC(mapEncoder, "beta", val[4]); - CBOR_ENC(mapEncoder, "gamma", val[5]); + CBOR_ENC(mapEncoder, "a", val.a); + CBOR_ENC(mapEncoder, "b", val.b); + CBOR_ENC(mapEncoder, "c", val.c); + CBOR_ENC(mapEncoder, "alpha", val.alpha); + CBOR_ENC(mapEncoder, "beta", val.beta); + CBOR_ENC(mapEncoder, "gamma", val.gamma); cborErr(cbor_encoder_close_container(&encoder, &mapEncoder)); } @@ -264,7 +264,7 @@ inline void CBOR_ENC_USER_DATA(CborEncoder &encoder, const StartMessage& message CborEncoder mapEncoder; cborErr(cbor_encode_text_stringz(&encoder, "user_data")); - cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, 23)); + cborErr(cbor_encoder_create_map(&encoder, &mapEncoder, CborIndefiniteLength)); CBOR_ENC(mapEncoder, "magic_number", user_data_magic_number); CBOR_ENC(mapEncoder, "file_prefix", message.file_prefix); @@ -292,7 +292,13 @@ inline void CBOR_ENC_USER_DATA(CborEncoder &encoder, const StartMessage& message } CBOR_ENC(mapEncoder, "compression_block_size", message.compression_block_size); - CBOR_ENC_UNIT_CELL(mapEncoder, "unit_cell", message.unit_cell); + if (message.unit_cell) + CBOR_ENC_UNIT_CELL(mapEncoder, "unit_cell", message.unit_cell.value()); + + if (message.attenuator_transmission) + CBOR_ENC(mapEncoder, "attenuator_transmission", message.attenuator_transmission.value()); + if (message.total_flux) + CBOR_ENC(mapEncoder, "total_flux", message.total_flux.value()); CBOR_ENC(mapEncoder, "source_name", message.source_name); CBOR_ENC(mapEncoder, "source_name_short", message.source_name_short); diff --git a/frame_serialize/CborErr.h b/frame_serialize/CborErr.h index d91ebf8f..2d4b82be 100644 --- a/frame_serialize/CborErr.h +++ b/frame_serialize/CborErr.h @@ -8,7 +8,7 @@ inline void cborErr(CborError err) { if (err != CborNoError) - throw JFJochException(JFJochExceptionCategory::CBORError, cbor_error_string(err), err); + throw JFJochException(JFJochExceptionCategory::CBORError, cbor_error_string(err)); } #endif //JUNGFRAUJOCH_CBORERR_H diff --git a/frame_serialize/JFJochMessages.h b/frame_serialize/JFJochMessages.h index b5fd9f1a..87bff4f2 100644 --- a/frame_serialize/JFJochMessages.h +++ b/frame_serialize/JFJochMessages.h @@ -7,8 +7,10 @@ #include #include #include +#include #include "../compression/CompressionAlgorithmEnum.h" #include "../common/SpotToSave.h" +#include "../common/UnitCell.h" constexpr const uint64_t user_data_release = 1; constexpr const uint64_t user_data_magic_number = 0x52320000UL | user_data_release; @@ -86,7 +88,7 @@ struct StartMessage { CompressionAlgorithm compression_algorithm; // user data uint64_t compression_block_size; // user data - float unit_cell[6]; // user data + std::optional unit_cell; // user data uint64_t space_group_number; // user data uint64_t max_spot_count; // user data @@ -124,6 +126,9 @@ struct StartMessage { std::vector pixel_mask; std::vector calibration; + std::optional total_flux; + std::optional attenuator_transmission; + size_t approx_size = 1024*1024; // Use function below to update approx_size diff --git a/frontend_ui/README.md b/frontend_ui/README.md index 54ef0943..a15e707a 100644 --- a/frontend_ui/README.md +++ b/frontend_ui/README.md @@ -1,4 +1,14 @@ -This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). +# Jungfraujoch Frontend + +## Building + +To build web interface: +``` +cd frontend_ui +npm install +npm run openapi +npm run build +``` ## Available Scripts @@ -27,6 +37,10 @@ Your app is ready to be deployed! See the section about [deployment](https://facebook.github.io/create-react-app/docs/deployment) for more information. +### `npm run openapi` + +Generate OpenAPI definitions. + ### `npm run eject` **Note: this is a one-way operation. Once you `eject`, you can’t go back!** diff --git a/frontend_ui/package-lock.json b/frontend_ui/package-lock.json index edeab264..177871bc 100644 --- a/frontend_ui/package-lock.json +++ b/frontend_ui/package-lock.json @@ -24,6 +24,9 @@ "react-plotly.js": "^2.6.0", "react-scripts": "^5.0.1", "typescript": "^4.9.4" + }, + "devDependencies": { + "openapi-typescript-codegen": "^0.25.0" } }, "node_modules/@ampproject/remapping": { @@ -38,6 +41,36 @@ "node": ">=6.0.0" } }, + "node_modules/@apidevtools/json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", + "dev": true, + "dependencies": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + } + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "node_modules/@apidevtools/json-schema-ref-parser/node_modules/js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "dependencies": { + "argparse": "^2.0.1" + }, + "bin": { + "js-yaml": "bin/js-yaml.js" + } + }, "node_modules/@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -3091,6 +3124,12 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "node_modules/@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, "node_modules/@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -5856,6 +5895,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -5904,9 +5949,9 @@ } }, "node_modules/caniuse-lite": { - "version": "1.0.30001436", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001436.tgz", - "integrity": "sha512-ZmWkKsnC2ifEPoWUvSAIGyOYwT+keAaaWPHiQ9DfMqS1t6tfuyFYoWR78TeZtznkEQ64+vGXH9cZrElwR2Mrxg==", + "version": "1.0.30001568", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001568.tgz", + "integrity": "sha512-vSUkH84HontZJ88MiNrOau1EBrCqEQYgkC5gIySiDlpsm8sGVrhU7Kx4V6h0tnqaHzIHZv08HlJIwPbL4XL9+A==", "funding": [ { "type": "opencollective", @@ -5915,6 +5960,10 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ] }, @@ -9574,6 +9623,36 @@ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, + "node_modules/handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "dependencies": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "wordwrap": "^1.0.0" + }, + "bin": { + "handlebars": "bin/handlebars" + }, + "engines": { + "node": ">=0.4.7" + }, + "optionalDependencies": { + "uglify-js": "^3.1.4" + } + }, + "node_modules/handlebars/node_modules/source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/harmony-reflect": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", @@ -12649,6 +12728,19 @@ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, + "node_modules/json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q==", + "deprecated": "Please switch to @apidevtools/json-schema-ref-parser", + "dev": true, + "dependencies": { + "@apidevtools/json-schema-ref-parser": "9.0.9" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -13569,6 +13661,45 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/openapi-typescript-codegen": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/openapi-typescript-codegen/-/openapi-typescript-codegen-0.25.0.tgz", + "integrity": "sha512-nN/TnIcGbP58qYgwEEy5FrAAjePcYgfMaCe3tsmYyTgI3v4RR9v8os14L+LEWDvV50+CmqiyTzRkKKtJeb6Ybg==", + "dev": true, + "dependencies": { + "camelcase": "^6.3.0", + "commander": "^11.0.0", + "fs-extra": "^11.1.1", + "handlebars": "^4.7.7", + "json-schema-ref-parser": "^9.0.9" + }, + "bin": { + "openapi": "bin/index.js" + } + }, + "node_modules/openapi-typescript-codegen/node_modules/commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true, + "engines": { + "node": ">=16" + } + }, + "node_modules/openapi-typescript-codegen/node_modules/fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=14.14" + } + }, "node_modules/optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -17723,6 +17854,19 @@ "node": ">=4.2.0" } }, + "node_modules/uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true, + "bin": { + "uglifyjs": "bin/uglifyjs" + }, + "engines": { + "node": ">=0.8.0" + } + }, "node_modules/unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -18536,6 +18680,12 @@ "node": ">=0.10.0" } }, + "node_modules/wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, "node_modules/workbox-background-sync": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", @@ -19006,6 +19156,35 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@apidevtools/json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/@apidevtools/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-GBD2Le9w2+lVFoc4vswGI/TjkNIZSVp7+9xPf+X3uidBfWnAeUWmquteSyt0+VCrhNMWj/FTABISQrD3Z/YA+w==", + "dev": true, + "requires": { + "@jsdevtools/ono": "^7.1.3", + "@types/json-schema": "^7.0.6", + "call-me-maybe": "^1.0.1", + "js-yaml": "^4.1.0" + }, + "dependencies": { + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "js-yaml": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz", + "integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + } + } + }, "@babel/code-frame": { "version": "7.18.6", "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", @@ -21067,6 +21246,12 @@ "@jridgewell/sourcemap-codec": "1.4.14" } }, + "@jsdevtools/ono": { + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/@jsdevtools/ono/-/ono-7.1.3.tgz", + "integrity": "sha512-4JQNk+3mVzK3xh2rqd6RB4J46qUR19azEHBneZyTZM+c456qOrbbM/5xcR8huNCCcbVt7+UmizG6GuUvPvKUYg==", + "dev": true + }, "@leichtgewicht/ip-codec": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz", @@ -23078,6 +23263,12 @@ "get-intrinsic": "^1.0.2" } }, + "call-me-maybe": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/call-me-maybe/-/call-me-maybe-1.0.2.tgz", + "integrity": "sha512-HpX65o1Hnr9HH25ojC1YGs7HCQLq0GCOibSaWER0eNpgJ/Z1MZv2mTc7+xh6WOPxbRVcmgbv4hGU+uSQ/2xFZQ==", + "dev": true + }, "callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -23114,9 +23305,9 @@ } }, "caniuse-lite": { - "version": "1.0.30001436", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001436.tgz", - "integrity": "sha512-ZmWkKsnC2ifEPoWUvSAIGyOYwT+keAaaWPHiQ9DfMqS1t6tfuyFYoWR78TeZtznkEQ64+vGXH9cZrElwR2Mrxg==" + "version": "1.0.30001568", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001568.tgz", + "integrity": "sha512-vSUkH84HontZJ88MiNrOau1EBrCqEQYgkC5gIySiDlpsm8sGVrhU7Kx4V6h0tnqaHzIHZv08HlJIwPbL4XL9+A==" }, "canvas-fit": { "version": "1.5.0", @@ -25946,6 +26137,27 @@ "resolved": "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz", "integrity": "sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg==" }, + "handlebars": { + "version": "4.7.8", + "resolved": "https://registry.npmjs.org/handlebars/-/handlebars-4.7.8.tgz", + "integrity": "sha512-vafaFqs8MZkRrSX7sFVUdo3ap/eNiLnb4IakshzvP56X5Nr1iGKAIqdX6tMlm6HcNRIkr6AxO5jFEoJzzpT8aQ==", + "dev": true, + "requires": { + "minimist": "^1.2.5", + "neo-async": "^2.6.2", + "source-map": "^0.6.1", + "uglify-js": "^3.1.4", + "wordwrap": "^1.0.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + } + } + }, "harmony-reflect": { "version": "1.6.2", "resolved": "https://registry.npmjs.org/harmony-reflect/-/harmony-reflect-1.6.2.tgz", @@ -28148,6 +28360,15 @@ "resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.4.0.tgz", "integrity": "sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==" }, + "json-schema-ref-parser": { + "version": "9.0.9", + "resolved": "https://registry.npmjs.org/json-schema-ref-parser/-/json-schema-ref-parser-9.0.9.tgz", + "integrity": "sha512-qcP2lmGy+JUoQJ4DOQeLaZDqH9qSkeGCK3suKWxJXS82dg728Mn3j97azDMaOUmJAN4uCq91LdPx4K7E8F1a7Q==", + "dev": true, + "requires": { + "@apidevtools/json-schema-ref-parser": "9.0.9" + } + }, "json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", @@ -28846,6 +29067,38 @@ "is-wsl": "^2.2.0" } }, + "openapi-typescript-codegen": { + "version": "0.25.0", + "resolved": "https://registry.npmjs.org/openapi-typescript-codegen/-/openapi-typescript-codegen-0.25.0.tgz", + "integrity": "sha512-nN/TnIcGbP58qYgwEEy5FrAAjePcYgfMaCe3tsmYyTgI3v4RR9v8os14L+LEWDvV50+CmqiyTzRkKKtJeb6Ybg==", + "dev": true, + "requires": { + "camelcase": "^6.3.0", + "commander": "^11.0.0", + "fs-extra": "^11.1.1", + "handlebars": "^4.7.7", + "json-schema-ref-parser": "^9.0.9" + }, + "dependencies": { + "commander": { + "version": "11.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-11.1.0.tgz", + "integrity": "sha512-yPVavfyCcRhmorC7rWlkHn15b4wDVgVmBA7kV4QVBsF7kv/9TKJAbAXVTxvTnwP8HHKjRCJDClKbciiYS7p0DQ==", + "dev": true + }, + "fs-extra": { + "version": "11.2.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz", + "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + } + } + } + }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -31818,6 +32071,13 @@ "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.4.tgz", "integrity": "sha512-Uz+dTXYzxXXbsFpM86Wh3dKCxrQqUcVMxwU54orwlJjOpO3ao8L7j5lH+dWfTwgCwIuM9GQ2kvVotzYJMXTBZg==" }, + "uglify-js": { + "version": "3.17.4", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.17.4.tgz", + "integrity": "sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==", + "dev": true, + "optional": true + }, "unbox-primitive": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", @@ -32437,6 +32697,12 @@ "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.3.tgz", "integrity": "sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==" }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==", + "dev": true + }, "workbox-background-sync": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/workbox-background-sync/-/workbox-background-sync-6.5.4.tgz", diff --git a/frontend_ui/package.json b/frontend_ui/package.json index 0e866d20..f88fde0d 100644 --- a/frontend_ui/package.json +++ b/frontend_ui/package.json @@ -25,7 +25,8 @@ "start": "PORT=8000 react-scripts start", "build": "react-scripts build", "test": "react-scripts test", - "eject": "react-scripts eject" + "eject": "react-scripts eject", + "openapi": "openapi --input ../broker/jfjoch_api.yaml --output ./src/openapi" }, "eslintConfig": { "extends": "react-app" @@ -41,5 +42,8 @@ "last 1 firefox version", "last 1 safari version" ] + }, + "devDependencies": { + "openapi-typescript-codegen": "^0.25.0" } } diff --git a/frontend_ui/src/components/BkgEstimatePlot.tsx b/frontend_ui/src/components/BkgEstimatePlot.tsx index db4e459c..9f9781ba 100644 --- a/frontend_ui/src/components/BkgEstimatePlot.tsx +++ b/frontend_ui/src/components/BkgEstimatePlot.tsx @@ -1,13 +1,6 @@ -/* - * Copyright (2019-2023) Paul Scherrer Institute - * - */ - import Paper from "@mui/material/Paper"; -import DataProcessingPlot from "./DataProcessingPlot"; +import DataProcessingPlot, {PlotType} from "./DataProcessingPlot"; import React, {Component} from "react"; -import {handleErrors} from "./handleErrors"; -import PlotWrapper from "./PlotWrapper"; import {Box} from "@mui/material"; type MyProps = { @@ -30,7 +23,7 @@ class BkgEstimatePlot extends Component {
Background estimate
-
diff --git a/frontend_ui/src/components/Calibration.tsx b/frontend_ui/src/components/Calibration.tsx index c4b59023..3ce8e014 100644 --- a/frontend_ui/src/components/Calibration.tsx +++ b/frontend_ui/src/components/Calibration.tsx @@ -1,30 +1,16 @@ -import React, {Component} from 'react'; +import React from 'react'; import Paper from '@mui/material/Paper'; import {DataGrid} from "@mui/x-data-grid"; -import {handleErrors} from "./handleErrors"; +import {calibration_statistics, DefaultService} from "../openapi"; type MyProps = { addr: string; }; -type CalibInfo = { - moduleNumber: number | string, - storageCellNumber: number | string, - pedestalG0Mean: number, - pedestalG1Mean: number, - pedestalG2Mean: number, - gainG0Mean: number, - gainG1Mean: number, - gainG2Mean: number, - maskedPixels: number | string -}; - type MyState = { - calib: { - moduleStatistics: CalibInfo[] | undefined - }; + calib: calibration_statistics | undefined; connection_error: boolean; }; @@ -38,104 +24,101 @@ class Calibration extends React.Component { } state : MyState = { - calib: {moduleStatistics: [ - { - moduleNumber: 0, - storageCellNumber: 0, - pedestalG0Mean: 3500, - pedestalG1Mean: 14000, - pedestalG2Mean: 15000, - gainG0Mean: 30, - gainG1Mean: 11, - gainG2Mean: 10, - maskedPixels: 80 - }, - { - moduleNumber: 1, - storageCellNumber: 0, - pedestalG0Mean: 3500, - pedestalG1Mean: 14000, - pedestalG2Mean: 15000, - gainG0Mean: 30, - gainG1Mean: 11, - gainG2Mean: 10, - maskedPixels: 80 - }, - { - moduleNumber: 2, - storageCellNumber: 0, - pedestalG0Mean: 3500, - pedestalG1Mean: 14000, - pedestalG2Mean: 15000, - gainG0Mean: 30, - gainG1Mean: 11, - gainG2Mean: 10, - maskedPixels: 80 - }, - { - moduleNumber: 3, - storageCellNumber: 0, - pedestalG0Mean: 3500, - pedestalG1Mean: 14000, - pedestalG2Mean: 15000, - gainG0Mean: 30, - gainG1Mean: 11, - gainG2Mean: 10, - maskedPixels: 80 - }, - { - moduleNumber: 4, - storageCellNumber: 0, - pedestalG0Mean: 3500, - pedestalG1Mean: 14000, - pedestalG2Mean: 15000, - gainG0Mean: 30, - gainG1Mean: 11, - gainG2Mean: 10, - maskedPixels: 80 - }, - { - moduleNumber: 5, - storageCellNumber: 0, - pedestalG0Mean: 3500, - pedestalG1Mean: 14000, - pedestalG2Mean: 15000, - gainG0Mean: 30, - gainG1Mean: 11, - gainG2Mean: 10, - maskedPixels: 80 - }, - { - moduleNumber: 6, - storageCellNumber: 0, - pedestalG0Mean: 3500, - pedestalG1Mean: 14000, - pedestalG2Mean: 15000, - gainG0Mean: 30, - gainG1Mean: 11, - gainG2Mean: 10, - maskedPixels: 80 - }, - { - moduleNumber: 7, - storageCellNumber: 0, - pedestalG0Mean: 3500, - pedestalG1Mean: 14000, - pedestalG2Mean: 15000, - gainG0Mean: 30, - gainG1Mean: 11, - gainG2Mean: 10, - maskedPixels: 80 - } - ], - }, + calib: [ + { + module_number: 0, + storage_cell_number: 0, + pedestal_g0_mean: 3500, + pedestal_g1_mean: 14000, + pedestal_g2_mean: 15000, + gain_g0_mean: 30, + gain_g1_mean: 11, + gain_g2_mean: 10, + masked_pixels: 80 + }, + { + module_number: 1, + storage_cell_number: 0, + pedestal_g0_mean: 3500, + pedestal_g1_mean: 14000, + pedestal_g2_mean: 15000, + gain_g0_mean: 30, + gain_g1_mean: 11, + gain_g2_mean: 10, + masked_pixels: 80 + }, + { + module_number: 2, + storage_cell_number: 0, + pedestal_g0_mean: 3500, + pedestal_g1_mean: 14000, + pedestal_g2_mean: 15000, + gain_g0_mean: 30, + gain_g1_mean: 11, + gain_g2_mean: 10, + masked_pixels: 80 + }, + { + module_number: 3, + storage_cell_number: 0, + pedestal_g0_mean: 3500, + pedestal_g1_mean: 14000, + pedestal_g2_mean: 15000, + gain_g0_mean: 30, + gain_g1_mean: 11, + gain_g2_mean: 10, + masked_pixels: 80 + }, + { + module_number: 4, + storage_cell_number: 0, + pedestal_g0_mean: 3500, + pedestal_g1_mean: 14000, + pedestal_g2_mean: 15000, + gain_g0_mean: 30, + gain_g1_mean: 11, + gain_g2_mean: 10, + masked_pixels: 80 + }, + { + module_number: 5, + storage_cell_number: 0, + pedestal_g0_mean: 3500, + pedestal_g1_mean: 14000, + pedestal_g2_mean: 15000, + gain_g0_mean: 30, + gain_g1_mean: 11, + gain_g2_mean: 10, + masked_pixels: 80 + }, + { + module_number: 6, + storage_cell_number: 0, + pedestal_g0_mean: 3500, + pedestal_g1_mean: 14000, + pedestal_g2_mean: 15000, + gain_g0_mean: 30, + gain_g1_mean: 11, + gain_g2_mean: 10, + masked_pixels: 80 + }, + { + module_number: 7, + storage_cell_number: 0, + pedestal_g0_mean: 3500, + pedestal_g1_mean: 14000, + pedestal_g2_mean: 15000, + gain_g0_mean: 30, + gain_g1_mean: 11, + gain_g2_mean: 10, + masked_pixels: 80 + } + ], connection_error : true } getValues() { - fetch(this.addr + 'detector/calibration') - .then(handleErrors) - .then(res => res.json()) + DefaultService.getStatisticsCalibration() .then(data => this.setState({calib: data, connection_error: false})) .catch(error => { console.log(error); @@ -152,23 +135,23 @@ class Calibration extends React.Component { } columns = [ - { field: 'moduleNumber', type: 'number', headerName: 'Module' }, - { field: 'storageCellNumber', type: 'number', headerName: 'SC'}, - { field: 'maskedPixels', headerName: 'Masked pxls', type: 'number'}, - { field: 'pedestalG0Mean', headerName: 'Pedestal G0', type: 'number'}, - { field: 'pedestalG1Mean', headerName: 'Pedestal G1', type: 'number'}, - { field: 'pedestalG2Mean', headerName: 'Pedestal G2', type: 'number'}, - { field: 'gainG0Mean', headerName: 'Gain G0', type: 'number'}, - { field: 'gainG1Mean', headerName: 'Gain G1', type: 'number'}, - { field: 'gainG2Mean', headerName: 'Gain G2', type: 'number'} + { field: 'module_number', type: 'number', headerName: 'Module' }, + { field: 'storage_cell_number', type: 'number', headerName: 'SC'}, + { field: 'masked_pixels', headerName: 'Masked pxls', type: 'number'}, + { field: 'pedestal_g0_mean', headerName: 'Pedestal G0', type: 'number'}, + { field: 'pedestal_g1_mean', headerName: 'Pedestal G1', type: 'number'}, + { field: 'pedestal_g2_mean', headerName: 'Pedestal G2', type: 'number'}, + { field: 'gain_g0_mean', headerName: 'Gain G0', type: 'number'}, + { field: 'gain_g1_mean', headerName: 'Gain G1', type: 'number'}, + { field: 'gain_g2_mean', headerName: 'Gain G2', type: 'number'} ]; render() { return - {this.state.calib.moduleStatistics !== undefined ? + {(!this.state.connection_error && Array.isArray(this.state.calib) && !this.state.calib.length) ? Number(row.moduleNumber) * 64 + Number(row.storageCellNumber)} - rows={this.state.calib.moduleStatistics} + getRowId={(row) => Number(row.module_number) * 64 + Number(row.storage_cell_number)} + rows={this.state.calib} columns={this.columns} pageSize={8} rowsPerPageOptions={[8]} diff --git a/frontend_ui/src/components/DataProcessingPlot.tsx b/frontend_ui/src/components/DataProcessingPlot.tsx index 69ce01b2..bc271891 100644 --- a/frontend_ui/src/components/DataProcessingPlot.tsx +++ b/frontend_ui/src/components/DataProcessingPlot.tsx @@ -1,23 +1,28 @@ import React, {Component} from 'react'; import PlotWrapper from "./PlotWrapper"; -import {handleErrors} from "./handleErrors"; +import {DefaultService, plot} from "../openapi"; + +export enum PlotType { + ADU_HISTOGRAM, + SPOT_COUNT, + RAD_INT, + INDEXING_RATE_PER_FILE, + INDEXING_RATE, + RAD_INT_PER_FILE, + BKG_ESTIMATE +} type MyProps = { addr: string; - type: string; + type: PlotType; xlabel: string; ylabel: string; binning: number; }; -type Plot = { - x: number[], - y: number[] -} - type MyState = { - plot : Plot, + plot : plot, connection_error: boolean } @@ -39,16 +44,56 @@ class DataProcessingPlot extends Component { } getValues() { - fetch(this.addr + 'data_processing/plots', { - method: "POST", - body: JSON.stringify({type: this.props.type, binning: this.props.binning}) - }).then(handleErrors) - .then(res => res.json()) - .then(data => this.setState({plot: data, connection_error: false})) - .catch(error => { - console.log(error); - this.setState({connection_error: true}); - }); + switch(this.props.type) { + case PlotType.ADU_HISTOGRAM: + DefaultService.getPlotAduHistogram() + .then(data => this.setState({plot: data, connection_error: false})) + .catch(error => { + console.log(error); + this.setState({connection_error: true}); + }); + break; + case PlotType.SPOT_COUNT: + DefaultService.postPlotSpotCount({binning: this.props.binning}) + .then(data => this.setState({plot: data, connection_error: false})) + .catch(error => { + console.log(error); + this.setState({connection_error: true}); + }); + break; + case PlotType.BKG_ESTIMATE: + DefaultService.postPlotBkgEstimate({binning: this.props.binning}) + .then(data => this.setState({plot: data, connection_error: false})) + .catch(error => { + console.log(error); + this.setState({connection_error: true}); + }); + break; + case PlotType.RAD_INT: + DefaultService.getPlotRadInt() + .then(data => this.setState({plot: data, connection_error: false})) + .catch(error => { + console.log(error); + this.setState({connection_error: true}); + }); + break; + case PlotType.INDEXING_RATE_PER_FILE: + DefaultService.getPlotIndexingRatePerFile() + .then(data => this.setState({plot: data, connection_error: false})) + .catch(error => { + console.log(error); + this.setState({connection_error: true}); + }); + break; + case PlotType.INDEXING_RATE: + DefaultService.postPlotIndexingRate({binning: this.props.binning}) + .then(data => this.setState({plot: data, connection_error: false})) + .catch(error => { + console.log(error); + this.setState({connection_error: true}); + }); + break; + } } componentDidMount() { this.getValues(); diff --git a/frontend_ui/src/components/DataProcessingPlots.tsx b/frontend_ui/src/components/DataProcessingPlots.tsx index d8a9bbd4..ec7e10c1 100644 --- a/frontend_ui/src/components/DataProcessingPlots.tsx +++ b/frontend_ui/src/components/DataProcessingPlots.tsx @@ -2,7 +2,7 @@ import React, {Component} from 'react'; import Paper from '@mui/material/Paper'; import {Box, Grid, Tab, Tabs} from "@mui/material"; -import DataProcessingPlot from "./DataProcessingPlot"; +import DataProcessingPlot, {PlotType} from "./DataProcessingPlot"; import Toolbar from "@mui/material/Toolbar"; import MenuItem from "@mui/material/MenuItem"; import FormControl from "@mui/material/FormControl"; @@ -14,7 +14,7 @@ type MyProps = { }; type MyState = { - type: string, + type: PlotType, xlabel: string, ylabel: string, binning: string, @@ -27,7 +27,7 @@ class DataProcessingPlots extends Component { interval: undefined | NodeJS.Timer; state: MyState = { - type: "INDEXING_RATE", + type: PlotType.INDEXING_RATE, xlabel: "Indexing rate", ylabel: "Photon count", binning: "0", @@ -44,22 +44,22 @@ class DataProcessingPlots extends Component { this.setState({tab: value}); switch (value) { case 1: - this.setState({type: "INDEXING_RATE", xlabel: "Image number", ylabel: "Indexing rate"}); + this.setState({type: PlotType.INDEXING_RATE, xlabel: "Image number", ylabel: "Indexing rate"}); break; case 2: - this.setState({type: "SPOT_COUNT", xlabel: "Image number", ylabel: "Spot count" }); + this.setState({type: PlotType.SPOT_COUNT, xlabel: "Image number", ylabel: "Spot count" }); break; case 3: - this.setState({type: "RAD_INT", xlabel: "Q [A-1]", ylabel: "Photon count"}); + this.setState({type: PlotType.RAD_INT, xlabel: "Q [A-1]", ylabel: "Photon count"}); break; case 4: - this.setState({type: "INDEXING_RATE_PER_FILE", xlabel: "File number", ylabel: "Indexing rate"}); + this.setState({type: PlotType.INDEXING_RATE_PER_FILE, xlabel: "File number", ylabel: "Indexing rate"}); break; case 5: - this.setState({type: "RAD_INT_PER_FILE", xlabel: "Q [A^-1]", ylabel: "Photon count"}); + this.setState({type: PlotType.RAD_INT_PER_FILE, xlabel: "Q [A^-1]", ylabel: "Photon count"}); break; case 6: - this.setState({type: "ADU_HISTOGRAM", xlabel: "ADU", ylabel: "Counts"}); + this.setState({type: PlotType.ADU_HISTOGRAM, xlabel: "ADU", ylabel: "Counts"}); break; } } @@ -104,7 +104,7 @@ class DataProcessingPlots extends Component { { - (this.state.type === "RAD_INT_PER_FILE") ? + (this.state.type === PlotType.RAD_INT_PER_FILE) ? : diff --git a/frontend_ui/src/components/DataProcessingSettings.tsx b/frontend_ui/src/components/DataProcessingSettings.tsx index 6a6d6474..8d0afc48 100644 --- a/frontend_ui/src/components/DataProcessingSettings.tsx +++ b/frontend_ui/src/components/DataProcessingSettings.tsx @@ -2,25 +2,14 @@ import React, {Component} from 'react'; import Paper from '@mui/material/Paper'; import {Grid, Slider, Switch, Typography} from "@mui/material"; -import {handleErrors} from "./handleErrors"; +import {DefaultService, spot_finding_settings} from "../openapi"; type MyProps = { addr: string; }; type MyState = { - s: { - photonCountThreshold: number | string, - signalToNoiseThreshold: number | string, - minPixPerSpot: number | string, - maxPixPerSpot: number | string, - localBkgSize: number | string, - highResolutionLimit?: number | string, - lowResolutionLimit?: number | string, - bkgEstimateLowQ: number | string, - bkgEstimateHighQ: number | string, - previewIndexedOnly: boolean - }, + s: spot_finding_settings, connection_error: boolean; } @@ -29,15 +18,13 @@ class DataProcessingSettings extends Component { interval : NodeJS.Timer | undefined; state : MyState = { s: { - photonCountThreshold: 8, - signalToNoiseThreshold: 3.0, - minPixPerSpot: 2, - maxPixPerSpot: 50, - localBkgSize: 5, - highResolutionLimit: 2.5, - bkgEstimateLowQ: 3, - bkgEstimateHighQ: 5, - previewIndexedOnly: false + photon_count_threshold: 8, + signal_to_noise_threshold: 3.0, + min_pix_per_spot: 2, + max_pix_per_spot: 50, + high_resolution_limit: 2.5, + low_resolution_limit: 20.0, + preview_indexed_only: false }, connection_error: true } @@ -48,25 +35,17 @@ class DataProcessingSettings extends Component { } putValues() { - fetch(this.addr + 'data_processing/settings', { - method: "PUT", - body: JSON.stringify(this.state.s) - }).then(handleErrors) + DefaultService.putConfigSpotFinding(this.state.s) .catch(error => console.log(error) ); } putValues2(x: MyState) { - fetch(this.addr + 'data_processing/settings', { - method: "PUT", - body: JSON.stringify(x.s) - }).then(handleErrors) + DefaultService.putConfigSpotFinding(x.s) .catch(error => console.log(error) ); } getValues() { - fetch(this.addr + 'data_processing/settings') - .then(handleErrors) - .then(res => res.json()) + DefaultService.getConfigSpotFinding() .then(data => this.setState({s: data, connection_error: false})) .catch(error => { console.log(error); @@ -87,7 +66,7 @@ class DataProcessingSettings extends Component { { s : { ...prevState.s, - photonCountThreshold: newValue as number + photon_count_threshold: newValue as number } } )); @@ -99,7 +78,7 @@ class DataProcessingSettings extends Component { { s : { ...prevState.s, - signalToNoiseThreshold: newValue as number + signal_to_noise_threshold: newValue as number } } )); @@ -111,7 +90,7 @@ class DataProcessingSettings extends Component { { s : { ...prevState.s, - minPixPerSpot: newValue as number + min_pix_per_spot: newValue as number } } )); @@ -123,7 +102,7 @@ class DataProcessingSettings extends Component { { s : { ...prevState.s, - highResolutionLimit: newValue as number + high_resolution_limit: newValue as number } } )); @@ -132,7 +111,7 @@ class DataProcessingSettings extends Component { previewIndexedToggle = (event: React.ChangeEvent) => { let x = this.state; - x.s.previewIndexedOnly = event.target.checked; + x.s.preview_indexed_only = event.target.checked; this.putValues2(x); } @@ -145,28 +124,28 @@ class DataProcessingSettings extends Component {
Data processing parameters

Count threshold
Signal-to-noise threshold
Minimum pixel / spot High resolution limit [Å]
- Preview only indexed frames

diff --git a/frontend_ui/src/components/DetectorSelection.tsx b/frontend_ui/src/components/DetectorSelection.tsx index 3943ffff..4f430019 100644 --- a/frontend_ui/src/components/DetectorSelection.tsx +++ b/frontend_ui/src/components/DetectorSelection.tsx @@ -4,27 +4,17 @@ import Select, { SelectChangeEvent } from '@mui/material/Select'; import {Grid} from "@mui/material"; import Button from "@mui/material/Button"; import Paper from "@mui/material/Paper"; -import {handleErrors} from "./handleErrors"; import InputLabel from '@mui/material/InputLabel'; import MenuItem from '@mui/material/MenuItem'; import FormControl from '@mui/material/FormControl'; +import {DefaultService, detector_list} from "../openapi"; type MyProps = { addr: string; } -type DetectorListElement = { - description: string, - nmodules: number | string, - id: number | string -}; - type MyState = { - detector_list: { - detector: DetectorListElement[] | undefined, - currentId: number | string, - currentDescription: string - }, + s: detector_list, choice: string, connection_error: boolean }; @@ -39,27 +29,39 @@ class DetectorSelection extends Component { } state : MyState = { - detector_list: { - detector: [], - currentId: "0", - currentDescription: "" + s: { + detectors: [], + current_id: 0 }, choice: "0", connection_error: true } + getValuesInitial() { + DefaultService.getConfigSelectDetector() + .then(data => this.setState({ + s: data, + choice: String(data.current_id), + connection_error: false + })) + .catch(error => { + console.log(error); + this.setState({connection_error: true}); + }); + } getValues() { - fetch(this.addr + 'detector/list') - .then(handleErrors) - .then(res => res.json()) - .then(data => this.setState({detector_list: data, connection_error: false})) + DefaultService.getConfigSelectDetector() + .then(data => this.setState({ + s: data, + connection_error: false + })) .catch(error => { console.log(error); this.setState({connection_error: true}); }); } componentDidMount() { - this.getValues(); + this.getValuesInitial(); this.interval = setInterval(() => this.getValues(), 1000); } @@ -74,12 +76,7 @@ class DetectorSelection extends Component { }; putValues = () => { - fetch(this.addr + 'detector/select', { - method: "PUT", - body: JSON.stringify({ - id: Number(this.state.choice) - }) - }).then(handleErrors) + DefaultService.putConfigSelectDetector({id: Number(this.state.choice)}) .catch(error => console.log(error) ); } @@ -93,7 +90,8 @@ class DetectorSelection extends Component {
Detector selection (EXPERT)


Current detector: - { this.state.connection_error ? "" : this.state.detector_list.currentDescription } + { (this.state.connection_error || this.state.s.detectors.length <= Number(this.state.choice)) ? + "" : this.state.s.detectors[Number(this.state.s.current_id)].description }

Detector @@ -106,9 +104,9 @@ class DetectorSelection extends Component { disabled={this.state.connection_error} > { - (this.state.detector_list.detector !== undefined) ? - this.state.detector_list.detector.map(d => ( - {d.description})) + (this.state.s.detectors !== undefined) ? + this.state.s.detectors.map(d => ( + {d.description} ({d.width}x{d.height} pxl))) : ""} diff --git a/frontend_ui/src/components/DetectorSettings.tsx b/frontend_ui/src/components/DetectorSettings.tsx index 0ba6dbc7..114a2c31 100644 --- a/frontend_ui/src/components/DetectorSettings.tsx +++ b/frontend_ui/src/components/DetectorSettings.tsx @@ -3,28 +3,18 @@ import React, {Component} from 'react'; import {Switch, Grid, InputAdornment, TextField} from "@mui/material"; import Button from "@mui/material/Button"; import Paper from "@mui/material/Paper"; -import {handleErrors} from "./handleErrors"; import FormControl from "@mui/material/FormControl"; import InputLabel from "@mui/material/InputLabel"; import Select, {SelectChangeEvent} from "@mui/material/Select"; import MenuItem from "@mui/material/MenuItem"; +import {DefaultService, detector_settings} from "../openapi"; type MyProps = { addr: string; } type MyState = { - s: { - frameTimeUs: number | string, - storageCellCount: number | string, - useInternalPacketGenerator: boolean, - collectRawData: boolean, - countTimeUs: number | string, - pedestalG0Frames: number | string, - pedestalG1Frames: number | string, - pedestalG2Frames: number | string, - storageCellDelayNs: number | string - }, + s: detector_settings, storage_cell_list_value: string, frame_time_error: boolean, count_time_error: boolean, @@ -41,15 +31,15 @@ class DetectorSettings extends Component { } state = { s: { - frameTimeUs: 1000, - storageCellCount: 1, - useInternalPacketGenerator: false, - collectRawData: false, - countTimeUs: 980, - pedestalG0Frames: 2000, - pedestalG1Frames: 300, - pedestalG2Frames: 300, - storageCellDelayNs: 10000 + frame_time_us: 1000, + storage_cell_count: 1, + internal_frame_generator: false, + collect_raw_data: false, + count_time_us: 980, + pedestal_g0_frames: 2000, + pedestal_g1_frames: 300, + pedestal_g2_frames: 300, + storage_cell_delay_ns: 10000 }, storage_cell_list_value: "1", frame_time_error: false, @@ -85,8 +75,8 @@ class DetectorSettings extends Component { frame_time_error: frame_err, count_time_error: count_err, s : {...prevState.s, - frameTimeUs: frame_time, - countTimeUs: count_time + frame_time_us: Number(frame_time), + count_time_us: Number(count_time) } } )); @@ -103,18 +93,18 @@ class DetectorSettings extends Component { { storage_cell_delay_error: err, s : {...prevState.s, - storageCellDelayNs: event.target.value + storage_cell_delay_ns: num_val } } )); } updateFrameTime = (event: React.ChangeEvent) => { - this.updateCollectionTime(event.target.value, this.state.s.countTimeUs); + this.updateCollectionTime(event.target.value, this.state.s.count_time_us); } updateCountTime = (event: React.ChangeEvent) => { - this.updateCollectionTime(this.state.s.frameTimeUs, event.target.value); + this.updateCollectionTime(this.state.s.frame_time_us, event.target.value); } @@ -122,22 +112,17 @@ class DetectorSettings extends Component { this.setState(prevState => ( { s : {...prevState.s, - collectRawData: event.target.checked} + collect_raw_data: event.target.checked} } )); } deactivate = () => { - fetch(this.addr + 'detector/deactivate', { - method: "POST" - }).then(handleErrors) + DefaultService.postDeactivate() .catch(error => console.log(error) ); } putValues = () => { - fetch(this.addr + 'detector/settings', { - method: "PUT", - body: JSON.stringify(this.state.s) - }).then(handleErrors) + DefaultService.putConfigDetector(this.state.s) .catch(error => console.log(error) ); } @@ -145,19 +130,17 @@ class DetectorSettings extends Component { this.setState(prevState => ({ storage_cell_list_value: String(event.target.value).toString(), s : {...prevState.s, - storageCellCount: String(event.target.value).toString() + storage_cell_count: Number(event.target.value) } }) ); }; getValues = () => { - fetch(this.addr + 'detector/settings') - .then(handleErrors) - .then(res => res.json()) + DefaultService.getConfigDetector() .then(data => this.setState({ s: data, - storage_cell_list_value: String(data.storageCellCount), + storage_cell_list_value: String(data.storage_cell_count), connection_error: false })) .catch(error => { @@ -181,7 +164,7 @@ class DetectorSettings extends Component { { { style={{ minWidth: "100px" }} error={this.state.storage_cell_delay_error} onChange={this.updateStorageCellDelay} - value={this.state.s.storageCellDelayNs} + value={this.state.s.storage_cell_delay_ns} disabled={this.state.connection_error || (this.state.storage_cell_list_value === "1")} InputProps = {{ inputProps: { @@ -247,7 +230,7 @@ class DetectorSettings extends Component { - Collect raw data

diff --git a/frontend_ui/src/components/MeasurementStatistics.tsx b/frontend_ui/src/components/MeasurementStatistics.tsx index 61235b97..9593d965 100644 --- a/frontend_ui/src/components/MeasurementStatistics.tsx +++ b/frontend_ui/src/components/MeasurementStatistics.tsx @@ -1,33 +1,30 @@ import React, {Component} from 'react'; import Paper from '@mui/material/Paper'; -import {Grid, Slider, Table, TableBody, TableCell, TableContainer, TableRow, Typography} from "@mui/material"; -import {handleErrors} from "./handleErrors"; +import {Grid, Table, TableBody, TableCell, TableContainer, TableRow,} from "@mui/material"; +import {DefaultService, measurement_statistics} from "../openapi"; type MyProps = { addr: string; }; type MyState = { - filePrefix: string, - imagesCollected: number | string, - collectionEfficiency: number, - compressionRatio: number, - maxReceiveDelay: number, - indexingRate: number, - connection_error: boolean; -} + s: measurement_statistics, + connection_error: boolean +}; class MeasurementStatistics extends Component { addr : string; interval : NodeJS.Timer | undefined; state : MyState = { - filePrefix: "", - imagesCollected: 0, - collectionEfficiency : 0, - compressionRatio: 0, - maxReceiveDelay: 0, - indexingRate: 0, + s: { + file_prefix: "", + images_collected: 0, + collection_efficiency : 0, + compression_ratio: 0, + max_receiver_delay: 0, + indexing_rate: 0 + }, connection_error: true } @@ -37,16 +34,9 @@ class MeasurementStatistics extends Component { } getValues() { - fetch(this.addr + 'detector/measurement_statistics') - .then(handleErrors) - .then(res => res.json()) + DefaultService.getStatisticsDataCollection() .then(data => this.setState({ - filePrefix: data.filePrefix, - imagesCollected: data.imagesCollected, - collectionEfficiency: data.collectionEfficiency, - compressionRatio: data.compressionRatio, - maxReceiveDelay: data.maxReceiveDelay, - indexingRate: data.indexingRate, + s: data, connection_error: false })) .catch(error => { @@ -75,24 +65,24 @@ class MeasurementStatistics extends Component { File prefix: - {this.state.filePrefix} + {this.state.s.file_prefix} Images collected: - {this.state.imagesCollected} + {this.state.s.images_collected} Compression ratio: - {this.state.compressionRatio} x + {this.state.s.compression_ratio} x Data acquisition efficiency: - {this.state.collectionEfficiency} + {this.state.s.collection_efficiency} Indexing rate: - {this.state.indexingRate} + {this.state.s.indexing_rate} diff --git a/frontend_ui/src/components/RadialIntegrationProfilePlots.tsx b/frontend_ui/src/components/RadialIntegrationProfilePlots.tsx index f3b79f50..28a496c9 100644 --- a/frontend_ui/src/components/RadialIntegrationProfilePlots.tsx +++ b/frontend_ui/src/components/RadialIntegrationProfilePlots.tsx @@ -1,24 +1,12 @@ import React, {Component} from 'react'; import MultiLinePlotWrapper from "./MultiLinePlotWrapper"; -import {handleErrors} from "./handleErrors"; +import {DefaultService, radial_integration_plots} from "../openapi"; type MyProps = { addr: string; }; -type Plot = { - x: number[], - y: number[] -} - -type RadialProfile = { - plot: Plot, - title: string -} - -type RadialProfiles = RadialProfile[] - type PlotlyPlot = { x: number[], y: number[], @@ -30,7 +18,7 @@ type PlotlyPlot = { type PlotlyData = PlotlyPlot[] type MyState = { - profiles : RadialProfiles, + profiles : radial_integration_plots, connection_error: boolean } @@ -57,11 +45,8 @@ class RadialIntegrationProfilePlots extends Component { } getValues() { - fetch(this.addr + 'data_processing/rad_int_profiles', { - method: "GET" - }).then(handleErrors) - .then(res => res.json()) - .then(data => this.setState({profiles: data.profiles, connection_error: false})) + DefaultService.getPlotRadIntPerFile() + .then(data => this.setState({profiles: data, connection_error: false})) .catch(error => { console.log(error); this.setState({connection_error: true}); @@ -77,7 +62,7 @@ class RadialIntegrationProfilePlots extends Component { } render() { - if (this.state.profiles !== undefined) { + if (Array.isArray(this.state.profiles) && !this.state.profiles.length) { let data: PlotlyData = []; this.state.profiles.map(d => data.push({ diff --git a/frontend_ui/src/components/StatusBar.tsx b/frontend_ui/src/components/StatusBar.tsx index 34b6fe47..1d77d3ce 100644 --- a/frontend_ui/src/components/StatusBar.tsx +++ b/frontend_ui/src/components/StatusBar.tsx @@ -1,41 +1,18 @@ - import React, {Component} from 'react'; import AppBar from '@mui/material/AppBar'; import Toolbar from '@mui/material/Toolbar'; import Typography from '@mui/material/Typography'; import Button from '@mui/material/Button'; -import {handleErrors} from "./handleErrors"; - -function decodeDAQState (val: string) : string { - switch(val) { - case "NOT_INITIALIZED": - return "Not initialized"; - case "BUSY": - return "Busy"; - case "IDLE": - return "Idle"; - case "DATA_COLLECTION": - return "Data collection"; - case "PEDESTAL": - return "Pedestal collection"; - case "ERROR": - return "Error"; - default: - return "Unknown state"; - } -} +import {broker_status, DefaultService} from "../openapi"; +import state = broker_status.state; type MyProps = { addr: string; }; type MyState = { - status: { - brokerState: string; - progress?: number; - indexingRate?: number; - } + status: broker_status connection_error: boolean; } @@ -57,28 +34,20 @@ class StatusBar extends Component { state : MyState = { status: { - brokerState: "NOT_CONNECTED" + state: state.INACTIVE }, connection_error: true } initialize = () => { - fetch(this.addr + 'detector/initialize', { - method: "POST" - }).then(handleErrors) - .catch(error => console.log(error) ); + DefaultService.postInitialize(); } cancel = () => { - fetch(this.addr + 'detector/cancel', { - method: "POST" - }).then(handleErrors) - .catch(error => console.log(error) ); + DefaultService.postCancel(); } getValues() { - fetch(this.addr + 'detector/status') - .then(handleErrors) - .then(res => res.json()) + DefaultService.getStatus() .then(data => this.setState({status: data, connection_error: false})) .catch(error => { console.log(error); @@ -96,9 +65,9 @@ class StatusBar extends Component { statusDescription() { return
- State: {decodeDAQState (this.state.status.brokerState)} - {"progress" in this.state.status ? " (" + FormatNumber(this.state.status.progress) + " %)" : ""} - {"indexing_rate" in this.state.status ? " Indexing rate: " + FormatNumber(this.state.status.indexingRate) + "%" : ""} + State: {this.state.status.state.toString()} + {(this.state.status.progress !== undefined) ? " (" + FormatNumber(this.state.status.progress) + " %)" : ""} + {(this.state.status.indexing_rate !== undefined) ? " Indexing rate: " + FormatNumber(this.state.status.indexing_rate) + "%" : ""}
} render() { diff --git a/frontend_ui/src/components/handleErrors.ts b/frontend_ui/src/components/handleErrors.ts deleted file mode 100644 index 47393629..00000000 --- a/frontend_ui/src/components/handleErrors.ts +++ /dev/null @@ -1,6 +0,0 @@ -export function handleErrors(response: Response): Response { - if (!response.ok) { - throw Error(response.statusText); - } - return response; -} diff --git a/frontend_ui/src/openapi/core/ApiError.ts b/frontend_ui/src/openapi/core/ApiError.ts new file mode 100644 index 00000000..d6b8fcc3 --- /dev/null +++ b/frontend_ui/src/openapi/core/ApiError.ts @@ -0,0 +1,25 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ApiRequestOptions } from './ApiRequestOptions'; +import type { ApiResult } from './ApiResult'; + +export class ApiError extends Error { + public readonly url: string; + public readonly status: number; + public readonly statusText: string; + public readonly body: any; + public readonly request: ApiRequestOptions; + + constructor(request: ApiRequestOptions, response: ApiResult, message: string) { + super(message); + + this.name = 'ApiError'; + this.url = response.url; + this.status = response.status; + this.statusText = response.statusText; + this.body = response.body; + this.request = request; + } +} diff --git a/frontend_ui/src/openapi/core/ApiRequestOptions.ts b/frontend_ui/src/openapi/core/ApiRequestOptions.ts new file mode 100644 index 00000000..c19adcc9 --- /dev/null +++ b/frontend_ui/src/openapi/core/ApiRequestOptions.ts @@ -0,0 +1,17 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type ApiRequestOptions = { + readonly method: 'GET' | 'PUT' | 'POST' | 'DELETE' | 'OPTIONS' | 'HEAD' | 'PATCH'; + readonly url: string; + readonly path?: Record; + readonly cookies?: Record; + readonly headers?: Record; + readonly query?: Record; + readonly formData?: Record; + readonly body?: any; + readonly mediaType?: string; + readonly responseHeader?: string; + readonly errors?: Record; +}; diff --git a/frontend_ui/src/openapi/core/ApiResult.ts b/frontend_ui/src/openapi/core/ApiResult.ts new file mode 100644 index 00000000..ad8fef2b --- /dev/null +++ b/frontend_ui/src/openapi/core/ApiResult.ts @@ -0,0 +1,11 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export type ApiResult = { + readonly url: string; + readonly ok: boolean; + readonly status: number; + readonly statusText: string; + readonly body: any; +}; diff --git a/frontend_ui/src/openapi/core/CancelablePromise.ts b/frontend_ui/src/openapi/core/CancelablePromise.ts new file mode 100644 index 00000000..55fef851 --- /dev/null +++ b/frontend_ui/src/openapi/core/CancelablePromise.ts @@ -0,0 +1,131 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export class CancelError extends Error { + + constructor(message: string) { + super(message); + this.name = 'CancelError'; + } + + public get isCancelled(): boolean { + return true; + } +} + +export interface OnCancel { + readonly isResolved: boolean; + readonly isRejected: boolean; + readonly isCancelled: boolean; + + (cancelHandler: () => void): void; +} + +export class CancelablePromise implements Promise { + #isResolved: boolean; + #isRejected: boolean; + #isCancelled: boolean; + readonly #cancelHandlers: (() => void)[]; + readonly #promise: Promise; + #resolve?: (value: T | PromiseLike) => void; + #reject?: (reason?: any) => void; + + constructor( + executor: ( + resolve: (value: T | PromiseLike) => void, + reject: (reason?: any) => void, + onCancel: OnCancel + ) => void + ) { + this.#isResolved = false; + this.#isRejected = false; + this.#isCancelled = false; + this.#cancelHandlers = []; + this.#promise = new Promise((resolve, reject) => { + this.#resolve = resolve; + this.#reject = reject; + + const onResolve = (value: T | PromiseLike): void => { + if (this.#isResolved || this.#isRejected || this.#isCancelled) { + return; + } + this.#isResolved = true; + this.#resolve?.(value); + }; + + const onReject = (reason?: any): void => { + if (this.#isResolved || this.#isRejected || this.#isCancelled) { + return; + } + this.#isRejected = true; + this.#reject?.(reason); + }; + + const onCancel = (cancelHandler: () => void): void => { + if (this.#isResolved || this.#isRejected || this.#isCancelled) { + return; + } + this.#cancelHandlers.push(cancelHandler); + }; + + Object.defineProperty(onCancel, 'isResolved', { + get: (): boolean => this.#isResolved, + }); + + Object.defineProperty(onCancel, 'isRejected', { + get: (): boolean => this.#isRejected, + }); + + Object.defineProperty(onCancel, 'isCancelled', { + get: (): boolean => this.#isCancelled, + }); + + return executor(onResolve, onReject, onCancel as OnCancel); + }); + } + + get [Symbol.toStringTag]() { + return "Cancellable Promise"; + } + + public then( + onFulfilled?: ((value: T) => TResult1 | PromiseLike) | null, + onRejected?: ((reason: any) => TResult2 | PromiseLike) | null + ): Promise { + return this.#promise.then(onFulfilled, onRejected); + } + + public catch( + onRejected?: ((reason: any) => TResult | PromiseLike) | null + ): Promise { + return this.#promise.catch(onRejected); + } + + public finally(onFinally?: (() => void) | null): Promise { + return this.#promise.finally(onFinally); + } + + public cancel(): void { + if (this.#isResolved || this.#isRejected || this.#isCancelled) { + return; + } + this.#isCancelled = true; + if (this.#cancelHandlers.length) { + try { + for (const cancelHandler of this.#cancelHandlers) { + cancelHandler(); + } + } catch (error) { + console.warn('Cancellation threw an error', error); + return; + } + } + this.#cancelHandlers.length = 0; + this.#reject?.(new CancelError('Request aborted')); + } + + public get isCancelled(): boolean { + return this.#isCancelled; + } +} diff --git a/frontend_ui/src/openapi/core/OpenAPI.ts b/frontend_ui/src/openapi/core/OpenAPI.ts new file mode 100644 index 00000000..52c1bc25 --- /dev/null +++ b/frontend_ui/src/openapi/core/OpenAPI.ts @@ -0,0 +1,32 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { ApiRequestOptions } from './ApiRequestOptions'; + +type Resolver = (options: ApiRequestOptions) => Promise; +type Headers = Record; + +export type OpenAPIConfig = { + BASE: string; + VERSION: string; + WITH_CREDENTIALS: boolean; + CREDENTIALS: 'include' | 'omit' | 'same-origin'; + TOKEN?: string | Resolver | undefined; + USERNAME?: string | Resolver | undefined; + PASSWORD?: string | Resolver | undefined; + HEADERS?: Headers | Resolver | undefined; + ENCODE_PATH?: ((path: string) => string) | undefined; +}; + +export const OpenAPI: OpenAPIConfig = { + BASE: '', + VERSION: '1.0.0', + WITH_CREDENTIALS: false, + CREDENTIALS: 'include', + TOKEN: undefined, + USERNAME: undefined, + PASSWORD: undefined, + HEADERS: undefined, + ENCODE_PATH: undefined, +}; diff --git a/frontend_ui/src/openapi/core/request.ts b/frontend_ui/src/openapi/core/request.ts new file mode 100644 index 00000000..b018a07c --- /dev/null +++ b/frontend_ui/src/openapi/core/request.ts @@ -0,0 +1,320 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import { ApiError } from './ApiError'; +import type { ApiRequestOptions } from './ApiRequestOptions'; +import type { ApiResult } from './ApiResult'; +import { CancelablePromise } from './CancelablePromise'; +import type { OnCancel } from './CancelablePromise'; +import type { OpenAPIConfig } from './OpenAPI'; + +export const isDefined = (value: T | null | undefined): value is Exclude => { + return value !== undefined && value !== null; +}; + +export const isString = (value: any): value is string => { + return typeof value === 'string'; +}; + +export const isStringWithValue = (value: any): value is string => { + return isString(value) && value !== ''; +}; + +export const isBlob = (value: any): value is Blob => { + return ( + typeof value === 'object' && + typeof value.type === 'string' && + typeof value.stream === 'function' && + typeof value.arrayBuffer === 'function' && + typeof value.constructor === 'function' && + typeof value.constructor.name === 'string' && + /^(Blob|File)$/.test(value.constructor.name) && + /^(Blob|File)$/.test(value[Symbol.toStringTag]) + ); +}; + +export const isFormData = (value: any): value is FormData => { + return value instanceof FormData; +}; + +export const base64 = (str: string): string => { + try { + return btoa(str); + } catch (err) { + // @ts-ignore + return Buffer.from(str).toString('base64'); + } +}; + +export const getQueryString = (params: Record): string => { + const qs: string[] = []; + + const append = (key: string, value: any) => { + qs.push(`${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`); + }; + + const process = (key: string, value: any) => { + if (isDefined(value)) { + if (Array.isArray(value)) { + value.forEach(v => { + process(key, v); + }); + } else if (typeof value === 'object') { + Object.entries(value).forEach(([k, v]) => { + process(`${key}[${k}]`, v); + }); + } else { + append(key, value); + } + } + }; + + Object.entries(params).forEach(([key, value]) => { + process(key, value); + }); + + if (qs.length > 0) { + return `?${qs.join('&')}`; + } + + return ''; +}; + +const getUrl = (config: OpenAPIConfig, options: ApiRequestOptions): string => { + const encoder = config.ENCODE_PATH || encodeURI; + + const path = options.url + .replace('{api-version}', config.VERSION) + .replace(/{(.*?)}/g, (substring: string, group: string) => { + if (options.path?.hasOwnProperty(group)) { + return encoder(String(options.path[group])); + } + return substring; + }); + + const url = `${config.BASE}${path}`; + if (options.query) { + return `${url}${getQueryString(options.query)}`; + } + return url; +}; + +export const getFormData = (options: ApiRequestOptions): FormData | undefined => { + if (options.formData) { + const formData = new FormData(); + + const process = (key: string, value: any) => { + if (isString(value) || isBlob(value)) { + formData.append(key, value); + } else { + formData.append(key, JSON.stringify(value)); + } + }; + + Object.entries(options.formData) + .filter(([_, value]) => isDefined(value)) + .forEach(([key, value]) => { + if (Array.isArray(value)) { + value.forEach(v => process(key, v)); + } else { + process(key, value); + } + }); + + return formData; + } + return undefined; +}; + +type Resolver = (options: ApiRequestOptions) => Promise; + +export const resolve = async (options: ApiRequestOptions, resolver?: T | Resolver): Promise => { + if (typeof resolver === 'function') { + return (resolver as Resolver)(options); + } + return resolver; +}; + +export const getHeaders = async (config: OpenAPIConfig, options: ApiRequestOptions): Promise => { + const token = await resolve(options, config.TOKEN); + const username = await resolve(options, config.USERNAME); + const password = await resolve(options, config.PASSWORD); + const additionalHeaders = await resolve(options, config.HEADERS); + + const headers = Object.entries({ + Accept: 'application/json', + ...additionalHeaders, + ...options.headers, + }) + .filter(([_, value]) => isDefined(value)) + .reduce((headers, [key, value]) => ({ + ...headers, + [key]: String(value), + }), {} as Record); + + if (isStringWithValue(token)) { + headers['Authorization'] = `Bearer ${token}`; + } + + if (isStringWithValue(username) && isStringWithValue(password)) { + const credentials = base64(`${username}:${password}`); + headers['Authorization'] = `Basic ${credentials}`; + } + + if (options.body) { + if (options.mediaType) { + headers['Content-Type'] = options.mediaType; + } else if (isBlob(options.body)) { + headers['Content-Type'] = options.body.type || 'application/octet-stream'; + } else if (isString(options.body)) { + headers['Content-Type'] = 'text/plain'; + } else if (!isFormData(options.body)) { + headers['Content-Type'] = 'application/json'; + } + } + + return new Headers(headers); +}; + +export const getRequestBody = (options: ApiRequestOptions): any => { + if (options.body !== undefined) { + if (options.mediaType?.includes('/json')) { + return JSON.stringify(options.body) + } else if (isString(options.body) || isBlob(options.body) || isFormData(options.body)) { + return options.body; + } else { + return JSON.stringify(options.body); + } + } + return undefined; +}; + +export const sendRequest = async ( + config: OpenAPIConfig, + options: ApiRequestOptions, + url: string, + body: any, + formData: FormData | undefined, + headers: Headers, + onCancel: OnCancel +): Promise => { + const controller = new AbortController(); + + const request: RequestInit = { + headers, + body: body ?? formData, + method: options.method, + signal: controller.signal, + }; + + if (config.WITH_CREDENTIALS) { + request.credentials = config.CREDENTIALS; + } + + onCancel(() => controller.abort()); + + return await fetch(url, request); +}; + +export const getResponseHeader = (response: Response, responseHeader?: string): string | undefined => { + if (responseHeader) { + const content = response.headers.get(responseHeader); + if (isString(content)) { + return content; + } + } + return undefined; +}; + +export const getResponseBody = async (response: Response): Promise => { + if (response.status !== 204) { + try { + const contentType = response.headers.get('Content-Type'); + if (contentType) { + const jsonTypes = ['application/json', 'application/problem+json'] + const isJSON = jsonTypes.some(type => contentType.toLowerCase().startsWith(type)); + if (isJSON) { + return await response.json(); + } else { + return await response.text(); + } + } + } catch (error) { + console.error(error); + } + } + return undefined; +}; + +export const catchErrorCodes = (options: ApiRequestOptions, result: ApiResult): void => { + const errors: Record = { + 400: 'Bad Request', + 401: 'Unauthorized', + 403: 'Forbidden', + 404: 'Not Found', + 500: 'Internal Server Error', + 502: 'Bad Gateway', + 503: 'Service Unavailable', + ...options.errors, + } + + const error = errors[result.status]; + if (error) { + throw new ApiError(options, result, error); + } + + if (!result.ok) { + const errorStatus = result.status ?? 'unknown'; + const errorStatusText = result.statusText ?? 'unknown'; + const errorBody = (() => { + try { + return JSON.stringify(result.body, null, 2); + } catch (e) { + return undefined; + } + })(); + + throw new ApiError(options, result, + `Generic Error: status: ${errorStatus}; status text: ${errorStatusText}; body: ${errorBody}` + ); + } +}; + +/** + * Request method + * @param config The OpenAPI configuration object + * @param options The request options from the service + * @returns CancelablePromise + * @throws ApiError + */ +export const request = (config: OpenAPIConfig, options: ApiRequestOptions): CancelablePromise => { + return new CancelablePromise(async (resolve, reject, onCancel) => { + try { + const url = getUrl(config, options); + const formData = getFormData(options); + const body = getRequestBody(options); + const headers = await getHeaders(config, options); + + if (!onCancel.isCancelled) { + const response = await sendRequest(config, options, url, body, formData, headers, onCancel); + const responseBody = await getResponseBody(response); + const responseHeader = getResponseHeader(response, options.responseHeader); + + const result: ApiResult = { + url, + ok: response.ok, + status: response.status, + statusText: response.statusText, + body: responseHeader ?? responseBody, + }; + + catchErrorCodes(options, result); + + resolve(result.body); + } + } catch (error) { + reject(error); + } + }); +}; diff --git a/frontend_ui/src/openapi/index.ts b/frontend_ui/src/openapi/index.ts new file mode 100644 index 00000000..35186571 --- /dev/null +++ b/frontend_ui/src/openapi/index.ts @@ -0,0 +1,24 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +export { ApiError } from './core/ApiError'; +export { CancelablePromise, CancelError } from './core/CancelablePromise'; +export { OpenAPI } from './core/OpenAPI'; +export type { OpenAPIConfig } from './core/OpenAPI'; + +export { broker_status } from './models/broker_status'; +export type { calibration_statistics } from './models/calibration_statistics'; +export { dataset_settings } from './models/dataset_settings'; +export type { detector_list } from './models/detector_list'; +export type { detector_selection } from './models/detector_selection'; +export type { detector_settings } from './models/detector_settings'; +export { error_message } from './models/error_message'; +export { measurement_statistics } from './models/measurement_statistics'; +export type { plot } from './models/plot'; +export type { plot_request } from './models/plot_request'; +export type { rad_int_settings } from './models/rad_int_settings'; +export type { radial_integration_plots } from './models/radial_integration_plots'; +export type { spot_finding_settings } from './models/spot_finding_settings'; + +export { DefaultService } from './services/DefaultService'; diff --git a/frontend_ui/src/openapi/models/broker_status.ts b/frontend_ui/src/openapi/models/broker_status.ts new file mode 100644 index 00000000..c238711c --- /dev/null +++ b/frontend_ui/src/openapi/models/broker_status.ts @@ -0,0 +1,26 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type broker_status = { + state: broker_status.state; + progress?: number; + indexing_rate?: number; + receiver_send_buffers_avail?: number; +}; + +export namespace broker_status { + + export enum state { + INACTIVE = 'Inactive', + IDLE = 'Idle', + BUSY = 'Busy', + MEASURING = 'Measuring', + PEDESTAL = 'Pedestal', + ERROR = 'Error', + } + + +} + diff --git a/frontend_ui/src/openapi/models/calibration_statistics.ts b/frontend_ui/src/openapi/models/calibration_statistics.ts new file mode 100644 index 00000000..7053e5bb --- /dev/null +++ b/frontend_ui/src/openapi/models/calibration_statistics.ts @@ -0,0 +1,16 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type calibration_statistics = Array<{ + module_number: number; + storage_cell_number: number; + pedestal_g0_mean: number; + pedestal_g1_mean: number; + pedestal_g2_mean: number; + gain_g0_mean: number; + gain_g1_mean: number; + gain_g2_mean: number; + masked_pixels: number; +}>; diff --git a/frontend_ui/src/openapi/models/dataset_settings.ts b/frontend_ui/src/openapi/models/dataset_settings.ts new file mode 100644 index 00000000..f6dc6d70 --- /dev/null +++ b/frontend_ui/src/openapi/models/dataset_settings.ts @@ -0,0 +1,103 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type dataset_settings = { + images_per_trigger: number; + ntrigger?: number; + summation?: number; + /** + * /entry/detector/beam_center_x in NXmx + * Beam center in X direction [pixels] + * + */ + beam_x_pxl: number; + /** + * /entry/detector/beam_center_y in NXmx + * Beam center in X direction [pixels] + * + */ + beam_y_pxl: number; + /** + * /entry/detector/distance in NXmx Detector distance [mm] + */ + detector_distance_mm: number; + /** + * Used to calculate /entry/beam/incident_wavelength in NXmx + * Incident photon energy in keV + * + */ + photon_energy_keV: number; + /** + * Prefix for filenames. If left empty, no file will be saved. + */ + file_prefix?: string; + /** + * Number of round-robin data files + */ + data_file_count?: number; + space_group_number?: number; + /** + * /entry/sample/name in NXmx + * Sample name + * + */ + sample_name: string; + /** + * Save pedestal together with the dataset + */ + save_calibration?: boolean; + /** + * FPGA output data type + */ + fpga_output?: dataset_settings.fpga_output; + compression?: dataset_settings.compression; + /** + * /entry/beam/total_flux in NXmx + * Flux incident on beam plane in photons per second. In other words this is the flux integrated over area. [photons/s] + * + */ + total_flux?: number; + /** + * /entry/instrument/attenuator/attenuator_transmission + * Transmission of attenuator (filter) [no units] + * + */ + transmission?: number; + /** + * Units of angstrom and degree + */ + unit_cell?: { + 'a': number; + 'b': number; + 'c': number; + alpha: number; + beta: number; + gamma: number; + }; +}; + +export namespace dataset_settings { + + /** + * FPGA output data type + */ + export enum fpga_output { + AUTO = 'auto', + INT32 = 'int32', + INT16 = 'int16', + UINT32 = 'uint32', + UINT16 = 'uint16', + } + + export enum compression { + BSLZ4 = 'bslz4', + BSZSTD = 'bszstd', + BSZSTD_RLE = 'bszstd_rle', + NONE = 'none', + } + + +} + diff --git a/frontend_ui/src/openapi/models/detector_list.ts b/frontend_ui/src/openapi/models/detector_list.ts new file mode 100644 index 00000000..a5d3c7f7 --- /dev/null +++ b/frontend_ui/src/openapi/models/detector_list.ts @@ -0,0 +1,16 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type detector_list = { + detectors: Array<{ + id: number; + description: string; + nmodules: number; + width: number; + height: number; + }>; + current_id: number; +}; + diff --git a/frontend_ui/src/openapi/models/detector_selection.ts b/frontend_ui/src/openapi/models/detector_selection.ts new file mode 100644 index 00000000..a8b8a942 --- /dev/null +++ b/frontend_ui/src/openapi/models/detector_selection.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type detector_selection = { + id: number; +}; + diff --git a/frontend_ui/src/openapi/models/detector_settings.ts b/frontend_ui/src/openapi/models/detector_settings.ts new file mode 100644 index 00000000..2bfc4f7d --- /dev/null +++ b/frontend_ui/src/openapi/models/detector_settings.ts @@ -0,0 +1,23 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type detector_settings = { + /** + * Interval between consecutive frames. + */ + frame_time_us: number; + /** + * Integration time of the detector. If not provided count time will be set to maximum value for a given frame time. + */ + count_time_us?: number; + storage_cell_count?: number; + internal_frame_generator?: boolean; + collect_raw_data?: boolean; + pedestal_g0_frames?: number; + pedestal_g1_frames?: number; + pedestal_g2_frames?: number; + storage_cell_delay_ns?: number; +}; + diff --git a/frontend_ui/src/openapi/models/error_message.ts b/frontend_ui/src/openapi/models/error_message.ts new file mode 100644 index 00000000..87f49287 --- /dev/null +++ b/frontend_ui/src/openapi/models/error_message.ts @@ -0,0 +1,29 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type error_message = { + /** + * Human readable message + */ + msg: string; + /** + * Enumerate field for automated analysis + */ + reason: error_message.reason; +}; + +export namespace error_message { + + /** + * Enumerate field for automated analysis + */ + export enum reason { + WRONG_DAQSTATE = 'WrongDAQState', + OTHER = 'Other', + } + + +} + diff --git a/frontend_ui/src/openapi/models/measurement_statistics.ts b/frontend_ui/src/openapi/models/measurement_statistics.ts new file mode 100644 index 00000000..5ed927f4 --- /dev/null +++ b/frontend_ui/src/openapi/models/measurement_statistics.ts @@ -0,0 +1,30 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type measurement_statistics = { + file_prefix?: string; + images_collected?: number; + max_image_number_sent?: number; + collection_efficiency?: number; + compression_ratio?: number; + cancelled?: boolean; + max_receiver_delay?: number; + indexing_rate?: number; + detector_width?: number; + detector_height?: number; + detector_pixel_depth?: measurement_statistics.detector_pixel_depth; + bkg_estimate?: number; +}; + +export namespace measurement_statistics { + + export enum detector_pixel_depth { + '_2' = 2, + '_4' = 4, + } + + +} + diff --git a/frontend_ui/src/openapi/models/plot.ts b/frontend_ui/src/openapi/models/plot.ts new file mode 100644 index 00000000..e471b00c --- /dev/null +++ b/frontend_ui/src/openapi/models/plot.ts @@ -0,0 +1,13 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +/** + * x and y coordinates for plotting, it is OK to assume that both arrays have the same size; layout is optimized for Plotly + */ +export type plot = { + 'x': Array; + 'y': Array; +}; + diff --git a/frontend_ui/src/openapi/models/plot_request.ts b/frontend_ui/src/openapi/models/plot_request.ts new file mode 100644 index 00000000..51da173e --- /dev/null +++ b/frontend_ui/src/openapi/models/plot_request.ts @@ -0,0 +1,9 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type plot_request = { + binning?: number; +}; + diff --git a/frontend_ui/src/openapi/models/rad_int_settings.ts b/frontend_ui/src/openapi/models/rad_int_settings.ts new file mode 100644 index 00000000..2a611bc5 --- /dev/null +++ b/frontend_ui/src/openapi/models/rad_int_settings.ts @@ -0,0 +1,19 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type rad_int_settings = { + /** + * If polarization factor is provided, than polarization correction is enabled. + */ + polarization_factor?: number; + /** + * Apply solid angle correction for radial integration + */ + solid_angle_corr: boolean; + high_q_recipA: number; + low_q_recipA: number; + q_spacing: number; +}; + diff --git a/frontend_ui/src/openapi/models/radial_integration_plots.ts b/frontend_ui/src/openapi/models/radial_integration_plots.ts new file mode 100644 index 00000000..52968499 --- /dev/null +++ b/frontend_ui/src/openapi/models/radial_integration_plots.ts @@ -0,0 +1,11 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +import type { plot } from './plot'; + +export type radial_integration_plots = Array<{ + title: string; + plot: plot; +}>; diff --git a/frontend_ui/src/openapi/models/spot_finding_settings.ts b/frontend_ui/src/openapi/models/spot_finding_settings.ts new file mode 100644 index 00000000..c5454db0 --- /dev/null +++ b/frontend_ui/src/openapi/models/spot_finding_settings.ts @@ -0,0 +1,15 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ + +export type spot_finding_settings = { + signal_to_noise_threshold: number; + photon_count_threshold: number; + min_pix_per_spot: number; + max_pix_per_spot: number; + high_resolution_limit: number; + low_resolution_limit: number; + preview_indexed_only?: boolean; +}; + diff --git a/frontend_ui/src/openapi/services/DefaultService.ts b/frontend_ui/src/openapi/services/DefaultService.ts new file mode 100644 index 00000000..93b62786 --- /dev/null +++ b/frontend_ui/src/openapi/services/DefaultService.ts @@ -0,0 +1,470 @@ +/* generated using openapi-typescript-codegen -- do no edit */ +/* istanbul ignore file */ +/* tslint:disable */ +/* eslint-disable */ +import type { broker_status } from '../models/broker_status'; +import type { calibration_statistics } from '../models/calibration_statistics'; +import type { dataset_settings } from '../models/dataset_settings'; +import type { detector_list } from '../models/detector_list'; +import type { detector_selection } from '../models/detector_selection'; +import type { detector_settings } from '../models/detector_settings'; +import type { measurement_statistics } from '../models/measurement_statistics'; +import type { plot } from '../models/plot'; +import type { plot_request } from '../models/plot_request'; +import type { rad_int_settings } from '../models/rad_int_settings'; +import type { radial_integration_plots } from '../models/radial_integration_plots'; +import type { spot_finding_settings } from '../models/spot_finding_settings'; + +import type { CancelablePromise } from '../core/CancelablePromise'; +import { OpenAPI } from '../core/OpenAPI'; +import { request as __request } from '../core/request'; + +export class DefaultService { + + /** + * Initialize detector and data acquisition + * Should be used in two cases: + * - Detector is in `Inactive` state + * - Detector is in `Error` state + * X-ray shutter must be closed. + * This operation will reconfigure network interface of the detector. + * During operation of the detector it is recommended to use the `POST /pedestal` operation instead. + * If storage cells are used, the execution time might be few minutes. + * + * This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + * + * @returns any Initialization started + * @throws ApiError + */ + public static postInitialize(): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/initialize', + errors: { + 500: `Error within Jungfraujoch code - see output message.`, + }, + }); + } + + /** + * Collect dark current for the detector + * Updates calibration of the JUNGFRAU detector. Must be in `Idle` state. + * + * X-ray shutter must be closed. Recommended to run once per hour for long integration times (> 100 us). + * + * This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + * + * @returns any Everything OK + * @throws ApiError + */ + public static postPedestal(): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/pedestal', + errors: { + 500: `Error within Jungfraujoch code - see output message.`, + }, + }); + } + + /** + * Start detector + * Start data acquisition. + * Detector must be in `Idle` state. + * Doesn't run calibration procedure. + * This is async function - one needs to use `POST /wait_till_done` to ensure operation is done. + * + * @param requestBody + * @returns any Everything OK + * @throws ApiError + */ + public static postStart( + requestBody?: dataset_settings, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/start', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Input parsing or validation error`, + 500: `Error within Jungfraujoch code - see output message.`, + }, + }); + } + + /** + * Wait for acquisition done + * 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. + * + * @returns any Detector in `Idle` state, another data collection can start immediately + * @throws ApiError + */ + public static postWaitTillDone(): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/wait_till_done', + errors: { + 500: `Error within Jungfraujoch code - see output message.`, + 504: `5 second timeout reached, need to restart operation`, + }, + }); + } + + /** + * Send soft trigger to the detector + * Generate soft trigger + * @returns any Trigger sent + * @throws ApiError + */ + public static postTrigger(): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/trigger', + }); + } + + /** + * Cancel running data collection + * Command will inform FPGA network card to stop pedestal or data collection at the current stage. + * Any frame that is currently being processed by CPU will be finished and sent to writer. + * Given the command is making sure to gracefully stop data acquisition and detector, it might take some time to switch back after command finished to `Idle` state. + * + * If data collection is not running, the command has no effect. + * + * @returns any Cancel request sent to FPGAs (or ignored, as data collection is not running) + * @throws ApiError + */ + public static postCancel(): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/cancel', + }); + } + + /** + * Prepare detector to turn off + * Should be in `Idle` or `Error` state. + * Command deactivates data acquisition and turns off detector high voltage and ASIC. + * Should be used always before turning off power from the detector. + * + * @returns any Detector ready to turn off + * @throws ApiError + */ + public static postDeactivate(): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/deactivate', + errors: { + 500: `Error within Jungfraujoch code - see output message.`, + }, + }); + } + + /** + * Change detector configuration + * Detector settings are ones that have effect on calibration, i.e., pedestal has to be collected again after changing these settings. + * This can only be done when detector is `Idle`, `Error` or `Inactive` states. + * If detector is in `Idle` state , pedestal procedure will be executed automatically - there must be no X-rays on the detector during the operation. + * If detector is in `Inactive` or `Error` states, new settings will be saved, but no calibration will be executed. + * + * @param requestBody + * @returns any Everything OK + * @throws ApiError + */ + public static putConfigDetector( + requestBody?: detector_settings, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/config/detector', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Input parsing or validation error`, + 500: `Error within Jungfraujoch code - see output message.`, + }, + }); + } + + /** + * Get detector configuration + * Can be done anytime + * @returns detector_settings Everything OK + * @throws ApiError + */ + public static getConfigDetector(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/config/detector', + }); + } + + /** + * Configure spot finding + * Can be done anytime, also while data collection is running + * @param requestBody + * @returns any Everything OK + * @throws ApiError + */ + public static putConfigSpotFinding( + requestBody?: spot_finding_settings, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/config/spot_finding', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Input parsing or validation error`, + }, + }); + } + + /** + * Get data processing configuration + * Can be done anytime + * @returns spot_finding_settings Everything OK + * @throws ApiError + */ + public static getConfigSpotFinding(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/config/spot_finding', + }); + } + + /** + * Configure radial integration + * Can be done when detector is Inactive or Idle + * @param requestBody + * @returns any Everything OK + * @throws ApiError + */ + public static putConfigRadInt( + requestBody?: rad_int_settings, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/config/rad_int', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Input parsing or validation error`, + 500: `Error within Jungfraujoch code - see output message.`, + }, + }); + } + + /** + * Get data processing configuration + * Can be done anytime + * @returns rad_int_settings Everything OK + * @throws ApiError + */ + public static getConfigRadInt(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/config/rad_int', + }); + } + + /** + * Select detector + * Jungfraujoch allows to control multiple detectors and/or region-of-interests. + * The command allows to choose one detector from the list (ID has to be consistent with one provided by GET response). + * Changing detector will set detector to `Inactive` state and will require reinitialization. + * + * @param requestBody + * @returns any Everything OK + * @throws ApiError + */ + public static putConfigSelectDetector( + requestBody?: detector_selection, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'PUT', + url: '/config/select_detector', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Input parsing or validation error`, + 500: `Error within Jungfraujoch code - see output message.`, + }, + }); + } + + /** + * List available detectors + * Configured detectors that can be selected by used + * @returns detector_list Everything OK + * @throws ApiError + */ + public static getConfigSelectDetector(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/config/select_detector', + }); + } + + /** + * Get Jungfraujoch status + * Status of the data acquisition + * @returns broker_status Everything OK + * @throws ApiError + */ + public static getStatus(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/status', + }); + } + + /** + * Generate background estimate plot + * Mean intensity for d = 3 - 5 A per image; binning is configurable + * @param requestBody + * @returns plot Everything OK + * @throws ApiError + */ + public static postPlotBkgEstimate( + requestBody?: plot_request, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/plot/bkg_estimate', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Input parsing or validation error`, + }, + }); + } + + /** + * Generate spot count plot + * Number of spots per image; binning is configurable + * @param requestBody + * @returns plot Everything OK + * @throws ApiError + */ + public static postPlotSpotCount( + requestBody?: plot_request, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/plot/spot_count', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Input parsing or validation error`, + }, + }); + } + + /** + * Generate indexing rate plot + * Image indexing rate; binning is configurable + * @param requestBody + * @returns plot Everything OK + * @throws ApiError + */ + public static postPlotIndexingRate( + requestBody?: plot_request, + ): CancelablePromise { + return __request(OpenAPI, { + method: 'POST', + url: '/plot/indexing_rate', + body: requestBody, + mediaType: 'application/json', + errors: { + 400: `Input parsing or validation error`, + }, + }); + } + + /** + * Generate ADU histogram + * ADU histogram for all images within current data collection + * @returns plot Everything OK + * @throws ApiError + */ + public static getPlotAduHistogram(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/plot/adu_histogram', + }); + } + + /** + * Generate indexing rate per file + * Indexing rate per each of data files; useful for example for time resolved data + * @returns plot Everything OK + * @throws ApiError + */ + public static getPlotIndexingRatePerFile(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/plot/indexing_rate_per_file', + }); + } + + /** + * Generate radial integration profile + * Generate average radial integration profile + * @returns plot Everything OK + * @throws ApiError + */ + public static getPlotRadInt(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/plot/rad_int', + }); + } + + /** + * Generate radial integration profiles per file + * Radial integration plots for both the whole dataset and per file; useful for time-resolved measurements + * @returns radial_integration_plots Everything OK + * @throws ApiError + */ + public static getPlotRadIntPerFile(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/plot/rad_int_per_file', + }); + } + + /** + * Get data collection statistics + * Results of the last data collection + * @returns measurement_statistics Everything OK + * @throws ApiError + */ + public static getStatisticsDataCollection(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/statistics/data_collection', + errors: { + 404: `No data collection performed so far`, + }, + }); + } + + /** + * Get calibration statistics + * Statistics are provided for each module/storage cell separately + * @returns calibration_statistics Everything OK + * @throws ApiError + */ + public static getStatisticsCalibration(): CancelablePromise { + return __request(OpenAPI, { + method: 'GET', + url: '/statistics/calibration', + }); + } + +} diff --git a/grpc/CMakeLists.txt b/grpc/CMakeLists.txt deleted file mode 100644 index 8bd23477..00000000 --- a/grpc/CMakeLists.txt +++ /dev/null @@ -1,47 +0,0 @@ -SET(ABSL_PROPAGATE_CXX_STD ON) -SET(protobuf_MODULE_COMPATIBLE TRUE) - -FIND_PACKAGE(Protobuf CONFIG REQUIRED) -FIND_PACKAGE(gRPC CONFIG REQUIRED) - -MESSAGE(STATUS "Using preinstalled protobuf ${Protobuf_VERSION}") -MESSAGE(STATUS "Using preinstalled gRPC ${gRPC_VERSION}") -SET(_GRPC_GRPCPP gRPC::grpc++) -SET(_PROTOBUF_PROTOC $) -SET(_GRPC_CPP_PLUGIN_EXECUTABLE $) -SET(_GRPC_PYTHON_PLUGIN_EXECUTABLE $) - -SET(rg_proto "jfjoch.proto") -SET(rg_proto_srcs "${CMAKE_CURRENT_BINARY_DIR}/jfjoch.pb.cc") -SET(rg_proto_hdrs "${CMAKE_CURRENT_BINARY_DIR}/jfjoch.pb.h") -SET(rg_grpc_srcs "${CMAKE_CURRENT_BINARY_DIR}/jfjoch.grpc.pb.cc") -SET(rg_grpc_hdrs "${CMAKE_CURRENT_BINARY_DIR}/jfjoch.grpc.pb.h" ) - -ADD_CUSTOM_COMMAND( - OUTPUT "${rg_proto_srcs}" "${rg_proto_hdrs}" "${rg_grpc_srcs}" "${rg_grpc_hdrs}" - COMMAND ${_PROTOBUF_PROTOC} - ARGS --grpc_out "${CMAKE_CURRENT_BINARY_DIR}" - --cpp_out "${CMAKE_CURRENT_BINARY_DIR}" - -I "${CMAKE_CURRENT_SOURCE_DIR}" - --plugin=protoc-gen-grpc="${_GRPC_CPP_PLUGIN_EXECUTABLE}" - "${rg_proto}" - DEPENDS "${rg_proto}") - -ADD_CUSTOM_COMMAND( - OUTPUT ${CMAKE_SOURCE_DIR}/python/jfjoch_pb2_grpc.py ${CMAKE_SOURCE_DIR}/python/jfjoch_pb2.py - COMMAND ${_PROTOBUF_PROTOC} - ARGS --grpc_python_out "${CMAKE_SOURCE_DIR}/python" - --python_out "${CMAKE_SOURCE_DIR}/python" - -I "${CMAKE_CURRENT_SOURCE_DIR}" - --plugin=protoc-gen-grpc_python="${_GRPC_PYTHON_PLUGIN_EXECUTABLE}" - "${rg_proto}" - DEPENDS "${rg_proto}") - -ADD_CUSTOM_TARGET(jfjoch-grpc-python - DEPENDS ${CMAKE_SOURCE_DIR}/python/jfjoch_pb2_grpc.py ${CMAKE_SOURCE_DIR}/python/jfjoch_pb2.py) - -ADD_LIBRARY(JFJochProtoBuf ${rg_grpc_srcs} ${rg_grpc_hdrs} ${rg_proto_srcs} ${rg_proto_hdrs}) -ADD_DEPENDENCIES(JFJochProtoBuf jfjoch-grpc-python) - -TARGET_INCLUDE_DIRECTORIES(JFJochProtoBuf PUBLIC ${CMAKE_CURRENT_BINARY_DIR}) -TARGET_LINK_LIBRARIES(JFJochProtoBuf ${_GRPC_GRPCPP}) diff --git a/grpc/gRPCServer_Template.h b/grpc/gRPCServer_Template.h deleted file mode 100644 index 85641458..00000000 --- a/grpc/gRPCServer_Template.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright (2019-2023) Paul Scherrer Institute - -#ifndef JUNGFRAUJOCH_GRPCSERVER_TEMPLATE_H -#define JUNGFRAUJOCH_GRPCSERVER_TEMPLATE_H - -#include -#include -#include -#include "../common/Definitions.h" - -inline std::unique_ptr gRPCServer(const std::string &addr, grpc::Service &service, int32_t max_threads = -1) { - grpc::ServerBuilder builder; - builder.AddListeningPort(addr, grpc::InsecureServerCredentials()); - builder.SetMaxReceiveMessageSize(GRPC_MAX_MESSAGE_SIZE); // 1 GB - builder.RegisterService(&service); - if (max_threads > 0) { - grpc::ResourceQuota rq; - rq.SetMaxThreads(max_threads); - builder.SetResourceQuota(rq); - } - return builder.BuildAndStart(); -} - -#endif //JUNGFRAUJOCH_GRPCSERVER_TEMPLATE_H diff --git a/grpc/jfjoch.proto b/grpc/jfjoch.proto deleted file mode 100644 index 07c37aa9..00000000 --- a/grpc/jfjoch.proto +++ /dev/null @@ -1,227 +0,0 @@ -// Copyright (2019-2023) Paul Scherrer Institute - -syntax = "proto3"; - -package JFJochProtoBuf; - -enum Compression { - BSHUF_LZ4 = 0; - BSHUF_ZSTD = 1; - BSHUF_ZSTD_RLE = 2; - NO_COMPRESSION = 3; -} - -enum DetectorMode { - CONVERSION = 0; - RAW = 1; - PEDESTAL_G0 = 2; - PEDESTAL_G1 = 3; - PEDESTAL_G2 = 4; -}; - -enum State { - NOT_INITIALIZED = 0; - IDLE = 1; - BUSY = 2; - PEDESTAL = 3; - DATA_COLLECTION = 4; - ERROR = 5; -} - -enum FPGAPixelOutput { - AUTO = 0; - INT16 = 1; - UINT16 = 2; - INT32 = 3; - UINT32 = 4; -} - -// Utilities -message Empty { -} - -message UnitCell { - float a = 1; - float b = 2; - float c = 3; - float alpha = 4; - float beta = 5; - float gamma = 6; -} - -message Vector { - float x = 1; - float y = 2; - float z = 3; -} - -message RotationSettings { - float start_angle_deg = 1; - float angle_incr_per_image_deg = 2; - Vector rotation_axis = 3; -} - -message Plot { - repeated float x = 1; - repeated float y = 2; -} - -message DatasetSettings { - int64 images_per_trigger = 1; - int64 ntrigger = 2; - - FPGAPixelOutput fpga_pixel_output = 3; - int64 summation = 4; - - float beam_x_pxl = 5; - float beam_y_pxl = 6; - float detector_distance_mm = 7; - float photon_energy_keV = 8; - - string file_prefix = 9; - int64 data_file_count = 10; - - Compression compression = 11; - - string sample_name = 12; - UnitCell unit_cell = 13; - int64 space_group_number = 14; - - bool rad_int_solid_angle_corr = 18; - bool rad_int_polarization_corr = 19; - float rad_int_polarization_factor = 20; - - bool save_calibration = 21; -} - -message DetectorSettings { - int64 frame_time_us = 1; - int64 count_time_us = 2; - - int64 storage_cell_count = 3; - bool use_internal_packet_generator = 4; - bool collect_raw_data = 5; - - int64 pedestal_g0_frames = 6; - int64 pedestal_g1_frames = 7; - int64 pedestal_g2_frames = 8; - - int64 storage_cell_delay_ns = 10; -} - -message ModuleStatistics { - int64 module_number = 1; - int64 storage_cell_number = 2; - - float pedestal_g0_mean = 3; - float pedestal_g1_mean = 4; - float pedestal_g2_mean = 5; - - float gain_g0_mean = 6; - float gain_g1_mean = 7; - float gain_g2_mean = 8; - - uint64 masked_pixels = 9; -} - -message JFCalibrationStatistics { - repeated ModuleStatistics module_statistics = 1; -} - -enum PlotType { - BKG_ESTIMATE = 0; - RAD_INT = 1; - SPOT_COUNT = 2; - INDEXING_RATE = 3; - INDEXING_RATE_PER_FILE = 4; - ADU_HISTOGRAM = 5; -} - -message PlotRequest { - PlotType type = 1; - uint64 binning = 2; -} - -message RadialIntegrationProfile { - string title = 1; - Plot plot = 2; -} - -message RadialIntegrationProfiles { - repeated RadialIntegrationProfile profiles = 1; -} - -message DataProcessingSettings { - float signal_to_noise_threshold = 1; // STRONG_PIXEL in XDS - int64 photon_count_threshold = 2; // Threshold in photon counts - int64 min_pix_per_spot = 3; // Minimum pixels per spot - int64 max_pix_per_spot = 4; // Maximum pixels per spot - float high_resolution_limit = 6; - float low_resolution_limit = 7; - bool preview_indexed_only = 10; -} - -message MeasurementStatistics { - string file_prefix = 1; - int64 images_collected = 2; - int64 max_image_number_sent = 3; - float collection_efficiency = 4; - float compression_ratio = 5; - - bool cancelled = 6; - int64 max_receive_delay = 7; - - float indexing_rate = 10; - - int64 detector_width = 12; - int64 detector_height = 13; - int64 detector_pixel_depth = 14; - - float bkg_estimate = 16; -} - -message BrokerStatus { - State broker_state = 1; - float progress = 2; - float indexing_rate = 3; - float receiver_send_buffers_avail = 4; -} - -message DetectorListElement { - string description = 1; - int64 nmodules = 2; - int64 id = 3; -} - -message DetectorList { - repeated DetectorListElement detector = 1; - int64 current_id = 2; - string current_description = 3; -} - -message DetectorSelection { - int64 id = 1; -} - -service gRPC_JFJochBroker { - rpc Start (DatasetSettings) returns (Empty) {} - rpc Stop (Empty) returns (Empty) {} - rpc Pedestal (Empty) returns (Empty) {} - rpc Initialize (Empty) returns (Empty) {} - rpc Cancel (Empty) returns (Empty) {} - rpc Deactivate (Empty) returns (Empty) {} - rpc Trigger (Empty) returns (Empty) {} - - rpc GetStatus (Empty) returns (BrokerStatus) {} - rpc GetCalibrationStatistics (Empty) returns (JFCalibrationStatistics) {} - rpc GetDetectorSettings (Empty) returns (DetectorSettings) {} - rpc PutDetectorSettings (DetectorSettings) returns (Empty) {} - rpc GetMeasurementStatistics (Empty) returns (MeasurementStatistics) {} - rpc GetDataProcessingSettings (Empty) returns (DataProcessingSettings) {} - rpc PutDataProcessingSettings (DataProcessingSettings) returns (Empty) {} - rpc GetPlots (PlotRequest) returns (Plot) {} - rpc GetRadialIntegrationProfiles(Empty) returns (RadialIntegrationProfiles) {} - - rpc GetDetectorList (Empty) returns (DetectorList) {} - rpc SelectDetector (DetectorSelection) returns (Empty) {} -} \ No newline at end of file diff --git a/image_analysis/CMakeLists.txt b/image_analysis/CMakeLists.txt index c98d143e..825b794d 100644 --- a/image_analysis/CMakeLists.txt +++ b/image_analysis/CMakeLists.txt @@ -3,7 +3,7 @@ ADD_LIBRARY(ImageAnalysis STATIC IndexerWrapper.cpp IndexerWrapper.h RadialIntegrationMapping.cpp RadialIntegrationMapping.h StrongPixelSet.cpp StrongPixelSet.h RadialIntegrationProfile.cpp RadialIntegrationProfile.h - DataProcessingSettings.h) + SpotFindingSettings.h) TARGET_LINK_LIBRARIES(ImageAnalysis CommonFunctions) diff --git a/image_analysis/DataProcessingSettings.h b/image_analysis/SpotFindingSettings.h similarity index 73% rename from image_analysis/DataProcessingSettings.h rename to image_analysis/SpotFindingSettings.h index 8e75d601..27b5db48 100644 --- a/image_analysis/DataProcessingSettings.h +++ b/image_analysis/SpotFindingSettings.h @@ -1,11 +1,11 @@ // Copyright (2019-2023) Paul Scherrer Institute -#ifndef JUNGFRAUJOCH_DATAPROCESSINGSETTINGS_H -#define JUNGFRAUJOCH_DATAPROCESSINGSETTINGS_H +#ifndef JUNGFRAUJOCH_SPOTFINDINGSETTINGS_H +#define JUNGFRAUJOCH_SPOTFINDINGSETTINGS_H #include -struct DataProcessingSettings { +struct SpotFindingSettings { float signal_to_noise_threshold; // STRONG_PIXEL in XDS int64_t photon_count_threshold; // Threshold in photon counts int64_t min_pix_per_spot; // Minimum pixels per spot @@ -15,4 +15,4 @@ struct DataProcessingSettings { bool preview_indexed_only; }; -#endif //JUNGFRAUJOCH_DATAPROCESSINGSETTINGS_H +#endif //JUNGFRAUJOCH_SPOTFINDINGSETTINGS_H diff --git a/image_analysis/StrongPixelSet.cpp b/image_analysis/StrongPixelSet.cpp index 1dd9395f..aeda1181 100644 --- a/image_analysis/StrongPixelSet.cpp +++ b/image_analysis/StrongPixelSet.cpp @@ -89,7 +89,7 @@ void StrongPixelSet::ExtendSpot(DiffractionSpot &spot, std::unordered_map &spots) { std::multimap spots_map; diff --git a/image_analysis/StrongPixelSet.h b/image_analysis/StrongPixelSet.h index 9347f3fd..16ffe885 100644 --- a/image_analysis/StrongPixelSet.h +++ b/image_analysis/StrongPixelSet.h @@ -9,7 +9,7 @@ #include "../common/Coord.h" #include "../common/DiffractionSpot.h" #include "../acquisition_device/AcquisitionDevice.h" -#include "DataProcessingSettings.h" +#include "SpotFindingSettings.h" inline uint32_t strong_pixel_coord(uint16_t col, uint16_t line) { return col + (static_cast(line) << 16u); @@ -36,7 +36,7 @@ public: StrongPixelSet(const DiffractionExperiment& experiment); size_t Count() const; void AddStrongPixel(uint16_t col, uint16_t line, int32_t photons = 1); - void FindSpots(const DiffractionExperiment &experiment, const DataProcessingSettings &settings, std::vector &spots); + void FindSpots(const DiffractionExperiment &experiment, const SpotFindingSettings &settings, std::vector &spots); size_t Common(const StrongPixelSet &set) const; }; diff --git a/python/jfjoch_grpc2http.py b/python/jfjoch_grpc2http.py deleted file mode 100644 index 7da82bdd..00000000 --- a/python/jfjoch_grpc2http.py +++ /dev/null @@ -1,313 +0,0 @@ -# Copyright (2019-2023) Paul Scherrer Institute -# - -from io import BytesIO - -import grpc -import numpy -from fastapi import FastAPI, HTTPException, Response, Request -from fastapi.responses import RedirectResponse -from fastapi.staticfiles import StaticFiles -from google.protobuf.json_format import Parse, ParseError, MessageToDict -from tifffile import imwrite - -import jfjoch_pb2 -import jfjoch_pb2_grpc - -static_directory = "../frontend_ui/build" -grpc_addr = "localhost:5232" - -app = FastAPI() - -app.mount("/frontend", StaticFiles(directory=static_directory), name="static") - -MAX_MESSAGE_LENGTH = 64 * 1024 * 1024 -channel = grpc.insecure_channel( - grpc_addr, - options=[ - ("grpc.max_send_message_length", MAX_MESSAGE_LENGTH), - ("grpc.max_receive_message_length", MAX_MESSAGE_LENGTH), - ], -) - - -@app.get("/", response_class=RedirectResponse) -async def get_root(): - return "/frontend/index.html" - - -@app.get("/frontend", response_class=RedirectResponse) -async def get_frontend(): - return "/frontend/index.html" - - -@app.post("/detector/pedestal") -async def pedestal(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.Pedestal(jfjoch_pb2.Empty()) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - return {} - - -@app.post("/detector/initialize") -async def initialize(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.Initialize(jfjoch_pb2.Empty()) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - return {} - - -@app.post("/detector/deactivate") -async def deactivate(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.Deactivate(jfjoch_pb2.Empty()) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - return {} - - -@app.post("/detector/start") -async def start(request: Request): - try: - data = await request.body() - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.Start(Parse(data, jfjoch_pb2.DatasetSettings())) - return {} - except ParseError as e: - return HTTPException(status_code=400, detail="Parser error: " + str(e)) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.post("/detector/stop") -async def stop(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.Stop(jfjoch_pb2.Empty()) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - return {} - - -@app.post("/detector/trigger") -async def trigger(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.Trigger(jfjoch_pb2.Empty()) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - return {} - - -@app.post("/detector/cancel") -async def cancel(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.Cancel(jfjoch_pb2.Empty()) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - return {} - - -@app.get("/detector/status") -async def get_status(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - return MessageToDict( - stub.GetStatus(jfjoch_pb2.Empty()), including_default_value_fields=True - ) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get("/detector/settings") -async def get_settings(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - return MessageToDict( - stub.GetDetectorSettings(jfjoch_pb2.Empty()), - including_default_value_fields=True, - ) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.put("/detector/settings") -async def put_settings(request: Request): - try: - data = await request.body() - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.PutDetectorSettings(Parse(data, jfjoch_pb2.DetectorSettings())) - return {} - except ParseError as e: - return HTTPException(status_code=400, detail="Parser error: " + str(e)) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get("/detector/calibration") -async def get_calibration(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - return MessageToDict( - stub.GetCalibrationStatistics(jfjoch_pb2.Empty()), - including_default_value_fields=True, - ) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get("/data_processing/settings") -async def get_settings(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - return MessageToDict( - stub.GetDataProcessingSettings(jfjoch_pb2.Empty()), - including_default_value_fields=True, - ) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.put("/data_processing/settings") -async def put_data_processing_settings(request: Request): - try: - data = await request.body() - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.PutDataProcessingSettings(Parse(data, jfjoch_pb2.DataProcessingSettings())) - return {} - except ParseError as e: - return HTTPException(status_code=400, detail="Parser error: " + str(e)) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.post("/data_processing/plots") -async def get_settings(request: Request): - try: - data = await request.body() - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - return MessageToDict( - stub.GetPlots(Parse(data, jfjoch_pb2.PlotRequest())), including_default_value_fields=True - ) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get("/data_processing/rad_int_profiles") -async def get_settings(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - return MessageToDict( - stub.GetRadialIntegrationProfiles(jfjoch_pb2.Empty()), including_default_value_fields=True - ) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get("/detector/measurement_statistics") -async def get_meas_stats(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - return MessageToDict( - stub.GetMeasurementStatistics(jfjoch_pb2.Empty()), including_default_value_fields=True - ) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get("/detector/list") -async def get_detector_list(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - return MessageToDict( - stub.GetDetectorList(jfjoch_pb2.Empty()), including_default_value_fields=True - ) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.put("/detector/select") -async def put_detector_selection(request: Request): - try: - data = await request.body() - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - stub.SelectDetector(Parse(data, jfjoch_pb2.DetectorSelection())) - return {} - except ParseError as e: - return HTTPException(status_code=400, detail="Parser error: " + str(e)) - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -def calib_to_tiff(im: jfjoch_pb2.Image) -> bytes: - if im.pixel_depth == 2: - image_array = numpy.frombuffer(im.data, numpy.uint16) - else: - image_array = numpy.frombuffer(im.data, numpy.uint32) - image_array = numpy.reshape(image_array, (im.height, im.width)) - b = BytesIO() - imwrite(b, image_array) - return bytes(b.getvalue()) - - -@app.get( - "/image/pedestalG0.tiff", - responses={200: {"content": {"image/tiff": {}}}}, - response_class=Response, -) -async def get_pedestalg0(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - pbuf = stub.GetPedestalG0(jfjoch_pb2.Empty()) - return Response(content=calib_to_tiff(pbuf), media_type="image/tiff") - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get( - "/image/pedestalG0.tiff", - responses={200: {"content": {"image/tiff": {}}}}, - response_class=Response, -) -async def get_pedestalg1(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - pbuf = stub.GetPedestalG1(jfjoch_pb2.Empty()) - return Response(content=calib_to_tiff(pbuf), media_type="image/tiff") - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get( - "/image/pedestalG2.tiff", - responses={200: {"content": {"image/tiff": {}}}}, - response_class=Response, -) -async def get_pedestalg2(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - pbuf = stub.GetPedestalG2(jfjoch_pb2.Empty()) - return Response(content=calib_to_tiff(pbuf), media_type="image/tiff") - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - - -@app.get( - "/image/mask.tiff", - responses={200: {"content": {"image/tiff": {}}}}, - response_class=Response, -) -async def get_mask(): - try: - stub = jfjoch_pb2_grpc.gRPC_JFJochBrokerStub(channel) - pbuf = stub.GetMask(jfjoch_pb2.Empty()) - return Response(content=calib_to_tiff(pbuf), media_type="image/tiff") - except grpc.RpcError as e: - raise HTTPException(status_code=400, detail=e.details()) - diff --git a/python/jfjoch_pb2.py b/python/jfjoch_pb2.py deleted file mode 100644 index f4df6482..00000000 --- a/python/jfjoch_pb2.py +++ /dev/null @@ -1,71 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: jfjoch.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x0cjfjoch.proto\x12\x0eJFJochProtoBuf\"\x07\n\x05\x45mpty\"W\n\x08UnitCell\x12\t\n\x01\x61\x18\x01 \x01(\x02\x12\t\n\x01\x62\x18\x02 \x01(\x02\x12\t\n\x01\x63\x18\x03 \x01(\x02\x12\r\n\x05\x61lpha\x18\x04 \x01(\x02\x12\x0c\n\x04\x62\x65ta\x18\x05 \x01(\x02\x12\r\n\x05gamma\x18\x06 \x01(\x02\")\n\x06Vector\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02\"|\n\x10RotationSettings\x12\x17\n\x0fstart_angle_deg\x18\x01 \x01(\x02\x12 \n\x18\x61ngle_incr_per_image_deg\x18\x02 \x01(\x02\x12-\n\rrotation_axis\x18\x03 \x01(\x0b\x32\x16.JFJochProtoBuf.Vector\"\x1c\n\x04Plot\x12\t\n\x01x\x18\x01 \x03(\x02\x12\t\n\x01y\x18\x02 \x03(\x02\"\xb1\x04\n\x0f\x44\x61tasetSettings\x12\x1a\n\x12images_per_trigger\x18\x01 \x01(\x03\x12\x10\n\x08ntrigger\x18\x02 \x01(\x03\x12:\n\x11\x66pga_pixel_output\x18\x03 \x01(\x0e\x32\x1f.JFJochProtoBuf.FPGAPixelOutput\x12\x11\n\tsummation\x18\x04 \x01(\x03\x12\x12\n\nbeam_x_pxl\x18\x05 \x01(\x02\x12\x12\n\nbeam_y_pxl\x18\x06 \x01(\x02\x12\x1c\n\x14\x64\x65tector_distance_mm\x18\x07 \x01(\x02\x12\x19\n\x11photon_energy_keV\x18\x08 \x01(\x02\x12\x13\n\x0b\x66ile_prefix\x18\t \x01(\t\x12\x17\n\x0f\x64\x61ta_file_count\x18\n \x01(\x03\x12\x30\n\x0b\x63ompression\x18\x0b \x01(\x0e\x32\x1b.JFJochProtoBuf.Compression\x12\x13\n\x0bsample_name\x18\x0c \x01(\t\x12+\n\tunit_cell\x18\r \x01(\x0b\x32\x18.JFJochProtoBuf.UnitCell\x12\x1a\n\x12space_group_number\x18\x0e \x01(\x03\x12 \n\x18rad_int_solid_angle_corr\x18\x12 \x01(\x08\x12!\n\x19rad_int_polarization_corr\x18\x13 \x01(\x08\x12#\n\x1brad_int_polarization_factor\x18\x14 \x01(\x02\x12\x18\n\x10save_calibration\x18\x15 \x01(\x08\"\x90\x02\n\x10\x44\x65tectorSettings\x12\x15\n\rframe_time_us\x18\x01 \x01(\x03\x12\x15\n\rcount_time_us\x18\x02 \x01(\x03\x12\x1a\n\x12storage_cell_count\x18\x03 \x01(\x03\x12%\n\x1duse_internal_packet_generator\x18\x04 \x01(\x08\x12\x18\n\x10\x63ollect_raw_data\x18\x05 \x01(\x08\x12\x1a\n\x12pedestal_g0_frames\x18\x06 \x01(\x03\x12\x1a\n\x12pedestal_g1_frames\x18\x07 \x01(\x03\x12\x1a\n\x12pedestal_g2_frames\x18\x08 \x01(\x03\x12\x1d\n\x15storage_cell_delay_ns\x18\n \x01(\x03\"\xed\x01\n\x10ModuleStatistics\x12\x15\n\rmodule_number\x18\x01 \x01(\x03\x12\x1b\n\x13storage_cell_number\x18\x02 \x01(\x03\x12\x18\n\x10pedestal_g0_mean\x18\x03 \x01(\x02\x12\x18\n\x10pedestal_g1_mean\x18\x04 \x01(\x02\x12\x18\n\x10pedestal_g2_mean\x18\x05 \x01(\x02\x12\x14\n\x0cgain_g0_mean\x18\x06 \x01(\x02\x12\x14\n\x0cgain_g1_mean\x18\x07 \x01(\x02\x12\x14\n\x0cgain_g2_mean\x18\x08 \x01(\x02\x12\x15\n\rmasked_pixels\x18\t \x01(\x04\"V\n\x17JFCalibrationStatistics\x12;\n\x11module_statistics\x18\x01 \x03(\x0b\x32 .JFJochProtoBuf.ModuleStatistics\"F\n\x0bPlotRequest\x12&\n\x04type\x18\x01 \x01(\x0e\x32\x18.JFJochProtoBuf.PlotType\x12\x0f\n\x07\x62inning\x18\x02 \x01(\x04\"M\n\x18RadialIntegrationProfile\x12\r\n\x05title\x18\x01 \x01(\t\x12\"\n\x04plot\x18\x02 \x01(\x0b\x32\x14.JFJochProtoBuf.Plot\"W\n\x19RadialIntegrationProfiles\x12:\n\x08profiles\x18\x01 \x03(\x0b\x32(.JFJochProtoBuf.RadialIntegrationProfile\"\xea\x01\n\x16\x44\x61taProcessingSettings\x12!\n\x19signal_to_noise_threshold\x18\x01 \x01(\x02\x12\x1e\n\x16photon_count_threshold\x18\x02 \x01(\x03\x12\x18\n\x10min_pix_per_spot\x18\x03 \x01(\x03\x12\x18\n\x10max_pix_per_spot\x18\x04 \x01(\x03\x12\x1d\n\x15high_resolution_limit\x18\x06 \x01(\x02\x12\x1c\n\x14low_resolution_limit\x18\x07 \x01(\x02\x12\x1c\n\x14preview_indexed_only\x18\n \x01(\x08\"\xc9\x02\n\x15MeasurementStatistics\x12\x13\n\x0b\x66ile_prefix\x18\x01 \x01(\t\x12\x18\n\x10images_collected\x18\x02 \x01(\x03\x12\x1d\n\x15max_image_number_sent\x18\x03 \x01(\x03\x12\x1d\n\x15\x63ollection_efficiency\x18\x04 \x01(\x02\x12\x19\n\x11\x63ompression_ratio\x18\x05 \x01(\x02\x12\x11\n\tcancelled\x18\x06 \x01(\x08\x12\x19\n\x11max_receive_delay\x18\x07 \x01(\x03\x12\x15\n\rindexing_rate\x18\n \x01(\x02\x12\x16\n\x0e\x64\x65tector_width\x18\x0c \x01(\x03\x12\x17\n\x0f\x64\x65tector_height\x18\r \x01(\x03\x12\x1c\n\x14\x64\x65tector_pixel_depth\x18\x0e \x01(\x03\x12\x14\n\x0c\x62kg_estimate\x18\x10 \x01(\x02\"\x89\x01\n\x0c\x42rokerStatus\x12+\n\x0c\x62roker_state\x18\x01 \x01(\x0e\x32\x15.JFJochProtoBuf.State\x12\x10\n\x08progress\x18\x02 \x01(\x02\x12\x15\n\rindexing_rate\x18\x03 \x01(\x02\x12#\n\x1breceiver_send_buffers_avail\x18\x04 \x01(\x02\"H\n\x13\x44\x65tectorListElement\x12\x13\n\x0b\x64\x65scription\x18\x01 \x01(\t\x12\x10\n\x08nmodules\x18\x02 \x01(\x03\x12\n\n\x02id\x18\x03 \x01(\x03\"v\n\x0c\x44\x65tectorList\x12\x35\n\x08\x64\x65tector\x18\x01 \x03(\x0b\x32#.JFJochProtoBuf.DetectorListElement\x12\x12\n\ncurrent_id\x18\x02 \x01(\x03\x12\x1b\n\x13\x63urrent_description\x18\x03 \x01(\t\"\x1f\n\x11\x44\x65tectorSelection\x12\n\n\x02id\x18\x01 \x01(\x03*T\n\x0b\x43ompression\x12\r\n\tBSHUF_LZ4\x10\x00\x12\x0e\n\nBSHUF_ZSTD\x10\x01\x12\x12\n\x0e\x42SHUF_ZSTD_RLE\x10\x02\x12\x12\n\x0eNO_COMPRESSION\x10\x03*Z\n\x0c\x44\x65tectorMode\x12\x0e\n\nCONVERSION\x10\x00\x12\x07\n\x03RAW\x10\x01\x12\x0f\n\x0bPEDESTAL_G0\x10\x02\x12\x0f\n\x0bPEDESTAL_G1\x10\x03\x12\x0f\n\x0bPEDESTAL_G2\x10\x04*^\n\x05State\x12\x13\n\x0fNOT_INITIALIZED\x10\x00\x12\x08\n\x04IDLE\x10\x01\x12\x08\n\x04\x42USY\x10\x02\x12\x0c\n\x08PEDESTAL\x10\x03\x12\x13\n\x0f\x44\x41TA_COLLECTION\x10\x04\x12\t\n\x05\x45RROR\x10\x05*I\n\x0f\x46PGAPixelOutput\x12\x08\n\x04\x41UTO\x10\x00\x12\t\n\x05INT16\x10\x01\x12\n\n\x06UINT16\x10\x02\x12\t\n\x05INT32\x10\x03\x12\n\n\x06UINT32\x10\x04*{\n\x08PlotType\x12\x10\n\x0c\x42KG_ESTIMATE\x10\x00\x12\x0b\n\x07RAD_INT\x10\x01\x12\x0e\n\nSPOT_COUNT\x10\x02\x12\x11\n\rINDEXING_RATE\x10\x03\x12\x1a\n\x16INDEXING_RATE_PER_FILE\x10\x04\x12\x11\n\rADU_HISTOGRAM\x10\x05\x32\xd6\n\n\x11gRPC_JFJochBroker\x12\x41\n\x05Start\x12\x1f.JFJochProtoBuf.DatasetSettings\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12\x36\n\x04Stop\x12\x15.JFJochProtoBuf.Empty\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12:\n\x08Pedestal\x12\x15.JFJochProtoBuf.Empty\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12<\n\nInitialize\x12\x15.JFJochProtoBuf.Empty\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12\x38\n\x06\x43\x61ncel\x12\x15.JFJochProtoBuf.Empty\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12<\n\nDeactivate\x12\x15.JFJochProtoBuf.Empty\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12\x39\n\x07Trigger\x12\x15.JFJochProtoBuf.Empty\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12\x42\n\tGetStatus\x12\x15.JFJochProtoBuf.Empty\x1a\x1c.JFJochProtoBuf.BrokerStatus\"\x00\x12\\\n\x18GetCalibrationStatistics\x12\x15.JFJochProtoBuf.Empty\x1a\'.JFJochProtoBuf.JFCalibrationStatistics\"\x00\x12P\n\x13GetDetectorSettings\x12\x15.JFJochProtoBuf.Empty\x1a .JFJochProtoBuf.DetectorSettings\"\x00\x12P\n\x13PutDetectorSettings\x12 .JFJochProtoBuf.DetectorSettings\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12Z\n\x18GetMeasurementStatistics\x12\x15.JFJochProtoBuf.Empty\x1a%.JFJochProtoBuf.MeasurementStatistics\"\x00\x12\\\n\x19GetDataProcessingSettings\x12\x15.JFJochProtoBuf.Empty\x1a&.JFJochProtoBuf.DataProcessingSettings\"\x00\x12\\\n\x19PutDataProcessingSettings\x12&.JFJochProtoBuf.DataProcessingSettings\x1a\x15.JFJochProtoBuf.Empty\"\x00\x12?\n\x08GetPlots\x12\x1b.JFJochProtoBuf.PlotRequest\x1a\x14.JFJochProtoBuf.Plot\"\x00\x12\x62\n\x1cGetRadialIntegrationProfiles\x12\x15.JFJochProtoBuf.Empty\x1a).JFJochProtoBuf.RadialIntegrationProfiles\"\x00\x12H\n\x0fGetDetectorList\x12\x15.JFJochProtoBuf.Empty\x1a\x1c.JFJochProtoBuf.DetectorList\"\x00\x12L\n\x0eSelectDetector\x12!.JFJochProtoBuf.DetectorSelection\x1a\x15.JFJochProtoBuf.Empty\"\x00\x62\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'jfjoch_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - _COMPRESSION._serialized_start=2672 - _COMPRESSION._serialized_end=2756 - _DETECTORMODE._serialized_start=2758 - _DETECTORMODE._serialized_end=2848 - _STATE._serialized_start=2850 - _STATE._serialized_end=2944 - _FPGAPIXELOUTPUT._serialized_start=2946 - _FPGAPIXELOUTPUT._serialized_end=3019 - _PLOTTYPE._serialized_start=3021 - _PLOTTYPE._serialized_end=3144 - _EMPTY._serialized_start=32 - _EMPTY._serialized_end=39 - _UNITCELL._serialized_start=41 - _UNITCELL._serialized_end=128 - _VECTOR._serialized_start=130 - _VECTOR._serialized_end=171 - _ROTATIONSETTINGS._serialized_start=173 - _ROTATIONSETTINGS._serialized_end=297 - _PLOT._serialized_start=299 - _PLOT._serialized_end=327 - _DATASETSETTINGS._serialized_start=330 - _DATASETSETTINGS._serialized_end=891 - _DETECTORSETTINGS._serialized_start=894 - _DETECTORSETTINGS._serialized_end=1166 - _MODULESTATISTICS._serialized_start=1169 - _MODULESTATISTICS._serialized_end=1406 - _JFCALIBRATIONSTATISTICS._serialized_start=1408 - _JFCALIBRATIONSTATISTICS._serialized_end=1494 - _PLOTREQUEST._serialized_start=1496 - _PLOTREQUEST._serialized_end=1566 - _RADIALINTEGRATIONPROFILE._serialized_start=1568 - _RADIALINTEGRATIONPROFILE._serialized_end=1645 - _RADIALINTEGRATIONPROFILES._serialized_start=1647 - _RADIALINTEGRATIONPROFILES._serialized_end=1734 - _DATAPROCESSINGSETTINGS._serialized_start=1737 - _DATAPROCESSINGSETTINGS._serialized_end=1971 - _MEASUREMENTSTATISTICS._serialized_start=1974 - _MEASUREMENTSTATISTICS._serialized_end=2303 - _BROKERSTATUS._serialized_start=2306 - _BROKERSTATUS._serialized_end=2443 - _DETECTORLISTELEMENT._serialized_start=2445 - _DETECTORLISTELEMENT._serialized_end=2517 - _DETECTORLIST._serialized_start=2519 - _DETECTORLIST._serialized_end=2637 - _DETECTORSELECTION._serialized_start=2639 - _DETECTORSELECTION._serialized_end=2670 - _GRPC_JFJOCHBROKER._serialized_start=3147 - _GRPC_JFJOCHBROKER._serialized_end=4513 -# @@protoc_insertion_point(module_scope) diff --git a/python/jfjoch_pb2_grpc.py b/python/jfjoch_pb2_grpc.py deleted file mode 100644 index 0ba9b983..00000000 --- a/python/jfjoch_pb2_grpc.py +++ /dev/null @@ -1,627 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -import jfjoch_pb2 as jfjoch__pb2 - - -class gRPC_JFJochBrokerStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.Start = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/Start', - request_serializer=jfjoch__pb2.DatasetSettings.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.Stop = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/Stop', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.Pedestal = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/Pedestal', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.Initialize = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/Initialize', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.Cancel = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/Cancel', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.Deactivate = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/Deactivate', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.Trigger = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/Trigger', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.GetStatus = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/GetStatus', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.BrokerStatus.FromString, - ) - self.GetCalibrationStatistics = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/GetCalibrationStatistics', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.JFCalibrationStatistics.FromString, - ) - self.GetDetectorSettings = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/GetDetectorSettings', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.DetectorSettings.FromString, - ) - self.PutDetectorSettings = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/PutDetectorSettings', - request_serializer=jfjoch__pb2.DetectorSettings.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.GetMeasurementStatistics = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/GetMeasurementStatistics', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.MeasurementStatistics.FromString, - ) - self.GetDataProcessingSettings = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/GetDataProcessingSettings', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.DataProcessingSettings.FromString, - ) - self.PutDataProcessingSettings = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/PutDataProcessingSettings', - request_serializer=jfjoch__pb2.DataProcessingSettings.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - self.GetPlots = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/GetPlots', - request_serializer=jfjoch__pb2.PlotRequest.SerializeToString, - response_deserializer=jfjoch__pb2.Plot.FromString, - ) - self.GetRadialIntegrationProfiles = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/GetRadialIntegrationProfiles', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.RadialIntegrationProfiles.FromString, - ) - self.GetDetectorList = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/GetDetectorList', - request_serializer=jfjoch__pb2.Empty.SerializeToString, - response_deserializer=jfjoch__pb2.DetectorList.FromString, - ) - self.SelectDetector = channel.unary_unary( - '/JFJochProtoBuf.gRPC_JFJochBroker/SelectDetector', - request_serializer=jfjoch__pb2.DetectorSelection.SerializeToString, - response_deserializer=jfjoch__pb2.Empty.FromString, - ) - - -class gRPC_JFJochBrokerServicer(object): - """Missing associated documentation comment in .proto file.""" - - def Start(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Stop(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Pedestal(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Initialize(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Cancel(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Deactivate(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Trigger(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetStatus(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetCalibrationStatistics(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetDetectorSettings(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutDetectorSettings(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetMeasurementStatistics(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetDataProcessingSettings(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutDataProcessingSettings(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetPlots(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetRadialIntegrationProfiles(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetDetectorList(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SelectDetector(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_gRPC_JFJochBrokerServicer_to_server(servicer, server): - rpc_method_handlers = { - 'Start': grpc.unary_unary_rpc_method_handler( - servicer.Start, - request_deserializer=jfjoch__pb2.DatasetSettings.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'Stop': grpc.unary_unary_rpc_method_handler( - servicer.Stop, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'Pedestal': grpc.unary_unary_rpc_method_handler( - servicer.Pedestal, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'Initialize': grpc.unary_unary_rpc_method_handler( - servicer.Initialize, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'Cancel': grpc.unary_unary_rpc_method_handler( - servicer.Cancel, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'Deactivate': grpc.unary_unary_rpc_method_handler( - servicer.Deactivate, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'Trigger': grpc.unary_unary_rpc_method_handler( - servicer.Trigger, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'GetStatus': grpc.unary_unary_rpc_method_handler( - servicer.GetStatus, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.BrokerStatus.SerializeToString, - ), - 'GetCalibrationStatistics': grpc.unary_unary_rpc_method_handler( - servicer.GetCalibrationStatistics, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.JFCalibrationStatistics.SerializeToString, - ), - 'GetDetectorSettings': grpc.unary_unary_rpc_method_handler( - servicer.GetDetectorSettings, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.DetectorSettings.SerializeToString, - ), - 'PutDetectorSettings': grpc.unary_unary_rpc_method_handler( - servicer.PutDetectorSettings, - request_deserializer=jfjoch__pb2.DetectorSettings.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'GetMeasurementStatistics': grpc.unary_unary_rpc_method_handler( - servicer.GetMeasurementStatistics, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.MeasurementStatistics.SerializeToString, - ), - 'GetDataProcessingSettings': grpc.unary_unary_rpc_method_handler( - servicer.GetDataProcessingSettings, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.DataProcessingSettings.SerializeToString, - ), - 'PutDataProcessingSettings': grpc.unary_unary_rpc_method_handler( - servicer.PutDataProcessingSettings, - request_deserializer=jfjoch__pb2.DataProcessingSettings.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - 'GetPlots': grpc.unary_unary_rpc_method_handler( - servicer.GetPlots, - request_deserializer=jfjoch__pb2.PlotRequest.FromString, - response_serializer=jfjoch__pb2.Plot.SerializeToString, - ), - 'GetRadialIntegrationProfiles': grpc.unary_unary_rpc_method_handler( - servicer.GetRadialIntegrationProfiles, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.RadialIntegrationProfiles.SerializeToString, - ), - 'GetDetectorList': grpc.unary_unary_rpc_method_handler( - servicer.GetDetectorList, - request_deserializer=jfjoch__pb2.Empty.FromString, - response_serializer=jfjoch__pb2.DetectorList.SerializeToString, - ), - 'SelectDetector': grpc.unary_unary_rpc_method_handler( - servicer.SelectDetector, - request_deserializer=jfjoch__pb2.DetectorSelection.FromString, - response_serializer=jfjoch__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'JFJochProtoBuf.gRPC_JFJochBroker', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class gRPC_JFJochBroker(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def Start(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/Start', - jfjoch__pb2.DatasetSettings.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Stop(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/Stop', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Pedestal(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/Pedestal', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Initialize(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/Initialize', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Cancel(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/Cancel', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Deactivate(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/Deactivate', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Trigger(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/Trigger', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetStatus(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/GetStatus', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.BrokerStatus.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetCalibrationStatistics(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/GetCalibrationStatistics', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.JFCalibrationStatistics.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetDetectorSettings(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/GetDetectorSettings', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.DetectorSettings.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutDetectorSettings(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/PutDetectorSettings', - jfjoch__pb2.DetectorSettings.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetMeasurementStatistics(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/GetMeasurementStatistics', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.MeasurementStatistics.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetDataProcessingSettings(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/GetDataProcessingSettings', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.DataProcessingSettings.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutDataProcessingSettings(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/PutDataProcessingSettings', - jfjoch__pb2.DataProcessingSettings.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetPlots(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/GetPlots', - jfjoch__pb2.PlotRequest.SerializeToString, - jfjoch__pb2.Plot.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetRadialIntegrationProfiles(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/GetRadialIntegrationProfiles', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.RadialIntegrationProfiles.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetDetectorList(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/GetDetectorList', - jfjoch__pb2.Empty.SerializeToString, - jfjoch__pb2.DetectorList.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SelectDetector(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/JFJochProtoBuf.gRPC_JFJochBroker/SelectDetector', - jfjoch__pb2.DetectorSelection.SerializeToString, - jfjoch__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/receiver/JFJochReceiver.cpp b/receiver/JFJochReceiver.cpp index 7674c889..2c900bca 100644 --- a/receiver/JFJochReceiver.cpp +++ b/receiver/JFJochReceiver.cpp @@ -270,9 +270,10 @@ void JFJochReceiver::FrameTransformationThread() { std::unique_ptr indexer; - if (experiment.HasUnitCell()) { + auto uc = experiment.GetUnitCell(); + if (uc) { indexer = std::make_unique(); - indexer->Setup(experiment.GetUnitCell()); + indexer->Setup(uc.value()); } frame_transformation_ready.count_down(); @@ -344,7 +345,7 @@ void JFJochReceiver::FrameTransformationThread() { if (send_image) { std::vector spots; - auto local_data_processing_settings = GetDataProcessingSettings(); + auto local_spot_finding_settings = GetSpotFindingSettings(); if (find_spots) { for (const auto &spot: spots) @@ -390,7 +391,7 @@ void JFJochReceiver::FrameTransformationThread() { message.image = transformation.GetCompressedImage(); - if (preview_publisher && (!local_data_processing_settings.preview_indexed_only || indexed)) + if (preview_publisher && (!local_spot_finding_settings.preview_indexed_only || indexed)) preview_publisher->SendImage(message); if (push_images_to_writer) { @@ -546,13 +547,13 @@ void JFJochReceiver::FinalizeMeasurement() { logger.Info("Receiving data done"); } -void JFJochReceiver::SetDataProcessingSettings(const DataProcessingSettings &in_data_processing_settings) { - std::unique_lock ul(data_processing_settings_mutex); - DiffractionExperiment::CheckDataProcessingSettings(in_data_processing_settings); - data_processing_settings = in_data_processing_settings; +void JFJochReceiver::SetSpotFindingSettings(const SpotFindingSettings &in_spot_finding_settings) { + std::unique_lock ul(spot_finding_settings_mutex); + DiffractionExperiment::CheckDataProcessingSettings(in_spot_finding_settings); + spot_finding_settings = in_spot_finding_settings; for (int i = 0; i < ndatastreams; i++) { - acquisition_device[i].SetSpotFinderParameters(data_processing_settings.photon_count_threshold, - data_processing_settings.signal_to_noise_threshold); + acquisition_device[i].SetSpotFinderParameters(spot_finding_settings.photon_count_threshold, + spot_finding_settings.signal_to_noise_threshold); } } @@ -568,9 +569,9 @@ JFJochReceiver::~JFJochReceiver() { measurement.get(); } -DataProcessingSettings JFJochReceiver::GetDataProcessingSettings() { - std::unique_lock ul(data_processing_settings_mutex); - return data_processing_settings; +SpotFindingSettings JFJochReceiver::GetSpotFindingSettings() { + std::unique_lock ul(spot_finding_settings_mutex); + return spot_finding_settings; } Plot JFJochReceiver::GetPlots(const PlotRequest &request) { diff --git a/receiver/JFJochReceiver.h b/receiver/JFJochReceiver.h index b9ed9196..6d86caa4 100644 --- a/receiver/JFJochReceiver.h +++ b/receiver/JFJochReceiver.h @@ -103,8 +103,8 @@ class JFJochReceiver { std::chrono::time_point start_time; std::chrono::time_point end_time; - DataProcessingSettings data_processing_settings; - std::mutex data_processing_settings_mutex; + SpotFindingSettings spot_finding_settings; + std::mutex spot_finding_settings_mutex; StatusVector bkg_estimate; StatusVector spot_count; @@ -124,8 +124,8 @@ class JFJochReceiver { void FrameTransformationThread(); void Cancel(const JFJochException &e); void FinalizeMeasurement(); - DataProcessingSettings GetDataProcessingSettings(); void RetrievePedestal(); + SpotFindingSettings GetSpotFindingSettings(); void UpdateMaxImage(int64_t image_number); void UpdateMaxDelay(int64_t delay); public: @@ -149,7 +149,7 @@ public: JFJochReceiverStatus GetStatus() const; - void SetDataProcessingSettings(const DataProcessingSettings &data_processing_settings); + void SetSpotFindingSettings(const SpotFindingSettings &spot_finding_settings); Plot GetPlots(const PlotRequest& request); RadialIntegrationProfiles GetRadialIntegrationProfiles(); diff --git a/receiver/JFJochReceiverService.cpp b/receiver/JFJochReceiverService.cpp index d44d5dea..870d3dc2 100644 --- a/receiver/JFJochReceiverService.cpp +++ b/receiver/JFJochReceiverService.cpp @@ -46,18 +46,14 @@ void JFJochReceiverService::FinalizeMeasurement() { } } -JFJochReceiverStatus JFJochReceiverService::GetStatus() { +std::optional JFJochReceiverService::GetStatus() { // Need to hold mutex, as receiver might not exist here, if state is idle std::unique_lock ul(state_mutex); if (state == ReceiverState::Running) return receiver->GetStatus(); else - return { - .progress = -1, - .indexing_rate = -1, - .send_buffers_avail = -1 - }; + return {}; } void JFJochReceiverService::Start(const DiffractionExperiment &experiment, const JFCalibration *calibration) { @@ -75,7 +71,7 @@ void JFJochReceiverService::Start(const DiffractionExperiment &experiment, const logger, nthreads, preview_publisher, numa_policy); try { // Don't want to stop - receiver->SetDataProcessingSettings(data_processing_settings); + receiver->SetSpotFindingSettings(data_processing_settings); } catch (...) {} measurement = std::async(std::launch::async, &JFJochReceiverService::FinalizeMeasurement, this); state = ReceiverState::Running; @@ -86,19 +82,10 @@ void JFJochReceiverService::Start(const DiffractionExperiment &experiment, const } } -void JFJochReceiverService::Abort() { - std::unique_lock ul(state_mutex); - if (state == ReceiverState::Idle) - throw JFJochException(JFJochExceptionCategory::WrongDAQState, "Receiver not idle, cannot start"); - else { - receiver->Cancel(); - } -} - void JFJochReceiverService::Cancel() { std::unique_lock ul(state_mutex); if (state == ReceiverState::Idle) - throw JFJochException(JFJochExceptionCategory::WrongDAQState, "Receiver not idle, cannot start"); + throw JFJochException(JFJochExceptionCategory::WrongReceiverState, "Receiver not idle, cannot start"); else { receiver->Cancel(); } @@ -110,7 +97,7 @@ JFJochReceiverOutput JFJochReceiverService::Stop() { measurement_done.wait(ul, [this] { return (state != ReceiverState::Running);}); if (state != ReceiverState::Idle) - throw JFJochException(JFJochExceptionCategory::WrongDAQState, "Receiver in weird state"); + throw JFJochException(JFJochExceptionCategory::WrongReceiverState, "Receiver in weird state"); try { if (measurement.valid()) @@ -122,17 +109,17 @@ JFJochReceiverOutput JFJochReceiverService::Stop() { if (!receiver) { logger.Warning("Request via gRPC, while receiver not running"); - throw JFJochException(JFJochExceptionCategory::WrongDAQState, "Receiver not idle, cannot start"); + throw JFJochException(JFJochExceptionCategory::WrongReceiverState, "Receiver not idle, cannot start"); } return receiver->GetStatistics(); } -void JFJochReceiverService::SetDataProcessingSettings(const DataProcessingSettings &settings) { +void JFJochReceiverService::SetSpotFindingSettings(const SpotFindingSettings &settings) { try { std::unique_lock ul(state_mutex); data_processing_settings = settings; if (state != ReceiverState::Idle) - receiver->SetDataProcessingSettings(settings); + receiver->SetSpotFindingSettings(settings); } catch (std::exception &e) { throw; } diff --git a/receiver/JFJochReceiverService.h b/receiver/JFJochReceiverService.h index 52c9ca98..be58e01f 100644 --- a/receiver/JFJochReceiverService.h +++ b/receiver/JFJochReceiverService.h @@ -26,7 +26,7 @@ class JFJochReceiverService { std::condition_variable measurement_done; std::future measurement; void FinalizeMeasurement(); - DataProcessingSettings data_processing_settings; + SpotFindingSettings data_processing_settings; public: JFJochReceiverService(AcquisitionDeviceGroup &aq_devices, Logger &logger, ImagePusher &pusher); @@ -37,13 +37,12 @@ public: JFJochReceiverService& NUMAPolicy(const std::string& policy); void Start(const DiffractionExperiment &experiment, const JFCalibration *calibration); - void Abort(); void Cancel(); JFJochReceiverOutput Stop(); - void SetDataProcessingSettings(const DataProcessingSettings& settings); + void SetSpotFindingSettings(const SpotFindingSettings& settings); Plot GetDataProcessingPlot(const PlotRequest& request); RadialIntegrationProfiles GetRadialIntegrationProfiles(); - JFJochReceiverStatus GetStatus(); + std::optional GetStatus(); std::vector GetNetworkConfig(); }; diff --git a/receiver/JFJochReceiverTest.cpp b/receiver/JFJochReceiverTest.cpp index cc3b0146..ecb9989a 100644 --- a/receiver/JFJochReceiverTest.cpp +++ b/receiver/JFJochReceiverTest.cpp @@ -19,12 +19,12 @@ JFJochReceiverOutput RunJFJochReceiverTest(AcquisitionDeviceGroup &aq_devices, I JFJochReceiverService service(aq_devices, logger, pusher); service.PreviewPublisher(in_preview_writer).NumThreads(nthreads).NUMAPolicy(numa_policy); - DataProcessingSettings settings; + SpotFindingSettings settings; settings.signal_to_noise_threshold = 2.5; settings.photon_count_threshold = 5; settings.min_pix_per_spot = 3; settings.max_pix_per_spot = 200; - service.SetDataProcessingSettings(settings); + service.SetSpotFindingSettings(settings); service.Start(x, &calib); diff --git a/tests/CBORTest.cpp b/tests/CBORTest.cpp index a44b1685..6488869d 100644 --- a/tests/CBORTest.cpp +++ b/tests/CBORTest.cpp @@ -34,7 +34,7 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") { .sensor_material = "Si", .compression_algorithm = CompressionAlgorithm::BSHUF_LZ4, .compression_block_size = 8192, - .unit_cell = {45,37,45,90,108,120}, + .unit_cell = UnitCell{.a = 45,.b = 37, .c = 45, .alpha = 90, .beta = 108,. gamma = 120}, .space_group_number = 154, .max_spot_count = 250, .storage_cell_number = 16, @@ -60,7 +60,9 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") { .rad_int_bin_number = 35, .summation = 567, .rad_int_bin_to_q = {0.1, 0.2, 0.3, 0.5}, - .rad_int_solid_angle_corr = {10, 20, 30, 50} + .rad_int_solid_angle_corr = {10, 20, 30, 50}, + .total_flux = 123, + .attenuator_transmission = 57 }; REQUIRE_NOTHROW(serializer.SerializeSequenceStart(message)); @@ -116,13 +118,22 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") { for (int i = 0; i < 3; i++) CHECK(output_message.detector_translation[i] == message.detector_translation[i]); - for (int i = 0; i < 6; i++) - CHECK(output_message.unit_cell[i] == message.unit_cell[i]); + + CHECK(output_message.unit_cell); + CHECK(output_message.unit_cell->a == message.unit_cell->a); + CHECK(output_message.unit_cell->b == message.unit_cell->b); + CHECK(output_message.unit_cell->c == message.unit_cell->c); + CHECK(output_message.unit_cell->alpha == message.unit_cell->alpha); + CHECK(output_message.unit_cell->beta == message.unit_cell->beta); + CHECK(output_message.unit_cell->gamma == message.unit_cell->gamma); REQUIRE(output_message.goniometer.contains("omega")); CHECK(output_message.goniometer["omega"].increment == 0.1f); CHECK(output_message.goniometer["omega"].start == 10.0f); - + REQUIRE (output_message.total_flux); + CHECK(output_message.total_flux.value() == message.total_flux.value()); + REQUIRE (output_message.attenuator_transmission); + CHECK(output_message.attenuator_transmission.value() == message.attenuator_transmission.value()); } TEST_CASE("CBORSerialize_Start_PixelMask", "[CBOR]") { @@ -670,7 +681,7 @@ TEST_CASE("CBORSerialize_Start_stream2", "[CBOR]") { .sensor_material = "Si", .compression_algorithm = CompressionAlgorithm::BSHUF_LZ4, .compression_block_size = 8192, - .unit_cell = {45,37,45,90,108,120}, + .unit_cell = UnitCell{.a = 45,.b = 37, .c = 45, .alpha = 90, .beta = 108,. gamma = 120}, .space_group_number = 154, .max_spot_count = 250, .storage_cell_number = 16, diff --git a/tests/DiffractionExperimentTest.cpp b/tests/DiffractionExperimentTest.cpp index 20a82599..e0dc8342 100644 --- a/tests/DiffractionExperimentTest.cpp +++ b/tests/DiffractionExperimentTest.cpp @@ -3,8 +3,6 @@ #define CATCH_CONFIG_MAIN #include -#include - #include "../common/DiffractionExperiment.h" #include "../compression/JFJochCompressor.h" #include "../common/NetworkAddressConvert.h" @@ -137,7 +135,7 @@ TEST_CASE("DiffractionExperiment_Compression","[DiffractionExperiment]") { TEST_CASE("DiffractionExperiment_UnitCell","[DiffractionExperiment]") { DiffractionExperiment x; - REQUIRE(!x.HasUnitCell()); + REQUIRE(!x.GetUnitCell()); UnitCell cell{ .a = 10, @@ -149,10 +147,10 @@ TEST_CASE("DiffractionExperiment_UnitCell","[DiffractionExperiment]") { }; REQUIRE_NOTHROW(x.SetUnitCell(cell)); - REQUIRE(x.HasUnitCell()); - REQUIRE(x.GetUnitCell().c == 30); - REQUIRE_NOTHROW(x.SetUnitCell()); - REQUIRE(!x.HasUnitCell()); + REQUIRE(x.GetUnitCell()); + REQUIRE(x.GetUnitCell()->c == 30); + REQUIRE_NOTHROW(x.SetUnitCell({})); + REQUIRE(!x.GetUnitCell()); REQUIRE_NOTHROW(x.SetUnitCell(cell)); } diff --git a/tests/JFJochStateMachineTest.cpp b/tests/JFJochStateMachineTest.cpp index 411e8d37..1279218d 100644 --- a/tests/JFJochStateMachineTest.cpp +++ b/tests/JFJochStateMachineTest.cpp @@ -27,6 +27,7 @@ TEST_CASE("JFJochStateMachine_States") { REQUIRE_THROWS(state_machine.Pedestal()); REQUIRE_NOTHROW(state_machine.Initialize()); + REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Idle); @@ -58,11 +59,12 @@ TEST_CASE("JFJochStateMachine_State_Pedestal") { REQUIRE_THROWS(state_machine.Start(setup)); REQUIRE_THROWS(state_machine.Pedestal()); REQUIRE_THROWS(state_machine.Initialize()); + REQUIRE(state_machine.WaitTillMeasurementDone(std::chrono::milliseconds(1)) == JFJochState::Pedestal); DetectorSettings settings{}; settings.frame_time_us = 500; settings.storage_cell_count = 16; - REQUIRE_THROWS(state_machine.SetDetectorSettings(settings)); + REQUIRE_THROWS(state_machine.LoadDetectorSettings(settings)); } TEST_CASE("JFJochStateMachine_State_Measure") { @@ -88,11 +90,12 @@ TEST_CASE("JFJochStateMachine_State_Measure") { REQUIRE_THROWS(state_machine.Start(setup)); REQUIRE_THROWS(state_machine.Pedestal()); REQUIRE_THROWS(state_machine.Initialize()); + REQUIRE(state_machine.WaitTillMeasurementDone(std::chrono::milliseconds(1)) == JFJochState::Measuring); DetectorSettings settings{}; settings.frame_time_us = 500; settings.storage_cell_count = 16; - REQUIRE_THROWS(state_machine.SetDetectorSettings(settings)); + REQUIRE_THROWS(state_machine.LoadDetectorSettings(settings)); } TEST_CASE("JFJochStateMachine_State_Error") { @@ -118,12 +121,15 @@ TEST_CASE("JFJochStateMachine_State_Error") { REQUIRE_THROWS(state_machine.Start(setup)); REQUIRE_THROWS(state_machine.Pedestal()); + REQUIRE(state_machine.WaitTillMeasurementDone(std::chrono::milliseconds(1)) == JFJochState::Error); + DetectorSettings settings{}; settings.frame_time_us = 500; settings.storage_cell_count = 16; - REQUIRE_NOTHROW(state_machine.SetDetectorSettings(settings)); + REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE_NOTHROW(state_machine.Initialize()); + REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); REQUIRE_NOTHROW(state = state_machine.GetState()); REQUIRE(state == JFJochState::Idle); } @@ -137,7 +143,7 @@ TEST_CASE("JFJochStateMachine_Setup") { DetectorSettings settings{}, settings_save{}; settings.pedestal_g1_frames = -15; settings.pedestal_g0_frames = 2378; - REQUIRE_THROWS(state_machine.SetDetectorSettings(settings)); + REQUIRE_THROWS(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG0Frames() != 2378); settings.pedestal_g2_frames = 2800; @@ -146,7 +152,7 @@ TEST_CASE("JFJochStateMachine_Setup") { settings.storage_cell_count = 16; settings.frame_time_us = 600; settings.count_time_us = 247; - REQUIRE_NOTHROW(state_machine.SetDetectorSettings(settings)); + REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG0Frames() == 2378); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG1Frames() == 3000); REQUIRE(state_machine.NotThreadSafe_Experiment().GetPedestalG2Frames() == 2800); @@ -164,6 +170,7 @@ TEST_CASE("JFJochStateMachine_NoDetectorSetup") { JFJochServices services(logger); JFJochStateMachine state_machine(services, logger); REQUIRE_THROWS(state_machine.Initialize()); + REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); } TEST_CASE("JFJochStateMachine_AddDetectorSetup") { @@ -173,6 +180,7 @@ TEST_CASE("JFJochStateMachine_AddDetectorSetup") { DetectorSetup setup = DetectorGeometry(4); state_machine.AddDetectorSetup(setup); REQUIRE_NOTHROW(state_machine.Initialize()); + REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); } TEST_CASE("JFJochStateMachine_AddDetectorSetup_Gain") { @@ -186,6 +194,7 @@ TEST_CASE("JFJochStateMachine_AddDetectorSetup_Gain") { "../../tests/test_data/gainMaps_M049.bin"}); state_machine.AddDetectorSetup(setup); REQUIRE_NOTHROW(state_machine.Initialize()); + REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); } TEST_CASE("JFJochStateMachine_StorageCells") { @@ -197,9 +206,10 @@ TEST_CASE("JFJochStateMachine_StorageCells") { DetectorSettings settings{}; settings.frame_time_us = 500; settings.storage_cell_count = 16; - REQUIRE_NOTHROW(state_machine.SetDetectorSettings(settings)); + REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellNumber() == 16); REQUIRE_NOTHROW(state_machine.Initialize()); + REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); } TEST_CASE("JFJochStateMachine_AddDetectorSetup_Multiple") { @@ -220,6 +230,7 @@ TEST_CASE("JFJochStateMachine_AddDetectorSetup_Multiple") { REQUIRE(dl.detector[2].nmodules == 1); REQUIRE_NOTHROW(state_machine.Initialize()); + REQUIRE_NOTHROW(state_machine.WaitTillMeasurementDone()); REQUIRE(state_machine.NotThreadSafe_Experiment().GetModulesNum() == 4); REQUIRE(state_machine.GetState() == JFJochState::Idle); @@ -300,7 +311,7 @@ TEST_CASE("JFJochStateMachine_SetDetectorSettings", "[DiffractionExperiment]") { settings.pedestal_g1_frames = 100; settings.pedestal_g2_frames = 150; - REQUIRE_NOTHROW(state_machine.SetDetectorSettings(settings)); + REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameTime().count() == 600); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameCountTime().count() == 400); @@ -327,7 +338,7 @@ TEST_CASE("JFJochStateMachine_SetDetectorSettings_StorageCellDelay", "[Diffracti settings.use_internal_packet_generator = true; settings.collect_raw_data = true; settings.storage_cell_delay_ns = 7000; - REQUIRE_NOTHROW(state_machine.SetDetectorSettings(settings)); + REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetStorageCellDelay().count() == 7000); } @@ -348,7 +359,7 @@ TEST_CASE("JFJochStateMachine_SetDetectorSettings_invalid", "[DiffractionExperim settings.pedestal_g0_frames = 5000; settings.pedestal_g1_frames = 100; settings.pedestal_g2_frames = 150; - REQUIRE_THROWS(state_machine.SetDetectorSettings(settings)); + REQUIRE_THROWS(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameTime().count() == 525); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameCountTime().count() == 525 - READOUT_TIME_IN_US); @@ -370,7 +381,7 @@ TEST_CASE("JFJochStateMachine_SetDetectorSettings_inferred", "[DiffractionExperi DetectorSettings settings{}; settings.frame_time_us = 600; settings.storage_cell_count = 1; - REQUIRE_NOTHROW(state_machine.SetDetectorSettings(settings)); + REQUIRE_NOTHROW(state_machine.LoadDetectorSettings(settings)); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameTime().count() == 600); REQUIRE(state_machine.NotThreadSafe_Experiment().GetFrameCountTime().count() == 600 - READOUT_TIME_IN_US); diff --git a/tests/SpotAnalyzeUnitTest.cpp b/tests/SpotAnalyzeUnitTest.cpp index 3fbc8e57..4d109039 100644 --- a/tests/SpotAnalyzeUnitTest.cpp +++ b/tests/SpotAnalyzeUnitTest.cpp @@ -28,7 +28,7 @@ TEST_CASE("StrongPixelSet_BuildSpots","[StrongPixelSet]") { DiffractionExperiment experiment; experiment.Mode(DetectorMode::Raw); - DataProcessingSettings settings; + SpotFindingSettings settings; settings.low_resolution_limit = 200.0; settings.high_resolution_limit = 0.5; settings.min_pix_per_spot = 3; diff --git a/writer/HDF5NXmx.cpp b/writer/HDF5NXmx.cpp index 5527762c..8f91f549 100644 --- a/writer/HDF5NXmx.cpp +++ b/writer/HDF5NXmx.cpp @@ -104,6 +104,16 @@ void HDF5Metadata::Beam(HDF5File *hdf5_file, const StartMessage &start, const En HDF5Group group(*hdf5_file, "/entry/instrument/beam"); group.NXClass("NXbeam"); SaveScalar(group, "incident_wavelength", start.incident_wavelength)->Units("angstrom"); + if (start.total_flux) + SaveScalar(group, "total_flux", start.total_flux.value())->Units("Hz"); +} + +void HDF5Metadata::Attenuator(HDF5File *hdf5_file, const StartMessage &start, const EndMessage &end) { + if (start.attenuator_transmission) { + HDF5Group group(*hdf5_file, "/entry/instrument/attenuator"); + group.NXClass("NXattenuator"); + SaveScalar(group, "attenuator_transmission", start.attenuator_transmission.value()); + } } void HDF5Metadata::Sample(HDF5File *hdf5_file, const StartMessage &start, const EndMessage &end) { @@ -114,9 +124,9 @@ void HDF5Metadata::Sample(HDF5File *hdf5_file, const StartMessage &start, const if (start.space_group_number > 0) group.SaveScalar("space_group", start.space_group_number); - if (start.unit_cell[0] > 0.0) { - std::vector v = {start.unit_cell[0], start.unit_cell[1], start.unit_cell[2], - start.unit_cell[3], start.unit_cell[4], start.unit_cell[5]}; + if (start.unit_cell) { + std::vector v = {start.unit_cell->a, start.unit_cell->b, start.unit_cell->c, + start.unit_cell->alpha, start.unit_cell->beta, start.unit_cell->gamma}; group.SaveVector("unit_cell", v); } diff --git a/writer/HDF5NXmx.h b/writer/HDF5NXmx.h index 00554787..9536b940 100644 --- a/writer/HDF5NXmx.h +++ b/writer/HDF5NXmx.h @@ -21,6 +21,7 @@ namespace HDF5Metadata { void Beam(HDF5File *hdf5_file, const StartMessage &start, const EndMessage &end); void Metrology(HDF5File *hdf5_file, const StartMessage &start, const EndMessage &end); void Sample(HDF5File *hdf5_file, const StartMessage &start, const EndMessage &end); + void Attenuator(HDF5File *hdf5_file, const StartMessage &start, const EndMessage &end); void Mask(HDF5File *hdf5_file, const StartMessage &start, const EndMessage &end); void Calibration(HDF5File *hdf5_file, const StartMessage &start, const EndMessage &end);