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

View file

@ -7,6 +7,11 @@ namespace scwx
namespace util
{
class Float16Test :
public testing ::TestWithParam<std ::pair<std::uint16_t, float>>
{
};
TEST(FloatTest, Decode32Positive1)
{
uint16_t msw = 0x3f80;
@ -37,14 +42,26 @@ TEST(FloatTest, Decode32Positive12345678)
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);
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 scwx

View file

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

View file

@ -66,6 +66,7 @@ public:
std::optional<DataLevelCode> data_level_code(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_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_ {
{37, "NCR"},
{56, "SRM"},
{57, "NVL"},
{94, "DR"},
{99, "DV"},
{134, "DVL"},
{153, "SDR"},
{154, "SDV"},
{159, "DZD"},
@ -68,12 +70,14 @@ static const std::unordered_map<std::string, std::string>
{"DZD", "Digital Differential Reflectivity"},
{"DCC", "Digital Correlation Coefficient"},
{"DKD", "Digital Specific Differential Phase"},
{"DVL", "Digital Vertically Integrated Liquid"},
{"DHC", "Digital Hydrometeor Classification"},
{"HHC", "Hybrid Hydrometeor Classification"},
{"ML", "Melting Layer"},
{"SW", "Spectrum Width"},
{"TDR", "Digital Reflectivity"},
{"TDV", "Digital Velocity"},
{"VIL", "Vertically Integrated Liquid"},
{"?", "Unknown"}};
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
{"DKD", {"NXK", "NYK", "NZK", "N0K", "NAK", "N1K", "NBK", "N2K", "N3K"}},
// Vertically Integrated Liquid
{"DVL", {"DVL"}},
{"VIL", {"NVL"}},
// Hydrometeor Classification
{"DHC", {"NXH", "NYH", "NZH", "N0H", "NAH", "N1H", "NBH", "N2H", "N3H"}},
{"HHC", {"HHC"}},
@ -123,6 +131,7 @@ static const std::unordered_map<Level3ProductCategory, std::string>
{Level3ProductCategory::DifferentialReflectivity, "ZDR"},
{Level3ProductCategory::SpecificDifferentialPhase, "KDP"},
{Level3ProductCategory::CorrelationCoefficient, "CC"},
{Level3ProductCategory::VerticallyIntegratedLiquid, "VIL"},
{Level3ProductCategory::HydrometeorClassification, "HC"},
{Level3ProductCategory::Unknown, "?"}};
@ -138,6 +147,8 @@ static const std::unordered_map<Level3ProductCategory, std::string>
"Specific Differential Phase"},
{Level3ProductCategory::CorrelationCoefficient,
"Correlation Coefficient"},
{Level3ProductCategory::VerticallyIntegratedLiquid,
"Vertically Integrated Liquid"},
{Level3ProductCategory::HydrometeorClassification,
"Hydrometeor Classification"},
{Level3ProductCategory::Unknown, "?"}};
@ -151,6 +162,7 @@ static const std::unordered_map<Level3ProductCategory, std::vector<std::string>>
{Level3ProductCategory::DifferentialReflectivity, {"DZD"}},
{Level3ProductCategory::SpecificDifferentialPhase, {"DKD"}},
{Level3ProductCategory::CorrelationCoefficient, {"DCC"}},
{Level3ProductCategory::VerticallyIntegratedLiquid, {"DVL", "VIL"}},
{Level3ProductCategory::HydrometeorClassification, {"DHC", "HHC"}},
{Level3ProductCategory::Unknown, {}}};
@ -163,6 +175,7 @@ static const std::unordered_map<Level3ProductCategory, std::string>
{Level3ProductCategory::DifferentialReflectivity, "N0X"},
{Level3ProductCategory::SpecificDifferentialPhase, "N0K"},
{Level3ProductCategory::CorrelationCoefficient, "N0C"},
{Level3ProductCategory::VerticallyIntegratedLiquid, "DVL"},
{Level3ProductCategory::HydrometeorClassification, "N0H"}};
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_LSB = 0;
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_SHIFT = 15 - E_LSB;
static constexpr std::uint16_t F_MASK = 0x03ff;

View file

@ -591,6 +591,20 @@ uint16_t ProductDescriptionBlock::number_of_levels() const
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 logOffset = 0.0f;
@ -1007,6 +1021,17 @@ ProductDescriptionBlock::data_value(std::uint8_t level) const
f = (level - dataOffset) / dataScale;
break;
case 134:
if (level < log_start())
{
f = (level - dataOffset) / dataScale;
}
else
{
f = expf((level - log_offset()) / log_scale());
}
break;
default:
f = level * dataScale + dataOffset;
break;