diff --git a/CLAUDE.md b/CLAUDE.md index 3f430a2e5..0bb1218a2 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -150,19 +150,27 @@ accident; name the files the change actually touches, and read `git status` befo ## Changelog -`docs/CHANGELOG.md` is written **for users**. It does not replace commit messages or developer -notes, so keep out of it anything that belongs there instead: +`docs/CHANGELOG.md` is written **for users**: it tells them what to expect from the new version. +It does not replace commit messages or developer notes, so keep out of it anything that belongs there +instead. -- **One line per entry**, ideally one sentence. Two only when a user genuinely needs both. -- **Say what changed** — not why, not what the investigation found, not how the change was arrived - at, not what it measured on. Rationale, measurements and history go in the commit message. +**When.** The changelog is written **once, just before the release branch is merged into main**, on +the maintainer's request, when the branch's full content is known. Never add or edit +`docs/CHANGELOG.md` as part of a feature, fix or performance change - describe the change in its +commit message instead. Written per change, every piece of work looks important enough for an entry +of its own; written at the end, it takes its true place in the release. + +**How.** +- **Condensed.** A release is a handful of one-liners. Fold connected changes into a single entry - + that is the expected outcome, not a loss of detail. +- **What users get, stated as fact.** Describe the capability or the behaviour a user will see. + Leave out the development story: what was tried, what failed, what was found along the way, how + the change was built. Rationale, measurements and history belong in the commit messages. +- **General beats specific.** "Significantly faster processing of serial data" serves a user better + than naming the function that changed, the reason it changed and the percentage it saved on one + dataset. - **No sample identities**, exactly as everywhere else (see below). -**Entries are written only on the maintainer's explicit request**, normally once per release branch -before it is merged, as a short summary of user-visible changes. Do not add or edit -`docs/CHANGELOG.md` as part of a feature, fix or performance change; describe the change in its -commit message instead. - ## Design direction Three standing preferences. They are **directional**, not absolute: they say which way to lean when a diff --git a/broker/JFJochBrokerHttp.cpp b/broker/JFJochBrokerHttp.cpp index 4853b4b0a..a6e7255a6 100644 --- a/broker/JFJochBrokerHttp.cpp +++ b/broker/JFJochBrokerHttp.cpp @@ -3,6 +3,7 @@ // Using OpenAPI licensed with Apache License 2.0 #include "JFJochBrokerHttp.h" +#include "../receiver/RugnuxStructure.h" #include @@ -155,7 +156,9 @@ static const std::set PROTECTED_PATHS{ "/preview/plot", "/preview/plot.bin", "/live/events", - "/rugnux/status" + "/rugnux/status", + "/rugnux/model.cif", + "/rugnux/map.ccp4" }; std::optional JFJochBrokerHttp::AuthorizationHeader(const httplib::Request &req) { @@ -259,6 +262,14 @@ void JFJochBrokerHttp::register_routes(httplib::Server &server) { server.Put("/config/rugnux/model", bind_req(&JFJochBrokerHttp::config_rugnux_model_put)); server.Delete("/config/rugnux/model", bind_noarg(&JFJochBrokerHttp::config_rugnux_model_delete)); server.Get("/rugnux/status", bind_noarg(&JFJochBrokerHttp::rugnux_status_get)); + server.Get("/rugnux/model.cif", bind_noarg(&JFJochBrokerHttp::rugnux_model_cif_get)); + server.Get("/rugnux/map.ccp4", [this](const httplib::Request &req, httplib::Response &res) { + try { + rugnux_map_ccp4_get(parse_query_string(req, "type"), res); + } catch (const std::exception &e) { + send_error(res, handleOperationException(e)); + } + }); server.Get("/config/bragg_integration", bind_noarg(&JFJochBrokerHttp::config_bragg_integration_get)); server.Put("/config/bragg_integration", bind_json(&JFJochBrokerHttp::config_bragg_integration_put, Bragg_integration_settings{})); server.Get("/config/instrument", bind_noarg(&JFJochBrokerHttp::config_instrument_get)); @@ -1025,6 +1036,33 @@ void JFJochBrokerHttp::rugnux_status_get(httplib::Response &response) { ProcessOutput(Convert(state_machine.GetRugnuxStatus()), response); } +void JFJochBrokerHttp::rugnux_model_cif_get(httplib::Response &response) { + const auto structure = state_machine.GetRugnuxStatus().structure; + if (!structure) { + response.status = 404; + return; + } + response.set_content(structure->ModelCif(), "chemical/x-mmcif"); +} + +void JFJochBrokerHttp::rugnux_map_ccp4_get(const std::optional &type, httplib::Response &response) { + const std::string t = type.value_or("2fofc"); + if (t != "2fofc" && t != "fofc" && t != "anom") { + response.status = 400; + response.set_content("Unknown map type " + t, "text/plain"); + return; + } + const auto structure = state_machine.GetRugnuxStatus().structure; + const RugnuxMapType map_type = t == "2fofc" ? RugnuxMapType::TwoFoFc + : t == "fofc" ? RugnuxMapType::FoFc : RugnuxMapType::Anomalous; + const std::string map = structure ? structure->Map(map_type) : std::string(); + if (map.empty()) { + response.status = 404; + return; + } + response.set_content(map, "application/octet-stream"); +} + void JFJochBrokerHttp::config_bragg_integration_get(httplib::Response &response) { ProcessOutput(Convert(state_machine.GetBraggIntegrationSettings()), response); } diff --git a/broker/JFJochBrokerHttp.h b/broker/JFJochBrokerHttp.h index 3528ab5d3..a5ff26c41 100644 --- a/broker/JFJochBrokerHttp.h +++ b/broker/JFJochBrokerHttp.h @@ -206,6 +206,8 @@ class JFJochBrokerHttp { void config_rugnux_model_put(const httplib::Request &request, httplib::Response &response); void config_rugnux_model_delete(httplib::Response &response); void rugnux_status_get(httplib::Response &response); + void rugnux_model_cif_get(httplib::Response &response); + void rugnux_map_ccp4_get(const std::optional &type, httplib::Response &response); void config_bragg_integration_get(httplib::Response &response); void config_bragg_integration_put(const org::openapitools::server::model::Bragg_integration_settings &braggIntegrationSettings, httplib::Response &response); diff --git a/broker/OpenAPIConvert.cpp b/broker/OpenAPIConvert.cpp index c97040847..53168776a 100644 --- a/broker/OpenAPIConvert.cpp +++ b/broker/OpenAPIConvert.cpp @@ -3,6 +3,7 @@ #include "../common/JFJochMath.h" #include "OpenAPIConvert.h" +#include "../receiver/RugnuxStructure.h" // From https://en.cppreference.com/w/cpp/string/byte/tolower std::string str_tolower(std::string s) { @@ -1276,6 +1277,8 @@ org::openapitools::server::model::Rugnux_live_status Convert(const RugnuxLiveSna } ret.setSummary(summary); ret.setWarnings(input.warnings); + ret.setPlacedModel(input.structure != nullptr); + ret.setAnomalousMap(input.structure != nullptr && input.structure->HasAnomalousMap()); return ret; } diff --git a/broker/gen/model/Rugnux_live_status.cpp b/broker/gen/model/Rugnux_live_status.cpp index df6c689da..b7abe100b 100644 --- a/broker/gen/model/Rugnux_live_status.cpp +++ b/broker/gen/model/Rugnux_live_status.cpp @@ -22,6 +22,8 @@ namespace org::openapitools::server::model Rugnux_live_status::Rugnux_live_status() { m_State = ""; + m_Placed_model = false; + m_Anomalous_map = false; m_Probe = ""; m_Probe_s = 0.0; m_Probe_sIsSet = false; @@ -67,7 +69,7 @@ bool Rugnux_live_status::validate(std::stringstream& msg, const std::string& pat bool success = true; const std::string _pathPrefix = pathPrefix.empty() ? "Rugnux_live_status" : pathPrefix; - + if (stepProgressIsSet()) { const float& value = m_Step_progress; @@ -161,6 +163,12 @@ bool Rugnux_live_status::operator==(const Rugnux_live_status& rhs) const (getState() == rhs.getState()) && + (isPlacedModel() == rhs.isPlacedModel()) + && + + (isAnomalousMap() == rhs.isAnomalousMap()) + && + (getProbe() == rhs.getProbe()) && @@ -227,6 +235,8 @@ void to_json(nlohmann::json& j, const Rugnux_live_status& o) { j = nlohmann::json::object(); j["state"] = o.m_State; + j["placed_model"] = o.m_Placed_model; + j["anomalous_map"] = o.m_Anomalous_map; j["probe"] = o.m_Probe; if(o.probeSIsSet()) j["probe_s"] = o.m_Probe_s; @@ -259,6 +269,8 @@ void to_json(nlohmann::json& j, const Rugnux_live_status& o) void from_json(const nlohmann::json& j, Rugnux_live_status& o) { j.at("state").get_to(o.m_State); + j.at("placed_model").get_to(o.m_Placed_model); + j.at("anomalous_map").get_to(o.m_Anomalous_map); j.at("probe").get_to(o.m_Probe); if(j.find("probe_s") != j.end()) { @@ -320,6 +332,22 @@ void Rugnux_live_status::setState(std::string const& value) { m_State = value; } +bool Rugnux_live_status::isPlacedModel() const +{ + return m_Placed_model; +} +void Rugnux_live_status::setPlacedModel(bool const value) +{ + m_Placed_model = value; +} +bool Rugnux_live_status::isAnomalousMap() const +{ + return m_Anomalous_map; +} +void Rugnux_live_status::setAnomalousMap(bool const value) +{ + m_Anomalous_map = value; +} std::string Rugnux_live_status::getProbe() const { return m_Probe; diff --git a/broker/gen/model/Rugnux_live_status.h b/broker/gen/model/Rugnux_live_status.h index e70814cee..a1d8ba05e 100644 --- a/broker/gen/model/Rugnux_live_status.h +++ b/broker/gen/model/Rugnux_live_status.h @@ -67,6 +67,16 @@ public: std::string getState() const; void setState(std::string const& value); /// + /// The run placed the model: it can be fetched from `/rugnux/model.cif` and its maps from `/rugnux/map.ccp4`. + /// + bool isPlacedModel() const; + void setPlacedModel(bool const value); + /// + /// The merge kept the Bijvoet pairs, so with the placed model there is an anomalous difference map (`/rugnux/map.ccp4?type=anom`). + /// + bool isAnomalousMap() const; + void setAnomalousMap(bool const value); + /// /// Answer of the early lattice probe on the first 60 degrees; empty until it answers /// std::string getProbe() const; @@ -178,6 +188,10 @@ public: protected: std::string m_State; + bool m_Placed_model; + + bool m_Anomalous_map; + std::string m_Probe; double m_Probe_s; diff --git a/broker/jfjoch_api.yaml b/broker/jfjoch_api.yaml index 4f45de5e6..305834ae3 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -2785,10 +2785,22 @@ components: - summary - warnings - probe + - placed_model + - anomalous_map properties: state: type: string enum: [Idle, Running, Done, Failed, Cancelled, Skipped] + placed_model: + type: boolean + description: | + The run placed the model: it can be fetched from `/rugnux/model.cif` and its maps from + `/rugnux/map.ccp4`. + anomalous_map: + type: boolean + description: | + The merge kept the Bijvoet pairs, so with the placed model there is an anomalous difference map + (`/rugnux/map.ccp4?type=anom`). probe: type: string description: Answer of the early lattice probe on the first 60 degrees; empty until it answers @@ -3605,6 +3617,75 @@ paths: application/json: schema: $ref: '#/components/schemas/rugnux_live_status' + /rugnux/model.cif: + get: + summary: Get the model as placed by the last rugnux live run + description: | + The model placed against the data by molecular replacement or validation, as mmCIF - the same text as the + `_model.cif` file written beside the data: the data's cell and space group, with the input model's own + metadata (entities, sequences, references, authors, software) kept. Kept as long as `/rugnux/status`. + security: + - bearerAuth: [] + responses: + "200": + description: Placed model + content: + chemical/x-mmcif: + schema: + type: string + format: binary + "401": + description: The current dataset is protected and no valid bearer token was presented. + content: + text/plain: + schema: + type: string + "404": + description: The last rugnux live run placed no model + /rugnux/map.ccp4: + get: + summary: Get an electron-density map of the last rugnux live run + description: | + The map of the placed model (`/rugnux/model.cif`) in CCP4 format (mode 2, float), made from the map + coefficients written to `_maps.mtz` (FWT/PHWT, DELFWT/PHDELWT, ANOM/PHANOM). It covers one unit cell centred on the model - along an axis where + the model reaches further than the cell, the model plus 5 A instead - sampled every d_min/3; the mean and + RMS in its header are those of the unit cell, so contour levels in sigma are the usual ones. + parameters: + - in: query + name: type + required: false + schema: + type: string + enum: [2fofc, fofc, anom] + default: 2fofc + description: | + `2fofc`: the 2mFo-DFc map; `fofc`: the mFo-DFc difference map; `anom`: the anomalous difference map, + (F(+) - F(-)) on the model phases less 90 degrees, where the merge kept the Bijvoet pairs (`anomalous_map` + in `/rugnux/status`) + security: + - bearerAuth: [] + responses: + "200": + description: Map + content: + application/octet-stream: + schema: + type: string + format: binary + "400": + description: Unknown map type + content: + text/plain: + schema: + type: string + "401": + description: The current dataset is protected and no valid bearer token was presented. + content: + text/plain: + schema: + type: string + "404": + description: The last rugnux live run placed no model or made no maps, or (`anom`) has no Bijvoet pairs /config/zeromq_preview: put: summary: Set ZeroMQ preview settings diff --git a/broker/redoc-static.html b/broker/redoc-static.html index bb3abf9d2..7e9320b0e 100644 --- a/broker/redoc-static.html +++ b/broker/redoc-static.html @@ -394,7 +394,7 @@ data-styled.g138[id="sc-dxcDKg"]{content:"eajCCh,"}/*!sc*/ -

Set ZeroMQ preview settings

Jungfraujoch can generate preview message stream on ZeroMQ SUB socket. +

http://localhost:5232/rugnux/status

Response samples

Content type
application/json
{
  • "state": "Idle",
  • "placed_model": true,
  • "anomalous_map": true,
  • "probe": "string",
  • "probe_s": 0.1,
  • "start_to_first_image_s": 0.1,
  • "message": "string",
  • "images_expected": 0,
  • "expected_collection_s": 0.1,
  • "images_received": 0,
  • "elapsed_s": 0.1,
  • "step_progress": 1,
  • "steps": [
    ],
  • "last_image_s": 0.1,
  • "cut": "string",
  • "cut_s": 0.1,
  • "last_image_to_written_s": 0.1,
  • "verdict": "string",
  • "verdict_text": "string",
  • "summary": [
    ],
  • "warnings": [
    ]
}

Get the model as placed by the last rugnux live run

The model placed against the data by molecular replacement or validation, as mmCIF - the same text as the +_model.cif file written beside the data: the data's cell and space group, with the input model's own +metadata (entities, sequences, references, authors, software) kept. Kept as long as /rugnux/status.

+
Authorizations:
bearerAuth

Responses

Get an electron-density map of the last rugnux live run

The map of the placed model (/rugnux/model.cif) in CCP4 format (mode 2, float), made from the map +coefficients written to _maps.mtz (FWT/PHWT, DELFWT/PHDELWT, ANOM/PHANOM). It covers one unit cell centred on the model - along an axis where +the model reaches further than the cell, the model plus 5 A instead - sampled every d_min/3; the mean and +RMS in its header are those of the unit cell, so contour levels in sigma are the usual ones.

