Index volume scan by time, change internal data structure from unordered to ordered map

This commit is contained in:
Dan Paulat 2021-11-12 21:37:48 -06:00
parent e78231ac48
commit efeb87baaa
9 changed files with 104 additions and 71 deletions

View file

@ -42,7 +42,9 @@ public:
std::vector<float> coordinates0_5Degree_; std::vector<float> coordinates0_5Degree_;
std::vector<float> coordinates1Degree_; std::vector<float> coordinates1Degree_;
std::deque<std::shared_ptr<wsr88d::Ar2vFile>> level2Data_; std::map<std::chrono::system_clock::time_point,
std::shared_ptr<wsr88d::Ar2vFile>>
level2VolumeScans_;
}; };
RadarProductManager::RadarProductManager() : RadarProductManager::RadarProductManager() :
@ -67,9 +69,9 @@ std::shared_ptr<const wsr88d::Ar2vFile> RadarProductManager::level2_data() const
{ {
std::shared_ptr<const wsr88d::Ar2vFile> level2Data = nullptr; std::shared_ptr<const wsr88d::Ar2vFile> level2Data = nullptr;
if (p->level2Data_.size() > 0) if (p->level2VolumeScans_.size() > 0)
{ {
level2Data = p->level2Data_.back(); level2Data = p->level2VolumeScans_.crbegin()->second;
} }
return level2Data; return level2Data;
@ -173,28 +175,22 @@ void RadarProductManager::LoadLevel2Data(const std::string& filename)
return; return;
} }
// TODO: Sort and index these p->level2VolumeScans_[ar2vFile->start_time()] = ar2vFile;
if (p->level2Data_.size() >= MAX_LEVEL2_FILES - 1)
{
p->level2Data_.pop_front();
}
p->level2Data_.push_back(ar2vFile);
emit Level2DataLoaded(); emit Level2DataLoaded();
} }
std::unordered_map<uint16_t, std::shared_ptr<wsr88d::rda::DigitalRadarData>> std::map<uint16_t, std::shared_ptr<wsr88d::rda::DigitalRadarData>>
RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, RadarProductManager::GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType,
uint8_t elevationIndex, uint8_t elevationIndex,
std::chrono::system_clock::time_point time) std::chrono::system_clock::time_point time)
{ {
std::unordered_map<uint16_t, std::shared_ptr<wsr88d::rda::DigitalRadarData>> std::map<uint16_t, std::shared_ptr<wsr88d::rda::DigitalRadarData>> radarData;
radarData;
if (p->level2Data_.size() > 0) if (p->level2VolumeScans_.size() > 0)
{ {
// TODO: Pull this from the database radarData =
radarData = p->level2Data_[0]->radar_data()[elevationIndex]; p->level2VolumeScans_.crbegin()->second->radar_data()[elevationIndex];
} }
else else
{ {

View file

@ -33,7 +33,7 @@ public:
void Initialize(); void Initialize();
void LoadLevel2Data(const std::string& filename); void LoadLevel2Data(const std::string& filename);
std::unordered_map<uint16_t, std::shared_ptr<wsr88d::rda::DigitalRadarData>> std::map<uint16_t, std::shared_ptr<wsr88d::rda::DigitalRadarData>>
GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType, GetLevel2Data(wsr88d::rda::DataBlockType dataBlockType,
uint8_t elevationIndex, uint8_t elevationIndex,
std::chrono::system_clock::time_point time = {}); std::chrono::system_clock::time_point time = {});

View file

@ -1,5 +1,6 @@
#include <scwx/qt/view/level2_product_view.hpp> #include <scwx/qt/view/level2_product_view.hpp>
#include <scwx/common/constants.hpp> #include <scwx/common/constants.hpp>
#include <scwx/util/time.hpp>
#include <boost/log/trivial.hpp> #include <boost/log/trivial.hpp>
#include <boost/range/irange.hpp> #include <boost/range/irange.hpp>
@ -34,9 +35,6 @@ static const std::unordered_map<common::Level2Product,
{common::Level2Product::ClutterFilterPowerRemoved, {common::Level2Product::ClutterFilterPowerRemoved,
wsr88d::rda::DataBlockType::MomentCfp}}; wsr88d::rda::DataBlockType::MomentCfp}};
static std::chrono::system_clock::time_point
TimePoint(uint16_t modifiedJulianDate, uint32_t milliseconds);
class Level2ProductViewImpl class Level2ProductViewImpl
{ {
public: public:
@ -250,7 +248,8 @@ void Level2ProductView::ComputeSweep()
const std::vector<float>& coordinates = const std::vector<float>& coordinates =
p->radarProductManager_->coordinates(radialSize); p->radarProductManager_->coordinates(radialSize);
auto momentData0 = radarData[0]->moment_data_block(p->dataBlockType_); auto radarData0 = radarData[0];
auto momentData0 = radarData0->moment_data_block(p->dataBlockType_);
p->momentDataBlock0_ = momentData0; p->momentDataBlock0_ = momentData0;
if (momentData0 == nullptr) if (momentData0 == nullptr)
@ -260,11 +259,11 @@ void Level2ProductView::ComputeSweep()
return; return;
} }
auto volumeData0 = radarData[0]->volume_data_block(); auto volumeData0 = radarData0->volume_data_block();
p->latitude_ = volumeData0->latitude(); p->latitude_ = volumeData0->latitude();
p->longitude_ = volumeData0->longitude(); p->longitude_ = volumeData0->longitude();
p->sweepTime_ = TimePoint(radarData[0]->modified_julian_date(), p->sweepTime_ = util::TimePoint(radarData0->modified_julian_date(),
radarData[0]->collection_time()); radarData0->collection_time());
// Calculate vertices // Calculate vertices
timer.start(); timer.start();
@ -307,16 +306,16 @@ void Level2ProductView::ComputeSweep()
// 1 = 0.5 degrees // 1 = 0.5 degrees
// 2 = 1.0 degrees // 2 = 1.0 degrees
const float radialMultiplier = const float radialMultiplier =
2.0f / 2.0f / std::clamp<int8_t>(radarData0->azimuth_resolution_spacing(), 1, 2);
std::clamp<int8_t>(radarData[0]->azimuth_resolution_spacing(), 1, 2);
const float startAngle = radarData[0]->azimuth_angle(); const float startAngle = radarData0->azimuth_angle();
const uint16_t startRadial = std::lroundf(startAngle * radialMultiplier); const uint16_t startRadial = std::lroundf(startAngle * radialMultiplier);
for (uint16_t radial = 0; radial < radials; ++radial) for (auto radialPair : radarData)
{ {
auto radialData = radarData[radial]; uint16_t radial = radialPair.first;
auto momentData = radarData[radial]->moment_data_block(p->dataBlockType_); auto radialData = radialPair.second;
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())
{ {
@ -481,17 +480,6 @@ std::shared_ptr<Level2ProductView> Level2ProductView::Create(
return std::make_shared<Level2ProductView>(product, radarProductManager); return std::make_shared<Level2ProductView>(product, radarProductManager);
} }
static std::chrono::system_clock::time_point
TimePoint(uint16_t modifiedJulianDate, uint32_t milliseconds)
{
using namespace std::chrono;
using sys_days = time_point<system_clock, days>;
constexpr auto epoch = sys_days {1969y / December / 31d};
return epoch + (modifiedJulianDate * 24h) +
std::chrono::milliseconds {milliseconds};
}
} // namespace view } // namespace view
} // namespace qt } // namespace qt
} // namespace scwx } // namespace scwx

