19#ifndef __stir_IO_PETSIRDInfo_helpers_H__
20#define __stir_IO_PETSIRDInfo_helpers_H__
58using Mat3 = std::array<std::array<float, 3>, 3>;
59using Vec3 = std::array<float, 3>;
69 std::array<std::array<float, 3>, 3> result{};
70 for (
int i = 0; i < 3; ++i)
71 for (
int j = 0; j < 3; ++j)
72 result[j][i] = mat[i][j];
85 std::array<std::array<float, 3>, 3> result{};
86 for (
size_t i = 0; i < 3; ++i)
87 for (
size_t j = 0; j < 3; ++j)
88 result[i][j] = A[i][j] - B[i][j];
101 0.5f * (S[2][1] - S[1][2]),
102 0.5f * (S[0][2] - S[2][0]),
103 0.5f * (S[1][0] - S[0][1])
132get_spacing_uniform(std::vector<float>& spacing,
const std::set<float>& unsorted_block_poss,
double epsilon = 1e-4)
134 std::vector<float> sorted_z(unsorted_block_poss.begin(), unsorted_block_poss.end());
135 for (
size_t i = 1; i < sorted_z.size(); ++i)
137 spacing.push_back(std::abs(sorted_z[i] - sorted_z[i - 1]));
140 return std::all_of(spacing.begin(), spacing.end(), [&](
float s) { return std::abs(s - spacing.front()) <= epsilon; });
153const std::set<float>&
156 const std::set<float>* largest = &x;
157 if (y.size() > largest->size())
161 if (z.size() > largest->size())
176 for (
float val : input)
191 for (
size_t row = 0; row < input.size(); ++row)
192 for (
size_t col = 0; col < input[row].size(); ++col)
193 values.insert(input[row][col]);
199almostEqual(
double a,
double b,
double tol = 1e-6)
201 return std::fabs(a - b) <= tol;
208 std::size_t& groupSize_dim2,
209 std::size_t& groupSize_dim3,
212 const std::size_t n = pts.size();
213 groupSize_dim2 = groupSize_dim3 = 0;
226 const float x0 = pts[0].x();
227 const float z0 = pts[0].z();
230 std::size_t runLen = 1;
231 while (runLen < n && almostEqual(pts[runLen].x(), x0, tol) && almostEqual(pts[runLen].z(), z0, tol))
236 groupSize_dim2 = runLen;
239 if (groupSize_dim2 == 0 || n % groupSize_dim2 != 0)
242 groupSize_dim3 = n / groupSize_dim2;
245 for (std::size_t b = 0; b < groupSize_dim3; ++b)
247 std::size_t start = b * groupSize_dim2;
248 float xb = pts[start].x();
249 float zb = pts[start].z();
251 for (std::size_t i = 1; i < groupSize_dim2; ++i)
253 const auto& p = pts[start + i];
254 if (!almostEqual(p.x(), xb, tol) || !almostEqual(p.z(), zb, tol))
262 for (std::size_t b = 1; b < groupSize_dim3; ++b)
264 float z_prev = pts[(b - 1) * groupSize_dim2].z();
265 float z_curr = pts[b * groupSize_dim2].z();
266 if (almostEqual(z_prev, z_curr, tol))
defines the stir::CartesianCoordinate3D<coordT> class
a templated class for 3-dimensional coordinates.
Definition CartesianCoordinate3D.h:53
Declaration of stir::info().
Lightweight 3x3 matrix and 3D vector helpers used during PETSIRD geometry analysis.
Vec3 getAxisFromSkew(const Mat3 &S)
Extract rotation axis from the skew-symmetric matrix S = R - R^T.
Definition PETSIRDInfo_helpers.h:98
Mat3 subtract(const Mat3 &A, const Mat3 &B)
Subtract two 3x3 matrices (A - B).
Definition PETSIRDInfo_helpers.h:83
Mat3 transpose(const Mat3 &mat)
Transpose a 3x3 matrix.
Definition PETSIRDInfo_helpers.h:67
Helpers for spacing analysis and axis inference from coordinate sets.
const std::set< float > & get_largest_vector(const std::set< float > &x, const std::set< float > &y, const std::set< float > &z)
Return the largest of three sets and report inferred axial direction.
Definition PETSIRDInfo_helpers.h:154
void find_unique_values_2D(std::set< float > &values, const std::vector< std::vector< float > > &input)
Collect unique values from a 2D vector (matrix).
Definition PETSIRDInfo_helpers.h:189
bool get_spacing_uniform(std::vector< float > &spacing, const std::set< float > &unsorted_block_poss, double epsilon=1e-4)
Compute spacings between sorted unique values and test uniformity.
Definition PETSIRDInfo_helpers.h:132
void find_unique_values_1D(std::set< float > &values, const std::vector< float > &input)
Collect unique values from a 1D vector.
Definition PETSIRDInfo_helpers.h:174