mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-30 13:30:06 +00:00
Handle negative data moment ranges for level 2 data
This commit is contained in:
parent
fb7f25e0bd
commit
a0f43b5f3f
6 changed files with 81 additions and 75 deletions
|
|
@ -522,17 +522,17 @@ void Level2ProductView::ComputeSweep()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute threshold at which to display an individual bin (minimum of 2)
|
// Compute threshold at which to display an individual bin (minimum of 2)
|
||||||
const uint16_t snrThreshold =
|
const std::uint16_t snrThreshold =
|
||||||
std::max<int16_t>(2, momentData0->snr_threshold_raw());
|
std::max<std::int16_t>(2, momentData0->snr_threshold_raw());
|
||||||
|
|
||||||
// Start radial is always 0, as coordinates are calculated for each sweep
|
// Start radial is always 0, as coordinates are calculated for each sweep
|
||||||
constexpr std::uint16_t startRadial = 0u;
|
constexpr std::uint16_t startRadial = 0u;
|
||||||
|
|
||||||
for (auto& radialPair : *radarData)
|
for (auto& radialPair : *radarData)
|
||||||
{
|
{
|
||||||
uint16_t radial = radialPair.first;
|
std::uint16_t radial = radialPair.first;
|
||||||
auto& radialData = radialPair.second;
|
auto& radialData = radialPair.second;
|
||||||
auto momentData = radialData->moment_data_block(p->dataBlockType_);
|
auto momentData = radialData->moment_data_block(p->dataBlockType_);
|
||||||
|
|
||||||
if (momentData0->data_word_size() != momentData->data_word_size())
|
if (momentData0->data_word_size() != momentData->data_word_size())
|
||||||
{
|
{
|
||||||
|
|
@ -541,65 +541,70 @@ void Level2ProductView::ComputeSweep()
|
||||||
}
|
}
|
||||||
|
|
||||||
// Compute gate interval
|
// Compute gate interval
|
||||||
const std::uint16_t dataMomentInterval =
|
const std::int32_t dataMomentInterval =
|
||||||
momentData->data_moment_range_sample_interval_raw();
|
momentData->data_moment_range_sample_interval_raw();
|
||||||
const std::uint16_t dataMomentIntervalH = dataMomentInterval / 2;
|
const std::int32_t dataMomentIntervalH = dataMomentInterval / 2;
|
||||||
const std::uint16_t dataMomentRange =
|
const std::int32_t dataMomentRange = std::max<std::int32_t>(
|
||||||
std::max(momentData->data_moment_range_raw(), dataMomentIntervalH);
|
momentData->data_moment_range_raw(), dataMomentIntervalH);
|
||||||
|
|
||||||
// Compute gate size (number of base 250m gates per bin)
|
// Compute gate size (number of base 250m gates per bin)
|
||||||
const uint16_t gateSizeMeters =
|
const std::int32_t gateSizeMeters =
|
||||||
static_cast<uint16_t>(radarProductManager->gate_size());
|
static_cast<std::int32_t>(radarProductManager->gate_size());
|
||||||
const uint16_t gateSize =
|
const std::int32_t gateSize =
|
||||||
std::max<uint16_t>(1, dataMomentInterval / gateSizeMeters);
|
std::max<std::int32_t>(1, dataMomentInterval / gateSizeMeters);
|
||||||
|
|
||||||
// Compute gate range [startGate, endGate)
|
// Compute gate range [startGate, endGate)
|
||||||
const uint16_t startGate =
|
const std::int32_t startGate =
|
||||||
(dataMomentRange - dataMomentIntervalH) / gateSizeMeters;
|
(dataMomentRange - dataMomentIntervalH) / gateSizeMeters;
|
||||||
const uint16_t numberOfDataMomentGates =
|
const std::int32_t numberOfDataMomentGates =
|
||||||
std::min<uint16_t>(momentData->number_of_data_moment_gates(),
|
std::min<std::int32_t>(momentData->number_of_data_moment_gates(),
|
||||||
static_cast<uint16_t>(gates));
|
static_cast<std::int32_t>(gates));
|
||||||
const uint16_t endGate =
|
const std::int32_t endGate = std::min<std::int32_t>(
|
||||||
std::min<uint16_t>(startGate + numberOfDataMomentGates * gateSize,
|
startGate + numberOfDataMomentGates * gateSize,
|
||||||
common::MAX_DATA_MOMENT_GATES);
|
static_cast<std::int32_t>(common::MAX_DATA_MOMENT_GATES));
|
||||||
|
|
||||||
const uint8_t* dataMomentsArray8 = nullptr;
|
const std::uint8_t* dataMomentsArray8 = nullptr;
|
||||||
const uint16_t* dataMomentsArray16 = nullptr;
|
const std::uint16_t* dataMomentsArray16 = nullptr;
|
||||||
const uint8_t* cfpMomentsArray = nullptr;
|
const std::uint8_t* cfpMomentsArray = nullptr;
|
||||||
|
|
||||||
if (momentData->data_word_size() == 8)
|
if (momentData->data_word_size() == 8)
|
||||||
{
|
{
|
||||||
dataMomentsArray8 =
|
dataMomentsArray8 =
|
||||||
reinterpret_cast<const uint8_t*>(momentData->data_moments());
|
reinterpret_cast<const std::uint8_t*>(momentData->data_moments());
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dataMomentsArray16 =
|
dataMomentsArray16 =
|
||||||
reinterpret_cast<const uint16_t*>(momentData->data_moments());
|
reinterpret_cast<const std::uint16_t*>(momentData->data_moments());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cfpMoments.size() > 0)
|
if (cfpMoments.size() > 0)
|
||||||
{
|
{
|
||||||
cfpMomentsArray = reinterpret_cast<const uint8_t*>(
|
cfpMomentsArray = reinterpret_cast<const std::uint8_t*>(
|
||||||
radialData->moment_data_block(wsr88d::rda::DataBlockType::MomentCfp)
|
radialData->moment_data_block(wsr88d::rda::DataBlockType::MomentCfp)
|
||||||
->data_moments());
|
->data_moments());
|
||||||
}
|
}
|
||||||
|
|
||||||
for (uint16_t gate = startGate, i = 0; gate + gateSize <= endGate;
|
for (std::int32_t gate = startGate, i = 0; gate + gateSize <= endGate;
|
||||||
gate += gateSize, ++i)
|
gate += gateSize, ++i)
|
||||||
{
|
{
|
||||||
size_t vertexCount = (gate > 0) ? 6 : 3;
|
if (gate < 0)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::size_t vertexCount = (gate > 0) ? 6 : 3;
|
||||||
|
|
||||||
// Store data moment value
|
// Store data moment value
|
||||||
if (dataMomentsArray8 != nullptr)
|
if (dataMomentsArray8 != nullptr)
|
||||||
{
|
{
|
||||||
uint8_t dataValue = dataMomentsArray8[i];
|
std::uint8_t dataValue = dataMomentsArray8[i];
|
||||||
if (dataValue < snrThreshold && dataValue != RANGE_FOLDED)
|
if (dataValue < snrThreshold && dataValue != RANGE_FOLDED)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t m = 0; m < vertexCount; m++)
|
for (std::size_t m = 0; m < vertexCount; m++)
|
||||||
{
|
{
|
||||||
dataMoments8[mIndex++] = dataMomentsArray8[i];
|
dataMoments8[mIndex++] = dataMomentsArray8[i];
|
||||||
|
|
||||||
|
|
@ -611,13 +616,13 @@ void Level2ProductView::ComputeSweep()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
uint16_t dataValue = dataMomentsArray16[i];
|
std::uint16_t dataValue = dataMomentsArray16[i];
|
||||||
if (dataValue < snrThreshold && dataValue != RANGE_FOLDED)
|
if (dataValue < snrThreshold && dataValue != RANGE_FOLDED)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t m = 0; m < vertexCount; m++)
|
for (std::size_t m = 0; m < vertexCount; m++)
|
||||||
{
|
{
|
||||||
dataMoments16[mIndex++] = dataMomentsArray16[i];
|
dataMoments16[mIndex++] = dataMomentsArray16[i];
|
||||||
}
|
}
|
||||||
|
|
@ -626,18 +631,18 @@ void Level2ProductView::ComputeSweep()
|
||||||
// Store vertices
|
// Store vertices
|
||||||
if (gate > 0)
|
if (gate > 0)
|
||||||
{
|
{
|
||||||
const uint16_t baseCoord = gate - 1;
|
const std::uint16_t baseCoord = gate - 1;
|
||||||
|
|
||||||
size_t offset1 = ((startRadial + radial) % radials *
|
std::size_t offset1 = ((startRadial + radial) % radials *
|
||||||
common::MAX_DATA_MOMENT_GATES +
|
common::MAX_DATA_MOMENT_GATES +
|
||||||
baseCoord) *
|
baseCoord) *
|
||||||
2;
|
2;
|
||||||
size_t offset2 = offset1 + gateSize * 2;
|
std::size_t offset2 = offset1 + gateSize * 2;
|
||||||
size_t offset3 = (((startRadial + radial + 1) % radials) *
|
std::size_t offset3 = (((startRadial + radial + 1) % radials) *
|
||||||
common::MAX_DATA_MOMENT_GATES +
|
common::MAX_DATA_MOMENT_GATES +
|
||||||
baseCoord) *
|
baseCoord) *
|
||||||
2;
|
2;
|
||||||
size_t offset4 = offset3 + gateSize * 2;
|
std::size_t offset4 = offset3 + gateSize * 2;
|
||||||
|
|
||||||
vertices[vIndex++] = coordinates[offset1];
|
vertices[vIndex++] = coordinates[offset1];
|
||||||
vertices[vIndex++] = coordinates[offset1 + 1];
|
vertices[vIndex++] = coordinates[offset1 + 1];
|
||||||
|
|
@ -661,16 +666,16 @@ void Level2ProductView::ComputeSweep()
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
const uint16_t baseCoord = gate;
|
const std::uint16_t baseCoord = gate;
|
||||||
|
|
||||||
size_t offset1 = ((startRadial + radial) % radials *
|
std::size_t offset1 = ((startRadial + radial) % radials *
|
||||||
common::MAX_DATA_MOMENT_GATES +
|
common::MAX_DATA_MOMENT_GATES +
|
||||||
baseCoord) *
|
baseCoord) *
|
||||||
2;
|
2;
|
||||||
size_t offset2 = (((startRadial + radial + 1) % radials) *
|
std::size_t offset2 = (((startRadial + radial + 1) % radials) *
|
||||||
common::MAX_DATA_MOMENT_GATES +
|
common::MAX_DATA_MOMENT_GATES +
|
||||||
baseCoord) *
|
baseCoord) *
|
||||||
2;
|
2;
|
||||||
|
|
||||||
vertices[vIndex++] = p->latitude_;
|
vertices[vIndex++] = p->latitude_;
|
||||||
vertices[vIndex++] = p->longitude_;
|
vertices[vIndex++] = p->longitude_;
|
||||||
|
|
@ -866,25 +871,26 @@ Level2ProductView::GetBinLevel(const common::Coordinate& coordinate) const
|
||||||
|
|
||||||
// Compute gate interval
|
// Compute gate interval
|
||||||
auto momentData = (*radarData)[*radial]->moment_data_block(dataBlockType);
|
auto momentData = (*radarData)[*radial]->moment_data_block(dataBlockType);
|
||||||
const std::uint16_t dataMomentInterval =
|
const std::int32_t dataMomentInterval =
|
||||||
momentData->data_moment_range_sample_interval_raw();
|
momentData->data_moment_range_sample_interval_raw();
|
||||||
const std::uint16_t dataMomentIntervalH = dataMomentInterval / 2;
|
const std::int32_t dataMomentIntervalH = dataMomentInterval / 2;
|
||||||
const std::uint16_t dataMomentRange =
|
const std::int32_t dataMomentRange = std::max<std::int32_t>(
|
||||||
std::max(momentData->data_moment_range_raw(), dataMomentIntervalH);
|
momentData->data_moment_range_raw(), dataMomentIntervalH);
|
||||||
|
|
||||||
// Compute gate size (number of base 250m gates per bin)
|
// Compute gate size (number of base 250m gates per bin)
|
||||||
const std::uint16_t gateSizeMeters =
|
const std::int32_t gateSizeMeters =
|
||||||
static_cast<std::uint16_t>(radarProductManager->gate_size());
|
static_cast<std::int32_t>(radarProductManager->gate_size());
|
||||||
|
|
||||||
// Compute gate range [startGate, endGate)
|
// Compute gate range [startGate, endGate)
|
||||||
const std::uint16_t startGate =
|
const std::int32_t startGate =
|
||||||
(dataMomentRange - dataMomentIntervalH) / gateSizeMeters;
|
(dataMomentRange - dataMomentIntervalH) / gateSizeMeters;
|
||||||
const std::uint16_t numberOfDataMomentGates =
|
const std::int32_t numberOfDataMomentGates =
|
||||||
momentData->number_of_data_moment_gates();
|
momentData->number_of_data_moment_gates();
|
||||||
|
|
||||||
const std::uint16_t gate = s12 / dataMomentInterval - startGate;
|
const std::int32_t gate = s12 / dataMomentInterval - startGate;
|
||||||
|
|
||||||
if (gate > numberOfDataMomentGates || gate > common::MAX_DATA_MOMENT_GATES)
|
if (gate < 0 || gate > numberOfDataMomentGates ||
|
||||||
|
gate > common::MAX_DATA_MOMENT_GATES)
|
||||||
{
|
{
|
||||||
// Coordinate is beyond radar range
|
// Coordinate is beyond radar range
|
||||||
return std::nullopt;
|
return std::nullopt;
|
||||||
|
|
|
||||||
|
|
@ -31,9 +31,9 @@ public:
|
||||||
std::uint16_t elevation_angle_raw() const;
|
std::uint16_t elevation_angle_raw() const;
|
||||||
units::degrees<float> elevation_angle() const;
|
units::degrees<float> elevation_angle() const;
|
||||||
std::uint16_t elevation_number() const;
|
std::uint16_t elevation_number() const;
|
||||||
std::uint16_t surveillance_range_raw() const;
|
std::int16_t surveillance_range_raw() const;
|
||||||
units::kilometers<float> surveillance_range() const;
|
units::kilometers<float> surveillance_range() const;
|
||||||
std::uint16_t doppler_range_raw() const;
|
std::int16_t doppler_range_raw() const;
|
||||||
units::kilometers<float> doppler_range() const;
|
units::kilometers<float> doppler_range() const;
|
||||||
std::uint16_t surveillance_range_sample_interval_raw() const;
|
std::uint16_t surveillance_range_sample_interval_raw() const;
|
||||||
units::kilometers<float> surveillance_range_sample_interval() const;
|
units::kilometers<float> surveillance_range_sample_interval() const;
|
||||||
|
|
|
||||||
|
|
@ -120,7 +120,7 @@ public:
|
||||||
|
|
||||||
std::uint16_t number_of_data_moment_gates() const;
|
std::uint16_t number_of_data_moment_gates() const;
|
||||||
units::kilometers<float> data_moment_range() const;
|
units::kilometers<float> data_moment_range() const;
|
||||||
std::uint16_t data_moment_range_raw() const;
|
std::int16_t data_moment_range_raw() const;
|
||||||
units::kilometers<float> data_moment_range_sample_interval() const;
|
units::kilometers<float> data_moment_range_sample_interval() const;
|
||||||
std::uint16_t data_moment_range_sample_interval_raw() const;
|
std::uint16_t data_moment_range_sample_interval_raw() const;
|
||||||
float snr_threshold() const;
|
float snr_threshold() const;
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ public:
|
||||||
|
|
||||||
virtual std::uint16_t number_of_data_moment_gates() const = 0;
|
virtual std::uint16_t number_of_data_moment_gates() const = 0;
|
||||||
virtual units::kilometers<float> data_moment_range() const = 0;
|
virtual units::kilometers<float> data_moment_range() const = 0;
|
||||||
virtual std::uint16_t data_moment_range_raw() const = 0;
|
virtual std::int16_t data_moment_range_raw() const = 0;
|
||||||
virtual units::kilometers<float>
|
virtual units::kilometers<float>
|
||||||
data_moment_range_sample_interval() const = 0;
|
data_moment_range_sample_interval() const = 0;
|
||||||
virtual std::uint16_t data_moment_range_sample_interval_raw() const = 0;
|
virtual std::uint16_t data_moment_range_sample_interval_raw() const = 0;
|
||||||
|
|
|
||||||
|
|
@ -33,8 +33,8 @@ public:
|
||||||
std::uint16_t radialStatus_ {};
|
std::uint16_t radialStatus_ {};
|
||||||
std::uint16_t elevationAngle_ {};
|
std::uint16_t elevationAngle_ {};
|
||||||
std::uint16_t elevationNumber_ {};
|
std::uint16_t elevationNumber_ {};
|
||||||
std::uint16_t surveillanceRange_ {};
|
std::int16_t surveillanceRange_ {};
|
||||||
std::uint16_t dopplerRange_ {};
|
std::int16_t dopplerRange_ {};
|
||||||
std::uint16_t surveillanceRangeSampleInterval_ {};
|
std::uint16_t surveillanceRangeSampleInterval_ {};
|
||||||
std::uint16_t dopplerRangeSampleInterval_ {};
|
std::uint16_t dopplerRangeSampleInterval_ {};
|
||||||
std::uint16_t numberOfSurveillanceBins_ {};
|
std::uint16_t numberOfSurveillanceBins_ {};
|
||||||
|
|
@ -71,7 +71,7 @@ public:
|
||||||
|
|
||||||
std::uint16_t number_of_data_moment_gates() const;
|
std::uint16_t number_of_data_moment_gates() const;
|
||||||
units::kilometers<float> data_moment_range() const;
|
units::kilometers<float> data_moment_range() const;
|
||||||
std::uint16_t data_moment_range_raw() const;
|
std::int16_t data_moment_range_raw() const;
|
||||||
units::kilometers<float> data_moment_range_sample_interval() const;
|
units::kilometers<float> data_moment_range_sample_interval() const;
|
||||||
std::uint16_t data_moment_range_sample_interval_raw() const;
|
std::uint16_t data_moment_range_sample_interval_raw() const;
|
||||||
std::int16_t snr_threshold_raw() const;
|
std::int16_t snr_threshold_raw() const;
|
||||||
|
|
@ -94,7 +94,7 @@ public:
|
||||||
~Impl() = default;
|
~Impl() = default;
|
||||||
|
|
||||||
std::uint16_t numberOfDataMomentGates_ {};
|
std::uint16_t numberOfDataMomentGates_ {};
|
||||||
std::uint16_t dataMomentRange_ {};
|
std::int16_t dataMomentRange_ {};
|
||||||
std::uint16_t dataMomentRangeSampleInterval_ {};
|
std::uint16_t dataMomentRangeSampleInterval_ {};
|
||||||
float scale_ {};
|
float scale_ {};
|
||||||
float offset_ {};
|
float offset_ {};
|
||||||
|
|
@ -162,7 +162,7 @@ std::uint16_t DigitalRadarData::elevation_number() const
|
||||||
return p->elevationNumber_;
|
return p->elevationNumber_;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint16_t DigitalRadarData::surveillance_range_raw() const
|
std::int16_t DigitalRadarData::surveillance_range_raw() const
|
||||||
{
|
{
|
||||||
return p->surveillanceRange_;
|
return p->surveillanceRange_;
|
||||||
}
|
}
|
||||||
|
|
@ -172,7 +172,7 @@ units::kilometers<float> DigitalRadarData::surveillance_range() const
|
||||||
return units::kilometers<float> {p->surveillanceRange_ * kRangeScale};
|
return units::kilometers<float> {p->surveillanceRange_ * kRangeScale};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint16_t DigitalRadarData::doppler_range_raw() const
|
std::int16_t DigitalRadarData::doppler_range_raw() const
|
||||||
{
|
{
|
||||||
return p->dopplerRange_;
|
return p->dopplerRange_;
|
||||||
}
|
}
|
||||||
|
|
@ -363,7 +363,7 @@ DigitalRadarData::Impl::MomentDataBlock::data_moment_range() const
|
||||||
return units::kilometers<float> {p->dataMomentRange_ * kRangeScale};
|
return units::kilometers<float> {p->dataMomentRange_ * kRangeScale};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint16_t
|
std::int16_t
|
||||||
DigitalRadarData::Impl::MomentDataBlock::data_moment_range_raw() const
|
DigitalRadarData::Impl::MomentDataBlock::data_moment_range_raw() const
|
||||||
{
|
{
|
||||||
return p->dataMomentRange_;
|
return p->dataMomentRange_;
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ public:
|
||||||
explicit Impl() {}
|
explicit Impl() {}
|
||||||
|
|
||||||
std::uint16_t numberOfDataMomentGates_ {0};
|
std::uint16_t numberOfDataMomentGates_ {0};
|
||||||
std::uint16_t dataMomentRange_ {0};
|
std::int16_t dataMomentRange_ {0};
|
||||||
std::uint16_t dataMomentRangeSampleInterval_ {0};
|
std::uint16_t dataMomentRangeSampleInterval_ {0};
|
||||||
std::uint16_t tover_ {0};
|
std::uint16_t tover_ {0};
|
||||||
std::int16_t snrThreshold_ {0};
|
std::int16_t snrThreshold_ {0};
|
||||||
|
|
@ -92,7 +92,7 @@ DigitalRadarDataGeneric::MomentDataBlock::data_moment_range() const
|
||||||
return units::kilometers<float> {p->dataMomentRange_ * 0.001f};
|
return units::kilometers<float> {p->dataMomentRange_ * 0.001f};
|
||||||
}
|
}
|
||||||
|
|
||||||
std::uint16_t
|
std::int16_t
|
||||||
DigitalRadarDataGeneric::MomentDataBlock::data_moment_range_raw() const
|
DigitalRadarDataGeneric::MomentDataBlock::data_moment_range_raw() const
|
||||||
{
|
{
|
||||||
return p->dataMomentRange_;
|
return p->dataMomentRange_;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue