IndexAndRefine: remove the online rotation-indexer trigger
With --single-pass-rotation gone and the broker no longer asking for rotation indexing, nothing reaches the counter-driven path any more: rugnux's rotation run always forces the first pass's lattice (a failed first pass stops the run). Removed: RotationIndexerCounter, the counter branch of DetermineLatticeAndSymmetryRotation (and RotationAngle, its only user), the RunIndexing fallback in FinalizeRotationIndexing, the uncalled AddImageToRotationIndexer, and IndexingSettings' rotation-indexing minimum angular range and stride with their entries in the rotation indexer's and rugnux's memo keys (constants there, so no key changes meaning). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HVeDQsU5a8AJUdJPgWevAK
This commit is contained in:
1 parent
d279827a82
commit
0d2a1c6783
11 files changed
+9
-152
No files matched your search
@@ -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();
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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<RotationIndexer>(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<float> 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<float>(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<RotationIndexerResult> 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 {};
|
||||
}
|
||||
|
||||
|
||||
@@ -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<RotationIndexer> rotation_indexer;
|
||||
RotationIndexerCounter rotation_indexer_counter;
|
||||
|
||||
struct IndexingOutcome {
|
||||
std::optional<CrystalLattice> lattice_candidate;
|
||||
@@ -222,8 +220,6 @@ class IndexAndRefine {
|
||||
|
||||
std::unique_ptr<ReindexAmbiguityResolver> reindex_resolver;
|
||||
void ScaleImage(DataMessage &msg, IntegrationOutcome& outcome);
|
||||
|
||||
std::optional<float> 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).
|
||||
|
||||
@@ -154,8 +154,7 @@ namespace {
|
||||
static_cast<double>(x.GetFFT_NumVectors()), x.GetFFT_HighResolution_A(),
|
||||
x.GetFFT_MinAngle_deg(), x.GetFFT_MaxAngle_deg(), x.GetUnitCellDistTolerance(),
|
||||
x.GetUnitCellAngleTolerance_deg(), static_cast<double>(x.GetIndexIceRings()),
|
||||
x.GetRotationIndexingMinAngularRange_deg(), x.GetRotationIndexingAngularStride_deg(),
|
||||
static_cast<double>(x.GetMaxExtraLattices()), static_cast<double>(x.GetLatticeClassDemoted()),
|
||||
static_cast<double>(x.GetMaxExtraLattices()), static_cast<double>(x.GetLatticeClassDemoted()),
|
||||
static_cast<double>(x.GetViableCellMinSpots()), static_cast<double>(x.GetAlgorithm()),
|
||||
static_cast<double>(x.GetGeomRefinementAlgorithm()),
|
||||
static_cast<double>(x.GetIndexingThreads()), static_cast<double>(x.GetRefineThreads())});
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// 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<int64_t>(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<bool, bool> RotationIndexerCounter::Process(int64_t image) {
|
||||
std::unique_lock ul(m);
|
||||
|
||||
std::pair<bool, bool> 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;
|
||||
}
|
||||
@@ -1,24 +0,0 @@
|
||||
// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute <filip.leonarski@psi.ch>
|
||||
// SPDX-License-Identifier: GPL-3.0-only
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
#include <mutex>
|
||||
|
||||
#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<bool, bool> Process(int64_t image); // Should you add image to a pile? Should you try indexing?
|
||||
};
|
||||
@@ -782,7 +782,6 @@ std::vector<double> Rugnux::ExperimentKey(const DiffractionExperiment &e, bool r
|
||||
static_cast<double>(x.GetFFT_NumVectors()), x.GetFFT_HighResolution_A(),
|
||||
x.GetFFT_MinAngle_deg(), x.GetFFT_MaxAngle_deg(), x.GetUnitCellDistTolerance(),
|
||||
x.GetUnitCellAngleTolerance_deg(), static_cast<double>(x.GetIndexIceRings()),
|
||||
x.GetRotationIndexingMinAngularRange_deg(), x.GetRotationIndexingAngularStride_deg(),
|
||||
static_cast<double>(x.GetMaxExtraLattices()), static_cast<double>(x.GetLatticeClassDemoted()),
|
||||
static_cast<double>(x.GetViableCellMinSpots()), static_cast<double>(x.GetAlgorithm()),
|
||||
static_cast<double>(x.GetGeomRefinementAlgorithm())});
|
||||
|
||||
@@ -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<RotationIndexerResult> 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);
|
||||
|
||||
Reference in new issue
Block a user