// SPDX-FileCopyrightText: 2025 Filip Leonarski, Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-only #pragma once #include "Indexer.h" #include "../../common/UnitCell.h" #include "../../common/Coord.h" #include "../../common/CrystalLattice.h" #include "../../common/IndexingSettings.h" #include "FFTResult.h" #define FFT_MAX_SPOTS (64*1024) class FFTIndexer : public Indexer { protected: const float min_length_A; const float max_length_A; const float min_angle_deg; const float max_angle_deg; const int nDirections; const unsigned refine_threads; float histogram_spacing; int64_t histogram_size; std::vector direction_vectors; size_t input_size; size_t output_size; // Per-direction best peaks (host) std::vector result_fft; void SetupUnitCell(const std::optional &cell) override; // widen=false: combine only the shortest few filtered vectors (fast, correct for compact cells). // widen=true: anchor the two short axes but let the third range over all vectors (reaches the long // axis of a large/elongated cell). Used only as a fallback when the standard reduction indexes poorly. std::vector ReduceResults(const std::vector &results, bool widen) const; std::vector FilterFFTResults(size_t max_vectors) const; std::vector ReduceAndRefine(const std::vector &coord, size_t nspots, const std::vector &filtered, bool widen); float IndexedFraction(const CrystalLattice &latt, const std::vector &coord, size_t nspots) const; void SetupDirectionVectors(); virtual void ExecuteFFT(const std::vector &coord, size_t nspots) = 0; public: explicit FFTIndexer(const IndexingSettings& settings); ~FFTIndexer() override = default; std::vector RunInternal(const std::vector &coord, size_t nspots) override; };