diff --git a/mcc/mcc_coord.h b/mcc/mcc_coord.h index 0cc94f3..d6d5a2a 100644 --- a/mcc/mcc_coord.h +++ b/mcc/mcc_coord.h @@ -1,7 +1,9 @@ #include "mcc_angle.h" +#include "mcc_ccte_iers.h" #include "mcc_defaults.h" #include "mcc_generics.h" +#include namespace mcc { @@ -157,41 +159,41 @@ using MccGenXY = MccNamedCoordPair; using MccGeoLONLAT = MccNamedCoordPair; -struct mcc_skycoord_interface_t { - virtual ~mcc_skycoord_interface_t() = default; +struct mcc_skypoint_interface_t { + virtual ~mcc_skypoint_interface_t() = default; - template SelfT, mcc_angle_c XT, mcc_angle_c YT> - SelfT& from(this SelfT&& self, XT&& x, YT&& y) - { - return std::forward(self).from(std::forward(x), std::forward(y)); - } + // template SelfT, mcc_angle_c XT, mcc_angle_c YT> + // SelfT& from(this SelfT&& self, XT&& x, YT&& y) + // { + // return std::forward(self).from(std::forward(x), std::forward(y)); + // } - template SelfT, mcc_coord_pair_c PT> - SelfT& from(this SelfT&& self, PT&& cpair) + template SelfT, mcc_coord_pair_c PT> + auto from(this SelfT&& self, PT&& cpair) { return std::forward(self).from(std::forward(cpair)); } - template SelfT, mcc_coord_pair_c PT> - SelfT& operator=(this SelfT&& self, PT&& cpair) + template SelfT, mcc_coord_pair_c PT> + auto operator=(this SelfT&& self, PT&& cpair) { return std::forward(self).operator=(std::forward(cpair)); } - template SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs> - SelfT& to(this SelfT&& self, PT& cpair, PTs&... cpairs) + template SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs> + auto to(this SelfT&& self, PT& cpair, PTs&... cpairs) { return std::forward(self).to(cpair, cpairs...); } - template SelfT, mcc_coord_pair_c PT> + template SelfT, mcc_coord_pair_c PT> operator PT(this SelfT&& self) { return std::forward(self).operator PT(); } - template SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs> + template SelfT, mcc_coord_pair_c PT, mcc_coord_pair_c... PTs> operator std::tuple(this SelfT&& self) { return std::forward(self).operator std::tuple(); @@ -199,16 +201,220 @@ struct mcc_skycoord_interface_t { }; template -concept mcc_skycoord_c = std::derived_from && requires(T t) { +concept mcc_skypoint_c = std::derived_from && requires(T t) { typename T::meteo_t; { T::meteo(std::declval()) }; }; -class MccSkyPoint : public mcc_skycoord_interface_t +/* MCC-LIBRARY DEFAULT SKY POINT CLASS IMPLEMENTATION BASED ON ERFA-LIBRARY */ + + +class MccSkyPoint : public mcc_skypoint_interface_t { public: + static constexpr double MJD0 = 2400000.5; + + struct meteo_t { + double temperature; // Temperature in C + double humidity; // humidity in % ([0.0, 1.0]) + double pressure; // atmospheric presure in hPa=mB + }; + + static ccte::iers::MccLeapSeconds iersLeapSeconds() + { + return _leapSeconds; + } + + static bool updateLeapSeconds(traits::mcc_input_char_range auto const& filename) + { + std::lock_guard lock{_leapSecondsMutex}; + + return _leapSeconds.load(filename); + }; + + static bool updateIersBulletinA(traits::mcc_input_char_range auto const& filename) + { + std::lock_guard lock{_bulletinAMutex}; + + return _bulletinA.load(filename); + }; + + static ccte::iers::MccIersBulletinA iersBulletinA() + { + return _bulletinA; + } + + static void setMeteo(meteo_t meteo) + { + std::lock_guard lock{_meteoMutex}; + + _currentMeteo = std::move(meteo); + } + + static meteo_t getMeteo() + { + return _currentMeteo; + } + + + MccSkyPoint() {} + + template + MccSkyPoint(const PT& coord_pair) : MccSkyPoint() + { + auto self = from(coord_pair); + } + + MccSkyPoint(const MccSkyPoint&) = default; + MccSkyPoint(MccSkyPoint&&) = default; + + MccSkyPoint& operator=(const MccSkyPoint&) = default; + MccSkyPoint& operator=(MccSkyPoint&&) = default; + + virtual ~MccSkyPoint() = default; + + MccCelestialCoordEpoch epoch() const + { + return _epoch; + } + + template + MccSkyPoint& from(const PT& coord_pair) + { + _x = coord_pair.x(); + _y = coord_pair.y(); + + _pairKind = coord_pair.pairKind; + + if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + _epoch = MccCelestialCoordEpoch(); // J2000.0 + } else { + _epoch.fromMJD(coord_pair.MJD()); + } + } + + MccSkyPoint& operator=(mcc_coord_pair_c auto const& coord_pair) + { + return from(coord_pair); + } + + + template + auto to(PT& cpair, PTs&... cpairs) + { + toHelper(cpair); + + if constexpr (sizeof...(PTs)) { + to(cpairs...); + } + } + +protected: + // IERS related static members + static inline ccte::iers::MccLeapSeconds _leapSeconds{}; + static inline ccte::iers::MccIersBulletinA _bulletinA{}; + + static inline std::mutex _leapSecondsMutex{}, _bulletinAMutex{}; + + // meteo related static members + + static inline meteo_t _currentMeteo{.temperature = 10.0, .humidity = 0.5, .pressure = 1010.0}; + static inline std::mutex _meteoMutex{}; + + + double _x{0.0}, _y{0.0}; + MccCoordPairKind _pairKind{MccCoordPairKind::COORDS_KIND_RADEC_ICRS}; + MccCelestialCoordEpoch _epoch{}; // J2000.0 + + template + auto toHelper(PT& cpair) + { + double ra_icrs, dec_icrs, ra_obs, dec_obs, ha_obs, az_obs, zd_obs, lst, eo; + + static_assert(PT::pairKind == MccCoordPairKind::COORDS_KIND_GENERIC, "UNSUPPORTED SKY POINT TRANSFORMATION!"); + static_assert(PT::pairKind == MccCoordPairKind::COORDS_KIND_UNKNOWN, "UNSUPPORTED SKY POINT TRANSFORMATION!"); + + if (_pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS && + PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + cpair = PT(PT::x_t(_x), PT::y_t(_y), _epoch); + return; + } + + if (_pairKind == PT::pairKind && utils::isEqual(_epoch.MJD(), cpair.MJD())) { + cpair = PT(PT::x_t(_x), PT::y_t(_y), _epoch); + return; + } + + MccCoordPairKind pkind = _pairKind; + if (!utils::isEqual(_epoch.MJD(), cpair.MJD())) { // convert stored pair to ICRS one (ra_icrs, dec_icrs) + if (_pairKind != MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + pkind = MccCoordPairKind::COORDS_KIND_RADEC_ICRS; + // convert here!!! + if (_pairKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { + // cct_engine.appToICRS(...) + } else if (_pairKind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) { + // cct_engine.obsToICRS(...) + } else if (_pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { + // cct_engine.appToICRS(...) + } else if (_pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) { + // cct_engine.obsToICRS(...) + } else if (_pairKind == MccCoordPairKind::COORDS_KIND_AZZD) { + // cct_engine.obsToICRS(...) + } else if (_pairKind == MccCoordPairKind::COORDS_KIND_AZALT) { + // cct_engine.obsToICRS(...) + } else { // unsupported transformation!!! + return; + } + } else { + ra_icrs = _x; + dec_icrs = _y; + } + } + + // here, APP or OBS to ICRS + if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS && + PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + cpair = PT(PT::x_t(ra_icrs), PT::y_t(dec_icrs), MccCelestialCoordEpoch{}); + return; + } + + if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_ICRS) { + if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { + // cct_engine.icrsToApp(...) + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) { + // cct_engine.icrsToObs(...) + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { + // cct_engine.icrsToApp(...) + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) { + // cct_engine.icrsToObs(...) + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZZD) { + // cct_engine.icrsToObs(...) + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZALT) { + // cct_engine.icrsToObs(...) + } else { + static_assert(false, "UNSUPPORTED SKY POINT TRANSFORMATION!"); + } + } else if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_APP) { + if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) { + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { + // ha = lst + eo - ra? + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) { + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZZD) { + } else if constexpr (PT::pairKind == MccCoordPairKind::COORDS_KIND_AZALT) { + } else { + static_assert(false, "UNSUPPORTED SKY POINT TRANSFORMATION!"); + } + } else if (pkind == MccCoordPairKind::COORDS_KIND_RADEC_OBS) { + } else if (pkind == MccCoordPairKind::COORDS_KIND_HADEC_APP) { + } else if (pkind == MccCoordPairKind::COORDS_KIND_HADEC_OBS) { + } else if (pkind == MccCoordPairKind::COORDS_KIND_AZZD) { + } else if (pkind == MccCoordPairKind::COORDS_KIND_AZALT) { + } else { // unsupported transformation!!! + return; + } + } }; } // end namespace mcc