+
Authorizations:
bearerAuth
query Parameters
type
string
Default: "2fofc"
Enum: "2fofc" "fofc" "anom"

2fofc: the 2mFo-DFc map; fofc: the mFo-DFc difference map; anom: the anomalous difference map, +(F(+) - F(-)) on the model phases less 90 degrees, where the merge kept the Bijvoet pairs (anomalous_map +in /rugnux/status)

+

Responses

Set ZeroMQ preview settings

Jungfraujoch can generate preview message stream on ZeroMQ SUB socket. Here settings of the socket can be adjusted. While the data structure contains also socket_address, this cannot be changed via HTTP and is ignore in PUT request. Options set with this PUT request have no effect on HTTP based preview.

@@ -880,9 +899,9 @@ Address follows ZeroMQ convention for sockets - in practice ipc://

Request samples

Content type
application/json
{
  • "enabled": true,
  • "period_ms": 1000,
  • "socket_address": "string"
}

Response samples

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

Get ZeroMQ preview settings

Responses

Request samples

Content type
application/json
{
  • "enabled": true,
  • "period_ms": 1000,
  • "socket_address": "string"
}

Response samples

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

Get ZeroMQ preview settings

Responses

Response samples

Content type
application/json
{
  • "enabled": true,
  • "period_ms": 1000,
  • "socket_address": "string"
}

