mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 21:10:04 +00:00
commit
f3b7dcddbd
7 changed files with 82 additions and 13 deletions
|
|
@ -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(
|
||||||
|
|
@ -247,9 +250,12 @@ void Level3ProductView::UpdateColorTableLut()
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
float offset = descriptionBlock->offset();
|
float offset = descriptionBlock->offset();
|
||||||
float scale = descriptionBlock->scale();
|
float scale = descriptionBlock->scale();
|
||||||
std::uint8_t threshold = static_cast<std::uint8_t>(
|
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::clamp<std::uint16_t>(descriptionBlock->threshold(),
|
||||||
std::numeric_limits<std::uint8_t>::min(),
|
std::numeric_limits<std::uint8_t>::min(),
|
||||||
std::numeric_limits<std::uint8_t>::max()));
|
std::numeric_limits<std::uint8_t>::max()));
|
||||||
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -47,6 +47,7 @@ enum class Level3ProductCategory
|
||||||
DifferentialReflectivity,
|
DifferentialReflectivity,
|
||||||
SpecificDifferentialPhase,
|
SpecificDifferentialPhase,
|
||||||
CorrelationCoefficient,
|
CorrelationCoefficient,
|
||||||
|
VerticallyIntegratedLiquid,
|
||||||
HydrometeorClassification,
|
HydrometeorClassification,
|
||||||
Unknown
|
Unknown
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -66,8 +66,9 @@ 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;
|
||||||
|
|
||||||
float log_offset() const;
|
std::uint16_t log_start() const;
|
||||||
float log_scale() const;
|
float log_offset() const;
|
||||||
|
float log_scale() const;
|
||||||
|
|
||||||
units::angle::degrees<double> elevation() const;
|
units::angle::degrees<double> elevation() const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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_ {
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
@ -598,7 +612,7 @@ float ProductDescriptionBlock::log_offset() const
|
||||||
switch (p->productCode_)
|
switch (p->productCode_)
|
||||||
{
|
{
|
||||||
case 134:
|
case 134:
|
||||||
logOffset = util ::DecodeFloat16(p->halfword(35));
|
logOffset = util::DecodeFloat16(p->halfword(35));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -612,7 +626,7 @@ float ProductDescriptionBlock::log_scale() const
|
||||||
switch (p->productCode_)
|
switch (p->productCode_)
|
||||||
{
|
{
|
||||||
case 134:
|
case 134:
|
||||||
logScale = util ::DecodeFloat16(p->halfword(34));
|
logScale = util::DecodeFloat16(p->halfword(34));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue