API: the per-image scale and the frames the merge left out in the rugnux live status

A rotation run now leaves two more things in `GET /rugnux/status` once it is over: `frame_scales`, the
per-image scale factor of the merge (one entry per image, 0 where the image got none), and
`frame_ranges`, the stretches of the sweep the merge downgraded or rejected, each with its disposition
and the reason the sweep-quality diagnostic saw there - which frames rugnux left out, and why. Both
come from what the run already has (the end message's scale vector and SweepQuality's per-image
dispositions, run-length encoded with the reason of the range they lie in); nothing is computed anew.

The C++ model, the Redoc page, the TypeScript client and the python client docs are regenerated from
the YAML. RugnuxLiveFrames_OpenAPI covers the encoding and the conversion.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK
This commit is contained in:
leonarski_fandClaude Fable 5.1 committed 2026-11-11 22:24:06 +01:00
1 parent fa94f24777
commit cb2dd697dd
17 files changed
+582 -6

No files matched your search

+16
View File
@@ -1380,6 +1380,22 @@ org::openapitools::server::model::Rugnux_live_status Convert(const RugnuxLiveSna
}
if (input.overall)
ret.setOverall(convert_shell(input.overall.value()));
if (!input.frame_scales.empty()) {
std::vector<float> scales; // JSON has no NaN: an image without a scale carries 0
for (float g: input.frame_scales)
scales.push_back(std::isfinite(g) ? g : 0.0f);
ret.setFrameScales(scales);
std::vector<org::openapitools::server::model::Rugnux_live_frame_range> ranges;
for (const auto &in: input.frame_ranges) {
org::openapitools::server::model::Rugnux_live_frame_range r;
r.setFirstImage(in.first_image);
r.setLastImage(in.last_image);
r.setDisposition(in.disposition);
r.setReason(in.reason);
ranges.push_back(r);
}
ret.setFrameRanges(ranges);
}
if (input.model) {
const RugnuxLiveModel &m = input.model.value();
org::openapitools::server::model::Rugnux_live_model model;
@@ -0,0 +1,133 @@
/**
* Jungfraujoch
* API to control Jungfraujoch developed by the Paul Scherrer Institute (Switzerland). Jungfraujoch is a data acquisition and analysis system for pixel array detectors, primarly PSI JUNGFRAU. Jungfraujoch uses FPGA boards to acquire data at high data rates. # License Clarification While this API definition is licensed under GPL-3.0, **the GPL copyleft provisions do not apply** when this file is used solely to generate OpenAPI clients or when implementing applications that interact with the API. Generated client code and applications using this API definition are not subject to the GPL license requirements and may be distributed under terms of your choosing. This exception is similar in spirit to the Linux Kernel's approach to userspace API headers and the GCC Runtime Library Exception. The Linux Kernel developers have explicitly stated that user programs that merely use the kernel interfaces (syscalls, ioctl definitions, etc.) are not derivative works of the kernel and are not subject to the terms of the GPL. This exception is intended to allow wider use of this API specification without imposing GPL requirements on applications that merely interact with the API, regardless of whether they communicate through network calls or other mechanisms.
*
* The version of the OpenAPI document: 1.0.0-rc.186
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
#include "Rugnux_live_frame_range.h"
#include "Helpers.h"
#include <sstream>
namespace org::openapitools::server::model
{
Rugnux_live_frame_range::Rugnux_live_frame_range()
{
m_First_image = 0L;
m_Last_image = 0L;
m_Disposition = "";
m_Reason = "";
}
void Rugnux_live_frame_range::validate() const
{
std::stringstream msg;
if (!validate(msg))
{
throw org::openapitools::server::helpers::ValidationException(msg.str());
}
}
bool Rugnux_live_frame_range::validate(std::stringstream& msg) const
{
return validate(msg, "");
}
bool Rugnux_live_frame_range::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Rugnux_live_frame_range" : pathPrefix;
return success;
}
bool Rugnux_live_frame_range::operator==(const Rugnux_live_frame_range& rhs) const
{
return
(getFirstImage() == rhs.getFirstImage())
&&
(getLastImage() == rhs.getLastImage())
&&
(getDisposition() == rhs.getDisposition())
&&
(getReason() == rhs.getReason())
;
}
bool Rugnux_live_frame_range::operator!=(const Rugnux_live_frame_range& rhs) const
{
return !(*this == rhs);
}
void to_json(nlohmann::json& j, const Rugnux_live_frame_range& o)
{
j = nlohmann::json::object();
j["first_image"] = o.m_First_image;
j["last_image"] = o.m_Last_image;
j["disposition"] = o.m_Disposition;
j["reason"] = o.m_Reason;
}
void from_json(const nlohmann::json& j, Rugnux_live_frame_range& o)
{
j.at("first_image").get_to(o.m_First_image);
j.at("last_image").get_to(o.m_Last_image);
j.at("disposition").get_to(o.m_Disposition);
j.at("reason").get_to(o.m_Reason);
}
int64_t Rugnux_live_frame_range::getFirstImage() const
{
return m_First_image;
}
void Rugnux_live_frame_range::setFirstImage(int64_t const value)
{
m_First_image = value;
}
int64_t Rugnux_live_frame_range::getLastImage() const
{
return m_Last_image;
}
void Rugnux_live_frame_range::setLastImage(int64_t const value)
{
m_Last_image = value;
}
std::string Rugnux_live_frame_range::getDisposition() const
{
return m_Disposition;
}
void Rugnux_live_frame_range::setDisposition(std::string const& value)
{
m_Disposition = value;
}
std::string Rugnux_live_frame_range::getReason() const
{
return m_Reason;
}
void Rugnux_live_frame_range::setReason(std::string const& value)
{
m_Reason = value;
}
} // namespace org::openapitools::server::model
@@ -0,0 +1,98 @@
/**
* Jungfraujoch
* API to control Jungfraujoch developed by the Paul Scherrer Institute (Switzerland). Jungfraujoch is a data acquisition and analysis system for pixel array detectors, primarly PSI JUNGFRAU. Jungfraujoch uses FPGA boards to acquire data at high data rates. # License Clarification While this API definition is licensed under GPL-3.0, **the GPL copyleft provisions do not apply** when this file is used solely to generate OpenAPI clients or when implementing applications that interact with the API. Generated client code and applications using this API definition are not subject to the GPL license requirements and may be distributed under terms of your choosing. This exception is similar in spirit to the Linux Kernel's approach to userspace API headers and the GCC Runtime Library Exception. The Linux Kernel developers have explicitly stated that user programs that merely use the kernel interfaces (syscalls, ioctl definitions, etc.) are not derivative works of the kernel and are not subject to the terms of the GPL. This exception is intended to allow wider use of this API specification without imposing GPL requirements on applications that merely interact with the API, regardless of whether they communicate through network calls or other mechanisms.
*
* The version of the OpenAPI document: 1.0.0-rc.186
* Contact: filip.leonarski@psi.ch
*
* NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
* https://openapi-generator.tech
* Do not edit the class manually.
*/
/*
* Rugnux_live_frame_range.h
*
* A stretch of a rotation sweep the merge did not take at face value: downgraded (merged at the reduced weight its own scale and sigmas give it) or rejected (nothing of it reached the merge), with the reason the sweep-quality diagnostic saw - the lines of the report&#39;s SWEEP section.
*/
#ifndef Rugnux_live_frame_range_H_
#define Rugnux_live_frame_range_H_
#include <string>
#include <nlohmann/json.hpp>
namespace org::openapitools::server::model
{
/// <summary>
/// A stretch of a rotation sweep the merge did not take at face value: downgraded (merged at the reduced weight its own scale and sigmas give it) or rejected (nothing of it reached the merge), with the reason the sweep-quality diagnostic saw - the lines of the report&#39;s SWEEP section.
/// </summary>
class Rugnux_live_frame_range
{
public:
Rugnux_live_frame_range();
virtual ~Rugnux_live_frame_range() = 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 Rugnux_live_frame_range& rhs) const;
bool operator!=(const Rugnux_live_frame_range& rhs) const;
/////////////////////////////////////////////
/// Rugnux_live_frame_range members
/// <summary>
/// First image of the stretch, inclusive, numbered as the collection&#39;s images
/// </summary>
int64_t getFirstImage() const;
void setFirstImage(int64_t const value);
/// <summary>
/// Last image of the stretch, inclusive
/// </summary>
int64_t getLastImage() const;
void setLastImage(int64_t const value);
/// <summary>
///
/// </summary>
std::string getDisposition() const;
void setDisposition(std::string const& value);
/// <summary>
/// What was seen over the stretch, e.g. \&quot;out of beam\&quot;, \&quot;no diffraction\&quot;, \&quot;radiation damage\&quot;
/// </summary>
std::string getReason() const;
void setReason(std::string const& value);
friend void to_json(nlohmann::json& j, const Rugnux_live_frame_range& o);
friend void from_json(const nlohmann::json& j, Rugnux_live_frame_range& o);
protected:
int64_t m_First_image;
int64_t m_Last_image;
std::string m_Disposition;
std::string m_Reason;
};
} // namespace org::openapitools::server::model
#endif /* Rugnux_live_frame_range_H_ */
+99 -1
View File
@@ -32,6 +32,8 @@ Rugnux_live_status::Rugnux_live_status()
m_Shells_mergeIsSet = false;
m_ShellsIsSet = false;
m_OverallIsSet = false;
m_Frame_scalesIsSet = false;
m_Frame_rangesIsSet = false;
m_Space_group = "";
m_Space_groupIsSet = false;
m_D_min = 0.0;
@@ -105,7 +107,49 @@ bool Rugnux_live_status::validate(std::stringstream& msg, const std::string& pat
}
}
if (frameScalesIsSet())
{
const std::vector<float>& value = m_Frame_scales;
const std::string currentValuePath = _pathPrefix + ".frameScales";
{ // Recursive validation of array elements
const std::string oldValuePath = currentValuePath;
int i = 0;
for (const float& value : value)
{
const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]";
i++;
}
}
}
if (frameRangesIsSet())
{
const std::vector<org::openapitools::server::model::Rugnux_live_frame_range>& value = m_Frame_ranges;
const std::string currentValuePath = _pathPrefix + ".frameRanges";
{ // Recursive validation of array elements
const std::string oldValuePath = currentValuePath;
int i = 0;
for (const org::openapitools::server::model::Rugnux_live_frame_range& value : value)
{
const std::string currentValuePath = oldValuePath + "[" + std::to_string(i) + "]";
success = value.validate(msg, currentValuePath + ".frameRanges") && success;
i++;
}
}
}
if (stepProgressIsSet())
{
const float& value = m_Step_progress;
@@ -248,6 +292,12 @@ bool Rugnux_live_status::operator==(const Rugnux_live_status& rhs) const
((!overallIsSet() && !rhs.overallIsSet()) || (overallIsSet() && rhs.overallIsSet() && getOverall() == rhs.getOverall())) &&
((!frameScalesIsSet() && !rhs.frameScalesIsSet()) || (frameScalesIsSet() && rhs.frameScalesIsSet() && getFrameScales() == rhs.getFrameScales())) &&
((!frameRangesIsSet() && !rhs.frameRangesIsSet()) || (frameRangesIsSet() && rhs.frameRangesIsSet() && getFrameRanges() == rhs.getFrameRanges())) &&
((!spaceGroupIsSet() && !rhs.spaceGroupIsSet()) || (spaceGroupIsSet() && rhs.spaceGroupIsSet() && getSpaceGroup() == rhs.getSpaceGroup())) &&
@@ -339,6 +389,10 @@ void to_json(nlohmann::json& j, const Rugnux_live_status& o)
j["shells"] = o.m_Shells;
if(o.overallIsSet())
j["overall"] = o.m_Overall;
if(o.frameScalesIsSet() || !o.m_Frame_scales.empty())
j["frame_scales"] = o.m_Frame_scales;
if(o.frameRangesIsSet() || !o.m_Frame_ranges.empty())
j["frame_ranges"] = o.m_Frame_ranges;
if(o.spaceGroupIsSet())
j["space_group"] = o.m_Space_group;
if(o.dMinIsSet())
@@ -408,6 +462,16 @@ void from_json(const nlohmann::json& j, Rugnux_live_status& o)
j.at("overall").get_to(o.m_Overall);
o.m_OverallIsSet = true;
}
if(j.find("frame_scales") != j.end())
{
j.at("frame_scales").get_to(o.m_Frame_scales);
o.m_Frame_scalesIsSet = true;
}
if(j.find("frame_ranges") != j.end())
{
j.at("frame_ranges").get_to(o.m_Frame_ranges);
o.m_Frame_rangesIsSet = true;
}
if(j.find("space_group") != j.end())
{
j.at("space_group").get_to(o.m_Space_group);
@@ -606,6 +670,40 @@ void Rugnux_live_status::unsetOverall()
{
m_OverallIsSet = false;
}
std::vector<float> Rugnux_live_status::getFrameScales() const
{
return m_Frame_scales;
}
void Rugnux_live_status::setFrameScales(std::vector<float> const value)
{
m_Frame_scales = value;
m_Frame_scalesIsSet = true;
}
bool Rugnux_live_status::frameScalesIsSet() const
{
return m_Frame_scalesIsSet;
}
void Rugnux_live_status::unsetFrame_scales()
{
m_Frame_scalesIsSet = false;
}
std::vector<org::openapitools::server::model::Rugnux_live_frame_range> Rugnux_live_status::getFrameRanges() const
{
return m_Frame_ranges;
}
void Rugnux_live_status::setFrameRanges(std::vector<org::openapitools::server::model::Rugnux_live_frame_range> const& value)
{
m_Frame_ranges = value;
m_Frame_rangesIsSet = true;
}
bool Rugnux_live_status::frameRangesIsSet() const
{
return m_Frame_rangesIsSet;
}
void Rugnux_live_status::unsetFrame_ranges()
{
m_Frame_rangesIsSet = false;
}
std::string Rugnux_live_status::getSpaceGroup() const
{
return m_Space_group;
+19
View File
@@ -25,6 +25,7 @@
#include <string>
#include "Rugnux_live_model.h"
#include "Rugnux_live_step.h"
#include "Rugnux_live_frame_range.h"
#include <vector>
#include "Rugnux_live_stills.h"
#include <nlohmann/json.hpp>
@@ -126,6 +127,20 @@ public:
bool overallIsSet() const;
void unsetOverall();
/// <summary>
/// Rotation, once the run is over: the per-image scale factor of the merge, one entry per image of the collection in its order, 0 where the image got none (not indexed, or rejected). Absent on serial data and until there is a merge.
/// </summary>
std::vector<float> getFrameScales() const;
void setFrameScales(std::vector<float> const value);
bool frameScalesIsSet() const;
void unsetFrame_scales();
/// <summary>
/// Rotation, once the run is over: the stretches of the sweep the merge downgraded or rejected, in order; every image outside them is merged at its own weight. Absent on serial data and until there is a merge; empty where the whole sweep was merged.
/// </summary>
std::vector<org::openapitools::server::model::Rugnux_live_frame_range> getFrameRanges() const;
void setFrameRanges(std::vector<org::openapitools::server::model::Rugnux_live_frame_range> const& value);
bool frameRangesIsSet() const;
void unsetFrame_ranges();
/// <summary>
/// Space group of the result (the summary&#39;s \&quot;Space group\&quot; row); absent until the run is over
/// </summary>
std::string getSpaceGroup() const;
@@ -283,6 +298,10 @@ protected:
bool m_ShellsIsSet;
org::openapitools::server::model::Rugnux_live_shell m_Overall;
bool m_OverallIsSet;
std::vector<float> m_Frame_scales;
bool m_Frame_scalesIsSet;
std::vector<org::openapitools::server::model::Rugnux_live_frame_range> m_Frame_ranges;
bool m_Frame_rangesIsSet;
std::string m_Space_group;
bool m_Space_groupIsSet;
double m_D_min;
+43
View File
@@ -3225,6 +3225,32 @@ components:
type: number
format: double
description: R-free of the placed model (as given, not refined) over the shell's free reflections
rugnux_live_frame_range:
type: object
description: |
A stretch of a rotation sweep the merge did not take at face value: downgraded (merged at the reduced
weight its own scale and sigmas give it) or rejected (nothing of it reached the merge), with the
reason the sweep-quality diagnostic saw - the lines of the report's SWEEP section.
required:
- first_image
- last_image
- disposition
- reason
properties:
first_image:
type: integer
format: int64
description: First image of the stretch, inclusive, numbered as the collection's images
last_image:
type: integer
format: int64
description: Last image of the stretch, inclusive
disposition:
type: string
enum: [downgraded, rejected]
reason:
type: string
description: What was seen over the stretch, e.g. "out of beam", "no diffraction", "radiation damage"
rugnux_live_status:
type: object
description: |
@@ -3289,6 +3315,23 @@ components:
$ref: '#/components/schemas/rugnux_live_shell'
overall:
$ref: '#/components/schemas/rugnux_live_shell'
frame_scales:
type: array
description: |
Rotation, once the run is over: the per-image scale factor of the merge, one entry per image of the
collection in its order, 0 where the image got none (not indexed, or rejected). Absent on serial
data and until there is a merge.
items:
type: number
format: float
frame_ranges:
type: array
description: |
Rotation, once the run is over: the stretches of the sweep the merge downgraded or rejected, in
order; every image outside them is merged at its own weight. Absent on serial data and until there
is a merge; empty where the whole sweep was merged.
items:
$ref: '#/components/schemas/rugnux_live_frame_range'
space_group:
type: string
description: Space group of the result (the summary's "Space group" row); absent until the run is over
+2 -2
View File
@@ -885,7 +885,7 @@ and validation of every following rugnux live collection, until it is removed wi
</div></div><div class="sc-jaXxmE eqYzvz"><div class="sc-iMTnTL fkPTul"><h5 class="sc-dAlyuH sc-hwdzOV jbQuod JjoyL">Authorizations:</h5><svg class="sc-cwHptR iZRiKW" 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></div><div class="sc-krNlru gkwgxc"><span class="sc-jMakVo bPNrjo"><span class="sc-ihgnxF jlNGfN"><i>bearerAuth</i></span></span></div></div><div><h3 class="sc-fMMURN egoxtT">Responses</h3><div><button class="sc-kzqdkY jgSwKD"><svg class="sc-cwHptR hWEnWx" 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-dSIIpw bpEYcE">200<!-- --> </strong><div class="sc-eeDRCY sc-eBMEME sc-dCFHLb gTGgei kekOtA kCaLQd"><p>Everything OK</p>
</div></button></div><div><button class="sc-kzqdkY bXzzUN"><svg class="sc-cwHptR cSkZlF" 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-dSIIpw bpEYcE">401<!-- --> </strong><div class="sc-eeDRCY sc-eBMEME sc-dCFHLb gTGgei kekOtA kCaLQd"><p>The current dataset is protected and no valid bearer token was presented.</p>
</div></button></div></div></div><div class="sc-iGgWBj sc-gsFSXq ibAZSi eDeKjd"><div class="sc-ejfMa-d bNUPQg"><button class="sc-EgOXT cFEcOl"><span type="get" class="sc-eZYNyq qGfV http-verb get">get</span><span class="sc-iEXKAA gUNSDu">/rugnux/status</span><svg class="sc-cwHptR iVFMLx" 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-dlWCHZ kWacYr"><div class="sc-hHOBiw cndTNO"><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Test Jungfraujoch system</p>
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/rugnux/status</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Response samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab_R_jiia_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_jiia_0" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_jiia_0" aria-labelledby="tab_R_jiia_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button><button> Expand all </button><button> Collapse all </button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><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">"state"</span>: <span class="token string">&quot;Idle&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"placed_model"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"refined_model"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"anomalous_map"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"anomalous_signal"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"model"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"placement"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"model_name"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"predicted"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"reason"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"r_work"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"r_free"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"cc_model"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"fit_sigma"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"map_atom_sigma"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"rigid_body_angle_deg"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"rigid_body_shift_A"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"mr_decision"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"mr_space_group"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"copies"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div>Line truncated
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/rugnux/status</div></div></div></div></div><div><h3 class="sc-kpDqfm eBBgSB"> <!-- -->Response samples<!-- --> </h3><div class="sc-bXCLTC dHowgL" data-rttabs="true"><ul class="react-tabs__tab-list" role="tablist"><li class="tab-success react-tabs__tab--selected" role="tab" id="tab_R_jiia_0" aria-selected="true" aria-disabled="false" aria-controls="panel_R_jiia_0" tabindex="0" data-rttab="true">200</li></ul><div class="react-tabs__tab-panel react-tabs__tab-panel--selected" role="tabpanel" id="panel_R_jiia_0" aria-labelledby="tab_R_jiia_0"><div><div class="sc-bbSZdi gCVTxk"><span class="sc-fjvvzt jWReSk">Content type</span><div class="sc-JrDLc iTKzPJ">application/json</div></div><div class="sc-uVWWZ gQROPU"><div class="sc-esYiGF dWQNJI"><div class="sc-koXPp efufqz"><button><div class="sc-fhzFiK kwZDms">Copy</div></button><button> Expand all </button><button> Collapse all </button></div><div tabindex="0" class="sc-eeDRCY gTGgei sc-fXSgeo bnrBiz"><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">"state"</span>: <span class="token string">&quot;Idle&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"placed_model"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"refined_model"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"anomalous_map"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"anomalous_signal"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable "><span class="property token string">"model"</span>: <button class="collapser" aria-label="collapse"></button><span class="token punctuation">{</span><span class="ellipsis"></span><ul class="obj collapsible"><li><div class="hoverable collapsed"><span class="property token string">"placement"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"model_name"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"predicted"</span>: <span class="token boolean">true</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"reason"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"r_work"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"r_free"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"cc_model"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"fit_sigma"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"map_atom_sigma"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"rigid_body_angle_deg"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"rigid_body_shift_A"</span>: <span class="token number">0.1</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"mr_decision"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"mr_space_group"</span>: <span class="token string">&quot;string&quot;</span><span class="token punctuation">,</span></div></li><li><div class="hoverable collapsed"><span class="property token string">"copies"</span>: <span class="token number">0</span><span class="token punctuation">,</span></div>Line truncated
<code>_model.cif</code> file written beside the data: the data&#39;s cell and space group, with the input model&#39;s own
metadata (entities, sequences, references, authors, software) kept. Kept as long as <code>/rugnux/status</code>.
Where the run refined the model, the refined model unless asked for <code>stage=placed</code>.</p>
@@ -1144,7 +1144,7 @@ then image might be replaced in the buffer between calling /images and /image.cb
</div></button></div></div></div><div class="sc-iGgWBj sc-gsFSXq ibAZSi eDeKjd"><div class="sc-ejfMa-d bNUPQg"><button class="sc-EgOXT cFEcOl"><span type="get" class="sc-eZYNyq qGfV http-verb get">get</span><span class="sc-iEXKAA gUNSDu">/version</span><svg class="sc-cwHptR iVFMLx" 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-dlWCHZ kWacYr"><div class="sc-hHOBiw cndTNO"><div class="sc-eeDRCY sc-eBMEME gTGgei fbXBig"><p>Test Jungfraujoch system</p>
</div><div tabindex="0" role="button"><div class="sc-kWtpeL gEncxT"><span>http://localhost:5232</span>/version</div></div></div></div></div></div></div></div></div><div class="sc-dExYaf gZbfaQ"></div></div></div>
<script>
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.3","info":{"title":"Jungfraujoch","description":"API to control Jungfraujoch developed by the Paul Scherrer Institute (Switzerland).\nJungfraujoch is a data acquisition and analysis system for pixel array detectors, primarly PSI JUNGFRAU.\nJungfraujoch uses FPGA boards to acquire data at high data rates.\n\n# License Clarification\n\nWhile this API definition is licensed under GPL-3.0, **the GPL copyleft provisions do not apply**\nwhen this file is used solely to generate OpenAPI clients or when implementing applications that\ninteract with the API. Generated client code and applications using this API definition are not\nsubject to the GPL license requirements and may be distributed under terms of your choosing.\n\nThis exception is similar in spirit to the Linux Kernel's approach to userspace API headers and\nthe GCC Runtime Library Exception. The Linux Kernel developers have explicitly stated that\nuser programs that merely use the kernel interfaces (syscalls, ioctl definitions, etc.) are not\nderivative works of the kernel and are not subject to the terms of the GPL.\n\nThis exception is intended to allow wider use of this API specification without imposing GPL\nrequirements on applications that merely interact with the API, regardless of whether they\ncommunicate through network calls or other mechanisms.\n","version":"1.0.0-rc.186","contact":{"name":"Filip Leonarski (Paul Scherrer Institute)","email":"filip.leonarski@psi.ch"},"license":{"name":"GPL-3.0","url":"https://www.gnu.org/licenses/gpl-3.0.html"}},"servers":[{"url":"http://localhost:5232","description":"Test Jungfraujoch system"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Per-dataset secret. `/start` may carry one or more equivalent `tokens`; while the current\ndataset has any, the operations marked with this scheme require `Authorization: Bearer <token>`\nand answer 401 otherwise. A dataset started without `tokens` is not protected and the header is ignored.\n"}},"parameters":{"binning":{"in":"query","name":"binning","required":false,"schema":{"default":1,"type":"integer"},"description":"Binning of frames for the plot (0 = default binning)"},"experimental_coord":{"in":"query","name":"experimental_coord","required":false,"schema":{"type":"boolean","default":false},"description":"If measurement has goniometer axis defined, plot X-axis will represent rotation angle\nIf measurement has grid scan defined, plot X-axis and Y-axis will represent grid position, Z will be used as the final value\nFor still measurement the number is ignored\n"},"azint_unit":{"in":"query","name":"azint_unit","required":false,"schema":{"type":"string","enum":["Q_recipA","d_A","two_theta_deg"],"default":"Q_recipA"},"description":"Unit used for azim int.\n"},"fill_value":{"in":"query","name":"fill","required":false,"schema":{"type":"number","format":"float"},"description":"Fill value for elements that were missed during data collection\n"},"plot_type":{"in":"query","name":"type","required":true,"description":"Type of requested plot","schema":{"type":"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"]}},"roi":{"in":"query","name":"roi","required":false,"schema":{"type":"string","minLength":1},"description":"Name of ROI for which plot is requested"},"image_id":{"in":"query","name":"id","required":false,"schema":{"type":"integer","format":"int64","default":-1,"minimum":-2},"description":"Image ID in the image buffer. Special values: -1 - last image in the buffer, -2: last indexed image in the buffer"},"saturation":{"in":"query","name":"saturation","required":false,"schema":{"type":"number","format":"float","minimum":-32767,"maximum":32767},"description":"Saturation value to set contrast in the preview image; if not provided, then autocontrast procedure is used"},"background":{"in":"query","name":"background","required":false,"schema":{"type":"number","format":"float","default":0,"minimum":-32767,"maximum":32767},"description":"Background value to set contrast in the preview image"},"show_spots":{"in":"query","name":"show_spots","schema":{"type":"boolean","default":true},"description":"Show spot finding results on the image"},"show_predictions":{"in":"query","name":"show_predictions","schema":Line truncated
const __redoc_state = {"menu":{"activeItemIdx":-1},"spec":{"data":{"openapi":"3.0.3","info":{"title":"Jungfraujoch","description":"API to control Jungfraujoch developed by the Paul Scherrer Institute (Switzerland).\nJungfraujoch is a data acquisition and analysis system for pixel array detectors, primarly PSI JUNGFRAU.\nJungfraujoch uses FPGA boards to acquire data at high data rates.\n\n# License Clarification\n\nWhile this API definition is licensed under GPL-3.0, **the GPL copyleft provisions do not apply**\nwhen this file is used solely to generate OpenAPI clients or when implementing applications that\ninteract with the API. Generated client code and applications using this API definition are not\nsubject to the GPL license requirements and may be distributed under terms of your choosing.\n\nThis exception is similar in spirit to the Linux Kernel's approach to userspace API headers and\nthe GCC Runtime Library Exception. The Linux Kernel developers have explicitly stated that\nuser programs that merely use the kernel interfaces (syscalls, ioctl definitions, etc.) are not\nderivative works of the kernel and are not subject to the terms of the GPL.\n\nThis exception is intended to allow wider use of this API specification without imposing GPL\nrequirements on applications that merely interact with the API, regardless of whether they\ncommunicate through network calls or other mechanisms.\n","version":"1.0.0-rc.186","contact":{"name":"Filip Leonarski (Paul Scherrer Institute)","email":"filip.leonarski@psi.ch"},"license":{"name":"GPL-3.0","url":"https://www.gnu.org/licenses/gpl-3.0.html"}},"servers":[{"url":"http://localhost:5232","description":"Test Jungfraujoch system"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Per-dataset secret. `/start` may carry one or more equivalent `tokens`; while the current\ndataset has any, the operations marked with this scheme require `Authorization: Bearer <token>`\nand answer 401 otherwise. A dataset started without `tokens` is not protected and the header is ignored.\n"}},"parameters":{"binning":{"in":"query","name":"binning","required":false,"schema":{"default":1,"type":"integer"},"description":"Binning of frames for the plot (0 = default binning)"},"experimental_coord":{"in":"query","name":"experimental_coord","required":false,"schema":{"type":"boolean","default":false},"description":"If measurement has goniometer axis defined, plot X-axis will represent rotation angle\nIf measurement has grid scan defined, plot X-axis and Y-axis will represent grid position, Z will be used as the final value\nFor still measurement the number is ignored\n"},"azint_unit":{"in":"query","name":"azint_unit","required":false,"schema":{"type":"string","enum":["Q_recipA","d_A","two_theta_deg"],"default":"Q_recipA"},"description":"Unit used for azim int.\n"},"fill_value":{"in":"query","name":"fill","required":false,"schema":{"type":"number","format":"float"},"description":"Fill value for elements that were missed during data collection\n"},"plot_type":{"in":"query","name":"type","required":true,"description":"Type of requested plot","schema":{"type":"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"]}},"roi":{"in":"query","name":"roi","required":false,"schema":{"type":"string","minLength":1},"description":"Name of ROI for which plot is requested"},"image_id":{"in":"query","name":"id","required":false,"schema":{"type":"integer","format":"int64","default":-1,"minimum":-2},"description":"Image ID in the image buffer. Special values: -1 - last image in the buffer, -2: last indexed image in the buffer"},"saturation":{"in":"query","name":"saturation","required":false,"schema":{"type":"number","format":"float","minimum":-32767,"maximum":32767},"description":"Saturation value to set contrast in the preview image; if not provided, then autocontrast procedure is used"},"background":{"in":"query","name":"background","required":false,"schema":{"type":"number","format":"float","default":0,"minimum":-32767,"maximum":32767},"description":"Background value to set contrast in the preview image"},"show_spots":{"in":"query","name":"show_spots","schema":{"type":"boolean","default":true},"description":"Show spot finding results on the image"},"show_predictions":{"in":"query","name":"show_predictions","schema":Line truncated
var container = document.getElementById('redoc');
Redoc.hydrate(__redoc_state, container);
+5 -2
View File
@@ -297,8 +297,11 @@ table of `<file_prefix>_report.txt`, on the same shells: multiplicity, ⟨I/σ
(rotation), R_split (serial), CCref (with reference data) and the R-free of the placed model as given (with a
model), each absent where the run does not measure it - and `shells_merge` the merge they are of. A rotation
run fills them when it is over; a serial one at each provisional merge and at the end, the R-free once the model
step on that same merge has its result. The web frontend shows it on the dashboard and in its "Rugnux live" tab,
which plots the shells against resolution, changes the settings and uploads the model. It, `/rugnux/model.cif` and `/rugnux/map.ccp4` need the dataset's bearer token
step on that same merge has its result. A rotation run also leaves `frame_scales`, the per-image scale factor of
the merge, and `frame_ranges`, the stretches of the sweep the merge downgraded or rejected (the report's SWEEP
section) with the reason it saw there - which frames rugnux left out, and why. The web frontend shows it on the
dashboard and in its "Rugnux live" tab, which plots the shells against resolution and the collection image by
image, changes the settings and uploads the model. It, `/rugnux/model.cif` and `/rugnux/map.ccp4` need the dataset's bearer token
like the dataset routes (`/statistics/data_collection`, `/image_buffer/*`, `/preview/plot*`). `GET /result/scan` carries the rotation lattice, unit cell and Bravais symbol
rugnux found. A collection in which rugnux finds no lattice still gets the spot count, resolution
estimate and background of every image in `GET /result/scan` and the master file, marked as not indexed.
@@ -0,0 +1,33 @@
# RugnuxLiveFrameRange
A stretch of a rotation sweep the merge did not take at face value: downgraded (merged at the reduced weight its own scale and sigmas give it) or rejected (nothing of it reached the merge), with the reason the sweep-quality diagnostic saw - the lines of the report's SWEEP section.
## Properties
Name | Type | Description | Notes
------------ | ------------- | ------------- | -------------
**first_image** | **int** | First image of the stretch, inclusive, numbered as the collection&#39;s images |
**last_image** | **int** | Last image of the stretch, inclusive |
**disposition** | **str** | |
**reason** | **str** | What was seen over the stretch, e.g. \&quot;out of beam\&quot;, \&quot;no diffraction\&quot;, \&quot;radiation damage\&quot; |
## Example
```python
from jfjoch_client.models.rugnux_live_frame_range import RugnuxLiveFrameRange
# TODO update the JSON string below
json = "{}"
# create an instance of RugnuxLiveFrameRange from a JSON string
rugnux_live_frame_range_instance = RugnuxLiveFrameRange.from_json(json)
# print the JSON string representation of the object
print(RugnuxLiveFrameRange.to_json())
# convert the object into a dict
rugnux_live_frame_range_dict = rugnux_live_frame_range_instance.to_dict()
# create an instance of RugnuxLiveFrameRange from a dict
rugnux_live_frame_range_from_dict = RugnuxLiveFrameRange.from_dict(rugnux_live_frame_range_dict)
```
[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md)
@@ -16,6 +16,8 @@ Name | Type | Description | Notes
**shells_merge** | **str** | Which merge &#x60;shells&#x60; are of - \&quot;the collection\&quot;, or on serial data a provisional merge such as \&quot;50% of the images (provisional)\&quot;; absent until there is a merge | [optional]
**shells** | [**List[RugnuxLiveShell]**](RugnuxLiveShell.md) | Merging statistics by resolution shell of the latest merge, coarse to fine, as the shell table of &#x60;_report.txt&#x60;. Rotation: once the run is over; serial: at each provisional merge and at the end. &#x60;overall&#x60; is the same table&#39;s \&quot;Overall\&quot; row (whole-merge completeness, multiplicity, I/sigma, CC1/2, R_meas or R_split, CCref, and the overall R-free of the model validated on it), present with &#x60;shells&#x60;. | [optional]
**overall** | [**RugnuxLiveShell**](RugnuxLiveShell.md) | | [optional]
**frame_scales** | **List[float]** | Rotation, once the run is over: the per-image scale factor of the merge, one entry per image of the collection in its order, 0 where the image got none (not indexed, or rejected). Absent on serial data and until there is a merge. | [optional]
**frame_ranges** | [**List[RugnuxLiveFrameRange]**](RugnuxLiveFrameRange.md) | Rotation, once the run is over: the stretches of the sweep the merge downgraded or rejected, in order; every image outside them is merged at its own weight. Absent on serial data and until there is a merge; empty where the whole sweep was merged. | [optional]
**space_group** | **str** | Space group of the result (the summary&#39;s \&quot;Space group\&quot; row); absent until the run is over | [optional]
**d_min** | **float** | High-resolution limit of the merge, in Angstrom; absent until the run is over, or without a merge | [optional]
**isa** | **float** | ISa of the error model; absent until the run is over, or where it was not determined | [optional]
+1 -1
View File
@@ -1,4 +1,4 @@
// This file is auto-generated by @hey-api/openapi-ts
export { deleteConfigRugnuxModel, getConfigAzimInt, getConfigBraggIntegration, getConfigDarkMask, getConfigDetector, getConfigFileWriter, getConfigImageFormat, getConfigIndexing, getConfigInstrument, getConfigMask, getConfigMaskTiff, getConfigRoi, getConfigRugnux, getConfigSelectDetector, getConfigSpotFinding, getConfigUserMask, getConfigUserMaskTiff, getConfigZeromqMetadata, getConfigZeromqPreview, getDetectorStatus, getFpgaStatus, getImageBufferImageCbor, getImageBufferImageJpeg, getImageBufferImageTiff, getImageBufferStartCbor, getImageBufferStatus, getImagePusherStatus, getLiveEvents, getPreviewPedestalTiff, getPreviewPlot, getPreviewPlotBin, getResultScan, getRugnuxMapCcp4, getRugnuxModelCif, getRugnuxStatus, getStatistics, getStatisticsCalibration, getStatisticsDataCollection, getStatus, getVersion, getXfelEventCode, getXfelPulseId, type Options, postCancel, postConfigImageFormatConversion, postConfigImageFormatRaw, postDeactivate, postImageBufferClear, postInitialize, postPedestal, postStart, postTrigger, postWaitTillDone, postWaitUntilRunning, putConfigAzimInt, putConfigBraggIntegration, putConfigDarkMask, putConfigDetector, putConfigFileWriter, putConfigImageFormat, putConfigIndexing, putConfigInstrument, putConfigInternalGeneratorImage, putConfigInternalGeneratorImageTiff, putConfigRoi, putConfigRugnux, putConfigRugnuxModel, putConfigSelectDetector, putConfigSpotFinding, putConfigUserMask, putConfigUserMaskTiff, putConfigZeromqMetadata, putConfigZeromqPreview } from './sdk.gen';
export { type azim_int_settings, azint_unit, type background, type binning, type bragg_integration_settings, type broker_status, type calibration_statistics, type ClientOptions, color_scale, type crystal_lattice, type dark_mask_settings, type dataset_settings, type dataset_settingsWritable, type deleteConfigRugnuxModelData, type deleteConfigRugnuxModelError, type deleteConfigRugnuxModelErrors, type deleteConfigRugnuxModelResponses, type detector, type detector_list, type detector_list_element, type detector_module, detector_module_direction, type detector_module_placement, detector_power_state, type detector_selection, type detector_settings, detector_state, type detector_status, detector_timing, detector_type, type error_message, type experimental_coord, file_writer_format, type file_writer_settings, type fill_value, type fpga_status, geom_refinement_algorithm, type getConfigAzimIntData, type getConfigAzimIntResponse, type getConfigAzimIntResponses, type getConfigBraggIntegrationData, type getConfigBraggIntegrationResponse, type getConfigBraggIntegrationResponses, type getConfigDarkMaskData, type getConfigDarkMaskResponse, type getConfigDarkMaskResponses, type getConfigDetectorData, type getConfigDetectorResponse, type getConfigDetectorResponses, type getConfigFileWriterData, type getConfigFileWriterResponse, type getConfigFileWriterResponses, type getConfigImageFormatData, type getConfigImageFormatResponse, type getConfigImageFormatResponses, type getConfigIndexingData, type getConfigIndexingResponse, type getConfigIndexingResponses, type getConfigInstrumentData, type getConfigInstrumentResponse, type getConfigInstrumentResponses, type getConfigMaskData, type getConfigMaskResponse, type getConfigMaskResponses, type getConfigMaskTiffData, type getConfigMaskTiffResponse, type getConfigMaskTiffResponses, type getConfigRoiData, type getConfigRoiResponse, type getConfigRoiResponses, type getConfigRugnuxData, type getConfigRugnuxResponse, type getConfigRugnuxResponses, type getConfigSelectDetectorData, type getConfigSelectDetectorResponse, type getConfigSelectDetectorResponses, type getConfigSpotFindingData, type getConfigSpotFindingResponse, type getConfigSpotFindingResponses, type getConfigUserMaskData, type getConfigUserMaskResponse, type getConfigUserMaskResponses, type getConfigUserMaskTiffData, type getConfigUserMaskTiffResponse, type getConfigUserMaskTiffResponses, type getConfigZeromqMetadataData, type getConfigZeromqMetadataResponse, type getConfigZeromqMetadataResponses, type getConfigZeromqPreviewData, type getConfigZeromqPreviewResponse, type getConfigZeromqPreviewResponses, type getDetectorStatusData, type getDetectorStatusError, type getDetectorStatusErrors, type getDetectorStatusResponse, type getDetectorStatusResponses, type getFpgaStatusData, type getFpgaStatusResponse, type getFpgaStatusResponses, type getImageBufferImageCborData, type getImageBufferImageCborError, type getImageBufferImageCborErrors, type getImageBufferImageCborResponse, type getImageBufferImageCborResponses, type getImageBufferImageJpegData, type getImageBufferImageJpegError, type getImageBufferImageJpegErrors, type getImageBufferImageJpegResponse, type getImageBufferImageJpegResponses, type getImageBufferImageTiffData, type getImageBufferImageTiffError, type getImageBufferImageTiffErrors, type getImageBufferImageTiffResponse, type getImageBufferImageTiffResponses, type getImageBufferStartCborData, type getImageBufferStartCborError, type getImageBufferStartCborErrors, type getImageBufferStartCborResponse, type getImageBufferStartCborResponses, type getImageBufferStatusData, type getImageBufferStatusError, type getImageBufferStatusErrors, type getImageBufferStatusResponse, type getImageBufferStatusResponses, type getImagePusherStatusData, type getImagePusherStatusError, type getImagePusherStatusErrors, type getImagePusherStatusResponse, type getImagePusherStatusResponses, type getLiveEventsData, type getLiveEventsError, type getLiveEventsErrors, type getLiveEventsResponse, type getLiveEventsResponses, type getPreviewPedestalTiffData, type getPreviewPedestalTiffErrors, type getPreviewPedestalTiffResponse, type getPreviewPedestalTiffResponses, type getPreviewPlotBinData, type getPreviewPlotBinError, type getPreviewPlotBinErrors, type getPreviewPlotBinResponse, type getPreviewPlotBinResponses, type getPreviewPlotData, type getPreviewPlotError, type getPreviewPlotErrors, type getPreviewPlotResponse, type getPreviewPlotResponses, type getResultScanData, type getResultScanError, type getResultScanErrors, type getResultScanResponse, type getResultScanResponses, type getRugnuxMapCcp4Data, type getRugnuxMapCcp4Error, type getRugnuxMapCcp4Errors, type getRugnuxMapCcp4Response, type getRugnuxMapCcp4Responses, type getRugnuxModelCifData, type getRugnuxModelCifError, type getRugnuxModelCifErrors, type getRugnuxModelCifResponse, type getRugnuxModelCifResponses, type getRugnuxStatusData, type getRugnuxStatusError, type getRugnuxStatusErrorsLine truncated
export { type azim_int_settings, azint_unit, type background, type binning, type bragg_integration_settings, type broker_status, type calibration_statistics, type ClientOptions, color_scale, type crystal_lattice, type dark_mask_settings, type dataset_settings, type dataset_settingsWritable, type deleteConfigRugnuxModelData, type deleteConfigRugnuxModelError, type deleteConfigRugnuxModelErrors, type deleteConfigRugnuxModelResponses, type detector, type detector_list, type detector_list_element, type detector_module, detector_module_direction, type detector_module_placement, detector_power_state, type detector_selection, type detector_settings, detector_state, type detector_status, detector_timing, detector_type, type error_message, type experimental_coord, file_writer_format, type file_writer_settings, type fill_value, type fpga_status, geom_refinement_algorithm, type getConfigAzimIntData, type getConfigAzimIntResponse, type getConfigAzimIntResponses, type getConfigBraggIntegrationData, type getConfigBraggIntegrationResponse, type getConfigBraggIntegrationResponses, type getConfigDarkMaskData, type getConfigDarkMaskResponse, type getConfigDarkMaskResponses, type getConfigDetectorData, type getConfigDetectorResponse, type getConfigDetectorResponses, type getConfigFileWriterData, type getConfigFileWriterResponse, type getConfigFileWriterResponses, type getConfigImageFormatData, type getConfigImageFormatResponse, type getConfigImageFormatResponses, type getConfigIndexingData, type getConfigIndexingResponse, type getConfigIndexingResponses, type getConfigInstrumentData, type getConfigInstrumentResponse, type getConfigInstrumentResponses, type getConfigMaskData, type getConfigMaskResponse, type getConfigMaskResponses, type getConfigMaskTiffData, type getConfigMaskTiffResponse, type getConfigMaskTiffResponses, type getConfigRoiData, type getConfigRoiResponse, type getConfigRoiResponses, type getConfigRugnuxData, type getConfigRugnuxResponse, type getConfigRugnuxResponses, type getConfigSelectDetectorData, type getConfigSelectDetectorResponse, type getConfigSelectDetectorResponses, type getConfigSpotFindingData, type getConfigSpotFindingResponse, type getConfigSpotFindingResponses, type getConfigUserMaskData, type getConfigUserMaskResponse, type getConfigUserMaskResponses, type getConfigUserMaskTiffData, type getConfigUserMaskTiffResponse, type getConfigUserMaskTiffResponses, type getConfigZeromqMetadataData, type getConfigZeromqMetadataResponse, type getConfigZeromqMetadataResponses, type getConfigZeromqPreviewData, type getConfigZeromqPreviewResponse, type getConfigZeromqPreviewResponses, type getDetectorStatusData, type getDetectorStatusError, type getDetectorStatusErrors, type getDetectorStatusResponse, type getDetectorStatusResponses, type getFpgaStatusData, type getFpgaStatusResponse, type getFpgaStatusResponses, type getImageBufferImageCborData, type getImageBufferImageCborError, type getImageBufferImageCborErrors, type getImageBufferImageCborResponse, type getImageBufferImageCborResponses, type getImageBufferImageJpegData, type getImageBufferImageJpegError, type getImageBufferImageJpegErrors, type getImageBufferImageJpegResponse, type getImageBufferImageJpegResponses, type getImageBufferImageTiffData, type getImageBufferImageTiffError, type getImageBufferImageTiffErrors, type getImageBufferImageTiffResponse, type getImageBufferImageTiffResponses, type getImageBufferStartCborData, type getImageBufferStartCborError, type getImageBufferStartCborErrors, type getImageBufferStartCborResponse, type getImageBufferStartCborResponses, type getImageBufferStatusData, type getImageBufferStatusError, type getImageBufferStatusErrors, type getImageBufferStatusResponse, type getImageBufferStatusResponses, type getImagePusherStatusData, type getImagePusherStatusError, type getImagePusherStatusErrors, type getImagePusherStatusResponse, type getImagePusherStatusResponses, type getLiveEventsData, type getLiveEventsError, type getLiveEventsErrors, type getLiveEventsResponse, type getLiveEventsResponses, type getPreviewPedestalTiffData, type getPreviewPedestalTiffErrors, type getPreviewPedestalTiffResponse, type getPreviewPedestalTiffResponses, type getPreviewPlotBinData, type getPreviewPlotBinError, type getPreviewPlotBinErrors, type getPreviewPlotBinResponse, type getPreviewPlotBinResponses, type getPreviewPlotData, type getPreviewPlotError, type getPreviewPlotErrors, type getPreviewPlotResponse, type getPreviewPlotResponses, type getResultScanData, type getResultScanError, type getResultScanErrors, type getResultScanResponse, type getResultScanResponses, type getRugnuxMapCcp4Data, type getRugnuxMapCcp4Error, type getRugnuxMapCcp4Errors, type getRugnuxMapCcp4Response, type getRugnuxMapCcp4Responses, type getRugnuxModelCifData, type getRugnuxModelCifError, type getRugnuxModelCifErrors, type getRugnuxModelCifResponse, type getRugnuxModelCifResponses, type getRugnuxStatusData, type getRugnuxStatusError, type getRugnuxStatusErrorsLine truncated
+36
View File
@@ -2361,6 +2361,28 @@ export type rugnux_live_shell = {
r_free?: number;
};
/**
* A stretch of a rotation sweep the merge did not take at face value: downgraded (merged at the reduced
* weight its own scale and sigmas give it) or rejected (nothing of it reached the merge), with the
* reason the sweep-quality diagnostic saw - the lines of the report's SWEEP section.
*
*/
export type rugnux_live_frame_range = {
/**
* First image of the stretch, inclusive, numbered as the collection's images
*/
first_image: number;
/**
* Last image of the stretch, inclusive
*/
last_image: number;
disposition: 'downgraded' | 'rejected';
/**
* What was seen over the stretch, e.g. "out of beam", "no diffraction", "radiation damage"
*/
reason: string;
};
/**
* Live rugnux processing of the last collection; kept until the next collection starts or `POST /initialize`.
* Times are taken when the image puller received a message, and are in seconds since the first image
@@ -2408,6 +2430,20 @@ export type rugnux_live_status = {
*/
shells?: Array<rugnux_live_shell>;
overall?: rugnux_live_shell;
/**
* Rotation, once the run is over: the per-image scale factor of the merge, one entry per image of the
* collection in its order, 0 where the image got none (not indexed, or rejected). Absent on serial
* data and until there is a merge.
*
*/
frame_scales?: Array<number>;
/**
* Rotation, once the run is over: the stretches of the sweep the merge downgraded or rejected, in
* order; every image outside them is merged at its own weight. Absent on serial data and until there
* is a merge; empty where the whole sweep was merged.
*
*/
frame_ranges?: Array<rugnux_live_frame_range>;
/**
* Space group of the result (the summary's "Space group" row); absent until the run is over
*/
+15
View File
@@ -1020,6 +1020,19 @@ export const zRugnuxLiveShell = z.object({
r_free: z.number().optional()
});
/**
* A stretch of a rotation sweep the merge did not take at face value: downgraded (merged at the reduced
* weight its own scale and sigmas give it) or rejected (nothing of it reached the merge), with the
* reason the sweep-quality diagnostic saw - the lines of the report's SWEEP section.
*
*/
export const zRugnuxLiveFrameRange = z.object({
first_image: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }),
last_image: z.coerce.bigint().min(BigInt('-9223372036854775808'), { error: 'Invalid value: Expected int64 to be >= -9223372036854775808' }).max(BigInt('9223372036854775807'), { error: 'Invalid value: Expected int64 to be <= 9223372036854775807' }),
disposition: z.enum(['downgraded', 'rejected']),
reason: z.string()
});
/**
* Live rugnux processing of the last collection; kept until the next collection starts or `POST /initialize`.
* Times are taken when the image puller received a message, and are in seconds since the first image
@@ -1044,6 +1057,8 @@ export const zRugnuxLiveStatus = z.object({
shells_merge: z.string().optional(),
shells: z.array(zRugnuxLiveShell).optional(),
overall: zRugnuxLiveShell.optional(),
frame_scales: z.array(z.number()).optional(),
frame_ranges: z.array(zRugnuxLiveFrameRange).optional(),
space_group: z.string().optional(),
d_min: z.number().optional(),
isa: z.number().optional(),
@@ -304,6 +304,7 @@ void JFJochReceiverRugnuxRotation::RugnuxThread() {
const ModelValidationResult *validation = result.model_validation ? &*result.model_validation : nullptr;
live_status.Shells("the collection", LiveShells(result.merge_statistics, validation),
LiveOverall(result.merge_statistics, validation));
live_status.Frames(result.end_message.image_scale_factor, LiveFrameRanges(result.merge_statistics.sweep_quality));
}
// For the broker's viewer routes; a copy of the map coefficients, as the end message takes the originals
if (result.outputs && result.outputs->placed_model) {
+28
View File
@@ -198,6 +198,12 @@ void RugnuxLiveStatus::ShellRFree(const std::string &merge, const ModelValidatio
AddShellRFree(snapshot.shells, snapshot.overall, validation);
}
void RugnuxLiveStatus::Frames(const std::vector<float> &scales, const std::vector<RugnuxLiveFrameRange> &ranges) {
std::unique_lock ul(status_mutex);
snapshot.frame_scales = scales;
snapshot.frame_ranges = ranges;
}
void RugnuxLiveStatus::Latency(double last_image_to_written_s) {
std::unique_lock ul(status_mutex);
snapshot.last_image_to_written_s = last_image_to_written_s;
@@ -357,3 +363,25 @@ std::optional<RugnuxLiveModel> LiveModel(const ProcessResult &result) {
}
return m;
}
std::vector<RugnuxLiveFrameRange> LiveFrameRanges(const SweepQuality &sweep) {
std::vector<RugnuxLiveFrameRange> ret;
const auto &d = sweep.frame_disposition;
for (size_t i = 0; i < d.size();) {
size_t j = i + 1;
while (j < d.size() && d[j] == d[i])
j++;
if (d[i] != static_cast<uint8_t>(FrameDisposition::Merged)) {
RugnuxLiveFrameRange r{.first_image = static_cast<int64_t>(i), .last_image = static_cast<int64_t>(j - 1),
.disposition = FrameDispositionCode(static_cast<FrameDisposition>(d[i]))};
for (const auto &range: sweep.ranges)
if (range.first_image <= r.last_image && range.last_image >= r.first_image) {
r.reason = SweepQualityReasonText(range.reason);
break;
}
ret.push_back(r);
}
i = j;
}
return ret;
}
+17
View File
@@ -15,6 +15,7 @@ class RugnuxStructure; // RugnuxStructure.h
struct ProcessResult; // rugnux/Rugnux.h
struct ReportDocument; // rugnux/ReportDocument.h
struct MergeStatistics; // image_analysis/scale_merge/Merge.h
struct SweepQuality; // image_analysis/scale_merge/Merge.h
struct ModelValidationResult; // image_analysis/structure_refinement/ModelValidation.h
// Where the live rugnux run of the last collection is.
@@ -106,6 +107,13 @@ struct RugnuxLiveShell {
std::optional<double> r_free; // of the placed model, where a model was given
};
// A stretch of a rotation sweep the merge downgraded or rejected (SweepQuality), with what was seen there
struct RugnuxLiveFrameRange {
int64_t first_image = 0, last_image = 0; // inclusive, numbered as the collection's images
std::string disposition; // "downgraded" | "rejected" (FrameDispositionCode)
std::string reason; // SweepQualityReasonText of the range it lies in
};
// Serial frames analysed on the GPU after a pre-pass (StillsGPUAnalysis)
enum class RugnuxLivePrePass { Holding, Running, Done, Failed };
@@ -161,6 +169,10 @@ struct RugnuxLiveSnapshot {
std::string shells_merge; // which merge, e.g. "the collection" or "50% of the images"
std::vector<RugnuxLiveShell> shells;
std::optional<RugnuxLiveShell> overall; // the same merge's overall row
// Rotation, with the merge: the per-image scale factor (NaN where an image got none) and the stretches
// the merge downgraded or rejected
std::vector<float> frame_scales;
std::vector<RugnuxLiveFrameRange> frame_ranges;
};
class RugnuxLiveStatus {
@@ -201,6 +213,7 @@ public:
const std::optional<RugnuxLiveShell> &overall);
// The R-free by shell of a model placed on a merge, if that merge's table is the one shown
void ShellRFree(const std::string &merge, const ModelValidationResult &validation);
void Frames(const std::vector<float> &scales, const std::vector<RugnuxLiveFrameRange> &ranges);
// Back to Idle with nothing of the last run, as before any collection.
void Clear();
RugnuxLiveSnapshot Get() const;
@@ -218,3 +231,7 @@ std::vector<RugnuxLiveShell> LiveShells(const MergeStatistics &statistics,
// The overall row of the same table, with the overall R-free of the model validated on it
RugnuxLiveShell LiveOverall(const MergeStatistics &statistics, const ModelValidationResult *validation = nullptr);
// The stretches of the sweep that were not merged at face value: the runs of one disposition in the
// per-image array of the sweep-quality diagnostic, each with the reason of the range it lies in
std::vector<RugnuxLiveFrameRange> LiveFrameRanges(const SweepQuality &sweep);
+34
View File
@@ -154,3 +154,37 @@ TEST_CASE("RugnuxLiveTriage_OpenAPI", "[RugnuxLive]") {
CHECK(items[2].getSeverity() == "serious");
CHECK(items[3].getSeverity() == "not_measured");
}
TEST_CASE("RugnuxLiveFrames_OpenAPI", "[RugnuxLive]") {
using D = FrameDisposition;
const auto d = [](D x) { return static_cast<uint8_t>(x); };
SweepQuality sweep;
sweep.frame_disposition = {d(D::Merged), d(D::Merged), d(D::Downgraded), d(D::Downgraded), d(D::Rejected),
d(D::Rejected), d(D::Rejected), d(D::Merged), d(D::Merged), d(D::Rejected)};
sweep.ranges = {{.first_image = 2, .last_image = 6, .reason = SweepQualityReason::CrystalOutOfBeam},
{.first_image = 9, .last_image = 9, .reason = SweepQualityReason::RadiationDamage}};
const auto ranges = LiveFrameRanges(sweep);
REQUIRE(ranges.size() == 3);
CHECK(ranges[0].first_image == 2);
CHECK(ranges[0].last_image == 3);
CHECK(ranges[0].disposition == "downgraded");
CHECK(ranges[0].reason == SweepQualityReasonText(SweepQualityReason::CrystalOutOfBeam));
CHECK(ranges[1].first_image == 4);
CHECK(ranges[1].last_image == 6);
CHECK(ranges[1].disposition == "rejected");
CHECK(ranges[2].first_image == 9);
CHECK(ranges[2].reason == SweepQualityReasonText(SweepQualityReason::RadiationDamage));
CHECK(LiveFrameRanges(SweepQuality{}).empty());
RugnuxLiveStatus status;
status.Start(10, std::nullopt, std::chrono::steady_clock::now());
CHECK(!Convert(status.Get()).frameScalesIsSet());
status.Frames({1.0f, NAN, 0.5f}, ranges);
const auto api = Convert(status.Get());
REQUIRE(api.frameScalesIsSet());
CHECK(api.getFrameScales() == std::vector<float>{1.0f, 0.0f, 0.5f});
REQUIRE(api.getFrameRanges().size() == 3);
CHECK(api.getFrameRanges()[1].getFirstImage() == 4);
CHECK(api.getFrameRanges()[1].getDisposition() == "rejected");
CHECK(api.getFrameRanges()[0].getReason() == ranges[0].reason);
}