Set ZeroMQ metadata settings

Jungfraujoch can generate metadata message stream on ZeroMQ PUB socket. This stream covers all images. +

http://localhost:5232/config/zeromq_preview

Response samples

Content type
application/json
{
  • "enabled": true,
  • "period_ms": 1000,
  • "socket_address": "string"
}

Set ZeroMQ metadata settings

Jungfraujoch can generate metadata message stream on ZeroMQ PUB socket. This stream covers all images. Here settings of the socket can be adjusted. While the data structure contains also socket_address, this cannot be changed via HTTP and is ignore in PUT request.

Request Body schema: application/json
enabled
required
boolean
Default: true

ZeroMQ metadata socket is enabled.

@@ -895,9 +914,9 @@ Address follows ZeroMQ convention for sockets - in practice ipc://

Request samples

Content type
application/json
{
  • "enabled": true,
  • "period_ms": 1000,
  • "socket_address": "string"
}

Response samples

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

Get ZeroMQ metadata socket settings

Responses

Request samples

Content type
application/json
{
  • "enabled": true,
  • "period_ms": 1000,
  • "socket_address": "string"
}

Response samples

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

Get ZeroMQ metadata socket settings

Responses

Response samples

Content type
application/json
{
  • "enabled": true,
  • "period_ms": 1000,
  • "socket_address": "string"
}

