From c0a486bf99b1a788aea0aa5ba41f7daa0c387809 Mon Sep 17 00:00:00 2001 From: Filip Leonarski Date: Mon, 9 Nov 2026 16:25:13 +0100 Subject: [PATCH] Stills -C hypothesis: fit de novo first, then the cell given from the de novo geometry Fitted from the file's geometry, a right cell on weak frames settled as far off as the start (a start 3% short ended 3% long), lost the comparison to the de novo cell and the run was processed as without -C. The frames are now fitted de novo first, as without -C, and the cell given from the distance, centre and module placement that fit found; the de novo fit, whose cell takes up the start's error, is the nearer start for any cell of the sample. The same-detector rule counts only where the cell given was actually fitted. Where nothing indexes de novo, the cell given is fitted from the file's geometry as before. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK (cherry picked from commit 610298396a0cb2169859922f554bcc652f78921d) --- docs/CPU_DATA_ANALYSIS_INDEXING.md | 7 ++++-- rugnux/RugnuxStills.cpp | 39 ++++++++++++++++++------------ 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/docs/CPU_DATA_ANALYSIS_INDEXING.md b/docs/CPU_DATA_ANALYSIS_INDEXING.md index 00407e7f4..673df990d 100644 --- a/docs/CPU_DATA_ANALYSIS_INDEXING.md +++ b/docs/CPU_DATA_ANALYSIS_INDEXING.md @@ -427,8 +427,11 @@ from (scale, each length, each angle) and how far the distance moved. A distance cell in any setting of the same lattice, and are described on its axes. With `-C` the cell given is also tested as a hypothesis against the cell the frames index to de novo. -Both are fitted from the file's geometry - the cell given as above, the de novo one as without `-C` - and -each, with its refined cell and geometry, indexes the same sample of frames. The cell given is kept where +The frames are first fitted de novo from the file's geometry, as without `-C`, and the cell given is then fitted +from the detector distance, centre and module placement that fit found: from a start several percent off, a fit +can settle as far off as it started, and the de novo fit, whose cell takes up the start's error, is the nearer +start for any cell of the sample. Each, with its refined cell and geometry, then indexes the same sample of +frames. The cell given is kept where it puts at least 0.9 times as many of the sample's spots on the lattice, and also where it does not but its fit puts the detector within 2 % of where the de novo fit puts it: the detector is the same for every crystal of the run, so such a cell is a crystal form of the sample (possibly a minority one, which the diff --git a/rugnux/RugnuxStills.cpp b/rugnux/RugnuxStills.cpp index 5234429af..25483b486 100644 --- a/rugnux/RugnuxStills.cpp +++ b/rugnux/RugnuxStills.cpp @@ -716,15 +716,18 @@ void Rugnux::RefineStillsGeometry(int start_image, int end_image, int images_to_ // The cell given (-C) is a hypothesis, and the cell the frames index to de novo another. A cell of the wrong shape // still indexes the frames, at a distance of its own: given 4% too long with its beta 4 degrees off, a cell // indexed the frames of a crystal at a distance 7% too long, refined towards its own shape there, and merged to -// CC1/2 0.4 where the run without -C merged to 0.9. Each hypothesis is fitted from the file's geometry - the -// cell given as RefineStillsGeometry fits it, and de novo as it does without -C - and each is then indexed with -// its refined cell and geometry on the same sample of frames, as DecideStillsGeometry tries its centres and -// distances. The cell given is kept where it puts as many of the sample's spots on the lattice, or nearly -// (GIVEN_KEPT_ABOVE, as a file's centre is kept), and also where it does not but its fit puts the detector where -// the de novo fit puts it: the detector is the same for every crystal of the run, so a cell that fits at the -// same distance is a crystal form of the sample - a minority one, which the user may ask for - and only a cell -// that needs a detector of its own describes no crystal of it. Otherwise the run goes on as it would without -// -C, from the de novo hypothesis, and says so. +// CC1/2 0.4 where the run without -C merged to 0.9. The frames are first fitted de novo from the file's geometry, +// as without -C, and the cell given is then fitted from where that put the detector: a cell fitted from a start +// distance 5% off can settle as far off as it started (a right cell on weak frames moved 6% from a start 3% off), +// and the de novo fit, whose cell takes up the start's error, is the nearer start for any cell of the sample. Each +// is then indexed with its refined cell and geometry on the same sample of frames, as DecideStillsGeometry tries +// its centres and distances. The cell given is kept where it puts as many of the sample's spots on the lattice, +// or nearly (GIVEN_KEPT_ABOVE, as a file's centre is kept), and also where it does not but its fit puts the +// detector where the de novo fit puts it: the detector is the same for every crystal of the run, so a cell that +// fits at the same distance is a crystal form of the sample - a minority one, which the user may ask for - and +// only a cell that needs a detector of its own describes no crystal of it. Otherwise the run goes on as it would +// without -C, from the de novo hypothesis, and says so. Where nothing indexes de novo, the cell given is fitted +// from the file's geometry, as without this test. void Rugnux::RefineStillsGeometryOrDeNovo(int start_image, int end_image, int images_to_process, RugnuxObserver *observer) { Logger logger("Rugnux"); @@ -753,20 +756,26 @@ void Rugnux::RefineStillsGeometryOrDeNovo(int start_image, int end_image, int im const State start = save(); const UnitCell given_cell = *stills_user_cell_; - RefineStillsGeometry(start_image, end_image, images_to_process, observer); - const State given = save(); - - restore(start); stills_user_cell_.reset(); experiment_.SetUnitCell(std::nullopt); RefineStillsGeometry(start_image, end_image, images_to_process, observer); const State de_novo = save(); stills_user_cell_ = given_cell; if (cancelled_ || !de_novo.experiment.GetUnitCell().has_value()) { - restore(given); + restore(start); + RefineStillsGeometry(start_image, end_image, images_to_process, observer); return; } + // The cell given, from the detector (and the modules) the de novo fit left. + stills_geometry_frames_ = 0; + experiment_.SetUnitCell(given_cell); + RefineStillsGeometry(start_image, end_image, images_to_process, observer); + const State given = save(); + const bool given_fitted = stills_geometry_frames_ > 0; + if (cancelled_) + return; + const std::vector sample = select_equally_spaced_image_ordinals( images_to_process, std::min(images_to_process, SAMPLE_FRAMES)); const std::vector frames = FindStillsSampleSpots(sample, start_image); @@ -783,7 +792,7 @@ void Rugnux::RefineStillsGeometryOrDeNovo(int start_image, int end_image, int im "{} sampled spots on the lattice; the cell indexed de novo, {:.2f} {:.2f} {:.2f} {:.2f} {:.2f} {:.2f} at " "{:.2f} mm, {}", g.a, g.b, g.c, g.alpha, g.beta, g.gamma, distance_g, trials[0].on_lattice, d.a, d.b, d.c, d.alpha, d.beta, d.gamma, distance_d, trials[1].on_lattice); - const bool same_detector = std::abs(distance_g / distance_d - 1.0) < SAME_DETECTOR; + const bool same_detector = given_fitted && std::abs(distance_g / distance_d - 1.0) < SAME_DETECTOR; if (trials[0].on_lattice >= GIVEN_KEPT_ABOVE * trials[1].on_lattice || same_detector) { restore(given); return;