diff --git a/common/DiffractionExperiment.cpp b/common/DiffractionExperiment.cpp index 6576c5e0e..e97974bdc 100644 --- a/common/DiffractionExperiment.cpp +++ b/common/DiffractionExperiment.cpp @@ -1913,8 +1913,7 @@ int64_t DiffractionExperiment::GetDarkMaskNumberOfFrames() const { } bool DiffractionExperiment::IsRotationIndexing() const { - // A stationary axis is not rotation data, however it got here. Without this, a constant axis - // reaches RotationIndexerCounter, whose stride stays zero, and indexing then never runs at all. + // A stationary axis is not rotation data, however it got here. const auto goniometer = GetGoniometer(); return goniometer.has_value() && goniometer->IsScanning() && indexing.GetRotationIndexing(); } diff --git a/common/IndexingSettings.cpp b/common/IndexingSettings.cpp index d8dfd1db6..62f79b8e7 100644 --- a/common/IndexingSettings.cpp +++ b/common/IndexingSettings.cpp @@ -197,32 +197,10 @@ IndexingSettings & IndexingSettings::RotationIndexing(bool input) { return*this; } -IndexingSettings & IndexingSettings::RotationIndexingMinAngularRange_deg(float input) { - check_finite("Rotation indexing minimum angular range (deg.)", input); - check_min("Rotation indexing minimum angular range (deg.)", input, 1.0); - rotation_indexing_min_angular_range_deg = input; - return *this; -} - -IndexingSettings & IndexingSettings::RotationIndexingAngularStride_deg(float input) { - check_finite("Rotation indexing angular stride (deg.)", input); - check_min("Rotation indexing angular stride (deg.)", input, 0.0); - rotation_indexing_angular_stride_deg = input; - return *this; -} - bool IndexingSettings::GetRotationIndexing() const { return enable_rotation_indexing; } -float IndexingSettings::GetRotationIndexingMinAngularRange_deg() const { - return rotation_indexing_min_angular_range_deg; -} - -float IndexingSettings::GetRotationIndexingAngularStride_deg() const { - return rotation_indexing_angular_stride_deg; -} - IndexingSettings & IndexingSettings::LatticeClassDemoted(bool input) { lattice_class_demoted = input; return *this; diff --git a/common/IndexingSettings.h b/common/IndexingSettings.h index 3b0e4db1d..6a5e9c508 100644 --- a/common/IndexingSettings.h +++ b/common/IndexingSettings.h @@ -71,8 +71,6 @@ private: bool lattice_class_demoted = false; bool enable_rotation_indexing = false; - float rotation_indexing_min_angular_range_deg = 20.0; - float rotation_indexing_angular_stride_deg = 0.5; GeomRefinementAlgorithmEnum refinement = GeomRefinementAlgorithmEnum::BeamCenter; public: @@ -93,8 +91,6 @@ public: IndexingSettings& GeomRefinementAlgorithm(GeomRefinementAlgorithmEnum input); IndexingSettings& IndexIceRings(bool input); IndexingSettings& RotationIndexing(bool input); - IndexingSettings& RotationIndexingMinAngularRange_deg(float input); - IndexingSettings& RotationIndexingAngularStride_deg(float input); IndexingSettings& BlockingBehavior(bool input); IndexingSettings& MaxExtraLattices(int64_t input); IndexingSettings& LatticeClassDemoted(bool input); @@ -115,8 +111,6 @@ public: [[nodiscard]] float GetUnitCellAngleTolerance_deg() const; [[nodiscard]] bool GetIndexIceRings() const; [[nodiscard]] bool GetRotationIndexing() const; - [[nodiscard]] float GetRotationIndexingMinAngularRange_deg() const; - [[nodiscard]] float GetRotationIndexingAngularStride_deg() const; [[nodiscard]] bool GetBlockingBehavior() const; [[nodiscard]] int64_t GetMaxExtraLattices() const; [[nodiscard]] bool GetLatticeClassDemoted() const; diff --git a/image_analysis/CMakeLists.txt b/image_analysis/CMakeLists.txt index 916ebb0e2..fd1ab7b87 100644 --- a/image_analysis/CMakeLists.txt +++ b/image_analysis/CMakeLists.txt @@ -116,8 +116,7 @@ ADD_LIBRARY(JFJochImageAnalysis STATIC UpdateReflectionResolution.cpp UpdateReflectionResolution.h IntegrationOutcome.h - rotation_indexer/RotationIndexerCounter.cpp - rotation_indexer/RotationIndexerCounter.h) +) ADD_SUBDIRECTORY(spot_finding) ADD_SUBDIRECTORY(bragg_integration) diff --git a/image_analysis/IndexAndRefine.cpp b/image_analysis/IndexAndRefine.cpp index 7dc673a16..7f8e982ce 100644 --- a/image_analysis/IndexAndRefine.cpp +++ b/image_analysis/IndexAndRefine.cpp @@ -70,8 +70,7 @@ IndexAndRefine::IndexAndRefine(const DiffractionExperiment &x, IndexerThreadPool : retain_outcomes_(retain_outcomes), real_time(real_time), experiment(x), - indexer_(indexer), - rotation_indexer_counter(x) { + indexer_(indexer) { if (indexer && x.IsRotationIndexing()) rotation_indexer = std::make_unique(x, *indexer, real_time); // Only retain the whole-run per-image reflections when a later scaling/merge pass will read them. @@ -85,13 +84,6 @@ IndexAndRefine::IndexAndRefine(const DiffractionExperiment &x, IndexerThreadPool unit_cells.resize(x.GetImageNum()); } -std::optional IndexAndRefine::RotationAngle(int64_t image) const { - // Mid-exposure rotation angle for image index `image`, matching the angle used for prediction. - if (const auto g = experiment.GetGoniometer()) - return g->GetAngle_deg(static_cast(image)) + g->GetWedge_deg() / 2.0f; - return std::nullopt; -} - void IndexAndRefine::RecordIndexerError(std::exception_ptr e) { std::lock_guard lock(indexer_error_mutex_); if (!first_indexer_error_) @@ -110,33 +102,13 @@ void IndexAndRefine::RethrowIndexerError() const { std::rethrow_exception(first_indexer_error_); } -void IndexAndRefine::AddImageToRotationIndexer(DataMessage &msg) { - if (rotation_indexer) - rotation_indexer->ProcessImage(msg.number, msg.spots, RotationAngle(msg.number)); -} - IndexAndRefine::IndexingOutcome IndexAndRefine::DetermineLatticeAndSymmetryRotation(DataMessage &msg) { IndexingOutcome outcome(experiment); if (!rotation_indexer) return outcome; - auto result = rotation_indexer->GetLattice(); - - if (!result.has_value()) { - auto rot_cnt = rotation_indexer_counter.Process(msg.number); - if (rot_cnt.first) - rotation_indexer->ProcessImage(msg.number, msg.spots, RotationAngle(msg.number)); - if (rot_cnt.second) { - try { - rotation_indexer->RunIndexing(); - } catch (...) { - RecordIndexerError(std::current_exception()); - } - } - result = rotation_indexer->GetLattice(); - } - + const auto result = rotation_indexer->GetLattice(); if (result.has_value()) { // For rotation indexing, indexing rate is calculated only for frames, where "global" rotation indexing solution was found msg.indexing_result = false; @@ -976,17 +948,8 @@ int64_t IndexAndRefine::CountSpotsOnLattice(DataMessage &msg, const SpotFindingS } std::optional IndexAndRefine::FinalizeRotationIndexing() { - if (rotation_indexer) { - if (const auto latt = rotation_indexer->GetLattice()) - return latt; - - try { - rotation_indexer->RunIndexing(); - } catch (...) { - RecordIndexerError(std::current_exception()); - } + if (rotation_indexer) return rotation_indexer->GetLattice(); - } return {}; } diff --git a/image_analysis/IndexAndRefine.h b/image_analysis/IndexAndRefine.h index f90c3267b..ffe2bbe6f 100644 --- a/image_analysis/IndexAndRefine.h +++ b/image_analysis/IndexAndRefine.h @@ -20,7 +20,6 @@ #include "indexing/IndexerThreadPool.h" #include "lattice_search/LatticeSearch.h" #include "rotation_indexer/RotationIndexer.h" -#include "rotation_indexer/RotationIndexerCounter.h" #include "scale_merge/ReindexAmbiguity.h" #include "scale_merge/ScaleOnTheFly.h" #include "scale_merge/ScalingResult.h" @@ -114,7 +113,6 @@ class IndexAndRefine { IndexerThreadPool *indexer_; std::unique_ptr rotation_indexer; - RotationIndexerCounter rotation_indexer_counter; struct IndexingOutcome { std::optional lattice_candidate; @@ -222,8 +220,6 @@ class IndexAndRefine { std::unique_ptr reindex_resolver; void ScaleImage(DataMessage &msg, IntegrationOutcome& outcome); - - std::optional RotationAngle(int64_t image) const; // mid-exposure angle for the indexer public: // real_time: bound the geometry refinements - the per-image one here and the candidate-cell ones // in the rotation indexer - by WALL CLOCK, as online acquisition must, it having a real budget. @@ -232,7 +228,6 @@ public: IndexAndRefine(const DiffractionExperiment &x, IndexerThreadPool *indexer, bool retain_outcomes = true, bool real_time = false); - void AddImageToRotationIndexer(DataMessage &msg); // An indexer that fails says nothing about the frame and everything about the machine, so it is // not a frame that did not index. Online, a collection goes on and reports how often it happened // (GetIndexerErrorCount); offline, the run stops on it (RethrowIndexerError). diff --git a/image_analysis/rotation_indexer/RotationIndexer.cpp b/image_analysis/rotation_indexer/RotationIndexer.cpp index 968a10a03..09b52f45e 100644 --- a/image_analysis/rotation_indexer/RotationIndexer.cpp +++ b/image_analysis/rotation_indexer/RotationIndexer.cpp @@ -154,8 +154,7 @@ namespace { static_cast(x.GetFFT_NumVectors()), x.GetFFT_HighResolution_A(), x.GetFFT_MinAngle_deg(), x.GetFFT_MaxAngle_deg(), x.GetUnitCellDistTolerance(), x.GetUnitCellAngleTolerance_deg(), static_cast(x.GetIndexIceRings()), - x.GetRotationIndexingMinAngularRange_deg(), x.GetRotationIndexingAngularStride_deg(), - static_cast(x.GetMaxExtraLattices()), static_cast(x.GetLatticeClassDemoted()), + static_cast(x.GetMaxExtraLattices()), static_cast(x.GetLatticeClassDemoted()), static_cast(x.GetViableCellMinSpots()), static_cast(x.GetAlgorithm()), static_cast(x.GetGeomRefinementAlgorithm()), static_cast(x.GetIndexingThreads()), static_cast(x.GetRefineThreads())}); diff --git a/image_analysis/rotation_indexer/RotationIndexerCounter.cpp b/image_analysis/rotation_indexer/RotationIndexerCounter.cpp deleted file mode 100644 index 79bc7efe2..000000000 --- a/image_analysis/rotation_indexer/RotationIndexerCounter.cpp +++ /dev/null @@ -1,45 +0,0 @@ -// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute -// SPDX-License-Identifier: GPL-3.0-only - -#include "RotationIndexerCounter.h" - -RotationIndexerCounter::RotationIndexerCounter(const DiffractionExperiment &x) { - const auto axis = x.GetGoniometer(); - - if (x.IsRotationIndexing() && axis.has_value()) { - float angle_norm_deg = std::fabs(axis->GetIncrement_deg()); - if (angle_norm_deg >= 1e-6) { - if (x.GetImageNum() < min_images_for_indexing) { - // For short measurements - no trying to index during the measurement - image_to_try_indexing = x.GetImageNum(); - image_stride = 1; - } else { - image_to_try_indexing = std::max(min_images_for_indexing, - x.GetIndexingSettings(). - GetRotationIndexingMinAngularRange_deg() / angle_norm_deg); - image_stride = std::ceil( - x.GetIndexingSettings().GetRotationIndexingAngularStride_deg() / angle_norm_deg); - if (image_stride == 0) - image_stride = 1; - } - } - } -} - -std::pair RotationIndexerCounter::Process(int64_t image) { - std::unique_lock ul(m); - - std::pair ret = {false, false}; - - if (image_stride == 0) - return ret; - - accumulated_images++; - ret.first = (image_stride == 1) || (image % image_stride == 0); - if (accumulated_images >= image_to_try_indexing) { - image_to_try_indexing += 10; - ret.second = true; - } - - return ret; -} diff --git a/image_analysis/rotation_indexer/RotationIndexerCounter.h b/image_analysis/rotation_indexer/RotationIndexerCounter.h deleted file mode 100644 index b8dc6ecbe..000000000 --- a/image_analysis/rotation_indexer/RotationIndexerCounter.h +++ /dev/null @@ -1,24 +0,0 @@ -// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute -// SPDX-License-Identifier: GPL-3.0-only - -#pragma once - -#include -#include - -#include "../common/DiffractionExperiment.h" - -class RotationIndexerCounter { - mutable std::mutex m; - - int64_t image_stride = 0; - int64_t image_to_try_indexing = INT64_MAX; - int64_t indexing_range_multiplier = 1; - - size_t accumulated_images = 0; - - constexpr static int64_t min_images_for_indexing = 10; -public: - RotationIndexerCounter(const DiffractionExperiment &experiment); - std::pair Process(int64_t image); // Should you add image to a pile? Should you try indexing? -}; diff --git a/rugnux/Rugnux.cpp b/rugnux/Rugnux.cpp index d998dbfd3..890e1eb89 100644 --- a/rugnux/Rugnux.cpp +++ b/rugnux/Rugnux.cpp @@ -782,7 +782,6 @@ std::vector Rugnux::ExperimentKey(const DiffractionExperiment &e, bool r static_cast(x.GetFFT_NumVectors()), x.GetFFT_HighResolution_A(), x.GetFFT_MinAngle_deg(), x.GetFFT_MaxAngle_deg(), x.GetUnitCellDistTolerance(), x.GetUnitCellAngleTolerance_deg(), static_cast(x.GetIndexIceRings()), - x.GetRotationIndexingMinAngularRange_deg(), x.GetRotationIndexingAngularStride_deg(), static_cast(x.GetMaxExtraLattices()), static_cast(x.GetLatticeClassDemoted()), static_cast(x.GetViableCellMinSpots()), static_cast(x.GetAlgorithm()), static_cast(x.GetGeomRefinementAlgorithm())}); diff --git a/tests/RotationIndexerTest.cpp b/tests/RotationIndexerTest.cpp index 5bf029ed6..c10551895 100644 --- a/tests/RotationIndexerTest.cpp +++ b/tests/RotationIndexerTest.cpp @@ -20,7 +20,7 @@ TEST_CASE("RotationIndexer") { IndexingSettings settings; settings.Algorithm(IndexingAlgorithmEnum::Auto); // rotation: FFT with a GPU, FFTW without - settings.RotationIndexing(true).RotationIndexingAngularStride_deg(1.0).RotationIndexingMinAngularRange_deg(30.0); + settings.RotationIndexing(true); exp_i.ImportIndexingSettings(settings); // Base lattice (non-pathological) @@ -105,7 +105,7 @@ TEST_CASE("RotationIndexer::RefineConstrained puts a free metric back on its cla IndexingSettings settings; settings.Algorithm(IndexingAlgorithmEnum::Auto); // rotation: FFT with a GPU, FFTW without - settings.RotationIndexing(true).RotationIndexingAngularStride_deg(1.0).RotationIndexingMinAngularRange_deg(30.0); + settings.RotationIndexing(true); exp_i.ImportIndexingSettings(settings); const CrystalLattice latt_base = @@ -181,7 +181,7 @@ static std::optional IndexOnTiltedDetector(double true_ti IndexingSettings settings; settings.Algorithm(IndexingAlgorithmEnum::Auto); // rotation: FFT with a GPU, FFTW without - settings.RotationIndexing(true).RotationIndexingAngularStride_deg(1.0).RotationIndexingMinAngularRange_deg(30.0); + settings.RotationIndexing(true); exp_header.ImportIndexingSettings(settings); GoniometerAxis axis("omega", 0.0f, 1.0f, Coord(1, 0, 0), std::nullopt);