mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 06:30:05 +00:00 
			
		
		
		
	Merge pull request #446 from dpaulat/feature/rda-rpg-build-23.0
Update to RDA/RPG Build 23.0
This commit is contained in:
		
						commit
						f08a7d9a8d
					
				
					 24 changed files with 2502 additions and 2319 deletions
				
			
		|  | @ -1460,7 +1460,7 @@ RadarProductManagerImpl::StoreRadarProductRecord( | ||||||
| 
 | 
 | ||||||
|          if (storedRecord != nullptr) |          if (storedRecord != nullptr) | ||||||
|          { |          { | ||||||
|             logger_->error( |             logger_->debug( | ||||||
|                "Level 2 product previously loaded, loading from cache"); |                "Level 2 product previously loaded, loading from cache"); | ||||||
|          } |          } | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  | @ -1,6 +1,7 @@ | ||||||
| #pragma once | #pragma once | ||||||
| 
 | 
 | ||||||
| #include <array> | #include <array> | ||||||
|  | #include <bit> | ||||||
| #include <cstring> | #include <cstring> | ||||||
| #include <execution> | #include <execution> | ||||||
| #include <istream> | #include <istream> | ||||||
|  | @ -13,12 +14,8 @@ | ||||||
| #   include <arpa/inet.h> | #   include <arpa/inet.h> | ||||||
| #endif | #endif | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::awips | ||||||
| { | { | ||||||
| namespace awips |  | ||||||
| { |  | ||||||
| 
 |  | ||||||
| class MessageImpl; |  | ||||||
| 
 | 
 | ||||||
| class Message | class Message | ||||||
| { | { | ||||||
|  | @ -56,78 +53,165 @@ public: | ||||||
| 
 | 
 | ||||||
|    static float SwapFloat(float f) |    static float SwapFloat(float f) | ||||||
|    { |    { | ||||||
|       std::uint32_t temp; |       if constexpr (std::endian::native == std::endian::little) | ||||||
|       std::memcpy(&temp, &f, sizeof(std::uint32_t)); |       { | ||||||
|       temp = ntohl(temp); |          // Variable is initialized by memcpy
 | ||||||
|       std::memcpy(&f, &temp, sizeof(float)); |          // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
 | ||||||
|  |          std::uint32_t temp; | ||||||
|  |          std::memcpy(&temp, &f, sizeof(std::uint32_t)); | ||||||
|  |          temp = ntohl(temp); | ||||||
|  |          std::memcpy(&f, &temp, sizeof(float)); | ||||||
|  |       } | ||||||
|       return f; |       return f; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    template<std::size_t _Size> |    static double SwapDouble(double d) | ||||||
|    static void SwapArray(std::array<float, _Size>& arr, |  | ||||||
|                          std::size_t               size = _Size) |  | ||||||
|    { |    { | ||||||
|       std::transform(std::execution::par_unseq, |       if constexpr (std::endian::native == std::endian::little) | ||||||
|                      arr.begin(), |       { | ||||||
|                      arr.begin() + size, |          // Variable is initialized by memcpy
 | ||||||
|                      arr.begin(), |          // NOLINTNEXTLINE(cppcoreguidelines-init-variables)
 | ||||||
|                      [](float f) { return SwapFloat(f); }); |          std::uint64_t temp; | ||||||
|  |          std::memcpy(&temp, &d, sizeof(std::uint64_t)); | ||||||
|  |          temp = Swap64(temp); | ||||||
|  |          std::memcpy(&d, &temp, sizeof(float)); | ||||||
|  |       } | ||||||
|  |       return d; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    template<std::size_t _Size> |    static std::uint64_t Swap64(std::uint64_t value) | ||||||
|    static void SwapArray(std::array<std::int16_t, _Size>& arr, |  | ||||||
|                          std::size_t                      size = _Size) |  | ||||||
|    { |    { | ||||||
|       std::transform(std::execution::par_unseq, |       if constexpr (std::endian::native == std::endian::little) | ||||||
|                      arr.begin(), |       { | ||||||
|                      arr.begin() + size, |          // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|                      arr.begin(), |          const std::uint32_t high = | ||||||
|                      [](std::int16_t u) { return ntohs(u); }); |             ntohl(static_cast<std::uint32_t>(value >> 32)); | ||||||
|  |          const std::uint32_t low = | ||||||
|  |             ntohl(static_cast<std::uint32_t>(value & 0xFFFFFFFFULL)); | ||||||
|  |          return (static_cast<std::uint64_t>(low) << 32) | high; | ||||||
|  |          // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  |       } | ||||||
|  |       else | ||||||
|  |       { | ||||||
|  |          return value; | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    template<std::size_t _Size> |    template<std::size_t kSize> | ||||||
|    static void SwapArray(std::array<std::uint16_t, _Size>& arr, |    static void SwapArray(std::array<float, kSize>& arr, | ||||||
|                          std::size_t                       size = _Size) |                          std::size_t               size = kSize) | ||||||
|    { |    { | ||||||
|       std::transform(std::execution::par_unseq, |       if constexpr (std::endian::native == std::endian::little) | ||||||
|                      arr.begin(), |       { | ||||||
|                      arr.begin() + size, |          std::transform(std::execution::par_unseq, | ||||||
|                      arr.begin(), |                         arr.begin(), | ||||||
|                      [](std::uint16_t u) { return ntohs(u); }); |                         arr.begin() + size, | ||||||
|  |                         arr.begin(), | ||||||
|  |                         [](float f) { return SwapFloat(f); }); | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    template<std::size_t _Size> |    template<std::size_t kSize> | ||||||
|    static void SwapArray(std::array<std::uint32_t, _Size>& arr, |    static void SwapArray(std::array<std::int16_t, kSize>& arr, | ||||||
|                          std::size_t                       size = _Size) |                          std::size_t                      size = kSize) | ||||||
|    { |    { | ||||||
|       std::transform(std::execution::par_unseq, |       if constexpr (std::endian::native == std::endian::little) | ||||||
|                      arr.begin(), |       { | ||||||
|                      arr.begin() + size, |          std::transform(std::execution::par_unseq, | ||||||
|                      arr.begin(), |                         arr.begin(), | ||||||
|                      [](std::uint32_t u) { return ntohl(u); }); |                         arr.begin() + size, | ||||||
|  |                         arr.begin(), | ||||||
|  |                         [](std::int16_t u) { return ntohs(u); }); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    template<std::size_t kSize> | ||||||
|  |    static void SwapArray(std::array<std::uint16_t, kSize>& arr, | ||||||
|  |                          std::size_t                       size = kSize) | ||||||
|  |    { | ||||||
|  |       if constexpr (std::endian::native == std::endian::little) | ||||||
|  |       { | ||||||
|  |          std::transform(std::execution::par_unseq, | ||||||
|  |                         arr.begin(), | ||||||
|  |                         arr.begin() + size, | ||||||
|  |                         arr.begin(), | ||||||
|  |                         [](std::uint16_t u) { return ntohs(u); }); | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    template<std::size_t kSize> | ||||||
|  |    static void SwapArray(std::array<std::uint32_t, kSize>& arr, | ||||||
|  |                          std::size_t                       size = kSize) | ||||||
|  |    { | ||||||
|  |       if constexpr (std::endian::native == std::endian::little) | ||||||
|  |       { | ||||||
|  |          std::transform(std::execution::par_unseq, | ||||||
|  |                         arr.begin(), | ||||||
|  |                         arr.begin() + size, | ||||||
|  |                         arr.begin(), | ||||||
|  |                         [](std::uint32_t u) { return ntohl(u); }); | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    template<typename T> |    template<typename T> | ||||||
|    static void SwapMap(std::map<T, float>& m) |    static void SwapMap(std::map<T, float>& m) | ||||||
|    { |    { | ||||||
|       std::for_each(std::execution::par_unseq, |       if constexpr (std::endian::native == std::endian::little) | ||||||
|                     m.begin(), |       { | ||||||
|                     m.end(), |          std::for_each(std::execution::par_unseq, | ||||||
|                     [](auto& p) { p.second = SwapFloat(p.second); }); |                        m.begin(), | ||||||
|  |                        m.end(), | ||||||
|  |                        [](auto& p) { p.second = SwapFloat(p.second); }); | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    static void SwapVector(std::vector<std::uint16_t>& v) |    template<typename T> | ||||||
|  |    static void SwapVector(std::vector<T>& v) | ||||||
|    { |    { | ||||||
|       std::transform(std::execution::par_unseq, |       if constexpr (std::endian::native == std::endian::little) | ||||||
|                      v.begin(), |       { | ||||||
|                      v.end(), |          std::transform( | ||||||
|                      v.begin(), |             std::execution::par_unseq, | ||||||
|                      [](std::uint16_t u) { return ntohs(u); }); |             v.begin(), | ||||||
|  |             v.end(), | ||||||
|  |             v.begin(), | ||||||
|  |             [](T u) | ||||||
|  |             { | ||||||
|  |                if constexpr (std::is_same_v<T, std::uint16_t> || | ||||||
|  |                              std::is_same_v<T, std::int16_t>) | ||||||
|  |                { | ||||||
|  |                   return static_cast<T>(ntohs(u)); | ||||||
|  |                } | ||||||
|  |                else if constexpr (std::is_same_v<T, std::uint32_t> || | ||||||
|  |                                   std::is_same_v<T, std::int32_t>) | ||||||
|  |                { | ||||||
|  |                   return static_cast<T>(ntohl(u)); | ||||||
|  |                } | ||||||
|  |                else if constexpr (std::is_same_v<T, std::uint64_t> || | ||||||
|  |                                   std::is_same_v<T, std::int64_t>) | ||||||
|  |                { | ||||||
|  |                   return static_cast<T>(Swap64(u)); | ||||||
|  |                } | ||||||
|  |                else if constexpr (std::is_same_v<T, float>) | ||||||
|  |                { | ||||||
|  |                   return SwapFloat(u); | ||||||
|  |                } | ||||||
|  |                else if constexpr (std::is_same_v<T, double>) | ||||||
|  |                { | ||||||
|  |                   return SwapDouble(u); | ||||||
|  |                } | ||||||
|  |                else | ||||||
|  |                { | ||||||
|  |                   static_assert(std::is_same_v<T, void>, | ||||||
|  |                                 "Unsupported type for SwapVector"); | ||||||
|  |                } | ||||||
|  |             }); | ||||||
|  |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|    std::unique_ptr<MessageImpl> p; |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace awips
 | } // namespace scwx::awips
 | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -2,11 +2,7 @@ | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rda/generic_radar_data.hpp> | #include <scwx/wsr88d/rda/generic_radar_data.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rda | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rda |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| class DigitalRadarDataGeneric : public GenericRadarData | class DigitalRadarDataGeneric : public GenericRadarData | ||||||
|  | @ -27,30 +23,31 @@ public: | ||||||
|    DigitalRadarDataGeneric(DigitalRadarDataGeneric&&) noexcept; |    DigitalRadarDataGeneric(DigitalRadarDataGeneric&&) noexcept; | ||||||
|    DigitalRadarDataGeneric& operator=(DigitalRadarDataGeneric&&) noexcept; |    DigitalRadarDataGeneric& operator=(DigitalRadarDataGeneric&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    std::string           radar_identifier() const; |    [[nodiscard]] std::string           radar_identifier() const; | ||||||
|    std::uint32_t         collection_time() const; |    [[nodiscard]] std::uint32_t         collection_time() const override; | ||||||
|    std::uint16_t         modified_julian_date() const; |    [[nodiscard]] std::uint16_t         modified_julian_date() const override; | ||||||
|    std::uint16_t         azimuth_number() const; |    [[nodiscard]] std::uint16_t         azimuth_number() const override; | ||||||
|    units::degrees<float> azimuth_angle() const; |    [[nodiscard]] units::degrees<float> azimuth_angle() const override; | ||||||
|    std::uint8_t          compression_indicator() const; |    [[nodiscard]] std::uint8_t          compression_indicator() const; | ||||||
|    std::uint16_t         radial_length() const; |    [[nodiscard]] std::uint16_t         radial_length() const; | ||||||
|    std::uint8_t          azimuth_resolution_spacing() const; |    [[nodiscard]] std::uint8_t          azimuth_resolution_spacing() const; | ||||||
|    std::uint8_t          radial_status() const; |    [[nodiscard]] std::uint8_t          radial_status() const; | ||||||
|    std::uint16_t         elevation_number() const; |    [[nodiscard]] std::uint16_t         elevation_number() const override; | ||||||
|    std::uint8_t          cut_sector_number() const; |    [[nodiscard]] std::uint8_t          cut_sector_number() const; | ||||||
|    units::degrees<float> elevation_angle() const; |    [[nodiscard]] units::degrees<float> elevation_angle() const; | ||||||
|    std::uint8_t          radial_spot_blanking_status() const; |    [[nodiscard]] std::uint8_t          radial_spot_blanking_status() const; | ||||||
|    std::uint8_t          azimuth_indexing_mode() const; |    [[nodiscard]] std::uint8_t          azimuth_indexing_mode() const; | ||||||
|    std::uint16_t         data_block_count() const; |    [[nodiscard]] std::uint16_t         data_block_count() const; | ||||||
|    std::uint16_t         volume_coverage_pattern_number() const; |    [[nodiscard]] std::uint16_t volume_coverage_pattern_number() const override; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<ElevationDataBlock> elevation_data_block() const; |    [[nodiscard]] std::shared_ptr<ElevationDataBlock> | ||||||
|    std::shared_ptr<RadialDataBlock>    radial_data_block() const; |                                                   elevation_data_block() const; | ||||||
|    std::shared_ptr<VolumeDataBlock>    volume_data_block() const; |    [[nodiscard]] std::shared_ptr<RadialDataBlock> radial_data_block() const; | ||||||
|    std::shared_ptr<GenericRadarData::MomentDataBlock> |    [[nodiscard]] std::shared_ptr<VolumeDataBlock> volume_data_block() const; | ||||||
|    moment_data_block(DataBlockType type) const; |    [[nodiscard]] std::shared_ptr<GenericRadarData::MomentDataBlock> | ||||||
|  |    moment_data_block(DataBlockType type) const override; | ||||||
| 
 | 
 | ||||||
|    bool Parse(std::istream& is); |    bool Parse(std::istream& is) override; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<DigitalRadarDataGeneric> |    static std::shared_ptr<DigitalRadarDataGeneric> | ||||||
|    Create(Level2MessageHeader&& header, std::istream& is); |    Create(Level2MessageHeader&& header, std::istream& is); | ||||||
|  | @ -65,11 +62,14 @@ class DigitalRadarDataGeneric::DataBlock | ||||||
| protected: | protected: | ||||||
|    explicit DataBlock(const std::string& dataBlockType, |    explicit DataBlock(const std::string& dataBlockType, | ||||||
|                       const std::string& dataName); |                       const std::string& dataName); | ||||||
|  | 
 | ||||||
|  | public: | ||||||
|    virtual ~DataBlock(); |    virtual ~DataBlock(); | ||||||
| 
 | 
 | ||||||
|    DataBlock(const DataBlock&)            = delete; |    DataBlock(const DataBlock&)            = delete; | ||||||
|    DataBlock& operator=(const DataBlock&) = delete; |    DataBlock& operator=(const DataBlock&) = delete; | ||||||
| 
 | 
 | ||||||
|  | protected: | ||||||
|    DataBlock(DataBlock&&) noexcept; |    DataBlock(DataBlock&&) noexcept; | ||||||
|    DataBlock& operator=(DataBlock&&) noexcept; |    DataBlock& operator=(DataBlock&&) noexcept; | ||||||
| 
 | 
 | ||||||
|  | @ -118,17 +118,19 @@ public: | ||||||
|    MomentDataBlock(MomentDataBlock&&) noexcept; |    MomentDataBlock(MomentDataBlock&&) noexcept; | ||||||
|    MomentDataBlock& operator=(MomentDataBlock&&) noexcept; |    MomentDataBlock& operator=(MomentDataBlock&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    std::uint16_t            number_of_data_moment_gates() const; |    [[nodiscard]] std::uint16_t number_of_data_moment_gates() const override; | ||||||
|    units::kilometers<float> data_moment_range() const; |    [[nodiscard]] units::kilometers<float> data_moment_range() const override; | ||||||
|    std::int16_t             data_moment_range_raw() const; |    [[nodiscard]] std::int16_t data_moment_range_raw() const override; | ||||||
|    units::kilometers<float> data_moment_range_sample_interval() const; |    [[nodiscard]] units::kilometers<float> | ||||||
|    std::uint16_t            data_moment_range_sample_interval_raw() const; |    data_moment_range_sample_interval() const override; | ||||||
|    float                    snr_threshold() const; |    [[nodiscard]] std::uint16_t | ||||||
|    std::int16_t             snr_threshold_raw() const; |                        data_moment_range_sample_interval_raw() const override; | ||||||
|    std::uint8_t             data_word_size() const; |    [[nodiscard]] float snr_threshold() const; | ||||||
|    float                    scale() const; |    [[nodiscard]] std::int16_t snr_threshold_raw() const override; | ||||||
|    float                    offset() const; |    [[nodiscard]] std::uint8_t data_word_size() const override; | ||||||
|    const void*              data_moments() const; |    [[nodiscard]] float        scale() const override; | ||||||
|  |    [[nodiscard]] float        offset() const override; | ||||||
|  |    [[nodiscard]] const void*  data_moments() const override; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<MomentDataBlock> |    static std::shared_ptr<MomentDataBlock> | ||||||
|    Create(const std::string& dataBlockType, |    Create(const std::string& dataBlockType, | ||||||
|  | @ -155,7 +157,7 @@ public: | ||||||
|    RadialDataBlock(RadialDataBlock&&) noexcept; |    RadialDataBlock(RadialDataBlock&&) noexcept; | ||||||
|    RadialDataBlock& operator=(RadialDataBlock&&) noexcept; |    RadialDataBlock& operator=(RadialDataBlock&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    float unambiguous_range() const; |    [[nodiscard]] float unambiguous_range() const; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<RadialDataBlock> |    static std::shared_ptr<RadialDataBlock> | ||||||
|    Create(const std::string& dataBlockType, |    Create(const std::string& dataBlockType, | ||||||
|  | @ -182,9 +184,9 @@ public: | ||||||
|    VolumeDataBlock(VolumeDataBlock&&) noexcept; |    VolumeDataBlock(VolumeDataBlock&&) noexcept; | ||||||
|    VolumeDataBlock& operator=(VolumeDataBlock&&) noexcept; |    VolumeDataBlock& operator=(VolumeDataBlock&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    float         latitude() const; |    [[nodiscard]] float         latitude() const; | ||||||
|    float         longitude() const; |    [[nodiscard]] float         longitude() const; | ||||||
|    std::uint16_t volume_coverage_pattern_number() const; |    [[nodiscard]] std::uint16_t volume_coverage_pattern_number() const; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<VolumeDataBlock> |    static std::shared_ptr<VolumeDataBlock> | ||||||
|    Create(const std::string& dataBlockType, |    Create(const std::string& dataBlockType, | ||||||
|  | @ -198,6 +200,4 @@ private: | ||||||
|    bool Parse(std::istream& is); |    bool Parse(std::istream& is); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace rda
 | } // namespace scwx::wsr88d::rda
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -2,28 +2,19 @@ | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rda/level2_message.hpp> | #include <scwx/wsr88d/rda/level2_message.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rda | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rda |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| struct Level2MessageInfo | struct Level2MessageInfo | ||||||
| { | { | ||||||
|    std::shared_ptr<Level2Message> message; |    std::shared_ptr<Level2Message> message {nullptr}; | ||||||
|    bool                           headerValid; |    bool                           headerValid {false}; | ||||||
|    bool                           messageValid; |    bool                           messageValid {false}; | ||||||
| 
 |  | ||||||
|    Level2MessageInfo() : |  | ||||||
|        message(nullptr), headerValid(false), messageValid(false) |  | ||||||
|    { |  | ||||||
|    } |  | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| class Level2MessageFactory | class Level2MessageFactory | ||||||
| { | { | ||||||
| private: | public: | ||||||
|    explicit Level2MessageFactory() = delete; |    explicit Level2MessageFactory() = delete; | ||||||
|    ~Level2MessageFactory()         = delete; |    ~Level2MessageFactory()         = delete; | ||||||
| 
 | 
 | ||||||
|  | @ -33,7 +24,6 @@ private: | ||||||
|    Level2MessageFactory(Level2MessageFactory&&) noexcept            = delete; |    Level2MessageFactory(Level2MessageFactory&&) noexcept            = delete; | ||||||
|    Level2MessageFactory& operator=(Level2MessageFactory&&) noexcept = delete; |    Level2MessageFactory& operator=(Level2MessageFactory&&) noexcept = delete; | ||||||
| 
 | 
 | ||||||
| public: |  | ||||||
|    struct Context; |    struct Context; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<Context> CreateContext(); |    static std::shared_ptr<Context> CreateContext(); | ||||||
|  | @ -41,6 +31,4 @@ public: | ||||||
|                                           std::shared_ptr<Context>& ctx); |                                           std::shared_ptr<Context>& ctx); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace rda
 | } // namespace scwx::wsr88d::rda
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -2,14 +2,8 @@ | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rda/level2_message.hpp> | #include <scwx/wsr88d/rda/level2_message.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rda | ||||||
| { | { | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rda |  | ||||||
| { |  | ||||||
| 
 |  | ||||||
| class PerformanceMaintenanceDataImpl; |  | ||||||
| 
 | 
 | ||||||
| class PerformanceMaintenanceData : public Level2Message | class PerformanceMaintenanceData : public Level2Message | ||||||
| { | { | ||||||
|  | @ -24,267 +18,261 @@ public: | ||||||
|    PerformanceMaintenanceData(PerformanceMaintenanceData&&) noexcept; |    PerformanceMaintenanceData(PerformanceMaintenanceData&&) noexcept; | ||||||
|    PerformanceMaintenanceData& operator=(PerformanceMaintenanceData&&) noexcept; |    PerformanceMaintenanceData& operator=(PerformanceMaintenanceData&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    uint16_t    loop_back_set_status() const; |    [[nodiscard]] std::uint16_t loop_back_set_status() const; | ||||||
|    uint32_t    t1_output_frames() const; |    [[nodiscard]] std::uint32_t t1_output_frames() const; | ||||||
|    uint32_t    t1_input_frames() const; |    [[nodiscard]] std::uint32_t t1_input_frames() const; | ||||||
|    uint32_t    router_memory_used() const; |    [[nodiscard]] std::uint32_t router_memory_used() const; | ||||||
|    uint32_t    router_memory_free() const; |    [[nodiscard]] std::uint32_t router_memory_free() const; | ||||||
|    uint16_t    router_memory_utilization() const; |    [[nodiscard]] std::uint16_t router_memory_utilization() const; | ||||||
|    uint16_t    route_to_rpg() const; |    [[nodiscard]] std::uint16_t route_to_rpg() const; | ||||||
|    uint32_t    csu_loss_of_signal() const; |    [[nodiscard]] std::uint16_t t1_port_status() const; | ||||||
|    uint32_t    csu_loss_of_frames() const; |    [[nodiscard]] std::uint16_t router_dedicated_ethernet_port_status() const; | ||||||
|    uint32_t    csu_yellow_alarms() const; |    [[nodiscard]] std::uint16_t router_commercial_ethernet_port_status() const; | ||||||
|    uint32_t    csu_blue_alarms() const; |    [[nodiscard]] std::uint32_t csu_24hr_errored_seconds() const; | ||||||
|    uint32_t    csu_24hr_errored_seconds() const; |    [[nodiscard]] std::uint32_t csu_24hr_severely_errored_seconds() const; | ||||||
|    uint32_t    csu_24hr_severely_errored_seconds() const; |    [[nodiscard]] std::uint32_t | ||||||
|    uint32_t    csu_24hr_severely_errored_framing_seconds() const; |    csu_24hr_severely_errored_framing_seconds() const; | ||||||
|    uint32_t    csu_24hr_unavailable_seconds() const; |    [[nodiscard]] std::uint32_t csu_24hr_unavailable_seconds() const; | ||||||
|    uint32_t    csu_24hr_controlled_slip_seconds() const; |    [[nodiscard]] std::uint32_t csu_24hr_controlled_slip_seconds() const; | ||||||
|    uint32_t    csu_24hr_path_coding_violations() const; |    [[nodiscard]] std::uint32_t csu_24hr_path_coding_violations() const; | ||||||
|    uint32_t    csu_24hr_line_errored_seconds() const; |    [[nodiscard]] std::uint32_t csu_24hr_line_errored_seconds() const; | ||||||
|    uint32_t    csu_24hr_bursty_errored_seconds() const; |    [[nodiscard]] std::uint32_t csu_24hr_bursty_errored_seconds() const; | ||||||
|    uint32_t    csu_24hr_degraded_minutes() const; |    [[nodiscard]] std::uint32_t csu_24hr_degraded_minutes() const; | ||||||
|    uint32_t    lan_switch_cpu_utilization() const; |    [[nodiscard]] std::uint32_t lan_switch_cpu_utilization() const; | ||||||
|    uint16_t    lan_switch_memory_utilization() const; |    [[nodiscard]] std::uint16_t lan_switch_memory_utilization() const; | ||||||
|    uint16_t    ifdr_chasis_temperature() const; |    [[nodiscard]] std::uint16_t ifdr_chasis_temperature() const; | ||||||
|    uint16_t    ifdr_fpga_temperature() const; |    [[nodiscard]] std::uint16_t ifdr_fpga_temperature() const; | ||||||
|    int32_t     gps_satellites() const; |    [[nodiscard]] std::uint16_t ntp_status() const; | ||||||
|    uint16_t    ipc_status() const; |    [[nodiscard]] std::uint16_t ipc_status() const; | ||||||
|    uint16_t    commanded_channel_control() const; |    [[nodiscard]] std::uint16_t commanded_channel_control() const; | ||||||
|    uint16_t    polarization() const; |    [[nodiscard]] std::uint16_t polarization() const; | ||||||
|    float       ame_internal_temperature() const; |    [[nodiscard]] float         ame_internal_temperature() const; | ||||||
|    float       ame_receiver_module_temperature() const; |    [[nodiscard]] float         ame_receiver_module_temperature() const; | ||||||
|    float       ame_bite_cal_module_temperature() const; |    [[nodiscard]] float         ame_bite_cal_module_temperature() const; | ||||||
|    uint16_t    ame_peltier_pulse_width_modulation() const; |    [[nodiscard]] std::uint16_t ame_peltier_pulse_width_modulation() const; | ||||||
|    uint16_t    ame_peltier_status() const; |    [[nodiscard]] std::uint16_t ame_peltier_status() const; | ||||||
|    uint16_t    ame_a_d_converter_status() const; |    [[nodiscard]] std::uint16_t ame_a_d_converter_status() const; | ||||||
|    uint16_t    ame_state() const; |    [[nodiscard]] std::uint16_t ame_state() const; | ||||||
|    float       ame_3_3v_ps_voltage() const; |    [[nodiscard]] float         ame_3_3v_ps_voltage() const; | ||||||
|    float       ame_5v_ps_voltage() const; |    [[nodiscard]] float         ame_5v_ps_voltage() const; | ||||||
|    float       ame_6_5v_ps_voltage() const; |    [[nodiscard]] float         ame_6_5v_ps_voltage() const; | ||||||
|    float       ame_15v_ps_voltage() const; |    [[nodiscard]] float         ame_15v_ps_voltage() const; | ||||||
|    float       ame_48v_ps_voltage() const; |    [[nodiscard]] float         ame_48v_ps_voltage() const; | ||||||
|    float       ame_stalo_power() const; |    [[nodiscard]] float         ame_stalo_power() const; | ||||||
|    float       peltier_current() const; |    [[nodiscard]] float         peltier_current() const; | ||||||
|    float       adc_calibration_reference_voltage() const; |    [[nodiscard]] float         adc_calibration_reference_voltage() const; | ||||||
|    uint16_t    ame_mode() const; |    [[nodiscard]] std::uint16_t ame_mode() const; | ||||||
|    uint16_t    ame_peltier_mode() const; |    [[nodiscard]] std::uint16_t ame_peltier_mode() const; | ||||||
|    float       ame_peltier_inside_fan_current() const; |    [[nodiscard]] float         ame_peltier_inside_fan_current() const; | ||||||
|    float       ame_peltier_outside_fan_current() const; |    [[nodiscard]] float         ame_peltier_outside_fan_current() const; | ||||||
|    float       horizontal_tr_limiter_voltage() const; |    [[nodiscard]] float         horizontal_tr_limiter_voltage() const; | ||||||
|    float       vertical_tr_limiter_voltage() const; |    [[nodiscard]] float         vertical_tr_limiter_voltage() const; | ||||||
|    float       adc_calibration_offset_voltage() const; |    [[nodiscard]] float         adc_calibration_offset_voltage() const; | ||||||
|    float       adc_calibration_gain_correction() const; |    [[nodiscard]] float         adc_calibration_gain_correction() const; | ||||||
|    uint16_t    rcp_status() const; |    [[nodiscard]] std::uint16_t rcp_status() const; | ||||||
|    std::string rcp_string() const; |    [[nodiscard]] std::string   rcp_string() const; | ||||||
|    uint16_t    spip_power_buttons() const; |    [[nodiscard]] std::uint16_t spip_power_buttons() const; | ||||||
|    float       master_power_administrator_load() const; |    [[nodiscard]] float         master_power_administrator_load() const; | ||||||
|    float       expansion_power_administrator_load() const; |    [[nodiscard]] float         expansion_power_administrator_load() const; | ||||||
|    uint16_t    _5vdc_ps() const; |    [[nodiscard]] std::uint16_t _5vdc_ps() const; | ||||||
|    uint16_t    _15vdc_ps() const; |    [[nodiscard]] std::uint16_t _15vdc_ps() const; | ||||||
|    uint16_t    _28vdc_ps() const; |    [[nodiscard]] std::uint16_t _28vdc_ps() const; | ||||||
|    uint16_t    neg_15vdc_ps() const; |    [[nodiscard]] std::uint16_t neg_15vdc_ps() const; | ||||||
|    uint16_t    _45vdc_ps() const; |    [[nodiscard]] std::uint16_t _45vdc_ps() const; | ||||||
|    uint16_t    filament_ps_voltage() const; |    [[nodiscard]] std::uint16_t filament_ps_voltage() const; | ||||||
|    uint16_t    vacuum_pump_ps_voltage() const; |    [[nodiscard]] std::uint16_t vacuum_pump_ps_voltage() const; | ||||||
|    uint16_t    focus_coil_ps_voltage() const; |    [[nodiscard]] std::uint16_t focus_coil_ps_voltage() const; | ||||||
|    uint16_t    filament_ps() const; |    [[nodiscard]] std::uint16_t filament_ps() const; | ||||||
|    uint16_t    klystron_warmup() const; |    [[nodiscard]] std::uint16_t klystron_warmup() const; | ||||||
|    uint16_t    transmitter_available() const; |    [[nodiscard]] std::uint16_t transmitter_available() const; | ||||||
|    uint16_t    wg_switch_position() const; |    [[nodiscard]] std::uint16_t wg_switch_position() const; | ||||||
|    uint16_t    wg_pfn_transfer_interlock() const; |    [[nodiscard]] std::uint16_t wg_pfn_transfer_interlock() const; | ||||||
|    uint16_t    maintenance_mode() const; |    [[nodiscard]] std::uint16_t maintenance_mode() const; | ||||||
|    uint16_t    maintenance_required() const; |    [[nodiscard]] std::uint16_t maintenance_required() const; | ||||||
|    uint16_t    pfn_switch_position() const; |    [[nodiscard]] std::uint16_t pfn_switch_position() const; | ||||||
|    uint16_t    modulator_overload() const; |    [[nodiscard]] std::uint16_t modulator_overload() const; | ||||||
|    uint16_t    modulator_inv_current() const; |    [[nodiscard]] std::uint16_t modulator_inv_current() const; | ||||||
|    uint16_t    modulator_switch_fail() const; |    [[nodiscard]] std::uint16_t modulator_switch_fail() const; | ||||||
|    uint16_t    main_power_voltage() const; |    [[nodiscard]] std::uint16_t main_power_voltage() const; | ||||||
|    uint16_t    charging_system_fail() const; |    [[nodiscard]] std::uint16_t charging_system_fail() const; | ||||||
|    uint16_t    inverse_diode_current() const; |    [[nodiscard]] std::uint16_t inverse_diode_current() const; | ||||||
|    uint16_t    trigger_amplifier() const; |    [[nodiscard]] std::uint16_t trigger_amplifier() const; | ||||||
|    uint16_t    circulator_temperature() const; |    [[nodiscard]] std::uint16_t circulator_temperature() const; | ||||||
|    uint16_t    spectrum_filter_pressure() const; |    [[nodiscard]] std::uint16_t spectrum_filter_pressure() const; | ||||||
|    uint16_t    wg_arc_vswr() const; |    [[nodiscard]] std::uint16_t wg_arc_vswr() const; | ||||||
|    uint16_t    cabinet_interlock() const; |    [[nodiscard]] std::uint16_t cabinet_interlock() const; | ||||||
|    uint16_t    cabinet_air_temperature() const; |    [[nodiscard]] std::uint16_t cabinet_air_temperature() const; | ||||||
|    uint16_t    cabinet_airflow() const; |    [[nodiscard]] std::uint16_t cabinet_airflow() const; | ||||||
|    uint16_t    klystron_current() const; |    [[nodiscard]] std::uint16_t klystron_current() const; | ||||||
|    uint16_t    klystron_filament_current() const; |    [[nodiscard]] std::uint16_t klystron_filament_current() const; | ||||||
|    uint16_t    klystron_vacion_current() const; |    [[nodiscard]] std::uint16_t klystron_vacion_current() const; | ||||||
|    uint16_t    klystron_air_temperature() const; |    [[nodiscard]] std::uint16_t klystron_air_temperature() const; | ||||||
|    uint16_t    klystron_airflow() const; |    [[nodiscard]] std::uint16_t klystron_airflow() const; | ||||||
|    uint16_t    modulator_switch_maintenance() const; |    [[nodiscard]] std::uint16_t modulator_switch_maintenance() const; | ||||||
|    uint16_t    post_charge_regulator_maintenance() const; |    [[nodiscard]] std::uint16_t post_charge_regulator_maintenance() const; | ||||||
|    uint16_t    wg_pressure_humidity() const; |    [[nodiscard]] std::uint16_t wg_pressure_humidity() const; | ||||||
|    uint16_t    transmitter_overvoltage() const; |    [[nodiscard]] std::uint16_t transmitter_overvoltage() const; | ||||||
|    uint16_t    transmitter_overcurrent() const; |    [[nodiscard]] std::uint16_t transmitter_overcurrent() const; | ||||||
|    uint16_t    focus_coil_current() const; |    [[nodiscard]] std::uint16_t focus_coil_current() const; | ||||||
|    uint16_t    focus_coil_airflow() const; |    [[nodiscard]] std::uint16_t focus_coil_airflow() const; | ||||||
|    uint16_t    oil_temperature() const; |    [[nodiscard]] std::uint16_t oil_temperature() const; | ||||||
|    uint16_t    prf_limit() const; |    [[nodiscard]] std::uint16_t prf_limit() const; | ||||||
|    uint16_t    transmitter_oil_level() const; |    [[nodiscard]] std::uint16_t transmitter_oil_level() const; | ||||||
|    uint16_t    transmitter_battery_charging() const; |    [[nodiscard]] std::uint16_t transmitter_battery_charging() const; | ||||||
|    uint16_t    high_voltage_status() const; |    [[nodiscard]] std::uint16_t high_voltage_status() const; | ||||||
|    uint16_t    transmitter_recycling_summary() const; |    [[nodiscard]] std::uint16_t transmitter_recycling_summary() const; | ||||||
|    uint16_t    transmitter_inoperable() const; |    [[nodiscard]] std::uint16_t transmitter_inoperable() const; | ||||||
|    uint16_t    transmitter_air_filter() const; |    [[nodiscard]] std::uint16_t transmitter_air_filter() const; | ||||||
|    uint16_t    zero_test_bit(unsigned i) const; |    [[nodiscard]] std::uint16_t zero_test_bit(unsigned i) const; | ||||||
|    uint16_t    one_test_bit(unsigned i) const; |    [[nodiscard]] std::uint16_t one_test_bit(unsigned i) const; | ||||||
|    uint16_t    xmtr_spip_interface() const; |    [[nodiscard]] std::uint16_t xmtr_spip_interface() const; | ||||||
|    uint16_t    transmitter_summary_status() const; |    [[nodiscard]] std::uint16_t transmitter_summary_status() const; | ||||||
|    float       transmitter_rf_power() const; |    [[nodiscard]] float         transmitter_rf_power() const; | ||||||
|    float       horizontal_xmtr_peak_power() const; |    [[nodiscard]] float         horizontal_xmtr_peak_power() const; | ||||||
|    float       xmtr_peak_power() const; |    [[nodiscard]] float         xmtr_peak_power() const; | ||||||
|    float       vertical_xmtr_peak_power() const; |    [[nodiscard]] float         vertical_xmtr_peak_power() const; | ||||||
|    float       xmtr_rf_avg_power() const; |    [[nodiscard]] float         xmtr_rf_avg_power() const; | ||||||
|    uint32_t    xmtr_recycle_count() const; |    [[nodiscard]] std::uint32_t xmtr_recycle_count() const; | ||||||
|    float       receiver_bias() const; |    [[nodiscard]] float         receiver_bias() const; | ||||||
|    float       transmit_imbalance() const; |    [[nodiscard]] float         transmit_imbalance() const; | ||||||
|    float       xmtr_power_meter_zero() const; |    [[nodiscard]] float         xmtr_power_meter_zero() const; | ||||||
|    uint16_t    ac_unit1_compressor_shut_off() const; |    [[nodiscard]] std::uint16_t ac_unit1_compressor_shut_off() const; | ||||||
|    uint16_t    ac_unit2_compressor_shut_off() const; |    [[nodiscard]] std::uint16_t ac_unit2_compressor_shut_off() const; | ||||||
|    uint16_t    generator_maintenance_required() const; |    [[nodiscard]] std::uint16_t generator_maintenance_required() const; | ||||||
|    uint16_t    generator_battery_voltage() const; |    [[nodiscard]] std::uint16_t generator_battery_voltage() const; | ||||||
|    uint16_t    generator_engine() const; |    [[nodiscard]] std::uint16_t generator_engine() const; | ||||||
|    uint16_t    generator_volt_frequency() const; |    [[nodiscard]] std::uint16_t generator_volt_frequency() const; | ||||||
|    uint16_t    power_source() const; |    [[nodiscard]] std::uint16_t power_source() const; | ||||||
|    uint16_t    transitional_power_source() const; |    [[nodiscard]] std::uint16_t transitional_power_source() const; | ||||||
|    uint16_t    generator_auto_run_off_switch() const; |    [[nodiscard]] std::uint16_t generator_auto_run_off_switch() const; | ||||||
|    uint16_t    aircraft_hazard_lighting() const; |    [[nodiscard]] std::uint16_t aircraft_hazard_lighting() const; | ||||||
|    uint16_t    equipment_shelter_fire_detection_system() const; |    [[nodiscard]] std::uint16_t equipment_shelter_fire_detection_system() const; | ||||||
|    uint16_t    equipment_shelter_fire_smoke() const; |    [[nodiscard]] std::uint16_t equipment_shelter_fire_smoke() const; | ||||||
|    uint16_t    generator_shelter_fire_smoke() const; |    [[nodiscard]] std::uint16_t generator_shelter_fire_smoke() const; | ||||||
|    uint16_t    utility_voltage_frequency() const; |    [[nodiscard]] std::uint16_t utility_voltage_frequency() const; | ||||||
|    uint16_t    site_security_alarm() const; |    [[nodiscard]] std::uint16_t site_security_alarm() const; | ||||||
|    uint16_t    security_equipment() const; |    [[nodiscard]] std::uint16_t security_equipment() const; | ||||||
|    uint16_t    security_system() const; |    [[nodiscard]] std::uint16_t security_system() const; | ||||||
|    uint16_t    receiver_connected_to_antenna() const; |    [[nodiscard]] std::uint16_t receiver_connected_to_antenna() const; | ||||||
|    uint16_t    radome_hatch() const; |    [[nodiscard]] std::uint16_t radome_hatch() const; | ||||||
|    uint16_t    ac_unit1_filter_dirty() const; |    [[nodiscard]] std::uint16_t ac_unit1_filter_dirty() const; | ||||||
|    uint16_t    ac_unit2_filter_dirty() const; |    [[nodiscard]] std::uint16_t ac_unit2_filter_dirty() const; | ||||||
|    float       equipment_shelter_temperature() const; |    [[nodiscard]] float         equipment_shelter_temperature() const; | ||||||
|    float       outside_ambient_temperature() const; |    [[nodiscard]] float         outside_ambient_temperature() const; | ||||||
|    float       transmitter_leaving_air_temp() const; |    [[nodiscard]] float         transmitter_leaving_air_temp() const; | ||||||
|    float       ac_unit1_discharge_air_temp() const; |    [[nodiscard]] float         ac_unit1_discharge_air_temp() const; | ||||||
|    float       generator_shelter_temperature() const; |    [[nodiscard]] float         generator_shelter_temperature() const; | ||||||
|    float       radome_air_temperature() const; |    [[nodiscard]] float         radome_air_temperature() const; | ||||||
|    float       ac_unit2_discharge_air_temp() const; |    [[nodiscard]] float         ac_unit2_discharge_air_temp() const; | ||||||
|    float       spip_15v_ps() const; |    [[nodiscard]] float         spip_15v_ps() const; | ||||||
|    float       spip_neg_15v_ps() const; |    [[nodiscard]] float         spip_neg_15v_ps() const; | ||||||
|    uint16_t    spip_28v_ps_status() const; |    [[nodiscard]] std::uint16_t spip_28v_ps_status() const; | ||||||
|    float       spip_5v_ps() const; |    [[nodiscard]] float         spip_5v_ps() const; | ||||||
|    uint16_t    converted_generator_fuel_level() const; |    [[nodiscard]] std::uint16_t converted_generator_fuel_level() const; | ||||||
|    uint16_t    elevation_pos_dead_limit() const; |    [[nodiscard]] std::uint16_t elevation_pos_dead_limit() const; | ||||||
|    uint16_t    _150v_overvoltage() const; |    [[nodiscard]] std::uint16_t _150v_overvoltage() const; | ||||||
|    uint16_t    _150v_undervoltage() const; |    [[nodiscard]] std::uint16_t _150v_undervoltage() const; | ||||||
|    uint16_t    elevation_servo_amp_inhibit() const; |    [[nodiscard]] std::uint16_t elevation_servo_amp_inhibit() const; | ||||||
|    uint16_t    elevation_servo_amp_short_circuit() const; |    [[nodiscard]] std::uint16_t elevation_servo_amp_short_circuit() const; | ||||||
|    uint16_t    elevation_servo_amp_overtemp() const; |    [[nodiscard]] std::uint16_t elevation_servo_amp_overtemp() const; | ||||||
|    uint16_t    elevation_motor_overtemp() const; |    [[nodiscard]] std::uint16_t elevation_motor_overtemp() const; | ||||||
|    uint16_t    elevation_stow_pin() const; |    [[nodiscard]] std::uint16_t elevation_stow_pin() const; | ||||||
|    uint16_t    elevation_housing_5v_ps() const; |    [[nodiscard]] std::uint16_t elevation_housing_5v_ps() const; | ||||||
|    uint16_t    elevation_neg_dead_limit() const; |    [[nodiscard]] std::uint16_t elevation_neg_dead_limit() const; | ||||||
|    uint16_t    elevation_pos_normal_limit() const; |    [[nodiscard]] std::uint16_t elevation_pos_normal_limit() const; | ||||||
|    uint16_t    elevation_neg_normal_limit() const; |    [[nodiscard]] std::uint16_t elevation_neg_normal_limit() const; | ||||||
|    uint16_t    elevation_encoder_light() const; |    [[nodiscard]] std::uint16_t elevation_encoder_light() const; | ||||||
|    uint16_t    elevation_gearbox_oil() const; |    [[nodiscard]] std::uint16_t elevation_gearbox_oil() const; | ||||||
|    uint16_t    elevation_handwheel() const; |    [[nodiscard]] std::uint16_t elevation_handwheel() const; | ||||||
|    uint16_t    elevation_amp_ps() const; |    [[nodiscard]] std::uint16_t elevation_amp_ps() const; | ||||||
|    uint16_t    azimuth_servo_amp_inhibit() const; |    [[nodiscard]] std::uint16_t azimuth_servo_amp_inhibit() const; | ||||||
|    uint16_t    azimuth_servo_amp_short_circuit() const; |    [[nodiscard]] std::uint16_t azimuth_servo_amp_short_circuit() const; | ||||||
|    uint16_t    azimuth_servo_amp_overtemp() const; |    [[nodiscard]] std::uint16_t azimuth_servo_amp_overtemp() const; | ||||||
|    uint16_t    azimuth_motor_overtemp() const; |    [[nodiscard]] std::uint16_t azimuth_motor_overtemp() const; | ||||||
|    uint16_t    azimuth_stow_pin() const; |    [[nodiscard]] std::uint16_t azimuth_stow_pin() const; | ||||||
|    uint16_t    azimuth_housing_5v_ps() const; |    [[nodiscard]] std::uint16_t azimuth_housing_5v_ps() const; | ||||||
|    uint16_t    azimuth_encoder_light() const; |    [[nodiscard]] std::uint16_t azimuth_encoder_light() const; | ||||||
|    uint16_t    azimuth_gearbox_oil() const; |    [[nodiscard]] std::uint16_t azimuth_gearbox_oil() const; | ||||||
|    uint16_t    azimuth_bull_gear_oil() const; |    [[nodiscard]] std::uint16_t azimuth_bull_gear_oil() const; | ||||||
|    uint16_t    azimuth_handwheel() const; |    [[nodiscard]] std::uint16_t azimuth_handwheel() const; | ||||||
|    uint16_t    azimuth_servo_amp_ps() const; |    [[nodiscard]] std::uint16_t azimuth_servo_amp_ps() const; | ||||||
|    uint16_t    servo() const; |    [[nodiscard]] std::uint16_t servo() const; | ||||||
|    uint16_t    pedestal_interlock_switch() const; |    [[nodiscard]] std::uint16_t pedestal_interlock_switch() const; | ||||||
|    uint16_t    coho_clock() const; |    [[nodiscard]] std::uint16_t coho_clock() const; | ||||||
|    uint16_t    rf_generator_frequency_select_oscillator() const; |    [[nodiscard]] std::uint16_t rf_generator_frequency_select_oscillator() const; | ||||||
|    uint16_t    rf_generator_rf_stalo() const; |    [[nodiscard]] std::uint16_t rf_generator_rf_stalo() const; | ||||||
|    uint16_t    rf_generator_phase_shifted_coho() const; |    [[nodiscard]] std::uint16_t rf_generator_phase_shifted_coho() const; | ||||||
|    uint16_t    _9v_receiver_ps() const; |    [[nodiscard]] std::uint16_t _9v_receiver_ps() const; | ||||||
|    uint16_t    _5v_receiver_ps() const; |    [[nodiscard]] std::uint16_t _5v_receiver_ps() const; | ||||||
|    uint16_t    _18v_receiver_ps() const; |    [[nodiscard]] std::uint16_t _18v_receiver_ps() const; | ||||||
|    uint16_t    neg_9v_receiver_ps() const; |    [[nodiscard]] std::uint16_t neg_9v_receiver_ps() const; | ||||||
|    uint16_t    _5v_single_channel_rdaiu_ps() const; |    [[nodiscard]] std::uint16_t _5v_single_channel_rdaiu_ps() const; | ||||||
|    float       horizontal_short_pulse_noise() const; |    [[nodiscard]] float         horizontal_short_pulse_noise() const; | ||||||
|    float       horizontal_long_pulse_noise() const; |    [[nodiscard]] float         horizontal_long_pulse_noise() const; | ||||||
|    float       horizontal_noise_temperature() const; |    [[nodiscard]] float         horizontal_noise_temperature() const; | ||||||
|    float       vertical_short_pulse_noise() const; |    [[nodiscard]] float         vertical_short_pulse_noise() const; | ||||||
|    float       vertical_long_pulse_noise() const; |    [[nodiscard]] float         vertical_long_pulse_noise() const; | ||||||
|    float       vertical_noise_temperature() const; |    [[nodiscard]] float         vertical_noise_temperature() const; | ||||||
|    float       horizontal_linearity() const; |    [[nodiscard]] float         horizontal_linearity() const; | ||||||
|    float       horizontal_dynamic_range() const; |    [[nodiscard]] float         horizontal_dynamic_range() const; | ||||||
|    float       horizontal_delta_dbz0() const; |    [[nodiscard]] float         horizontal_delta_dbz0() const; | ||||||
|    float       vertical_delta_dbz0() const; |    [[nodiscard]] float         vertical_delta_dbz0() const; | ||||||
|    float       kd_peak_measured() const; |    [[nodiscard]] float         kd_peak_measured() const; | ||||||
|    float       short_pulse_horizontal_dbz0() const; |    [[nodiscard]] float         short_pulse_horizontal_dbz0() const; | ||||||
|    float       long_pulse_horizontal_dbz0() const; |    [[nodiscard]] float         long_pulse_horizontal_dbz0() const; | ||||||
|    uint16_t    velocity_processed() const; |    [[nodiscard]] std::uint16_t velocity_processed() const; | ||||||
|    uint16_t    width_processed() const; |    [[nodiscard]] std::uint16_t width_processed() const; | ||||||
|    uint16_t    velocity_rf_gen() const; |    [[nodiscard]] std::uint16_t velocity_rf_gen() const; | ||||||
|    uint16_t    width_rf_gen() const; |    [[nodiscard]] std::uint16_t width_rf_gen() const; | ||||||
|    float       horizontal_i0() const; |    [[nodiscard]] float         horizontal_i0() const; | ||||||
|    float       vertical_i0() const; |    [[nodiscard]] float         vertical_i0() const; | ||||||
|    float       vertical_dynamic_range() const; |    [[nodiscard]] float         vertical_dynamic_range() const; | ||||||
|    float       short_pulse_vertical_dbz0() const; |    [[nodiscard]] float         short_pulse_vertical_dbz0() const; | ||||||
|    float       long_pulse_vertical_dbz0() const; |    [[nodiscard]] float         long_pulse_vertical_dbz0() const; | ||||||
|    float       horizontal_power_sense() const; |    [[nodiscard]] float         horizontal_power_sense() const; | ||||||
|    float       vertical_power_sense() const; |    [[nodiscard]] float         vertical_power_sense() const; | ||||||
|    float       zdr_bias() const; |    [[nodiscard]] float         zdr_offset() const; | ||||||
|    float       clutter_suppression_delta() const; |    [[nodiscard]] float         clutter_suppression_delta() const; | ||||||
|    float       clutter_suppression_unfiltered_power() const; |    [[nodiscard]] float         clutter_suppression_unfiltered_power() const; | ||||||
|    float       clutter_suppression_filtered_power() const; |    [[nodiscard]] float         clutter_suppression_filtered_power() const; | ||||||
|    float       vertical_linearity() const; |    [[nodiscard]] float         vertical_linearity() const; | ||||||
|    uint16_t    state_file_read_status() const; |    [[nodiscard]] std::uint16_t state_file_read_status() const; | ||||||
|    uint16_t    state_file_write_status() const; |    [[nodiscard]] std::uint16_t state_file_write_status() const; | ||||||
|    uint16_t    bypass_map_file_read_status() const; |    [[nodiscard]] std::uint16_t bypass_map_file_read_status() const; | ||||||
|    uint16_t    bypass_map_file_write_status() const; |    [[nodiscard]] std::uint16_t bypass_map_file_write_status() const; | ||||||
|    uint16_t    current_adaptation_file_read_status() const; |    [[nodiscard]] std::uint16_t current_adaptation_file_read_status() const; | ||||||
|    uint16_t    current_adaptation_file_write_status() const; |    [[nodiscard]] std::uint16_t current_adaptation_file_write_status() const; | ||||||
|    uint16_t    censor_zone_file_read_status() const; |    [[nodiscard]] std::uint16_t censor_zone_file_read_status() const; | ||||||
|    uint16_t    censor_zone_file_write_status() const; |    [[nodiscard]] std::uint16_t censor_zone_file_write_status() const; | ||||||
|    uint16_t    remote_vcp_file_read_status() const; |    [[nodiscard]] std::uint16_t remote_vcp_file_read_status() const; | ||||||
|    uint16_t    remote_vcp_file_write_status() const; |    [[nodiscard]] std::uint16_t remote_vcp_file_write_status() const; | ||||||
|    uint16_t    baseline_adaptation_file_read_status() const; |    [[nodiscard]] std::uint16_t baseline_adaptation_file_read_status() const; | ||||||
|    uint16_t    read_status_of_prf_sets() const; |    [[nodiscard]] std::uint16_t read_status_of_prf_sets() const; | ||||||
|    uint16_t    clutter_filter_map_file_read_status() const; |    [[nodiscard]] std::uint16_t clutter_filter_map_file_read_status() const; | ||||||
|    uint16_t    clutter_filter_map_file_write_status() const; |    [[nodiscard]] std::uint16_t clutter_filter_map_file_write_status() const; | ||||||
|    uint16_t    generatl_disk_io_error() const; |    [[nodiscard]] std::uint16_t general_disk_io_error() const; | ||||||
|    uint8_t     rsp_status() const; |    [[nodiscard]] std::uint8_t  rsp_status() const; | ||||||
|    uint8_t     motherboard_temperature() const; |    [[nodiscard]] std::uint8_t  cpu1_temperature() const; | ||||||
|    uint8_t     cpu1_temperature() const; |    [[nodiscard]] std::uint8_t  cpu2_temperature() const; | ||||||
|    uint8_t     cpu2_temperature() const; |    [[nodiscard]] std::uint16_t rsp_motherboard_power() const; | ||||||
|    uint16_t    cpu1_fan_speed() const; |    [[nodiscard]] std::uint16_t spip_comm_status() const; | ||||||
|    uint16_t    cpu2_fan_speed() const; |    [[nodiscard]] std::uint16_t hci_comm_status() const; | ||||||
|    uint16_t    rsp_fan1_speed() const; |    [[nodiscard]] std::uint16_t signal_processor_command_status() const; | ||||||
|    uint16_t    rsp_fan2_speed() const; |    [[nodiscard]] std::uint16_t ame_communication_status() const; | ||||||
|    uint16_t    rsp_fan3_speed() const; |    [[nodiscard]] std::uint16_t rms_link_status() const; | ||||||
|    uint16_t    spip_comm_status() const; |    [[nodiscard]] std::uint16_t rpg_link_status() const; | ||||||
|    uint16_t    hci_comm_status() const; |    [[nodiscard]] std::uint16_t interpanel_link_status() const; | ||||||
|    uint16_t    signal_processor_command_status() const; |    [[nodiscard]] std::uint32_t performance_check_time() const; | ||||||
|    uint16_t    ame_communication_status() const; |    [[nodiscard]] std::uint16_t version() const; | ||||||
|    uint16_t    rms_link_status() const; |  | ||||||
|    uint16_t    rpg_link_status() const; |  | ||||||
|    uint16_t    interpanel_link_status() const; |  | ||||||
|    uint32_t    performance_check_time() const; |  | ||||||
|    uint16_t    version() const; |  | ||||||
| 
 | 
 | ||||||
|    bool Parse(std::istream& is); |    bool Parse(std::istream& is) override; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<PerformanceMaintenanceData> |    static std::shared_ptr<PerformanceMaintenanceData> | ||||||
|    Create(Level2MessageHeader&& header, std::istream& is); |    Create(Level2MessageHeader&& header, std::istream& is); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|    std::unique_ptr<PerformanceMaintenanceDataImpl> p; |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace rda
 | } // namespace scwx::wsr88d::rda
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -2,14 +2,8 @@ | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rda/level2_message.hpp> | #include <scwx/wsr88d/rda/level2_message.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rda | ||||||
| { | { | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rda |  | ||||||
| { |  | ||||||
| 
 |  | ||||||
| class RdaAdaptationDataImpl; |  | ||||||
| 
 | 
 | ||||||
| class RdaAdaptationData : public Level2Message | class RdaAdaptationData : public Level2Message | ||||||
| { | { | ||||||
|  | @ -17,199 +11,205 @@ public: | ||||||
|    explicit RdaAdaptationData(); |    explicit RdaAdaptationData(); | ||||||
|    ~RdaAdaptationData(); |    ~RdaAdaptationData(); | ||||||
| 
 | 
 | ||||||
|    RdaAdaptationData(const RdaAdaptationData&) = delete; |    RdaAdaptationData(const RdaAdaptationData&)            = delete; | ||||||
|    RdaAdaptationData& operator=(const RdaAdaptationData&) = delete; |    RdaAdaptationData& operator=(const RdaAdaptationData&) = delete; | ||||||
| 
 | 
 | ||||||
|    RdaAdaptationData(RdaAdaptationData&&) noexcept; |    RdaAdaptationData(RdaAdaptationData&&) noexcept; | ||||||
|    RdaAdaptationData& operator=(RdaAdaptationData&&) noexcept; |    RdaAdaptationData& operator=(RdaAdaptationData&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    std::string adap_file_name() const; |    [[nodiscard]] std::string   adap_file_name() const; | ||||||
|    std::string adap_format() const; |    [[nodiscard]] std::string   adap_format() const; | ||||||
|    std::string adap_revision() const; |    [[nodiscard]] std::string   adap_revision() const; | ||||||
|    std::string adap_date() const; |    [[nodiscard]] std::string   adap_date() const; | ||||||
|    std::string adap_time() const; |    [[nodiscard]] std::string   adap_time() const; | ||||||
|    float       lower_pre_limit() const; |    [[nodiscard]] float         lower_pre_limit() const; | ||||||
|    float       az_lat() const; |    [[nodiscard]] float         az_lat() const; | ||||||
|    float       upper_pre_limit() const; |    [[nodiscard]] float         upper_pre_limit() const; | ||||||
|    float       el_lat() const; |    [[nodiscard]] float         el_lat() const; | ||||||
|    float       parkaz() const; |    [[nodiscard]] float         parkaz() const; | ||||||
|    float       parkel() const; |    [[nodiscard]] float         parkel() const; | ||||||
|    float       a_fuel_conv(unsigned i) const; |    [[nodiscard]] float         a_fuel_conv(unsigned i) const; | ||||||
|    float       a_min_shelter_temp() const; |    [[nodiscard]] float         a_min_shelter_temp() const; | ||||||
|    float       a_max_shelter_temp() const; |    [[nodiscard]] float         a_max_shelter_temp() const; | ||||||
|    float       a_min_shelter_ac_temp_diff() const; |    [[nodiscard]] float         a_min_shelter_ac_temp_diff() const; | ||||||
|    float       a_max_xmtr_air_temp() const; |    [[nodiscard]] float         a_max_xmtr_air_temp() const; | ||||||
|    float       a_max_rad_temp() const; |    [[nodiscard]] float         a_max_rad_temp() const; | ||||||
|    float       a_max_rad_temp_rise() const; |    [[nodiscard]] float         a_max_rad_temp_rise() const; | ||||||
|    float       lower_dead_limit() const; |    [[nodiscard]] float         lower_dead_limit() const; | ||||||
|    float       upper_dead_limit() const; |    [[nodiscard]] float         upper_dead_limit() const; | ||||||
|    float       a_min_gen_room_temp() const; |    [[nodiscard]] float         a_min_gen_room_temp() const; | ||||||
|    float       a_max_gen_room_temp() const; |    [[nodiscard]] float         a_max_gen_room_temp() const; | ||||||
|    float       spip_5v_reg_lim() const; |    [[nodiscard]] float         spip_5v_reg_lim() const; | ||||||
|    float       spip_15v_reg_lim() const; |    [[nodiscard]] float         spip_15v_reg_lim() const; | ||||||
|    bool        rpg_co_located() const; |    [[nodiscard]] bool          rpg_co_located() const; | ||||||
|    bool        spec_filter_installed() const; |    [[nodiscard]] bool          spec_filter_installed() const; | ||||||
|    bool        tps_installed() const; |    [[nodiscard]] bool          tps_installed() const; | ||||||
|    bool        rms_installed() const; |    [[nodiscard]] bool          rms_installed() const; | ||||||
|    uint32_t    a_hvdl_tst_int() const; |    [[nodiscard]] std::uint32_t a_hvdl_tst_int() const; | ||||||
|    uint32_t    a_rpg_lt_int() const; |    [[nodiscard]] std::uint32_t a_rpg_lt_int() const; | ||||||
|    uint32_t    a_min_stab_util_pwr_time() const; |    [[nodiscard]] std::uint32_t a_min_stab_util_pwr_time() const; | ||||||
|    uint32_t    a_gen_auto_exer_interval() const; |    [[nodiscard]] std::uint32_t a_gen_auto_exer_interval() const; | ||||||
|    uint32_t    a_util_pwr_sw_req_interval() const; |    [[nodiscard]] std::uint32_t a_util_pwr_sw_req_interval() const; | ||||||
|    float       a_low_fuel_level() const; |    [[nodiscard]] float         a_low_fuel_level() const; | ||||||
|    uint32_t    config_chan_number() const; |    [[nodiscard]] std::uint32_t config_chan_number() const; | ||||||
|    uint32_t    redundant_chan_config() const; |    [[nodiscard]] std::uint32_t redundant_chan_config() const; | ||||||
|    float       atten_table(unsigned i) const; |    [[nodiscard]] float         atten_table(unsigned i) const; | ||||||
|    float       path_losses(unsigned i) const; |    [[nodiscard]] float         path_losses(unsigned i) const; | ||||||
|    float       h_coupler_xmt_loss() const; |    [[nodiscard]] float         h_coupler_xmt_loss() const; | ||||||
|    float       h_coupler_cw_loss() const; |    [[nodiscard]] float         h_coupler_cw_loss() const; | ||||||
|    float       v_coupler_xmt_loss() const; |    [[nodiscard]] float         v_coupler_xmt_loss() const; | ||||||
|    float       ame_ts_bias() const; |    [[nodiscard]] float         ame_ts_bias() const; | ||||||
|    float       v_coupler_cw_loss() const; |    [[nodiscard]] float         v_coupler_cw_loss() const; | ||||||
|    float       pwr_sense_bias() const; |    [[nodiscard]] float         pwr_sense_bias() const; | ||||||
|    float       ame_v_noise_enr() const; |    [[nodiscard]] float         ame_v_noise_enr() const; | ||||||
|    float       chan_cal_diff() const; |    [[nodiscard]] float         chan_cal_diff() const; | ||||||
|    float       v_ts_cw() const; |    [[nodiscard]] float         v_ts_cw() const; | ||||||
|    float       h_rnscale(unsigned i) const; |    [[nodiscard]] float         h_rnscale(unsigned i) const; | ||||||
|    float       atmos(unsigned i) const; |    [[nodiscard]] float         atmos(unsigned i) const; | ||||||
|    float       el_index(unsigned i) const; |    [[nodiscard]] float         el_index(unsigned i) const; | ||||||
|    uint32_t    tfreq_mhz() const; |    [[nodiscard]] std::uint32_t tfreq_mhz() const; | ||||||
|    float       base_data_tcn() const; |    [[nodiscard]] float         base_data_tcn() const; | ||||||
|    float       refl_data_tover() const; |    [[nodiscard]] float         refl_data_tover() const; | ||||||
|    float       tar_h_dbz0_lp() const; |    [[nodiscard]] float         tar_h_dbz0_lp() const; | ||||||
|    float       tar_v_dbz0_lp() const; |    [[nodiscard]] float         tar_v_dbz0_lp() const; | ||||||
|    uint32_t    init_phi_dp() const; |    [[nodiscard]] std::uint32_t init_phi_dp() const; | ||||||
|    uint32_t    norm_init_phi_dp() const; |    [[nodiscard]] std::uint32_t norm_init_phi_dp() const; | ||||||
|    float       lx_lp() const; |    [[nodiscard]] float         lx_lp() const; | ||||||
|    float       lx_sp() const; |    [[nodiscard]] float         lx_sp() const; | ||||||
|    float       meteor_param() const; |    [[nodiscard]] float         meteor_param() const; | ||||||
|    float       antenna_gain() const; |    [[nodiscard]] float         antenna_gain() const; | ||||||
|    float       vel_degrad_limit() const; |    [[nodiscard]] float         vel_degrad_limit() const; | ||||||
|    float       wth_degrad_limit() const; |    [[nodiscard]] float         wth_degrad_limit() const; | ||||||
|    float       h_noisetemp_dgrad_limit() const; |    [[nodiscard]] float         h_noisetemp_dgrad_limit() const; | ||||||
|    uint32_t    h_min_noisetemp() const; |    [[nodiscard]] std::uint32_t h_min_noisetemp() const; | ||||||
|    float       v_noisetemp_dgrad_limit() const; |    [[nodiscard]] float         v_noisetemp_dgrad_limit() const; | ||||||
|    uint32_t    v_min_noisetemp() const; |    [[nodiscard]] std::uint32_t v_min_noisetemp() const; | ||||||
|    float       kly_degrade_limit() const; |    [[nodiscard]] float         kly_degrade_limit() const; | ||||||
|    float       ts_coho() const; |    [[nodiscard]] float         ts_coho() const; | ||||||
|    float       h_ts_cw() const; |    [[nodiscard]] float         h_ts_cw() const; | ||||||
|    float       ts_stalo() const; |    [[nodiscard]] float         ts_stalo() const; | ||||||
|    float       ame_h_noise_enr() const; |    [[nodiscard]] float         ame_h_noise_enr() const; | ||||||
|    float       xmtr_peak_pwr_high_limit() const; |    [[nodiscard]] float         xmtr_peak_pwr_high_limit() const; | ||||||
|    float       xmtr_peak_pwr_low_limit() const; |    [[nodiscard]] float         xmtr_peak_pwr_low_limit() const; | ||||||
|    float       h_dbz0_delta_limit() const; |    [[nodiscard]] float         h_dbz0_delta_limit() const; | ||||||
|    float       threshold1() const; |    [[nodiscard]] float         threshold1() const; | ||||||
|    float       threshold2() const; |    [[nodiscard]] float         threshold2() const; | ||||||
|    float       clut_supp_dgrad_lim() const; |    [[nodiscard]] float         clut_supp_dgrad_lim() const; | ||||||
|    float       range0_value() const; |    [[nodiscard]] float         range0_value() const; | ||||||
|    float       xmtr_pwr_mtr_scale() const; |    [[nodiscard]] float         xmtr_pwr_mtr_scale() const; | ||||||
|    float       v_dbz0_delta_limit() const; |    [[nodiscard]] float         v_dbz0_delta_limit() const; | ||||||
|    float       tar_h_dbz0_sp() const; |    [[nodiscard]] float         tar_h_dbz0_sp() const; | ||||||
|    float       tar_v_dbz0_sp() const; |    [[nodiscard]] float         tar_v_dbz0_sp() const; | ||||||
|    uint32_t    deltaprf() const; |    [[nodiscard]] std::uint32_t deltaprf() const; | ||||||
|    uint32_t    tau_sp() const; |    [[nodiscard]] std::uint32_t tau_sp() const; | ||||||
|    uint32_t    tau_lp() const; |    [[nodiscard]] std::uint32_t tau_lp() const; | ||||||
|    uint32_t    nc_dead_value() const; |    [[nodiscard]] std::uint32_t nc_dead_value() const; | ||||||
|    uint32_t    tau_rf_sp() const; |    [[nodiscard]] std::uint32_t tau_rf_sp() const; | ||||||
|    uint32_t    tau_rf_lp() const; |    [[nodiscard]] std::uint32_t tau_rf_lp() const; | ||||||
|    float       seg1_lim() const; |    [[nodiscard]] float         seg1_lim() const; | ||||||
|    float       slatsec() const; |    [[nodiscard]] float         slatsec() const; | ||||||
|    float       slonsec() const; |    [[nodiscard]] float         slonsec() const; | ||||||
|    uint32_t    slatdeg() const; |    [[nodiscard]] std::uint32_t slatdeg() const; | ||||||
|    uint32_t    slatmin() const; |    [[nodiscard]] std::uint32_t slatmin() const; | ||||||
|    uint32_t    slondeg() const; |    [[nodiscard]] std::uint32_t slondeg() const; | ||||||
|    uint32_t    slonmin() const; |    [[nodiscard]] std::uint32_t slonmin() const; | ||||||
|    char        slatdir() const; |    [[nodiscard]] char          slatdir() const; | ||||||
|    char        slondir() const; |    [[nodiscard]] char          slondir() const; | ||||||
|    float       az_correction_factor() const; |    [[nodiscard]] double        dig_rcvr_clock_freq() const; | ||||||
|    float       el_correction_factor() const; |    [[nodiscard]] double        coho_freq() const; | ||||||
|    std::string site_name() const; |    [[nodiscard]] float         az_correction_factor() const; | ||||||
|    float       ant_manual_setup_ielmin() const; |    [[nodiscard]] float         el_correction_factor() const; | ||||||
|    float       ant_manual_setup_ielmax() const; |    [[nodiscard]] std::string   site_name() const; | ||||||
|    uint32_t    ant_manual_setup_fazvelmax() const; |    [[nodiscard]] float         ant_manual_setup_ielmin() const; | ||||||
|    uint32_t    ant_manual_setup_felvelmax() const; |    [[nodiscard]] float         ant_manual_setup_ielmax() const; | ||||||
|    int32_t     ant_manual_setup_ignd_hgt() const; |    [[nodiscard]] std::uint32_t ant_manual_setup_fazvelmax() const; | ||||||
|    uint32_t    ant_manual_setup_irad_hgt() const; |    [[nodiscard]] std::uint32_t ant_manual_setup_felvelmax() const; | ||||||
|    float       az_pos_sustain_drive() const; |    [[nodiscard]] std::int32_t  ant_manual_setup_ignd_hgt() const; | ||||||
|    float       az_neg_sustain_drive() const; |    [[nodiscard]] std::uint32_t ant_manual_setup_irad_hgt() const; | ||||||
|    float       az_nom_pos_drive_slope() const; |    [[nodiscard]] float         az_pos_sustain_drive() const; | ||||||
|    float       az_nom_neg_drive_slope() const; |    [[nodiscard]] float         az_neg_sustain_drive() const; | ||||||
|    float       az_feedback_slope() const; |    [[nodiscard]] float         az_nom_pos_drive_slope() const; | ||||||
|    float       el_pos_sustain_drive() const; |    [[nodiscard]] float         az_nom_neg_drive_slope() const; | ||||||
|    float       el_neg_sustain_drive() const; |    [[nodiscard]] float         az_feedback_slope() const; | ||||||
|    float       el_nom_pos_drive_slope() const; |    [[nodiscard]] float         el_pos_sustain_drive() const; | ||||||
|    float       el_nom_neg_drive_slope() const; |    [[nodiscard]] float         el_neg_sustain_drive() const; | ||||||
|    float       el_feedback_slope() const; |    [[nodiscard]] float         el_nom_pos_drive_slope() const; | ||||||
|    float       el_first_slope() const; |    [[nodiscard]] float         el_nom_neg_drive_slope() const; | ||||||
|    float       el_second_slope() const; |    [[nodiscard]] float         el_feedback_slope() const; | ||||||
|    float       el_third_slope() const; |    [[nodiscard]] float         el_first_slope() const; | ||||||
|    float       el_droop_pos() const; |    [[nodiscard]] float         el_second_slope() const; | ||||||
|    float       el_off_neutral_drive() const; |    [[nodiscard]] float         el_third_slope() const; | ||||||
|    float       az_intertia() const; |    [[nodiscard]] float         el_droop_pos() const; | ||||||
|    float       el_inertia() const; |    [[nodiscard]] float         el_off_neutral_drive() const; | ||||||
|    uint32_t    rvp8nv_iwaveguide_length() const; |    [[nodiscard]] float         az_intertia() const; | ||||||
|    float       v_rnscale(unsigned i) const; |    [[nodiscard]] float         el_inertia() const; | ||||||
|    float       vel_data_tover() const; |    [[nodiscard]] float         az_stow_angle() const; | ||||||
|    float       width_data_tover() const; |    [[nodiscard]] float         el_stow_angle() const; | ||||||
|    float       doppler_range_start() const; |    [[nodiscard]] float         az_encoder_alignment() const; | ||||||
|    uint32_t    max_el_index() const; |    [[nodiscard]] float         el_encoder_alignment() const; | ||||||
|    float       seg2_lim() const; |    [[nodiscard]] std::string   refined_park() const; | ||||||
|    float       seg3_lim() const; |    [[nodiscard]] std::uint32_t rvp8nv_iwaveguide_length() const; | ||||||
|    float       seg4_lim() const; |    [[nodiscard]] float         v_rnscale(unsigned i) const; | ||||||
|    uint32_t    nbr_el_segments() const; |    [[nodiscard]] float         vel_data_tover() const; | ||||||
|    float       h_noise_long() const; |    [[nodiscard]] float         width_data_tover() const; | ||||||
|    float       ant_noise_temp() const; |    [[nodiscard]] float         doppler_range_start() const; | ||||||
|    float       h_noise_short() const; |    [[nodiscard]] std::uint32_t max_el_index() const; | ||||||
|    float       h_noise_tolerance() const; |    [[nodiscard]] float         seg2_lim() const; | ||||||
|    float       min_h_dyn_range() const; |    [[nodiscard]] float         seg3_lim() const; | ||||||
|    bool        gen_installed() const; |    [[nodiscard]] float         seg4_lim() const; | ||||||
|    bool        gen_exercise() const; |    [[nodiscard]] std::uint32_t nbr_el_segments() const; | ||||||
|    float       v_noise_tolerance() const; |    [[nodiscard]] float         h_noise_long() const; | ||||||
|    float       min_v_dyn_range() const; |    [[nodiscard]] float         ant_noise_temp() const; | ||||||
|    float       zdr_bias_dgrad_lim() const; |    [[nodiscard]] float         h_noise_short() const; | ||||||
|    float       baseline_zdr_bias() const; |    [[nodiscard]] float         h_noise_tolerance() const; | ||||||
|    float       v_noise_long() const; |    [[nodiscard]] float         min_h_dyn_range() const; | ||||||
|    float       v_noise_short() const; |    [[nodiscard]] bool          gen_installed() const; | ||||||
|    float       zdr_data_tover() const; |    [[nodiscard]] bool          gen_exercise() const; | ||||||
|    float       phi_data_tover() const; |    [[nodiscard]] float         v_noise_tolerance() const; | ||||||
|    float       rho_data_tover() const; |    [[nodiscard]] float         min_v_dyn_range() const; | ||||||
|    float       stalo_power_dgrad_limit() const; |    [[nodiscard]] float         zdr_offset_dgrad_lim() const; | ||||||
|    float       stalo_power_maint_limit() const; |    [[nodiscard]] float         baseline_zdr_offset() const; | ||||||
|    float       min_h_pwr_sense() const; |    [[nodiscard]] float         v_noise_long() const; | ||||||
|    float       min_v_pwr_sense() const; |    [[nodiscard]] float         v_noise_short() const; | ||||||
|    float       h_pwr_sense_offset() const; |    [[nodiscard]] float         zdr_data_tover() const; | ||||||
|    float       v_pwr_sense_offset() const; |    [[nodiscard]] float         phi_data_tover() const; | ||||||
|    float       ps_gain_ref() const; |    [[nodiscard]] float         rho_data_tover() const; | ||||||
|    float       rf_pallet_broad_loss() const; |    [[nodiscard]] float         stalo_power_dgrad_limit() const; | ||||||
|    float       ame_ps_tolerance() const; |    [[nodiscard]] float         stalo_power_maint_limit() const; | ||||||
|    float       ame_max_temp() const; |    [[nodiscard]] float         min_h_pwr_sense() const; | ||||||
|    float       ame_min_temp() const; |    [[nodiscard]] float         min_v_pwr_sense() const; | ||||||
|    float       rcvr_mod_max_temp() const; |    [[nodiscard]] float         h_pwr_sense_offset() const; | ||||||
|    float       rcvr_mod_min_temp() const; |    [[nodiscard]] float         v_pwr_sense_offset() const; | ||||||
|    float       bite_mod_max_temp() const; |    [[nodiscard]] float         ps_gain_ref() const; | ||||||
|    float       bite_mod_min_temp() const; |    [[nodiscard]] float         rf_pallet_broad_loss() const; | ||||||
|    uint32_t    default_polarization() const; |    [[nodiscard]] float         ame_ps_tolerance() const; | ||||||
|    float       tr_limit_dgrad_limit() const; |    [[nodiscard]] float         ame_max_temp() const; | ||||||
|    float       tr_limit_fail_limit() const; |    [[nodiscard]] float         ame_min_temp() const; | ||||||
|    bool        rfp_stepper_enabled() const; |    [[nodiscard]] float         rcvr_mod_max_temp() const; | ||||||
|    float       ame_current_tolerance() const; |    [[nodiscard]] float         rcvr_mod_min_temp() const; | ||||||
|    uint32_t    h_only_polarization() const; |    [[nodiscard]] float         bite_mod_max_temp() const; | ||||||
|    uint32_t    v_only_polarization() const; |    [[nodiscard]] float         bite_mod_min_temp() const; | ||||||
|    float       sun_bias() const; |    [[nodiscard]] std::uint32_t default_polarization() const; | ||||||
|    float       a_min_shelter_temp_warn() const; |    [[nodiscard]] float         tr_limit_dgrad_limit() const; | ||||||
|    float       power_meter_zero() const; |    [[nodiscard]] float         tr_limit_fail_limit() const; | ||||||
|    float       txb_baseline() const; |    [[nodiscard]] bool          rfp_stepper_enabled() const; | ||||||
|    float       txb_alarm_thresh() const; |    [[nodiscard]] float         ame_current_tolerance() const; | ||||||
|  |    [[nodiscard]] std::uint32_t h_only_polarization() const; | ||||||
|  |    [[nodiscard]] std::uint32_t v_only_polarization() const; | ||||||
|  |    [[nodiscard]] float         sun_bias() const; | ||||||
|  |    [[nodiscard]] float         a_min_shelter_temp_warn() const; | ||||||
|  |    [[nodiscard]] float         power_meter_zero() const; | ||||||
|  |    [[nodiscard]] float         txb_baseline() const; | ||||||
|  |    [[nodiscard]] float         txb_alarm_thresh() const; | ||||||
| 
 | 
 | ||||||
|    bool Parse(std::istream& is); |    bool Parse(std::istream& is) override; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<RdaAdaptationData> |    static std::shared_ptr<RdaAdaptationData> | ||||||
|    Create(Level2MessageHeader&& header, std::istream& is); |    Create(Level2MessageHeader&& header, std::istream& is); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|    std::unique_ptr<RdaAdaptationDataImpl> p; |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace rda
 | } // namespace scwx::wsr88d::rda
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
							
								
								
									
										30
									
								
								wxdata/include/scwx/wsr88d/rda/rda_prf_data.hpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										30
									
								
								wxdata/include/scwx/wsr88d/rda/rda_prf_data.hpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,30 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/wsr88d/rda/level2_message.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx::wsr88d::rda | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class RdaPrfData : public Level2Message | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit RdaPrfData(); | ||||||
|  |    ~RdaPrfData() override; | ||||||
|  | 
 | ||||||
|  |    RdaPrfData(const RdaPrfData&)            = delete; | ||||||
|  |    RdaPrfData& operator=(const RdaPrfData&) = delete; | ||||||
|  | 
 | ||||||
|  |    RdaPrfData(RdaPrfData&&) noexcept; | ||||||
|  |    RdaPrfData& operator=(RdaPrfData&&) noexcept; | ||||||
|  | 
 | ||||||
|  |    bool Parse(std::istream& is) override; | ||||||
|  | 
 | ||||||
|  |    static std::shared_ptr<RdaPrfData> Create(Level2MessageHeader&& header, | ||||||
|  |                                              std::istream&         is); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace scwx::wsr88d::rda
 | ||||||
|  | @ -2,14 +2,8 @@ | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rda/level2_message.hpp> | #include <scwx/wsr88d/rda/level2_message.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rda | ||||||
| { | { | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rda |  | ||||||
| { |  | ||||||
| 
 |  | ||||||
| class RdaStatusDataImpl; |  | ||||||
| 
 | 
 | ||||||
| class RdaStatusData : public Level2Message | class RdaStatusData : public Level2Message | ||||||
| { | { | ||||||
|  | @ -17,51 +11,51 @@ public: | ||||||
|    explicit RdaStatusData(); |    explicit RdaStatusData(); | ||||||
|    ~RdaStatusData(); |    ~RdaStatusData(); | ||||||
| 
 | 
 | ||||||
|    RdaStatusData(const RdaStatusData&) = delete; |    RdaStatusData(const RdaStatusData&)            = delete; | ||||||
|    RdaStatusData& operator=(const RdaStatusData&) = delete; |    RdaStatusData& operator=(const RdaStatusData&) = delete; | ||||||
| 
 | 
 | ||||||
|    RdaStatusData(RdaStatusData&&) noexcept; |    RdaStatusData(RdaStatusData&&) noexcept; | ||||||
|    RdaStatusData& operator=(RdaStatusData&&) noexcept; |    RdaStatusData& operator=(RdaStatusData&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    uint16_t rda_status() const; |    [[nodiscard]] std::uint16_t rda_status() const; | ||||||
|    uint16_t operability_status() const; |    [[nodiscard]] std::uint16_t operability_status() const; | ||||||
|    uint16_t control_status() const; |    [[nodiscard]] std::uint16_t control_status() const; | ||||||
|    uint16_t auxiliary_power_generator_state() const; |    [[nodiscard]] std::uint16_t auxiliary_power_generator_state() const; | ||||||
|    uint16_t average_transmitter_power() const; |    [[nodiscard]] std::uint16_t average_transmitter_power() const; | ||||||
|    float    horizontal_reflectivity_calibration_correction() const; |    [[nodiscard]] float horizontal_reflectivity_calibration_correction() const; | ||||||
|    uint16_t data_transmission_enabled() const; |    [[nodiscard]] std::uint16_t data_transmission_enabled() const; | ||||||
|    uint16_t volume_coverage_pattern_number() const; |    [[nodiscard]] std::uint16_t volume_coverage_pattern_number() const; | ||||||
|    uint16_t rda_control_authorization() const; |    [[nodiscard]] std::uint16_t rda_control_authorization() const; | ||||||
|    uint16_t rda_build_number() const; |    [[nodiscard]] std::uint16_t rda_build_number() const; | ||||||
|    uint16_t operational_mode() const; |    [[nodiscard]] std::uint16_t operational_mode() const; | ||||||
|    uint16_t super_resolution_status() const; |    [[nodiscard]] std::uint16_t super_resolution_status() const; | ||||||
|    uint16_t clutter_mitigation_decision_status() const; |    [[nodiscard]] std::uint16_t clutter_mitigation_decision_status() const; | ||||||
|    uint16_t avset_ebc_rda_log_data_status() const; |    [[nodiscard]] std::uint16_t rda_scan_and_data_flags() const; | ||||||
|    uint16_t rda_alarm_summary() const; |    [[nodiscard]] std::uint16_t rda_alarm_summary() const; | ||||||
|    uint16_t command_acknowledgement() const; |    [[nodiscard]] std::uint16_t command_acknowledgement() const; | ||||||
|    uint16_t channel_control_status() const; |    [[nodiscard]] std::uint16_t channel_control_status() const; | ||||||
|    uint16_t spot_blanking_status() const; |    [[nodiscard]] std::uint16_t spot_blanking_status() const; | ||||||
|    uint16_t bypass_map_generation_date() const; |    [[nodiscard]] std::uint16_t bypass_map_generation_date() const; | ||||||
|    uint16_t bypass_map_generation_time() const; |    [[nodiscard]] std::uint16_t bypass_map_generation_time() const; | ||||||
|    uint16_t clutter_filter_map_generation_date() const; |    [[nodiscard]] std::uint16_t clutter_filter_map_generation_date() const; | ||||||
|    uint16_t clutter_filter_map_generation_time() const; |    [[nodiscard]] std::uint16_t clutter_filter_map_generation_time() const; | ||||||
|    float    vertical_reflectivity_calibration_correction() const; |    [[nodiscard]] float vertical_reflectivity_calibration_correction() const; | ||||||
|    uint16_t transition_power_source_status() const; |    [[nodiscard]] std::uint16_t transition_power_source_status() const; | ||||||
|    uint16_t rms_control_status() const; |    [[nodiscard]] std::uint16_t rms_control_status() const; | ||||||
|    uint16_t performance_check_status() const; |    [[nodiscard]] std::uint16_t performance_check_status() const; | ||||||
|    uint16_t alarm_codes(unsigned i) const; |    [[nodiscard]] std::uint16_t alarm_codes(unsigned i) const; | ||||||
|    uint16_t signal_processing_options() const; |    [[nodiscard]] std::uint16_t signal_processing_options() const; | ||||||
|    uint16_t status_version() const; |    [[nodiscard]] std::uint16_t downloaded_pattern_number() const; | ||||||
|  |    [[nodiscard]] std::uint16_t status_version() const; | ||||||
| 
 | 
 | ||||||
|    bool Parse(std::istream& is); |    bool Parse(std::istream& is) override; | ||||||
| 
 | 
 | ||||||
|    static std::shared_ptr<RdaStatusData> Create(Level2MessageHeader&& header, |    static std::shared_ptr<RdaStatusData> Create(Level2MessageHeader&& header, | ||||||
|                                                 std::istream&         is); |                                                 std::istream&         is); | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|    std::unique_ptr<RdaStatusDataImpl> p; |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace rda
 | } // namespace scwx::wsr88d::rda
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,48 @@ | ||||||
|  | #pragma once | ||||||
|  | 
 | ||||||
|  | #include <scwx/wsr88d/rpg/packet.hpp> | ||||||
|  | 
 | ||||||
|  | #include <cstdint> | ||||||
|  | #include <memory> | ||||||
|  | 
 | ||||||
|  | namespace scwx::wsr88d::rpg | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | class DigitalRasterDataArrayPacket : public Packet | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit DigitalRasterDataArrayPacket(); | ||||||
|  |    ~DigitalRasterDataArrayPacket() override; | ||||||
|  | 
 | ||||||
|  |    DigitalRasterDataArrayPacket(const DigitalRasterDataArrayPacket&) = delete; | ||||||
|  |    DigitalRasterDataArrayPacket& | ||||||
|  |    operator=(const DigitalRasterDataArrayPacket&) = delete; | ||||||
|  | 
 | ||||||
|  |    DigitalRasterDataArrayPacket(DigitalRasterDataArrayPacket&&) noexcept; | ||||||
|  |    DigitalRasterDataArrayPacket& | ||||||
|  |    operator=(DigitalRasterDataArrayPacket&&) noexcept; | ||||||
|  | 
 | ||||||
|  |    [[nodiscard]] std::uint16_t packet_code() const override; | ||||||
|  |    [[nodiscard]] std::uint16_t i_coordinate_start() const; | ||||||
|  |    [[nodiscard]] std::uint16_t j_coordinate_start() const; | ||||||
|  |    [[nodiscard]] std::uint16_t i_scale_factor() const; | ||||||
|  |    [[nodiscard]] std::uint16_t j_scale_factor() const; | ||||||
|  |    [[nodiscard]] std::uint16_t number_of_cells() const; | ||||||
|  |    [[nodiscard]] std::uint16_t number_of_rows() const; | ||||||
|  | 
 | ||||||
|  |    [[nodiscard]] std::uint16_t number_of_bytes_in_row(std::uint16_t r) const; | ||||||
|  |    [[nodiscard]] const std::vector<std::uint8_t>& level(std::uint16_t r) const; | ||||||
|  | 
 | ||||||
|  |    [[nodiscard]] std::size_t data_size() const override; | ||||||
|  | 
 | ||||||
|  |    bool Parse(std::istream& is) override; | ||||||
|  | 
 | ||||||
|  |    static std::shared_ptr<DigitalRasterDataArrayPacket> | ||||||
|  |    Create(std::istream& is); | ||||||
|  | 
 | ||||||
|  | private: | ||||||
|  |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | } // namespace scwx::wsr88d::rpg
 | ||||||
|  | @ -2,29 +2,22 @@ | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rpg/level3_message.hpp> | #include <scwx/wsr88d/rpg/level3_message.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rpg | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rpg |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| class Level3MessageFactory | class Level3MessageFactory | ||||||
| { | { | ||||||
| private: | public: | ||||||
|    explicit Level3MessageFactory() = delete; |    explicit Level3MessageFactory() = delete; | ||||||
|    ~Level3MessageFactory()         = delete; |    ~Level3MessageFactory()         = delete; | ||||||
| 
 | 
 | ||||||
|    Level3MessageFactory(const Level3MessageFactory&) = delete; |    Level3MessageFactory(const Level3MessageFactory&)            = delete; | ||||||
|    Level3MessageFactory& operator=(const Level3MessageFactory&) = delete; |    Level3MessageFactory& operator=(const Level3MessageFactory&) = delete; | ||||||
| 
 | 
 | ||||||
|    Level3MessageFactory(Level3MessageFactory&&) noexcept = delete; |    Level3MessageFactory(Level3MessageFactory&&) noexcept            = delete; | ||||||
|    Level3MessageFactory& operator=(Level3MessageFactory&&) noexcept = delete; |    Level3MessageFactory& operator=(Level3MessageFactory&&) noexcept = delete; | ||||||
| 
 | 
 | ||||||
| public: |  | ||||||
|    static std::shared_ptr<Level3Message> Create(std::istream& is); |    static std::shared_ptr<Level3Message> Create(std::istream& is); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace rpg
 | } // namespace scwx::wsr88d::rpg
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -2,29 +2,22 @@ | ||||||
| 
 | 
 | ||||||
| #include <scwx/wsr88d/rpg/packet.hpp> | #include <scwx/wsr88d/rpg/packet.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rpg | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rpg |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| class PacketFactory | class PacketFactory | ||||||
| { | { | ||||||
| private: | public: | ||||||
|    explicit PacketFactory() = delete; |    explicit PacketFactory() = delete; | ||||||
|    ~PacketFactory()         = delete; |    ~PacketFactory()         = delete; | ||||||
| 
 | 
 | ||||||
|    PacketFactory(const PacketFactory&) = delete; |    PacketFactory(const PacketFactory&)            = delete; | ||||||
|    PacketFactory& operator=(const PacketFactory&) = delete; |    PacketFactory& operator=(const PacketFactory&) = delete; | ||||||
| 
 | 
 | ||||||
|    PacketFactory(PacketFactory&&) noexcept = delete; |    PacketFactory(PacketFactory&&) noexcept            = delete; | ||||||
|    PacketFactory& operator=(PacketFactory&&) noexcept = delete; |    PacketFactory& operator=(PacketFactory&&) noexcept = delete; | ||||||
| 
 | 
 | ||||||
| public: |  | ||||||
|    static std::shared_ptr<Packet> Create(std::istream& is); |    static std::shared_ptr<Packet> Create(std::istream& is); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace rpg
 | } // namespace scwx::wsr88d::rpg
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -12,8 +12,6 @@ | ||||||
| namespace scwx::wsr88d::rpg | namespace scwx::wsr88d::rpg | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| class ProductDescriptionBlockImpl; |  | ||||||
| 
 |  | ||||||
| class ProductDescriptionBlock : public awips::Message | class ProductDescriptionBlock : public awips::Message | ||||||
| { | { | ||||||
| public: | public: | ||||||
|  | @ -26,38 +24,38 @@ public: | ||||||
|    ProductDescriptionBlock(ProductDescriptionBlock&&) noexcept; |    ProductDescriptionBlock(ProductDescriptionBlock&&) noexcept; | ||||||
|    ProductDescriptionBlock& operator=(ProductDescriptionBlock&&) noexcept; |    ProductDescriptionBlock& operator=(ProductDescriptionBlock&&) noexcept; | ||||||
| 
 | 
 | ||||||
|    [[nodiscard]] int16_t  block_divider() const; |    [[nodiscard]] std::int16_t  block_divider() const; | ||||||
|    [[nodiscard]] float    latitude_of_radar() const; |    [[nodiscard]] float         latitude_of_radar() const; | ||||||
|    [[nodiscard]] float    longitude_of_radar() const; |    [[nodiscard]] float         longitude_of_radar() const; | ||||||
|    [[nodiscard]] int16_t  height_of_radar() const; |    [[nodiscard]] std::int16_t  height_of_radar() const; | ||||||
|    [[nodiscard]] int16_t  product_code() const; |    [[nodiscard]] std::int16_t  product_code() const; | ||||||
|    [[nodiscard]] uint16_t operational_mode() const; |    [[nodiscard]] std::uint16_t operational_mode() const; | ||||||
|    [[nodiscard]] uint16_t volume_coverage_pattern() const; |    [[nodiscard]] std::uint16_t volume_coverage_pattern() const; | ||||||
|    [[nodiscard]] int16_t  sequence_number() const; |    [[nodiscard]] std::int16_t  sequence_number() const; | ||||||
|    [[nodiscard]] uint16_t volume_scan_number() const; |    [[nodiscard]] std::uint16_t volume_scan_number() const; | ||||||
|    [[nodiscard]] uint16_t volume_scan_date() const; |    [[nodiscard]] std::uint16_t volume_scan_date() const; | ||||||
|    [[nodiscard]] uint32_t volume_scan_start_time() const; |    [[nodiscard]] std::uint32_t volume_scan_start_time() const; | ||||||
|    [[nodiscard]] uint16_t generation_date_of_product() const; |    [[nodiscard]] std::uint16_t generation_date_of_product() const; | ||||||
|    [[nodiscard]] uint32_t generation_time_of_product() const; |    [[nodiscard]] std::uint32_t generation_time_of_product() const; | ||||||
|    [[nodiscard]] uint16_t elevation_number() const; |    [[nodiscard]] std::uint16_t elevation_number() const; | ||||||
|    [[nodiscard]] uint16_t data_level_threshold(size_t i) const; |    [[nodiscard]] std::uint16_t data_level_threshold(size_t i) const; | ||||||
|    [[nodiscard]] uint8_t  version() const; |    [[nodiscard]] std::uint8_t  version() const; | ||||||
|    [[nodiscard]] uint8_t  spot_blank() const; |    [[nodiscard]] std::uint8_t  spot_blank() const; | ||||||
|    [[nodiscard]] uint32_t offset_to_symbology() const; |    [[nodiscard]] std::uint32_t offset_to_symbology() const; | ||||||
|    [[nodiscard]] uint32_t offset_to_graphic() const; |    [[nodiscard]] std::uint32_t offset_to_graphic() const; | ||||||
|    [[nodiscard]] uint32_t offset_to_tabular() const; |    [[nodiscard]] std::uint32_t offset_to_tabular() const; | ||||||
| 
 | 
 | ||||||
|    [[nodiscard]] float    range() const; |    [[nodiscard]] float         range() const; | ||||||
|    [[nodiscard]] uint16_t range_raw() const; |    [[nodiscard]] std::uint16_t range_raw() const; | ||||||
|    [[nodiscard]] float    x_resolution() const; |    [[nodiscard]] float         x_resolution() const; | ||||||
|    [[nodiscard]] uint16_t x_resolution_raw() const; |    [[nodiscard]] std::uint16_t x_resolution_raw() const; | ||||||
|    [[nodiscard]] float    y_resolution() const; |    [[nodiscard]] float         y_resolution() const; | ||||||
|    [[nodiscard]] uint16_t y_resolution_raw() const; |    [[nodiscard]] std::uint16_t y_resolution_raw() const; | ||||||
| 
 | 
 | ||||||
|    [[nodiscard]] uint16_t threshold() const; |    [[nodiscard]] std::uint16_t threshold() const; | ||||||
|    [[nodiscard]] float    offset() const; |    [[nodiscard]] float         offset() const; | ||||||
|    [[nodiscard]] float    scale() const; |    [[nodiscard]] float         scale() const; | ||||||
|    [[nodiscard]] uint16_t number_of_levels() const; |    [[nodiscard]] std::uint16_t number_of_levels() const; | ||||||
| 
 | 
 | ||||||
|    [[nodiscard]] std::optional<DataLevelCode> |    [[nodiscard]] std::optional<DataLevelCode> | ||||||
|                                       data_level_code(std::uint8_t level) const; |                                       data_level_code(std::uint8_t level) const; | ||||||
|  | @ -78,14 +76,15 @@ public: | ||||||
|    [[nodiscard]] bool IsCompressionEnabled() const; |    [[nodiscard]] bool IsCompressionEnabled() const; | ||||||
|    [[nodiscard]] bool IsDataLevelCoded() const; |    [[nodiscard]] bool IsDataLevelCoded() const; | ||||||
| 
 | 
 | ||||||
|    [[nodiscard]] size_t data_size() const override; |    [[nodiscard]] std::size_t data_size() const override; | ||||||
| 
 | 
 | ||||||
|    bool Parse(std::istream& is) override; |    bool Parse(std::istream& is) override; | ||||||
| 
 | 
 | ||||||
|    static constexpr size_t SIZE = 102u; |    static constexpr std::size_t SIZE = 102u; | ||||||
| 
 | 
 | ||||||
| private: | private: | ||||||
|    std::unique_ptr<ProductDescriptionBlockImpl> p; |    class Impl; | ||||||
|  |    std::unique_ptr<Impl> p; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| } // namespace scwx::wsr88d::rpg
 | } // namespace scwx::wsr88d::rpg
 | ||||||
|  |  | ||||||
|  | @ -9,17 +9,22 @@ namespace awips | ||||||
| static const std::string logPrefix_ = "scwx::awips::message"; | static const std::string logPrefix_ = "scwx::awips::message"; | ||||||
| static const auto        logger_    = util::Logger::Create(logPrefix_); | static const auto        logger_    = util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| class MessageImpl | class Message::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit MessageImpl() {}; |    explicit Impl() = default; | ||||||
|    ~MessageImpl() = default; |    ~Impl()         = default; | ||||||
|  | 
 | ||||||
|  |    Impl(const Impl&)             = delete; | ||||||
|  |    Impl& operator=(const Impl&)  = delete; | ||||||
|  |    Impl(const Impl&&)            = delete; | ||||||
|  |    Impl& operator=(const Impl&&) = delete; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| Message::Message() : p(std::make_unique<MessageImpl>()) {} | Message::Message() : p(std::make_unique<Impl>()) {} | ||||||
| Message::~Message() = default; | Message::~Message() = default; | ||||||
| 
 | 
 | ||||||
| Message::Message(Message&&) noexcept = default; | Message::Message(Message&&) noexcept            = default; | ||||||
| Message& Message::operator=(Message&&) noexcept = default; | Message& Message::operator=(Message&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
| bool Message::ValidateMessage(std::istream& is, size_t bytesRead) const | bool Message::ValidateMessage(std::istream& is, size_t bytesRead) const | ||||||
|  |  | ||||||
|  | @ -1,11 +1,7 @@ | ||||||
| #include <scwx/wsr88d/rda/digital_radar_data_generic.hpp> | #include <scwx/wsr88d/rda/digital_radar_data_generic.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rda | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rda |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| static const std::string logPrefix_ = | static const std::string logPrefix_ = | ||||||
|  | @ -27,9 +23,9 @@ static const std::unordered_map<std::string, DataBlockType> strToDataBlock_ { | ||||||
| class DigitalRadarDataGeneric::DataBlock::Impl | class DigitalRadarDataGeneric::DataBlock::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl(const std::string& dataBlockType, |    explicit Impl(std::string dataBlockType, std::string dataName) : | ||||||
|                  const std::string& dataName) : |        dataBlockType_ {std::move(dataBlockType)}, | ||||||
|        dataBlockType_ {dataBlockType}, dataName_ {dataName} |        dataName_ {std::move(dataName)} | ||||||
|    { |    { | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  | @ -51,7 +47,13 @@ DigitalRadarDataGeneric::DataBlock::operator=(DataBlock&&) noexcept = default; | ||||||
| class DigitalRadarDataGeneric::MomentDataBlock::Impl | class DigitalRadarDataGeneric::MomentDataBlock::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl() {} |    explicit Impl() = default; | ||||||
|  |    ~Impl()         = default; | ||||||
|  | 
 | ||||||
|  |    Impl(const Impl&)             = delete; | ||||||
|  |    Impl& operator=(const Impl&)  = delete; | ||||||
|  |    Impl(const Impl&&)            = delete; | ||||||
|  |    Impl& operator=(const Impl&&) = delete; | ||||||
| 
 | 
 | ||||||
|    std::uint16_t numberOfDataMomentGates_ {0}; |    std::uint16_t numberOfDataMomentGates_ {0}; | ||||||
|    std::int16_t  dataMomentRange_ {0}; |    std::int16_t  dataMomentRange_ {0}; | ||||||
|  | @ -89,7 +91,9 @@ DigitalRadarDataGeneric::MomentDataBlock::number_of_data_moment_gates() const | ||||||
| units::kilometers<float> | units::kilometers<float> | ||||||
| DigitalRadarDataGeneric::MomentDataBlock::data_moment_range() const | DigitalRadarDataGeneric::MomentDataBlock::data_moment_range() const | ||||||
| { | { | ||||||
|    return units::kilometers<float> {p->dataMomentRange_ * 0.001f}; |    static constexpr float kScale_ = 0.001f; | ||||||
|  |    return units::kilometers<float> {static_cast<float>(p->dataMomentRange_) * | ||||||
|  |                                     kScale_}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::int16_t | std::int16_t | ||||||
|  | @ -102,7 +106,9 @@ units::kilometers<float> | ||||||
| DigitalRadarDataGeneric::MomentDataBlock::data_moment_range_sample_interval() | DigitalRadarDataGeneric::MomentDataBlock::data_moment_range_sample_interval() | ||||||
|    const |    const | ||||||
| { | { | ||||||
|    return units::kilometers<float> {p->dataMomentRangeSampleInterval_ * 0.001f}; |    static constexpr float kScale_ = 0.001f; | ||||||
|  |    return units::kilometers<float> { | ||||||
|  |       static_cast<float>(p->dataMomentRangeSampleInterval_) * kScale_}; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::uint16_t DigitalRadarDataGeneric::MomentDataBlock:: | std::uint16_t DigitalRadarDataGeneric::MomentDataBlock:: | ||||||
|  | @ -113,7 +119,8 @@ std::uint16_t DigitalRadarDataGeneric::MomentDataBlock:: | ||||||
| 
 | 
 | ||||||
| float DigitalRadarDataGeneric::MomentDataBlock::snr_threshold() const | float DigitalRadarDataGeneric::MomentDataBlock::snr_threshold() const | ||||||
| { | { | ||||||
|    return p->snrThreshold_ * 0.1f; |    static constexpr float kScale_ = 0.1f; | ||||||
|  |    return static_cast<float>(p->snrThreshold_) * kScale_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::int16_t DigitalRadarDataGeneric::MomentDataBlock::snr_threshold_raw() const | std::int16_t DigitalRadarDataGeneric::MomentDataBlock::snr_threshold_raw() const | ||||||
|  | @ -138,14 +145,14 @@ float DigitalRadarDataGeneric::MomentDataBlock::offset() const | ||||||
| 
 | 
 | ||||||
| const void* DigitalRadarDataGeneric::MomentDataBlock::data_moments() const | const void* DigitalRadarDataGeneric::MomentDataBlock::data_moments() const | ||||||
| { | { | ||||||
|    const void* dataMoments; |    const void* dataMoments = nullptr; | ||||||
| 
 | 
 | ||||||
|    switch (p->dataWordSize_) |    switch (p->dataWordSize_) | ||||||
|    { |    { | ||||||
|    case 8: |    case 8: // NOLINT(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|       dataMoments = p->momentGates8_.data(); |       dataMoments = p->momentGates8_.data(); | ||||||
|       break; |       break; | ||||||
|    case 16: |    case 16: // NOLINT(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|       dataMoments = p->momentGates16_.data(); |       dataMoments = p->momentGates16_.data(); | ||||||
|       break; |       break; | ||||||
|    default: |    default: | ||||||
|  | @ -189,13 +196,15 @@ bool DigitalRadarDataGeneric::MomentDataBlock::Parse(std::istream& is) | ||||||
|    is.read(reinterpret_cast<char*>(&p->scale_), 4);        // 20-23
 |    is.read(reinterpret_cast<char*>(&p->scale_), 4);        // 20-23
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->offset_), 4);       // 24-27
 |    is.read(reinterpret_cast<char*>(&p->offset_), 4);       // 24-27
 | ||||||
| 
 | 
 | ||||||
|    p->numberOfDataMomentGates_       = ntohs(p->numberOfDataMomentGates_); |    p->numberOfDataMomentGates_ = ntohs(p->numberOfDataMomentGates_); | ||||||
|    p->dataMomentRange_               = ntohs(p->dataMomentRange_); |    p->dataMomentRange_ = static_cast<std::int16_t>(ntohs(p->dataMomentRange_)); | ||||||
|    p->dataMomentRangeSampleInterval_ = ntohs(p->dataMomentRangeSampleInterval_); |    p->dataMomentRangeSampleInterval_ = ntohs(p->dataMomentRangeSampleInterval_); | ||||||
|    p->tover_                         = ntohs(p->tover_); |    p->tover_                         = ntohs(p->tover_); | ||||||
|    p->snrThreshold_                  = ntohs(p->snrThreshold_); |    p->snrThreshold_ = static_cast<std::int16_t>(ntohs(p->snrThreshold_)); | ||||||
|    p->scale_                         = awips::Message::SwapFloat(p->scale_); |    p->scale_        = awips::Message::SwapFloat(p->scale_); | ||||||
|    p->offset_                        = awips::Message::SwapFloat(p->offset_); |    p->offset_       = awips::Message::SwapFloat(p->offset_); | ||||||
|  | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
| 
 | 
 | ||||||
|    if (p->numberOfDataMomentGates_ <= 1840) |    if (p->numberOfDataMomentGates_ <= 1840) | ||||||
|    { |    { | ||||||
|  | @ -209,7 +218,7 @@ bool DigitalRadarDataGeneric::MomentDataBlock::Parse(std::istream& is) | ||||||
|       { |       { | ||||||
|          p->momentGates16_.resize(p->numberOfDataMomentGates_); |          p->momentGates16_.resize(p->numberOfDataMomentGates_); | ||||||
|          is.read(reinterpret_cast<char*>(p->momentGates16_.data()), |          is.read(reinterpret_cast<char*>(p->momentGates16_.data()), | ||||||
|                  p->numberOfDataMomentGates_ * 2); |                  static_cast<std::streamsize>(p->numberOfDataMomentGates_) * 2); | ||||||
|          awips::Message::SwapVector(p->momentGates16_); |          awips::Message::SwapVector(p->momentGates16_); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|  | @ -225,13 +234,21 @@ bool DigitalRadarDataGeneric::MomentDataBlock::Parse(std::istream& is) | ||||||
|       dataBlockValid = false; |       dataBlockValid = false; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return dataBlockValid; |    return dataBlockValid; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class DigitalRadarDataGeneric::VolumeDataBlock::Impl | class DigitalRadarDataGeneric::VolumeDataBlock::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl() {} |    explicit Impl() = default; | ||||||
|  |    ~Impl()         = default; | ||||||
|  | 
 | ||||||
|  |    Impl(const Impl&)             = delete; | ||||||
|  |    Impl& operator=(const Impl&)  = delete; | ||||||
|  |    Impl(const Impl&&)            = delete; | ||||||
|  |    Impl& operator=(const Impl&&) = delete; | ||||||
| 
 | 
 | ||||||
|    std::uint16_t lrtup_ {0}; |    std::uint16_t lrtup_ {0}; | ||||||
|    std::uint8_t  versionNumberMajor_ {0}; |    std::uint8_t  versionNumberMajor_ {0}; | ||||||
|  | @ -247,6 +264,7 @@ public: | ||||||
|    float         initialSystemDifferentialPhase_ {0.0f}; |    float         initialSystemDifferentialPhase_ {0.0f}; | ||||||
|    std::uint16_t volumeCoveragePatternNumber_ {0}; |    std::uint16_t volumeCoveragePatternNumber_ {0}; | ||||||
|    std::uint16_t processingStatus_ {0}; |    std::uint16_t processingStatus_ {0}; | ||||||
|  |    std::uint16_t zdrBiasEstimateWeightedMean_ {0}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| DigitalRadarDataGeneric::VolumeDataBlock::VolumeDataBlock( | DigitalRadarDataGeneric::VolumeDataBlock::VolumeDataBlock( | ||||||
|  | @ -320,7 +338,7 @@ bool DigitalRadarDataGeneric::VolumeDataBlock::Parse(std::istream& is) | ||||||
|    p->lrtup_               = ntohs(p->lrtup_); |    p->lrtup_               = ntohs(p->lrtup_); | ||||||
|    p->latitude_            = awips::Message::SwapFloat(p->latitude_); |    p->latitude_            = awips::Message::SwapFloat(p->latitude_); | ||||||
|    p->longitude_           = awips::Message::SwapFloat(p->longitude_); |    p->longitude_           = awips::Message::SwapFloat(p->longitude_); | ||||||
|    p->siteHeight_          = ntohs(p->siteHeight_); |    p->siteHeight_          = static_cast<std::int16_t>(ntohs(p->siteHeight_)); | ||||||
|    p->feedhornHeight_      = ntohs(p->feedhornHeight_); |    p->feedhornHeight_      = ntohs(p->feedhornHeight_); | ||||||
|    p->calibrationConstant_ = awips::Message::SwapFloat(p->calibrationConstant_); |    p->calibrationConstant_ = awips::Message::SwapFloat(p->calibrationConstant_); | ||||||
|    p->horizontaShvTxPower_ = awips::Message::SwapFloat(p->horizontaShvTxPower_); |    p->horizontaShvTxPower_ = awips::Message::SwapFloat(p->horizontaShvTxPower_); | ||||||
|  | @ -332,13 +350,35 @@ bool DigitalRadarDataGeneric::VolumeDataBlock::Parse(std::istream& is) | ||||||
|    p->volumeCoveragePatternNumber_ = ntohs(p->volumeCoveragePatternNumber_); |    p->volumeCoveragePatternNumber_ = ntohs(p->volumeCoveragePatternNumber_); | ||||||
|    p->processingStatus_            = ntohs(p->processingStatus_); |    p->processingStatus_            = ntohs(p->processingStatus_); | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|  |    if (p->lrtup_ >= 46) | ||||||
|  |    { | ||||||
|  |       is.read(reinterpret_cast<char*>(&p->zdrBiasEstimateWeightedMean_), | ||||||
|  |               2); // 44-45
 | ||||||
|  |       p->zdrBiasEstimateWeightedMean_ = ntohs(p->zdrBiasEstimateWeightedMean_); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (p->lrtup_ >= 52) | ||||||
|  |    { | ||||||
|  |       is.seekg(6, std::ios_base::cur); // 46-51
 | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return dataBlockValid; |    return dataBlockValid; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| class DigitalRadarDataGeneric::ElevationDataBlock::Impl | class DigitalRadarDataGeneric::ElevationDataBlock::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl() {} |    explicit Impl() = default; | ||||||
|  |    ~Impl()         = default; | ||||||
|  | 
 | ||||||
|  |    Impl(const Impl&)             = delete; | ||||||
|  |    Impl& operator=(const Impl&)  = delete; | ||||||
|  |    Impl(const Impl&&)            = delete; | ||||||
|  |    Impl& operator=(const Impl&&) = delete; | ||||||
| 
 | 
 | ||||||
|    std::uint16_t lrtup_ {0}; |    std::uint16_t lrtup_ {0}; | ||||||
|    std::int16_t  atmos_ {0}; |    std::int16_t  atmos_ {0}; | ||||||
|  | @ -384,7 +424,7 @@ bool DigitalRadarDataGeneric::ElevationDataBlock::Parse(std::istream& is) | ||||||
|    is.read(reinterpret_cast<char*>(&p->calibrationConstant_), 4); // 8-11
 |    is.read(reinterpret_cast<char*>(&p->calibrationConstant_), 4); // 8-11
 | ||||||
| 
 | 
 | ||||||
|    p->lrtup_               = ntohs(p->lrtup_); |    p->lrtup_               = ntohs(p->lrtup_); | ||||||
|    p->atmos_               = ntohs(p->atmos_); |    p->atmos_               = static_cast<std::int16_t>(ntohs(p->atmos_)); | ||||||
|    p->calibrationConstant_ = awips::Message::SwapFloat(p->calibrationConstant_); |    p->calibrationConstant_ = awips::Message::SwapFloat(p->calibrationConstant_); | ||||||
| 
 | 
 | ||||||
|    return dataBlockValid; |    return dataBlockValid; | ||||||
|  | @ -393,7 +433,13 @@ bool DigitalRadarDataGeneric::ElevationDataBlock::Parse(std::istream& is) | ||||||
| class DigitalRadarDataGeneric::RadialDataBlock::Impl | class DigitalRadarDataGeneric::RadialDataBlock::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl() {} |    explicit Impl() = default; | ||||||
|  |    ~Impl()         = default; | ||||||
|  | 
 | ||||||
|  |    Impl(const Impl&)             = delete; | ||||||
|  |    Impl& operator=(const Impl&)  = delete; | ||||||
|  |    Impl(const Impl&&)            = delete; | ||||||
|  |    Impl& operator=(const Impl&&) = delete; | ||||||
| 
 | 
 | ||||||
|    std::uint16_t lrtup_ {0}; |    std::uint16_t lrtup_ {0}; | ||||||
|    std::uint16_t unambigiousRange_ {0}; |    std::uint16_t unambigiousRange_ {0}; | ||||||
|  | @ -420,7 +466,8 @@ DigitalRadarDataGeneric::RadialDataBlock::operator=( | ||||||
| 
 | 
 | ||||||
| float DigitalRadarDataGeneric::RadialDataBlock::unambiguous_range() const | float DigitalRadarDataGeneric::RadialDataBlock::unambiguous_range() const | ||||||
| { | { | ||||||
|    return p->unambigiousRange_ / 10.0f; |    static constexpr float kScale_ = 0.1f; | ||||||
|  |    return static_cast<float>(p->unambigiousRange_) * kScale_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<DigitalRadarDataGeneric::RadialDataBlock> | std::shared_ptr<DigitalRadarDataGeneric::RadialDataBlock> | ||||||
|  | @ -473,24 +520,31 @@ bool DigitalRadarDataGeneric::RadialDataBlock::Parse(std::istream& is) | ||||||
| class DigitalRadarDataGeneric::Impl | class DigitalRadarDataGeneric::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit Impl() {}; |    explicit Impl() = default; | ||||||
|    ~Impl() = default; |    ~Impl()         = default; | ||||||
| 
 | 
 | ||||||
|    std::string                   radarIdentifier_ {}; |    Impl(const Impl&)             = delete; | ||||||
|    std::uint32_t                 collectionTime_ {0}; |    Impl& operator=(const Impl&)  = delete; | ||||||
|    std::uint16_t                 modifiedJulianDate_ {0}; |    Impl(const Impl&&)            = delete; | ||||||
|    std::uint16_t                 azimuthNumber_ {0}; |    Impl& operator=(const Impl&&) = delete; | ||||||
|    float                         azimuthAngle_ {0.0f}; | 
 | ||||||
|    std::uint8_t                  compressionIndicator_ {0}; |    std::string   radarIdentifier_ {}; | ||||||
|    std::uint16_t                 radialLength_ {0}; |    std::uint32_t collectionTime_ {0}; | ||||||
|    std::uint8_t                  azimuthResolutionSpacing_ {0}; |    std::uint16_t modifiedJulianDate_ {0}; | ||||||
|    std::uint8_t                  radialStatus_ {0}; |    std::uint16_t azimuthNumber_ {0}; | ||||||
|    std::uint8_t                  elevationNumber_ {0}; |    float         azimuthAngle_ {0.0f}; | ||||||
|    std::uint8_t                  cutSectorNumber_ {0}; |    std::uint8_t  compressionIndicator_ {0}; | ||||||
|    float                         elevationAngle_ {0.0f}; |    std::uint16_t radialLength_ {0}; | ||||||
|    std::uint8_t                  radialSpotBlankingStatus_ {0}; |    std::uint8_t  azimuthResolutionSpacing_ {0}; | ||||||
|    std::uint8_t                  azimuthIndexingMode_ {0}; |    std::uint8_t  radialStatus_ {0}; | ||||||
|    std::uint16_t                 dataBlockCount_ {0}; |    std::uint8_t  elevationNumber_ {0}; | ||||||
|  |    std::uint8_t  cutSectorNumber_ {0}; | ||||||
|  |    float         elevationAngle_ {0.0f}; | ||||||
|  |    std::uint8_t  radialSpotBlankingStatus_ {0}; | ||||||
|  |    std::uint8_t  azimuthIndexingMode_ {0}; | ||||||
|  |    std::uint16_t dataBlockCount_ {0}; | ||||||
|  | 
 | ||||||
|  |    // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|    std::array<std::uint32_t, 10> dataBlockPointer_ {0}; |    std::array<std::uint32_t, 10> dataBlockPointer_ {0}; | ||||||
| 
 | 
 | ||||||
|    std::shared_ptr<VolumeDataBlock>    volumeDataBlock_ {nullptr}; |    std::shared_ptr<VolumeDataBlock>    volumeDataBlock_ {nullptr}; | ||||||
|  | @ -666,6 +720,8 @@ bool DigitalRadarDataGeneric::Parse(std::istream& is) | ||||||
|    p->elevationAngle_     = SwapFloat(p->elevationAngle_); |    p->elevationAngle_     = SwapFloat(p->elevationAngle_); | ||||||
|    p->dataBlockCount_     = ntohs(p->dataBlockCount_); |    p->dataBlockCount_     = ntohs(p->dataBlockCount_); | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    if (p->azimuthNumber_ < 1 || p->azimuthNumber_ > 720) |    if (p->azimuthNumber_ < 1 || p->azimuthNumber_ > 720) | ||||||
|    { |    { | ||||||
|       logger_->warn("Invalid azimuth number: {}", p->azimuthNumber_); |       logger_->warn("Invalid azimuth number: {}", p->azimuthNumber_); | ||||||
|  | @ -687,18 +743,22 @@ bool DigitalRadarDataGeneric::Parse(std::istream& is) | ||||||
|       messageValid = false; |       messageValid = false; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    if (!messageValid) |    if (!messageValid) | ||||||
|    { |    { | ||||||
|       p->dataBlockCount_ = 0; |       p->dataBlockCount_ = 0; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->dataBlockPointer_), |    is.read(reinterpret_cast<char*>(&p->dataBlockPointer_), | ||||||
|            p->dataBlockCount_ * 4); |            static_cast<std::streamsize>(p->dataBlockCount_) * 4); | ||||||
| 
 | 
 | ||||||
|    SwapArray(p->dataBlockPointer_, p->dataBlockCount_); |    SwapArray(p->dataBlockPointer_, p->dataBlockCount_); | ||||||
| 
 | 
 | ||||||
|    for (uint16_t b = 0; b < p->dataBlockCount_; ++b) |    for (uint16_t b = 0; b < p->dataBlockCount_; ++b) | ||||||
|    { |    { | ||||||
|  |       // Index already has bounds check
 | ||||||
|  |       // NOLINTNEXTLINE(cppcoreguidelines-pro-bounds-constant-array-index)
 | ||||||
|       is.seekg(isBegin + std::streamoff(p->dataBlockPointer_[b]), |       is.seekg(isBegin + std::streamoff(p->dataBlockPointer_[b]), | ||||||
|                std::ios_base::beg); |                std::ios_base::beg); | ||||||
| 
 | 
 | ||||||
|  | @ -771,6 +831,4 @@ DigitalRadarDataGeneric::Create(Level2MessageHeader&& header, std::istream& is) | ||||||
|    return message; |    return message; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace rda
 | } // namespace scwx::wsr88d::rda
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -8,26 +8,23 @@ | ||||||
| #include <scwx/wsr88d/rda/digital_radar_data_generic.hpp> | #include <scwx/wsr88d/rda/digital_radar_data_generic.hpp> | ||||||
| #include <scwx/wsr88d/rda/performance_maintenance_data.hpp> | #include <scwx/wsr88d/rda/performance_maintenance_data.hpp> | ||||||
| #include <scwx/wsr88d/rda/rda_adaptation_data.hpp> | #include <scwx/wsr88d/rda/rda_adaptation_data.hpp> | ||||||
|  | #include <scwx/wsr88d/rda/rda_prf_data.hpp> | ||||||
| #include <scwx/wsr88d/rda/rda_status_data.hpp> | #include <scwx/wsr88d/rda/rda_status_data.hpp> | ||||||
| #include <scwx/wsr88d/rda/volume_coverage_pattern_data.hpp> | #include <scwx/wsr88d/rda/volume_coverage_pattern_data.hpp> | ||||||
| 
 | 
 | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| #include <vector> | #include <vector> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rda | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rda |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| static const std::string logPrefix_ = | static const std::string logPrefix_ = | ||||||
|    "scwx::wsr88d::rda::level2_message_factory"; |    "scwx::wsr88d::rda::level2_message_factory"; | ||||||
| static const auto logger_ = util::Logger::Create(logPrefix_); | static const auto logger_ = util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| typedef std::function<std::shared_ptr<Level2Message>(Level2MessageHeader&&, | using CreateLevel2MessageFunction = | ||||||
|                                                      std::istream&)> |    std::function<std::shared_ptr<Level2Message>(Level2MessageHeader&&, | ||||||
|    CreateLevel2MessageFunction; |                                                 std::istream&)>; | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<unsigned int, CreateLevel2MessageFunction> | static const std::unordered_map<unsigned int, CreateLevel2MessageFunction> | ||||||
|    create_ {{1, DigitalRadarData::Create}, |    create_ {{1, DigitalRadarData::Create}, | ||||||
|  | @ -37,20 +34,18 @@ static const std::unordered_map<unsigned int, CreateLevel2MessageFunction> | ||||||
|             {13, ClutterFilterBypassMap::Create}, |             {13, ClutterFilterBypassMap::Create}, | ||||||
|             {15, ClutterFilterMap::Create}, |             {15, ClutterFilterMap::Create}, | ||||||
|             {18, RdaAdaptationData::Create}, |             {18, RdaAdaptationData::Create}, | ||||||
|             {31, DigitalRadarDataGeneric::Create}}; |             {31, DigitalRadarDataGeneric::Create}, | ||||||
|  |             {32, RdaPrfData::Create}}; | ||||||
| 
 | 
 | ||||||
| struct Level2MessageFactory::Context | struct Level2MessageFactory::Context | ||||||
| { | { | ||||||
|    Context() : |    Context() : | ||||||
|        messageData_ {}, |        messageBuffer_ {messageData_}, messageBufferStream_ {&messageBuffer_} | ||||||
|        bufferedSize_ {}, |  | ||||||
|        messageBuffer_ {messageData_}, |  | ||||||
|        messageBufferStream_ {&messageBuffer_} |  | ||||||
|    { |    { | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    std::vector<char> messageData_; |    std::vector<char> messageData_ {}; | ||||||
|    size_t            bufferedSize_; |    std::size_t       bufferedSize_ {}; | ||||||
|    util::vectorbuf   messageBuffer_; |    util::vectorbuf   messageBuffer_; | ||||||
|    std::istream      messageBufferStream_; |    std::istream      messageBufferStream_; | ||||||
|    bool              bufferingData_ {false}; |    bool              bufferingData_ {false}; | ||||||
|  | @ -76,13 +71,16 @@ Level2MessageInfo Level2MessageFactory::Create(std::istream&             is, | ||||||
| 
 | 
 | ||||||
|    if (info.headerValid) |    if (info.headerValid) | ||||||
|    { |    { | ||||||
|       if (header.message_size() == 65535) |       if (header.message_size() == std::numeric_limits<std::uint16_t>::max()) | ||||||
|       { |       { | ||||||
|  |          // A message size of 65535 indicates a message with a single segment.
 | ||||||
|  |          // The size is specified in the bytes normally reserved for the segment
 | ||||||
|  |          // number and total number of segments.
 | ||||||
|          segment       = 1; |          segment       = 1; | ||||||
|          totalSegments = 1; |          totalSegments = 1; | ||||||
|          dataSize = |          dataSize = | ||||||
|             (static_cast<std::size_t>(header.number_of_message_segments()) |             (static_cast<std::size_t>(header.number_of_message_segments()) | ||||||
|              << 16) + |              << 16) + // NOLINT(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|             header.message_segment_number(); |             header.message_segment_number(); | ||||||
|       } |       } | ||||||
|       else |       else | ||||||
|  | @ -143,14 +141,16 @@ Level2MessageInfo Level2MessageFactory::Create(std::istream&             is, | ||||||
|                logger_->debug("Bad size estimate, increasing size"); |                logger_->debug("Bad size estimate, increasing size"); | ||||||
| 
 | 
 | ||||||
|                // Estimate remaining size
 |                // Estimate remaining size
 | ||||||
|                uint16_t remainingSegments = |                static const std::uint16_t kMinRemainingSegments_ = 100u; | ||||||
|                   std::max<uint16_t>(totalSegments - segment + 1, 100u); |                const std::uint16_t remainingSegments = std::max<std::uint16_t>( | ||||||
|                size_t remainingSize = remainingSegments * dataSize; |                   totalSegments - segment + 1, kMinRemainingSegments_); | ||||||
|  |                const std::size_t remainingSize = remainingSegments * dataSize; | ||||||
| 
 | 
 | ||||||
|                ctx->messageData_.resize(ctx->bufferedSize_ + remainingSize); |                ctx->messageData_.resize(ctx->bufferedSize_ + remainingSize); | ||||||
|             } |             } | ||||||
| 
 | 
 | ||||||
|             is.read(ctx->messageData_.data() + ctx->bufferedSize_, dataSize); |             is.read(&ctx->messageData_[ctx->bufferedSize_], | ||||||
|  |                     static_cast<std::streamsize>(dataSize)); | ||||||
|             ctx->bufferedSize_ += dataSize; |             ctx->bufferedSize_ += dataSize; | ||||||
| 
 | 
 | ||||||
|             if (is.eof()) |             if (is.eof()) | ||||||
|  | @ -164,7 +164,7 @@ Level2MessageInfo Level2MessageFactory::Create(std::istream&             is, | ||||||
|             else if (segment == totalSegments) |             else if (segment == totalSegments) | ||||||
|             { |             { | ||||||
|                ctx->messageBuffer_.update_read_pointers(ctx->bufferedSize_); |                ctx->messageBuffer_.update_read_pointers(ctx->bufferedSize_); | ||||||
|                header.set_message_size(static_cast<uint16_t>( |                header.set_message_size(static_cast<std::uint16_t>( | ||||||
|                   ctx->bufferedSize_ / 2 + Level2MessageHeader::SIZE)); |                   ctx->bufferedSize_ / 2 + Level2MessageHeader::SIZE)); | ||||||
| 
 | 
 | ||||||
|                messageStream = &ctx->messageBufferStream_; |                messageStream = &ctx->messageBufferStream_; | ||||||
|  | @ -186,7 +186,7 @@ Level2MessageInfo Level2MessageFactory::Create(std::istream&             is, | ||||||
|    else if (info.headerValid) |    else if (info.headerValid) | ||||||
|    { |    { | ||||||
|       // Seek to the end of the current message
 |       // Seek to the end of the current message
 | ||||||
|       is.seekg(dataSize, std::ios_base::cur); |       is.seekg(static_cast<std::streamoff>(dataSize), std::ios_base::cur); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    if (info.message == nullptr) |    if (info.message == nullptr) | ||||||
|  | @ -197,6 +197,4 @@ Level2MessageInfo Level2MessageFactory::Create(std::istream&             is, | ||||||
|    return info; |    return info; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace rda
 | } // namespace scwx::wsr88d::rda
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
										
											
												File diff suppressed because it is too large
												Load diff
											
										
									
								
							
							
								
								
									
										120
									
								
								wxdata/source/scwx/wsr88d/rda/rda_prf_data.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										120
									
								
								wxdata/source/scwx/wsr88d/rda/rda_prf_data.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,120 @@ | ||||||
|  | #include <scwx/wsr88d/rda/rda_prf_data.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | namespace scwx::wsr88d::rda | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = "scwx::wsr88d::rda::rda_prf_data"; | ||||||
|  | static const auto        logger_    = scwx::util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | struct RdaPrfWaveformData | ||||||
|  | { | ||||||
|  |    std::uint16_t              waveformType_ {0}; | ||||||
|  |    std::uint16_t              prfCount_ {0}; | ||||||
|  |    std::vector<std::uint32_t> prfValues_ {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | class RdaPrfData::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    explicit Impl() = default; | ||||||
|  |    ~Impl()         = default; | ||||||
|  | 
 | ||||||
|  |    Impl(const Impl&)             = delete; | ||||||
|  |    Impl& operator=(const Impl&)  = delete; | ||||||
|  |    Impl(const Impl&&)            = delete; | ||||||
|  |    Impl& operator=(const Impl&&) = delete; | ||||||
|  | 
 | ||||||
|  |    std::uint16_t                   numberOfWaveforms_ {0}; | ||||||
|  |    std::vector<RdaPrfWaveformData> waveformData_ {}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | RdaPrfData::RdaPrfData() : p(std::make_unique<Impl>()) {} | ||||||
|  | RdaPrfData::~RdaPrfData() = default; | ||||||
|  | 
 | ||||||
|  | RdaPrfData::RdaPrfData(RdaPrfData&&) noexcept            = default; | ||||||
|  | RdaPrfData& RdaPrfData::operator=(RdaPrfData&&) noexcept = default; | ||||||
|  | 
 | ||||||
|  | bool RdaPrfData::Parse(std::istream& is) | ||||||
|  | { | ||||||
|  |    logger_->trace("Parsing RDA PRF Data (Message Type 32)"); | ||||||
|  | 
 | ||||||
|  |    bool        messageValid = true; | ||||||
|  |    std::size_t bytesRead    = 0; | ||||||
|  | 
 | ||||||
|  |    const std::streampos isBegin = is.tellg(); | ||||||
|  | 
 | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->numberOfWaveforms_), 2); // 1
 | ||||||
|  |    is.seekg(2, std::ios_base::cur);                             // 2
 | ||||||
|  | 
 | ||||||
|  |    bytesRead += 4; | ||||||
|  | 
 | ||||||
|  |    p->numberOfWaveforms_ = ntohs(p->numberOfWaveforms_); | ||||||
|  | 
 | ||||||
|  |    // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers): Readability
 | ||||||
|  |    if (p->numberOfWaveforms_ < 1 || p->numberOfWaveforms_ > 5) | ||||||
|  |    { | ||||||
|  |       logger_->warn("Invalid number of waveforms: {}", p->numberOfWaveforms_); | ||||||
|  |       p->numberOfWaveforms_ = 0; | ||||||
|  |       messageValid          = false; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    p->waveformData_.resize(p->numberOfWaveforms_); | ||||||
|  | 
 | ||||||
|  |    for (std::uint16_t i = 0; i < p->numberOfWaveforms_; ++i) | ||||||
|  |    { | ||||||
|  |       auto& w = p->waveformData_[i]; | ||||||
|  | 
 | ||||||
|  |       is.read(reinterpret_cast<char*>(&w.waveformType_), 2); // P1
 | ||||||
|  |       is.read(reinterpret_cast<char*>(&w.prfCount_), 2);     // P2
 | ||||||
|  | 
 | ||||||
|  |       w.waveformType_ = ntohs(w.waveformType_); | ||||||
|  |       w.prfCount_     = ntohs(w.prfCount_); | ||||||
|  | 
 | ||||||
|  |       bytesRead += 4; | ||||||
|  | 
 | ||||||
|  |       // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers): Readability
 | ||||||
|  |       if (w.prfCount_ > 255) | ||||||
|  |       { | ||||||
|  |          logger_->warn("Invalid PRF count: {} (waveform {})", w.prfCount_, i); | ||||||
|  |          w.prfCount_  = 0; | ||||||
|  |          messageValid = false; | ||||||
|  |          break; | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       w.prfValues_.resize(w.prfCount_); | ||||||
|  | 
 | ||||||
|  |       for (std::uint16_t j = 0; j < w.prfCount_; ++j) | ||||||
|  |       { | ||||||
|  |          is.read(reinterpret_cast<char*>(&w.prfValues_[j]), 4); | ||||||
|  |       } | ||||||
|  | 
 | ||||||
|  |       bytesRead += static_cast<std::size_t>(w.prfCount_) * 4; | ||||||
|  | 
 | ||||||
|  |       SwapVector(w.prfValues_); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    is.seekg(isBegin, std::ios_base::beg); | ||||||
|  |    if (!ValidateMessage(is, bytesRead)) | ||||||
|  |    { | ||||||
|  |       messageValid = false; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return messageValid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<RdaPrfData> RdaPrfData::Create(Level2MessageHeader&& header, | ||||||
|  |                                                std::istream&         is) | ||||||
|  | { | ||||||
|  |    std::shared_ptr<RdaPrfData> message = std::make_shared<RdaPrfData>(); | ||||||
|  |    message->set_header(std::move(header)); | ||||||
|  | 
 | ||||||
|  |    if (!message->Parse(is)) | ||||||
|  |    { | ||||||
|  |       message.reset(); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return message; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace scwx::wsr88d::rda
 | ||||||
|  | @ -1,232 +1,214 @@ | ||||||
| #include <scwx/wsr88d/rda/rda_status_data.hpp> | #include <scwx/wsr88d/rda/rda_status_data.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rda | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rda |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| static const std::string logPrefix_ = "scwx::wsr88d::rda::rda_status_data"; | static const std::string logPrefix_ = "scwx::wsr88d::rda::rda_status_data"; | ||||||
| static const auto        logger_    = util::Logger::Create(logPrefix_); | static const auto        logger_    = util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| class RdaStatusDataImpl | class RdaStatusData::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit RdaStatusDataImpl() : |    explicit Impl() = default; | ||||||
|        rdaStatus_ {0}, |    ~Impl()         = default; | ||||||
|        operabilityStatus_ {0}, |  | ||||||
|        controlStatus_ {0}, |  | ||||||
|        auxiliaryPowerGeneratorState_ {0}, |  | ||||||
|        averageTransmitterPower_ {0}, |  | ||||||
|        horizontalReflectivityCalibrationCorrection_ {0}, |  | ||||||
|        dataTransmissionEnabled_ {0}, |  | ||||||
|        volumeCoveragePatternNumber_ {0}, |  | ||||||
|        rdaControlAuthorization_ {0}, |  | ||||||
|        rdaBuildNumber_ {0}, |  | ||||||
|        operationalMode_ {0}, |  | ||||||
|        superResolutionStatus_ {0}, |  | ||||||
|        clutterMitigationDecisionStatus_ {0}, |  | ||||||
|        avsetEbcRdaLogDataStatus_ {0}, |  | ||||||
|        rdaAlarmSummary_ {0}, |  | ||||||
|        commandAcknowledgement_ {0}, |  | ||||||
|        channelControlStatus_ {0}, |  | ||||||
|        spotBlankingStatus_ {0}, |  | ||||||
|        bypassMapGenerationDate_ {0}, |  | ||||||
|        bypassMapGenerationTime_ {0}, |  | ||||||
|        clutterFilterMapGenerationDate_ {0}, |  | ||||||
|        clutterFilterMapGenerationTime_ {0}, |  | ||||||
|        verticalReflectivityCalibrationCorrection_ {0}, |  | ||||||
|        transitionPowerSourceStatus_ {0}, |  | ||||||
|        rmsControlStatus_ {0}, |  | ||||||
|        performanceCheckStatus_ {0}, |  | ||||||
|        alarmCodes_ {0}, |  | ||||||
|        signalProcessingOptions_ {0}, |  | ||||||
|        statusVersion_ {0} {}; |  | ||||||
|    ~RdaStatusDataImpl() = default; |  | ||||||
| 
 | 
 | ||||||
|    uint16_t                 rdaStatus_; |    Impl(const Impl&)             = delete; | ||||||
|    uint16_t                 operabilityStatus_; |    Impl& operator=(const Impl&)  = delete; | ||||||
|    uint16_t                 controlStatus_; |    Impl(const Impl&&)            = delete; | ||||||
|    uint16_t                 auxiliaryPowerGeneratorState_; |    Impl& operator=(const Impl&&) = delete; | ||||||
|    uint16_t                 averageTransmitterPower_; | 
 | ||||||
|    int16_t                  horizontalReflectivityCalibrationCorrection_; |    std::uint16_t rdaStatus_ {0}; | ||||||
|    uint16_t                 dataTransmissionEnabled_; |    std::uint16_t operabilityStatus_ {0}; | ||||||
|    uint16_t                 volumeCoveragePatternNumber_; |    std::uint16_t controlStatus_ {0}; | ||||||
|    uint16_t                 rdaControlAuthorization_; |    std::uint16_t auxiliaryPowerGeneratorState_ {0}; | ||||||
|    uint16_t                 rdaBuildNumber_; |    std::uint16_t averageTransmitterPower_ {0}; | ||||||
|    uint16_t                 operationalMode_; |    std::int16_t  horizontalReflectivityCalibrationCorrection_ {0}; | ||||||
|    uint16_t                 superResolutionStatus_; |    std::uint16_t dataTransmissionEnabled_ {0}; | ||||||
|    uint16_t                 clutterMitigationDecisionStatus_; |    std::uint16_t volumeCoveragePatternNumber_ {0}; | ||||||
|    uint16_t                 avsetEbcRdaLogDataStatus_; |    std::uint16_t rdaControlAuthorization_ {0}; | ||||||
|    uint16_t                 rdaAlarmSummary_; |    std::uint16_t rdaBuildNumber_ {0}; | ||||||
|    uint16_t                 commandAcknowledgement_; |    std::uint16_t operationalMode_ {0}; | ||||||
|    uint16_t                 channelControlStatus_; |    std::uint16_t superResolutionStatus_ {0}; | ||||||
|    uint16_t                 spotBlankingStatus_; |    std::uint16_t clutterMitigationDecisionStatus_ {0}; | ||||||
|    uint16_t                 bypassMapGenerationDate_; |    std::uint16_t rdaScanAndDataFlags_ {0}; | ||||||
|    uint16_t                 bypassMapGenerationTime_; |    std::uint16_t rdaAlarmSummary_ {0}; | ||||||
|    uint16_t                 clutterFilterMapGenerationDate_; |    std::uint16_t commandAcknowledgement_ {0}; | ||||||
|    uint16_t                 clutterFilterMapGenerationTime_; |    std::uint16_t channelControlStatus_ {0}; | ||||||
|    int16_t                  verticalReflectivityCalibrationCorrection_; |    std::uint16_t spotBlankingStatus_ {0}; | ||||||
|    uint16_t                 transitionPowerSourceStatus_; |    std::uint16_t bypassMapGenerationDate_ {0}; | ||||||
|    uint16_t                 rmsControlStatus_; |    std::uint16_t bypassMapGenerationTime_ {0}; | ||||||
|    uint16_t                 performanceCheckStatus_; |    std::uint16_t clutterFilterMapGenerationDate_ {0}; | ||||||
|    std::array<uint16_t, 14> alarmCodes_; |    std::uint16_t clutterFilterMapGenerationTime_ {0}; | ||||||
|    uint16_t                 signalProcessingOptions_; |    std::int16_t  verticalReflectivityCalibrationCorrection_ {0}; | ||||||
|    uint16_t                 statusVersion_; |    std::uint16_t transitionPowerSourceStatus_ {0}; | ||||||
|  |    std::uint16_t rmsControlStatus_ {0}; | ||||||
|  |    std::uint16_t performanceCheckStatus_ {0}; | ||||||
|  | 
 | ||||||
|  |    // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  |    std::array<std::uint16_t, 14> alarmCodes_ {0}; | ||||||
|  | 
 | ||||||
|  |    std::uint16_t signalProcessingOptions_ {0}; | ||||||
|  |    std::uint16_t downloadedPatternNumber_ {0}; | ||||||
|  |    std::uint16_t statusVersion_ {0}; | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| RdaStatusData::RdaStatusData() : | RdaStatusData::RdaStatusData() : Level2Message(), p(std::make_unique<Impl>()) {} | ||||||
|     Level2Message(), p(std::make_unique<RdaStatusDataImpl>()) |  | ||||||
| { |  | ||||||
| } |  | ||||||
| RdaStatusData::~RdaStatusData() = default; | RdaStatusData::~RdaStatusData() = default; | ||||||
| 
 | 
 | ||||||
| RdaStatusData::RdaStatusData(RdaStatusData&&) noexcept = default; | RdaStatusData::RdaStatusData(RdaStatusData&&) noexcept            = default; | ||||||
| RdaStatusData& RdaStatusData::operator=(RdaStatusData&&) noexcept = default; | RdaStatusData& RdaStatusData::operator=(RdaStatusData&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::rda_status() const | std::uint16_t RdaStatusData::rda_status() const | ||||||
| { | { | ||||||
|    return p->rdaStatus_; |    return p->rdaStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::operability_status() const | std::uint16_t RdaStatusData::operability_status() const | ||||||
| { | { | ||||||
|    return p->operabilityStatus_; |    return p->operabilityStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::control_status() const | std::uint16_t RdaStatusData::control_status() const | ||||||
| { | { | ||||||
|    return p->controlStatus_; |    return p->controlStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::auxiliary_power_generator_state() const | std::uint16_t RdaStatusData::auxiliary_power_generator_state() const | ||||||
| { | { | ||||||
|    return p->auxiliaryPowerGeneratorState_; |    return p->auxiliaryPowerGeneratorState_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::average_transmitter_power() const | std::uint16_t RdaStatusData::average_transmitter_power() const | ||||||
| { | { | ||||||
|    return p->averageTransmitterPower_; |    return p->averageTransmitterPower_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float RdaStatusData::horizontal_reflectivity_calibration_correction() const | float RdaStatusData::horizontal_reflectivity_calibration_correction() const | ||||||
| { | { | ||||||
|    return p->horizontalReflectivityCalibrationCorrection_ * 0.01f; |    constexpr float kScale_ = 0.01f; | ||||||
|  |    return static_cast<float>(p->horizontalReflectivityCalibrationCorrection_) * | ||||||
|  |           kScale_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::data_transmission_enabled() const | std::uint16_t RdaStatusData::data_transmission_enabled() const | ||||||
| { | { | ||||||
|    return p->dataTransmissionEnabled_; |    return p->dataTransmissionEnabled_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::volume_coverage_pattern_number() const | std::uint16_t RdaStatusData::volume_coverage_pattern_number() const | ||||||
| { | { | ||||||
|    return p->volumeCoveragePatternNumber_; |    return p->volumeCoveragePatternNumber_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::rda_control_authorization() const | std::uint16_t RdaStatusData::rda_control_authorization() const | ||||||
| { | { | ||||||
|    return p->rdaControlAuthorization_; |    return p->rdaControlAuthorization_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::rda_build_number() const | std::uint16_t RdaStatusData::rda_build_number() const | ||||||
| { | { | ||||||
|    return p->rdaBuildNumber_; |    return p->rdaBuildNumber_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::operational_mode() const | std::uint16_t RdaStatusData::operational_mode() const | ||||||
| { | { | ||||||
|    return p->operationalMode_; |    return p->operationalMode_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::super_resolution_status() const | std::uint16_t RdaStatusData::super_resolution_status() const | ||||||
| { | { | ||||||
|    return p->superResolutionStatus_; |    return p->superResolutionStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::clutter_mitigation_decision_status() const | std::uint16_t RdaStatusData::clutter_mitigation_decision_status() const | ||||||
| { | { | ||||||
|    return p->clutterMitigationDecisionStatus_; |    return p->clutterMitigationDecisionStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::avset_ebc_rda_log_data_status() const | std::uint16_t RdaStatusData::rda_scan_and_data_flags() const | ||||||
| { | { | ||||||
|    return p->avsetEbcRdaLogDataStatus_; |    return p->rdaScanAndDataFlags_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::rda_alarm_summary() const | std::uint16_t RdaStatusData::rda_alarm_summary() const | ||||||
| { | { | ||||||
|    return p->rdaAlarmSummary_; |    return p->rdaAlarmSummary_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::command_acknowledgement() const | std::uint16_t RdaStatusData::command_acknowledgement() const | ||||||
| { | { | ||||||
|    return p->commandAcknowledgement_; |    return p->commandAcknowledgement_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::channel_control_status() const | std::uint16_t RdaStatusData::channel_control_status() const | ||||||
| { | { | ||||||
|    return p->channelControlStatus_; |    return p->channelControlStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::spot_blanking_status() const | std::uint16_t RdaStatusData::spot_blanking_status() const | ||||||
| { | { | ||||||
|    return p->spotBlankingStatus_; |    return p->spotBlankingStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::bypass_map_generation_date() const | std::uint16_t RdaStatusData::bypass_map_generation_date() const | ||||||
| { | { | ||||||
|    return p->bypassMapGenerationDate_; |    return p->bypassMapGenerationDate_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::bypass_map_generation_time() const | std::uint16_t RdaStatusData::bypass_map_generation_time() const | ||||||
| { | { | ||||||
|    return p->bypassMapGenerationTime_; |    return p->bypassMapGenerationTime_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::clutter_filter_map_generation_date() const | std::uint16_t RdaStatusData::clutter_filter_map_generation_date() const | ||||||
| { | { | ||||||
|    return p->clutterFilterMapGenerationDate_; |    return p->clutterFilterMapGenerationDate_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::clutter_filter_map_generation_time() const | std::uint16_t RdaStatusData::clutter_filter_map_generation_time() const | ||||||
| { | { | ||||||
|    return p->clutterFilterMapGenerationTime_; |    return p->clutterFilterMapGenerationTime_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float RdaStatusData::vertical_reflectivity_calibration_correction() const | float RdaStatusData::vertical_reflectivity_calibration_correction() const | ||||||
| { | { | ||||||
|    return p->verticalReflectivityCalibrationCorrection_ * 0.01f; |    constexpr float kScale_ = 0.01f; | ||||||
|  |    return static_cast<float>(p->verticalReflectivityCalibrationCorrection_) * | ||||||
|  |           kScale_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::transition_power_source_status() const | std::uint16_t RdaStatusData::transition_power_source_status() const | ||||||
| { | { | ||||||
|    return p->transitionPowerSourceStatus_; |    return p->transitionPowerSourceStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::rms_control_status() const | std::uint16_t RdaStatusData::rms_control_status() const | ||||||
| { | { | ||||||
|    return p->rmsControlStatus_; |    return p->rmsControlStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::performance_check_status() const | std::uint16_t RdaStatusData::performance_check_status() const | ||||||
| { | { | ||||||
|    return p->performanceCheckStatus_; |    return p->performanceCheckStatus_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::alarm_codes(unsigned i) const | std::uint16_t RdaStatusData::alarm_codes(unsigned i) const | ||||||
| { | { | ||||||
|    return p->alarmCodes_[i]; |    return p->alarmCodes_.at(i); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::signal_processing_options() const | std::uint16_t RdaStatusData::signal_processing_options() const | ||||||
| { | { | ||||||
|    return p->signalProcessingOptions_; |    return p->signalProcessingOptions_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t RdaStatusData::status_version() const | std::uint16_t RdaStatusData::downloaded_pattern_number() const | ||||||
|  | { | ||||||
|  |    return p->downloadedPatternNumber_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint16_t RdaStatusData::status_version() const | ||||||
| { | { | ||||||
|    return p->statusVersion_; |    return p->statusVersion_; | ||||||
| } | } | ||||||
|  | @ -238,6 +220,7 @@ bool RdaStatusData::Parse(std::istream& is) | ||||||
|    bool   messageValid = true; |    bool   messageValid = true; | ||||||
|    size_t bytesRead    = 0; |    size_t bytesRead    = 0; | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers): Readability
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->rdaStatus_), 2);                    // 1
 |    is.read(reinterpret_cast<char*>(&p->rdaStatus_), 2);                    // 1
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->operabilityStatus_), 2);            // 2
 |    is.read(reinterpret_cast<char*>(&p->operabilityStatus_), 2);            // 2
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->controlStatus_), 2);                // 3
 |    is.read(reinterpret_cast<char*>(&p->controlStatus_), 2);                // 3
 | ||||||
|  | @ -253,14 +236,14 @@ bool RdaStatusData::Parse(std::istream& is) | ||||||
|    is.read(reinterpret_cast<char*>(&p->operationalMode_), 2);             // 11
 |    is.read(reinterpret_cast<char*>(&p->operationalMode_), 2);             // 11
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->superResolutionStatus_), 2);       // 12
 |    is.read(reinterpret_cast<char*>(&p->superResolutionStatus_), 2);       // 12
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->clutterMitigationDecisionStatus_), |    is.read(reinterpret_cast<char*>(&p->clutterMitigationDecisionStatus_), | ||||||
|            2);                                                         // 13
 |            2);                                                        // 13
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->avsetEbcRdaLogDataStatus_), 2); // 14
 |    is.read(reinterpret_cast<char*>(&p->rdaScanAndDataFlags_), 2);     // 14
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->rdaAlarmSummary_), 2);          // 15
 |    is.read(reinterpret_cast<char*>(&p->rdaAlarmSummary_), 2);         // 15
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->commandAcknowledgement_), 2);   // 16
 |    is.read(reinterpret_cast<char*>(&p->commandAcknowledgement_), 2);  // 16
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->channelControlStatus_), 2);     // 17
 |    is.read(reinterpret_cast<char*>(&p->channelControlStatus_), 2);    // 17
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->spotBlankingStatus_), 2);       // 18
 |    is.read(reinterpret_cast<char*>(&p->spotBlankingStatus_), 2);      // 18
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->bypassMapGenerationDate_), 2);  // 19
 |    is.read(reinterpret_cast<char*>(&p->bypassMapGenerationDate_), 2); // 19
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->bypassMapGenerationTime_), 2);  // 20
 |    is.read(reinterpret_cast<char*>(&p->bypassMapGenerationTime_), 2); // 20
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->clutterFilterMapGenerationDate_), |    is.read(reinterpret_cast<char*>(&p->clutterFilterMapGenerationDate_), | ||||||
|            2); // 21
 |            2); // 21
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->clutterFilterMapGenerationTime_), |    is.read(reinterpret_cast<char*>(&p->clutterFilterMapGenerationTime_), | ||||||
|  | @ -272,7 +255,7 @@ bool RdaStatusData::Parse(std::istream& is) | ||||||
|    is.read(reinterpret_cast<char*>(&p->rmsControlStatus_), 2);            // 25
 |    is.read(reinterpret_cast<char*>(&p->rmsControlStatus_), 2);            // 25
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->performanceCheckStatus_), 2);      // 26
 |    is.read(reinterpret_cast<char*>(&p->performanceCheckStatus_), 2);      // 26
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->alarmCodes_), |    is.read(reinterpret_cast<char*>(&p->alarmCodes_), | ||||||
|            p->alarmCodes_.size() * 2); // 27-40
 |            static_cast<std::streamsize>(p->alarmCodes_.size() * 2)); // 27-40
 | ||||||
|    bytesRead += 80; |    bytesRead += 80; | ||||||
| 
 | 
 | ||||||
|    p->rdaStatus_                    = ntohs(p->rdaStatus_); |    p->rdaStatus_                    = ntohs(p->rdaStatus_); | ||||||
|  | @ -280,8 +263,8 @@ bool RdaStatusData::Parse(std::istream& is) | ||||||
|    p->controlStatus_                = ntohs(p->controlStatus_); |    p->controlStatus_                = ntohs(p->controlStatus_); | ||||||
|    p->auxiliaryPowerGeneratorState_ = ntohs(p->auxiliaryPowerGeneratorState_); |    p->auxiliaryPowerGeneratorState_ = ntohs(p->auxiliaryPowerGeneratorState_); | ||||||
|    p->averageTransmitterPower_      = ntohs(p->averageTransmitterPower_); |    p->averageTransmitterPower_      = ntohs(p->averageTransmitterPower_); | ||||||
|    p->horizontalReflectivityCalibrationCorrection_ = |    p->horizontalReflectivityCalibrationCorrection_ = static_cast<std::int16_t>( | ||||||
|       ntohs(p->horizontalReflectivityCalibrationCorrection_); |       ntohs(p->horizontalReflectivityCalibrationCorrection_)); | ||||||
|    p->dataTransmissionEnabled_     = ntohs(p->dataTransmissionEnabled_); |    p->dataTransmissionEnabled_     = ntohs(p->dataTransmissionEnabled_); | ||||||
|    p->volumeCoveragePatternNumber_ = ntohs(p->volumeCoveragePatternNumber_); |    p->volumeCoveragePatternNumber_ = ntohs(p->volumeCoveragePatternNumber_); | ||||||
|    p->rdaControlAuthorization_     = ntohs(p->rdaControlAuthorization_); |    p->rdaControlAuthorization_     = ntohs(p->rdaControlAuthorization_); | ||||||
|  | @ -290,36 +273,40 @@ bool RdaStatusData::Parse(std::istream& is) | ||||||
|    p->superResolutionStatus_       = ntohs(p->superResolutionStatus_); |    p->superResolutionStatus_       = ntohs(p->superResolutionStatus_); | ||||||
|    p->clutterMitigationDecisionStatus_ = |    p->clutterMitigationDecisionStatus_ = | ||||||
|       ntohs(p->clutterMitigationDecisionStatus_); |       ntohs(p->clutterMitigationDecisionStatus_); | ||||||
|    p->avsetEbcRdaLogDataStatus_ = ntohs(p->avsetEbcRdaLogDataStatus_); |    p->rdaScanAndDataFlags_     = ntohs(p->rdaScanAndDataFlags_); | ||||||
|    p->rdaAlarmSummary_          = ntohs(p->rdaAlarmSummary_); |    p->rdaAlarmSummary_         = ntohs(p->rdaAlarmSummary_); | ||||||
|    p->commandAcknowledgement_   = ntohs(p->commandAcknowledgement_); |    p->commandAcknowledgement_  = ntohs(p->commandAcknowledgement_); | ||||||
|    p->channelControlStatus_     = ntohs(p->channelControlStatus_); |    p->channelControlStatus_    = ntohs(p->channelControlStatus_); | ||||||
|    p->spotBlankingStatus_       = ntohs(p->spotBlankingStatus_); |    p->spotBlankingStatus_      = ntohs(p->spotBlankingStatus_); | ||||||
|    p->bypassMapGenerationDate_  = ntohs(p->bypassMapGenerationDate_); |    p->bypassMapGenerationDate_ = ntohs(p->bypassMapGenerationDate_); | ||||||
|    p->bypassMapGenerationTime_  = ntohs(p->bypassMapGenerationTime_); |    p->bypassMapGenerationTime_ = ntohs(p->bypassMapGenerationTime_); | ||||||
|    p->clutterFilterMapGenerationDate_ = |    p->clutterFilterMapGenerationDate_ = | ||||||
|       ntohs(p->clutterFilterMapGenerationDate_); |       ntohs(p->clutterFilterMapGenerationDate_); | ||||||
|    p->clutterFilterMapGenerationTime_ = |    p->clutterFilterMapGenerationTime_ = | ||||||
|       ntohs(p->clutterFilterMapGenerationTime_); |       ntohs(p->clutterFilterMapGenerationTime_); | ||||||
|    p->verticalReflectivityCalibrationCorrection_ = |    p->verticalReflectivityCalibrationCorrection_ = static_cast<std::int16_t>( | ||||||
|       ntohs(p->verticalReflectivityCalibrationCorrection_); |       ntohs(p->verticalReflectivityCalibrationCorrection_)); | ||||||
|    p->transitionPowerSourceStatus_ = ntohs(p->transitionPowerSourceStatus_); |    p->transitionPowerSourceStatus_ = ntohs(p->transitionPowerSourceStatus_); | ||||||
|    p->rmsControlStatus_            = ntohs(p->rmsControlStatus_); |    p->rmsControlStatus_            = ntohs(p->rmsControlStatus_); | ||||||
|    p->performanceCheckStatus_      = ntohs(p->performanceCheckStatus_); |    p->performanceCheckStatus_      = ntohs(p->performanceCheckStatus_); | ||||||
|    SwapArray(p->alarmCodes_); |    SwapArray(p->alarmCodes_); | ||||||
| 
 | 
 | ||||||
|    // RDA Build 18.0 increased the size of the message from 80 to 120 bytes
 |    // RDA Build 18.0 increased the size of the message from 80 to 120 bytes
 | ||||||
|    if (header().message_size() * 2 > Level2MessageHeader::SIZE + 80) |    if (static_cast<std::size_t>(header().message_size()) * 2 > | ||||||
|  |        Level2MessageHeader::SIZE + 80) | ||||||
|    { |    { | ||||||
|       is.read(reinterpret_cast<char*>(&p->signalProcessingOptions_), 2); // 41
 |       is.read(reinterpret_cast<char*>(&p->signalProcessingOptions_), 2); // 41
 | ||||||
|       is.seekg(36, std::ios_base::cur);                        // 42-59
 |       is.seekg(34, std::ios_base::cur); // 42-58
 | ||||||
|       is.read(reinterpret_cast<char*>(&p->statusVersion_), 2); // 60
 |       is.read(reinterpret_cast<char*>(&p->downloadedPatternNumber_), 2); // 59
 | ||||||
|  |       is.read(reinterpret_cast<char*>(&p->statusVersion_), 2);           // 60
 | ||||||
|       bytesRead += 40; |       bytesRead += 40; | ||||||
| 
 | 
 | ||||||
|       p->signalProcessingOptions_ = ntohs(p->signalProcessingOptions_); |       p->signalProcessingOptions_ = ntohs(p->signalProcessingOptions_); | ||||||
|       p->statusVersion_           = ntohs(p->statusVersion_); |       p->statusVersion_           = ntohs(p->statusVersion_); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    if (!ValidateMessage(is, bytesRead)) |    if (!ValidateMessage(is, bytesRead)) | ||||||
|    { |    { | ||||||
|       messageValid = false; |       messageValid = false; | ||||||
|  | @ -342,6 +329,4 @@ RdaStatusData::Create(Level2MessageHeader&& header, std::istream& is) | ||||||
|    return message; |    return message; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace rda
 | } // namespace scwx::wsr88d::rda
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -0,0 +1,225 @@ | ||||||
|  | #include <scwx/wsr88d/rpg/digital_raster_data_array_packet.hpp> | ||||||
|  | #include <scwx/util/logger.hpp> | ||||||
|  | 
 | ||||||
|  | #include <istream> | ||||||
|  | #include <string> | ||||||
|  | 
 | ||||||
|  | namespace scwx::wsr88d::rpg | ||||||
|  | { | ||||||
|  | 
 | ||||||
|  | static const std::string logPrefix_ = | ||||||
|  |    "scwx::wsr88d::rpg::digital_raster_data_array_packet"; | ||||||
|  | static const auto logger_ = util::Logger::Create(logPrefix_); | ||||||
|  | 
 | ||||||
|  | class DigitalRasterDataArrayPacket::Impl | ||||||
|  | { | ||||||
|  | public: | ||||||
|  |    struct Row | ||||||
|  |    { | ||||||
|  |       std::uint16_t             numberOfBytes_ {0}; | ||||||
|  |       std::vector<std::uint8_t> level_ {}; | ||||||
|  |    }; | ||||||
|  | 
 | ||||||
|  |    explicit Impl() = default; | ||||||
|  |    ~Impl()         = default; | ||||||
|  | 
 | ||||||
|  |    Impl(const Impl&)             = delete; | ||||||
|  |    Impl& operator=(const Impl&)  = delete; | ||||||
|  |    Impl(const Impl&&)            = delete; | ||||||
|  |    Impl& operator=(const Impl&&) = delete; | ||||||
|  | 
 | ||||||
|  |    std::uint16_t packetCode_ {0}; | ||||||
|  |    std::uint16_t iCoordinateStart_ {0}; | ||||||
|  |    std::uint16_t jCoordinateStart_ {0}; | ||||||
|  |    std::uint16_t iScaleFactor_ {0}; | ||||||
|  |    std::uint16_t jScaleFactor_ {0}; | ||||||
|  |    std::uint16_t numberOfCells_ {0}; | ||||||
|  |    std::uint16_t numberOfRows_ {0}; | ||||||
|  |    std::uint16_t numberOfBytesInRow_ {0}; | ||||||
|  | 
 | ||||||
|  |    // Repeat for each row
 | ||||||
|  |    std::vector<Row> row_ {}; | ||||||
|  | 
 | ||||||
|  |    std::size_t dataSize_ {0}; | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | DigitalRasterDataArrayPacket::DigitalRasterDataArrayPacket() : | ||||||
|  |     p(std::make_unique<Impl>()) | ||||||
|  | { | ||||||
|  | } | ||||||
|  | DigitalRasterDataArrayPacket::~DigitalRasterDataArrayPacket() = default; | ||||||
|  | 
 | ||||||
|  | DigitalRasterDataArrayPacket::DigitalRasterDataArrayPacket( | ||||||
|  |    DigitalRasterDataArrayPacket&&) noexcept = default; | ||||||
|  | DigitalRasterDataArrayPacket& DigitalRasterDataArrayPacket::operator=( | ||||||
|  |    DigitalRasterDataArrayPacket&&) noexcept = default; | ||||||
|  | 
 | ||||||
|  | std::uint16_t DigitalRasterDataArrayPacket::packet_code() const | ||||||
|  | { | ||||||
|  |    return p->packetCode_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint16_t DigitalRasterDataArrayPacket::i_coordinate_start() const | ||||||
|  | { | ||||||
|  |    return p->iCoordinateStart_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint16_t DigitalRasterDataArrayPacket::j_coordinate_start() const | ||||||
|  | { | ||||||
|  |    return p->jCoordinateStart_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint16_t DigitalRasterDataArrayPacket::i_scale_factor() const | ||||||
|  | { | ||||||
|  |    return p->iScaleFactor_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint16_t DigitalRasterDataArrayPacket::j_scale_factor() const | ||||||
|  | { | ||||||
|  |    return p->jScaleFactor_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint16_t DigitalRasterDataArrayPacket::number_of_cells() const | ||||||
|  | { | ||||||
|  |    return p->numberOfCells_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint16_t DigitalRasterDataArrayPacket::number_of_rows() const | ||||||
|  | { | ||||||
|  |    return p->numberOfRows_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::uint16_t | ||||||
|  | DigitalRasterDataArrayPacket::number_of_bytes_in_row(std::uint16_t r) const | ||||||
|  | { | ||||||
|  |    return p->row_[r].numberOfBytes_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | const std::vector<std::uint8_t>& | ||||||
|  | DigitalRasterDataArrayPacket::level(std::uint16_t r) const | ||||||
|  | { | ||||||
|  |    return p->row_[r].level_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | size_t DigitalRasterDataArrayPacket::data_size() const | ||||||
|  | { | ||||||
|  |    return p->dataSize_; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | bool DigitalRasterDataArrayPacket::Parse(std::istream& is) | ||||||
|  | { | ||||||
|  |    bool        blockValid = true; | ||||||
|  |    std::size_t bytesRead  = 0; | ||||||
|  | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->packetCode_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->iCoordinateStart_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->jCoordinateStart_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->iScaleFactor_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->jScaleFactor_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->numberOfCells_), 2); | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->numberOfRows_), 2); | ||||||
|  |    bytesRead += 14; | ||||||
|  | 
 | ||||||
|  |    p->packetCode_       = ntohs(p->packetCode_); | ||||||
|  |    p->iCoordinateStart_ = ntohs(p->iCoordinateStart_); | ||||||
|  |    p->jCoordinateStart_ = ntohs(p->jCoordinateStart_); | ||||||
|  |    p->iScaleFactor_     = ntohs(p->iScaleFactor_); | ||||||
|  |    p->jScaleFactor_     = ntohs(p->jScaleFactor_); | ||||||
|  |    p->numberOfCells_    = ntohs(p->numberOfCells_); | ||||||
|  |    p->numberOfRows_     = ntohs(p->numberOfRows_); | ||||||
|  | 
 | ||||||
|  |    if (is.eof()) | ||||||
|  |    { | ||||||
|  |       logger_->debug("Reached end of file"); | ||||||
|  |       blockValid = false; | ||||||
|  |    } | ||||||
|  |    else | ||||||
|  |    { | ||||||
|  |       if (p->packetCode_ != 33) | ||||||
|  |       { | ||||||
|  |          logger_->warn("Invalid packet code: {}", p->packetCode_); | ||||||
|  |          blockValid = false; | ||||||
|  |       } | ||||||
|  |       if (p->numberOfCells_ < 1 || p->numberOfCells_ > 1840) | ||||||
|  |       { | ||||||
|  |          logger_->warn("Invalid number of cells: {}", p->numberOfCells_); | ||||||
|  |          blockValid = false; | ||||||
|  |       } | ||||||
|  |       if (p->numberOfRows_ < 1 || p->numberOfRows_ > 464) | ||||||
|  |       { | ||||||
|  |          logger_->warn("Invalid number of rows: {}", p->numberOfRows_); | ||||||
|  |          blockValid = false; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    if (blockValid) | ||||||
|  |    { | ||||||
|  |       p->row_.resize(p->numberOfRows_); | ||||||
|  | 
 | ||||||
|  |       for (std::uint16_t r = 0; r < p->numberOfRows_; r++) | ||||||
|  |       { | ||||||
|  |          auto& row = p->row_[r]; | ||||||
|  | 
 | ||||||
|  |          is.read(reinterpret_cast<char*>(&row.numberOfBytes_), 2); | ||||||
|  |          bytesRead += 2; | ||||||
|  | 
 | ||||||
|  |          row.numberOfBytes_ = ntohs(row.numberOfBytes_); | ||||||
|  | 
 | ||||||
|  |          if (row.numberOfBytes_ < 1 || row.numberOfBytes_ > 1840) | ||||||
|  |          { | ||||||
|  |             logger_->warn( | ||||||
|  |                "Invalid number of bytes: {} (Row {})", row.numberOfBytes_, r); | ||||||
|  |             blockValid = false; | ||||||
|  |             break; | ||||||
|  |          } | ||||||
|  |          else if (row.numberOfBytes_ < p->numberOfCells_) | ||||||
|  |          { | ||||||
|  |             logger_->warn("Number of bytes < number of cells: {} < {} (Row {})", | ||||||
|  |                           row.numberOfBytes_, | ||||||
|  |                           p->numberOfCells_, | ||||||
|  |                           r); | ||||||
|  |             blockValid = false; | ||||||
|  |             break; | ||||||
|  |          } | ||||||
|  | 
 | ||||||
|  |          // Read raster bins
 | ||||||
|  |          const std::size_t dataSize = p->numberOfCells_; | ||||||
|  |          row.level_.resize(dataSize); | ||||||
|  |          is.read(reinterpret_cast<char*>(row.level_.data()), | ||||||
|  |                  static_cast<std::streamsize>(dataSize)); | ||||||
|  | 
 | ||||||
|  |          is.seekg(static_cast<std::streamoff>(row.numberOfBytes_ - dataSize), | ||||||
|  |                   std::ios_base::cur); | ||||||
|  |          bytesRead += row.numberOfBytes_; | ||||||
|  |       } | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|  |    p->dataSize_ = bytesRead; | ||||||
|  | 
 | ||||||
|  |    if (!ValidateMessage(is, bytesRead)) | ||||||
|  |    { | ||||||
|  |       blockValid = false; | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return blockValid; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | std::shared_ptr<DigitalRasterDataArrayPacket> | ||||||
|  | DigitalRasterDataArrayPacket::Create(std::istream& is) | ||||||
|  | { | ||||||
|  |    std::shared_ptr<DigitalRasterDataArrayPacket> packet = | ||||||
|  |       std::make_shared<DigitalRasterDataArrayPacket>(); | ||||||
|  | 
 | ||||||
|  |    if (!packet->Parse(is)) | ||||||
|  |    { | ||||||
|  |       packet.reset(); | ||||||
|  |    } | ||||||
|  | 
 | ||||||
|  |    return packet; | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | } // namespace scwx::wsr88d::rpg
 | ||||||
|  | @ -9,22 +9,17 @@ | ||||||
| #include <scwx/wsr88d/rpg/tabular_product_message.hpp> | #include <scwx/wsr88d/rpg/tabular_product_message.hpp> | ||||||
| 
 | 
 | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| #include <vector> |  | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rpg | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rpg |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| static const std::string logPrefix_ = | static const std::string logPrefix_ = | ||||||
|    "scwx::wsr88d::rpg::level3_message_factory"; |    "scwx::wsr88d::rpg::level3_message_factory"; | ||||||
| static const auto logger_ = util::Logger::Create(logPrefix_); | static const auto logger_ = util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| typedef std::function<std::shared_ptr<Level3Message>(Level3MessageHeader&&, | using CreateLevel3MessageFunction = | ||||||
|                                                      std::istream&)> |    std::function<std::shared_ptr<Level3Message>(Level3MessageHeader&&, | ||||||
|    CreateLevel3MessageFunction; |                                                 std::istream&)>; | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<int, CreateLevel3MessageFunction> //
 | static const std::unordered_map<int, CreateLevel3MessageFunction> //
 | ||||||
|    create_ {{2, GeneralStatusMessage::Create}, |    create_ {{2, GeneralStatusMessage::Create}, | ||||||
|  | @ -119,9 +114,14 @@ static const std::unordered_map<int, CreateLevel3MessageFunction> // | ||||||
|             {182, GraphicProductMessage::Create}, |             {182, GraphicProductMessage::Create}, | ||||||
|             {184, GraphicProductMessage::Create}, |             {184, GraphicProductMessage::Create}, | ||||||
|             {186, GraphicProductMessage::Create}, |             {186, GraphicProductMessage::Create}, | ||||||
|  |             {189, GraphicProductMessage::Create}, | ||||||
|  |             {190, GraphicProductMessage::Create}, | ||||||
|  |             {191, GraphicProductMessage::Create}, | ||||||
|  |             {192, GraphicProductMessage::Create}, | ||||||
|             {193, GraphicProductMessage::Create}, |             {193, GraphicProductMessage::Create}, | ||||||
|             {195, GraphicProductMessage::Create}, |             {195, GraphicProductMessage::Create}, | ||||||
|             {196, GraphicProductMessage::Create}, |             {196, GraphicProductMessage::Create}, | ||||||
|  |             {197, GraphicProductMessage::Create}, | ||||||
|             {202, GraphicProductMessage::Create}}; |             {202, GraphicProductMessage::Create}}; | ||||||
| 
 | 
 | ||||||
| std::shared_ptr<Level3Message> Level3MessageFactory::Create(std::istream& is) | std::shared_ptr<Level3Message> Level3MessageFactory::Create(std::istream& is) | ||||||
|  | @ -149,13 +149,12 @@ std::shared_ptr<Level3Message> Level3MessageFactory::Create(std::istream& is) | ||||||
|    else if (headerValid) |    else if (headerValid) | ||||||
|    { |    { | ||||||
|       // Seek to the end of the current message
 |       // Seek to the end of the current message
 | ||||||
|       is.seekg(header.length_of_message() - Level3MessageHeader::SIZE, |       is.seekg(static_cast<std::streamoff>(header.length_of_message()) - | ||||||
|  |                   static_cast<std::streamoff>(Level3MessageHeader::SIZE), | ||||||
|                std::ios_base::cur); |                std::ios_base::cur); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return message; |    return message; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace rpg
 | } // namespace scwx::wsr88d::rpg
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -5,6 +5,7 @@ | ||||||
| #include <scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp> | #include <scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp> | ||||||
| #include <scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp> | #include <scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp> | ||||||
| #include <scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp> | #include <scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp> | ||||||
|  | #include <scwx/wsr88d/rpg/digital_raster_data_array_packet.hpp> | ||||||
| #include <scwx/wsr88d/rpg/generic_data_packet.hpp> | #include <scwx/wsr88d/rpg/generic_data_packet.hpp> | ||||||
| #include <scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp> | #include <scwx/wsr88d/rpg/hda_hail_symbol_packet.hpp> | ||||||
| #include <scwx/wsr88d/rpg/linked_contour_vector_packet.hpp> | #include <scwx/wsr88d/rpg/linked_contour_vector_packet.hpp> | ||||||
|  | @ -27,18 +28,14 @@ | ||||||
| 
 | 
 | ||||||
| #include <unordered_map> | #include <unordered_map> | ||||||
| 
 | 
 | ||||||
| namespace scwx | namespace scwx::wsr88d::rpg | ||||||
| { |  | ||||||
| namespace wsr88d |  | ||||||
| { |  | ||||||
| namespace rpg |  | ||||||
| { | { | ||||||
| 
 | 
 | ||||||
| static const std::string logPrefix_ = "scwx::wsr88d::rpg::packet_factory"; | static const std::string logPrefix_ = "scwx::wsr88d::rpg::packet_factory"; | ||||||
| static const auto        logger_    = util::Logger::Create(logPrefix_); | static const auto        logger_    = util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| typedef std::function<std::shared_ptr<Packet>(std::istream&)> | using CreateMessageFunction = | ||||||
|    CreateMessageFunction; |    std::function<std::shared_ptr<Packet>(std::istream&)>; | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<unsigned int, CreateMessageFunction> create_ { | static const std::unordered_map<unsigned int, CreateMessageFunction> create_ { | ||||||
|    {1, TextAndSpecialSymbolPacket::Create}, |    {1, TextAndSpecialSymbolPacket::Create}, | ||||||
|  | @ -69,6 +66,7 @@ static const std::unordered_map<unsigned int, CreateMessageFunction> create_ { | ||||||
|    {26, PointGraphicSymbolPacket::Create}, |    {26, PointGraphicSymbolPacket::Create}, | ||||||
|    {28, GenericDataPacket::Create}, |    {28, GenericDataPacket::Create}, | ||||||
|    {29, GenericDataPacket::Create}, |    {29, GenericDataPacket::Create}, | ||||||
|  |    {33, DigitalRasterDataArrayPacket::Create}, | ||||||
|    {0x0802, SetColorLevelPacket::Create}, |    {0x0802, SetColorLevelPacket::Create}, | ||||||
|    {0x0E03, LinkedContourVectorPacket::Create}, |    {0x0E03, LinkedContourVectorPacket::Create}, | ||||||
|    {0x3501, UnlinkedContourVectorPacket::Create}, |    {0x3501, UnlinkedContourVectorPacket::Create}, | ||||||
|  | @ -81,7 +79,7 @@ std::shared_ptr<Packet> PacketFactory::Create(std::istream& is) | ||||||
|    std::shared_ptr<Packet> packet      = nullptr; |    std::shared_ptr<Packet> packet      = nullptr; | ||||||
|    bool                    packetValid = true; |    bool                    packetValid = true; | ||||||
| 
 | 
 | ||||||
|    uint16_t packetCode; |    std::uint16_t packetCode {0}; | ||||||
| 
 | 
 | ||||||
|    is.read(reinterpret_cast<char*>(&packetCode), 2); |    is.read(reinterpret_cast<char*>(&packetCode), 2); | ||||||
|    packetCode = ntohs(packetCode); |    packetCode = ntohs(packetCode); | ||||||
|  | @ -108,6 +106,4 @@ std::shared_ptr<Packet> PacketFactory::Create(std::istream& is) | ||||||
|    return packet; |    return packet; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| } // namespace rpg
 | } // namespace scwx::wsr88d::rpg
 | ||||||
| } // namespace wsr88d
 |  | ||||||
| } // namespace scwx
 |  | ||||||
|  |  | ||||||
|  | @ -1,3 +1,4 @@ | ||||||
|  | #include <cstddef> | ||||||
| #include <scwx/wsr88d/rpg/product_description_block.hpp> | #include <scwx/wsr88d/rpg/product_description_block.hpp> | ||||||
| #include <scwx/util/float.hpp> | #include <scwx/util/float.hpp> | ||||||
| #include <scwx/util/logger.hpp> | #include <scwx/util/logger.hpp> | ||||||
|  | @ -21,28 +22,13 @@ static const std::string logPrefix_ = | ||||||
| static const auto logger_ = util::Logger::Create(logPrefix_); | static const auto logger_ = util::Logger::Create(logPrefix_); | ||||||
| 
 | 
 | ||||||
| static const std::set<int> compressedProducts_ = { | static const std::set<int> compressedProducts_ = { | ||||||
|    32,  94,  99,  134, 135, 138, 149, 152, 153, 154, 155, |    32,  94,  99,  113, 134, 135, 138, 149, 152, 153, 154, 155, 159, | ||||||
|    159, 161, 163, 165, 167, 168, 170, 172, 173, 174, 175, |    161, 163, 165, 167, 168, 170, 172, 173, 174, 175, 176, 177, 178, | ||||||
|    176, 177, 178, 179, 180, 182, 186, 193, 195, 202}; |    179, 180, 182, 186, 189, 190, 191, 192, 193, 195, 197, 202}; | ||||||
| 
 | 
 | ||||||
| static const std::set<int> uncodedDataLevelProducts_ = {32, | static const std::set<int> uncodedDataLevelProducts_ = { | ||||||
|                                                         34, |    32,  34,  81,  93,  94,  99,  134, 135, 138, 153, 154, 155, | ||||||
|                                                         81, |    159, 161, 163, 177, 189, 190, 191, 192, 193, 195, 197}; | ||||||
|                                                         93, |  | ||||||
|                                                         94, |  | ||||||
|                                                         99, |  | ||||||
|                                                         134, |  | ||||||
|                                                         135, |  | ||||||
|                                                         138, |  | ||||||
|                                                         153, |  | ||||||
|                                                         154, |  | ||||||
|                                                         155, |  | ||||||
|                                                         159, |  | ||||||
|                                                         161, |  | ||||||
|                                                         163, |  | ||||||
|                                                         177, |  | ||||||
|                                                         193, |  | ||||||
|                                                         195}; |  | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<int, unsigned int> rangeMap_ { | static const std::unordered_map<int, unsigned int> rangeMap_ { | ||||||
|    {19, 230},  {20, 460},  {27, 230},  {30, 230},  {31, 230},  {32, 230}, |    {19, 230},  {20, 460},  {27, 230},  {30, 230},  {31, 230},  {32, 230}, | ||||||
|  | @ -57,7 +43,8 @@ static const std::unordered_map<int, unsigned int> rangeMap_ { | ||||||
|    {163, 300}, {165, 300}, {166, 230}, {167, 300}, {168, 300}, {169, 230}, |    {163, 300}, {165, 300}, {166, 230}, {167, 300}, {168, 300}, {169, 230}, | ||||||
|    {170, 230}, {171, 230}, {172, 230}, {173, 230}, {174, 230}, {175, 230}, |    {170, 230}, {171, 230}, {172, 230}, {173, 230}, {174, 230}, {175, 230}, | ||||||
|    {176, 230}, {177, 230}, {178, 300}, {179, 300}, {180, 89},  {181, 89}, |    {176, 230}, {177, 230}, {178, 300}, {179, 300}, {180, 89},  {181, 89}, | ||||||
|    {182, 89},  {184, 89},  {186, 417}, {193, 460}, {195, 460}, {196, 50}}; |    {182, 89},  {184, 89},  {186, 417}, {193, 460}, {195, 460}, {196, 50}, | ||||||
|  |    {197, 230}}; | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<int, unsigned int> xResolutionMap_ { | static const std::unordered_map<int, unsigned int> xResolutionMap_ { | ||||||
|    {19, 1000},  {20, 2000},  {27, 1000},  {30, 1000},  {31, 2000},  {32, 1000}, |    {19, 1000},  {20, 2000},  {27, 1000},  {30, 1000},  {31, 2000},  {32, 1000}, | ||||||
|  | @ -71,7 +58,7 @@ static const std::unordered_map<int, unsigned int> xResolutionMap_ { | ||||||
|    {166, 250},  {167, 250},  {168, 250},  {169, 2000}, {170, 250},  {171, 2000}, |    {166, 250},  {167, 250},  {168, 250},  {169, 2000}, {170, 250},  {171, 2000}, | ||||||
|    {172, 250},  {173, 250},  {174, 250},  {175, 250},  {176, 250},  {177, 250}, |    {172, 250},  {173, 250},  {174, 250},  {175, 250},  {176, 250},  {177, 250}, | ||||||
|    {178, 1000}, {179, 1000}, {180, 150},  {181, 150},  {182, 150},  {184, 150}, |    {178, 1000}, {179, 1000}, {180, 150},  {181, 150},  {182, 150},  {184, 150}, | ||||||
|    {186, 300},  {193, 250},  {195, 1000}}; |    {186, 300},  {193, 250},  {195, 1000}, {197, 250}}; | ||||||
| 
 | 
 | ||||||
| static const std::unordered_map<int, unsigned int> yResolutionMap_ {{37, 1000}, | static const std::unordered_map<int, unsigned int> yResolutionMap_ {{37, 1000}, | ||||||
|                                                                     {38, 4000}, |                                                                     {38, 4000}, | ||||||
|  | @ -86,7 +73,11 @@ static const std::unordered_map<int, unsigned int> yResolutionMap_ {{37, 1000}, | ||||||
|                                                                     {90, 4000}, |                                                                     {90, 4000}, | ||||||
|                                                                     {97, 1000}, |                                                                     {97, 1000}, | ||||||
|                                                                     {98, 4000}, |                                                                     {98, 4000}, | ||||||
|                                                                     {166, 250}}; |                                                                     {166, 250}, | ||||||
|  |                                                                     {189, 20}, | ||||||
|  |                                                                     {190, 20}, | ||||||
|  |                                                                     {191, 20}, | ||||||
|  |                                                                     {192, 20}}; | ||||||
| 
 | 
 | ||||||
| // GR uses different internal units than defined units in level 3 products
 | // GR uses different internal units than defined units in level 3 products
 | ||||||
| static const std::unordered_map<std::int16_t, float> grScale_ { | static const std::unordered_map<std::int16_t, float> grScale_ { | ||||||
|  | @ -105,73 +96,57 @@ static const std::unordered_map<std::int16_t, float> grScale_ { | ||||||
|    {174, ((units::inches<float> {1} * 0.01f) / units::millimeters<float> {1})}, |    {174, ((units::inches<float> {1} * 0.01f) / units::millimeters<float> {1})}, | ||||||
|    {175, ((units::inches<float> {1} * 0.01f) / units::millimeters<float> {1})}}; |    {175, ((units::inches<float> {1} * 0.01f) / units::millimeters<float> {1})}}; | ||||||
| 
 | 
 | ||||||
| class ProductDescriptionBlockImpl | class ProductDescriptionBlock::Impl | ||||||
| { | { | ||||||
| public: | public: | ||||||
|    explicit ProductDescriptionBlockImpl() : |    explicit Impl() = default; | ||||||
|        blockDivider_ {0}, |    ~Impl()         = default; | ||||||
|        latitudeOfRadar_ {0}, |  | ||||||
|        longitudeOfRadar_ {0}, |  | ||||||
|        heightOfRadar_ {0}, |  | ||||||
|        productCode_ {0}, |  | ||||||
|        operationalMode_ {0}, |  | ||||||
|        volumeCoveragePattern_ {0}, |  | ||||||
|        sequenceNumber_ {0}, |  | ||||||
|        volumeScanNumber_ {0}, |  | ||||||
|        volumeScanDate_ {0}, |  | ||||||
|        volumeScanStartTime_ {0}, |  | ||||||
|        generationDateOfProduct_ {0}, |  | ||||||
|        generationTimeOfProduct_ {0}, |  | ||||||
|        elevationNumber_ {0}, |  | ||||||
|        version_ {0}, |  | ||||||
|        spotBlank_ {0}, |  | ||||||
|        offsetToSymbology_ {0}, |  | ||||||
|        offsetToGraphic_ {0}, |  | ||||||
|        offsetToTabular_ {0}, |  | ||||||
|        parameters_ {0}, |  | ||||||
|        halfwords_ {0} |  | ||||||
|    { |  | ||||||
|    } |  | ||||||
|    ~ProductDescriptionBlockImpl() = default; |  | ||||||
| 
 | 
 | ||||||
|    uint16_t halfword(size_t i); |    Impl(const Impl&)             = delete; | ||||||
|  |    Impl& operator=(const Impl&)  = delete; | ||||||
|  |    Impl(const Impl&&)            = delete; | ||||||
|  |    Impl& operator=(const Impl&&) = delete; | ||||||
| 
 | 
 | ||||||
|    int16_t  blockDivider_; |    std::uint16_t halfword(std::size_t i); | ||||||
|    int32_t  latitudeOfRadar_; | 
 | ||||||
|    int32_t  longitudeOfRadar_; |    std::int16_t  blockDivider_ {0}; | ||||||
|    int16_t  heightOfRadar_; |    std::int32_t  latitudeOfRadar_ {0}; | ||||||
|    int16_t  productCode_; |    std::int32_t  longitudeOfRadar_ {0}; | ||||||
|    uint16_t operationalMode_; |    std::int16_t  heightOfRadar_ {0}; | ||||||
|    uint16_t volumeCoveragePattern_; |    std::int16_t  productCode_ {0}; | ||||||
|    int16_t  sequenceNumber_; |    std::uint16_t operationalMode_ {0}; | ||||||
|    uint16_t volumeScanNumber_; |    std::uint16_t volumeCoveragePattern_ {0}; | ||||||
|    uint16_t volumeScanDate_; |    std::int16_t  sequenceNumber_ {0}; | ||||||
|    uint32_t volumeScanStartTime_; |    std::uint16_t volumeScanNumber_ {0}; | ||||||
|    uint16_t generationDateOfProduct_; |    std::uint16_t volumeScanDate_ {0}; | ||||||
|    uint32_t generationTimeOfProduct_; |    std::uint32_t volumeScanStartTime_ {0}; | ||||||
|  |    std::uint16_t generationDateOfProduct_ {0}; | ||||||
|  |    std::uint32_t generationTimeOfProduct_ {0}; | ||||||
|    // 27-28: Product dependent parameters 1 and 2 (Table V)
 |    // 27-28: Product dependent parameters 1 and 2 (Table V)
 | ||||||
|    uint16_t elevationNumber_; |    std::uint16_t elevationNumber_ {0}; | ||||||
|    // 30:    Product dependent parameter 3 (Table V)
 |    // 30:    Product dependent parameter 3 (Table V)
 | ||||||
|    // 31-46: Product dependent (Note 1)
 |    // 31-46: Product dependent (Note 1)
 | ||||||
|    // 47-53: Product dependent parameters 4-10 (Table V, Note 3)
 |    // 47-53: Product dependent parameters 4-10 (Table V, Note 3)
 | ||||||
|    uint8_t  version_; |    std::uint8_t  version_ {0}; | ||||||
|    uint8_t  spotBlank_; |    std::uint8_t  spotBlank_ {0}; | ||||||
|    uint32_t offsetToSymbology_; |    std::uint32_t offsetToSymbology_ {0}; | ||||||
|    uint32_t offsetToGraphic_; |    std::uint32_t offsetToGraphic_ {0}; | ||||||
|    uint32_t offsetToTabular_; |    std::uint32_t offsetToTabular_ {0}; | ||||||
| 
 | 
 | ||||||
|    std::array<uint16_t, 10> parameters_; |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|    std::array<uint16_t, 16> halfwords_; |    std::array<std::uint16_t, 10> parameters_ {0}; | ||||||
|  |    std::array<std::uint16_t, 16> halfwords_ {0}; | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlockImpl::halfword(size_t i) | std::uint16_t ProductDescriptionBlock::Impl::halfword(std::size_t i) | ||||||
| { | { | ||||||
|    // Halfwords start at halfword 31
 |    // Halfwords start at halfword 31
 | ||||||
|    return halfwords_[i - 31]; |    // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  |    return halfwords_.at(i - 31); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| ProductDescriptionBlock::ProductDescriptionBlock() : | ProductDescriptionBlock::ProductDescriptionBlock() : p(std::make_unique<Impl>()) | ||||||
|     p(std::make_unique<ProductDescriptionBlockImpl>()) |  | ||||||
| { | { | ||||||
| } | } | ||||||
| ProductDescriptionBlock::~ProductDescriptionBlock() = default; | ProductDescriptionBlock::~ProductDescriptionBlock() = default; | ||||||
|  | @ -181,102 +156,104 @@ ProductDescriptionBlock::ProductDescriptionBlock( | ||||||
| ProductDescriptionBlock& ProductDescriptionBlock::operator=( | ProductDescriptionBlock& ProductDescriptionBlock::operator=( | ||||||
|    ProductDescriptionBlock&&) noexcept = default; |    ProductDescriptionBlock&&) noexcept = default; | ||||||
| 
 | 
 | ||||||
| int16_t ProductDescriptionBlock::block_divider() const | std::int16_t ProductDescriptionBlock::block_divider() const | ||||||
| { | { | ||||||
|    return p->blockDivider_; |    return p->blockDivider_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float ProductDescriptionBlock::latitude_of_radar() const | float ProductDescriptionBlock::latitude_of_radar() const | ||||||
| { | { | ||||||
|    return p->latitudeOfRadar_ * 0.001f; |    static constexpr float kScale = 0.001f; | ||||||
|  |    return static_cast<float>(p->latitudeOfRadar_) * kScale; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| float ProductDescriptionBlock::longitude_of_radar() const | float ProductDescriptionBlock::longitude_of_radar() const | ||||||
| { | { | ||||||
|    return p->longitudeOfRadar_ * 0.001f; |    static constexpr float kScale = 0.001f; | ||||||
|  |    return static_cast<float>(p->longitudeOfRadar_) * kScale; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int16_t ProductDescriptionBlock::height_of_radar() const | std::int16_t ProductDescriptionBlock::height_of_radar() const | ||||||
| { | { | ||||||
|    return p->heightOfRadar_; |    return p->heightOfRadar_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int16_t ProductDescriptionBlock::product_code() const | std::int16_t ProductDescriptionBlock::product_code() const | ||||||
| { | { | ||||||
|    return p->productCode_; |    return p->productCode_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::operational_mode() const | std::uint16_t ProductDescriptionBlock::operational_mode() const | ||||||
| { | { | ||||||
|    return p->operationalMode_; |    return p->operationalMode_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::volume_coverage_pattern() const | std::uint16_t ProductDescriptionBlock::volume_coverage_pattern() const | ||||||
| { | { | ||||||
|    return p->volumeCoveragePattern_; |    return p->volumeCoveragePattern_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| int16_t ProductDescriptionBlock::sequence_number() const | std::int16_t ProductDescriptionBlock::sequence_number() const | ||||||
| { | { | ||||||
|    return p->sequenceNumber_; |    return p->sequenceNumber_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::volume_scan_number() const | std::uint16_t ProductDescriptionBlock::volume_scan_number() const | ||||||
| { | { | ||||||
|    return p->volumeScanNumber_; |    return p->volumeScanNumber_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::volume_scan_date() const | std::uint16_t ProductDescriptionBlock::volume_scan_date() const | ||||||
| { | { | ||||||
|    return p->volumeScanDate_; |    return p->volumeScanDate_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t ProductDescriptionBlock::volume_scan_start_time() const | std::uint32_t ProductDescriptionBlock::volume_scan_start_time() const | ||||||
| { | { | ||||||
|    return p->volumeScanStartTime_; |    return p->volumeScanStartTime_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::generation_date_of_product() const | std::uint16_t ProductDescriptionBlock::generation_date_of_product() const | ||||||
| { | { | ||||||
|    return p->generationDateOfProduct_; |    return p->generationDateOfProduct_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t ProductDescriptionBlock::generation_time_of_product() const | std::uint32_t ProductDescriptionBlock::generation_time_of_product() const | ||||||
| { | { | ||||||
|    return p->generationTimeOfProduct_; |    return p->generationTimeOfProduct_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::elevation_number() const | std::uint16_t ProductDescriptionBlock::elevation_number() const | ||||||
| { | { | ||||||
|    return p->elevationNumber_; |    return p->elevationNumber_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::data_level_threshold(size_t i) const | std::uint16_t ProductDescriptionBlock::data_level_threshold(std::size_t i) const | ||||||
| { | { | ||||||
|    return p->halfwords_[i]; |    return p->halfwords_.at(i); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint8_t ProductDescriptionBlock::version() const | std::uint8_t ProductDescriptionBlock::version() const | ||||||
| { | { | ||||||
|    return p->version_; |    return p->version_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint8_t ProductDescriptionBlock::spot_blank() const | std::uint8_t ProductDescriptionBlock::spot_blank() const | ||||||
| { | { | ||||||
|    return p->spotBlank_; |    return p->spotBlank_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t ProductDescriptionBlock::offset_to_symbology() const | std::uint32_t ProductDescriptionBlock::offset_to_symbology() const | ||||||
| { | { | ||||||
|    return p->offsetToSymbology_; |    return p->offsetToSymbology_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t ProductDescriptionBlock::offset_to_graphic() const | std::uint32_t ProductDescriptionBlock::offset_to_graphic() const | ||||||
| { | { | ||||||
|    return p->offsetToGraphic_; |    return p->offsetToGraphic_; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint32_t ProductDescriptionBlock::offset_to_tabular() const | std::uint32_t ProductDescriptionBlock::offset_to_tabular() const | ||||||
| { | { | ||||||
|    return p->offsetToTabular_; |    return p->offsetToTabular_; | ||||||
| } | } | ||||||
|  | @ -286,14 +263,14 @@ float ProductDescriptionBlock::range() const | ||||||
|    return range_raw(); |    return range_raw(); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::range_raw() const | std::uint16_t ProductDescriptionBlock::range_raw() const | ||||||
| { | { | ||||||
|    uint16_t range = 0; |    std::uint16_t range = 0; | ||||||
| 
 | 
 | ||||||
|    auto it = rangeMap_.find(p->productCode_); |    auto it = rangeMap_.find(p->productCode_); | ||||||
|    if (it != rangeMap_.cend()) |    if (it != rangeMap_.cend()) | ||||||
|    { |    { | ||||||
|       range = static_cast<uint16_t>(it->second); |       range = static_cast<std::uint16_t>(it->second); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return range; |    return range; | ||||||
|  | @ -301,17 +278,18 @@ uint16_t ProductDescriptionBlock::range_raw() const | ||||||
| 
 | 
 | ||||||
| float ProductDescriptionBlock::x_resolution() const | float ProductDescriptionBlock::x_resolution() const | ||||||
| { | { | ||||||
|    return x_resolution_raw() * 0.001f; |    static constexpr float kScale = 0.001f; | ||||||
|  |    return static_cast<float>(x_resolution_raw()) * kScale; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::x_resolution_raw() const | std::uint16_t ProductDescriptionBlock::x_resolution_raw() const | ||||||
| { | { | ||||||
|    uint16_t xResolution = 0; |    std::uint16_t xResolution = 0; | ||||||
| 
 | 
 | ||||||
|    auto it = xResolutionMap_.find(p->productCode_); |    auto it = xResolutionMap_.find(p->productCode_); | ||||||
|    if (it != xResolutionMap_.cend()) |    if (it != xResolutionMap_.cend()) | ||||||
|    { |    { | ||||||
|       xResolution = static_cast<uint16_t>(it->second); |       xResolution = static_cast<std::uint16_t>(it->second); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return xResolution; |    return xResolution; | ||||||
|  | @ -319,25 +297,28 @@ uint16_t ProductDescriptionBlock::x_resolution_raw() const | ||||||
| 
 | 
 | ||||||
| float ProductDescriptionBlock::y_resolution() const | float ProductDescriptionBlock::y_resolution() const | ||||||
| { | { | ||||||
|    return y_resolution_raw() * 0.001f; |    static constexpr float kScale = 0.001f; | ||||||
|  |    return static_cast<float>(y_resolution_raw()) * kScale; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::y_resolution_raw() const | std::uint16_t ProductDescriptionBlock::y_resolution_raw() const | ||||||
| { | { | ||||||
|    uint16_t yResolution = 0; |    std::uint16_t yResolution = 0; | ||||||
| 
 | 
 | ||||||
|    auto it = yResolutionMap_.find(p->productCode_); |    auto it = yResolutionMap_.find(p->productCode_); | ||||||
|    if (it != yResolutionMap_.cend()) |    if (it != yResolutionMap_.cend()) | ||||||
|    { |    { | ||||||
|       yResolution = static_cast<uint16_t>(it->second); |       yResolution = static_cast<std::uint16_t>(it->second); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return yResolution; |    return yResolution; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::threshold() const | std::uint16_t ProductDescriptionBlock::threshold() const | ||||||
| { | { | ||||||
|    uint16_t threshold = 1; |    std::uint16_t threshold = 1; | ||||||
|  | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
| 
 | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|  | @ -394,6 +375,8 @@ uint16_t ProductDescriptionBlock::threshold() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return threshold; |    return threshold; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -401,6 +384,8 @@ float ProductDescriptionBlock::offset() const | ||||||
| { | { | ||||||
|    float offset = 0.0f; |    float offset = 0.0f; | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|    case 32: |    case 32: | ||||||
|  | @ -416,7 +401,8 @@ float ProductDescriptionBlock::offset() const | ||||||
|    case 186: |    case 186: | ||||||
|    case 193: |    case 193: | ||||||
|    case 195: |    case 195: | ||||||
|       offset = static_cast<int16_t>(p->halfword(31)) * 0.1f; |       offset = | ||||||
|  |          static_cast<float>(static_cast<std::int16_t>(p->halfword(31))) * 0.1f; | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|    case 134: |    case 134: | ||||||
|  | @ -424,7 +410,7 @@ float ProductDescriptionBlock::offset() const | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|    case 135: |    case 135: | ||||||
|       offset = static_cast<int16_t>(p->halfword(33)); |       offset = static_cast<std::int16_t>(p->halfword(33)); | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|    case 159: |    case 159: | ||||||
|  | @ -445,6 +431,8 @@ float ProductDescriptionBlock::offset() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return offset; |    return offset; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -452,6 +440,8 @@ float ProductDescriptionBlock::scale() const | ||||||
| { | { | ||||||
|    float scale = 1.0f; |    float scale = 1.0f; | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|    case 32: |    case 32: | ||||||
|  | @ -466,11 +456,11 @@ float ProductDescriptionBlock::scale() const | ||||||
|    case 186: |    case 186: | ||||||
|    case 193: |    case 193: | ||||||
|    case 195: |    case 195: | ||||||
|       scale = p->halfword(32) * 0.1f; |       scale = static_cast<float>(p->halfword(32)) * 0.1f; | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|    case 81: |    case 81: | ||||||
|       scale = p->halfword(32) * 0.001f; |       scale = static_cast<float>(p->halfword(32)) * 0.001f; | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|    case 134: |    case 134: | ||||||
|  | @ -482,7 +472,7 @@ float ProductDescriptionBlock::scale() const | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|    case 138: |    case 138: | ||||||
|       scale = p->halfword(32) * 0.01f; |       scale = static_cast<float>(p->halfword(32)) * 0.01f; | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|    case 159: |    case 159: | ||||||
|  | @ -503,12 +493,16 @@ float ProductDescriptionBlock::scale() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return scale; |    return scale; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| uint16_t ProductDescriptionBlock::number_of_levels() const | std::uint16_t ProductDescriptionBlock::number_of_levels() const | ||||||
| { | { | ||||||
|    uint16_t numberOfLevels = 16u; |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|  |    std::uint16_t numberOfLevels = 16u; | ||||||
| 
 | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|  | @ -580,6 +574,10 @@ uint16_t ProductDescriptionBlock::number_of_levels() const | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|    case 134: |    case 134: | ||||||
|  |    case 189: | ||||||
|  |    case 190: | ||||||
|  |    case 191: | ||||||
|  |    case 192: | ||||||
|       numberOfLevels = 256; |       numberOfLevels = 256; | ||||||
|       break; |       break; | ||||||
| 
 | 
 | ||||||
|  | @ -619,6 +617,8 @@ uint16_t ProductDescriptionBlock::number_of_levels() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return numberOfLevels; |    return numberOfLevels; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -626,6 +626,8 @@ std::uint16_t ProductDescriptionBlock::log_start() const | ||||||
| { | { | ||||||
|    std::uint16_t logStart = std::numeric_limits<std::uint16_t>::max(); |    std::uint16_t logStart = std::numeric_limits<std::uint16_t>::max(); | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|    case 134: |    case 134: | ||||||
|  | @ -636,6 +638,8 @@ std::uint16_t ProductDescriptionBlock::log_start() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return logStart; |    return logStart; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -643,6 +647,8 @@ float ProductDescriptionBlock::log_offset() const | ||||||
| { | { | ||||||
|    float logOffset = 0.0f; |    float logOffset = 0.0f; | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|    case 134: |    case 134: | ||||||
|  | @ -653,6 +659,8 @@ float ProductDescriptionBlock::log_offset() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return logOffset; |    return logOffset; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -660,6 +668,8 @@ float ProductDescriptionBlock::log_scale() const | ||||||
| { | { | ||||||
|    float logScale = 1.0f; |    float logScale = 1.0f; | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|    case 134: |    case 134: | ||||||
|  | @ -670,6 +680,8 @@ float ProductDescriptionBlock::log_scale() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return logScale; |    return logScale; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -688,6 +700,8 @@ float ProductDescriptionBlock::gr_scale() const | ||||||
| 
 | 
 | ||||||
| std::uint8_t ProductDescriptionBlock::data_mask() const | std::uint8_t ProductDescriptionBlock::data_mask() const | ||||||
| { | { | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    std::uint8_t dataMask = 0xff; |    std::uint8_t dataMask = 0xff; | ||||||
| 
 | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|  | @ -700,6 +714,8 @@ std::uint8_t ProductDescriptionBlock::data_mask() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return dataMask; |    return dataMask; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -707,6 +723,8 @@ std::uint8_t ProductDescriptionBlock::topped_mask() const | ||||||
| { | { | ||||||
|    std::uint8_t toppedMask = 0x00; |    std::uint8_t toppedMask = 0x00; | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|    case 135: |    case 135: | ||||||
|  | @ -717,6 +735,8 @@ std::uint8_t ProductDescriptionBlock::topped_mask() const | ||||||
|       break; |       break; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return toppedMask; |    return toppedMask; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -728,7 +748,7 @@ units::angle::degrees<double> ProductDescriptionBlock::elevation() const | ||||||
|    { |    { | ||||||
|       // Elevation is given in tenths of a degree
 |       // Elevation is given in tenths of a degree
 | ||||||
|       // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 |       // NOLINTNEXTLINE(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|       elevation = static_cast<int16_t>(p->parameters_[2]) * 0.1; |       elevation = static_cast<std::int16_t>(p->parameters_[2]) * 0.1; | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|    return units::angle::degrees<double> {elevation}; |    return units::angle::degrees<double> {elevation}; | ||||||
|  | @ -743,11 +763,15 @@ bool ProductDescriptionBlock::IsCompressionEnabled() const | ||||||
| { | { | ||||||
|    bool isCompressed = false; |    bool isCompressed = false; | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    if (compressedProducts_.contains(p->productCode_)) |    if (compressedProducts_.contains(p->productCode_)) | ||||||
|    { |    { | ||||||
|       isCompressed = (p->parameters_[7] == 1u); |       isCompressed = (p->parameters_[7] == 1u); | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return isCompressed; |    return isCompressed; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -756,7 +780,7 @@ bool ProductDescriptionBlock::IsDataLevelCoded() const | ||||||
|    return !uncodedDataLevelProducts_.contains(p->productCode_); |    return !uncodedDataLevelProducts_.contains(p->productCode_); | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| size_t ProductDescriptionBlock::data_size() const | std::size_t ProductDescriptionBlock::data_size() const | ||||||
| { | { | ||||||
|    return SIZE; |    return SIZE; | ||||||
| } | } | ||||||
|  | @ -767,6 +791,8 @@ bool ProductDescriptionBlock::Parse(std::istream& is) | ||||||
| 
 | 
 | ||||||
|    const std::streampos blockStart = is.tellg(); |    const std::streampos blockStart = is.tellg(); | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->blockDivider_), 2);            // 10
 |    is.read(reinterpret_cast<char*>(&p->blockDivider_), 2);            // 10
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->latitudeOfRadar_), 4);         // 11-12
 |    is.read(reinterpret_cast<char*>(&p->latitudeOfRadar_), 4);         // 11-12
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->longitudeOfRadar_), 4);        // 13-14
 |    is.read(reinterpret_cast<char*>(&p->longitudeOfRadar_), 4);        // 13-14
 | ||||||
|  | @ -780,27 +806,31 @@ bool ProductDescriptionBlock::Parse(std::istream& is) | ||||||
|    is.read(reinterpret_cast<char*>(&p->volumeScanStartTime_), 4);     // 22-23
 |    is.read(reinterpret_cast<char*>(&p->volumeScanStartTime_), 4);     // 22-23
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->generationDateOfProduct_), 2); // 24
 |    is.read(reinterpret_cast<char*>(&p->generationDateOfProduct_), 2); // 24
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->generationTimeOfProduct_), 4); // 25-26
 |    is.read(reinterpret_cast<char*>(&p->generationTimeOfProduct_), 4); // 25-26
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->parameters_[0]), 2 * 2);       // 27-28
 |    is.read(reinterpret_cast<char*>(&p->parameters_[0]), | ||||||
|    is.read(reinterpret_cast<char*>(&p->elevationNumber_), 2);         // 29
 |            static_cast<std::streamsize>(2 * 2));              // 27-28
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->parameters_[2]), 2);           // 30
 |    is.read(reinterpret_cast<char*>(&p->elevationNumber_), 2); // 29
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->halfwords_[0]), 16 * 2);       // 31-46
 |    is.read(reinterpret_cast<char*>(&p->parameters_[2]), 2);   // 30
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->parameters_[3]), 7 * 2);       // 47-53
 |    is.read(reinterpret_cast<char*>(&p->halfwords_[0]), | ||||||
|    is.read(reinterpret_cast<char*>(&p->version_), 1);                 // 54
 |            static_cast<std::streamsize>(16 * 2)); // 31-46
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->spotBlank_), 1);               // 54
 |    is.read(reinterpret_cast<char*>(&p->parameters_[3]), | ||||||
|    is.read(reinterpret_cast<char*>(&p->offsetToSymbology_), 4);       // 55-56
 |            static_cast<std::streamsize>(7 * 2));                // 47-53
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->offsetToGraphic_), 4);         // 57-58
 |    is.read(reinterpret_cast<char*>(&p->version_), 1);           // 54
 | ||||||
|    is.read(reinterpret_cast<char*>(&p->offsetToTabular_), 4);         // 59-60
 |    is.read(reinterpret_cast<char*>(&p->spotBlank_), 1);         // 54
 | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->offsetToSymbology_), 4); // 55-56
 | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->offsetToGraphic_), 4);   // 57-58
 | ||||||
|  |    is.read(reinterpret_cast<char*>(&p->offsetToTabular_), 4);   // 59-60
 | ||||||
| 
 | 
 | ||||||
|    p->blockDivider_            = ntohs(p->blockDivider_); |    p->blockDivider_    = static_cast<std::int16_t>(ntohs(p->blockDivider_)); | ||||||
|    p->latitudeOfRadar_         = ntohl(p->latitudeOfRadar_); |    p->latitudeOfRadar_ = static_cast<std::int32_t>(ntohl(p->latitudeOfRadar_)); | ||||||
|    p->longitudeOfRadar_        = ntohl(p->longitudeOfRadar_); |    p->longitudeOfRadar_ = | ||||||
|    p->heightOfRadar_           = ntohs(p->heightOfRadar_); |       static_cast<std::int32_t>(ntohl(p->longitudeOfRadar_)); | ||||||
|    p->productCode_             = ntohs(p->productCode_); |    p->heightOfRadar_   = static_cast<std::int16_t>(ntohs(p->heightOfRadar_)); | ||||||
|    p->operationalMode_         = ntohs(p->operationalMode_); |    p->productCode_     = static_cast<std::int16_t>(ntohs(p->productCode_)); | ||||||
|    p->volumeCoveragePattern_   = ntohs(p->volumeCoveragePattern_); |    p->operationalMode_ = ntohs(p->operationalMode_); | ||||||
|    p->sequenceNumber_          = ntohs(p->sequenceNumber_); |    p->volumeCoveragePattern_ = ntohs(p->volumeCoveragePattern_); | ||||||
|    p->volumeScanNumber_        = ntohs(p->volumeScanNumber_); |    p->sequenceNumber_   = static_cast<std::int16_t>(ntohs(p->sequenceNumber_)); | ||||||
|    p->volumeScanDate_          = ntohs(p->volumeScanDate_); |    p->volumeScanNumber_ = ntohs(p->volumeScanNumber_); | ||||||
|  |    p->volumeScanDate_   = ntohs(p->volumeScanDate_); | ||||||
|    p->volumeScanStartTime_     = ntohl(p->volumeScanStartTime_); |    p->volumeScanStartTime_     = ntohl(p->volumeScanStartTime_); | ||||||
|    p->generationDateOfProduct_ = ntohs(p->generationDateOfProduct_); |    p->generationDateOfProduct_ = ntohs(p->generationDateOfProduct_); | ||||||
|    p->generationTimeOfProduct_ = ntohl(p->generationTimeOfProduct_); |    p->generationTimeOfProduct_ = ntohl(p->generationTimeOfProduct_); | ||||||
|  | @ -833,6 +863,8 @@ bool ProductDescriptionBlock::Parse(std::istream& is) | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    if (blockValid) |    if (blockValid) | ||||||
|    { |    { | ||||||
|       logger_->trace("Product code: {}", p->productCode_); |       logger_->trace("Product code: {}", p->productCode_); | ||||||
|  | @ -850,6 +882,8 @@ bool ProductDescriptionBlock::Parse(std::istream& is) | ||||||
| std::optional<DataLevelCode> | std::optional<DataLevelCode> | ||||||
| ProductDescriptionBlock::data_level_code(std::uint8_t level) const | ProductDescriptionBlock::data_level_code(std::uint8_t level) const | ||||||
| { | { | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    switch (p->productCode_) |    switch (p->productCode_) | ||||||
|    { |    { | ||||||
|    case 32: |    case 32: | ||||||
|  | @ -864,6 +898,10 @@ ProductDescriptionBlock::data_level_code(std::uint8_t level) const | ||||||
|    case 163: |    case 163: | ||||||
|    case 167: |    case 167: | ||||||
|    case 168: |    case 168: | ||||||
|  |    case 189: | ||||||
|  |    case 190: | ||||||
|  |    case 191: | ||||||
|  |    case 192: | ||||||
|    case 195: |    case 195: | ||||||
|       switch (level) |       switch (level) | ||||||
|       { |       { | ||||||
|  | @ -1035,11 +1073,11 @@ ProductDescriptionBlock::data_level_code(std::uint8_t level) const | ||||||
|    if (number_of_levels() <= 16 && level < 16 && |    if (number_of_levels() <= 16 && level < 16 && | ||||||
|        !uncodedDataLevelProducts_.contains(p->productCode_)) |        !uncodedDataLevelProducts_.contains(p->productCode_)) | ||||||
|    { |    { | ||||||
|       uint16_t th = data_level_threshold(level); |       const std::uint16_t th = data_level_threshold(level); | ||||||
|       if ((th & 0x8000u)) |       if ((th & 0x8000u)) | ||||||
|       { |       { | ||||||
|          // If bit 0 is one, then the LSB is coded
 |          // If bit 0 is one, then the LSB is coded
 | ||||||
|          uint16_t lsb = th & 0x00ffu; |          const std::uint16_t lsb = th & 0x00ffu; | ||||||
| 
 | 
 | ||||||
|          switch (lsb) |          switch (lsb) | ||||||
|          { |          { | ||||||
|  | @ -1083,6 +1121,8 @@ ProductDescriptionBlock::data_level_code(std::uint8_t level) const | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    return std::nullopt; |    return std::nullopt; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -1101,6 +1141,8 @@ ProductDescriptionBlock::data_value(std::uint8_t level) const | ||||||
| 
 | 
 | ||||||
|    std::optional<float> f = std::nullopt; |    std::optional<float> f = std::nullopt; | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTBEGIN(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    // Different products use different scale/offset formulas
 |    // Different products use different scale/offset formulas
 | ||||||
|    if (numberOfLevels > 16 || |    if (numberOfLevels > 16 || | ||||||
|        uncodedDataLevelProducts_.contains(p->productCode_)) |        uncodedDataLevelProducts_.contains(p->productCode_)) | ||||||
|  | @ -1118,17 +1160,17 @@ ProductDescriptionBlock::data_value(std::uint8_t level) const | ||||||
|       case 174: |       case 174: | ||||||
|       case 175: |       case 175: | ||||||
|       case 176: |       case 176: | ||||||
|          f = (level - dataOffset) / dataScale; |          f = (static_cast<float>(level) - dataOffset) / dataScale; | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|       case 134: |       case 134: | ||||||
|          if (level < log_start()) |          if (level < log_start()) | ||||||
|          { |          { | ||||||
|             f = (level - dataOffset) / dataScale; |             f = (static_cast<float>(level) - dataOffset) / dataScale; | ||||||
|          } |          } | ||||||
|          else |          else | ||||||
|          { |          { | ||||||
|             f = expf((level - log_offset()) / log_scale()); |             f = expf((static_cast<float>(level) - log_offset()) / log_scale()); | ||||||
|          } |          } | ||||||
|          break; |          break; | ||||||
| 
 | 
 | ||||||
|  | @ -1137,7 +1179,7 @@ ProductDescriptionBlock::data_value(std::uint8_t level) const | ||||||
|          [[fallthrough]]; |          [[fallthrough]]; | ||||||
| 
 | 
 | ||||||
|       default: |       default: | ||||||
|          f = level * dataScale + dataOffset; |          f = static_cast<float>(level) * dataScale + dataOffset; | ||||||
|          break; |          break; | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
|  | @ -1177,6 +1219,8 @@ ProductDescriptionBlock::data_value(std::uint8_t level) const | ||||||
|       } |       } | ||||||
|    } |    } | ||||||
| 
 | 
 | ||||||
|  |    // NOLINTEND(cppcoreguidelines-avoid-magic-numbers)
 | ||||||
|  | 
 | ||||||
|    // Scale for GR compatibility
 |    // Scale for GR compatibility
 | ||||||
|    if (f.has_value()) |    if (f.has_value()) | ||||||
|    { |    { | ||||||
|  |  | ||||||
|  | @ -125,6 +125,7 @@ set(HDR_WSR88D_RDA include/scwx/wsr88d/rda/clutter_filter_bypass_map.hpp | ||||||
|                    include/scwx/wsr88d/rda/level2_message_header.hpp |                    include/scwx/wsr88d/rda/level2_message_header.hpp | ||||||
|                    include/scwx/wsr88d/rda/performance_maintenance_data.hpp |                    include/scwx/wsr88d/rda/performance_maintenance_data.hpp | ||||||
|                    include/scwx/wsr88d/rda/rda_adaptation_data.hpp |                    include/scwx/wsr88d/rda/rda_adaptation_data.hpp | ||||||
|  |                    include/scwx/wsr88d/rda/rda_prf_data.hpp | ||||||
|                    include/scwx/wsr88d/rda/rda_status_data.hpp |                    include/scwx/wsr88d/rda/rda_status_data.hpp | ||||||
|                    include/scwx/wsr88d/rda/rda_types.hpp |                    include/scwx/wsr88d/rda/rda_types.hpp | ||||||
|                    include/scwx/wsr88d/rda/volume_coverage_pattern_data.hpp) |                    include/scwx/wsr88d/rda/volume_coverage_pattern_data.hpp) | ||||||
|  | @ -138,6 +139,7 @@ set(SRC_WSR88D_RDA source/scwx/wsr88d/rda/clutter_filter_bypass_map.cpp | ||||||
|                    source/scwx/wsr88d/rda/level2_message_header.cpp |                    source/scwx/wsr88d/rda/level2_message_header.cpp | ||||||
|                    source/scwx/wsr88d/rda/performance_maintenance_data.cpp |                    source/scwx/wsr88d/rda/performance_maintenance_data.cpp | ||||||
|                    source/scwx/wsr88d/rda/rda_adaptation_data.cpp |                    source/scwx/wsr88d/rda/rda_adaptation_data.cpp | ||||||
|  |                    source/scwx/wsr88d/rda/rda_prf_data.cpp | ||||||
|                    source/scwx/wsr88d/rda/rda_status_data.cpp |                    source/scwx/wsr88d/rda/rda_status_data.cpp | ||||||
|                    source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp) |                    source/scwx/wsr88d/rda/volume_coverage_pattern_data.cpp) | ||||||
| set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/ccb_header.hpp | set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/ccb_header.hpp | ||||||
|  | @ -145,6 +147,7 @@ set(HDR_WSR88D_RPG include/scwx/wsr88d/rpg/ccb_header.hpp | ||||||
|                    include/scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp |                    include/scwx/wsr88d/rpg/cell_trend_volume_scan_times.hpp | ||||||
|                    include/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp |                    include/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp |                    include/scwx/wsr88d/rpg/digital_radial_data_array_packet.hpp | ||||||
|  |                    include/scwx/wsr88d/rpg/digital_raster_data_array_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/general_status_message.hpp |                    include/scwx/wsr88d/rpg/general_status_message.hpp | ||||||
|                    include/scwx/wsr88d/rpg/generic_data_packet.hpp |                    include/scwx/wsr88d/rpg/generic_data_packet.hpp | ||||||
|                    include/scwx/wsr88d/rpg/generic_radial_data_packet.hpp |                    include/scwx/wsr88d/rpg/generic_radial_data_packet.hpp | ||||||
|  | @ -186,6 +189,7 @@ set(SRC_WSR88D_RPG source/scwx/wsr88d/rpg/ccb_header.cpp | ||||||
|                    source/scwx/wsr88d/rpg/cell_trend_volume_scan_times.cpp |                    source/scwx/wsr88d/rpg/cell_trend_volume_scan_times.cpp | ||||||
|                    source/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.cpp |                    source/scwx/wsr88d/rpg/digital_precipitation_data_array_packet.cpp | ||||||
|                    source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp |                    source/scwx/wsr88d/rpg/digital_radial_data_array_packet.cpp | ||||||
|  |                    source/scwx/wsr88d/rpg/digital_raster_data_array_packet.cpp | ||||||
|                    source/scwx/wsr88d/rpg/general_status_message.cpp |                    source/scwx/wsr88d/rpg/general_status_message.cpp | ||||||
|                    source/scwx/wsr88d/rpg/generic_data_packet.cpp |                    source/scwx/wsr88d/rpg/generic_data_packet.cpp | ||||||
|                    source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp |                    source/scwx/wsr88d/rpg/generic_radial_data_packet.cpp | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Dan Paulat
						Dan Paulat