88 lines
3.5 KiB
C++
88 lines
3.5 KiB
C++
#include <gtest/gtest.h>
|
|
#include <cstdint>
|
|
#include <filesystem>
|
|
#include <fstream>
|
|
#include "io/gpr/NormalizedRadarReader.hpp"
|
|
using namespace geopro::io::gpr;
|
|
namespace fs = std::filesystem;
|
|
|
|
TEST(NormalizedRadarHead, ParsesCoreFieldsAndDerivesTraces) {
|
|
const std::string head =
|
|
"SAMPLES:516\nNUMBER_OF_CH:16\nLAST_TRACE:60448\nBITS:16\nENDIAN_TYPE:1\n"
|
|
"DISTANCE_INTERVAL:0.099194\nTIMEWINDOW:96.419553\nDIELECTRIC:\n"
|
|
"CH_X_OFFSETS:0.080 0.160 0.240 0.320 0.400 0.480 0.560 0.640 0.720 0.800 "
|
|
"0.880 0.960 1.040 1.120 1.200 1.280\n";
|
|
const RadarHeader h = parseRadarHead(head);
|
|
EXPECT_EQ(h.samples, 516);
|
|
EXPECT_EQ(h.channels, 16);
|
|
EXPECT_EQ(h.lastTrace, 60448);
|
|
EXPECT_EQ(h.traces, 3778); // 60448/16
|
|
EXPECT_EQ(h.bits, 16);
|
|
EXPECT_EQ(h.endianType, 1);
|
|
EXPECT_DOUBLE_EQ(h.distanceInterval, 0.099194);
|
|
ASSERT_EQ(h.chXOffsets.size(), 16u);
|
|
EXPECT_DOUBLE_EQ(h.chXOffsets.front(), 0.080);
|
|
EXPECT_DOUBLE_EQ(h.chXOffsets.back(), 1.280);
|
|
}
|
|
|
|
TEST(NormalizedRadarHead, MissingRequiredFieldThrows) {
|
|
EXPECT_THROW(parseRadarHead("SAMPLES:516\nNUMBER_OF_CH:16\n"), std::runtime_error);
|
|
}
|
|
|
|
TEST(NormalizedRadarHead, DepthSpacingUsesDefaultVelocityWhenNoDielectric) {
|
|
const std::string head = "SAMPLES:516\nNUMBER_OF_CH:16\nLAST_TRACE:32\n"
|
|
"TIMEWINDOW:96.419553\nDIELECTRIC:\n";
|
|
const RadarHeader h = parseRadarHead(head);
|
|
EXPECT_NEAR(waveVelocityMperNs(h), 0.1, 1e-9); // 无介电 → 默认 0.1
|
|
const double dz = depthSpacingZ(h);
|
|
EXPECT_NEAR(dz, (96.419553 / 515.0) * 0.1 / 2.0, 1e-9);
|
|
}
|
|
|
|
TEST(NormalizedRadarData, ReadsPositionMajorCubeLittleEndian) {
|
|
// K=2 道, M=3 通道, N=2 采样; 值 v(t,c,s)=int16(100*t+10*c+s)。position-major 写。
|
|
fs::path dir = fs::temp_directory_path() / "radar_data_test";
|
|
fs::create_directories(dir);
|
|
const fs::path dp = dir / "L.data";
|
|
{
|
|
std::ofstream f(dp, std::ios::binary);
|
|
for (int t = 0; t < 2; ++t)
|
|
for (int c = 0; c < 3; ++c)
|
|
for (int s = 0; s < 2; ++s) {
|
|
std::int16_t v = static_cast<std::int16_t>(100 * t + 10 * c + s);
|
|
f.write(reinterpret_cast<const char*>(&v), sizeof(v)); // 小端(x86)
|
|
}
|
|
}
|
|
geopro::io::gpr::RadarHeader h;
|
|
h.samples = 2; h.channels = 3; h.lastTrace = 6; h.traces = 2; h.bits = 16; h.endianType = 1;
|
|
const auto cube = geopro::io::gpr::readRadarDataCube(dp.string(), h);
|
|
ASSERT_EQ(cube.size(), 2u * 3u * 2u);
|
|
auto at = [&](int t, int c, int s) { return cube[(size_t(t) * 3 + c) * 2 + s]; };
|
|
EXPECT_EQ(at(0, 0, 0), 0);
|
|
EXPECT_EQ(at(1, 2, 1), 121); // 100+20+1
|
|
EXPECT_EQ(at(0, 1, 0), 10);
|
|
}
|
|
|
|
TEST(NormalizedRadarCor, ParsesRowsSkippingVersion) {
|
|
const std::string cor =
|
|
"VERSION:1\n"
|
|
"1\t317.179340\tN\t472.759046\tE\t49.980000\tM\t4\n"
|
|
"12\t317.201303\tN\t472.700649\tE\t51.040000\tM\t4\n";
|
|
const auto pts = geopro::io::gpr::parseRadarCor(cor);
|
|
ASSERT_EQ(pts.size(), 2u);
|
|
EXPECT_EQ(pts[0].index, 1);
|
|
EXPECT_DOUBLE_EQ(pts[0].lat, 317.179340);
|
|
EXPECT_DOUBLE_EQ(pts[0].lon, 472.759046);
|
|
EXPECT_DOUBLE_EQ(pts[1].elev, 51.040000);
|
|
EXPECT_EQ(pts[1].solution, 4);
|
|
}
|
|
|
|
TEST(NormalizedRadarData, WrongFileSizeThrows) {
|
|
fs::path dir = fs::temp_directory_path() / "radar_data_test";
|
|
fs::create_directories(dir);
|
|
const fs::path dp = dir / "bad.data";
|
|
{ std::ofstream f(dp, std::ios::binary); std::int16_t v = 0; f.write((char*)&v, 2); }
|
|
geopro::io::gpr::RadarHeader h;
|
|
h.samples = 2; h.channels = 3; h.lastTrace = 6; h.traces = 2; h.bits = 16;
|
|
EXPECT_THROW(geopro::io::gpr::readRadarDataCube(dp.string(), h), std::runtime_error);
|
|
}
|