diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 53fc10e73..ae1f9add3 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -17,6 +17,7 @@ * Twinning is no longer reported when the L-test contradicts it. * The `rugnux` report gives the detector tilt and the direct beam beside the beam centre, and carries the tilt in the `dataset_settings` block. * The `rugnux` report gives the detector tilt rotation indexing measured, so it can be checked against a powder calibration. +* `--no-refine-tilt` holds the detector tilt at the value in the file, instead of zeroing it, when the calibration starts from the spots. * The `jfjoch_viewer` grid scan view draws the cells in the proportion of the scan steps, so the map has the shape of the scanned area. ### 1.0.0-rc.165 diff --git a/image_analysis/geom_refinement/PowderCalibration.cpp b/image_analysis/geom_refinement/PowderCalibration.cpp index 2e4c45604..b583a6a00 100644 --- a/image_analysis/geom_refinement/PowderCalibration.cpp +++ b/image_analysis/geom_refinement/PowderCalibration.cpp @@ -295,7 +295,12 @@ CalibrationResult CalibrateFromProfile(const std::vector &profile, && (best->uncertainty.sigma_rot1_rad > 0.0 || best->uncertainty.sigma_rot2_rad > 0.0); const float significance = tilt_was_free ? TiltSignificance(best->geometry, best->uncertainty) : 0.0f; bool tilt_refined = refine_tilt && tilt_was_free && significance >= TILT_MIN_SIGNIFICANCE; - if (refine_tilt && !tilt_refined) { + // Not `refine_tilt && !tilt_refined`: with --no-refine-tilt the tilt is never free, so + // tilt_refined is false and this branch was skipped entirely - leaving the rotations at the ZERO + // that GuessInitialGeometry sets, while the CLI reported them as held at the header value. A + // declined tilt and a tilt nobody asked to refine both need the header put back and the rest + // refitted around it. + if (!tilt_refined) { // From the header's tilt, not from the one being declined. fit_from now takes a whole geometry, // so without this the "pinned" refit would pin rot1/rot2 at exactly the unvalidated values the // gate just rejected - which is the same fault the gate exists to catch, reintroduced one level @@ -346,7 +351,12 @@ CalibrationResult CalibrateFromSpots(const std::vector &spots, && (unc.sigma_rot1_rad > 0.0 || unc.sigma_rot2_rad > 0.0); const float significance = tilt_was_free ? TiltSignificance(fitted, unc) : 0.0f; const bool tilt_refined = refine_tilt && tilt_was_free && significance >= TILT_MIN_SIGNIFICANCE; - if (refine_tilt && !tilt_refined) { + // Not `refine_tilt && !tilt_refined`: with --no-refine-tilt the tilt is never free, so + // tilt_refined is false and this branch was skipped entirely - leaving the rotations at the ZERO + // that GuessInitialGeometry sets, while the CLI reported them as held at the header value. A + // declined tilt and a tilt nobody asked to refine both need the header put back and the rest + // refitted around it. + if (!tilt_refined) { fitted.PoniRot1_rad(geom.GetPoniRot1_rad()).PoniRot2_rad(geom.GetPoniRot2_rad()); OptimizeGeometry(fitted, spots, calibrant_ring_q, false, &unc); }