Set configuration for dark data collection to calculate mask

This is only possible when operating DECTRIS detectors at the moment; it will be also available for PSI EIGER at some point. +

http://localhost:5232/config/zeromq_metadata

Response samples

Content type
application/json
{
  • "enabled": true,
  • "period_ms": 1000,
  • "socket_address": "string"
}

Set configuration for dark data collection to calculate mask

This is only possible when operating DECTRIS detectors at the moment; it will be also available for PSI EIGER at some point. This can only be done when detector is Idle, Error or Inactive states.

Request Body schema: application/json
detector_threshold_keV
required
number <float> [ 2.5 .. 100 ]
Default: 3.5

Energy threshold for dark image collection

frame_time_us
required
integer <int64> [ 500 .. 100000 ]
Default: 10000

Time between frames for dark image collection

@@ -908,51 +927,51 @@ This can only be done when detector is Idle, Error or

Request samples

Content type
application/json
{
  • "detector_threshold_keV": 3.5,
  • "frame_time_us": 10000,
  • "number_of_frames": 1000,
  • "max_allowed_pixel_count": 1,
  • "max_frames_with_signal": 10
}

Response samples

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

Get settings for dark data collection to calculate mask

Responses

Request samples

Content type
application/json
{
  • "detector_threshold_keV": 3.5,
  • "frame_time_us": 10000,
  • "number_of_frames": 1000,
  • "max_allowed_pixel_count": 1,
  • "max_frames_with_signal": 10
}

Response samples

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

Get settings for dark data collection to calculate mask

Responses

Response samples

Content type
application/json
{
  • "detector_threshold_keV": 3.5,
  • "frame_time_us": 10000,
  • "number_of_frames": 1000,
  • "max_allowed_pixel_count": 1,
  • "max_frames_with_signal": 10
}

Get Jungfraujoch status

Status of the data acquisition

+
http://localhost:5232/config/dark_mask

Response samples

Content type
application/json
{
  • "detector_threshold_keV": 3.5,
  • "frame_time_us": 10000,
  • "number_of_frames": 1000,
  • "max_allowed_pixel_count": 1,
  • "max_frames_with_signal": 10
}

Get Jungfraujoch status

Status of the data acquisition

Responses

Response samples

Content type
application/json
{
  • "state": "Inactive",
  • "progress": 1,
  • "message": "string",
  • "message_severity": "success",
  • "gpu_count": 0,
  • "broker_version": "1.0.0-rc.128"
}

Get status of FPGA devices

Responses

Response samples

Content type
application/json
{
  • "state": "Inactive",
  • "progress": 1,
  • "message": "string",
  • "message_severity": "success",
  • "gpu_count": 0,
  • "broker_version": "1.0.0-rc.128"
}

Get status of FPGA devices

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Return XFEL pulse IDs for the current data acquisition

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

