// 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.enable = input.isEnable(); ret.indexing = input.isIndexing(); ret.indexing_tolerance = input.getIndexingTolerance(); 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.setEnable(input.enable); ret.setIndexing(input.indexing); ret.setIndexingTolerance(input.indexing_tolerance); return ret; } inline org::openapitools::server::model::Measurement_statistics Convert(const MeasurementStatistics &input) { org::openapitools::server::model::Measurement_statistics ret{}; if (!input.file_prefix.empty()) ret.setFilePrefix(input.file_prefix); ret.setImagesExpected(input.images_expected); ret.setImagesCollected(input.images_collected); ret.setImagesSent(input.images_sent); ret.setImagesDiscardedLossyCompression(input.images_skipped); ret.setMaxImageNumberSent(input.max_image_number_sent); if (input.collection_efficiency) ret.setCollectionEfficiency(input.collection_efficiency.value()); if (input.compression_ratio) ret.setCompressionRatio(input.compression_ratio.value()); ret.setCancelled(input.cancelled); ret.setMaxReceiverDelay(input.max_receive_delay); ret.setDetectorWidth(input.detector_width); ret.setDetectorHeight(input.detector_height); ret.setDetectorPixelDepth(input.detector_pixel_depth); if (input.indexing_rate) ret.setIndexingRate(input.indexing_rate.value()); if (input.bkg_estimate) ret.setBkgEstimate(input.bkg_estimate.value()); ret.setUnitCell(input.unit_cell); 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(); ret.fixed_gain_g1 = input.isFixedGainG1(); ret.use_gain_hg0 = input.isUseGainHg0(); 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.storageCellDelayUsIsSet() && std::isfinite(input.getStorageCellDelayUs())) ret.storage_cell_delay_ns = std::round(input.getStorageCellDelayUs() * 1000.0f); if (input.detectorTriggerDelayUsIsSet() && std::isfinite(input.getDetectorTriggerDelayUs())) ret.detector_delay_ns = std::round(input.getDetectorTriggerDelayUs() * 1000.0f); if (input.internalFrameGeneratorImagesIsSet()) ret.internal_packet_generator_images = input.getInternalFrameGeneratorImages(); 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); if (input.count_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.setFixedGainG1(input.fixed_gain_g1); ret.setUseGainHg0(input.use_gain_hg0); if (input.pedestal_g0_frames) ret.setPedestalG0Frames(input.pedestal_g0_frames.value()); if (input.pedestal_g1_frames) ret.setPedestalG1Frames(input.pedestal_g1_frames.value()); if (input.pedestal_g2_frames) ret.setPedestalG2Frames(input.pedestal_g2_frames.value()); if (input.storage_cell_delay_ns) ret.setStorageCellDelayUs(static_cast(input.storage_cell_delay_ns.value()) / 1000.0f); if (input.detector_delay_ns) ret.setDetectorTriggerDelayUs(static_cast(input.detector_delay_ns.value()) / 1000.0f); if (input.internal_packet_generator_images) ret.setInternalFrameGeneratorImages(input.internal_packet_generator_images.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() && (input.indexing_rate >= 0.0)) ret.setIndexingRate(input.indexing_rate.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.bad_pixels); output.setStorageCellNumber(input.storage_cell_number); output.setGainG0Mean(input.gain_g0_mean); output.setGainG1Mean(input.gain_g1_mean); output.setGainG2Mean(input.gain_g2_mean); output.setPedestalG0Mean(input.pedestal_g0_mean); output.setPedestalG1Mean(input.pedestal_g1_mean); output.setPedestalG2Mean(input.pedestal_g2_mean); return output; } inline org::openapitools::server::model::Detector_status Convert(const DetectorStatus &input) { org::openapitools::server::model::Detector_status output; output.setServerVersion(input.detector_server_version); output.setNumberOfTriggersLeft(input.remaining_triggers); output.setFpgaTempDegC(input.temperature_fpga_degC); output.setHighVoltageV(input.high_voltage_V); switch (input.power_state) { case DetectorPowerState::ON: output.setPowerchip("On"); break; case DetectorPowerState::OFF: output.setPowerchip("Off"); break; case DetectorPowerState::PARTIAL: output.setPowerchip("Partial"); break; } switch (input.detector_state) { case DetectorState::IDLE: output.setState("Idle"); break; case DetectorState::ERROR: output.setState("Error"); break; case DetectorState::BUSY: output.setState("Busy"); break; case DetectorState::WAITING: output.setState("Waiting"); break; } 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::Plots Convert(const MultiLinePlot& input) { std::vector tmp(input.size()); for (int i = 0; i < input.size(); i++) { tmp[i].setTitle(input[i].title); tmp[i].setX(input[i].x); tmp[i].setY(input[i].y); } org::openapitools::server::model::Plots output; output.setPlot(tmp); return output; } 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 std::vector Convert(const org::openapitools::server::model::Roi_box_list& input) { std::vector ret; for (const auto &i: input.getRois()) ret.emplace_back(ROIBox(i.getName(), i.getMinXPxl(), i.getMaxXPxl(), i.getMinYPxl(), i.getMaxYPxl())); return ret; } inline std::vector Convert(const org::openapitools::server::model::Roi_circle_list& input) { std::vector ret; for (const auto &i: input.getRois()) ret.emplace_back(ROICircle(i.getName(), i.getCenterXPxl(), i.getCenterYPxl(), i.getRadiusPxl())); return ret; } inline org::openapitools::server::model::Roi_circle_list Convert(const std::vector &input) { org::openapitools::server::model::Roi_circle_list ret{}; std::vector tmp; for (const auto &i: input) { org::openapitools::server::model::Roi_circle elem; elem.setName(i.GetName()); elem.setCenterXPxl(i.GetX()); elem.setCenterYPxl(i.GetY()); elem.setRadiusPxl(i.GetRadius_pxl()); tmp.emplace_back(elem); } ret.setRois(tmp); return ret; } inline org::openapitools::server::model::Roi_box_list Convert(const std::vector &input) { org::openapitools::server::model::Roi_box_list ret{}; std::vector tmp; for (const auto &i: input) { org::openapitools::server::model::Roi_box elem; elem.setName(i.GetName()); elem.setMinXPxl(i.GetXMin()); elem.setMaxXPxl(i.GetXMax()); elem.setMinYPxl(i.GetYMin()); elem.setMaxYPxl(i.GetYMax()); tmp.emplace_back(elem); } ret.setRois(tmp); return ret; } inline PreviewJPEGSettings Convert(const org::openapitools::server::model::Preview_settings& input) { PreviewJPEGSettings ret{}; ret.show_spots = input.isShowSpots(); ret.jpeg_quality = input.getJpegQuality(); ret.saturation_value = input.getSaturation(); ret.show_roi = input.isShowRoi(); ret.show_indexed = input.isShowIndexed(); if (input.resolutionRingIsSet()) ret.resolution_ring = input.getResolutionRing(); return ret; } inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_settings& input) { DatasetSettings ret; ret.ImagesPerTrigger(input.getImagesPerTrigger()); ret.NumTriggers(input.getNtrigger()); if (!input.fpgaOutputIsSet()) ret.FPGAOutputMode(FPGAPixelOutput::Auto); else { std::string out = str_tolower(input.getFpgaOutput()); if (out == "auto") ret.FPGAOutputMode(FPGAPixelOutput::Auto); else if (out == "int16") ret.FPGAOutputMode(FPGAPixelOutput::Int16); else if (out == "uint16") ret.FPGAOutputMode(FPGAPixelOutput::Uint16); else if (out == "int32") ret.FPGAOutputMode(FPGAPixelOutput::Int32); else if (out == "uint32") ret.FPGAOutputMode(FPGAPixelOutput::Uint32); else throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown output format"); } ret.Summation(input.getSummation()); ret.BeamX_pxl(input.getBeamXPxl()); ret.BeamY_pxl(input.getBeamYPxl()); ret.DetectorDistance_mm(input.getDetectorDistanceMm()); ret.PhotonEnergy_keV(input.getPhotonEnergyKeV()); ret.PhotonEnergyMultiplayer(input.getPhotonEnergyMultiplier()); ret.FilePrefix(input.getFilePrefix()); if (!input.compressionIsSet()) ret.Compression(CompressionAlgorithm::BSHUF_LZ4); else { std::string compr = str_tolower(input.getCompression()); if (compr == "bslz4") ret.Compression(CompressionAlgorithm::BSHUF_LZ4); else if (compr == "bszstd") ret.Compression(CompressionAlgorithm::BSHUF_ZSTD); else if (compr == "bszstd_rle") ret.Compression(CompressionAlgorithm::BSHUF_ZSTD_RLE); else if (compr == "none") ret.Compression(CompressionAlgorithm::NO_COMPRESSION); else throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown compression"); } if (input.unitCellIsSet()) ret.SetUnitCell(UnitCell{ .a = input.getUnitCell().getA(), .b = input.getUnitCell().getB(), .c = input.getUnitCell().getC(), .alpha = input.getUnitCell().getAlpha(), .beta = input.getUnitCell().getBeta(), .gamma = input.getUnitCell().getGamma() }); if (input.totalFluxIsSet()) ret.TotalFlux(input.getTotalFlux()); if (input.transmissionIsSet()) ret.AttenuatorTransmission(input.getTransmission()); if (input.omegaIsSet()) { ret.OmegaStep(input.getOmega().getStep()); ret.OmegaStart(input.getOmega().getStart()); if (input.getOmega().getVector().size() == 3) { auto v = input.getOmega().getVector(); ret.OmegaAxis(Coord(v[0], v[1], v[2])); } } ret.SpaceGroupNumber(input.getSpaceGroupNumber()); ret.SampleName(input.getSampleName()); ret.HeaderAppendix(input.getHeaderAppendix()); ret.ImageAppendix(input.getImageAppendix()); ret.ImagesPerFile(input.getImagesPerFile()); if (input.dataReductionFactorSerialmxIsSet()) ret.DataReductionFactorSerialMX(input.getDataReductionFactorSerialmx()); return ret; } 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(); response.send(Pistache::Http::Code::Ok); } 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.SetRadialIntegrationSettings(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_indexing_rate_per_file_get(Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::IndexingRatePerTimePoint, 0, response); } void JFJochBrokerHttp::plot_rad_int_get(Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::RadInt, 0, response); } void JFJochBrokerHttp::plot_rad_int_per_file_get(Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::RadIntPerTimePoint, 0, 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; } void JFJochBrokerHttp::detector_status_get(Pistache::Http::ResponseWriter &response) { auto out = state_machine.GetDetectorStatus(); if (out) ProcessOutput(Convert(out.value()), response); else response.send(Pistache::Http::Code::Not_Found); } void JFJochBrokerHttp::preview_calibration_tiff_get(Pistache::Http::ResponseWriter &response) { std::string s = state_machine.GetPreviewTIFF(true); if (!s.empty()) response.send(Pistache::Http::Code::Ok, s, Pistache::Http::Mime::MediaType::fromString("image/tiff")); else response.send(Pistache::Http::Code::Not_Found); } void JFJochBrokerHttp::preview_image_jpeg_post(const org::openapitools::server::model::Preview_settings &previewSettings, Pistache::Http::ResponseWriter &response) { std::string s = state_machine.GetPreviewJPEG(Convert(previewSettings)); if (!s.empty()) response.send(Pistache::Http::Code::Ok, s, Pistache::Http::Mime::MediaType::fromString("image/jpeg")); else response.send(Pistache::Http::Code::Not_Found); } void JFJochBrokerHttp::preview_image_jpeg_get(Pistache::Http::ResponseWriter &response) { std::string s = state_machine.GetPreviewJPEG(PreviewJPEGSettings()); if (!s.empty()) response.send(Pistache::Http::Code::Ok, s, Pistache::Http::Mime::MediaType::fromString("image/jpeg")); else response.send(Pistache::Http::Code::Not_Found); } void JFJochBrokerHttp::preview_image_tiff_get(Pistache::Http::ResponseWriter &response) { std::string s = state_machine.GetPreviewTIFF(false); if (!s.empty()) response.send(Pistache::Http::Code::Ok, s, Pistache::Http::Mime::MediaType::fromString("image/tiff")); else response.send(Pistache::Http::Code::Not_Found); } void JFJochBrokerHttp::config_internal_generator_image_put(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter &response) { int64_t image_number = 0; auto number_query = request.query().get("number"); if (number_query) image_number = std::stoi(number_query.value()); if ((image_number < 0) || (image_number > 127)) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "image_number must be in range 0-127"); state_machine.LoadInternalGeneratorImage(request.body().data(), request.body().size(), image_number); logger.Info("Internal generator image #{} loaded", image_number); response.send(Pistache::Http::Code::Ok); } void JFJochBrokerHttp::roi_box_get(Pistache::Http::ResponseWriter &response) { ProcessOutput(Convert(state_machine.GetBoxROI()), response); } void JFJochBrokerHttp::roi_box_put(const org::openapitools::server::model::Roi_box_list &roiBoxList, Pistache::Http::ResponseWriter &response) { state_machine.SetBoxROI(Convert(roiBoxList)); response.send(Pistache::Http::Code::Ok); } void JFJochBrokerHttp::roi_circle_get(Pistache::Http::ResponseWriter &response) { ProcessOutput(Convert(state_machine.GetCircleROI()), response); } void JFJochBrokerHttp::roi_circle_put(const org::openapitools::server::model::Roi_circle_list &roiCircleList, Pistache::Http::ResponseWriter &response) { state_machine.SetCircleROI(Convert(roiCircleList)); response.send(Pistache::Http::Code::Ok); } void JFJochBrokerHttp::xfel_event_code_get(Pistache::Http::ResponseWriter &response) { auto array = state_machine.GetXFELEventCode(); if (array.empty()) response.send(Pistache::Http::Code::Not_Found); nlohmann::json j = array; response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json)); } void JFJochBrokerHttp::xfel_pulse_id_get(Pistache::Http::ResponseWriter &response) { auto array = state_machine.GetXFELPulseID(); if (array.empty()) response.send(Pistache::Http::Code::Not_Found); nlohmann::json j = array; response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json)); } void JFJochBrokerHttp::preview_pedestal_tiff_get(const std::optional &gainLevel, const std::optional &sc, Pistache::Http::ResponseWriter &response) { if (!gainLevel) response.send(Pistache::Http::Code::Bad_Request); std::string s = state_machine.GetPedestalTIFF(gainLevel.value(), sc ? sc.value() : 0); if (!s.empty()) response.send(Pistache::Http::Code::Ok, s, Pistache::Http::Mime::MediaType::fromString("image/tiff")); else response.send(Pistache::Http::Code::Not_Found); } void JFJochBrokerHttp::GenericPlot(PlotType plot_type, const std::optional &binning, Pistache::Http::ResponseWriter &response) { PlotRequest req{.type = plot_type, .binning = 0}; if (binning) { if (binning.value() < 0) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Binning must be positive number or zero"); req.binning = binning.value(); } auto plot = state_machine.GetPlots(req); ProcessOutput(Convert(plot), response); } void JFJochBrokerHttp::plot_bkg_estimate_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::BkgEstimate, binning, response); } void JFJochBrokerHttp::plot_error_pixel_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::ErrorPixels, binning, response); } void JFJochBrokerHttp::plot_image_collection_efficiency_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::ImageCollectionEfficiency, binning, response); } void JFJochBrokerHttp::plot_indexing_rate_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::IndexingRate, binning, response); } void JFJochBrokerHttp::plot_receiver_delay_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::ReceiverDelay, binning, response); } void JFJochBrokerHttp::plot_receiver_free_send_buffers_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::ReceiverFreeSendBuf, binning, response); } void JFJochBrokerHttp::plot_roi_max_count_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::ROIMaxCount, binning, response); } void JFJochBrokerHttp::plot_roi_sum_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::ROISum, binning, response); } void JFJochBrokerHttp::plot_roi_valid_pixels_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::ROIPixels, binning, response); } void JFJochBrokerHttp::plot_spot_count_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::SpotCount, binning, response); } void JFJochBrokerHttp::plot_strong_pixel_get(const std::optional &binning, Pistache::Http::ResponseWriter &response) { GenericPlot(PlotType::StrongPixels, binning, response); }