Compare commits

...

4 Commits

Author SHA1 Message Date
53b5a304d3 Merge branch '2406-openapi-python-client' into 'main'
Minor modifications to jfjoch_writer and OpenAPI

See merge request jungfraujoch/nextgendcu!72
2024-06-28 20:44:51 +02:00
30a92d8eb9 Minor modifications to jfjoch_writer and OpenAPI 2024-06-28 20:44:51 +02:00
81df571961 Merge branch '2406-after-crmx' into 'main'
Modifications after CristallinaMX beamtime

See merge request jungfraujoch/nextgendcu!71
2024-06-27 20:26:11 +02:00
1717e171b9 Modifications after CristallinaMX beamtime 2024-06-27 20:26:11 +02:00
98 changed files with 1713 additions and 1784 deletions

View File

@@ -134,7 +134,12 @@ IF (NOT JFJOCH_WRITER_ONLY)
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/
DESTINATION /usr/src/jfjoch-1.0.0
COMPONENT driver-dkms
FILES_MATCHING PATTERN "*.c" PATTERN "*.h" PATTERN "Makefile" PATTERN "dkms.conf")
FILES_MATCHING PATTERN "dkms.conf")
INSTALL(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/fpga/pcie_driver/
DESTINATION /usr/src/jfjoch-1.0.0/src
COMPONENT driver-dkms
FILES_MATCHING PATTERN "*.c" PATTERN "*.h" PATTERN "Makefile")
FILE(MAKE_DIRECTORY ${CMAKE_SOURCE_DIR}/frontend_ui/build/)
INSTALL(DIRECTORY ${CMAKE_SOURCE_DIR}/frontend_ui/build/ DESTINATION share/jfjoch/frontend COMPONENT jfjoch )

View File

@@ -1 +1 @@
1.0.0_rc.9
1.0.0_rc.10

View File

