Program Listing for File SpecsynLib.hpp
↰ Return to documentation for file (src/specsyn/SpecsynLib.hpp)
#ifndef SPECSYNLIB_HPP
#define SPECSYNLIB_HPP
#include "../utils/ThreadVec.hpp"
#include "Specsyn.hpp"
#include "SpecsynCommons.hpp"
#include <cstddef>
#include <mdspan> // NOLINT(misc-include-cleaner)
#include <string>
#include <vector>
namespace io
{
class SimControls;
} // namespace io
namespace specsyn
{
template <OOBPolicy Policy>
class SpecsynLib : public Specsyn
{
public:
explicit SpecsynLib(const io::SimControls& controls) :
Specsyn(controls) { }
[[nodiscard]] auto spec(const StarData& props, double feh) const
-> std::vector<double> override = 0;
virtual void resample(const std::vector<double>& wlNew);
[[nodiscard]] static auto resample(const std::vector<double>& wl,
const std::vector<double>& wlNew, const std::vector<double>& spectrum)
-> std::vector<double>;
protected:
using SpectraGrid = std::mdspan<std::vector<double>, std::dextents<std::size_t, 3>>; // NOLINT(misc-include-cleaner) -- <mdspan> is already included above; clang-tidy-18's libc++-18 header-mapping data doesn't yet recognize it as std::mdspan/std::dextents' canonical header
[[nodiscard]] virtual auto spec(double d1, double d2, double d3) const -> std::vector<double>;
[[nodiscard]] static auto outOfBoundsResult(const std::string& message) -> std::vector<double>;
std::vector<double> dim1_;
std::vector<double> dim2_;
std::vector<double> dim3_;
std::vector<std::vector<double>> spectra_;
SpectraGrid grid_;
private:
// Cached bracket indices for search acceleration, one per
// tensor-grid axis, exactly as interp::Mesh2DGrid caches
// iSave_/jSave_: the common calling pattern is a long series
// of spec() queries at (d1, d2, d3) points that are sorted or
// nearly sorted along each axis (e.g. a series of stars fed
// through in Teff/logg order), so the bracket found for one
// query is usually still correct, or nearly so, for the next
// one. Caching it lets findBracket (utils::findBracket, in
// src/utils/GridBracket.cpp) skip the binary search entirely
// on a cache hit, and narrow its search range on a miss, rather than
// always searching the full axis from scratch. ThreadVec's,
// rather than plain size_t's, so that each OpenMP thread gets
// its own private cached index -- without this, concurrent
// calls from different threads would race to update a single
// shared cache. spec(double, double, double) must bind a
// local reference to the element private to the calling
// thread (e.g. "dim1Cache_()") before passing it to
// findBracket, exactly as Mesh2DGrid's own methods do with
// iSave_/jSave_. dim2Cache_/dim3Cache_ are protected, rather
// than private like dim1Cache_, so that SpecsynLib2D's own 2D
// spec(double, double) -- which never touches dim1_ at all --
// can reuse them directly instead of keeping a redundant cache
// of its own.
mutable utils::ThreadVec<size_t> dim1Cache_;
protected:
mutable utils::ThreadVec<size_t> dim2Cache_;
mutable utils::ThreadVec<size_t> dim3Cache_;
};
} // namespace specsyn
#endif // SPECSYNLIB_HPP