+
http://localhost:5232/fpga_status

Response samples

Content type
application/json
[
  • {
    }
]

Return XFEL pulse IDs for the current data acquisition

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

Responses

Response samples

Content type
application/json
[
  • 0
]

Return XFEL event codes for the current data acquisition

Return array of XFEL event codes

+
http://localhost:5232/xfel/pulse_id

Response samples

Content type
application/json
[
  • 0
]

Return XFEL event codes for the current data acquisition

Return array of XFEL event codes

Responses

Response samples

Content type
application/json
[
  • 0
]

Get status of image pusher

Responses

Response samples

Content type
application/json
[
  • 0
]

Get status of image pusher

Responses

Response samples

Content type
application/json
{
  • "pusher_type": "ZeroMQ",
  • "addr": [
    ],
  • "connected_writers": 0,
  • "images_written": 0,
  • "images_write_error": 0,
  • "writer_fifo_utilization": [
    ]
}

Get detector status

Status of the JUNGFRAU detector

+
http://localhost:5232/image_pusher/status

Response samples

Content type
application/json
{
  • "pusher_type": "ZeroMQ",
  • "addr": [
    ],
  • "connected_writers": 0,
  • "images_written": 0,
  • "images_write_error": 0,
  • "writer_fifo_utilization": [
    ]
}

Get detector status

Status of the JUNGFRAU detector

Responses

Response samples

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

Get ROI definitions

Responses

Response samples

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

Get ROI definitions

Responses

Response samples

Content type
application/json
{
  • "box": {
    },
  • "circle": {
    },
  • "azim": {
    }
}

Upload ROI definitions

Request Body schema: application/json
required
object (roi_box_list)

List of box ROIs

+
http://localhost:5232/config/roi

Response samples

Content type
application/json
{
  • "box": {
    },
  • "circle": {
    },
  • "azim": {
    }
}

Upload ROI definitions

Request Body schema: application/json
required
object (roi_box_list)

List of box ROIs

required
object (roi_circle_list)

List of circular ROIs

required
object (roi_azim_list)

List of azimuthal ROIs

Responses

Request samples

Content type
application/json
{
  • "box": {
    },
  • "circle": {
    },
  • "azim": {
    }
}

Response samples

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

Get general statistics

measurement is omitted unless the request carries a valid bearer token for a protected +

http://localhost:5232/config/roi

Request samples

Content type
application/json
{
  • "box": {
    },
  • "circle": {
    },
  • "azim": {
    }
}

Response samples

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

Get general statistics

measurement is omitted unless the request carries a valid bearer token for a protected dataset (see tokens in /start).

Responses

Response samples

Content type
application/json
{
  • "detector": {
    },
  • "detector_list": {
    },
  • "detector_settings": {
    },
  • "image_format_settings": {
    },
  • "instrument_metadata": {
    },
  • "file_writer_settings": {
    },
  • "data_processing_settings": {
    },
  • "measurement": {
    },
  • "broker": {
    },
  • "fpga": [
    ],
  • "calibration": [
    ],
  • "zeromq_preview": {
    },
  • "zeromq_metadata": {
    },
  • "dark_mask": {
    },
  • "pixel_mask": {
    },
  • "roi": {
    },
  • "az_int": {
    },
  • "buffer": {
    },
  • "indexing": {
    },
  • "bragg_integration": {
    },
  • "image_pusher": {
    }
}

Get data collection statistics

Results of the last data collection (dataset name, unit cell, ...)

+
http://localhost:5232/statistics

Response samples

Content type
application/json
{
  • "detector": {
    },
  • "detector_list": {
    },
  • "detector_settings": {
    },
  • "image_format_settings": {
    },
  • "instrument_metadata": {
    },
  • "file_writer_settings": {
    },
  • "data_processing_settings": {
    },
  • "measurement": {
    },
  • "broker": {
    },
  • "fpga": [
    ],
  • "calibration": [
    ],
  • "zeromq_preview": {
    },
  • "zeromq_metadata": {
    },
  • "dark_mask": {
    },
  • "pixel_mask": {
    },
  • "roi": {
    },
  • "az_int": {
    },
  • "buffer": {
    },
  • "indexing": {
    },
  • "bragg_integration": {
    },
  • "image_pusher": {
    }
}

Get data collection statistics

