report: the measured tilt, and one geometry instead of two
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 9m28s
Build Packages / build:windows:nocuda (push) Successful in 17m21s
Build Packages / build:windows:cuda (push) Successful in 19m41s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 19m57s
Build Packages / build:viewer-tgz:cpu (push) Successful in 20m58s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 22m43s
Build Packages / build:viewer-tgz:cuda (push) Successful in 23m28s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 27m46s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 27m47s
Build Packages / build:rugnux:windows (push) Successful in 11m26s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 19m24s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 22m12s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 26m56s
Build Packages / build:rpm (rocky9) (push) Successful in 23m46s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 23m48s
Build Packages / build:rpm (rocky8) (push) Successful in 29m28s
Build Packages / Generate python client (push) Successful in 34s
Build Packages / Create release (push) Skipped
Build Packages / Build documentation (push) Successful in 1m32s
Build Packages / XDS test (durin plugin) (push) Successful in 11m33s
Build Packages / DIALS test (push) Successful in 26m43s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 27m55s
Build Packages / XDS test (neggia plugin) (push) Successful in 9m18s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 9m56s
Build Packages / Unit tests (push) Successful in 2h43m15s
Build Packages / build:rugnux:aarch64 (cross) (push) Successful in 9m28s
Build Packages / build:windows:nocuda (push) Successful in 17m21s
Build Packages / build:windows:cuda (push) Successful in 19m41s
Build Packages / build:rugnux-tgz (x86_64) (push) Successful in 19m57s
Build Packages / build:viewer-tgz:cpu (push) Successful in 20m58s
Build Packages / build:rpm (rocky9_nocuda) (push) Successful in 22m43s
Build Packages / build:viewer-tgz:cuda (push) Successful in 23m28s
Build Packages / build:rpm (rocky8_nocuda) (push) Successful in 27m46s
Build Packages / build:rpm (ubuntu2204_nocuda) (push) Successful in 27m47s
Build Packages / build:rugnux:windows (push) Successful in 11m26s
Build Packages / build:rpm (ubuntu2404_nocuda) (push) Successful in 19m24s
Build Packages / build:rpm (rocky9_sls9) (push) Successful in 22m12s
Build Packages / build:rpm (rocky8_sls9) (push) Successful in 26m56s
Build Packages / build:rpm (rocky9) (push) Successful in 23m46s
Build Packages / build:rpm (ubuntu2404) (push) Successful in 23m48s
Build Packages / build:rpm (rocky8) (push) Successful in 29m28s
Build Packages / Generate python client (push) Successful in 34s
Build Packages / Create release (push) Skipped
Build Packages / Build documentation (push) Successful in 1m32s
Build Packages / XDS test (durin plugin) (push) Successful in 11m33s
Build Packages / DIALS test (push) Successful in 26m43s
Build Packages / build:rpm (ubuntu2204) (push) Successful in 27m55s
Build Packages / XDS test (neggia plugin) (push) Successful in 9m18s
Build Packages / XDS test (JFJoch plugin) (push) Successful in 9m56s
Build Packages / Unit tests (push) Successful in 2h43m15s
Adds REFINED_DETECTOR_TILT - rot1/rot2 in degrees as rotation indexing measured them - so the value can be checked against a powder calibration, which measures the tilt from ring shape and is the better instrument for it. rot3 is not carried: a rotation about the beam is an exact null of a single-axis rotation experiment, so the fit cannot move it and printing it would suggest otherwise. Also repairs two defects in the commit that added DETECTOR_TILT, found in review. The geometry was taken from the caller's copy of the experiment, which is the state BEFORE the run, while BEAM_CENTRE and DETECTOR_DISTANCE come from result.used_*, which is the state after - so on a rotation two-pass the report mixed a post-refined centre with the file's rotations and DIRECT_BEAM was off by the whole post-refinement shift. JFJOCH_DATASET_SETTINGS carried the same mixture, which is a geometry no pass ever ran at. The tilt and the direct beam are now taken from experiment_ alongside the other three, so the block describes one geometry. And the prose claimed the tilt "is not refined here". It is: rotation indexing refines rot1/rot2 on every rotation run. What is true is that the result is never written back onto the geometry, which is why it needs a key of its own. M_PI -> PI (common/JFJochMath.h). rugnux is in the forced-Windows viewer-only set and M_PI is not portable to MSVC; the file did not include <cmath> either. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EFEJG6WBQv8th4UJFNe53N
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
* `rugnux` ranks screw axes on the evidence their absences carry, rather than on how many control reflections a candidate happens to have.
|
||||
* 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.
|
||||
* 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
|
||||
|
||||
+23
-10
@@ -7,6 +7,7 @@
|
||||
|
||||
#include <spdlog/fmt/fmt.h>
|
||||
|
||||
#include "../common/JFJochMath.h" // PI - M_PI is not portable to MSVC
|
||||
#include "../common/GitInfo.h"
|
||||
#include "../common/time_utc.h"
|
||||
#include "../image_analysis/scale_merge/AnisotropyAnalysis.h"
|
||||
@@ -96,20 +97,31 @@ std::string RenderResultReport(const std::string &output_prefix,
|
||||
// beam lands, and the two were previously indistinguishable in this report because only one of
|
||||
// them was printed. Degrees here; the JSON below carries radians, as the API spells it.
|
||||
{
|
||||
const auto &g = experiment.GetDiffractionGeometry();
|
||||
constexpr double DEG = 180.0 / M_PI;
|
||||
const auto direct = g.GetDirectBeam_pxl();
|
||||
Key(os, "DETECTOR_TILT", fmt::format("{:.4f} {:.4f} {:.4f}", g.GetPoniRot1_rad() * DEG,
|
||||
g.GetPoniRot2_rad() * DEG, g.GetPoniRot3_rad() * DEG));
|
||||
Key(os, "DIRECT_BEAM", fmt::format("{:.2f} {:.2f}", direct.first, direct.second));
|
||||
Key(os, "DETECTOR_TILT", fmt::format("{:.4f} {:.4f} {:.4f}", result.used_detector_tilt_deg[0],
|
||||
result.used_detector_tilt_deg[1],
|
||||
result.used_detector_tilt_deg[2]));
|
||||
Key(os, "DIRECT_BEAM", fmt::format("{:.2f} {:.2f}", result.used_direct_beam_x_pxl,
|
||||
result.used_direct_beam_y_pxl));
|
||||
if (result.refined_detector_tilt_deg)
|
||||
Key(os, "REFINED_DETECTOR_TILT",
|
||||
fmt::format("{:.4f} {:.4f}", (*result.refined_detector_tilt_deg)[0],
|
||||
(*result.refined_detector_tilt_deg)[1]));
|
||||
}
|
||||
os << "\n"
|
||||
<< " The distance and beam centre above are the ones this result was integrated at, which on\n"
|
||||
<< " a rotation run is the post-refined geometry rather than the values in the input file.\n"
|
||||
<< " DETECTOR_TILT is rot1/rot2/rot3 in degrees, as the run used them - it is not refined here.\n"
|
||||
<< " DETECTOR_TILT is rot1/rot2/rot3 in degrees, as the run INTEGRATED at them. Rotation\n"
|
||||
<< " indexing does refine rot1/rot2, but the result is never written back onto the geometry,\n"
|
||||
<< " so what it measured is reported separately as REFINED_DETECTOR_TILT.\n"
|
||||
<< " BEAM_CENTRE is the PONI and DIRECT_BEAM is where the beam actually lands; they differ by\n"
|
||||
<< " distance*tan(tilt)/pixel and are identical only when the tilt is zero. Quote whichever the\n"
|
||||
<< " program you are feeding expects, and check which one it means.\n";
|
||||
if (result.refined_detector_tilt_deg)
|
||||
os << " REFINED_DETECTOR_TILT is rot1/rot2 in degrees as rotation indexing MEASURED them, and is\n"
|
||||
<< " NOT what this run integrated at - nothing writes a refined tilt back onto the geometry.\n"
|
||||
<< " It is here to be checked against a powder calibration, which measures the tilt from ring\n"
|
||||
<< " SHAPE and is the better instrument for it. rot3 is omitted because a rotation about the\n"
|
||||
<< " beam is an exact null of this experiment and the fit cannot move it.\n";
|
||||
|
||||
// The same geometry once more, as the object jfjoch_broker takes it in: the four required
|
||||
// properties of dataset_settings in broker/jfjoch_api.yaml, spelled the way the API spells them.
|
||||
@@ -122,12 +134,13 @@ std::string RenderResultReport(const std::string &output_prefix,
|
||||
// poni_rot1/2/3_rad, and a block that omits them describes a FLAT detector - a different
|
||||
// geometry from the one this run used, silently, on every tilted setup. Omitted when zero
|
||||
// because the API's own default is 0.0, so the shorter block means the same thing.
|
||||
const auto &g = experiment.GetDiffractionGeometry();
|
||||
constexpr double RAD = PI / 180.0;
|
||||
const auto &t = result.used_detector_tilt_deg;
|
||||
std::string rot;
|
||||
if (g.GetPoniRot1_rad() != 0.0f || g.GetPoniRot2_rad() != 0.0f || g.GetPoniRot3_rad() != 0.0f)
|
||||
if (t[0] != 0.0 || t[1] != 0.0 || t[2] != 0.0)
|
||||
rot = fmt::format(R"(, "poni_rot1_rad": {:.6f}, "poni_rot2_rad": {:.6f}, )"
|
||||
R"("poni_rot3_rad": {:.6f})",
|
||||
g.GetPoniRot1_rad(), g.GetPoniRot2_rad(), g.GetPoniRot3_rad());
|
||||
t[0] * RAD, t[1] * RAD, t[2] * RAD);
|
||||
Key(os, "JFJOCH_DATASET_SETTINGS",
|
||||
fmt::format(R"({{"beam_x_pxl": {:.2f}, "beam_y_pxl": {:.2f}, "detector_distance_mm": {:.3f}, )"
|
||||
R"("incident_energy_keV": {:.4f}{}}})",
|
||||
|
||||
@@ -3125,6 +3125,12 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
|
||||
end_msg.refined_poni_rot1 = rot->geom.GetPoniRot1_rad();
|
||||
end_msg.refined_poni_rot2 = rot->geom.GetPoniRot2_rad();
|
||||
end_msg.refined_poni_rot3 = rot->geom.GetPoniRot3_rad();
|
||||
// rot3 is not carried: a rotation about the beam is an exact null of this experiment
|
||||
// (measured, smallest eigenvalue -5e-16), so the fit never moves it and reporting it would
|
||||
// suggest it had been determined.
|
||||
result.refined_detector_tilt_deg = std::array<double, 2>{
|
||||
rot->geom.GetPoniRot1_rad() * 180.0 / PI,
|
||||
rot->geom.GetPoniRot2_rad() * 180.0 / PI};
|
||||
if (rot->axis)
|
||||
end_msg.refined_rotation_axis = rot->axis->GetAxis();
|
||||
end_msg.rotation_lattice_type = LatticeMessage{
|
||||
@@ -4555,5 +4561,14 @@ ProcessResult Rugnux::RunPipeline(RugnuxObserver *observer, bool write_output, b
|
||||
result.used_beam_x_pxl = experiment_.GetBeamX_pxl();
|
||||
result.used_beam_y_pxl = experiment_.GetBeamY_pxl();
|
||||
result.used_distance_mm = experiment_.GetDetectorDistance_mm();
|
||||
{
|
||||
const auto &g = experiment_.GetDiffractionGeometry();
|
||||
constexpr double DEG = 180.0 / PI;
|
||||
result.used_detector_tilt_deg = {g.GetPoniRot1_rad() * DEG, g.GetPoniRot2_rad() * DEG,
|
||||
g.GetPoniRot3_rad() * DEG};
|
||||
const auto direct = g.GetDirectBeam_pxl();
|
||||
result.used_direct_beam_x_pxl = direct.first;
|
||||
result.used_direct_beam_y_pxl = direct.second;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -206,6 +206,17 @@ struct ProcessResult {
|
||||
// Truncating cannot be undone and refinement can downweight, so the data are cut generously and this
|
||||
// is the number to quote. Empty when no automatic cut ran (a manual limit, or the method turned off).
|
||||
std::optional<double> resolution_fit_A;
|
||||
// Detector tilt (PONI rot1/rot2, degrees) as rotation indexing MEASURED it, which is not what the
|
||||
// run integrated at - nothing writes a refined tilt back onto the experiment. Reported so the value
|
||||
// can be checked against a powder calibration or handed to another program; empty on stills and
|
||||
// when no rotation lattice was finalized.
|
||||
std::optional<std::array<double, 2>> refined_detector_tilt_deg;
|
||||
// The tilt this pass integrated at, and where the beam actually lands under it - taken from the
|
||||
// same experiment_ as used_beam_*/used_distance_mm, so the four describe ONE geometry. Reading any
|
||||
// of them off the caller's pre-run copy instead would mix a post-refined centre with the file's
|
||||
// rotations, which is a geometry no pass ever ran at.
|
||||
std::array<double, 3> used_detector_tilt_deg{};
|
||||
double used_direct_beam_x_pxl = 0.0, used_direct_beam_y_pxl = 0.0;
|
||||
std::optional<UnitCell> consensus_cell;
|
||||
bool rotation_lattice_found = false;
|
||||
MeanProcessingTime mean_processing_time{};
|
||||
|
||||
Reference in New Issue
Block a user