mirror of
				https://github.com/ciphervance/supercell-wx.git
				synced 2025-10-31 01:40:04 +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
	
	 Dan Paulat
						Dan Paulat