@@ -5,6 +5,7 @@
#include "JFJochBrokerHttp.h"
#include "gen/model/Error_message.h"
#include "../preview/JFJochTIFF.h"
#include "../common/GitInfo.h"
// From https://en.cppreference.com/w/cpp/string/byte/tolower
inline std::string str_tolower(std::string s) {
@@ -339,6 +340,9 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
if (input.runNumberIsSet())
ret.RunNumber(input.getRunNumber());
if (input.runNameIsSet())
ret.RunName(input.getRunName());
ret.ExperimentGroup(input.getExperimentGroup());
if (!input.fpgaOutputIsSet())
@@ -359,7 +363,8 @@ inline DatasetSettings Convert(const org::openapitools::server::model::Dataset_s
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Unknown output format");
}
ret.Summation(input.getSummation());
if (input.imageTimeUsIsSet())
ret.ImageTime(std::chrono::microseconds(input.getImageTimeUs()));
ret.BeamX_pxl(input.getBeamXPxl());
ret.BeamY_pxl(input.getBeamYPxl());
ret.DetectorDistance_mm(input.getDetectorDistanceMm());
@@ -828,3 +833,7 @@ void JFJochBrokerHttp::config_user_mask_tiff_put(const Pistache::Rest::Request &
state_machine.SetUserPixelMask(request.body());
response.send(Pistache::Http::Code::Ok);
}
void JFJochBrokerHttp::version_get(Pistache::Http::ResponseWriter &response) {
response.send(Pistache::Http::Code::Ok, jfjoch_version(), MIME(Text, Plain));
}

View File

@@ -143,6 +143,9 @@ class JFJochBrokerHttp : public org::openapitools::server::api::DefaultApi {
to_json(j, output);
response.send(Pistache::Http::Code::Ok, j.dump(), MIME(Application, Json));
}
void version_get(Pistache::Http::ResponseWriter &response) override;
public:
JFJochBrokerHttp(const DiffractionExperiment& experiment, std::shared_ptr<Pistache::Rest::Router> &rtr);
void AddDetectorSetup(const DetectorSetup &setup);

View File

@@ -283,7 +283,8 @@ DetectorSetup ParseDetectorSetup(const nlohmann::json &j) {
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"));
.SensorMaterial(GET_STR(j, "sensor_material", "Si"))
.SerialNumber(GET_STR(j, "serial_number",""));
if (j.contains("tx_delay"))
setup.TxDelay(GET_I64_ARR(j, "tx_delay"));

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
@@ -79,6 +79,7 @@ void DefaultApi::setupRoutes() {
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::Get(*router, base + "/version", Routes::bind(&DefaultApi::version_get_handler, this));
Routes::Post(*router, base + "/wait_till_done", Routes::bind(&DefaultApi::wait_till_done_post_handler, this));
Routes::Get(*router, base + "/xfel/event_code", Routes::bind(&DefaultApi::xfel_event_code_get_handler, this));
Routes::Get(*router, base + "/xfel/pulse_id", Routes::bind(&DefaultApi::xfel_pulse_id_get_handler, this));
@@ -1253,6 +1254,26 @@ void DefaultApi::trigger_post_handler(const Pistache::Rest::Request &, Pistache:
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
}
}
void DefaultApi::version_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
try {
try {
this->version_get(response);
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
const std::pair<Pistache::Http::Code, std::string> 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 {

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
@@ -103,6 +103,7 @@ private:
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 version_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void wait_till_done_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void xfel_event_code_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void xfel_pulse_id_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
@@ -468,6 +469,13 @@ private:
/// </remarks>
virtual void trigger_post(Pistache::Http::ResponseWriter &response) = 0;
/// <summary>
///
/// </summary>
/// <remarks>
///
/// </remarks>
virtual void version_get(Pistache::Http::ResponseWriter &response) = 0;
/// <summary>
/// Wait for acquisition done
/// </summary>
/// <remarks>

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
@@ -25,8 +25,8 @@ Dataset_settings::Dataset_settings()
m_Images_per_triggerIsSet = false;
m_Ntrigger = 1L;
m_NtriggerIsSet = false;
m_Summation = 1L;
m_SummationIsSet = false;
m_Image_time_us = 0L;
m_Image_time_usIsSet = false;
m_Beam_x_pxl = 0.0f;
m_Beam_y_pxl = 0.0f;
m_Detector_distance_mm = 0.0f;
@@ -47,9 +47,7 @@ Dataset_settings::Dataset_settings()
m_Transmission = 0.0f;
m_TransmissionIsSet = false;
m_GoniometerIsSet = false;
m_Header_appendix = "";
m_Header_appendixIsSet = false;
m_Image_appendix = "";
m_Image_appendixIsSet = false;
m_Energy_multiplier = 1.0f;
m_Energy_multiplierIsSet = false;
@@ -57,6 +55,8 @@ Dataset_settings::Dataset_settings()
m_Data_reduction_factor_serialmxIsSet = false;
m_Run_number = 0L;
m_Run_numberIsSet = false;
m_Run_name = "";
m_Run_nameIsSet = false;
m_Experiment_group = "";
m_Experiment_groupIsSet = false;
m_Unit_cellIsSet = false;
@@ -111,21 +111,16 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
}
if (summationIsSet())
if (imageTimeUsIsSet())
{
const int64_t& value = m_Summation;
const std::string currentValuePath = _pathPrefix + ".summation";
const int64_t& value = m_Image_time_us;
const std::string currentValuePath = _pathPrefix + ".imageTimeUs";
if (value < 1ll)
if (value < 0ll)
{
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;";
msg << currentValuePath << ": must be greater than or equal to 0;";
}
}
@@ -261,7 +256,7 @@ bool Dataset_settings::validate(std::stringstream& msg, const std::string& pathP
}
}
return success;
}
@@ -277,7 +272,7 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
((!ntriggerIsSet() && !rhs.ntriggerIsSet()) || (ntriggerIsSet() && rhs.ntriggerIsSet() && getNtrigger() == rhs.getNtrigger())) &&
((!summationIsSet() && !rhs.summationIsSet()) || (summationIsSet() && rhs.summationIsSet() && getSummation() == rhs.getSummation())) &&
((!imageTimeUsIsSet() && !rhs.imageTimeUsIsSet()) || (imageTimeUsIsSet() && rhs.imageTimeUsIsSet() && getImageTimeUs() == rhs.getImageTimeUs())) &&
(getBeamXPxl() == rhs.getBeamXPxl())
&&
@@ -334,6 +329,9 @@ bool Dataset_settings::operator==(const Dataset_settings& rhs) const
((!runNumberIsSet() && !rhs.runNumberIsSet()) || (runNumberIsSet() && rhs.runNumberIsSet() && getRunNumber() == rhs.getRunNumber())) &&
((!runNameIsSet() && !rhs.runNameIsSet()) || (runNameIsSet() && rhs.runNameIsSet() && getRunName() == rhs.getRunName())) &&
((!experimentGroupIsSet() && !rhs.experimentGroupIsSet()) || (experimentGroupIsSet() && rhs.experimentGroupIsSet() && getExperimentGroup() == rhs.getExperimentGroup())) &&
@@ -354,8 +352,8 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
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;
if(o.imageTimeUsIsSet())
j["image_time_us"] = o.m_Image_time_us;
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;
@@ -387,6 +385,8 @@ void to_json(nlohmann::json& j, const Dataset_settings& o)
j["data_reduction_factor_serialmx"] = o.m_Data_reduction_factor_serialmx;
if(o.runNumberIsSet())
j["run_number"] = o.m_Run_number;
if(o.runNameIsSet())
j["run_name"] = o.m_Run_name;
if(o.experimentGroupIsSet())
j["experiment_group"] = o.m_Experiment_group;
if(o.unitCellIsSet())
@@ -406,10 +406,10 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
j.at("ntrigger").get_to(o.m_Ntrigger);
o.m_NtriggerIsSet = true;
}
if(j.find("summation") != j.end())
if(j.find("image_time_us") != j.end())
{
j.at("summation").get_to(o.m_Summation);
o.m_SummationIsSet = true;
j.at("image_time_us").get_to(o.m_Image_time_us);
o.m_Image_time_usIsSet = 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);
@@ -481,6 +481,11 @@ void from_json(const nlohmann::json& j, Dataset_settings& o)
j.at("run_number").get_to(o.m_Run_number);
o.m_Run_numberIsSet = true;
}
if(j.find("run_name") != j.end())
{
j.at("run_name").get_to(o.m_Run_name);
o.m_Run_nameIsSet = true;
}
if(j.find("experiment_group") != j.end())
{
j.at("experiment_group").get_to(o.m_Experiment_group);
@@ -528,22 +533,22 @@ void Dataset_settings::unsetNtrigger()
{
m_NtriggerIsSet = false;
}
int64_t Dataset_settings::getSummation() const
int64_t Dataset_settings::getImageTimeUs() const
{
return m_Summation;
return m_Image_time_us;
}
void Dataset_settings::setSummation(int64_t const value)
void Dataset_settings::setImageTimeUs(int64_t const value)
{
m_Summation = value;
m_SummationIsSet = true;
m_Image_time_us = value;
m_Image_time_usIsSet = true;
}
bool Dataset_settings::summationIsSet() const
bool Dataset_settings::imageTimeUsIsSet() const
{
return m_SummationIsSet;
return m_Image_time_usIsSet;
}
void Dataset_settings::unsetSummation()
void Dataset_settings::unsetImage_time_us()
{
m_SummationIsSet = false;
m_Image_time_usIsSet = false;
}
float Dataset_settings::getBeamXPxl() const
{
@@ -721,11 +726,11 @@ void Dataset_settings::unsetGoniometer()
{
m_GoniometerIsSet = false;
}
std::string Dataset_settings::getHeaderAppendix() const
nlohmann::json Dataset_settings::getHeaderAppendix() const
{
return m_Header_appendix;
}
void Dataset_settings::setHeaderAppendix(std::string const& value)
void Dataset_settings::setHeaderAppendix(nlohmann::json const& value)
{
m_Header_appendix = value;
m_Header_appendixIsSet = true;
@@ -738,11 +743,11 @@ void Dataset_settings::unsetHeader_appendix()
{
m_Header_appendixIsSet = false;
}
std::string Dataset_settings::getImageAppendix() const
nlohmann::json Dataset_settings::getImageAppendix() const
{
return m_Image_appendix;
}
void Dataset_settings::setImageAppendix(std::string const& value)
void Dataset_settings::setImageAppendix(nlohmann::json const& value)
{
m_Image_appendix = value;
m_Image_appendixIsSet = true;
@@ -806,6 +811,23 @@ void Dataset_settings::unsetRun_number()
{
m_Run_numberIsSet = false;
}
std::string Dataset_settings::getRunName() const
{
return m_Run_name;
}
void Dataset_settings::setRunName(std::string const& value)
{
m_Run_name = value;
m_Run_nameIsSet = true;
}
bool Dataset_settings::runNameIsSet() const
{
return m_Run_nameIsSet;
}
void Dataset_settings::unsetRun_name()
{
m_Run_nameIsSet = false;
}
std::string Dataset_settings::getExperimentGroup() const
{
return m_Experiment_group;

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
@@ -19,6 +19,7 @@
#define Dataset_settings_H_
#include <nlohmann/json.hpp>
#include "Rotation_axis.h"
#include <string>
#include "Dataset_settings_unit_cell.h"
@@ -75,12 +76,12 @@ public:
bool ntriggerIsSet() const;
void unsetNtrigger();
/// <summary>
/// FPGA frame summation. For summation above two 32-bit pixel format will be used, unless explicitly specified. Frame summation factor applies only to conversion mode (assumed as 1 for raw data). In XFEL mode: summation happens for frames collected with multiple triggers. Ignored for storage cells (assumed as 1).
/// Image time. If not provided (or zero value) the frame time is assumed as default. For JUNGFRAU, image time must be multiple of frame time, up to 256 * frame_time. In XFEL mode: summation happens for frames collected with multiple triggers. Ignored for storage cells and if raw data are saved.
/// </summary>
int64_t getSummation() const;
void setSummation(int64_t const value);
bool summationIsSet() const;
void unsetSummation();
int64_t getImageTimeUs() const;
void setImageTimeUs(int64_t const value);
bool imageTimeUsIsSet() const;
void unsetImage_time_us();
/// <summary>
/// /entry/detector/beam_center_x in NXmx Beam center in X direction [pixels]
/// </summary>
@@ -163,17 +164,17 @@ public:
bool goniometerIsSet() const;
void unsetGoniometer();
/// <summary>
/// Header appendix, added as user_data to start message
/// Header appendix, added as user_data/user to start message (can be any valid JSON)
/// </summary>
std::string getHeaderAppendix() const;
void setHeaderAppendix(std::string const& value);
nlohmann::json getHeaderAppendix() const;
void setHeaderAppendix(nlohmann::json const& value);
bool headerAppendixIsSet() const;
void unsetHeader_appendix();
/// <summary>
/// Image appendix, added as user_data to image message
/// Image appendix, added as user_data to image message (can be any valid JSON)
/// </summary>
std::string getImageAppendix() const;
void setImageAppendix(std::string const& value);
nlohmann::json getImageAppendix() const;
void setImageAppendix(nlohmann::json const& value);
bool imageAppendixIsSet() const;
void unsetImage_appendix();
/// <summary>
@@ -198,6 +199,13 @@ public:
bool runNumberIsSet() const;
void unsetRun_number();
/// <summary>
/// Unique ID of run. Transferred over CBOR stream as \&quot;unique series ID\&quot;, though not saved in HDF5 file. It is highly recommended to keep this name unique for each data collection during experimental series. If not provided, the name will be automatically generated as number + colon + file_prefix.
/// </summary>
std::string getRunName() const;
void setRunName(std::string const& value);
bool runNameIsSet() const;
void unsetRun_name();
/// <summary>
/// Name of group owning the data (e.g. p-group or proposal number). Transferred over CBOR stream, though not saved in HDF5 file.
/// </summary>
std::string getExperimentGroup() const;
@@ -219,8 +227,8 @@ protected:
bool m_Images_per_triggerIsSet;
int64_t m_Ntrigger;
bool m_NtriggerIsSet;
int64_t m_Summation;
bool m_SummationIsSet;
int64_t m_Image_time_us;
bool m_Image_time_usIsSet;
float m_Beam_x_pxl;
float m_Beam_y_pxl;
@@ -247,9 +255,9 @@ protected:
bool m_TransmissionIsSet;
org::openapitools::server::model::Rotation_axis m_Goniometer;
bool m_GoniometerIsSet;
std::string m_Header_appendix;
nlohmann::json m_Header_appendix;
bool m_Header_appendixIsSet;
std::string m_Image_appendix;
nlohmann::json m_Image_appendix;
bool m_Image_appendixIsSet;
float m_Energy_multiplier;
bool m_Energy_multiplierIsSet;
@@ -257,6 +265,8 @@ protected:
bool m_Data_reduction_factor_serialmxIsSet;
int64_t m_Run_number;
bool m_Run_numberIsSet;
std::string m_Run_name;
bool m_Run_nameIsSet;
std::string m_Experiment_group;
bool m_Experiment_groupIsSet;
org::openapitools::server::model::Dataset_settings_unit_cell m_Unit_cell;

View File

@@ -1,133 +0,0 @@
/**
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "Dataset_settings_roi_sum_area.h"
#include "Helpers.h"
#include <sstream>
namespace org::openapitools::server::model
{
Dataset_settings_roi_sum_area::Dataset_settings_roi_sum_area()
{
m_X_min = 0L;
m_X_max = 0L;
m_Y_min = 0L;
m_Y_max = 0L;
}
void Dataset_settings_roi_sum_area::validate() const
{
std::stringstream msg;
if (!validate(msg))
{
throw org::openapitools::server::helpers::ValidationException(msg.str());
}
}
bool Dataset_settings_roi_sum_area::validate(std::stringstream& msg) const
{
return validate(msg, "");
}
bool Dataset_settings_roi_sum_area::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Dataset_settings_roi_sum_area" : pathPrefix;
return success;
}
bool Dataset_settings_roi_sum_area::operator==(const Dataset_settings_roi_sum_area& rhs) const
{
return
(getXMin() == rhs.getXMin())
&&
(getXMax() == rhs.getXMax())
&&
(getYMin() == rhs.getYMin())
&&
(getYMax() == rhs.getYMax())
;
}
bool Dataset_settings_roi_sum_area::operator!=(const Dataset_settings_roi_sum_area& rhs) const
{
return !(*this == rhs);
}
void to_json(nlohmann::json& j, const Dataset_settings_roi_sum_area& o)
{
j = nlohmann::json();
j["x_min"] = o.m_X_min;
j["x_max"] = o.m_X_max;
j["y_min"] = o.m_Y_min;
j["y_max"] = o.m_Y_max;
}
void from_json(const nlohmann::json& j, Dataset_settings_roi_sum_area& o)
{
j.at("x_min").get_to(o.m_X_min);
j.at("x_max").get_to(o.m_X_max);
j.at("y_min").get_to(o.m_Y_min);
j.at("y_max").get_to(o.m_Y_max);
}
int64_t Dataset_settings_roi_sum_area::getXMin() const
{
return m_X_min;
}
void Dataset_settings_roi_sum_area::setXMin(int64_t const value)
{
m_X_min = value;
}
int64_t Dataset_settings_roi_sum_area::getXMax() const
{
return m_X_max;
}
void Dataset_settings_roi_sum_area::setXMax(int64_t const value)
{
m_X_max = value;
}
int64_t Dataset_settings_roi_sum_area::getYMin() const
{
return m_Y_min;
}
void Dataset_settings_roi_sum_area::setYMin(int64_t const value)
{
m_Y_min = value;
}
int64_t Dataset_settings_roi_sum_area::getYMax() const
{
return m_Y_max;
}
void Dataset_settings_roi_sum_area::setYMax(int64_t const value)
{
m_Y_max = value;
}
} // namespace org::openapitools::server::model

View File

@@ -1,97 +0,0 @@
/**
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* Dataset_settings_roi_sum_area.h
*
* Rectangle for ROI summation
*/
#ifndef Dataset_settings_roi_sum_area_H_
#define Dataset_settings_roi_sum_area_H_
#include <nlohmann/json.hpp>
namespace org::openapitools::server::model
{
/// <summary>
/// Rectangle for ROI summation
/// </summary>
class Dataset_settings_roi_sum_area
{
public:
Dataset_settings_roi_sum_area();
virtual ~Dataset_settings_roi_sum_area() = default;
/// <summary>
/// Validate the current data in the model. Throws a ValidationException on failure.
/// </summary>
void validate() const;
/// <summary>
/// Validate the current data in the model. Returns false on error and writes an error
/// message into the given stringstream.
/// </summary>
bool validate(std::stringstream& msg) const;
/// <summary>
/// Helper overload for validate. Used when one model stores another model and calls it's validate.
/// Not meant to be called outside that case.
/// </summary>
bool validate(std::stringstream& msg, const std::string& pathPrefix) const;
bool operator==(const Dataset_settings_roi_sum_area& rhs) const;
bool operator!=(const Dataset_settings_roi_sum_area& rhs) const;
/////////////////////////////////////////////
/// Dataset_settings_roi_sum_area members
/// <summary>
///
/// </summary>
int64_t getXMin() const;
void setXMin(int64_t const value);
/// <summary>
///
/// </summary>
int64_t getXMax() const;
void setXMax(int64_t const value);
/// <summary>
///
/// </summary>
int64_t getYMin() const;
void setYMin(int64_t const value);
/// <summary>
///
/// </summary>
int64_t getYMax() const;
void setYMax(int64_t const value);
friend void to_json(nlohmann::json& j, const Dataset_settings_roi_sum_area& o);
friend void from_json(const nlohmann::json& j, Dataset_settings_roi_sum_area& o);
protected:
int64_t m_X_min;
int64_t m_X_max;
int64_t m_Y_min;
int64_t m_Y_max;
};
} // namespace org::openapitools::server::model
#endif /* Dataset_settings_roi_sum_area_H_ */

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -1,106 +0,0 @@
/**
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "Plot_request.h"
#include "Helpers.h"
#include <sstream>
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

View File

@@ -1,78 +0,0 @@
/**
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* Plot_request.h
*
*
*/
#ifndef Plot_request_H_
#define Plot_request_H_
#include <nlohmann/json.hpp>
namespace org::openapitools::server::model
{
/// <summary>
///
/// </summary>
class Plot_request
{
public:
Plot_request();
virtual ~Plot_request() = default;
/// <summary>
/// Validate the current data in the model. Throws a ValidationException on failure.
/// </summary>
void validate() const;
/// <summary>
/// Validate the current data in the model. Returns false on error and writes an error
/// message into the given stringstream.
/// </summary>
bool validate(std::stringstream& msg) const;
/// <summary>
/// Helper overload for validate. Used when one model stores another model and calls it's validate.
/// Not meant to be called outside that case.
/// </summary>
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
/// <summary>
///
/// </summary>
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_ */

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,8 +2,8 @@
* Jungfraujoch
* Jungfraujoch Broker Web API
*
* The version of the OpenAPI document: 1.0.1
*
* The version of the OpenAPI document: 1.0.0_rc.10
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech

View File

@@ -2,7 +2,9 @@ openapi: 3.0.3
info:
title: Jungfraujoch
description: Jungfraujoch Broker Web API
version: 1.0.1
version: 1.0.0_rc.10
contact:
email: filip.leonarski@psi.ch
components:
schemas:
rotation_axis:
@@ -61,17 +63,16 @@ components:
minimum: 1
description: |
Number of TTL trigger that the detector is expected to receive during data collection
summation:
image_time_us:
type: integer
format: int64
minimum: 1
maximum: 256
default: 1
minimum: 0
description: |
FPGA frame summation. For summation above two 32-bit pixel format will be used, unless explicitly specified.
Frame summation factor applies only to conversion mode (assumed as 1 for raw data).
Image time.
If not provided (or zero value) the frame time is assumed as default.
Image time must be multiple of frame time; max value is 256 * frame_time.
In XFEL mode: summation happens for frames collected with multiple triggers.
Ignored for storage cells (assumed as 1).
Ignored for storage cells and if raw data are saved.
beam_x_pxl:
type: number
format: float
@@ -156,11 +157,9 @@ components:
goniometer:
$ref: "#/components/schemas/rotation_axis"
header_appendix:
type: string
description: Header appendix, added as user_data to start message
description: Header appendix, added as user_data/user to start message (can be any valid JSON)
image_appendix:
type: string
description: Image appendix, added as user_data to image message
description: Image appendix, added as user_data to image message (can be any valid JSON)
energy_multiplier:
type: number
format: float
@@ -187,6 +186,13 @@ components:
Transferred over CBOR stream as "series ID", though not saved in HDF5 file.
It is highly recommended to keep this number unique for each data collection during experimental series.
If not provided, the number will be automatically incremented.
run_name:
type: string
description: |
Unique ID of run.
Transferred over CBOR stream as "unique series ID", though not saved in HDF5 file.
It is highly recommended to keep this name unique for each data collection during experimental series.
If not provided, the name will be automatically generated as number + colon + file_prefix.
experiment_group:
type: string
description: |
@@ -1724,4 +1730,14 @@ paths:
type: string
format: binary
"404":
description: No calibration recorded so far
description: No calibration recorded so far
/version:
get:
responses:
"200":
description: Release number of Jungfraujoch
content:
text/plain:
schema:
type: string
example: 1.0.0

File diff suppressed because one or more lines are too long

View File

@@ -17,8 +17,11 @@ int32_t get_gpu_count() {
void set_gpu(int32_t dev_id) {
auto dev_count = get_gpu_count();
if ((dev_id < 0) || (dev_id >= dev_count))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Device ID cannot be negative");
// Ignore if no GPU present
if (dev_count > 0) {
if ((dev_id < 0) || (dev_id >= dev_count))
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Device ID cannot be negative");
cuda_err(cudaSetDevice(dev_id));
}
cuda_err(cudaSetDevice(dev_id));
}
}

View File

@@ -19,7 +19,6 @@ DatasetSettings::DatasetSettings() {
file_prefix = "test";
ntrigger = 1;
images_per_trigger = 1;
summation = 1;
fpga_pixel_output = FPGAPixelOutput::Auto;
space_group_number = 0; // not set
compression = CompressionAlgorithm::BSHUF_LZ4;
@@ -172,12 +171,12 @@ DatasetSettings &DatasetSettings::RotationAxis(const std::optional<Coord> &c) {
return *this;
}
DatasetSettings &DatasetSettings::HeaderAppendix(const std::string &input) {
DatasetSettings &DatasetSettings::HeaderAppendix(const nlohmann::json &input) {
header_appendix = input;
return *this;
}
DatasetSettings &DatasetSettings::ImageAppendix(const std::string &input) {
DatasetSettings &DatasetSettings::ImageAppendix(const nlohmann::json &input) {
image_appendix = input;
return *this;
}
@@ -191,13 +190,6 @@ DatasetSettings &DatasetSettings::PhotonEnergyMultiplayer(float input) {
return *this;
}
DatasetSettings &DatasetSettings::Summation(int64_t input) {
check_min("Summation", input, 1);
check_max("Summation", input, MAX_FPGA_SUMMATION);
summation = input;
return *this;
}
DatasetSettings &DatasetSettings::FPGAOutputMode(FPGAPixelOutput input) {
switch (input) {
case FPGAPixelOutput::Auto:
@@ -229,11 +221,11 @@ std::optional<Coord> DatasetSettings::GetRotationAxis() const {
return rotation_axis;
}
std::string DatasetSettings::GetHeaderAppendix() const {
const nlohmann::json& DatasetSettings::GetHeaderAppendix() const {
return header_appendix;
}
std::string DatasetSettings::GetImageAppendix() const {
const nlohmann::json& DatasetSettings::GetImageAppendix() const {
return image_appendix;
}
@@ -249,10 +241,6 @@ int64_t DatasetSettings::GetSpaceGroupNumber() const {
return space_group_number;
}
int64_t DatasetSettings::GetSummation() const {
return summation;
}
FPGAPixelOutput DatasetSettings::GetFPGAOutputMode() const {
return fpga_pixel_output;
}
@@ -331,6 +319,14 @@ DatasetSettings &DatasetSettings::RunNumber(const std::optional<uint64_t> &input
return *this;
}
DatasetSettings & DatasetSettings::RunName(const std::optional<std::string> &input) {
if (input && input.value().empty())
run_name = {};
else
run_name = input;
return *this;
}
DatasetSettings &DatasetSettings::ExperimentGroup(const std::string &input) {
group = input;
return *this;
@@ -340,6 +336,22 @@ std::optional<uint64_t> DatasetSettings::GetRunNumber() const {
return run_number;
}
std::optional<std::string> DatasetSettings::GetRunName() const {
return run_name;
}
std::string DatasetSettings::GetExperimentGroup() const {
return group;
}
std::optional<std::chrono::microseconds> DatasetSettings::GetImageTime() const {
return image_time;
}
DatasetSettings &DatasetSettings::ImageTime(const std::optional<std::chrono::microseconds> input) {
if (input && (input.value().count() == 0))
image_time = {};
else
image_time = input;
return *this;
}

View File

@@ -21,7 +21,6 @@ class DatasetSettings {
int64_t ntrigger;
FPGAPixelOutput fpga_pixel_output;
int64_t summation;
float beam_x_pxl;
float beam_y_pxl;
@@ -41,14 +40,16 @@ class DatasetSettings {
std::optional<float> total_flux;
std::optional<float> attenuator_transmission;
std::optional<GoniometerAxis> goniometer;
std::string image_appendix;
std::string header_appendix;
nlohmann::json image_appendix;
nlohmann::json header_appendix;
std::optional<Coord> rotation_axis;
float data_reduction_factor_serialmx;
std::optional<std::chrono::microseconds> image_time;
std::optional<uint64_t> run_number;
std::optional<std::string> run_name;
std::string group;
public:
@@ -69,26 +70,26 @@ public:
DatasetSettings& TotalFlux(const std::optional<float> &input);
DatasetSettings& Goniometer(const std::optional<GoniometerAxis>& input);
DatasetSettings& RotationAxis(const std::optional<Coord> &c);
DatasetSettings& HeaderAppendix(const std::string& input);
DatasetSettings& ImageAppendix(const std::string& input);
DatasetSettings& HeaderAppendix(const nlohmann::json& input);
DatasetSettings& ImageAppendix(const nlohmann::json& input);
DatasetSettings& PhotonEnergyMultiplayer(float input);
DatasetSettings& Summation(int64_t input);
DatasetSettings& FPGAOutputMode(FPGAPixelOutput input);
DatasetSettings& ImagesPerFile(int64_t input);
DatasetSettings& DataReductionFactorSerialMX(float input);
DatasetSettings& RunNumber(const std::optional<uint64_t> &run_number);
DatasetSettings& RunName(const std::optional<std::string> &input);
DatasetSettings& ExperimentGroup(const std::string &group);
DatasetSettings& ImageTime(const std::optional<std::chrono::microseconds> input);
std::optional<float> GetAttenuatorTransmission() const;
std::optional<float> GetTotalFlux() const;
std::optional<GoniometerAxis> GetGoniometer() const;
std::optional<Coord> GetRotationAxis() const;
std::string GetHeaderAppendix() const;
std::string GetImageAppendix() const;
const nlohmann::json& GetHeaderAppendix() const;
const nlohmann::json& GetImageAppendix() const;
float GetPhotonEnergyMultiplier() const;
std::optional<UnitCell> GetUnitCell() const;
int64_t GetSpaceGroupNumber() const;
int64_t GetSummation() const;
FPGAPixelOutput GetFPGAOutputMode() const;
std::string GetSampleName() const;
float GetPhotonEnergy_keV() const;
@@ -108,7 +109,9 @@ public:
float GetDataReductionFactorSerialMX() const;
std::optional<uint64_t> GetRunNumber() const;
std::optional<std::string> GetRunName() const;
std::string GetExperimentGroup() const;
std::optional<std::chrono::microseconds> GetImageTime() const;
};
#endif //JUNGFRAUJOCH_DATASETSETTINGS_H

View File

@@ -148,3 +148,12 @@ void DetectorSetup::SetTrimFiles(const std::vector<std::string> &filenames) {
const std::vector<std::string> &DetectorSetup::GetTrimFileNames() const {
return trim_file_names;
}
std::string DetectorSetup::GetSerialNumber() const {
return serial_number;
}
DetectorSetup &DetectorSetup::SerialNumber(const std::string &input) {
serial_number = input;
return *this;
}

View File

@@ -10,6 +10,7 @@ enum class DetectorType {EIGER, JUNGFRAU};
class DetectorSetup {
std::string description;
std::string serial_number;
DetectorGeometry geometry;
std::vector<std::string> det_modules_hostname;
std::vector<std::string> gain_file_names;
@@ -41,6 +42,7 @@ public:
DetectorSetup& SensorThickness_um(float input);
DetectorSetup& PixelSize_um(float input);
DetectorSetup& HighVoltage(int32_t input);
DetectorSetup& SerialNumber(const std::string &input);
[[nodiscard]] DetectorType GetDetectorType() const;
[[nodiscard]] const DetectorGeometry& GetGeometry() const;
@@ -56,6 +58,7 @@ public:
[[nodiscard]] const std::vector<std::string> &GetGainFileNames() const;
[[nodiscard]] const std::vector<std::string> &GetTrimFileNames() const;
[[nodiscard]] int32_t GetHighVoltage() const;
[[nodiscard]] std::string GetSerialNumber() const;
};

View File

@@ -67,6 +67,8 @@ DiffractionExperiment::DiffractionExperiment(const DetectorSetup& det_setup)
mode = DetectorMode::Conversion;
max_spot_count = MAX_SPOT_COUNT;
summation = 1;
}
// setter functions
@@ -751,8 +753,8 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
message.rotation_axis[2] = GetRotationAxis().z;
}
message.series_id = GetRunNumber();
message.series_unique_id = GetRunName();
message.run_number = GetRunNumber();
message.run_name = GetRunName();
message.gain_file_names = detector.GetGainFileNames();
@@ -762,6 +764,7 @@ void DiffractionExperiment::FillMessage(StartMessage &message) const {
message.data_reduction_factor_serialmx = GetDataReductionFactorSerialMX();
message.experiment_group = dataset.GetExperimentGroup();
message.jfjoch_release = jfjoch_version();
message.detector_serial_number = detector.GetSerialNumber();
}
float DiffractionExperiment::GetPixelSize_mm() const {
@@ -882,7 +885,9 @@ std::chrono::nanoseconds DiffractionExperiment::GetStorageCellDelay() const {
}
DiffractionExperiment &DiffractionExperiment::Summation(int64_t input) {
dataset.Summation(input);
check_min("Summation factor", input, 1);
check_max("Summation factor", input, MAX_FPGA_SUMMATION);
summation = input;
return *this;
}
@@ -898,7 +903,7 @@ int64_t DiffractionExperiment::GetSummation() const {
if (GetStorageCellNumber() > 1)
return 1;
else
return dataset.GetSummation();
return summation;
}
}
@@ -994,21 +999,21 @@ bool DiffractionExperiment::IsUsingGainHG0() const {
return use_gain_hg0;
}
DiffractionExperiment &DiffractionExperiment::HeaderAppendix(const std::string &input) {
DiffractionExperiment &DiffractionExperiment::HeaderAppendix(const nlohmann::json &input) {
dataset.HeaderAppendix(input);
return *this;
}
DiffractionExperiment &DiffractionExperiment::ImageAppendix(const std::string &input) {
DiffractionExperiment &DiffractionExperiment::ImageAppendix(const nlohmann::json &input) {
dataset.ImageAppendix(input);
return *this;
}
std::string DiffractionExperiment::GetHeaderAppendix() const {
const nlohmann::json& DiffractionExperiment::GetHeaderAppendix() const {
return dataset.GetHeaderAppendix();
}
std::string DiffractionExperiment::GetImageAppendix() const {
const nlohmann::json& DiffractionExperiment::GetImageAppendix() const {
return dataset.GetImageAppendix();
}
@@ -1044,7 +1049,11 @@ uint64_t DiffractionExperiment::GetRunNumber() const {
}
std::string DiffractionExperiment::GetRunName() const {
return std::to_string(series_id) + ": " + dataset.GetFilePrefix();
auto run_name = dataset.GetRunName();
if (run_name)
return run_name.value();
else
return std::to_string(series_id) + ":" + dataset.GetFilePrefix();
}
DiffractionExperiment &DiffractionExperiment::IncrementRunNumber() {
@@ -1134,6 +1143,19 @@ int64_t DiffractionExperiment::GetInternalPacketGeneratorImages() const {
DiffractionExperiment &DiffractionExperiment::ImportDatasetSettings(const DatasetSettings &input) {
auto tmp = dataset;
dataset = input;
auto image_time = input.GetImageTime();
if (image_time) {
if (image_time->count() % GetFrameTime().count() != 0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Image time must be multiple of frame time");
if (GetFrameTime().count() == 0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Frame time cannot be zero");
this->Summation(image_time.value() / GetFrameTime());
} else
summation = 1;
if (GetFrameNum() >= MAX_FRAMES) {
dataset = tmp;
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,

View File

@@ -98,6 +98,8 @@ class DiffractionExperiment {
ROIMap roi_mask;
int64_t max_spot_count;
int64_t summation;
public:
// Public methods are atomic
DiffractionExperiment();
@@ -160,8 +162,8 @@ public:
DiffractionExperiment& TotalFlux(const std::optional<float> &input);
DiffractionExperiment& Goniometer(const std::optional<GoniometerAxis> &input);
DiffractionExperiment& RotationAxis(const std::optional<Coord> &c);
DiffractionExperiment& HeaderAppendix(const std::string& input);
DiffractionExperiment& ImageAppendix(const std::string& input);
DiffractionExperiment& HeaderAppendix(const nlohmann::json& input);
DiffractionExperiment& ImageAppendix(const nlohmann::json& input);
DiffractionExperiment& PhotonEnergyMultiplayer(float input);
DiffractionExperiment& Summation(int64_t input);
DiffractionExperiment& FPGAOutputMode(FPGAPixelOutput input);
@@ -291,8 +293,8 @@ public:
std::optional<GoniometerAxis> GetGoniometer() const;
Coord GetRotationAxis() const;
std::string GetHeaderAppendix() const;
std::string GetImageAppendix() const;
const nlohmann::json& GetHeaderAppendix() const;
const nlohmann::json& GetImageAppendix() const;
float GetPhotonEnergyMultiplier() const;
std::optional<UnitCell> GetUnitCell() const;
std::string GetUnitCellString() const;

View File

@@ -91,7 +91,7 @@ void DetectorWrapper::Initialize(const DiffractionExperiment& experiment,
throw JFJochException(JFJochExceptionCategory::Detector,
"Discrepancy in module number between DAQ and detector");
}
det.setDynamicRange(16);
det.setTenGiga(true);
auto trim_files = experiment.GetDetectorSetup().GetTrimFileNames();

View File

@@ -75,6 +75,7 @@ void host_writer(STREAM_512 &data_in,
state = 0;
ap_uint<16> req_handle;
ap_uint<16> req_handle_send = HANDLE_START;
ap_uint<64> req_host_offset;
while (data_in.empty()) {
@@ -240,7 +241,9 @@ void host_writer(STREAM_512 &data_in,
host_memory_out << packet_out;
if (send_images) {
write_completion(m_axis_completion, req_handle, data_collection_id);
if (req_handle_send != HANDLE_START)
write_completion(m_axis_completion, req_handle_send, data_collection_id);
req_handle_send = req_handle;
internal_packets_processed += cmpl.packet_count;
packets_processed = internal_packets_processed;
}
@@ -252,6 +255,21 @@ void host_writer(STREAM_512 &data_in,
data_in >> packet;
#ifdef JFJOCH_HLS_NOSYNTH
while (!host_memory_out.empty())
std::this_thread::sleep_for(std::chrono::milliseconds(1));
#else
{
// wait for 5 ms (ensure that PCIe buffer is clean)
#pragma HLS PROTOCOL
for (int i = 0; i < 5 * 200 * 1000; i++)
ap_wait();
}
#endif
if (req_handle_send != HANDLE_START)
write_completion(m_axis_completion, req_handle_send, data_collection_id);
write_completion(m_axis_completion, HANDLE_END, data_collection_id);
idle = 1;

View File

@@ -177,11 +177,9 @@ struct jfjoch_drvdata {
// however getting things from the queue happens in system call and can be executed in parallel
// therefore this part is protected by mutex (it is assumed that waiting for interrupts can take seconds,
// process has to be able to sleep while holding the lock => spinlock would not work)
// the mutex is also protecting work_compl_count variable
struct mutex work_compl_read_mutex;
DECLARE_KFIFO(work_compl, u32, MAX_FPGA_BUFFER); // protected by work_compl_read_mutex
wait_queue_head_t work_compl_wait_queue; // used for read completion queue method to wait for interrupt, ISR has wake-up call
u32 work_compl_count; // protected by work_compl_read_mutex
atomic_t active_handles;
};
@@ -220,7 +218,6 @@ void jfjoch_set_ipv4_addr(struct jfjoch_drvdata *drvdata, const u32 *addr);
void jfjoch_get_ipv4_addr(struct jfjoch_drvdata *drvdata, u32 *addr);
int jfjoch_load_calibration(struct jfjoch_drvdata *drvdata, struct LoadCalibrationConfig *config);
int jfjoch_run_frame_gen(struct jfjoch_drvdata *drvdata, struct FrameGeneratorConfig *config);
u32 jfjoch_get_c2h_descriptors(struct jfjoch_drvdata *drvdata);
void jfjoch_set_spot_finder_parameters(struct jfjoch_drvdata *drvdata, struct SpotFinderParameters *params);
void jfjoch_get_spot_finder_parameters(struct jfjoch_drvdata *drvdata, struct SpotFinderParameters *params);
u32 jfjoch_get_data_source(struct jfjoch_drvdata *drvdata);
@@ -236,7 +233,6 @@ void jfjoch_get_env_data(struct jfjoch_drvdata *drvdata, struct DeviceStatus *en
void jfjoch_reset(struct jfjoch_drvdata *drvdata);
void jfjoch_write_register(struct jfjoch_drvdata *drvdata, uint32_t addr, uint32_t val);
uint32_t jfjoch_read_register(struct jfjoch_drvdata *drvdata, uint32_t addr);
int jfjoch_register_sysfs(struct jfjoch_drvdata *drvdata);

View File

@@ -75,7 +75,7 @@ typedef __u64 uint64_t;
#define INT24_MIN (-8388608)
// INT32_MAX is written explicitly, as the constant is not present in kernel
#define MAX_FRAMES (2147483647/(MAX_MODULES_FPGA*DMA_DESCRIPTORS_PER_MODULE))
#define MAX_FRAMES (2147483647)
#pragma pack(push)
#pragma pack(4)

View File

@@ -16,13 +16,8 @@ void jfjoch_start(struct jfjoch_drvdata *drvdata) {
mutex_lock(&drvdata->work_compl_read_mutex);
while(!kfifo_is_empty(&drvdata->work_compl))
tmp2 = kfifo_get(&drvdata->work_compl, &tmp1);
// Reset work completion queue
drvdata->work_compl_count = 0;
mutex_unlock(&drvdata->work_compl_read_mutex);
// Set PCIe beats counters
iowrite32((1 << 1), drvdata->bar0 + PCIE_OFFSET + (1<<12) + 0xC0);
iowrite32((1 << 2), drvdata->bar0 + PCIE_OFFSET + (1<<12) + 0xC0);
@@ -69,28 +64,14 @@ int jfjoch_send_wr(struct jfjoch_drvdata *drvdata, u32 handle) {
}
int jfjoch_read_wc(struct jfjoch_drvdata *drvdata, u32 *output) {
struct device *const dev = &drvdata->pdev->dev;
int ret, tmp, i;
u32 curr_compl_count, handle;
u32 data_collection_id;
int ret, tmp;
mutex_lock(&drvdata->work_compl_read_mutex);
ret = wait_event_interruptible_timeout(drvdata->work_compl_wait_queue, !kfifo_is_empty(&drvdata->work_compl), HZ);
if (ret > 0) {
if (ret > 0)
tmp = kfifo_get(&drvdata->work_compl, output);
handle = (*output) & 0xFFFF;
data_collection_id = (*output >> 16) & 0xFFFF;
if (handle == HANDLE_START) {
drvdata->work_compl_count = 0;
curr_compl_count = 0;
} else if ((handle != HANDLE_END) && (data_collection_id != DATA_COLLECTION_ID_PURGE)) {
curr_compl_count = drvdata->work_compl_count;
drvdata->work_compl_count++;
}
}
mutex_unlock(&drvdata->work_compl_read_mutex);
if (ret < 0)
@@ -98,27 +79,9 @@ int jfjoch_read_wc(struct jfjoch_drvdata *drvdata, u32 *output) {
else if ((ret == 0) || (tmp == 0))
return -EAGAIN;
// Guarantee that data are in host memory
if ((handle != HANDLE_START) && (handle != HANDLE_END)) {
u32 descriptors = ioread32(drvdata->bar0 + PCIE_OFFSET + (1 << 12) + 0x48);
i = 0;
while ((descriptors < curr_compl_count * DMA_DESCRIPTORS_PER_MODULE) && (i < 100)) {
udelay(10);
descriptors = ioread32(drvdata->bar0 + PCIE_OFFSET + (1 << 12) + 0x48);
i++;
}
if (descriptors < DMA_DESCRIPTORS_PER_MODULE * curr_compl_count) {
dev_err(dev, "Late completion count SW %u, HW %u HANDLE %x", curr_compl_count, descriptors, handle);
return -EIO;
} else if (i > 0) {
dev_warn(dev, "Late completion count SW %u, HW %u HANDLE %x delay %d", curr_compl_count, descriptors, handle, i);
}
}
return 0;
}
int jfjoch_set_config(struct jfjoch_drvdata *drvdata, const struct DataCollectionConfig *config) {
if (config->nframes > MAX_FRAMES)
return -EINVAL;
@@ -409,10 +372,6 @@ int jfjoch_run_frame_gen(struct jfjoch_drvdata *drvdata, struct FrameGeneratorCo
return 0;
}
u32 jfjoch_get_c2h_descriptors(struct jfjoch_drvdata *drvdata) {
return ioread32(drvdata->bar0 + PCIE_OFFSET + (1<<12) + 0x48);
}
void jfjoch_set_spot_finder_parameters(struct jfjoch_drvdata *drvdata, struct SpotFinderParameters *params) {
memcpy_toio((drvdata->bar0) + ACTION_CONFIG_OFFSET + ADDR_SPOT_FINDER_THRESHOLD,
params,

View File

@@ -154,11 +154,6 @@ long jfjoch_cdev_ioctl(struct file *file, unsigned int cmd, unsigned long arg) {
if (copy_from_user(&frame_generator_config, (char *) arg, sizeof(struct FrameGeneratorConfig)) != 0)
return -EFAULT;
return jfjoch_run_frame_gen(drvdata, &frame_generator_config);
case IOCTL_JFJOCH_C2H_DMA_DESC:
exchange[0] = jfjoch_get_c2h_descriptors(drvdata);
if (copy_to_user((char *) arg, exchange, sizeof(u32)) != 0)
return -EFAULT;
return 0;
case IOCTL_JFJOCH_READ_REGISTER:
// This is the most powerful option from security point of view and can only be performed by root
if (!capable(CAP_SYS_ADMIN))

View File

@@ -34,8 +34,7 @@
#define IOCTL_JFJOCH_GET_IPV4 _IOR(IOCTL_JFJOCH_MAGIC, 18, uint32_t)
// 19-21 are reserved
#define IOCTL_JFJOCH_RUN_FRAME_GEN _IOW(IOCTL_JFJOCH_MAGIC, 23, struct FrameGeneratorConfig)
#define IOCTL_JFJOCH_C2H_DMA_DESC _IOR(IOCTL_JFJOCH_MAGIC, 24, uint32_t)
// 25 is reserved
// 24-25 are reserved
#define IOCTL_JFJOCH_READ_REGISTER _IOWR(IOCTL_JFJOCH_MAGIC, 26, struct RegisterConfig )
#define IOCTL_JFJOCH_SET_SPOTFIN_PAR _IOW(IOCTL_JFJOCH_MAGIC, 27, struct SpotFinderParameters)
#define IOCTL_JFJOCH_SET_DATA_SOURCE _IOW(IOCTL_JFJOCH_MAGIC, 28, uint32_t)

View File

@@ -441,9 +441,9 @@ namespace {
else if (key == "data")
ProcessImageData(value, message.image);
else if (key == "series_unique_id")
message.series_unique_id = GetCBORString(value);
message.run_name = GetCBORString(value);
else if (key == "series_id")
message.series_id = GetCBORUInt(value);
message.run_number = GetCBORUInt(value);
else if (key == "real_time") {
auto r = GetRational(value);
message.exptime = r.first;
@@ -452,9 +452,14 @@ namespace {
auto r = GetRational(value);
message.timestamp = r.first;
message.timestamp_base = r.second;
} else if (key == "user_data")
message.user_data = GetCBORString(value);
else if (key == "spots")
} else if (key == "user_data") {
const std::string s = GetCBORString(value);
try {
message.user_data = nlohmann::json::parse(s);
} catch (...) {
message.user_data = s;
}
} else if (key == "spots")
GetCBORSpots(message, value);
else if (key == "spot_count_in_rings")
message.spot_count_in_rings = GetCBORUInt(value);
@@ -710,9 +715,9 @@ namespace {
else if (key == "detector_serial_number")
message.detector_serial_number = GetCBORString(value);
else if (key == "series_unique_id")
message.series_unique_id = GetCBORString(value);
message.run_name = GetCBORString(value);
else if (key == "series_id")
message.series_id = GetCBORUInt(value);
message.run_number = GetCBORUInt(value);
else if (key == "pixel_mask")
ProcessPixelMaskElement(message, value);
else if (key == "channels")
@@ -832,9 +837,9 @@ namespace {
if (key == "end_date")
message.end_date = GetCBORString(value);
else if (key == "series_unique_id")
message.series_unique_id = GetCBORString(value);
message.run_name = GetCBORString(value);
else if (key == "series_id")
message.series_id = GetCBORUInt(value);
message.run_number = GetCBORUInt(value);
else if (key == "max_image_number")
message.max_image_number = GetCBORUInt(value);
else if (key == "images_collected")

View File

@@ -372,8 +372,8 @@ void CBORStream2Serializer::SerializeSequenceStart(const StartMessage& message)
CBOR_ENC(mapEncoder, "pixel_mask_enabled", message.pixel_mask_enabled);
CBOR_ENC(mapEncoder, "detector_description", message.detector_description);
CBOR_ENC(mapEncoder, "detector_serial_number", message.detector_serial_number);
CBOR_ENC(mapEncoder, "series_unique_id", message.series_unique_id);
CBOR_ENC(mapEncoder, "series_id", message.series_id);
CBOR_ENC(mapEncoder, "series_unique_id", message.run_name);
CBOR_ENC(mapEncoder, "series_id", message.run_number);
CBOR_ENC_AXIS(mapEncoder, "detector_translation", message.detector_translation);
CBOR_ENC_GONIOMETER_MAP(mapEncoder, "goniometer", message);
@@ -418,8 +418,8 @@ void CBORStream2Serializer::SerializeSequenceEnd(const EndMessage& message) {
CBOR_ENC(mapEncoder, "type", "end");
CBOR_ENC(mapEncoder, "magic_number", user_data_magic_number);
CBOR_ENC(mapEncoder, "series_unique_id", message.series_unique_id);
CBOR_ENC(mapEncoder, "series_id", message.series_id);
CBOR_ENC(mapEncoder, "series_unique_id", message.run_name);
CBOR_ENC(mapEncoder, "series_id", message.run_number);
CBOR_ENC(mapEncoder, "end_date", message.end_date);
CBOR_ENC(mapEncoder, "max_image_number", message.max_image_number);
@@ -444,8 +444,8 @@ void CBORStream2Serializer::SerializeImage(const DataMessage& message) {
CBOR_ENC(mapEncoder, "type", "image");
CBOR_ENC(mapEncoder, "magic_number", user_data_magic_number);
CBOR_ENC(mapEncoder, "series_unique_id", message.series_unique_id);
CBOR_ENC(mapEncoder, "series_id", message.series_id);
CBOR_ENC(mapEncoder, "series_unique_id", message.run_name);
CBOR_ENC(mapEncoder, "series_id", message.run_number);
CBOR_ENC(mapEncoder, "image_id", message.number);
CBOR_ENC(mapEncoder, "original_image_id", message.original_number);
@@ -474,7 +474,7 @@ void CBORStream2Serializer::SerializeImage(const DataMessage& message) {
CBOR_ENC(mapEncoder, "bkg_estimate", message.bkg_estimate);
CBOR_ENC(mapEncoder, "adu_histogram", message.adu_histogram);
CBOR_ENC(mapEncoder, "roi_integrals", message.roi);
CBOR_ENC(mapEncoder, "user_data", message.user_data);
CBOR_ENC(mapEncoder, "user_data", message.user_data.dump());
CBOR_ENC(mapEncoder, "data", message.image);
cborErr(cbor_encoder_close_container(&encoder, &mapEncoder));

View File

@@ -10,6 +10,8 @@
#include <optional>
#include <cstring>
#include <stdexcept>
#include <nlohmann/json.hpp>
#include "../compression/CompressionAlgorithmEnum.h"
#include "../common/SpotToSave.h"
#include "../common/UnitCell.h"
@@ -62,14 +64,14 @@ struct DataMessage {
uint32_t exptime;
uint32_t exptime_base;
std::string series_unique_id;
uint64_t series_id;
std::string run_name;
uint64_t run_number;
uint64_t saturated_pixel_count;
uint64_t error_pixel_count;
uint64_t strong_pixel_count;
std::string user_data;
nlohmann::json user_data;
std::optional<uint64_t> jf_info;
std::optional<uint64_t> receiver_aq_dev_delay;
@@ -138,8 +140,8 @@ struct StartMessage {
std::string detector_description;
std::string detector_serial_number;
std::string series_unique_id;
uint64_t series_id;
std::string run_name;
uint64_t run_number;
std::vector<std::string> gain_file_names;
std::vector<std::string> roi_names;
@@ -170,7 +172,7 @@ struct StartMessage {
pixel_mask.emplace_back(std::move(image));
}
std::string user_data;
nlohmann::json user_data;
std::optional<float> data_reduction_factor_serialmx;
std::optional<std::string> experiment_group;
@@ -187,8 +189,8 @@ struct EndMessage {
std::optional<std::string> end_date;
std::string series_unique_id;
uint64_t series_id;
std::string run_name;
uint64_t run_number;
std::map<std::string, std::vector<float>> az_int_result;
std::map<std::string, std::vector<uint64_t>> adu_histogram;

View File

@@ -37,8 +37,8 @@ There are minor differences at the moment:
| arm_data | data | Approximate date of arming | X |
| pixel_mask_enabled | bool | Pixel mask applied on images | X |
| detector_description | string | Name of the detector | X |
| series_unique_id | string | Unique text ID of the series | X |
| series_id | uint64 | Unique numeric ID of the series | X |
| series_unique_id | string | Unique text ID of the series (run_name parameter) | X |
| series_id | uint64 | Unique numeric ID of the series (run_number parameter) | X |
| goniometer | Map | See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/stream_v2) - only one axis is supported | X |
| pixel_mask | Map(string -> Image) | Pixel mask - multiple in case of storage cells | X |
| channels | Array(string) | List of image channels | X |
@@ -49,7 +49,8 @@ There are minor differences at the moment:
| az_int_bin_number | uint64 | Number of azimuthal integration bins | |
| az_int_bin_to_q | Array(float) | Q value for each azimuthal integration bin \[angstrom^-1\] | |
| summation | uint64 | Factor of frame summation | |
| user_data | string | JSON string that can contain the following fields (among others): | X |
| user_data | string | JSON serialized to string that can contain the following fields: | X |
| - user | any valid JSON | Value of header_appendix provided at collection start to Jungfraujoch | |
| - source_name | string | Facility name | |
| - source_name_short | string | Facility name (short) | |
| - source_type | string (optional) | Type of X-ray source (use NXsource/type values, for example "Synchrotron X-ray Source" or "Free-Electron Laser") | |
@@ -69,42 +70,42 @@ See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/s
## Image message
| Field name | Type | Description | Present in DECTRIS format | Optional |
|----------------------------|-----------------------------|--------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|:--------:|
| type | String | value "image" | X | |
| Field name | Type | Description | Present in DECTRIS format | Optional |
|----------------------------|-----------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|:--------:|
| type | String | value "image" | X | |
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | | |
| series_unique_id | string | Unique text ID of the series | X | |
| series_id | uint64 | Unique numeric ID of the series | X | |
| image_id | uint64 | Number of image within the series | X | |
| real_time | Rational | Exposure time | X | |
| start_time | Rational | Exposure start time (highly approximate) | X | |
| end_time | Rational | Exposure end time (highly approximate) | X | |
| spots | Array(object) | Spots: | | |
| - x | float | position in x (pixels) | | |
| - y | float | position in y (pixels) | | |
| - I | float | intensity (photons) | | |
| - indexed | bool | indexed solution | | |
| az_int_profile | Array(float) | Azimuthal integration results, use az_int_bin_to_q from start message for legend | | |
| indexing_result | bool | Indexing successful | | |
| indexing_lattice | Array(float * 9) (optional) | Indexing result real lattice; present only if indexed | | |
| xfel_pulse_id | uint64 | Bunch ID (for pulsed source, e.g., SwissFEL) | | X |
| xfel_event_code | uint64 | Event code (for pulsed source, e.g., SwissFEL) | | X |
| jf_info | uint64 | Detector info field | | |
| receiver_aq_dev_delay | uint64 | Receiver internal delay | | |
| receiver_free_send_buf | uint64 | Receiver internal number of available send buffers | | |
| storage_cell | uint64 | Storage cell number | | |
| saturated_pixel_count | uint64 | Saturated pixel count | | |
| error_pixel_count | uint64 | Error pixel count | | |
| strong_pixel_count | uint64 | Strong pixel count (first stage of spot finding) | | |
| data_collection_efficiency | float | Image collection efficiency \[\] | | |
| bkg_estimate | float | Mean value for pixels in resolution range from 3.0 to 5.0 A [\photons\] | | |
| adu_histogram | Array(uint64) | ADU histogram | | |
| corr_beam_x_pxl | float | Difference between provided and calculated beam center X (pixels) - requires indexing | | X |
| corr_beam_y_pxl | float | Difference between provided and calculated beam center Y (pixels) - requires indexing | | X |
| corr_det_dist_mm | float | Difference between provided and calculated detector distance (mm) - requires indexing | | X |
| user_data | string | Optional user defined text information | | |
| roi_sum | int64 | Sum of ROI rectangle \[photons\] | | X |
| image | Map(string -> Image) | Image | | |
| series_unique_id | string | Unique text ID of the series (run_name parameter) | X | |
| series_id | uint64 | Unique numeric ID of the series (run_number parameter) | X | |
| image_id | uint64 | Number of image within the series | X | |
| real_time | Rational | Exposure time | X | |
| start_time | Rational | Exposure start time (highly approximate) | X | |
| end_time | Rational | Exposure end time (highly approximate) | X | |
| spots | Array(object) | Spots: | | |
| - x | float | position in x (pixels) | | |
| - y | float | position in y (pixels) | | |
| - I | float | intensity (photons) | | |
| - indexed | bool | indexed solution | | |
| az_int_profile | Array(float) | Azimuthal integration results, use az_int_bin_to_q from start message for legend | | |
| indexing_result | bool | Indexing successful | | |
| indexing_lattice | Array(float * 9) (optional) | Indexing result real lattice; present only if indexed | | |
| xfel_pulse_id | uint64 | Bunch ID (for pulsed source, e.g., SwissFEL) | | X |
| xfel_event_code | uint64 | Event code (for pulsed source, e.g., SwissFEL) | | X |
| jf_info | uint64 | Detector info field | | |
| receiver_aq_dev_delay | uint64 | Receiver internal delay | | |
| receiver_free_send_buf | uint64 | Receiver internal number of available send buffers | | |
| storage_cell | uint64 | Storage cell number | | |
| saturated_pixel_count | uint64 | Saturated pixel count | | |
| error_pixel_count | uint64 | Error pixel count | | |
| strong_pixel_count | uint64 | Strong pixel count (first stage of spot finding) | | |
| data_collection_efficiency | float | Image collection efficiency \[\] | | |
| bkg_estimate | float | Mean value for pixels in resolution range from 3.0 to 5.0 A [\photons\] | | |
| adu_histogram | Array(uint64) | ADU histogram | | |
| corr_beam_x_pxl | float | Difference between provided and calculated beam center X (pixels) - requires indexing | | X |
| corr_beam_y_pxl | float | Difference between provided and calculated beam center Y (pixels) - requires indexing | | X |
| corr_det_dist_mm | float | Difference between provided and calculated detector distance (mm) - requires indexing | | X |
| user_data | string | Optional user defined text information - this is image_appendix serialized to JSON format | | |
| roi_sum | int64 | Sum of ROI rectangle \[photons\] | | X |
| image | Map(string -> Image) | Image | | |
## End message
@@ -112,8 +113,8 @@ See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/s
|----------------------------|--------------------------|-----------------------------------------------------------------------------------------------------------------------------------|:-------------------------:|
| type | String | value "end" | X |
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
| series_unique_id | string | Unique text ID of the series | X |
| series_id | uint64 | Unique numeric ID of the series | X |
| series_unique_id | string | Unique text ID of the series (run_name parameter) | X |
| series_id | uint64 | Unique numeric ID of the series (run_number parameter) | X |
| end_date | date | Approximate end date | |
| max_image_number | uint64 | Number of image with the highest number (this is counted from 1 - to distinguish zero images and one image) | |
| images_collected | uint64 | Number of image collected | |
@@ -132,20 +133,21 @@ See [DECTRIS documentation](https://github.com/dectris/documentation/tree/main/s
| magic_number | uint64 | Number used to describe version of the Jungfraujoch data interface - to allow to detect inconsistency between sender and receiver | |
| data | Map(string -> Image) | Calibration map (only single pedestal array per message) | |
# User data
In many cases there is an interest from facilities to forward more metadata, than available explicitly in the Jungfraujoch.
For this reason two fields can be provided: `header_appendix` (sent with start message) and `image_appendix` (send with image message).
To increase flexibility, both appendices can contain any valid JSON message.
These appendices are serialized into string and stored in CBOR messages as `user_data`.
Notably for start message, `user_data` contain more information (non-DECTRIS compliant metadata).
Therefore `user_data` is serialized by Jungfraujoch as CBOR object. There is member `user` which contains `header_appendix`.
# Image transfer
Images can be forwarded by Jungraujoch through few interfaces. All of them are ZeroMQ based at the moment, though they differ with serialization layer.
All interfaces are subclasses of `ImagePusher` class. The following options are available:
Images can be forwarded by Jungraujoch through ZeroMQ interfaces with serialization compatible with DECTRIS Stream2 serialization.
This is using PUSH ZeroMQ socket(s). Multiple sockets can be used, in this case images will be split according to file number to which they belong. All sockets will forward start and end messages. Only first socket will forward calibration messages.
## ZMQStream2Pusher
Pushes images using Stream2 serialization. This is using PUSH ZeroMQ sockets. Behavior is as following:
* Start message is sent with timeout of 5s. If within the time the message cannot be put in the outgoing queue or there is no connected puller exception is thrown - this is to stop data collection in absence of writer.
* Images are sent in non-blocking way and without timeout. If message cannot be sent `false` is returned for the send call - need to be reported or handled in calling function.
* End message is sent with timeout of 5s. If message cannot be sent `false` is returned for the send call - need to be reported or handled in calling function.
## ZMQStream2PusherGroup
Same as above, but multiple ZeroMQ sockets are used and images are distributed on a round-robin basis between the sockets based on the image number.
Behavior for errors is the same as for `ZMQStream2Pusher`.
## TestImagePusher
This interface is used for automated tests. It reads incoming images and compares one image with the reference data provided.
Behavior is as following:
* Start message is sent with timeout of 5s. If within the time the message cannot be put in the outgoing queue or there is no connected puller exception is thrown - stop data collection with error due to absence of a writer.
* Images are sent in non-blocking way and without timeout.
* End message is sent with timeout of 5s. No error is reported

View File

@@ -4,6 +4,7 @@
#include "CPUSpotFinder.h"
#include "../common/DiffractionGeometry.h"
#include "Regression.h"
#include "../common/CUDAWrapper.h"
double stddev(const std::vector<float> &v) {
if (v.size() <= 1)
@@ -26,7 +27,7 @@ double stddev(const std::vector<float> &v) {
MXAnalyzer::MXAnalyzer(const DiffractionExperiment &in_experiment)
: experiment(in_experiment) {
auto uc = experiment.GetUnitCell();
if (uc) {
if (uc && (get_gpu_count() > 0)) {
try {
indexer = std::make_unique<IndexerWrapper>();
indexer->Setup(uc.value());

View File

@@ -9,6 +9,7 @@
#include "ImageMetadata.h"
#include "../common/time_utc.h"
#include "../common/PixelMask.h"
#include "../common/CUDAWrapper.h"
JFJochReceiver::JFJochReceiver(const DiffractionExperiment& in_experiment,
const PixelMask &pixel_mask,
@@ -55,6 +56,11 @@ JFJochReceiver::JFJochReceiver(const DiffractionExperiment& in_experiment,
logger.Info("NUMA policy: {}", numa_policy.GetName());
#ifdef JFJOCH_USE_CUDA
if (get_gpu_count() == 0)
logger.Warning("GPU absent, indexing is not possible");
#endif
for (int d = 0; d < ndatastreams; d++) {
acquisition_device[d].PrepareAction(experiment);
acquisition_device[d].SetSpotFinderParameters(spot_finding_settings);
@@ -297,8 +303,8 @@ void JFJochReceiver::FrameTransformationThread(uint32_t threadid) {
message.number = image_number;
message.original_number = image_number;
message.user_data = experiment.GetImageAppendix();
message.series_id = experiment.GetRunNumber();
message.series_unique_id = experiment.GetRunName();
message.run_number = experiment.GetRunNumber();
message.run_name = experiment.GetRunName();
ImageMetadata metadata(experiment);
@@ -452,8 +458,8 @@ void JFJochReceiver::FinalizeMeasurement() {
message.max_receiver_delay = max_delay;
message.efficiency = GetEfficiency();
message.end_date = time_UTC(std::chrono::system_clock::now());
message.series_id = experiment.GetRunNumber();
message.series_unique_id = experiment.GetRunName();
message.run_number = experiment.GetRunNumber();
message.run_name = experiment.GetRunName();
message.az_int_result["dataset"] = plots.GetAzIntProfile();
for (int i = 0; i < experiment.GetTimePointNumber(); i++)

View File

@@ -44,8 +44,8 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
.channels = {"default", "sc2"},
.detector_description = "EIGER 16M",
.detector_serial_number = "123",
.series_unique_id = "bla",
.series_id = 4567,
.run_name = "bla",
.run_number = 4567,
.gain_file_names = {"abc" , "def", "/dsadasdsa/dadsadas/dsadsa/M056.bin"},
.roi_names = {"roi0", "roi1"},
.goniometer = GoniometerAxis{
@@ -66,7 +66,7 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
.total_flux = 123,
.attenuator_transmission = 0.345,
.write_master_file = true,
.user_data = "Some random string 12345",
.user_data = R"({"pi":3.1415, "z":"string"})"_json,
.data_reduction_factor_serialmx = 0.75,
.experiment_group = "p10001",
.jfjoch_release = "1.4.98"
@@ -110,8 +110,8 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
CHECK(output_message.channels == message.channels);
CHECK(output_message.detector_description == message.detector_description);
CHECK(output_message.detector_serial_number == message.detector_serial_number);
CHECK(output_message.series_unique_id == message.series_unique_id);
CHECK(output_message.series_id == message.series_id);
CHECK(output_message.run_name == message.run_name);
CHECK(output_message.run_number == message.run_number);
CHECK(output_message.source_type == message.source_type);
CHECK(output_message.source_name == message.source_name);
CHECK(output_message.source_name_short == message.source_name_short);
@@ -143,6 +143,8 @@ TEST_CASE("CBORSerialize_Start", "[CBOR]") {
REQUIRE (output_message.attenuator_transmission);
CHECK(output_message.attenuator_transmission.value() == message.attenuator_transmission.value());
CHECK(output_message.user_data == message.user_data);
REQUIRE(output_message.user_data.is_object());
CHECK(output_message.user_data.size() == 2);
CHECK(output_message.gain_file_names == message.gain_file_names);
CHECK(output_message.roi_names == message.roi_names);
CHECK(output_message.countrate_correction_enabled == message.countrate_correction_enabled);
@@ -239,8 +241,8 @@ TEST_CASE("CBORSerialize_End", "[CBOR]") {
.max_receiver_delay = 3456,
.efficiency = 0.99,
.end_date = "ccc",
.series_unique_id = "bla5",
.series_id = 45676782
.run_name = "bla5",
.run_number = 45676782
};
REQUIRE_NOTHROW(serializer.SerializeSequenceEnd(message));
@@ -258,8 +260,8 @@ TEST_CASE("CBORSerialize_End", "[CBOR]") {
REQUIRE(output_message.efficiency);
REQUIRE(output_message.efficiency == Catch::Approx(message.efficiency.value()));
REQUIRE(output_message.end_date == message.end_date);
REQUIRE(output_message.series_id == message.series_id);
REQUIRE(output_message.series_unique_id == message.series_unique_id);
REQUIRE(output_message.run_number == message.run_number);
REQUIRE(output_message.run_name == message.run_name);
REQUIRE(output_message.az_int_result.empty());
}
@@ -272,8 +274,8 @@ TEST_CASE("CBORSerialize_End_RadIntResult", "[CBOR]") {
.max_receiver_delay = 3456,
.efficiency = 0.99,
.end_date = "ccc",
.series_unique_id = "bla5",
.series_id = 45676782
.run_name = "bla5",
.run_number = 45676782
};
message.az_int_result["avg"] = {11.0, 12.0, 13.0};
@@ -302,8 +304,8 @@ TEST_CASE("CBORSerialize_End_ADUHistogram", "[CBOR]") {
.max_receiver_delay = 3456,
.efficiency = 0.99,
.end_date = "ccc",
.series_unique_id = "bla5",
.series_id = 45676782,
.run_name = "bla5",
.run_number = 45676782,
.adu_histogram_bin_width = 55
};
@@ -359,12 +361,12 @@ TEST_CASE("CBORSerialize_Image", "[CBOR]") {
.adu_histogram = {3, 4, 5, 8},
.timestamp = 1ul<<27 | 1ul <<35,
.exptime = 1000,
.series_unique_id = "bla2",
.series_id = 4567678,
.run_name = "bla2",
.run_number = 4567678,
.saturated_pixel_count = 378,
.error_pixel_count = 123,
.strong_pixel_count = 1234,
.user_data = "Some random string ABCDEF",
.user_data = R"({"pi":3.1415, "z":"string"})"_json,
.jf_info = UINT32_MAX,
.receiver_aq_dev_delay = 2323,
.storage_cell = 0xF,
@@ -391,8 +393,8 @@ TEST_CASE("CBORSerialize_Image", "[CBOR]") {
REQUIRE(image_array.image.size == test.size());
REQUIRE(image_array.indexing_result == message.indexing_result);
REQUIRE(image_array.number == 456);
REQUIRE(image_array.series_id == message.series_id);
REQUIRE(image_array.series_unique_id == message.series_unique_id);
REQUIRE(image_array.run_number == message.run_number);
REQUIRE(image_array.run_name == message.run_name);
REQUIRE(memcmp(image_array.image.data, test.data(), test.size()) == 0);
REQUIRE(image_array.xfel_pulse_id == message.xfel_pulse_id);

View File

@@ -661,6 +661,23 @@ TEST_CASE("DiffractionExperiment_StorageCells_Pedestal_FixedG1","[DiffractionExp
REQUIRE(x.GetFrameNum() == 323 * 15);
}
TEST_CASE("DiffractionExperiment_ImageTime","[DiffractionExperiment]") {
DiffractionExperiment x(DetectorSetup(3, DetectorType::JUNGFRAU));
DatasetSettings s;
x.FrameTime(583us);
s.ImageTime(583us * 4);
x.ImportDatasetSettings(s);
REQUIRE(x.GetSummation() == 4);
s.ImageTime({});
x.ImportDatasetSettings(s);
REQUIRE(x.GetSummation() == 1);
s.ImageTime(585us);
REQUIRE_THROWS(x.ImportDatasetSettings(s));
}
TEST_CASE("DiffractionExperiment_PulsedSource","[DiffractionExperiment]") {
DiffractionExperiment x;
REQUIRE(!x.IsPulsedSource()); // default must be off
@@ -770,9 +787,9 @@ TEST_CASE("DiffractionExperiment_Appendix","") {
StartMessage message;
x.FillMessage(message);
REQUIRE(message.user_data == "");
REQUIRE(x.GetImageAppendix() == "");
REQUIRE(x.GetHeaderAppendix() == "");
REQUIRE(message.user_data == nlohmann::json());
REQUIRE(x.GetImageAppendix() == nlohmann::json());
REQUIRE(x.GetHeaderAppendix() == nlohmann::json());
x.ImageAppendix("ImageAppendix").HeaderAppendix("HeaderAppendix");
@@ -885,13 +902,15 @@ TEST_CASE("DiffractionExperiment_SeriesID","[DiffractionExperiment]") {
REQUIRE(x.GetRunNumber() == 1);
DatasetSettings d;
d.RunNumber(25);
d.RunNumber(25).RunName("run1");
x.ImportDatasetSettings(d);
REQUIRE(x.GetRunNumber() == 25);
REQUIRE(x.GetRunName() == "run1");
d.RunNumber({});
d.RunNumber({}).RunName({}).FilePrefix("file1");
x.ImportDatasetSettings(d);
REQUIRE(x.GetRunNumber() == 1);
REQUIRE(x.GetRunName() == "1:file1");
}
TEST_CASE("DiffractionExperiment_GetDefaultPlotBinning", "[DiffractionExperiment]") {

View File

@@ -227,9 +227,9 @@ TEST_CASE("HDF5Writer_Socket", "[HDF5][Full]") {
DatasetSettings d;
d.FilePrefix("run0345_lysozyme_acq").ImagesPerTrigger(5).ImagesPerFile(2).Compression(CompressionAlgorithm::NO_COMPRESSION)
.HeaderAppendix("{\"z\":567}").DetectorDistance_mm(155).BeamX_pxl(1606.62).BeamY_pxl(1669.59)
.HeaderAppendix(R"({"z":567})"_json).DetectorDistance_mm(155).BeamX_pxl(1606.62).BeamY_pxl(1669.59)
.PhotonEnergy_keV(12.07).SetUnitCell(UnitCell{.a = 97, .b = 97, .c = 38, .alpha= 90, .beta = 90, .gamma = 90})
.SpaceGroupNumber(96).RunNumber(345).ExperimentGroup("p12345").SampleName("lysozyme");
.SpaceGroupNumber(96).RunNumber(345).ExperimentGroup("p12345").SampleName("lysozyme").RunName("run1");
x.ImportDatasetSettings(d);
std::vector<SpotToSave> spots;
@@ -271,10 +271,11 @@ TEST_CASE("HDF5Writer_Socket", "[HDF5][Full]") {
REQUIRE(j["filename"] == "run0345_lysozyme_acq_data_000001.h5");
REQUIRE(j["file_number"] == 1);
REQUIRE(j["nimages"] == 2);
REQUIRE(j["photon_energy_eV"] == Catch::Approx(x.GetPhotonEnergy_keV() * 1000.0));
REQUIRE(j["incident_energy_eV"] == Catch::Approx(x.GetPhotonEnergy_keV() * 1000.0));
REQUIRE(j["space_group_number"] == 96);
REQUIRE(j["experiment_group"] == "p12345");
REQUIRE(j["run_number"] == 345);
REQUIRE(j["run_name"] == "run1");
REQUIRE(j.contains("user_data"));
REQUIRE(j["user_data"]["z"] == 567);
std::cout << j.dump(4) << std::endl;
@@ -383,10 +384,26 @@ TEST_CASE("HDF5Writer_Rad_Int_Profile", "[HDF5][Full]") {
}
TEST_CASE("HDF5NXmx_DataFileName", "[HDF5]") {
REQUIRE(HDF5Metadata::DataFileName("z/x", 34) == "z/x_data_000035.h5");
REQUIRE(HDF5Metadata::DataFileName("z/x", 0) == "z/x_data_000001.h5");
REQUIRE_THROWS(HDF5Metadata::DataFileName("z/x", 1000000));
REQUIRE_THROWS(HDF5Metadata::DataFileName("z/x", -1));
StartMessage message;
message.file_prefix = "z/x";
REQUIRE(HDF5Metadata::DataFileName(message, 34) == "z/x_data_000035.h5");
REQUIRE(HDF5Metadata::DataFileName(message, 0) == "z/x_data_000001.h5");
REQUIRE_THROWS(HDF5Metadata::DataFileName(message, 1000000));
REQUIRE_THROWS(HDF5Metadata::DataFileName(message, -1));
}
TEST_CASE("HDF5NXmx_DataFileName_SwissFEL", "[HDF5]") {
StartMessage message;
message.file_prefix = "acq";
message.source_name = "SwissFEL";
message.detector_serial_number = "JF17T16V01";
REQUIRE(HDF5Metadata::DataFileName(message, 34) == "acq0035.JF17T16V01.h5");
REQUIRE(HDF5Metadata::DataFileName(message, 0) == "acq0001.JF17T16V01.h5");
REQUIRE_THROWS(HDF5Metadata::DataFileName(message, 10000));
REQUIRE_THROWS(HDF5Metadata::DataFileName(message, -1));
message.detector_serial_number = "";
REQUIRE(HDF5Metadata::DataFileName(message, 34) == "acq0035.JF.h5");
}
TEST_CASE("HDF5Objects_ExtractFilename", "[HDF5]") {

View File

@@ -101,6 +101,7 @@ TEST_CASE("JFJochBrokerParser_DetectorSetup") {
"description": "PSI JUNGFRAU 2M",
"udp_interface_count": 1,
"module_hostname": ["mx1", "mx2", "mx3", "mx4"],
"serial_number": "JF1",
"gain_files": [
"../../tests/test_data/gainMaps_M049.bin",
"../../tests/test_data/gainMaps_M049.bin",
@@ -121,6 +122,7 @@ TEST_CASE("JFJochBrokerParser_DetectorSetup") {
REQUIRE(detector.GetDetectorModuleHostname()[2] == "mx3");
REQUIRE(detector.GetGainCalibration().size() == 4);
REQUIRE(detector.GetUDPInterfaceCount() == 1);
REQUIRE(detector.GetSerialNumber() == "JF1");
}
TEST_CASE("JFJochBrokerParser_DetectorType_implicit") {

View File

@@ -20,7 +20,7 @@ HDF5DataFile::HDF5DataFile(const StartMessage &msg, uint64_t in_file_number) {
ypixel = 0;
max_image_number = 0;
nimages = 0;
filename = HDF5Metadata::DataFileName(msg.file_prefix, file_number);
filename = HDF5Metadata::DataFileName(msg, file_number);
image_low = file_number * msg.images_per_file;
tmp_filename = fmt::format("{}.tmp{:8x}", filename, std::chrono::system_clock::now().time_since_epoch().count());

View File

@@ -40,15 +40,26 @@ NXmx::~NXmx() {
std::rename(tmp_filename.c_str(), filename.c_str());
}
std::string HDF5Metadata::DataFileName(const std::string &prefix, int64_t file_number) {
std::string HDF5Metadata::DataFileName(const StartMessage &msg, int64_t file_number) {
if (file_number < 0)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"File number cannot be negative");
else if (file_number >= 1000000)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Format doesn't allow for 1 million or more files");
else
return fmt::format("{:s}_data_{:06d}.h5", prefix, file_number + 1);
if (msg.source_name == "SwissFEL") {
if (file_number >= 10000)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Format doesn't allow for 10'000 or more files");
else if (msg.detector_serial_number.empty())
return fmt::format("{:s}{:04d}.JF.h5", msg.file_prefix, file_number + 1);
else
return fmt::format("{:s}{:04d}.{:s}.h5", msg.file_prefix, file_number + 1, msg.detector_serial_number);
} else {
if (file_number >= 1000000)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Format doesn't allow for 1 million or more files");
else
return fmt::format("{:s}_data_{:06d}.h5", msg.file_prefix, file_number + 1);
}
}
void NXmx::LinkToData(const StartMessage &start, const EndMessage &end) {
@@ -66,7 +77,7 @@ void NXmx::LinkToData(const StartMessage &start, const EndMessage &end) {
for (uint32_t file_id = 0; file_id < file_count; file_id++) {
char buff[32];
snprintf(buff,32,"/entry/data/data_%06d", file_id+1);
hdf5_file->ExternalLink(HDF5Metadata::DataFileName(start.file_prefix, file_id),
hdf5_file->ExternalLink(HDF5Metadata::DataFileName(start, file_id),
"/entry/data/data",
std::string(buff));
}

View File

@@ -8,7 +8,7 @@
#include "HDF5Objects.h"
namespace HDF5Metadata {
std::string DataFileName(const std::string &prefix, int64_t file_number);
std::string DataFileName(const StartMessage &msg, int64_t file_number);
}
class NXmx {

View File

@@ -62,10 +62,11 @@ void HDF5Writer::AddStats(const std::optional<HDF5DataFileStatistics>& s) {
j["pixel_size_m"] = start_message.pixel_size_x;
j["detector_width_pxl"] = start_message.image_size_x;
j["detector_height_pxl"] = start_message.image_size_y;
j["photon_energy_eV"] = start_message.incident_energy;
j["incident_energy_eV"] = start_message.incident_energy;
j["saturation"] = start_message.saturation_value;
j["sample_name"] = start_message.sample_name;
j["run_number"] = start_message.series_id;
j["run_number"] = start_message.run_number;
j["run_name"] = start_message.run_name;
if (start_message.experiment_group)
j["experiment_group"] = start_message.experiment_group.value();
@@ -83,17 +84,7 @@ void HDF5Writer::AddStats(const std::optional<HDF5DataFileStatistics>& s) {
if (start_message.error_value)
j["underload"] = start_message.error_value.value();
if (!start_message.user_data.empty()) {
nlohmann::json j_userdata;
// if user_data is valid json, interpret it as such, otherwise embed as string
try {
j_userdata = nlohmann::json::parse(start_message.user_data);
} catch (...) {
j_userdata = start_message.user_data;
}
j["user_data"] = j_userdata;
}
j["user_data"] = start_message.user_data;
socket->Send(j.dump());
}
}

View File

@@ -1,6 +1,8 @@
// Copyright (2019-2023) Paul Scherrer Institute
#include "../common/GitInfo.h"
#include "JFJochWriterHttp.h"
#include "gen/model/Writer_statistics.h"
void JFJochWriterHttp::status_get(Pistache::Http::ResponseWriter &response) {
auto stat = writer.GetStatistics();
@@ -9,6 +11,9 @@ void JFJochWriterHttp::status_get(Pistache::Http::ResponseWriter &response) {
resp_struct.setPerformanceMBs(stat.performance_MBs);
resp_struct.setPerformanceHz(stat.performance_Hz);
resp_struct.setFilePrefix(stat.file_prefix);
resp_struct.setRunName(stat.run_name);
resp_struct.setRunNumber(stat.run_number);
switch (stat.state) {
case StreamWriterState::Idle:
resp_struct.setState("idle");
@@ -34,3 +39,7 @@ JFJochWriterHttp::JFJochWriterHttp(StreamWriter &in_writer, std::shared_ptr<Pist
: DefaultApi(rtr), writer(in_writer){
init();
}
void JFJochWriterHttp::version_get(Pistache::Http::ResponseWriter &response) {
response.send(Pistache::Http::Code::Ok, jfjoch_version(), MIME(Text, Plain));
}

View File

@@ -13,7 +13,11 @@
class JFJochWriterHttp : public org::openapitools::server::api::DefaultApi {
StreamWriter& writer;
void status_get(Pistache::Http::ResponseWriter &response) override;
void version_get(Pistache::Http::ResponseWriter &response) override;
void cancel_post(Pistache::Http::ResponseWriter &response) override;
public:
JFJochWriterHttp(StreamWriter& writer, std::shared_ptr<Pistache::Rest::Router> &rtr);

View File

@@ -43,14 +43,19 @@ Creates PUB socket to inform about finalized data files. For each closed file, t
```
{
"filename": <string>: HDF5 data file name (relative to writer root directory),
"nimages": <int> number of images in the file,
"user_data": <string> or <json> user_data
"nimages": <int> number of images in the file (counting from 1!),
"file_number": <int> number of file within the acquisition,
"sample_name": <string> name of sample,
"run_name": <string> name of run,
"run_number": <int> number of run,
"experiment_group": <string> number of p-group / proposal (optional),
"user_data": <any json> user_data,
"beam_x_pxl": <float> beam center (X) in pixels,
"beam_y_pxl": <float> beam center (Y) in pixels,
"detector_distance_m": <float> detector distance (X) in m,
"detector_height_pxl": <int> detector size (X) in pixels,
"detector_width_pxl": <int> detector size (Y) in pixels,
"photon_energy_eV": <float> photon energy of the X-ray beam,
"incident_energy_eV": <float> photon energy of the X-ray beam,
"pixel_size_m": <float> pixel size in meter (assuming pixel X == Y),
"saturation": <int> this count and higher mean saturation,
"space_group_number": <int> space group number (optional),
@@ -70,6 +75,11 @@ For example `header_appendix` of `{"param1": "test1", "param2": ["test1", "test2
{
"filename": "dataset_name_data_000001.h5",
"nimages": 1000,
"file_number": 0,
"sample_name": "lysozyme",
"run_name": "lyso_cryo",
"run_number": 25,
"experiment_group": "p00001",
"beam_x_pxl": 1200,
"beam_y_pxl": 1500,
"detector_distance_m": 0.155,
@@ -77,7 +87,7 @@ For example `header_appendix` of `{"param1": "test1", "param2": ["test1", "test2
"detector_width_pxl": 2068,
"image_time_s": 0.001,
"nimages": 2,
"photon_energy_eV": 12400.0,
"incident_energy_eV": 12400.0,
"pixel_size_m": 7.5e-05,
"saturation": 32766,
"space_group_number": 96,
@@ -97,8 +107,8 @@ For example `header_appendix` of `{"param1": "test1", "param2": ["test1", "test2
}
```
Notifications for finalized files are optional, if notification port number is omitted this functionality is not enabled.
## NXmx extensions
Jungfraujoch aims to generate files compliant with NXmx format, as well as make them as close as possible to files
written by DECTRIS Filewriter. This ensures the file compatibility of Neggia and Durin XDS plugins, as well as Albula viewer.

View File

@@ -37,7 +37,10 @@ void StreamWriter::CollectImages(std::vector<HDF5DataFileStatistics> &v) {
processed_images = 0;
processed_image_size = 0;
file_prefix = image_puller_output.cbor->start_message->file_prefix;
run_number = image_puller_output.cbor->start_message->run_number;
run_name = image_puller_output.cbor->start_message->run_name;
CheckPath(image_puller_output.cbor->start_message->file_prefix);
MakeDirectory(image_puller_output.cbor->start_message->file_prefix);
@@ -141,6 +144,8 @@ StreamWriterStatistics StreamWriter::GetStatistics() const {
.performance_MBs = perf_MBs,
.performance_Hz = perf_Hz,
.file_prefix = file_prefix,
.run_name = run_name,
.run_number = run_number,
.state = state
};
}

View File

@@ -15,6 +15,8 @@ struct StreamWriterStatistics {
float performance_MBs;
float performance_Hz;
std::string file_prefix;
std::string run_name;
uint64_t run_number;
StreamWriterState state;
};
@@ -35,6 +37,8 @@ class StreamWriter {
std::chrono::time_point<std::chrono::system_clock> start_time;
std::chrono::time_point<std::chrono::system_clock> end_time;
std::string file_prefix;
std::string run_name;
uint64_t run_number;
ZMQImagePuller image_puller;
Logger &logger;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0
* The version of the OpenAPI document: 1.0.0.rc_10
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -35,6 +35,7 @@ void DefaultApi::setupRoutes() {
Routes::Post(*router, base + "/cancel", Routes::bind(&DefaultApi::cancel_post_handler, this));
Routes::Get(*router, base + "/status", Routes::bind(&DefaultApi::status_get_handler, this));
Routes::Get(*router, base + "/version", Routes::bind(&DefaultApi::version_get_handler, this));
// Default handler, called when a route is not found
router->addCustomHandler(Routes::bind(&DefaultApi::default_api_default_handler, this));
@@ -97,6 +98,26 @@ void DefaultApi::status_get_handler(const Pistache::Rest::Request &, Pistache::H
response.send(Pistache::Http::Code::Internal_Server_Error, e.what());
}
}
void DefaultApi::version_get_handler(const Pistache::Rest::Request &, Pistache::Http::ResponseWriter response) {
try {
try {
this->version_get(response);
} catch (Pistache::Http::HttpError &e) {
response.send(static_cast<Pistache::Http::Code>(e.code()), e.what());
return;
} catch (std::exception &e) {
const std::pair<Pistache::Http::Code, std::string> 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) {

View File

@@ -2,7 +2,7 @@
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0
* The version of the OpenAPI document: 1.0.0.rc_10
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -27,6 +27,7 @@
#include <utility>
#include "Writer_statistics.h"
#include <string>
namespace org::openapitools::server::api
{
@@ -44,6 +45,7 @@ private:
void cancel_post_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void status_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void version_get_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
void default_api_default_handler(const Pistache::Rest::Request &request, Pistache::Http::ResponseWriter response);
const std::shared_ptr<Pistache::Rest::Router> router;
@@ -76,6 +78,13 @@ private:
///
/// </remarks>
virtual void status_get(Pistache::Http::ResponseWriter &response) = 0;
/// <summary>
///
/// </summary>
/// <remarks>
///
/// </remarks>
virtual void version_get(Pistache::Http::ResponseWriter &response) = 0;
};

View File

@@ -2,7 +2,7 @@
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0
* The version of the OpenAPI document: 1.0.0.rc_10
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -2,7 +2,7 @@
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0
* The version of the OpenAPI document: 1.0.0.rc_10
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).

View File

@@ -2,7 +2,7 @@
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0
* The version of the OpenAPI document: 1.0.0.rc_10
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -27,6 +27,10 @@ Writer_statistics::Writer_statistics()
m_Performance_MBsIsSet = false;
m_Performance_Hz = 0.0f;
m_Performance_HzIsSet = false;
m_Run_number = 0L;
m_Run_numberIsSet = false;
m_Run_name = "";
m_Run_nameIsSet = false;
m_File_prefix = "";
m_File_prefixIsSet = false;
m_State = "";
@@ -53,7 +57,7 @@ bool Writer_statistics::validate(std::stringstream& msg, const std::string& path
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Writer_statistics" : pathPrefix;
return success;
}
@@ -72,6 +76,12 @@ bool Writer_statistics::operator==(const Writer_statistics& rhs) const
((!performanceHzIsSet() && !rhs.performanceHzIsSet()) || (performanceHzIsSet() && rhs.performanceHzIsSet() && getPerformanceHz() == rhs.getPerformanceHz())) &&
((!runNumberIsSet() && !rhs.runNumberIsSet()) || (runNumberIsSet() && rhs.runNumberIsSet() && getRunNumber() == rhs.getRunNumber())) &&
((!runNameIsSet() && !rhs.runNameIsSet()) || (runNameIsSet() && rhs.runNameIsSet() && getRunName() == rhs.getRunName())) &&
((!filePrefixIsSet() && !rhs.filePrefixIsSet()) || (filePrefixIsSet() && rhs.filePrefixIsSet() && getFilePrefix() == rhs.getFilePrefix())) &&
@@ -94,6 +104,10 @@ void to_json(nlohmann::json& j, const Writer_statistics& o)
j["performance_MBs"] = o.m_Performance_MBs;
if(o.performanceHzIsSet())
j["performance_Hz"] = o.m_Performance_Hz;
if(o.runNumberIsSet())
j["run_number"] = o.m_Run_number;
if(o.runNameIsSet())
j["run_name"] = o.m_Run_name;
if(o.filePrefixIsSet())
j["file_prefix"] = o.m_File_prefix;
if(o.stateIsSet())
@@ -118,6 +132,16 @@ void from_json(const nlohmann::json& j, Writer_statistics& o)
j.at("performance_Hz").get_to(o.m_Performance_Hz);
o.m_Performance_HzIsSet = true;
}
if(j.find("run_number") != j.end())
{
j.at("run_number").get_to(o.m_Run_number);
o.m_Run_numberIsSet = true;
}
if(j.find("run_name") != j.end())
{
j.at("run_name").get_to(o.m_Run_name);
o.m_Run_nameIsSet = true;
}
if(j.find("file_prefix") != j.end())
{
j.at("file_prefix").get_to(o.m_File_prefix);
@@ -182,6 +206,40 @@ void Writer_statistics::unsetPerformance_Hz()
{
m_Performance_HzIsSet = false;
}
int64_t Writer_statistics::getRunNumber() const
{
return m_Run_number;
}
void Writer_statistics::setRunNumber(int64_t const value)
{
m_Run_number = value;
m_Run_numberIsSet = true;
}
bool Writer_statistics::runNumberIsSet() const
{
return m_Run_numberIsSet;
}
void Writer_statistics::unsetRun_number()
{
m_Run_numberIsSet = false;
}
std::string Writer_statistics::getRunName() const
{
return m_Run_name;
}
void Writer_statistics::setRunName(std::string const& value)
{
m_Run_name = value;
m_Run_nameIsSet = true;
}
bool Writer_statistics::runNameIsSet() const
{
return m_Run_nameIsSet;
}
void Writer_statistics::unsetRun_name()
{
m_Run_nameIsSet = false;
}
std::string Writer_statistics::getFilePrefix() const
{
return m_File_prefix;

View File

@@ -2,7 +2,7 @@
* Jungfraujoch writer
* Jungfraujoch Writer Web API
*
* The version of the OpenAPI document: 1.0.0
* The version of the OpenAPI document: 1.0.0.rc_10
*
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
@@ -80,6 +80,20 @@ public:
bool performanceHzIsSet() const;
void unsetPerformance_Hz();
/// <summary>
///
/// </summary>
int64_t getRunNumber() const;
void setRunNumber(int64_t const value);
bool runNumberIsSet() const;
void unsetRun_number();
/// <summary>
///
/// </summary>
std::string getRunName() const;
void setRunName(std::string const& value);
bool runNameIsSet() const;
void unsetRun_name();
/// <summary>
/// File prefix for the last written dataset
/// </summary>
std::string getFilePrefix() const;
@@ -103,6 +117,10 @@ protected:
bool m_Performance_MBsIsSet;
float m_Performance_Hz;
bool m_Performance_HzIsSet;
int64_t m_Run_number;
bool m_Run_numberIsSet;
std::string m_Run_name;
bool m_Run_nameIsSet;
std::string m_File_prefix;
bool m_File_prefixIsSet;
std::string m_State;

View File

@@ -12,263 +12,263 @@
margin: 0;
}
</style>
<script src="https://cdn.redoc.ly/redoc/v2.1.2/bundles/redoc.standalone.js"></script><style data-styled="true" data-styled-version="6.1.1">.gvoNGN{width:calc(100% - 40%);padding:0 40px;}/*!sc*/
@media print,screen and (max-width: 75rem){.gvoNGN{width:100%;padding:40px 40px;}}/*!sc*/
data-styled.g4[id="sc-hKgKIp"]{content:"gvoNGN,"}/*!sc*/
.kxmVZO{padding:40px 0;}/*!sc*/
.kxmVZO:last-child{min-height:calc(100vh + 1px);}/*!sc*/
.kxmVZO>.kxmVZO:last-child{min-height:initial;}/*!sc*/
@media print,screen and (max-width: 75rem){.kxmVZO{padding:0;}}/*!sc*/
.bCpIRB{padding:40px 0;position:relative;}/*!sc*/
.bCpIRB:last-child{min-height:calc(100vh + 1px);}/*!sc*/
.bCpIRB>.bCpIRB:last-child{min-height:initial;}/*!sc*/
@media print,screen and (max-width: 75rem){.bCpIRB{padding:0;}}/*!sc*/
.bCpIRB:not(:last-of-type):after{position:absolute;bottom:0;width:100%;display:block;content:'';border-bottom:1px solid rgba(0, 0, 0, 0.2);}/*!sc*/
data-styled.g5[id="sc-eCstZk"]{content:"kxmVZO,bCpIRB,"}/*!sc*/
.QymcT{width:40%;color:#ffffff;background-color:#263238;padding:0 40px;}/*!sc*/
@media print,screen and (max-width: 75rem){.QymcT{width:100%;padding:40px 40px;}}/*!sc*/
data-styled.g6[id="sc-jSguLX"]{content:"QymcT,"}/*!sc*/
.bZqtR{background-color:#263238;}/*!sc*/
data-styled.g7[id="sc-gKsecS"]{content:"bZqtR,"}/*!sc*/
.keMybc{display:flex;width:100%;padding:0;}/*!sc*/
@media print,screen and (max-width: 75rem){.keMybc{flex-direction:column;}}/*!sc*/
data-styled.g8[id="sc-iBPTVF"]{content:"keMybc,"}/*!sc*/
.djltfY{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.85714em;line-height:1.6em;color:#333333;}/*!sc*/
data-styled.g9[id="sc-fubDmA"]{content:"djltfY,"}/*!sc*/
.biKwui{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.57143em;line-height:1.6em;color:#333333;margin:0 0 20px;}/*!sc*/
data-styled.g10[id="sc-pGaPU"]{content:"biKwui,"}/*!sc*/
.jmifsN{color:#ffffff;}/*!sc*/
data-styled.g12[id="sc-kEjbdu"]{content:"jmifsN,"}/*!sc*/
.sc-crrtmM{cursor:pointer;margin-left:-20px;padding:0;line-height:1;width:20px;display:inline-block;outline:0;}/*!sc*/
.jGBpue:before{content:'';width:15px;height:15px;background-size:contain;background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjMDEwMTAxIiBkPSJNNDU5LjcgMjMzLjRsLTkwLjUgOTAuNWMtNTAgNTAtMTMxIDUwLTE4MSAwIC03LjktNy44LTE0LTE2LjctMTkuNC0yNS44bDQyLjEtNDIuMWMyLTIgNC41LTMuMiA2LjgtNC41IDIuOSA5LjkgOCAxOS4zIDE1LjggMjcuMiAyNSAyNSA2NS42IDI0LjkgOTAuNSAwbDkwLjUtOTAuNWMyNS0yNSAyNS02NS42IDAtOTAuNSAtMjQuOS0yNS02NS41LTI1LTkwLjUgMGwtMzIuMiAzMi4yYy0yNi4xLTEwLjItNTQuMi0xMi45LTgxLjYtOC45bDY4LjYtNjguNmM1MC01MCAxMzEtNTAgMTgxIDBDNTA5LjYgMTAyLjMgNTA5LjYgMTgzLjQgNDU5LjcgMjMzLjR6TTIyMC4zIDM4Mi4ybC0zMi4yIDMyLjJjLTI1IDI0LjktNjUuNiAyNC45LTkwLjUgMCAtMjUtMjUtMjUtNjUuNiAwLTkwLjVsOTAuNS05MC41YzI1LTI1IDY1LjUtMjUgOTAuNSAwIDcuOCA3LjggMTIuOSAxNy4yIDE1LjggMjcuMSAyLjQtMS40IDQuOC0yLjUgNi44LTQuNWw0Mi4xLTQyYy01LjQtOS4yLTExLjYtMTgtMTkuNC0yNS44IC01MC01MC0xMzEtNTAtMTgxIDBsLTkwLjUgOTAuNWMtNTAgNTAtNTAgMTMxIDAgMTgxIDUwIDUwIDEzMSA1MCAxODEgMGw2OC42LTY4LjZDMjc0LjYgMzk1LjEgMjQ2LjQgMzkyLjMgMjIwLjMgMzgyLjJ6Ii8+PC9zdmc+Cg==');opacity:0.5;visibility:hidden;display:inline-block;vertical-align:middle;}/*!sc*/
h1:hover>.jGBpue::before,h2:hover>.jGBpue::before,.jGBpue:hover::before{visibility:visible;}/*!sc*/
data-styled.g14[id="sc-crrtmM"]{content:"jGBpue,"}/*!sc*/
.iHKCKT{height:1.5em;width:1.5em;min-width:1.5em;vertical-align:middle;float:left;transition:transform 0.2s ease-out;transform:rotateZ(-90deg);}/*!sc*/
.iHKCKT polygon{fill:#1d8127;}/*!sc*/
.hHbBnT{height:20px;width:20px;min-width:20px;vertical-align:middle;float:right;transition:transform 0.2s ease-out;transform:rotateZ(0);}/*!sc*/
.hHbBnT polygon{fill:white;}/*!sc*/
data-styled.g15[id="sc-dQpIV"]{content:"iHKCKT,hHbBnT,"}/*!sc*/
.jVRsAZ >ul{list-style:none;padding:0;margin:0;margin:0 -5px;}/*!sc*/
.jVRsAZ >ul >li{padding:5px 10px;display:inline-block;background-color:#11171a;border-bottom:1px solid rgba(0, 0, 0, 0.5);cursor:pointer;text-align:center;outline:none;color:#ccc;margin:0 5px 5px 5px;border:1px solid #07090b;border-radius:5px;min-width:60px;font-size:0.9em;font-weight:bold;}/*!sc*/
.jVRsAZ >ul >li.react-tabs__tab--selected{color:#333333;background:#ffffff;}/*!sc*/
.jVRsAZ >ul >li.react-tabs__tab--selected:focus{outline:auto;}/*!sc*/
.jVRsAZ >ul >li:only-child{flex:none;min-width:100px;}/*!sc*/
.jVRsAZ >ul >li.tab-success{color:#1d8127;}/*!sc*/
.jVRsAZ >ul >li.tab-redirect{color:#ffa500;}/*!sc*/
.jVRsAZ >ul >li.tab-info{color:#87ceeb;}/*!sc*/
.jVRsAZ >ul >li.tab-error{color:#d41f1c;}/*!sc*/
.jVRsAZ >.react-tabs__tab-panel{background:#11171a;}/*!sc*/
.jVRsAZ >.react-tabs__tab-panel>div,.jVRsAZ >.react-tabs__tab-panel>pre{padding:20px;margin:0;}/*!sc*/
.jVRsAZ >.react-tabs__tab-panel>div>pre{padding:0;}/*!sc*/
data-styled.g30[id="sc-cxFKTC"]{content:"jVRsAZ,"}/*!sc*/
.gpkGbA code[class*='language-'],.gpkGbA pre[class*='language-']{text-shadow:0 -0.1em 0.2em black;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}/*!sc*/
@media print{.gpkGbA code[class*='language-'],.gpkGbA pre[class*='language-']{text-shadow:none;}}/*!sc*/
.gpkGbA pre[class*='language-']{padding:1em;margin:0.5em 0;overflow:auto;}/*!sc*/
.gpkGbA .token.comment,.gpkGbA .token.prolog,.gpkGbA .token.doctype,.gpkGbA .token.cdata{color:hsl(30, 20%, 50%);}/*!sc*/
.gpkGbA .token.punctuation{opacity:0.7;}/*!sc*/
.gpkGbA .namespace{opacity:0.7;}/*!sc*/
.gpkGbA .token.property,.gpkGbA .token.tag,.gpkGbA .token.number,.gpkGbA .token.constant,.gpkGbA .token.symbol{color:#4a8bb3;}/*!sc*/
.gpkGbA .token.boolean{color:#e64441;}/*!sc*/
.gpkGbA .token.selector,.gpkGbA .token.attr-name,.gpkGbA .token.string,.gpkGbA .token.char,.gpkGbA .token.builtin,.gpkGbA .token.inserted{color:#a0fbaa;}/*!sc*/
.gpkGbA .token.selector+a,.gpkGbA .token.attr-name+a,.gpkGbA .token.string+a,.gpkGbA .token.char+a,.gpkGbA .token.builtin+a,.gpkGbA .token.inserted+a,.gpkGbA .token.selector+a:visited,.gpkGbA .token.attr-name+a:visited,.gpkGbA .token.string+a:visited,.gpkGbA .token.char+a:visited,.gpkGbA .token.builtin+a:visited,.gpkGbA .token.inserted+a:visited{color:#4ed2ba;text-decoration:underline;}/*!sc*/
.gpkGbA .token.property.string{color:white;}/*!sc*/
.gpkGbA .token.operator,.gpkGbA .token.entity,.gpkGbA .token.url,.gpkGbA .token.variable{color:hsl(40, 90%, 60%);}/*!sc*/
.gpkGbA .token.atrule,.gpkGbA .token.attr-value,.gpkGbA .token.keyword{color:hsl(350, 40%, 70%);}/*!sc*/
.gpkGbA .token.regex,.gpkGbA .token.important{color:#e90;}/*!sc*/
.gpkGbA .token.important,.gpkGbA .token.bold{font-weight:bold;}/*!sc*/
.gpkGbA .token.italic{font-style:italic;}/*!sc*/
.gpkGbA .token.entity{cursor:help;}/*!sc*/
.gpkGbA .token.deleted{color:red;}/*!sc*/
data-styled.g32[id="sc-iJuWdM"]{content:"gpkGbA,"}/*!sc*/
.bIDavi{opacity:0.7;transition:opacity 0.3s ease;text-align:right;}/*!sc*/
.bIDavi:focus-within{opacity:1;}/*!sc*/
.bIDavi >button{background-color:transparent;border:0;color:inherit;padding:2px 10px;font-family:Roboto,sans-serif;font-size:14px;line-height:1.5em;cursor:pointer;outline:0;}/*!sc*/
.bIDavi >button :hover,.bIDavi >button :focus{background:rgba(255, 255, 255, 0.1);}/*!sc*/
data-styled.g33[id="sc-giInvV"]{content:"bIDavi,"}/*!sc*/
.eJckYb{position:relative;}/*!sc*/
data-styled.g37[id="sc-kLgoAE"]{content:"eJckYb,"}/*!sc*/
.casAkG{font-family:Roboto,sans-serif;font-weight:400;line-height:1.5em;}/*!sc*/
.casAkG p:last-child{margin-bottom:0;}/*!sc*/
.casAkG h1{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.85714em;line-height:1.6em;color:#32329f;margin-top:0;}/*!sc*/
.casAkG h2{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.57143em;line-height:1.6em;color:#333333;}/*!sc*/
.casAkG code{color:#e53935;background-color:rgba(38, 50, 56, 0.05);font-family:Courier,monospace;border-radius:2px;border:1px solid rgba(38, 50, 56, 0.1);padding:0 5px;font-size:13px;font-weight:400;word-break:break-word;}/*!sc*/
.casAkG pre{font-family:Courier,monospace;white-space:pre;background-color:#11171a;color:white;padding:20px;overflow-x:auto;line-height:normal;border-radius:0;border:1px solid rgba(38, 50, 56, 0.1);}/*!sc*/
.casAkG pre code{background-color:transparent;color:white;padding:0;}/*!sc*/
.casAkG pre code:before,.casAkG pre code:after{content:none;}/*!sc*/
.casAkG blockquote{margin:0;margin-bottom:1em;padding:0 15px;color:#777;border-left:4px solid #ddd;}/*!sc*/
.casAkG img{max-width:100%;box-sizing:content-box;}/*!sc*/
.casAkG ul,.casAkG ol{padding-left:2em;margin:0;margin-bottom:1em;}/*!sc*/
.casAkG ul ul,.casAkG ol ul,.casAkG ul ol,.casAkG ol ol{margin-bottom:0;margin-top:0;}/*!sc*/
.casAkG table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all;border-collapse:collapse;border-spacing:0;margin-top:1.5em;margin-bottom:1.5em;}/*!sc*/
.casAkG table tr{background-color:#fff;border-top:1px solid #ccc;}/*!sc*/
.casAkG table tr:nth-child(2n){background-color:#fafafa;}/*!sc*/
.casAkG table th,.casAkG table td{padding:6px 13px;border:1px solid #ddd;}/*!sc*/
.casAkG table th{text-align:left;font-weight:bold;}/*!sc*/
.casAkG .share-link{cursor:pointer;margin-left:-20px;padding:0;line-height:1;width:20px;display:inline-block;outline:0;}/*!sc*/
.casAkG .share-link:before{content:'';width:15px;height:15px;background-size:contain;background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjMDEwMTAxIiBkPSJNNDU5LjcgMjMzLjRsLTkwLjUgOTAuNWMtNTAgNTAtMTMxIDUwLTE4MSAwIC03LjktNy44LTE0LTE2LjctMTkuNC0yNS44bDQyLjEtNDIuMWMyLTIgNC41LTMuMiA2LjgtNC41IDIuOSA5LjkgOCAxOS4zIDE1LjggMjcuMiAyNSAyNSA2NS42IDI0LjkgOTAuNSAwbDkwLjUtOTAuNWMyNS0yNSAyNS02NS42IDAtOTAuNSAtMjQuOS0yNS02NS41LTI1LTkwLjUgMGwtMzIuMiAzMi4yYy0yNi4xLTEwLjItNTQuMi0xMi45LTgxLjYtOC45bDY4LjYtNjguNmM1MC01MCAxMzEtNTAgMTgxIDBDNTA5LjYgMTAyLjMgNTA5LjYgMTgzLjQgNDU5LjcgMjMzLjR6TTIyMC4zIDM4Mi4ybC0zMi4yIDMyLjJjLTI1IDI0LjktNjUuNiAyNC45LTkwLjUgMCAtMjUtMjUtMjUtNjUuNiAwLTkwLjVsOTAuNS05MC41YzI1LTI1IDY1LjUtMjUgOTAuNSAwIDcuOCA3LjggMTIuOSAxNy4yIDE1LjggMjcuMSAyLjQtMS40IDQuOC0yLjUgNi44LTQuNWw0Mi4xLTQyYy01LjQtOS4yLTExLjYtMTgtMTkuNC0yNS44IC01MC01MC0xMzEtNTAtMTgxIDBsLTkwLjUgOTAuNWMtNTAgNTAtNTAgMTMxIDAgMTgxIDUwIDUwIDEzMSA1MCAxODEgMGw2OC42LTY4LjZDMjc0LjYgMzk1LjEgMjQ2LjQgMzkyLjMgMjIwLjMgMzgyLjJ6Ii8+PC9zdmc+Cg==');opacity:0.5;visibility:hidden;display:inline-block;vertical-align:middle;}/*!sc*/
.casAkG h1:hover>.share-link::before,.casAkG h2:hover>.share-link::before,.casAkG .share-link:hover::before{visibility:visible;}/*!sc*/
.casAkG a{text-decoration:auto;color:#32329f;}/*!sc*/
.casAkG a:visited{color:#32329f;}/*!sc*/
.casAkG a:hover{color:#6868cf;text-decoration:auto;}/*!sc*/
.dujygE{font-family:Roboto,sans-serif;font-weight:400;line-height:1.5em;}/*!sc*/
.dujygE p:last-child{margin-bottom:0;}/*!sc*/
.dujygE p:first-child{margin-top:0;}/*!sc*/
.dujygE p:last-child{margin-bottom:0;}/*!sc*/
.dujygE h1{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.85714em;line-height:1.6em;color:#32329f;margin-top:0;}/*!sc*/
.dujygE h2{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.57143em;line-height:1.6em;color:#333333;}/*!sc*/
.dujygE code{color:#e53935;background-color:rgba(38, 50, 56, 0.05);font-family:Courier,monospace;border-radius:2px;border:1px solid rgba(38, 50, 56, 0.1);padding:0 5px;font-size:13px;font-weight:400;word-break:break-word;}/*!sc*/
.dujygE pre{font-family:Courier,monospace;white-space:pre;background-color:#11171a;color:white;padding:20px;overflow-x:auto;line-height:normal;border-radius:0;border:1px solid rgba(38, 50, 56, 0.1);}/*!sc*/
.dujygE pre code{background-color:transparent;color:white;padding:0;}/*!sc*/
.dujygE pre code:before,.dujygE pre code:after{content:none;}/*!sc*/
.dujygE blockquote{margin:0;margin-bottom:1em;padding:0 15px;color:#777;border-left:4px solid #ddd;}/*!sc*/
.dujygE img{max-width:100%;box-sizing:content-box;}/*!sc*/
.dujygE ul,.dujygE ol{padding-left:2em;margin:0;margin-bottom:1em;}/*!sc*/
.dujygE ul ul,.dujygE ol ul,.dujygE ul ol,.dujygE ol ol{margin-bottom:0;margin-top:0;}/*!sc*/
.dujygE table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all;border-collapse:collapse;border-spacing:0;margin-top:1.5em;margin-bottom:1.5em;}/*!sc*/
.dujygE table tr{background-color:#fff;border-top:1px solid #ccc;}/*!sc*/
.dujygE table tr:nth-child(2n){background-color:#fafafa;}/*!sc*/
.dujygE table th,.dujygE table td{padding:6px 13px;border:1px solid #ddd;}/*!sc*/
.dujygE table th{text-align:left;font-weight:bold;}/*!sc*/
.dujygE .share-link{cursor:pointer;margin-left:-20px;padding:0;line-height:1;width:20px;display:inline-block;outline:0;}/*!sc*/
.dujygE .share-link:before{content:'';width:15px;height:15px;background-size:contain;background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjMDEwMTAxIiBkPSJNNDU5LjcgMjMzLjRsLTkwLjUgOTAuNWMtNTAgNTAtMTMxIDUwLTE4MSAwIC03LjktNy44LTE0LTE2LjctMTkuNC0yNS44bDQyLjEtNDIuMWMyLTIgNC41LTMuMiA2LjgtNC41IDIuOSA5LjkgOCAxOS4zIDE1LjggMjcuMiAyNSAyNSA2NS42IDI0LjkgOTAuNSAwbDkwLjUtOTAuNWMyNS0yNSAyNS02NS42IDAtOTAuNSAtMjQuOS0yNS02NS41LTI1LTkwLjUgMGwtMzIuMiAzMi4yYy0yNi4xLTEwLjItNTQuMi0xMi45LTgxLjYtOC45bDY4LjYtNjguNmM1MC01MCAxMzEtNTAgMTgxIDBDNTA5LjYgMTAyLjMgNTA5LjYgMTgzLjQgNDU5LjcgMjMzLjR6TTIyMC4zIDM4Mi4ybC0zMi4yIDMyLjJjLTI1IDI0LjktNjUuNiAyNC45LTkwLjUgMCAtMjUtMjUtMjUtNjUuNiAwLTkwLjVsOTAuNS05MC41YzI1LTI1IDY1LjUtMjUgOTAuNSAwIDcuOCA3LjggMTIuOSAxNy4yIDE1LjggMjcuMSAyLjQtMS40IDQuOC0yLjUgNi44LTQuNWw0Mi4xLTQyYy01LjQtOS4yLTExLjYtMTgtMTkuNC0yNS44IC01MC01MC0xMzEtNTAtMTgxIDBsLTkwLjUgOTAuNWMtNTAgNTAtNTAgMTMxIDAgMTgxIDUwIDUwIDEzMSA1MCAxODEgMGw2OC42LTY4LjZDMjc0LjYgMzk1LjEgMjQ2LjQgMzkyLjMgMjIwLjMgMzgyLjJ6Ii8+PC9zdmc+Cg==');opacity:0.5;visibility:hidden;display:inline-block;vertical-align:middle;}/*!sc*/
.dujygE h1:hover>.share-link::before,.dujygE h2:hover>.share-link::before,.dujygE .share-link:hover::before{visibility:visible;}/*!sc*/
.dujygE a{text-decoration:auto;color:#32329f;}/*!sc*/
.dujygE a:visited{color:#32329f;}/*!sc*/
.dujygE a:hover{color:#6868cf;text-decoration:auto;}/*!sc*/
data-styled.g42[id="sc-cBNeRQ"]{content:"casAkG,dujygE,"}/*!sc*/
.bzkUsW{display:inline;}/*!sc*/
data-styled.g43[id="sc-citwID"]{content:"bzkUsW,"}/*!sc*/
.iVrxDL{position:relative;}/*!sc*/
data-styled.g44[id="sc-jcVcfa"]{content:"iVrxDL,"}/*!sc*/
.gLzJQv:hover>.sc-giInvV{opacity:1;}/*!sc*/
data-styled.g49[id="sc-cTkyaV"]{content:"gLzJQv,"}/*!sc*/
.jXmkAn{font-family:Courier,monospace;font-size:13px;white-space:pre;contain:content;overflow-x:auto;}/*!sc*/
.jXmkAn .redoc-json code>.collapser{display:none;pointer-events:none;}/*!sc*/
.jXmkAn .callback-function{color:gray;}/*!sc*/
.jXmkAn .collapser:after{content:'-';cursor:pointer;}/*!sc*/
.jXmkAn .collapsed>.collapser:after{content:'+';cursor:pointer;}/*!sc*/
.jXmkAn .ellipsis:after{content:' … ';}/*!sc*/
.jXmkAn .collapsible{margin-left:2em;}/*!sc*/
.jXmkAn .hoverable{padding-top:1px;padding-bottom:1px;padding-left:2px;padding-right:2px;border-radius:2px;}/*!sc*/
.jXmkAn .hovered{background-color:rgba(235, 238, 249, 1);}/*!sc*/
.jXmkAn .collapser{background-color:transparent;border:0;color:#fff;font-family:Courier,monospace;font-size:13px;padding-right:6px;padding-left:6px;padding-top:0;padding-bottom:0;display:flex;align-items:center;justify-content:center;width:15px;height:15px;position:absolute;top:4px;left:-1.5em;cursor:default;user-select:none;-webkit-user-select:none;padding:2px;}/*!sc*/
.jXmkAn .collapser:focus{outline-color:#fff;outline-style:dotted;outline-width:1px;}/*!sc*/
.jXmkAn ul{list-style-type:none;padding:0px;margin:0px 0px 0px 26px;}/*!sc*/
.jXmkAn li{position:relative;display:block;}/*!sc*/
.jXmkAn .hoverable{display:inline-block;}/*!sc*/
.jXmkAn .selected{outline-style:solid;outline-width:1px;outline-style:dotted;}/*!sc*/
.jXmkAn .collapsed>.collapsible{display:none;}/*!sc*/
.jXmkAn .ellipsis{display:none;}/*!sc*/
.jXmkAn .collapsed>.ellipsis{display:inherit;}/*!sc*/
data-styled.g50[id="sc-jNMdxs"]{content:"jXmkAn,"}/*!sc*/
.bAzVww{padding:0.9em;background-color:rgba(38,50,56,0.4);margin:0 0 10px 0;display:block;font-family:Montserrat,sans-serif;font-size:0.929em;line-height:1.5em;}/*!sc*/
data-styled.g51[id="sc-dOSSlk"]{content:"bAzVww,"}/*!sc*/
.etjuEr{font-family:Montserrat,sans-serif;font-size:12px;position:absolute;z-index:1;top:-11px;left:12px;font-weight:600;color:rgba(255,255,255,0.7);}/*!sc*/
data-styled.g52[id="sc-bBrOHt"]{content:"etjuEr,"}/*!sc*/
.eDzWuJ{position:relative;}/*!sc*/
data-styled.g53[id="sc-cOaiZO"]{content:"eDzWuJ,"}/*!sc*/
.kTaCsY{margin-top:15px;}/*!sc*/
data-styled.g56[id="sc-hTZhMB"]{content:"kTaCsY,"}/*!sc*/
.hWeMwQ{margin-top:0;margin-bottom:0.5em;}/*!sc*/
data-styled.g91[id="sc-eGCbyA"]{content:"hWeMwQ,"}/*!sc*/
.gUXnfH{border:1px solid #32329f;color:#32329f;font-weight:normal;margin-left:0.5em;padding:4px 8px 4px;display:inline-block;text-decoration:none;cursor:pointer;}/*!sc*/
data-styled.g92[id="sc-ctaXUJ"]{content:"gUXnfH,"}/*!sc*/
.bwwtyo{width:9ex;display:inline-block;height:13px;line-height:13px;background-color:#333;border-radius:3px;background-repeat:no-repeat;background-position:6px 4px;font-size:7px;font-family:Verdana,sans-serif;color:white;text-transform:uppercase;text-align:center;font-weight:bold;vertical-align:middle;margin-right:6px;margin-top:2px;}/*!sc*/
.bwwtyo.get{background-color:#2F8132;}/*!sc*/
.bwwtyo.post{background-color:#186FAF;}/*!sc*/
.bwwtyo.put{background-color:#95507c;}/*!sc*/
.bwwtyo.options{background-color:#947014;}/*!sc*/
.bwwtyo.patch{background-color:#bf581d;}/*!sc*/
.bwwtyo.delete{background-color:#cc3333;}/*!sc*/
.bwwtyo.basic{background-color:#707070;}/*!sc*/
.bwwtyo.link{background-color:#07818F;}/*!sc*/
.bwwtyo.head{background-color:#A23DAD;}/*!sc*/
.bwwtyo.hook{background-color:#32329f;}/*!sc*/
.bwwtyo.schema{background-color:#707070;}/*!sc*/
data-styled.g99[id="sc-dkIYMQ"]{content:"bwwtyo,"}/*!sc*/
.YKcaq{margin:0;padding:0;}/*!sc*/
.YKcaq:first-child{padding-bottom:32px;}/*!sc*/
.sc-XhViZ .sc-XhViZ{font-size:0.929em;}/*!sc*/
data-styled.g100[id="sc-XhViZ"]{content:"YKcaq,"}/*!sc*/
.fhNqYr{list-style:none inside none;overflow:hidden;text-overflow:ellipsis;padding:0;}/*!sc*/
data-styled.g101[id="sc-ikPBrU"]{content:"fhNqYr,"}/*!sc*/
.CYQVt{cursor:pointer;color:#333333;margin:0;padding:12.5px 20px;display:flex;justify-content:space-between;font-family:Montserrat,sans-serif;background-color:#fafafa;}/*!sc*/
.CYQVt:hover{color:#32329f;background-color:#ededed;}/*!sc*/
.CYQVt .sc-dQpIV{height:1.5em;width:1.5em;}/*!sc*/
.CYQVt .sc-dQpIV polygon{fill:#333333;}/*!sc*/
data-styled.g102[id="sc-tYqQR"]{content:"CYQVt,"}/*!sc*/
.bkVowu{display:inline-block;vertical-align:middle;width:calc(100% - 38px);overflow:hidden;text-overflow:ellipsis;}/*!sc*/
data-styled.g103[id="sc-biBryG"]{content:"bkVowu,"}/*!sc*/
.jrtoRW{font-size:0.8em;margin-top:10px;text-align:center;position:fixed;width:260px;bottom:0;background:#fafafa;}/*!sc*/
.jrtoRW a,.jrtoRW a:visited,.jrtoRW a:hover{color:#333333!important;padding:5px 0;border-top:1px solid #e1e1e1;text-decoration:none;display:flex;align-items:center;justify-content:center;}/*!sc*/
.jrtoRW img{width:15px;margin-right:5px;}/*!sc*/
@media screen and (max-width: 50rem){.jrtoRW{width:100%;}}/*!sc*/
data-styled.g104[id="sc-eHfQwz"]{content:"jrtoRW,"}/*!sc*/
.bhuodb{cursor:pointer;position:relative;margin-bottom:5px;}/*!sc*/
data-styled.g110[id="sc-bQdSiB"]{content:"bhuodb,"}/*!sc*/
.jzevEV{font-family:Courier,monospace;margin-left:10px;flex:1;overflow-x:hidden;text-overflow:ellipsis;}/*!sc*/
data-styled.g111[id="sc-fXoxOd"]{content:"jzevEV,"}/*!sc*/
.jlriCd{outline:0;color:inherit;width:100%;text-align:left;cursor:pointer;padding:10px 30px 10px 20px;border-radius:4px 4px 0 0;background-color:#11171a;display:flex;white-space:nowrap;align-items:center;border:1px solid transparent;border-bottom:0;transition:border-color 0.25s ease;}/*!sc*/
.jlriCd ..sc-fXoxOd{color:#ffffff;}/*!sc*/
.jlriCd:focus{box-shadow:inset 0 2px 2px rgba(0, 0, 0, 0.45),0 2px 0 rgba(128, 128, 128, 0.25);}/*!sc*/
data-styled.g112[id="sc-FyfbU"]{content:"jlriCd,"}/*!sc*/
.gDPfwK{font-size:0.929em;line-height:20px;background-color:#2F8132;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/
.coiChI{font-size:0.929em;line-height:20px;background-color:#186FAF;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/
data-styled.g113[id="sc-jXkspL"]{content:"gDPfwK,coiChI,"}/*!sc*/
.ciRGmD{position:absolute;width:100%;z-index:100;background:#fafafa;color:#263238;box-sizing:border-box;box-shadow:0 0 6px rgba(0, 0, 0, 0.33);overflow:hidden;border-bottom-left-radius:4px;border-bottom-right-radius:4px;transition:all 0.25s ease;visibility:hidden;transform:translateY(-50%) scaleY(0);}/*!sc*/
data-styled.g114[id="sc-eFtZDC"]{content:"ciRGmD,"}/*!sc*/
.buTZbL{padding:10px;}/*!sc*/
data-styled.g115[id="sc-fmlKft"]{content:"buTZbL,"}/*!sc*/
.uePtT{padding:5px;border:1px solid #ccc;background:#fff;word-break:break-all;color:#32329f;}/*!sc*/
.uePtT >span{color:#333333;}/*!sc*/
data-styled.g116[id="sc-ljRaSg"]{content:"uePtT,"}/*!sc*/
.iePdRD{display:block;border:0;width:100%;text-align:left;padding:10px;border-radius:2px;margin-bottom:4px;line-height:1.5em;cursor:pointer;color:#1d8127;background-color:rgba(29,129,39,0.07);}/*!sc*/
.iePdRD:focus{outline:auto #1d8127;}/*!sc*/
.eEqsZl{display:block;border:0;width:100%;text-align:left;padding:10px;border-radius:2px;margin-bottom:4px;line-height:1.5em;cursor:pointer;color:#1d8127;background-color:rgba(29,129,39,0.07);cursor:default;}/*!sc*/
.eEqsZl:focus{outline:auto #1d8127;}/*!sc*/
.eEqsZl::before{content:"—";font-weight:bold;width:1.5em;text-align:center;display:inline-block;vertical-align:top;}/*!sc*/
.eEqsZl:focus{outline:0;}/*!sc*/
data-styled.g119[id="sc-httZfN"]{content:"iePdRD,eEqsZl,"}/*!sc*/
.goojcW{vertical-align:top;}/*!sc*/
data-styled.g122[id="sc-gVgoeb"]{content:"goojcW,"}/*!sc*/
.fCsSHf{font-size:1.3em;padding:0.2em 0;margin:3em 0 1.1em;color:#333333;font-weight:normal;}/*!sc*/
data-styled.g123[id="sc-fWPdKs"]{content:"fCsSHf,"}/*!sc*/
.fgfjUV{margin-bottom:30px;}/*!sc*/
data-styled.g128[id="sc-eWVLZl"]{content:"fgfjUV,"}/*!sc*/
.iEVneI{user-select:none;width:20px;height:20px;align-self:center;display:flex;flex-direction:column;color:#32329f;}/*!sc*/
data-styled.g129[id="sc-iGctyi"]{content:"iEVneI,"}/*!sc*/
.gXSQkB{width:260px;background-color:#fafafa;overflow:hidden;display:flex;flex-direction:column;backface-visibility:hidden;height:100vh;position:sticky;position:-webkit-sticky;top:0;}/*!sc*/
@media screen and (max-width: 50rem){.gXSQkB{position:fixed;z-index:20;width:100%;background:#fafafa;display:none;}}/*!sc*/
@media print{.gXSQkB{display:none;}}/*!sc*/
data-styled.g130[id="sc-irlPvL"]{content:"gXSQkB,"}/*!sc*/
.bEOmaQ{outline:none;user-select:none;background-color:#f2f2f2;color:#32329f;display:none;cursor:pointer;position:fixed;right:20px;z-index:100;border-radius:50%;box-shadow:0 0 20px rgba(0, 0, 0, 0.3);bottom:44px;width:60px;height:60px;padding:0 20px;}/*!sc*/
@media screen and (max-width: 50rem){.bEOmaQ{display:flex;}}/*!sc*/
.bEOmaQ svg{color:#0065FB;}/*!sc*/
@media print{.bEOmaQ{display:none;}}/*!sc*/
data-styled.g131[id="sc-eWvOCH"]{content:"bEOmaQ,"}/*!sc*/
.bwTiCm{font-family:Roboto,sans-serif;font-size:14px;font-weight:400;line-height:1.5em;color:#333333;display:flex;position:relative;text-align:left;-webkit-font-smoothing:antialiased;font-smoothing:antialiased;text-rendering:optimizeSpeed!important;tap-highlight-color:rgba(0, 0, 0, 0);text-size-adjust:100%;}/*!sc*/
.bwTiCm *{box-sizing:border-box;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);}/*!sc*/
data-styled.g132[id="sc-kUbfpu"]{content:"bwTiCm,"}/*!sc*/
.dPIjnf{z-index:1;position:relative;overflow:hidden;width:calc(100% - 260px);contain:layout;}/*!sc*/
@media print,screen and (max-width: 50rem){.dPIjnf{width:100%;}}/*!sc*/
data-styled.g133[id="sc-dwcvcB"]{content:"dPIjnf,"}/*!sc*/
.gfiMgB{background:#263238;position:absolute;top:0;bottom:0;right:0;width:calc((100% - 260px) * 0.4);}/*!sc*/
@media print,screen and (max-width: 75rem){.gfiMgB{display:none;}}/*!sc*/
data-styled.g134[id="sc-jtHLPo"]{content:"gfiMgB,"}/*!sc*/
.hwhlAl{padding:5px 0;}/*!sc*/
data-styled.g135[id="sc-eltaTX"]{content:"hwhlAl,"}/*!sc*/
.eWIXbA{width:calc(100% - 40px);box-sizing:border-box;margin:0 20px;padding:5px 10px 5px 20px;border:0;border-bottom:1px solid #e1e1e1;font-family:Roboto,sans-serif;font-weight:bold;font-size:13px;color:#333333;background-color:transparent;outline:none;}/*!sc*/
data-styled.g136[id="sc-kiYrGK"]{content:"eWIXbA,"}/*!sc*/
.lcoFQc{position:absolute;left:20px;height:1.8em;width:0.9em;}/*!sc*/
.lcoFQc path{fill:#333333;}/*!sc*/
data-styled.g137[id="sc-cKZHtR"]{content:"lcoFQc,"}/*!sc*/
<script src="https://cdn.redoc.ly/redoc/v2.1.3/bundles/redoc.standalone.js"></script><style data-styled="true" data-styled-version="6.1.8">.gikxZY{width:calc(100% - 40%);padding:0 40px;}/*!sc*/
@media print,screen and (max-width: 75rem){.gikxZY{width:100%;padding:40px 40px;}}/*!sc*/
data-styled.g4[id="sc-hLQSwg"]{content:"gikxZY,"}/*!sc*/
.hNzKJC{padding:40px 0;}/*!sc*/
.hNzKJC:last-child{min-height:calc(100vh + 1px);}/*!sc*/
.hNzKJC>.hNzKJC:last-child{min-height:initial;}/*!sc*/
@media print,screen and (max-width: 75rem){.hNzKJC{padding:0;}}/*!sc*/
.cSNAXN{padding:40px 0;position:relative;}/*!sc*/
.cSNAXN:last-child{min-height:calc(100vh + 1px);}/*!sc*/
.cSNAXN>.cSNAXN:last-child{min-height:initial;}/*!sc*/
@media print,screen and (max-width: 75rem){.cSNAXN{padding:0;}}/*!sc*/
.cSNAXN:not(:last-of-type):after{position:absolute;bottom:0;width:100%;display:block;content:'';border-bottom:1px solid rgba(0, 0, 0, 0.2);}/*!sc*/
data-styled.g5[id="sc-eDLKkx"]{content:"hNzKJC,cSNAXN,"}/*!sc*/
.imiXRU{width:40%;color:#ffffff;background-color:#263238;padding:0 40px;}/*!sc*/
@media print,screen and (max-width: 75rem){.imiXRU{width:100%;padding:40px 40px;}}/*!sc*/
data-styled.g6[id="sc-jTQCzO"]{content:"imiXRU,"}/*!sc*/
.jGdkPR{background-color:#263238;}/*!sc*/
data-styled.g7[id="sc-gLLuof"]{content:"jGdkPR,"}/*!sc*/
.fsPUig{display:flex;width:100%;padding:0;}/*!sc*/
@media print,screen and (max-width: 75rem){.fsPUig{flex-direction:column;}}/*!sc*/
data-styled.g8[id="sc-iBdnpw"]{content:"fsPUig,"}/*!sc*/
.gqLiaw{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.85714em;line-height:1.6em;color:#333333;}/*!sc*/
data-styled.g9[id="sc-fsYfdN"]{content:"gqLiaw,"}/*!sc*/
.gwJLUj{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.57143em;line-height:1.6em;color:#333333;margin:0 0 20px;}/*!sc*/
data-styled.g10[id="sc-qZrbh"]{content:"gwJLUj,"}/*!sc*/
.klfnyk{color:#ffffff;}/*!sc*/
data-styled.g12[id="sc-kFCroH"]{content:"klfnyk,"}/*!sc*/
.fNhImz{cursor:pointer;margin-left:-20px;padding:0;line-height:1;width:20px;display:inline-block;outline:0;}/*!sc*/
.fNhImz:before{content:'';width:15px;height:15px;background-size:contain;background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjMDEwMTAxIiBkPSJNNDU5LjcgMjMzLjRsLTkwLjUgOTAuNWMtNTAgNTAtMTMxIDUwLTE4MSAwIC03LjktNy44LTE0LTE2LjctMTkuNC0yNS44bDQyLjEtNDIuMWMyLTIgNC41LTMuMiA2LjgtNC41IDIuOSA5LjkgOCAxOS4zIDE1LjggMjcuMiAyNSAyNSA2NS42IDI0LjkgOTAuNSAwbDkwLjUtOTAuNWMyNS0yNSAyNS02NS42IDAtOTAuNSAtMjQuOS0yNS02NS41LTI1LTkwLjUgMGwtMzIuMiAzMi4yYy0yNi4xLTEwLjItNTQuMi0xMi45LTgxLjYtOC45bDY4LjYtNjguNmM1MC01MCAxMzEtNTAgMTgxIDBDNTA5LjYgMTAyLjMgNTA5LjYgMTgzLjQgNDU5LjcgMjMzLjR6TTIyMC4zIDM4Mi4ybC0zMi4yIDMyLjJjLTI1IDI0LjktNjUuNiAyNC45LTkwLjUgMCAtMjUtMjUtMjUtNjUuNiAwLTkwLjVsOTAuNS05MC41YzI1LTI1IDY1LjUtMjUgOTAuNSAwIDcuOCA3LjggMTIuOSAxNy4yIDE1LjggMjcuMSAyLjQtMS40IDQuOC0yLjUgNi44LTQuNWw0Mi4xLTQyYy01LjQtOS4yLTExLjYtMTgtMTkuNC0yNS44IC01MC01MC0xMzEtNTAtMTgxIDBsLTkwLjUgOTAuNWMtNTAgNTAtNTAgMTMxIDAgMTgxIDUwIDUwIDEzMSA1MCAxODEgMGw2OC42LTY4LjZDMjc0LjYgMzk1LjEgMjQ2LjQgMzkyLjMgMjIwLjMgMzgyLjJ6Ii8+PC9zdmc+Cg==');opacity:0.5;visibility:hidden;display:inline-block;vertical-align:middle;}/*!sc*/
h1:hover>.fNhImz::before,h2:hover>.fNhImz::before,.fNhImz:hover::before{visibility:visible;}/*!sc*/
data-styled.g14[id="sc-csKJxZ"]{content:"fNhImz,"}/*!sc*/
.hUWsvg{height:1.5em;width:1.5em;min-width:1.5em;vertical-align:middle;float:left;transition:transform 0.2s ease-out;transform:rotateZ(-90deg);}/*!sc*/
.hUWsvg polygon{fill:#1d8127;}/*!sc*/
.exoGJA{height:20px;width:20px;min-width:20px;vertical-align:middle;float:right;transition:transform 0.2s ease-out;transform:rotateZ(0);}/*!sc*/
.exoGJA polygon{fill:white;}/*!sc*/
data-styled.g15[id="sc-eTNRI"]{content:"hUWsvg,exoGJA,"}/*!sc*/
.jSWvqu >ul{list-style:none;padding:0;margin:0;margin:0 -5px;}/*!sc*/
.jSWvqu >ul >li{padding:5px 10px;display:inline-block;background-color:#11171a;border-bottom:1px solid rgba(0, 0, 0, 0.5);cursor:pointer;text-align:center;outline:none;color:#ccc;margin:0 5px 5px 5px;border:1px solid #07090b;border-radius:5px;min-width:60px;font-size:0.9em;font-weight:bold;}/*!sc*/
.jSWvqu >ul >li.react-tabs__tab--selected{color:#333333;background:#ffffff;}/*!sc*/
.jSWvqu >ul >li.react-tabs__tab--selected:focus{outline:auto;}/*!sc*/
.jSWvqu >ul >li:only-child{flex:none;min-width:100px;}/*!sc*/
.jSWvqu >ul >li.tab-success{color:#1d8127;}/*!sc*/
.jSWvqu >ul >li.tab-redirect{color:#ffa500;}/*!sc*/
.jSWvqu >ul >li.tab-info{color:#87ceeb;}/*!sc*/
.jSWvqu >ul >li.tab-error{color:#d41f1c;}/*!sc*/
.jSWvqu >.react-tabs__tab-panel{background:#11171a;}/*!sc*/
.jSWvqu >.react-tabs__tab-panel>div,.jSWvqu >.react-tabs__tab-panel>pre{padding:20px;margin:0;}/*!sc*/
.jSWvqu >.react-tabs__tab-panel>div>pre{padding:0;}/*!sc*/
data-styled.g30[id="sc-cyZbeP"]{content:"jSWvqu,"}/*!sc*/
.WVNwY code[class*='language-'],.WVNwY pre[class*='language-']{text-shadow:0 -0.1em 0.2em black;text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;line-height:1.5;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none;}/*!sc*/
@media print{.WVNwY code[class*='language-'],.WVNwY pre[class*='language-']{text-shadow:none;}}/*!sc*/
.WVNwY pre[class*='language-']{padding:1em;margin:0.5em 0;overflow:auto;}/*!sc*/
.WVNwY .token.comment,.WVNwY .token.prolog,.WVNwY .token.doctype,.WVNwY .token.cdata{color:hsl(30, 20%, 50%);}/*!sc*/
.WVNwY .token.punctuation{opacity:0.7;}/*!sc*/
.WVNwY .namespace{opacity:0.7;}/*!sc*/
.WVNwY .token.property,.WVNwY .token.tag,.WVNwY .token.number,.WVNwY .token.constant,.WVNwY .token.symbol{color:#4a8bb3;}/*!sc*/
.WVNwY .token.boolean{color:#e64441;}/*!sc*/
.WVNwY .token.selector,.WVNwY .token.attr-name,.WVNwY .token.string,.WVNwY .token.char,.WVNwY .token.builtin,.WVNwY .token.inserted{color:#a0fbaa;}/*!sc*/
.WVNwY .token.selector+a,.WVNwY .token.attr-name+a,.WVNwY .token.string+a,.WVNwY .token.char+a,.WVNwY .token.builtin+a,.WVNwY .token.inserted+a,.WVNwY .token.selector+a:visited,.WVNwY .token.attr-name+a:visited,.WVNwY .token.string+a:visited,.WVNwY .token.char+a:visited,.WVNwY .token.builtin+a:visited,.WVNwY .token.inserted+a:visited{color:#4ed2ba;text-decoration:underline;}/*!sc*/
.WVNwY .token.property.string{color:white;}/*!sc*/
.WVNwY .token.operator,.WVNwY .token.entity,.WVNwY .token.url,.WVNwY .token.variable{color:hsl(40, 90%, 60%);}/*!sc*/
.WVNwY .token.atrule,.WVNwY .token.attr-value,.WVNwY .token.keyword{color:hsl(350, 40%, 70%);}/*!sc*/
.WVNwY .token.regex,.WVNwY .token.important{color:#e90;}/*!sc*/
.WVNwY .token.important,.WVNwY .token.bold{font-weight:bold;}/*!sc*/
.WVNwY .token.italic{font-style:italic;}/*!sc*/
.WVNwY .token.entity{cursor:help;}/*!sc*/
.WVNwY .token.deleted{color:red;}/*!sc*/
data-styled.g32[id="sc-iKOmoZ"]{content:"WVNwY,"}/*!sc*/
.iwAAMv{opacity:0.7;transition:opacity 0.3s ease;text-align:right;}/*!sc*/
.iwAAMv:focus-within{opacity:1;}/*!sc*/
.iwAAMv >button{background-color:transparent;border:0;color:inherit;padding:2px 10px;font-family:Roboto,sans-serif;font-size:14px;line-height:1.5em;cursor:pointer;outline:0;}/*!sc*/
.iwAAMv >button :hover,.iwAAMv >button :focus{background:rgba(255, 255, 255, 0.1);}/*!sc*/
data-styled.g33[id="sc-gjLLEI"]{content:"iwAAMv,"}/*!sc*/
.kIqtpW{position:relative;}/*!sc*/
data-styled.g37[id="sc-kMzELR"]{content:"kIqtpW,"}/*!sc*/
.VEBGS{font-family:Roboto,sans-serif;font-weight:400;line-height:1.5em;}/*!sc*/
.VEBGS p:last-child{margin-bottom:0;}/*!sc*/
.VEBGS h1{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.85714em;line-height:1.6em;color:#32329f;margin-top:0;}/*!sc*/
.VEBGS h2{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.57143em;line-height:1.6em;color:#333333;}/*!sc*/
.VEBGS code{color:#e53935;background-color:rgba(38, 50, 56, 0.05);font-family:Courier,monospace;border-radius:2px;border:1px solid rgba(38, 50, 56, 0.1);padding:0 5px;font-size:13px;font-weight:400;word-break:break-word;}/*!sc*/
.VEBGS pre{font-family:Courier,monospace;white-space:pre;background-color:#11171a;color:white;padding:20px;overflow-x:auto;line-height:normal;border-radius:0;border:1px solid rgba(38, 50, 56, 0.1);}/*!sc*/
.VEBGS pre code{background-color:transparent;color:white;padding:0;}/*!sc*/
.VEBGS pre code:before,.VEBGS pre code:after{content:none;}/*!sc*/
.VEBGS blockquote{margin:0;margin-bottom:1em;padding:0 15px;color:#777;border-left:4px solid #ddd;}/*!sc*/
.VEBGS img{max-width:100%;box-sizing:content-box;}/*!sc*/
.VEBGS ul,.VEBGS ol{padding-left:2em;margin:0;margin-bottom:1em;}/*!sc*/
.VEBGS ul ul,.VEBGS ol ul,.VEBGS ul ol,.VEBGS ol ol{margin-bottom:0;margin-top:0;}/*!sc*/
.VEBGS table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all;border-collapse:collapse;border-spacing:0;margin-top:1.5em;margin-bottom:1.5em;}/*!sc*/
.VEBGS table tr{background-color:#fff;border-top:1px solid #ccc;}/*!sc*/
.VEBGS table tr:nth-child(2n){background-color:#fafafa;}/*!sc*/
.VEBGS table th,.VEBGS table td{padding:6px 13px;border:1px solid #ddd;}/*!sc*/
.VEBGS table th{text-align:left;font-weight:bold;}/*!sc*/
.VEBGS .share-link{cursor:pointer;margin-left:-20px;padding:0;line-height:1;width:20px;display:inline-block;outline:0;}/*!sc*/
.VEBGS .share-link:before{content:'';width:15px;height:15px;background-size:contain;background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjMDEwMTAxIiBkPSJNNDU5LjcgMjMzLjRsLTkwLjUgOTAuNWMtNTAgNTAtMTMxIDUwLTE4MSAwIC03LjktNy44LTE0LTE2LjctMTkuNC0yNS44bDQyLjEtNDIuMWMyLTIgNC41LTMuMiA2LjgtNC41IDIuOSA5LjkgOCAxOS4zIDE1LjggMjcuMiAyNSAyNSA2NS42IDI0LjkgOTAuNSAwbDkwLjUtOTAuNWMyNS0yNSAyNS02NS42IDAtOTAuNSAtMjQuOS0yNS02NS41LTI1LTkwLjUgMGwtMzIuMiAzMi4yYy0yNi4xLTEwLjItNTQuMi0xMi45LTgxLjYtOC45bDY4LjYtNjguNmM1MC01MCAxMzEtNTAgMTgxIDBDNTA5LjYgMTAyLjMgNTA5LjYgMTgzLjQgNDU5LjcgMjMzLjR6TTIyMC4zIDM4Mi4ybC0zMi4yIDMyLjJjLTI1IDI0LjktNjUuNiAyNC45LTkwLjUgMCAtMjUtMjUtMjUtNjUuNiAwLTkwLjVsOTAuNS05MC41YzI1LTI1IDY1LjUtMjUgOTAuNSAwIDcuOCA3LjggMTIuOSAxNy4yIDE1LjggMjcuMSAyLjQtMS40IDQuOC0yLjUgNi44LTQuNWw0Mi4xLTQyYy01LjQtOS4yLTExLjYtMTgtMTkuNC0yNS44IC01MC01MC0xMzEtNTAtMTgxIDBsLTkwLjUgOTAuNWMtNTAgNTAtNTAgMTMxIDAgMTgxIDUwIDUwIDEzMSA1MCAxODEgMGw2OC42LTY4LjZDMjc0LjYgMzk1LjEgMjQ2LjQgMzkyLjMgMjIwLjMgMzgyLjJ6Ii8+PC9zdmc+Cg==');opacity:0.5;visibility:hidden;display:inline-block;vertical-align:middle;}/*!sc*/
.VEBGS h1:hover>.share-link::before,.VEBGS h2:hover>.share-link::before,.VEBGS .share-link:hover::before{visibility:visible;}/*!sc*/
.VEBGS a{text-decoration:auto;color:#32329f;}/*!sc*/
.VEBGS a:visited{color:#32329f;}/*!sc*/
.VEBGS a:hover{color:#6868cf;text-decoration:auto;}/*!sc*/
.jaVotg{font-family:Roboto,sans-serif;font-weight:400;line-height:1.5em;}/*!sc*/
.jaVotg p:last-child{margin-bottom:0;}/*!sc*/
.jaVotg p:first-child{margin-top:0;}/*!sc*/
.jaVotg p:last-child{margin-bottom:0;}/*!sc*/
.jaVotg h1{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.85714em;line-height:1.6em;color:#32329f;margin-top:0;}/*!sc*/
.jaVotg h2{font-family:Montserrat,sans-serif;font-weight:400;font-size:1.57143em;line-height:1.6em;color:#333333;}/*!sc*/
.jaVotg code{color:#e53935;background-color:rgba(38, 50, 56, 0.05);font-family:Courier,monospace;border-radius:2px;border:1px solid rgba(38, 50, 56, 0.1);padding:0 5px;font-size:13px;font-weight:400;word-break:break-word;}/*!sc*/
.jaVotg pre{font-family:Courier,monospace;white-space:pre;background-color:#11171a;color:white;padding:20px;overflow-x:auto;line-height:normal;border-radius:0;border:1px solid rgba(38, 50, 56, 0.1);}/*!sc*/
.jaVotg pre code{background-color:transparent;color:white;padding:0;}/*!sc*/
.jaVotg pre code:before,.jaVotg pre code:after{content:none;}/*!sc*/
.jaVotg blockquote{margin:0;margin-bottom:1em;padding:0 15px;color:#777;border-left:4px solid #ddd;}/*!sc*/
.jaVotg img{max-width:100%;box-sizing:content-box;}/*!sc*/
.jaVotg ul,.jaVotg ol{padding-left:2em;margin:0;margin-bottom:1em;}/*!sc*/
.jaVotg ul ul,.jaVotg ol ul,.jaVotg ul ol,.jaVotg ol ol{margin-bottom:0;margin-top:0;}/*!sc*/
.jaVotg table{display:block;width:100%;overflow:auto;word-break:normal;word-break:keep-all;border-collapse:collapse;border-spacing:0;margin-top:1.5em;margin-bottom:1.5em;}/*!sc*/
.jaVotg table tr{background-color:#fff;border-top:1px solid #ccc;}/*!sc*/
.jaVotg table tr:nth-child(2n){background-color:#fafafa;}/*!sc*/
.jaVotg table th,.jaVotg table td{padding:6px 13px;border:1px solid #ddd;}/*!sc*/
.jaVotg table th{text-align:left;font-weight:bold;}/*!sc*/
.jaVotg .share-link{cursor:pointer;margin-left:-20px;padding:0;line-height:1;width:20px;display:inline-block;outline:0;}/*!sc*/
.jaVotg .share-link:before{content:'';width:15px;height:15px;background-size:contain;background-image:url('data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHZlcnNpb249IjEuMSIgeD0iMCIgeT0iMCIgd2lkdGg9IjUxMiIgaGVpZ2h0PSI1MTIiIHZpZXdCb3g9IjAgMCA1MTIgNTEyIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIiB4bWw6c3BhY2U9InByZXNlcnZlIj48cGF0aCBmaWxsPSIjMDEwMTAxIiBkPSJNNDU5LjcgMjMzLjRsLTkwLjUgOTAuNWMtNTAgNTAtMTMxIDUwLTE4MSAwIC03LjktNy44LTE0LTE2LjctMTkuNC0yNS44bDQyLjEtNDIuMWMyLTIgNC41LTMuMiA2LjgtNC41IDIuOSA5LjkgOCAxOS4zIDE1LjggMjcuMiAyNSAyNSA2NS42IDI0LjkgOTAuNSAwbDkwLjUtOTAuNWMyNS0yNSAyNS02NS42IDAtOTAuNSAtMjQuOS0yNS02NS41LTI1LTkwLjUgMGwtMzIuMiAzMi4yYy0yNi4xLTEwLjItNTQuMi0xMi45LTgxLjYtOC45bDY4LjYtNjguNmM1MC01MCAxMzEtNTAgMTgxIDBDNTA5LjYgMTAyLjMgNTA5LjYgMTgzLjQgNDU5LjcgMjMzLjR6TTIyMC4zIDM4Mi4ybC0zMi4yIDMyLjJjLTI1IDI0LjktNjUuNiAyNC45LTkwLjUgMCAtMjUtMjUtMjUtNjUuNiAwLTkwLjVsOTAuNS05MC41YzI1LTI1IDY1LjUtMjUgOTAuNSAwIDcuOCA3LjggMTIuOSAxNy4yIDE1LjggMjcuMSAyLjQtMS40IDQuOC0yLjUgNi44LTQuNWw0Mi4xLTQyYy01LjQtOS4yLTExLjYtMTgtMTkuNC0yNS44IC01MC01MC0xMzEtNTAtMTgxIDBsLTkwLjUgOTAuNWMtNTAgNTAtNTAgMTMxIDAgMTgxIDUwIDUwIDEzMSA1MCAxODEgMGw2OC42LTY4LjZDMjc0LjYgMzk1LjEgMjQ2LjQgMzkyLjMgMjIwLjMgMzgyLjJ6Ii8+PC9zdmc+Cg==');opacity:0.5;visibility:hidden;display:inline-block;vertical-align:middle;}/*!sc*/
.jaVotg h1:hover>.share-link::before,.jaVotg h2:hover>.share-link::before,.jaVotg .share-link:hover::before{visibility:visible;}/*!sc*/
.jaVotg a{text-decoration:auto;color:#32329f;}/*!sc*/
.jaVotg a:visited{color:#32329f;}/*!sc*/
.jaVotg a:hover{color:#6868cf;text-decoration:auto;}/*!sc*/
data-styled.g42[id="sc-cCzLxZ"]{content:"VEBGS,jaVotg,"}/*!sc*/
.LxEPk{display:inline;}/*!sc*/
data-styled.g43[id="sc-ckdEwu"]{content:"LxEPk,"}/*!sc*/
.krcPXE{position:relative;}/*!sc*/
data-styled.g44[id="sc-jdHILj"]{content:"krcPXE,"}/*!sc*/
.fOJBdW:hover>.sc-gjLLEI{opacity:1;}/*!sc*/
data-styled.g49[id="sc-cSxRuM"]{content:"fOJBdW,"}/*!sc*/
.DqFKH{font-family:Courier,monospace;font-size:13px;white-space:pre;contain:content;overflow-x:auto;}/*!sc*/
.DqFKH .redoc-json code>.collapser{display:none;pointer-events:none;}/*!sc*/
.DqFKH .callback-function{color:gray;}/*!sc*/
.DqFKH .collapser:after{content:'-';cursor:pointer;}/*!sc*/
.DqFKH .collapsed>.collapser:after{content:'+';cursor:pointer;}/*!sc*/
.DqFKH .ellipsis:after{content:' … ';}/*!sc*/
.DqFKH .collapsible{margin-left:2em;}/*!sc*/
.DqFKH .hoverable{padding-top:1px;padding-bottom:1px;padding-left:2px;padding-right:2px;border-radius:2px;}/*!sc*/
.DqFKH .hovered{background-color:rgba(235, 238, 249, 1);}/*!sc*/
.DqFKH .collapser{background-color:transparent;border:0;color:#fff;font-family:Courier,monospace;font-size:13px;padding-right:6px;padding-left:6px;padding-top:0;padding-bottom:0;display:flex;align-items:center;justify-content:center;width:15px;height:15px;position:absolute;top:4px;left:-1.5em;cursor:default;user-select:none;-webkit-user-select:none;padding:2px;}/*!sc*/
.DqFKH .collapser:focus{outline-color:#fff;outline-style:dotted;outline-width:1px;}/*!sc*/
.DqFKH ul{list-style-type:none;padding:0px;margin:0px 0px 0px 26px;}/*!sc*/
.DqFKH li{position:relative;display:block;}/*!sc*/
.DqFKH .hoverable{display:inline-block;}/*!sc*/
.DqFKH .selected{outline-style:solid;outline-width:1px;outline-style:dotted;}/*!sc*/
.DqFKH .collapsed>.collapsible{display:none;}/*!sc*/
.DqFKH .ellipsis{display:none;}/*!sc*/
.DqFKH .collapsed>.ellipsis{display:inherit;}/*!sc*/
data-styled.g50[id="sc-jMbVJB"]{content:"DqFKH,"}/*!sc*/
.jCmKdj{padding:0.9em;background-color:rgba(38,50,56,0.4);margin:0 0 10px 0;display:block;font-family:Montserrat,sans-serif;font-size:0.929em;line-height:1.5em;}/*!sc*/
data-styled.g51[id="sc-dQmiwx"]{content:"jCmKdj,"}/*!sc*/
.eTZsJr{font-family:Montserrat,sans-serif;font-size:12px;position:absolute;z-index:1;top:-11px;left:12px;font-weight:600;color:rgba(255,255,255,0.7);}/*!sc*/
data-styled.g52[id="sc-bCvmQg"]{content:"eTZsJr,"}/*!sc*/
.jBjImi{position:relative;}/*!sc*/
data-styled.g53[id="sc-cPtzlb"]{content:"jBjImi,"}/*!sc*/
.jeLSWq{margin-top:15px;}/*!sc*/
data-styled.g56[id="sc-hVcFVo"]{content:"jeLSWq,"}/*!sc*/
.ObWVe{margin-top:0;margin-bottom:0.5em;}/*!sc*/
data-styled.g91[id="sc-eFyDpN"]{content:"ObWVe,"}/*!sc*/
.iGcmRf{border:1px solid #32329f;color:#32329f;font-weight:normal;margin-left:0.5em;padding:4px 8px 4px;display:inline-block;text-decoration:none;cursor:pointer;}/*!sc*/
data-styled.g92[id="sc-crHHJw"]{content:"iGcmRf,"}/*!sc*/
.gxSVta{width:9ex;display:inline-block;height:13px;line-height:13px;background-color:#333;border-radius:3px;background-repeat:no-repeat;background-position:6px 4px;font-size:7px;font-family:Verdana,sans-serif;color:white;text-transform:uppercase;text-align:center;font-weight:bold;vertical-align:middle;margin-right:6px;margin-top:2px;}/*!sc*/
.gxSVta.get{background-color:#2F8132;}/*!sc*/
.gxSVta.post{background-color:#186FAF;}/*!sc*/
.gxSVta.put{background-color:#95507c;}/*!sc*/
.gxSVta.options{background-color:#947014;}/*!sc*/
.gxSVta.patch{background-color:#bf581d;}/*!sc*/
.gxSVta.delete{background-color:#cc3333;}/*!sc*/
.gxSVta.basic{background-color:#707070;}/*!sc*/
.gxSVta.link{background-color:#07818F;}/*!sc*/
.gxSVta.head{background-color:#A23DAD;}/*!sc*/
.gxSVta.hook{background-color:#32329f;}/*!sc*/
.gxSVta.schema{background-color:#707070;}/*!sc*/
data-styled.g99[id="sc-dmcoYd"]{content:"gxSVta,"}/*!sc*/
.fTlmpg{margin:0;padding:0;}/*!sc*/
.fTlmpg:first-child{padding-bottom:32px;}/*!sc*/
.sc-YltrM .sc-YltrM{font-size:0.929em;}/*!sc*/
data-styled.g100[id="sc-YltrM"]{content:"fTlmpg,"}/*!sc*/
.kIUuLW{list-style:none inside none;overflow:hidden;text-overflow:ellipsis;padding:0;}/*!sc*/
data-styled.g101[id="sc-imiRDh"]{content:"kIUuLW,"}/*!sc*/
.gvinAL{cursor:pointer;color:#333333;margin:0;padding:12.5px 20px;display:flex;justify-content:space-between;font-family:Montserrat,sans-serif;background-color:#fafafa;}/*!sc*/
.gvinAL:hover{color:#32329f;background-color:#ededed;}/*!sc*/
.gvinAL .sc-eTNRI{height:1.5em;width:1.5em;}/*!sc*/
.gvinAL .sc-eTNRI polygon{fill:#333333;}/*!sc*/
data-styled.g102[id="sc-vIyEI"]{content:"gvinAL,"}/*!sc*/
.fXgHFV{display:inline-block;vertical-align:middle;width:calc(100% - 38px);overflow:hidden;text-overflow:ellipsis;}/*!sc*/
data-styled.g103[id="sc-bjUHJT"]{content:"fXgHFV,"}/*!sc*/
.dWVQcL{font-size:0.8em;margin-top:10px;text-align:center;position:fixed;width:260px;bottom:0;background:#fafafa;}/*!sc*/
.dWVQcL a,.dWVQcL a:visited,.dWVQcL a:hover{color:#333333!important;padding:5px 0;border-top:1px solid #e1e1e1;text-decoration:none;display:flex;align-items:center;justify-content:center;}/*!sc*/
.dWVQcL img{width:15px;margin-right:5px;}/*!sc*/
@media screen and (max-width: 50rem){.dWVQcL{width:100%;}}/*!sc*/
data-styled.g104[id="sc-eIPYkq"]{content:"dWVQcL,"}/*!sc*/
.cIsduN{cursor:pointer;position:relative;margin-bottom:5px;}/*!sc*/
data-styled.g110[id="sc-bPrlCs"]{content:"cIsduN,"}/*!sc*/
.gllLir{font-family:Courier,monospace;margin-left:10px;flex:1;overflow-x:hidden;text-overflow:ellipsis;}/*!sc*/
data-styled.g111[id="sc-fYrVWQ"]{content:"gllLir,"}/*!sc*/
.bclCVA{outline:0;color:inherit;width:100%;text-align:left;cursor:pointer;padding:10px 30px 10px 20px;border-radius:4px 4px 0 0;background-color:#11171a;display:flex;white-space:nowrap;align-items:center;border:1px solid transparent;border-bottom:0;transition:border-color 0.25s ease;}/*!sc*/
.bclCVA ..sc-fYrVWQ{color:#ffffff;}/*!sc*/
.bclCVA:focus{box-shadow:inset 0 2px 2px rgba(0, 0, 0, 0.45),0 2px 0 rgba(128, 128, 128, 0.25);}/*!sc*/
data-styled.g112[id="sc-GkLId"]{content:"bclCVA,"}/*!sc*/
.eIFDdZ{font-size:0.929em;line-height:20px;background-color:#2F8132;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/
.jBKVIL{font-size:0.929em;line-height:20px;background-color:#186FAF;color:#ffffff;padding:3px 10px;text-transform:uppercase;font-family:Montserrat,sans-serif;margin:0;}/*!sc*/
data-styled.g113[id="sc-jYnQyy"]{content:"eIFDdZ,jBKVIL,"}/*!sc*/
.hsEiws{position:absolute;width:100%;z-index:100;background:#fafafa;color:#263238;box-sizing:border-box;box-shadow:0 0 6px rgba(0, 0, 0, 0.33);overflow:hidden;border-bottom-left-radius:4px;border-bottom-right-radius:4px;transition:all 0.25s ease;visibility:hidden;transform:translateY(-50%) scaleY(0);}/*!sc*/
data-styled.g114[id="sc-eGgGjL"]{content:"hsEiws,"}/*!sc*/
.jerStl{padding:10px;}/*!sc*/
data-styled.g115[id="sc-fnpiog"]{content:"jerStl,"}/*!sc*/
.etvaCd{padding:5px;border:1px solid #ccc;background:#fff;word-break:break-all;color:#32329f;}/*!sc*/
.etvaCd >span{color:#333333;}/*!sc*/
data-styled.g116[id="sc-lkDHyp"]{content:"etvaCd,"}/*!sc*/
.fIqGlH{display:block;border:0;width:100%;text-align:left;padding:10px;border-radius:2px;margin-bottom:4px;line-height:1.5em;cursor:pointer;color:#1d8127;background-color:rgba(29,129,39,0.07);}/*!sc*/
.fIqGlH:focus{outline:auto #1d8127;}/*!sc*/
.iSOCsR{display:block;border:0;width:100%;text-align:left;padding:10px;border-radius:2px;margin-bottom:4px;line-height:1.5em;cursor:pointer;color:#1d8127;background-color:rgba(29,129,39,0.07);cursor:default;}/*!sc*/
.iSOCsR:focus{outline:auto #1d8127;}/*!sc*/
.iSOCsR::before{content:"—";font-weight:bold;width:1.5em;text-align:center;display:inline-block;vertical-align:top;}/*!sc*/
.iSOCsR:focus{outline:0;}/*!sc*/
data-styled.g119[id="sc-hsaIUA"]{content:"fIqGlH,iSOCsR,"}/*!sc*/
.ePkkgX{vertical-align:top;}/*!sc*/
data-styled.g122[id="sc-gWQvRS"]{content:"ePkkgX,"}/*!sc*/
.duKVDl{font-size:1.3em;padding:0.2em 0;margin:3em 0 1.1em;color:#333333;font-weight:normal;}/*!sc*/
data-styled.g123[id="sc-fYitVF"]{content:"duKVDl,"}/*!sc*/
.dZbpPF{margin-bottom:30px;}/*!sc*/
data-styled.g128[id="sc-eYFTNc"]{content:"dZbpPF,"}/*!sc*/
.bUvUmx{user-select:none;width:20px;height:20px;align-self:center;display:flex;flex-direction:column;color:#32329f;}/*!sc*/
data-styled.g129[id="sc-iEYVpv"]{content:"bUvUmx,"}/*!sc*/
.hHYXMN{width:260px;background-color:#fafafa;overflow:hidden;display:flex;flex-direction:column;backface-visibility:hidden;height:100vh;position:sticky;position:-webkit-sticky;top:0;}/*!sc*/
@media screen and (max-width: 50rem){.hHYXMN{position:fixed;z-index:20;width:100%;background:#fafafa;display:none;}}/*!sc*/
@media print{.hHYXMN{display:none;}}/*!sc*/
data-styled.g130[id="sc-iqziPC"]{content:"hHYXMN,"}/*!sc*/
.kHszPm{outline:none;user-select:none;background-color:#f2f2f2;color:#32329f;display:none;cursor:pointer;position:fixed;right:20px;z-index:100;border-radius:50%;box-shadow:0 0 20px rgba(0, 0, 0, 0.3);bottom:44px;width:60px;height:60px;padding:0 20px;}/*!sc*/
@media screen and (max-width: 50rem){.kHszPm{display:flex;}}/*!sc*/
.kHszPm svg{color:#0065FB;}/*!sc*/
@media print{.kHszPm{display:none;}}/*!sc*/
data-styled.g131[id="sc-eXzmLu"]{content:"kHszPm,"}/*!sc*/
.cSYMrW{font-family:Roboto,sans-serif;font-size:14px;font-weight:400;line-height:1.5em;color:#333333;display:flex;position:relative;text-align:left;-webkit-font-smoothing:antialiased;font-smoothing:antialiased;text-rendering:optimizeSpeed!important;tap-highlight-color:rgba(0, 0, 0, 0);text-size-adjust:100%;}/*!sc*/
.cSYMrW *{box-sizing:border-box;-webkit-tap-highlight-color:rgba(255, 255, 255, 0);}/*!sc*/
data-styled.g132[id="sc-kUNLVD"]{content:"cSYMrW,"}/*!sc*/
.cOuMek{z-index:1;position:relative;overflow:hidden;width:calc(100% - 260px);contain:layout;}/*!sc*/
@media print,screen and (max-width: 50rem){.cOuMek{width:100%;}}/*!sc*/
data-styled.g133[id="sc-dxfTlo"]{content:"cOuMek,"}/*!sc*/
.bsunyy{background:#263238;position:absolute;top:0;bottom:0;right:0;width:calc((100% - 260px) * 0.4);}/*!sc*/
@media print,screen and (max-width: 75rem){.bsunyy{display:none;}}/*!sc*/
data-styled.g134[id="sc-juusvx"]{content:"bsunyy,"}/*!sc*/
.cUtpgV{padding:5px 0;}/*!sc*/
data-styled.g135[id="sc-emwzcK"]{content:"cUtpgV,"}/*!sc*/
.iiRHzu{width:calc(100% - 40px);box-sizing:border-box;margin:0 20px;padding:5px 10px 5px 20px;border:0;border-bottom:1px solid #e1e1e1;font-family:Roboto,sans-serif;font-weight:bold;font-size:13px;color:#333333;background-color:transparent;outline:none;}/*!sc*/
data-styled.g136[id="sc-kjKYmT"]{content:"iiRHzu,"}/*!sc*/
.dvQijr{position:absolute;left:20px;height:1.8em;width:0.9em;}/*!sc*/
.dvQijr path{fill:#333333;}/*!sc*/
data-styled.g137[id="sc-cMdfCE"]{content:"dvQijr,"}/*!sc*/
</style>
<link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
</head>
<body>
<div id="redoc"><div class="sc-kUbfpu bwTiCm redoc-wrap"><div class="sc-irlPvL gXSQkB menu-content" style="top:0px;height:calc(100vh - 0px)"><div role="search" class="sc-eltaTX hwhlAl"><svg class="sc-cKZHtR lcoFQc search-icon" version="1.1" viewBox="0 0 1000 1000" x="0px" xmlns="http://www.w3.org/2000/svg" y="0px"><path d="M968.2,849.4L667.3,549c83.9-136.5,66.7-317.4-51.7-435.6C477.1-25,252.5-25,113.9,113.4c-138.5,138.3-138.5,362.6,0,501C219.2,730.1,413.2,743,547.6,666.5l301.9,301.4c43.6,43.6,76.9,14.9,104.2-12.4C981,928.3,1011.8,893,968.2,849.4z M524.5,522c-88.9,88.7-233,88.7-321.8,0c-88.9-88.7-88.9-232.6,0-321.3c88.9-88.7,233-88.7,321.8,0C613.4,289.4,613.4,433.3,524.5,522z"></path></svg><input placeholder="Search..." aria-label="Search" type="text" class="sc-kiYrGK eWIXbA search-input" value=""/></div><div class="sc-kLgoAE eJckYb scrollbar-container undefined"><ul role="menu" class="sc-XhViZ YKcaq"><li tabindex="0" depth="2" data-item-id="/paths/~1status/get" role="menuitem" class="sc-ikPBrU fhNqYr"><label class="sc-tYqQR CYQVt -depth2"><span type="get" class="sc-dkIYMQ bwwtyo operation-type get">get</span><span tabindex="0" width="calc(100% - 38px)" class="sc-biBryG bkVowu">Get writer status</span></label></li><li tabindex="0" depth="2" data-item-id="/paths/~1cancel/post" role="menuitem" class="sc-ikPBrU fhNqYr"><label class="sc-tYqQR CYQVt -depth2"><span type="post" class="sc-dkIYMQ bwwtyo operation-type post">post</span><span tabindex="0" width="calc(100% - 38px)" class="sc-biBryG bkVowu">Cancel running data collection</span></label></li></ul><div class="sc-eHfQwz jrtoRW"><a target="_blank" rel="noopener noreferrer" href="https://redocly.com/redoc/">API docs by Redocly</a></div></div></div><div class="sc-eWvOCH bEOmaQ"><div class="sc-iGctyi iEVneI"><svg class="" style="transform:translate(2px, -4px) rotate(180deg);transition:transform 0.2s ease" viewBox="0 0 926.23699 573.74994" version="1.1" x="0px" y="0px" width="15" height="15"><g transform="translate(904.92214,-879.1482)"><path d="
<div id="redoc"><div class="sc-kUNLVD cSYMrW redoc-wrap"><div class="sc-iqziPC hHYXMN menu-content" style="top:0px;height:calc(100vh - 0px)"><div role="search" class="sc-emwzcK cUtpgV"><svg class="sc-cMdfCE dvQijr search-icon" version="1.1" viewBox="0 0 1000 1000" x="0px" xmlns="http://www.w3.org/2000/svg" y="0px"><path d="M968.2,849.4L667.3,549c83.9-136.5,66.7-317.4-51.7-435.6C477.1-25,252.5-25,113.9,113.4c-138.5,138.3-138.5,362.6,0,501C219.2,730.1,413.2,743,547.6,666.5l301.9,301.4c43.6,43.6,76.9,14.9,104.2-12.4C981,928.3,1011.8,893,968.2,849.4z M524.5,522c-88.9,88.7-233,88.7-321.8,0c-88.9-88.7-88.9-232.6,0-321.3c88.9-88.7,233-88.7,321.8,0C613.4,289.4,613.4,433.3,524.5,522z"></path></svg><input placeholder="Search..." aria-label="Search" type="text" class="sc-kjKYmT iiRHzu search-input" value=""/></div><div class="sc-kMzELR kIqtpW scrollbar-container undefined"><ul role="menu" class="sc-YltrM fTlmpg"><li tabindex="0" depth="2" data-item-id="/paths/~1status/get" role="menuitem" class="sc-imiRDh kIUuLW"><label class="sc-vIyEI gvinAL -depth2"><span type="get" class="sc-dmcoYd gxSVta operation-type get">get</span><span tabindex="0" width="calc(100% - 38px)" class="sc-bjUHJT fXgHFV">Get writer status</span></label></li><li tabindex="0" depth="2" data-item-id="/paths/~1cancel/post" role="menuitem" class="sc-imiRDh kIUuLW"><label class="sc-vIyEI gvinAL -depth2"><span type="post" class="sc-dmcoYd gxSVta operation-type post">post</span><span tabindex="0" width="calc(100% - 38px)" class="sc-bjUHJT fXgHFV">Cancel running data collection</span></label></li><li tabindex="0" depth="2" data-item-id="/paths/~1version/get" role="menuitem" class="sc-imiRDh kIUuLW"><label class="sc-vIyEI gvinAL -depth2"><span type="get" class="sc-dmcoYd gxSVta operation-type get">get</span><span tabindex="0" width="calc(100% - 38px)" class="sc-bjUHJT fXgHFV">/version</span></label></li></ul><div class="sc-eIPYkq dWVQcL"><a target="_blank" rel="noopener noreferrer" href="https://redocly.com/redoc/">API docs by Redocly</a></div></div></div><div class="sc-eXzmLu kHszPm"><div class="sc-iEYVpv bUvUmx"><svg class="" style="transform:translate(2px, -4px) rotate(180deg);transition:transform 0.2s ease" viewBox="0 0 926.23699 573.74994" version="1.1" x="0px" y="0px" width="15" height="15"><g transform="translate(904.92214,-879.1482)"><path d="
m -673.67664,1221.6502 -231.2455,-231.24803 55.6165,
-55.627 c 30.5891,-30.59485 56.1806,-55.627 56.8701,-55.627 0.6894,
0 79.8637,78.60862 175.9427,174.68583 l 174.6892,174.6858 174.6892,
@@ -286,19 +286,21 @@ data-styled.g137[id="sc-cKZHtR"]{content:"lcoFQc,"}/*!sc*/
55.627 l 55.6165,55.627 -231.245496,231.24803 c -127.185,127.1864
-231.5279,231.248 -231.873,231.248 -0.3451,0 -104.688,
-104.0616 -231.873,-231.248 z
" fill="currentColor"></path></g></svg></div></div><div class="sc-dwcvcB dPIjnf api-content"><div class="sc-eCstZk kxmVZO"><div class="sc-iBPTVF keMybc"><div class="sc-hKgKIp gvoNGN api-info"><h1 class="sc-fubDmA sc-eGCbyA djltfY hWeMwQ">Jungfraujoch writer<!-- --> <span>(<!-- -->1.0.0<!-- -->)</span></h1><p>Download OpenAPI specification<!-- -->:<a download="openapi.json" target="_blank" class="sc-ctaXUJ gUXnfH">Download</a></p><div class="sc-iJuWdM sc-cBNeRQ gpkGbA casAkG"></div><div data-role="redoc-summary" html="" class="sc-iJuWdM sc-cBNeRQ gpkGbA casAkG"></div><div data-role="redoc-description" html="&lt;p&gt;Jungfraujoch Writer Web API&lt;/p&gt;
" class="sc-iJuWdM sc-cBNeRQ gpkGbA casAkG"><p>Jungfraujoch Writer Web API</p>
</div></div></div></div><div id="/paths/~1status/get" data-section-id="/paths/~1status/get" class="sc-eCstZk bCpIRB"><div class="sc-iBPTVF keMybc"><div class="sc-hKgKIp gvoNGN"><h2 class="sc-pGaPU biKwui"><a class="sc-crrtmM jGBpue" href="#/paths/~1status/get" aria-label="/paths/~1status/get"></a>Get writer status<!-- --> </h2><div><h3 class="sc-fWPdKs fCsSHf">Responses</h3><div><button class="sc-httZfN iePdRD"><svg class="sc-dQpIV iHKCKT" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-gVgoeb goojcW">200<!-- --> </strong><div html="&lt;p&gt;Statistics of the last measurement&lt;/p&gt;
" class="sc-iJuWdM sc-cBNeRQ gpkGbA casAkG sc-citwID bzkUsW"><p>Statistics of the last measurement</p>
</div></button></div></div></div><div class="sc-jSguLX sc-gKsecS QymcT bZqtR"><div class="sc-bQdSiB bhuodb"><button class="sc-FyfbU jlriCd"><span type="get" class="sc-jXkspL gDPfwK http-verb get">get</span><span class="sc-fXoxOd jzevEV">/status</span><svg class="sc-dQpIV hHbBnT" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-eFtZDC ciRGmD"><div class="sc-fmlKft buTZbL"><div html="" class="sc-iJuWdM sc-cBNeRQ gpkGbA dujygE"></div><div tabindex="0" role="button"><div class="sc-ljRaSg uePtT"><span></span>/status</div></div></div></div></div><div><h3 class="sc-kEjbdu jmifsN"> <!-- -->Response samples<!-- --> </h3><div class="sc-cxFKTC jVRsAZ" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="react-tabs-0" aria-selected="true" aria-disabled="false" aria-controls="react-tabs-1" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="react-tabs-1" aria-labelledby="react-tabs-0"><div><div class="sc-cOaiZO eDzWuJ"><span class="sc-bBrOHt etjuEr">Content type</span><div class="sc-dOSSlk bAzVww">application/json</div></div><div class="sc-hTZhMB kTaCsY"><div class="sc-cTkyaV gLzJQv"><div class="sc-giInvV bIDavi"><button><div class="sc-jcVcfa iVrxDL">Copy</div></button></div><div class="sc-iJuWdM gpkGbA sc-jNMdxs jXmkAn"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"nimages"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"performance_MBs"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"performance_Hz"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"file_prefix"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"state"</span>: <span class="token string">&quot;idle&quot;</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div></div></div></div><div id="/paths/~1cancel/post" data-section-id="/paths/~1cancel/post" class="sc-eCstZk bCpIRB"><div class="sc-iBPTVF keMybc"><div class="sc-hKgKIp gvoNGN"><h2 class="sc-pGaPU biKwui"><a class="sc-crrtmM jGBpue" href="#/paths/~1cancel/post" aria-label="/paths/~1cancel/post"></a>Cancel running data collection<!-- --> </h2><div class="sc-eWVLZl fgfjUV"><div html="&lt;p&gt;It only instructs writer to cancel, but doesn&amp;#39;t wait for cancellation actually happening.
" fill="currentColor"></path></g></svg></div></div><div class="sc-dxfTlo cOuMek api-content"><div class="sc-eDLKkx hNzKJC"><div class="sc-iBdnpw fsPUig"><div class="sc-hLQSwg gikxZY api-info"><h1 class="sc-fsYfdN sc-eFyDpN gqLiaw ObWVe">Jungfraujoch writer<!-- --> <span>(<!-- -->1.0.0<!-- -->)</span></h1><p>Download OpenAPI specification<!-- -->:<a download="openapi.json" target="_blank" class="sc-crHHJw iGcmRf">Download</a></p><div class="sc-iKOmoZ sc-cCzLxZ WVNwY VEBGS"></div><div data-role="redoc-summary" html="" class="sc-iKOmoZ sc-cCzLxZ WVNwY VEBGS"></div><div data-role="redoc-description" html="&lt;p&gt;Jungfraujoch Writer Web API&lt;/p&gt;
" class="sc-iKOmoZ sc-cCzLxZ WVNwY VEBGS"><p>Jungfraujoch Writer Web API</p>
</div></div></div></div><div id="/paths/~1status/get" data-section-id="/paths/~1status/get" class="sc-eDLKkx cSNAXN"><div class="sc-iBdnpw fsPUig"><div class="sc-hLQSwg gikxZY"><h2 class="sc-qZrbh gwJLUj"><a class="sc-csKJxZ fNhImz" href="#/paths/~1status/get" aria-label="/paths/~1status/get"></a>Get writer status<!-- --> </h2><div><h3 class="sc-fYitVF duKVDl">Responses</h3><div><button class="sc-hsaIUA fIqGlH"><svg class="sc-eTNRI hUWsvg" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-gWQvRS ePkkgX">200<!-- --> </strong><div html="&lt;p&gt;Statistics of the last measurement&lt;/p&gt;
" class="sc-iKOmoZ sc-cCzLxZ WVNwY VEBGS sc-ckdEwu LxEPk"><p>Statistics of the last measurement</p>
</div></button></div></div></div><div class="sc-jTQCzO sc-gLLuof imiXRU jGdkPR"><div class="sc-bPrlCs cIsduN"><button class="sc-GkLId bclCVA"><span type="get" class="sc-jYnQyy eIFDdZ http-verb get">get</span><span class="sc-fYrVWQ gllLir">/status</span><svg class="sc-eTNRI exoGJA" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-eGgGjL hsEiws"><div class="sc-fnpiog jerStl"><div html="" class="sc-iKOmoZ sc-cCzLxZ WVNwY jaVotg"></div><div tabindex="0" role="button"><div class="sc-lkDHyp etvaCd"><span></span>/status</div></div></div></div></div><div><h3 class="sc-kFCroH klfnyk"> <!-- -->Response samples<!-- --> </h3><div class="sc-cyZbeP jSWvqu" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="react-tabs-0" aria-selected="true" aria-disabled="false" aria-controls="react-tabs-1" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="react-tabs-1" aria-labelledby="react-tabs-0"><div><div class="sc-cPtzlb jBjImi"><span class="sc-bCvmQg eTZsJr">Content type</span><div class="sc-dQmiwx jCmKdj">application/json</div></div><div class="sc-hVcFVo jeLSWq"><div class="sc-cSxRuM fOJBdW"><div class="sc-gjLLEI iwAAMv"><button><div class="sc-jdHILj krcPXE">Copy</div></button></div><div class="sc-iKOmoZ WVNwY sc-jMbVJB DqFKH"><div class="redoc-json"><code><button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable "><span class="property token string">"nimages"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"performance_MBs"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"performance_Hz"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"file_prefix"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"state"</span>: <span class="token string">&quot;idle&quot;</span></div></li></ul><span class="token punctuation">}</span></code></div></div></div></div></div></div></div></div></div></div></div><div id="/paths/~1cancel/post" data-section-id="/paths/~1cancel/post" class="sc-eDLKkx cSNAXN"><div class="sc-iBdnpw fsPUig"><div class="sc-hLQSwg gikxZY"><h2 class="sc-qZrbh gwJLUj"><a class="sc-csKJxZ fNhImz" href="#/paths/~1cancel/post" aria-label="/paths/~1cancel/post"></a>Cancel running data collection<!-- --> </h2><div class="sc-eYFTNc dZbpPF"><div html="&lt;p&gt;It only instructs writer to cancel, but doesn&amp;#39;t wait for cancellation actually happening.
It still requires to call &lt;code&gt;/wait_till_done&lt;/code&gt;&lt;/p&gt;
" class="sc-iJuWdM sc-cBNeRQ gpkGbA casAkG"><p>It only instructs writer to cancel, but doesn&#39;t wait for cancellation actually happening.
" class="sc-iKOmoZ sc-cCzLxZ WVNwY VEBGS"><p>It only instructs writer to cancel, but doesn&#39;t wait for cancellation actually happening.
It still requires to call <code>/wait_till_done</code></p>
</div></div><div><h3 class="sc-fWPdKs fCsSHf">Responses</h3><div><button class="sc-httZfN eEqsZl" disabled=""><strong class="sc-gVgoeb goojcW">200<!-- --> </strong><div html="&lt;p&gt;Cancel message acknowledged&lt;/p&gt;
" class="sc-iJuWdM sc-cBNeRQ gpkGbA casAkG sc-citwID bzkUsW"><p>Cancel message acknowledged</p>
</div></button></div></div></div><div class="sc-jSguLX sc-gKsecS QymcT bZqtR"><div class="sc-bQdSiB bhuodb"><button class="sc-FyfbU jlriCd"><span type="post" class="sc-jXkspL coiChI http-verb post">post</span><span class="sc-fXoxOd jzevEV">/cancel</span><svg class="sc-dQpIV hHbBnT" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-eFtZDC ciRGmD"><div class="sc-fmlKft buTZbL"><div html="" class="sc-iJuWdM sc-cBNeRQ gpkGbA dujygE"></div><div tabindex="0" role="button"><div class="sc-ljRaSg uePtT"><span></span>/cancel</div></div></div></div></div></div></div></div></div><div class="sc-jtHLPo gfiMgB"></div></div></div>
</div></div><div><h3 class="sc-fYitVF duKVDl">Responses</h3><div><button class="sc-hsaIUA iSOCsR" disabled=""><strong class="sc-gWQvRS ePkkgX">200<!-- --> </strong><div html="&lt;p&gt;Cancel message acknowledged&lt;/p&gt;
" class="sc-iKOmoZ sc-cCzLxZ WVNwY VEBGS sc-ckdEwu LxEPk"><p>Cancel message acknowledged</p>
</div></button></div></div></div><div class="sc-jTQCzO sc-gLLuof imiXRU jGdkPR"><div class="sc-bPrlCs cIsduN"><button class="sc-GkLId bclCVA"><span type="post" class="sc-jYnQyy jBKVIL http-verb post">post</span><span class="sc-fYrVWQ gllLir">/cancel</span><svg class="sc-eTNRI exoGJA" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-eGgGjL hsEiws"><div class="sc-fnpiog jerStl"><div html="" class="sc-iKOmoZ sc-cCzLxZ WVNwY jaVotg"></div><div tabindex="0" role="button"><div class="sc-lkDHyp etvaCd"><span></span>/cancel</div></div></div></div></div></div></div></div><div id="/paths/~1version/get" data-section-id="/paths/~1version/get" class="sc-eDLKkx cSNAXN"><div class="sc-iBdnpw fsPUig"><div class="sc-hLQSwg gikxZY"><h2 class="sc-qZrbh gwJLUj"><a class="sc-csKJxZ fNhImz" href="#/paths/~1version/get" aria-label="/paths/~1version/get"></a>/version<!-- --> </h2><div><h3 class="sc-fYitVF duKVDl">Responses</h3><div><button class="sc-hsaIUA fIqGlH"><svg class="sc-eTNRI hUWsvg" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg><strong class="sc-gWQvRS ePkkgX">200<!-- --> </strong><div html="&lt;p&gt;Release number of Jungfraujoch&lt;/p&gt;
" class="sc-iKOmoZ sc-cCzLxZ WVNwY VEBGS sc-ckdEwu LxEPk"><p>Release number of Jungfraujoch</p>
</div></button></div></div></div><div class="sc-jTQCzO sc-gLLuof imiXRU jGdkPR"><div class="sc-bPrlCs cIsduN"><button class="sc-GkLId bclCVA"><span type="get" class="sc-jYnQyy eIFDdZ http-verb get">get</span><span class="sc-fYrVWQ gllLir">/version</span><svg class="sc-eTNRI exoGJA" style="margin-right:-25px" version="1.1" viewBox="0 0 24 24" x="0" xmlns="http://www.w3.org/2000/svg" y="0" aria-hidden="true"><polygon points="17.3 8.3 12 13.6 6.7 8.3 5.3 9.7 12 16.4 18.7 9.7 "></polygon></svg></button><div aria-hidden="true" class="sc-eGgGjL hsEiws"><div class="sc-fnpiog jerStl"><div html="" class="sc-iKOmoZ sc-cCzLxZ WVNwY jaVotg"></div><div tabindex="0" role="button"><div class="sc-lkDHyp etvaCd"><span></span>/version</div></div></div></div></div></div></div></div></div><div class="sc-juusvx bsunyy"></div></div></div>
<script>
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.3","info":{"title":"Jungfraujoch writer","description":"Jungfraujoch Writer Web API","version":"1.0.0"},"components":{"schemas":{"writer_statistics":{"type":"object","properties":{"nimages":{"type":"integer","format":"int64","description":"Number of images written"},"performance_MBs":{"type":"number","format":"float","description":"Performance in MB/s"},"performance_Hz":{"type":"number","format":"float","description":"Performance in images/s"},"file_prefix":{"type":"string","description":"File prefix for the last written dataset"},"state":{"type":"string","enum":["idle","started","receiving"]}}}}},"paths":{"/status":{"get":{"summary":"Get writer status","responses":{"200":{"description":"Statistics of the last measurement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/writer_statistics"}}}}}}},"/cancel":{"post":{"summary":"Cancel running data collection","description":"It only instructs writer to cancel, but doesn't wait for cancellation actually happening.\nIt still requires to call `/wait_till_done`\n","responses":{"200":{"description":"Cancel message acknowledged"}}}}}}},"searchIndex":{"store":["/paths/~1status/get","/paths/~1cancel/post"],"index":{"version":"2.3.9","fields":["title","description"],"fieldVectors":[["title/0",[0,0.211,1,0.211]],["description/0",[1,0.281]],["title/1",[2,0.16,3,0.61,4,0.61,5,0.61]],["description/1",[0,0.135,2,0.242,6,0.513,7,0.513,8,0.513,9,0.513,10,0.513,11,0.513,12,0.513,13,0.513,14,0.513]]],"invertedIndex":[["actual",{"_index":9,"title":{},"description":{"1":{}}}],["call",{"_index":13,"title":{},"description":{"1":{}}}],["cancel",{"_index":2,"title":{"1":{}},"description":{"1":{}}}],["collect",{"_index":5,"title":{"1":{}},"description":{}}],["data",{"_index":4,"title":{"1":{}},"description":{}}],["doesn't",{"_index":7,"title":{},"description":{"1":{}}}],["happen",{"_index":10,"title":{},"description":{"1":{}}}],["instruct",{"_index":6,"title":{},"description":{"1":{}}}],["requir",{"_index":12,"title":{},"description":{"1":{}}}],["run",{"_index":3,"title":{"1":{}},"description":{}}],["statu",{"_index":1,"title":{"0":{}},"description":{"0":{}}}],["still",{"_index":11,"title":{},"description":{"1":{}}}],["wait",{"_index":8,"title":{},"description":{"1":{}}}],["wait_till_don",{"_index":14,"title":{},"description":{"1":{}}}],["writer",{"_index":0,"title":{"0":{}},"description":{"1":{}}}]],"pipeline":[]}},"options":{}};
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.3","info":{"title":"Jungfraujoch writer","description":"Jungfraujoch Writer Web API","version":"1.0.0"},"components":{"schemas":{"writer_statistics":{"type":"object","properties":{"nimages":{"type":"integer","format":"int64","description":"Number of images written"},"performance_MBs":{"type":"number","format":"float","description":"Performance in MB/s"},"performance_Hz":{"type":"number","format":"float","description":"Performance in images/s"},"file_prefix":{"type":"string","description":"File prefix for the last written dataset"},"state":{"type":"string","enum":["idle","started","receiving"]}}}}},"paths":{"/status":{"get":{"summary":"Get writer status","responses":{"200":{"description":"Statistics of the last measurement","content":{"application/json":{"schema":{"$ref":"#/components/schemas/writer_statistics"}}}}}}},"/cancel":{"post":{"summary":"Cancel running data collection","description":"It only instructs writer to cancel, but doesn't wait for cancellation actually happening.\nIt still requires to call `/wait_till_done`\n","responses":{"200":{"description":"Cancel message acknowledged"}}}},"/version":{"get":{"responses":{"200":{"description":"Release number of Jungfraujoch","content":{"text/plain":{"schema":{"type":"string","example":"1.0.0"}}}}}}}}}},"searchIndex":{"store":["/paths/~1status/get","/paths/~1cancel/post","/paths/~1version/get"],"index":{"version":"2.3.9","fields":["title","description"],"fieldVectors":[["title/0",[0,0.499,1,0.499]],["description/0",[1,0.699]],["title/1",[2,0.364,3,0.759,4,0.759,5,0.759]],["description/1",[0,0.284,2,0.55,6,0.593,7,0.593,8,0.593,9,0.593,10,0.593,11,0.593,12,0.593,13,0.593,14,0.593]],["title/2",[15,0.613]],["description/2",[15,0.699]]],"invertedIndex":[["actual",{"_index":9,"title":{},"description":{"1":{}}}],["call",{"_index":13,"title":{},"description":{"1":{}}}],["cancel",{"_index":2,"title":{"1":{}},"description":{"1":{}}}],["collect",{"_index":5,"title":{"1":{}},"description":{}}],["data",{"_index":4,"title":{"1":{}},"description":{}}],["doesn't",{"_index":7,"title":{},"description":{"1":{}}}],["happen",{"_index":10,"title":{},"description":{"1":{}}}],["instruct",{"_index":6,"title":{},"description":{"1":{}}}],["requir",{"_index":12,"title":{},"description":{"1":{}}}],["run",{"_index":3,"title":{"1":{}},"description":{}}],["statu",{"_index":1,"title":{"0":{}},"description":{"0":{}}}],["still",{"_index":11,"title":{},"description":{"1":{}}}],["version",{"_index":15,"title":{"2":{}},"description":{"2":{}}}],["wait",{"_index":8,"title":{},"description":{"1":{}}}],["wait_till_don",{"_index":14,"title":{},"description":{"1":{}}}],["writer",{"_index":0,"title":{"0":{}},"description":{"1":{}}}]],"pipeline":[]}},"options":{}};
var container = document.getElementById('redoc');
Redoc.hydrate(__redoc_state, container);

View File

@@ -2,7 +2,7 @@ openapi: 3.0.3
info:
title: Jungfraujoch writer
description: Jungfraujoch Writer Web API
version: 1.0.0
version: 1.0.0.rc_10
components:
schemas:
writer_statistics:
@@ -20,6 +20,11 @@ components:
type: number
format: float
description: Performance in images/s
run_number:
type: integer
format: int64
run_name:
type: string
file_prefix:
type: string
description: File prefix for the last written dataset
@@ -48,4 +53,14 @@ paths:
It still requires to call `/wait_till_done`
responses:
"200":
description: Cancel message acknowledged
description: Cancel message acknowledged
/version:
get:
responses:
"200":
description: Release number of Jungfraujoch
content:
text/plain:
schema:
type: string
example: 1.0.0