Program Listing for File PhotCommons.hpp
↰ Return to documentation for file (src/phot/PhotCommons.hpp)
#ifndef PHOTCOMMONS_HPP
#define PHOTCOMMONS_HPP
#include "../utils/Constants.hpp"
#include <cmath>
#include <cstdint>
#include <filesystem>
#include <numbers>
#include <string>
namespace phot
{
enum class PhotSystem : std::uint8_t // NOLINT(readability-identifier-naming) -- capitalized to match Flambda/Fnu/ST/AB/Vega's own fixed photometric-system naming below, rather than the project's usual camelBack enum-constant convention
{
Flambda, // NOLINT(readability-identifier-naming) -- see PhotSystem
Fnu, // NOLINT(readability-identifier-naming) -- see PhotSystem
ST, // NOLINT(readability-identifier-naming) -- see PhotSystem
AB, // NOLINT(readability-identifier-naming) -- see PhotSystem
Vega // NOLINT(readability-identifier-naming) -- see PhotSystem
};
inline constexpr double flux0AB = 3631.0;
inline constexpr double flux0ST = 3.631e-9;
inline constexpr double fourPiTenPcSq =
4.0 * std::numbers::pi_v<double> * (10.0 * utils::pc) * (10.0 * utils::pc);
inline static const std::string defaultVegaSpec = // NOLINT(bugprone-throwing-static-initialization,cert-err58-cpp) -- built from fixed string literals, so the (theoretically throwing) path conversion can never actually throw here
(std::filesystem::path("data") / std::filesystem::path("spectra")
/ std::filesystem::path("vega.h5"));
template <PhotSystem From, PhotSystem To>
constexpr auto PhotConvert(double photIn, double wl) -> double; // NOLINT(readability-identifier-naming) -- capitalized to match this file's other fixed photometric naming (PhotSystem above), rather than the project's usual camelBack function convention
template <PhotSystem From, PhotSystem To>
auto PhotConvert(double photIn, double wl, double fluxVega) -> double; // NOLINT(readability-identifier-naming) -- see the two-argument overload above
template <>
constexpr auto PhotConvert<PhotSystem::Flambda, PhotSystem::Fnu>(const double photIn, const double wl) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
return photIn * wl * wl * utils::Angstrom / utils::c;
}
template <>
constexpr auto PhotConvert<PhotSystem::Fnu, PhotSystem::Flambda>(const double photIn, const double wl) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
return photIn * utils::c / (wl * wl * utils::Angstrom);
}
template <>
inline auto PhotConvert<PhotSystem::Fnu, PhotSystem::AB>(const double photIn, double /*wl*/) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
const double fluxIn = (photIn / fourPiTenPcSq) / utils::Jy;
return -2.5 * std::log10(fluxIn / flux0AB);
}
template <>
inline auto PhotConvert<PhotSystem::AB, PhotSystem::Fnu>(const double photIn, double /*wl*/) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
const double fluxIn = flux0AB * std::pow(10.0, photIn / -2.5);
return (fluxIn * utils::Jy) * fourPiTenPcSq;
}
template <>
inline auto PhotConvert<PhotSystem::Flambda, PhotSystem::ST>(const double photIn, double /*wl*/) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
const double fluxIn = photIn / fourPiTenPcSq;
return -2.5 * std::log10(fluxIn / flux0ST);
}
template <>
inline auto PhotConvert<PhotSystem::ST, PhotSystem::Flambda>(const double photIn, double /*wl*/) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
const double fluxIn = flux0ST * std::pow(10.0, photIn / -2.5);
return fluxIn * fourPiTenPcSq;
}
// The remaining (from, to) combinations -- every one not directly
// defined above, excluding any involving Vega (handled separately
// as a special case rather than through this template -- see the
// primary template's own comment) -- are each composed from the
// six direct conversions above, chained through Flambda and/or Fnu
// (the two physical-flux systems every magnitude system's own
// conversion above already goes through). wl is genuinely used by
// each of these, unlike PhotConvert<Fnu, AB>/<Flambda, ST> and
// their inverses: it's threaded through to whichever of those
// Flambda <-> Fnu steps the chain actually needs. None of these
// are marked constexpr either, since each calls at least one of
// the log10/pow-based conversions above that aren't -- see
// PhotConvert<Fnu, AB>'s own comment for why. Each is marked
// inline for the same ODR reason those non-constexpr conversions
// are.
template <>
inline auto PhotConvert<PhotSystem::Flambda, PhotSystem::AB>(const double photIn, const double wl) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
return PhotConvert<PhotSystem::Fnu, PhotSystem::AB>(
PhotConvert<PhotSystem::Flambda, PhotSystem::Fnu>(photIn, wl), wl);
}
template <>
inline auto PhotConvert<PhotSystem::AB, PhotSystem::Flambda>(const double photIn, const double wl) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
return PhotConvert<PhotSystem::Fnu, PhotSystem::Flambda>(
PhotConvert<PhotSystem::AB, PhotSystem::Fnu>(photIn, wl), wl);
}
template <>
inline auto PhotConvert<PhotSystem::Fnu, PhotSystem::ST>(const double photIn, const double wl) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::ST>(
PhotConvert<PhotSystem::Fnu, PhotSystem::Flambda>(photIn, wl), wl);
}
template <>
inline auto PhotConvert<PhotSystem::ST, PhotSystem::Fnu>(const double photIn, const double wl) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::Fnu>(
PhotConvert<PhotSystem::ST, PhotSystem::Flambda>(photIn, wl), wl);
}
template <>
inline auto PhotConvert<PhotSystem::ST, PhotSystem::AB>(const double photIn, const double wl) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
return PhotConvert<PhotSystem::Fnu, PhotSystem::AB>(
PhotConvert<PhotSystem::Flambda, PhotSystem::Fnu>(
PhotConvert<PhotSystem::ST, PhotSystem::Flambda>(photIn, wl), wl), wl);
}
template <>
inline auto PhotConvert<PhotSystem::AB, PhotSystem::ST>(const double photIn, const double wl) -> double // NOLINT(readability-identifier-naming) -- see the primary template above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::ST>(
PhotConvert<PhotSystem::Fnu, PhotSystem::Flambda>(
PhotConvert<PhotSystem::AB, PhotSystem::Fnu>(photIn, wl), wl), wl);
}
// ---- Vega magnitude conversions (three-argument overload) ----
//
// Flambda <-> Vega are direct: identical in form to Flambda <->
// ST, but with flux0ST (a fixed constant) replaced by fluxVega (a
// per-filter value) as the zero point -- so Vega itself (photIn
// == fluxVega) evaluates to magnitude 0 by construction, exactly
// as the Vega system is defined to work. Unlike photIn, fluxVega
// is always a genuine flux (from the real, already-at-Earth Vega
// reference spectrum -- see Filter::fluxVega()), never a specific
// luminosity, so it needs no fourPiTenPcSq scaling of its own; only
// photIn (when it's on the Flambda side) does, exactly as for
// PhotConvert<Flambda, ST>/<ST, Flambda>. Every other (From, To)
// pair involving Vega is built by chaining through Flambda: To
// Vega, first convert From -> Flambda (via the two-argument
// overload), then Flambda -> Vega; from Vega, first convert
// Vega -> Flambda, then Flambda -> To (via the two-argument
// overload again). None of these are constexpr, for the same
// reason as their AB/ST counterparts above.
template <>
inline auto PhotConvert<PhotSystem::Flambda, PhotSystem::Vega>(const double photIn, double /*wl*/, const double fluxVega) -> double // NOLINT(readability-identifier-naming) -- see the two-argument overload above
{
const double fluxIn = photIn / fourPiTenPcSq;
return -2.5 * std::log10(fluxIn / fluxVega);
}
template <>
inline auto PhotConvert<PhotSystem::Vega, PhotSystem::Flambda>(const double photIn, double /*wl*/, const double fluxVega) -> double // NOLINT(readability-identifier-naming) -- see the two-argument overload above
{
const double fluxIn = fluxVega * std::pow(10.0, photIn / -2.5);
return fluxIn * fourPiTenPcSq;
}
template <>
inline auto PhotConvert<PhotSystem::Fnu, PhotSystem::Vega>(const double photIn, const double wl, const double fluxVega) -> double // NOLINT(readability-identifier-naming) -- see the two-argument overload above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::Vega>(
PhotConvert<PhotSystem::Fnu, PhotSystem::Flambda>(photIn, wl), wl, fluxVega);
}
template <>
inline auto PhotConvert<PhotSystem::Vega, PhotSystem::Fnu>(const double photIn, const double wl, const double fluxVega) -> double // NOLINT(readability-identifier-naming) -- see the two-argument overload above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::Fnu>(
PhotConvert<PhotSystem::Vega, PhotSystem::Flambda>(photIn, wl, fluxVega), wl);
}
template <>
inline auto PhotConvert<PhotSystem::ST, PhotSystem::Vega>(const double photIn, const double wl, const double fluxVega) -> double // NOLINT(readability-identifier-naming) -- see the two-argument overload above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::Vega>(
PhotConvert<PhotSystem::ST, PhotSystem::Flambda>(photIn, wl), wl, fluxVega);
}
template <>
inline auto PhotConvert<PhotSystem::Vega, PhotSystem::ST>(const double photIn, const double wl, const double fluxVega) -> double // NOLINT(readability-identifier-naming) -- see the two-argument overload above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::ST>(
PhotConvert<PhotSystem::Vega, PhotSystem::Flambda>(photIn, wl, fluxVega), wl);
}
template <>
inline auto PhotConvert<PhotSystem::AB, PhotSystem::Vega>(const double photIn, const double wl, const double fluxVega) -> double // NOLINT(readability-identifier-naming) -- see the two-argument overload above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::Vega>(
PhotConvert<PhotSystem::AB, PhotSystem::Flambda>(photIn, wl), wl, fluxVega);
}
template <>
inline auto PhotConvert<PhotSystem::Vega, PhotSystem::AB>(const double photIn, const double wl, const double fluxVega) -> double // NOLINT(readability-identifier-naming) -- see the two-argument overload above
{
return PhotConvert<PhotSystem::Flambda, PhotSystem::AB>(
PhotConvert<PhotSystem::Vega, PhotSystem::Flambda>(photIn, wl, fluxVega), wl);
}
} // namespace phot
#endif // PHOTCOMMONS_HPP