api: define the powder calibration result as calibration_output

The JSON a calibration writes was a shape invented at its writer, described
only by the comments around it. That is enough for a file somebody reads with
jq and not enough for anything else: a client cannot type it, and an endpoint
returning it later would have to declare the shape a second time and keep the
two in step by hand.

So declare it where every other shape in this system is declared.
calibration_output holds dataset_settings and a calibration member; the latter
is calibration_quality, which nests calibration_fit_sigma and
calibration_spot_check. The descriptions carry what a reader has to know to use
the numbers rather than only what they are named - that beam_x_pxl is the PONI
and the direct beam is elsewhere, that the rotations travel together because a
body omitting them states a flat detector, that a tilt below about three sigma
was declined and pinned, and that the two correlations approach 1 as the tilt
stops being separable from the beam centre.

Nothing references it yet. It is declared now because /powder_calibration will
return exactly this, and because the file rugnux already writes is decodable
today: jfjoch_client's CalibrationOutput.from_dict reads it as it stands, with
o.calibration.fit_sigma.correlation_beam_x_rot1 and the rest typed.

Generated clients regenerated from the spec, as the spec requires: the C++
server model (four new pairs under broker/gen/model), the TypeScript frontend
client, and broker/redoc-static.html. Both regenerations are purely additive -
no existing generated file changed except to export the new names. The python
client regenerates from the same spec and is gitignored.

