From cc334c5c55f8d307a3b2baaa9f559ed0b9a31089 Mon Sep 17 00:00:00 2001 From: leonarski_f Date: Sat, 22 Aug 2026 22:33:30 +0200 Subject: [PATCH] Name the right rotation in the NXmx frame comment The comment said internal-to-McStas is 180 degrees about x. It is 180 degrees about z: internal (a,b,c) maps to McStas (-a,-b,+c), which is what makes the written vectors correct - internal +y becomes (0,-1,0), the -x of Rx(-rot2) becomes (1,0,0), and the -z of Rz(-rot3) is unchanged. 180 degrees about x is the internal-to-imgCIF relation, one step further on, and it is the frame the verification was done in - which is why the vectors are right and only the prose was wrong. Re-measured after the change: still 1.6e-6 mm over nine tilt settings. Co-Authored-By: Claude Opus 5 (1M context) --- writer/HDF5NXmx.cpp | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/writer/HDF5NXmx.cpp b/writer/HDF5NXmx.cpp index 866aa7d8..0762b05f 100644 --- a/writer/HDF5NXmx.cpp +++ b/writer/HDF5NXmx.cpp @@ -665,8 +665,11 @@ void NXmx::Metrology(const StartMessage &start, const EndMessage &end) { // Jungfraujoch holds the tilt in the PyFAI PONI convention, poni_rot = Rz(-rot3)*Rx(-rot2)*Ry(+rot1) // (DiffractionGeometry::UpdatePoniRotMatrix), written in the internal frame: x along increasing // column, y along increasing row, z along the beam. NXmx uses McStas, which is that frame turned - // 180 degrees about x - a proper rotation, not a mirror - so rotations about y and z reverse sense - // while those about x keep it. Hence the axis vectors below. A depends_on chain applies the + // 180 degrees about z - a proper rotation, not a mirror - so rotations about x and y reverse sense + // while those about z keep it. Hence the axis vectors below: internal +y becomes (0,-1,0), the + // -x of Rx(-rot2) becomes (1,0,0), and the -z of Rz(-rot3) is unchanged. (Do not confuse this + // with the internal-to-imgCIF relation, which IS 180 degrees about x - that is the frame DIALS + // reports in, one step further on.) A depends_on chain applies the // DEEPEST dependency first, so rot3 sits at the root to make the product R_rot3*R_rot2*R_rot1. SaveScalar(transformations, "rot1", rot1)-> Transformation("rad",