Carry the sample transformation chain as DetectorTransformation
Replaces the start-message TransformationAxis of the previous commit, which was the wrong shape in two ways. DetectorTransformation (common/) mirrors a NeXus NXtransformations axis and holds nothing else: name, type, units, vector, offset, depends_on and the positions themselves. Deliberately without cleverness - the values are either a single number for an axis that does not move or one per image, and nothing derives a position from a start and an increment. That is the point: a producer will later want to report where a stage actually WENT rather than where it was told to go, and a structure that stores start+increment cannot express that. A million images cost 4 MB per axis, which is not a reason to be clever. Hence also the move to the END message: measured positions are only known once the run is over. And hence no metadata version bump, which the previous commit did make. The chain is optional; when it is absent the writer builds the identical chain from the start message, exactly as before. Nothing on the wire changes for a producer that does not send it, so a broker and a writer of different releases still interwork - the constraint the previous version stated is withdrawn. The writer transcribes a chain it is given, without recomputing an angle, which is what makes measured positions possible end to end. JFJochReader_TransformationChain_SentAndBuilt writes the same run both ways and checks the two files read back the same, chi/phi included. CBORSerialize_End_Transformations covers the wire 1:1, asserting the order survives and that a moving axis keeps one value per image while a stationary one keeps a single value. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,106 @@
|
||||
// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#include <utility>
|
||||
|
||||
#include "DetectorTransformation.h"
|
||||
|
||||
DetectorTransformation::DetectorTransformation(std::string name, TransformationType type,
|
||||
const Coord &vector)
|
||||
: name(std::move(name)), type(type), vector(vector) {
|
||||
units = (type == TransformationType::Rotation) ? "deg" : "m";
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::Name(const std::string &input) {
|
||||
name = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::Type(TransformationType input) {
|
||||
type = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::Units(const std::string &input) {
|
||||
units = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::Vector(const Coord &input) {
|
||||
vector = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::Offset(const Coord &input) {
|
||||
offset = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::DependsOn(const std::string &input) {
|
||||
depends_on = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::Equipment(const std::string &input) {
|
||||
equipment = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::EquipmentComponent(const std::string &input) {
|
||||
equipment_component = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::Values(const std::vector<float> &input) {
|
||||
values = input;
|
||||
return *this;
|
||||
}
|
||||
|
||||
DetectorTransformation &DetectorTransformation::Value(float input) {
|
||||
values = {input};
|
||||
return *this;
|
||||
}
|
||||
|
||||
const std::string &DetectorTransformation::GetName() const {
|
||||
return name;
|
||||
}
|
||||
|
||||
TransformationType DetectorTransformation::GetType() const {
|
||||
return type;
|
||||
}
|
||||
|
||||
const std::string &DetectorTransformation::GetUnits() const {
|
||||
return units;
|
||||
}
|
||||
|
||||
Coord DetectorTransformation::GetVector() const {
|
||||
return vector;
|
||||
}
|
||||
|
||||
Coord DetectorTransformation::GetOffset() const {
|
||||
return offset;
|
||||
}
|
||||
|
||||
const std::string &DetectorTransformation::GetDependsOn() const {
|
||||
return depends_on;
|
||||
}
|
||||
|
||||
const std::string &DetectorTransformation::GetEquipment() const {
|
||||
return equipment;
|
||||
}
|
||||
|
||||
const std::string &DetectorTransformation::GetEquipmentComponent() const {
|
||||
return equipment_component;
|
||||
}
|
||||
|
||||
const std::vector<float> &DetectorTransformation::GetValues() const {
|
||||
return values;
|
||||
}
|
||||
|
||||
bool DetectorTransformation::IsRotation() const {
|
||||
return type == TransformationType::Rotation;
|
||||
}
|
||||
|
||||
bool DetectorTransformation::IsConstant() const {
|
||||
return values.size() <= 1;
|
||||
}
|
||||
Reference in New Issue
Block a user