View file

@ -29,7 +29,7 @@ source_group("Source Files\\wsr88d" FILES ${SRC_WSR88D_TESTS})
target_include_directories(wxtest PRIVATE ${GTest_INCLUDE_DIRS}) target_include_directories(wxtest PRIVATE ${GTest_INCLUDE_DIRS})
set_target_properties(wxtest PROPERTIES CXX_STANDARD 17 set_target_properties(wxtest PROPERTIES CXX_STANDARD 20
CXX_STANDARD_REQUIRED ON CXX_STANDARD_REQUIRED ON
CXX_EXTENSIONS OFF) CXX_EXTENSIONS OFF)

View file

@ -0,0 +1,14 @@
#pragma once
#include <chrono>
namespace scwx
{
namespace util
{
std::chrono::system_clock::time_point TimePoint(uint16_t modifiedJulianDate,
uint32_t milliseconds);
} // namespace util
} // namespace scwx

View file

@ -3,9 +3,9 @@
#include <scwx/wsr88d/rda/digital_radar_data.hpp> #include <scwx/wsr88d/rda/digital_radar_data.hpp>
#include <scwx/wsr88d/rda/volume_coverage_pattern_data.hpp> #include <scwx/wsr88d/rda/volume_coverage_pattern_data.hpp>
#include <chrono>
#include <memory> #include <memory>
#include <string> #include <string>
#include <unordered_map>
namespace scwx namespace scwx
{ {
@ -31,9 +31,14 @@ public:
Ar2vFile(Ar2vFile&&) noexcept; Ar2vFile(Ar2vFile&&) noexcept;
Ar2vFile& operator=(Ar2vFile&&) noexcept; Ar2vFile& operator=(Ar2vFile&&) noexcept;
std::unordered_map< uint32_t julian_date() const;
uint16_t, uint32_t milliseconds() const;
std::unordered_map<uint16_t, std::shared_ptr<rda::DigitalRadarData>>>
std::chrono::system_clock::time_point start_time() const;
std::chrono::system_clock::time_point end_time() const;
std::map<uint16_t,
std::map<uint16_t, std::shared_ptr<rda::DigitalRadarData>>>
radar_data() const; radar_data() const;
std::shared_ptr<const rda::VolumeCoveragePatternData> vcp_data() const; std::shared_ptr<const rda::VolumeCoveragePatternData> vcp_data() const;

View file

@ -0,0 +1,20 @@
#include <scwx/util/time.hpp>
namespace scwx
{
namespace util
{
std::chrono::system_clock::time_point
TimePoint(uint16_t modifiedJulianDate, uint32_t milliseconds)
{
using namespace std::chrono;
using sys_days = time_point<system_clock, days>;
constexpr auto epoch = sys_days {1969y / December / 31d};
return epoch + (modifiedJulianDate * 24h) +
std::chrono::milliseconds {milliseconds};
}
} // namespace qt
} // namespace scwx

View file

@ -2,6 +2,7 @@
#include <scwx/wsr88d/rda/message_factory.hpp> #include <scwx/wsr88d/rda/message_factory.hpp>
#include <scwx/wsr88d/rda/types.hpp> #include <scwx/wsr88d/rda/types.hpp>
#include <scwx/util/rangebuf.hpp> #include <scwx/util/rangebuf.hpp>
#include <scwx/util/time.hpp>
#include <fstream> #include <fstream>
#include <sstream> #include <sstream>
@ -37,7 +38,6 @@ public:
void LoadLDMRecords(std::ifstream& f); void LoadLDMRecords(std::ifstream& f);
void ParseLDMRecords(); void ParseLDMRecords();
void ProcessRadarData(std::shared_ptr<rda::DigitalRadarData> message); void ProcessRadarData(std::shared_ptr<rda::DigitalRadarData> message);
void ProcessVcpData();
std::string tapeFilename_; std::string tapeFilename_;
std::string extensionNumber_; std::string extensionNumber_;
@ -48,9 +48,8 @@ public:
size_t numRecords_; size_t numRecords_;
std::shared_ptr<rda::VolumeCoveragePatternData> vcpData_; std::shared_ptr<rda::VolumeCoveragePatternData> vcpData_;
std::unordered_map< std::map<uint16_t,
uint16_t, std::map<uint16_t, std::shared_ptr<rda::DigitalRadarData>>>
std::unordered_map<uint16_t, std::shared_ptr<rda::DigitalRadarData>>>
radarData_; radarData_;
std::list<std::stringstream> rawRecords_; std::list<std::stringstream> rawRecords_;
@ -62,9 +61,37 @@ Ar2vFile::~Ar2vFile() = default;
Ar2vFile::Ar2vFile(Ar2vFile&&) noexcept = default; Ar2vFile::Ar2vFile(Ar2vFile&&) noexcept = default;
Ar2vFile& Ar2vFile::operator=(Ar2vFile&&) noexcept = default; Ar2vFile& Ar2vFile::operator=(Ar2vFile&&) noexcept = default;
std::unordered_map< uint32_t Ar2vFile::julian_date() const
uint16_t, {
std::unordered_map<uint16_t, std::shared_ptr<rda::DigitalRadarData>>> return p->julianDate_;
}
uint32_t Ar2vFile::milliseconds() const
{
return p->milliseconds_;
}
std::chrono::system_clock::time_point Ar2vFile::start_time() const
{
return util::TimePoint(p->julianDate_, p->milliseconds_);
}
std::chrono::system_clock::time_point Ar2vFile::end_time() const
{
std::chrono::system_clock::time_point endTime {};
if (p->radarData_.size() > 0)
{
std::shared_ptr<rda::DigitalRadarData> lastRadial =
p->radarData_.crbegin()->second.crbegin()->second;
endTime = util::TimePoint(lastRadial->modified_julian_date(),
lastRadial->collection_time());
}
return endTime;
}
std::map<uint16_t, std::map<uint16_t, std::shared_ptr<rda::DigitalRadarData>>>
Ar2vFile::radar_data() const Ar2vFile::radar_data() const
{ {
return p->radarData_; return p->radarData_;
@ -245,7 +272,6 @@ void Ar2vFileImpl::HandleMessage(std::shared_ptr<rda::Message>& message)
case static_cast<uint8_t>(rda::MessageId::VolumeCoveragePatternData): case static_cast<uint8_t>(rda::MessageId::VolumeCoveragePatternData):
vcpData_ = vcpData_ =
std::static_pointer_cast<rda::VolumeCoveragePatternData>(message); std::static_pointer_cast<rda::VolumeCoveragePatternData>(message);
ProcessVcpData();
break; break;
case static_cast<uint8_t>(rda::MessageId::DigitalRadarData): case static_cast<uint8_t>(rda::MessageId::DigitalRadarData):
@ -266,23 +292,5 @@ void Ar2vFileImpl::ProcessRadarData(
radarData_[elevationIndex][azimuthIndex] = message; radarData_[elevationIndex][azimuthIndex] = message;
} }
void Ar2vFileImpl::ProcessVcpData()
{
uint16_t numberOfElevationCuts = vcpData_->number_of_elevation_cuts();
radarData_.reserve(numberOfElevationCuts);
for (uint16_t e = 0; e < numberOfElevationCuts; ++e)
{
if (vcpData_->half_degree_azimuth(e))
{
radarData_[e].reserve(720);
}
else
{
radarData_[e].reserve(360);
}
}
}
} // namespace wsr88d } // namespace wsr88d
} // namespace scwx } // namespace scwx

View file

@ -12,9 +12,11 @@ set(HDR_UTIL include/scwx/util/iterator.hpp
include/scwx/util/rangebuf.hpp include/scwx/util/rangebuf.hpp
include/scwx/util/streams.hpp include/scwx/util/streams.hpp
include/scwx/util/threads.hpp include/scwx/util/threads.hpp
include/scwx/util/time.hpp
include/scwx/util/vectorbuf.hpp) include/scwx/util/vectorbuf.hpp)
set(SRC_UTIL source/scwx/util/rangebuf.cpp set(SRC_UTIL source/scwx/util/rangebuf.cpp
source/scwx/util/streams.cpp source/scwx/util/streams.cpp
source/scwx/util/time.cpp
source/scwx/util/vectorbuf.cpp) source/scwx/util/vectorbuf.cpp)
set(HDR_WSR88D include/scwx/wsr88d/ar2v_file.hpp) set(HDR_WSR88D include/scwx/wsr88d/ar2v_file.hpp)
set(SRC_WSR88D source/scwx/wsr88d/ar2v_file.cpp) set(SRC_WSR88D source/scwx/wsr88d/ar2v_file.cpp)