// SPDX-FileCopyrightText: 2026 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #include "AnalysisSettings.h" #include "GridScanAnalysisSettings.h" // The mode-to-analysis table. One place, one row per mode, and every gate in the pipeline reads it - // so what a mode does can be read off here instead of being reconstructed from `if (mode == ...)` // scattered through the engines. // // spots index bragg merge score azint // None - - - - - - // MXRotation x x x x x x // MXStills x x x x x x // Azint - - - - - x // Grid x * - - x x * = default; a setting // PowderCalibration x - - - - x // // Two rows want a word. // // PowderCalibration keeps spot finding. The geometry is fitted either to the ring arcs of the summed // (q x azimuth) profile or to the POOLED SPOTS (rugnux --calibration rings|spots), and the second of // those is a spot finder run - so the mode must not decide this; whoever picks the source does. // // Grid indexes by default, but that entry is not the mode's to fix: it is // GridScanAnalysisSettings::indexing, and what stands here is only what that setting defaults to. A // raster runs at up to 100 Hz, which the FFT indexer keeps up with, and a fixed-target serial // experiment with a known cell wants ffbidx on every cell - so whether a raster indexes is a property // of the experiment, not of rasters. DiffractionExperiment::GetAnalysisStages substitutes the // configured value. // // The switch has no default: adding a mode must be a compile error here rather than a silent // fall-through to whatever the last row happened to be. AnalysisStages AnalysisModeStages(AnalysisMode mode) { switch (mode) { case AnalysisMode::None: return {false, false, false, false, false, false}; case AnalysisMode::MXRotation: case AnalysisMode::MXStills: return {true, true, true, true, true, true}; case AnalysisMode::Azint: return {false, false, false, false, false, true}; case AnalysisMode::Grid: return {true, GridScanAnalysisSettings().IsIndexing(), false, false, true, true}; case AnalysisMode::PowderCalibration: return {true, false, false, false, false, true}; } return {false, false, false, false, false, false}; } bool AnalysisModeIsMX(AnalysisMode mode) { switch (mode) { case AnalysisMode::MXRotation: case AnalysisMode::MXStills: return true; case AnalysisMode::None: case AnalysisMode::Azint: case AnalysisMode::Grid: case AnalysisMode::PowderCalibration: return false; } return false; } std::string AnalysisModeName(AnalysisMode mode) { switch (mode) { case AnalysisMode::None: return "none"; case AnalysisMode::MXRotation: return "mx_rotation"; case AnalysisMode::MXStills: return "mx_stills"; case AnalysisMode::Azint: return "azint"; case AnalysisMode::Grid: return "grid"; case AnalysisMode::PowderCalibration: return "powder_calibration"; } return "none"; } std::optional AnalysisModeFromName(std::string_view name) { if (name == "none") return AnalysisMode::None; if (name == "mx_rotation") return AnalysisMode::MXRotation; if (name == "mx_stills") return AnalysisMode::MXStills; if (name == "azint") return AnalysisMode::Azint; if (name == "grid") return AnalysisMode::Grid; if (name == "powder_calibration") return AnalysisMode::PowderCalibration; return {}; } AnalysisSettings &AnalysisSettings::Mode(AnalysisMode input) { mode = input; return *this; } AnalysisMode AnalysisSettings::GetMode() const { return mode; } bool AnalysisSettings::IsMX() const { return AnalysisModeIsMX(mode); }