Results of the last data collection (dataset name, unit cell, ...)

Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "file_prefix": "string",
  • "run_number": 0,
  • "experiment_group": "string",
  • "images_expected": 0,
  • "images_collected": 0,
  • "images_sent": 0,
  • "images_written": 0,
  • "images_discarded_lossy_compression": 0,
  • "max_image_number_sent": 0,
  • "collection_efficiency": 1,
  • "compression_ratio": 5.3,
  • "cancelled": true,
  • "max_receiver_delay": 0,
  • "indexing_rate": 0.1,
  • "detector_width": 0,
  • "detector_height": 0,
  • "detector_pixel_depth": 2,
  • "bkg_estimate": 0.1,
  • "unit_cell": "string",
  • "error_pixels": 0.1,
  • "saturated_pixels": 0.1,
  • "roi_beam_pixels": 0.1,
  • "roi_beam_sum": 0.1
}

Get calibration statistics

Statistics are provided for each module/storage cell separately

+
http://localhost:5232/statistics/data_collection

Response samples

Content type
application/json
{
  • "file_prefix": "string",
  • "run_number": 0,
  • "experiment_group": "string",
  • "images_expected": 0,
  • "images_collected": 0,
  • "images_sent": 0,
  • "images_written": 0,
  • "images_discarded_lossy_compression": 0,
  • "max_image_number_sent": 0,
  • "collection_efficiency": 1,
  • "compression_ratio": 5.3,
  • "cancelled": true,
  • "max_receiver_delay": 0,
  • "indexing_rate": 0.1,
  • "detector_width": 0,
  • "detector_height": 0,
  • "detector_pixel_depth": 2,
  • "bkg_estimate": 0.1,
  • "unit_cell": "string",
  • "error_pixels": 0.1,
  • "saturated_pixels": 0.1,
  • "roi_beam_pixels": 0.1,
  • "roi_beam_sum": 0.1
}

Get calibration statistics

Statistics are provided for each module/storage cell separately

Responses

Response samples

Content type
application/json
[
  • {
    }
]

Get mask of the detector (binary)

Detector must be Initialized. +

http://localhost:5232/statistics/calibration

Response samples

Content type
application/json
[
  • {
    }
]

Get mask of the detector (binary)

Detector must be Initialized. Get full pixel mask of the detector. See NXmx standard for meaning of pixel values.

Responses

Response samples

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

Get mask of the detector (TIFF)

Should be in Idle state. +

http://localhost:5232/config/user_mask

Response samples

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

Get mask of the detector (TIFF)

Should be in Idle state. Get full pixel mask of the detector See NXmx standard for meaning of pixel values

Responses

Response samples

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

Get pedestal in TIFF format

query Parameters
gain_level
required
integer

Gain level (0, 1, 2)

+
http://localhost:5232/config/user_mask.tiff

Response samples

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

Get pedestal in TIFF format

query Parameters
gain_level
required
integer

Gain level (0, 1, 2)

sc
integer

Storage cell number

Responses

Response samples

Content type
application/json
{
  • "title": "string",
  • "unit_x": "image_number",
  • "size_x": 0.1,
  • "size_y": 0.1,
  • "plot": [
    ]
}

Generate 1D plot from Jungfraujoch and send in raw binary format. +

http://localhost:5232/preview/plot

Response samples

Content type
application/json
{
  • "title": "string",
  • "unit_x": "image_number",
  • "size_x": 0.1,
  • "size_y": 0.1,
  • "plot": [
    ]
}

Generate 1D plot from Jungfraujoch and send in raw binary format. Data are provided as (32-bit) float binary array. This format doesn't transmit information about X-axis, only values, so it is of limited use for azimuthal integration.

Authorizations:
bearerAuth
query Parameters
type
required
string
Enum: "bkg_estimate" "spindle_blind_fraction" "azint" "azint_1d" "spot_count" "spot_count_low_res" "spot_count_indexed" "spot_count_ice" "indexing_rate" "indexing_lattice_count" "indexing_unit_cell_length" "indexing_unit_cell_angle" "profile_radius" "mosaicity" "b_factor" "error_pixels" "saturated_pixels" "image_collection_efficiency" "receiver_delay" "receiver_free_send_buf" "strong_pixels" "roi_sum" "roi_mean" "roi_max_count" "roi_pixels" "roi_weighted_x" "roi_weighted_y" "packets_received" "max_pixel_value" "resolution_estimate" "pixel_sum" "processing_time" "beam_center_x" "beam_center_y" "integrated_reflections" "image_scale_factor" "image_scale_cc" "compression_ratio" "ice_ring_score"

