Merge pull request #147 from dpaulat/feature/vil

VIL Support
This commit is contained in:
Dan Paulat 2024-02-25 20:21:35 -06:00 committed by GitHub
commit f3b7dcddbd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 82 additions and 13 deletions

View file

@ -56,8 +56,11 @@ public:
uint16_t colorTableMax_; uint16_t colorTableMax_;
std::shared_ptr<common::ColorTable> savedColorTable_; std::shared_ptr<common::ColorTable> savedColorTable_;
float savedScale_; float savedScale_ {1.0f};
float savedOffset_; float savedOffset_ {0.0f};
std::uint16_t savedLogStart_ {20u};
float savedLogScale_ {1.0f};
float savedLogOffset_ {0.0f};
}; };
Level3ProductView::Level3ProductView( Level3ProductView::Level3ProductView(
@ -249,6 +252,9 @@ void Level3ProductView::UpdateColorTableLut()
float offset = descriptionBlock->offset(); float offset = descriptionBlock->offset();
float scale = descriptionBlock->scale(); float scale = descriptionBlock->scale();
float logOffset = descriptionBlock->log_offset();
float logScale = descriptionBlock->log_scale();
std::uint16_t logStart = descriptionBlock->log_start();
std::uint8_t threshold = static_cast<std::uint8_t>( std::uint8_t threshold = static_cast<std::uint8_t>(
std::clamp<std::uint16_t>(descriptionBlock->threshold(), std::clamp<std::uint16_t>(descriptionBlock->threshold(),
std::numeric_limits<std::uint8_t>::min(), std::numeric_limits<std::uint8_t>::min(),
@ -266,6 +272,9 @@ void Level3ProductView::UpdateColorTableLut()
if (p->savedColorTable_ == p->colorTable_ && // if (p->savedColorTable_ == p->colorTable_ && //
p->savedOffset_ == offset && // p->savedOffset_ == offset && //
p->savedScale_ == scale && // p->savedScale_ == scale && //
p->savedLogOffset_ == logOffset && //
p->savedLogScale_ == logScale && //
p->savedLogStart_ == logStart && //
numberOfLevels > 16) numberOfLevels > 16)
{ {
// The color table LUT does not need updated // The color table LUT does not need updated
@ -335,6 +344,9 @@ void Level3ProductView::UpdateColorTableLut()
p->savedColorTable_ = p->colorTable_; p->savedColorTable_ = p->colorTable_;
p->savedOffset_ = offset; p->savedOffset_ = offset;
p->savedScale_ = scale; p->savedScale_ = scale;
p->savedLogOffset_ = logOffset;
p->savedLogScale_ = logScale;
p->savedLogStart_ = logStart;
Q_EMIT ColorTableLutUpdated(); Q_EMIT ColorTableLutUpdated();
} }

View file

@ -7,6 +7,11 @@ namespace scwx
namespace util namespace util
{ {
class Float16Test :
public testing ::TestWithParam<std ::pair<std::uint16_t, float>>
{
};
TEST(FloatTest, Decode32Positive1) TEST(FloatTest, Decode32Positive1)
{ {
uint16_t msw = 0x3f80; uint16_t msw = 0x3f80;
@ -37,14 +42,26 @@ TEST(FloatTest, Decode32Positive12345678)
EXPECT_FLOAT_EQ(x, 12345678.0f); EXPECT_FLOAT_EQ(x, 12345678.0f);
} }
TEST(FloatTest, Decode16h0x5bb4) TEST_P(Float16Test, DecodeFloat16)
{ {
uint16_t hex = 0x5bb4; auto param = GetParam();
std::uint16_t hex = param.first;
float x = DecodeFloat16(hex); float x = DecodeFloat16(hex);
EXPECT_FLOAT_EQ(x, 123.25f); EXPECT_FLOAT_EQ(x, param.second);
} }
INSTANTIATE_TEST_SUITE_P(
FloatTest,
Float16Test,
testing::Values(std::pair<std::uint16_t, float> {0x4400, 2.0f},
std::pair<std::uint16_t, float> {0x59ab, 90.6875f},
std::pair<std::uint16_t, float> {0x593e, 83.875f},
std::pair<std::uint16_t, float> {0x54dc, 38.875f},
std::pair<std::uint16_t, float> {0xc82a, -4.1640625f},
std::pair<std::uint16_t, float> {0x5bb4, 123.25f}));
} // namespace util } // namespace util
} // namespace scwx } // namespace scwx

View file

@ -47,6 +47,7 @@ enum class Level3ProductCategory
DifferentialReflectivity, DifferentialReflectivity,
SpecificDifferentialPhase, SpecificDifferentialPhase,
CorrelationCoefficient, CorrelationCoefficient,
VerticallyIntegratedLiquid,
HydrometeorClassification, HydrometeorClassification,
Unknown Unknown
}; };

View file

@ -66,6 +66,7 @@ public:
std::optional<DataLevelCode> data_level_code(std::uint8_t level) const; std::optional<DataLevelCode> data_level_code(std::uint8_t level) const;
std::optional<float> data_value(std::uint8_t level) const; std::optional<float> data_value(std::uint8_t level) const;
std::uint16_t log_start() const;
float log_offset() const; float log_offset() const;
float log_scale() const; float log_scale() const;

View file

@ -45,8 +45,10 @@ static const std::unordered_map<Level2Product, std::string> level2Palette_ {
static const std::unordered_map<int, std::string> level3ProductCodeMap_ { static const std::unordered_map<int, std::string> level3ProductCodeMap_ {
{37, "NCR"}, {37, "NCR"},
{56, "SRM"}, {56, "SRM"},
{57, "NVL"},
{94, "DR"}, {94, "DR"},
{99, "DV"}, {99, "DV"},
{134, "DVL"},
{153, "SDR"}, {153, "SDR"},
{154, "SDV"}, {154, "SDV"},
{159, "DZD"}, {159, "DZD"},
@ -68,12 +70,14 @@ static const std::unordered_map<std::string, std::string>
{"DZD", "Digital Differential Reflectivity"}, {"DZD", "Digital Differential Reflectivity"},
{"DCC", "Digital Correlation Coefficient"}, {"DCC", "Digital Correlation Coefficient"},
{"DKD", "Digital Specific Differential Phase"}, {"DKD", "Digital Specific Differential Phase"},
{"DVL", "Digital Vertically Integrated Liquid"},
{"DHC", "Digital Hydrometeor Classification"}, {"DHC", "Digital Hydrometeor Classification"},
{"HHC", "Hybrid Hydrometeor Classification"}, {"HHC", "Hybrid Hydrometeor Classification"},
{"ML", "Melting Layer"}, {"ML", "Melting Layer"},
{"SW", "Spectrum Width"}, {"SW", "Spectrum Width"},
{"TDR", "Digital Reflectivity"}, {"TDR", "Digital Reflectivity"},
{"TDV", "Digital Velocity"}, {"TDV", "Digital Velocity"},
{"VIL", "Vertically Integrated Liquid"},
{"?", "Unknown"}}; {"?", "Unknown"}};
static const std::unordered_map<std::string, std::vector<std::string>> static const std::unordered_map<std::string, std::vector<std::string>>
@ -104,6 +108,10 @@ static const std::unordered_map<std::string, std::vector<std::string>>
// Specific Differential Phase // Specific Differential Phase
{"DKD", {"NXK", "NYK", "NZK", "N0K", "NAK", "N1K", "NBK", "N2K", "N3K"}}, {"DKD", {"NXK", "NYK", "NZK", "N0K", "NAK", "N1K", "NBK", "N2K", "N3K"}},
// Vertically Integrated Liquid
{"DVL", {"DVL"}},
{"VIL", {"NVL"}},
// Hydrometeor Classification // Hydrometeor Classification
{"DHC", {"NXH", "NYH", "NZH", "N0H", "NAH", "N1H", "NBH", "N2H", "N3H"}}, {"DHC", {"NXH", "NYH", "NZH", "N0H", "NAH", "N1H", "NBH", "N2H", "N3H"}},
{"HHC", {"HHC"}}, {"HHC", {"HHC"}},
@ -123,6 +131,7 @@ static const std::unordered_map<Level3ProductCategory, std::string>
{Level3ProductCategory::DifferentialReflectivity, "ZDR"}, {Level3ProductCategory::DifferentialReflectivity, "ZDR"},
{Level3ProductCategory::SpecificDifferentialPhase, "KDP"}, {Level3ProductCategory::SpecificDifferentialPhase, "KDP"},
{Level3ProductCategory::CorrelationCoefficient, "CC"}, {Level3ProductCategory::CorrelationCoefficient, "CC"},
{Level3ProductCategory::VerticallyIntegratedLiquid, "VIL"},
{Level3ProductCategory::HydrometeorClassification, "HC"}, {Level3ProductCategory::HydrometeorClassification, "HC"},
{Level3ProductCategory::Unknown, "?"}}; {Level3ProductCategory::Unknown, "?"}};
@ -138,6 +147,8 @@ static const std::unordered_map<Level3ProductCategory, std::string>
"Specific Differential Phase"}, "Specific Differential Phase"},
{Level3ProductCategory::CorrelationCoefficient, {Level3ProductCategory::CorrelationCoefficient,
"Correlation Coefficient"}, "Correlation Coefficient"},
{Level3ProductCategory::VerticallyIntegratedLiquid,
"Vertically Integrated Liquid"},
{Level3ProductCategory::HydrometeorClassification, {Level3ProductCategory::HydrometeorClassification,
"Hydrometeor Classification"}, "Hydrometeor Classification"},
{Level3ProductCategory::Unknown, "?"}}; {Level3ProductCategory::Unknown, "?"}};
@ -151,6 +162,7 @@ static const std::unordered_map<Level3ProductCategory, std::vector<std::string>>
{Level3ProductCategory::DifferentialReflectivity, {"DZD"}}, {Level3ProductCategory::DifferentialReflectivity, {"DZD"}},
{Level3ProductCategory::SpecificDifferentialPhase, {"DKD"}}, {Level3ProductCategory::SpecificDifferentialPhase, {"DKD"}},
{Level3ProductCategory::CorrelationCoefficient, {"DCC"}}, {Level3ProductCategory::CorrelationCoefficient, {"DCC"}},
{Level3ProductCategory::VerticallyIntegratedLiquid, {"DVL", "VIL"}},
{Level3ProductCategory::HydrometeorClassification, {"DHC", "HHC"}}, {Level3ProductCategory::HydrometeorClassification, {"DHC", "HHC"}},
{Level3ProductCategory::Unknown, {}}}; {Level3ProductCategory::Unknown, {}}};
@ -163,6 +175,7 @@ static const std::unordered_map<Level3ProductCategory, std::string>
{Level3ProductCategory::DifferentialReflectivity, "N0X"}, {Level3ProductCategory::DifferentialReflectivity, "N0X"},
{Level3ProductCategory::SpecificDifferentialPhase, "N0K"}, {Level3ProductCategory::SpecificDifferentialPhase, "N0K"},
{Level3ProductCategory::CorrelationCoefficient, "N0C"}, {Level3ProductCategory::CorrelationCoefficient, "N0C"},
{Level3ProductCategory::VerticallyIntegratedLiquid, "DVL"},
{Level3ProductCategory::HydrometeorClassification, "N0H"}}; {Level3ProductCategory::HydrometeorClassification, "N0H"}};
static const std::unordered_map<int, std::string> level3Palette_ { static const std::unordered_map<int, std::string> level3Palette_ {

View file

@ -19,7 +19,7 @@ float DecodeFloat16(std::uint16_t hex)
static constexpr std::uint16_t S_MASK = 0x8000; static constexpr std::uint16_t S_MASK = 0x8000;
static constexpr std::uint16_t S_LSB = 0; static constexpr std::uint16_t S_LSB = 0;
static constexpr std::uint16_t S_SHIFT = 15 - S_LSB; static constexpr std::uint16_t S_SHIFT = 15 - S_LSB;
static constexpr std::uint16_t E_MASK = 0x7a00; static constexpr std::uint16_t E_MASK = 0x7c00;
static constexpr std::uint16_t E_LSB = 5; static constexpr std::uint16_t E_LSB = 5;
static constexpr std::uint16_t E_SHIFT = 15 - E_LSB; static constexpr std::uint16_t E_SHIFT = 15 - E_LSB;
static constexpr std::uint16_t F_MASK = 0x03ff; static constexpr std::uint16_t F_MASK = 0x03ff;

View file

@ -591,6 +591,20 @@ uint16_t ProductDescriptionBlock::number_of_levels() const
return numberOfLevels; return numberOfLevels;
} }
std::uint16_t ProductDescriptionBlock::log_start() const
{
std::uint16_t logStart = std::numeric_limits<std::uint16_t>::max();
switch (p->productCode_)
{
case 134:
logStart = p->halfword(33);
break;
}
return logStart;
}
float ProductDescriptionBlock::log_offset() const float ProductDescriptionBlock::log_offset() const
{ {
float logOffset = 0.0f; float logOffset = 0.0f;
@ -1007,6 +1021,17 @@ ProductDescriptionBlock::data_value(std::uint8_t level) const
f = (level - dataOffset) / dataScale; f = (level - dataOffset) / dataScale;
break; break;
case 134:
if (level < log_start())
{
f = (level - dataOffset) / dataScale;
}
else
{
f = expf((level - log_offset()) / log_scale());
}
break;
default: default:
f = level * dataScale + dataOffset; f = level * dataScale + dataOffset;
break; break;