The test now validates the WHOLE file against the generated Calibration_output
rather than only its geometry member against Dataset_settings, so the quality
block is under the same contract: a field renamed or newly required in
jfjoch_api.yaml fails here rather than at a client.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NfuDvf5ipV3Hi8TiCUKD27
This commit is contained in:
2026-08-31 18:54:09 +02:00
co-authored by Claude Opus 5
parent 8691bf4876
commit 6fe3f30ab4
14 changed files with 2014 additions and 2 deletions
+280
View File
@@ -0,0 +1,280 @@
/**
* 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.166
* 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 "Calibration_fit_sigma.h"
#include "Helpers.h"
#include <sstream>
namespace org::openapitools::server::model
{
Calibration_fit_sigma::Calibration_fit_sigma()
{
m_Beam_x_pxl = 0.0f;
m_Beam_x_pxlIsSet = false;
m_Beam_y_pxl = 0.0f;
m_Beam_y_pxlIsSet = false;
m_Detector_distance_mm = 0.0f;
m_Detector_distance_mmIsSet = false;
m_Poni_rot1_rad = 0.0f;
m_Poni_rot1_radIsSet = false;
m_Poni_rot2_rad = 0.0f;
m_Poni_rot2_radIsSet = false;
m_Correlation_beam_x_rot1 = 0.0f;
m_Correlation_beam_x_rot1IsSet = false;
m_Correlation_beam_y_rot2 = 0.0f;
m_Correlation_beam_y_rot2IsSet = false;
}
void Calibration_fit_sigma::validate() const
{
std::stringstream msg;
if (!validate(msg))
{
throw org::openapitools::server::helpers::ValidationException(msg.str());
}
}
bool Calibration_fit_sigma::validate(std::stringstream& msg) const
{
return validate(msg, "");
}
bool Calibration_fit_sigma::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Calibration_fit_sigma" : pathPrefix;
return success;
}
bool Calibration_fit_sigma::operator==(const Calibration_fit_sigma& rhs) const
{
return
((!beamXPxlIsSet() && !rhs.beamXPxlIsSet()) || (beamXPxlIsSet() && rhs.beamXPxlIsSet() && getBeamXPxl() == rhs.getBeamXPxl())) &&
((!beamYPxlIsSet() && !rhs.beamYPxlIsSet()) || (beamYPxlIsSet() && rhs.beamYPxlIsSet() && getBeamYPxl() == rhs.getBeamYPxl())) &&
((!detectorDistanceMmIsSet() && !rhs.detectorDistanceMmIsSet()) || (detectorDistanceMmIsSet() && rhs.detectorDistanceMmIsSet() && getDetectorDistanceMm() == rhs.getDetectorDistanceMm())) &&
((!poniRot1RadIsSet() && !rhs.poniRot1RadIsSet()) || (poniRot1RadIsSet() && rhs.poniRot1RadIsSet() && getPoniRot1Rad() == rhs.getPoniRot1Rad())) &&
((!poniRot2RadIsSet() && !rhs.poniRot2RadIsSet()) || (poniRot2RadIsSet() && rhs.poniRot2RadIsSet() && getPoniRot2Rad() == rhs.getPoniRot2Rad())) &&
((!correlationBeamXRot1IsSet() && !rhs.correlationBeamXRot1IsSet()) || (correlationBeamXRot1IsSet() && rhs.correlationBeamXRot1IsSet() && getCorrelationBeamXRot1() == rhs.getCorrelationBeamXRot1())) &&
((!correlationBeamYRot2IsSet() && !rhs.correlationBeamYRot2IsSet()) || (correlationBeamYRot2IsSet() && rhs.correlationBeamYRot2IsSet() && getCorrelationBeamYRot2() == rhs.getCorrelationBeamYRot2()))
;
}
bool Calibration_fit_sigma::operator!=(const Calibration_fit_sigma& rhs) const
{
return !(*this == rhs);
}
void to_json(nlohmann::json& j, const Calibration_fit_sigma& o)
{
j = nlohmann::json::object();
if(o.beamXPxlIsSet())
j["beam_x_pxl"] = o.m_Beam_x_pxl;
if(o.beamYPxlIsSet())
j["beam_y_pxl"] = o.m_Beam_y_pxl;
if(o.detectorDistanceMmIsSet())
j["detector_distance_mm"] = o.m_Detector_distance_mm;
if(o.poniRot1RadIsSet())
j["poni_rot1_rad"] = o.m_Poni_rot1_rad;
if(o.poniRot2RadIsSet())
j["poni_rot2_rad"] = o.m_Poni_rot2_rad;
if(o.correlationBeamXRot1IsSet())
j["correlation_beam_x_rot1"] = o.m_Correlation_beam_x_rot1;
if(o.correlationBeamYRot2IsSet())
j["correlation_beam_y_rot2"] = o.m_Correlation_beam_y_rot2;
}
void from_json(const nlohmann::json& j, Calibration_fit_sigma& o)
{
if(j.find("beam_x_pxl") != j.end())
{
j.at("beam_x_pxl").get_to(o.m_Beam_x_pxl);
o.m_Beam_x_pxlIsSet = true;
}
if(j.find("beam_y_pxl") != j.end())
{
j.at("beam_y_pxl").get_to(o.m_Beam_y_pxl);
o.m_Beam_y_pxlIsSet = true;
}
if(j.find("detector_distance_mm") != j.end())
{
j.at("detector_distance_mm").get_to(o.m_Detector_distance_mm);
o.m_Detector_distance_mmIsSet = true;
}
if(j.find("poni_rot1_rad") != j.end())
{
j.at("poni_rot1_rad").get_to(o.m_Poni_rot1_rad);
o.m_Poni_rot1_radIsSet = true;
}
if(j.find("poni_rot2_rad") != j.end())
{
j.at("poni_rot2_rad").get_to(o.m_Poni_rot2_rad);
o.m_Poni_rot2_radIsSet = true;
}
if(j.find("correlation_beam_x_rot1") != j.end())
{
j.at("correlation_beam_x_rot1").get_to(o.m_Correlation_beam_x_rot1);
o.m_Correlation_beam_x_rot1IsSet = true;
}
if(j.find("correlation_beam_y_rot2") != j.end())
{
j.at("correlation_beam_y_rot2").get_to(o.m_Correlation_beam_y_rot2);
o.m_Correlation_beam_y_rot2IsSet = true;
}
}
float Calibration_fit_sigma::getBeamXPxl() const
{
return m_Beam_x_pxl;
}
void Calibration_fit_sigma::setBeamXPxl(float const value)
{
m_Beam_x_pxl = value;
m_Beam_x_pxlIsSet = true;
}
bool Calibration_fit_sigma::beamXPxlIsSet() const
{
return m_Beam_x_pxlIsSet;
}
void Calibration_fit_sigma::unsetBeam_x_pxl()
{
m_Beam_x_pxlIsSet = false;
}
float Calibration_fit_sigma::getBeamYPxl() const
{
return m_Beam_y_pxl;
}
void Calibration_fit_sigma::setBeamYPxl(float const value)
{
m_Beam_y_pxl = value;
m_Beam_y_pxlIsSet = true;
}
bool Calibration_fit_sigma::beamYPxlIsSet() const
{
return m_Beam_y_pxlIsSet;
}
void Calibration_fit_sigma::unsetBeam_y_pxl()
{
m_Beam_y_pxlIsSet = false;
}
float Calibration_fit_sigma::getDetectorDistanceMm() const
{
return m_Detector_distance_mm;
}
void Calibration_fit_sigma::setDetectorDistanceMm(float const value)
{
m_Detector_distance_mm = value;
m_Detector_distance_mmIsSet = true;
}
bool Calibration_fit_sigma::detectorDistanceMmIsSet() const
{
return m_Detector_distance_mmIsSet;
}
void Calibration_fit_sigma::unsetDetector_distance_mm()
{
m_Detector_distance_mmIsSet = false;
}
float Calibration_fit_sigma::getPoniRot1Rad() const
{
return m_Poni_rot1_rad;
}
void Calibration_fit_sigma::setPoniRot1Rad(float const value)
{
m_Poni_rot1_rad = value;
m_Poni_rot1_radIsSet = true;
}
bool Calibration_fit_sigma::poniRot1RadIsSet() const
{
return m_Poni_rot1_radIsSet;
}
void Calibration_fit_sigma::unsetPoni_rot1_rad()
{
m_Poni_rot1_radIsSet = false;
}
float Calibration_fit_sigma::getPoniRot2Rad() const
{
return m_Poni_rot2_rad;
}
void Calibration_fit_sigma::setPoniRot2Rad(float const value)
{
m_Poni_rot2_rad = value;
m_Poni_rot2_radIsSet = true;
}
bool Calibration_fit_sigma::poniRot2RadIsSet() const
{
return m_Poni_rot2_radIsSet;
}
void Calibration_fit_sigma::unsetPoni_rot2_rad()
{
m_Poni_rot2_radIsSet = false;
}
float Calibration_fit_sigma::getCorrelationBeamXRot1() const
{
return m_Correlation_beam_x_rot1;
}
void Calibration_fit_sigma::setCorrelationBeamXRot1(float const value)
{
m_Correlation_beam_x_rot1 = value;
m_Correlation_beam_x_rot1IsSet = true;
}
bool Calibration_fit_sigma::correlationBeamXRot1IsSet() const
{
return m_Correlation_beam_x_rot1IsSet;
}
void Calibration_fit_sigma::unsetCorrelation_beam_x_rot1()
{
m_Correlation_beam_x_rot1IsSet = false;
}
float Calibration_fit_sigma::getCorrelationBeamYRot2() const
{
return m_Correlation_beam_y_rot2;
}
void Calibration_fit_sigma::setCorrelationBeamYRot2(float const value)
{
m_Correlation_beam_y_rot2 = value;
m_Correlation_beam_y_rot2IsSet = true;
}
bool Calibration_fit_sigma::correlationBeamYRot2IsSet() const
{
return m_Correlation_beam_y_rot2IsSet;
}
void Calibration_fit_sigma::unsetCorrelation_beam_y_rot2()
{
m_Correlation_beam_y_rot2IsSet = false;
}
} // namespace org::openapitools::server::model
+132
View File
@@ -0,0 +1,132 @@
/**
* 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.166
* 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.
*/
/*
* Calibration_fit_sigma.h
*
* What the powder ring fit knows about its own answer, from the covariance of the converged problem. Each sigma is in its parameter&#39;s own unit and is scaled by the residual scatter of that fit, so it is the usual \&quot;how far could this move before the fit got visibly worse\&quot;. The two correlations are the ones that matter: a tilt and a beam-centre shift both displace a ring&#39;s radius as cos(phi) and are told apart only by how that amplitude grows with the ring&#39;s radius, so as the rings run out the pair stops being separable and these approach 1. The rotation sigmas and the correlations are absent when the tilt was not a free parameter.
*/
#ifndef Calibration_fit_sigma_H_
#define Calibration_fit_sigma_H_
#include <nlohmann/json.hpp>
namespace org::openapitools::server::model
{
/// <summary>
/// What the powder ring fit knows about its own answer, from the covariance of the converged problem. Each sigma is in its parameter&#39;s own unit and is scaled by the residual scatter of that fit, so it is the usual \&quot;how far could this move before the fit got visibly worse\&quot;. The two correlations are the ones that matter: a tilt and a beam-centre shift both displace a ring&#39;s radius as cos(phi) and are told apart only by how that amplitude grows with the ring&#39;s radius, so as the rings run out the pair stops being separable and these approach 1. The rotation sigmas and the correlations are absent when the tilt was not a free parameter.
/// </summary>
class Calibration_fit_sigma
{
public:
Calibration_fit_sigma();
virtual ~Calibration_fit_sigma() = 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 Calibration_fit_sigma& rhs) const;
bool operator!=(const Calibration_fit_sigma& rhs) const;
/////////////////////////////////////////////
/// Calibration_fit_sigma members
/// <summary>
/// Standard error of the fitted PONI x [pixels]
/// </summary>
float getBeamXPxl() const;
void setBeamXPxl(float const value);
bool beamXPxlIsSet() const;
void unsetBeam_x_pxl();
/// <summary>
/// Standard error of the fitted PONI y [pixels]
/// </summary>
float getBeamYPxl() const;
void setBeamYPxl(float const value);
bool beamYPxlIsSet() const;
void unsetBeam_y_pxl();
/// <summary>
/// Standard error of the fitted detector distance [mm]
/// </summary>
float getDetectorDistanceMm() const;
void setDetectorDistanceMm(float const value);
bool detectorDistanceMmIsSet() const;
void unsetDetector_distance_mm();
/// <summary>
/// Standard error of the fitted rot1 [rad]
/// </summary>
float getPoniRot1Rad() const;
void setPoniRot1Rad(float const value);
bool poniRot1RadIsSet() const;
void unsetPoni_rot1_rad();
/// <summary>
/// Standard error of the fitted rot2 [rad]
/// </summary>
float getPoniRot2Rad() const;
void setPoniRot2Rad(float const value);
bool poniRot2RadIsSet() const;
void unsetPoni_rot2_rad();
/// <summary>
/// Correlation between the fitted PONI x and rot1, -1 to 1
/// </summary>
float getCorrelationBeamXRot1() const;
void setCorrelationBeamXRot1(float const value);
bool correlationBeamXRot1IsSet() const;
void unsetCorrelation_beam_x_rot1();
/// <summary>
/// Correlation between the fitted PONI y and rot2, -1 to 1
/// </summary>
float getCorrelationBeamYRot2() const;
void setCorrelationBeamYRot2(float const value);
bool correlationBeamYRot2IsSet() const;
void unsetCorrelation_beam_y_rot2();
friend void to_json(nlohmann::json& j, const Calibration_fit_sigma& o);
friend void from_json(const nlohmann::json& j, Calibration_fit_sigma& o);
protected:
float m_Beam_x_pxl;
bool m_Beam_x_pxlIsSet;
float m_Beam_y_pxl;
bool m_Beam_y_pxlIsSet;
float m_Detector_distance_mm;
bool m_Detector_distance_mmIsSet;
float m_Poni_rot1_rad;
bool m_Poni_rot1_radIsSet;
float m_Poni_rot2_rad;
bool m_Poni_rot2_radIsSet;
float m_Correlation_beam_x_rot1;
bool m_Correlation_beam_x_rot1IsSet;
float m_Correlation_beam_y_rot2;
bool m_Correlation_beam_y_rot2IsSet;
};
} // namespace org::openapitools::server::model
#endif /* Calibration_fit_sigma_H_ */
+151
View File
@@ -0,0 +1,151 @@
/**
* 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.166
* 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 "Calibration_output.h"
#include "Helpers.h"
#include <sstream>
namespace org::openapitools::server::model
{
Calibration_output::Calibration_output()
{
m_CalibrationIsSet = false;
m_Jfjoch_version = "";
m_Jfjoch_versionIsSet = false;
}
void Calibration_output::validate() const
{
std::stringstream msg;
if (!validate(msg))
{
throw org::openapitools::server::helpers::ValidationException(msg.str());
}
}
bool Calibration_output::validate(std::stringstream& msg) const
{
return validate(msg, "");
}
bool Calibration_output::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Calibration_output" : pathPrefix;
if (!m_Dataset_settings.validate(msg, _pathPrefix + ".datasetSettings")) {
msg << _pathPrefix << ": Dataset_settings is invalid;";
success = false;
}
return success;
}
bool Calibration_output::operator==(const Calibration_output& rhs) const
{
return
(getDatasetSettings() == rhs.getDatasetSettings())
&&
((!calibrationIsSet() && !rhs.calibrationIsSet()) || (calibrationIsSet() && rhs.calibrationIsSet() && getCalibration() == rhs.getCalibration())) &&
((!jfjochVersionIsSet() && !rhs.jfjochVersionIsSet()) || (jfjochVersionIsSet() && rhs.jfjochVersionIsSet() && getJfjochVersion() == rhs.getJfjochVersion()))
;
}
bool Calibration_output::operator!=(const Calibration_output& rhs) const
{
return !(*this == rhs);
}
void to_json(nlohmann::json& j, const Calibration_output& o)
{
j = nlohmann::json::object();
j["dataset_settings"] = o.m_Dataset_settings;
if(o.calibrationIsSet())
j["calibration"] = o.m_Calibration;
if(o.jfjochVersionIsSet())
j["jfjoch_version"] = o.m_Jfjoch_version;
}
void from_json(const nlohmann::json& j, Calibration_output& o)
{
j.at("dataset_settings").get_to(o.m_Dataset_settings);
if(j.find("calibration") != j.end())
{
j.at("calibration").get_to(o.m_Calibration);
o.m_CalibrationIsSet = true;
}
if(j.find("jfjoch_version") != j.end())
{
j.at("jfjoch_version").get_to(o.m_Jfjoch_version);
o.m_Jfjoch_versionIsSet = true;
}
}
org::openapitools::server::model::Dataset_settings Calibration_output::getDatasetSettings() const
{
return m_Dataset_settings;
}
void Calibration_output::setDatasetSettings(org::openapitools::server::model::Dataset_settings const& value)
{
m_Dataset_settings = value;
}
org::openapitools::server::model::Calibration_quality Calibration_output::getCalibration() const
{
return m_Calibration;
}
void Calibration_output::setCalibration(org::openapitools::server::model::Calibration_quality const& value)
{
m_Calibration = value;
m_CalibrationIsSet = true;
}
bool Calibration_output::calibrationIsSet() const
{
return m_CalibrationIsSet;
}
void Calibration_output::unsetCalibration()
{
m_CalibrationIsSet = false;
}
std::string Calibration_output::getJfjochVersion() const
{
return m_Jfjoch_version;
}
void Calibration_output::setJfjochVersion(std::string const& value)
{
m_Jfjoch_version = value;
m_Jfjoch_versionIsSet = true;
}
bool Calibration_output::jfjochVersionIsSet() const
{
return m_Jfjoch_versionIsSet;
}
void Calibration_output::unsetJfjoch_version()
{
m_Jfjoch_versionIsSet = false;
}
} // namespace org::openapitools::server::model
+97
View File
@@ -0,0 +1,97 @@
/**
* 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.166
* 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.
*/
/*
* Calibration_output.h
*
* The result of a powder-ring detector calibration - what rugnux --mode calibration writes as &lt;prefix&gt;.json, and what a calibration run over the image buffer would return. dataset_settings holds the geometry and nothing else, under the property names this API gives them, so it can be POSTed or merged without translating a field. Its beam_x_pxl/beam_y_pxl is the PONI, the foot of the perpendicular from the sample; where the beam actually lands is calibration.direct_beam_x_pxl. The poni_rot*_rad are present whenever any of them is non-zero and absent when all are zero, since a body omitting them states a FLAT detector rather than an unstated one.
*/
#ifndef Calibration_output_H_
#define Calibration_output_H_
#include "Dataset_settings.h"
#include "Calibration_quality.h"
#include <string>
#include <nlohmann/json.hpp>
namespace org::openapitools::server::model
{
/// <summary>
/// The result of a powder-ring detector calibration - what rugnux --mode calibration writes as &lt;prefix&gt;.json, and what a calibration run over the image buffer would return. dataset_settings holds the geometry and nothing else, under the property names this API gives them, so it can be POSTed or merged without translating a field. Its beam_x_pxl/beam_y_pxl is the PONI, the foot of the perpendicular from the sample; where the beam actually lands is calibration.direct_beam_x_pxl. The poni_rot*_rad are present whenever any of them is non-zero and absent when all are zero, since a body omitting them states a FLAT detector rather than an unstated one.
/// </summary>
class Calibration_output
{
public:
Calibration_output();
virtual ~Calibration_output() = 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 Calibration_output& rhs) const;
bool operator!=(const Calibration_output& rhs) const;
/////////////////////////////////////////////
/// Calibration_output members
/// <summary>
///
/// </summary>
org::openapitools::server::model::Dataset_settings getDatasetSettings() const;
void setDatasetSettings(org::openapitools::server::model::Dataset_settings const& value);
/// <summary>
///
/// </summary>
org::openapitools::server::model::Calibration_quality getCalibration() const;
void setCalibration(org::openapitools::server::model::Calibration_quality const& value);
bool calibrationIsSet() const;
void unsetCalibration();
/// <summary>
/// Version of the program that produced this
/// </summary>
std::string getJfjochVersion() const;
void setJfjochVersion(std::string const& value);
bool jfjochVersionIsSet() const;
void unsetJfjoch_version();
friend void to_json(nlohmann::json& j, const Calibration_output& o);
friend void from_json(const nlohmann::json& j, Calibration_output& o);
protected:
org::openapitools::server::model::Dataset_settings m_Dataset_settings;
org::openapitools::server::model::Calibration_quality m_Calibration;
bool m_CalibrationIsSet;
std::string m_Jfjoch_version;
bool m_Jfjoch_versionIsSet;
};
} // namespace org::openapitools::server::model
#endif /* Calibration_output_H_ */
+452
View File
@@ -0,0 +1,452 @@
/**
* 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.166
* 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 "Calibration_quality.h"
#include "Helpers.h"
#include <sstream>
namespace org::openapitools::server::model
{
Calibration_quality::Calibration_quality()
{
m_Calibrant = "";
m_CalibrantIsSet = false;
m_Method = "";
m_MethodIsSet = false;
m_Ring_points = 0L;
m_Ring_pointsIsSet = false;
m_Rms_radial_pxl = 0.0f;
m_Rms_radial_pxlIsSet = false;
m_Beam_sigma_pxl = 0.0f;
m_Beam_sigma_pxlIsSet = false;
m_Direct_beam_x_pxl = 0.0f;
m_Direct_beam_x_pxlIsSet = false;
m_Direct_beam_y_pxl = 0.0f;
m_Direct_beam_y_pxlIsSet = false;
m_Header_distance_mm = 0.0f;
m_Header_distance_mmIsSet = false;
m_Ring_seed_distance_mm = 0.0f;
m_Ring_seed_distance_mmIsSet = false;
m_Tilt_refined = false;
m_Tilt_refinedIsSet = false;
m_Tilt_significance = 0.0f;
m_Tilt_significanceIsSet = false;
m_Fit_sigmaIsSet = false;
m_Spot_cross_checkIsSet = false;
}
void Calibration_quality::validate() const
{
std::stringstream msg;
if (!validate(msg))
{
throw org::openapitools::server::helpers::ValidationException(msg.str());
}
}
bool Calibration_quality::validate(std::stringstream& msg) const
{
return validate(msg, "");
}
bool Calibration_quality::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Calibration_quality" : pathPrefix;
return success;
}
bool Calibration_quality::operator==(const Calibration_quality& rhs) const
{
return
((!calibrantIsSet() && !rhs.calibrantIsSet()) || (calibrantIsSet() && rhs.calibrantIsSet() && getCalibrant() == rhs.getCalibrant())) &&
((!methodIsSet() && !rhs.methodIsSet()) || (methodIsSet() && rhs.methodIsSet() && getMethod() == rhs.getMethod())) &&
((!ringPointsIsSet() && !rhs.ringPointsIsSet()) || (ringPointsIsSet() && rhs.ringPointsIsSet() && getRingPoints() == rhs.getRingPoints())) &&
((!rmsRadialPxlIsSet() && !rhs.rmsRadialPxlIsSet()) || (rmsRadialPxlIsSet() && rhs.rmsRadialPxlIsSet() && getRmsRadialPxl() == rhs.getRmsRadialPxl())) &&
((!beamSigmaPxlIsSet() && !rhs.beamSigmaPxlIsSet()) || (beamSigmaPxlIsSet() && rhs.beamSigmaPxlIsSet() && getBeamSigmaPxl() == rhs.getBeamSigmaPxl())) &&
((!directBeamXPxlIsSet() && !rhs.directBeamXPxlIsSet()) || (directBeamXPxlIsSet() && rhs.directBeamXPxlIsSet() && getDirectBeamXPxl() == rhs.getDirectBeamXPxl())) &&
((!directBeamYPxlIsSet() && !rhs.directBeamYPxlIsSet()) || (directBeamYPxlIsSet() && rhs.directBeamYPxlIsSet() && getDirectBeamYPxl() == rhs.getDirectBeamYPxl())) &&
((!headerDistanceMmIsSet() && !rhs.headerDistanceMmIsSet()) || (headerDistanceMmIsSet() && rhs.headerDistanceMmIsSet() && getHeaderDistanceMm() == rhs.getHeaderDistanceMm())) &&
((!ringSeedDistanceMmIsSet() && !rhs.ringSeedDistanceMmIsSet()) || (ringSeedDistanceMmIsSet() && rhs.ringSeedDistanceMmIsSet() && getRingSeedDistanceMm() == rhs.getRingSeedDistanceMm())) &&
((!tiltRefinedIsSet() && !rhs.tiltRefinedIsSet()) || (tiltRefinedIsSet() && rhs.tiltRefinedIsSet() && isTiltRefined() == rhs.isTiltRefined())) &&
((!tiltSignificanceIsSet() && !rhs.tiltSignificanceIsSet()) || (tiltSignificanceIsSet() && rhs.tiltSignificanceIsSet() && getTiltSignificance() == rhs.getTiltSignificance())) &&
((!fitSigmaIsSet() && !rhs.fitSigmaIsSet()) || (fitSigmaIsSet() && rhs.fitSigmaIsSet() && getFitSigma() == rhs.getFitSigma())) &&
((!spotCrossCheckIsSet() && !rhs.spotCrossCheckIsSet()) || (spotCrossCheckIsSet() && rhs.spotCrossCheckIsSet() && getSpotCrossCheck() == rhs.getSpotCrossCheck()))
;
}
bool Calibration_quality::operator!=(const Calibration_quality& rhs) const
{
return !(*this == rhs);
}
void to_json(nlohmann::json& j, const Calibration_quality& o)
{
j = nlohmann::json::object();
if(o.calibrantIsSet())
j["calibrant"] = o.m_Calibrant;
if(o.methodIsSet())
j["method"] = o.m_Method;
if(o.ringPointsIsSet())
j["ring_points"] = o.m_Ring_points;
if(o.rmsRadialPxlIsSet())
j["rms_radial_pxl"] = o.m_Rms_radial_pxl;
if(o.beamSigmaPxlIsSet())
j["beam_sigma_pxl"] = o.m_Beam_sigma_pxl;
if(o.directBeamXPxlIsSet())
j["direct_beam_x_pxl"] = o.m_Direct_beam_x_pxl;
if(o.directBeamYPxlIsSet())
j["direct_beam_y_pxl"] = o.m_Direct_beam_y_pxl;
if(o.headerDistanceMmIsSet())
j["header_distance_mm"] = o.m_Header_distance_mm;
if(o.ringSeedDistanceMmIsSet())
j["ring_seed_distance_mm"] = o.m_Ring_seed_distance_mm;
if(o.tiltRefinedIsSet())
j["tilt_refined"] = o.m_Tilt_refined;
if(o.tiltSignificanceIsSet())
j["tilt_significance"] = o.m_Tilt_significance;
if(o.fitSigmaIsSet())
j["fit_sigma"] = o.m_Fit_sigma;
if(o.spotCrossCheckIsSet())
j["spot_cross_check"] = o.m_Spot_cross_check;
}
void from_json(const nlohmann::json& j, Calibration_quality& o)
{
if(j.find("calibrant") != j.end())
{
j.at("calibrant").get_to(o.m_Calibrant);
o.m_CalibrantIsSet = true;
}
if(j.find("method") != j.end())
{
j.at("method").get_to(o.m_Method);
o.m_MethodIsSet = true;
}
if(j.find("ring_points") != j.end())
{
j.at("ring_points").get_to(o.m_Ring_points);
o.m_Ring_pointsIsSet = true;
}
if(j.find("rms_radial_pxl") != j.end())
{
j.at("rms_radial_pxl").get_to(o.m_Rms_radial_pxl);
o.m_Rms_radial_pxlIsSet = true;
}
if(j.find("beam_sigma_pxl") != j.end())
{
j.at("beam_sigma_pxl").get_to(o.m_Beam_sigma_pxl);
o.m_Beam_sigma_pxlIsSet = true;
}
if(j.find("direct_beam_x_pxl") != j.end())
{
j.at("direct_beam_x_pxl").get_to(o.m_Direct_beam_x_pxl);
o.m_Direct_beam_x_pxlIsSet = true;
}
if(j.find("direct_beam_y_pxl") != j.end())
{
j.at("direct_beam_y_pxl").get_to(o.m_Direct_beam_y_pxl);
o.m_Direct_beam_y_pxlIsSet = true;
}
if(j.find("header_distance_mm") != j.end())
{
j.at("header_distance_mm").get_to(o.m_Header_distance_mm);
o.m_Header_distance_mmIsSet = true;
}
if(j.find("ring_seed_distance_mm") != j.end())
{
j.at("ring_seed_distance_mm").get_to(o.m_Ring_seed_distance_mm);
o.m_Ring_seed_distance_mmIsSet = true;
}
if(j.find("tilt_refined") != j.end())
{
j.at("tilt_refined").get_to(o.m_Tilt_refined);
o.m_Tilt_refinedIsSet = true;
}
if(j.find("tilt_significance") != j.end())
{
j.at("tilt_significance").get_to(o.m_Tilt_significance);
o.m_Tilt_significanceIsSet = true;
}
if(j.find("fit_sigma") != j.end())
{
j.at("fit_sigma").get_to(o.m_Fit_sigma);
o.m_Fit_sigmaIsSet = true;
}
if(j.find("spot_cross_check") != j.end())
{
j.at("spot_cross_check").get_to(o.m_Spot_cross_check);
o.m_Spot_cross_checkIsSet = true;
}
}
std::string Calibration_quality::getCalibrant() const
{
return m_Calibrant;
}
void Calibration_quality::setCalibrant(std::string const& value)
{
m_Calibrant = value;
m_CalibrantIsSet = true;
}
bool Calibration_quality::calibrantIsSet() const
{
return m_CalibrantIsSet;
}
void Calibration_quality::unsetCalibrant()
{
m_CalibrantIsSet = false;
}
std::string Calibration_quality::getMethod() const
{
return m_Method;
}
void Calibration_quality::setMethod(std::string const& value)
{
m_Method = value;
m_MethodIsSet = true;
}
bool Calibration_quality::methodIsSet() const
{
return m_MethodIsSet;
}
void Calibration_quality::unsetMethod()
{
m_MethodIsSet = false;
}
int64_t Calibration_quality::getRingPoints() const
{
return m_Ring_points;
}
void Calibration_quality::setRingPoints(int64_t const value)
{
m_Ring_points = value;
m_Ring_pointsIsSet = true;
}
bool Calibration_quality::ringPointsIsSet() const
{
return m_Ring_pointsIsSet;
}
void Calibration_quality::unsetRing_points()
{
m_Ring_pointsIsSet = false;
}
float Calibration_quality::getRmsRadialPxl() const
{
return m_Rms_radial_pxl;
}
void Calibration_quality::setRmsRadialPxl(float const value)
{
m_Rms_radial_pxl = value;
m_Rms_radial_pxlIsSet = true;
}
bool Calibration_quality::rmsRadialPxlIsSet() const
{
return m_Rms_radial_pxlIsSet;
}
void Calibration_quality::unsetRms_radial_pxl()
{
m_Rms_radial_pxlIsSet = false;
}
float Calibration_quality::getBeamSigmaPxl() const
{
return m_Beam_sigma_pxl;
}
void Calibration_quality::setBeamSigmaPxl(float const value)
{
m_Beam_sigma_pxl = value;
m_Beam_sigma_pxlIsSet = true;
}
bool Calibration_quality::beamSigmaPxlIsSet() const
{
return m_Beam_sigma_pxlIsSet;
}
void Calibration_quality::unsetBeam_sigma_pxl()
{
m_Beam_sigma_pxlIsSet = false;
}
float Calibration_quality::getDirectBeamXPxl() const
{
return m_Direct_beam_x_pxl;
}
void Calibration_quality::setDirectBeamXPxl(float const value)
{
m_Direct_beam_x_pxl = value;
m_Direct_beam_x_pxlIsSet = true;
}
bool Calibration_quality::directBeamXPxlIsSet() const
{
return m_Direct_beam_x_pxlIsSet;
}
void Calibration_quality::unsetDirect_beam_x_pxl()
{
m_Direct_beam_x_pxlIsSet = false;
}
float Calibration_quality::getDirectBeamYPxl() const
{
return m_Direct_beam_y_pxl;
}
void Calibration_quality::setDirectBeamYPxl(float const value)
{
m_Direct_beam_y_pxl = value;
m_Direct_beam_y_pxlIsSet = true;
}
bool Calibration_quality::directBeamYPxlIsSet() const
{
return m_Direct_beam_y_pxlIsSet;
}
void Calibration_quality::unsetDirect_beam_y_pxl()
{
m_Direct_beam_y_pxlIsSet = false;
}
float Calibration_quality::getHeaderDistanceMm() const
{
return m_Header_distance_mm;
}
void Calibration_quality::setHeaderDistanceMm(float const value)
{
m_Header_distance_mm = value;
m_Header_distance_mmIsSet = true;
}
bool Calibration_quality::headerDistanceMmIsSet() const
{
return m_Header_distance_mmIsSet;
}
void Calibration_quality::unsetHeader_distance_mm()
{
m_Header_distance_mmIsSet = false;
}
float Calibration_quality::getRingSeedDistanceMm() const
{
return m_Ring_seed_distance_mm;
}
void Calibration_quality::setRingSeedDistanceMm(float const value)
{
m_Ring_seed_distance_mm = value;
m_Ring_seed_distance_mmIsSet = true;
}
bool Calibration_quality::ringSeedDistanceMmIsSet() const
{
return m_Ring_seed_distance_mmIsSet;
}
void Calibration_quality::unsetRing_seed_distance_mm()
{
m_Ring_seed_distance_mmIsSet = false;
}
bool Calibration_quality::isTiltRefined() const
{
return m_Tilt_refined;
}
void Calibration_quality::setTiltRefined(bool const value)
{
m_Tilt_refined = value;
m_Tilt_refinedIsSet = true;
}
bool Calibration_quality::tiltRefinedIsSet() const
{
return m_Tilt_refinedIsSet;
}
void Calibration_quality::unsetTilt_refined()
{
m_Tilt_refinedIsSet = false;
}
float Calibration_quality::getTiltSignificance() const
{
return m_Tilt_significance;
}
void Calibration_quality::setTiltSignificance(float const value)
{
m_Tilt_significance = value;
m_Tilt_significanceIsSet = true;
}
bool Calibration_quality::tiltSignificanceIsSet() const
{
return m_Tilt_significanceIsSet;
}
void Calibration_quality::unsetTilt_significance()
{
m_Tilt_significanceIsSet = false;
}
org::openapitools::server::model::Calibration_fit_sigma Calibration_quality::getFitSigma() const
{
return m_Fit_sigma;
}
void Calibration_quality::setFitSigma(org::openapitools::server::model::Calibration_fit_sigma const& value)
{
m_Fit_sigma = value;
m_Fit_sigmaIsSet = true;
}
bool Calibration_quality::fitSigmaIsSet() const
{
return m_Fit_sigmaIsSet;
}
void Calibration_quality::unsetFit_sigma()
{
m_Fit_sigmaIsSet = false;
}
org::openapitools::server::model::Calibration_spot_check Calibration_quality::getSpotCrossCheck() const
{
return m_Spot_cross_check;
}
void Calibration_quality::setSpotCrossCheck(org::openapitools::server::model::Calibration_spot_check const& value)
{
m_Spot_cross_check = value;
m_Spot_cross_checkIsSet = true;
}
bool Calibration_quality::spotCrossCheckIsSet() const
{
return m_Spot_cross_checkIsSet;
}
void Calibration_quality::unsetSpot_cross_check()
{
m_Spot_cross_checkIsSet = false;
}
} // namespace org::openapitools::server::model
+189
View File
@@ -0,0 +1,189 @@
/**
* 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.166
* 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.
*/
/*
* Calibration_quality.h
*
* What a powder calibration knows about the geometry it produced. A calibration that has gone wrong - the wrong standard named, a header too far out for the rings to be found - looks exactly like one that has not until these are read.
*/
#ifndef Calibration_quality_H_
#define Calibration_quality_H_
#include "Calibration_spot_check.h"
#include "Calibration_fit_sigma.h"
#include <string>
#include <nlohmann/json.hpp>
namespace org::openapitools::server::model
{
/// <summary>
/// What a powder calibration knows about the geometry it produced. A calibration that has gone wrong - the wrong standard named, a header too far out for the rings to be found - looks exactly like one that has not until these are read.
/// </summary>
class Calibration_quality
{
public:
Calibration_quality();
virtual ~Calibration_quality() = 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 Calibration_quality& rhs) const;
bool operator!=(const Calibration_quality& rhs) const;
/////////////////////////////////////////////
/// Calibration_quality members
/// <summary>
/// The powder standard the rings were fitted to, or the unit cell given in its place
/// </summary>
std::string getCalibrant() const;
void setCalibrant(std::string const& value);
bool calibrantIsSet() const;
void unsetCalibrant();
/// <summary>
/// How the rings were measured. rings fits the arcs of the run-summed (q x azimuth) azimuthal profile; spots fits the pooled per-image spot lists.
/// </summary>
std::string getMethod() const;
void setMethod(std::string const& value);
bool methodIsSet() const;
void unsetMethod();
/// <summary>
/// Ring measurements the fit used
/// </summary>
int64_t getRingPoints() const;
void setRingPoints(int64_t const value);
bool ringPointsIsSet() const;
void unsetRing_points();
/// <summary>
/// Scatter of those measurements about the fitted rings, as a radial distance [pixels]. The single number that separates a calibration that worked from one that did not.
/// </summary>
float getRmsRadialPxl() const;
void setRmsRadialPxl(float const value);
bool rmsRadialPxlIsSet() const;
void unsetRms_radial_pxl();
/// <summary>
/// Standard error the scatter implies on the beam centre [pixels], for a ring of that many points. See calibration_fit_sigma for what the fit itself says, which is not the same and is the larger of the two whenever the tilt is poorly separated.
/// </summary>
float getBeamSigmaPxl() const;
void setBeamSigmaPxl(float const value);
bool beamSigmaPxlIsSet() const;
void unsetBeam_sigma_pxl();
/// <summary>
/// Where the direct beam lands [pixels]. NOT dataset_settings.beam_x_pxl, which is the PONI: the two part company by distance*tan(tilt)/pixel as soon as the detector is tilted.
/// </summary>
float getDirectBeamXPxl() const;
void setDirectBeamXPxl(float const value);
bool directBeamXPxlIsSet() const;
void unsetDirect_beam_x_pxl();
/// <summary>
/// Where the direct beam lands, y [pixels]
/// </summary>
float getDirectBeamYPxl() const;
void setDirectBeamYPxl(float const value);
bool directBeamYPxlIsSet() const;
void unsetDirect_beam_y_pxl();
/// <summary>
/// The detector distance the input file declared, for comparison [mm]
/// </summary>
float getHeaderDistanceMm() const;
void setHeaderDistanceMm(float const value);
bool headerDistanceMmIsSet() const;
void unsetHeader_distance_mm();
/// <summary>
/// The distance measured from the ring radii before the fit ran [mm]. It is taken from the radii, the wavelength and the pixel size alone, so a large gap from header_distance_mm is the answer to the question the calibration was run to ask. Absent when the profile showed too few rings to fix a scale.
/// </summary>
float getRingSeedDistanceMm() const;
void setRingSeedDistanceMm(float const value);
bool ringSeedDistanceMmIsSet() const;
void unsetRing_seed_distance_mm();
/// <summary>
/// Whether the reported rot1/rot2 were measured by this fit. False means they were declined and pinned at the input file&#39;s values, because the rings could not separate a tilt from a shift of the beam centre.
/// </summary>
bool isTiltRefined() const;
void setTiltRefined(bool const value);
bool tiltRefinedIsSet() const;
void unsetTilt_refined();
/// <summary>
/// How many of its own sigmas the fitted tilt stands from zero. Below about 3 it is not a measurement of a tilt but of a beam-centre shift, and the tilt is declined. Passing does not certify a tilt: that estimator is limited by systematics rather than by this sigma.
/// </summary>
float getTiltSignificance() const;
void setTiltSignificance(float const value);
bool tiltSignificanceIsSet() const;
void unsetTilt_significance();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Calibration_fit_sigma getFitSigma() const;
void setFitSigma(org::openapitools::server::model::Calibration_fit_sigma const& value);
bool fitSigmaIsSet() const;
void unsetFit_sigma();
/// <summary>
///
/// </summary>
org::openapitools::server::model::Calibration_spot_check getSpotCrossCheck() const;
void setSpotCrossCheck(org::openapitools::server::model::Calibration_spot_check const& value);
bool spotCrossCheckIsSet() const;
void unsetSpot_cross_check();
friend void to_json(nlohmann::json& j, const Calibration_quality& o);
friend void from_json(const nlohmann::json& j, Calibration_quality& o);
protected:
std::string m_Calibrant;
bool m_CalibrantIsSet;
std::string m_Method;
bool m_MethodIsSet;
int64_t m_Ring_points;
bool m_Ring_pointsIsSet;
float m_Rms_radial_pxl;
bool m_Rms_radial_pxlIsSet;
float m_Beam_sigma_pxl;
bool m_Beam_sigma_pxlIsSet;
float m_Direct_beam_x_pxl;
bool m_Direct_beam_x_pxlIsSet;
float m_Direct_beam_y_pxl;
bool m_Direct_beam_y_pxlIsSet;
float m_Header_distance_mm;
bool m_Header_distance_mmIsSet;
float m_Ring_seed_distance_mm;
bool m_Ring_seed_distance_mmIsSet;
bool m_Tilt_refined;
bool m_Tilt_refinedIsSet;
float m_Tilt_significance;
bool m_Tilt_significanceIsSet;
org::openapitools::server::model::Calibration_fit_sigma m_Fit_sigma;
bool m_Fit_sigmaIsSet;
org::openapitools::server::model::Calibration_spot_check m_Spot_cross_check;
bool m_Spot_cross_checkIsSet;
};
} // namespace org::openapitools::server::model
#endif /* Calibration_quality_H_ */
+193
View File
@@ -0,0 +1,193 @@
/**
* 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.166
* 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 "Calibration_spot_check.h"
#include "Helpers.h"
#include <sstream>
namespace org::openapitools::server::model
{
Calibration_spot_check::Calibration_spot_check()
{
m_Beam_x_pxl = 0.0f;
m_Beam_x_pxlIsSet = false;
m_Beam_y_pxl = 0.0f;
m_Beam_y_pxlIsSet = false;
m_Detector_distance_mm = 0.0f;
m_Detector_distance_mmIsSet = false;
m_Disagreement_pxl = 0.0f;
m_Disagreement_pxlIsSet = false;
}
void Calibration_spot_check::validate() const
{
std::stringstream msg;
if (!validate(msg))
{
throw org::openapitools::server::helpers::ValidationException(msg.str());
}
}
bool Calibration_spot_check::validate(std::stringstream& msg) const
{
return validate(msg, "");
}
bool Calibration_spot_check::validate(std::stringstream& msg, const std::string& pathPrefix) const
{
bool success = true;
const std::string _pathPrefix = pathPrefix.empty() ? "Calibration_spot_check" : pathPrefix;
return success;
}
bool Calibration_spot_check::operator==(const Calibration_spot_check& rhs) const
{
return
((!beamXPxlIsSet() && !rhs.beamXPxlIsSet()) || (beamXPxlIsSet() && rhs.beamXPxlIsSet() && getBeamXPxl() == rhs.getBeamXPxl())) &&
((!beamYPxlIsSet() && !rhs.beamYPxlIsSet()) || (beamYPxlIsSet() && rhs.beamYPxlIsSet() && getBeamYPxl() == rhs.getBeamYPxl())) &&
((!detectorDistanceMmIsSet() && !rhs.detectorDistanceMmIsSet()) || (detectorDistanceMmIsSet() && rhs.detectorDistanceMmIsSet() && getDetectorDistanceMm() == rhs.getDetectorDistanceMm())) &&
((!disagreementPxlIsSet() && !rhs.disagreementPxlIsSet()) || (disagreementPxlIsSet() && rhs.disagreementPxlIsSet() && getDisagreementPxl() == rhs.getDisagreementPxl()))
;
}
bool Calibration_spot_check::operator!=(const Calibration_spot_check& rhs) const
{
return !(*this == rhs);
}
void to_json(nlohmann::json& j, const Calibration_spot_check& o)
{
j = nlohmann::json::object();
if(o.beamXPxlIsSet())
j["beam_x_pxl"] = o.m_Beam_x_pxl;
if(o.beamYPxlIsSet())
j["beam_y_pxl"] = o.m_Beam_y_pxl;
if(o.detectorDistanceMmIsSet())
j["detector_distance_mm"] = o.m_Detector_distance_mm;
if(o.disagreementPxlIsSet())
j["disagreement_pxl"] = o.m_Disagreement_pxl;
}
void from_json(const nlohmann::json& j, Calibration_spot_check& o)
{
if(j.find("beam_x_pxl") != j.end())
{
j.at("beam_x_pxl").get_to(o.m_Beam_x_pxl);
o.m_Beam_x_pxlIsSet = true;
}
if(j.find("beam_y_pxl") != j.end())
{
j.at("beam_y_pxl").get_to(o.m_Beam_y_pxl);
o.m_Beam_y_pxlIsSet = true;
}
if(j.find("detector_distance_mm") != j.end())
{
j.at("detector_distance_mm").get_to(o.m_Detector_distance_mm);
o.m_Detector_distance_mmIsSet = true;
}
if(j.find("disagreement_pxl") != j.end())
{
j.at("disagreement_pxl").get_to(o.m_Disagreement_pxl);
o.m_Disagreement_pxlIsSet = true;
}
}
float Calibration_spot_check::getBeamXPxl() const
{
return m_Beam_x_pxl;
}
void Calibration_spot_check::setBeamXPxl(float const value)
{
m_Beam_x_pxl = value;
m_Beam_x_pxlIsSet = true;
}
bool Calibration_spot_check::beamXPxlIsSet() const
{
return m_Beam_x_pxlIsSet;
}
void Calibration_spot_check::unsetBeam_x_pxl()
{
m_Beam_x_pxlIsSet = false;
}
float Calibration_spot_check::getBeamYPxl() const
{
return m_Beam_y_pxl;
}
void Calibration_spot_check::setBeamYPxl(float const value)
{
m_Beam_y_pxl = value;
m_Beam_y_pxlIsSet = true;
}
bool Calibration_spot_check::beamYPxlIsSet() const
{
return m_Beam_y_pxlIsSet;
}
void Calibration_spot_check::unsetBeam_y_pxl()
{
m_Beam_y_pxlIsSet = false;
}
float Calibration_spot_check::getDetectorDistanceMm() const
{
return m_Detector_distance_mm;
}
void Calibration_spot_check::setDetectorDistanceMm(float const value)
{
m_Detector_distance_mm = value;
m_Detector_distance_mmIsSet = true;
}
bool Calibration_spot_check::detectorDistanceMmIsSet() const
{
return m_Detector_distance_mmIsSet;
}
void Calibration_spot_check::unsetDetector_distance_mm()
{
m_Detector_distance_mmIsSet = false;
}
float Calibration_spot_check::getDisagreementPxl() const
{
return m_Disagreement_pxl;
}
void Calibration_spot_check::setDisagreementPxl(float const value)
{
m_Disagreement_pxl = value;
m_Disagreement_pxlIsSet = true;
}
bool Calibration_spot_check::disagreementPxlIsSet() const
{
return m_Disagreement_pxlIsSet;
}
void Calibration_spot_check::unsetDisagreement_pxl()
{
m_Disagreement_pxlIsSet = false;
}
} // namespace org::openapitools::server::model
+105
View File
@@ -0,0 +1,105 @@
/**
* 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.166
* 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.
*/
/*
* Calibration_spot_check.h
*
* Where the circle through the found spots puts the beam, and how far that is from the geometry actually fitted. An independent cross-check: it reads nothing from the file&#39;s own geometry, so it holds where the summed azimuthal profile does not - a profile binned about a badly wrong centre shows each ring smeared across its sectors, and a fit on it converges on the wrong answer without saying so. Two methods sharing no assumption, so the disagreement is the statement. Absent when no spots were available.
*/
#ifndef Calibration_spot_check_H_
#define Calibration_spot_check_H_
#include <nlohmann/json.hpp>
namespace org::openapitools::server::model
{
/// <summary>
/// Where the circle through the found spots puts the beam, and how far that is from the geometry actually fitted. An independent cross-check: it reads nothing from the file&#39;s own geometry, so it holds where the summed azimuthal profile does not - a profile binned about a badly wrong centre shows each ring smeared across its sectors, and a fit on it converges on the wrong answer without saying so. Two methods sharing no assumption, so the disagreement is the statement. Absent when no spots were available.
/// </summary>
class Calibration_spot_check
{
public:
Calibration_spot_check();
virtual ~Calibration_spot_check() = 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 Calibration_spot_check& rhs) const;
bool operator!=(const Calibration_spot_check& rhs) const;
/////////////////////////////////////////////
/// Calibration_spot_check members
/// <summary>
/// Beam centre x the spots vote for [pixels]
/// </summary>
float getBeamXPxl() const;
void setBeamXPxl(float const value);
bool beamXPxlIsSet() const;
void unsetBeam_x_pxl();
/// <summary>
/// Beam centre y the spots vote for [pixels]
/// </summary>
float getBeamYPxl() const;
void setBeamYPxl(float const value);
bool beamYPxlIsSet() const;
void unsetBeam_y_pxl();
/// <summary>
/// Detector distance the spots imply [mm]
/// </summary>
float getDetectorDistanceMm() const;
void setDetectorDistanceMm(float const value);
bool detectorDistanceMmIsSet() const;
void unsetDetector_distance_mm();
/// <summary>
/// Distance between the spots&#39; beam centre and the fitted one [pixels]
/// </summary>
float getDisagreementPxl() const;
void setDisagreementPxl(float const value);
bool disagreementPxlIsSet() const;
void unsetDisagreement_pxl();
friend void to_json(nlohmann::json& j, const Calibration_spot_check& o);
friend void from_json(const nlohmann::json& j, Calibration_spot_check& o);
protected:
float m_Beam_x_pxl;
bool m_Beam_x_pxlIsSet;
float m_Beam_y_pxl;
bool m_Beam_y_pxlIsSet;
float m_Detector_distance_mm;
bool m_Detector_distance_mmIsSet;
float m_Disagreement_pxl;
bool m_Disagreement_pxlIsSet;
};
} // namespace org::openapitools::server::model
#endif /* Calibration_spot_check_H_ */
+161
View File
@@ -1684,6 +1684,167 @@ components:
type: number
format: float
description: Diffraction resolution estimate
calibration_fit_sigma:
type: object
description: |
What the powder ring fit knows about its own answer, from the covariance of the converged
problem. Each sigma is in its parameter's own unit and is scaled by the residual scatter of
that fit, so it is the usual "how far could this move before the fit got visibly worse".
The two correlations are the ones that matter: a tilt and a beam-centre shift both displace a
ring's radius as cos(phi) and are told apart only by how that amplitude grows with the ring's
radius, so as the rings run out the pair stops being separable and these approach 1.
The rotation sigmas and the correlations are absent when the tilt was not a free parameter.
properties:
beam_x_pxl:
type: number
format: float
description: Standard error of the fitted PONI x [pixels]
beam_y_pxl:
type: number
format: float
description: Standard error of the fitted PONI y [pixels]
detector_distance_mm:
type: number
format: float
description: Standard error of the fitted detector distance [mm]
poni_rot1_rad:
type: number
format: float
description: Standard error of the fitted rot1 [rad]
poni_rot2_rad:
type: number
format: float
description: Standard error of the fitted rot2 [rad]
correlation_beam_x_rot1:
type: number
format: float
description: Correlation between the fitted PONI x and rot1, -1 to 1
correlation_beam_y_rot2:
type: number
format: float
description: Correlation between the fitted PONI y and rot2, -1 to 1
calibration_spot_check:
type: object
description: |
Where the circle through the found spots puts the beam, and how far that is from the geometry
actually fitted. An independent cross-check: it reads nothing from the file's own geometry, so
it holds where the summed azimuthal profile does not - a profile binned about a badly wrong
centre shows each ring smeared across its sectors, and a fit on it converges on the wrong
answer without saying so. Two methods sharing no assumption, so the disagreement is the
statement. Absent when no spots were available.
properties:
beam_x_pxl:
type: number
format: float
description: Beam centre x the spots vote for [pixels]
beam_y_pxl:
type: number
format: float
description: Beam centre y the spots vote for [pixels]
detector_distance_mm:
type: number
format: float
description: Detector distance the spots imply [mm]
disagreement_pxl:
type: number
format: float
description: Distance between the spots' beam centre and the fitted one [pixels]
calibration_quality:
type: object
description: |
What a powder calibration knows about the geometry it produced. A calibration that has gone
wrong - the wrong standard named, a header too far out for the rings to be found - looks
exactly like one that has not until these are read.
properties:
calibrant:
type: string
description: The powder standard the rings were fitted to, or the unit cell given in its place
method:
type: string
description: |
How the rings were measured. rings fits the arcs of the run-summed (q x azimuth) azimuthal
profile; spots fits the pooled per-image spot lists.
enum:
- "rings"
- "spots"
ring_points:
type: integer
format: int64
description: Ring measurements the fit used
rms_radial_pxl:
type: number
format: float
description: |
Scatter of those measurements about the fitted rings, as a radial distance [pixels]. The
single number that separates a calibration that worked from one that did not.
beam_sigma_pxl:
type: number
format: float
description: |
Standard error the scatter implies on the beam centre [pixels], for a ring of that many
points. See calibration_fit_sigma for what the fit itself says, which is not the same and
is the larger of the two whenever the tilt is poorly separated.
direct_beam_x_pxl:
type: number
format: float
description: |
Where the direct beam lands [pixels]. NOT dataset_settings.beam_x_pxl, which is the PONI:
the two part company by distance*tan(tilt)/pixel as soon as the detector is tilted.
direct_beam_y_pxl:
type: number
format: float
description: Where the direct beam lands, y [pixels]
header_distance_mm:
type: number
format: float
description: The detector distance the input file declared, for comparison [mm]
ring_seed_distance_mm:
type: number
format: float
description: |
The distance measured from the ring radii before the fit ran [mm]. It is taken from the
radii, the wavelength and the pixel size alone, so a large gap from header_distance_mm is
the answer to the question the calibration was run to ask. Absent when the profile showed
too few rings to fix a scale.
tilt_refined:
type: boolean
description: |
Whether the reported rot1/rot2 were measured by this fit. False means they were declined
and pinned at the input file's values, because the rings could not separate a tilt from a
shift of the beam centre.
tilt_significance:
type: number
format: float
description: |
How many of its own sigmas the fitted tilt stands from zero. Below about 3 it is not a
measurement of a tilt but of a beam-centre shift, and the tilt is declined. Passing does
not certify a tilt: that estimator is limited by systematics rather than by this sigma.
fit_sigma:
$ref: '#/components/schemas/calibration_fit_sigma'
spot_cross_check:
$ref: '#/components/schemas/calibration_spot_check'
calibration_output:
type: object
required:
- dataset_settings
description: |
The result of a powder-ring detector calibration - what rugnux --mode calibration writes as
<prefix>.json, and what a calibration run over the image buffer would return.
dataset_settings holds the geometry and nothing else, under the property names this API gives
them, so it can be POSTed or merged without translating a field. Its beam_x_pxl/beam_y_pxl is
the PONI, the foot of the perpendicular from the sample; where the beam actually lands is
calibration.direct_beam_x_pxl. The poni_rot*_rad are present whenever any of them is non-zero
and absent when all are zero, since a body omitting them states a FLAT detector rather than an
unstated one.
properties:
dataset_settings:
$ref: '#/components/schemas/dataset_settings'
calibration:
$ref: '#/components/schemas/calibration_quality'
jfjoch_version:
type: string
description: Version of the program that produced this
calibration_statistics:
type: array
items:
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+164
View File
@@ -1125,6 +1125,170 @@ export type scan_result = {
}>;
};
/**
* What the powder ring fit knows about its own answer, from the covariance of the converged
* problem. Each sigma is in its parameter's own unit and is scaled by the residual scatter of
* that fit, so it is the usual "how far could this move before the fit got visibly worse".
* The two correlations are the ones that matter: a tilt and a beam-centre shift both displace a
* ring's radius as cos(phi) and are told apart only by how that amplitude grows with the ring's
* radius, so as the rings run out the pair stops being separable and these approach 1.
* The rotation sigmas and the correlations are absent when the tilt was not a free parameter.
*
*/
export type calibration_fit_sigma = {
/**
* Standard error of the fitted PONI x [pixels]
*/
beam_x_pxl?: number;
/**
* Standard error of the fitted PONI y [pixels]
*/
beam_y_pxl?: number;
/**
* Standard error of the fitted detector distance [mm]
*/
detector_distance_mm?: number;
/**
* Standard error of the fitted rot1 [rad]
*/
poni_rot1_rad?: number;
/**
* Standard error of the fitted rot2 [rad]
*/
poni_rot2_rad?: number;
/**
* Correlation between the fitted PONI x and rot1, -1 to 1
*/
correlation_beam_x_rot1?: number;
/**
* Correlation between the fitted PONI y and rot2, -1 to 1
*/
correlation_beam_y_rot2?: number;
};
/**
* Where the circle through the found spots puts the beam, and how far that is from the geometry
* actually fitted. An independent cross-check: it reads nothing from the file's own geometry, so
* it holds where the summed azimuthal profile does not - a profile binned about a badly wrong
* centre shows each ring smeared across its sectors, and a fit on it converges on the wrong
* answer without saying so. Two methods sharing no assumption, so the disagreement is the
* statement. Absent when no spots were available.
*
*/
export type calibration_spot_check = {
/**
* Beam centre x the spots vote for [pixels]
*/
beam_x_pxl?: number;
/**
* Beam centre y the spots vote for [pixels]
*/
beam_y_pxl?: number;
/**
* Detector distance the spots imply [mm]
*/
detector_distance_mm?: number;
/**
* Distance between the spots' beam centre and the fitted one [pixels]
*/
disagreement_pxl?: number;
};
/**
* What a powder calibration knows about the geometry it produced. A calibration that has gone
* wrong - the wrong standard named, a header too far out for the rings to be found - looks
* exactly like one that has not until these are read.
*
*/
export type calibration_quality = {
/**
* The powder standard the rings were fitted to, or the unit cell given in its place
*/
calibrant?: string;
/**
* How the rings were measured. rings fits the arcs of the run-summed (q x azimuth) azimuthal
* profile; spots fits the pooled per-image spot lists.
*
*/
method?: 'rings' | 'spots';
/**
* Ring measurements the fit used
*/
ring_points?: number;
/**
* Scatter of those measurements about the fitted rings, as a radial distance [pixels]. The
* single number that separates a calibration that worked from one that did not.
*
*/
rms_radial_pxl?: number;
/**
* Standard error the scatter implies on the beam centre [pixels], for a ring of that many
* points. See calibration_fit_sigma for what the fit itself says, which is not the same and
* is the larger of the two whenever the tilt is poorly separated.
*
*/
beam_sigma_pxl?: number;
/**
* Where the direct beam lands [pixels]. NOT dataset_settings.beam_x_pxl, which is the PONI:
* the two part company by distance*tan(tilt)/pixel as soon as the detector is tilted.
*
*/
direct_beam_x_pxl?: number;
/**
* Where the direct beam lands, y [pixels]
*/
direct_beam_y_pxl?: number;
/**
* The detector distance the input file declared, for comparison [mm]
*/
header_distance_mm?: number;
/**
* The distance measured from the ring radii before the fit ran [mm]. It is taken from the
* radii, the wavelength and the pixel size alone, so a large gap from header_distance_mm is
* the answer to the question the calibration was run to ask. Absent when the profile showed
* too few rings to fix a scale.
*
*/
ring_seed_distance_mm?: number;
/**
* Whether the reported rot1/rot2 were measured by this fit. False means they were declined
* and pinned at the input file's values, because the rings could not separate a tilt from a
* shift of the beam centre.
*
*/
tilt_refined?: boolean;
/**
* How many of its own sigmas the fitted tilt stands from zero. Below about 3 it is not a
* measurement of a tilt but of a beam-centre shift, and the tilt is declined. Passing does
* not certify a tilt: that estimator is limited by systematics rather than by this sigma.
*
*/
tilt_significance?: number;
fit_sigma?: calibration_fit_sigma;
spot_cross_check?: calibration_spot_check;
};
/**
* The result of a powder-ring detector calibration - what rugnux --mode calibration writes as
* <prefix>.json, and what a calibration run over the image buffer would return.
*
* dataset_settings holds the geometry and nothing else, under the property names this API gives
* them, so it can be POSTed or merged without translating a field. Its beam_x_pxl/beam_y_pxl is
* the PONI, the foot of the perpendicular from the sample; where the beam actually lands is
* calibration.direct_beam_x_pxl. The poni_rot*_rad are present whenever any of them is non-zero
* and absent when all are zero, since a body omitting them states a FLAT detector rather than an
* unstated one.
*
*/
export type calibration_output = {
dataset_settings: dataset_settings;
calibration?: calibration_quality;
/**
* Version of the program that produced this
*/
jfjoch_version?: string;
};
export type calibration_statistics = Array<{
module_number: number;
storage_cell_number: number;
+76
View File
@@ -451,6 +451,82 @@ export const zScanResult = z.object({
}))
});
/**
* What the powder ring fit knows about its own answer, from the covariance of the converged
* problem. Each sigma is in its parameter's own unit and is scaled by the residual scatter of
* that fit, so it is the usual "how far could this move before the fit got visibly worse".
* The two correlations are the ones that matter: a tilt and a beam-centre shift both displace a
* ring's radius as cos(phi) and are told apart only by how that amplitude grows with the ring's
* radius, so as the rings run out the pair stops being separable and these approach 1.
* The rotation sigmas and the correlations are absent when the tilt was not a free parameter.
*
*/
export const zCalibrationFitSigma = z.object({
beam_x_pxl: z.number().optional(),
beam_y_pxl: z.number().optional(),
detector_distance_mm: z.number().optional(),
poni_rot1_rad: z.number().optional(),
poni_rot2_rad: z.number().optional(),
correlation_beam_x_rot1: z.number().optional(),
correlation_beam_y_rot2: z.number().optional()
});
/**
* Where the circle through the found spots puts the beam, and how far that is from the geometry
* actually fitted. An independent cross-check: it reads nothing from the file's own geometry, so
* it holds where the summed azimuthal profile does not - a profile binned about a badly wrong
* centre shows each ring smeared across its sectors, and a fit on it converges on the wrong
* answer without saying so. Two methods sharing no assumption, so the disagreement is the
* statement. Absent when no spots were available.
*
*/
export const zCalibrationSpotCheck = z.object({
beam_x_pxl: z.number().optional(),
beam_y_pxl: z.number().optional(),
detector_distance_mm: z.number().optional(),
disagreement_pxl: z.number().optional()
});
/**
* What a powder calibration knows about the geometry it produced. A calibration that has gone
* wrong - the wrong standard named, a header too far out for the rings to be found - looks
* exactly like one that has not until these are read.
*
*/
export const zCalibrationQuality = z.object({
calibrant: z.string().optional(),
method: z.enum(['rings', 'spots']).optional(),
ring_points: 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' }).optional(),
rms_radial_pxl: z.number().optional(),
beam_sigma_pxl: z.number().optional(),
direct_beam_x_pxl: z.number().optional(),
direct_beam_y_pxl: z.number().optional(),
header_distance_mm: z.number().optional(),
ring_seed_distance_mm: z.number().optional(),
tilt_refined: z.boolean().optional(),
tilt_significance: z.number().optional(),
fit_sigma: zCalibrationFitSigma.optional(),
spot_cross_check: zCalibrationSpotCheck.optional()
});
/**
* The result of a powder-ring detector calibration - what rugnux --mode calibration writes as
* <prefix>.json, and what a calibration run over the image buffer would return.
*
* dataset_settings holds the geometry and nothing else, under the property names this API gives
* them, so it can be POSTed or merged without translating a field. Its beam_x_pxl/beam_y_pxl is
* the PONI, the foot of the perpendicular from the sample; where the beam actually lands is
* calibration.direct_beam_x_pxl. The poni_rot*_rad are present whenever any of them is non-zero
* and absent when all are zero, since a body omitting them states a FLAT detector rather than an
* unstated one.
*
*/
export const zCalibrationOutput = z.object({
dataset_settings: zDatasetSettings,
calibration: zCalibrationQuality.optional(),
jfjoch_version: z.string().optional()
});
export const zCalibrationStatistics = z.array(z.object({
module_number: 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' }),
storage_cell_number: 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' }),
+12
View File
@@ -13,6 +13,7 @@
#include "../common/JFJochMath.h"
#include <nlohmann/json.hpp>
#include "Calibration_output.h"
#include "Dataset_settings.h"
#include "../image_analysis/geom_refinement/AssignSpotsToRings.h"
#include "../image_analysis/geom_refinement/Calibrants.h"
@@ -262,6 +263,17 @@ TEST_CASE("Calibration_JsonIsADatasetSettingsBody", "[DetGeomCalib]") {
REQUIRE(j.contains("dataset_settings"));
const auto &settings = j.at("dataset_settings");
// The WHOLE file is a calibration_output, not just its geometry member - so the quality block a
// reader needs in order to tell a calibration that worked from one that did not is part of the
// published contract too, and a python client can decode the file without knowing anything else.
org::openapitools::server::model::Calibration_output output;
REQUIRE_NOTHROW(from_json(j, output));
std::stringstream output_msg;
CHECK(output.validate(output_msg));
CHECK(output.getCalibration().getRingPoints() == 321);
CHECK(output.getCalibration().getMethod() == "rings");
CHECK(output.getCalibration().isTiltRefined());
// Every key is a property the schema knows, and the four it requires are all there.
org::openapitools::server::model::Dataset_settings model;
REQUIRE_NOTHROW(from_json(settings, model));