diff --git a/broker/JFJochBrokerHttp.cpp b/broker/JFJochBrokerHttp.cpp index 0215495e2..a6e7255a6 100644 --- a/broker/JFJochBrokerHttp.cpp +++ b/broker/JFJochBrokerHttp.cpp @@ -1047,18 +1047,20 @@ void JFJochBrokerHttp::rugnux_model_cif_get(httplib::Response &response) { 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") { + 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; - if (!structure || !structure->HasMaps()) { + 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(structure->Map(t == "2fofc" ? RugnuxMapType::TwoFoFc : RugnuxMapType::FoFc), - "application/octet-stream"); + response.set_content(map, "application/octet-stream"); } void JFJochBrokerHttp::config_bragg_integration_get(httplib::Response &response) { diff --git a/broker/OpenAPIConvert.cpp b/broker/OpenAPIConvert.cpp index ffd43b274..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) { @@ -1277,6 +1278,7 @@ 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 7a4c1059d..b7abe100b 100644 --- a/broker/gen/model/Rugnux_live_status.cpp +++ b/broker/gen/model/Rugnux_live_status.cpp @@ -23,6 +23,7 @@ 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; @@ -68,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; @@ -165,6 +166,9 @@ bool Rugnux_live_status::operator==(const Rugnux_live_status& rhs) const (isPlacedModel() == rhs.isPlacedModel()) && + (isAnomalousMap() == rhs.isAnomalousMap()) + && + (getProbe() == rhs.getProbe()) && @@ -232,6 +236,7 @@ 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; @@ -265,6 +270,7 @@ 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()) { @@ -334,6 +340,14 @@ 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 20932abd8..a1d8ba05e 100644 --- a/broker/gen/model/Rugnux_live_status.h +++ b/broker/gen/model/Rugnux_live_status.h @@ -72,6 +72,11 @@ public: 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; @@ -185,6 +190,8 @@ protected: 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 265206dba..305834ae3 100644 --- a/broker/jfjoch_api.yaml +++ b/broker/jfjoch_api.yaml @@ -2786,6 +2786,7 @@ components: - warnings - probe - placed_model + - anomalous_map properties: state: type: string @@ -2795,6 +2796,11 @@ components: 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 @@ -3641,7 +3647,7 @@ paths: 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`. It covers one unit cell centred on the model - along an axis where + 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: @@ -3650,9 +3656,12 @@ paths: required: false schema: type: string - enum: [2fofc, fofc] + enum: [2fofc, fofc, anom] default: 2fofc - description: "`2fofc`: the 2mFo-DFc map; `fofc`: the mFo-DFc difference map" + 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: @@ -3676,7 +3685,7 @@ paths: schema: type: string "404": - description: The last rugnux live run placed no model or made no maps + 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 d346ae438..7e9320b0e 100644 --- a/broker/redoc-static.html +++ b/broker/redoc-static.html @@ -864,7 +864,7 @@ and validation of every following rugnux live collection, until it is removed wi
Authorizations:
bearerAuth

Responses

Response samples

Content type
application/json
{
  • "state": "Idle",
  • "placed_model": 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 +

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. It covers one unit cell centred on the model - along an axis where +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"

2fofc: the 2mFo-DFc map; fofc: the mFo-DFc difference map

+
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. @@ -1113,7 +1115,7 @@ then image might be replaced in the buffer between calling /images and /image.cb