Type of requested plot

@@ -1026,13 +1045,13 @@ This format doesn't transmit information about X-axis, only values, so it i

Response samples

Content type
application/json
{
  • "file_prefix": "string",
  • "rotation_unit_cell": {
    },
  • "rotation_crystal_lattice": [
    ],
  • "rotation_bravais": "string",
  • "images": [
    ]
}

Get Start message in CBOR format

Contains metadata for a dataset (e.g., experimental geometry)

+
http://localhost:5232/result/scan

Response samples

Content type
application/json
{
  • "file_prefix": "string",
  • "rotation_unit_cell": {
    },
  • "rotation_crystal_lattice": [
    ],
  • "rotation_bravais": "string",
  • "images": [
    ]
}

Get Start message in CBOR format

Contains metadata for a dataset (e.g., experimental geometry)

Authorizations:
bearerAuth

Responses

Response samples

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

Event stream of the collection, for a reader following it

Server-sent events (text/event-stream) for the current collection, from the moment /start has +

http://localhost:5232/image_buffer/start.cbor

Response samples

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

Event stream of the collection, for a reader following it

Server-sent events (text/event-stream) for the current collection, from the moment /start has accepted it: first its whole history, then every change, until it ends or a new collection begins. Only one reader at a time. Events, each with a JSON data line:

    @@ -1060,7 +1079,7 @@ A comment line (: keepalive) every 10 s when nothing happens.

Response samples

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

Get preview image in JPEG format using custom settings

Authorizations:
bearerAuth
query Parameters
id
integer <int64> >= -2
Default: -1

Image ID in the image buffer. Special values: -1 - last image in the buffer, -2: last indexed image in the buffer

+
http://localhost:5232/image_buffer/image.cbor

Response samples

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

Get preview image in JPEG format using custom settings

Authorizations:
bearerAuth
query Parameters
id
integer <int64> >= -2
Default: -1

Image ID in the image buffer. Special values: -1 - last image in the buffer, -2: last indexed image in the buffer

show_user_mask
boolean
Default: false

Show user mask

show_roi
boolean
Default: false

Show ROI areas on the image

show_spots
boolean
Default: true

Show spot finding results on the image

@@ -1077,7 +1096,7 @@ A comment line (: keepalive) every 10 s when nothing happens.

Response samples

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

Get preview image in TIFF format

Authorizations:
bearerAuth
query Parameters
id
integer <int64> >= -2
Default: -1

Image ID in the image buffer. Special values: -1 - last image in the buffer, -2: last indexed image in the buffer

+
http://localhost:5232/image_buffer/image.jpeg

Response samples

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

Get preview image in TIFF format

Authorizations:
bearerAuth
query Parameters
id
integer <int64> >= -2
Default: -1

Image ID in the image buffer. Special values: -1 - last image in the buffer, -2: last indexed image in the buffer

Responses

Responses

Response samples

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

Get status of the image buffers

Can be run at any stage of Jungfraujoch operation, including during data collection. +

http://localhost:5232/image_buffer/clear

Response samples

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

Get status of the image buffers

Can be run at any stage of Jungfraujoch operation, including during data collection. The status of the image buffer is volatile during data collection - if data collection goes for more images than available buffer slots, then image might be replaced in the buffer between calling /images and /image.cbor.

Responses

Response samples

Content type
application/json
{
  • "min_image_number": 0,
  • "max_image_number": 0,
  • "image_numbers": [
    ],
  • "total_slots": 0,
  • "available_slots": 0,
  • "in_preparation_slots": 0,
  • "in_sending_slots": 0,
  • "current_counter": 0
}

Get Jungfraujoch version of jfjoch_broker

Responses

Response samples

Content type
application/json
{
  • "min_image_number": 0,
  • "max_image_number": 0,
  • "image_numbers": [
    ],
  • "total_slots": 0,
  • "available_slots": 0,
  • "in_preparation_slots": 0,
  • "in_sending_slots": 0,
  • "current_counter": 0
}

Get Jungfraujoch version of jfjoch_broker

Responses