Files
Jungfraujoch/common/GoniometerAxis.cpp
Filip Leonarski 31a357fa57
All checks were successful
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 11m0s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 11m2s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 11m54s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 8m20s
Build Packages / Generate python client (push) Successful in 24s
Build Packages / Build documentation (push) Successful in 56s
Build Packages / Create release (push) Has been skipped
Build Packages / build:rpm (rocky8) (push) Successful in 8m51s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 9m9s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 8m53s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 8m21s
Build Packages / build:rpm (rocky9) (push) Successful in 9m47s
Build Packages / Unit tests (push) Successful in 1h13m38s
v1.0.0-rc.113 (#19)
This is an UNSTABLE release and not recommended for production use (please use rc.111 instead).

* jfjoch_broker: Improve handling of rotation indexing
* jfjoch_broker: More information saved in CBOR end message (WIP)
* jfjoch_writer: Save rotation indexing lattice parameters and Niggli class
* jfjoch_viewer: Remove (for now) primitive cell information

Reviewed-on: #19
Co-authored-by: Filip Leonarski <filip.leonarski@psi.ch>
Co-committed-by: Filip Leonarski <filip.leonarski@psi.ch>
2025-12-02 09:29:22 +01:00

129 lines
4.2 KiB
C++

// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
// SPDX-License-Identifier: GPL-3.0-only
#include <cmath>
#include "GoniometerAxis.h"
#include "JFJochException.h"
#define check_finite(param, val) if (!std::isfinite(val)) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, param)
GoniometerAxis::GoniometerAxis(const std::string& in_name,
float in_start,
float in_increment,
const Coord &in_axis,
const std::optional<Coord> &in_helical_step) {
if (in_name.empty())
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Name of goniometer axis cannot be empty");
check_finite("Rotation angle increment", in_increment);
check_finite("Rotation angle start", in_start);
if (in_axis.Length() == 0.0f)
throw JFJochException(JFJochExceptionCategory::InputParameterInvalid,
"Rotation axis cannot have 0 length");
name = in_name;
start = in_start;
increment = in_increment;
axis = in_axis.Normalize(); // Make sure rotation axis is normalized!
helical_step = in_helical_step;
}
std::string GoniometerAxis::GetName() const {
return name;
}
float GoniometerAxis::GetStart_deg() const {
return start;
}
float GoniometerAxis::GetIncrement_deg() const {
return increment;
}
Coord GoniometerAxis::GetAxis() const {
return axis;
}
std::optional<Coord> GoniometerAxis::GetHelicalStep() const {
return helical_step;
}
Coord GoniometerAxis::GetPosition(int64_t image_number) const {
return helical_step.value_or(Coord()) * static_cast<float>(image_number);
}
float GoniometerAxis::GetAngle_deg(float image_number) const {
return start + increment * image_number;
}
std::vector<double> GoniometerAxis::GetAxisVector() const {
return {axis[0], axis[1], axis[2]};
}
std::vector<double> GoniometerAxis::GetXContainer_m(int64_t max_image_number) const {
if (!helical_step.has_value())
return {};
std::vector<double> angle_container(max_image_number);
for (int32_t i = 0; i < max_image_number; i++)
angle_container[i] = helical_step->x * i * 1e-6;
return angle_container;
}
std::vector<double> GoniometerAxis::GetYContainer_m(int64_t max_image_number) const {
if (!helical_step.has_value())
return {};
std::vector<double> angle_container(max_image_number);
for (int32_t i = 0; i < max_image_number; i++)
angle_container[i] = helical_step->y * i * 1e-6;
return angle_container;
}
std::vector<double> GoniometerAxis::GetZContainer_m(int64_t max_image_number) const {
if (!helical_step.has_value())
return {};
std::vector<double> angle_container(max_image_number);
for (int32_t i = 0; i < max_image_number; i++)
angle_container[i] = helical_step->z * i * 1e-6;
return angle_container;
}
std::vector<double> GoniometerAxis::GetAngleContainer(int64_t max_image_number) const {
std::vector<double> angle_container(max_image_number);
for (int32_t i = 0; i < max_image_number; i++)
angle_container[i] = GetAngle_deg(i);
return angle_container;
}
GoniometerAxis &GoniometerAxis::ScreeningWedge(const std::optional<float> &input) {
screening_wedge = input;
return *this;
}
std::optional<float> GoniometerAxis::GetScreeningWedge() const {
return screening_wedge;
}
float GoniometerAxis::GetWedge_deg() const {
if (!screening_wedge.has_value())
return GetIncrement_deg();
return *screening_wedge;
}
std::vector<double> GoniometerAxis::GetAngleContainerEnd(int64_t max_image_number) const {
float wedge = GetWedge_deg();
std::vector<double> angle_container(max_image_number);
for (int32_t i = 0; i < max_image_number; i++)
angle_container[i] = GetAngle_deg(i) + wedge;
return angle_container;
}
RotMatrix GoniometerAxis::GetTransformation(int64_t image_number) const {
// Transformation goes back from rotated to "start"
auto angle_deg = GetAngle_deg(image_number);
auto angle_rad = angle_deg / 180.0f * static_cast<float>(M_PI);
return {angle_rad, axis};
}