From 0a5e02886dd8eee5a2b0b7a6da30d94bc97a5514 Mon Sep 17 00:00:00 2001 From: Dan Smith Date: Mon, 21 Aug 2023 09:59:01 -0400 Subject: [PATCH 1/2] CRLF --- UnitTest/CppUnitTestAssert.cpp | 86 +- UnitTest/Test.cpp | 192 +- UnitTest/Test.h | 20 +- UnitTest/UnitTest.vcxproj | 630 +-- UnitTest/UnitTest.vcxproj.filters | 386 +- processFiles.py | 198 +- six.sln | 262 +- six/modules/c++/cphd/cphd.vcxproj | 364 +- six/modules/c++/cphd/cphd.vcxproj.filters | 388 +- six/modules/c++/cphd/include/cphd/Antenna.h | 748 +-- six/modules/c++/cphd/include/cphd/Dwell.h | 256 +- .../c++/cphd/include/cphd/ErrorParameters.h | 480 +- .../c++/cphd/include/cphd/MetadataBase.h | 222 +- six/modules/c++/cphd/include/cphd/PVP.h | 1224 ++--- .../c++/cphd/include/cphd/ProductInfo.h | 234 +- .../c++/cphd/include/cphd/ReferenceGeometry.h | 700 +-- six/modules/c++/cphd/include/cphd/TxRcv.h | 368 +- six/modules/c++/cphd/source/Antenna.cpp | 296 +- six/modules/c++/cphd/source/CPHDXMLParser.cpp | 4844 ++++++++--------- six/modules/c++/cphd/source/Channel.cpp | 454 +- six/modules/c++/cphd/source/Dwell.cpp | 146 +- .../c++/cphd/source/ErrorParameters.cpp | 382 +- six/modules/c++/cphd/source/PVP.cpp | 560 +- six/modules/c++/cphd/source/ProductInfo.cpp | 126 +- .../c++/cphd/source/ReferenceGeometry.cpp | 348 +- six/modules/c++/cphd/source/TxRcv.cpp | 198 +- .../c++/cphd/unittests/test_channel.cpp | 170 +- .../cphd/unittests/test_cphd_xml_optional.cpp | 2256 ++++---- six/modules/c++/cphd/unittests/test_dwell.cpp | 240 +- six/modules/c++/cphd/unittests/test_pvp.cpp | 218 +- .../cphd/unittests/test_pvp_block_round.cpp | 506 +- .../unittests/test_reference_geometry.cpp | 126 +- .../unittests/test_signal_block_round.cpp | 448 +- .../unittests/test_support_block_round.cpp | 336 +- six/modules/c++/cphd03/cphd03.vcxproj | 300 +- six/modules/c++/samples/check_valid_six.cpp | 556 +- .../check_valid_six.vcxproj | 252 +- .../samples/crop_sicd.dir/crop_sicd.vcxproj | 252 +- six/modules/c++/samples/utils.h | 122 +- .../c++/scene/include/scene/sys_Conf.h | 30 +- six/modules/c++/scene/scene.ruleset | 62 +- six/modules/c++/scene/scene.vcxproj | 308 +- six/modules/c++/scene/scene.vcxproj.filters | 244 +- .../source/ProjectionPolynomialFitter.cpp | 978 ++-- .../c++/six.convert/six.convert.vcxproj | 274 +- six/modules/c++/six.ruleset | 62 +- .../six.sicd/include/six/sicd/ImageCreation.h | 126 +- .../six/sicd/NITFReadComplexXMLControl.h | 212 +- .../c++/six.sicd/include/six/sicd/PFA.h | 254 +- .../c++/six.sicd/include/six/sicd/Position.h | 194 +- .../c++/six.sicd/include/six/sicd/Timeline.h | 222 +- six/modules/c++/six.sicd/six.sicd.vcxproj | 394 +- .../c++/six.sicd/six.sicd.vcxproj.filters | 496 +- six/modules/c++/six.sicd/source/Grid.cpp | 1820 +++---- six/modules/c++/six.sicd/source/ImageData.cpp | 556 +- .../source/NITFReadComplexXMLControl.cpp | 258 +- six/modules/c++/six.sicd/source/PFA.cpp | 174 +- six/modules/c++/six.sicd/source/Position.cpp | 92 +- .../c++/six.sicd/source/RadarCollection.cpp | 1200 ++-- 59 files changed, 13925 insertions(+), 13925 deletions(-) diff --git a/UnitTest/CppUnitTestAssert.cpp b/UnitTest/CppUnitTestAssert.cpp index fdcf5f92b5..9b2594ac58 100644 --- a/UnitTest/CppUnitTestAssert.cpp +++ b/UnitTest/CppUnitTestAssert.cpp @@ -1,43 +1,43 @@ -#include "pch.h" -#include "TestCase.h" - -#include "str/EncodedStringView.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -// EQUALS_MESSAGE() wants ToString() specializations (or overloads) for our types, which is a nusiance. -// This hooks up our existing str::toString() into the VC++ unit-test infrastructure - -// C++ hack to call private methods -// https://stackoverflow.com/a/71578383/8877 - -using FailOnCondition_t = void(bool condition, const unsigned short* message, const __LineInfo* pLineInfo); // declare method's type -using GetAssertMessage_t = std::wstring(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message); // declare method's type -template -struct caller final // helper structure to inject call() code -{ - friend void FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo) - { - fFailOnCondition(condition, message, pLineInfo); - } - - friend std::wstring GetAssertMessage(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message) - { - return fGetAssertMessage(equality, expected, actual, message); - } -}; -template struct caller<&Assert::FailOnCondition, &Assert::GetAssertMessage>; // even instantiation of the helper - -void FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo); // declare caller -void test::Assert::FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo) -{ - ::FailOnCondition(condition, message, pLineInfo); // and call! -} - -std::wstring GetAssertMessage(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message); // declare caller -std::wstring test::Assert::GetAssertMessage(bool equality, const std::string& expected, const std::string& actual, const wchar_t *message) -{ - const str::EncodedStringView vExpected(expected); - const str::EncodedStringView vActual(actual); - return ::GetAssertMessage(equality, vExpected.wstring(), vActual.wstring(), message); // and call! -} +#include "pch.h" +#include "TestCase.h" + +#include "str/EncodedStringView.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +// EQUALS_MESSAGE() wants ToString() specializations (or overloads) for our types, which is a nusiance. +// This hooks up our existing str::toString() into the VC++ unit-test infrastructure + +// C++ hack to call private methods +// https://stackoverflow.com/a/71578383/8877 + +using FailOnCondition_t = void(bool condition, const unsigned short* message, const __LineInfo* pLineInfo); // declare method's type +using GetAssertMessage_t = std::wstring(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message); // declare method's type +template +struct caller final // helper structure to inject call() code +{ + friend void FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo) + { + fFailOnCondition(condition, message, pLineInfo); + } + + friend std::wstring GetAssertMessage(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message) + { + return fGetAssertMessage(equality, expected, actual, message); + } +}; +template struct caller<&Assert::FailOnCondition, &Assert::GetAssertMessage>; // even instantiation of the helper + +void FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo); // declare caller +void test::Assert::FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo) +{ + ::FailOnCondition(condition, message, pLineInfo); // and call! +} + +std::wstring GetAssertMessage(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message); // declare caller +std::wstring test::Assert::GetAssertMessage(bool equality, const std::string& expected, const std::string& actual, const wchar_t *message) +{ + const str::EncodedStringView vExpected(expected); + const str::EncodedStringView vActual(actual); + return ::GetAssertMessage(equality, vExpected.wstring(), vActual.wstring(), message); // and call! +} diff --git a/UnitTest/Test.cpp b/UnitTest/Test.cpp index 1b5022b55b..288bc85ad2 100644 --- a/UnitTest/Test.cpp +++ b/UnitTest/Test.cpp @@ -1,96 +1,96 @@ -#include "pch.h" -#include "Test.h" - -#include - -#include - -namespace fs = std::filesystem; - -static bool is_x64_Configuration(const fs::path& path) // "Configuration" is typically "Debug" or "Release" -{ - const std::string build_configuration = -#if defined(NDEBUG) // i.e., release - "Release"; -#else - "Debug"; -#endif - - const auto Configuration = path.filename(); - const auto path_parent_path = path.parent_path(); - const auto x64 = path_parent_path.filename(); - return (Configuration == build_configuration) && (x64 == "x64"); -} - -static bool is_install_unittests(const fs::path& path) -{ - const auto unittests = path.filename(); - const auto path_parent_path = path.parent_path(); - const auto install = path_parent_path.filename(); - return (unittests == "unittests") && (install == "install"); -} -static bool is_install_tests(const fs::path& path) -{ - const auto tests = path.filename(); - const auto path_parent_path = path.parent_path(); - const auto install = path_parent_path.filename(); - return (tests == "tests") && (install == "install"); -} - -fs::path six::Test::buildSchemaDir() -{ - const auto cwd = fs::current_path(); - - const sys::OS os; - const auto exec = fs::path(os.getCurrentExecutable()); - const auto argv0 = exec.filename(); - if ((argv0 == "Test.exe") || (argv0 == "testhost.exe")) - { - // Running GTest unit-tests in Visual Studio on Windows - if (is_x64_Configuration(cwd)) - { - const auto root_path = cwd.parent_path().parent_path(); - return root_path / "six" / "modules" / "c++" / "six.sidd" / "conf" / "schema"; - } - } - - if (argv0 == "unittests.exe") - { - // stand-alone unittest executable on Windows (ends in .EXE) - const auto parent_path = exec.parent_path(); - if (is_x64_Configuration(parent_path)) - { - const auto parent_path_ = parent_path.parent_path().parent_path(); - return parent_path_ / "dev" / "tests" / "images"; - } - } - - // stand-alone unit-test on Linux - const auto exec_dir = exec.parent_path(); - if (is_install_unittests(exec_dir)) - { - const auto install = exec_dir.parent_path(); - return install / "unittests" / "data"; - } - if (is_install_tests(exec_dir)) - { - const auto install = exec_dir.parent_path(); - return install / "unittests" / "data"; - } - - if (argv0 == "unittests") - { - // stand-alone unittest executable on Linux - const auto bin = exec.parent_path(); - if (bin.filename() == "bin") - { - const auto unittests = bin.parent_path(); - return unittests / "unittests" / "data"; - } - } - - //fprintf(stderr, "cwd = %s\n", cwd.c_str()); - //fprintf(stderr, "exec = %s\n", exec.c_str()); - - return cwd; -} +#include "pch.h" +#include "Test.h" + +#include + +#include + +namespace fs = std::filesystem; + +static bool is_x64_Configuration(const fs::path& path) // "Configuration" is typically "Debug" or "Release" +{ + const std::string build_configuration = +#if defined(NDEBUG) // i.e., release + "Release"; +#else + "Debug"; +#endif + + const auto Configuration = path.filename(); + const auto path_parent_path = path.parent_path(); + const auto x64 = path_parent_path.filename(); + return (Configuration == build_configuration) && (x64 == "x64"); +} + +static bool is_install_unittests(const fs::path& path) +{ + const auto unittests = path.filename(); + const auto path_parent_path = path.parent_path(); + const auto install = path_parent_path.filename(); + return (unittests == "unittests") && (install == "install"); +} +static bool is_install_tests(const fs::path& path) +{ + const auto tests = path.filename(); + const auto path_parent_path = path.parent_path(); + const auto install = path_parent_path.filename(); + return (tests == "tests") && (install == "install"); +} + +fs::path six::Test::buildSchemaDir() +{ + const auto cwd = fs::current_path(); + + const sys::OS os; + const auto exec = fs::path(os.getCurrentExecutable()); + const auto argv0 = exec.filename(); + if ((argv0 == "Test.exe") || (argv0 == "testhost.exe")) + { + // Running GTest unit-tests in Visual Studio on Windows + if (is_x64_Configuration(cwd)) + { + const auto root_path = cwd.parent_path().parent_path(); + return root_path / "six" / "modules" / "c++" / "six.sidd" / "conf" / "schema"; + } + } + + if (argv0 == "unittests.exe") + { + // stand-alone unittest executable on Windows (ends in .EXE) + const auto parent_path = exec.parent_path(); + if (is_x64_Configuration(parent_path)) + { + const auto parent_path_ = parent_path.parent_path().parent_path(); + return parent_path_ / "dev" / "tests" / "images"; + } + } + + // stand-alone unit-test on Linux + const auto exec_dir = exec.parent_path(); + if (is_install_unittests(exec_dir)) + { + const auto install = exec_dir.parent_path(); + return install / "unittests" / "data"; + } + if (is_install_tests(exec_dir)) + { + const auto install = exec_dir.parent_path(); + return install / "unittests" / "data"; + } + + if (argv0 == "unittests") + { + // stand-alone unittest executable on Linux + const auto bin = exec.parent_path(); + if (bin.filename() == "bin") + { + const auto unittests = bin.parent_path(); + return unittests / "unittests" / "data"; + } + } + + //fprintf(stderr, "cwd = %s\n", cwd.c_str()); + //fprintf(stderr, "exec = %s\n", exec.c_str()); + + return cwd; +} diff --git a/UnitTest/Test.h b/UnitTest/Test.h index 232a94cf1b..057b8d5209 100644 --- a/UnitTest/Test.h +++ b/UnitTest/Test.h @@ -1,11 +1,11 @@ -#pragma once - -#include - -namespace six -{ - namespace Test - { - extern std::filesystem::path buildSchemaDir(); - } +#pragma once + +#include + +namespace six +{ + namespace Test + { + extern std::filesystem::path buildSchemaDir(); + } } \ No newline at end of file diff --git a/UnitTest/UnitTest.vcxproj b/UnitTest/UnitTest.vcxproj index a982b81e2c..d98ea5b10e 100644 --- a/UnitTest/UnitTest.vcxproj +++ b/UnitTest/UnitTest.vcxproj @@ -1,316 +1,316 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 17.0 - {F6888896-E658-414C-90CD-1208FA31A22E} - Win32Proj - UnitTest - 10.0 - NativeUnitTestProject - - - - DynamicLibrary - true - v143 - Unicode - false - - - DynamicLibrary - false - v143 - true - Unicode - false - - - - - - - - - - - - - - - true - - - false - - - - Use - Level3 - true - $(SolutionDir);$(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration);$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration);$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - _DEBUG;SIX_DEFAULT_SCHEMA_PATH=R"($(SolutionDir)install-$(Configuration)-$(Platform).$(PlatformToolset)\conf\schema\six)";%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - pch.h - true - AdvancedVectorExtensions2 - true - MultiThreadedDebugDLL - true - true - true - - - Windows - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Use - Level3 - true - true - true - $(SolutionDir);$(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration);$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration);$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - NDEBUG;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - pch.h - true - AdvancedVectorExtensions2 - true - true - true - - - Windows - true - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - {016ef417-e41c-404c-b3b5-34b6cdd94bb3} - - - {01be4480-9620-4ded-b34f-d2e3ab4b7c8b} - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {ddc587c2-53ba-44a9-94e7-07be52af3d0b} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {F6888896-E658-414C-90CD-1208FA31A22E} + Win32Proj + UnitTest + 10.0 + NativeUnitTestProject + + + + DynamicLibrary + true + v143 + Unicode + false + + + DynamicLibrary + false + v143 + true + Unicode + false + + + + + + + + + + + + + + + true + + + false + + + + Use + Level3 + true + $(SolutionDir);$(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration);$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration);$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + _DEBUG;SIX_DEFAULT_SCHEMA_PATH=R"($(SolutionDir)install-$(Configuration)-$(Platform).$(PlatformToolset)\conf\schema\six)";%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + pch.h + true + AdvancedVectorExtensions2 + true + MultiThreadedDebugDLL + true + true + true + + + Windows + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + Use + Level3 + true + true + true + $(SolutionDir);$(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration);$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration);$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + pch.h + true + AdvancedVectorExtensions2 + true + true + true + + + Windows + true + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + {016ef417-e41c-404c-b3b5-34b6cdd94bb3} + + + {01be4480-9620-4ded-b34f-d2e3ab4b7c8b} + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {ddc587c2-53ba-44a9-94e7-07be52af3d0b} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + + + + + \ No newline at end of file diff --git a/UnitTest/UnitTest.vcxproj.filters b/UnitTest/UnitTest.vcxproj.filters index 924b309cfc..440a0297ed 100644 --- a/UnitTest/UnitTest.vcxproj.filters +++ b/UnitTest/UnitTest.vcxproj.filters @@ -1,194 +1,194 @@ - - - - - - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd03 - - - cphd03 - - - cphd03 - - - cphd03 - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sidd - - - sidd - - - sidd - - - sidd - - - sidd - - - sidd - - - six - - - six - - - six - - - six - - - six - - - - - - - - cphd - - - cphd03 - - - sicd - - - sidd - - - six - - - - - {004a37ca-2175-4642-988e-94516ea1a147} - - - {ef494548-4aed-4ebb-a93c-b56a11f17f5e} - - - {593807ae-bc84-424f-ba11-0537277cd2fc} - - - {f8053c57-ba04-41c4-8dd8-2056f5a19f25} - - - {8d8a73fb-96b1-4bdf-a055-2b34d7f94e14} - - - - - sidd - - - sidd - - + + + + + + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd03 + + + cphd03 + + + cphd03 + + + cphd03 + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sidd + + + sidd + + + sidd + + + sidd + + + sidd + + + sidd + + + six + + + six + + + six + + + six + + + six + + + + + + + + cphd + + + cphd03 + + + sicd + + + sidd + + + six + + + + + {004a37ca-2175-4642-988e-94516ea1a147} + + + {ef494548-4aed-4ebb-a93c-b56a11f17f5e} + + + {593807ae-bc84-424f-ba11-0537277cd2fc} + + + {f8053c57-ba04-41c4-8dd8-2056f5a19f25} + + + {8d8a73fb-96b1-4bdf-a055-2b34d7f94e14} + + + + + sidd + + + sidd + + \ No newline at end of file diff --git a/processFiles.py b/processFiles.py index 1e3904ec43..67d13fc9ab 100644 --- a/processFiles.py +++ b/processFiles.py @@ -1,99 +1,99 @@ -import sys, os, re, subprocess -from os.path import isdir, join, split, exists - - -def cosmoSkyMed(filename): - path, fname = split(filename) - if re.match(r'CSK.*.MBI.tif', fname): - xmlName = join(path, fname.rsplit('MBI.tif')[0] + 'attribs.xml') - if exists(xmlName): - return (xmlName, filename) - return None - -def radarsat2(filename): - path, fname = split(filename) -# if re.match(r'RS2_.*', split(path)[1]) and re.match(r'imagery_.*.tif', fname): - if re.match(r'imagery_.*.tif', fname): - xmlName = join(path, 'product.xml') - if exists(xmlName): - return (xmlName, filename) - return None - -def terraSAR(filename): - path, fname = split(filename) - if re.match(r'IMAGEDATA', split(path)[1]) and re.match(r'IMAGE_.*.tif', fname): - parDir, xmlName = split(split(path)[0]) - xmlName = join(parDir, xmlName, '%s.xml' % xmlName) - if exists(xmlName): - return (xmlName, filename) - return None - - -if __name__ == '__main__': - from optparse import OptionParser - parser = OptionParser(usage="usage: %prog [options] [path(s)]") - parser.add_option("-d", "--dir", dest='outDir', metavar='DIR', - help="specify the output directory (default=cwd)") - parser.add_option("-x", "--xml", dest='xml', action='store_true', - help="Write An XML output") - parser.add_option("-n", "--nitf", dest='nitf', action='store_true', - help="Write A NITF output") - parser.add_option("-t", "--tiff", dest='tiff', action='store_true', - help="Write A TIFF output") - parser.add_option("-k", "--kml", dest='kml', action='store_true', - help="Write A KML output") - parser.add_option("-l", "--level", dest='level', metavar='LEVEL', default=None, - help="Level at which to log ") - parser.add_option("--limit", dest='limit', metavar='NUM', default=0, type='int', - help="Specify a limit on the number of images to process") - (options, args) = parser.parse_args() - - #default to cwd if none provided - outDir = options.outDir or os.getcwd() - if not exists(outDir): - os.makedirs(outDir) - - inputs = [] - paths = args[:] - while paths: - path = paths.pop(0) - if isdir(path): - paths.extend(map(lambda x: join(path, x), os.listdir(path))) - else: - f = cosmoSkyMed(path) - if not f: - f = radarsat2(path) - if not f: - f = terraSAR(path) - if f: - inputs.append(f) - - appName = os.path.abspath(join(split(__file__)[0], './install/bin/ScanSARConverter')) - if 'win32' in sys.platform: - appName += '.exe' - - cmd = [appName] - cmd.extend(['-d', outDir]) - if options.xml: - cmd.append('-x') - if options.nitf: - cmd.append('-n') - if options.tiff: - cmd.append('-t') - if options.kml: - cmd.append('-k') - if options.level: - cmd.extend(['-l', options.level]) - - def process(xml, image): - command = cmd[:] - command.append('%s,%s' % (xml, image)) - print command - p = subprocess.Popen(command).communicate() - - limit = (options.limit > 0 and min(options.limit, len(inputs)) or len(inputs)) - print 'Processing %d files' % limit - for i, (xml, image) in enumerate(inputs): - if i >= limit: - break - process(xml, image) +import sys, os, re, subprocess +from os.path import isdir, join, split, exists + + +def cosmoSkyMed(filename): + path, fname = split(filename) + if re.match(r'CSK.*.MBI.tif', fname): + xmlName = join(path, fname.rsplit('MBI.tif')[0] + 'attribs.xml') + if exists(xmlName): + return (xmlName, filename) + return None + +def radarsat2(filename): + path, fname = split(filename) +# if re.match(r'RS2_.*', split(path)[1]) and re.match(r'imagery_.*.tif', fname): + if re.match(r'imagery_.*.tif', fname): + xmlName = join(path, 'product.xml') + if exists(xmlName): + return (xmlName, filename) + return None + +def terraSAR(filename): + path, fname = split(filename) + if re.match(r'IMAGEDATA', split(path)[1]) and re.match(r'IMAGE_.*.tif', fname): + parDir, xmlName = split(split(path)[0]) + xmlName = join(parDir, xmlName, '%s.xml' % xmlName) + if exists(xmlName): + return (xmlName, filename) + return None + + +if __name__ == '__main__': + from optparse import OptionParser + parser = OptionParser(usage="usage: %prog [options] [path(s)]") + parser.add_option("-d", "--dir", dest='outDir', metavar='DIR', + help="specify the output directory (default=cwd)") + parser.add_option("-x", "--xml", dest='xml', action='store_true', + help="Write An XML output") + parser.add_option("-n", "--nitf", dest='nitf', action='store_true', + help="Write A NITF output") + parser.add_option("-t", "--tiff", dest='tiff', action='store_true', + help="Write A TIFF output") + parser.add_option("-k", "--kml", dest='kml', action='store_true', + help="Write A KML output") + parser.add_option("-l", "--level", dest='level', metavar='LEVEL', default=None, + help="Level at which to log ") + parser.add_option("--limit", dest='limit', metavar='NUM', default=0, type='int', + help="Specify a limit on the number of images to process") + (options, args) = parser.parse_args() + + #default to cwd if none provided + outDir = options.outDir or os.getcwd() + if not exists(outDir): + os.makedirs(outDir) + + inputs = [] + paths = args[:] + while paths: + path = paths.pop(0) + if isdir(path): + paths.extend(map(lambda x: join(path, x), os.listdir(path))) + else: + f = cosmoSkyMed(path) + if not f: + f = radarsat2(path) + if not f: + f = terraSAR(path) + if f: + inputs.append(f) + + appName = os.path.abspath(join(split(__file__)[0], './install/bin/ScanSARConverter')) + if 'win32' in sys.platform: + appName += '.exe' + + cmd = [appName] + cmd.extend(['-d', outDir]) + if options.xml: + cmd.append('-x') + if options.nitf: + cmd.append('-n') + if options.tiff: + cmd.append('-t') + if options.kml: + cmd.append('-k') + if options.level: + cmd.extend(['-l', options.level]) + + def process(xml, image): + command = cmd[:] + command.append('%s,%s' % (xml, image)) + print command + p = subprocess.Popen(command).communicate() + + limit = (options.limit > 0 and min(options.limit, len(inputs)) or len(inputs)) + print 'Processing %d files' % limit + for i, (xml, image) in enumerate(inputs): + if i >= limit: + break + process(xml, image) diff --git a/six.sln b/six.sln index 258b1a0eb1..d4bf483ca1 100644 --- a/six.sln +++ b/six.sln @@ -1,131 +1,131 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c", "externals\nitro\modules\c\nitf-c.vcxproj", "{F06550AD-CFC7-40B8-8727-6C82C69A8982}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c++", "externals\nitro\modules\c++\nitf-c++.vcxproj", "{8F357A19-799E-4971-850E-3F28485C130B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six", "six\modules\c++\six\six.vcxproj", "{62AAD4DD-35BA-41A0-8263-1F4DFD755689}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scene", "six\modules\c++\scene\scene.vcxproj", "{1CFCDE59-6410-4037-95EB-B37D31E10820}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cphd", "six\modules\c++\cphd\cphd.vcxproj", "{01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cphd03", "six\modules\c++\cphd03\cphd03.vcxproj", "{016EF417-E41C-404C-B3B5-34B6CDD94BB3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.sicd", "six\modules\c++\six.sicd\six.sicd.vcxproj", "{34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.sidd", "six\modules\c++\six.sidd\six.sidd.vcxproj", "{DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.convert", "six\modules\c++\six.convert\six.convert.vcxproj", "{DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XML_DATA_CONTENT", "externals\nitro\modules\c\nitf\XML_DATA_CONTENT.vcxproj", "{78849481-D356-4CC7-B182-31C21F857ED1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AD152C2-1F3D-4108-826C-79BA5011874F}" - ProjectSection(SolutionItems) = preProject - six\modules\c++\cpp_pch.h = six\modules\c++\cpp_pch.h - README.md = README.md - ReleaseNotes.md = ReleaseNotes.md - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "check_valid_six", "six\modules\c++\samples\check_valid_six.dir\check_valid_six.vcxproj", "{F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crop_sicd", "six\modules\c++\samples\crop_sicd.dir\crop_sicd.vcxproj", "{7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "csm", "six\projects\csm\csm.vcxproj", "{6E767B43-D1A9-4B02-8D08-42037B7C9262}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{F6888896-E658-414C-90CD-1208FA31A22E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "externals", "externals", "{F033066A-4172-4AC0-96AD-BF5090F713C2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coda-oss", "externals\coda-oss\modules\c++\coda-oss.vcxproj", "{9997E895-5161-4DDF-8F3F-099894CB2F21}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github-workflows", ".github-workflows", "{DB2B94ED-952C-4794-A692-E6B64AA9EE5A}" - ProjectSection(SolutionItems) = preProject - .github\workflows\codeql.yml = .github\workflows\codeql.yml - .github\workflows\frequent_check.yml = .github\workflows\frequent_check.yml - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Debug|x64.ActiveCfg = Debug|x64 - {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Debug|x64.Build.0 = Debug|x64 - {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Release|x64.ActiveCfg = Release|x64 - {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Release|x64.Build.0 = Release|x64 - {8F357A19-799E-4971-850E-3F28485C130B}.Debug|x64.ActiveCfg = Debug|x64 - {8F357A19-799E-4971-850E-3F28485C130B}.Debug|x64.Build.0 = Debug|x64 - {8F357A19-799E-4971-850E-3F28485C130B}.Release|x64.ActiveCfg = Release|x64 - {8F357A19-799E-4971-850E-3F28485C130B}.Release|x64.Build.0 = Release|x64 - {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Debug|x64.ActiveCfg = Debug|x64 - {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Debug|x64.Build.0 = Debug|x64 - {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Release|x64.ActiveCfg = Release|x64 - {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Release|x64.Build.0 = Release|x64 - {1CFCDE59-6410-4037-95EB-B37D31E10820}.Debug|x64.ActiveCfg = Debug|x64 - {1CFCDE59-6410-4037-95EB-B37D31E10820}.Debug|x64.Build.0 = Debug|x64 - {1CFCDE59-6410-4037-95EB-B37D31E10820}.Release|x64.ActiveCfg = Release|x64 - {1CFCDE59-6410-4037-95EB-B37D31E10820}.Release|x64.Build.0 = Release|x64 - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Debug|x64.ActiveCfg = Debug|x64 - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Debug|x64.Build.0 = Debug|x64 - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Release|x64.ActiveCfg = Release|x64 - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Release|x64.Build.0 = Release|x64 - {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Debug|x64.ActiveCfg = Debug|x64 - {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Debug|x64.Build.0 = Debug|x64 - {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Release|x64.ActiveCfg = Release|x64 - {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Release|x64.Build.0 = Release|x64 - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Debug|x64.ActiveCfg = Debug|x64 - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Debug|x64.Build.0 = Debug|x64 - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Release|x64.ActiveCfg = Release|x64 - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Release|x64.Build.0 = Release|x64 - {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Debug|x64.ActiveCfg = Debug|x64 - {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Debug|x64.Build.0 = Debug|x64 - {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Release|x64.ActiveCfg = Release|x64 - {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Release|x64.Build.0 = Release|x64 - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Debug|x64.ActiveCfg = Debug|x64 - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Debug|x64.Build.0 = Debug|x64 - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Release|x64.ActiveCfg = Release|x64 - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Release|x64.Build.0 = Release|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.ActiveCfg = Debug|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.Build.0 = Debug|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.ActiveCfg = Release|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.Build.0 = Release|x64 - {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Debug|x64.ActiveCfg = Debug|x64 - {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Debug|x64.Build.0 = Debug|x64 - {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Release|x64.ActiveCfg = Release|x64 - {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Release|x64.Build.0 = Release|x64 - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Debug|x64.ActiveCfg = Debug|x64 - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Debug|x64.Build.0 = Debug|x64 - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Release|x64.ActiveCfg = Release|x64 - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Release|x64.Build.0 = Release|x64 - {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Debug|x64.ActiveCfg = Debug|x64 - {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Debug|x64.Build.0 = Debug|x64 - {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Release|x64.ActiveCfg = Release|x64 - {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Release|x64.Build.0 = Release|x64 - {F6888896-E658-414C-90CD-1208FA31A22E}.Debug|x64.ActiveCfg = Debug|x64 - {F6888896-E658-414C-90CD-1208FA31A22E}.Debug|x64.Build.0 = Debug|x64 - {F6888896-E658-414C-90CD-1208FA31A22E}.Release|x64.ActiveCfg = Release|x64 - {F6888896-E658-414C-90CD-1208FA31A22E}.Release|x64.Build.0 = Release|x64 - {9997E895-5161-4DDF-8F3F-099894CB2F21}.Debug|x64.ActiveCfg = Debug|x64 - {9997E895-5161-4DDF-8F3F-099894CB2F21}.Debug|x64.Build.0 = Debug|x64 - {9997E895-5161-4DDF-8F3F-099894CB2F21}.Release|x64.ActiveCfg = Release|x64 - {9997E895-5161-4DDF-8F3F-099894CB2F21}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {F06550AD-CFC7-40B8-8727-6C82C69A8982} = {F033066A-4172-4AC0-96AD-BF5090F713C2} - {8F357A19-799E-4971-850E-3F28485C130B} = {F033066A-4172-4AC0-96AD-BF5090F713C2} - {78849481-D356-4CC7-B182-31C21F857ED1} = {F033066A-4172-4AC0-96AD-BF5090F713C2} - {9997E895-5161-4DDF-8F3F-099894CB2F21} = {F033066A-4172-4AC0-96AD-BF5090F713C2} - {DB2B94ED-952C-4794-A692-E6B64AA9EE5A} = {3AD152C2-1F3D-4108-826C-79BA5011874F} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {E20E9FC7-D138-4517-8597-79C1FAC3E28D} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c", "externals\nitro\modules\c\nitf-c.vcxproj", "{F06550AD-CFC7-40B8-8727-6C82C69A8982}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c++", "externals\nitro\modules\c++\nitf-c++.vcxproj", "{8F357A19-799E-4971-850E-3F28485C130B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six", "six\modules\c++\six\six.vcxproj", "{62AAD4DD-35BA-41A0-8263-1F4DFD755689}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scene", "six\modules\c++\scene\scene.vcxproj", "{1CFCDE59-6410-4037-95EB-B37D31E10820}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cphd", "six\modules\c++\cphd\cphd.vcxproj", "{01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cphd03", "six\modules\c++\cphd03\cphd03.vcxproj", "{016EF417-E41C-404C-B3B5-34B6CDD94BB3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.sicd", "six\modules\c++\six.sicd\six.sicd.vcxproj", "{34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.sidd", "six\modules\c++\six.sidd\six.sidd.vcxproj", "{DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.convert", "six\modules\c++\six.convert\six.convert.vcxproj", "{DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XML_DATA_CONTENT", "externals\nitro\modules\c\nitf\XML_DATA_CONTENT.vcxproj", "{78849481-D356-4CC7-B182-31C21F857ED1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AD152C2-1F3D-4108-826C-79BA5011874F}" + ProjectSection(SolutionItems) = preProject + six\modules\c++\cpp_pch.h = six\modules\c++\cpp_pch.h + README.md = README.md + ReleaseNotes.md = ReleaseNotes.md + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "check_valid_six", "six\modules\c++\samples\check_valid_six.dir\check_valid_six.vcxproj", "{F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crop_sicd", "six\modules\c++\samples\crop_sicd.dir\crop_sicd.vcxproj", "{7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "csm", "six\projects\csm\csm.vcxproj", "{6E767B43-D1A9-4B02-8D08-42037B7C9262}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{F6888896-E658-414C-90CD-1208FA31A22E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "externals", "externals", "{F033066A-4172-4AC0-96AD-BF5090F713C2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coda-oss", "externals\coda-oss\modules\c++\coda-oss.vcxproj", "{9997E895-5161-4DDF-8F3F-099894CB2F21}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github-workflows", ".github-workflows", "{DB2B94ED-952C-4794-A692-E6B64AA9EE5A}" + ProjectSection(SolutionItems) = preProject + .github\workflows\codeql.yml = .github\workflows\codeql.yml + .github\workflows\frequent_check.yml = .github\workflows\frequent_check.yml + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Debug|x64.ActiveCfg = Debug|x64 + {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Debug|x64.Build.0 = Debug|x64 + {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Release|x64.ActiveCfg = Release|x64 + {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Release|x64.Build.0 = Release|x64 + {8F357A19-799E-4971-850E-3F28485C130B}.Debug|x64.ActiveCfg = Debug|x64 + {8F357A19-799E-4971-850E-3F28485C130B}.Debug|x64.Build.0 = Debug|x64 + {8F357A19-799E-4971-850E-3F28485C130B}.Release|x64.ActiveCfg = Release|x64 + {8F357A19-799E-4971-850E-3F28485C130B}.Release|x64.Build.0 = Release|x64 + {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Debug|x64.ActiveCfg = Debug|x64 + {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Debug|x64.Build.0 = Debug|x64 + {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Release|x64.ActiveCfg = Release|x64 + {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Release|x64.Build.0 = Release|x64 + {1CFCDE59-6410-4037-95EB-B37D31E10820}.Debug|x64.ActiveCfg = Debug|x64 + {1CFCDE59-6410-4037-95EB-B37D31E10820}.Debug|x64.Build.0 = Debug|x64 + {1CFCDE59-6410-4037-95EB-B37D31E10820}.Release|x64.ActiveCfg = Release|x64 + {1CFCDE59-6410-4037-95EB-B37D31E10820}.Release|x64.Build.0 = Release|x64 + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Debug|x64.ActiveCfg = Debug|x64 + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Debug|x64.Build.0 = Debug|x64 + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Release|x64.ActiveCfg = Release|x64 + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Release|x64.Build.0 = Release|x64 + {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Debug|x64.ActiveCfg = Debug|x64 + {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Debug|x64.Build.0 = Debug|x64 + {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Release|x64.ActiveCfg = Release|x64 + {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Release|x64.Build.0 = Release|x64 + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Debug|x64.ActiveCfg = Debug|x64 + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Debug|x64.Build.0 = Debug|x64 + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Release|x64.ActiveCfg = Release|x64 + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Release|x64.Build.0 = Release|x64 + {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Debug|x64.ActiveCfg = Debug|x64 + {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Debug|x64.Build.0 = Debug|x64 + {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Release|x64.ActiveCfg = Release|x64 + {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Release|x64.Build.0 = Release|x64 + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Debug|x64.ActiveCfg = Debug|x64 + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Debug|x64.Build.0 = Debug|x64 + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Release|x64.ActiveCfg = Release|x64 + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Release|x64.Build.0 = Release|x64 + {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.ActiveCfg = Debug|x64 + {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.Build.0 = Debug|x64 + {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.ActiveCfg = Release|x64 + {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.Build.0 = Release|x64 + {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Debug|x64.ActiveCfg = Debug|x64 + {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Debug|x64.Build.0 = Debug|x64 + {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Release|x64.ActiveCfg = Release|x64 + {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Release|x64.Build.0 = Release|x64 + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Debug|x64.ActiveCfg = Debug|x64 + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Debug|x64.Build.0 = Debug|x64 + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Release|x64.ActiveCfg = Release|x64 + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Release|x64.Build.0 = Release|x64 + {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Debug|x64.ActiveCfg = Debug|x64 + {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Debug|x64.Build.0 = Debug|x64 + {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Release|x64.ActiveCfg = Release|x64 + {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Release|x64.Build.0 = Release|x64 + {F6888896-E658-414C-90CD-1208FA31A22E}.Debug|x64.ActiveCfg = Debug|x64 + {F6888896-E658-414C-90CD-1208FA31A22E}.Debug|x64.Build.0 = Debug|x64 + {F6888896-E658-414C-90CD-1208FA31A22E}.Release|x64.ActiveCfg = Release|x64 + {F6888896-E658-414C-90CD-1208FA31A22E}.Release|x64.Build.0 = Release|x64 + {9997E895-5161-4DDF-8F3F-099894CB2F21}.Debug|x64.ActiveCfg = Debug|x64 + {9997E895-5161-4DDF-8F3F-099894CB2F21}.Debug|x64.Build.0 = Debug|x64 + {9997E895-5161-4DDF-8F3F-099894CB2F21}.Release|x64.ActiveCfg = Release|x64 + {9997E895-5161-4DDF-8F3F-099894CB2F21}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {F06550AD-CFC7-40B8-8727-6C82C69A8982} = {F033066A-4172-4AC0-96AD-BF5090F713C2} + {8F357A19-799E-4971-850E-3F28485C130B} = {F033066A-4172-4AC0-96AD-BF5090F713C2} + {78849481-D356-4CC7-B182-31C21F857ED1} = {F033066A-4172-4AC0-96AD-BF5090F713C2} + {9997E895-5161-4DDF-8F3F-099894CB2F21} = {F033066A-4172-4AC0-96AD-BF5090F713C2} + {DB2B94ED-952C-4794-A692-E6B64AA9EE5A} = {3AD152C2-1F3D-4108-826C-79BA5011874F} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E20E9FC7-D138-4517-8597-79C1FAC3E28D} + EndGlobalSection +EndGlobal diff --git a/six/modules/c++/cphd/cphd.vcxproj b/six/modules/c++/cphd/cphd.vcxproj index fc081ca05d..45aaa5e6a5 100644 --- a/six/modules/c++/cphd/cphd.vcxproj +++ b/six/modules/c++/cphd/cphd.vcxproj @@ -1,183 +1,183 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..\scene\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\six.sicd\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..\scene\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\six.sicd\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - {8f357a19-799e-4971-850e-3f28485c130b} - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..\scene\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\six.sicd\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..\scene\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\six.sicd\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + {8f357a19-799e-4971-850e-3f28485c130b} + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/six/modules/c++/cphd/cphd.vcxproj.filters b/six/modules/c++/cphd/cphd.vcxproj.filters index 0eace9d1af..5c6354173b 100644 --- a/six/modules/c++/cphd/cphd.vcxproj.filters +++ b/six/modules/c++/cphd/cphd.vcxproj.filters @@ -1,195 +1,195 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + \ No newline at end of file diff --git a/six/modules/c++/cphd/include/cphd/Antenna.h b/six/modules/c++/cphd/include/cphd/Antenna.h index 300936e05a..0e7a29b7e6 100644 --- a/six/modules/c++/cphd/include/cphd/Antenna.h +++ b/six/modules/c++/cphd/include/cphd/Antenna.h @@ -1,374 +1,374 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#pragma once -#ifndef SIX_cphd_Antenna_h_INCLUDED_ -#define SIX_cphd_Antenna_h_INCLUDED_ - -#include - -#include -#include -#include - -#include -#include - -#include -#include - -namespace cphd -{ -/* - * \struct AntCoordFrame - * \brief CPHD Antenna Coordinate Frame parameter - * - * Unit vectors that describe the orientation of an - * Antenna Coordinate Frame as a function of time. - * AntCoordFrame used by CPHD, representing the tag - * . - */ -struct AntCoordFrame final -{ - //! Constructor - AntCoordFrame(); - - //! Equality operators - bool operator==(const AntCoordFrame& other) const - { - return (identifier == other.identifier) - && (xAxisPoly == other.xAxisPoly) - && (yAxisPoly == other.yAxisPoly) - && (useACFPVP == other.useACFPVP); - } - bool operator!=(const AntCoordFrame& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this ACF - //! (ACF_ID) - std::string identifier; - - //!Antenna coordinate frame X-Axis unit vector in - //! ECF coordinates as a function time (sec). - PolyXYZ xAxisPoly; - - //!Antenna coordinate frame Y-Axis unit vector in - //! ECF coordinates as a function time (sec). - PolyXYZ yAxisPoly; - - //!Indicates the provided ACF PVP arrays provide a more accurate description the ACF orientation vs.time. - six::XsElement_minOccurs0 useACFPVP{ "UseACFPVP" }; // new in CPHD 1.1.0 -}; - -/* - * \struct AntPhaseCenter - * \brief Parameters that describe each Antenna Phase Center. - * - * AntPhaseCenter used by CPHD, representing the tag - * . - */ -struct AntPhaseCenter -{ - //! Constructor - AntPhaseCenter(); - - //! Equality operators - bool operator==(const AntPhaseCenter& other) const - { - return identifier == other.identifier && - acfId == other.acfId && apcXYZ == other.apcXYZ; - } - bool operator!=(const AntPhaseCenter& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this APC - //! (APC_ID). - std::string identifier; - - //! Identifier of Antenna Coordinate Frame used for - //! computing the antenna gain and phase patterns - std::string acfId; - - //! The APC location in the ACF XYZ coordinate - //! frame - Vector3 apcXYZ; -}; - -/* - * \struct AntPattern - * \brief CPHD Antenna Pattern parameter - * - * Parameter set that defines each Antenna Pattern - * as a function of time. - * AntPattern used by CPHD, representing the tag - * . - */ -struct AntPattern final -{ - /* - * \struct EBFreqShiftSF - * \brief Scale factors used compute the EB shift vs. frequency - * - * (Optional) Scale factors used compute the EB shift vs. frequency in DCX and DCY. - * - */ - struct EBFreqShiftSF final - { - bool operator==(const EBFreqShiftSF& other) const - { - return (dcxsf == other.dcxsf) - && (dcysf == other.dcysf); - } - bool operator!=(const EBFreqShiftSF& other) const - { - return !((*this) == other); - } - - //! Scale factor used to compute the ML dilation factor in DCX vs. frequency. - six::XsElement dcxsf{ "DCXSF" }; - - //! Scale factor used to compute the ML dilation factor in DCY vs. frequency. - six::XsElement dcysf{ "DCYSF" }; - }; - - /* - * \struct MLFreqDilationSF - * \brief Scale factors used to compute the array pattern - * - * (Optional) Scale factors used to compute the array pattern mainlobe dilation vs. frequency in DCX and DCY. - * - */ - struct MLFreqDilationSF final - { - bool operator==(const MLFreqDilationSF& other) const - { - return (dcxsf == other.dcxsf) - && (dcysf == other.dcysf); - } - bool operator!=(const MLFreqDilationSF& other) const - { - return !((*this) == other); - } - - //! Scale factor used to compute the ML dilation factor in DCX vs. frequency. - six::XsElement dcxsf{ "DCXSF" }; - - //! Scale factor used to compute the ML dilation factor in DCY vs. frequency. - six::XsElement dcysf{ "DCYSF" }; - }; - - /* - * \struct AntPolRef - * \brief Polarization parameters - * - * (Optional) Polarization parameters for the EB steered to mechanical boresight - * - */ - struct AntPolRef final - { - bool operator==(const AntPolRef& other) const - { - return (ampX == other.ampX) - && (ampY == other.ampY) - && (phaseY == other.phaseY); - } - bool operator!=(const AntPolRef& other) const - { - return !((*this) == other); - } - - //! E-field relative amplitude in ACF X direction at f = f_0. - six::XsElement ampX{ "AmpX" }; - - //! E-field relative amplitude in ACY direction at f = f_0. - six::XsElement ampY{ "AmpY" }; - - //! Relative phase of the Y E-field relative to the X E-field at f = f_0. - six::XsElement phaseY{ "PhaseY" }; - }; - - /* - * \struct GainPhaseArray - * \brief Gain Phase Array parameter - * - * (Optional) Parameters that identify 2-D sampled Grain & Phase patterns at - * a single frequency value. - * - */ - struct GainPhaseArray - { - //! Constructor - GainPhaseArray(); - - //! Equality operators - bool operator==(const GainPhaseArray& other) const - { - return freq == other.freq && arrayId == other.arrayId && - elementId == other.elementId; - } - bool operator!=(const GainPhaseArray& other) const - { - return !((*this) == other); - } - - //! Frequency value for which the sampled Array & - //! Element pattern(s) are provided. - double freq; - - //! Support Array identifier of the sampled - //! Gain/Phase of the Array at RefFrequency - std::string arrayId; - - //! (Optional) Support Array identifier of the sampled - //! Gain/Phase of the Element at RefFrequency - std::string elementId; - }; - - //! Default constructor - AntPattern(); - - //! Equality operators - bool operator==(const AntPattern& other) const - { - return identifier == other.identifier && - freqZero == other.freqZero && gainZero == other.gainZero && - ebFreqShift == other.ebFreqShift && - mlFreqDilation == other.mlFreqDilation && - gainBSPoly == other.gainBSPoly && eb == other.eb && - array == other.array && element == other.element && - gainPhaseArray == other.gainPhaseArray; - } - bool operator!=(const AntPattern& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this Antenna - //! Pattern (APAT_ID). - std::string identifier; - - //! The reference frequency (f_0) value for which - //! the Electrical Boresight and array pattern - //! polynomials are computed. - double freqZero; - - //! (Optional) The reference antenna gain (G_0) at zero steering - //! angle at the reference frequency (f_0) - double gainZero; - - //! (Optional) Parameter to indicate the EB steering direction - //! shifts with frequency. - six::BooleanType ebFreqShift; - - //! (Optional) Parameter to indicate the mainlobe width varies - //! with frequency. - six::BooleanType mlFreqDilation; - - //! (Optional) Gain polynomial (dB) vs. frequency for the array - //! pattern at boresight. Gain relative to gain at f_0. - //! Poly1D gainBSPoly; - Poly1D gainBSPoly; - - //! (Optional) Scale factors used compute the EB shift vs. frequency - six::XsElement_minOccurs0 ebFreqShiftSF{ "EBFreqShiftSF" }; // new in CPHD 1.1.0 - - //! (Optional) Scale factors used to compute the array pattern - six::XsElement_minOccurs0 mlFreqDilationSF{ "MLFreqDilationSF" }; // new in CPHD 1.1.0 - - //! (Optional) Polarization parameters for the EB steered to mechanical boresight - six::XsElement_minOccurs0 antPolRef{ "AntPolRef" }; // new in CPHD 1.1.0 - - //! The Electrical Boresight steering direction versus - //! time. Defines array pattern pointing direction - six::sicd::ElectricalBoresight eb; - - //! Array Pattern polynomials that describe the - //! mainlobe gain and phase patterns. Patterns - //! defined at f = f_0 - six::sicd::GainAndPhasePolys array; - - //! Element Pattern polynomials that describe the - //! gain and phase patterns - six::sicd::GainAndPhasePolys element; - - //! Parameters that identify 2-D sampled Gain & - //! Phase patterns at single frequency value. - std::vector gainPhaseArray; -}; - -/* - * \struct Antenna - * \brief (Optional) Antenna parameters - * - * Parameters that describe the transmit and - * receive antennas used to collect the signal array. - * See section 8.2 - */ -struct Antenna -{ - //! Default constructor - Antenna(); - - //! Equality operators - bool operator==(const Antenna& other) const - { - return antCoordFrame == other.antCoordFrame && - antPhaseCenter == other.antPhaseCenter && - antPattern == other.antPattern; - } - bool operator!=(const Antenna& other) const - { - return !((*this) == other); - } - - //! Unit vectors that describe the orientation of an - //! Antenna Coordinate Frame (ACF) as function of - //! time. - std::vector antCoordFrame; - - //! Parameters that describe each Antenna Phase - //! Center (APC). Parameter set repeated for each - //! APC - std::vector antPhaseCenter; - - //! Parameter set that defines each Antenna Pattern - //! as function time. Parameters set repeated for - //! each Antenna Pattern - std::vector antPattern; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const AntCoordFrame& a); -std::ostream& operator<< (std::ostream& os, const AntPhaseCenter& a); -std::ostream& operator<< (std::ostream& os, const AntPattern::EBFreqShiftSF&); -std::ostream& operator<< (std::ostream& os, const AntPattern::AntPolRef&); -std::ostream& operator<< (std::ostream& os, const AntPattern::MLFreqDilationSF&); -std::ostream& operator<< (std::ostream& os, const AntPattern::GainPhaseArray& g); -std::ostream& operator<< (std::ostream& os, const AntPattern& a); -std::ostream& operator<< (std::ostream& os, const Antenna& a); -} - -#endif // SIX_cphd_Antenna_h_INCLUDED_ +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#pragma once +#ifndef SIX_cphd_Antenna_h_INCLUDED_ +#define SIX_cphd_Antenna_h_INCLUDED_ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +namespace cphd +{ +/* + * \struct AntCoordFrame + * \brief CPHD Antenna Coordinate Frame parameter + * + * Unit vectors that describe the orientation of an + * Antenna Coordinate Frame as a function of time. + * AntCoordFrame used by CPHD, representing the tag + * . + */ +struct AntCoordFrame final +{ + //! Constructor + AntCoordFrame(); + + //! Equality operators + bool operator==(const AntCoordFrame& other) const + { + return (identifier == other.identifier) + && (xAxisPoly == other.xAxisPoly) + && (yAxisPoly == other.yAxisPoly) + && (useACFPVP == other.useACFPVP); + } + bool operator!=(const AntCoordFrame& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this ACF + //! (ACF_ID) + std::string identifier; + + //!Antenna coordinate frame X-Axis unit vector in + //! ECF coordinates as a function time (sec). + PolyXYZ xAxisPoly; + + //!Antenna coordinate frame Y-Axis unit vector in + //! ECF coordinates as a function time (sec). + PolyXYZ yAxisPoly; + + //!Indicates the provided ACF PVP arrays provide a more accurate description the ACF orientation vs.time. + six::XsElement_minOccurs0 useACFPVP{ "UseACFPVP" }; // new in CPHD 1.1.0 +}; + +/* + * \struct AntPhaseCenter + * \brief Parameters that describe each Antenna Phase Center. + * + * AntPhaseCenter used by CPHD, representing the tag + * . + */ +struct AntPhaseCenter +{ + //! Constructor + AntPhaseCenter(); + + //! Equality operators + bool operator==(const AntPhaseCenter& other) const + { + return identifier == other.identifier && + acfId == other.acfId && apcXYZ == other.apcXYZ; + } + bool operator!=(const AntPhaseCenter& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this APC + //! (APC_ID). + std::string identifier; + + //! Identifier of Antenna Coordinate Frame used for + //! computing the antenna gain and phase patterns + std::string acfId; + + //! The APC location in the ACF XYZ coordinate + //! frame + Vector3 apcXYZ; +}; + +/* + * \struct AntPattern + * \brief CPHD Antenna Pattern parameter + * + * Parameter set that defines each Antenna Pattern + * as a function of time. + * AntPattern used by CPHD, representing the tag + * . + */ +struct AntPattern final +{ + /* + * \struct EBFreqShiftSF + * \brief Scale factors used compute the EB shift vs. frequency + * + * (Optional) Scale factors used compute the EB shift vs. frequency in DCX and DCY. + * + */ + struct EBFreqShiftSF final + { + bool operator==(const EBFreqShiftSF& other) const + { + return (dcxsf == other.dcxsf) + && (dcysf == other.dcysf); + } + bool operator!=(const EBFreqShiftSF& other) const + { + return !((*this) == other); + } + + //! Scale factor used to compute the ML dilation factor in DCX vs. frequency. + six::XsElement dcxsf{ "DCXSF" }; + + //! Scale factor used to compute the ML dilation factor in DCY vs. frequency. + six::XsElement dcysf{ "DCYSF" }; + }; + + /* + * \struct MLFreqDilationSF + * \brief Scale factors used to compute the array pattern + * + * (Optional) Scale factors used to compute the array pattern mainlobe dilation vs. frequency in DCX and DCY. + * + */ + struct MLFreqDilationSF final + { + bool operator==(const MLFreqDilationSF& other) const + { + return (dcxsf == other.dcxsf) + && (dcysf == other.dcysf); + } + bool operator!=(const MLFreqDilationSF& other) const + { + return !((*this) == other); + } + + //! Scale factor used to compute the ML dilation factor in DCX vs. frequency. + six::XsElement dcxsf{ "DCXSF" }; + + //! Scale factor used to compute the ML dilation factor in DCY vs. frequency. + six::XsElement dcysf{ "DCYSF" }; + }; + + /* + * \struct AntPolRef + * \brief Polarization parameters + * + * (Optional) Polarization parameters for the EB steered to mechanical boresight + * + */ + struct AntPolRef final + { + bool operator==(const AntPolRef& other) const + { + return (ampX == other.ampX) + && (ampY == other.ampY) + && (phaseY == other.phaseY); + } + bool operator!=(const AntPolRef& other) const + { + return !((*this) == other); + } + + //! E-field relative amplitude in ACF X direction at f = f_0. + six::XsElement ampX{ "AmpX" }; + + //! E-field relative amplitude in ACY direction at f = f_0. + six::XsElement ampY{ "AmpY" }; + + //! Relative phase of the Y E-field relative to the X E-field at f = f_0. + six::XsElement phaseY{ "PhaseY" }; + }; + + /* + * \struct GainPhaseArray + * \brief Gain Phase Array parameter + * + * (Optional) Parameters that identify 2-D sampled Grain & Phase patterns at + * a single frequency value. + * + */ + struct GainPhaseArray + { + //! Constructor + GainPhaseArray(); + + //! Equality operators + bool operator==(const GainPhaseArray& other) const + { + return freq == other.freq && arrayId == other.arrayId && + elementId == other.elementId; + } + bool operator!=(const GainPhaseArray& other) const + { + return !((*this) == other); + } + + //! Frequency value for which the sampled Array & + //! Element pattern(s) are provided. + double freq; + + //! Support Array identifier of the sampled + //! Gain/Phase of the Array at RefFrequency + std::string arrayId; + + //! (Optional) Support Array identifier of the sampled + //! Gain/Phase of the Element at RefFrequency + std::string elementId; + }; + + //! Default constructor + AntPattern(); + + //! Equality operators + bool operator==(const AntPattern& other) const + { + return identifier == other.identifier && + freqZero == other.freqZero && gainZero == other.gainZero && + ebFreqShift == other.ebFreqShift && + mlFreqDilation == other.mlFreqDilation && + gainBSPoly == other.gainBSPoly && eb == other.eb && + array == other.array && element == other.element && + gainPhaseArray == other.gainPhaseArray; + } + bool operator!=(const AntPattern& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this Antenna + //! Pattern (APAT_ID). + std::string identifier; + + //! The reference frequency (f_0) value for which + //! the Electrical Boresight and array pattern + //! polynomials are computed. + double freqZero; + + //! (Optional) The reference antenna gain (G_0) at zero steering + //! angle at the reference frequency (f_0) + double gainZero; + + //! (Optional) Parameter to indicate the EB steering direction + //! shifts with frequency. + six::BooleanType ebFreqShift; + + //! (Optional) Parameter to indicate the mainlobe width varies + //! with frequency. + six::BooleanType mlFreqDilation; + + //! (Optional) Gain polynomial (dB) vs. frequency for the array + //! pattern at boresight. Gain relative to gain at f_0. + //! Poly1D gainBSPoly; + Poly1D gainBSPoly; + + //! (Optional) Scale factors used compute the EB shift vs. frequency + six::XsElement_minOccurs0 ebFreqShiftSF{ "EBFreqShiftSF" }; // new in CPHD 1.1.0 + + //! (Optional) Scale factors used to compute the array pattern + six::XsElement_minOccurs0 mlFreqDilationSF{ "MLFreqDilationSF" }; // new in CPHD 1.1.0 + + //! (Optional) Polarization parameters for the EB steered to mechanical boresight + six::XsElement_minOccurs0 antPolRef{ "AntPolRef" }; // new in CPHD 1.1.0 + + //! The Electrical Boresight steering direction versus + //! time. Defines array pattern pointing direction + six::sicd::ElectricalBoresight eb; + + //! Array Pattern polynomials that describe the + //! mainlobe gain and phase patterns. Patterns + //! defined at f = f_0 + six::sicd::GainAndPhasePolys array; + + //! Element Pattern polynomials that describe the + //! gain and phase patterns + six::sicd::GainAndPhasePolys element; + + //! Parameters that identify 2-D sampled Gain & + //! Phase patterns at single frequency value. + std::vector gainPhaseArray; +}; + +/* + * \struct Antenna + * \brief (Optional) Antenna parameters + * + * Parameters that describe the transmit and + * receive antennas used to collect the signal array. + * See section 8.2 + */ +struct Antenna +{ + //! Default constructor + Antenna(); + + //! Equality operators + bool operator==(const Antenna& other) const + { + return antCoordFrame == other.antCoordFrame && + antPhaseCenter == other.antPhaseCenter && + antPattern == other.antPattern; + } + bool operator!=(const Antenna& other) const + { + return !((*this) == other); + } + + //! Unit vectors that describe the orientation of an + //! Antenna Coordinate Frame (ACF) as function of + //! time. + std::vector antCoordFrame; + + //! Parameters that describe each Antenna Phase + //! Center (APC). Parameter set repeated for each + //! APC + std::vector antPhaseCenter; + + //! Parameter set that defines each Antenna Pattern + //! as function time. Parameters set repeated for + //! each Antenna Pattern + std::vector antPattern; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const AntCoordFrame& a); +std::ostream& operator<< (std::ostream& os, const AntPhaseCenter& a); +std::ostream& operator<< (std::ostream& os, const AntPattern::EBFreqShiftSF&); +std::ostream& operator<< (std::ostream& os, const AntPattern::AntPolRef&); +std::ostream& operator<< (std::ostream& os, const AntPattern::MLFreqDilationSF&); +std::ostream& operator<< (std::ostream& os, const AntPattern::GainPhaseArray& g); +std::ostream& operator<< (std::ostream& os, const AntPattern& a); +std::ostream& operator<< (std::ostream& os, const Antenna& a); +} + +#endif // SIX_cphd_Antenna_h_INCLUDED_ diff --git a/six/modules/c++/cphd/include/cphd/Dwell.h b/six/modules/c++/cphd/include/cphd/Dwell.h index 44c2537371..86092806f6 100644 --- a/six/modules/c++/cphd/include/cphd/Dwell.h +++ b/six/modules/c++/cphd/include/cphd/Dwell.h @@ -1,128 +1,128 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_DWELL_H__ -#define __CPHD_DWELL_H__ - -#include -#include - -#include -#include - -#include - -namespace cphd -{ - -/* - * \struct DwellTime - * - * \brief Dwell Time Polynomial - */ -struct DwellTime -{ - //! Constructor - DwellTime(); - - //! Equality operators - bool operator==(const DwellTime& other) const - { - return identifier == other.identifier && dwellTimePoly == other.dwellTimePoly; - } - bool operator!=(const DwellTime& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this Dwell Time polynomial (Dwell_ID) - std::string identifier; - - //! Polynomial that yields Dwell Time as a function of IAX and IAY - Poly2D dwellTimePoly; -}; - -/* - * \struct COD - * - * \brief Center of Dwell Time Polynomial - */ -struct COD -{ - //! Constructor - COD(); - - //! Equality operators - bool operator==(const COD& other) const - { - return identifier == other.identifier && codTimePoly == other.codTimePoly; - } - bool operator!=(const COD& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this COD Time polynomial (COD_ID) - std::string identifier; - - //! Polynomial that yields COD Time as a function of IAX and IAY - Poly2D codTimePoly; -}; - -/* - * \struct Dwell - * - * \brief Dwell Time parameters - * - * Parameters that specify the dwell time supported by the signal arrays - * contained in the CPHD product - * See section 7.3 - */ -struct Dwell -{ - //! Constructor - Dwell(); - - // Equality operator - bool operator==(const Dwell& other) const - { - return cod == other.cod && dtime == other.dtime; - } - bool operator!=(const Dwell& other) const - { - return !((*this) == other); - } - - //! Center of Dwell (COD) Time Polynomial - std::vector cod; - - //! Dwell Time Polynomial - std::vector dtime; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const DwellTime& d); -std::ostream& operator<< (std::ostream& os, const COD& c); -std::ostream& operator<< (std::ostream& os, const Dwell& d); -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_DWELL_H__ +#define __CPHD_DWELL_H__ + +#include +#include + +#include +#include + +#include + +namespace cphd +{ + +/* + * \struct DwellTime + * + * \brief Dwell Time Polynomial + */ +struct DwellTime +{ + //! Constructor + DwellTime(); + + //! Equality operators + bool operator==(const DwellTime& other) const + { + return identifier == other.identifier && dwellTimePoly == other.dwellTimePoly; + } + bool operator!=(const DwellTime& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this Dwell Time polynomial (Dwell_ID) + std::string identifier; + + //! Polynomial that yields Dwell Time as a function of IAX and IAY + Poly2D dwellTimePoly; +}; + +/* + * \struct COD + * + * \brief Center of Dwell Time Polynomial + */ +struct COD +{ + //! Constructor + COD(); + + //! Equality operators + bool operator==(const COD& other) const + { + return identifier == other.identifier && codTimePoly == other.codTimePoly; + } + bool operator!=(const COD& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this COD Time polynomial (COD_ID) + std::string identifier; + + //! Polynomial that yields COD Time as a function of IAX and IAY + Poly2D codTimePoly; +}; + +/* + * \struct Dwell + * + * \brief Dwell Time parameters + * + * Parameters that specify the dwell time supported by the signal arrays + * contained in the CPHD product + * See section 7.3 + */ +struct Dwell +{ + //! Constructor + Dwell(); + + // Equality operator + bool operator==(const Dwell& other) const + { + return cod == other.cod && dtime == other.dtime; + } + bool operator!=(const Dwell& other) const + { + return !((*this) == other); + } + + //! Center of Dwell (COD) Time Polynomial + std::vector cod; + + //! Dwell Time Polynomial + std::vector dtime; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const DwellTime& d); +std::ostream& operator<< (std::ostream& os, const COD& c); +std::ostream& operator<< (std::ostream& os, const Dwell& d); +} + +#endif diff --git a/six/modules/c++/cphd/include/cphd/ErrorParameters.h b/six/modules/c++/cphd/include/cphd/ErrorParameters.h index 0f4be81343..6bd94d91c7 100644 --- a/six/modules/c++/cphd/include/cphd/ErrorParameters.h +++ b/six/modules/c++/cphd/include/cphd/ErrorParameters.h @@ -1,240 +1,240 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#pragma once -#ifndef SIX_cphd_ErrorParameters_h_INCLUDED_ -#define SIX_cphd_ErrorParameters_h_INCLUDED_ - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -namespace cphd -{ - -/* - * \struct ErrorParameters - * - * \brief Describes error parameters - * - * (Optional) Parameters that describe the statistics of errors - * in measured or estimated parameters that describe - * the collection - */ -struct ErrorParameters -{ - /* - * \struct Monostatic - * - * \brief (Conditional) Parameters for CollectType = "MONOSTATIC" - */ - struct Monostatic - { - /* - * \struct RadarSensor - * - * \brief Position and velocity error statistics for the - * sensor platform - */ - struct RadarSensor - { - //! Constructor - RadarSensor(); - - //! Equality operators - bool operator==(const RadarSensor& other) const - { - return rangeBias == other.rangeBias && - clockFreqSF == other.clockFreqSF && - collectionStartTime == other.collectionStartTime && - rangeBiasDecorr == other.rangeBiasDecorr; - } - bool operator!=(const RadarSensor& other) const - { - return !((*this) == other); - } - - //! Range bias error standard deviation. - double rangeBias; - - //! (Optional) Payload clock frequency scale factor standard deviation - double clockFreqSF; - - //! (Optional) Collection Start time error standard deviation - double collectionStartTime; - - //! (Optional) Range Bias error decorrelation function - mem::ScopedCopyablePtr rangeBiasDecorr; - }; - - //! Equality operators - bool operator==(const Monostatic& other) const - { - return posVelErr == other.posVelErr && - radarSensor == other.radarSensor && - tropoError == other.tropoError && - ionoError == other.ionoError && - parameter == other.parameter; - } - bool operator!=(const Monostatic& other) const - { - return !((*this) == other); - } - - //! Position and velocity error statistics for the - //! Transmit platform. - six::PosVelError posVelErr; - - //! Radar sensor error statistics - RadarSensor radarSensor; - - //! (Optional) Error parameters related to the Troposphere - mem::ScopedCopyablePtr tropoError; - - //! (Optional) Error parameters related to the Ionosphere - mem::ScopedCopyablePtr ionoError; - - //! (Optional) Additional error parameters to be added for - //! Monostatic collections - six::ParameterCollection parameter; - }; - - /* - * \struct Bistatic - * - * \brief (Conditional) Parameters for CollectType = "BISTATIC" - */ - struct Bistatic final - { - /* - * \struct RadarSensor - * - * \brief Error statistics for the Transmit platform - */ - struct RadarSensor final - { - //! Constructor - RadarSensor(); - - //! Equality operators - bool operator==(const RadarSensor& other) const - { - return (delayBias == other.delayBias) - && (clockFreqSF == other.clockFreqSF) - && (collectionStartTime == other.collectionStartTime); - } - bool operator!=(const RadarSensor& other) const - { - return !((*this) == other); - } - - //! Transmit time delay bias error standard deviation - six::XsElement_minOccurs0 delayBias{ "DelayBias" }; // new in CPHD 1.1.0 - - //! (Optional) Payload clock frequency scale factor standard deviation - double clockFreqSF; - - //! Collection Start time error standard deviation. - double collectionStartTime; - }; - - /* - * \struct Platform - * - * \brief Error statisitcs of platforms - */ - struct Platform - { - //! Equality operators - bool operator==(const Platform& other) const - { - return posVelErr == other.posVelErr && - radarSensor == other.radarSensor; - } - bool operator!=(const Platform& other) const - { - return !((*this) == other); - } - - //! Position and velocity error statistics - six::PosVelError posVelErr; - - //! Transmit sensor error statistics - RadarSensor radarSensor; - }; - - //! Equality operators - bool operator==(const Bistatic& other) const - { - return txPlatform == other.txPlatform && - rcvPlatform == other.rcvPlatform && - parameter == other.parameter; - } - bool operator!=(const Bistatic& other) const - { - return !((*this) == other); - } - - //! Error statistics for the Transmit platform - Platform txPlatform; - - //! Error statistics for the Receive Only platform. - Platform rcvPlatform; - - //! Additional error parameters to be added for - //! Bistatic collections - six::ParameterCollection parameter; - }; - - //! Equality operators - bool operator==(const ErrorParameters& other) const - { - return monostatic == other.monostatic && - bistatic == other.bistatic; - } - bool operator!=(const ErrorParameters& other) const - { - return !((*this) == other); - } - - //! (Conditional) Parameters for CollectType = "MONOSTATIC" - mem::ScopedCopyablePtr monostatic; - - //! (Conditional) Parameters for CollectType = "BISTATIC" - mem::ScopedCopyablePtr bistatic; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const six::PosVelError& p); -std::ostream& operator<< (std::ostream& os, const ErrorParameters& e); -} - -#endif // SIX_cphd_ErrorParameters_h_INCLUDED_ +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#pragma once +#ifndef SIX_cphd_ErrorParameters_h_INCLUDED_ +#define SIX_cphd_ErrorParameters_h_INCLUDED_ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace cphd +{ + +/* + * \struct ErrorParameters + * + * \brief Describes error parameters + * + * (Optional) Parameters that describe the statistics of errors + * in measured or estimated parameters that describe + * the collection + */ +struct ErrorParameters +{ + /* + * \struct Monostatic + * + * \brief (Conditional) Parameters for CollectType = "MONOSTATIC" + */ + struct Monostatic + { + /* + * \struct RadarSensor + * + * \brief Position and velocity error statistics for the + * sensor platform + */ + struct RadarSensor + { + //! Constructor + RadarSensor(); + + //! Equality operators + bool operator==(const RadarSensor& other) const + { + return rangeBias == other.rangeBias && + clockFreqSF == other.clockFreqSF && + collectionStartTime == other.collectionStartTime && + rangeBiasDecorr == other.rangeBiasDecorr; + } + bool operator!=(const RadarSensor& other) const + { + return !((*this) == other); + } + + //! Range bias error standard deviation. + double rangeBias; + + //! (Optional) Payload clock frequency scale factor standard deviation + double clockFreqSF; + + //! (Optional) Collection Start time error standard deviation + double collectionStartTime; + + //! (Optional) Range Bias error decorrelation function + mem::ScopedCopyablePtr rangeBiasDecorr; + }; + + //! Equality operators + bool operator==(const Monostatic& other) const + { + return posVelErr == other.posVelErr && + radarSensor == other.radarSensor && + tropoError == other.tropoError && + ionoError == other.ionoError && + parameter == other.parameter; + } + bool operator!=(const Monostatic& other) const + { + return !((*this) == other); + } + + //! Position and velocity error statistics for the + //! Transmit platform. + six::PosVelError posVelErr; + + //! Radar sensor error statistics + RadarSensor radarSensor; + + //! (Optional) Error parameters related to the Troposphere + mem::ScopedCopyablePtr tropoError; + + //! (Optional) Error parameters related to the Ionosphere + mem::ScopedCopyablePtr ionoError; + + //! (Optional) Additional error parameters to be added for + //! Monostatic collections + six::ParameterCollection parameter; + }; + + /* + * \struct Bistatic + * + * \brief (Conditional) Parameters for CollectType = "BISTATIC" + */ + struct Bistatic final + { + /* + * \struct RadarSensor + * + * \brief Error statistics for the Transmit platform + */ + struct RadarSensor final + { + //! Constructor + RadarSensor(); + + //! Equality operators + bool operator==(const RadarSensor& other) const + { + return (delayBias == other.delayBias) + && (clockFreqSF == other.clockFreqSF) + && (collectionStartTime == other.collectionStartTime); + } + bool operator!=(const RadarSensor& other) const + { + return !((*this) == other); + } + + //! Transmit time delay bias error standard deviation + six::XsElement_minOccurs0 delayBias{ "DelayBias" }; // new in CPHD 1.1.0 + + //! (Optional) Payload clock frequency scale factor standard deviation + double clockFreqSF; + + //! Collection Start time error standard deviation. + double collectionStartTime; + }; + + /* + * \struct Platform + * + * \brief Error statisitcs of platforms + */ + struct Platform + { + //! Equality operators + bool operator==(const Platform& other) const + { + return posVelErr == other.posVelErr && + radarSensor == other.radarSensor; + } + bool operator!=(const Platform& other) const + { + return !((*this) == other); + } + + //! Position and velocity error statistics + six::PosVelError posVelErr; + + //! Transmit sensor error statistics + RadarSensor radarSensor; + }; + + //! Equality operators + bool operator==(const Bistatic& other) const + { + return txPlatform == other.txPlatform && + rcvPlatform == other.rcvPlatform && + parameter == other.parameter; + } + bool operator!=(const Bistatic& other) const + { + return !((*this) == other); + } + + //! Error statistics for the Transmit platform + Platform txPlatform; + + //! Error statistics for the Receive Only platform. + Platform rcvPlatform; + + //! Additional error parameters to be added for + //! Bistatic collections + six::ParameterCollection parameter; + }; + + //! Equality operators + bool operator==(const ErrorParameters& other) const + { + return monostatic == other.monostatic && + bistatic == other.bistatic; + } + bool operator!=(const ErrorParameters& other) const + { + return !((*this) == other); + } + + //! (Conditional) Parameters for CollectType = "MONOSTATIC" + mem::ScopedCopyablePtr monostatic; + + //! (Conditional) Parameters for CollectType = "BISTATIC" + mem::ScopedCopyablePtr bistatic; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const six::PosVelError& p); +std::ostream& operator<< (std::ostream& os, const ErrorParameters& e); +} + +#endif // SIX_cphd_ErrorParameters_h_INCLUDED_ diff --git a/six/modules/c++/cphd/include/cphd/MetadataBase.h b/six/modules/c++/cphd/include/cphd/MetadataBase.h index abdac611bc..5852887e5f 100644 --- a/six/modules/c++/cphd/include/cphd/MetadataBase.h +++ b/six/modules/c++/cphd/include/cphd/MetadataBase.h @@ -1,111 +1,111 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_METADATA_BASE_H__ -#define __CPHD_METADATA_BASE_H__ - -#include -#include -#include - -namespace cphd -{ -/*! - * \class MetadataBase - * \brief Abstract base class for the CPHD and CPHD03 Metdata objects. - * - * The metadata object is derived for CPHD and CPHD03 - *. This class provides the interface needed - * to interact with the signal block reader Wideband, currently in CPHD - * - */ -struct MetadataBase -{ - //! Default constructor - MetadataBase() - { - } - - //! Destructor - virtual ~MetadataBase() - { - } - - /* - * Getter functions - */ - virtual size_t getNumChannels() const = 0; - virtual size_t getNumVectors(size_t channel) const = 0; // 0-based channel number - virtual size_t getNumSamples(size_t channel) const = 0; // 0-based channel number - virtual size_t getNumBytesPerSample() const = 0; // 2, 4, or 8 bytes/complex sample - - /* - * \func getCompressedSignalSize - * \brief Gets the size of compressed signal array - * if applicable - * - * This function returns default value. Can be overridden - * if required (Ex: CPHD::Metadata) - * - * \return undefined value by default - */ - virtual size_t getCompressedSignalSize(size_t /*channel*/) const - { - return six::Init::undefined(); - } - - /* - * \func isCompressed - * \brief Check if signal data is compressed - * - * This function returns default value false. Function can - * be overridden if required (Ex: CPHD::Metadata) - * - * \return false by default - */ - virtual bool isCompressed() const - { - return false; - } - - /*! - * Get domain type - * FX for frequency domain, - * TOA for time-of-arrival domain - */ - virtual DomainType getDomainType() const = 0; - - //! Is this CPHD formed in the transmit frequency domain? - bool isFX() const - { - return (getDomainType() == cphd::DomainType::FX); - } - - //! Is this CPHD formed in the Time of Arrival domain? - bool isTOA() const - { - return (getDomainType() == cphd::DomainType::TOA); - } -}; -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_METADATA_BASE_H__ +#define __CPHD_METADATA_BASE_H__ + +#include +#include +#include + +namespace cphd +{ +/*! + * \class MetadataBase + * \brief Abstract base class for the CPHD and CPHD03 Metdata objects. + * + * The metadata object is derived for CPHD and CPHD03 + *. This class provides the interface needed + * to interact with the signal block reader Wideband, currently in CPHD + * + */ +struct MetadataBase +{ + //! Default constructor + MetadataBase() + { + } + + //! Destructor + virtual ~MetadataBase() + { + } + + /* + * Getter functions + */ + virtual size_t getNumChannels() const = 0; + virtual size_t getNumVectors(size_t channel) const = 0; // 0-based channel number + virtual size_t getNumSamples(size_t channel) const = 0; // 0-based channel number + virtual size_t getNumBytesPerSample() const = 0; // 2, 4, or 8 bytes/complex sample + + /* + * \func getCompressedSignalSize + * \brief Gets the size of compressed signal array + * if applicable + * + * This function returns default value. Can be overridden + * if required (Ex: CPHD::Metadata) + * + * \return undefined value by default + */ + virtual size_t getCompressedSignalSize(size_t /*channel*/) const + { + return six::Init::undefined(); + } + + /* + * \func isCompressed + * \brief Check if signal data is compressed + * + * This function returns default value false. Function can + * be overridden if required (Ex: CPHD::Metadata) + * + * \return false by default + */ + virtual bool isCompressed() const + { + return false; + } + + /*! + * Get domain type + * FX for frequency domain, + * TOA for time-of-arrival domain + */ + virtual DomainType getDomainType() const = 0; + + //! Is this CPHD formed in the transmit frequency domain? + bool isFX() const + { + return (getDomainType() == cphd::DomainType::FX); + } + + //! Is this CPHD formed in the Time of Arrival domain? + bool isTOA() const + { + return (getDomainType() == cphd::DomainType::TOA); + } +}; +} + +#endif diff --git a/six/modules/c++/cphd/include/cphd/PVP.h b/six/modules/c++/cphd/include/cphd/PVP.h index f19341303c..d302b60a8c 100644 --- a/six/modules/c++/cphd/include/cphd/PVP.h +++ b/six/modules/c++/cphd/include/cphd/PVP.h @@ -1,612 +1,612 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#pragma once -#ifndef SIX_cphd_PVP_h_INCLUDED_ -#define SIX_cphd_PVP_h_INCLUDED_ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "cphd/Types.h" - -namespace cphd -{ - -/*! - * \struct PVPType - * - * \brief Specifies a defined Per Vector Parameter. - * - * Size and Offset specify the size and placement of - * the binary parameter in the set of Per Vector - * parameters provided for each vector. - */ -struct PVPType -{ - static constexpr size_t WORD_BYTE_SIZE = 8; - - /*! - * \func PVPType - * - * \brief Default constructor - */ - PVPType(); - - //! Equality operators - bool operator==(const PVPType& other) const - { - return mSize == other.getSize() && - mOffset == other.getOffset() && - mFormat == other.getFormat(); - } - bool operator!=(const PVPType& other) const - { - return !((*this) == other); - } - - //! Setter Functions - void setOffset(size_t offset) - { - mOffset = offset; - } - void setSize(size_t size) - { - mSize = size; - } - void setFormat(const std::string& format) - { - mFormat = format; - } - - //! Get size - size_t getSize() const - { - return mSize; - } - //! Get size in bytes - size_t getByteSize() const - { - return mSize * WORD_BYTE_SIZE; - } - //! Get offset - size_t getOffset() const - { - return mOffset; - } - - //! Get offset in bytes - size_t getByteOffset() const - { - return mOffset * WORD_BYTE_SIZE; - } - - //! Get format - std::string getFormat() const - { - return mFormat; - } - -protected: - //! Size of parameter - XsPositiveInteger_fixed2 mSize; // txACX{ "TxACX" }; - - //! TxACY PVP Structure - six::XsElement txACY{ "TxACY" }; - - //! TxEB PVP Structure - six::XsElement txEB{ "TxEB" }; -}; - -/*! - * \struct RcvAntenna - * \brief Specify the Receive Antenna orientation and the Steering vector. - * - * Parameters included that specify the Receive Antenna ACF orientation and the EB Steering vector. - * (New in CPHD 1.1.0) - */ -struct RcvAntenna final -{ - bool operator==(const RcvAntenna& other) const - { - return (rcvACX == other.rcvACX) - && (rcvACY == other.rcvACY) - && (rcvEB == other.rcvEB); - } - bool operator!=(const RcvAntenna& other) const - { - return !((*this) == other); - } - - //! RcvACX PVP Structure - six::XsElement rcvACX{ "RcvACX" }; - - //! RcvACY PVP Structure - six::XsElement rcvACY{ "RcvACY" }; - - //! RcvEB PVP Structure - six::XsElement rcvEB{ "RcvEB" }; -}; - -/*! - * \struct Pvp - * - * \brief Structure used to specify the Per Vector - * parameters - * - * Provided for each channel of a given product. - */ -struct Pvp final -{ - /*! - * Transmit time for the center of the transmitted pulse relative to the - * transmit platform Collection Start Time (sec). - */ - PVPType txTime; - - /*! - * Transmit APC position at time txc(v) in Earth Centered Fixed - * (ECF) coordinates (meters). Components in X, Y, Z order. - * 3 8-byte floats required. - */ - PVPType txPos; - - /*! - * Transmit APC velocity at time txc(v) in ECF coordinates - * (meters/sec). - * 3 8-byte floats required. - */ - PVPType txVel; - - /*! - * Receive time for the center of the echo from the srp relative to the - * transmit platform Collection Start Time (sec). Time is the Time of - * Arrival (toa) of the received echo from the srp for the signal - * transmitted at txc(v). - */ - PVPType rcvTime; - - - /*! - * Receive APC position at time trc(v)srp in ECF coordinates - * (meters). - * 3 8-byte floats required. - */ - PVPType rcvPos; - - /*! - * Receive APC velocity at time trc(v)srp in ECF coordinates - * (meters/sec). - * 3 8-byte floats required - */ - PVPType rcvVel; - - /*! - * Stabilization Reference Point (srp) position in ECF coordinates - * (meters). - * 3 8-byte floats required. - */ - PVPType srpPos; - - /*! - * (Optional) Amplitude scale Factor to be applied to all samples of the signal - * vector. For signal vector v, each sample value is multiplied by - * Amp_SF(v) to yield the proper sample values for the vector. - */ - PVPType ampSF; - - /*! - * The DOPPLER shift micro parameter. Parameter accounts for the - * time dilation/Doppler shift for the echoes from all targets with the - * same time dilation/Doppler shift as the srp echo. - */ - PVPType aFDOP; - - /*! - * First order phase micro parameter (i.e. linear phase). Accounts for - * linear phase vs. FX frequency for targets with time - * dilation/Doppler shift different than the echo from the srp. - * Provides precise linear phase prediction for Linear FM waveforms. - */ - PVPType aFRR1; - - /*! - * Second order phase micro parameter (i.e. quadratic phase). - * Accounts for quadratic phase vs. FX frequency for targets with - * time dilation/Doppler shift different than the echo from the srp. - * Provides precise quadratic phase prediction for Linear FM - * waveforms. - */ - PVPType aFRR2; - - /*! - * The FX domain frequency limits of the transmitted waveform - * retained in the signal vector (Hz). - * Saved transmit band is from fx_1(v) < fx < fx_2(v) - * For the vector: FX_BW(v) = fx_2(v) – fx_1(v) - */ - PVPType fx1; - - /*! - * The FX domain frequency limits of the transmitted waveform - * retained in the signal vector (Hz). - * Saved transmit band is from fx_1(v) < fx < fx_2(v) - * For the vector: FX_BW(v) = fx_2(v) – fx_1(v) - */ - PVPType fx2; - - /*! - * (Optional) The FX domain frequency limits for out-of-band noise signal for - * frequencies below fx_1(v) and above fx_2(v). May ONLY be - * included for Domain_Type = FX. - * For any vector: fx_N1 < fx_1 & fx_2 < fx_N2 - * When included in a product, fx_N1 & fx_N2 are both included. - */ - PVPType fxN1; - - /*! - * (Optional) The FX domain frequency limits for out-of-band noise signal for - * frequencies below fx_1(v) and above fx_2(v). May ONLY be - * included for Domain_Type = FX. - * For any vector: fx_N1 < fx_1 & fx_2 < fx_N2 - * When included in a product, fx_N1 & fx_N2 are both included. - */ - PVPType fxN2; - - /*! - * The change in toa limits for the full resolution echoes retained in the - * signal vector (sec). Full resolution echoes are formed with - * FX_BW(v) saved bandwidth. - * Full resolution toa limits: Dtoa_1 < Dtoa < Dtoa_2 - */ - PVPType toa1; - - /*! - * The change in toa limits for the full resolution echoes retained in the - * signal vector (sec). Full resolution echoes are formed with - * FX_BW(v) saved bandwidth. - * Full resolution toa limits: Dtoa_1 < Dtoa < Dtoa_2 - */ - PVPType toa2; - - /*! - * (Optional) The TOA limits for all echoes retained in the signal vector (sec). - */ - PVPType toaE1; - - /*! - * (Optional) The TOA limits for all echoes retained in the signal vector (sec). - */ - PVPType toaE2; - - /*! - * Two-way time delay due to the troposphere (sec) that was added - * when computing the propagation time for the SRP - */ - PVPType tdTropoSRP; - - /*! - * (Optional) Two-way time delay due to the ionosphere (sec) that was added - * when computing the propagation time for the SRP - */ - PVPType tdIonoSRP; - - /*! - * FX DOMAIN & TOA DOMAIN: The domain signal vector coordinate value for - * sample s = 0 (Hz). - */ - PVPType sc0; - - /*! - * FX DOMAIN & TOA DOMAIN: The domain signal vector coordinate value for - * signal coordinate sample spacing (Hz). - */ - PVPType scss; - - /*! - * (Optional) Integer parameter that may be included to indicate the signal - * content for some vectors is known or is likely to be distorted. - */ - PVPType signal; - - //! (Optional) Parameters included that specify the Transmit Antenna ACF orientation and the EB Steering vector - six::XsElement_minOccurs0 txAntenna{ "TxAntenna" }; // new in CPHD 1.1.0 - - //! (Optional) Parameters included that specify the Receive Antenna ACF orientation and the EB Steering vector - six::XsElement_minOccurs0 rcvAntenna{ "RcvAntenna" }; // new in CPHD 1.1.0 - - /* - * (Optional) User defined PV parameters - */ - std::map addedPVP; - - /* - * \func Constructor - * \brief Initialize default values for each parameter - * - */ - Pvp(); - - //! Equality operators - bool operator==(const Pvp& other) const - { - return txTime == other.txTime && txPos == other.txPos && - txVel == other.txVel && rcvTime == other.rcvTime && - rcvPos == other.rcvPos && rcvVel == other.rcvVel && - srpPos == other.srpPos && aFDOP == other.aFDOP && - aFRR1 == other.aFRR1 && aFRR2 == other.aFRR2 && - fx1 == other.fx1 && fx2 == other.fx2 && - toa1 == other.toa1 && toa2 == other.toa2 && - tdTropoSRP == other.tdTropoSRP && sc0 == other.sc0 && - scss == other.scss && - ampSF == other.ampSF && fxN1 == other. fxN1 && - fxN2 == other.fxN2 && toaE1 == other.toaE1 && - toaE2 == other.toaE2 && tdIonoSRP == other.tdIonoSRP && - signal == other.signal - && txAntenna == other.txAntenna - && rcvAntenna == other.rcvAntenna - && addedPVP == other.addedPVP; - } - bool operator!=(const Pvp& other) const - { - return !((*this) == other); - } - - //! Get size of pvp set in blocks - size_t getReqSetSize() const; - - //! Get total byte size of pvp set - size_t sizeInBytes() const; - - /* - * \func setOffset - * - * \brief Validate and set the offset of parameters - * - * \param offset The offset of the parameter to be expected for the param - * \param[out] param The PVPType parameter that should be set - * - * \throws except::Exception If param offset or size overlaps another parameter, or - * if format is invalid - */ - void setOffset(size_t offset, PVPType& param); - - /* - * \func append - * - * \brief Validate and append parameter to the next available block - * - * \param[out] param The PVPType parameter that should be set - * - * \throws except::Exception If param offset or size overlaps another parameter, or - * if format is invalid - */ - void append(PVPType& param); - - /* - * \func setParameter - * - * \brief Validate and set the metadata of an additional parameter identified by name - * - * \param size The size of the parameter to be expected for the param - * \param offset The offset of the parameter to be expected for the param - * \param format The string format of the parameter to be expected for the param - * \param name The unique identifier of the additional parameter that should be set - * - * \throws except::Exception If param offset or size overlaps another parameter, - * if format is invalid or if name is not unique - */ - void setCustomParameter(size_t size, size_t offset, const std::string& format, const std::string& name); - - /* - * \func setCustomParameter - * - * \brief Validate and append additional parameter to the next available block - * - * \param size The size of the parameter to be expected for the param - * \param format The string format of the parameter to be expected for the param - * \param name The unique identifier of the additional parameter that should be set - * - * \throws except::Exception If param offset or size overlaps another parameter, - * if format is invalid or if name is not unique - */ - void appendCustomParameter(size_t size, const std::string& format, const std::string& name); - -private: - /* - * Validate parameter size and offset when setting parameter - */ - void validate(size_t size, size_t offset); - - /* - * Marks filled bytes - */ - std::vector mParamLocations; - - /* - * Set default size and format for each parameter - */ - void setDefaultValues(size_t size, const std::string& format, PVPType& param); - - /* - * Initializes default size and format for parameters - */ - void initialize(); -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const PVPType& p); -std::ostream& operator<< (std::ostream& os, const APVPType& a); -std::ostream& operator<< (std::ostream& os, const Pvp& p); -} -#endif // SIX_cphd_PVP_h_INCLUDED_ +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#pragma once +#ifndef SIX_cphd_PVP_h_INCLUDED_ +#define SIX_cphd_PVP_h_INCLUDED_ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "cphd/Types.h" + +namespace cphd +{ + +/*! + * \struct PVPType + * + * \brief Specifies a defined Per Vector Parameter. + * + * Size and Offset specify the size and placement of + * the binary parameter in the set of Per Vector + * parameters provided for each vector. + */ +struct PVPType +{ + static constexpr size_t WORD_BYTE_SIZE = 8; + + /*! + * \func PVPType + * + * \brief Default constructor + */ + PVPType(); + + //! Equality operators + bool operator==(const PVPType& other) const + { + return mSize == other.getSize() && + mOffset == other.getOffset() && + mFormat == other.getFormat(); + } + bool operator!=(const PVPType& other) const + { + return !((*this) == other); + } + + //! Setter Functions + void setOffset(size_t offset) + { + mOffset = offset; + } + void setSize(size_t size) + { + mSize = size; + } + void setFormat(const std::string& format) + { + mFormat = format; + } + + //! Get size + size_t getSize() const + { + return mSize; + } + //! Get size in bytes + size_t getByteSize() const + { + return mSize * WORD_BYTE_SIZE; + } + //! Get offset + size_t getOffset() const + { + return mOffset; + } + + //! Get offset in bytes + size_t getByteOffset() const + { + return mOffset * WORD_BYTE_SIZE; + } + + //! Get format + std::string getFormat() const + { + return mFormat; + } + +protected: + //! Size of parameter + XsPositiveInteger_fixed2 mSize; // txACX{ "TxACX" }; + + //! TxACY PVP Structure + six::XsElement txACY{ "TxACY" }; + + //! TxEB PVP Structure + six::XsElement txEB{ "TxEB" }; +}; + +/*! + * \struct RcvAntenna + * \brief Specify the Receive Antenna orientation and the Steering vector. + * + * Parameters included that specify the Receive Antenna ACF orientation and the EB Steering vector. + * (New in CPHD 1.1.0) + */ +struct RcvAntenna final +{ + bool operator==(const RcvAntenna& other) const + { + return (rcvACX == other.rcvACX) + && (rcvACY == other.rcvACY) + && (rcvEB == other.rcvEB); + } + bool operator!=(const RcvAntenna& other) const + { + return !((*this) == other); + } + + //! RcvACX PVP Structure + six::XsElement rcvACX{ "RcvACX" }; + + //! RcvACY PVP Structure + six::XsElement rcvACY{ "RcvACY" }; + + //! RcvEB PVP Structure + six::XsElement rcvEB{ "RcvEB" }; +}; + +/*! + * \struct Pvp + * + * \brief Structure used to specify the Per Vector + * parameters + * + * Provided for each channel of a given product. + */ +struct Pvp final +{ + /*! + * Transmit time for the center of the transmitted pulse relative to the + * transmit platform Collection Start Time (sec). + */ + PVPType txTime; + + /*! + * Transmit APC position at time txc(v) in Earth Centered Fixed + * (ECF) coordinates (meters). Components in X, Y, Z order. + * 3 8-byte floats required. + */ + PVPType txPos; + + /*! + * Transmit APC velocity at time txc(v) in ECF coordinates + * (meters/sec). + * 3 8-byte floats required. + */ + PVPType txVel; + + /*! + * Receive time for the center of the echo from the srp relative to the + * transmit platform Collection Start Time (sec). Time is the Time of + * Arrival (toa) of the received echo from the srp for the signal + * transmitted at txc(v). + */ + PVPType rcvTime; + + + /*! + * Receive APC position at time trc(v)srp in ECF coordinates + * (meters). + * 3 8-byte floats required. + */ + PVPType rcvPos; + + /*! + * Receive APC velocity at time trc(v)srp in ECF coordinates + * (meters/sec). + * 3 8-byte floats required + */ + PVPType rcvVel; + + /*! + * Stabilization Reference Point (srp) position in ECF coordinates + * (meters). + * 3 8-byte floats required. + */ + PVPType srpPos; + + /*! + * (Optional) Amplitude scale Factor to be applied to all samples of the signal + * vector. For signal vector v, each sample value is multiplied by + * Amp_SF(v) to yield the proper sample values for the vector. + */ + PVPType ampSF; + + /*! + * The DOPPLER shift micro parameter. Parameter accounts for the + * time dilation/Doppler shift for the echoes from all targets with the + * same time dilation/Doppler shift as the srp echo. + */ + PVPType aFDOP; + + /*! + * First order phase micro parameter (i.e. linear phase). Accounts for + * linear phase vs. FX frequency for targets with time + * dilation/Doppler shift different than the echo from the srp. + * Provides precise linear phase prediction for Linear FM waveforms. + */ + PVPType aFRR1; + + /*! + * Second order phase micro parameter (i.e. quadratic phase). + * Accounts for quadratic phase vs. FX frequency for targets with + * time dilation/Doppler shift different than the echo from the srp. + * Provides precise quadratic phase prediction for Linear FM + * waveforms. + */ + PVPType aFRR2; + + /*! + * The FX domain frequency limits of the transmitted waveform + * retained in the signal vector (Hz). + * Saved transmit band is from fx_1(v) < fx < fx_2(v) + * For the vector: FX_BW(v) = fx_2(v) – fx_1(v) + */ + PVPType fx1; + + /*! + * The FX domain frequency limits of the transmitted waveform + * retained in the signal vector (Hz). + * Saved transmit band is from fx_1(v) < fx < fx_2(v) + * For the vector: FX_BW(v) = fx_2(v) – fx_1(v) + */ + PVPType fx2; + + /*! + * (Optional) The FX domain frequency limits for out-of-band noise signal for + * frequencies below fx_1(v) and above fx_2(v). May ONLY be + * included for Domain_Type = FX. + * For any vector: fx_N1 < fx_1 & fx_2 < fx_N2 + * When included in a product, fx_N1 & fx_N2 are both included. + */ + PVPType fxN1; + + /*! + * (Optional) The FX domain frequency limits for out-of-band noise signal for + * frequencies below fx_1(v) and above fx_2(v). May ONLY be + * included for Domain_Type = FX. + * For any vector: fx_N1 < fx_1 & fx_2 < fx_N2 + * When included in a product, fx_N1 & fx_N2 are both included. + */ + PVPType fxN2; + + /*! + * The change in toa limits for the full resolution echoes retained in the + * signal vector (sec). Full resolution echoes are formed with + * FX_BW(v) saved bandwidth. + * Full resolution toa limits: Dtoa_1 < Dtoa < Dtoa_2 + */ + PVPType toa1; + + /*! + * The change in toa limits for the full resolution echoes retained in the + * signal vector (sec). Full resolution echoes are formed with + * FX_BW(v) saved bandwidth. + * Full resolution toa limits: Dtoa_1 < Dtoa < Dtoa_2 + */ + PVPType toa2; + + /*! + * (Optional) The TOA limits for all echoes retained in the signal vector (sec). + */ + PVPType toaE1; + + /*! + * (Optional) The TOA limits for all echoes retained in the signal vector (sec). + */ + PVPType toaE2; + + /*! + * Two-way time delay due to the troposphere (sec) that was added + * when computing the propagation time for the SRP + */ + PVPType tdTropoSRP; + + /*! + * (Optional) Two-way time delay due to the ionosphere (sec) that was added + * when computing the propagation time for the SRP + */ + PVPType tdIonoSRP; + + /*! + * FX DOMAIN & TOA DOMAIN: The domain signal vector coordinate value for + * sample s = 0 (Hz). + */ + PVPType sc0; + + /*! + * FX DOMAIN & TOA DOMAIN: The domain signal vector coordinate value for + * signal coordinate sample spacing (Hz). + */ + PVPType scss; + + /*! + * (Optional) Integer parameter that may be included to indicate the signal + * content for some vectors is known or is likely to be distorted. + */ + PVPType signal; + + //! (Optional) Parameters included that specify the Transmit Antenna ACF orientation and the EB Steering vector + six::XsElement_minOccurs0 txAntenna{ "TxAntenna" }; // new in CPHD 1.1.0 + + //! (Optional) Parameters included that specify the Receive Antenna ACF orientation and the EB Steering vector + six::XsElement_minOccurs0 rcvAntenna{ "RcvAntenna" }; // new in CPHD 1.1.0 + + /* + * (Optional) User defined PV parameters + */ + std::map addedPVP; + + /* + * \func Constructor + * \brief Initialize default values for each parameter + * + */ + Pvp(); + + //! Equality operators + bool operator==(const Pvp& other) const + { + return txTime == other.txTime && txPos == other.txPos && + txVel == other.txVel && rcvTime == other.rcvTime && + rcvPos == other.rcvPos && rcvVel == other.rcvVel && + srpPos == other.srpPos && aFDOP == other.aFDOP && + aFRR1 == other.aFRR1 && aFRR2 == other.aFRR2 && + fx1 == other.fx1 && fx2 == other.fx2 && + toa1 == other.toa1 && toa2 == other.toa2 && + tdTropoSRP == other.tdTropoSRP && sc0 == other.sc0 && + scss == other.scss && + ampSF == other.ampSF && fxN1 == other. fxN1 && + fxN2 == other.fxN2 && toaE1 == other.toaE1 && + toaE2 == other.toaE2 && tdIonoSRP == other.tdIonoSRP && + signal == other.signal + && txAntenna == other.txAntenna + && rcvAntenna == other.rcvAntenna + && addedPVP == other.addedPVP; + } + bool operator!=(const Pvp& other) const + { + return !((*this) == other); + } + + //! Get size of pvp set in blocks + size_t getReqSetSize() const; + + //! Get total byte size of pvp set + size_t sizeInBytes() const; + + /* + * \func setOffset + * + * \brief Validate and set the offset of parameters + * + * \param offset The offset of the parameter to be expected for the param + * \param[out] param The PVPType parameter that should be set + * + * \throws except::Exception If param offset or size overlaps another parameter, or + * if format is invalid + */ + void setOffset(size_t offset, PVPType& param); + + /* + * \func append + * + * \brief Validate and append parameter to the next available block + * + * \param[out] param The PVPType parameter that should be set + * + * \throws except::Exception If param offset or size overlaps another parameter, or + * if format is invalid + */ + void append(PVPType& param); + + /* + * \func setParameter + * + * \brief Validate and set the metadata of an additional parameter identified by name + * + * \param size The size of the parameter to be expected for the param + * \param offset The offset of the parameter to be expected for the param + * \param format The string format of the parameter to be expected for the param + * \param name The unique identifier of the additional parameter that should be set + * + * \throws except::Exception If param offset or size overlaps another parameter, + * if format is invalid or if name is not unique + */ + void setCustomParameter(size_t size, size_t offset, const std::string& format, const std::string& name); + + /* + * \func setCustomParameter + * + * \brief Validate and append additional parameter to the next available block + * + * \param size The size of the parameter to be expected for the param + * \param format The string format of the parameter to be expected for the param + * \param name The unique identifier of the additional parameter that should be set + * + * \throws except::Exception If param offset or size overlaps another parameter, + * if format is invalid or if name is not unique + */ + void appendCustomParameter(size_t size, const std::string& format, const std::string& name); + +private: + /* + * Validate parameter size and offset when setting parameter + */ + void validate(size_t size, size_t offset); + + /* + * Marks filled bytes + */ + std::vector mParamLocations; + + /* + * Set default size and format for each parameter + */ + void setDefaultValues(size_t size, const std::string& format, PVPType& param); + + /* + * Initializes default size and format for parameters + */ + void initialize(); +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const PVPType& p); +std::ostream& operator<< (std::ostream& os, const APVPType& a); +std::ostream& operator<< (std::ostream& os, const Pvp& p); +} +#endif // SIX_cphd_PVP_h_INCLUDED_ diff --git a/six/modules/c++/cphd/include/cphd/ProductInfo.h b/six/modules/c++/cphd/include/cphd/ProductInfo.h index bb520e7cd3..6abef48c6e 100644 --- a/six/modules/c++/cphd/include/cphd/ProductInfo.h +++ b/six/modules/c++/cphd/include/cphd/ProductInfo.h @@ -1,117 +1,117 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_PRODUCT_INFO_H__ -#define __CPHD_PRODUCT_INFO_H__ - -#include -#include -#include - -#include -#include - -namespace cphd -{ -/* - * \struct ProductInfo - * - * \brief Contains product information - * - * (Optional) Parameters that provide general information about the - * CPHD product and/or the derived products that may be created from it - */ -struct ProductInfo -{ - /* - * \struct CreationInfo - * - * \brief Contains creation information - * - * (Optional) Parameters that provide general information about - * the CPHD product generation - */ - struct CreationInfo - { - //! Constructor - CreationInfo(); - - //! Equality operators - bool operator==(const CreationInfo& other) const - { - return application == other.application && - dateTime == other.dateTime && site == other.site && - parameter == other.parameter; - } - bool operator!=(const CreationInfo& other) const - { - return !((*this) == other); - } - - //! (Optional) Name and version of the applications that created - //! the CPHD product - std::string application; - - //! Date and time the CPHD product was created (UTC). - DateTime dateTime; - - //! (Optional) Name of the site where the product was created - std::string site; - - //! (Optional) Text field that can be used for program specific - //! name and value - six::ParameterCollection parameter; - }; - - //! Constructor - ProductInfo(); - - //! Equality operators - bool operator==(const ProductInfo& other) const - { - return profile == other.profile && - creationInfo == other.creationInfo && - parameter == other.parameter; - } - bool operator!=(const ProductInfo& other) const - { - return !((*this) == other); - } - - //! (Optional) Identifies what profile was used to create this - //! CPHD product - std::string profile; - - //! (Optional) Parameters that provide general information - //! about the CPHD product generation. - std::vector creationInfo; - - //! (Optional) Text field that can be used for program specific - //! parameter name & value - six::ParameterCollection parameter; -}; - -//! Ostream operator -std::ostream& operator<< (std::ostream& os, const ProductInfo& p); -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_PRODUCT_INFO_H__ +#define __CPHD_PRODUCT_INFO_H__ + +#include +#include +#include + +#include +#include + +namespace cphd +{ +/* + * \struct ProductInfo + * + * \brief Contains product information + * + * (Optional) Parameters that provide general information about the + * CPHD product and/or the derived products that may be created from it + */ +struct ProductInfo +{ + /* + * \struct CreationInfo + * + * \brief Contains creation information + * + * (Optional) Parameters that provide general information about + * the CPHD product generation + */ + struct CreationInfo + { + //! Constructor + CreationInfo(); + + //! Equality operators + bool operator==(const CreationInfo& other) const + { + return application == other.application && + dateTime == other.dateTime && site == other.site && + parameter == other.parameter; + } + bool operator!=(const CreationInfo& other) const + { + return !((*this) == other); + } + + //! (Optional) Name and version of the applications that created + //! the CPHD product + std::string application; + + //! Date and time the CPHD product was created (UTC). + DateTime dateTime; + + //! (Optional) Name of the site where the product was created + std::string site; + + //! (Optional) Text field that can be used for program specific + //! name and value + six::ParameterCollection parameter; + }; + + //! Constructor + ProductInfo(); + + //! Equality operators + bool operator==(const ProductInfo& other) const + { + return profile == other.profile && + creationInfo == other.creationInfo && + parameter == other.parameter; + } + bool operator!=(const ProductInfo& other) const + { + return !((*this) == other); + } + + //! (Optional) Identifies what profile was used to create this + //! CPHD product + std::string profile; + + //! (Optional) Parameters that provide general information + //! about the CPHD product generation. + std::vector creationInfo; + + //! (Optional) Text field that can be used for program specific + //! parameter name & value + six::ParameterCollection parameter; +}; + +//! Ostream operator +std::ostream& operator<< (std::ostream& os, const ProductInfo& p); +} + +#endif diff --git a/six/modules/c++/cphd/include/cphd/ReferenceGeometry.h b/six/modules/c++/cphd/include/cphd/ReferenceGeometry.h index 13d73968ad..4bccc9203b 100644 --- a/six/modules/c++/cphd/include/cphd/ReferenceGeometry.h +++ b/six/modules/c++/cphd/include/cphd/ReferenceGeometry.h @@ -1,350 +1,350 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_REFERENCE_GEOMETRY_H__ -#define __CPHD_REFERENCE_GEOMETRY_H__ - -#include - -#include -#include -#include - -namespace cphd -{ - -/*! - * \struct SRP - * - * \brief The SRP position for the reference vector of the - * reference channel - */ -struct SRP -{ - //! Constructor - SRP(); - - //! Equality operator - bool operator==(const SRP& other) const - { - return ecf == other.ecf && iac == other.iac; - } - bool operator!=(const SRP& other) const - { - return !((*this) == other); - } - - //! SRP position in ECF coordinates. Value - //! included in the SRPPos PVP - Vector3 ecf; - - //! SRP position in Image Area Coordinates (IAX, - //! IAY, IAZ). - Vector3 iac; -}; - -/*! - * \struct ImagingType - * - * \brief Base class for both Monostatic and - * Bistatic imaging types - */ -struct ImagingType -{ - //! Constructor - ImagingType(); - - //! Equality operators - bool operator==(const ImagingType& other) const - { - return azimuthAngle == other.azimuthAngle && - grazeAngle == other.grazeAngle && - twistAngle == other.twistAngle && - slopeAngle == other.slopeAngle && - layoverAngle == other.layoverAngle; - } - bool operator!=(const ImagingType& other) const - { - return !((*this) == other); - } - - //! Destructor - virtual ~ImagingType() {} - - //! Angle from north to the line from the SRP to the - //! ARP ETP Nadir (i.e. North to +GPX). Measured - //! clockwise from +North toward +East. - double azimuthAngle; - - //! Grazing angle for the ARP to SRP LOS and the - //! Earth Tangent Plane (ETP) at the SRP. - double grazeAngle; - - //! Twist angle between cross range in the ETP and - //! cross range in the slant plane at the SRP - double twistAngle; - - //! Angle between the ETP normal (uUP) and the - //! slant plane normal (uSPN) at the SRP - double slopeAngle; - - //! Angle from north to the layover direction in the - //! ETP. Measured clockwise from +North toward - //! +East - double layoverAngle; -}; - -/*! - * \struct Monostatic - * - * \brief (Conditional) Collection Type Monostatic metadata. - * - * Single radar platform that is both the transmitter - * and the receiver - */ -struct Monostatic : public ImagingType -{ - //! Constructor - Monostatic(); - - //! Equality operators - bool operator==(const Monostatic& other) const - { - if((ImagingType)(*this) != (ImagingType)other) { - return false; - } - - return sideOfTrack == other.sideOfTrack && - slantRange == other.slantRange && - groundRange == other.groundRange && - dopplerConeAngle == other.dopplerConeAngle && - incidenceAngle == other.incidenceAngle && - arpPos == other.arpPos && arpVel == other.arpVel; - } - bool operator!=(const Monostatic& other) const - { - return !((*this) == other); - } - - //! Side of Track parameter for the collection. - //! L Left-looking or R Right-looking - six::SideOfTrackType sideOfTrack; - - //! Slant range from the ARP to the SRP - double slantRange; - - //! Ground range from the ARP nadir to the SRP. - //! Distance measured along spherical earth model - //! passing through the SRP. - double groundRange; - - //! Doppler Cone Angle between ARP velocity and - //! SRP Line of Sight (LOS). - double dopplerConeAngle; - - //! Incidence angle for the ARP to SRP LOS and the - //! Earth Tangent Plane (ETP) at the SRP - double incidenceAngle; - - //! ARP position in ECF coordinates (ARP) - Vector3 arpPos; - - //! ARP velocity in ECF coordinates (VARP). - Vector3 arpVel; -}; - -/*! - * \struct Bistatic - * - * \brief (Conditional) Collection Type Bistatic metadata. - * - * Pair of radar platforms, with a seperate transmitter - * and a passive receiver. - */ -struct Bistatic : public ImagingType -{ - /*! - * \struct PlatformParams - * - * \brief Describe transmit and recieve platform parameters - */ - struct PlatformParams - { - //! Constructor - PlatformParams(); - - //! Equality operator - bool operator==(const PlatformParams& other) const - { - return sideOfTrack == other.sideOfTrack && - azimuthAngle == other.azimuthAngle && - grazeAngle == other.grazeAngle && - dopplerConeAngle == other.dopplerConeAngle && - groundRange == other.groundRange && - slantRange == other.slantRange && - time == other.time && - pos == other.pos && vel == other.vel; - } - bool operator!=(const PlatformParams& other) const - { - return !((*this) == other); - } - - //! Side of Track parameter for the collection. - //! L Left-looking or R Right-looking - six::SideOfTrackType sideOfTrack; - - //! The transmit time for the vector (txc = TxTime). - double time; - - //! Angle from north to the line from the SCP to the - //! Pos Nadir in the ETP - double azimuthAngle; - - //! Grazing angle between the RefPt LOS and Earth - //! Tangent Plane (ETP - double grazeAngle; - - //! Incidence angle between the RefPt LOS and ETP - //! normal - double incidenceAngle; - - //! Doppler Cone Angle between VXmt and line of - //! sight to the ARP - double dopplerConeAngle; - - //! Ground range from the transmit APC to the SRP - //! (measured on the spherical surface containing the - //! SRP). - double groundRange; - - //! Slant range from the transmit APC to the SRP. - double slantRange; - - //! Transmit APC position (Xmt) in ECF - //! coordinates at txc - Vector3 pos; - - //! Transmit APC velocity (VXmt) in ECF - //! coordinates at txc. - Vector3 vel; - }; - - //! Constructor - Bistatic(); - - //! Equality operator - bool operator==(const Bistatic& other) const - { - if((ImagingType)(*this) != (ImagingType)other) { - return false; - } - - return azimuthAngleRate == other.azimuthAngleRate && - bistaticAngle == other.bistaticAngle && - bistaticAngleRate == other.bistaticAngleRate && - txPlatform == other.txPlatform && - rcvPlatform == other.rcvPlatform; - } - bool operator!=(const Bistatic& other) const - { - return !((*this) == other); - } - - //! Angle from north to the line from the SCP to the - //! Pos Nadir in the ETP - double azimuthAngleRate; - - //! Bistatic angle (Beta) between unit vector from - //! SRP to transmit APC (uXmt) and the unit vector - //! from the SRP to the receive APC (uRcv). - double bistaticAngle; - - //! Instantaneous rate of change of the bistatic angle - //! (d(Beta)/dt). - double bistaticAngleRate; - - //! Parameters that describe the Transmit platform. - PlatformParams txPlatform; - - //! Parameters that describe the Receive platform - PlatformParams rcvPlatform; - -}; - -/*! - * \struct ReferenceGeometry - * - * \brief Parameters that describe the collection geometry - */ -struct ReferenceGeometry -{ - //! Constructor - ReferenceGeometry(); - - //! Equality operator - bool operator==(const ReferenceGeometry& other) const - { - return referenceTime == other.referenceTime && - srpCODTime == other.srpCODTime && - srpDwellTime == other.srpDwellTime && - srp == other.srp && - monostatic == other.monostatic && - bistatic == other.bistatic; - } - bool operator!=(const ReferenceGeometry& other) const - { - return !((*this) == other); - } - - //! Reference time for the selected reference vector - double referenceTime; - - //! The COD Time for point on the reference surface - //! at (SRP_IAX, SRP_IAY). - double srpCODTime; - - //! The Dwell Time for point on the reference - //! surface at (SRP_IAX, SRP_IAY) - double srpDwellTime; - - //! The SRP position for the reference vector of the - //! reference channel. - SRP srp; - - //! Parameters for CollectType = "MONOSTATIC" - mem::ScopedCopyablePtr monostatic; - - //! Parameters for CollectType = "BISTATIC" - mem::ScopedCopyablePtr bistatic; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const SRP& s); -std::ostream& operator<< (std::ostream& os, const ImagingType& i); -std::ostream& operator<< (std::ostream& os, const Monostatic& m); -std::ostream& operator<< (std::ostream& os, const Bistatic::PlatformParams& p); -std::ostream& operator<< (std::ostream& os, const Bistatic& b); -std::ostream& operator<< (std::ostream& os, const ReferenceGeometry& r); -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_REFERENCE_GEOMETRY_H__ +#define __CPHD_REFERENCE_GEOMETRY_H__ + +#include + +#include +#include +#include + +namespace cphd +{ + +/*! + * \struct SRP + * + * \brief The SRP position for the reference vector of the + * reference channel + */ +struct SRP +{ + //! Constructor + SRP(); + + //! Equality operator + bool operator==(const SRP& other) const + { + return ecf == other.ecf && iac == other.iac; + } + bool operator!=(const SRP& other) const + { + return !((*this) == other); + } + + //! SRP position in ECF coordinates. Value + //! included in the SRPPos PVP + Vector3 ecf; + + //! SRP position in Image Area Coordinates (IAX, + //! IAY, IAZ). + Vector3 iac; +}; + +/*! + * \struct ImagingType + * + * \brief Base class for both Monostatic and + * Bistatic imaging types + */ +struct ImagingType +{ + //! Constructor + ImagingType(); + + //! Equality operators + bool operator==(const ImagingType& other) const + { + return azimuthAngle == other.azimuthAngle && + grazeAngle == other.grazeAngle && + twistAngle == other.twistAngle && + slopeAngle == other.slopeAngle && + layoverAngle == other.layoverAngle; + } + bool operator!=(const ImagingType& other) const + { + return !((*this) == other); + } + + //! Destructor + virtual ~ImagingType() {} + + //! Angle from north to the line from the SRP to the + //! ARP ETP Nadir (i.e. North to +GPX). Measured + //! clockwise from +North toward +East. + double azimuthAngle; + + //! Grazing angle for the ARP to SRP LOS and the + //! Earth Tangent Plane (ETP) at the SRP. + double grazeAngle; + + //! Twist angle between cross range in the ETP and + //! cross range in the slant plane at the SRP + double twistAngle; + + //! Angle between the ETP normal (uUP) and the + //! slant plane normal (uSPN) at the SRP + double slopeAngle; + + //! Angle from north to the layover direction in the + //! ETP. Measured clockwise from +North toward + //! +East + double layoverAngle; +}; + +/*! + * \struct Monostatic + * + * \brief (Conditional) Collection Type Monostatic metadata. + * + * Single radar platform that is both the transmitter + * and the receiver + */ +struct Monostatic : public ImagingType +{ + //! Constructor + Monostatic(); + + //! Equality operators + bool operator==(const Monostatic& other) const + { + if((ImagingType)(*this) != (ImagingType)other) { + return false; + } + + return sideOfTrack == other.sideOfTrack && + slantRange == other.slantRange && + groundRange == other.groundRange && + dopplerConeAngle == other.dopplerConeAngle && + incidenceAngle == other.incidenceAngle && + arpPos == other.arpPos && arpVel == other.arpVel; + } + bool operator!=(const Monostatic& other) const + { + return !((*this) == other); + } + + //! Side of Track parameter for the collection. + //! L Left-looking or R Right-looking + six::SideOfTrackType sideOfTrack; + + //! Slant range from the ARP to the SRP + double slantRange; + + //! Ground range from the ARP nadir to the SRP. + //! Distance measured along spherical earth model + //! passing through the SRP. + double groundRange; + + //! Doppler Cone Angle between ARP velocity and + //! SRP Line of Sight (LOS). + double dopplerConeAngle; + + //! Incidence angle for the ARP to SRP LOS and the + //! Earth Tangent Plane (ETP) at the SRP + double incidenceAngle; + + //! ARP position in ECF coordinates (ARP) + Vector3 arpPos; + + //! ARP velocity in ECF coordinates (VARP). + Vector3 arpVel; +}; + +/*! + * \struct Bistatic + * + * \brief (Conditional) Collection Type Bistatic metadata. + * + * Pair of radar platforms, with a seperate transmitter + * and a passive receiver. + */ +struct Bistatic : public ImagingType +{ + /*! + * \struct PlatformParams + * + * \brief Describe transmit and recieve platform parameters + */ + struct PlatformParams + { + //! Constructor + PlatformParams(); + + //! Equality operator + bool operator==(const PlatformParams& other) const + { + return sideOfTrack == other.sideOfTrack && + azimuthAngle == other.azimuthAngle && + grazeAngle == other.grazeAngle && + dopplerConeAngle == other.dopplerConeAngle && + groundRange == other.groundRange && + slantRange == other.slantRange && + time == other.time && + pos == other.pos && vel == other.vel; + } + bool operator!=(const PlatformParams& other) const + { + return !((*this) == other); + } + + //! Side of Track parameter for the collection. + //! L Left-looking or R Right-looking + six::SideOfTrackType sideOfTrack; + + //! The transmit time for the vector (txc = TxTime). + double time; + + //! Angle from north to the line from the SCP to the + //! Pos Nadir in the ETP + double azimuthAngle; + + //! Grazing angle between the RefPt LOS and Earth + //! Tangent Plane (ETP + double grazeAngle; + + //! Incidence angle between the RefPt LOS and ETP + //! normal + double incidenceAngle; + + //! Doppler Cone Angle between VXmt and line of + //! sight to the ARP + double dopplerConeAngle; + + //! Ground range from the transmit APC to the SRP + //! (measured on the spherical surface containing the + //! SRP). + double groundRange; + + //! Slant range from the transmit APC to the SRP. + double slantRange; + + //! Transmit APC position (Xmt) in ECF + //! coordinates at txc + Vector3 pos; + + //! Transmit APC velocity (VXmt) in ECF + //! coordinates at txc. + Vector3 vel; + }; + + //! Constructor + Bistatic(); + + //! Equality operator + bool operator==(const Bistatic& other) const + { + if((ImagingType)(*this) != (ImagingType)other) { + return false; + } + + return azimuthAngleRate == other.azimuthAngleRate && + bistaticAngle == other.bistaticAngle && + bistaticAngleRate == other.bistaticAngleRate && + txPlatform == other.txPlatform && + rcvPlatform == other.rcvPlatform; + } + bool operator!=(const Bistatic& other) const + { + return !((*this) == other); + } + + //! Angle from north to the line from the SCP to the + //! Pos Nadir in the ETP + double azimuthAngleRate; + + //! Bistatic angle (Beta) between unit vector from + //! SRP to transmit APC (uXmt) and the unit vector + //! from the SRP to the receive APC (uRcv). + double bistaticAngle; + + //! Instantaneous rate of change of the bistatic angle + //! (d(Beta)/dt). + double bistaticAngleRate; + + //! Parameters that describe the Transmit platform. + PlatformParams txPlatform; + + //! Parameters that describe the Receive platform + PlatformParams rcvPlatform; + +}; + +/*! + * \struct ReferenceGeometry + * + * \brief Parameters that describe the collection geometry + */ +struct ReferenceGeometry +{ + //! Constructor + ReferenceGeometry(); + + //! Equality operator + bool operator==(const ReferenceGeometry& other) const + { + return referenceTime == other.referenceTime && + srpCODTime == other.srpCODTime && + srpDwellTime == other.srpDwellTime && + srp == other.srp && + monostatic == other.monostatic && + bistatic == other.bistatic; + } + bool operator!=(const ReferenceGeometry& other) const + { + return !((*this) == other); + } + + //! Reference time for the selected reference vector + double referenceTime; + + //! The COD Time for point on the reference surface + //! at (SRP_IAX, SRP_IAY). + double srpCODTime; + + //! The Dwell Time for point on the reference + //! surface at (SRP_IAX, SRP_IAY) + double srpDwellTime; + + //! The SRP position for the reference vector of the + //! reference channel. + SRP srp; + + //! Parameters for CollectType = "MONOSTATIC" + mem::ScopedCopyablePtr monostatic; + + //! Parameters for CollectType = "BISTATIC" + mem::ScopedCopyablePtr bistatic; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const SRP& s); +std::ostream& operator<< (std::ostream& os, const ImagingType& i); +std::ostream& operator<< (std::ostream& os, const Monostatic& m); +std::ostream& operator<< (std::ostream& os, const Bistatic::PlatformParams& p); +std::ostream& operator<< (std::ostream& os, const Bistatic& b); +std::ostream& operator<< (std::ostream& os, const ReferenceGeometry& r); +} + +#endif diff --git a/six/modules/c++/cphd/include/cphd/TxRcv.h b/six/modules/c++/cphd/include/cphd/TxRcv.h index 856966ac88..7e80674ce2 100644 --- a/six/modules/c++/cphd/include/cphd/TxRcv.h +++ b/six/modules/c++/cphd/include/cphd/TxRcv.h @@ -1,184 +1,184 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_TXRCV_H__ -#define __CPHD_TXRCV_H__ - -#include -#include -#include - -#include -#include - - -namespace cphd -{ - -/*! - * \struct ParameterType - * - * \brief Base parameter class for both TxWF and Rcv type parameters - */ -struct ParameterType -{ - //! Constructor - ParameterType(); - - //! Equality operators - bool operator==(const ParameterType& other) const - { - return identifier == other.identifier && - freqCenter == other.freqCenter && - lfmRate == other.lfmRate && - polarization == other.polarization; - } - - bool operator!=(const ParameterType& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this Transmit Waveform - std::string identifier; - - //! Center frequency of the transmitted waveform - double freqCenter; - - //! (Optional) Chirp rate of transmitted pulse if LFM - // Allowed lfmRate != 0 - double lfmRate; - - //! Transmit polarization - PolarizationType polarization; -}; - -/*! - * \struct TxWFParameters - * - * \brief Parameters that describe a Transmit Waveform - */ -struct TxWFParameters : public ParameterType -{ - //! Constructor - TxWFParameters(); - - //! Equality operators - bool operator==(const TxWFParameters& other) const - { - return pulseLength == other.pulseLength && - rfBandwidth == other.rfBandwidth && - power == other.power; - } - bool operator!=(const TxWFParameters& other) const - { - return !((*this) == other); - } - - //! Length of transmitted pulse - double pulseLength; - - //! Bandwidth if transmitted pulse - double rfBandwidth; - - //! Peak transmitted power at the interface to the - //! antenna - double power; -}; - -/* - * \struct RcvParameters - * - * \brief Parameters that describe a Receive configuration - */ -struct RcvParameters : public ParameterType -{ - //! Constructor - RcvParameters(); - - //! Equality operators - bool operator==(const RcvParameters& other) const - { - return windowLength == other.windowLength && - sampleRate == other.sampleRate && - ifFilterBW == other.ifFilterBW && - pathGain == other.pathGain; - } - bool operator!=(const RcvParameters& other) const - { - return !((*this) == other); - } - - //! Length of the receive window - double windowLength; - - //! Rate at which the signal in the receive window - //! is sampled - double sampleRate; - - //! Bandwidth of the anti-aliasing filter prior to - //! sampling - double ifFilterBW; - - //! Receiver gain from the antenna interface to the - //! ADC. - double pathGain; -}; - -/*! - * \struct TxRcv - * - * (Optional) Parameters that describe the transmitted - * waveform(s) and receiver configurations used in - * the collection - */ -struct TxRcv -{ - //! Constructor - TxRcv(); - - //! Equality operators - bool operator==(const TxRcv& other) const - { - return txWFParameters == other.txWFParameters && - rcvParameters == other.rcvParameters; - } - bool operator!=(const TxRcv& other) const - { - return !((*this) == other); - } - - //! Parameters that describe a Transmit Waveform - std::vector txWFParameters; - - //! Parameters that describe a Receive configuration - std::vector rcvParameters; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const ParameterType& p); -std::ostream& operator<< (std::ostream& os, const TxWFParameters& t); -std::ostream& operator<< (std::ostream& os, const RcvParameters& r); -std::ostream& operator<< (std::ostream& os, const TxRcv& t); -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_TXRCV_H__ +#define __CPHD_TXRCV_H__ + +#include +#include +#include + +#include +#include + + +namespace cphd +{ + +/*! + * \struct ParameterType + * + * \brief Base parameter class for both TxWF and Rcv type parameters + */ +struct ParameterType +{ + //! Constructor + ParameterType(); + + //! Equality operators + bool operator==(const ParameterType& other) const + { + return identifier == other.identifier && + freqCenter == other.freqCenter && + lfmRate == other.lfmRate && + polarization == other.polarization; + } + + bool operator!=(const ParameterType& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this Transmit Waveform + std::string identifier; + + //! Center frequency of the transmitted waveform + double freqCenter; + + //! (Optional) Chirp rate of transmitted pulse if LFM + // Allowed lfmRate != 0 + double lfmRate; + + //! Transmit polarization + PolarizationType polarization; +}; + +/*! + * \struct TxWFParameters + * + * \brief Parameters that describe a Transmit Waveform + */ +struct TxWFParameters : public ParameterType +{ + //! Constructor + TxWFParameters(); + + //! Equality operators + bool operator==(const TxWFParameters& other) const + { + return pulseLength == other.pulseLength && + rfBandwidth == other.rfBandwidth && + power == other.power; + } + bool operator!=(const TxWFParameters& other) const + { + return !((*this) == other); + } + + //! Length of transmitted pulse + double pulseLength; + + //! Bandwidth if transmitted pulse + double rfBandwidth; + + //! Peak transmitted power at the interface to the + //! antenna + double power; +}; + +/* + * \struct RcvParameters + * + * \brief Parameters that describe a Receive configuration + */ +struct RcvParameters : public ParameterType +{ + //! Constructor + RcvParameters(); + + //! Equality operators + bool operator==(const RcvParameters& other) const + { + return windowLength == other.windowLength && + sampleRate == other.sampleRate && + ifFilterBW == other.ifFilterBW && + pathGain == other.pathGain; + } + bool operator!=(const RcvParameters& other) const + { + return !((*this) == other); + } + + //! Length of the receive window + double windowLength; + + //! Rate at which the signal in the receive window + //! is sampled + double sampleRate; + + //! Bandwidth of the anti-aliasing filter prior to + //! sampling + double ifFilterBW; + + //! Receiver gain from the antenna interface to the + //! ADC. + double pathGain; +}; + +/*! + * \struct TxRcv + * + * (Optional) Parameters that describe the transmitted + * waveform(s) and receiver configurations used in + * the collection + */ +struct TxRcv +{ + //! Constructor + TxRcv(); + + //! Equality operators + bool operator==(const TxRcv& other) const + { + return txWFParameters == other.txWFParameters && + rcvParameters == other.rcvParameters; + } + bool operator!=(const TxRcv& other) const + { + return !((*this) == other); + } + + //! Parameters that describe a Transmit Waveform + std::vector txWFParameters; + + //! Parameters that describe a Receive configuration + std::vector rcvParameters; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const ParameterType& p); +std::ostream& operator<< (std::ostream& os, const TxWFParameters& t); +std::ostream& operator<< (std::ostream& os, const RcvParameters& r); +std::ostream& operator<< (std::ostream& os, const TxRcv& t); +} + +#endif diff --git a/six/modules/c++/cphd/source/Antenna.cpp b/six/modules/c++/cphd/source/Antenna.cpp index 5a5dc9e916..7dc9d1b781 100644 --- a/six/modules/c++/cphd/source/Antenna.cpp +++ b/six/modules/c++/cphd/source/Antenna.cpp @@ -1,148 +1,148 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include - -namespace cphd -{ - -AntCoordFrame::AntCoordFrame() -{ -} - -AntPhaseCenter::AntPhaseCenter() -{ -} - -AntPattern::AntPattern(): - freqZero(six::Init::undefined()), - gainZero(six::Init::undefined()), - ebFreqShift(six::Init::undefined()), - mlFreqDilation(six::Init::undefined()), - gainBSPoly(six::Init::undefined()) -{ -} - -AntPattern::GainPhaseArray::GainPhaseArray() : - freq(six::Init::undefined()) -{ -} - -Antenna::Antenna() -{ -} - -std::ostream& operator<< (std::ostream& os, const AntCoordFrame& a) -{ - os << " AntCoordFrame:: \n" - << " Identifier : " << a.identifier << "\n" - << " XAxisPoly : " << a.xAxisPoly << "\n" - << " YAxisPoly : " << a.yAxisPoly << "\n" - << a.useACFPVP; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPhaseCenter& a) -{ - os << " AntPhaseCenter:: \n" - << " Identifier : " << a.identifier << "\n" - << " ACFId : " << a.acfId << "\n" - << " APCXYZ : " << a.apcXYZ << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPattern::EBFreqShiftSF& v) -{ - os << " EBFreqShiftSF:: \n" - << v.dcxsf << v.dcysf << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPattern::MLFreqDilationSF& v) -{ - os << " MLFreqDilationSF:: \n" - << v.dcxsf << v.dcysf << "\n"; - return os; -} - - -std::ostream& operator<< (std::ostream& os, const AntPattern::AntPolRef& v) -{ - os << " AntPolRef:: \n" - << v.ampX << v.ampY << v.phaseY << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPattern::GainPhaseArray& g) -{ - os << " GainPhaseArray:: \n" - << " Freq : " << g.freq << "\n" - << " ArrayId : " << g.arrayId << "\n" - << " ElementId : " << g.elementId << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPattern& a) -{ - os << " AntPattern \n" - << " Identifier : " << a.identifier << "\n" - << " FreqZero : " << a.freqZero << "\n" - << " GainZero : " << a.gainZero << "\n" - << " EBFreqShift : " << a.ebFreqShift << "\n" - << a.ebFreqShiftSF << "\n" - << " MLFreqDilation : " << a.mlFreqDilation << "\n" - << a.mlFreqDilationSF << "\n" - << " GainBSPoly : " << a.gainBSPoly << "\n" - << a.antPolRef << "\n" - << a.eb << "\n" - << " Array:: \n" - << a.array << "\n" - << " Element:: \n" - << a.element << "\n"; - for (const auto& gainPhase : a.gainPhaseArray) - { - os << gainPhase << "\n"; - } - return os; -} - -std::ostream& operator<< (std::ostream& os, const Antenna& a) -{ - os << "Antenna:: \n" - << " NumACFs : " << a.antCoordFrame.size() << "\n" - << " NumAPCs : " << a.antPhaseCenter.size() << "\n" - << " NumAntPats : " << a.antPattern.size() << "\n"; - for (size_t ii = 0; ii < a.antCoordFrame.size(); ++ii) - { - os << a.antCoordFrame[ii] << "\n"; - } - for (size_t ii = 0; ii < a.antPhaseCenter.size(); ++ii) - { - os << a.antPhaseCenter[ii] << "\n"; - } - for (size_t ii = 0; ii < a.antPattern.size(); ++ii) - { - os << a.antPattern[ii] << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include + +namespace cphd +{ + +AntCoordFrame::AntCoordFrame() +{ +} + +AntPhaseCenter::AntPhaseCenter() +{ +} + +AntPattern::AntPattern(): + freqZero(six::Init::undefined()), + gainZero(six::Init::undefined()), + ebFreqShift(six::Init::undefined()), + mlFreqDilation(six::Init::undefined()), + gainBSPoly(six::Init::undefined()) +{ +} + +AntPattern::GainPhaseArray::GainPhaseArray() : + freq(six::Init::undefined()) +{ +} + +Antenna::Antenna() +{ +} + +std::ostream& operator<< (std::ostream& os, const AntCoordFrame& a) +{ + os << " AntCoordFrame:: \n" + << " Identifier : " << a.identifier << "\n" + << " XAxisPoly : " << a.xAxisPoly << "\n" + << " YAxisPoly : " << a.yAxisPoly << "\n" + << a.useACFPVP; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPhaseCenter& a) +{ + os << " AntPhaseCenter:: \n" + << " Identifier : " << a.identifier << "\n" + << " ACFId : " << a.acfId << "\n" + << " APCXYZ : " << a.apcXYZ << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPattern::EBFreqShiftSF& v) +{ + os << " EBFreqShiftSF:: \n" + << v.dcxsf << v.dcysf << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPattern::MLFreqDilationSF& v) +{ + os << " MLFreqDilationSF:: \n" + << v.dcxsf << v.dcysf << "\n"; + return os; +} + + +std::ostream& operator<< (std::ostream& os, const AntPattern::AntPolRef& v) +{ + os << " AntPolRef:: \n" + << v.ampX << v.ampY << v.phaseY << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPattern::GainPhaseArray& g) +{ + os << " GainPhaseArray:: \n" + << " Freq : " << g.freq << "\n" + << " ArrayId : " << g.arrayId << "\n" + << " ElementId : " << g.elementId << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPattern& a) +{ + os << " AntPattern \n" + << " Identifier : " << a.identifier << "\n" + << " FreqZero : " << a.freqZero << "\n" + << " GainZero : " << a.gainZero << "\n" + << " EBFreqShift : " << a.ebFreqShift << "\n" + << a.ebFreqShiftSF << "\n" + << " MLFreqDilation : " << a.mlFreqDilation << "\n" + << a.mlFreqDilationSF << "\n" + << " GainBSPoly : " << a.gainBSPoly << "\n" + << a.antPolRef << "\n" + << a.eb << "\n" + << " Array:: \n" + << a.array << "\n" + << " Element:: \n" + << a.element << "\n"; + for (const auto& gainPhase : a.gainPhaseArray) + { + os << gainPhase << "\n"; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const Antenna& a) +{ + os << "Antenna:: \n" + << " NumACFs : " << a.antCoordFrame.size() << "\n" + << " NumAPCs : " << a.antPhaseCenter.size() << "\n" + << " NumAntPats : " << a.antPattern.size() << "\n"; + for (size_t ii = 0; ii < a.antCoordFrame.size(); ++ii) + { + os << a.antCoordFrame[ii] << "\n"; + } + for (size_t ii = 0; ii < a.antPhaseCenter.size(); ++ii) + { + os << a.antPhaseCenter[ii] << "\n"; + } + for (size_t ii = 0; ii < a.antPattern.size(); ++ii) + { + os << a.antPattern[ii] << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/CPHDXMLParser.cpp b/six/modules/c++/cphd/source/CPHDXMLParser.cpp index 61a24d3d1e..1ea206ba35 100644 --- a/six/modules/c++/cphd/source/CPHDXMLParser.cpp +++ b/six/modules/c++/cphd/source/CPHDXMLParser.cpp @@ -1,2422 +1,2422 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define ENFORCESPEC 0 - -namespace -{ -typedef xml::lite::Element* XMLElem; -} - -namespace cphd -{ - -CPHDXMLParser::CPHDXMLParser( - const std::string& uri, - bool addClassAttributes, - logging::Logger* log, - bool ownLog) : - six::XMLParser(uri, addClassAttributes, log, ownLog), - mCommon(getDefaultURI(), addClassAttributes, getDefaultURI(), log) -{ -} - -/* - * TO XML - */ -std::unique_ptr CPHDXMLParser::toXML( - const Metadata& metadata) -{ - std::unique_ptr doc(new xml::lite::Document()); - - XMLElem root = newElement("CPHD"); - doc->setRootElement(root); - - toXML(metadata.collectionID, root); - toXML(metadata.global, root); - toXML(metadata.sceneCoordinates, root); - toXML(metadata.data, root); - toXML(metadata.channel, root); - toXML(metadata.pvp, root); - toXML(metadata.dwell, root); - toXML(metadata.referenceGeometry, root); - - if (metadata.supportArray.get()) - { - toXML(*(metadata.supportArray), root); - } - if (metadata.antenna.get()) - { - toXML(*(metadata.antenna), root); - } - if (metadata.txRcv.get()) - { - toXML(*(metadata.txRcv), root); - } - if (metadata.errorParameters.get()) - { - toXML(*(metadata.errorParameters), root); - } - if (metadata.productInfo.get()) - { - toXML(*(metadata.productInfo), root); - } - for (const auto& geoInfo : metadata.geoInfo) - { - toXML(geoInfo, root); - } - if (metadata.matchInfo.get()) - { - toXML(*(metadata.matchInfo), root); - } - - //set the XMLNS - root->setNamespacePrefix("", getDefaultURI()); - - return doc; -} - -XMLElem CPHDXMLParser::toXML(const CollectionInformation& collectionID, XMLElem parent) -{ - XMLElem collectionXML = newElement("CollectionID", parent); - - createString("CollectorName", collectionID.collectorName, collectionXML); - if(!six::Init::isUndefined(collectionID.illuminatorName)) - { - createString("IlluminatorName", collectionID.illuminatorName, collectionXML); - } - createString("CoreName", collectionID.coreName, collectionXML); - createString("CollectType", collectionID.collectType, collectionXML); - - // RadarMode - XMLElem radarModeXML = newElement("RadarMode", collectionXML); - createSixString("ModeType", collectionID.radarMode, radarModeXML); - if(!six::Init::isUndefined(collectionID.radarModeID)) - { - createString("ModeID", collectionID.radarModeID, radarModeXML); - } - createString("Classification", collectionID.getClassificationLevel(), collectionXML); - createString("ReleaseInfo", collectionID.releaseInfo, collectionXML); - if (!collectionID.countryCodes.empty()) - { - std::string countryCodes = str::join(collectionID.countryCodes, ","); - createString("CountryCode", countryCodes, collectionXML); - } - mCommon.addParameters("Parameter", getDefaultURI(), collectionID.parameters, collectionXML); - return collectionXML; -} - -XMLElem CPHDXMLParser::toXML(const Global& global, XMLElem parent) -{ - XMLElem globalXML = newElement("Global", parent); - createString("DomainType", global.domainType, globalXML); - createString("SGN", global.sgn, globalXML); - - //Timeline - XMLElem timelineXML = newElement("Timeline", globalXML); - createDateTime("CollectionStart", global.timeline.collectionStart, timelineXML); - if (!six::Init::isUndefined(global.timeline.rcvCollectionStart)) - { - createDateTime("RcvCollectionStart", global.timeline.rcvCollectionStart, timelineXML); - } - createDouble("TxTime1", global.timeline.txTime1, timelineXML); - createDouble("TxTime2", global.timeline.txTime2, timelineXML); - - XMLElem fxBandXML = newElement("FxBand", globalXML); - createDouble("FxMin", global.fxBand.fxMin, fxBandXML); - createDouble("FxMax", global.fxBand.fxMax, fxBandXML); - - XMLElem toaSwathXML = newElement("TOASwath", globalXML); - createDouble("TOAMin", global.toaSwath.toaMin, toaSwathXML); - createDouble("TOAMax", global.toaSwath.toaMax, toaSwathXML); - - if (global.tropoParameters.get()) - { - XMLElem tropoXML = newElement("TropoParameters", globalXML); - createDouble("N0", global.tropoParameters->n0, tropoXML); - createString("RefHeight", global.tropoParameters->refHeight, tropoXML); - } - if (global.ionoParameters.get()) - { - XMLElem ionoXML = newElement("IonoParameters", globalXML); - createDouble("TECV", global.ionoParameters->tecv, ionoXML); - createOptionalDouble("F2Height", global.ionoParameters->f2Height, ionoXML); - } - return globalXML; -} - -XMLElem CPHDXMLParser::toXML(const SceneCoordinates& sceneCoords, XMLElem parent) -{ - XMLElem sceneCoordsXML = newElement("SceneCoordinates", parent); - createString("EarthModel", sceneCoords.earthModel, sceneCoordsXML); - - XMLElem iarpXML = newElement("IARP", sceneCoordsXML); - mCommon.createVector3D("ECF", sceneCoords.iarp.ecf, iarpXML); - mCommon.createLatLonAlt("LLH", sceneCoords.iarp.llh, iarpXML); - - XMLElem refSurfXML = newElement("ReferenceSurface", sceneCoordsXML); - if (sceneCoords.referenceSurface.planar.get()) - { - XMLElem planarXML = newElement("Planar", refSurfXML); - mCommon.createVector3D("uIAX", sceneCoords.referenceSurface.planar->uIax, planarXML); - mCommon.createVector3D("uIAY", sceneCoords.referenceSurface.planar->uIay, planarXML); - } - else if (sceneCoords.referenceSurface.hae.get()) - { - XMLElem haeXML = newElement("HAE", refSurfXML); - mCommon.createLatLon("uIAXLL", sceneCoords.referenceSurface.hae->uIax, haeXML); - mCommon.createLatLon("uIAYLL", sceneCoords.referenceSurface.hae->uIay, haeXML); - } - else - { - throw except::Exception(Ctxt( - "Reference Surface must be one of two types")); - } - - XMLElem imageAreaXML = newElement("ImageArea", sceneCoordsXML); - mCommon.createVector2D("X1Y1", sceneCoords.imageArea.x1y1, imageAreaXML); - mCommon.createVector2D("X2Y2", sceneCoords.imageArea.x2y2, imageAreaXML); - - if (!sceneCoords.imageArea.polygon.empty()) - { - XMLElem polygonXML = newElement("Polygon", imageAreaXML); - setAttribute(polygonXML, "size", sceneCoords.imageArea.polygon.size()); - for (size_t ii = 0; ii < sceneCoords.imageArea.polygon.size(); ++ii) - { - XMLElem vertexXML = mCommon.createVector2D("Vertex", sceneCoords.imageArea.polygon[ii], polygonXML); - setAttribute(vertexXML, "index", ii+1); - } - } - createLatLonFootprint("ImageAreaCornerPoints", "IACP", sceneCoords.imageAreaCorners, sceneCoordsXML); - - // Extended Area (Optional) - if(sceneCoords.extendedArea.get()) - { - XMLElem extendedAreaXML = newElement("ExtendedArea", sceneCoordsXML); - mCommon.createVector2D("X1Y1", sceneCoords.extendedArea->x1y1, extendedAreaXML); - mCommon.createVector2D("X2Y2", sceneCoords.extendedArea->x2y2, extendedAreaXML); - - if (!sceneCoords.extendedArea->polygon.empty()) - { - XMLElem polygonXML = newElement("Polygon", sceneCoordsXML); - setAttribute(polygonXML, "size", sceneCoords.extendedArea->polygon.size()); - for (size_t ii = 0; ii < sceneCoords.extendedArea->polygon.size(); ++ii) - { - XMLElem vertexXML = mCommon.createVector2D("Vertex", sceneCoords.extendedArea->polygon[ii], polygonXML); - setAttribute(vertexXML, "index", ii+1); - } - } - } - - // ImageGrid (Optional) - if(sceneCoords.imageGrid.get()) - { - XMLElem imageGridXML = newElement("ImageGrid", sceneCoordsXML); - if(!six::Init::isUndefined(sceneCoords.imageGrid->identifier)) - { - createString("Identifier", sceneCoords.imageGrid->identifier, imageGridXML); - } - XMLElem iarpLocationXML = newElement("IARPLocation", imageGridXML); - createDouble("Line", sceneCoords.imageGrid->iarpLocation.line, iarpLocationXML); - createDouble("Sample", sceneCoords.imageGrid->iarpLocation.sample, iarpLocationXML); - - XMLElem iaxExtentXML = newElement("IAXExtent", imageGridXML); - createDouble("LineSpacing", sceneCoords.imageGrid->xExtent.lineSpacing, iaxExtentXML); - createInt("FirstLine", sceneCoords.imageGrid->xExtent.firstLine, iaxExtentXML); - createInt("NumLines", sceneCoords.imageGrid->xExtent.numLines, iaxExtentXML); - - XMLElem iayExtentXML = newElement("IAYExtent", imageGridXML); - createDouble("SampleSpacing", sceneCoords.imageGrid->yExtent.sampleSpacing, iayExtentXML); - createInt("FirstSample", sceneCoords.imageGrid->yExtent.firstSample, iayExtentXML); - createInt("NumSamples", sceneCoords.imageGrid->yExtent.numSamples, iayExtentXML); - - if (!sceneCoords.imageGrid->segments.empty()) - { - XMLElem segmentListXML = newElement("SegmentList", imageGridXML); - createInt("NumSegments", sceneCoords.imageGrid->segments.size(), segmentListXML); - - for (size_t ii = 0; ii < sceneCoords.imageGrid->segments.size(); ++ii) - { - XMLElem segmentXML = newElement("Segment", segmentListXML); - createString("Identifier", sceneCoords.imageGrid->segments[ii].identifier, segmentXML); - createInt("StartLine", sceneCoords.imageGrid->segments[ii].startLine, segmentXML); - createInt("StartSample", sceneCoords.imageGrid->segments[ii].startSample, segmentXML); - createInt("EndLine", sceneCoords.imageGrid->segments[ii].endLine, segmentXML); - createInt("EndSample", sceneCoords.imageGrid->segments[ii].endSample, segmentXML); - - if (!sceneCoords.imageGrid->segments[ii].polygon.empty()) - { - XMLElem polygonXML = newElement("SegmentPolygon", segmentXML); - setAttribute(polygonXML, "size", sceneCoords.imageGrid->segments[ii].polygon.size()); - for (size_t jj = 0; jj < sceneCoords.imageGrid->segments[ii].polygon.size(); ++jj) - { - XMLElem svXML = newElement("SV", polygonXML); - setAttribute(svXML, "index", sceneCoords.imageGrid->segments[ii].polygon[jj].getIndex()); - createDouble("Line", sceneCoords.imageGrid->segments[ii].polygon[jj].line, svXML); - createDouble("Sample", sceneCoords.imageGrid->segments[ii].polygon[jj].sample, svXML); - } - } - } - } - } - return sceneCoordsXML; -} - -XMLElem CPHDXMLParser::toXML(const Data& data, XMLElem parent) -{ - XMLElem dataXML = newElement("Data", parent); - createString("SignalArrayFormat", data.signalArrayFormat, dataXML); - createInt("NumBytesPVP", data.numBytesPVP, dataXML); - createInt("NumCPHDChannels", data.channels.size(), dataXML); - if (!six::Init::isUndefined(data.signalCompressionID)) - { - createString("SignalCompressionID", data.signalCompressionID, dataXML); - } - - for (size_t ii = 0; ii < data.channels.size(); ++ii) - { - XMLElem channelXML = newElement("Channel", dataXML); - createString("Identifier", data.channels[ii].identifier, channelXML); - createInt("NumVectors", data.channels[ii].numVectors, channelXML); - createInt("NumSamples", data.channels[ii].numSamples, channelXML); - createInt("SignalArrayByteOffset", data.channels[ii].signalArrayByteOffset, channelXML); - createInt("PVPArrayByteOffset", data.channels[ii].pvpArrayByteOffset, channelXML); - if(!six::Init::isUndefined(data.channels[ii].compressedSignalSize)) - { - createInt("CompressedSignalSize", data.channels[ii].compressedSignalSize, channelXML); - } - } - createInt("NumSupportArrays", data.supportArrayMap.size(), dataXML); - for (const auto& entry : data.supportArrayMap) - { - XMLElem supportArrayXML = newElement("SupportArray", dataXML); - createString("Identifier", entry.second.identifier, supportArrayXML); - createInt("NumRows", entry.second.numRows, supportArrayXML); - createInt("NumCols", entry.second.numCols, supportArrayXML); - createInt("BytesPerElement", entry.second.bytesPerElement, supportArrayXML); - createInt("ArrayByteOffset", entry.second.arrayByteOffset, supportArrayXML); - } - return dataXML; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem pXML = nullptr; - if (has_value(o)) - { - pXML = newElement(o.tag(), &parent); - std::ignore = create(parser(), value(o).ampH, *pXML); - std::ignore = create(parser(), value(o).ampV, *pXML); - std::ignore = create(parser(), value(o).phaseV, *pXML); - } - - return pXML; -} - -XMLElem CPHDXMLParser::toXML(const Polarization& obj, xml::lite::Element& parent) -{ - auto polXML = newElement("Polarization", &parent); - createString("TxPol", obj.txPol, polXML); - createString("RcvPol", obj.rcvPol, polXML); - - toXML(obj.txPolRef, *polXML); // added in CPHD 1.1.0 - toXML(obj.rcvPolRef, *polXML); // added in CPHD 1.1.0 - - return polXML; -} - -XMLElem CPHDXMLParser::toXML(const Channel& channel, XMLElem parent) -{ - XMLElem channelXML = newElement("Channel", parent); - createString("RefChId", channel.refChId, channelXML); - createBooleanType("FXFixedCPHD", channel.fxFixedCphd, channelXML); - createBooleanType("TOAFixedCPHD", channel.toaFixedCphd, channelXML); - createBooleanType("SRPFixedCPHD", channel.srpFixedCphd, channelXML); - - for (size_t ii = 0; ii < channel.parameters.size(); ++ii) - { - XMLElem parametersXML = newElement("Parameters", channelXML); - createString("Identifier", channel.parameters[ii].identifier, parametersXML); - createInt("RefVectorIndex", channel.parameters[ii].refVectorIndex, parametersXML); - createBooleanType("FXFixed", channel.parameters[ii].fxFixed, parametersXML); - createBooleanType("TOAFixed", channel.parameters[ii].toaFixed, parametersXML); - createBooleanType("SRPFixed", channel.parameters[ii].srpFixed, parametersXML); - if (!six::Init::isUndefined(channel.parameters[ii].signalNormal)) - { - createBooleanType("SignalNormal", channel.parameters[ii].signalNormal, parametersXML); - } - std::ignore = toXML(channel.parameters[ii].polarization, *parametersXML); - - createDouble("FxC", channel.parameters[ii].fxC, parametersXML); - createDouble("FxBW", channel.parameters[ii].fxBW, parametersXML); - createOptionalDouble("FxBWNoise", channel.parameters[ii].fxBWNoise, parametersXML); - createDouble("TOASaved", channel.parameters[ii].toaSaved, parametersXML); - - if(channel.parameters[ii].toaExtended.get()) - { - XMLElem toaExtendedXML = newElement("TOAExtended", parametersXML); - createDouble("TOAExtSaved", channel.parameters[ii].toaExtended->toaExtSaved, toaExtendedXML); - if(channel.parameters[ii].toaExtended->lfmEclipse.get()) - { - XMLElem lfmEclipseXML = newElement("LFMEclipse", toaExtendedXML); - createDouble("FxEarlyLow", channel.parameters[ii].toaExtended->lfmEclipse->fxEarlyLow, lfmEclipseXML); - createDouble("FxEarlyHigh", channel.parameters[ii].toaExtended->lfmEclipse->fxEarlyHigh, lfmEclipseXML); - createDouble("FxLateLow", channel.parameters[ii].toaExtended->lfmEclipse->fxLateLow, lfmEclipseXML); - createDouble("FxLateHigh", channel.parameters[ii].toaExtended->lfmEclipse->fxLateHigh, lfmEclipseXML); - } - } - XMLElem dwellTimesXML = newElement("DwellTimes", parametersXML); - createString("CODId", channel.parameters[ii].dwellTimes.codId, dwellTimesXML); - createString("DwellId", channel.parameters[ii].dwellTimes.dwellId, dwellTimesXML); - std::ignore = create(parser(), channel.parameters[ii].dwellTimes.dtaId, *dwellTimesXML); - std::ignore = create(parser(), channel.parameters[ii].dwellTimes.useDTA, *dwellTimesXML); - - if(!six::Init::isUndefined(channel.parameters[ii].imageArea)) - { - XMLElem imageAreaXML = newElement("ImageArea", parametersXML); - mCommon.createVector2D("X1Y1", channel.parameters[ii].imageArea.x1y1, imageAreaXML); - mCommon.createVector2D("X2Y2", channel.parameters[ii].imageArea.x2y2, imageAreaXML); - if(!channel.parameters[ii].imageArea.polygon.empty()) - { - XMLElem polygonXML = newElement("Polygon", imageAreaXML); - setAttribute(polygonXML, "size", channel.parameters[ii].imageArea.polygon.size()); - for (size_t jj = 0; jj < channel.parameters[ii].imageArea.polygon.size(); ++jj) - { - XMLElem vertexXML = mCommon.createVector2D("Vertex", channel.parameters[ii].imageArea.polygon[jj], polygonXML); - setAttribute(vertexXML, "index", jj+1); - } - } - } - if(channel.parameters[ii].antenna.get()) - { - XMLElem antennaXML = newElement("Antenna", parametersXML); - createString("TxAPCId", channel.parameters[ii].antenna->txAPCId, antennaXML); - createString("TxAPATId", channel.parameters[ii].antenna->txAPATId, antennaXML); - createString("RcvAPCId", channel.parameters[ii].antenna->rcvAPCId, antennaXML); - createString("RcvAPATId", channel.parameters[ii].antenna->rcvAPATId, antennaXML); - } - if(channel.parameters[ii].txRcv.get()) - { - XMLElem txRcvXML = newElement("TxRcv", parametersXML); - for (size_t jj = 0; jj < channel.parameters[ii].txRcv->txWFId.size(); ++jj) - { - createString("TxWFId", channel.parameters[ii].txRcv->txWFId[jj], txRcvXML); - } - for (size_t jj = 0; jj < channel.parameters[ii].txRcv->rcvId.size(); ++jj) - { - createString("RcvId", channel.parameters[ii].txRcv->rcvId[jj], txRcvXML); - } - } - if(channel.parameters[ii].tgtRefLevel.get()) - { - XMLElem tgtRefXML = newElement("TgtRefLevel", parametersXML); - createDouble("PTRef", channel.parameters[ii].tgtRefLevel->ptRef, tgtRefXML); - } - if(channel.parameters[ii].noiseLevel.get()) - { - XMLElem noiseLevelXML = newElement("NoiseLevel", parametersXML); - createDouble("PNRef", channel.parameters[ii].noiseLevel->pnRef, noiseLevelXML); - createDouble("BNRef", channel.parameters[ii].noiseLevel->bnRef, noiseLevelXML); - if(channel.parameters[ii].noiseLevel->fxNoiseProfile.get()) - { - XMLElem fxNoiseProfileXML = newElement("FxNoiseProfile", noiseLevelXML); - for (size_t jj = 0; jj < channel.parameters[ii].noiseLevel->fxNoiseProfile->point.size(); ++jj) - { - XMLElem pointXML = newElement("Point", fxNoiseProfileXML); - createDouble("Fx", channel.parameters[ii].noiseLevel->fxNoiseProfile->point[jj].fx, pointXML); - createDouble("PN", channel.parameters[ii].noiseLevel->fxNoiseProfile->point[jj].pn, pointXML); - } - } - } - } - if(!channel.addedParameters.empty()) - { - XMLElem addedParamsXML = newElement("AddedParameters", channelXML); - mCommon.addParameters("Parameter", getDefaultURI(), channel.addedParameters, addedParamsXML); - } - return channelXML; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement& v, xml::lite::Element& parent) -{ - return createPVPType(v.tag(), v.value().param, &parent); -} -XMLElem CPHDXMLParser::toXML(const six::XsElement& v, xml::lite::Element& parent) -{ - return createPVPType(v.tag(), v.value().param, &parent); -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem pXML = nullptr; - if (has_value(o)) - { - pXML = newElement(o.tag(), &parent); - std::ignore = toXML(value(o).txACX, *pXML); - std::ignore = toXML(value(o).txACY, *pXML); - std::ignore = toXML(value(o).txEB, *pXML); - } - - return pXML; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem pXML = nullptr; - if (has_value(o)) - { - pXML = newElement(o.tag(), &parent); - std::ignore = toXML(value(o).rcvACX, *pXML); - std::ignore = toXML(value(o).rcvACY, *pXML); - std::ignore = toXML(value(o).rcvEB, *pXML); - } - - return pXML; -} - -XMLElem CPHDXMLParser::toXML(const Pvp& pvp, XMLElem parent) -{ - XMLElem pvpXML = newElement("PVP", parent); - createPVPType("TxTime", pvp.txTime, pvpXML); - createPVPType("TxPos", pvp.txPos, pvpXML); - createPVPType("TxVel", pvp.txVel, pvpXML); - createPVPType("RcvTime", pvp.rcvTime, pvpXML); - createPVPType("RcvPos", pvp.rcvPos, pvpXML); - createPVPType("RcvVel", pvp.rcvVel, pvpXML); - createPVPType("SRPPos", pvp.srpPos, pvpXML); - if (!six::Init::isUndefined(pvp.ampSF.getOffset())) - { - createPVPType("AmpSF", pvp.ampSF, pvpXML); - } - createPVPType("aFDOP", pvp.aFDOP, pvpXML); - createPVPType("aFRR1", pvp.aFRR1, pvpXML); - createPVPType("aFRR2", pvp.aFRR2, pvpXML); - createPVPType("FX1", pvp.fx1, pvpXML); - createPVPType("FX2", pvp.fx2, pvpXML); - if (!six::Init::isUndefined(pvp.fxN1.getOffset())) - { - createPVPType("FXN1", pvp.fxN1, pvpXML); - } - if (!six::Init::isUndefined(pvp.fxN2.getOffset())) - { - createPVPType("FXN2", pvp.fxN2, pvpXML); - } - createPVPType("TOA1", pvp.toa1, pvpXML); - createPVPType("TOA2", pvp.toa2, pvpXML); - if (!six::Init::isUndefined(pvp.toaE1.getOffset())) - { - createPVPType("TOAE1", pvp.toaE1, pvpXML); - } - if (!six::Init::isUndefined(pvp.toaE2.getOffset())) - { - createPVPType("TOAE2", pvp.toaE2, pvpXML); - } - createPVPType("TDTropoSRP", pvp.tdTropoSRP, pvpXML); - if (!six::Init::isUndefined(pvp.tdIonoSRP.getOffset())) - { - createPVPType("TDIonoSRP", pvp.tdIonoSRP, pvpXML); - } - createPVPType("SC0", pvp.sc0, pvpXML); - createPVPType("SCSS", pvp.scss, pvpXML); - if (!six::Init::isUndefined(pvp.signal.getOffset())) - { - createPVPType("SIGNAL", pvp.signal, pvpXML); - } - - std::ignore = toXML(pvp.txAntenna, *pvpXML); - std::ignore = toXML(pvp.rcvAntenna, *pvpXML); - - for (auto it = pvp.addedPVP.begin(); it != pvp.addedPVP.end(); ++it) - { - createAPVPType("AddedPVP", it->second, pvpXML); - } - - return pvpXML; -} - -void CPHDXMLParser::createSupportArray(const std::vector& supportArray, - const std::string& tag, xml::lite::Element& parent) -{ - for (auto&& param : supportArray) - { - XMLElem pXML = newElement(tag, &parent); - createInt("Identifier", param.getIdentifier(), pXML); - createString("ElementFormat", param.elementFormat, pXML); - createDouble("X0", param.x0, pXML); - createDouble("Y0", param.y0, pXML); - createDouble("XSS", param.xSS, pXML); - createDouble("YSS", param.ySS, pXML); - - } -} - -//Assumes optional handled by caller -XMLElem CPHDXMLParser::toXML(const SupportArray& supports, XMLElem parent) -{ - XMLElem supportsXML = newElement("SupportArray", parent); - createSupportArray(supports.iazArray, "IAZArray", *supportsXML); - createSupportArray(supports.antGainPhase, "AntGainPhase", *supportsXML); - createSupportArray(supports.dwellTimeArray, "DwellTimeArray", *supportsXML); // added in CPHD 1.1.0 - - if (!supports.addedSupportArray.empty()) - { - for (auto it = supports.addedSupportArray.begin(); it != supports.addedSupportArray.end(); ++it) - { - XMLElem addedSupportArrayXML = newElement("AddedSupportArray", supportsXML); - createString("Identifier", it->first, addedSupportArrayXML); - createString("ElementFormat", it->second.elementFormat, addedSupportArrayXML); - createDouble("X0", it->second.x0, addedSupportArrayXML); - createDouble("Y0", it->second.y0, addedSupportArrayXML); - createDouble("XSS", it->second.xSS, addedSupportArrayXML); - createDouble("YSS", it->second.ySS, addedSupportArrayXML); - createString("XUnits", it->second.xUnits, addedSupportArrayXML); - createString("YUnits", it->second.yUnits, addedSupportArrayXML); - createString("ZUnits", it->second.zUnits, addedSupportArrayXML); - mCommon.addParameters("Parameter", getDefaultURI(), it->second.parameter, addedSupportArrayXML); - } - } - return supportsXML; -} - -XMLElem CPHDXMLParser::toXML(const Dwell& dwell, XMLElem parent) -{ - XMLElem dwellXML = newElement("Dwell", parent); - createInt("NumCODTimes", dwell.cod.size(), dwellXML); - - for (size_t ii = 0; ii < dwell.cod.size(); ++ii) - { - XMLElem codTimeXML = newElement("CODTime", dwellXML); - createString("Identifier", dwell.cod[ii].identifier, codTimeXML); - mCommon.createPoly2D("CODTimePoly", dwell.cod[ii].codTimePoly, codTimeXML); - } - createInt("NumDwellTimes", dwell.dtime.size(), dwellXML); - for (size_t ii = 0; ii < dwell.dtime.size(); ++ii) - { - XMLElem dwellTimeXML = newElement("DwellTime", dwellXML); - createString("Identifier", dwell.dtime[ii].identifier, dwellTimeXML); - mCommon.createPoly2D("DwellTimePoly", dwell.dtime[ii].dwellTimePoly, dwellTimeXML); - } - return dwellXML; -} - -XMLElem CPHDXMLParser::toXML(const ReferenceGeometry& refGeo, XMLElem parent) -{ - XMLElem refGeoXML = newElement("ReferenceGeometry", parent); - XMLElem srpXML = newElement("SRP", refGeoXML); - mCommon.createVector3D("ECF", refGeo.srp.ecf, srpXML); - mCommon.createVector3D("IAC", refGeo.srp.iac, srpXML); - createDouble("ReferenceTime", refGeo.referenceTime, refGeoXML); - createDouble("SRPCODTime", refGeo.srpCODTime, refGeoXML); - createDouble("SRPDwellTime", refGeo.srpDwellTime, refGeoXML); - - if (refGeo.monostatic.get()) - { - XMLElem monoXML = newElement("Monostatic", refGeoXML); - mCommon.createVector3D("ARPPos", refGeo.monostatic->arpPos, monoXML); - mCommon.createVector3D("ARPVel", refGeo.monostatic->arpVel, monoXML); - const auto side = refGeo.monostatic->sideOfTrack.toString(); - createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), monoXML); - createDouble("SlantRange", refGeo.monostatic->slantRange, monoXML); - createDouble("GroundRange", refGeo.monostatic->groundRange, monoXML); - createDouble("DopplerConeAngle", refGeo.monostatic->dopplerConeAngle, monoXML); - createDouble("GrazeAngle", refGeo.monostatic->grazeAngle, monoXML); - createDouble("IncidenceAngle", refGeo.monostatic->incidenceAngle, monoXML); - createDouble("AzimuthAngle", refGeo.monostatic->azimuthAngle, monoXML); - createDouble("TwistAngle", refGeo.monostatic->twistAngle, monoXML); - createDouble("SlopeAngle", refGeo.monostatic->slopeAngle, monoXML); - createDouble("LayoverAngle", refGeo.monostatic->layoverAngle, monoXML); - } - else if(refGeo.bistatic.get()) - { - XMLElem biXML = newElement("Bistatic", refGeoXML); - createDouble("AzimuthAngle", refGeo.bistatic->azimuthAngle, biXML); - createDouble("AzimuthAngleRate", refGeo.bistatic->azimuthAngleRate, biXML); - createDouble("BistaticAngle", refGeo.bistatic->bistaticAngle, biXML); - createDouble("BistaticAngleRate", refGeo.bistatic->bistaticAngleRate, biXML); - createDouble("GrazeAngle", refGeo.bistatic->grazeAngle, biXML); - createDouble("TwistAngle", refGeo.bistatic->twistAngle, biXML); - createDouble("SlopeAngle", refGeo.bistatic->slopeAngle, biXML); - createDouble("LayoverAngle", refGeo.bistatic->layoverAngle, biXML); - XMLElem txPlatXML = newElement("TxPlatform", biXML); - createDouble("Time", refGeo.bistatic->txPlatform.time, txPlatXML); - mCommon.createVector3D("Pos", refGeo.bistatic->txPlatform.pos, txPlatXML); - mCommon.createVector3D("Vel", refGeo.bistatic->txPlatform.vel, txPlatXML); - - { - const auto side = refGeo.bistatic->txPlatform.sideOfTrack.toString(); - createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), txPlatXML); - } - createDouble("SlantRange", refGeo.bistatic->txPlatform.slantRange, txPlatXML); - createDouble("GroundRange", refGeo.bistatic->txPlatform.groundRange, txPlatXML); - createDouble("DopplerConeAngle", refGeo.bistatic->txPlatform.dopplerConeAngle, txPlatXML); - createDouble("GrazeAngle", refGeo.bistatic->txPlatform.grazeAngle, txPlatXML); - createDouble("IncidenceAngle", refGeo.bistatic->txPlatform.incidenceAngle, txPlatXML); - createDouble("AzimuthAngle", refGeo.bistatic->txPlatform.azimuthAngle, txPlatXML); - XMLElem rcvPlatXML = newElement("RcvPlatform", biXML); - createDouble("Time", refGeo.bistatic->rcvPlatform.time, rcvPlatXML); - mCommon.createVector3D("Pos", refGeo.bistatic->rcvPlatform.pos, rcvPlatXML); - mCommon.createVector3D("Vel", refGeo.bistatic->rcvPlatform.vel, rcvPlatXML); - - { - const auto side = refGeo.bistatic->rcvPlatform.sideOfTrack.toString(); - createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), rcvPlatXML); - } - createDouble("SlantRange", refGeo.bistatic->rcvPlatform.slantRange, rcvPlatXML); - createDouble("GroundRange", refGeo.bistatic->rcvPlatform.groundRange, rcvPlatXML); - createDouble("DopplerConeAngle", refGeo.bistatic->rcvPlatform.dopplerConeAngle, rcvPlatXML); - createDouble("GrazeAngle", refGeo.bistatic->rcvPlatform.grazeAngle, rcvPlatXML); - createDouble("IncidenceAngle", refGeo.bistatic->rcvPlatform.incidenceAngle, rcvPlatXML); - createDouble("AzimuthAngle", refGeo.bistatic->rcvPlatform.azimuthAngle, rcvPlatXML); - } - return refGeoXML; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem retval = nullptr; - if (has_value(o)) - { - retval = newElement(o.tag(), &parent); - std::ignore = create(parser(), value(o).dcxsf, *retval); - std::ignore = create(parser(), value(o).dcysf, *retval); - } - - return retval; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem retval = nullptr; - if (has_value(o)) - { - retval = newElement(o.tag(), &parent); - std::ignore = create(parser(), value(o).dcxsf, *retval); - std::ignore = create(parser(), value(o).dcysf, *retval); - } - - return retval; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem retval = nullptr; - if (has_value(o)) - { - retval = newElement(o.tag(), &parent); - std::ignore = create(parser(), value(o).ampX, *retval); - std::ignore = create(parser(), value(o).ampY, *retval); - std::ignore = create(parser(), value(o).phaseY, *retval); - } - - return retval; -} - -XMLElem CPHDXMLParser::toXML(const Antenna& antenna, XMLElem parent) -{ - XMLElem antennaXML = newElement("Antenna", parent); - createInt("NumACFs", antenna.antCoordFrame.size(), antennaXML); - createInt("NumAPCs", antenna.antPhaseCenter.size(), antennaXML); - createInt("NumAntPats", antenna.antPattern.size(), antennaXML); - for (size_t ii = 0; ii < antenna.antCoordFrame.size(); ++ii) - { - XMLElem antCoordFrameXML = newElement("AntCoordFrame", antennaXML); - createString("Identifier", antenna.antCoordFrame[ii].identifier, antCoordFrameXML); - mCommon.createPolyXYZ("XAxisPoly", antenna.antCoordFrame[ii].xAxisPoly, antCoordFrameXML); - mCommon.createPolyXYZ("YAxisPoly", antenna.antCoordFrame[ii].yAxisPoly, antCoordFrameXML); - create(parser(), antenna.antCoordFrame[ii].useACFPVP, *antCoordFrameXML); - } - for (size_t ii = 0; ii < antenna.antPhaseCenter.size(); ++ii) - { - XMLElem antPhaseCenterXML = newElement("AntPhaseCenter", antennaXML); - createString("Identifier", antenna.antPhaseCenter[ii].identifier, antPhaseCenterXML); - createString("ACFId", antenna.antPhaseCenter[ii].acfId, antPhaseCenterXML); - mCommon.createVector3D("APCXYZ", antenna.antPhaseCenter[ii].apcXYZ, antPhaseCenterXML); - } - for (size_t ii = 0; ii < antenna.antPattern.size(); ++ii) - { - XMLElem antPatternXML = newElement("AntPattern", antennaXML); - createString("Identifier", antenna.antPattern[ii].identifier, antPatternXML); - createDouble("FreqZero", antenna.antPattern[ii].freqZero, antPatternXML); - createOptionalDouble("GainZero", antenna.antPattern[ii].gainZero, antPatternXML); - if (!six::Init::isUndefined(antenna.antPattern[ii].ebFreqShift)) - { - createBooleanType("EBFreqShift", antenna.antPattern[ii].ebFreqShift, antPatternXML); - } - std::ignore = toXML(antenna.antPattern[ii].ebFreqShiftSF, *antPatternXML); - - if (!six::Init::isUndefined(antenna.antPattern[ii].mlFreqDilation)) - { - createBooleanType("MLFreqDilation", antenna.antPattern[ii].mlFreqDilation, antPatternXML); - } - std::ignore = toXML(antenna.antPattern[ii].mlFreqDilationSF, *antPatternXML); - - if (!six::Init::isUndefined(antenna.antPattern[ii].gainBSPoly)) - { - mCommon.createPoly1D("GainBSPoly", antenna.antPattern[ii].gainBSPoly, antPatternXML); - } - - std::ignore = toXML(antenna.antPattern[ii].antPolRef, *antPatternXML); - - XMLElem ebXML = newElement("EB", antPatternXML); - mCommon.createPoly1D("DCXPoly", antenna.antPattern[ii].eb.dcxPoly, ebXML); - mCommon.createPoly1D("DCYPoly", antenna.antPattern[ii].eb.dcyPoly, ebXML); - create(parser(), antenna.antPattern[ii].eb.useEBPVP, *ebXML); - - XMLElem arrayXML = newElement("Array", antPatternXML); - mCommon.createPoly2D("GainPoly", antenna.antPattern[ii].array.gainPoly, arrayXML); - mCommon.createPoly2D("PhasePoly", antenna.antPattern[ii].array.phasePoly, arrayXML); - create(parser(), antenna.antPattern[ii].array.antGPId, *arrayXML); - - XMLElem elementXML = newElement("Element", antPatternXML); - mCommon.createPoly2D("GainPoly", antenna.antPattern[ii].element.gainPoly, elementXML); - mCommon.createPoly2D("PhasePoly", antenna.antPattern[ii].element.phasePoly, elementXML); - for (size_t jj = 0; jj < antenna.antPattern[ii].gainPhaseArray.size(); ++jj) - { - XMLElem gainPhaseArrayXML = newElement("GainPhaseArray", antPatternXML); - createDouble("Freq", antenna.antPattern[ii].gainPhaseArray[jj].freq, gainPhaseArrayXML); - createString("ArrayId", antenna.antPattern[ii].gainPhaseArray[jj].arrayId, gainPhaseArrayXML); - if (!six::Init::isUndefined(antenna.antPattern[ii].gainPhaseArray[jj].elementId)) - { - createString("ElementId", antenna.antPattern[ii].gainPhaseArray[jj].elementId, gainPhaseArrayXML); - } - } - } - return antennaXML; -} - -XMLElem CPHDXMLParser::toXML(const TxRcv& txRcv, XMLElem parent) -{ - XMLElem txRcvXML = newElement("TxRcv", parent); - createInt("NumTxWFs", txRcv.txWFParameters.size(), txRcvXML); - for (size_t ii = 0; ii < txRcv.txWFParameters.size(); ++ii) - { - XMLElem txWFParamsXML = newElement("TxWFParameters", txRcvXML); - createString("Identifier", txRcv.txWFParameters[ii].identifier, txWFParamsXML); - createDouble("PulseLength", txRcv.txWFParameters[ii].pulseLength, txWFParamsXML); - createDouble("RFBandwidth", txRcv.txWFParameters[ii].rfBandwidth, txWFParamsXML); - createDouble("FreqCenter", txRcv.txWFParameters[ii].freqCenter, txWFParamsXML); - createOptionalDouble("LFMRate", txRcv.txWFParameters[ii].lfmRate, txWFParamsXML); - createString("Polarization", txRcv.txWFParameters[ii].polarization, txWFParamsXML); - createOptionalDouble("Power", txRcv.txWFParameters[ii].power, txWFParamsXML); - } - createInt("NumRcvs", txRcv.rcvParameters.size(), txRcvXML); - for (size_t ii = 0; ii < txRcv.rcvParameters.size(); ++ii) - { - XMLElem rcvParamsXML = newElement("RcvParameters", txRcvXML); - createString("Identifier", txRcv.rcvParameters[ii].identifier, rcvParamsXML); - createDouble("WindowLength", txRcv.rcvParameters[ii].windowLength, rcvParamsXML); - createDouble("SampleRate", txRcv.rcvParameters[ii].sampleRate, rcvParamsXML); - createDouble("IFFilterBW", txRcv.rcvParameters[ii].ifFilterBW, rcvParamsXML); - createDouble("FreqCenter", txRcv.rcvParameters[ii].freqCenter, rcvParamsXML); - createOptionalDouble("LFMRate", txRcv.rcvParameters[ii].lfmRate, rcvParamsXML); - createString("Polarization", txRcv.rcvParameters[ii].polarization, rcvParamsXML); - createOptionalDouble("PathGain", txRcv.rcvParameters[ii].pathGain, rcvParamsXML); - } - return txRcvXML; -} - -XMLElem CPHDXMLParser::toXML(const ErrorParameters& errParams, XMLElem parent) -{ - XMLElem errParamsXML = newElement("ErrorParameters", parent); - if (errParams.monostatic.get()) - { - XMLElem monoXML = newElement("Monostatic", errParamsXML); - XMLElem posVelErrXML = newElement("PosVelErr", monoXML); - createString("Frame", errParams.monostatic->posVelErr.frame, posVelErrXML); - createDouble("P1", errParams.monostatic->posVelErr.p1, posVelErrXML); - createDouble("P2", errParams.monostatic->posVelErr.p2, posVelErrXML); - createDouble("P3", errParams.monostatic->posVelErr.p3, posVelErrXML); - createDouble("V1", errParams.monostatic->posVelErr.v1, posVelErrXML); - createDouble("V2", errParams.monostatic->posVelErr.v2, posVelErrXML); - createDouble("V3", errParams.monostatic->posVelErr.v3, posVelErrXML); - if(errParams.monostatic->posVelErr.corrCoefs.get()) - { - XMLElem corrCoefsXML = newElement("CorrCoefs", posVelErrXML); - createDouble("P1P2", errParams.monostatic->posVelErr.corrCoefs->p1p2, corrCoefsXML); - createDouble("P1P3", errParams.monostatic->posVelErr.corrCoefs->p1p3, corrCoefsXML); - createDouble("P1V1", errParams.monostatic->posVelErr.corrCoefs->p1v1, corrCoefsXML); - createDouble("P1V2", errParams.monostatic->posVelErr.corrCoefs->p1v2, corrCoefsXML); - createDouble("P1V3", errParams.monostatic->posVelErr.corrCoefs->p1v3, corrCoefsXML); - createDouble("P2P3", errParams.monostatic->posVelErr.corrCoefs->p2p3, corrCoefsXML); - createDouble("P2V1", errParams.monostatic->posVelErr.corrCoefs->p2v1, corrCoefsXML); - createDouble("P2V2", errParams.monostatic->posVelErr.corrCoefs->p2v2, corrCoefsXML); - createDouble("P2V3", errParams.monostatic->posVelErr.corrCoefs->p2v3, corrCoefsXML); - createDouble("P3V1", errParams.monostatic->posVelErr.corrCoefs->p3v1, corrCoefsXML); - createDouble("P3V2", errParams.monostatic->posVelErr.corrCoefs->p3v2, corrCoefsXML); - createDouble("P3V3", errParams.monostatic->posVelErr.corrCoefs->p3v3, corrCoefsXML); - createDouble("V1V2", errParams.monostatic->posVelErr.corrCoefs->v1v2, corrCoefsXML); - createDouble("V1V3", errParams.monostatic->posVelErr.corrCoefs->v1v3, corrCoefsXML); - createDouble("V2V3", errParams.monostatic->posVelErr.corrCoefs->v2v3, corrCoefsXML); - } - createDecorrType("PositionDecorr", errParams.monostatic->posVelErr.positionDecorr, posVelErrXML); - - // RadarSensor - XMLElem radarXML = newElement("RadarSensor", monoXML); - createDouble("RangeBias", errParams.monostatic->radarSensor.rangeBias, radarXML); - createOptionalDouble("ClockFreqSF", errParams.monostatic->radarSensor.clockFreqSF, radarXML); - createOptionalDouble("CollectionStartTime", errParams.monostatic->radarSensor.collectionStartTime, radarXML); - if (errParams.monostatic->radarSensor.rangeBiasDecorr.get()) - { - XMLElem rangeBiasDecorrXML = newElement("RangeBiasDecorr", radarXML); - createDouble("CorrCoefZero", errParams.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero, rangeBiasDecorrXML); - createDouble("DecorrRate", errParams.monostatic->radarSensor.rangeBiasDecorr->decorrRate, rangeBiasDecorrXML); - } - - if (errParams.monostatic->tropoError.get()) - { - XMLElem tropoXML = newElement("TropoError", monoXML); - createOptionalDouble("TropoRangeVertical", errParams.monostatic->tropoError->tropoRangeVertical, tropoXML); - createOptionalDouble("TropoRangeSlant", errParams.monostatic->tropoError->tropoRangeSlant, tropoXML); - createDecorrType("TropoRangeDecorr", errParams.monostatic->tropoError->tropoRangeDecorr, tropoXML); - } - if (errParams.monostatic->ionoError.get()) - { - XMLElem ionoXML = newElement("IonoError", monoXML); - createDouble("IonoRangeVertical", errParams.monostatic->ionoError->ionoRangeVertical, ionoXML); - createOptionalDouble("IonoRangeRateVertical", errParams.monostatic->ionoError->ionoRangeRateVertical, ionoXML); - createOptionalDouble("IonoRgRgRateCC", errParams.monostatic->ionoError->ionoRgRgRateCC, ionoXML); - createDecorrType("IonoRangeVertDecorr", errParams.monostatic->tropoError->tropoRangeDecorr, ionoXML); - } - if (!errParams.monostatic->parameter.empty()) - { - XMLElem addedParamsXML = newElement("AddedParameters", monoXML); - mCommon.addParameters("Parameter", getDefaultURI(), errParams.monostatic->parameter, addedParamsXML); - } - } - else if (errParams.bistatic.get()) - { - XMLElem biXML = newElement("Bistatic", errParamsXML); - XMLElem txPlatXML = newElement("TxPlatform", biXML); - createErrorParamPlatform("TxPlatform", errParams.bistatic->txPlatform, txPlatXML); - XMLElem radarTxXML = newElement("RadarSensor", txPlatXML); - create(parser(), errParams.bistatic->txPlatform.radarSensor.delayBias, *radarTxXML); - createOptionalDouble("ClockFreqSF", errParams.bistatic->txPlatform.radarSensor.clockFreqSF, radarTxXML); - createDouble("CollectionStartTime", errParams.bistatic->txPlatform.radarSensor.collectionStartTime, radarTxXML); - - XMLElem rcvPlatXML = newElement("RcvPlatform", biXML); - createErrorParamPlatform("RcvPlatform", errParams.bistatic->rcvPlatform, rcvPlatXML); - XMLElem radarRcvXML = newElement("RadarSensor", rcvPlatXML); - createOptionalDouble("ClockFreqSF", errParams.bistatic->rcvPlatform.radarSensor.clockFreqSF, radarRcvXML); - createDouble("CollectionStartTime", errParams.bistatic->rcvPlatform.radarSensor.collectionStartTime, radarRcvXML); - - if (!errParams.bistatic->parameter.empty()) - { - XMLElem addedParamsXML = newElement("AddedParameters", biXML); - mCommon.addParameters("Parameter", getDefaultURI(), errParams.bistatic->parameter, addedParamsXML); - } - } - - return errParamsXML; -} - -XMLElem CPHDXMLParser::toXML(const ProductInfo& productInfo, XMLElem parent) -{ - XMLElem productInfoXML = newElement("ProductInfo", parent); - if(!six::Init::isUndefined(productInfo.profile)) - { - createString("Profile", productInfo.profile, productInfoXML); - } - for (size_t ii = 0; ii < productInfo.creationInfo.size(); ++ii) - { - XMLElem creationInfoXML = newElement("CreationInfo", productInfoXML); - if(!six::Init::isUndefined(productInfo.creationInfo[ii].application)) - { - createString("Application", productInfo.creationInfo[ii].application, creationInfoXML); - } - createDateTime("DateTime", productInfo.creationInfo[ii].dateTime, creationInfoXML); - if (!six::Init::isUndefined(productInfo.creationInfo[ii].site)) - { - createString("Site", productInfo.creationInfo[ii].site, creationInfoXML); - } - mCommon.addParameters("Parameter", getDefaultURI(), productInfo.creationInfo[ii].parameter, creationInfoXML); - } - mCommon.addParameters("Parameter", getDefaultURI(), productInfo.parameter, productInfoXML); - return productInfoXML; -} - -XMLElem CPHDXMLParser::toXML(const GeoInfo& geoInfo, XMLElem parent) -{ - XMLElem geoInfoXML = newElement("GeoInfo", parent); - - mCommon.addParameters("Desc", geoInfo.desc, geoInfoXML); - - const size_t numLatLons = geoInfo.geometryLatLon.size(); - if (numLatLons == 1) - { - mCommon.createLatLon("Point", geoInfo.geometryLatLon[0], geoInfoXML); - } - else if (numLatLons >= 2) - { - XMLElem linePolyXML = newElement(numLatLons == 2 ? "Line" : "Polygon", - geoInfoXML); - setAttribute(linePolyXML, "size", numLatLons); - - for (size_t ii = 0; ii < numLatLons; ++ii) - { - XMLElem v = mCommon.createLatLon(numLatLons == 2 ? "Endpoint" : "Vertex", - geoInfo.geometryLatLon[ii], linePolyXML); - setAttribute(v, "index", ii + 1); - } - } - - if (!geoInfo.name.empty()) - setAttribute(geoInfoXML, "name", geoInfo.name); - - for (size_t ii = 0; ii < geoInfo.geoInfos.size(); ++ii) - { - toXML(*geoInfo.geoInfos[ii], geoInfoXML); - } - - return geoInfoXML; -} - -XMLElem CPHDXMLParser::toXML(const MatchInformation& matchInfo, XMLElem parent) -{ - return mCommon.convertMatchInformationToXML(matchInfo, parent); -} - -/* - * FROM XML - */ - -std::unique_ptr CPHDXMLParser::fromXML( - const xml::lite::Document* doc) -{ - std::unique_ptr cphd(new Metadata()); - - const auto root = doc->getRootElement(); - - XMLElem collectionIDXML = getFirstAndOnly(root, "CollectionID"); - XMLElem globalXML = getFirstAndOnly(root, "Global"); - XMLElem sceneCoordsXML = getFirstAndOnly(root, "SceneCoordinates"); - XMLElem dataXML = getFirstAndOnly(root, "Data"); - XMLElem channelXML = getFirstAndOnly(root, "Channel"); - XMLElem pvpXML = getFirstAndOnly(root, "PVP"); - XMLElem dwellXML = getFirstAndOnly(root, "Dwell"); - XMLElem refGeoXML = getFirstAndOnly(root, "ReferenceGeometry"); - - XMLElem supportArrayXML = getOptional(root, "SupportArray"); - XMLElem antennaXML = getOptional(root, "Antenna"); - XMLElem txRcvXML = getOptional(root, "TxRcv"); - XMLElem errParamXML = getOptional(root, "ErrorParameters"); - XMLElem productInfoXML = getOptional(root, "ProductInfo"); - std::vector geoInfoXMLVec; - root->getElementsByTagName("GeoInfo", geoInfoXMLVec); - cphd->geoInfo.resize(geoInfoXMLVec.size()); - XMLElem matchInfoXML = getOptional(root, "MatchInfo"); - - // Parse XML for each section - fromXML(collectionIDXML, cphd->collectionID); - fromXML(globalXML, cphd->global); - fromXML(sceneCoordsXML, cphd->sceneCoordinates); - fromXML(dataXML, cphd->data); - fromXML(channelXML, cphd->channel); - fromXML(pvpXML, cphd->pvp); - fromXML(dwellXML, cphd->dwell); - fromXML(refGeoXML, cphd->referenceGeometry); - - if(supportArrayXML) - { - cphd->supportArray.reset(new SupportArray()); - fromXML(supportArrayXML, *(cphd->supportArray)); - } - if(antennaXML) - { - cphd->antenna.reset(new Antenna()); - fromXML(antennaXML, *(cphd->antenna)); - } - if(txRcvXML) - { - cphd->txRcv.reset(new TxRcv()); - fromXML(txRcvXML, *(cphd->txRcv)); - } - if(errParamXML) - { - cphd->errorParameters.reset(new ErrorParameters()); - fromXML(errParamXML, *(cphd->errorParameters)); - } - if(productInfoXML) - { - cphd->productInfo.reset(new ProductInfo()); - fromXML(productInfoXML, *(cphd->productInfo)); - } - for (size_t ii = 0; ii < geoInfoXMLVec.size(); ++ii) - { - fromXML(geoInfoXMLVec[ii], cphd->geoInfo[ii]); - } - if (matchInfoXML) - { - cphd->matchInfo.reset(new MatchInformation()); - fromXML(matchInfoXML, *(cphd->matchInfo)); - } - - return cphd; -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* collectionIDXML, CollectionInformation& collectionID) -{ - parseString(getFirstAndOnly(collectionIDXML, "CollectorName"), - collectionID.collectorName); - - XMLElem element = getOptional(collectionIDXML, "IlluminatorName"); - if (element) - { - parseString(element, collectionID.illuminatorName); - } - - element = getOptional(collectionIDXML, "CoreName"); - if (element) - { - parseString(element, collectionID.coreName); - } - - element = getOptional(collectionIDXML, "CollectType"); - if (element) - { - collectionID.collectType - = six::toType(element->getCharacterData()); - } - - XMLElem radarModeXML = getFirstAndOnly(collectionIDXML, "RadarMode"); - - collectionID.radarMode - = six::toType(getFirstAndOnly(radarModeXML, - "ModeType")->getCharacterData()); - - element = getOptional(radarModeXML, "ModeID"); - if (element) - { - parseString(element, collectionID.radarModeID); - } - - element = getFirstAndOnly(collectionIDXML, "ReleaseInfo"); - parseString(element, collectionID.releaseInfo); - - std::string classification; - parseString(getFirstAndOnly(collectionIDXML, "Classification"), - classification); - collectionID.setClassificationLevel(classification); - - // Optional - std::vector countryCodes; - element = getOptional(collectionIDXML, "CountryCode"); - if (element) - { - std::string countryCodeStr; - parseString(element, countryCodeStr); - collectionID.countryCodes = str::split(countryCodeStr, ","); - for (size_t ii = 0; ii < collectionID.countryCodes.size(); ++ii) - { - str::trim(collectionID.countryCodes[ii]); - } - } - - //optional - mCommon.parseParameters(collectionIDXML, "Parameter", collectionID.parameters); -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* globalXML, Global& global) -{ - global.domainType = DomainType::toType( - getFirstAndOnly(globalXML, "DomainType")->getCharacterData()); - global.sgn = PhaseSGN::toType( - getFirstAndOnly(globalXML, "SGN")->getCharacterData()); - - // Timeline - const xml::lite::Element* timelineXML = getFirstAndOnly(globalXML, "Timeline"); - parseDateTime( - getFirstAndOnly(timelineXML, "CollectionStart"), - global.timeline.collectionStart); - - // Optional - const xml::lite::Element* rcvCollectionXML = getOptional(timelineXML, - "RcvCollectionStart"); - if (rcvCollectionXML) - { - parseDateTime(rcvCollectionXML, - global.timeline.rcvCollectionStart); - } - - parseDouble( - getFirstAndOnly(timelineXML, "TxTime1"), global.timeline.txTime1); - parseDouble( - getFirstAndOnly(timelineXML, "TxTime2"), global.timeline.txTime2); - - // FxBand - const xml::lite::Element* fxBandXML = getFirstAndOnly(globalXML, "FxBand"); - parseDouble(getFirstAndOnly(fxBandXML, "FxMin"), global.fxBand.fxMin); - parseDouble(getFirstAndOnly(fxBandXML, "FxMax"), global.fxBand.fxMax); - - // TOASwath - const xml::lite::Element* toaSwathXML = getFirstAndOnly(globalXML, "TOASwath"); - parseDouble(getFirstAndOnly(toaSwathXML, "TOAMin"), global.toaSwath.toaMin); - parseDouble(getFirstAndOnly(toaSwathXML, "TOAMax"), global.toaSwath.toaMax); - - // TropoParameters - const xml::lite::Element* tropoXML = getOptional(globalXML, "TropoParameters"); - if (tropoXML) - { - // Optional - global.tropoParameters.reset(new TropoParameters()); - parseDouble(getFirstAndOnly(tropoXML, "N0"), global.tropoParameters->n0); - global.tropoParameters->refHeight = - RefHeight::toType(getFirstAndOnly(tropoXML, "RefHeight")->getCharacterData()); - } - - // IonoParameters - if (const auto ionoXML = getOptional(globalXML, "IonoParameters")) - { - // Optional - global.ionoParameters.reset(new IonoParameters()); - parseDouble(getFirstAndOnly(ionoXML, "TECV"), global.ionoParameters->tecv); - if (const auto f2HeightXML = getOptional(ionoXML, "F2Height")) - { - parseDouble(f2HeightXML, global.ionoParameters->f2Height); - } - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* sceneCoordsXML, - SceneCoordinates& scene) -{ - scene.earthModel = EarthModelType::toType( - getFirstAndOnly(sceneCoordsXML, "EarthModel")->getCharacterData()); - - // IARP - const xml::lite::Element* iarpXML = getFirstAndOnly(sceneCoordsXML, "IARP"); - mCommon.parseVector3D(getFirstAndOnly(iarpXML, "ECF"), scene.iarp.ecf); - mCommon.parseLatLonAlt(getFirstAndOnly(iarpXML, "LLH"), scene.iarp.llh); - - // ReferenceSurface - const xml::lite::Element* surfaceXML = getFirstAndOnly(sceneCoordsXML, "ReferenceSurface"); - const xml::lite::Element* planarXML = getOptional(surfaceXML, "Planar"); - const xml::lite::Element* haeXML = getOptional(surfaceXML, "HAE"); - if (planarXML && !haeXML) - { - // Choice type - scene.referenceSurface.planar.reset(new Planar()); - mCommon.parseVector3D(getFirstAndOnly(planarXML, "uIAX"), - scene.referenceSurface.planar->uIax); - mCommon.parseVector3D(getFirstAndOnly(planarXML, "uIAY"), - scene.referenceSurface.planar->uIay); - } - else if (haeXML && !planarXML) - { - // Choice type - scene.referenceSurface.hae.reset(new HAE()); - mCommon.parseLatLon(getFirstAndOnly(haeXML, "uIAXLL"), - scene.referenceSurface.hae->uIax); - mCommon.parseLatLon(getFirstAndOnly(haeXML, "uIAYLL"), - scene.referenceSurface.hae->uIay); - } - else - { - throw except::Exception(Ctxt( - "ReferenceSurface must exactly one of Planar or HAE element")); - } - - // ImageArea - const xml::lite::Element* imageAreaXML = getFirstAndOnly(sceneCoordsXML, "ImageArea"); - parseAreaType(imageAreaXML, scene.imageArea); - - // ImageAreaCorners - const xml::lite::Element* cornersXML = getFirstAndOnly(sceneCoordsXML, - "ImageAreaCornerPoints"); - mCommon.parseFootprint(cornersXML, "IACP", scene.imageAreaCorners); - - // Extended Area - const xml::lite::Element* extendedAreaXML = getOptional(sceneCoordsXML, "ExtendedArea"); - if (extendedAreaXML) - { - scene.extendedArea.reset(new AreaType()); - parseAreaType(extendedAreaXML, *scene.extendedArea); - } - - // Image Grid - const xml::lite::Element* gridXML = getOptional(sceneCoordsXML, "ImageGrid"); - if (gridXML) - { - // Optional - scene.imageGrid.reset(new ImageGrid()); - const xml::lite::Element* identifierXML = getOptional(gridXML, "Identifier"); - if (identifierXML) - { - parseString(identifierXML, scene.imageGrid->identifier); - } - parseLineSample(getFirstAndOnly(gridXML, "IARPLocation"), - scene.imageGrid->iarpLocation); - parseIAExtent(getFirstAndOnly(gridXML, "IAXExtent"), - scene.imageGrid->xExtent); - parseIAExtent(getFirstAndOnly(gridXML, "IAYExtent"), - scene.imageGrid->yExtent); - - // Segment List - const xml::lite::Element* segListXML = getOptional(gridXML, "SegmentList"); - if (segListXML) - { - // Optional - size_t numSegments; - parseUInt(getFirstAndOnly(segListXML, "NumSegments"), numSegments); - scene.imageGrid->segments.resize(numSegments); - - std::vector segmentsXML; - segListXML->getElementsByTagName("Segment", segmentsXML); - - for (size_t ii = 0; ii < segmentsXML.size(); ++ii) - { - const xml::lite::Element* segmentXML = segmentsXML[ii]; - parseString(getFirstAndOnly(segmentXML, "Identifier"), - scene.imageGrid->segments[ii].identifier); - parseInt(getFirstAndOnly(segmentXML, "StartLine"), - scene.imageGrid->segments[ii].startLine); - parseInt(getFirstAndOnly(segmentXML, "StartSample"), - scene.imageGrid->segments[ii].startSample); - parseInt(getFirstAndOnly(segmentXML, "EndLine"), - scene.imageGrid->segments[ii].endLine); - parseInt(getFirstAndOnly(segmentXML, "EndSample"), - scene.imageGrid->segments[ii].endSample); - - const xml::lite::Element* polygonXML = getOptional(segmentXML, - "SegmentPolygon"); - if (polygonXML) - { - // Optional - size_t polygonSize = 0; - sscanf(const_cast(polygonXML)->attribute("size").c_str(), "%zu", &polygonSize); - scene.imageGrid->segments[ii].polygon.resize(polygonSize); - std::vector polyVerticesXMLVec; - polygonXML->getElementsByTagName("SV", polyVerticesXMLVec); - if (scene.imageGrid->segments[ii].polygon.size() != polyVerticesXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect polygon vertices provided")); - } - if (polyVerticesXMLVec.size() < 3) - { - throw except::Exception(Ctxt( - "Polygon must have at least 3 vertices")); - } - std::vector& vertices = - scene.imageGrid->segments[ii].polygon; - vertices.resize(polyVerticesXMLVec.size()); - for (size_t jj = 0; jj < polyVerticesXMLVec.size(); ++jj) - { - size_t tempIdx; - sscanf(polyVerticesXMLVec[jj]->attribute("index").c_str(), "%zu", &tempIdx); - vertices[jj].setIndex(tempIdx); - parseLineSample(polyVerticesXMLVec[jj], vertices[jj]); - } - } - } - } - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* dataXML, Data& data) -{ - const xml::lite::Element* signalXML = getFirstAndOnly(dataXML, "SignalArrayFormat"); - data.signalArrayFormat = SignalArrayFormat::toType(signalXML->getCharacterData()); - - size_t numBytesPVP_temp = 0; - XMLElem numBytesPVPXML = getFirstAndOnly(dataXML, "NumBytesPVP"); - parseUInt(numBytesPVPXML, numBytesPVP_temp); - if(numBytesPVP_temp % 8 != 0) - { - throw except::Exception(Ctxt( - "Number of bytes must be multiple of 8")); - } - data.numBytesPVP = numBytesPVP_temp; - - // Channels - std::vector channelsXML; - dataXML->getElementsByTagName("Channel", channelsXML); - data.channels.resize(channelsXML.size()); - for (size_t ii = 0; ii < channelsXML.size(); ++ii) - { - parseString(getFirstAndOnly(channelsXML[ii], "Identifier"), - data.channels[ii].identifier); - parseUInt(getFirstAndOnly(channelsXML[ii], "NumVectors"), - data.channels[ii].numVectors); - parseUInt(getFirstAndOnly(channelsXML[ii], "NumSamples"), - data.channels[ii].numSamples); - parseUInt(getFirstAndOnly(channelsXML[ii], "SignalArrayByteOffset"), - data.channels[ii].signalArrayByteOffset); - parseUInt(getFirstAndOnly(channelsXML[ii], "PVPArrayByteOffset"), - data.channels[ii].pvpArrayByteOffset); - XMLElem compressionXML = getOptional(channelsXML[ii], "CompressedSignalSize"); - if (compressionXML) - { - parseUInt(compressionXML, data.channels[ii].compressedSignalSize); - } - } - XMLElem compressionXML = getOptional(dataXML, "SignalCompressionID"); - if (compressionXML) - { - parseString(compressionXML, - data.signalCompressionID); - } - - // Support Arrays - std::vector supportsXML; - dataXML->getElementsByTagName("SupportArray", supportsXML); - for (size_t ii = 0; ii < supportsXML.size(); ++ii) - { - std::string id; - size_t offset; - size_t numRows; - size_t numCols; - size_t numBytes; - parseString(getFirstAndOnly(supportsXML[ii], "Identifier"), id); - parseUInt(getFirstAndOnly(supportsXML[ii], "ArrayByteOffset"), offset); - parseUInt(getFirstAndOnly(supportsXML[ii], "NumRows"), numRows); - parseUInt(getFirstAndOnly(supportsXML[ii], "NumCols"), numCols); - parseUInt(getFirstAndOnly(supportsXML[ii], "BytesPerElement"), numBytes); - data.setSupportArray(id, numRows, numCols, numBytes, offset); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* channelXML, Channel& channel) -{ - parseString(getFirstAndOnly(channelXML, "RefChId"), channel.refChId); - parseBooleanType(getFirstAndOnly(channelXML, "FXFixedCPHD"), channel.fxFixedCphd); - parseBooleanType(getFirstAndOnly(channelXML, "TOAFixedCPHD"), channel.toaFixedCphd); - parseBooleanType(getFirstAndOnly(channelXML, "SRPFixedCPHD"), channel.srpFixedCphd); - - std::vector parametersXML; - channelXML->getElementsByTagName("Parameters", parametersXML); - channel.parameters.resize(parametersXML.size()); - for (size_t ii = 0; ii < parametersXML.size(); ++ii) - { - parseChannelParameters(parametersXML[ii], channel.parameters[ii]); - } - - XMLElem addedParametersXML = getOptional(channelXML, "AddedParameters"); - if(addedParametersXML) - { - mCommon.parseParameters(addedParametersXML, "Parameter", channel.addedParameters); - } -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement& v) const -{ - auto& param = value(v).param; - const auto offset = parsePVPType(parent, param); - setOffset(param, offset); -} -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement& v) const -{ - auto& param = value(v).param; - const auto offset = parsePVPType(parent, param); - setOffset(param, offset); -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = TxAntenna{}; - parse(*pXML, value(o).txACX); - parse(*pXML, value(o).txACY); - parse(*pXML, value(o).txEB); - } -} -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = RcvAntenna{}; - parse(*pXML, value(o).rcvACX); - parse(*pXML, value(o).rcvACY); - parse(*pXML, value(o).rcvEB); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* pvpXML, Pvp& pvp) -{ - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxTime"), pvp.txTime); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxPos"), pvp.txPos); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxVel"), pvp.txVel); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvTime"), pvp.rcvTime); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvPos"), pvp.rcvPos); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvVel"), pvp.rcvVel); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "SRPPos"), pvp.srpPos); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFDOP"), pvp.aFDOP); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFRR1"), pvp.aFRR1); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFRR2"), pvp.aFRR2); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "FX1"), pvp.fx1); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "FX2"), pvp.fx2); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TOA1"), pvp.toa1); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TOA2"), pvp.toa2); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TDTropoSRP"), pvp.tdTropoSRP); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "SC0"), pvp.sc0); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "SCSS"), pvp.scss); - - parseOptionalPVPType(pvpXML, "AmpSF", pvp, pvp.ampSF); - parseOptionalPVPType(pvpXML, "FXN1", pvp, pvp.fxN1); - parseOptionalPVPType(pvpXML, "FXN2", pvp, pvp.fxN2); - parseOptionalPVPType(pvpXML, "TOAE1", pvp, pvp.toaE1); - parseOptionalPVPType(pvpXML, "TOAE2", pvp, pvp.toaE2); - parseOptionalPVPType(pvpXML, "TDIonoSRP", pvp, pvp.tdIonoSRP); - parseOptionalPVPType(pvpXML, "SIGNAL", pvp, pvp.signal); - - parse(*pvpXML, pvp.txAntenna); - parse(*pvpXML, pvp.rcvAntenna); - - std::vector addedParamsXML; - const std::string str = "AddedPVP"; - pvpXML->getElementsByTagName(str, addedParamsXML); - if(addedParamsXML.empty()) - { - return; - } - for (size_t ii = 0; ii < addedParamsXML.size(); ++ii) - { - parsePVPType(pvp, addedParamsXML[ii]); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* DwellXML, - Dwell& dwell) -{ - // CODTime - size_t numCODTimes; - parseUInt(getFirstAndOnly(DwellXML, "NumCODTimes"), numCODTimes); - dwell.cod.resize(numCODTimes); - - std::vector codXMLVec; - DwellXML->getElementsByTagName("CODTime", codXMLVec); - for(size_t ii = 0; ii < codXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(codXMLVec[ii], "Identifier"), dwell.cod[ii].identifier); - mCommon.parsePoly2D(getFirstAndOnly(codXMLVec[ii], "CODTimePoly"), dwell.cod[ii].codTimePoly); - } - - // DwellTime - size_t numDwellTimes = 0; - parseUInt(getFirstAndOnly(DwellXML, "NumDwellTimes"), numDwellTimes); - dwell.dtime.resize(numDwellTimes); - - std::vector dtimeXMLVec; - DwellXML->getElementsByTagName("DwellTime", dtimeXMLVec); - for(size_t ii = 0; ii < dtimeXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(dtimeXMLVec[ii], "Identifier"), dwell.dtime[ii].identifier); - mCommon.parsePoly2D(getFirstAndOnly(dtimeXMLVec[ii], "DwellTimePoly"), dwell.dtime[ii].dwellTimePoly); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* refGeoXML, ReferenceGeometry& refGeo) -{ - XMLElem srpXML = getFirstAndOnly(refGeoXML, "SRP"); - mCommon.parseVector3D(getFirstAndOnly(srpXML, "ECF"), refGeo.srp.ecf); - mCommon.parseVector3D(getFirstAndOnly(srpXML, "IAC"), refGeo.srp.iac); - parseDouble(getFirstAndOnly(refGeoXML, "ReferenceTime"), refGeo.referenceTime); - parseDouble(getFirstAndOnly(refGeoXML, "SRPCODTime"), refGeo.srpCODTime); - parseDouble(getFirstAndOnly(refGeoXML, "SRPDwellTime"), refGeo.srpDwellTime); - - const xml::lite::Element* monoXML = getOptional(refGeoXML, "Monostatic"); - const xml::lite::Element* biXML = getOptional(refGeoXML, "Bistatic"); - if (monoXML && !biXML) - { - refGeo.monostatic.reset(new Monostatic()); - parseCommon(monoXML, (ImagingType*)refGeo.monostatic.get()); - parseDouble(getFirstAndOnly(monoXML, "SlantRange"), refGeo.monostatic->slantRange); - parseDouble(getFirstAndOnly(monoXML, "GroundRange"), refGeo.monostatic->groundRange); - parseDouble(getFirstAndOnly(monoXML, "DopplerConeAngle"), refGeo.monostatic->dopplerConeAngle); - parseDouble(getFirstAndOnly(monoXML, "IncidenceAngle"), refGeo.monostatic->incidenceAngle); - mCommon.parseVector3D(getFirstAndOnly(monoXML, "ARPPos"), refGeo.monostatic->arpPos); - mCommon.parseVector3D(getFirstAndOnly(monoXML, "ARPVel"), refGeo.monostatic->arpVel); - std::string side = ""; - parseString(getFirstAndOnly(monoXML, "SideOfTrack"), side); - refGeo.monostatic->sideOfTrack = (side == "L" ? six::SideOfTrackType::LEFT : six::SideOfTrackType::RIGHT); - - } - else if (!monoXML && biXML) - { - refGeo.bistatic.reset(new Bistatic()); - parseCommon(biXML, (ImagingType*)refGeo.bistatic.get()); - parseDouble(getFirstAndOnly(biXML, "AzimuthAngleRate"), refGeo.bistatic->azimuthAngleRate); - parseDouble(getFirstAndOnly(biXML, "BistaticAngle"), refGeo.bistatic->bistaticAngle); - parseDouble(getFirstAndOnly(biXML, "BistaticAngleRate"), refGeo.bistatic->bistaticAngleRate); - - parsePlatformParams(getFirstAndOnly(biXML, "TxPlatform"), refGeo.bistatic->txPlatform); - parsePlatformParams(getFirstAndOnly(biXML, "RcvPlatform"), refGeo.bistatic->rcvPlatform); - } - else - { - throw except::Exception(Ctxt( - "One of the two types Mono or Bi must be provided")); - } -} - -std::vector CPHDXMLParser::parseSupportArray(const std::string& tag, const xml::lite::Element& parent) const -{ - std::vector elements; - parent.getElementsByTagName(tag, elements); - std::vector supportArray; - supportArray.reserve(elements.size()); - for (const auto& element : elements) - { - SupportArrayParameter param; - parseSupportArrayParameter(element, param, false /*additionalFlag*/); - supportArray.push_back(std::move(param)); - } - return supportArray; -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* supportArrayXML, SupportArray& supportArray) -{ - supportArray.iazArray = parseSupportArray("IAZArray", *supportArrayXML); - supportArray.antGainPhase = parseSupportArray("AntGainPhase", *supportArrayXML); - supportArray.dwellTimeArray = parseSupportArray("DwellTimeArray", *supportArrayXML); - - std::vector addedSupportArrayXMLVec; - supportArrayXML->getElementsByTagName("AddedSupportArray", addedSupportArrayXMLVec); - for (size_t ii = 0; ii < addedSupportArrayXMLVec.size(); ++ii) - { - std::string id; - parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "Identifier"), id); - if (supportArray.addedSupportArray.count(id) == 0) - { - parseSupportArrayParameter(addedSupportArrayXMLVec[ii], supportArray.addedSupportArray[id], true); - parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "XUnits"), supportArray.addedSupportArray[id].xUnits); - parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "YUnits"), supportArray.addedSupportArray[id].yUnits); - parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "ZUnits"), supportArray.addedSupportArray[id].zUnits); - mCommon.parseParameters(addedSupportArrayXMLVec[ii], "Parameter", supportArray.addedSupportArray[id].parameter); - } - else - { - throw except::Exception(Ctxt( - "Support array identifier for support array is not unique: " + id)); - } - } -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = AntPattern::EBFreqShiftSF{}; - six::getFirstAndOnly(parser(), *pXML, value(o).dcxsf); - six::getFirstAndOnly(parser(), *pXML, value(o).dcysf); - } -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = AntPattern::MLFreqDilationSF{}; - six::getFirstAndOnly(parser(), *pXML, value(o).dcxsf); - six::getFirstAndOnly(parser(), *pXML, value(o).dcysf); - } -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = AntPattern::AntPolRef{}; - six::getFirstAndOnly(parser(), *pXML, value(o).ampX); - six::getFirstAndOnly(parser(), *pXML, value(o).ampY); - six::getFirstAndOnly(parser(), *pXML, value(o).phaseY); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* antennaXML, Antenna& antenna) -{ - size_t numACFs = 0; - size_t numAPCs = 0; - size_t numAntPats = 0; - parseUInt(getFirstAndOnly(antennaXML, "NumACFs"), numACFs); - antenna.antCoordFrame.resize(numACFs); - parseUInt(getFirstAndOnly(antennaXML, "NumAPCs"), numAPCs); - antenna.antPhaseCenter.resize(numAPCs); - parseUInt(getFirstAndOnly(antennaXML, "NumAntPats"), numAntPats); - antenna.antPattern.resize(numAntPats); - - // Parse AntCoordFrame - std::vector antCoordFrameXMLVec; - antennaXML->getElementsByTagName("AntCoordFrame", antCoordFrameXMLVec); - if(antenna.antCoordFrame.size() != antCoordFrameXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of AntCoordFrames provided")); - } - for( size_t ii = 0; ii < antCoordFrameXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(antCoordFrameXMLVec[ii], "Identifier"), antenna.antCoordFrame[ii].identifier); - mCommon.parsePolyXYZ(getFirstAndOnly(antCoordFrameXMLVec[ii], "XAxisPoly"), antenna.antCoordFrame[ii].xAxisPoly); - mCommon.parsePolyXYZ(getFirstAndOnly(antCoordFrameXMLVec[ii], "YAxisPoly"), antenna.antCoordFrame[ii].yAxisPoly); - std::ignore = six::parse(parser(), *antCoordFrameXMLVec[ii], antenna.antCoordFrame[ii].useACFPVP); - } - - // Parse AntPhaseCenter - std::vector antPhaseCenterXMLVec; - antennaXML->getElementsByTagName("AntPhaseCenter", antPhaseCenterXMLVec); - if(antenna.antPhaseCenter.size() != antPhaseCenterXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of AntPhaseCenters provided")); - } - for( size_t ii = 0; ii < antPhaseCenterXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(antPhaseCenterXMLVec[ii], "Identifier"), antenna.antPhaseCenter[ii].identifier); - parseString(getFirstAndOnly(antPhaseCenterXMLVec[ii], "ACFId"), antenna.antPhaseCenter[ii].acfId); - mCommon.parseVector3D(getFirstAndOnly(antPhaseCenterXMLVec[ii], "APCXYZ"), antenna.antPhaseCenter[ii].apcXYZ); - } - - std::vector antPatternXMLVec; - antennaXML->getElementsByTagName("AntPattern", antPatternXMLVec); - if(antenna.antPattern.size() != antPatternXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of AntPatterns provided")); - } - for( size_t ii = 0; ii < antPatternXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(antPatternXMLVec[ii], "Identifier"), antenna.antPattern[ii].identifier); - parseDouble(getFirstAndOnly(antPatternXMLVec[ii], "FreqZero"), antenna.antPattern[ii].freqZero); - parseOptionalDouble(antPatternXMLVec[ii], "GainZero", antenna.antPattern[ii].gainZero); - - XMLElem ebFreqShiftXML = getOptional(antPatternXMLVec[ii], "EBFreqShift"); - if(ebFreqShiftXML) - { - parseBooleanType(ebFreqShiftXML, antenna.antPattern[ii].ebFreqShift); - } - parse(*antPatternXMLVec[ii], antenna.antPattern[ii].ebFreqShiftSF); - - XMLElem mlFreqDilationXML = getOptional(antPatternXMLVec[ii], "MLFreqDilation"); - if(mlFreqDilationXML) - { - parseBooleanType(mlFreqDilationXML, antenna.antPattern[ii].mlFreqDilation); - } - parse(*antPatternXMLVec[ii], antenna.antPattern[ii].mlFreqDilationSF); - - XMLElem gainBSPoly = getOptional(antPatternXMLVec[ii], "GainBSPoly"); - if(gainBSPoly) - { - mCommon.parsePoly1D(gainBSPoly, antenna.antPattern[ii].gainBSPoly); - } - - parse(*antPatternXMLVec[ii], antenna.antPattern[ii].antPolRef); - - // Parse EB - XMLElem ebXML = getFirstAndOnly(antPatternXMLVec[ii], "EB"); - mCommon.parsePoly1D(getFirstAndOnly(ebXML, "DCXPoly"), antenna.antPattern[ii].eb.dcxPoly); - mCommon.parsePoly1D(getFirstAndOnly(ebXML, "DCYPoly"), antenna.antPattern[ii].eb.dcyPoly); - std::ignore = six::parse(parser(), *ebXML, antenna.antPattern[ii].eb.useEBPVP); - - // Parse Array - XMLElem arrayXML = getFirstAndOnly(antPatternXMLVec[ii], "Array"); - mCommon.parsePoly2D(getFirstAndOnly(arrayXML, "GainPoly"), antenna.antPattern[ii].array.gainPoly); - mCommon.parsePoly2D(getFirstAndOnly(arrayXML, "PhasePoly"), antenna.antPattern[ii].array.phasePoly); - - // Parse Element - XMLElem elementXML = getFirstAndOnly(antPatternXMLVec[ii], "Element"); - mCommon.parsePoly2D(getFirstAndOnly(elementXML, "GainPoly"), antenna.antPattern[ii].element.gainPoly); - mCommon.parsePoly2D(getFirstAndOnly(elementXML, "PhasePoly"), antenna.antPattern[ii].element.phasePoly); - std::ignore = six::parse(parser(), *elementXML, antenna.antPattern[ii].element.antGPId); - - // Parse GainPhaseArray - std::vector gainPhaseArrayXMLVec; - antPatternXMLVec[ii]->getElementsByTagName("GainPhaseArray", gainPhaseArrayXMLVec); - antenna.antPattern[ii].gainPhaseArray.resize(gainPhaseArrayXMLVec.size()); - for (size_t jj = 0; jj < gainPhaseArrayXMLVec.size(); ++jj) - { - parseDouble(getFirstAndOnly(gainPhaseArrayXMLVec[jj], "Freq"), antenna.antPattern[ii].gainPhaseArray[jj].freq); - parseString(getFirstAndOnly(gainPhaseArrayXMLVec[jj], "ArrayId"), antenna.antPattern[ii].gainPhaseArray[jj].arrayId); - XMLElem elementIdXML = getOptional(gainPhaseArrayXMLVec[jj], "ElementId"); - if(elementIdXML) - { - parseString(elementIdXML, antenna.antPattern[ii].gainPhaseArray[jj].elementId); - } - - } - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* txRcvXML, TxRcv& txRcv) -{ - size_t numTxWFs = 0; - size_t numRcvs = 0; - parseUInt(getFirstAndOnly(txRcvXML, "NumTxWFs"), numTxWFs); - txRcv.txWFParameters.resize(numTxWFs); - parseUInt(getFirstAndOnly(txRcvXML, "NumRcvs"), numRcvs); - txRcv.rcvParameters.resize(numRcvs); - - std::vector txWFXMLVec; - txRcvXML->getElementsByTagName("TxWFParameters", txWFXMLVec); - if(txRcv.txWFParameters.size() != txWFXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of TxWF parameters provided")); - } - for(size_t ii = 0; ii < txWFXMLVec.size(); ++ii) - { - parseTxRcvParameter(txWFXMLVec[ii], txRcv.txWFParameters[ii]); - parseDouble(getFirstAndOnly(txWFXMLVec[ii], "PulseLength"), txRcv.txWFParameters[ii].pulseLength); - parseDouble(getFirstAndOnly(txWFXMLVec[ii], "RFBandwidth"), txRcv.txWFParameters[ii].rfBandwidth); - parseOptionalDouble(txWFXMLVec[ii], "Power", txRcv.txWFParameters[ii].power); - } - - std::vector rcvXMLVec; - txRcvXML->getElementsByTagName("RcvParameters", rcvXMLVec); - if(txRcv.rcvParameters.size() != rcvXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of Rcv parameters provided")); - } - for(size_t ii = 0; ii < rcvXMLVec.size(); ++ii) - { - parseTxRcvParameter(rcvXMLVec[ii], txRcv.rcvParameters[ii]); - parseDouble(getFirstAndOnly(rcvXMLVec[ii], "WindowLength"), txRcv.rcvParameters[ii].windowLength); - parseDouble(getFirstAndOnly(rcvXMLVec[ii], "SampleRate"), txRcv.rcvParameters[ii].sampleRate); - parseDouble(getFirstAndOnly(rcvXMLVec[ii], "IFFilterBW"), txRcv.rcvParameters[ii].ifFilterBW); - parseOptionalDouble(rcvXMLVec[ii], "PathGain", txRcv.rcvParameters[ii].pathGain); - } - -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* errParamXML, ErrorParameters& errParam) -{ - XMLElem monostaticXML = getOptional(errParamXML, "Monostatic"); - XMLElem bistaticXML = getOptional(errParamXML, "Bistatic"); - - if(monostaticXML && !bistaticXML) - { - errParam.monostatic.reset(new ErrorParameters::Monostatic()); - parsePosVelErr(getFirstAndOnly(monostaticXML, "PosVelErr"), errParam.monostatic->posVelErr); - - XMLElem radarSensorXML = getFirstAndOnly(monostaticXML, "RadarSensor"); - parseDouble(getFirstAndOnly(radarSensorXML, "RangeBias"), errParam.monostatic->radarSensor.rangeBias); - - parseOptionalDouble(radarSensorXML, "ClockFreqSF", errParam.monostatic->radarSensor.clockFreqSF); - parseOptionalDouble(radarSensorXML, "CollectionStartTime", errParam.monostatic->radarSensor.collectionStartTime); - - XMLElem rangeBiasDecorrXML = getOptional(radarSensorXML, "RangeBiasDecorr"); - if(rangeBiasDecorrXML) - { - errParam.monostatic->radarSensor.rangeBiasDecorr.reset(new six::DecorrType()); - mCommon.parseDecorrType(rangeBiasDecorrXML, *(errParam.monostatic->radarSensor.rangeBiasDecorr)); - } - - XMLElem tropoErrorXML = getOptional(monostaticXML, "TropoError"); - if(tropoErrorXML) - { - errParam.monostatic->tropoError.reset(new six::TropoError()); - parseOptionalDouble(tropoErrorXML, "TropoRangeVertical", errParam.monostatic->tropoError->tropoRangeVertical); - parseOptionalDouble(tropoErrorXML, "TropoRangeSlant", errParam.monostatic->tropoError->tropoRangeSlant); - mCommon.parseOptionalDecorrType(tropoErrorXML, "TropoRangeDecorr", errParam.monostatic->tropoError->tropoRangeDecorr); - } - - XMLElem ionoErrorXML = getOptional(monostaticXML, "IonoError"); - if(ionoErrorXML) - { - errParam.monostatic->ionoError.reset(new six::IonoError()); - parseDouble(getFirstAndOnly(ionoErrorXML, "IonoRangeVertical"), errParam.monostatic->ionoError->ionoRangeVertical); - - parseOptionalDouble(ionoErrorXML, "IonoRangeRateVertical", errParam.monostatic->ionoError->ionoRangeRateVertical); - parseOptionalDouble(ionoErrorXML, "IonoRgRgRateCC", errParam.monostatic->ionoError->ionoRgRgRateCC); - mCommon.parseOptionalDecorrType(ionoErrorXML, "IonoRangeVertDecorr", errParam.monostatic->ionoError->ionoRangeVertDecorr); - } - mCommon.parseParameters(monostaticXML, "Parameter", errParam.monostatic->parameter); - } - else if(!monostaticXML && bistaticXML) - { - errParam.bistatic.reset(new ErrorParameters::Bistatic()); - parsePlatform(getFirstAndOnly(bistaticXML, "TxPlatform"), errParam.bistatic->txPlatform); - parsePlatform(getFirstAndOnly(bistaticXML, "RcvPlatform"), errParam.bistatic->rcvPlatform); - mCommon.parseParameters(bistaticXML, "Parameter", errParam.bistatic->parameter); - } - else - { - throw except::Exception(Ctxt( - "Must be one of monostatic or bistatic")); - } -} - - -void CPHDXMLParser::fromXML(const xml::lite::Element* productInfoXML, ProductInfo& productInfo) -{ - XMLElem profileXML = getOptional(productInfoXML, "Profile"); - if(profileXML) - { - parseString(profileXML, productInfo.profile); - } - - std::vector creationInfoXML; - productInfoXML->getElementsByTagName("CreationInfo", creationInfoXML); - productInfo.creationInfo.resize(creationInfoXML.size()); - - for (size_t ii = 0; ii < creationInfoXML.size(); ++ii) - { - XMLElem applicationXML = getOptional(creationInfoXML[ii], "Application"); - if(applicationXML) - { - parseString(applicationXML, productInfo.creationInfo[ii].application); - } - - parseDateTime(getFirstAndOnly(creationInfoXML[ii], "DateTime"), productInfo.creationInfo[ii].dateTime); - - XMLElem siteXML = getOptional(creationInfoXML[ii], "Site"); - if(siteXML) - { - parseString(siteXML, productInfo.creationInfo[ii].site); - } - mCommon.parseParameters(creationInfoXML[ii], "Parameter", productInfo.creationInfo[ii].parameter); - } - mCommon.parseParameters(productInfoXML, "Parameter", productInfo.parameter); - -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* geoInfoXML, GeoInfo& geoInfo) -{ - std::vector < XMLElem > geoInfosXML; - geoInfoXML->getElementsByTagName("GeoInfo", geoInfosXML); - geoInfo.name = geoInfoXML->getAttributes().getValue("name"); - - //optional - mCommon.parseParameters(geoInfoXML, "Desc", geoInfo.desc); - - XMLElem tmpElem = getOptional(geoInfoXML, "Point"); - if (tmpElem) - { - LatLon ll; - mCommon.parseLatLon(tmpElem, ll); - geoInfo.geometryLatLon.push_back(ll); - } - else - { - std::string pointName = "Endpoint"; - tmpElem = getOptional(geoInfoXML, "Line"); - if (!tmpElem) - { - pointName = "Vertex"; - tmpElem = getOptional(geoInfoXML, "Polygon"); - } - if (tmpElem) - { - mCommon.parseLatLons(tmpElem, pointName, geoInfo.geometryLatLon); - } - } - - //optional - size_t idx(geoInfo.geoInfos.size()); - geoInfo.geoInfos.resize(idx + geoInfosXML.size()); - - for (auto it = geoInfosXML.begin(); it - != geoInfosXML.end(); ++it, ++idx) - { - geoInfo.geoInfos[idx].reset(new GeoInfo()); - fromXML(*it, *geoInfo.geoInfos[idx]); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* matchInfoXML, MatchInformation& matchInfo) -{ - mCommon.parseMatchInformationFromXML(matchInfoXML, &matchInfo); -} - - -XMLElem CPHDXMLParser::createLatLonFootprint(const std::string& name, - const std::string& cornerName, - const cphd::LatLonCorners& corners, - XMLElem parent) const -{ - XMLElem footprint = newElement(name, parent); - - // Write the corners in CW order - XMLElem vertex = - mCommon.createLatLon(cornerName, corners.upperLeft, footprint); - setAttribute(vertex, "index", "1"); - - vertex = mCommon.createLatLon(cornerName, corners.upperRight, footprint); - setAttribute(vertex, "index", "2"); - - vertex = mCommon.createLatLon(cornerName, corners.lowerRight, footprint); - setAttribute(vertex, "index", "3"); - - vertex = mCommon.createLatLon(cornerName, corners.lowerLeft, footprint); - setAttribute(vertex, "index", "4"); - - return footprint; -} - -XMLElem CPHDXMLParser::createPVPType(const std::string& name, - const PVPType& p, - XMLElem parent) const -{ - XMLElem pvpXML = newElement(name, parent); - createInt("Offset", p.getOffset(), pvpXML); - createInt("Size", p.getSize(), pvpXML); - createString("Format", p.getFormat(), pvpXML); - return pvpXML; -} - -XMLElem CPHDXMLParser::createAPVPType(const std::string& name, - const APVPType& p, - XMLElem parent) const -{ - XMLElem apvpXML = newElement(name, parent); - createString("Name", p.getName(), apvpXML); - createInt("Offset", p.getOffset(), apvpXML); - createInt("Size", p.getSize(), apvpXML); - createString("Format", p.getFormat(), apvpXML); - return apvpXML; -} - -XMLElem CPHDXMLParser::createErrorParamPlatform( - const std::string& /*name*/, - const ErrorParameters::Bistatic::Platform p, - XMLElem parent) const -{ - XMLElem posVelErrXML = newElement("PosVelErr", parent); - createString("Frame", p.posVelErr.frame, posVelErrXML); - createDouble("P1", p.posVelErr.p1, posVelErrXML); - createDouble("P2", p.posVelErr.p2, posVelErrXML); - createDouble("P3", p.posVelErr.p3, posVelErrXML); - createDouble("V1", p.posVelErr.v1, posVelErrXML); - createDouble("V2", p.posVelErr.v2, posVelErrXML); - createDouble("V3", p.posVelErr.v3, posVelErrXML); - if(p.posVelErr.corrCoefs.get()) - { - XMLElem corrCoefsXML = newElement("CorrCoefs", posVelErrXML); - createDouble("P1P2", p.posVelErr.corrCoefs->p1p2, corrCoefsXML); - createDouble("P1P3", p.posVelErr.corrCoefs->p1p3, corrCoefsXML); - createDouble("P1V1", p.posVelErr.corrCoefs->p1v1, corrCoefsXML); - createDouble("P1V2", p.posVelErr.corrCoefs->p1v2, corrCoefsXML); - createDouble("P1V3", p.posVelErr.corrCoefs->p1v3, corrCoefsXML); - createDouble("P2P3", p.posVelErr.corrCoefs->p2p3, corrCoefsXML); - createDouble("P2V1", p.posVelErr.corrCoefs->p2v1, corrCoefsXML); - createDouble("P2V2", p.posVelErr.corrCoefs->p2v2, corrCoefsXML); - createDouble("P2V3", p.posVelErr.corrCoefs->p2v3, corrCoefsXML); - createDouble("P3V1", p.posVelErr.corrCoefs->p3v1, corrCoefsXML); - createDouble("P3V2", p.posVelErr.corrCoefs->p3v2, corrCoefsXML); - createDouble("P3V3", p.posVelErr.corrCoefs->p3v3, corrCoefsXML); - createDouble("V1V2", p.posVelErr.corrCoefs->v1v2, corrCoefsXML); - createDouble("V1V3", p.posVelErr.corrCoefs->v1v3, corrCoefsXML); - createDouble("V2V3", p.posVelErr.corrCoefs->v2v3, corrCoefsXML); - } - createDecorrType("PositionDecorr", p.posVelErr.positionDecorr, posVelErrXML); - return posVelErrXML; -} - -XMLElem CPHDXMLParser::createDecorrType(const std::string& name, const six::DecorrType& dt, - XMLElem parent) const -{ - if (six::Init::isDefined(dt)) - { - XMLElem element = newElement(name, parent); - createDouble("CorrCoefZero", dt.corrCoefZero, element); - createDouble("DecorrRate", dt.decorrRate, element); - return element; - } - return nullptr; -} -XMLElem CPHDXMLParser::createDecorrType(const std::string& name, const std::optional& dt, - XMLElem parent) const -{ - if (dt.has_value()) - { - return createDecorrType(name, *dt, parent); - } - return nullptr; -} - -/* - * Parser helper functions - */ -void CPHDXMLParser::parseAreaType(const xml::lite::Element* areaXML, AreaType& area) const -{ - mCommon.parseVector2D(getFirstAndOnly(areaXML, "X1Y1"), area.x1y1); - mCommon.parseVector2D(getFirstAndOnly(areaXML, "X2Y2"), area.x2y2); - const xml::lite::Element* polygonXML = getOptional(areaXML, "Polygon"); - if (polygonXML) - { - std::vector verticesXML; - polygonXML->getElementsByTagName("Vertex", verticesXML); - if (verticesXML.size() < 3) - { - throw except::Exception(Ctxt( - "Polygons must have at least 3 sides")); - } - area.polygon.resize(verticesXML.size()); - for (size_t ii = 0; ii < area.polygon.size(); ++ii) - { - Vector2& vertex = area.polygon[ii]; - const xml::lite::Element* vertexXML = verticesXML[ii]; - mCommon.parseVector2D(vertexXML, vertex); - } - } -} - -void CPHDXMLParser::parseLineSample(const xml::lite::Element* lsXML, LineSample& ls) const -{ - parseDouble(getFirstAndOnly(lsXML, "Line"), ls.line); - parseDouble(getFirstAndOnly(lsXML, "Sample"), ls.sample); -} - -void CPHDXMLParser::parseIAExtent(const xml::lite::Element* extentXML, - ImageAreaXExtent& extent) const -{ - parseDouble(getFirstAndOnly(extentXML, "LineSpacing"), - extent.lineSpacing); - parseInt(getFirstAndOnly(extentXML, "FirstLine"), - extent.firstLine); - parseUInt(getFirstAndOnly(extentXML, "NumLines"), - extent.numLines); -} - -void CPHDXMLParser::parseIAExtent(const xml::lite::Element* extentXML, - ImageAreaYExtent& extent) const -{ - parseDouble(getFirstAndOnly(extentXML, "SampleSpacing"), - extent.sampleSpacing); - parseInt(getFirstAndOnly(extentXML, "FirstSample"), - extent.firstSample); - parseUInt(getFirstAndOnly(extentXML, "NumSamples"), - extent.numSamples); -} - -void CPHDXMLParser::parseChannelParameters( - const xml::lite::Element* paramXML, ChannelParameter& param) const -{ - parseString(getFirstAndOnly(paramXML, "Identifier"), param.identifier); - parseUInt(getFirstAndOnly(paramXML, "RefVectorIndex"), param.refVectorIndex); - parseBooleanType(getFirstAndOnly(paramXML, "FXFixed"), param.fxFixed); - parseBooleanType(getFirstAndOnly(paramXML, "TOAFixed"), param.toaFixed); - parseBooleanType(getFirstAndOnly(paramXML, "SRPFixed"), param.srpFixed); - - XMLElem signalXML = getOptional(paramXML, "SignalNormal"); - if (signalXML) - { - parseBooleanType(signalXML, param.signalNormal); - } - - parseDouble(getFirstAndOnly(paramXML, "FxC"), param.fxC); - parseDouble(getFirstAndOnly(paramXML, "FxBW"), param.fxBW); - parseOptionalDouble(paramXML, "FxBWNoise", param.fxBWNoise); - parseDouble(getFirstAndOnly(paramXML, "TOASaved"), param.toaSaved); - - XMLElem toaExtendedXML = getOptional(paramXML, "TOAExtended"); - if(toaExtendedXML) - { - param.toaExtended.reset(new TOAExtended()); - parseDouble(getFirstAndOnly(toaExtendedXML, "TOAExtSaved"), param.toaExtended->toaExtSaved); - XMLElem lfmEclipseXML = getOptional(toaExtendedXML, "LFMEclipse"); - if(lfmEclipseXML) - { - param.toaExtended->lfmEclipse.reset(new TOAExtended::LFMEclipse()); - parseDouble(getFirstAndOnly(lfmEclipseXML, "FxEarlyLow"), param.toaExtended->lfmEclipse->fxEarlyLow); - parseDouble(getFirstAndOnly(lfmEclipseXML, "FxEarlyHigh"), param.toaExtended->lfmEclipse->fxEarlyHigh); - parseDouble(getFirstAndOnly(lfmEclipseXML, "FxLateLow"), param.toaExtended->lfmEclipse->fxLateLow); - parseDouble(getFirstAndOnly(lfmEclipseXML, "FxLateHigh"), param.toaExtended->lfmEclipse->fxLateHigh); - } - } - - XMLElem dwellTimesXML = getFirstAndOnly(paramXML, "DwellTimes"); - parseString(getFirstAndOnly(dwellTimesXML, "CODId"), param.dwellTimes.codId); - parseString(getFirstAndOnly(dwellTimesXML, "DwellId"), param.dwellTimes.dwellId); - std::ignore = six::parse(parser(), *dwellTimesXML, param.dwellTimes.dtaId); - std::ignore = six::parse(parser(), *dwellTimesXML, param.dwellTimes.useDTA); - - XMLElem imageAreaXML = getOptional(paramXML, "ImageArea"); - if(imageAreaXML) - { - parseAreaType(imageAreaXML, param.imageArea); - } - - XMLElem antennaXML = getOptional(paramXML, "Antenna"); - if(antennaXML) - { - param.antenna.reset(new ChannelParameter::Antenna()); - parseString(getFirstAndOnly(antennaXML, "TxAPCId"), param.antenna->txAPCId); - parseString(getFirstAndOnly(antennaXML, "TxAPATId"), param.antenna->txAPATId); - parseString(getFirstAndOnly(antennaXML, "RcvAPCId"), param.antenna->rcvAPCId); - parseString(getFirstAndOnly(antennaXML, "RcvAPATId"), param.antenna->rcvAPATId); - } - - XMLElem txRcvXML = getOptional(paramXML, "TxRcv"); - if(txRcvXML) - { - std::vector txWFIdXML; - txRcvXML->getElementsByTagName("TxWFId", txWFIdXML); - param.txRcv.reset(new ChannelParameter::TxRcv()); - param.txRcv->txWFId.resize(txWFIdXML.size()); - for(size_t ii = 0; ii < txWFIdXML.size(); ++ii) - { - parseString(txWFIdXML[ii], param.txRcv->txWFId[ii]); - } - - std::vector rcvIdXML; - txRcvXML->getElementsByTagName("RcvId", rcvIdXML); - param.txRcv->rcvId.resize(rcvIdXML.size()); - for(size_t ii = 0; ii < rcvIdXML.size(); ++ii) - { - parseString(rcvIdXML[ii], param.txRcv->rcvId[ii]); - } - } - - XMLElem tgtRefLevelXML = getOptional(paramXML, "TgtRefLevel"); - if(tgtRefLevelXML) - { - param.tgtRefLevel.reset(new TgtRefLevel()); - parseDouble(getFirstAndOnly(tgtRefLevelXML, "PTRef"), param.tgtRefLevel->ptRef); - } - - XMLElem noiseLevelXML = getOptional(paramXML, "NoiseLevel"); - if(noiseLevelXML) - { - param.noiseLevel.reset(new NoiseLevel()); - parseDouble(getFirstAndOnly(noiseLevelXML, "PNRef"), param.noiseLevel->pnRef); - parseDouble(getFirstAndOnly(noiseLevelXML, "BNRef"), param.noiseLevel->bnRef); - if(!(param.noiseLevel->bnRef > 0 && param.noiseLevel->bnRef <= 1)) - { - throw except::Exception(Ctxt( - "Noise equivalent BW value must be > 0.0 and <= 1.0")); - } - - XMLElem fxNoiseProfileXML = getOptional(noiseLevelXML, "FxNoiseProfile"); - if(fxNoiseProfileXML) - { - param.noiseLevel->fxNoiseProfile.reset(new FxNoiseProfile()); - std::vector pointXMLVec; - fxNoiseProfileXML->getElementsByTagName("Point", pointXMLVec); - if(pointXMLVec.size() < 2) - { - throw except::Exception(Ctxt( - "Atleast 2 noise profile points must be provided")); - } - param.noiseLevel->fxNoiseProfile->point.resize(pointXMLVec.size()); - double prevPoint = six::Init::undefined(); - for(size_t ii = 0; ii < pointXMLVec.size(); ++ii) - { - double fx; - parseDouble(getFirstAndOnly(pointXMLVec[ii], "Fx"), fx); - parseDouble(getFirstAndOnly(pointXMLVec[ii], "PN"), param.noiseLevel->fxNoiseProfile->point[ii].pn); - - if(!six::Init::isUndefined(prevPoint) && fx <= prevPoint) - { - throw except::Exception(Ctxt( - "Fx values are strictly increasing")); - } - param.noiseLevel->fxNoiseProfile->point[ii].fx = fx; - prevPoint = fx; - } - } - } - - // Polarization - parsePolarization(*paramXML, param.polarization); -} - -void CPHDXMLParser::parse(const xml::lite::Element& polarizationXML, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(polarizationXML, o.tag())) - { - o = PolRef{}; - six::getFirstAndOnly(parser(), *pXML, value(o).ampH); - six::getFirstAndOnly(parser(), *pXML, value(o).ampV); - six::getFirstAndOnly(parser(), *pXML, value(o).phaseV); - } -} - -void CPHDXMLParser::parsePolarization(const xml::lite::Element& paramXML, Polarization& polarization) const -{ - std::vector PolarizationXML; - paramXML.getElementsByTagName("Polarization", PolarizationXML); - for (size_t ii = 0; ii < PolarizationXML.size(); ++ii) - { - const xml::lite::Element* TxPolXML = getFirstAndOnly(PolarizationXML[ii], "TxPol"); - polarization.txPol = PolarizationType::toType(TxPolXML->getCharacterData()); - - const xml::lite::Element* RcvPolXML = getFirstAndOnly(PolarizationXML[ii], "RcvPol"); - polarization.rcvPol = PolarizationType::toType(RcvPolXML->getCharacterData()); - - parse(*(PolarizationXML[ii]), polarization.txPolRef); // added in CPHD 1.1.0 - parse(*(PolarizationXML[ii]), polarization.rcvPolRef); // added in CPHD 1.1.0 - } -} - -size_t CPHDXMLParser::parsePVPType(const xml::lite::Element& paramXML, PVPType& param) const -{ - size_t size; - size_t offset; - std::string format; - parseUInt(getFirstAndOnly(paramXML, "Size"), size); - parseUInt(getFirstAndOnly(paramXML, "Offset"), offset); - parseString(getFirstAndOnly(paramXML, "Format"), format); - if (param.getSize() != size) - { - std::ostringstream ostr; - ostr << "Specified size: " << size << " does not match default size: " << param.getSize(); - throw except::Exception(Ctxt(ostr.str())); - } - if (param.getFormat() != format) - { - std::ostringstream ostr; - ostr << "Specified format: " << format << " does not match default format: " << param.getFormat(); - throw except::Exception(Ctxt(ostr.str())); - } - return offset; -} -void CPHDXMLParser::parsePVPType(Pvp& pvp, const xml::lite::Element* paramXML, PVPType& param) const -{ - const auto offset = parsePVPType(*paramXML, param); - pvp.setOffset(offset, param); -} - -void CPHDXMLParser::parsePVPType(Pvp& pvp, const xml::lite::Element* paramXML) const -{ - std::string name; - size_t size; - size_t offset; - std::string format; - parseString(getFirstAndOnly(paramXML, "Name"), name); - parseUInt(getFirstAndOnly(paramXML, "Size"), size); - parseUInt(getFirstAndOnly(paramXML, "Offset"), offset); - parseString(getFirstAndOnly(paramXML, "Format"), format); - pvp.setCustomParameter(size, offset, format, name); -} - -bool CPHDXMLParser::parseOptionalPVPType(const xml::lite::Element* parent, const std::string& tag, Pvp& pvp, PVPType& param) const -{ - if (const xml::lite::Element* const element = getOptional(parent, tag)) - { - parsePVPType(pvp, element, param); - return true; - } - return false; -} - -void CPHDXMLParser::parsePlatformParams(const xml::lite::Element* platXML, Bistatic::PlatformParams& plat) const -{ - parseDouble(getFirstAndOnly(platXML, "Time"), plat.time); - parseDouble(getFirstAndOnly(platXML, "SlantRange"), plat.slantRange); - parseDouble(getFirstAndOnly(platXML, "GroundRange"), plat.groundRange); - parseDouble(getFirstAndOnly(platXML, "DopplerConeAngle"), plat.dopplerConeAngle); - parseDouble(getFirstAndOnly(platXML, "AzimuthAngle"), plat.azimuthAngle); - parseDouble(getFirstAndOnly(platXML, "GrazeAngle"), plat.grazeAngle); - parseDouble(getFirstAndOnly(platXML, "IncidenceAngle"), plat.incidenceAngle); - mCommon.parseVector3D(getFirstAndOnly(platXML, "Pos"), plat.pos); - mCommon.parseVector3D(getFirstAndOnly(platXML, "Vel"), plat.vel); - std::string side = ""; - parseString(getFirstAndOnly(platXML, "SideOfTrack"), side); - plat.sideOfTrack = (side == "L" ? six::SideOfTrackType::LEFT : six::SideOfTrackType::RIGHT); - -} - -void CPHDXMLParser::parseCommon(const xml::lite::Element* imgTypeXML, ImagingType* imgType) const -{ - parseDouble(getFirstAndOnly(imgTypeXML, "TwistAngle"), imgType->twistAngle); - parseDouble(getFirstAndOnly(imgTypeXML, "SlopeAngle"), imgType->slopeAngle); - parseDouble(getFirstAndOnly(imgTypeXML, "LayoverAngle"), imgType->layoverAngle); - parseDouble(getFirstAndOnly(imgTypeXML, "AzimuthAngle"), imgType->azimuthAngle); - parseDouble(getFirstAndOnly(imgTypeXML, "GrazeAngle"), imgType->grazeAngle); -} - -void CPHDXMLParser::parsePosVelErr(const xml::lite::Element* posVelErrXML, six::PosVelError& posVelErr) const -{ - std::string frameStr; - parseString(getFirstAndOnly(posVelErrXML, "Frame"), frameStr); - posVelErr.frame.mValue = scene::FrameType::fromString(frameStr); - parseDouble(getFirstAndOnly(posVelErrXML, "P1"), posVelErr.p1); - parseDouble(getFirstAndOnly(posVelErrXML, "P2"), posVelErr.p2); - parseDouble(getFirstAndOnly(posVelErrXML, "P3"), posVelErr.p3); - parseDouble(getFirstAndOnly(posVelErrXML, "V1"), posVelErr.v1); - parseDouble(getFirstAndOnly(posVelErrXML, "V2"), posVelErr.v2); - parseDouble(getFirstAndOnly(posVelErrXML, "V3"), posVelErr.v3); - - XMLElem corrCoefsXML = getOptional(posVelErrXML, "CorrCoefs"); - - if(corrCoefsXML) - { - posVelErr.corrCoefs.reset(new six::CorrCoefs()); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1P2"), posVelErr.corrCoefs->p1p2); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1P3"), posVelErr.corrCoefs->p1p3); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1V1"), posVelErr.corrCoefs->p1v1); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1V2"), posVelErr.corrCoefs->p1v2); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1V3"), posVelErr.corrCoefs->p1v3); - parseDouble(getFirstAndOnly(corrCoefsXML, "P2P3"), posVelErr.corrCoefs->p2p3); - parseDouble(getFirstAndOnly(corrCoefsXML, "P2V1"), posVelErr.corrCoefs->p2v1); - parseDouble(getFirstAndOnly(corrCoefsXML, "P2V2"), posVelErr.corrCoefs->p2v2); - parseDouble(getFirstAndOnly(corrCoefsXML, "P2V3"), posVelErr.corrCoefs->p2v3); - parseDouble(getFirstAndOnly(corrCoefsXML, "P3V1"), posVelErr.corrCoefs->p3v1); - parseDouble(getFirstAndOnly(corrCoefsXML, "P3V2"), posVelErr.corrCoefs->p3v2); - parseDouble(getFirstAndOnly(corrCoefsXML, "P3V3"), posVelErr.corrCoefs->p3v3); - parseDouble(getFirstAndOnly(corrCoefsXML, "V1V2"), posVelErr.corrCoefs->v1v2); - parseDouble(getFirstAndOnly(corrCoefsXML, "V1V3"), posVelErr.corrCoefs->v1v3); - parseDouble(getFirstAndOnly(corrCoefsXML, "V2V3"), posVelErr.corrCoefs->v2v3); - } - - // posVelErr.positionDecorr.reset(new six::DecorrType()); - mCommon.parseOptionalDecorrType(posVelErrXML, "PositionDecorr", posVelErr.positionDecorr); -} - -void CPHDXMLParser::parsePlatform(const xml::lite::Element* platXML, ErrorParameters::Bistatic::Platform& plat) const -{ - parsePosVelErr(getFirstAndOnly(platXML, "PosVelErr"), plat.posVelErr); - XMLElem radarSensorXML = getFirstAndOnly(platXML, "RadarSensor"); - six::parse(parser(), *radarSensorXML, plat.radarSensor.delayBias); - parseOptionalDouble(radarSensorXML, "ClockFreqSF", plat.radarSensor.clockFreqSF); - parseDouble(getFirstAndOnly(radarSensorXML, "CollectionStartTime"), plat.radarSensor.collectionStartTime); -} - -void CPHDXMLParser::parseSupportArrayParameter(const xml::lite::Element* paramXML, SupportArrayParameter& param, bool additionalFlag) const -{ - if(!additionalFlag) - { - size_t identifierVal; - parseUInt(getFirstAndOnly(paramXML, "Identifier"), identifierVal); - param.setIdentifier(identifierVal); - } - parseString(getFirstAndOnly(paramXML, "ElementFormat"), param.elementFormat); - parseDouble(getFirstAndOnly(paramXML, "X0"), param.x0); - parseDouble(getFirstAndOnly(paramXML, "Y0"), param.y0); - parseDouble(getFirstAndOnly(paramXML, "XSS"), param.xSS); - parseDouble(getFirstAndOnly(paramXML, "YSS"), param.ySS); -} - -void CPHDXMLParser::parseTxRcvParameter(const xml::lite::Element* paramXML, ParameterType& param) const -{ - parseString(getFirstAndOnly(paramXML, "Identifier"), param.identifier); - parseDouble(getFirstAndOnly(paramXML, "FreqCenter"), param.freqCenter); - parseOptionalDouble(paramXML, "LFMRate", param.lfmRate); - param.polarization = PolarizationType::toType(getFirstAndOnly(paramXML, "Polarization")->getCharacterData()); -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define ENFORCESPEC 0 + +namespace +{ +typedef xml::lite::Element* XMLElem; +} + +namespace cphd +{ + +CPHDXMLParser::CPHDXMLParser( + const std::string& uri, + bool addClassAttributes, + logging::Logger* log, + bool ownLog) : + six::XMLParser(uri, addClassAttributes, log, ownLog), + mCommon(getDefaultURI(), addClassAttributes, getDefaultURI(), log) +{ +} + +/* + * TO XML + */ +std::unique_ptr CPHDXMLParser::toXML( + const Metadata& metadata) +{ + std::unique_ptr doc(new xml::lite::Document()); + + XMLElem root = newElement("CPHD"); + doc->setRootElement(root); + + toXML(metadata.collectionID, root); + toXML(metadata.global, root); + toXML(metadata.sceneCoordinates, root); + toXML(metadata.data, root); + toXML(metadata.channel, root); + toXML(metadata.pvp, root); + toXML(metadata.dwell, root); + toXML(metadata.referenceGeometry, root); + + if (metadata.supportArray.get()) + { + toXML(*(metadata.supportArray), root); + } + if (metadata.antenna.get()) + { + toXML(*(metadata.antenna), root); + } + if (metadata.txRcv.get()) + { + toXML(*(metadata.txRcv), root); + } + if (metadata.errorParameters.get()) + { + toXML(*(metadata.errorParameters), root); + } + if (metadata.productInfo.get()) + { + toXML(*(metadata.productInfo), root); + } + for (const auto& geoInfo : metadata.geoInfo) + { + toXML(geoInfo, root); + } + if (metadata.matchInfo.get()) + { + toXML(*(metadata.matchInfo), root); + } + + //set the XMLNS + root->setNamespacePrefix("", getDefaultURI()); + + return doc; +} + +XMLElem CPHDXMLParser::toXML(const CollectionInformation& collectionID, XMLElem parent) +{ + XMLElem collectionXML = newElement("CollectionID", parent); + + createString("CollectorName", collectionID.collectorName, collectionXML); + if(!six::Init::isUndefined(collectionID.illuminatorName)) + { + createString("IlluminatorName", collectionID.illuminatorName, collectionXML); + } + createString("CoreName", collectionID.coreName, collectionXML); + createString("CollectType", collectionID.collectType, collectionXML); + + // RadarMode + XMLElem radarModeXML = newElement("RadarMode", collectionXML); + createSixString("ModeType", collectionID.radarMode, radarModeXML); + if(!six::Init::isUndefined(collectionID.radarModeID)) + { + createString("ModeID", collectionID.radarModeID, radarModeXML); + } + createString("Classification", collectionID.getClassificationLevel(), collectionXML); + createString("ReleaseInfo", collectionID.releaseInfo, collectionXML); + if (!collectionID.countryCodes.empty()) + { + std::string countryCodes = str::join(collectionID.countryCodes, ","); + createString("CountryCode", countryCodes, collectionXML); + } + mCommon.addParameters("Parameter", getDefaultURI(), collectionID.parameters, collectionXML); + return collectionXML; +} + +XMLElem CPHDXMLParser::toXML(const Global& global, XMLElem parent) +{ + XMLElem globalXML = newElement("Global", parent); + createString("DomainType", global.domainType, globalXML); + createString("SGN", global.sgn, globalXML); + + //Timeline + XMLElem timelineXML = newElement("Timeline", globalXML); + createDateTime("CollectionStart", global.timeline.collectionStart, timelineXML); + if (!six::Init::isUndefined(global.timeline.rcvCollectionStart)) + { + createDateTime("RcvCollectionStart", global.timeline.rcvCollectionStart, timelineXML); + } + createDouble("TxTime1", global.timeline.txTime1, timelineXML); + createDouble("TxTime2", global.timeline.txTime2, timelineXML); + + XMLElem fxBandXML = newElement("FxBand", globalXML); + createDouble("FxMin", global.fxBand.fxMin, fxBandXML); + createDouble("FxMax", global.fxBand.fxMax, fxBandXML); + + XMLElem toaSwathXML = newElement("TOASwath", globalXML); + createDouble("TOAMin", global.toaSwath.toaMin, toaSwathXML); + createDouble("TOAMax", global.toaSwath.toaMax, toaSwathXML); + + if (global.tropoParameters.get()) + { + XMLElem tropoXML = newElement("TropoParameters", globalXML); + createDouble("N0", global.tropoParameters->n0, tropoXML); + createString("RefHeight", global.tropoParameters->refHeight, tropoXML); + } + if (global.ionoParameters.get()) + { + XMLElem ionoXML = newElement("IonoParameters", globalXML); + createDouble("TECV", global.ionoParameters->tecv, ionoXML); + createOptionalDouble("F2Height", global.ionoParameters->f2Height, ionoXML); + } + return globalXML; +} + +XMLElem CPHDXMLParser::toXML(const SceneCoordinates& sceneCoords, XMLElem parent) +{ + XMLElem sceneCoordsXML = newElement("SceneCoordinates", parent); + createString("EarthModel", sceneCoords.earthModel, sceneCoordsXML); + + XMLElem iarpXML = newElement("IARP", sceneCoordsXML); + mCommon.createVector3D("ECF", sceneCoords.iarp.ecf, iarpXML); + mCommon.createLatLonAlt("LLH", sceneCoords.iarp.llh, iarpXML); + + XMLElem refSurfXML = newElement("ReferenceSurface", sceneCoordsXML); + if (sceneCoords.referenceSurface.planar.get()) + { + XMLElem planarXML = newElement("Planar", refSurfXML); + mCommon.createVector3D("uIAX", sceneCoords.referenceSurface.planar->uIax, planarXML); + mCommon.createVector3D("uIAY", sceneCoords.referenceSurface.planar->uIay, planarXML); + } + else if (sceneCoords.referenceSurface.hae.get()) + { + XMLElem haeXML = newElement("HAE", refSurfXML); + mCommon.createLatLon("uIAXLL", sceneCoords.referenceSurface.hae->uIax, haeXML); + mCommon.createLatLon("uIAYLL", sceneCoords.referenceSurface.hae->uIay, haeXML); + } + else + { + throw except::Exception(Ctxt( + "Reference Surface must be one of two types")); + } + + XMLElem imageAreaXML = newElement("ImageArea", sceneCoordsXML); + mCommon.createVector2D("X1Y1", sceneCoords.imageArea.x1y1, imageAreaXML); + mCommon.createVector2D("X2Y2", sceneCoords.imageArea.x2y2, imageAreaXML); + + if (!sceneCoords.imageArea.polygon.empty()) + { + XMLElem polygonXML = newElement("Polygon", imageAreaXML); + setAttribute(polygonXML, "size", sceneCoords.imageArea.polygon.size()); + for (size_t ii = 0; ii < sceneCoords.imageArea.polygon.size(); ++ii) + { + XMLElem vertexXML = mCommon.createVector2D("Vertex", sceneCoords.imageArea.polygon[ii], polygonXML); + setAttribute(vertexXML, "index", ii+1); + } + } + createLatLonFootprint("ImageAreaCornerPoints", "IACP", sceneCoords.imageAreaCorners, sceneCoordsXML); + + // Extended Area (Optional) + if(sceneCoords.extendedArea.get()) + { + XMLElem extendedAreaXML = newElement("ExtendedArea", sceneCoordsXML); + mCommon.createVector2D("X1Y1", sceneCoords.extendedArea->x1y1, extendedAreaXML); + mCommon.createVector2D("X2Y2", sceneCoords.extendedArea->x2y2, extendedAreaXML); + + if (!sceneCoords.extendedArea->polygon.empty()) + { + XMLElem polygonXML = newElement("Polygon", sceneCoordsXML); + setAttribute(polygonXML, "size", sceneCoords.extendedArea->polygon.size()); + for (size_t ii = 0; ii < sceneCoords.extendedArea->polygon.size(); ++ii) + { + XMLElem vertexXML = mCommon.createVector2D("Vertex", sceneCoords.extendedArea->polygon[ii], polygonXML); + setAttribute(vertexXML, "index", ii+1); + } + } + } + + // ImageGrid (Optional) + if(sceneCoords.imageGrid.get()) + { + XMLElem imageGridXML = newElement("ImageGrid", sceneCoordsXML); + if(!six::Init::isUndefined(sceneCoords.imageGrid->identifier)) + { + createString("Identifier", sceneCoords.imageGrid->identifier, imageGridXML); + } + XMLElem iarpLocationXML = newElement("IARPLocation", imageGridXML); + createDouble("Line", sceneCoords.imageGrid->iarpLocation.line, iarpLocationXML); + createDouble("Sample", sceneCoords.imageGrid->iarpLocation.sample, iarpLocationXML); + + XMLElem iaxExtentXML = newElement("IAXExtent", imageGridXML); + createDouble("LineSpacing", sceneCoords.imageGrid->xExtent.lineSpacing, iaxExtentXML); + createInt("FirstLine", sceneCoords.imageGrid->xExtent.firstLine, iaxExtentXML); + createInt("NumLines", sceneCoords.imageGrid->xExtent.numLines, iaxExtentXML); + + XMLElem iayExtentXML = newElement("IAYExtent", imageGridXML); + createDouble("SampleSpacing", sceneCoords.imageGrid->yExtent.sampleSpacing, iayExtentXML); + createInt("FirstSample", sceneCoords.imageGrid->yExtent.firstSample, iayExtentXML); + createInt("NumSamples", sceneCoords.imageGrid->yExtent.numSamples, iayExtentXML); + + if (!sceneCoords.imageGrid->segments.empty()) + { + XMLElem segmentListXML = newElement("SegmentList", imageGridXML); + createInt("NumSegments", sceneCoords.imageGrid->segments.size(), segmentListXML); + + for (size_t ii = 0; ii < sceneCoords.imageGrid->segments.size(); ++ii) + { + XMLElem segmentXML = newElement("Segment", segmentListXML); + createString("Identifier", sceneCoords.imageGrid->segments[ii].identifier, segmentXML); + createInt("StartLine", sceneCoords.imageGrid->segments[ii].startLine, segmentXML); + createInt("StartSample", sceneCoords.imageGrid->segments[ii].startSample, segmentXML); + createInt("EndLine", sceneCoords.imageGrid->segments[ii].endLine, segmentXML); + createInt("EndSample", sceneCoords.imageGrid->segments[ii].endSample, segmentXML); + + if (!sceneCoords.imageGrid->segments[ii].polygon.empty()) + { + XMLElem polygonXML = newElement("SegmentPolygon", segmentXML); + setAttribute(polygonXML, "size", sceneCoords.imageGrid->segments[ii].polygon.size()); + for (size_t jj = 0; jj < sceneCoords.imageGrid->segments[ii].polygon.size(); ++jj) + { + XMLElem svXML = newElement("SV", polygonXML); + setAttribute(svXML, "index", sceneCoords.imageGrid->segments[ii].polygon[jj].getIndex()); + createDouble("Line", sceneCoords.imageGrid->segments[ii].polygon[jj].line, svXML); + createDouble("Sample", sceneCoords.imageGrid->segments[ii].polygon[jj].sample, svXML); + } + } + } + } + } + return sceneCoordsXML; +} + +XMLElem CPHDXMLParser::toXML(const Data& data, XMLElem parent) +{ + XMLElem dataXML = newElement("Data", parent); + createString("SignalArrayFormat", data.signalArrayFormat, dataXML); + createInt("NumBytesPVP", data.numBytesPVP, dataXML); + createInt("NumCPHDChannels", data.channels.size(), dataXML); + if (!six::Init::isUndefined(data.signalCompressionID)) + { + createString("SignalCompressionID", data.signalCompressionID, dataXML); + } + + for (size_t ii = 0; ii < data.channels.size(); ++ii) + { + XMLElem channelXML = newElement("Channel", dataXML); + createString("Identifier", data.channels[ii].identifier, channelXML); + createInt("NumVectors", data.channels[ii].numVectors, channelXML); + createInt("NumSamples", data.channels[ii].numSamples, channelXML); + createInt("SignalArrayByteOffset", data.channels[ii].signalArrayByteOffset, channelXML); + createInt("PVPArrayByteOffset", data.channels[ii].pvpArrayByteOffset, channelXML); + if(!six::Init::isUndefined(data.channels[ii].compressedSignalSize)) + { + createInt("CompressedSignalSize", data.channels[ii].compressedSignalSize, channelXML); + } + } + createInt("NumSupportArrays", data.supportArrayMap.size(), dataXML); + for (const auto& entry : data.supportArrayMap) + { + XMLElem supportArrayXML = newElement("SupportArray", dataXML); + createString("Identifier", entry.second.identifier, supportArrayXML); + createInt("NumRows", entry.second.numRows, supportArrayXML); + createInt("NumCols", entry.second.numCols, supportArrayXML); + createInt("BytesPerElement", entry.second.bytesPerElement, supportArrayXML); + createInt("ArrayByteOffset", entry.second.arrayByteOffset, supportArrayXML); + } + return dataXML; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem pXML = nullptr; + if (has_value(o)) + { + pXML = newElement(o.tag(), &parent); + std::ignore = create(parser(), value(o).ampH, *pXML); + std::ignore = create(parser(), value(o).ampV, *pXML); + std::ignore = create(parser(), value(o).phaseV, *pXML); + } + + return pXML; +} + +XMLElem CPHDXMLParser::toXML(const Polarization& obj, xml::lite::Element& parent) +{ + auto polXML = newElement("Polarization", &parent); + createString("TxPol", obj.txPol, polXML); + createString("RcvPol", obj.rcvPol, polXML); + + toXML(obj.txPolRef, *polXML); // added in CPHD 1.1.0 + toXML(obj.rcvPolRef, *polXML); // added in CPHD 1.1.0 + + return polXML; +} + +XMLElem CPHDXMLParser::toXML(const Channel& channel, XMLElem parent) +{ + XMLElem channelXML = newElement("Channel", parent); + createString("RefChId", channel.refChId, channelXML); + createBooleanType("FXFixedCPHD", channel.fxFixedCphd, channelXML); + createBooleanType("TOAFixedCPHD", channel.toaFixedCphd, channelXML); + createBooleanType("SRPFixedCPHD", channel.srpFixedCphd, channelXML); + + for (size_t ii = 0; ii < channel.parameters.size(); ++ii) + { + XMLElem parametersXML = newElement("Parameters", channelXML); + createString("Identifier", channel.parameters[ii].identifier, parametersXML); + createInt("RefVectorIndex", channel.parameters[ii].refVectorIndex, parametersXML); + createBooleanType("FXFixed", channel.parameters[ii].fxFixed, parametersXML); + createBooleanType("TOAFixed", channel.parameters[ii].toaFixed, parametersXML); + createBooleanType("SRPFixed", channel.parameters[ii].srpFixed, parametersXML); + if (!six::Init::isUndefined(channel.parameters[ii].signalNormal)) + { + createBooleanType("SignalNormal", channel.parameters[ii].signalNormal, parametersXML); + } + std::ignore = toXML(channel.parameters[ii].polarization, *parametersXML); + + createDouble("FxC", channel.parameters[ii].fxC, parametersXML); + createDouble("FxBW", channel.parameters[ii].fxBW, parametersXML); + createOptionalDouble("FxBWNoise", channel.parameters[ii].fxBWNoise, parametersXML); + createDouble("TOASaved", channel.parameters[ii].toaSaved, parametersXML); + + if(channel.parameters[ii].toaExtended.get()) + { + XMLElem toaExtendedXML = newElement("TOAExtended", parametersXML); + createDouble("TOAExtSaved", channel.parameters[ii].toaExtended->toaExtSaved, toaExtendedXML); + if(channel.parameters[ii].toaExtended->lfmEclipse.get()) + { + XMLElem lfmEclipseXML = newElement("LFMEclipse", toaExtendedXML); + createDouble("FxEarlyLow", channel.parameters[ii].toaExtended->lfmEclipse->fxEarlyLow, lfmEclipseXML); + createDouble("FxEarlyHigh", channel.parameters[ii].toaExtended->lfmEclipse->fxEarlyHigh, lfmEclipseXML); + createDouble("FxLateLow", channel.parameters[ii].toaExtended->lfmEclipse->fxLateLow, lfmEclipseXML); + createDouble("FxLateHigh", channel.parameters[ii].toaExtended->lfmEclipse->fxLateHigh, lfmEclipseXML); + } + } + XMLElem dwellTimesXML = newElement("DwellTimes", parametersXML); + createString("CODId", channel.parameters[ii].dwellTimes.codId, dwellTimesXML); + createString("DwellId", channel.parameters[ii].dwellTimes.dwellId, dwellTimesXML); + std::ignore = create(parser(), channel.parameters[ii].dwellTimes.dtaId, *dwellTimesXML); + std::ignore = create(parser(), channel.parameters[ii].dwellTimes.useDTA, *dwellTimesXML); + + if(!six::Init::isUndefined(channel.parameters[ii].imageArea)) + { + XMLElem imageAreaXML = newElement("ImageArea", parametersXML); + mCommon.createVector2D("X1Y1", channel.parameters[ii].imageArea.x1y1, imageAreaXML); + mCommon.createVector2D("X2Y2", channel.parameters[ii].imageArea.x2y2, imageAreaXML); + if(!channel.parameters[ii].imageArea.polygon.empty()) + { + XMLElem polygonXML = newElement("Polygon", imageAreaXML); + setAttribute(polygonXML, "size", channel.parameters[ii].imageArea.polygon.size()); + for (size_t jj = 0; jj < channel.parameters[ii].imageArea.polygon.size(); ++jj) + { + XMLElem vertexXML = mCommon.createVector2D("Vertex", channel.parameters[ii].imageArea.polygon[jj], polygonXML); + setAttribute(vertexXML, "index", jj+1); + } + } + } + if(channel.parameters[ii].antenna.get()) + { + XMLElem antennaXML = newElement("Antenna", parametersXML); + createString("TxAPCId", channel.parameters[ii].antenna->txAPCId, antennaXML); + createString("TxAPATId", channel.parameters[ii].antenna->txAPATId, antennaXML); + createString("RcvAPCId", channel.parameters[ii].antenna->rcvAPCId, antennaXML); + createString("RcvAPATId", channel.parameters[ii].antenna->rcvAPATId, antennaXML); + } + if(channel.parameters[ii].txRcv.get()) + { + XMLElem txRcvXML = newElement("TxRcv", parametersXML); + for (size_t jj = 0; jj < channel.parameters[ii].txRcv->txWFId.size(); ++jj) + { + createString("TxWFId", channel.parameters[ii].txRcv->txWFId[jj], txRcvXML); + } + for (size_t jj = 0; jj < channel.parameters[ii].txRcv->rcvId.size(); ++jj) + { + createString("RcvId", channel.parameters[ii].txRcv->rcvId[jj], txRcvXML); + } + } + if(channel.parameters[ii].tgtRefLevel.get()) + { + XMLElem tgtRefXML = newElement("TgtRefLevel", parametersXML); + createDouble("PTRef", channel.parameters[ii].tgtRefLevel->ptRef, tgtRefXML); + } + if(channel.parameters[ii].noiseLevel.get()) + { + XMLElem noiseLevelXML = newElement("NoiseLevel", parametersXML); + createDouble("PNRef", channel.parameters[ii].noiseLevel->pnRef, noiseLevelXML); + createDouble("BNRef", channel.parameters[ii].noiseLevel->bnRef, noiseLevelXML); + if(channel.parameters[ii].noiseLevel->fxNoiseProfile.get()) + { + XMLElem fxNoiseProfileXML = newElement("FxNoiseProfile", noiseLevelXML); + for (size_t jj = 0; jj < channel.parameters[ii].noiseLevel->fxNoiseProfile->point.size(); ++jj) + { + XMLElem pointXML = newElement("Point", fxNoiseProfileXML); + createDouble("Fx", channel.parameters[ii].noiseLevel->fxNoiseProfile->point[jj].fx, pointXML); + createDouble("PN", channel.parameters[ii].noiseLevel->fxNoiseProfile->point[jj].pn, pointXML); + } + } + } + } + if(!channel.addedParameters.empty()) + { + XMLElem addedParamsXML = newElement("AddedParameters", channelXML); + mCommon.addParameters("Parameter", getDefaultURI(), channel.addedParameters, addedParamsXML); + } + return channelXML; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement& v, xml::lite::Element& parent) +{ + return createPVPType(v.tag(), v.value().param, &parent); +} +XMLElem CPHDXMLParser::toXML(const six::XsElement& v, xml::lite::Element& parent) +{ + return createPVPType(v.tag(), v.value().param, &parent); +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem pXML = nullptr; + if (has_value(o)) + { + pXML = newElement(o.tag(), &parent); + std::ignore = toXML(value(o).txACX, *pXML); + std::ignore = toXML(value(o).txACY, *pXML); + std::ignore = toXML(value(o).txEB, *pXML); + } + + return pXML; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem pXML = nullptr; + if (has_value(o)) + { + pXML = newElement(o.tag(), &parent); + std::ignore = toXML(value(o).rcvACX, *pXML); + std::ignore = toXML(value(o).rcvACY, *pXML); + std::ignore = toXML(value(o).rcvEB, *pXML); + } + + return pXML; +} + +XMLElem CPHDXMLParser::toXML(const Pvp& pvp, XMLElem parent) +{ + XMLElem pvpXML = newElement("PVP", parent); + createPVPType("TxTime", pvp.txTime, pvpXML); + createPVPType("TxPos", pvp.txPos, pvpXML); + createPVPType("TxVel", pvp.txVel, pvpXML); + createPVPType("RcvTime", pvp.rcvTime, pvpXML); + createPVPType("RcvPos", pvp.rcvPos, pvpXML); + createPVPType("RcvVel", pvp.rcvVel, pvpXML); + createPVPType("SRPPos", pvp.srpPos, pvpXML); + if (!six::Init::isUndefined(pvp.ampSF.getOffset())) + { + createPVPType("AmpSF", pvp.ampSF, pvpXML); + } + createPVPType("aFDOP", pvp.aFDOP, pvpXML); + createPVPType("aFRR1", pvp.aFRR1, pvpXML); + createPVPType("aFRR2", pvp.aFRR2, pvpXML); + createPVPType("FX1", pvp.fx1, pvpXML); + createPVPType("FX2", pvp.fx2, pvpXML); + if (!six::Init::isUndefined(pvp.fxN1.getOffset())) + { + createPVPType("FXN1", pvp.fxN1, pvpXML); + } + if (!six::Init::isUndefined(pvp.fxN2.getOffset())) + { + createPVPType("FXN2", pvp.fxN2, pvpXML); + } + createPVPType("TOA1", pvp.toa1, pvpXML); + createPVPType("TOA2", pvp.toa2, pvpXML); + if (!six::Init::isUndefined(pvp.toaE1.getOffset())) + { + createPVPType("TOAE1", pvp.toaE1, pvpXML); + } + if (!six::Init::isUndefined(pvp.toaE2.getOffset())) + { + createPVPType("TOAE2", pvp.toaE2, pvpXML); + } + createPVPType("TDTropoSRP", pvp.tdTropoSRP, pvpXML); + if (!six::Init::isUndefined(pvp.tdIonoSRP.getOffset())) + { + createPVPType("TDIonoSRP", pvp.tdIonoSRP, pvpXML); + } + createPVPType("SC0", pvp.sc0, pvpXML); + createPVPType("SCSS", pvp.scss, pvpXML); + if (!six::Init::isUndefined(pvp.signal.getOffset())) + { + createPVPType("SIGNAL", pvp.signal, pvpXML); + } + + std::ignore = toXML(pvp.txAntenna, *pvpXML); + std::ignore = toXML(pvp.rcvAntenna, *pvpXML); + + for (auto it = pvp.addedPVP.begin(); it != pvp.addedPVP.end(); ++it) + { + createAPVPType("AddedPVP", it->second, pvpXML); + } + + return pvpXML; +} + +void CPHDXMLParser::createSupportArray(const std::vector& supportArray, + const std::string& tag, xml::lite::Element& parent) +{ + for (auto&& param : supportArray) + { + XMLElem pXML = newElement(tag, &parent); + createInt("Identifier", param.getIdentifier(), pXML); + createString("ElementFormat", param.elementFormat, pXML); + createDouble("X0", param.x0, pXML); + createDouble("Y0", param.y0, pXML); + createDouble("XSS", param.xSS, pXML); + createDouble("YSS", param.ySS, pXML); + + } +} + +//Assumes optional handled by caller +XMLElem CPHDXMLParser::toXML(const SupportArray& supports, XMLElem parent) +{ + XMLElem supportsXML = newElement("SupportArray", parent); + createSupportArray(supports.iazArray, "IAZArray", *supportsXML); + createSupportArray(supports.antGainPhase, "AntGainPhase", *supportsXML); + createSupportArray(supports.dwellTimeArray, "DwellTimeArray", *supportsXML); // added in CPHD 1.1.0 + + if (!supports.addedSupportArray.empty()) + { + for (auto it = supports.addedSupportArray.begin(); it != supports.addedSupportArray.end(); ++it) + { + XMLElem addedSupportArrayXML = newElement("AddedSupportArray", supportsXML); + createString("Identifier", it->first, addedSupportArrayXML); + createString("ElementFormat", it->second.elementFormat, addedSupportArrayXML); + createDouble("X0", it->second.x0, addedSupportArrayXML); + createDouble("Y0", it->second.y0, addedSupportArrayXML); + createDouble("XSS", it->second.xSS, addedSupportArrayXML); + createDouble("YSS", it->second.ySS, addedSupportArrayXML); + createString("XUnits", it->second.xUnits, addedSupportArrayXML); + createString("YUnits", it->second.yUnits, addedSupportArrayXML); + createString("ZUnits", it->second.zUnits, addedSupportArrayXML); + mCommon.addParameters("Parameter", getDefaultURI(), it->second.parameter, addedSupportArrayXML); + } + } + return supportsXML; +} + +XMLElem CPHDXMLParser::toXML(const Dwell& dwell, XMLElem parent) +{ + XMLElem dwellXML = newElement("Dwell", parent); + createInt("NumCODTimes", dwell.cod.size(), dwellXML); + + for (size_t ii = 0; ii < dwell.cod.size(); ++ii) + { + XMLElem codTimeXML = newElement("CODTime", dwellXML); + createString("Identifier", dwell.cod[ii].identifier, codTimeXML); + mCommon.createPoly2D("CODTimePoly", dwell.cod[ii].codTimePoly, codTimeXML); + } + createInt("NumDwellTimes", dwell.dtime.size(), dwellXML); + for (size_t ii = 0; ii < dwell.dtime.size(); ++ii) + { + XMLElem dwellTimeXML = newElement("DwellTime", dwellXML); + createString("Identifier", dwell.dtime[ii].identifier, dwellTimeXML); + mCommon.createPoly2D("DwellTimePoly", dwell.dtime[ii].dwellTimePoly, dwellTimeXML); + } + return dwellXML; +} + +XMLElem CPHDXMLParser::toXML(const ReferenceGeometry& refGeo, XMLElem parent) +{ + XMLElem refGeoXML = newElement("ReferenceGeometry", parent); + XMLElem srpXML = newElement("SRP", refGeoXML); + mCommon.createVector3D("ECF", refGeo.srp.ecf, srpXML); + mCommon.createVector3D("IAC", refGeo.srp.iac, srpXML); + createDouble("ReferenceTime", refGeo.referenceTime, refGeoXML); + createDouble("SRPCODTime", refGeo.srpCODTime, refGeoXML); + createDouble("SRPDwellTime", refGeo.srpDwellTime, refGeoXML); + + if (refGeo.monostatic.get()) + { + XMLElem monoXML = newElement("Monostatic", refGeoXML); + mCommon.createVector3D("ARPPos", refGeo.monostatic->arpPos, monoXML); + mCommon.createVector3D("ARPVel", refGeo.monostatic->arpVel, monoXML); + const auto side = refGeo.monostatic->sideOfTrack.toString(); + createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), monoXML); + createDouble("SlantRange", refGeo.monostatic->slantRange, monoXML); + createDouble("GroundRange", refGeo.monostatic->groundRange, monoXML); + createDouble("DopplerConeAngle", refGeo.monostatic->dopplerConeAngle, monoXML); + createDouble("GrazeAngle", refGeo.monostatic->grazeAngle, monoXML); + createDouble("IncidenceAngle", refGeo.monostatic->incidenceAngle, monoXML); + createDouble("AzimuthAngle", refGeo.monostatic->azimuthAngle, monoXML); + createDouble("TwistAngle", refGeo.monostatic->twistAngle, monoXML); + createDouble("SlopeAngle", refGeo.monostatic->slopeAngle, monoXML); + createDouble("LayoverAngle", refGeo.monostatic->layoverAngle, monoXML); + } + else if(refGeo.bistatic.get()) + { + XMLElem biXML = newElement("Bistatic", refGeoXML); + createDouble("AzimuthAngle", refGeo.bistatic->azimuthAngle, biXML); + createDouble("AzimuthAngleRate", refGeo.bistatic->azimuthAngleRate, biXML); + createDouble("BistaticAngle", refGeo.bistatic->bistaticAngle, biXML); + createDouble("BistaticAngleRate", refGeo.bistatic->bistaticAngleRate, biXML); + createDouble("GrazeAngle", refGeo.bistatic->grazeAngle, biXML); + createDouble("TwistAngle", refGeo.bistatic->twistAngle, biXML); + createDouble("SlopeAngle", refGeo.bistatic->slopeAngle, biXML); + createDouble("LayoverAngle", refGeo.bistatic->layoverAngle, biXML); + XMLElem txPlatXML = newElement("TxPlatform", biXML); + createDouble("Time", refGeo.bistatic->txPlatform.time, txPlatXML); + mCommon.createVector3D("Pos", refGeo.bistatic->txPlatform.pos, txPlatXML); + mCommon.createVector3D("Vel", refGeo.bistatic->txPlatform.vel, txPlatXML); + + { + const auto side = refGeo.bistatic->txPlatform.sideOfTrack.toString(); + createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), txPlatXML); + } + createDouble("SlantRange", refGeo.bistatic->txPlatform.slantRange, txPlatXML); + createDouble("GroundRange", refGeo.bistatic->txPlatform.groundRange, txPlatXML); + createDouble("DopplerConeAngle", refGeo.bistatic->txPlatform.dopplerConeAngle, txPlatXML); + createDouble("GrazeAngle", refGeo.bistatic->txPlatform.grazeAngle, txPlatXML); + createDouble("IncidenceAngle", refGeo.bistatic->txPlatform.incidenceAngle, txPlatXML); + createDouble("AzimuthAngle", refGeo.bistatic->txPlatform.azimuthAngle, txPlatXML); + XMLElem rcvPlatXML = newElement("RcvPlatform", biXML); + createDouble("Time", refGeo.bistatic->rcvPlatform.time, rcvPlatXML); + mCommon.createVector3D("Pos", refGeo.bistatic->rcvPlatform.pos, rcvPlatXML); + mCommon.createVector3D("Vel", refGeo.bistatic->rcvPlatform.vel, rcvPlatXML); + + { + const auto side = refGeo.bistatic->rcvPlatform.sideOfTrack.toString(); + createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), rcvPlatXML); + } + createDouble("SlantRange", refGeo.bistatic->rcvPlatform.slantRange, rcvPlatXML); + createDouble("GroundRange", refGeo.bistatic->rcvPlatform.groundRange, rcvPlatXML); + createDouble("DopplerConeAngle", refGeo.bistatic->rcvPlatform.dopplerConeAngle, rcvPlatXML); + createDouble("GrazeAngle", refGeo.bistatic->rcvPlatform.grazeAngle, rcvPlatXML); + createDouble("IncidenceAngle", refGeo.bistatic->rcvPlatform.incidenceAngle, rcvPlatXML); + createDouble("AzimuthAngle", refGeo.bistatic->rcvPlatform.azimuthAngle, rcvPlatXML); + } + return refGeoXML; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem retval = nullptr; + if (has_value(o)) + { + retval = newElement(o.tag(), &parent); + std::ignore = create(parser(), value(o).dcxsf, *retval); + std::ignore = create(parser(), value(o).dcysf, *retval); + } + + return retval; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem retval = nullptr; + if (has_value(o)) + { + retval = newElement(o.tag(), &parent); + std::ignore = create(parser(), value(o).dcxsf, *retval); + std::ignore = create(parser(), value(o).dcysf, *retval); + } + + return retval; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem retval = nullptr; + if (has_value(o)) + { + retval = newElement(o.tag(), &parent); + std::ignore = create(parser(), value(o).ampX, *retval); + std::ignore = create(parser(), value(o).ampY, *retval); + std::ignore = create(parser(), value(o).phaseY, *retval); + } + + return retval; +} + +XMLElem CPHDXMLParser::toXML(const Antenna& antenna, XMLElem parent) +{ + XMLElem antennaXML = newElement("Antenna", parent); + createInt("NumACFs", antenna.antCoordFrame.size(), antennaXML); + createInt("NumAPCs", antenna.antPhaseCenter.size(), antennaXML); + createInt("NumAntPats", antenna.antPattern.size(), antennaXML); + for (size_t ii = 0; ii < antenna.antCoordFrame.size(); ++ii) + { + XMLElem antCoordFrameXML = newElement("AntCoordFrame", antennaXML); + createString("Identifier", antenna.antCoordFrame[ii].identifier, antCoordFrameXML); + mCommon.createPolyXYZ("XAxisPoly", antenna.antCoordFrame[ii].xAxisPoly, antCoordFrameXML); + mCommon.createPolyXYZ("YAxisPoly", antenna.antCoordFrame[ii].yAxisPoly, antCoordFrameXML); + create(parser(), antenna.antCoordFrame[ii].useACFPVP, *antCoordFrameXML); + } + for (size_t ii = 0; ii < antenna.antPhaseCenter.size(); ++ii) + { + XMLElem antPhaseCenterXML = newElement("AntPhaseCenter", antennaXML); + createString("Identifier", antenna.antPhaseCenter[ii].identifier, antPhaseCenterXML); + createString("ACFId", antenna.antPhaseCenter[ii].acfId, antPhaseCenterXML); + mCommon.createVector3D("APCXYZ", antenna.antPhaseCenter[ii].apcXYZ, antPhaseCenterXML); + } + for (size_t ii = 0; ii < antenna.antPattern.size(); ++ii) + { + XMLElem antPatternXML = newElement("AntPattern", antennaXML); + createString("Identifier", antenna.antPattern[ii].identifier, antPatternXML); + createDouble("FreqZero", antenna.antPattern[ii].freqZero, antPatternXML); + createOptionalDouble("GainZero", antenna.antPattern[ii].gainZero, antPatternXML); + if (!six::Init::isUndefined(antenna.antPattern[ii].ebFreqShift)) + { + createBooleanType("EBFreqShift", antenna.antPattern[ii].ebFreqShift, antPatternXML); + } + std::ignore = toXML(antenna.antPattern[ii].ebFreqShiftSF, *antPatternXML); + + if (!six::Init::isUndefined(antenna.antPattern[ii].mlFreqDilation)) + { + createBooleanType("MLFreqDilation", antenna.antPattern[ii].mlFreqDilation, antPatternXML); + } + std::ignore = toXML(antenna.antPattern[ii].mlFreqDilationSF, *antPatternXML); + + if (!six::Init::isUndefined(antenna.antPattern[ii].gainBSPoly)) + { + mCommon.createPoly1D("GainBSPoly", antenna.antPattern[ii].gainBSPoly, antPatternXML); + } + + std::ignore = toXML(antenna.antPattern[ii].antPolRef, *antPatternXML); + + XMLElem ebXML = newElement("EB", antPatternXML); + mCommon.createPoly1D("DCXPoly", antenna.antPattern[ii].eb.dcxPoly, ebXML); + mCommon.createPoly1D("DCYPoly", antenna.antPattern[ii].eb.dcyPoly, ebXML); + create(parser(), antenna.antPattern[ii].eb.useEBPVP, *ebXML); + + XMLElem arrayXML = newElement("Array", antPatternXML); + mCommon.createPoly2D("GainPoly", antenna.antPattern[ii].array.gainPoly, arrayXML); + mCommon.createPoly2D("PhasePoly", antenna.antPattern[ii].array.phasePoly, arrayXML); + create(parser(), antenna.antPattern[ii].array.antGPId, *arrayXML); + + XMLElem elementXML = newElement("Element", antPatternXML); + mCommon.createPoly2D("GainPoly", antenna.antPattern[ii].element.gainPoly, elementXML); + mCommon.createPoly2D("PhasePoly", antenna.antPattern[ii].element.phasePoly, elementXML); + for (size_t jj = 0; jj < antenna.antPattern[ii].gainPhaseArray.size(); ++jj) + { + XMLElem gainPhaseArrayXML = newElement("GainPhaseArray", antPatternXML); + createDouble("Freq", antenna.antPattern[ii].gainPhaseArray[jj].freq, gainPhaseArrayXML); + createString("ArrayId", antenna.antPattern[ii].gainPhaseArray[jj].arrayId, gainPhaseArrayXML); + if (!six::Init::isUndefined(antenna.antPattern[ii].gainPhaseArray[jj].elementId)) + { + createString("ElementId", antenna.antPattern[ii].gainPhaseArray[jj].elementId, gainPhaseArrayXML); + } + } + } + return antennaXML; +} + +XMLElem CPHDXMLParser::toXML(const TxRcv& txRcv, XMLElem parent) +{ + XMLElem txRcvXML = newElement("TxRcv", parent); + createInt("NumTxWFs", txRcv.txWFParameters.size(), txRcvXML); + for (size_t ii = 0; ii < txRcv.txWFParameters.size(); ++ii) + { + XMLElem txWFParamsXML = newElement("TxWFParameters", txRcvXML); + createString("Identifier", txRcv.txWFParameters[ii].identifier, txWFParamsXML); + createDouble("PulseLength", txRcv.txWFParameters[ii].pulseLength, txWFParamsXML); + createDouble("RFBandwidth", txRcv.txWFParameters[ii].rfBandwidth, txWFParamsXML); + createDouble("FreqCenter", txRcv.txWFParameters[ii].freqCenter, txWFParamsXML); + createOptionalDouble("LFMRate", txRcv.txWFParameters[ii].lfmRate, txWFParamsXML); + createString("Polarization", txRcv.txWFParameters[ii].polarization, txWFParamsXML); + createOptionalDouble("Power", txRcv.txWFParameters[ii].power, txWFParamsXML); + } + createInt("NumRcvs", txRcv.rcvParameters.size(), txRcvXML); + for (size_t ii = 0; ii < txRcv.rcvParameters.size(); ++ii) + { + XMLElem rcvParamsXML = newElement("RcvParameters", txRcvXML); + createString("Identifier", txRcv.rcvParameters[ii].identifier, rcvParamsXML); + createDouble("WindowLength", txRcv.rcvParameters[ii].windowLength, rcvParamsXML); + createDouble("SampleRate", txRcv.rcvParameters[ii].sampleRate, rcvParamsXML); + createDouble("IFFilterBW", txRcv.rcvParameters[ii].ifFilterBW, rcvParamsXML); + createDouble("FreqCenter", txRcv.rcvParameters[ii].freqCenter, rcvParamsXML); + createOptionalDouble("LFMRate", txRcv.rcvParameters[ii].lfmRate, rcvParamsXML); + createString("Polarization", txRcv.rcvParameters[ii].polarization, rcvParamsXML); + createOptionalDouble("PathGain", txRcv.rcvParameters[ii].pathGain, rcvParamsXML); + } + return txRcvXML; +} + +XMLElem CPHDXMLParser::toXML(const ErrorParameters& errParams, XMLElem parent) +{ + XMLElem errParamsXML = newElement("ErrorParameters", parent); + if (errParams.monostatic.get()) + { + XMLElem monoXML = newElement("Monostatic", errParamsXML); + XMLElem posVelErrXML = newElement("PosVelErr", monoXML); + createString("Frame", errParams.monostatic->posVelErr.frame, posVelErrXML); + createDouble("P1", errParams.monostatic->posVelErr.p1, posVelErrXML); + createDouble("P2", errParams.monostatic->posVelErr.p2, posVelErrXML); + createDouble("P3", errParams.monostatic->posVelErr.p3, posVelErrXML); + createDouble("V1", errParams.monostatic->posVelErr.v1, posVelErrXML); + createDouble("V2", errParams.monostatic->posVelErr.v2, posVelErrXML); + createDouble("V3", errParams.monostatic->posVelErr.v3, posVelErrXML); + if(errParams.monostatic->posVelErr.corrCoefs.get()) + { + XMLElem corrCoefsXML = newElement("CorrCoefs", posVelErrXML); + createDouble("P1P2", errParams.monostatic->posVelErr.corrCoefs->p1p2, corrCoefsXML); + createDouble("P1P3", errParams.monostatic->posVelErr.corrCoefs->p1p3, corrCoefsXML); + createDouble("P1V1", errParams.monostatic->posVelErr.corrCoefs->p1v1, corrCoefsXML); + createDouble("P1V2", errParams.monostatic->posVelErr.corrCoefs->p1v2, corrCoefsXML); + createDouble("P1V3", errParams.monostatic->posVelErr.corrCoefs->p1v3, corrCoefsXML); + createDouble("P2P3", errParams.monostatic->posVelErr.corrCoefs->p2p3, corrCoefsXML); + createDouble("P2V1", errParams.monostatic->posVelErr.corrCoefs->p2v1, corrCoefsXML); + createDouble("P2V2", errParams.monostatic->posVelErr.corrCoefs->p2v2, corrCoefsXML); + createDouble("P2V3", errParams.monostatic->posVelErr.corrCoefs->p2v3, corrCoefsXML); + createDouble("P3V1", errParams.monostatic->posVelErr.corrCoefs->p3v1, corrCoefsXML); + createDouble("P3V2", errParams.monostatic->posVelErr.corrCoefs->p3v2, corrCoefsXML); + createDouble("P3V3", errParams.monostatic->posVelErr.corrCoefs->p3v3, corrCoefsXML); + createDouble("V1V2", errParams.monostatic->posVelErr.corrCoefs->v1v2, corrCoefsXML); + createDouble("V1V3", errParams.monostatic->posVelErr.corrCoefs->v1v3, corrCoefsXML); + createDouble("V2V3", errParams.monostatic->posVelErr.corrCoefs->v2v3, corrCoefsXML); + } + createDecorrType("PositionDecorr", errParams.monostatic->posVelErr.positionDecorr, posVelErrXML); + + // RadarSensor + XMLElem radarXML = newElement("RadarSensor", monoXML); + createDouble("RangeBias", errParams.monostatic->radarSensor.rangeBias, radarXML); + createOptionalDouble("ClockFreqSF", errParams.monostatic->radarSensor.clockFreqSF, radarXML); + createOptionalDouble("CollectionStartTime", errParams.monostatic->radarSensor.collectionStartTime, radarXML); + if (errParams.monostatic->radarSensor.rangeBiasDecorr.get()) + { + XMLElem rangeBiasDecorrXML = newElement("RangeBiasDecorr", radarXML); + createDouble("CorrCoefZero", errParams.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero, rangeBiasDecorrXML); + createDouble("DecorrRate", errParams.monostatic->radarSensor.rangeBiasDecorr->decorrRate, rangeBiasDecorrXML); + } + + if (errParams.monostatic->tropoError.get()) + { + XMLElem tropoXML = newElement("TropoError", monoXML); + createOptionalDouble("TropoRangeVertical", errParams.monostatic->tropoError->tropoRangeVertical, tropoXML); + createOptionalDouble("TropoRangeSlant", errParams.monostatic->tropoError->tropoRangeSlant, tropoXML); + createDecorrType("TropoRangeDecorr", errParams.monostatic->tropoError->tropoRangeDecorr, tropoXML); + } + if (errParams.monostatic->ionoError.get()) + { + XMLElem ionoXML = newElement("IonoError", monoXML); + createDouble("IonoRangeVertical", errParams.monostatic->ionoError->ionoRangeVertical, ionoXML); + createOptionalDouble("IonoRangeRateVertical", errParams.monostatic->ionoError->ionoRangeRateVertical, ionoXML); + createOptionalDouble("IonoRgRgRateCC", errParams.monostatic->ionoError->ionoRgRgRateCC, ionoXML); + createDecorrType("IonoRangeVertDecorr", errParams.monostatic->tropoError->tropoRangeDecorr, ionoXML); + } + if (!errParams.monostatic->parameter.empty()) + { + XMLElem addedParamsXML = newElement("AddedParameters", monoXML); + mCommon.addParameters("Parameter", getDefaultURI(), errParams.monostatic->parameter, addedParamsXML); + } + } + else if (errParams.bistatic.get()) + { + XMLElem biXML = newElement("Bistatic", errParamsXML); + XMLElem txPlatXML = newElement("TxPlatform", biXML); + createErrorParamPlatform("TxPlatform", errParams.bistatic->txPlatform, txPlatXML); + XMLElem radarTxXML = newElement("RadarSensor", txPlatXML); + create(parser(), errParams.bistatic->txPlatform.radarSensor.delayBias, *radarTxXML); + createOptionalDouble("ClockFreqSF", errParams.bistatic->txPlatform.radarSensor.clockFreqSF, radarTxXML); + createDouble("CollectionStartTime", errParams.bistatic->txPlatform.radarSensor.collectionStartTime, radarTxXML); + + XMLElem rcvPlatXML = newElement("RcvPlatform", biXML); + createErrorParamPlatform("RcvPlatform", errParams.bistatic->rcvPlatform, rcvPlatXML); + XMLElem radarRcvXML = newElement("RadarSensor", rcvPlatXML); + createOptionalDouble("ClockFreqSF", errParams.bistatic->rcvPlatform.radarSensor.clockFreqSF, radarRcvXML); + createDouble("CollectionStartTime", errParams.bistatic->rcvPlatform.radarSensor.collectionStartTime, radarRcvXML); + + if (!errParams.bistatic->parameter.empty()) + { + XMLElem addedParamsXML = newElement("AddedParameters", biXML); + mCommon.addParameters("Parameter", getDefaultURI(), errParams.bistatic->parameter, addedParamsXML); + } + } + + return errParamsXML; +} + +XMLElem CPHDXMLParser::toXML(const ProductInfo& productInfo, XMLElem parent) +{ + XMLElem productInfoXML = newElement("ProductInfo", parent); + if(!six::Init::isUndefined(productInfo.profile)) + { + createString("Profile", productInfo.profile, productInfoXML); + } + for (size_t ii = 0; ii < productInfo.creationInfo.size(); ++ii) + { + XMLElem creationInfoXML = newElement("CreationInfo", productInfoXML); + if(!six::Init::isUndefined(productInfo.creationInfo[ii].application)) + { + createString("Application", productInfo.creationInfo[ii].application, creationInfoXML); + } + createDateTime("DateTime", productInfo.creationInfo[ii].dateTime, creationInfoXML); + if (!six::Init::isUndefined(productInfo.creationInfo[ii].site)) + { + createString("Site", productInfo.creationInfo[ii].site, creationInfoXML); + } + mCommon.addParameters("Parameter", getDefaultURI(), productInfo.creationInfo[ii].parameter, creationInfoXML); + } + mCommon.addParameters("Parameter", getDefaultURI(), productInfo.parameter, productInfoXML); + return productInfoXML; +} + +XMLElem CPHDXMLParser::toXML(const GeoInfo& geoInfo, XMLElem parent) +{ + XMLElem geoInfoXML = newElement("GeoInfo", parent); + + mCommon.addParameters("Desc", geoInfo.desc, geoInfoXML); + + const size_t numLatLons = geoInfo.geometryLatLon.size(); + if (numLatLons == 1) + { + mCommon.createLatLon("Point", geoInfo.geometryLatLon[0], geoInfoXML); + } + else if (numLatLons >= 2) + { + XMLElem linePolyXML = newElement(numLatLons == 2 ? "Line" : "Polygon", + geoInfoXML); + setAttribute(linePolyXML, "size", numLatLons); + + for (size_t ii = 0; ii < numLatLons; ++ii) + { + XMLElem v = mCommon.createLatLon(numLatLons == 2 ? "Endpoint" : "Vertex", + geoInfo.geometryLatLon[ii], linePolyXML); + setAttribute(v, "index", ii + 1); + } + } + + if (!geoInfo.name.empty()) + setAttribute(geoInfoXML, "name", geoInfo.name); + + for (size_t ii = 0; ii < geoInfo.geoInfos.size(); ++ii) + { + toXML(*geoInfo.geoInfos[ii], geoInfoXML); + } + + return geoInfoXML; +} + +XMLElem CPHDXMLParser::toXML(const MatchInformation& matchInfo, XMLElem parent) +{ + return mCommon.convertMatchInformationToXML(matchInfo, parent); +} + +/* + * FROM XML + */ + +std::unique_ptr CPHDXMLParser::fromXML( + const xml::lite::Document* doc) +{ + std::unique_ptr cphd(new Metadata()); + + const auto root = doc->getRootElement(); + + XMLElem collectionIDXML = getFirstAndOnly(root, "CollectionID"); + XMLElem globalXML = getFirstAndOnly(root, "Global"); + XMLElem sceneCoordsXML = getFirstAndOnly(root, "SceneCoordinates"); + XMLElem dataXML = getFirstAndOnly(root, "Data"); + XMLElem channelXML = getFirstAndOnly(root, "Channel"); + XMLElem pvpXML = getFirstAndOnly(root, "PVP"); + XMLElem dwellXML = getFirstAndOnly(root, "Dwell"); + XMLElem refGeoXML = getFirstAndOnly(root, "ReferenceGeometry"); + + XMLElem supportArrayXML = getOptional(root, "SupportArray"); + XMLElem antennaXML = getOptional(root, "Antenna"); + XMLElem txRcvXML = getOptional(root, "TxRcv"); + XMLElem errParamXML = getOptional(root, "ErrorParameters"); + XMLElem productInfoXML = getOptional(root, "ProductInfo"); + std::vector geoInfoXMLVec; + root->getElementsByTagName("GeoInfo", geoInfoXMLVec); + cphd->geoInfo.resize(geoInfoXMLVec.size()); + XMLElem matchInfoXML = getOptional(root, "MatchInfo"); + + // Parse XML for each section + fromXML(collectionIDXML, cphd->collectionID); + fromXML(globalXML, cphd->global); + fromXML(sceneCoordsXML, cphd->sceneCoordinates); + fromXML(dataXML, cphd->data); + fromXML(channelXML, cphd->channel); + fromXML(pvpXML, cphd->pvp); + fromXML(dwellXML, cphd->dwell); + fromXML(refGeoXML, cphd->referenceGeometry); + + if(supportArrayXML) + { + cphd->supportArray.reset(new SupportArray()); + fromXML(supportArrayXML, *(cphd->supportArray)); + } + if(antennaXML) + { + cphd->antenna.reset(new Antenna()); + fromXML(antennaXML, *(cphd->antenna)); + } + if(txRcvXML) + { + cphd->txRcv.reset(new TxRcv()); + fromXML(txRcvXML, *(cphd->txRcv)); + } + if(errParamXML) + { + cphd->errorParameters.reset(new ErrorParameters()); + fromXML(errParamXML, *(cphd->errorParameters)); + } + if(productInfoXML) + { + cphd->productInfo.reset(new ProductInfo()); + fromXML(productInfoXML, *(cphd->productInfo)); + } + for (size_t ii = 0; ii < geoInfoXMLVec.size(); ++ii) + { + fromXML(geoInfoXMLVec[ii], cphd->geoInfo[ii]); + } + if (matchInfoXML) + { + cphd->matchInfo.reset(new MatchInformation()); + fromXML(matchInfoXML, *(cphd->matchInfo)); + } + + return cphd; +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* collectionIDXML, CollectionInformation& collectionID) +{ + parseString(getFirstAndOnly(collectionIDXML, "CollectorName"), + collectionID.collectorName); + + XMLElem element = getOptional(collectionIDXML, "IlluminatorName"); + if (element) + { + parseString(element, collectionID.illuminatorName); + } + + element = getOptional(collectionIDXML, "CoreName"); + if (element) + { + parseString(element, collectionID.coreName); + } + + element = getOptional(collectionIDXML, "CollectType"); + if (element) + { + collectionID.collectType + = six::toType(element->getCharacterData()); + } + + XMLElem radarModeXML = getFirstAndOnly(collectionIDXML, "RadarMode"); + + collectionID.radarMode + = six::toType(getFirstAndOnly(radarModeXML, + "ModeType")->getCharacterData()); + + element = getOptional(radarModeXML, "ModeID"); + if (element) + { + parseString(element, collectionID.radarModeID); + } + + element = getFirstAndOnly(collectionIDXML, "ReleaseInfo"); + parseString(element, collectionID.releaseInfo); + + std::string classification; + parseString(getFirstAndOnly(collectionIDXML, "Classification"), + classification); + collectionID.setClassificationLevel(classification); + + // Optional + std::vector countryCodes; + element = getOptional(collectionIDXML, "CountryCode"); + if (element) + { + std::string countryCodeStr; + parseString(element, countryCodeStr); + collectionID.countryCodes = str::split(countryCodeStr, ","); + for (size_t ii = 0; ii < collectionID.countryCodes.size(); ++ii) + { + str::trim(collectionID.countryCodes[ii]); + } + } + + //optional + mCommon.parseParameters(collectionIDXML, "Parameter", collectionID.parameters); +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* globalXML, Global& global) +{ + global.domainType = DomainType::toType( + getFirstAndOnly(globalXML, "DomainType")->getCharacterData()); + global.sgn = PhaseSGN::toType( + getFirstAndOnly(globalXML, "SGN")->getCharacterData()); + + // Timeline + const xml::lite::Element* timelineXML = getFirstAndOnly(globalXML, "Timeline"); + parseDateTime( + getFirstAndOnly(timelineXML, "CollectionStart"), + global.timeline.collectionStart); + + // Optional + const xml::lite::Element* rcvCollectionXML = getOptional(timelineXML, + "RcvCollectionStart"); + if (rcvCollectionXML) + { + parseDateTime(rcvCollectionXML, + global.timeline.rcvCollectionStart); + } + + parseDouble( + getFirstAndOnly(timelineXML, "TxTime1"), global.timeline.txTime1); + parseDouble( + getFirstAndOnly(timelineXML, "TxTime2"), global.timeline.txTime2); + + // FxBand + const xml::lite::Element* fxBandXML = getFirstAndOnly(globalXML, "FxBand"); + parseDouble(getFirstAndOnly(fxBandXML, "FxMin"), global.fxBand.fxMin); + parseDouble(getFirstAndOnly(fxBandXML, "FxMax"), global.fxBand.fxMax); + + // TOASwath + const xml::lite::Element* toaSwathXML = getFirstAndOnly(globalXML, "TOASwath"); + parseDouble(getFirstAndOnly(toaSwathXML, "TOAMin"), global.toaSwath.toaMin); + parseDouble(getFirstAndOnly(toaSwathXML, "TOAMax"), global.toaSwath.toaMax); + + // TropoParameters + const xml::lite::Element* tropoXML = getOptional(globalXML, "TropoParameters"); + if (tropoXML) + { + // Optional + global.tropoParameters.reset(new TropoParameters()); + parseDouble(getFirstAndOnly(tropoXML, "N0"), global.tropoParameters->n0); + global.tropoParameters->refHeight = + RefHeight::toType(getFirstAndOnly(tropoXML, "RefHeight")->getCharacterData()); + } + + // IonoParameters + if (const auto ionoXML = getOptional(globalXML, "IonoParameters")) + { + // Optional + global.ionoParameters.reset(new IonoParameters()); + parseDouble(getFirstAndOnly(ionoXML, "TECV"), global.ionoParameters->tecv); + if (const auto f2HeightXML = getOptional(ionoXML, "F2Height")) + { + parseDouble(f2HeightXML, global.ionoParameters->f2Height); + } + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* sceneCoordsXML, + SceneCoordinates& scene) +{ + scene.earthModel = EarthModelType::toType( + getFirstAndOnly(sceneCoordsXML, "EarthModel")->getCharacterData()); + + // IARP + const xml::lite::Element* iarpXML = getFirstAndOnly(sceneCoordsXML, "IARP"); + mCommon.parseVector3D(getFirstAndOnly(iarpXML, "ECF"), scene.iarp.ecf); + mCommon.parseLatLonAlt(getFirstAndOnly(iarpXML, "LLH"), scene.iarp.llh); + + // ReferenceSurface + const xml::lite::Element* surfaceXML = getFirstAndOnly(sceneCoordsXML, "ReferenceSurface"); + const xml::lite::Element* planarXML = getOptional(surfaceXML, "Planar"); + const xml::lite::Element* haeXML = getOptional(surfaceXML, "HAE"); + if (planarXML && !haeXML) + { + // Choice type + scene.referenceSurface.planar.reset(new Planar()); + mCommon.parseVector3D(getFirstAndOnly(planarXML, "uIAX"), + scene.referenceSurface.planar->uIax); + mCommon.parseVector3D(getFirstAndOnly(planarXML, "uIAY"), + scene.referenceSurface.planar->uIay); + } + else if (haeXML && !planarXML) + { + // Choice type + scene.referenceSurface.hae.reset(new HAE()); + mCommon.parseLatLon(getFirstAndOnly(haeXML, "uIAXLL"), + scene.referenceSurface.hae->uIax); + mCommon.parseLatLon(getFirstAndOnly(haeXML, "uIAYLL"), + scene.referenceSurface.hae->uIay); + } + else + { + throw except::Exception(Ctxt( + "ReferenceSurface must exactly one of Planar or HAE element")); + } + + // ImageArea + const xml::lite::Element* imageAreaXML = getFirstAndOnly(sceneCoordsXML, "ImageArea"); + parseAreaType(imageAreaXML, scene.imageArea); + + // ImageAreaCorners + const xml::lite::Element* cornersXML = getFirstAndOnly(sceneCoordsXML, + "ImageAreaCornerPoints"); + mCommon.parseFootprint(cornersXML, "IACP", scene.imageAreaCorners); + + // Extended Area + const xml::lite::Element* extendedAreaXML = getOptional(sceneCoordsXML, "ExtendedArea"); + if (extendedAreaXML) + { + scene.extendedArea.reset(new AreaType()); + parseAreaType(extendedAreaXML, *scene.extendedArea); + } + + // Image Grid + const xml::lite::Element* gridXML = getOptional(sceneCoordsXML, "ImageGrid"); + if (gridXML) + { + // Optional + scene.imageGrid.reset(new ImageGrid()); + const xml::lite::Element* identifierXML = getOptional(gridXML, "Identifier"); + if (identifierXML) + { + parseString(identifierXML, scene.imageGrid->identifier); + } + parseLineSample(getFirstAndOnly(gridXML, "IARPLocation"), + scene.imageGrid->iarpLocation); + parseIAExtent(getFirstAndOnly(gridXML, "IAXExtent"), + scene.imageGrid->xExtent); + parseIAExtent(getFirstAndOnly(gridXML, "IAYExtent"), + scene.imageGrid->yExtent); + + // Segment List + const xml::lite::Element* segListXML = getOptional(gridXML, "SegmentList"); + if (segListXML) + { + // Optional + size_t numSegments; + parseUInt(getFirstAndOnly(segListXML, "NumSegments"), numSegments); + scene.imageGrid->segments.resize(numSegments); + + std::vector segmentsXML; + segListXML->getElementsByTagName("Segment", segmentsXML); + + for (size_t ii = 0; ii < segmentsXML.size(); ++ii) + { + const xml::lite::Element* segmentXML = segmentsXML[ii]; + parseString(getFirstAndOnly(segmentXML, "Identifier"), + scene.imageGrid->segments[ii].identifier); + parseInt(getFirstAndOnly(segmentXML, "StartLine"), + scene.imageGrid->segments[ii].startLine); + parseInt(getFirstAndOnly(segmentXML, "StartSample"), + scene.imageGrid->segments[ii].startSample); + parseInt(getFirstAndOnly(segmentXML, "EndLine"), + scene.imageGrid->segments[ii].endLine); + parseInt(getFirstAndOnly(segmentXML, "EndSample"), + scene.imageGrid->segments[ii].endSample); + + const xml::lite::Element* polygonXML = getOptional(segmentXML, + "SegmentPolygon"); + if (polygonXML) + { + // Optional + size_t polygonSize = 0; + sscanf(const_cast(polygonXML)->attribute("size").c_str(), "%zu", &polygonSize); + scene.imageGrid->segments[ii].polygon.resize(polygonSize); + std::vector polyVerticesXMLVec; + polygonXML->getElementsByTagName("SV", polyVerticesXMLVec); + if (scene.imageGrid->segments[ii].polygon.size() != polyVerticesXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect polygon vertices provided")); + } + if (polyVerticesXMLVec.size() < 3) + { + throw except::Exception(Ctxt( + "Polygon must have at least 3 vertices")); + } + std::vector& vertices = + scene.imageGrid->segments[ii].polygon; + vertices.resize(polyVerticesXMLVec.size()); + for (size_t jj = 0; jj < polyVerticesXMLVec.size(); ++jj) + { + size_t tempIdx; + sscanf(polyVerticesXMLVec[jj]->attribute("index").c_str(), "%zu", &tempIdx); + vertices[jj].setIndex(tempIdx); + parseLineSample(polyVerticesXMLVec[jj], vertices[jj]); + } + } + } + } + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* dataXML, Data& data) +{ + const xml::lite::Element* signalXML = getFirstAndOnly(dataXML, "SignalArrayFormat"); + data.signalArrayFormat = SignalArrayFormat::toType(signalXML->getCharacterData()); + + size_t numBytesPVP_temp = 0; + XMLElem numBytesPVPXML = getFirstAndOnly(dataXML, "NumBytesPVP"); + parseUInt(numBytesPVPXML, numBytesPVP_temp); + if(numBytesPVP_temp % 8 != 0) + { + throw except::Exception(Ctxt( + "Number of bytes must be multiple of 8")); + } + data.numBytesPVP = numBytesPVP_temp; + + // Channels + std::vector channelsXML; + dataXML->getElementsByTagName("Channel", channelsXML); + data.channels.resize(channelsXML.size()); + for (size_t ii = 0; ii < channelsXML.size(); ++ii) + { + parseString(getFirstAndOnly(channelsXML[ii], "Identifier"), + data.channels[ii].identifier); + parseUInt(getFirstAndOnly(channelsXML[ii], "NumVectors"), + data.channels[ii].numVectors); + parseUInt(getFirstAndOnly(channelsXML[ii], "NumSamples"), + data.channels[ii].numSamples); + parseUInt(getFirstAndOnly(channelsXML[ii], "SignalArrayByteOffset"), + data.channels[ii].signalArrayByteOffset); + parseUInt(getFirstAndOnly(channelsXML[ii], "PVPArrayByteOffset"), + data.channels[ii].pvpArrayByteOffset); + XMLElem compressionXML = getOptional(channelsXML[ii], "CompressedSignalSize"); + if (compressionXML) + { + parseUInt(compressionXML, data.channels[ii].compressedSignalSize); + } + } + XMLElem compressionXML = getOptional(dataXML, "SignalCompressionID"); + if (compressionXML) + { + parseString(compressionXML, + data.signalCompressionID); + } + + // Support Arrays + std::vector supportsXML; + dataXML->getElementsByTagName("SupportArray", supportsXML); + for (size_t ii = 0; ii < supportsXML.size(); ++ii) + { + std::string id; + size_t offset; + size_t numRows; + size_t numCols; + size_t numBytes; + parseString(getFirstAndOnly(supportsXML[ii], "Identifier"), id); + parseUInt(getFirstAndOnly(supportsXML[ii], "ArrayByteOffset"), offset); + parseUInt(getFirstAndOnly(supportsXML[ii], "NumRows"), numRows); + parseUInt(getFirstAndOnly(supportsXML[ii], "NumCols"), numCols); + parseUInt(getFirstAndOnly(supportsXML[ii], "BytesPerElement"), numBytes); + data.setSupportArray(id, numRows, numCols, numBytes, offset); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* channelXML, Channel& channel) +{ + parseString(getFirstAndOnly(channelXML, "RefChId"), channel.refChId); + parseBooleanType(getFirstAndOnly(channelXML, "FXFixedCPHD"), channel.fxFixedCphd); + parseBooleanType(getFirstAndOnly(channelXML, "TOAFixedCPHD"), channel.toaFixedCphd); + parseBooleanType(getFirstAndOnly(channelXML, "SRPFixedCPHD"), channel.srpFixedCphd); + + std::vector parametersXML; + channelXML->getElementsByTagName("Parameters", parametersXML); + channel.parameters.resize(parametersXML.size()); + for (size_t ii = 0; ii < parametersXML.size(); ++ii) + { + parseChannelParameters(parametersXML[ii], channel.parameters[ii]); + } + + XMLElem addedParametersXML = getOptional(channelXML, "AddedParameters"); + if(addedParametersXML) + { + mCommon.parseParameters(addedParametersXML, "Parameter", channel.addedParameters); + } +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement& v) const +{ + auto& param = value(v).param; + const auto offset = parsePVPType(parent, param); + setOffset(param, offset); +} +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement& v) const +{ + auto& param = value(v).param; + const auto offset = parsePVPType(parent, param); + setOffset(param, offset); +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = TxAntenna{}; + parse(*pXML, value(o).txACX); + parse(*pXML, value(o).txACY); + parse(*pXML, value(o).txEB); + } +} +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = RcvAntenna{}; + parse(*pXML, value(o).rcvACX); + parse(*pXML, value(o).rcvACY); + parse(*pXML, value(o).rcvEB); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* pvpXML, Pvp& pvp) +{ + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxTime"), pvp.txTime); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxPos"), pvp.txPos); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxVel"), pvp.txVel); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvTime"), pvp.rcvTime); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvPos"), pvp.rcvPos); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvVel"), pvp.rcvVel); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "SRPPos"), pvp.srpPos); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFDOP"), pvp.aFDOP); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFRR1"), pvp.aFRR1); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFRR2"), pvp.aFRR2); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "FX1"), pvp.fx1); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "FX2"), pvp.fx2); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TOA1"), pvp.toa1); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TOA2"), pvp.toa2); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TDTropoSRP"), pvp.tdTropoSRP); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "SC0"), pvp.sc0); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "SCSS"), pvp.scss); + + parseOptionalPVPType(pvpXML, "AmpSF", pvp, pvp.ampSF); + parseOptionalPVPType(pvpXML, "FXN1", pvp, pvp.fxN1); + parseOptionalPVPType(pvpXML, "FXN2", pvp, pvp.fxN2); + parseOptionalPVPType(pvpXML, "TOAE1", pvp, pvp.toaE1); + parseOptionalPVPType(pvpXML, "TOAE2", pvp, pvp.toaE2); + parseOptionalPVPType(pvpXML, "TDIonoSRP", pvp, pvp.tdIonoSRP); + parseOptionalPVPType(pvpXML, "SIGNAL", pvp, pvp.signal); + + parse(*pvpXML, pvp.txAntenna); + parse(*pvpXML, pvp.rcvAntenna); + + std::vector addedParamsXML; + const std::string str = "AddedPVP"; + pvpXML->getElementsByTagName(str, addedParamsXML); + if(addedParamsXML.empty()) + { + return; + } + for (size_t ii = 0; ii < addedParamsXML.size(); ++ii) + { + parsePVPType(pvp, addedParamsXML[ii]); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* DwellXML, + Dwell& dwell) +{ + // CODTime + size_t numCODTimes; + parseUInt(getFirstAndOnly(DwellXML, "NumCODTimes"), numCODTimes); + dwell.cod.resize(numCODTimes); + + std::vector codXMLVec; + DwellXML->getElementsByTagName("CODTime", codXMLVec); + for(size_t ii = 0; ii < codXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(codXMLVec[ii], "Identifier"), dwell.cod[ii].identifier); + mCommon.parsePoly2D(getFirstAndOnly(codXMLVec[ii], "CODTimePoly"), dwell.cod[ii].codTimePoly); + } + + // DwellTime + size_t numDwellTimes = 0; + parseUInt(getFirstAndOnly(DwellXML, "NumDwellTimes"), numDwellTimes); + dwell.dtime.resize(numDwellTimes); + + std::vector dtimeXMLVec; + DwellXML->getElementsByTagName("DwellTime", dtimeXMLVec); + for(size_t ii = 0; ii < dtimeXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(dtimeXMLVec[ii], "Identifier"), dwell.dtime[ii].identifier); + mCommon.parsePoly2D(getFirstAndOnly(dtimeXMLVec[ii], "DwellTimePoly"), dwell.dtime[ii].dwellTimePoly); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* refGeoXML, ReferenceGeometry& refGeo) +{ + XMLElem srpXML = getFirstAndOnly(refGeoXML, "SRP"); + mCommon.parseVector3D(getFirstAndOnly(srpXML, "ECF"), refGeo.srp.ecf); + mCommon.parseVector3D(getFirstAndOnly(srpXML, "IAC"), refGeo.srp.iac); + parseDouble(getFirstAndOnly(refGeoXML, "ReferenceTime"), refGeo.referenceTime); + parseDouble(getFirstAndOnly(refGeoXML, "SRPCODTime"), refGeo.srpCODTime); + parseDouble(getFirstAndOnly(refGeoXML, "SRPDwellTime"), refGeo.srpDwellTime); + + const xml::lite::Element* monoXML = getOptional(refGeoXML, "Monostatic"); + const xml::lite::Element* biXML = getOptional(refGeoXML, "Bistatic"); + if (monoXML && !biXML) + { + refGeo.monostatic.reset(new Monostatic()); + parseCommon(monoXML, (ImagingType*)refGeo.monostatic.get()); + parseDouble(getFirstAndOnly(monoXML, "SlantRange"), refGeo.monostatic->slantRange); + parseDouble(getFirstAndOnly(monoXML, "GroundRange"), refGeo.monostatic->groundRange); + parseDouble(getFirstAndOnly(monoXML, "DopplerConeAngle"), refGeo.monostatic->dopplerConeAngle); + parseDouble(getFirstAndOnly(monoXML, "IncidenceAngle"), refGeo.monostatic->incidenceAngle); + mCommon.parseVector3D(getFirstAndOnly(monoXML, "ARPPos"), refGeo.monostatic->arpPos); + mCommon.parseVector3D(getFirstAndOnly(monoXML, "ARPVel"), refGeo.monostatic->arpVel); + std::string side = ""; + parseString(getFirstAndOnly(monoXML, "SideOfTrack"), side); + refGeo.monostatic->sideOfTrack = (side == "L" ? six::SideOfTrackType::LEFT : six::SideOfTrackType::RIGHT); + + } + else if (!monoXML && biXML) + { + refGeo.bistatic.reset(new Bistatic()); + parseCommon(biXML, (ImagingType*)refGeo.bistatic.get()); + parseDouble(getFirstAndOnly(biXML, "AzimuthAngleRate"), refGeo.bistatic->azimuthAngleRate); + parseDouble(getFirstAndOnly(biXML, "BistaticAngle"), refGeo.bistatic->bistaticAngle); + parseDouble(getFirstAndOnly(biXML, "BistaticAngleRate"), refGeo.bistatic->bistaticAngleRate); + + parsePlatformParams(getFirstAndOnly(biXML, "TxPlatform"), refGeo.bistatic->txPlatform); + parsePlatformParams(getFirstAndOnly(biXML, "RcvPlatform"), refGeo.bistatic->rcvPlatform); + } + else + { + throw except::Exception(Ctxt( + "One of the two types Mono or Bi must be provided")); + } +} + +std::vector CPHDXMLParser::parseSupportArray(const std::string& tag, const xml::lite::Element& parent) const +{ + std::vector elements; + parent.getElementsByTagName(tag, elements); + std::vector supportArray; + supportArray.reserve(elements.size()); + for (const auto& element : elements) + { + SupportArrayParameter param; + parseSupportArrayParameter(element, param, false /*additionalFlag*/); + supportArray.push_back(std::move(param)); + } + return supportArray; +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* supportArrayXML, SupportArray& supportArray) +{ + supportArray.iazArray = parseSupportArray("IAZArray", *supportArrayXML); + supportArray.antGainPhase = parseSupportArray("AntGainPhase", *supportArrayXML); + supportArray.dwellTimeArray = parseSupportArray("DwellTimeArray", *supportArrayXML); + + std::vector addedSupportArrayXMLVec; + supportArrayXML->getElementsByTagName("AddedSupportArray", addedSupportArrayXMLVec); + for (size_t ii = 0; ii < addedSupportArrayXMLVec.size(); ++ii) + { + std::string id; + parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "Identifier"), id); + if (supportArray.addedSupportArray.count(id) == 0) + { + parseSupportArrayParameter(addedSupportArrayXMLVec[ii], supportArray.addedSupportArray[id], true); + parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "XUnits"), supportArray.addedSupportArray[id].xUnits); + parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "YUnits"), supportArray.addedSupportArray[id].yUnits); + parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "ZUnits"), supportArray.addedSupportArray[id].zUnits); + mCommon.parseParameters(addedSupportArrayXMLVec[ii], "Parameter", supportArray.addedSupportArray[id].parameter); + } + else + { + throw except::Exception(Ctxt( + "Support array identifier for support array is not unique: " + id)); + } + } +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = AntPattern::EBFreqShiftSF{}; + six::getFirstAndOnly(parser(), *pXML, value(o).dcxsf); + six::getFirstAndOnly(parser(), *pXML, value(o).dcysf); + } +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = AntPattern::MLFreqDilationSF{}; + six::getFirstAndOnly(parser(), *pXML, value(o).dcxsf); + six::getFirstAndOnly(parser(), *pXML, value(o).dcysf); + } +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = AntPattern::AntPolRef{}; + six::getFirstAndOnly(parser(), *pXML, value(o).ampX); + six::getFirstAndOnly(parser(), *pXML, value(o).ampY); + six::getFirstAndOnly(parser(), *pXML, value(o).phaseY); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* antennaXML, Antenna& antenna) +{ + size_t numACFs = 0; + size_t numAPCs = 0; + size_t numAntPats = 0; + parseUInt(getFirstAndOnly(antennaXML, "NumACFs"), numACFs); + antenna.antCoordFrame.resize(numACFs); + parseUInt(getFirstAndOnly(antennaXML, "NumAPCs"), numAPCs); + antenna.antPhaseCenter.resize(numAPCs); + parseUInt(getFirstAndOnly(antennaXML, "NumAntPats"), numAntPats); + antenna.antPattern.resize(numAntPats); + + // Parse AntCoordFrame + std::vector antCoordFrameXMLVec; + antennaXML->getElementsByTagName("AntCoordFrame", antCoordFrameXMLVec); + if(antenna.antCoordFrame.size() != antCoordFrameXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of AntCoordFrames provided")); + } + for( size_t ii = 0; ii < antCoordFrameXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(antCoordFrameXMLVec[ii], "Identifier"), antenna.antCoordFrame[ii].identifier); + mCommon.parsePolyXYZ(getFirstAndOnly(antCoordFrameXMLVec[ii], "XAxisPoly"), antenna.antCoordFrame[ii].xAxisPoly); + mCommon.parsePolyXYZ(getFirstAndOnly(antCoordFrameXMLVec[ii], "YAxisPoly"), antenna.antCoordFrame[ii].yAxisPoly); + std::ignore = six::parse(parser(), *antCoordFrameXMLVec[ii], antenna.antCoordFrame[ii].useACFPVP); + } + + // Parse AntPhaseCenter + std::vector antPhaseCenterXMLVec; + antennaXML->getElementsByTagName("AntPhaseCenter", antPhaseCenterXMLVec); + if(antenna.antPhaseCenter.size() != antPhaseCenterXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of AntPhaseCenters provided")); + } + for( size_t ii = 0; ii < antPhaseCenterXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(antPhaseCenterXMLVec[ii], "Identifier"), antenna.antPhaseCenter[ii].identifier); + parseString(getFirstAndOnly(antPhaseCenterXMLVec[ii], "ACFId"), antenna.antPhaseCenter[ii].acfId); + mCommon.parseVector3D(getFirstAndOnly(antPhaseCenterXMLVec[ii], "APCXYZ"), antenna.antPhaseCenter[ii].apcXYZ); + } + + std::vector antPatternXMLVec; + antennaXML->getElementsByTagName("AntPattern", antPatternXMLVec); + if(antenna.antPattern.size() != antPatternXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of AntPatterns provided")); + } + for( size_t ii = 0; ii < antPatternXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(antPatternXMLVec[ii], "Identifier"), antenna.antPattern[ii].identifier); + parseDouble(getFirstAndOnly(antPatternXMLVec[ii], "FreqZero"), antenna.antPattern[ii].freqZero); + parseOptionalDouble(antPatternXMLVec[ii], "GainZero", antenna.antPattern[ii].gainZero); + + XMLElem ebFreqShiftXML = getOptional(antPatternXMLVec[ii], "EBFreqShift"); + if(ebFreqShiftXML) + { + parseBooleanType(ebFreqShiftXML, antenna.antPattern[ii].ebFreqShift); + } + parse(*antPatternXMLVec[ii], antenna.antPattern[ii].ebFreqShiftSF); + + XMLElem mlFreqDilationXML = getOptional(antPatternXMLVec[ii], "MLFreqDilation"); + if(mlFreqDilationXML) + { + parseBooleanType(mlFreqDilationXML, antenna.antPattern[ii].mlFreqDilation); + } + parse(*antPatternXMLVec[ii], antenna.antPattern[ii].mlFreqDilationSF); + + XMLElem gainBSPoly = getOptional(antPatternXMLVec[ii], "GainBSPoly"); + if(gainBSPoly) + { + mCommon.parsePoly1D(gainBSPoly, antenna.antPattern[ii].gainBSPoly); + } + + parse(*antPatternXMLVec[ii], antenna.antPattern[ii].antPolRef); + + // Parse EB + XMLElem ebXML = getFirstAndOnly(antPatternXMLVec[ii], "EB"); + mCommon.parsePoly1D(getFirstAndOnly(ebXML, "DCXPoly"), antenna.antPattern[ii].eb.dcxPoly); + mCommon.parsePoly1D(getFirstAndOnly(ebXML, "DCYPoly"), antenna.antPattern[ii].eb.dcyPoly); + std::ignore = six::parse(parser(), *ebXML, antenna.antPattern[ii].eb.useEBPVP); + + // Parse Array + XMLElem arrayXML = getFirstAndOnly(antPatternXMLVec[ii], "Array"); + mCommon.parsePoly2D(getFirstAndOnly(arrayXML, "GainPoly"), antenna.antPattern[ii].array.gainPoly); + mCommon.parsePoly2D(getFirstAndOnly(arrayXML, "PhasePoly"), antenna.antPattern[ii].array.phasePoly); + + // Parse Element + XMLElem elementXML = getFirstAndOnly(antPatternXMLVec[ii], "Element"); + mCommon.parsePoly2D(getFirstAndOnly(elementXML, "GainPoly"), antenna.antPattern[ii].element.gainPoly); + mCommon.parsePoly2D(getFirstAndOnly(elementXML, "PhasePoly"), antenna.antPattern[ii].element.phasePoly); + std::ignore = six::parse(parser(), *elementXML, antenna.antPattern[ii].element.antGPId); + + // Parse GainPhaseArray + std::vector gainPhaseArrayXMLVec; + antPatternXMLVec[ii]->getElementsByTagName("GainPhaseArray", gainPhaseArrayXMLVec); + antenna.antPattern[ii].gainPhaseArray.resize(gainPhaseArrayXMLVec.size()); + for (size_t jj = 0; jj < gainPhaseArrayXMLVec.size(); ++jj) + { + parseDouble(getFirstAndOnly(gainPhaseArrayXMLVec[jj], "Freq"), antenna.antPattern[ii].gainPhaseArray[jj].freq); + parseString(getFirstAndOnly(gainPhaseArrayXMLVec[jj], "ArrayId"), antenna.antPattern[ii].gainPhaseArray[jj].arrayId); + XMLElem elementIdXML = getOptional(gainPhaseArrayXMLVec[jj], "ElementId"); + if(elementIdXML) + { + parseString(elementIdXML, antenna.antPattern[ii].gainPhaseArray[jj].elementId); + } + + } + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* txRcvXML, TxRcv& txRcv) +{ + size_t numTxWFs = 0; + size_t numRcvs = 0; + parseUInt(getFirstAndOnly(txRcvXML, "NumTxWFs"), numTxWFs); + txRcv.txWFParameters.resize(numTxWFs); + parseUInt(getFirstAndOnly(txRcvXML, "NumRcvs"), numRcvs); + txRcv.rcvParameters.resize(numRcvs); + + std::vector txWFXMLVec; + txRcvXML->getElementsByTagName("TxWFParameters", txWFXMLVec); + if(txRcv.txWFParameters.size() != txWFXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of TxWF parameters provided")); + } + for(size_t ii = 0; ii < txWFXMLVec.size(); ++ii) + { + parseTxRcvParameter(txWFXMLVec[ii], txRcv.txWFParameters[ii]); + parseDouble(getFirstAndOnly(txWFXMLVec[ii], "PulseLength"), txRcv.txWFParameters[ii].pulseLength); + parseDouble(getFirstAndOnly(txWFXMLVec[ii], "RFBandwidth"), txRcv.txWFParameters[ii].rfBandwidth); + parseOptionalDouble(txWFXMLVec[ii], "Power", txRcv.txWFParameters[ii].power); + } + + std::vector rcvXMLVec; + txRcvXML->getElementsByTagName("RcvParameters", rcvXMLVec); + if(txRcv.rcvParameters.size() != rcvXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of Rcv parameters provided")); + } + for(size_t ii = 0; ii < rcvXMLVec.size(); ++ii) + { + parseTxRcvParameter(rcvXMLVec[ii], txRcv.rcvParameters[ii]); + parseDouble(getFirstAndOnly(rcvXMLVec[ii], "WindowLength"), txRcv.rcvParameters[ii].windowLength); + parseDouble(getFirstAndOnly(rcvXMLVec[ii], "SampleRate"), txRcv.rcvParameters[ii].sampleRate); + parseDouble(getFirstAndOnly(rcvXMLVec[ii], "IFFilterBW"), txRcv.rcvParameters[ii].ifFilterBW); + parseOptionalDouble(rcvXMLVec[ii], "PathGain", txRcv.rcvParameters[ii].pathGain); + } + +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* errParamXML, ErrorParameters& errParam) +{ + XMLElem monostaticXML = getOptional(errParamXML, "Monostatic"); + XMLElem bistaticXML = getOptional(errParamXML, "Bistatic"); + + if(monostaticXML && !bistaticXML) + { + errParam.monostatic.reset(new ErrorParameters::Monostatic()); + parsePosVelErr(getFirstAndOnly(monostaticXML, "PosVelErr"), errParam.monostatic->posVelErr); + + XMLElem radarSensorXML = getFirstAndOnly(monostaticXML, "RadarSensor"); + parseDouble(getFirstAndOnly(radarSensorXML, "RangeBias"), errParam.monostatic->radarSensor.rangeBias); + + parseOptionalDouble(radarSensorXML, "ClockFreqSF", errParam.monostatic->radarSensor.clockFreqSF); + parseOptionalDouble(radarSensorXML, "CollectionStartTime", errParam.monostatic->radarSensor.collectionStartTime); + + XMLElem rangeBiasDecorrXML = getOptional(radarSensorXML, "RangeBiasDecorr"); + if(rangeBiasDecorrXML) + { + errParam.monostatic->radarSensor.rangeBiasDecorr.reset(new six::DecorrType()); + mCommon.parseDecorrType(rangeBiasDecorrXML, *(errParam.monostatic->radarSensor.rangeBiasDecorr)); + } + + XMLElem tropoErrorXML = getOptional(monostaticXML, "TropoError"); + if(tropoErrorXML) + { + errParam.monostatic->tropoError.reset(new six::TropoError()); + parseOptionalDouble(tropoErrorXML, "TropoRangeVertical", errParam.monostatic->tropoError->tropoRangeVertical); + parseOptionalDouble(tropoErrorXML, "TropoRangeSlant", errParam.monostatic->tropoError->tropoRangeSlant); + mCommon.parseOptionalDecorrType(tropoErrorXML, "TropoRangeDecorr", errParam.monostatic->tropoError->tropoRangeDecorr); + } + + XMLElem ionoErrorXML = getOptional(monostaticXML, "IonoError"); + if(ionoErrorXML) + { + errParam.monostatic->ionoError.reset(new six::IonoError()); + parseDouble(getFirstAndOnly(ionoErrorXML, "IonoRangeVertical"), errParam.monostatic->ionoError->ionoRangeVertical); + + parseOptionalDouble(ionoErrorXML, "IonoRangeRateVertical", errParam.monostatic->ionoError->ionoRangeRateVertical); + parseOptionalDouble(ionoErrorXML, "IonoRgRgRateCC", errParam.monostatic->ionoError->ionoRgRgRateCC); + mCommon.parseOptionalDecorrType(ionoErrorXML, "IonoRangeVertDecorr", errParam.monostatic->ionoError->ionoRangeVertDecorr); + } + mCommon.parseParameters(monostaticXML, "Parameter", errParam.monostatic->parameter); + } + else if(!monostaticXML && bistaticXML) + { + errParam.bistatic.reset(new ErrorParameters::Bistatic()); + parsePlatform(getFirstAndOnly(bistaticXML, "TxPlatform"), errParam.bistatic->txPlatform); + parsePlatform(getFirstAndOnly(bistaticXML, "RcvPlatform"), errParam.bistatic->rcvPlatform); + mCommon.parseParameters(bistaticXML, "Parameter", errParam.bistatic->parameter); + } + else + { + throw except::Exception(Ctxt( + "Must be one of monostatic or bistatic")); + } +} + + +void CPHDXMLParser::fromXML(const xml::lite::Element* productInfoXML, ProductInfo& productInfo) +{ + XMLElem profileXML = getOptional(productInfoXML, "Profile"); + if(profileXML) + { + parseString(profileXML, productInfo.profile); + } + + std::vector creationInfoXML; + productInfoXML->getElementsByTagName("CreationInfo", creationInfoXML); + productInfo.creationInfo.resize(creationInfoXML.size()); + + for (size_t ii = 0; ii < creationInfoXML.size(); ++ii) + { + XMLElem applicationXML = getOptional(creationInfoXML[ii], "Application"); + if(applicationXML) + { + parseString(applicationXML, productInfo.creationInfo[ii].application); + } + + parseDateTime(getFirstAndOnly(creationInfoXML[ii], "DateTime"), productInfo.creationInfo[ii].dateTime); + + XMLElem siteXML = getOptional(creationInfoXML[ii], "Site"); + if(siteXML) + { + parseString(siteXML, productInfo.creationInfo[ii].site); + } + mCommon.parseParameters(creationInfoXML[ii], "Parameter", productInfo.creationInfo[ii].parameter); + } + mCommon.parseParameters(productInfoXML, "Parameter", productInfo.parameter); + +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* geoInfoXML, GeoInfo& geoInfo) +{ + std::vector < XMLElem > geoInfosXML; + geoInfoXML->getElementsByTagName("GeoInfo", geoInfosXML); + geoInfo.name = geoInfoXML->getAttributes().getValue("name"); + + //optional + mCommon.parseParameters(geoInfoXML, "Desc", geoInfo.desc); + + XMLElem tmpElem = getOptional(geoInfoXML, "Point"); + if (tmpElem) + { + LatLon ll; + mCommon.parseLatLon(tmpElem, ll); + geoInfo.geometryLatLon.push_back(ll); + } + else + { + std::string pointName = "Endpoint"; + tmpElem = getOptional(geoInfoXML, "Line"); + if (!tmpElem) + { + pointName = "Vertex"; + tmpElem = getOptional(geoInfoXML, "Polygon"); + } + if (tmpElem) + { + mCommon.parseLatLons(tmpElem, pointName, geoInfo.geometryLatLon); + } + } + + //optional + size_t idx(geoInfo.geoInfos.size()); + geoInfo.geoInfos.resize(idx + geoInfosXML.size()); + + for (auto it = geoInfosXML.begin(); it + != geoInfosXML.end(); ++it, ++idx) + { + geoInfo.geoInfos[idx].reset(new GeoInfo()); + fromXML(*it, *geoInfo.geoInfos[idx]); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* matchInfoXML, MatchInformation& matchInfo) +{ + mCommon.parseMatchInformationFromXML(matchInfoXML, &matchInfo); +} + + +XMLElem CPHDXMLParser::createLatLonFootprint(const std::string& name, + const std::string& cornerName, + const cphd::LatLonCorners& corners, + XMLElem parent) const +{ + XMLElem footprint = newElement(name, parent); + + // Write the corners in CW order + XMLElem vertex = + mCommon.createLatLon(cornerName, corners.upperLeft, footprint); + setAttribute(vertex, "index", "1"); + + vertex = mCommon.createLatLon(cornerName, corners.upperRight, footprint); + setAttribute(vertex, "index", "2"); + + vertex = mCommon.createLatLon(cornerName, corners.lowerRight, footprint); + setAttribute(vertex, "index", "3"); + + vertex = mCommon.createLatLon(cornerName, corners.lowerLeft, footprint); + setAttribute(vertex, "index", "4"); + + return footprint; +} + +XMLElem CPHDXMLParser::createPVPType(const std::string& name, + const PVPType& p, + XMLElem parent) const +{ + XMLElem pvpXML = newElement(name, parent); + createInt("Offset", p.getOffset(), pvpXML); + createInt("Size", p.getSize(), pvpXML); + createString("Format", p.getFormat(), pvpXML); + return pvpXML; +} + +XMLElem CPHDXMLParser::createAPVPType(const std::string& name, + const APVPType& p, + XMLElem parent) const +{ + XMLElem apvpXML = newElement(name, parent); + createString("Name", p.getName(), apvpXML); + createInt("Offset", p.getOffset(), apvpXML); + createInt("Size", p.getSize(), apvpXML); + createString("Format", p.getFormat(), apvpXML); + return apvpXML; +} + +XMLElem CPHDXMLParser::createErrorParamPlatform( + const std::string& /*name*/, + const ErrorParameters::Bistatic::Platform p, + XMLElem parent) const +{ + XMLElem posVelErrXML = newElement("PosVelErr", parent); + createString("Frame", p.posVelErr.frame, posVelErrXML); + createDouble("P1", p.posVelErr.p1, posVelErrXML); + createDouble("P2", p.posVelErr.p2, posVelErrXML); + createDouble("P3", p.posVelErr.p3, posVelErrXML); + createDouble("V1", p.posVelErr.v1, posVelErrXML); + createDouble("V2", p.posVelErr.v2, posVelErrXML); + createDouble("V3", p.posVelErr.v3, posVelErrXML); + if(p.posVelErr.corrCoefs.get()) + { + XMLElem corrCoefsXML = newElement("CorrCoefs", posVelErrXML); + createDouble("P1P2", p.posVelErr.corrCoefs->p1p2, corrCoefsXML); + createDouble("P1P3", p.posVelErr.corrCoefs->p1p3, corrCoefsXML); + createDouble("P1V1", p.posVelErr.corrCoefs->p1v1, corrCoefsXML); + createDouble("P1V2", p.posVelErr.corrCoefs->p1v2, corrCoefsXML); + createDouble("P1V3", p.posVelErr.corrCoefs->p1v3, corrCoefsXML); + createDouble("P2P3", p.posVelErr.corrCoefs->p2p3, corrCoefsXML); + createDouble("P2V1", p.posVelErr.corrCoefs->p2v1, corrCoefsXML); + createDouble("P2V2", p.posVelErr.corrCoefs->p2v2, corrCoefsXML); + createDouble("P2V3", p.posVelErr.corrCoefs->p2v3, corrCoefsXML); + createDouble("P3V1", p.posVelErr.corrCoefs->p3v1, corrCoefsXML); + createDouble("P3V2", p.posVelErr.corrCoefs->p3v2, corrCoefsXML); + createDouble("P3V3", p.posVelErr.corrCoefs->p3v3, corrCoefsXML); + createDouble("V1V2", p.posVelErr.corrCoefs->v1v2, corrCoefsXML); + createDouble("V1V3", p.posVelErr.corrCoefs->v1v3, corrCoefsXML); + createDouble("V2V3", p.posVelErr.corrCoefs->v2v3, corrCoefsXML); + } + createDecorrType("PositionDecorr", p.posVelErr.positionDecorr, posVelErrXML); + return posVelErrXML; +} + +XMLElem CPHDXMLParser::createDecorrType(const std::string& name, const six::DecorrType& dt, + XMLElem parent) const +{ + if (six::Init::isDefined(dt)) + { + XMLElem element = newElement(name, parent); + createDouble("CorrCoefZero", dt.corrCoefZero, element); + createDouble("DecorrRate", dt.decorrRate, element); + return element; + } + return nullptr; +} +XMLElem CPHDXMLParser::createDecorrType(const std::string& name, const std::optional& dt, + XMLElem parent) const +{ + if (dt.has_value()) + { + return createDecorrType(name, *dt, parent); + } + return nullptr; +} + +/* + * Parser helper functions + */ +void CPHDXMLParser::parseAreaType(const xml::lite::Element* areaXML, AreaType& area) const +{ + mCommon.parseVector2D(getFirstAndOnly(areaXML, "X1Y1"), area.x1y1); + mCommon.parseVector2D(getFirstAndOnly(areaXML, "X2Y2"), area.x2y2); + const xml::lite::Element* polygonXML = getOptional(areaXML, "Polygon"); + if (polygonXML) + { + std::vector verticesXML; + polygonXML->getElementsByTagName("Vertex", verticesXML); + if (verticesXML.size() < 3) + { + throw except::Exception(Ctxt( + "Polygons must have at least 3 sides")); + } + area.polygon.resize(verticesXML.size()); + for (size_t ii = 0; ii < area.polygon.size(); ++ii) + { + Vector2& vertex = area.polygon[ii]; + const xml::lite::Element* vertexXML = verticesXML[ii]; + mCommon.parseVector2D(vertexXML, vertex); + } + } +} + +void CPHDXMLParser::parseLineSample(const xml::lite::Element* lsXML, LineSample& ls) const +{ + parseDouble(getFirstAndOnly(lsXML, "Line"), ls.line); + parseDouble(getFirstAndOnly(lsXML, "Sample"), ls.sample); +} + +void CPHDXMLParser::parseIAExtent(const xml::lite::Element* extentXML, + ImageAreaXExtent& extent) const +{ + parseDouble(getFirstAndOnly(extentXML, "LineSpacing"), + extent.lineSpacing); + parseInt(getFirstAndOnly(extentXML, "FirstLine"), + extent.firstLine); + parseUInt(getFirstAndOnly(extentXML, "NumLines"), + extent.numLines); +} + +void CPHDXMLParser::parseIAExtent(const xml::lite::Element* extentXML, + ImageAreaYExtent& extent) const +{ + parseDouble(getFirstAndOnly(extentXML, "SampleSpacing"), + extent.sampleSpacing); + parseInt(getFirstAndOnly(extentXML, "FirstSample"), + extent.firstSample); + parseUInt(getFirstAndOnly(extentXML, "NumSamples"), + extent.numSamples); +} + +void CPHDXMLParser::parseChannelParameters( + const xml::lite::Element* paramXML, ChannelParameter& param) const +{ + parseString(getFirstAndOnly(paramXML, "Identifier"), param.identifier); + parseUInt(getFirstAndOnly(paramXML, "RefVectorIndex"), param.refVectorIndex); + parseBooleanType(getFirstAndOnly(paramXML, "FXFixed"), param.fxFixed); + parseBooleanType(getFirstAndOnly(paramXML, "TOAFixed"), param.toaFixed); + parseBooleanType(getFirstAndOnly(paramXML, "SRPFixed"), param.srpFixed); + + XMLElem signalXML = getOptional(paramXML, "SignalNormal"); + if (signalXML) + { + parseBooleanType(signalXML, param.signalNormal); + } + + parseDouble(getFirstAndOnly(paramXML, "FxC"), param.fxC); + parseDouble(getFirstAndOnly(paramXML, "FxBW"), param.fxBW); + parseOptionalDouble(paramXML, "FxBWNoise", param.fxBWNoise); + parseDouble(getFirstAndOnly(paramXML, "TOASaved"), param.toaSaved); + + XMLElem toaExtendedXML = getOptional(paramXML, "TOAExtended"); + if(toaExtendedXML) + { + param.toaExtended.reset(new TOAExtended()); + parseDouble(getFirstAndOnly(toaExtendedXML, "TOAExtSaved"), param.toaExtended->toaExtSaved); + XMLElem lfmEclipseXML = getOptional(toaExtendedXML, "LFMEclipse"); + if(lfmEclipseXML) + { + param.toaExtended->lfmEclipse.reset(new TOAExtended::LFMEclipse()); + parseDouble(getFirstAndOnly(lfmEclipseXML, "FxEarlyLow"), param.toaExtended->lfmEclipse->fxEarlyLow); + parseDouble(getFirstAndOnly(lfmEclipseXML, "FxEarlyHigh"), param.toaExtended->lfmEclipse->fxEarlyHigh); + parseDouble(getFirstAndOnly(lfmEclipseXML, "FxLateLow"), param.toaExtended->lfmEclipse->fxLateLow); + parseDouble(getFirstAndOnly(lfmEclipseXML, "FxLateHigh"), param.toaExtended->lfmEclipse->fxLateHigh); + } + } + + XMLElem dwellTimesXML = getFirstAndOnly(paramXML, "DwellTimes"); + parseString(getFirstAndOnly(dwellTimesXML, "CODId"), param.dwellTimes.codId); + parseString(getFirstAndOnly(dwellTimesXML, "DwellId"), param.dwellTimes.dwellId); + std::ignore = six::parse(parser(), *dwellTimesXML, param.dwellTimes.dtaId); + std::ignore = six::parse(parser(), *dwellTimesXML, param.dwellTimes.useDTA); + + XMLElem imageAreaXML = getOptional(paramXML, "ImageArea"); + if(imageAreaXML) + { + parseAreaType(imageAreaXML, param.imageArea); + } + + XMLElem antennaXML = getOptional(paramXML, "Antenna"); + if(antennaXML) + { + param.antenna.reset(new ChannelParameter::Antenna()); + parseString(getFirstAndOnly(antennaXML, "TxAPCId"), param.antenna->txAPCId); + parseString(getFirstAndOnly(antennaXML, "TxAPATId"), param.antenna->txAPATId); + parseString(getFirstAndOnly(antennaXML, "RcvAPCId"), param.antenna->rcvAPCId); + parseString(getFirstAndOnly(antennaXML, "RcvAPATId"), param.antenna->rcvAPATId); + } + + XMLElem txRcvXML = getOptional(paramXML, "TxRcv"); + if(txRcvXML) + { + std::vector txWFIdXML; + txRcvXML->getElementsByTagName("TxWFId", txWFIdXML); + param.txRcv.reset(new ChannelParameter::TxRcv()); + param.txRcv->txWFId.resize(txWFIdXML.size()); + for(size_t ii = 0; ii < txWFIdXML.size(); ++ii) + { + parseString(txWFIdXML[ii], param.txRcv->txWFId[ii]); + } + + std::vector rcvIdXML; + txRcvXML->getElementsByTagName("RcvId", rcvIdXML); + param.txRcv->rcvId.resize(rcvIdXML.size()); + for(size_t ii = 0; ii < rcvIdXML.size(); ++ii) + { + parseString(rcvIdXML[ii], param.txRcv->rcvId[ii]); + } + } + + XMLElem tgtRefLevelXML = getOptional(paramXML, "TgtRefLevel"); + if(tgtRefLevelXML) + { + param.tgtRefLevel.reset(new TgtRefLevel()); + parseDouble(getFirstAndOnly(tgtRefLevelXML, "PTRef"), param.tgtRefLevel->ptRef); + } + + XMLElem noiseLevelXML = getOptional(paramXML, "NoiseLevel"); + if(noiseLevelXML) + { + param.noiseLevel.reset(new NoiseLevel()); + parseDouble(getFirstAndOnly(noiseLevelXML, "PNRef"), param.noiseLevel->pnRef); + parseDouble(getFirstAndOnly(noiseLevelXML, "BNRef"), param.noiseLevel->bnRef); + if(!(param.noiseLevel->bnRef > 0 && param.noiseLevel->bnRef <= 1)) + { + throw except::Exception(Ctxt( + "Noise equivalent BW value must be > 0.0 and <= 1.0")); + } + + XMLElem fxNoiseProfileXML = getOptional(noiseLevelXML, "FxNoiseProfile"); + if(fxNoiseProfileXML) + { + param.noiseLevel->fxNoiseProfile.reset(new FxNoiseProfile()); + std::vector pointXMLVec; + fxNoiseProfileXML->getElementsByTagName("Point", pointXMLVec); + if(pointXMLVec.size() < 2) + { + throw except::Exception(Ctxt( + "Atleast 2 noise profile points must be provided")); + } + param.noiseLevel->fxNoiseProfile->point.resize(pointXMLVec.size()); + double prevPoint = six::Init::undefined(); + for(size_t ii = 0; ii < pointXMLVec.size(); ++ii) + { + double fx; + parseDouble(getFirstAndOnly(pointXMLVec[ii], "Fx"), fx); + parseDouble(getFirstAndOnly(pointXMLVec[ii], "PN"), param.noiseLevel->fxNoiseProfile->point[ii].pn); + + if(!six::Init::isUndefined(prevPoint) && fx <= prevPoint) + { + throw except::Exception(Ctxt( + "Fx values are strictly increasing")); + } + param.noiseLevel->fxNoiseProfile->point[ii].fx = fx; + prevPoint = fx; + } + } + } + + // Polarization + parsePolarization(*paramXML, param.polarization); +} + +void CPHDXMLParser::parse(const xml::lite::Element& polarizationXML, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(polarizationXML, o.tag())) + { + o = PolRef{}; + six::getFirstAndOnly(parser(), *pXML, value(o).ampH); + six::getFirstAndOnly(parser(), *pXML, value(o).ampV); + six::getFirstAndOnly(parser(), *pXML, value(o).phaseV); + } +} + +void CPHDXMLParser::parsePolarization(const xml::lite::Element& paramXML, Polarization& polarization) const +{ + std::vector PolarizationXML; + paramXML.getElementsByTagName("Polarization", PolarizationXML); + for (size_t ii = 0; ii < PolarizationXML.size(); ++ii) + { + const xml::lite::Element* TxPolXML = getFirstAndOnly(PolarizationXML[ii], "TxPol"); + polarization.txPol = PolarizationType::toType(TxPolXML->getCharacterData()); + + const xml::lite::Element* RcvPolXML = getFirstAndOnly(PolarizationXML[ii], "RcvPol"); + polarization.rcvPol = PolarizationType::toType(RcvPolXML->getCharacterData()); + + parse(*(PolarizationXML[ii]), polarization.txPolRef); // added in CPHD 1.1.0 + parse(*(PolarizationXML[ii]), polarization.rcvPolRef); // added in CPHD 1.1.0 + } +} + +size_t CPHDXMLParser::parsePVPType(const xml::lite::Element& paramXML, PVPType& param) const +{ + size_t size; + size_t offset; + std::string format; + parseUInt(getFirstAndOnly(paramXML, "Size"), size); + parseUInt(getFirstAndOnly(paramXML, "Offset"), offset); + parseString(getFirstAndOnly(paramXML, "Format"), format); + if (param.getSize() != size) + { + std::ostringstream ostr; + ostr << "Specified size: " << size << " does not match default size: " << param.getSize(); + throw except::Exception(Ctxt(ostr.str())); + } + if (param.getFormat() != format) + { + std::ostringstream ostr; + ostr << "Specified format: " << format << " does not match default format: " << param.getFormat(); + throw except::Exception(Ctxt(ostr.str())); + } + return offset; +} +void CPHDXMLParser::parsePVPType(Pvp& pvp, const xml::lite::Element* paramXML, PVPType& param) const +{ + const auto offset = parsePVPType(*paramXML, param); + pvp.setOffset(offset, param); +} + +void CPHDXMLParser::parsePVPType(Pvp& pvp, const xml::lite::Element* paramXML) const +{ + std::string name; + size_t size; + size_t offset; + std::string format; + parseString(getFirstAndOnly(paramXML, "Name"), name); + parseUInt(getFirstAndOnly(paramXML, "Size"), size); + parseUInt(getFirstAndOnly(paramXML, "Offset"), offset); + parseString(getFirstAndOnly(paramXML, "Format"), format); + pvp.setCustomParameter(size, offset, format, name); +} + +bool CPHDXMLParser::parseOptionalPVPType(const xml::lite::Element* parent, const std::string& tag, Pvp& pvp, PVPType& param) const +{ + if (const xml::lite::Element* const element = getOptional(parent, tag)) + { + parsePVPType(pvp, element, param); + return true; + } + return false; +} + +void CPHDXMLParser::parsePlatformParams(const xml::lite::Element* platXML, Bistatic::PlatformParams& plat) const +{ + parseDouble(getFirstAndOnly(platXML, "Time"), plat.time); + parseDouble(getFirstAndOnly(platXML, "SlantRange"), plat.slantRange); + parseDouble(getFirstAndOnly(platXML, "GroundRange"), plat.groundRange); + parseDouble(getFirstAndOnly(platXML, "DopplerConeAngle"), plat.dopplerConeAngle); + parseDouble(getFirstAndOnly(platXML, "AzimuthAngle"), plat.azimuthAngle); + parseDouble(getFirstAndOnly(platXML, "GrazeAngle"), plat.grazeAngle); + parseDouble(getFirstAndOnly(platXML, "IncidenceAngle"), plat.incidenceAngle); + mCommon.parseVector3D(getFirstAndOnly(platXML, "Pos"), plat.pos); + mCommon.parseVector3D(getFirstAndOnly(platXML, "Vel"), plat.vel); + std::string side = ""; + parseString(getFirstAndOnly(platXML, "SideOfTrack"), side); + plat.sideOfTrack = (side == "L" ? six::SideOfTrackType::LEFT : six::SideOfTrackType::RIGHT); + +} + +void CPHDXMLParser::parseCommon(const xml::lite::Element* imgTypeXML, ImagingType* imgType) const +{ + parseDouble(getFirstAndOnly(imgTypeXML, "TwistAngle"), imgType->twistAngle); + parseDouble(getFirstAndOnly(imgTypeXML, "SlopeAngle"), imgType->slopeAngle); + parseDouble(getFirstAndOnly(imgTypeXML, "LayoverAngle"), imgType->layoverAngle); + parseDouble(getFirstAndOnly(imgTypeXML, "AzimuthAngle"), imgType->azimuthAngle); + parseDouble(getFirstAndOnly(imgTypeXML, "GrazeAngle"), imgType->grazeAngle); +} + +void CPHDXMLParser::parsePosVelErr(const xml::lite::Element* posVelErrXML, six::PosVelError& posVelErr) const +{ + std::string frameStr; + parseString(getFirstAndOnly(posVelErrXML, "Frame"), frameStr); + posVelErr.frame.mValue = scene::FrameType::fromString(frameStr); + parseDouble(getFirstAndOnly(posVelErrXML, "P1"), posVelErr.p1); + parseDouble(getFirstAndOnly(posVelErrXML, "P2"), posVelErr.p2); + parseDouble(getFirstAndOnly(posVelErrXML, "P3"), posVelErr.p3); + parseDouble(getFirstAndOnly(posVelErrXML, "V1"), posVelErr.v1); + parseDouble(getFirstAndOnly(posVelErrXML, "V2"), posVelErr.v2); + parseDouble(getFirstAndOnly(posVelErrXML, "V3"), posVelErr.v3); + + XMLElem corrCoefsXML = getOptional(posVelErrXML, "CorrCoefs"); + + if(corrCoefsXML) + { + posVelErr.corrCoefs.reset(new six::CorrCoefs()); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1P2"), posVelErr.corrCoefs->p1p2); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1P3"), posVelErr.corrCoefs->p1p3); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1V1"), posVelErr.corrCoefs->p1v1); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1V2"), posVelErr.corrCoefs->p1v2); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1V3"), posVelErr.corrCoefs->p1v3); + parseDouble(getFirstAndOnly(corrCoefsXML, "P2P3"), posVelErr.corrCoefs->p2p3); + parseDouble(getFirstAndOnly(corrCoefsXML, "P2V1"), posVelErr.corrCoefs->p2v1); + parseDouble(getFirstAndOnly(corrCoefsXML, "P2V2"), posVelErr.corrCoefs->p2v2); + parseDouble(getFirstAndOnly(corrCoefsXML, "P2V3"), posVelErr.corrCoefs->p2v3); + parseDouble(getFirstAndOnly(corrCoefsXML, "P3V1"), posVelErr.corrCoefs->p3v1); + parseDouble(getFirstAndOnly(corrCoefsXML, "P3V2"), posVelErr.corrCoefs->p3v2); + parseDouble(getFirstAndOnly(corrCoefsXML, "P3V3"), posVelErr.corrCoefs->p3v3); + parseDouble(getFirstAndOnly(corrCoefsXML, "V1V2"), posVelErr.corrCoefs->v1v2); + parseDouble(getFirstAndOnly(corrCoefsXML, "V1V3"), posVelErr.corrCoefs->v1v3); + parseDouble(getFirstAndOnly(corrCoefsXML, "V2V3"), posVelErr.corrCoefs->v2v3); + } + + // posVelErr.positionDecorr.reset(new six::DecorrType()); + mCommon.parseOptionalDecorrType(posVelErrXML, "PositionDecorr", posVelErr.positionDecorr); +} + +void CPHDXMLParser::parsePlatform(const xml::lite::Element* platXML, ErrorParameters::Bistatic::Platform& plat) const +{ + parsePosVelErr(getFirstAndOnly(platXML, "PosVelErr"), plat.posVelErr); + XMLElem radarSensorXML = getFirstAndOnly(platXML, "RadarSensor"); + six::parse(parser(), *radarSensorXML, plat.radarSensor.delayBias); + parseOptionalDouble(radarSensorXML, "ClockFreqSF", plat.radarSensor.clockFreqSF); + parseDouble(getFirstAndOnly(radarSensorXML, "CollectionStartTime"), plat.radarSensor.collectionStartTime); +} + +void CPHDXMLParser::parseSupportArrayParameter(const xml::lite::Element* paramXML, SupportArrayParameter& param, bool additionalFlag) const +{ + if(!additionalFlag) + { + size_t identifierVal; + parseUInt(getFirstAndOnly(paramXML, "Identifier"), identifierVal); + param.setIdentifier(identifierVal); + } + parseString(getFirstAndOnly(paramXML, "ElementFormat"), param.elementFormat); + parseDouble(getFirstAndOnly(paramXML, "X0"), param.x0); + parseDouble(getFirstAndOnly(paramXML, "Y0"), param.y0); + parseDouble(getFirstAndOnly(paramXML, "XSS"), param.xSS); + parseDouble(getFirstAndOnly(paramXML, "YSS"), param.ySS); +} + +void CPHDXMLParser::parseTxRcvParameter(const xml::lite::Element* paramXML, ParameterType& param) const +{ + parseString(getFirstAndOnly(paramXML, "Identifier"), param.identifier); + parseDouble(getFirstAndOnly(paramXML, "FreqCenter"), param.freqCenter); + parseOptionalDouble(paramXML, "LFMRate", param.lfmRate); + param.polarization = PolarizationType::toType(getFirstAndOnly(paramXML, "Polarization")->getCharacterData()); +} +} diff --git a/six/modules/c++/cphd/source/Channel.cpp b/six/modules/c++/cphd/source/Channel.cpp index 351303a402..e9e6df6ad0 100644 --- a/six/modules/c++/cphd/source/Channel.cpp +++ b/six/modules/c++/cphd/source/Channel.cpp @@ -1,227 +1,227 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include - -#include - -namespace cphd -{ - -TOAExtended::TOAExtended() : - toaExtSaved(six::Init::undefined()) -{ -} - -TOAExtended::LFMEclipse::LFMEclipse() : - fxEarlyLow(six::Init::undefined()), - fxEarlyHigh(six::Init::undefined()), - fxLateLow(six::Init::undefined()), - fxLateHigh(six::Init::undefined()) -{ -} - -DwellTimes::DwellTimes() -{ -} - -TgtRefLevel::TgtRefLevel() : - ptRef(six::Init::undefined()) -{ -} - -Point::Point() : - fx(six::Init::undefined()), - pn(six::Init::undefined()) -{ -} - -NoiseLevel::NoiseLevel() : - pnRef(six::Init::undefined()), - bnRef(six::Init::undefined()) -{ -} - -ChannelParameter::ChannelParameter() : - refVectorIndex(six::Init::undefined()), - fxFixed(six::Init::undefined()), - toaFixed(six::Init::undefined()), - srpFixed(six::Init::undefined()), - signalNormal(six::Init::undefined()), - fxC(six::Init::undefined()), - fxBW(six::Init::undefined()), - fxBWNoise(six::Init::undefined()), - toaSaved(six::Init::undefined()) -{ -} - -ChannelParameter::Antenna::Antenna() -{ -} - -Channel::Channel() : - fxFixedCphd(six::Init::undefined()), - toaFixedCphd(six::Init::undefined()), - srpFixedCphd(six::Init::undefined()) -{ -} - -std::ostream& operator<< (std::ostream& os, const PolRef& v) -{ - os << v.ampH << v.ampV << v.phaseV << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Polarization& p) -{ - os << " TxPol : " << p.txPol << "\n" - << " RcvPol : " << p.rcvPol << "\n" - << p.txPolRef << p.rcvPolRef; - return os; -} - -std::ostream& operator<< (std::ostream& os, const TOAExtended& t) -{ - os << " TOAExtended:: \n" - << " TOAExtSaved : " << t.toaExtSaved << "\n" - << " LFMEclipse:: \n" - << " FxEarlyLow : " << t.lfmEclipse->fxEarlyLow << "\n" - << " FxEarlyHigh : " << t.lfmEclipse->fxEarlyHigh << "\n" - << " FxLateLow : " << t.lfmEclipse->fxLateLow << "\n" - << " FxLateHigh : " << t.lfmEclipse->fxLateHigh << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const DwellTimes& d) -{ - os << " DwellTimes:: \n" - << " CODId : " << d.codId << "\n" - << " DwellId : " << d.dwellId << "\n" - << d.dtaId - << d.useDTA; - return os; -} - -std::ostream& operator<< (std::ostream& os, const TgtRefLevel& t) -{ - os << " TgtRefLevel:: \n" - << " PtRef : " << t.ptRef << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Point& p) -{ - os << " Point:: \n" - << " Fx : " << p.fx << "\n" - << " Pn : " << p.pn << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const FxNoiseProfile& f) -{ - os << " FxNoiseProfile:: \n"; - for (const auto& point : f.point) - { - os << " Point : " << point << "\n"; - } - return os; -} - -std::ostream& operator<< (std::ostream& os, const NoiseLevel& n) -{ - os << " NoiseLevel:: \n" - << " PnRef : " << n.pnRef << "\n" - << " BnRef : " << n.bnRef << "\n"; - if(n.fxNoiseProfile.get()) - { - os << *(n.fxNoiseProfile) << "\n"; - } - return os; -} - -std::ostream& operator<< (std::ostream& os, const ChannelParameter& c) -{ - os << " ChannelParameter:: \n" - << " Identifier : " << c.identifier << "\n" - << " RefVectorIndex : " << c.refVectorIndex << "\n" - << " FxFixed : " << c.fxFixed << "\n" - << " TOAFixed : " << c.toaFixed << "\n" - << " SRPFixed : " << c.srpFixed << "\n" - << " SginalNormal : " << c.signalNormal << "\n" - << " Polarization:: \n" - << c.polarization << "\n" - << " FxC : " << c.fxC << "\n" - << " FxBW : " << c.fxBW << "\n" - << " FxBWNoise : " << c.fxBWNoise << "\n" - << " TOASaved : " << c.toaSaved << "\n"; - if (c.toaExtended.get()) - { - os << *(c.toaExtended) << "\n"; - } - os << c.dwellTimes << "\n" - << c.imageArea << "\n" - << " Antenna:: \n" - << " TxAPCId : " << c.antenna->txAPCId << "\n" - << " TxAPATId : " << c.antenna->txAPATId << "\n" - << " RcvAPCId : " << c.antenna->rcvAPCId << "\n" - << " RcvAPATId : " << c.antenna->rcvAPATId << "\n" - << " TxRcv:: \n"; - for (size_t ii = 0; ii < c.txRcv->txWFId.size(); ++ii) - { - os << " TxWFId : " << c.txRcv->txWFId[ii] << "\n"; - } - for (size_t ii = 0; ii < c.txRcv->rcvId.size(); ++ii) - { - os << " RcvId : " << c.txRcv->rcvId[ii] << "\n"; - } - if (c.tgtRefLevel.get()) - { - os << *(c.tgtRefLevel) << "\n"; - } - if (c.noiseLevel.get()) - { - os << *(c.noiseLevel) << "\n"; - } - return os; -} - -std::ostream& operator<< (std::ostream& os, const Channel& c) -{ - os << "Channel:: \n" - << " RefChId : " << c.refChId << "\n" - << " FxFixedCphd : " << c.fxFixedCphd << "\n" - << " TOAFixedCphd : " << c.toaFixedCphd << "\n" - << " SRPFixedCphd : " << c.srpFixedCphd << "\n" - << " Parameters:: \n"; - for (size_t ii = 0; ii < c.parameters.size(); ++ii) - { - os << c.parameters[ii] << "\n"; - } - for (size_t ii = 0; ii < c.addedParameters.size(); ++ii) - { - os << " Parameter name : " << c.addedParameters[ii].getName() << "\n"; - os << " Parameter value : " << c.addedParameters[ii].str() << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include + +#include + +namespace cphd +{ + +TOAExtended::TOAExtended() : + toaExtSaved(six::Init::undefined()) +{ +} + +TOAExtended::LFMEclipse::LFMEclipse() : + fxEarlyLow(six::Init::undefined()), + fxEarlyHigh(six::Init::undefined()), + fxLateLow(six::Init::undefined()), + fxLateHigh(six::Init::undefined()) +{ +} + +DwellTimes::DwellTimes() +{ +} + +TgtRefLevel::TgtRefLevel() : + ptRef(six::Init::undefined()) +{ +} + +Point::Point() : + fx(six::Init::undefined()), + pn(six::Init::undefined()) +{ +} + +NoiseLevel::NoiseLevel() : + pnRef(six::Init::undefined()), + bnRef(six::Init::undefined()) +{ +} + +ChannelParameter::ChannelParameter() : + refVectorIndex(six::Init::undefined()), + fxFixed(six::Init::undefined()), + toaFixed(six::Init::undefined()), + srpFixed(six::Init::undefined()), + signalNormal(six::Init::undefined()), + fxC(six::Init::undefined()), + fxBW(six::Init::undefined()), + fxBWNoise(six::Init::undefined()), + toaSaved(six::Init::undefined()) +{ +} + +ChannelParameter::Antenna::Antenna() +{ +} + +Channel::Channel() : + fxFixedCphd(six::Init::undefined()), + toaFixedCphd(six::Init::undefined()), + srpFixedCphd(six::Init::undefined()) +{ +} + +std::ostream& operator<< (std::ostream& os, const PolRef& v) +{ + os << v.ampH << v.ampV << v.phaseV << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Polarization& p) +{ + os << " TxPol : " << p.txPol << "\n" + << " RcvPol : " << p.rcvPol << "\n" + << p.txPolRef << p.rcvPolRef; + return os; +} + +std::ostream& operator<< (std::ostream& os, const TOAExtended& t) +{ + os << " TOAExtended:: \n" + << " TOAExtSaved : " << t.toaExtSaved << "\n" + << " LFMEclipse:: \n" + << " FxEarlyLow : " << t.lfmEclipse->fxEarlyLow << "\n" + << " FxEarlyHigh : " << t.lfmEclipse->fxEarlyHigh << "\n" + << " FxLateLow : " << t.lfmEclipse->fxLateLow << "\n" + << " FxLateHigh : " << t.lfmEclipse->fxLateHigh << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const DwellTimes& d) +{ + os << " DwellTimes:: \n" + << " CODId : " << d.codId << "\n" + << " DwellId : " << d.dwellId << "\n" + << d.dtaId + << d.useDTA; + return os; +} + +std::ostream& operator<< (std::ostream& os, const TgtRefLevel& t) +{ + os << " TgtRefLevel:: \n" + << " PtRef : " << t.ptRef << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Point& p) +{ + os << " Point:: \n" + << " Fx : " << p.fx << "\n" + << " Pn : " << p.pn << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const FxNoiseProfile& f) +{ + os << " FxNoiseProfile:: \n"; + for (const auto& point : f.point) + { + os << " Point : " << point << "\n"; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const NoiseLevel& n) +{ + os << " NoiseLevel:: \n" + << " PnRef : " << n.pnRef << "\n" + << " BnRef : " << n.bnRef << "\n"; + if(n.fxNoiseProfile.get()) + { + os << *(n.fxNoiseProfile) << "\n"; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const ChannelParameter& c) +{ + os << " ChannelParameter:: \n" + << " Identifier : " << c.identifier << "\n" + << " RefVectorIndex : " << c.refVectorIndex << "\n" + << " FxFixed : " << c.fxFixed << "\n" + << " TOAFixed : " << c.toaFixed << "\n" + << " SRPFixed : " << c.srpFixed << "\n" + << " SginalNormal : " << c.signalNormal << "\n" + << " Polarization:: \n" + << c.polarization << "\n" + << " FxC : " << c.fxC << "\n" + << " FxBW : " << c.fxBW << "\n" + << " FxBWNoise : " << c.fxBWNoise << "\n" + << " TOASaved : " << c.toaSaved << "\n"; + if (c.toaExtended.get()) + { + os << *(c.toaExtended) << "\n"; + } + os << c.dwellTimes << "\n" + << c.imageArea << "\n" + << " Antenna:: \n" + << " TxAPCId : " << c.antenna->txAPCId << "\n" + << " TxAPATId : " << c.antenna->txAPATId << "\n" + << " RcvAPCId : " << c.antenna->rcvAPCId << "\n" + << " RcvAPATId : " << c.antenna->rcvAPATId << "\n" + << " TxRcv:: \n"; + for (size_t ii = 0; ii < c.txRcv->txWFId.size(); ++ii) + { + os << " TxWFId : " << c.txRcv->txWFId[ii] << "\n"; + } + for (size_t ii = 0; ii < c.txRcv->rcvId.size(); ++ii) + { + os << " RcvId : " << c.txRcv->rcvId[ii] << "\n"; + } + if (c.tgtRefLevel.get()) + { + os << *(c.tgtRefLevel) << "\n"; + } + if (c.noiseLevel.get()) + { + os << *(c.noiseLevel) << "\n"; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const Channel& c) +{ + os << "Channel:: \n" + << " RefChId : " << c.refChId << "\n" + << " FxFixedCphd : " << c.fxFixedCphd << "\n" + << " TOAFixedCphd : " << c.toaFixedCphd << "\n" + << " SRPFixedCphd : " << c.srpFixedCphd << "\n" + << " Parameters:: \n"; + for (size_t ii = 0; ii < c.parameters.size(); ++ii) + { + os << c.parameters[ii] << "\n"; + } + for (size_t ii = 0; ii < c.addedParameters.size(); ++ii) + { + os << " Parameter name : " << c.addedParameters[ii].getName() << "\n"; + os << " Parameter value : " << c.addedParameters[ii].str() << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/Dwell.cpp b/six/modules/c++/cphd/source/Dwell.cpp index c3e5ef39c1..16d77eb0a5 100644 --- a/six/modules/c++/cphd/source/Dwell.cpp +++ b/six/modules/c++/cphd/source/Dwell.cpp @@ -1,73 +1,73 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include - -namespace cphd -{ - -DwellTime::DwellTime() : - dwellTimePoly(six::Init::undefined()) -{ -} - -COD::COD() : - codTimePoly(six::Init::undefined()) -{ -} - -Dwell::Dwell() -{ -} - -std::ostream& operator<< (std::ostream& os, const DwellTime& d) -{ - os << " DwellTime:: \n" - << " Identifier : " << d.identifier << "\n" - << " DwellTimePoly : " << d.dwellTimePoly << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const COD& c) -{ - os << " COD:: \n" - << " Identifier : " << c.identifier << "\n" - << " CODTimePoly : " << c.codTimePoly << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Dwell& d) -{ - os << "Dwell:: \n" - << " NumCODTimes : " << d.cod.size() << "\n" - << " NumDwellTimes : " << d.dtime.size() << "\n"; - for (const auto& cod : d.cod) - { - os << cod << "\n"; - } - for (const auto& dtime : d.dtime) - { - os << dtime << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include + +namespace cphd +{ + +DwellTime::DwellTime() : + dwellTimePoly(six::Init::undefined()) +{ +} + +COD::COD() : + codTimePoly(six::Init::undefined()) +{ +} + +Dwell::Dwell() +{ +} + +std::ostream& operator<< (std::ostream& os, const DwellTime& d) +{ + os << " DwellTime:: \n" + << " Identifier : " << d.identifier << "\n" + << " DwellTimePoly : " << d.dwellTimePoly << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const COD& c) +{ + os << " COD:: \n" + << " Identifier : " << c.identifier << "\n" + << " CODTimePoly : " << c.codTimePoly << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Dwell& d) +{ + os << "Dwell:: \n" + << " NumCODTimes : " << d.cod.size() << "\n" + << " NumDwellTimes : " << d.dtime.size() << "\n"; + for (const auto& cod : d.cod) + { + os << cod << "\n"; + } + for (const auto& dtime : d.dtime) + { + os << dtime << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/ErrorParameters.cpp b/six/modules/c++/cphd/source/ErrorParameters.cpp index 368773f7a2..4dfe3550b8 100644 --- a/six/modules/c++/cphd/source/ErrorParameters.cpp +++ b/six/modules/c++/cphd/source/ErrorParameters.cpp @@ -1,191 +1,191 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include -#include - -namespace cphd -{ -ErrorParameters::Monostatic::RadarSensor::RadarSensor() : - rangeBias(six::Init::undefined()), - clockFreqSF(six::Init::undefined()), - collectionStartTime(six::Init::undefined()) -{ -} - -ErrorParameters::Bistatic::RadarSensor::RadarSensor() : - clockFreqSF(six::Init::undefined()), - collectionStartTime(six::Init::undefined()) -{ -} - -static std::ostream& unchecked(std::ostream& os, const six::DecorrType& decorr_) -{ - const auto decorr = six::value(decorr_); - os << " CorrCoefZero : " << decorr.corrCoefZero << "\n" - << " DecorrRate : " << decorr.decorrRate << "\n"; - return os; -} -std::ostream& unchecked(std::ostream& os, const std::optional& decorr) -{ - return unchecked(os, *decorr); -} - -static std::ostream& checked(std::ostream& os, const std::string& s, const six::DecorrType& decorr) -{ - if (six::Init::isDefined(decorr)) - { - os << s; - return unchecked(os, decorr); - } - return os; -} -std::ostream& checked(std::ostream& os, const std::string& s, const std::optional& decorr) -{ - return decorr.has_value() ? checked(os, s, *decorr) : os; -} - - -static std::ostream& checked(std::ostream& os, const std::string& s, const double& v) -{ - if (six::Init::isDefined(v)) - { - os << s << v << "\n"; - } - return os; -} -std::ostream& checked(std::ostream& os, const std::string& s, const std::optional& v) -{ - return v.has_value() ? checked(os, s, *v) : os; -} - -std::ostream& operator<< (std::ostream& os, const six::PosVelError& p) -{ - os << " PosVelError:: \n" - << " Frame : " << p.frame << "\n" - << " P1 : " << p.p1 << "\n" - << " P2 : " << p.p2 << "\n" - << " P3 : " << p.p3 << "\n" - << " V1 : " << p.v1 << "\n" - << " V2 : " << p.v2 << "\n" - << " V3 : " << p.v3 << "\n"; - if (p.corrCoefs.get()) - { - os << " CorrCoefs:: \n" - << " p1p2 : " << p.corrCoefs->p1p2 << "\n" - << " p1p3 : " << p.corrCoefs->p1p3 << "\n" - << " p1v1 : " << p.corrCoefs->p1v1 << "\n" - << " p1v2 : " << p.corrCoefs->p1v2 << "\n" - << " p1v3 : " << p.corrCoefs->p1v3 << "\n" - << " p2p3 : " << p.corrCoefs->p2p3 << "\n" - << " p2v1 : " << p.corrCoefs->p2v1 << "\n" - << " p2v2 : " << p.corrCoefs->p2v2 << "\n" - << " p2v3 : " << p.corrCoefs->p2v3 << "\n" - << " p3v1 : " << p.corrCoefs->p3v1 << "\n" - << " p3v2 : " << p.corrCoefs->p3v2 << "\n" - << " p3v3 : " << p.corrCoefs->p3v3 << "\n" - << " v1v2 : " << p.corrCoefs->v1v2 << "\n" - << " v1v3 : " << p.corrCoefs->v1v3 << "\n" - << " v2v3 : " << p.corrCoefs->v2v3 << "\n"; - } - os << " Decorr:: \n"; - return unchecked(os, p.positionDecorr); -} - -static std::ostream& operator<< (std::ostream& os, const ErrorParameters::Bistatic::RadarSensor& v) -{ - os << " RadarSensor:: \n" - << v.delayBias - << " ClockFreqSF : " << v.clockFreqSF << "\n" - << " CollectionStartTime : " <posVelErr << "\n" - << " RadarSensor:: \n" - << " RangeBias : " << e.monostatic->radarSensor.rangeBias << "\n"; - if (!six::Init::isUndefined(e.monostatic->radarSensor.clockFreqSF)) - { - os << " ClockFreqSF : " << e.monostatic->radarSensor.clockFreqSF << "\n"; - } - if (!six::Init::isUndefined(e.monostatic->radarSensor.collectionStartTime)) - { - os << " CollectionStartTime : " << e.monostatic->radarSensor.collectionStartTime << "\n"; - } - if (e.monostatic->radarSensor.rangeBiasDecorr.get()) - { - os << " RangeBiasDecorr:: \n" - << " CorrCoefZero : " << e.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero << "\n" - << " DecorrRate : " << e.monostatic->radarSensor.rangeBiasDecorr->decorrRate << "\n"; - } - if (e.monostatic->tropoError.get()) - { - os << " TropoError:: \n"; - checked(os, " TropoRangeVertical : ", e.monostatic->tropoError->tropoRangeVertical); - checked(os, " TropoRangeSlant : ", e.monostatic->tropoError->tropoRangeSlant); - checked(os, " TropoRangeDecorr:: \n", e.monostatic->tropoError->tropoRangeDecorr); - } - if (e.monostatic->ionoError.get()) - { - os << " IonoError:: \n"; - checked(os, " IonoRangeVertical : ", e.monostatic->ionoError->ionoRangeVertical); - checked(os, " IonoRangeRateVertical : ", e.monostatic->ionoError->ionoRangeRateVertical); - os << " IonoRgRgRateCC : " << six::value(e.monostatic->ionoError->ionoRgRgRateCC) << "\n"; - checked(os, " IonoRangeDecorr:: \n", e.monostatic->ionoError->ionoRangeVertDecorr); - } - for (const auto& parameter : e.monostatic->parameter) - { - os << " Parameter Name : " << parameter.getName() << "\n" - << " Parameter Value : " << parameter.str() << "\n"; - } - } - else if (e.bistatic.get()) - { - os << " Bistatic:: \n" - << " TxPlatform:: \n" - << e.bistatic->txPlatform.posVelErr << "\n" - << e.bistatic->txPlatform.radarSensor - << "\n" - << " RcvPlatform:: \n" - << e.bistatic->rcvPlatform.posVelErr << "\n" - << e.bistatic->rcvPlatform.radarSensor; - for (const auto& parameter : e.bistatic->parameter) - { - os << " Parameter Name : " << parameter.getName() << "\n" - << " Parameter Value : " << parameter.str() << "\n"; - } - } - else - { - throw except::Exception(Ctxt( - "One of either monostatic or bistatic is required")); - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include +#include + +namespace cphd +{ +ErrorParameters::Monostatic::RadarSensor::RadarSensor() : + rangeBias(six::Init::undefined()), + clockFreqSF(six::Init::undefined()), + collectionStartTime(six::Init::undefined()) +{ +} + +ErrorParameters::Bistatic::RadarSensor::RadarSensor() : + clockFreqSF(six::Init::undefined()), + collectionStartTime(six::Init::undefined()) +{ +} + +static std::ostream& unchecked(std::ostream& os, const six::DecorrType& decorr_) +{ + const auto decorr = six::value(decorr_); + os << " CorrCoefZero : " << decorr.corrCoefZero << "\n" + << " DecorrRate : " << decorr.decorrRate << "\n"; + return os; +} +std::ostream& unchecked(std::ostream& os, const std::optional& decorr) +{ + return unchecked(os, *decorr); +} + +static std::ostream& checked(std::ostream& os, const std::string& s, const six::DecorrType& decorr) +{ + if (six::Init::isDefined(decorr)) + { + os << s; + return unchecked(os, decorr); + } + return os; +} +std::ostream& checked(std::ostream& os, const std::string& s, const std::optional& decorr) +{ + return decorr.has_value() ? checked(os, s, *decorr) : os; +} + + +static std::ostream& checked(std::ostream& os, const std::string& s, const double& v) +{ + if (six::Init::isDefined(v)) + { + os << s << v << "\n"; + } + return os; +} +std::ostream& checked(std::ostream& os, const std::string& s, const std::optional& v) +{ + return v.has_value() ? checked(os, s, *v) : os; +} + +std::ostream& operator<< (std::ostream& os, const six::PosVelError& p) +{ + os << " PosVelError:: \n" + << " Frame : " << p.frame << "\n" + << " P1 : " << p.p1 << "\n" + << " P2 : " << p.p2 << "\n" + << " P3 : " << p.p3 << "\n" + << " V1 : " << p.v1 << "\n" + << " V2 : " << p.v2 << "\n" + << " V3 : " << p.v3 << "\n"; + if (p.corrCoefs.get()) + { + os << " CorrCoefs:: \n" + << " p1p2 : " << p.corrCoefs->p1p2 << "\n" + << " p1p3 : " << p.corrCoefs->p1p3 << "\n" + << " p1v1 : " << p.corrCoefs->p1v1 << "\n" + << " p1v2 : " << p.corrCoefs->p1v2 << "\n" + << " p1v3 : " << p.corrCoefs->p1v3 << "\n" + << " p2p3 : " << p.corrCoefs->p2p3 << "\n" + << " p2v1 : " << p.corrCoefs->p2v1 << "\n" + << " p2v2 : " << p.corrCoefs->p2v2 << "\n" + << " p2v3 : " << p.corrCoefs->p2v3 << "\n" + << " p3v1 : " << p.corrCoefs->p3v1 << "\n" + << " p3v2 : " << p.corrCoefs->p3v2 << "\n" + << " p3v3 : " << p.corrCoefs->p3v3 << "\n" + << " v1v2 : " << p.corrCoefs->v1v2 << "\n" + << " v1v3 : " << p.corrCoefs->v1v3 << "\n" + << " v2v3 : " << p.corrCoefs->v2v3 << "\n"; + } + os << " Decorr:: \n"; + return unchecked(os, p.positionDecorr); +} + +static std::ostream& operator<< (std::ostream& os, const ErrorParameters::Bistatic::RadarSensor& v) +{ + os << " RadarSensor:: \n" + << v.delayBias + << " ClockFreqSF : " << v.clockFreqSF << "\n" + << " CollectionStartTime : " <posVelErr << "\n" + << " RadarSensor:: \n" + << " RangeBias : " << e.monostatic->radarSensor.rangeBias << "\n"; + if (!six::Init::isUndefined(e.monostatic->radarSensor.clockFreqSF)) + { + os << " ClockFreqSF : " << e.monostatic->radarSensor.clockFreqSF << "\n"; + } + if (!six::Init::isUndefined(e.monostatic->radarSensor.collectionStartTime)) + { + os << " CollectionStartTime : " << e.monostatic->radarSensor.collectionStartTime << "\n"; + } + if (e.monostatic->radarSensor.rangeBiasDecorr.get()) + { + os << " RangeBiasDecorr:: \n" + << " CorrCoefZero : " << e.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero << "\n" + << " DecorrRate : " << e.monostatic->radarSensor.rangeBiasDecorr->decorrRate << "\n"; + } + if (e.monostatic->tropoError.get()) + { + os << " TropoError:: \n"; + checked(os, " TropoRangeVertical : ", e.monostatic->tropoError->tropoRangeVertical); + checked(os, " TropoRangeSlant : ", e.monostatic->tropoError->tropoRangeSlant); + checked(os, " TropoRangeDecorr:: \n", e.monostatic->tropoError->tropoRangeDecorr); + } + if (e.monostatic->ionoError.get()) + { + os << " IonoError:: \n"; + checked(os, " IonoRangeVertical : ", e.monostatic->ionoError->ionoRangeVertical); + checked(os, " IonoRangeRateVertical : ", e.monostatic->ionoError->ionoRangeRateVertical); + os << " IonoRgRgRateCC : " << six::value(e.monostatic->ionoError->ionoRgRgRateCC) << "\n"; + checked(os, " IonoRangeDecorr:: \n", e.monostatic->ionoError->ionoRangeVertDecorr); + } + for (const auto& parameter : e.monostatic->parameter) + { + os << " Parameter Name : " << parameter.getName() << "\n" + << " Parameter Value : " << parameter.str() << "\n"; + } + } + else if (e.bistatic.get()) + { + os << " Bistatic:: \n" + << " TxPlatform:: \n" + << e.bistatic->txPlatform.posVelErr << "\n" + << e.bistatic->txPlatform.radarSensor + << "\n" + << " RcvPlatform:: \n" + << e.bistatic->rcvPlatform.posVelErr << "\n" + << e.bistatic->rcvPlatform.radarSensor; + for (const auto& parameter : e.bistatic->parameter) + { + os << " Parameter Name : " << parameter.getName() << "\n" + << " Parameter Value : " << parameter.str() << "\n"; + } + } + else + { + throw except::Exception(Ctxt( + "One of either monostatic or bistatic is required")); + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/PVP.cpp b/six/modules/c++/cphd/source/PVP.cpp index 7400ac4bd0..ab675012aa 100644 --- a/six/modules/c++/cphd/source/PVP.cpp +++ b/six/modules/c++/cphd/source/PVP.cpp @@ -1,280 +1,280 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include - -#include -#include - -#include -#include - -namespace cphd -{ -PVPType::PVPType() : - mSize(0), - mOffset(six::Init::undefined()) -{ -} - -APVPType::APVPType() -{ -} - -Pvp::Pvp() -{ - initialize(); -} - -void Pvp::initialize() -{ - // Default size and formats for each PVP - // listed in Table 11-6 CPHD1.0 Spec - setDefaultValues(1,"F8", txTime); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", txPos); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", txVel); - setDefaultValues(1,"F8", rcvTime); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvVel); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", srpPos); - setDefaultValues(1,"F8", ampSF); - setDefaultValues(1,"F8", aFDOP); - setDefaultValues(1,"F8", aFRR1); - setDefaultValues(1,"F8", aFRR2); - setDefaultValues(1,"F8", fx1); - setDefaultValues(1,"F8", fx2); - setDefaultValues(1,"F8", fxN1); - setDefaultValues(1,"F8", fxN2); - setDefaultValues(1,"F8", toa1); - setDefaultValues(1,"F8", toa2); - setDefaultValues(1,"F8", toaE1); - setDefaultValues(1,"F8", toaE2); - setDefaultValues(1,"F8", tdTropoSRP); - setDefaultValues(1,"F8", tdIonoSRP); - setDefaultValues(1,"F8", sc0); - setDefaultValues(1,"F8", scss); - setDefaultValues(1,"I8", signal); -} - -void Pvp::validate(size_t size, size_t offset) -{ - //Check if size of array is sufficient for write - if (offset + size > mParamLocations.size()) - { - mParamLocations.resize(offset+size); - } - - //Check if any blocks will be overwritten - for (size_t ii = 0; ii < size; ++ii) - { - if(mParamLocations.at(offset + ii) == true) - { - throw except::Exception(Ctxt("This byte block is occupied")); - } - } - - // Mark each block as written - for (size_t ii = 0; ii < size; ++ii) - { - mParamLocations.at(offset + ii) = true; - } -} - -void setOffset(PVPType& param, size_t offset) -{ - validateFormat(param.getFormat()); - param.setOffset(offset); -} - -void Pvp::setOffset(size_t offset, PVPType& param) -{ - validate(param.getSize(), offset); - cphd::setOffset(param, offset); -} - -void Pvp::append(PVPType& param) -{ - size_t currentOffset = mParamLocations.size(); - setOffset(currentOffset, param); -} - -// Assumes addedPVP is already correct size -void Pvp::setCustomParameter(size_t size, size_t offset, const std::string& format, const std::string& name) -{ - validate(size, offset); - validateFormat(format); - if (addedPVP.count(name) == 0) - { - addedPVP[name] = APVPType(); - addedPVP.find(name)->second.setData(size, offset, format, name); - return; - } - throw except::Exception(Ctxt( - "Additional parameter name is not unique")); -} - -void Pvp::appendCustomParameter(size_t size, const std::string& format, const std::string& name) -{ - size_t currentOffset = mParamLocations.size(); - setCustomParameter(size, currentOffset, format, name); -} - -void Pvp::setDefaultValues(size_t size, const std::string& format, PVPType& param) -{ - param.setSize(size); - param.setFormat(format); -} - -// Returns num blocks (not bytes) -size_t Pvp::getReqSetSize() const -{ - size_t res = txTime.getSize() + txPos.getSize() + txVel.getSize() + - rcvTime.getSize() + rcvPos.getSize() + rcvVel.getSize() + srpPos.getSize() + - aFDOP.getSize() + aFRR1.getSize() + aFRR2.getSize() + fx1.getSize() + - fx2.getSize() + toa1.getSize() + toa2.getSize() + tdTropoSRP.getSize() + - sc0.getSize() + scss.getSize(); - if(!six::Init::isUndefined(ampSF.getOffset())) - { - res += ampSF.getSize(); - } - if(!six::Init::isUndefined(fxN1.getOffset())) - { - res += fxN1.getSize(); - } - if(!six::Init::isUndefined(fxN2.getOffset())) - { - res += fxN2.getSize(); - } - if(!six::Init::isUndefined(toaE1.getOffset())) - { - res += toaE1.getSize(); - } - if(!six::Init::isUndefined(toaE2.getOffset())) - { - res += toaE2.getSize(); - } - if(!six::Init::isUndefined(tdIonoSRP.getOffset())) - { - res += tdIonoSRP.getSize(); - } - if(!six::Init::isUndefined(signal.getOffset())) - { - res += signal.getSize(); - } - for (auto it = addedPVP.begin(); it != addedPVP.end(); ++it) - { - res += it->second.getSize(); - } - return res; -} - -size_t Pvp::sizeInBytes() const -{ - return getReqSetSize() * PVPType::WORD_BYTE_SIZE; -} - -std::ostream& operator<< (std::ostream& os, const PVPType& p) -{ - os << " Size : " << p.getSize() << "\n" - << " Offset : " << p.getOffset() << "\n" - << " Format : " << p.getFormat() << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const APVPType& a) -{ - os << " Name : " << a.getName() << "\n" - << (PVPType)a; - - return os; -} - -std::ostream& operator<< (std::ostream& os, const Pvp& p) -{ - os << " TxTime : \n" << p.txTime << "\n" - << " TxPos : \n" << p.txPos << "\n" - << " TxVel : \n" << p.txVel << "\n" - << " RcvTime : \n" << p.rcvTime << "\n" - << " RcvPos : \n" << p.rcvPos << "\n" - << " RcvVel : \n" << p.rcvVel << "\n" - << " SRPPos : \n" << p.srpPos << "\n" - << " aFDOP : \n" << p.aFDOP << "\n" - << " aFRR1 : \n" << p.aFRR1 << "\n" - << " aFRR2 : \n" << p.aFRR2 << "\n" - << " Fx1 : \n" << p.fx1 << "\n" - << " Fx2 : \n" << p.fx2 << "\n" - << " TOA1 : \n" << p.toa1 << "\n" - << " TOA2 : \n" << p.toa2 << "\n" - << " TdTropoSRP : \n" << p.tdTropoSRP << "\n" - << " SC0 : \n" << p.sc0 << "\n" - << " SCSS : \n" << p.scss << "\n"; - - if(!six::Init::isUndefined(p.ampSF.getOffset())) - { - os << " AmpSF : \n" << p.ampSF << "\n"; - } - if(!six::Init::isUndefined(p.fxN1.getOffset())) - { - os << " FxN1 : \n" << p.fxN1 << "\n"; - } - if(!six::Init::isUndefined(p.fxN2.getOffset())) - { - os << " FxN2 : \n" << p.fxN2 << "\n"; - } - if(!six::Init::isUndefined(p.toaE1.getOffset())) - { - os << " TOAE1 : \n" << p.toaE1 << "\n"; - } - if(!six::Init::isUndefined(p.toaE2.getOffset())) - { - os << " TOAE2 : \n" << p.toaE2 << "\n"; - } - if(!six::Init::isUndefined(p.tdIonoSRP.getOffset())) - { - os << " TdIonoSRP : \n" << p.tdIonoSRP << "\n"; - } - if(!six::Init::isUndefined(p.signal.getOffset())) - { - os << " SIGNAL : \n" << p.signal << "\n"; - } - for (auto it = p.addedPVP.begin(); it != p.addedPVP.end(); ++it) - { - os << " Additional Parameter : " << it->second << "\n"; - } - return os; -} - -PerVectorParameterXYZ::PerVectorParameterXYZ() -{ - // setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); - param.setSize(3); // - param.setFormat("X=F8;Y=F8;Z=F8;"); // -} - -PerVectorParameterEB::PerVectorParameterEB() -{ - // setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); - param.setSize(2); // - param.setFormat("DCX=F8;DCY=F8;"); // -} - -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include + +#include +#include + +#include +#include + +namespace cphd +{ +PVPType::PVPType() : + mSize(0), + mOffset(six::Init::undefined()) +{ +} + +APVPType::APVPType() +{ +} + +Pvp::Pvp() +{ + initialize(); +} + +void Pvp::initialize() +{ + // Default size and formats for each PVP + // listed in Table 11-6 CPHD1.0 Spec + setDefaultValues(1,"F8", txTime); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", txPos); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", txVel); + setDefaultValues(1,"F8", rcvTime); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvVel); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", srpPos); + setDefaultValues(1,"F8", ampSF); + setDefaultValues(1,"F8", aFDOP); + setDefaultValues(1,"F8", aFRR1); + setDefaultValues(1,"F8", aFRR2); + setDefaultValues(1,"F8", fx1); + setDefaultValues(1,"F8", fx2); + setDefaultValues(1,"F8", fxN1); + setDefaultValues(1,"F8", fxN2); + setDefaultValues(1,"F8", toa1); + setDefaultValues(1,"F8", toa2); + setDefaultValues(1,"F8", toaE1); + setDefaultValues(1,"F8", toaE2); + setDefaultValues(1,"F8", tdTropoSRP); + setDefaultValues(1,"F8", tdIonoSRP); + setDefaultValues(1,"F8", sc0); + setDefaultValues(1,"F8", scss); + setDefaultValues(1,"I8", signal); +} + +void Pvp::validate(size_t size, size_t offset) +{ + //Check if size of array is sufficient for write + if (offset + size > mParamLocations.size()) + { + mParamLocations.resize(offset+size); + } + + //Check if any blocks will be overwritten + for (size_t ii = 0; ii < size; ++ii) + { + if(mParamLocations.at(offset + ii) == true) + { + throw except::Exception(Ctxt("This byte block is occupied")); + } + } + + // Mark each block as written + for (size_t ii = 0; ii < size; ++ii) + { + mParamLocations.at(offset + ii) = true; + } +} + +void setOffset(PVPType& param, size_t offset) +{ + validateFormat(param.getFormat()); + param.setOffset(offset); +} + +void Pvp::setOffset(size_t offset, PVPType& param) +{ + validate(param.getSize(), offset); + cphd::setOffset(param, offset); +} + +void Pvp::append(PVPType& param) +{ + size_t currentOffset = mParamLocations.size(); + setOffset(currentOffset, param); +} + +// Assumes addedPVP is already correct size +void Pvp::setCustomParameter(size_t size, size_t offset, const std::string& format, const std::string& name) +{ + validate(size, offset); + validateFormat(format); + if (addedPVP.count(name) == 0) + { + addedPVP[name] = APVPType(); + addedPVP.find(name)->second.setData(size, offset, format, name); + return; + } + throw except::Exception(Ctxt( + "Additional parameter name is not unique")); +} + +void Pvp::appendCustomParameter(size_t size, const std::string& format, const std::string& name) +{ + size_t currentOffset = mParamLocations.size(); + setCustomParameter(size, currentOffset, format, name); +} + +void Pvp::setDefaultValues(size_t size, const std::string& format, PVPType& param) +{ + param.setSize(size); + param.setFormat(format); +} + +// Returns num blocks (not bytes) +size_t Pvp::getReqSetSize() const +{ + size_t res = txTime.getSize() + txPos.getSize() + txVel.getSize() + + rcvTime.getSize() + rcvPos.getSize() + rcvVel.getSize() + srpPos.getSize() + + aFDOP.getSize() + aFRR1.getSize() + aFRR2.getSize() + fx1.getSize() + + fx2.getSize() + toa1.getSize() + toa2.getSize() + tdTropoSRP.getSize() + + sc0.getSize() + scss.getSize(); + if(!six::Init::isUndefined(ampSF.getOffset())) + { + res += ampSF.getSize(); + } + if(!six::Init::isUndefined(fxN1.getOffset())) + { + res += fxN1.getSize(); + } + if(!six::Init::isUndefined(fxN2.getOffset())) + { + res += fxN2.getSize(); + } + if(!six::Init::isUndefined(toaE1.getOffset())) + { + res += toaE1.getSize(); + } + if(!six::Init::isUndefined(toaE2.getOffset())) + { + res += toaE2.getSize(); + } + if(!six::Init::isUndefined(tdIonoSRP.getOffset())) + { + res += tdIonoSRP.getSize(); + } + if(!six::Init::isUndefined(signal.getOffset())) + { + res += signal.getSize(); + } + for (auto it = addedPVP.begin(); it != addedPVP.end(); ++it) + { + res += it->second.getSize(); + } + return res; +} + +size_t Pvp::sizeInBytes() const +{ + return getReqSetSize() * PVPType::WORD_BYTE_SIZE; +} + +std::ostream& operator<< (std::ostream& os, const PVPType& p) +{ + os << " Size : " << p.getSize() << "\n" + << " Offset : " << p.getOffset() << "\n" + << " Format : " << p.getFormat() << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const APVPType& a) +{ + os << " Name : " << a.getName() << "\n" + << (PVPType)a; + + return os; +} + +std::ostream& operator<< (std::ostream& os, const Pvp& p) +{ + os << " TxTime : \n" << p.txTime << "\n" + << " TxPos : \n" << p.txPos << "\n" + << " TxVel : \n" << p.txVel << "\n" + << " RcvTime : \n" << p.rcvTime << "\n" + << " RcvPos : \n" << p.rcvPos << "\n" + << " RcvVel : \n" << p.rcvVel << "\n" + << " SRPPos : \n" << p.srpPos << "\n" + << " aFDOP : \n" << p.aFDOP << "\n" + << " aFRR1 : \n" << p.aFRR1 << "\n" + << " aFRR2 : \n" << p.aFRR2 << "\n" + << " Fx1 : \n" << p.fx1 << "\n" + << " Fx2 : \n" << p.fx2 << "\n" + << " TOA1 : \n" << p.toa1 << "\n" + << " TOA2 : \n" << p.toa2 << "\n" + << " TdTropoSRP : \n" << p.tdTropoSRP << "\n" + << " SC0 : \n" << p.sc0 << "\n" + << " SCSS : \n" << p.scss << "\n"; + + if(!six::Init::isUndefined(p.ampSF.getOffset())) + { + os << " AmpSF : \n" << p.ampSF << "\n"; + } + if(!six::Init::isUndefined(p.fxN1.getOffset())) + { + os << " FxN1 : \n" << p.fxN1 << "\n"; + } + if(!six::Init::isUndefined(p.fxN2.getOffset())) + { + os << " FxN2 : \n" << p.fxN2 << "\n"; + } + if(!six::Init::isUndefined(p.toaE1.getOffset())) + { + os << " TOAE1 : \n" << p.toaE1 << "\n"; + } + if(!six::Init::isUndefined(p.toaE2.getOffset())) + { + os << " TOAE2 : \n" << p.toaE2 << "\n"; + } + if(!six::Init::isUndefined(p.tdIonoSRP.getOffset())) + { + os << " TdIonoSRP : \n" << p.tdIonoSRP << "\n"; + } + if(!six::Init::isUndefined(p.signal.getOffset())) + { + os << " SIGNAL : \n" << p.signal << "\n"; + } + for (auto it = p.addedPVP.begin(); it != p.addedPVP.end(); ++it) + { + os << " Additional Parameter : " << it->second << "\n"; + } + return os; +} + +PerVectorParameterXYZ::PerVectorParameterXYZ() +{ + // setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); + param.setSize(3); // + param.setFormat("X=F8;Y=F8;Z=F8;"); // +} + +PerVectorParameterEB::PerVectorParameterEB() +{ + // setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); + param.setSize(2); // + param.setFormat("DCX=F8;DCY=F8;"); // +} + +} diff --git a/six/modules/c++/cphd/source/ProductInfo.cpp b/six/modules/c++/cphd/source/ProductInfo.cpp index 44607d601f..caf266aaa1 100644 --- a/six/modules/c++/cphd/source/ProductInfo.cpp +++ b/six/modules/c++/cphd/source/ProductInfo.cpp @@ -1,63 +1,63 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include - -namespace cphd -{ -ProductInfo::ProductInfo() -{ -} - -ProductInfo::CreationInfo::CreationInfo(): - dateTime(six::Init::undefined()) -{ -} - -std::ostream& operator<< (std::ostream& os, const ProductInfo& p) -{ - os << "Product Information : \n" - << " Profile : " << p.profile << "\n"; - for (size_t ii = 0; ii < p.creationInfo.size(); ++ii) - { - os << " Creation Information : " << "\n" - << " Application : " << p.creationInfo[ii].application << "\n" - << " DateTime : " << p.creationInfo[ii].dateTime.getMonth() << "/" - << p.creationInfo[ii].dateTime.getDayOfMonth() << "/" - << p.creationInfo[ii].dateTime.getYear() << "\n" - << " Site : " << p.creationInfo[ii].site << "\n"; - for (size_t jj = 0; jj < p.creationInfo[ii].parameter.size(); ++jj) - { - os << " Parameter name : " - << p.creationInfo[ii].parameter[jj].getName() << "\n" - << " Parameter value : " << p.creationInfo[ii].parameter[jj].str() << "\n"; - } - } - for (size_t ii = 0; ii < p.parameter.size(); ++ii) - { - os << " Parameter name : " << p.parameter[ii].getName() << "\n" - << " Parameter value : " << p.parameter[ii].str() << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include + +namespace cphd +{ +ProductInfo::ProductInfo() +{ +} + +ProductInfo::CreationInfo::CreationInfo(): + dateTime(six::Init::undefined()) +{ +} + +std::ostream& operator<< (std::ostream& os, const ProductInfo& p) +{ + os << "Product Information : \n" + << " Profile : " << p.profile << "\n"; + for (size_t ii = 0; ii < p.creationInfo.size(); ++ii) + { + os << " Creation Information : " << "\n" + << " Application : " << p.creationInfo[ii].application << "\n" + << " DateTime : " << p.creationInfo[ii].dateTime.getMonth() << "/" + << p.creationInfo[ii].dateTime.getDayOfMonth() << "/" + << p.creationInfo[ii].dateTime.getYear() << "\n" + << " Site : " << p.creationInfo[ii].site << "\n"; + for (size_t jj = 0; jj < p.creationInfo[ii].parameter.size(); ++jj) + { + os << " Parameter name : " + << p.creationInfo[ii].parameter[jj].getName() << "\n" + << " Parameter value : " << p.creationInfo[ii].parameter[jj].str() << "\n"; + } + } + for (size_t ii = 0; ii < p.parameter.size(); ++ii) + { + os << " Parameter name : " << p.parameter[ii].getName() << "\n" + << " Parameter value : " << p.parameter[ii].str() << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/ReferenceGeometry.cpp b/six/modules/c++/cphd/source/ReferenceGeometry.cpp index 0823dd4950..7c6bb22b1e 100644 --- a/six/modules/c++/cphd/source/ReferenceGeometry.cpp +++ b/six/modules/c++/cphd/source/ReferenceGeometry.cpp @@ -1,174 +1,174 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include - -namespace cphd -{ - -SRP::SRP() : - ecf(six::Init::undefined()), - iac(six::Init::undefined()) -{ -} - -ImagingType::ImagingType() : - azimuthAngle(0), - grazeAngle(0), - twistAngle(0), - slopeAngle(0), - layoverAngle(0) -{ -} - -Monostatic::Monostatic() : - sideOfTrack(six::Init::undefined()), - slantRange(0), - groundRange(0), - dopplerConeAngle(0), - incidenceAngle(0), - arpPos(six::Init::undefined()), - arpVel(six::Init::undefined()) -{ -} - -Bistatic::Bistatic() : - azimuthAngleRate(0), - bistaticAngle(0), - bistaticAngleRate(0) -{ -} - -Bistatic::PlatformParams::PlatformParams() : - sideOfTrack(six::Init::undefined()), - time(0), - azimuthAngle(0), - grazeAngle(0), - incidenceAngle(0), - dopplerConeAngle(0), - groundRange(0), - slantRange(0), - pos(six::Init::undefined()), - vel(six::Init::undefined()) -{ -} - -ReferenceGeometry::ReferenceGeometry() : - referenceTime(0), - srpCODTime(0), - srpDwellTime(0) -{ -} - -std::ostream& operator<< (std::ostream& os, const SRP& s) -{ - os << "SRP:: \n" - << " ECF : " << s.ecf << "\n" - << " IAC : " << s.iac << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const ImagingType& i) -{ - os << " AzimuthAngle : " << i.azimuthAngle << "\n" - << " GrazeAngle : " << i.grazeAngle << "\n" - << " TwistAngle : " << i.twistAngle << "\n" - << " SlopeAngle : " << i.slopeAngle << "\n" - << " layoverAngle : " << i.layoverAngle << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Monostatic& m) -{ - os << "Monostatic:: \n" - << (ImagingType)m << "\n" - << " SideOfTrack : " << m.sideOfTrack << "\n" - << " SlantRange : " << m.slantRange << "\n" - << " GroundRange : " << m.groundRange << "\n" - << " DopplerConeAngle : " << m.dopplerConeAngle << "\n" - << " IncidenceAngle : " << m.incidenceAngle << "\n" - << " ArpPos:: \n" - << " X : " << m.arpPos[0] << "\n" - << " Y : " << m.arpPos[1] << "\n" - << " Z : " << m.arpPos[2] << "\n" - << " ArpVel:: \n" - << " X : " << m.arpVel[0] << "\n" - << " Y : " << m.arpVel[1] << "\n" - << " Z : " << m.arpVel[2] << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Bistatic::PlatformParams& p) -{ - os << " SideOfTrack : " << p.sideOfTrack << "\n" - << " Time: : " << p.time << "\n" - << " AzimuthAngle : " << p.azimuthAngle << "\n" - << " GrazeAngle : " << p.grazeAngle << "\n" - << " IncidenceAngle : " << p.incidenceAngle << "\n" - << " DopplerConeAngle : " << p.dopplerConeAngle << "\n" - << " GroundRange : " << p.groundRange << "\n" - << " SlantRange : " << p.slantRange << "\n" - << " Pos:: \n" - << " X : " << p.pos[0] << "\n" - << " Y : " << p.pos[1] << "\n" - << " Z : " << p.pos[2] << "\n" - << " Vel:: \n" - << " X : " << p.vel[0] << "\n" - << " Y : " << p.vel[1] << "\n" - << " Z : " << p.vel[2] << "\n"; - - return os; -} - -std::ostream& operator<< (std::ostream& os, const Bistatic& b) -{ - os << "Bistatic:: \n" - << (ImagingType)b << "\n" - << " AzimuthAngleRate : " << b.azimuthAngleRate << "\n" - << " BistaticAngle : " << b.bistaticAngle << "\n" - << " BistaticAngleRate : " << b.bistaticAngleRate << "\n" - << " TxPlatform:: \n" - << b.txPlatform << "\n" - << b.rcvPlatform << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const ReferenceGeometry& r) -{ - os << "Reference Geometry:: \n" - << " ReferenceTime : " << r.referenceTime << "\n" - << " SRPCODTime : " << r.srpCODTime << "\n" - << " SRPDwellTime : " << r.srpDwellTime << "\n" - << r.srp; - - if (r.monostatic.get()) - { - os << *r.monostatic << "\n"; - } - else if (r.bistatic.get()) - { - os << *r.bistatic << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include + +namespace cphd +{ + +SRP::SRP() : + ecf(six::Init::undefined()), + iac(six::Init::undefined()) +{ +} + +ImagingType::ImagingType() : + azimuthAngle(0), + grazeAngle(0), + twistAngle(0), + slopeAngle(0), + layoverAngle(0) +{ +} + +Monostatic::Monostatic() : + sideOfTrack(six::Init::undefined()), + slantRange(0), + groundRange(0), + dopplerConeAngle(0), + incidenceAngle(0), + arpPos(six::Init::undefined()), + arpVel(six::Init::undefined()) +{ +} + +Bistatic::Bistatic() : + azimuthAngleRate(0), + bistaticAngle(0), + bistaticAngleRate(0) +{ +} + +Bistatic::PlatformParams::PlatformParams() : + sideOfTrack(six::Init::undefined()), + time(0), + azimuthAngle(0), + grazeAngle(0), + incidenceAngle(0), + dopplerConeAngle(0), + groundRange(0), + slantRange(0), + pos(six::Init::undefined()), + vel(six::Init::undefined()) +{ +} + +ReferenceGeometry::ReferenceGeometry() : + referenceTime(0), + srpCODTime(0), + srpDwellTime(0) +{ +} + +std::ostream& operator<< (std::ostream& os, const SRP& s) +{ + os << "SRP:: \n" + << " ECF : " << s.ecf << "\n" + << " IAC : " << s.iac << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const ImagingType& i) +{ + os << " AzimuthAngle : " << i.azimuthAngle << "\n" + << " GrazeAngle : " << i.grazeAngle << "\n" + << " TwistAngle : " << i.twistAngle << "\n" + << " SlopeAngle : " << i.slopeAngle << "\n" + << " layoverAngle : " << i.layoverAngle << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Monostatic& m) +{ + os << "Monostatic:: \n" + << (ImagingType)m << "\n" + << " SideOfTrack : " << m.sideOfTrack << "\n" + << " SlantRange : " << m.slantRange << "\n" + << " GroundRange : " << m.groundRange << "\n" + << " DopplerConeAngle : " << m.dopplerConeAngle << "\n" + << " IncidenceAngle : " << m.incidenceAngle << "\n" + << " ArpPos:: \n" + << " X : " << m.arpPos[0] << "\n" + << " Y : " << m.arpPos[1] << "\n" + << " Z : " << m.arpPos[2] << "\n" + << " ArpVel:: \n" + << " X : " << m.arpVel[0] << "\n" + << " Y : " << m.arpVel[1] << "\n" + << " Z : " << m.arpVel[2] << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Bistatic::PlatformParams& p) +{ + os << " SideOfTrack : " << p.sideOfTrack << "\n" + << " Time: : " << p.time << "\n" + << " AzimuthAngle : " << p.azimuthAngle << "\n" + << " GrazeAngle : " << p.grazeAngle << "\n" + << " IncidenceAngle : " << p.incidenceAngle << "\n" + << " DopplerConeAngle : " << p.dopplerConeAngle << "\n" + << " GroundRange : " << p.groundRange << "\n" + << " SlantRange : " << p.slantRange << "\n" + << " Pos:: \n" + << " X : " << p.pos[0] << "\n" + << " Y : " << p.pos[1] << "\n" + << " Z : " << p.pos[2] << "\n" + << " Vel:: \n" + << " X : " << p.vel[0] << "\n" + << " Y : " << p.vel[1] << "\n" + << " Z : " << p.vel[2] << "\n"; + + return os; +} + +std::ostream& operator<< (std::ostream& os, const Bistatic& b) +{ + os << "Bistatic:: \n" + << (ImagingType)b << "\n" + << " AzimuthAngleRate : " << b.azimuthAngleRate << "\n" + << " BistaticAngle : " << b.bistaticAngle << "\n" + << " BistaticAngleRate : " << b.bistaticAngleRate << "\n" + << " TxPlatform:: \n" + << b.txPlatform << "\n" + << b.rcvPlatform << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const ReferenceGeometry& r) +{ + os << "Reference Geometry:: \n" + << " ReferenceTime : " << r.referenceTime << "\n" + << " SRPCODTime : " << r.srpCODTime << "\n" + << " SRPDwellTime : " << r.srpDwellTime << "\n" + << r.srp; + + if (r.monostatic.get()) + { + os << *r.monostatic << "\n"; + } + else if (r.bistatic.get()) + { + os << *r.bistatic << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/TxRcv.cpp b/six/modules/c++/cphd/source/TxRcv.cpp index 99e03aadac..11a9b9017f 100644 --- a/six/modules/c++/cphd/source/TxRcv.cpp +++ b/six/modules/c++/cphd/source/TxRcv.cpp @@ -1,99 +1,99 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include - -namespace cphd -{ - -ParameterType::ParameterType() : - freqCenter(six::Init::undefined()), - lfmRate(six::Init::undefined()) -{ -} - -TxWFParameters::TxWFParameters() : - pulseLength(six::Init::undefined()), - rfBandwidth(six::Init::undefined()), - power(six::Init::undefined()) -{ -} - -RcvParameters::RcvParameters() : - windowLength(six::Init::undefined()), - sampleRate(six::Init::undefined()), - ifFilterBW(six::Init::undefined()), - pathGain(six::Init::undefined()) -{ -} - -TxRcv::TxRcv() -{ -} - -std::ostream& operator<< (std::ostream& os, const ParameterType& p) -{ - os << " Identifier : " << p.identifier << "\n" - << " FreqCenter : " << p.freqCenter << "\n" - << " LFMRate : " << p.lfmRate << "\n" - << " Polarization : " << p.polarization << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const TxWFParameters& t) -{ - os << " TxWFParamters:: \n" - << (ParameterType)t - << " PulseLength : " << t.pulseLength << "\n" - << " RFBandwidth : " << t.rfBandwidth << "\n" - << " Power : " << t.power << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const RcvParameters& r) -{ - os << " RcvParamters:: \n" - << (ParameterType)r - << " WindowLength : " << r.windowLength << "\n" - << " SampleRate : " << r.sampleRate << "\n" - << " IFFilterBW : " << r.ifFilterBW << "\n" - << " PathGain : " << r.pathGain << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const TxRcv& t) -{ - os << "TxRcv:: \n" - << " NumTxWFs : " << t.txWFParameters.size() << "\n" - << " NumRcvs : " << t.rcvParameters.size() << "\n"; - for (size_t ii = 0; ii < t.txWFParameters.size(); ++ii) - { - os << t.txWFParameters[ii] << "\n"; - } - for (size_t ii = 0; ii < t.rcvParameters.size(); ++ii) - { - os << t.rcvParameters[ii] << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include + +namespace cphd +{ + +ParameterType::ParameterType() : + freqCenter(six::Init::undefined()), + lfmRate(six::Init::undefined()) +{ +} + +TxWFParameters::TxWFParameters() : + pulseLength(six::Init::undefined()), + rfBandwidth(six::Init::undefined()), + power(six::Init::undefined()) +{ +} + +RcvParameters::RcvParameters() : + windowLength(six::Init::undefined()), + sampleRate(six::Init::undefined()), + ifFilterBW(six::Init::undefined()), + pathGain(six::Init::undefined()) +{ +} + +TxRcv::TxRcv() +{ +} + +std::ostream& operator<< (std::ostream& os, const ParameterType& p) +{ + os << " Identifier : " << p.identifier << "\n" + << " FreqCenter : " << p.freqCenter << "\n" + << " LFMRate : " << p.lfmRate << "\n" + << " Polarization : " << p.polarization << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const TxWFParameters& t) +{ + os << " TxWFParamters:: \n" + << (ParameterType)t + << " PulseLength : " << t.pulseLength << "\n" + << " RFBandwidth : " << t.rfBandwidth << "\n" + << " Power : " << t.power << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const RcvParameters& r) +{ + os << " RcvParamters:: \n" + << (ParameterType)r + << " WindowLength : " << r.windowLength << "\n" + << " SampleRate : " << r.sampleRate << "\n" + << " IFFilterBW : " << r.ifFilterBW << "\n" + << " PathGain : " << r.pathGain << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const TxRcv& t) +{ + os << "TxRcv:: \n" + << " NumTxWFs : " << t.txWFParameters.size() << "\n" + << " NumRcvs : " << t.rcvParameters.size() << "\n"; + for (size_t ii = 0; ii < t.txWFParameters.size(); ++ii) + { + os << t.txWFParameters[ii] << "\n"; + } + for (size_t ii = 0; ii < t.rcvParameters.size(); ++ii) + { + os << t.rcvParameters[ii] << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/unittests/test_channel.cpp b/six/modules/c++/cphd/unittests/test_channel.cpp index 00820eaf35..ae679bc374 100644 --- a/six/modules/c++/cphd/unittests/test_channel.cpp +++ b/six/modules/c++/cphd/unittests/test_channel.cpp @@ -1,85 +1,85 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include - -#include -#include -#include -#include - -#include "TestCase.h" - -TEST_CASE(EmptyChannel) -{ - cphd::Channel channel1, channel2; - channel1.parameters.resize(3); - channel2.parameters.resize(3); - TEST_ASSERT_TRUE((channel1.parameters == channel2.parameters)); - TEST_ASSERT_TRUE((channel1 == channel2)); -} - -TEST_CASE(TestPolygonInvalid) -{ - cphd::Channel channel; - - six::Vector2 vertex1, vertex2; - vertex1[0] = 0; - vertex1[1] = 0; - vertex2[0] = 5; - vertex2[1] = 5; - - channel.parameters.resize(1); - channel.parameters[0].imageArea.x1y1[0] = 0; - channel.parameters[0].imageArea.x1y1[1] = 0; - channel.parameters[0].imageArea.x2y2[0] = 10; - channel.parameters[0].imageArea.x2y2[1] = 10; - channel.parameters[0].imageArea.polygon.push_back(vertex1); - channel.parameters[0].imageArea.polygon.push_back(vertex2); - - TEST_ASSERT_FALSE(channel.parameters[0].imageArea.polygon.size() >= 3); -} - - -TEST_CASE(TxRcvMultIds) -{ - cphd::Channel channel; - channel.parameters.resize(2); - channel.parameters[0].txRcv.reset(new cphd::ChannelParameter::TxRcv()); - channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam1"); - channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam2"); - channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam3"); - - channel.parameters[0].txRcv->rcvId.push_back("ReceiverWaveformParam1"); - channel.parameters[0].txRcv->rcvId.push_back("ReceiverWaveformParam2"); - - TEST_ASSERT_EQ(channel.parameters[0].txRcv->txWFId.size(), static_cast(3)); - TEST_ASSERT_EQ(channel.parameters[0].txRcv->rcvId.size(), static_cast(2)); -} - -TEST_MAIN( - TEST_CHECK(EmptyChannel); - TEST_CHECK(TestPolygonInvalid); - TEST_CHECK(TxRcvMultIds); - ) - +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include + +#include +#include +#include +#include + +#include "TestCase.h" + +TEST_CASE(EmptyChannel) +{ + cphd::Channel channel1, channel2; + channel1.parameters.resize(3); + channel2.parameters.resize(3); + TEST_ASSERT_TRUE((channel1.parameters == channel2.parameters)); + TEST_ASSERT_TRUE((channel1 == channel2)); +} + +TEST_CASE(TestPolygonInvalid) +{ + cphd::Channel channel; + + six::Vector2 vertex1, vertex2; + vertex1[0] = 0; + vertex1[1] = 0; + vertex2[0] = 5; + vertex2[1] = 5; + + channel.parameters.resize(1); + channel.parameters[0].imageArea.x1y1[0] = 0; + channel.parameters[0].imageArea.x1y1[1] = 0; + channel.parameters[0].imageArea.x2y2[0] = 10; + channel.parameters[0].imageArea.x2y2[1] = 10; + channel.parameters[0].imageArea.polygon.push_back(vertex1); + channel.parameters[0].imageArea.polygon.push_back(vertex2); + + TEST_ASSERT_FALSE(channel.parameters[0].imageArea.polygon.size() >= 3); +} + + +TEST_CASE(TxRcvMultIds) +{ + cphd::Channel channel; + channel.parameters.resize(2); + channel.parameters[0].txRcv.reset(new cphd::ChannelParameter::TxRcv()); + channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam1"); + channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam2"); + channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam3"); + + channel.parameters[0].txRcv->rcvId.push_back("ReceiverWaveformParam1"); + channel.parameters[0].txRcv->rcvId.push_back("ReceiverWaveformParam2"); + + TEST_ASSERT_EQ(channel.parameters[0].txRcv->txWFId.size(), static_cast(3)); + TEST_ASSERT_EQ(channel.parameters[0].txRcv->rcvId.size(), static_cast(2)); +} + +TEST_MAIN( + TEST_CHECK(EmptyChannel); + TEST_CHECK(TestPolygonInvalid); + TEST_CHECK(TxRcvMultIds); + ) + diff --git a/six/modules/c++/cphd/unittests/test_cphd_xml_optional.cpp b/six/modules/c++/cphd/unittests/test_cphd_xml_optional.cpp index 2bfe76f733..ebc55372f2 100644 --- a/six/modules/c++/cphd/unittests/test_cphd_xml_optional.cpp +++ b/six/modules/c++/cphd/unittests/test_cphd_xml_optional.cpp @@ -1,1129 +1,1129 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "TestCase.h" - -const char* test_cphd_xml_optional_XML = -"\n" -" \n" -" Collector\n" -" Core\n" -" MONOSTATIC\n" -" \n" -" STRIPMAP\n" -" Mode\n" -" \n" -" U\n" -" Release\n" -" US,GB,AZ\n" -" val\n" -" \n" -" \n" -" FX\n" -" +1\n" -" \n" -" 2013-04-10T08:52:09.000000Z\n" -" 2014-04-10T08:52:09.000000Z\n" -" 1.300000000000000E00\n" -" 1.500000000000000E00\n" -" \n" -" \n" -" 9.000000000000000E-01\n" -" 1.700000000000000E00\n" -" \n" -" \n" -" 3.400000000000000E00\n" -" 6.100000000000000E00\n" -" \n" -" \n" -" 6.520000000000000E01\n" -" IARP\n" -" \n" -" \n" -" 5.800000000000000E00\n" -" 3.000000000000000E00\n" -" \n" -" \n" -" \n" -" WGS_84\n" -" \n" -" \n" -" 1.200000000000000E00\n" -" 2.300000000000000E00\n" -" 3.400000000000000E00\n" -" \n" -" \n" -" 4.500000000000000E01\n" -" -1.020000000000000E02\n" -" 3.400000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 1.200000000000000E01\n" -" 2.400000000000000E01\n" -" \n" -" \n" -" 3.600000000000000E01\n" -" 4.800000000000000E01\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 3.500000000000000E00\n" -" 5.300000000000000E00\n" -" \n" -" \n" -" 5.300000000000000E00\n" -" 3.500000000000000E00\n" -" \n" -" \n" -" \n" -" 1.000000000000000E-01\n" -" 3.000000000000000E-01\n" -" \n" -" \n" -" 4.000000000000000E-01\n" -" 2.000000000000000E-01\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 9.000000000000000E-01\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E01\n" -" 1.100000000000000E01\n" -" \n" -" \n" -" 2.000000000000000E01\n" -" 2.100000000000000E01\n" -" \n" -" \n" -" 3.000000000000000E01\n" -" 3.100000000000000E01\n" -" \n" -" \n" -" 4.000000000000000E01\n" -" 4.100000000000000E01\n" -" \n" -" \n" -" \n" -" Grid\n" -" \n" -" 1.230000000000000E00\n" -" 3.210000000000000E00\n" -" \n" -" \n" -" 3.140000000000000E00\n" -" 4\n" -" 50\n" -" \n" -" \n" -" 6.280000000000000E00\n" -" 8\n" -" 100\n" -" \n" -" \n" -" 2\n" -" \n" -" Segment1\n" -" 0\n" -" 1\n" -" 2\n" -" 3\n" -" \n" -" \n" -" 4.000000000000000E-01\n" -" 6.000000000000000E-01\n" -" \n" -" \n" -" 8.000000000000000E-01\n" -" 1.200000000000000E00\n" -" \n" -" \n" -" 1.200000000000000E00\n" -" 1.800000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" Segment2\n" -" 1\n" -" 2\n" -" 3\n" -" 4\n" -" \n" -" \n" -" 4.000000000000000E-01\n" -" 6.000000000000000E-01\n" -" \n" -" \n" -" 8.000000000000000E-01\n" -" 1.200000000000000E00\n" -" \n" -" \n" -" 1.200000000000000E00\n" -" 1.800000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" CI4\n" -" 24\n" -" 2\n" -" Compress\n" -" \n" -" Channel\n" -" 2\n" -" 3\n" -" 0\n" -" 1\n" -" 3\n" -" \n" -" \n" -" Channel\n" -" 2\n" -" 3\n" -" 0\n" -" 1\n" -" 3\n" -" \n" -" 3\n" -" \n" -" 1.0\n" -" 3\n" -" 4\n" -" 8\n" -" 0\n" -" \n" -" \n" -" 2.0\n" -" 3\n" -" 4\n" -" 4\n" -" 96\n" -" \n" -" \n" -" AddedSupportArray\n" -" 3\n" -" 4\n" -" 4\n" -" 144\n" -" \n" -" \n" -" \n" -" ChId\n" -" true\n" -" false\n" -" true\n" -" \n" -" CPI\n" -" 1\n" -" false\n" -" true\n" -" true\n" -" false\n" -" \n" -" X\n" -" RHC\n" -" \n" -" 1.300000000000000E00\n" -" 8.000000000000000E-01\n" -" 5.000000000000000E-01\n" -" 2.700000000000000E00\n" -" \n" -" 1.000000000000000E00\n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" CODPolynomial\n" -" DwellPolynomial\n" -" \n" -" \n" -" \n" -" 3.500000000000000E00\n" -" 5.300000000000000E00\n" -" \n" -" \n" -" 5.300000000000000E00\n" -" 3.500000000000000E00\n" -" \n" -" \n" -" \n" -" 1.000000000000000E-01\n" -" 3.000000000000000E-01\n" -" \n" -" \n" -" 4.000000000000000E-01\n" -" 2.000000000000000E-01\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 9.000000000000000E-01\n" -" \n" -" \n" -" \n" -" \n" -" TxAPCId\n" -" TxAPATId\n" -" RcvAPCId\n" -" RcvAPATId\n" -" \n" -" \n" -" TxWFId\n" -" RcvId\n" -" \n" -" \n" -" 1.200000000000000E01\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" \n" -" \n" -" 3.000000000000000E-01\n" -" 2.700000000000000E00\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 2.700000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" Param\n" -" Param\n" -" \n" -" \n" -" \n" -" \n" -" 0\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 1\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 4\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 7\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 8\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 11\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 14\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 17\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 18\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 19\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 20\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 21\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 22\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 23\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 24\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 25\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 26\n" -" 1\n" -" F8\n" -" \n" -" \n" -" newParam1\n" -" 27\n" -" 1\n" -" F8\n" -" \n" -" \n" -" newParam2\n" -" 28\n" -" 1\n" -" F8\n" -" \n" -" \n" -" \n" -" \n" -" 1\n" -" IAZ=F4;\n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" 2\n" -" Gain=F4;Phase=F4;\n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" AddedSupportArray\n" -" F4\n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" XUnits\n" -" YUnits\n" -" ZUnits\n" -" Additional parameter\n" -" Additional parameter\n" -" \n" -" \n" -" \n" -" 1\n" -" \n" -" codPolynomial1\n" -" \n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" 1\n" -" \n" -" dwellPolynomial1\n" -" \n" -" 0.000000000000000E00\n" -" 2.000000000000000E00\n" -" 3.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" 3.500000000000000E00\n" -" \n" -" \n" -" 1.500000000000000E00\n" -" 2.500000000000000E00\n" -" 4.000000000000000E00\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 2.300000000000000E01\n" -" 2.500000000000000E01\n" -" \n" -" \n" -" 1.000000000000000E01\n" -" 1.000000000000000E01\n" -" 1.000000000000000E01\n" -" \n" -" \n" -" 1.000000000000000E01\n" -" 1.000000000000000E01\n" -" 1.000000000000000E01\n" -" \n" -" L\n" -" 2.000000000000000E01\n" -" 2.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" \n" -" \n" -" \n" -" 2\n" -" 1\n" -" 1\n" -" \n" -" ACF1\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" 3.000000000000000E00\n" -" 4.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" 3.000000000000000E00\n" -" 4.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 0.000000000000000E00\n" -" 3.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" ACF2\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" APC\n" -" ACF1\n" -" \n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" APAT\n" -" 2.300000000000000E00\n" -" 2.300000000000000E00\n" -" 1\n" -" 0\n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" 5.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" 2.300000000000000E00\n" -" Parameter1\n" -" Parameter2\n" -" \n" -" \n" -" 2.800000000000000E00\n" -" Parameter1\n" -" Parameter2\n" -" \n" -" \n" -" \n" -" \n" -" 1\n" -" \n" -" TxWFParam\n" -" 3.000000000000000E00\n" -" 2.300000000000000E00\n" -" 1.800000000000000E00\n" -" 1.000000000000000E00\n" -" LHC\n" -" 5.000000000000000E00\n" -" \n" -" 2\n" -" \n" -" RcvParam1\n" -" 3.000000000000000E00\n" -" 2.300000000000000E00\n" -" 2.300000000000000E00\n" -" 1.800000000000000E00\n" -" 1.000000000000000E00\n" -" LHC\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" RcvParam2\n" -" 3.000000000000000E00\n" -" 2.300000000000000E00\n" -" 2.300000000000000E00\n" -" 1.800000000000000E00\n" -" 1.000000000000000E00\n" -" LHC\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" ECF\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E-01\n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" Profile\n" -" \n" -" Application\n" -" 2014-04-10T08:52:09.000000Z\n" -" Area51\n" -" Value1\n" -" Value2\n" -" \n" -" Value1\n" -" \n" -" \n" -" 51\n" -" \n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E-01\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E-01\n" -" 1.000000000000000E-01\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 04/22\n" -" \n" -" \n" -" 2.000000000000000E-02\n" -" 3.000000000000000E-02\n" -" \n" -" \n" -" 8.000000000000000E-02\n" -" 8.000000000000000E-02\n" -" \n" -" \n" -" \n" -" \n" -" 09/27\n" -" \n" -" \n" -" 5.000000000000000E-02\n" -" 2.000000000000000E-02\n" -" \n" -" \n" -" 5.000000000000000E-02\n" -" 8.000000000000000E-02\n" -" \n" -" \n" -" \n" -" \n" -" Main\n" -" \n" -" 6.000000000000000E-01\n" -" 4.000000000000000E-01\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" 1.100000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" 1.100000000000000E00\n" -" 1.100000000000000E00\n" -" \n" -" \n" -" 1.200000000000000E00\n" -" 1.200000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 2\n" -" \n" -" STEREO\n" -" 1\n" -" 1\n" -" \n" -" CollectionName\n" -" 1\n" -" Match1\n" -" \n" -" \n" -" \n" -" COHERENT\n" -" 1\n" -" 1\n" -" \n" -" CollectionName\n" -" 1\n" -" Match1\n" -" \n" -" \n" -" \n" -"\n"; - -TEST_CASE(testOptional) -{ - io::StringStream cphdStream; - cphdStream.write(test_cphd_xml_optional_XML, strlen(test_cphd_xml_optional_XML)); - - xml::lite::MinidomParser xmlParser; - xmlParser.preserveCharacterData(true); - xmlParser.parse(cphdStream, cphdStream.available()); - const std::unique_ptr metadata = - cphd::CPHDXMLControl().fromXML(xmlParser.getDocument()); - - const cphd::SupportArray& supportArray = *(metadata->supportArray); - TEST_ASSERT_EQ(supportArray.iazArray.size(), static_cast(1)); - TEST_ASSERT_EQ(supportArray.iazArray[0].getIdentifier(), static_cast(1)); - TEST_ASSERT_EQ(supportArray.iazArray[0].elementFormat, "IAZ=F4;"); - TEST_ASSERT_EQ(supportArray.iazArray[0].x0, 0.0); - TEST_ASSERT_EQ(supportArray.iazArray[0].y0, 0.0); - TEST_ASSERT_EQ(supportArray.iazArray[0].xSS, 5.0); - TEST_ASSERT_EQ(supportArray.iazArray[0].ySS, 5.0); - - TEST_ASSERT_EQ(supportArray.antGainPhase.size(), static_cast(1)); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].getIdentifier(), static_cast(2)); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].elementFormat, "Gain=F4;Phase=F4;"); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].x0, 0.0); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].y0, 0.0); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].xSS, 5.0); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].ySS, 5.0); - - TEST_ASSERT_EQ(supportArray.addedSupportArray.size(), static_cast(1)); - TEST_ASSERT_EQ(supportArray.addedSupportArray.count("AddedSupportArray"), static_cast(1)); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.elementFormat, "F4"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.x0, 0.0); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.y0, 0.0); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.xSS, 5.0); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.ySS, 5.0); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.xUnits, "XUnits"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.yUnits, "YUnits"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.zUnits, "ZUnits"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter.size(), static_cast(2)); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[0].getName(), "Parameter1"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[1].getName(), "Parameter2"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[0].str(), "Additional parameter"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[1].str(), "Additional parameter"); - - const cphd::Antenna& antenna = *(metadata->antenna); - TEST_ASSERT_EQ(antenna.antCoordFrame.size(), static_cast(2)); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].identifier, "ACF1"); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.order(), static_cast(3)); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][0], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][0], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][0], 3); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][0], 4); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][1], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][1], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][1], 3); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][1], 4); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][2], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][2], 0); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][2], 3); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][2], 0); - - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[0][0], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[1][0], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[0][1], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[1][1], 2); - - TEST_ASSERT_EQ(antenna.antCoordFrame[1].identifier, "ACF2"); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[0][0], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[1][0], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[0][1], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[1][1], 2); - - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[0][0], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[1][0], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[0][1], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[1][1], 2); - - TEST_ASSERT_EQ(antenna.antPhaseCenter.size(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].identifier, "APC"); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].acfId, "ACF1"); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[0], 5.0); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[1], 5.0); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[2], 5.0); - - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].identifier, "APC"); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].acfId, "ACF1"); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[0], 5.0); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[1], 5.0); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[2], 5.0); - - TEST_ASSERT_EQ(antenna.antPattern.size(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].identifier, "APAT"); - TEST_ASSERT_EQ(antenna.antPattern[0].freqZero, 2.3); - TEST_ASSERT_EQ(antenna.antPattern[0].gainZero, 2.3); - TEST_ASSERT_EQ(antenna.antPattern[0].ebFreqShift, 1); - TEST_ASSERT_EQ(antenna.antPattern[0].mlFreqDilation, 0); - TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.coeffs()[0], 1.0); - TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.coeffs()[1], 2.0); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcxPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcxPoly.coeffs()[0], 5.0); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.coeffs()[0], 0.0); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.coeffs()[1], 5.0); - TEST_ASSERT_EQ(antenna.antPattern[0].array.gainPoly.orderX(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].array.gainPoly.orderY(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].array.phasePoly.orderX(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].array.phasePoly.orderY(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].element.gainPoly.orderX(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].element.gainPoly.orderY(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].element.phasePoly.orderX(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].element.phasePoly.orderY(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].freq, 2.3); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].arrayId, "Parameter1"); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].elementId, "Parameter2"); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].freq, 2.8); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].arrayId, "Parameter1"); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].elementId, "Parameter2"); - - const cphd::TxRcv& txRcv = *(metadata->txRcv); - TEST_ASSERT_EQ(txRcv.txWFParameters.size(), static_cast(1)); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].identifier, "TxWFParam"); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].pulseLength, 3.0); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].rfBandwidth, 2.3); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].freqCenter, 1.8); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].lfmRate, 1.0); - TEST_ASSERT(txRcv.txWFParameters[0].polarization.toString() == "LHC"); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].polarization, cphd::PolarizationType::LHC); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].power, 5.0); - - TEST_ASSERT_EQ(txRcv.rcvParameters.size(), static_cast(2)); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].identifier, "RcvParam1"); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].windowLength, 3.0); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].sampleRate, 2.3); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].ifFilterBW, 2.3); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].freqCenter, 1.8); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].lfmRate, 1.0); - TEST_ASSERT(txRcv.rcvParameters[0].polarization.toString() == "LHC"); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].polarization, cphd::PolarizationType::LHC); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].pathGain, 5.0); - - TEST_ASSERT_EQ(txRcv.rcvParameters[1].identifier, "RcvParam2"); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].windowLength, 3.0); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].sampleRate, 2.3); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].ifFilterBW, 2.3); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].freqCenter, 1.8); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].lfmRate, 1.0); - TEST_ASSERT(txRcv.rcvParameters[1].polarization.toString() == "LHC"); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].polarization, cphd::PolarizationType::LHC); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].pathGain, 5.0); - - const cphd::ErrorParameters& errorParams = *(metadata->errorParameters); - TEST_ASSERT(errorParams.monostatic->posVelErr.frame == "ECF"); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.frame, six::FrameType(six::FrameType::ECF)); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.p1, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.p2, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.corrCoefs->p1p2, 0.8); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.corrCoefs->v2v3, 0.8); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->posVelErr.positionDecorr).corrCoefZero, 0.5); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->posVelErr.positionDecorr).decorrRate, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBias, 0.5); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.clockFreqSF, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.collectionStartTime, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero, 0.5); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBiasDecorr->decorrRate, 1.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->tropoError->tropoRangeVertical), 5.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->tropoError->tropoRangeSlant), 5.0); - const auto& tropoRangeDecorr = value(errorParams.monostatic->tropoError->tropoRangeDecorr); - TEST_ASSERT_EQ(tropoRangeDecorr.corrCoefZero, 0.5); - TEST_ASSERT_EQ(tropoRangeDecorr.decorrRate, 1.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRangeVertical), 5.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRangeRateVertical), 5.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRgRgRateCC), 0.5); - const auto& ionoRangeVertDecorr = six::value(errorParams.monostatic->ionoError->ionoRangeVertDecorr); - TEST_ASSERT_EQ(ionoRangeVertDecorr.corrCoefZero, 0.5); - TEST_ASSERT_EQ(ionoRangeVertDecorr.decorrRate, 1.0); - - const cphd::ProductInfo& productInfo = *(metadata->productInfo); - TEST_ASSERT_EQ(productInfo.profile, "Profile"); - TEST_ASSERT_EQ(productInfo.creationInfo[0].application, "Application"); - TEST_ASSERT_EQ(productInfo.creationInfo[0].dateTime.getYear(), 2014); - TEST_ASSERT_EQ(productInfo.creationInfo[0].site, "Area51"); - TEST_ASSERT_EQ(productInfo.creationInfo[0].parameter[0].getName(), "Param1"); - TEST_ASSERT_EQ(productInfo.creationInfo[0].parameter[1].getName(), "Param2"); - TEST_ASSERT_EQ(productInfo.parameter[0].getName(), "Param1"); - - std::vector geoInfo = metadata->geoInfo; - TEST_ASSERT_EQ(geoInfo[0].name, "Airport"); - TEST_ASSERT_EQ(geoInfo[0].desc[0].getName(), "Airport ID"); - TEST_ASSERT_EQ(geoInfo[0].desc[0].str(), "51"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->name, "Perimeter"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon.size(), static_cast(4)); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[0].getLat(), 0.0); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[0].getLon(), 0.0); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[1].getLat(), 0.1); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[1].getLon(), 0.0); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[2].getLat(), 0.1); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[2].getLon(), 0.1); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[3].getLat(), 0.0); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[3].getLon(), 0.0); - - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->name, "Runway"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->desc[0].getName(), "ID"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->desc[0].str(), "04/22"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon.size(), static_cast(2)); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[0].getLat(), 0.02); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[0].getLon(), 0.03); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[1].getLat(), 0.08); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[1].getLon(), 0.08); - - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->name, "Control Tower"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->desc[0].getName(), "ID"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->desc[0].str(), "Main"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->geometryLatLon[0].getLat(), 0.6); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->geometryLatLon[0].getLon(), 0.4); - - TEST_ASSERT_EQ(geoInfo[1].name, "Farm"); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon.size(), static_cast(5)); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[0].getLat(), 1.0); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[0].getLon(), 1.0); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[1].getLat(), 1.1); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[1].getLon(), 1.0); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[4].getLat(), 1.0); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[4].getLon(), 1.0); - - const cphd::MatchInformation& matchInfo = *(metadata->matchInfo); - TEST_ASSERT_EQ(matchInfo.types.size(), static_cast(2)); - TEST_ASSERT_EQ(matchInfo.types[0].typeID, "STEREO"); - TEST_ASSERT_EQ(matchInfo.types[0].currentIndex, 1); - TEST_ASSERT_EQ(matchInfo.types[0].matchCollects.size(), static_cast(1)); - TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].coreName, "CollectionName"); - TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].matchIndex, 1); - TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].parameters[0].getName(), "param1"); - TEST_ASSERT_EQ(matchInfo.types[1].typeID, "COHERENT"); - TEST_ASSERT_EQ(matchInfo.types[1].currentIndex, 1); - TEST_ASSERT_EQ(matchInfo.types[1].matchCollects.size(), static_cast(1)); - TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].coreName, "CollectionName"); - TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].matchIndex, 1); - TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].parameters[0].getName(), "param1"); -} - -TEST_MAIN( - TEST_CHECK(testOptional); +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "TestCase.h" + +const char* test_cphd_xml_optional_XML = +"\n" +" \n" +" Collector\n" +" Core\n" +" MONOSTATIC\n" +" \n" +" STRIPMAP\n" +" Mode\n" +" \n" +" U\n" +" Release\n" +" US,GB,AZ\n" +" val\n" +" \n" +" \n" +" FX\n" +" +1\n" +" \n" +" 2013-04-10T08:52:09.000000Z\n" +" 2014-04-10T08:52:09.000000Z\n" +" 1.300000000000000E00\n" +" 1.500000000000000E00\n" +" \n" +" \n" +" 9.000000000000000E-01\n" +" 1.700000000000000E00\n" +" \n" +" \n" +" 3.400000000000000E00\n" +" 6.100000000000000E00\n" +" \n" +" \n" +" 6.520000000000000E01\n" +" IARP\n" +" \n" +" \n" +" 5.800000000000000E00\n" +" 3.000000000000000E00\n" +" \n" +" \n" +" \n" +" WGS_84\n" +" \n" +" \n" +" 1.200000000000000E00\n" +" 2.300000000000000E00\n" +" 3.400000000000000E00\n" +" \n" +" \n" +" 4.500000000000000E01\n" +" -1.020000000000000E02\n" +" 3.400000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 1.200000000000000E01\n" +" 2.400000000000000E01\n" +" \n" +" \n" +" 3.600000000000000E01\n" +" 4.800000000000000E01\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 3.500000000000000E00\n" +" 5.300000000000000E00\n" +" \n" +" \n" +" 5.300000000000000E00\n" +" 3.500000000000000E00\n" +" \n" +" \n" +" \n" +" 1.000000000000000E-01\n" +" 3.000000000000000E-01\n" +" \n" +" \n" +" 4.000000000000000E-01\n" +" 2.000000000000000E-01\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 9.000000000000000E-01\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E01\n" +" 1.100000000000000E01\n" +" \n" +" \n" +" 2.000000000000000E01\n" +" 2.100000000000000E01\n" +" \n" +" \n" +" 3.000000000000000E01\n" +" 3.100000000000000E01\n" +" \n" +" \n" +" 4.000000000000000E01\n" +" 4.100000000000000E01\n" +" \n" +" \n" +" \n" +" Grid\n" +" \n" +" 1.230000000000000E00\n" +" 3.210000000000000E00\n" +" \n" +" \n" +" 3.140000000000000E00\n" +" 4\n" +" 50\n" +" \n" +" \n" +" 6.280000000000000E00\n" +" 8\n" +" 100\n" +" \n" +" \n" +" 2\n" +" \n" +" Segment1\n" +" 0\n" +" 1\n" +" 2\n" +" 3\n" +" \n" +" \n" +" 4.000000000000000E-01\n" +" 6.000000000000000E-01\n" +" \n" +" \n" +" 8.000000000000000E-01\n" +" 1.200000000000000E00\n" +" \n" +" \n" +" 1.200000000000000E00\n" +" 1.800000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" Segment2\n" +" 1\n" +" 2\n" +" 3\n" +" 4\n" +" \n" +" \n" +" 4.000000000000000E-01\n" +" 6.000000000000000E-01\n" +" \n" +" \n" +" 8.000000000000000E-01\n" +" 1.200000000000000E00\n" +" \n" +" \n" +" 1.200000000000000E00\n" +" 1.800000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" CI4\n" +" 24\n" +" 2\n" +" Compress\n" +" \n" +" Channel\n" +" 2\n" +" 3\n" +" 0\n" +" 1\n" +" 3\n" +" \n" +" \n" +" Channel\n" +" 2\n" +" 3\n" +" 0\n" +" 1\n" +" 3\n" +" \n" +" 3\n" +" \n" +" 1.0\n" +" 3\n" +" 4\n" +" 8\n" +" 0\n" +" \n" +" \n" +" 2.0\n" +" 3\n" +" 4\n" +" 4\n" +" 96\n" +" \n" +" \n" +" AddedSupportArray\n" +" 3\n" +" 4\n" +" 4\n" +" 144\n" +" \n" +" \n" +" \n" +" ChId\n" +" true\n" +" false\n" +" true\n" +" \n" +" CPI\n" +" 1\n" +" false\n" +" true\n" +" true\n" +" false\n" +" \n" +" X\n" +" RHC\n" +" \n" +" 1.300000000000000E00\n" +" 8.000000000000000E-01\n" +" 5.000000000000000E-01\n" +" 2.700000000000000E00\n" +" \n" +" 1.000000000000000E00\n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" CODPolynomial\n" +" DwellPolynomial\n" +" \n" +" \n" +" \n" +" 3.500000000000000E00\n" +" 5.300000000000000E00\n" +" \n" +" \n" +" 5.300000000000000E00\n" +" 3.500000000000000E00\n" +" \n" +" \n" +" \n" +" 1.000000000000000E-01\n" +" 3.000000000000000E-01\n" +" \n" +" \n" +" 4.000000000000000E-01\n" +" 2.000000000000000E-01\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 9.000000000000000E-01\n" +" \n" +" \n" +" \n" +" \n" +" TxAPCId\n" +" TxAPATId\n" +" RcvAPCId\n" +" RcvAPATId\n" +" \n" +" \n" +" TxWFId\n" +" RcvId\n" +" \n" +" \n" +" 1.200000000000000E01\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" \n" +" \n" +" 3.000000000000000E-01\n" +" 2.700000000000000E00\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 2.700000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" Param\n" +" Param\n" +" \n" +" \n" +" \n" +" \n" +" 0\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 1\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 4\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 7\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 8\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 11\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 14\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 17\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 18\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 19\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 20\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 21\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 22\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 23\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 24\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 25\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 26\n" +" 1\n" +" F8\n" +" \n" +" \n" +" newParam1\n" +" 27\n" +" 1\n" +" F8\n" +" \n" +" \n" +" newParam2\n" +" 28\n" +" 1\n" +" F8\n" +" \n" +" \n" +" \n" +" \n" +" 1\n" +" IAZ=F4;\n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" 2\n" +" Gain=F4;Phase=F4;\n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" AddedSupportArray\n" +" F4\n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" XUnits\n" +" YUnits\n" +" ZUnits\n" +" Additional parameter\n" +" Additional parameter\n" +" \n" +" \n" +" \n" +" 1\n" +" \n" +" codPolynomial1\n" +" \n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" 1\n" +" \n" +" dwellPolynomial1\n" +" \n" +" 0.000000000000000E00\n" +" 2.000000000000000E00\n" +" 3.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" 3.500000000000000E00\n" +" \n" +" \n" +" 1.500000000000000E00\n" +" 2.500000000000000E00\n" +" 4.000000000000000E00\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 2.300000000000000E01\n" +" 2.500000000000000E01\n" +" \n" +" \n" +" 1.000000000000000E01\n" +" 1.000000000000000E01\n" +" 1.000000000000000E01\n" +" \n" +" \n" +" 1.000000000000000E01\n" +" 1.000000000000000E01\n" +" 1.000000000000000E01\n" +" \n" +" L\n" +" 2.000000000000000E01\n" +" 2.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" \n" +" \n" +" \n" +" 2\n" +" 1\n" +" 1\n" +" \n" +" ACF1\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" 3.000000000000000E00\n" +" 4.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" 3.000000000000000E00\n" +" 4.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 0.000000000000000E00\n" +" 3.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" ACF2\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" APC\n" +" ACF1\n" +" \n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" APAT\n" +" 2.300000000000000E00\n" +" 2.300000000000000E00\n" +" 1\n" +" 0\n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" 5.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" 2.300000000000000E00\n" +" Parameter1\n" +" Parameter2\n" +" \n" +" \n" +" 2.800000000000000E00\n" +" Parameter1\n" +" Parameter2\n" +" \n" +" \n" +" \n" +" \n" +" 1\n" +" \n" +" TxWFParam\n" +" 3.000000000000000E00\n" +" 2.300000000000000E00\n" +" 1.800000000000000E00\n" +" 1.000000000000000E00\n" +" LHC\n" +" 5.000000000000000E00\n" +" \n" +" 2\n" +" \n" +" RcvParam1\n" +" 3.000000000000000E00\n" +" 2.300000000000000E00\n" +" 2.300000000000000E00\n" +" 1.800000000000000E00\n" +" 1.000000000000000E00\n" +" LHC\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" RcvParam2\n" +" 3.000000000000000E00\n" +" 2.300000000000000E00\n" +" 2.300000000000000E00\n" +" 1.800000000000000E00\n" +" 1.000000000000000E00\n" +" LHC\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" ECF\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E-01\n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" Profile\n" +" \n" +" Application\n" +" 2014-04-10T08:52:09.000000Z\n" +" Area51\n" +" Value1\n" +" Value2\n" +" \n" +" Value1\n" +" \n" +" \n" +" 51\n" +" \n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E-01\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E-01\n" +" 1.000000000000000E-01\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 04/22\n" +" \n" +" \n" +" 2.000000000000000E-02\n" +" 3.000000000000000E-02\n" +" \n" +" \n" +" 8.000000000000000E-02\n" +" 8.000000000000000E-02\n" +" \n" +" \n" +" \n" +" \n" +" 09/27\n" +" \n" +" \n" +" 5.000000000000000E-02\n" +" 2.000000000000000E-02\n" +" \n" +" \n" +" 5.000000000000000E-02\n" +" 8.000000000000000E-02\n" +" \n" +" \n" +" \n" +" \n" +" Main\n" +" \n" +" 6.000000000000000E-01\n" +" 4.000000000000000E-01\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" 1.100000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" 1.100000000000000E00\n" +" 1.100000000000000E00\n" +" \n" +" \n" +" 1.200000000000000E00\n" +" 1.200000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 2\n" +" \n" +" STEREO\n" +" 1\n" +" 1\n" +" \n" +" CollectionName\n" +" 1\n" +" Match1\n" +" \n" +" \n" +" \n" +" COHERENT\n" +" 1\n" +" 1\n" +" \n" +" CollectionName\n" +" 1\n" +" Match1\n" +" \n" +" \n" +" \n" +"\n"; + +TEST_CASE(testOptional) +{ + io::StringStream cphdStream; + cphdStream.write(test_cphd_xml_optional_XML, strlen(test_cphd_xml_optional_XML)); + + xml::lite::MinidomParser xmlParser; + xmlParser.preserveCharacterData(true); + xmlParser.parse(cphdStream, cphdStream.available()); + const std::unique_ptr metadata = + cphd::CPHDXMLControl().fromXML(xmlParser.getDocument()); + + const cphd::SupportArray& supportArray = *(metadata->supportArray); + TEST_ASSERT_EQ(supportArray.iazArray.size(), static_cast(1)); + TEST_ASSERT_EQ(supportArray.iazArray[0].getIdentifier(), static_cast(1)); + TEST_ASSERT_EQ(supportArray.iazArray[0].elementFormat, "IAZ=F4;"); + TEST_ASSERT_EQ(supportArray.iazArray[0].x0, 0.0); + TEST_ASSERT_EQ(supportArray.iazArray[0].y0, 0.0); + TEST_ASSERT_EQ(supportArray.iazArray[0].xSS, 5.0); + TEST_ASSERT_EQ(supportArray.iazArray[0].ySS, 5.0); + + TEST_ASSERT_EQ(supportArray.antGainPhase.size(), static_cast(1)); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].getIdentifier(), static_cast(2)); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].elementFormat, "Gain=F4;Phase=F4;"); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].x0, 0.0); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].y0, 0.0); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].xSS, 5.0); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].ySS, 5.0); + + TEST_ASSERT_EQ(supportArray.addedSupportArray.size(), static_cast(1)); + TEST_ASSERT_EQ(supportArray.addedSupportArray.count("AddedSupportArray"), static_cast(1)); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.elementFormat, "F4"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.x0, 0.0); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.y0, 0.0); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.xSS, 5.0); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.ySS, 5.0); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.xUnits, "XUnits"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.yUnits, "YUnits"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.zUnits, "ZUnits"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter.size(), static_cast(2)); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[0].getName(), "Parameter1"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[1].getName(), "Parameter2"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[0].str(), "Additional parameter"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[1].str(), "Additional parameter"); + + const cphd::Antenna& antenna = *(metadata->antenna); + TEST_ASSERT_EQ(antenna.antCoordFrame.size(), static_cast(2)); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].identifier, "ACF1"); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.order(), static_cast(3)); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][0], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][0], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][0], 3); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][0], 4); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][1], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][1], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][1], 3); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][1], 4); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][2], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][2], 0); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][2], 3); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][2], 0); + + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[0][0], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[1][0], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[0][1], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[1][1], 2); + + TEST_ASSERT_EQ(antenna.antCoordFrame[1].identifier, "ACF2"); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[0][0], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[1][0], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[0][1], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[1][1], 2); + + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[0][0], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[1][0], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[0][1], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[1][1], 2); + + TEST_ASSERT_EQ(antenna.antPhaseCenter.size(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].identifier, "APC"); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].acfId, "ACF1"); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[0], 5.0); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[1], 5.0); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[2], 5.0); + + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].identifier, "APC"); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].acfId, "ACF1"); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[0], 5.0); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[1], 5.0); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[2], 5.0); + + TEST_ASSERT_EQ(antenna.antPattern.size(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].identifier, "APAT"); + TEST_ASSERT_EQ(antenna.antPattern[0].freqZero, 2.3); + TEST_ASSERT_EQ(antenna.antPattern[0].gainZero, 2.3); + TEST_ASSERT_EQ(antenna.antPattern[0].ebFreqShift, 1); + TEST_ASSERT_EQ(antenna.antPattern[0].mlFreqDilation, 0); + TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.coeffs()[0], 1.0); + TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.coeffs()[1], 2.0); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcxPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcxPoly.coeffs()[0], 5.0); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.coeffs()[0], 0.0); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.coeffs()[1], 5.0); + TEST_ASSERT_EQ(antenna.antPattern[0].array.gainPoly.orderX(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].array.gainPoly.orderY(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].array.phasePoly.orderX(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].array.phasePoly.orderY(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].element.gainPoly.orderX(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].element.gainPoly.orderY(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].element.phasePoly.orderX(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].element.phasePoly.orderY(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].freq, 2.3); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].arrayId, "Parameter1"); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].elementId, "Parameter2"); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].freq, 2.8); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].arrayId, "Parameter1"); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].elementId, "Parameter2"); + + const cphd::TxRcv& txRcv = *(metadata->txRcv); + TEST_ASSERT_EQ(txRcv.txWFParameters.size(), static_cast(1)); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].identifier, "TxWFParam"); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].pulseLength, 3.0); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].rfBandwidth, 2.3); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].freqCenter, 1.8); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].lfmRate, 1.0); + TEST_ASSERT(txRcv.txWFParameters[0].polarization.toString() == "LHC"); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].polarization, cphd::PolarizationType::LHC); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].power, 5.0); + + TEST_ASSERT_EQ(txRcv.rcvParameters.size(), static_cast(2)); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].identifier, "RcvParam1"); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].windowLength, 3.0); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].sampleRate, 2.3); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].ifFilterBW, 2.3); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].freqCenter, 1.8); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].lfmRate, 1.0); + TEST_ASSERT(txRcv.rcvParameters[0].polarization.toString() == "LHC"); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].polarization, cphd::PolarizationType::LHC); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].pathGain, 5.0); + + TEST_ASSERT_EQ(txRcv.rcvParameters[1].identifier, "RcvParam2"); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].windowLength, 3.0); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].sampleRate, 2.3); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].ifFilterBW, 2.3); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].freqCenter, 1.8); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].lfmRate, 1.0); + TEST_ASSERT(txRcv.rcvParameters[1].polarization.toString() == "LHC"); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].polarization, cphd::PolarizationType::LHC); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].pathGain, 5.0); + + const cphd::ErrorParameters& errorParams = *(metadata->errorParameters); + TEST_ASSERT(errorParams.monostatic->posVelErr.frame == "ECF"); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.frame, six::FrameType(six::FrameType::ECF)); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.p1, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.p2, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.corrCoefs->p1p2, 0.8); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.corrCoefs->v2v3, 0.8); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->posVelErr.positionDecorr).corrCoefZero, 0.5); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->posVelErr.positionDecorr).decorrRate, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBias, 0.5); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.clockFreqSF, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.collectionStartTime, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero, 0.5); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBiasDecorr->decorrRate, 1.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->tropoError->tropoRangeVertical), 5.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->tropoError->tropoRangeSlant), 5.0); + const auto& tropoRangeDecorr = value(errorParams.monostatic->tropoError->tropoRangeDecorr); + TEST_ASSERT_EQ(tropoRangeDecorr.corrCoefZero, 0.5); + TEST_ASSERT_EQ(tropoRangeDecorr.decorrRate, 1.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRangeVertical), 5.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRangeRateVertical), 5.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRgRgRateCC), 0.5); + const auto& ionoRangeVertDecorr = six::value(errorParams.monostatic->ionoError->ionoRangeVertDecorr); + TEST_ASSERT_EQ(ionoRangeVertDecorr.corrCoefZero, 0.5); + TEST_ASSERT_EQ(ionoRangeVertDecorr.decorrRate, 1.0); + + const cphd::ProductInfo& productInfo = *(metadata->productInfo); + TEST_ASSERT_EQ(productInfo.profile, "Profile"); + TEST_ASSERT_EQ(productInfo.creationInfo[0].application, "Application"); + TEST_ASSERT_EQ(productInfo.creationInfo[0].dateTime.getYear(), 2014); + TEST_ASSERT_EQ(productInfo.creationInfo[0].site, "Area51"); + TEST_ASSERT_EQ(productInfo.creationInfo[0].parameter[0].getName(), "Param1"); + TEST_ASSERT_EQ(productInfo.creationInfo[0].parameter[1].getName(), "Param2"); + TEST_ASSERT_EQ(productInfo.parameter[0].getName(), "Param1"); + + std::vector geoInfo = metadata->geoInfo; + TEST_ASSERT_EQ(geoInfo[0].name, "Airport"); + TEST_ASSERT_EQ(geoInfo[0].desc[0].getName(), "Airport ID"); + TEST_ASSERT_EQ(geoInfo[0].desc[0].str(), "51"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->name, "Perimeter"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon.size(), static_cast(4)); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[0].getLat(), 0.0); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[0].getLon(), 0.0); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[1].getLat(), 0.1); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[1].getLon(), 0.0); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[2].getLat(), 0.1); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[2].getLon(), 0.1); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[3].getLat(), 0.0); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[3].getLon(), 0.0); + + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->name, "Runway"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->desc[0].getName(), "ID"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->desc[0].str(), "04/22"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon.size(), static_cast(2)); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[0].getLat(), 0.02); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[0].getLon(), 0.03); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[1].getLat(), 0.08); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[1].getLon(), 0.08); + + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->name, "Control Tower"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->desc[0].getName(), "ID"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->desc[0].str(), "Main"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->geometryLatLon[0].getLat(), 0.6); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->geometryLatLon[0].getLon(), 0.4); + + TEST_ASSERT_EQ(geoInfo[1].name, "Farm"); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon.size(), static_cast(5)); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[0].getLat(), 1.0); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[0].getLon(), 1.0); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[1].getLat(), 1.1); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[1].getLon(), 1.0); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[4].getLat(), 1.0); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[4].getLon(), 1.0); + + const cphd::MatchInformation& matchInfo = *(metadata->matchInfo); + TEST_ASSERT_EQ(matchInfo.types.size(), static_cast(2)); + TEST_ASSERT_EQ(matchInfo.types[0].typeID, "STEREO"); + TEST_ASSERT_EQ(matchInfo.types[0].currentIndex, 1); + TEST_ASSERT_EQ(matchInfo.types[0].matchCollects.size(), static_cast(1)); + TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].coreName, "CollectionName"); + TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].matchIndex, 1); + TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].parameters[0].getName(), "param1"); + TEST_ASSERT_EQ(matchInfo.types[1].typeID, "COHERENT"); + TEST_ASSERT_EQ(matchInfo.types[1].currentIndex, 1); + TEST_ASSERT_EQ(matchInfo.types[1].matchCollects.size(), static_cast(1)); + TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].coreName, "CollectionName"); + TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].matchIndex, 1); + TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].parameters[0].getName(), "param1"); +} + +TEST_MAIN( + TEST_CHECK(testOptional); ) \ No newline at end of file diff --git a/six/modules/c++/cphd/unittests/test_dwell.cpp b/six/modules/c++/cphd/unittests/test_dwell.cpp index 7651f6b180..0f4dd45c6e 100644 --- a/six/modules/c++/cphd/unittests/test_dwell.cpp +++ b/six/modules/c++/cphd/unittests/test_dwell.cpp @@ -1,120 +1,120 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include - -#include -#include -#include -#include -#include - -#include "TestCase.h" - -TEST_CASE(testDerivativeCODValid) -{ - cphd::Dwell dwell; - cphd::COD cod1; - size_t numCODTimes = 1; - dwell.cod.resize(numCODTimes); - dwell.cod[0] = cod1; - - cphd::Poly2D p2D(1, 1); - dwell.cod[0].codTimePoly = p2D; - dwell.cod[0].codTimePoly[0][0] = 1; - dwell.cod[0].codTimePoly[1][0] = 2; - dwell.cod[0].codTimePoly[0][1] = 3; - dwell.cod[0].codTimePoly[1][1] = 4; - - // Test Derivative in terms of x - cphd::Poly2D derivativeX2D(1,1); - derivativeX2D[0][0] = 2; - derivativeX2D[0][1] = 4; - TEST_ASSERT_EQ(dwell.cod[0].codTimePoly.derivativeX(),derivativeX2D); -} - -TEST_CASE(testDerivativeDwellValid) -{ - cphd::Dwell dwell; - cphd::DwellTime dtime1; - size_t numDwellTimes = 1; - dwell.dtime.resize(numDwellTimes); - dwell.dtime[0] = dtime1; - - cphd::Poly2D p2D(1, 1); - dwell.dtime[0].dwellTimePoly = p2D; - dwell.dtime[0].dwellTimePoly[0][0] = 1; - dwell.dtime[0].dwellTimePoly[1][0] = 2; - dwell.dtime[0].dwellTimePoly[0][1] = 3; - dwell.dtime[0].dwellTimePoly[1][1] = 4; - - // Test Derivative in terms of x - cphd::Poly2D derivativeY2D(1,1); - derivativeY2D[0][0] = 3; - derivativeY2D[1][0] = 4; - TEST_ASSERT_EQ(dwell.dtime[0].dwellTimePoly.derivativeY(),derivativeY2D); -} - - -TEST_CASE(testEquality) -{ - cphd::Dwell dwell; - cphd::DwellTime dtime1, dtime2; - - size_t numDwellTimes = 2; - dwell.dtime.resize(numDwellTimes); - dwell.dtime[0] = dtime1; - dwell.dtime[1] = dtime2; - - cphd:: Poly2D p2D_1(2,1), p2D_2(2,1); - - dwell.dtime[0].dwellTimePoly = p2D_1; - dwell.dtime[1].dwellTimePoly = p2D_2; - for (size_t i = 0; i < dwell.dtime.size(); ++i) { - dwell.dtime[i].dwellTimePoly[0][0] = 1; - dwell.dtime[i].dwellTimePoly[0][1] = 2; - dwell.dtime[i].dwellTimePoly[1][0] = 3; - dwell.dtime[i].dwellTimePoly[1][1] = 4; - dwell.dtime[i].dwellTimePoly[2][0] = 5; - } - - cphd:: Poly2D derivX(1,1); - derivX[0][0] = 3; - derivX[0][1] = 4; - derivX[1][0] = 10; - - // Test identical polynomial vectors - TEST_ASSERT_EQ(dwell.dtime[0].dwellTimePoly.derivativeX(), derivX); - TEST_ASSERT_TRUE((dwell.dtime[0] == dwell.dtime[1])); - - dwell.dtime[1].dwellTimePoly = dwell.dtime[1].dwellTimePoly.flipXY(); - - // Test different polynomial vectors - TEST_ASSERT_NOT_EQ(dwell.dtime[0].dwellTimePoly.derivativeX(), dwell.dtime[1].dwellTimePoly.derivativeX()); - TEST_ASSERT_TRUE((dwell.dtime[0] != dwell.dtime[1])); -} - -TEST_MAIN( - TEST_CHECK(testDerivativeCODValid); - TEST_CHECK(testDerivativeDwellValid); - TEST_CHECK(testEquality); - ) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include + +#include +#include +#include +#include +#include + +#include "TestCase.h" + +TEST_CASE(testDerivativeCODValid) +{ + cphd::Dwell dwell; + cphd::COD cod1; + size_t numCODTimes = 1; + dwell.cod.resize(numCODTimes); + dwell.cod[0] = cod1; + + cphd::Poly2D p2D(1, 1); + dwell.cod[0].codTimePoly = p2D; + dwell.cod[0].codTimePoly[0][0] = 1; + dwell.cod[0].codTimePoly[1][0] = 2; + dwell.cod[0].codTimePoly[0][1] = 3; + dwell.cod[0].codTimePoly[1][1] = 4; + + // Test Derivative in terms of x + cphd::Poly2D derivativeX2D(1,1); + derivativeX2D[0][0] = 2; + derivativeX2D[0][1] = 4; + TEST_ASSERT_EQ(dwell.cod[0].codTimePoly.derivativeX(),derivativeX2D); +} + +TEST_CASE(testDerivativeDwellValid) +{ + cphd::Dwell dwell; + cphd::DwellTime dtime1; + size_t numDwellTimes = 1; + dwell.dtime.resize(numDwellTimes); + dwell.dtime[0] = dtime1; + + cphd::Poly2D p2D(1, 1); + dwell.dtime[0].dwellTimePoly = p2D; + dwell.dtime[0].dwellTimePoly[0][0] = 1; + dwell.dtime[0].dwellTimePoly[1][0] = 2; + dwell.dtime[0].dwellTimePoly[0][1] = 3; + dwell.dtime[0].dwellTimePoly[1][1] = 4; + + // Test Derivative in terms of x + cphd::Poly2D derivativeY2D(1,1); + derivativeY2D[0][0] = 3; + derivativeY2D[1][0] = 4; + TEST_ASSERT_EQ(dwell.dtime[0].dwellTimePoly.derivativeY(),derivativeY2D); +} + + +TEST_CASE(testEquality) +{ + cphd::Dwell dwell; + cphd::DwellTime dtime1, dtime2; + + size_t numDwellTimes = 2; + dwell.dtime.resize(numDwellTimes); + dwell.dtime[0] = dtime1; + dwell.dtime[1] = dtime2; + + cphd:: Poly2D p2D_1(2,1), p2D_2(2,1); + + dwell.dtime[0].dwellTimePoly = p2D_1; + dwell.dtime[1].dwellTimePoly = p2D_2; + for (size_t i = 0; i < dwell.dtime.size(); ++i) { + dwell.dtime[i].dwellTimePoly[0][0] = 1; + dwell.dtime[i].dwellTimePoly[0][1] = 2; + dwell.dtime[i].dwellTimePoly[1][0] = 3; + dwell.dtime[i].dwellTimePoly[1][1] = 4; + dwell.dtime[i].dwellTimePoly[2][0] = 5; + } + + cphd:: Poly2D derivX(1,1); + derivX[0][0] = 3; + derivX[0][1] = 4; + derivX[1][0] = 10; + + // Test identical polynomial vectors + TEST_ASSERT_EQ(dwell.dtime[0].dwellTimePoly.derivativeX(), derivX); + TEST_ASSERT_TRUE((dwell.dtime[0] == dwell.dtime[1])); + + dwell.dtime[1].dwellTimePoly = dwell.dtime[1].dwellTimePoly.flipXY(); + + // Test different polynomial vectors + TEST_ASSERT_NOT_EQ(dwell.dtime[0].dwellTimePoly.derivativeX(), dwell.dtime[1].dwellTimePoly.derivativeX()); + TEST_ASSERT_TRUE((dwell.dtime[0] != dwell.dtime[1])); +} + +TEST_MAIN( + TEST_CHECK(testDerivativeCODValid); + TEST_CHECK(testDerivativeDwellValid); + TEST_CHECK(testEquality); + ) diff --git a/six/modules/c++/cphd/unittests/test_pvp.cpp b/six/modules/c++/cphd/unittests/test_pvp.cpp index fe498fb10f..79a4128b7f 100644 --- a/six/modules/c++/cphd/unittests/test_pvp.cpp +++ b/six/modules/c++/cphd/unittests/test_pvp.cpp @@ -1,110 +1,110 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include - -#include -#include - -#include - -#include "TestCase.h" - - -TEST_CASE(testSimpleEqualityOperatorTrue) -{ - cphd::Pvp pvp1, pvp2; - - pvp1.txTime.setOffset(0); - pvp2.txTime.setOffset(0); - - TEST_ASSERT_TRUE((pvp1 == pvp2)); -} - -TEST_CASE(testAppend) -{ - cphd::Pvp pvp; - pvp.append(pvp.txTime); - pvp.append(pvp.txPos); - pvp.append(pvp.txVel); - pvp.append(pvp.ampSF); - pvp.appendCustomParameter(8, "S8", "AddedParam1"); - pvp.append(pvp.signal); - - TEST_ASSERT_TRUE(pvp.txTime.getOffset() == 0); - TEST_ASSERT_TRUE(pvp.txPos.getOffset() == 1); - TEST_ASSERT_TRUE(pvp.txVel.getOffset() == 4); - TEST_ASSERT_TRUE(pvp.ampSF.getOffset() == 7); - TEST_ASSERT_TRUE(pvp.addedPVP["AddedParam1"].getOffset() == 8); - TEST_ASSERT_TRUE(pvp.signal.getOffset() == 16); -} - -TEST_CASE(testAddedParamsEqualityOperatorTrue) -{ - cphd::Pvp pvp1; - pvp1.setCustomParameter(1, 0, "F8", "AddedParam1"); - pvp1.setCustomParameter(1, 1, "F8", "AddedParam2"); - - cphd::Pvp pvp2; - pvp2.setCustomParameter(1, 0, "F8", "AddedParam1"); - pvp2.setCustomParameter(1, 1, "F8", "AddedParam2"); - - TEST_ASSERT_TRUE((pvp1 == pvp2)); -} - - -TEST_CASE(testSimpleEqualityOperatorFalse) -{ - cphd::Pvp pvp1; - pvp1.fxN1.setOffset(0); - - cphd::Pvp pvp2; - pvp2.txTime.setOffset(1); - - TEST_ASSERT_TRUE((pvp1 != pvp2)); - -} - -TEST_CASE(testAddedParamsEqualityOperatorFalse) -{ - cphd::Pvp pvp1; - pvp1.setCustomParameter(1, 0, "F8", "AddedParam1"); - pvp1.setCustomParameter(1, 1, "F8", "AddedParam2"); - - cphd::Pvp pvp2; - pvp2.setCustomParameter(1, 0, "F8", "AddedParam1"); - - cphd::Pvp pvp3; - pvp3.setCustomParameter(1, 0, "F8", "AddedParam1"); - pvp3.setCustomParameter(1, 1, "F8", "AddedParam3"); - - TEST_ASSERT_TRUE((pvp1 != pvp2)); - TEST_ASSERT_TRUE((pvp1 != pvp3)); -} - -TEST_MAIN( - TEST_CHECK(testSimpleEqualityOperatorTrue); - TEST_CHECK(testAppend); - TEST_CHECK(testAddedParamsEqualityOperatorTrue); - TEST_CHECK(testSimpleEqualityOperatorFalse); - TEST_CHECK(testAddedParamsEqualityOperatorFalse); +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include + +#include +#include + +#include + +#include "TestCase.h" + + +TEST_CASE(testSimpleEqualityOperatorTrue) +{ + cphd::Pvp pvp1, pvp2; + + pvp1.txTime.setOffset(0); + pvp2.txTime.setOffset(0); + + TEST_ASSERT_TRUE((pvp1 == pvp2)); +} + +TEST_CASE(testAppend) +{ + cphd::Pvp pvp; + pvp.append(pvp.txTime); + pvp.append(pvp.txPos); + pvp.append(pvp.txVel); + pvp.append(pvp.ampSF); + pvp.appendCustomParameter(8, "S8", "AddedParam1"); + pvp.append(pvp.signal); + + TEST_ASSERT_TRUE(pvp.txTime.getOffset() == 0); + TEST_ASSERT_TRUE(pvp.txPos.getOffset() == 1); + TEST_ASSERT_TRUE(pvp.txVel.getOffset() == 4); + TEST_ASSERT_TRUE(pvp.ampSF.getOffset() == 7); + TEST_ASSERT_TRUE(pvp.addedPVP["AddedParam1"].getOffset() == 8); + TEST_ASSERT_TRUE(pvp.signal.getOffset() == 16); +} + +TEST_CASE(testAddedParamsEqualityOperatorTrue) +{ + cphd::Pvp pvp1; + pvp1.setCustomParameter(1, 0, "F8", "AddedParam1"); + pvp1.setCustomParameter(1, 1, "F8", "AddedParam2"); + + cphd::Pvp pvp2; + pvp2.setCustomParameter(1, 0, "F8", "AddedParam1"); + pvp2.setCustomParameter(1, 1, "F8", "AddedParam2"); + + TEST_ASSERT_TRUE((pvp1 == pvp2)); +} + + +TEST_CASE(testSimpleEqualityOperatorFalse) +{ + cphd::Pvp pvp1; + pvp1.fxN1.setOffset(0); + + cphd::Pvp pvp2; + pvp2.txTime.setOffset(1); + + TEST_ASSERT_TRUE((pvp1 != pvp2)); + +} + +TEST_CASE(testAddedParamsEqualityOperatorFalse) +{ + cphd::Pvp pvp1; + pvp1.setCustomParameter(1, 0, "F8", "AddedParam1"); + pvp1.setCustomParameter(1, 1, "F8", "AddedParam2"); + + cphd::Pvp pvp2; + pvp2.setCustomParameter(1, 0, "F8", "AddedParam1"); + + cphd::Pvp pvp3; + pvp3.setCustomParameter(1, 0, "F8", "AddedParam1"); + pvp3.setCustomParameter(1, 1, "F8", "AddedParam3"); + + TEST_ASSERT_TRUE((pvp1 != pvp2)); + TEST_ASSERT_TRUE((pvp1 != pvp3)); +} + +TEST_MAIN( + TEST_CHECK(testSimpleEqualityOperatorTrue); + TEST_CHECK(testAppend); + TEST_CHECK(testAddedParamsEqualityOperatorTrue); + TEST_CHECK(testSimpleEqualityOperatorFalse); + TEST_CHECK(testAddedParamsEqualityOperatorFalse); ) \ No newline at end of file diff --git a/six/modules/c++/cphd/unittests/test_pvp_block_round.cpp b/six/modules/c++/cphd/unittests/test_pvp_block_round.cpp index 3bb70ad502..93ec99c9c6 100644 --- a/six/modules/c++/cphd/unittests/test_pvp_block_round.cpp +++ b/six/modules/c++/cphd/unittests/test_pvp_block_round.cpp @@ -1,253 +1,253 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -template -auto generateComplexData(size_t length) -{ - using value_type = typename TComplex::value_type; - std::vector data(length); - srand(0); - for (size_t ii = 0; ii < data.size(); ++ii) - { - auto real = static_cast(rand() / 100); - auto imag = static_cast(rand() / 100); - data[ii] = TComplex(real, imag); - } - return data; -} - -void setPVPBlock(const types::RowCol dims, - cphd::PVPBlock& pvpBlock, - bool isAmpSF, - bool isFxN1, - bool isFxN2, - bool isTOAE1, - bool isTOAE2, - bool isSignal, - const std::vector& addedParams) -{ - const size_t numChannels = 1; - const std::vector numVectors(numChannels, dims.row); - - for (size_t ii = 0; ii < numChannels; ++ii) - { - for (size_t jj = 0; jj < numVectors[ii]; ++jj) - { - setVectorParameters(ii, jj, pvpBlock); - - if (isAmpSF) - { - const double ampSF = cphd::getRandom(); - pvpBlock.setAmpSF(ampSF, ii, jj); - } - if (isFxN1) - { - const double fxN1 = cphd::getRandom(); - pvpBlock.setFxN1(fxN1, ii, jj); - } - if (isFxN2) - { - const double fxN2 = cphd::getRandom(); - pvpBlock.setFxN2(fxN2, ii, jj); - } - if (isTOAE1) - { - const double toaE1 = cphd::getRandom(); - pvpBlock.setTOAE1(toaE1, ii, jj); - } - if (isTOAE2) - { - const double toaE2 = cphd::getRandom(); - pvpBlock.setTOAE2(toaE2, ii, jj); - } - if (isSignal) - { - const double signal = cphd::getRandom(); - pvpBlock.setTOAE2(signal, ii, jj); - } - - for (size_t idx = 0; idx < addedParams.size(); ++idx) - { - const double val = cphd::getRandom(); - pvpBlock.setAddedPVP(val, ii, jj, addedParams[idx]); - } - } - } -} - -template -void writeCPHD(const std::string& outPathname, - size_t numThreads, - const types::RowCol dims, - const TCxVector& writeData, - cphd::Metadata& metadata, - cphd::PVPBlock& pvpBlock) -{ - const size_t numChannels = 1; - - cphd::CPHDWriter writer(metadata, - outPathname, - std::vector(), - numThreads); - writer.writeMetadata(pvpBlock); - writer.writePVPData(pvpBlock); - for (size_t ii = 0; ii < numChannels; ++ii) - { - writer.writeCPHDData(writeData.data(), dims.area()); - } -} - -bool checkData(const std::string& pathname, - size_t numThreads, - cphd::Metadata& metadata, - cphd::PVPBlock& pvpBlock) -{ - cphd::CPHDReader reader(pathname, numThreads); - - if (metadata.pvp != reader.getMetadata().pvp) - { - return false; - } - if (pvpBlock != reader.getPVPBlock()) - { - return false; - } - return true; -} - -template -bool runTest(bool /*scale*/, - const TCxVector& writeData, - cphd::Metadata& meta, - cphd::PVPBlock& pvpBlock, - const types::RowCol dims) -{ - io::TempFile tempfile; - const size_t numThreads = std::thread::hardware_concurrency(); - writeCPHD(tempfile.pathname(), numThreads, dims, writeData, meta, pvpBlock); - return checkData(tempfile.pathname(), numThreads, meta, pvpBlock); -} - -TEST_CASE(testPVPBlockSimple) -{ - const types::RowCol dims(128, 256); - const auto writeData = generateComplexData(dims.area()); - const bool scale = false; - cphd::Metadata meta = cphd::Metadata(); - cphd::setUpData(meta, dims, writeData); - cphd::setPVPXML(meta.pvp); - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - std::vector addedParams; - setPVPBlock(dims, - pvpBlock, - false, - false, - false, - false, - false, - false, - addedParams); - - TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); -} - -TEST_CASE(testPVPBlockOptional) -{ - const types::RowCol dims(128, 256); - const auto writeData = generateComplexData(dims.area()); - const bool scale = false; - cphd::Metadata meta = cphd::Metadata(); - cphd::setUpData(meta, dims, writeData); - cphd::setPVPXML(meta.pvp); - meta.pvp.setOffset(27, meta.pvp.fxN1); - meta.pvp.setOffset(28, meta.pvp.fxN2); - meta.data.numBytesPVP += 2 * 8; - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - std::vector addedParams; - setPVPBlock(dims, - pvpBlock, - false, - true, - true, - false, - false, - false, - addedParams); - - TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); -} - -TEST_CASE(testPVPBlockAdditional) -{ - const types::RowCol dims(128, 256); - const auto writeData = generateComplexData(dims.area()); - const bool scale = false; - cphd::Metadata meta = cphd::Metadata(); - cphd::setUpData(meta, dims, writeData); - cphd::setPVPXML(meta.pvp); - meta.pvp.setCustomParameter(1, 27, "F8", "param1"); - meta.pvp.setCustomParameter(1, 28, "F8", "param2"); - meta.data.numBytesPVP += 2 * 8; - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - std::vector addedParams; - addedParams.push_back("param1"); - addedParams.push_back("param2"); - setPVPBlock(dims, - pvpBlock, - false, - false, - false, - false, - false, - false, - addedParams); - - TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); -} - -TEST_MAIN( - TEST_CHECK(testPVPBlockSimple); - TEST_CHECK(testPVPBlockOptional); - TEST_CHECK(testPVPBlockAdditional); - ) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template +auto generateComplexData(size_t length) +{ + using value_type = typename TComplex::value_type; + std::vector data(length); + srand(0); + for (size_t ii = 0; ii < data.size(); ++ii) + { + auto real = static_cast(rand() / 100); + auto imag = static_cast(rand() / 100); + data[ii] = TComplex(real, imag); + } + return data; +} + +void setPVPBlock(const types::RowCol dims, + cphd::PVPBlock& pvpBlock, + bool isAmpSF, + bool isFxN1, + bool isFxN2, + bool isTOAE1, + bool isTOAE2, + bool isSignal, + const std::vector& addedParams) +{ + const size_t numChannels = 1; + const std::vector numVectors(numChannels, dims.row); + + for (size_t ii = 0; ii < numChannels; ++ii) + { + for (size_t jj = 0; jj < numVectors[ii]; ++jj) + { + setVectorParameters(ii, jj, pvpBlock); + + if (isAmpSF) + { + const double ampSF = cphd::getRandom(); + pvpBlock.setAmpSF(ampSF, ii, jj); + } + if (isFxN1) + { + const double fxN1 = cphd::getRandom(); + pvpBlock.setFxN1(fxN1, ii, jj); + } + if (isFxN2) + { + const double fxN2 = cphd::getRandom(); + pvpBlock.setFxN2(fxN2, ii, jj); + } + if (isTOAE1) + { + const double toaE1 = cphd::getRandom(); + pvpBlock.setTOAE1(toaE1, ii, jj); + } + if (isTOAE2) + { + const double toaE2 = cphd::getRandom(); + pvpBlock.setTOAE2(toaE2, ii, jj); + } + if (isSignal) + { + const double signal = cphd::getRandom(); + pvpBlock.setTOAE2(signal, ii, jj); + } + + for (size_t idx = 0; idx < addedParams.size(); ++idx) + { + const double val = cphd::getRandom(); + pvpBlock.setAddedPVP(val, ii, jj, addedParams[idx]); + } + } + } +} + +template +void writeCPHD(const std::string& outPathname, + size_t numThreads, + const types::RowCol dims, + const TCxVector& writeData, + cphd::Metadata& metadata, + cphd::PVPBlock& pvpBlock) +{ + const size_t numChannels = 1; + + cphd::CPHDWriter writer(metadata, + outPathname, + std::vector(), + numThreads); + writer.writeMetadata(pvpBlock); + writer.writePVPData(pvpBlock); + for (size_t ii = 0; ii < numChannels; ++ii) + { + writer.writeCPHDData(writeData.data(), dims.area()); + } +} + +bool checkData(const std::string& pathname, + size_t numThreads, + cphd::Metadata& metadata, + cphd::PVPBlock& pvpBlock) +{ + cphd::CPHDReader reader(pathname, numThreads); + + if (metadata.pvp != reader.getMetadata().pvp) + { + return false; + } + if (pvpBlock != reader.getPVPBlock()) + { + return false; + } + return true; +} + +template +bool runTest(bool /*scale*/, + const TCxVector& writeData, + cphd::Metadata& meta, + cphd::PVPBlock& pvpBlock, + const types::RowCol dims) +{ + io::TempFile tempfile; + const size_t numThreads = std::thread::hardware_concurrency(); + writeCPHD(tempfile.pathname(), numThreads, dims, writeData, meta, pvpBlock); + return checkData(tempfile.pathname(), numThreads, meta, pvpBlock); +} + +TEST_CASE(testPVPBlockSimple) +{ + const types::RowCol dims(128, 256); + const auto writeData = generateComplexData(dims.area()); + const bool scale = false; + cphd::Metadata meta = cphd::Metadata(); + cphd::setUpData(meta, dims, writeData); + cphd::setPVPXML(meta.pvp); + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + std::vector addedParams; + setPVPBlock(dims, + pvpBlock, + false, + false, + false, + false, + false, + false, + addedParams); + + TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); +} + +TEST_CASE(testPVPBlockOptional) +{ + const types::RowCol dims(128, 256); + const auto writeData = generateComplexData(dims.area()); + const bool scale = false; + cphd::Metadata meta = cphd::Metadata(); + cphd::setUpData(meta, dims, writeData); + cphd::setPVPXML(meta.pvp); + meta.pvp.setOffset(27, meta.pvp.fxN1); + meta.pvp.setOffset(28, meta.pvp.fxN2); + meta.data.numBytesPVP += 2 * 8; + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + std::vector addedParams; + setPVPBlock(dims, + pvpBlock, + false, + true, + true, + false, + false, + false, + addedParams); + + TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); +} + +TEST_CASE(testPVPBlockAdditional) +{ + const types::RowCol dims(128, 256); + const auto writeData = generateComplexData(dims.area()); + const bool scale = false; + cphd::Metadata meta = cphd::Metadata(); + cphd::setUpData(meta, dims, writeData); + cphd::setPVPXML(meta.pvp); + meta.pvp.setCustomParameter(1, 27, "F8", "param1"); + meta.pvp.setCustomParameter(1, 28, "F8", "param2"); + meta.data.numBytesPVP += 2 * 8; + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + std::vector addedParams; + addedParams.push_back("param1"); + addedParams.push_back("param2"); + setPVPBlock(dims, + pvpBlock, + false, + false, + false, + false, + false, + false, + addedParams); + + TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); +} + +TEST_MAIN( + TEST_CHECK(testPVPBlockSimple); + TEST_CHECK(testPVPBlockOptional); + TEST_CHECK(testPVPBlockAdditional); + ) diff --git a/six/modules/c++/cphd/unittests/test_reference_geometry.cpp b/six/modules/c++/cphd/unittests/test_reference_geometry.cpp index 28fa51ffe8..f8ad96b91c 100644 --- a/six/modules/c++/cphd/unittests/test_reference_geometry.cpp +++ b/six/modules/c++/cphd/unittests/test_reference_geometry.cpp @@ -1,63 +1,63 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include -#include - -#include -#include -#include -#include - -#include "TestCase.h" - -TEST_CASE(testEquality) -{ - cphd::ReferenceGeometry refGeo; - cphd::ReferenceGeometry refGeoOther; - refGeo.monostatic.reset(new cphd::Monostatic()); - refGeoOther.monostatic.reset(new cphd::Monostatic()); - - // Fill Values - refGeo.monostatic->azimuthAngle = 1.0; - refGeo.monostatic->grazeAngle = 1.0; - refGeo.monostatic->twistAngle = 1.0; - refGeo.monostatic->slopeAngle = 1.0; - refGeo.monostatic->layoverAngle = 1.0; - refGeo.monostatic->sideOfTrack = six::SideOfTrackType::LEFT; - refGeo.monostatic->slantRange = 20.0; - - refGeoOther.monostatic->azimuthAngle = 2.0; - refGeoOther.monostatic->grazeAngle = 2.0; - refGeoOther.monostatic->twistAngle = 2.0; - refGeoOther.monostatic->slopeAngle = 2.0; - refGeoOther.monostatic->layoverAngle = 2.0; - refGeoOther.monostatic->sideOfTrack = six::SideOfTrackType::LEFT; - refGeoOther.monostatic->slantRange = 20.0; - - TEST_ASSERT_NOT_EQ(refGeo, refGeoOther); -} - -TEST_MAIN( - TEST_CHECK(testEquality); -) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include +#include + +#include +#include +#include +#include + +#include "TestCase.h" + +TEST_CASE(testEquality) +{ + cphd::ReferenceGeometry refGeo; + cphd::ReferenceGeometry refGeoOther; + refGeo.monostatic.reset(new cphd::Monostatic()); + refGeoOther.monostatic.reset(new cphd::Monostatic()); + + // Fill Values + refGeo.monostatic->azimuthAngle = 1.0; + refGeo.monostatic->grazeAngle = 1.0; + refGeo.monostatic->twistAngle = 1.0; + refGeo.monostatic->slopeAngle = 1.0; + refGeo.monostatic->layoverAngle = 1.0; + refGeo.monostatic->sideOfTrack = six::SideOfTrackType::LEFT; + refGeo.monostatic->slantRange = 20.0; + + refGeoOther.monostatic->azimuthAngle = 2.0; + refGeoOther.monostatic->grazeAngle = 2.0; + refGeoOther.monostatic->twistAngle = 2.0; + refGeoOther.monostatic->slopeAngle = 2.0; + refGeoOther.monostatic->layoverAngle = 2.0; + refGeoOther.monostatic->sideOfTrack = six::SideOfTrackType::LEFT; + refGeoOther.monostatic->slantRange = 20.0; + + TEST_ASSERT_NOT_EQ(refGeo, refGeoOther); +} + +TEST_MAIN( + TEST_CHECK(testEquality); +) diff --git a/six/modules/c++/cphd/unittests/test_signal_block_round.cpp b/six/modules/c++/cphd/unittests/test_signal_block_round.cpp index 197bc10698..3953c8bd63 100644 --- a/six/modules/c++/cphd/unittests/test_signal_block_round.cpp +++ b/six/modules/c++/cphd/unittests/test_signal_block_round.cpp @@ -1,224 +1,224 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*! - * Tests write and read of Signal Block - * Fails if values don't match - */ - -template -auto generateData(size_t length) -{ - using value_type = typename TComplex::value_type; - std::vector data(length); - srand(0); - for (size_t ii = 0; ii < data.size(); ++ii) - { - auto real = static_cast(rand() / 100); - auto imag = static_cast(rand() / 100); - data[ii] = TComplex(real, imag); - } - return data; -} - -inline std::vector generateScaleFactors(size_t length, bool scale) -{ - std::vector scaleFactors(length, 1); - if (scale) - { - for (size_t ii = 0; ii < scaleFactors.size(); ++ii) - { - scaleFactors[ii] *= 2; - } - } - return scaleFactors; -} - -template -void writeCPHD(const std::string& outPathname, size_t /*numThreads*/, - const types::RowCol dims, - const TCxVector& writeData, - cphd::Metadata& metadata, - cphd::PVPBlock& pvpBlock) -{ - const size_t numChannels = 1; - const std::vector numVectors(numChannels, dims.row); - - for (size_t ii = 0; ii < numChannels; ++ii) - { - for (size_t jj = 0; jj < numVectors[ii]; ++jj) - { - cphd::setVectorParameters(ii, jj, pvpBlock); - } - } - - cphd::CPHDWriter writer(metadata, outPathname); - writer.writeMetadata(pvpBlock); - writer.writePVPData(pvpBlock); - for (size_t ii = 0; ii < numChannels; ++ii) - { - writer.writeCPHDData(writeData.data(),dims.area()); - } -} - -std::vector checkData(const std::string& pathname, - size_t numThreads, - const std::vector& scaleFactors, - const types::RowCol dims) -{ - cphd::CPHDReader reader(pathname, numThreads); - const cphd::Wideband& wideband = reader.getWideband(); - std::vector readData(dims.area()); - - size_t sizeInBytes = readData.size() * sizeof(readData[0]); - std::vector scratchData(sizeInBytes); - std::span scratch(scratchData.data(), scratchData.size()); - std::span data(readData.data(), readData.size()); - - wideband.read(0, 0, cphd::Wideband::ALL, 0, cphd::Wideband::ALL, - scaleFactors, numThreads, scratch, data); - - return readData; -} - -template -bool compareVectors(const std::vector& readData, - const TCxVector& writeData, - const std::vector& scaleFactors, - bool scale) -{ - size_t pointsPerScale = readData.size() / scaleFactors.size(); - for (size_t ii = 0; ii < readData.size(); ++ii) - { - cphd::zfloat val(writeData[ii].real(), writeData[ii].imag()); - if (scale) - { - val *= scaleFactors[ii / pointsPerScale]; - } - - if (val != readData[ii]) - { - std::cerr << "Value mismatch at index " << ii << std::endl; - return false; - } - } - return true; -} - -template -bool runTest(bool scale, const TCxVector& writeData) -{ - io::TempFile tempfile; - const size_t numThreads = std::thread::hardware_concurrency(); - const types::RowCol dims(128, 128); - const std::vector scaleFactors = - generateScaleFactors(dims.row, scale); - cphd::Metadata meta = cphd::Metadata(); - setUpData(meta, dims, writeData); - cphd::setPVPXML(meta.pvp); - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - - writeCPHD(tempfile.pathname(), numThreads, dims, writeData, meta, pvpBlock); - const std::vector readData = - checkData(tempfile.pathname(), numThreads, - scaleFactors, dims); - return compareVectors(readData, writeData, scaleFactors, scale); - return true; -} - -TEST_CASE(testUnscaledInt8) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = false; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testScaledInt8) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = true; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testUnscaledInt16) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = false; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testScaledInt16) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = true; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testUnscaledFloat) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = false; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testScaledFloat) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = true; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_MAIN( - TEST_CHECK(testUnscaledInt8); - TEST_CHECK(testScaledInt8); - TEST_CHECK(testUnscaledInt16); - TEST_CHECK(testScaledInt16); - TEST_CHECK(testUnscaledFloat); - TEST_CHECK(testScaledFloat); - ) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + * Tests write and read of Signal Block + * Fails if values don't match + */ + +template +auto generateData(size_t length) +{ + using value_type = typename TComplex::value_type; + std::vector data(length); + srand(0); + for (size_t ii = 0; ii < data.size(); ++ii) + { + auto real = static_cast(rand() / 100); + auto imag = static_cast(rand() / 100); + data[ii] = TComplex(real, imag); + } + return data; +} + +inline std::vector generateScaleFactors(size_t length, bool scale) +{ + std::vector scaleFactors(length, 1); + if (scale) + { + for (size_t ii = 0; ii < scaleFactors.size(); ++ii) + { + scaleFactors[ii] *= 2; + } + } + return scaleFactors; +} + +template +void writeCPHD(const std::string& outPathname, size_t /*numThreads*/, + const types::RowCol dims, + const TCxVector& writeData, + cphd::Metadata& metadata, + cphd::PVPBlock& pvpBlock) +{ + const size_t numChannels = 1; + const std::vector numVectors(numChannels, dims.row); + + for (size_t ii = 0; ii < numChannels; ++ii) + { + for (size_t jj = 0; jj < numVectors[ii]; ++jj) + { + cphd::setVectorParameters(ii, jj, pvpBlock); + } + } + + cphd::CPHDWriter writer(metadata, outPathname); + writer.writeMetadata(pvpBlock); + writer.writePVPData(pvpBlock); + for (size_t ii = 0; ii < numChannels; ++ii) + { + writer.writeCPHDData(writeData.data(),dims.area()); + } +} + +std::vector checkData(const std::string& pathname, + size_t numThreads, + const std::vector& scaleFactors, + const types::RowCol dims) +{ + cphd::CPHDReader reader(pathname, numThreads); + const cphd::Wideband& wideband = reader.getWideband(); + std::vector readData(dims.area()); + + size_t sizeInBytes = readData.size() * sizeof(readData[0]); + std::vector scratchData(sizeInBytes); + std::span scratch(scratchData.data(), scratchData.size()); + std::span data(readData.data(), readData.size()); + + wideband.read(0, 0, cphd::Wideband::ALL, 0, cphd::Wideband::ALL, + scaleFactors, numThreads, scratch, data); + + return readData; +} + +template +bool compareVectors(const std::vector& readData, + const TCxVector& writeData, + const std::vector& scaleFactors, + bool scale) +{ + size_t pointsPerScale = readData.size() / scaleFactors.size(); + for (size_t ii = 0; ii < readData.size(); ++ii) + { + cphd::zfloat val(writeData[ii].real(), writeData[ii].imag()); + if (scale) + { + val *= scaleFactors[ii / pointsPerScale]; + } + + if (val != readData[ii]) + { + std::cerr << "Value mismatch at index " << ii << std::endl; + return false; + } + } + return true; +} + +template +bool runTest(bool scale, const TCxVector& writeData) +{ + io::TempFile tempfile; + const size_t numThreads = std::thread::hardware_concurrency(); + const types::RowCol dims(128, 128); + const std::vector scaleFactors = + generateScaleFactors(dims.row, scale); + cphd::Metadata meta = cphd::Metadata(); + setUpData(meta, dims, writeData); + cphd::setPVPXML(meta.pvp); + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + + writeCPHD(tempfile.pathname(), numThreads, dims, writeData, meta, pvpBlock); + const std::vector readData = + checkData(tempfile.pathname(), numThreads, + scaleFactors, dims); + return compareVectors(readData, writeData, scaleFactors, scale); + return true; +} + +TEST_CASE(testUnscaledInt8) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = false; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testScaledInt8) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = true; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testUnscaledInt16) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = false; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testScaledInt16) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = true; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testUnscaledFloat) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = false; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testScaledFloat) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = true; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_MAIN( + TEST_CHECK(testUnscaledInt8); + TEST_CHECK(testScaledInt8); + TEST_CHECK(testUnscaledInt16); + TEST_CHECK(testScaledInt16); + TEST_CHECK(testUnscaledFloat); + TEST_CHECK(testScaledFloat); + ) diff --git a/six/modules/c++/cphd/unittests/test_support_block_round.cpp b/six/modules/c++/cphd/unittests/test_support_block_round.cpp index 8dd52bbd82..0e075b58b3 100644 --- a/six/modules/c++/cphd/unittests/test_support_block_round.cpp +++ b/six/modules/c++/cphd/unittests/test_support_block_round.cpp @@ -1,168 +1,168 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static constexpr size_t NUM_SUPPORT = 3; -static constexpr size_t NUM_ROWS = 3; -static constexpr size_t NUM_COLS = 4; - -template -std::vector generateSupportData(size_t length) -{ - std::vector data(length); - srand(0); - for (size_t ii = 0; ii < data.size(); ++ii) - { - data[ii] = rand() % 16; - } - return data; -} - -template -void setSupport(cphd::Data& d) -{ - d.setSupportArray("1.0", NUM_ROWS, NUM_COLS, sizeof(T), 0); - d.setSupportArray("2.0", NUM_ROWS, NUM_COLS, sizeof(T), NUM_ROWS*NUM_COLS*sizeof(T)); - d.setSupportArray("AddedSupport", NUM_ROWS, NUM_COLS, sizeof(T), 2*NUM_ROWS*NUM_COLS*sizeof(T)); -} - -template -void writeSupportData(const std::string& outPathname, size_t numThreads, - const std::vector& writeData, - cphd::Metadata& metadata, - cphd::PVPBlock& pvpBlock) -{ - const size_t numChannels = 1; - // Required but doesn't matter - const std::vector numVectors(numChannels, 128); - - for (size_t ii = 0; ii < numChannels; ++ii) - { - for (size_t jj = 0; jj < numVectors[ii]; ++jj) - { - cphd::setVectorParameters(ii, jj, pvpBlock); - } - } - cphd::CPHDWriter writer(metadata, outPathname, std::vector(), numThreads); - writer.writeMetadata(pvpBlock); - writer.writeSupportData(writeData.data()); - writer.writePVPData(pvpBlock); -} - -std::vector checkSupportData( - const std::string& pathname, - size_t /*size*/, - size_t numThreads) -{ - cphd::CPHDReader reader(pathname, numThreads); - const cphd::SupportBlock& supportBlock = reader.getSupportBlock(); - - std::unique_ptr readPtr; - supportBlock.readAll(numThreads, readPtr); - - std::vector readData(readPtr.get(), readPtr.get() + reader.getMetadata().data.getAllSupportSize()); - return readData; -} - -template -bool compareVectors(const std::vector& readData, - const T* writeData, - size_t writeDataSize) -{ - if (writeDataSize * sizeof(T) != readData.size()) - { - std::cerr << "Size mismatch. Writedata size: "<< writeDataSize * sizeof(T) - << "ReadData size: " << readData.size() << "\n"; - return false; - } - const std::byte* ptr = reinterpret_cast(writeData); - for (size_t ii = 0; ii < readData.size(); ++ii, ++ptr) - { - if (*ptr != readData[ii]) - { - std::cerr << "Value mismatch at index " << ii << std::endl; - std::cerr << "readData: " << static_cast(readData[ii]) << " " << "writeData: " << static_cast(*ptr) << "\n"; - return false; - } - } - return true; -} - -template -bool runTest(const std::vector& writeData) -{ - io::TempFile tempfile; - const size_t numThreads = 1; - cphd::Metadata meta = cphd::Metadata(); - cphd::setUpData(meta, types::RowCol(128,256), std::vector()); - setSupport(meta.data); - cphd::setPVPXML(meta.pvp); - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - writeSupportData(tempfile.pathname(), numThreads, writeData, meta, pvpBlock); - const std::vector readData = - checkSupportData(tempfile.pathname(), NUM_SUPPORT*NUM_ROWS*NUM_COLS*sizeof(T), numThreads); - - return compareVectors(readData, writeData.data(), writeData.size()); -} - -TEST_CASE(testSupportsInt) -{ - const types::RowCol dims(NUM_ROWS, NUM_COLS); - const std::vector writeData = - generateSupportData(NUM_SUPPORT*dims.area()); - TEST_ASSERT_TRUE(runTest(writeData)); -} - -TEST_CASE(testSupportsDouble) -{ - const types::RowCol dims(NUM_ROWS, NUM_COLS); - const std::vector writeData = - generateSupportData(NUM_SUPPORT*dims.area()); - TEST_ASSERT_TRUE(runTest(writeData)); -} - -TEST_MAIN( - TEST_CHECK(testSupportsInt); - TEST_CHECK(testSupportsDouble); - ) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static constexpr size_t NUM_SUPPORT = 3; +static constexpr size_t NUM_ROWS = 3; +static constexpr size_t NUM_COLS = 4; + +template +std::vector generateSupportData(size_t length) +{ + std::vector data(length); + srand(0); + for (size_t ii = 0; ii < data.size(); ++ii) + { + data[ii] = rand() % 16; + } + return data; +} + +template +void setSupport(cphd::Data& d) +{ + d.setSupportArray("1.0", NUM_ROWS, NUM_COLS, sizeof(T), 0); + d.setSupportArray("2.0", NUM_ROWS, NUM_COLS, sizeof(T), NUM_ROWS*NUM_COLS*sizeof(T)); + d.setSupportArray("AddedSupport", NUM_ROWS, NUM_COLS, sizeof(T), 2*NUM_ROWS*NUM_COLS*sizeof(T)); +} + +template +void writeSupportData(const std::string& outPathname, size_t numThreads, + const std::vector& writeData, + cphd::Metadata& metadata, + cphd::PVPBlock& pvpBlock) +{ + const size_t numChannels = 1; + // Required but doesn't matter + const std::vector numVectors(numChannels, 128); + + for (size_t ii = 0; ii < numChannels; ++ii) + { + for (size_t jj = 0; jj < numVectors[ii]; ++jj) + { + cphd::setVectorParameters(ii, jj, pvpBlock); + } + } + cphd::CPHDWriter writer(metadata, outPathname, std::vector(), numThreads); + writer.writeMetadata(pvpBlock); + writer.writeSupportData(writeData.data()); + writer.writePVPData(pvpBlock); +} + +std::vector checkSupportData( + const std::string& pathname, + size_t /*size*/, + size_t numThreads) +{ + cphd::CPHDReader reader(pathname, numThreads); + const cphd::SupportBlock& supportBlock = reader.getSupportBlock(); + + std::unique_ptr readPtr; + supportBlock.readAll(numThreads, readPtr); + + std::vector readData(readPtr.get(), readPtr.get() + reader.getMetadata().data.getAllSupportSize()); + return readData; +} + +template +bool compareVectors(const std::vector& readData, + const T* writeData, + size_t writeDataSize) +{ + if (writeDataSize * sizeof(T) != readData.size()) + { + std::cerr << "Size mismatch. Writedata size: "<< writeDataSize * sizeof(T) + << "ReadData size: " << readData.size() << "\n"; + return false; + } + const std::byte* ptr = reinterpret_cast(writeData); + for (size_t ii = 0; ii < readData.size(); ++ii, ++ptr) + { + if (*ptr != readData[ii]) + { + std::cerr << "Value mismatch at index " << ii << std::endl; + std::cerr << "readData: " << static_cast(readData[ii]) << " " << "writeData: " << static_cast(*ptr) << "\n"; + return false; + } + } + return true; +} + +template +bool runTest(const std::vector& writeData) +{ + io::TempFile tempfile; + const size_t numThreads = 1; + cphd::Metadata meta = cphd::Metadata(); + cphd::setUpData(meta, types::RowCol(128,256), std::vector()); + setSupport(meta.data); + cphd::setPVPXML(meta.pvp); + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + writeSupportData(tempfile.pathname(), numThreads, writeData, meta, pvpBlock); + const std::vector readData = + checkSupportData(tempfile.pathname(), NUM_SUPPORT*NUM_ROWS*NUM_COLS*sizeof(T), numThreads); + + return compareVectors(readData, writeData.data(), writeData.size()); +} + +TEST_CASE(testSupportsInt) +{ + const types::RowCol dims(NUM_ROWS, NUM_COLS); + const std::vector writeData = + generateSupportData(NUM_SUPPORT*dims.area()); + TEST_ASSERT_TRUE(runTest(writeData)); +} + +TEST_CASE(testSupportsDouble) +{ + const types::RowCol dims(NUM_ROWS, NUM_COLS); + const std::vector writeData = + generateSupportData(NUM_SUPPORT*dims.area()); + TEST_ASSERT_TRUE(runTest(writeData)); +} + +TEST_MAIN( + TEST_CHECK(testSupportsInt); + TEST_CHECK(testSupportsDouble); + ) diff --git a/six/modules/c++/cphd03/cphd03.vcxproj b/six/modules/c++/cphd03/cphd03.vcxproj index cbdb44a2b7..129e159151 100644 --- a/six/modules/c++/cphd03/cphd03.vcxproj +++ b/six/modules/c++/cphd03/cphd03.vcxproj @@ -1,151 +1,151 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {016EF417-E41C-404C-B3B5-34B6CDD94BB3} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..\cphd\include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..\cphd\include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - {01be4480-9620-4ded-b34f-d2e3ab4b7c8b} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {016EF417-E41C-404C-B3B5-34B6CDD94BB3} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..\cphd\include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..\cphd\include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + {01be4480-9620-4ded-b34f-d2e3ab4b7c8b} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/six/modules/c++/samples/check_valid_six.cpp b/six/modules/c++/samples/check_valid_six.cpp index f6d6efecc9..0a9c287528 100644 --- a/six/modules/c++/samples/check_valid_six.cpp +++ b/six/modules/c++/samples/check_valid_six.cpp @@ -1,279 +1,279 @@ -/* ========================================================================= - * This file is part of six-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2014, MDA Information Systems LLC - * - * six-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include "utils.h" - -namespace fs = std::filesystem; - -namespace -{ -// TODO: Does this belong in sys? -class ExtensionsPredicate : public sys::FileOnlyPredicate -{ -public: - ExtensionsPredicate(const std::vector& extensions, - bool ignoreCase = true) : - mExtensions(extensions), - mIgnoreCase(ignoreCase) - { - if (mIgnoreCase) - { - for (size_t ii = 0; ii < mExtensions.size(); ++ii) - { - str::lower(mExtensions[ii]); - } - } - } - - virtual bool operator()(const std::string& pathname) const - { - if (!sys::FileOnlyPredicate::operator()(pathname)) - { - return false; - } - - std::string ext = fs::path(pathname).extension().string(); - if (mIgnoreCase) - { - str::lower(ext); - } - - for (size_t ii = 0; ii < mExtensions.size(); ++ii) - { - if (ext == mExtensions[ii]) - { - return true; - } - } - - return false; - } - -private: - std::vector mExtensions; - const bool mIgnoreCase; -}; - -std::vector getPathnames(const std::string& dirname) -{ - std::vector extensions; - extensions.push_back(".nitf"); - extensions.push_back(".ntf"); - extensions.push_back(".xml"); - - return sys::FileFinder::search(ExtensionsPredicate(extensions), - std::vector(1, dirname), - false); -} - -bool runValidation(const std::unique_ptr& data, - std::unique_ptr& log) -{ - if (data->getDataType() == six::DataType::COMPLEX) - { - six::sicd::ComplexData* complexData = - static_cast( - data.get()); - - if (complexData->validate(*log)) - { - log->info(Ctxt("Successful: No Errors Found!")); - return true; - } - return false; - } - else - { - // Nothing to validate - log->info(Ctxt("Nothing done: not a SICD.")); - return true; - } -} -} - -// make it a little easier to use from MSVC -#if defined(_DEBUG) && defined(_MSC_VER) -static fs::path getNitfPath() -{ - const auto cwd = fs::current_path(); - const auto root_dir = cwd.parent_path().parent_path(); - return root_dir / "six" / "tests" / "nitf" / "sicd_1.1.0.nitf"; -} - -static void setNitfPluginPath() -{ - const auto cwd = fs::current_path(); - const auto root_dir = cwd.parent_path().parent_path().parent_path().parent_path().parent_path(); - - const std::string configuration = -#if defined(NDEBUG) // i.e., release - "Release"; -#else - "Debug"; -#endif - const std::string platform = "x64"; - - const auto path = root_dir / "externals" / "nitro" / platform / configuration / "share" / "nitf" / "plugins"; - sys::OS().setEnv("NITF_PLUGIN_PATH", path.string(), true /*overwrite*/); -} -#endif - -static int main_(int argc, char** argv) -{ - // make it a little easier to use from MSVC - #if defined(_DEBUG) && defined(_MSC_VER) - if (argc == 1) - { - setNitfPluginPath(); - - // ./six/modules/c++/six/tests/nitf/sidd_1.0.0.nitf - static const std::string nitf_path = getNitfPath().string(); - argc = 2; - auto argv_ = static_cast(malloc(argc * sizeof(char*))); - argv_[0] = argv[0]; - argv_[1] = const_cast(nitf_path.c_str()); - //argv[1] - argv = argv_; - } - #endif - - - // create a parser and add our options to it - cli::ArgumentParser parser; - parser.setDescription("This program reads a SIDD/SICD along with a "\ - "directory of schemas, and returns any error messages "\ - "that may be contained in the DES XML"); - parser.addArgument("-f --log", "Specify a log file", cli::STORE, "log", - "FILE")->setDefault("console"); - parser.addArgument("-l --level", "Specify log level", cli::STORE, - "level", "LEVEL")->setChoices( - str::split("debug info warn error"))->setDefault( - "info"); - parser.addArgument("-s --schema", - "Specify a schema or directory of schemas", - cli::STORE, "schema", "FILE"); - parser.addArgument("input", "Input SICD/SIDD file or directory of files", cli::STORE, "input", - "INPUT", 1, 1); - - const std::unique_ptr - options(parser.parse(argc, (const char**) argv)); - - const std::string inputPath(options->get("input")); - std::vector inputPathnames = getPathnames(inputPath); - const std::string logFile(options->get("log")); - std::string level(options->get("level")); - std::vector schemaPaths; - getSchemaPaths(*options, "--schema", "schema", schemaPaths); - - // create an XML registry - // The reason to do this is to avoid adding XMLControlCreators to the - // XMLControlFactory singleton - this way has more fine-grained control - six::XMLControlRegistry xmlRegistry; - xmlRegistry.addCreator(); - xmlRegistry.addCreator(); - - str::upper(level); - str::trim(level); - std::unique_ptr log = - logging::setupLogger(fs::path(argv[0]).filename().string(), level, logFile); - - // this validates the DES of the input against the - // best available schema - six::NITFReadControl reader; - reader.setLogger(*log); - reader.setXMLControlRegistry(&xmlRegistry); - bool allValid = true; - for (size_t ii = 0; ii < inputPathnames.size(); ++ii) - { - const std::string& inputPathname(inputPathnames[ii]); - log->info(Ctxt("Reading " + inputPathname)); - std::unique_ptr data; - try - { - if (nitf::Reader::getNITFVersion(inputPathname) == - NITF_VER_UNKNOWN) - { - data = six::parseDataFromFile(xmlRegistry, - inputPathname, - schemaPaths, - *log); - allValid = allValid && runValidation(data, log); - } - else - { - reader.load(inputPathname, schemaPaths); - auto container = reader.getContainer(); - for (size_t jj = 0; jj < container->size(); ++jj) - { - data.reset(container->getData(jj)->clone()); - allValid = allValid && runValidation(data, log); - } - } - - } - catch (const six::DESValidationException& ex) - { - log->error(ex); - log->error(Ctxt("Unsuccessful: Please contact your product " - "vendor with these details!")); - allValid = false; - } - catch (const except::Exception& ex) - { - log->error(ex); - allValid = false; - } - } - - return allValid ? EXIT_SUCCESS : EXIT_FAILURE; -} -int main(int argc, char** argv) -{ - try - { - return main_(argc, argv); - } - catch (const std::exception& ex) - { - std::cerr << ex.what() << std::endl; - } - catch (const except::Exception& ex) - { - std::cerr << ex.toString() << std::endl; - return 1; - } - catch (...) - { - std::cerr << "Unknown exception\n"; - } - - return EXIT_FAILURE; +/* ========================================================================= + * This file is part of six-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * six-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include "utils.h" + +namespace fs = std::filesystem; + +namespace +{ +// TODO: Does this belong in sys? +class ExtensionsPredicate : public sys::FileOnlyPredicate +{ +public: + ExtensionsPredicate(const std::vector& extensions, + bool ignoreCase = true) : + mExtensions(extensions), + mIgnoreCase(ignoreCase) + { + if (mIgnoreCase) + { + for (size_t ii = 0; ii < mExtensions.size(); ++ii) + { + str::lower(mExtensions[ii]); + } + } + } + + virtual bool operator()(const std::string& pathname) const + { + if (!sys::FileOnlyPredicate::operator()(pathname)) + { + return false; + } + + std::string ext = fs::path(pathname).extension().string(); + if (mIgnoreCase) + { + str::lower(ext); + } + + for (size_t ii = 0; ii < mExtensions.size(); ++ii) + { + if (ext == mExtensions[ii]) + { + return true; + } + } + + return false; + } + +private: + std::vector mExtensions; + const bool mIgnoreCase; +}; + +std::vector getPathnames(const std::string& dirname) +{ + std::vector extensions; + extensions.push_back(".nitf"); + extensions.push_back(".ntf"); + extensions.push_back(".xml"); + + return sys::FileFinder::search(ExtensionsPredicate(extensions), + std::vector(1, dirname), + false); +} + +bool runValidation(const std::unique_ptr& data, + std::unique_ptr& log) +{ + if (data->getDataType() == six::DataType::COMPLEX) + { + six::sicd::ComplexData* complexData = + static_cast( + data.get()); + + if (complexData->validate(*log)) + { + log->info(Ctxt("Successful: No Errors Found!")); + return true; + } + return false; + } + else + { + // Nothing to validate + log->info(Ctxt("Nothing done: not a SICD.")); + return true; + } +} +} + +// make it a little easier to use from MSVC +#if defined(_DEBUG) && defined(_MSC_VER) +static fs::path getNitfPath() +{ + const auto cwd = fs::current_path(); + const auto root_dir = cwd.parent_path().parent_path(); + return root_dir / "six" / "tests" / "nitf" / "sicd_1.1.0.nitf"; +} + +static void setNitfPluginPath() +{ + const auto cwd = fs::current_path(); + const auto root_dir = cwd.parent_path().parent_path().parent_path().parent_path().parent_path(); + + const std::string configuration = +#if defined(NDEBUG) // i.e., release + "Release"; +#else + "Debug"; +#endif + const std::string platform = "x64"; + + const auto path = root_dir / "externals" / "nitro" / platform / configuration / "share" / "nitf" / "plugins"; + sys::OS().setEnv("NITF_PLUGIN_PATH", path.string(), true /*overwrite*/); +} +#endif + +static int main_(int argc, char** argv) +{ + // make it a little easier to use from MSVC + #if defined(_DEBUG) && defined(_MSC_VER) + if (argc == 1) + { + setNitfPluginPath(); + + // ./six/modules/c++/six/tests/nitf/sidd_1.0.0.nitf + static const std::string nitf_path = getNitfPath().string(); + argc = 2; + auto argv_ = static_cast(malloc(argc * sizeof(char*))); + argv_[0] = argv[0]; + argv_[1] = const_cast(nitf_path.c_str()); + //argv[1] + argv = argv_; + } + #endif + + + // create a parser and add our options to it + cli::ArgumentParser parser; + parser.setDescription("This program reads a SIDD/SICD along with a "\ + "directory of schemas, and returns any error messages "\ + "that may be contained in the DES XML"); + parser.addArgument("-f --log", "Specify a log file", cli::STORE, "log", + "FILE")->setDefault("console"); + parser.addArgument("-l --level", "Specify log level", cli::STORE, + "level", "LEVEL")->setChoices( + str::split("debug info warn error"))->setDefault( + "info"); + parser.addArgument("-s --schema", + "Specify a schema or directory of schemas", + cli::STORE, "schema", "FILE"); + parser.addArgument("input", "Input SICD/SIDD file or directory of files", cli::STORE, "input", + "INPUT", 1, 1); + + const std::unique_ptr + options(parser.parse(argc, (const char**) argv)); + + const std::string inputPath(options->get("input")); + std::vector inputPathnames = getPathnames(inputPath); + const std::string logFile(options->get("log")); + std::string level(options->get("level")); + std::vector schemaPaths; + getSchemaPaths(*options, "--schema", "schema", schemaPaths); + + // create an XML registry + // The reason to do this is to avoid adding XMLControlCreators to the + // XMLControlFactory singleton - this way has more fine-grained control + six::XMLControlRegistry xmlRegistry; + xmlRegistry.addCreator(); + xmlRegistry.addCreator(); + + str::upper(level); + str::trim(level); + std::unique_ptr log = + logging::setupLogger(fs::path(argv[0]).filename().string(), level, logFile); + + // this validates the DES of the input against the + // best available schema + six::NITFReadControl reader; + reader.setLogger(*log); + reader.setXMLControlRegistry(&xmlRegistry); + bool allValid = true; + for (size_t ii = 0; ii < inputPathnames.size(); ++ii) + { + const std::string& inputPathname(inputPathnames[ii]); + log->info(Ctxt("Reading " + inputPathname)); + std::unique_ptr data; + try + { + if (nitf::Reader::getNITFVersion(inputPathname) == + NITF_VER_UNKNOWN) + { + data = six::parseDataFromFile(xmlRegistry, + inputPathname, + schemaPaths, + *log); + allValid = allValid && runValidation(data, log); + } + else + { + reader.load(inputPathname, schemaPaths); + auto container = reader.getContainer(); + for (size_t jj = 0; jj < container->size(); ++jj) + { + data.reset(container->getData(jj)->clone()); + allValid = allValid && runValidation(data, log); + } + } + + } + catch (const six::DESValidationException& ex) + { + log->error(ex); + log->error(Ctxt("Unsuccessful: Please contact your product " + "vendor with these details!")); + allValid = false; + } + catch (const except::Exception& ex) + { + log->error(ex); + allValid = false; + } + } + + return allValid ? EXIT_SUCCESS : EXIT_FAILURE; +} +int main(int argc, char** argv) +{ + try + { + return main_(argc, argv); + } + catch (const std::exception& ex) + { + std::cerr << ex.what() << std::endl; + } + catch (const except::Exception& ex) + { + std::cerr << ex.toString() << std::endl; + return 1; + } + catch (...) + { + std::cerr << "Unknown exception\n"; + } + + return EXIT_FAILURE; } \ No newline at end of file diff --git a/six/modules/c++/samples/check_valid_six.dir/check_valid_six.vcxproj b/six/modules/c++/samples/check_valid_six.dir/check_valid_six.vcxproj index 7ce7e498dd..eb0e48d067 100644 --- a/six/modules/c++/samples/check_valid_six.dir/check_valid_six.vcxproj +++ b/six/modules/c++/samples/check_valid_six.dir/check_valid_six.vcxproj @@ -1,127 +1,127 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {f0e2c8ff-57d4-4331-9bd2-76ff01cb54eb} - checkvalidsix - 10.0 - - - - Application - true - v143 - - - Application - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include - Use - pch.h - pch.h - true - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - Console - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include - Use - pch.h - pch.h - true - true - AdvancedVectorExtensions2 - Speed - Guard - true - - - Console - true - true - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) - - - - - - Create - Create - - - - - - - - - - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {ddc587c2-53ba-44a9-94e7-07be52af3d0b} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {f0e2c8ff-57d4-4331-9bd2-76ff01cb54eb} + checkvalidsix + 10.0 + + + + Application + true + v143 + + + Application + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include + Use + pch.h + pch.h + true + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + Console + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include + Use + pch.h + pch.h + true + true + AdvancedVectorExtensions2 + Speed + Guard + true + + + Console + true + true + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) + + + + + + Create + Create + + + + + + + + + + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {ddc587c2-53ba-44a9-94e7-07be52af3d0b} + + + + + \ No newline at end of file diff --git a/six/modules/c++/samples/crop_sicd.dir/crop_sicd.vcxproj b/six/modules/c++/samples/crop_sicd.dir/crop_sicd.vcxproj index 51253b9f63..5b8ed9267e 100644 --- a/six/modules/c++/samples/crop_sicd.dir/crop_sicd.vcxproj +++ b/six/modules/c++/samples/crop_sicd.dir/crop_sicd.vcxproj @@ -1,127 +1,127 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC} - checkvalidsix - 10.0 - - - - Application - true - v143 - - - Application - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include - Use - pch.h - pch.h - true - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - Console - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include - Use - pch.h - pch.h - true - true - AdvancedVectorExtensions2 - Speed - Guard - true - - - Console - true - true - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) - - - - - - Create - Create - - - - - - - - - - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {ddc587c2-53ba-44a9-94e7-07be52af3d0b} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC} + checkvalidsix + 10.0 + + + + Application + true + v143 + + + Application + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include + Use + pch.h + pch.h + true + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + Console + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include + Use + pch.h + pch.h + true + true + AdvancedVectorExtensions2 + Speed + Guard + true + + + Console + true + true + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) + + + + + + Create + Create + + + + + + + + + + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {ddc587c2-53ba-44a9-94e7-07be52af3d0b} + + + + + \ No newline at end of file diff --git a/six/modules/c++/samples/utils.h b/six/modules/c++/samples/utils.h index 52e6cd4ced..a6c47df222 100644 --- a/six/modules/c++/samples/utils.h +++ b/six/modules/c++/samples/utils.h @@ -1,61 +1,61 @@ -#ifndef __SIX_TEST_UTILS_H__ -#define __SIX_TEST_UTILS_H__ - -#include -#include -#include - -/*! - * This function converts DMS corners into decimal degrees using NITRO, - * and then puts them into a lat-lon - */ -inline -six::LatLonCorners makeUpCornersFromDMS() -{ - int latTopDMS[3] = { 42, 17, 50 }; - int latBottomDMS[3] = { 42, 15, 14 }; - int lonEastDMS[3] = { -83, 42, 12 }; - int lonWestDMS[3] = { -83, 45, 44 }; - - const double latTopDecimal = - nitf::Utils::geographicToDecimal(latTopDMS[0], - latTopDMS[1], - latTopDMS[2]); - - const double latBottomDecimal = - nitf::Utils::geographicToDecimal(latBottomDMS[0], - latBottomDMS[1], - latBottomDMS[2]); - - const double lonEastDecimal = - nitf::Utils::geographicToDecimal(lonEastDMS[0], - lonEastDMS[1], - lonEastDMS[2]); - - const double lonWestDecimal = - nitf::Utils::geographicToDecimal(lonWestDMS[0], - lonWestDMS[1], - lonWestDMS[2]); - - six::LatLonCorners corners; - corners.upperLeft = six::LatLon(latTopDecimal, lonWestDecimal); - corners.upperRight = six::LatLon(latTopDecimal, lonEastDecimal); - corners.lowerRight = six::LatLon(latBottomDecimal, lonEastDecimal); - corners.lowerLeft = six::LatLon(latBottomDecimal, lonWestDecimal); - return corners; -} - -inline -void getSchemaPaths(const cli::Results& options, - const std::string& /*commandLineArg*/, - const std::string& cliArgName, - std::vector& schemaPaths) -{ - if(options.hasValue(cliArgName)) - { - schemaPaths.push_back(options.get(cliArgName)); - } - six::XMLControl::loadSchemaPaths(schemaPaths); -} - -#endif +#ifndef __SIX_TEST_UTILS_H__ +#define __SIX_TEST_UTILS_H__ + +#include +#include +#include + +/*! + * This function converts DMS corners into decimal degrees using NITRO, + * and then puts them into a lat-lon + */ +inline +six::LatLonCorners makeUpCornersFromDMS() +{ + int latTopDMS[3] = { 42, 17, 50 }; + int latBottomDMS[3] = { 42, 15, 14 }; + int lonEastDMS[3] = { -83, 42, 12 }; + int lonWestDMS[3] = { -83, 45, 44 }; + + const double latTopDecimal = + nitf::Utils::geographicToDecimal(latTopDMS[0], + latTopDMS[1], + latTopDMS[2]); + + const double latBottomDecimal = + nitf::Utils::geographicToDecimal(latBottomDMS[0], + latBottomDMS[1], + latBottomDMS[2]); + + const double lonEastDecimal = + nitf::Utils::geographicToDecimal(lonEastDMS[0], + lonEastDMS[1], + lonEastDMS[2]); + + const double lonWestDecimal = + nitf::Utils::geographicToDecimal(lonWestDMS[0], + lonWestDMS[1], + lonWestDMS[2]); + + six::LatLonCorners corners; + corners.upperLeft = six::LatLon(latTopDecimal, lonWestDecimal); + corners.upperRight = six::LatLon(latTopDecimal, lonEastDecimal); + corners.lowerRight = six::LatLon(latBottomDecimal, lonEastDecimal); + corners.lowerLeft = six::LatLon(latBottomDecimal, lonWestDecimal); + return corners; +} + +inline +void getSchemaPaths(const cli::Results& options, + const std::string& /*commandLineArg*/, + const std::string& cliArgName, + std::vector& schemaPaths) +{ + if(options.hasValue(cliArgName)) + { + schemaPaths.push_back(options.get(cliArgName)); + } + six::XMLControl::loadSchemaPaths(schemaPaths); +} + +#endif diff --git a/six/modules/c++/scene/include/scene/sys_Conf.h b/six/modules/c++/scene/include/scene/sys_Conf.h index 4828d27d57..46a06c3260 100644 --- a/six/modules/c++/scene/include/scene/sys_Conf.h +++ b/six/modules/c++/scene/include/scene/sys_Conf.h @@ -1,15 +1,15 @@ -#ifndef SIX_scene_sys_Conf_h_INCLUDED_ -#define SIX_scene_sys_Conf_h_INCLUDED_ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include - -#endif // SIX_scene_sys_Conf_h_INCLUDED_ +#ifndef SIX_scene_sys_Conf_h_INCLUDED_ +#define SIX_scene_sys_Conf_h_INCLUDED_ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +#endif // SIX_scene_sys_Conf_h_INCLUDED_ diff --git a/six/modules/c++/scene/scene.ruleset b/six/modules/c++/scene/scene.ruleset index 2a2edcef36..598fbdbd65 100644 --- a/six/modules/c++/scene/scene.ruleset +++ b/six/modules/c++/scene/scene.ruleset @@ -1,32 +1,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/six/modules/c++/scene/scene.vcxproj b/six/modules/c++/scene/scene.vcxproj index 52b4731862..62eb7adb3c 100644 --- a/six/modules/c++/scene/scene.vcxproj +++ b/six/modules/c++/scene/scene.vcxproj @@ -1,155 +1,155 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {1CFCDE59-6410-4037-95EB-B37D31E10820} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - true - v143 - - - - - - - - - - - - - - - true - ..\six.ruleset - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - true - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - - {8f357a19-799e-4971-850e-3f28485c130b} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {1CFCDE59-6410-4037-95EB-B37D31E10820} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + true + v143 + + + + + + + + + + + + + + + true + ..\six.ruleset + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + true + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + {8f357a19-799e-4971-850e-3f28485c130b} + + + + + \ No newline at end of file diff --git a/six/modules/c++/scene/scene.vcxproj.filters b/six/modules/c++/scene/scene.vcxproj.filters index ca51817fe9..61d0fcdcbc 100644 --- a/six/modules/c++/scene/scene.vcxproj.filters +++ b/six/modules/c++/scene/scene.vcxproj.filters @@ -1,123 +1,123 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + \ No newline at end of file diff --git a/six/modules/c++/scene/source/ProjectionPolynomialFitter.cpp b/six/modules/c++/scene/source/ProjectionPolynomialFitter.cpp index 233d7f8b93..10f3fb9654 100644 --- a/six/modules/c++/scene/source/ProjectionPolynomialFitter.cpp +++ b/six/modules/c++/scene/source/ProjectionPolynomialFitter.cpp @@ -1,489 +1,489 @@ -/* ========================================================================= - * This file is part of scene-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2014, MDA Information Systems LLC - * - * scene-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include - -#include -#include - -#undef min -#undef max - -namespace -{ -struct Shift final -{ - Shift(double shift) : - mShift(shift) - { - } - Shift(const Shift& other) = delete; - Shift& operator=(const Shift& other) = delete; - - inline double operator()(double input) const - { - return (input - mShift); - } - -private: - const double mShift; -}; -} - -namespace scene -{ -const size_t ProjectionPolynomialFitter::DEFAULTS_POINTS_1D = 10; - -ProjectionPolynomialFitter::ProjectionPolynomialFitter( - const ProjectionModel& projModel, - const GridECEFTransform& gridTransform, - const types::RowCol& outPixelStart, - const types::RowCol& outExtent, - size_t numPoints1D) : - mNumPoints1D(numPoints1D), - mOutputPlaneRows(numPoints1D, numPoints1D), - mOutputPlaneCols(numPoints1D, numPoints1D), - mSceneCoordinates(numPoints1D, - numPoints1D, - types::RowCol(0.0, 0.0)), - mTimeCOA(numPoints1D, numPoints1D) -{ - // Want to sample [outPixelStart, outPixelStart + outExtent) in the loop - // below. That is, we are marching through the portion of interest of the - // output grid in pixel space. In the case of multi-segment SICDs, we'll - // only sample our part of the grid defined by outPixelStart and - // outExtent. - const types::RowCol skip( - static_cast(outExtent.row - 1) / static_cast(mNumPoints1D - 1), - static_cast(outExtent.col - 1) / static_cast(mNumPoints1D - 1)); - - types::RowCol currentOffset(outPixelStart); - - for (size_t ii = 0; - ii < mNumPoints1D; - ++ii, currentOffset.row += skip.row) - { - currentOffset.col = outPixelStart.col; - - for (size_t jj = 0; - jj < mNumPoints1D; - ++jj, currentOffset.col += skip.col) - { - projectToSlantPlane(projModel, gridTransform, outPixelStart, - currentOffset, ii, jj); - } - } -} - -ProjectionPolynomialFitter::ProjectionPolynomialFitter( - const ProjectionModel& projModel, - const GridECEFTransform& gridTransform, - const types::RowCol& fullExtent, - const types::RowCol& outPixelStart, - const types::RowCol& /*outExtent*/, - const std::vector >& polygon, - size_t numPoints1D) : - mNumPoints1D(numPoints1D), - mOutputPlaneRows(numPoints1D, numPoints1D), - mOutputPlaneCols(numPoints1D, numPoints1D), - mSceneCoordinates(numPoints1D, - numPoints1D, - types::RowCol(0.0, 0.0)), - mTimeCOA(numPoints1D, numPoints1D) -{ - // Get bounding rectangle of output plane polygon. - double minRow = std::numeric_limits::max(); - double maxRow = -std::numeric_limits::max(); - double minCol = std::numeric_limits::max(); - double maxCol = -std::numeric_limits::max(); - - for (size_t ii = 0; ii < polygon.size(); ++ii) - { - minRow = std::min(minRow, polygon[ii].row); - maxRow = std::max(maxRow, polygon[ii].row); - minCol = std::min(minCol, polygon[ii].col); - maxCol = std::max(maxCol, polygon[ii].col); - } - - if (minRow > static_cast(fullExtent.row) || - maxRow < 0 || - minCol > static_cast(fullExtent.col) || - maxCol < 0) - { - throw except::Exception(Ctxt( - "Bounding rectangle is outside of output extent")); - } - - // Only interested in pixels inside the fullExtent. - minRow = std::max(minRow, 0.0); - minCol = std::max(minCol, 0.0); - maxRow = std::min(maxRow, static_cast(fullExtent.row) - 1); - maxCol = std::min(maxCol, static_cast(fullExtent.col) - 1); - - // Get size_t extent of the set of points. - const auto minRowI = gsl::narrow_cast(std::ceil(minRow)); - const auto minColI = gsl::narrow_cast(std::ceil(minCol)); - const auto maxRowI = gsl::narrow_cast(std::floor(maxRow)); - const auto maxColI = gsl::narrow_cast(std::floor(maxCol)); - - if (minRowI > maxRowI || minColI > maxColI) - { - throw except::Exception(Ctxt( - "Bounding rectangle has no area")); - } - - // The offset and extent are relative to the entire global output plane. - const types::RowCol boundingOffset(types::RowCol(minRowI, minColI)); - const types::RowCol boundingExtent(maxRowI - minRowI + 1, - maxColI - minColI + 1); - - // Get the PolygonMas. For each row of the polygon this will determine - // the first and last column of the row inside the convex hull of the - // polygon sent in. - const polygon::PolygonMask polygonMask(polygon, fullExtent); - - // Compute a delta in the row direction as if the entire bounding row - // extent will be covered by the point grid. - const double initialDeltaRow = - static_cast(boundingExtent.row - 1) / static_cast(numPoints1D - 1); - - // Scale factor for shrinking the row extent. - constexpr double shrinkFactor = 0.1; - - // Shring the row extent a bit. - const double deltaToRemove = initialDeltaRow * shrinkFactor; - - // Get the new row start and end values. - const size_t newStartRow = gsl::narrow_cast( - std::ceil(boundingOffset.row + deltaToRemove)); - const size_t newEndRow = gsl::narrow_cast( - std::floor(boundingOffset.row + static_cast(boundingExtent.row) - 1 - - deltaToRemove)); - - // Check the new row extent. - if (newStartRow > newEndRow) - { - throw except::Exception(Ctxt( - "New bounding rectangle has no area")); - } - - // Compute the row exent. - const size_t newExtentRow = (newEndRow - newStartRow + 1); - - // Compute the delta in the row direction for the new extent. - const double newDeltaRow = - static_cast(newExtentRow - 1) / - static_cast(numPoints1D - 1); - - double currentOffsetRow = static_cast(newStartRow); - for (size_t ii = 0; ii < numPoints1D; ++ii, currentOffsetRow += newDeltaRow) - { - const double currentRow = std::floor(currentOffsetRow); - const auto row = gsl::narrow_cast(currentRow); - - // Get the start column and number of columns inside the polygon row - // the current row. - const types::Range colRange = polygonMask.getRange(row); - - // Check that there are internal points. - if (colRange.mNumElements == 0) - { - throw except::Exception(Ctxt( - "Column range has no elements")); - } - - // Compute the delta in the column direction to cover the internal - // points. - const double newDeltaCol = - static_cast(colRange.mNumElements - 1) / - static_cast(numPoints1D - 1); - - double currentCol = static_cast(colRange.mStartElement); - for (size_t jj = 0; jj < numPoints1D; ++jj, currentCol += newDeltaCol) - { - const types::RowCol currentOffset(currentRow, currentCol); - projectToSlantPlane(projModel, gridTransform, outPixelStart, - currentOffset, ii, jj); - } - } -} - -void ProjectionPolynomialFitter::projectToSlantPlane( - const ProjectionModel& projModel, - const GridECEFTransform& gridTransform, - const types::RowCol& outPixelStart, - const types::RowCol& currentOffset, - size_t row, - size_t col) -{ - // Get the coordinate relative to the outPixelStart. - mOutputPlaneRows(row, col) = currentOffset.row - outPixelStart.row; - mOutputPlaneCols(row, col) = currentOffset.col - outPixelStart.col; - - // Find ECEF of the output plane pixel. - const scene::Vector3 ecef = - gridTransform.rowColToECEF(currentOffset); - - // Project ECEF coordinate into the slant plane and get meters from - // the slant plane scene center point. - double timeCOA(0.0); - mSceneCoordinates(row, col) = projModel.sceneToImage(ecef, &timeCOA); - mTimeCOA(row, col) = timeCOA; -} - -void ProjectionPolynomialFitter::getSlantPlaneSamples( - const types::RowCol& inPixelStart, - const types::RowCol& inSceneCenter, - const types::RowCol& interimSceneCenter, - const types::RowCol& interimSampleSpacing, - math::linear::Matrix2D& slantPlaneRows, - math::linear::Matrix2D& slantPlaneCols) const -{ - const types::RowCol ratio(interimSceneCenter / inSceneCenter); - - const types::RowCol aoiOffset(static_cast(inPixelStart.row) * ratio.row, - static_cast(inPixelStart.col) * ratio.col); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - // sceneCoord is in meters from the slant plane SCP - // So, divide by the sample spacing to get it in pixels, then - // offset by the slant plane SCP pixel. Need to further offset to - // take non-zero inPixelStart into account. - const types::RowCol sceneCoord(mSceneCoordinates(ii, jj)); - - slantPlaneRows(ii, jj) = - sceneCoord.row / interimSampleSpacing.row + - interimSceneCenter.row - aoiOffset.row; - - slantPlaneCols(ii, jj) = - sceneCoord.col / interimSampleSpacing.col + - interimSceneCenter.col - aoiOffset.col; - } - } -} - -void ProjectionPolynomialFitter::fitOutputToSlantPolynomials( - const types::RowCol& inPixelStart, - const types::RowCol& inSceneCenter, - const types::RowCol& interimSceneCenter, - const types::RowCol& interimSampleSpacing, - size_t polyOrderX, - size_t polyOrderY, - math::poly::TwoD& outputToSlantRow, - math::poly::TwoD& outputToSlantCol, - double* meanResidualErrorRow, - double* meanResidualErrorCol) const -{ - // Collect up slant plane pixel locations for the output plane samples we - // have - math::linear::Matrix2D slantPlaneRows(mNumPoints1D, mNumPoints1D); - math::linear::Matrix2D slantPlaneCols(mNumPoints1D, mNumPoints1D); - getSlantPlaneSamples(inPixelStart, - inSceneCenter, - interimSceneCenter, - interimSampleSpacing, - slantPlaneRows, - slantPlaneCols); - - // Now fit the polynomials - outputToSlantRow = math::poly::fit(mOutputPlaneRows, - mOutputPlaneCols, - slantPlaneRows, - polyOrderX, polyOrderY); - - outputToSlantCol = math::poly::fit(mOutputPlaneRows, - mOutputPlaneCols, - slantPlaneCols, - polyOrderX, polyOrderY); - - // Optionally report the residual error - if (meanResidualErrorRow || meanResidualErrorCol) - { - double errorSumRow(0.0); - double errorSumCol(0.0); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - const double row(mOutputPlaneRows(ii, jj)); - const double col(mOutputPlaneCols(ii, jj)); - - double diff = - slantPlaneRows(ii, jj) - outputToSlantRow(row, col); - errorSumRow += diff * diff; - - diff = slantPlaneCols(ii, jj) - outputToSlantCol(row, col); - errorSumCol += diff * diff; - } - } - - const auto numPoints = static_cast(mNumPoints1D * mNumPoints1D); - if (meanResidualErrorRow) - { - *meanResidualErrorRow = errorSumRow / numPoints; - } - if (meanResidualErrorCol) - { - *meanResidualErrorCol = errorSumCol / numPoints; - } - } -} - -void ProjectionPolynomialFitter::fitSlantToOutputPolynomials( - const types::RowCol& inPixelStart, - const types::RowCol& inSceneCenter, - const types::RowCol& interimSceneCenter, - const types::RowCol& interimSampleSpacing, - size_t polyOrderX, - size_t polyOrderY, - math::poly::TwoD& slantToOutputRow, - math::poly::TwoD& slantToOutputCol, - double* meanResidualErrorRow, - double* meanResidualErrorCol) const -{ - // Collect up slant plane pixel locations for the output plane samples we - // have - math::linear::Matrix2D slantPlaneRows(mNumPoints1D, mNumPoints1D); - math::linear::Matrix2D slantPlaneCols(mNumPoints1D, mNumPoints1D); - getSlantPlaneSamples(inPixelStart, - inSceneCenter, - interimSceneCenter, - interimSampleSpacing, - slantPlaneRows, - slantPlaneCols); - - // Now fit the polynomials - slantToOutputRow = math::poly::fit(slantPlaneRows, - slantPlaneCols, - mOutputPlaneRows, - polyOrderX, polyOrderY); - - slantToOutputCol = math::poly::fit(slantPlaneRows, - slantPlaneCols, - mOutputPlaneCols, - polyOrderX, polyOrderY); - - // Optionally report the residual error - if (meanResidualErrorRow || meanResidualErrorCol) - { - double errorSumRow(0.0); - double errorSumCol(0.0); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - const double row(slantPlaneRows(ii, jj)); - const double col(slantPlaneCols(ii, jj)); - - double diff = - mOutputPlaneRows(ii, jj) - slantToOutputRow(row, col); - errorSumRow += diff * diff; - - diff = mOutputPlaneCols(ii, jj) - slantToOutputCol(row, col); - errorSumCol += diff * diff; - } - } - - const auto numPoints = static_cast(mNumPoints1D * mNumPoints1D); - if (meanResidualErrorRow) - { - *meanResidualErrorRow = errorSumRow / numPoints; - } - if (meanResidualErrorCol) - { - *meanResidualErrorCol = errorSumCol / numPoints; - } - } -} - -void ProjectionPolynomialFitter::fitTimeCOAPolynomial( - const types::RowCol& outSceneCenter, - const types::RowCol& outSampleSpacing, - size_t polyOrderX, - size_t polyOrderY, - math::poly::TwoD& timeCOAPoly, - double* meanResidualError) const -{ - math::linear::Matrix2D rowMapping(mNumPoints1D, mNumPoints1D); - math::linear::Matrix2D colMapping(mNumPoints1D, mNumPoints1D); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - // Need to map output plane pixels to meters from the output - // plane SCP - rowMapping(ii, jj) = - (mOutputPlaneRows(ii,jj) - outSceneCenter.row) * - outSampleSpacing.row; - - colMapping(ii, jj) = - (mOutputPlaneCols(ii,jj) - outSceneCenter.col) * - outSampleSpacing.col; - } - } - - // Now fit the polynomial - timeCOAPoly = math::poly::fit(rowMapping, colMapping, mTimeCOA, - polyOrderX, polyOrderY); - - // Optionally report the residual error - if (meanResidualError) - { - double errorSum(0.0); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - const double row(rowMapping(ii, jj)); - const double col(colMapping(ii, jj)); - - const double diff = mTimeCOA(ii, jj) - timeCOAPoly(row, col); - errorSum += diff * diff; - } - } - - *meanResidualError = errorSum / static_cast(mNumPoints1D * mNumPoints1D); - } -} - -void ProjectionPolynomialFitter::fitPixelBasedTimeCOAPolynomial( - const types::RowCol& outPixelShift, - size_t polyOrderX, - size_t polyOrderY, - math::poly::TwoD& timeCOAPoly, - double* meanResidualError) const -{ - fitPixelBasedTimeCOAPolynomial(Shift(outPixelShift.row), - Shift(outPixelShift.col), - polyOrderX, - polyOrderY, - timeCOAPoly, - meanResidualError); -} -} +/* ========================================================================= + * This file is part of scene-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * scene-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include + +#include +#include + +#undef min +#undef max + +namespace +{ +struct Shift final +{ + Shift(double shift) : + mShift(shift) + { + } + Shift(const Shift& other) = delete; + Shift& operator=(const Shift& other) = delete; + + inline double operator()(double input) const + { + return (input - mShift); + } + +private: + const double mShift; +}; +} + +namespace scene +{ +const size_t ProjectionPolynomialFitter::DEFAULTS_POINTS_1D = 10; + +ProjectionPolynomialFitter::ProjectionPolynomialFitter( + const ProjectionModel& projModel, + const GridECEFTransform& gridTransform, + const types::RowCol& outPixelStart, + const types::RowCol& outExtent, + size_t numPoints1D) : + mNumPoints1D(numPoints1D), + mOutputPlaneRows(numPoints1D, numPoints1D), + mOutputPlaneCols(numPoints1D, numPoints1D), + mSceneCoordinates(numPoints1D, + numPoints1D, + types::RowCol(0.0, 0.0)), + mTimeCOA(numPoints1D, numPoints1D) +{ + // Want to sample [outPixelStart, outPixelStart + outExtent) in the loop + // below. That is, we are marching through the portion of interest of the + // output grid in pixel space. In the case of multi-segment SICDs, we'll + // only sample our part of the grid defined by outPixelStart and + // outExtent. + const types::RowCol skip( + static_cast(outExtent.row - 1) / static_cast(mNumPoints1D - 1), + static_cast(outExtent.col - 1) / static_cast(mNumPoints1D - 1)); + + types::RowCol currentOffset(outPixelStart); + + for (size_t ii = 0; + ii < mNumPoints1D; + ++ii, currentOffset.row += skip.row) + { + currentOffset.col = outPixelStart.col; + + for (size_t jj = 0; + jj < mNumPoints1D; + ++jj, currentOffset.col += skip.col) + { + projectToSlantPlane(projModel, gridTransform, outPixelStart, + currentOffset, ii, jj); + } + } +} + +ProjectionPolynomialFitter::ProjectionPolynomialFitter( + const ProjectionModel& projModel, + const GridECEFTransform& gridTransform, + const types::RowCol& fullExtent, + const types::RowCol& outPixelStart, + const types::RowCol& /*outExtent*/, + const std::vector >& polygon, + size_t numPoints1D) : + mNumPoints1D(numPoints1D), + mOutputPlaneRows(numPoints1D, numPoints1D), + mOutputPlaneCols(numPoints1D, numPoints1D), + mSceneCoordinates(numPoints1D, + numPoints1D, + types::RowCol(0.0, 0.0)), + mTimeCOA(numPoints1D, numPoints1D) +{ + // Get bounding rectangle of output plane polygon. + double minRow = std::numeric_limits::max(); + double maxRow = -std::numeric_limits::max(); + double minCol = std::numeric_limits::max(); + double maxCol = -std::numeric_limits::max(); + + for (size_t ii = 0; ii < polygon.size(); ++ii) + { + minRow = std::min(minRow, polygon[ii].row); + maxRow = std::max(maxRow, polygon[ii].row); + minCol = std::min(minCol, polygon[ii].col); + maxCol = std::max(maxCol, polygon[ii].col); + } + + if (minRow > static_cast(fullExtent.row) || + maxRow < 0 || + minCol > static_cast(fullExtent.col) || + maxCol < 0) + { + throw except::Exception(Ctxt( + "Bounding rectangle is outside of output extent")); + } + + // Only interested in pixels inside the fullExtent. + minRow = std::max(minRow, 0.0); + minCol = std::max(minCol, 0.0); + maxRow = std::min(maxRow, static_cast(fullExtent.row) - 1); + maxCol = std::min(maxCol, static_cast(fullExtent.col) - 1); + + // Get size_t extent of the set of points. + const auto minRowI = gsl::narrow_cast(std::ceil(minRow)); + const auto minColI = gsl::narrow_cast(std::ceil(minCol)); + const auto maxRowI = gsl::narrow_cast(std::floor(maxRow)); + const auto maxColI = gsl::narrow_cast(std::floor(maxCol)); + + if (minRowI > maxRowI || minColI > maxColI) + { + throw except::Exception(Ctxt( + "Bounding rectangle has no area")); + } + + // The offset and extent are relative to the entire global output plane. + const types::RowCol boundingOffset(types::RowCol(minRowI, minColI)); + const types::RowCol boundingExtent(maxRowI - minRowI + 1, + maxColI - minColI + 1); + + // Get the PolygonMas. For each row of the polygon this will determine + // the first and last column of the row inside the convex hull of the + // polygon sent in. + const polygon::PolygonMask polygonMask(polygon, fullExtent); + + // Compute a delta in the row direction as if the entire bounding row + // extent will be covered by the point grid. + const double initialDeltaRow = + static_cast(boundingExtent.row - 1) / static_cast(numPoints1D - 1); + + // Scale factor for shrinking the row extent. + constexpr double shrinkFactor = 0.1; + + // Shring the row extent a bit. + const double deltaToRemove = initialDeltaRow * shrinkFactor; + + // Get the new row start and end values. + const size_t newStartRow = gsl::narrow_cast( + std::ceil(boundingOffset.row + deltaToRemove)); + const size_t newEndRow = gsl::narrow_cast( + std::floor(boundingOffset.row + static_cast(boundingExtent.row) - 1 - + deltaToRemove)); + + // Check the new row extent. + if (newStartRow > newEndRow) + { + throw except::Exception(Ctxt( + "New bounding rectangle has no area")); + } + + // Compute the row exent. + const size_t newExtentRow = (newEndRow - newStartRow + 1); + + // Compute the delta in the row direction for the new extent. + const double newDeltaRow = + static_cast(newExtentRow - 1) / + static_cast(numPoints1D - 1); + + double currentOffsetRow = static_cast(newStartRow); + for (size_t ii = 0; ii < numPoints1D; ++ii, currentOffsetRow += newDeltaRow) + { + const double currentRow = std::floor(currentOffsetRow); + const auto row = gsl::narrow_cast(currentRow); + + // Get the start column and number of columns inside the polygon row + // the current row. + const types::Range colRange = polygonMask.getRange(row); + + // Check that there are internal points. + if (colRange.mNumElements == 0) + { + throw except::Exception(Ctxt( + "Column range has no elements")); + } + + // Compute the delta in the column direction to cover the internal + // points. + const double newDeltaCol = + static_cast(colRange.mNumElements - 1) / + static_cast(numPoints1D - 1); + + double currentCol = static_cast(colRange.mStartElement); + for (size_t jj = 0; jj < numPoints1D; ++jj, currentCol += newDeltaCol) + { + const types::RowCol currentOffset(currentRow, currentCol); + projectToSlantPlane(projModel, gridTransform, outPixelStart, + currentOffset, ii, jj); + } + } +} + +void ProjectionPolynomialFitter::projectToSlantPlane( + const ProjectionModel& projModel, + const GridECEFTransform& gridTransform, + const types::RowCol& outPixelStart, + const types::RowCol& currentOffset, + size_t row, + size_t col) +{ + // Get the coordinate relative to the outPixelStart. + mOutputPlaneRows(row, col) = currentOffset.row - outPixelStart.row; + mOutputPlaneCols(row, col) = currentOffset.col - outPixelStart.col; + + // Find ECEF of the output plane pixel. + const scene::Vector3 ecef = + gridTransform.rowColToECEF(currentOffset); + + // Project ECEF coordinate into the slant plane and get meters from + // the slant plane scene center point. + double timeCOA(0.0); + mSceneCoordinates(row, col) = projModel.sceneToImage(ecef, &timeCOA); + mTimeCOA(row, col) = timeCOA; +} + +void ProjectionPolynomialFitter::getSlantPlaneSamples( + const types::RowCol& inPixelStart, + const types::RowCol& inSceneCenter, + const types::RowCol& interimSceneCenter, + const types::RowCol& interimSampleSpacing, + math::linear::Matrix2D& slantPlaneRows, + math::linear::Matrix2D& slantPlaneCols) const +{ + const types::RowCol ratio(interimSceneCenter / inSceneCenter); + + const types::RowCol aoiOffset(static_cast(inPixelStart.row) * ratio.row, + static_cast(inPixelStart.col) * ratio.col); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + // sceneCoord is in meters from the slant plane SCP + // So, divide by the sample spacing to get it in pixels, then + // offset by the slant plane SCP pixel. Need to further offset to + // take non-zero inPixelStart into account. + const types::RowCol sceneCoord(mSceneCoordinates(ii, jj)); + + slantPlaneRows(ii, jj) = + sceneCoord.row / interimSampleSpacing.row + + interimSceneCenter.row - aoiOffset.row; + + slantPlaneCols(ii, jj) = + sceneCoord.col / interimSampleSpacing.col + + interimSceneCenter.col - aoiOffset.col; + } + } +} + +void ProjectionPolynomialFitter::fitOutputToSlantPolynomials( + const types::RowCol& inPixelStart, + const types::RowCol& inSceneCenter, + const types::RowCol& interimSceneCenter, + const types::RowCol& interimSampleSpacing, + size_t polyOrderX, + size_t polyOrderY, + math::poly::TwoD& outputToSlantRow, + math::poly::TwoD& outputToSlantCol, + double* meanResidualErrorRow, + double* meanResidualErrorCol) const +{ + // Collect up slant plane pixel locations for the output plane samples we + // have + math::linear::Matrix2D slantPlaneRows(mNumPoints1D, mNumPoints1D); + math::linear::Matrix2D slantPlaneCols(mNumPoints1D, mNumPoints1D); + getSlantPlaneSamples(inPixelStart, + inSceneCenter, + interimSceneCenter, + interimSampleSpacing, + slantPlaneRows, + slantPlaneCols); + + // Now fit the polynomials + outputToSlantRow = math::poly::fit(mOutputPlaneRows, + mOutputPlaneCols, + slantPlaneRows, + polyOrderX, polyOrderY); + + outputToSlantCol = math::poly::fit(mOutputPlaneRows, + mOutputPlaneCols, + slantPlaneCols, + polyOrderX, polyOrderY); + + // Optionally report the residual error + if (meanResidualErrorRow || meanResidualErrorCol) + { + double errorSumRow(0.0); + double errorSumCol(0.0); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + const double row(mOutputPlaneRows(ii, jj)); + const double col(mOutputPlaneCols(ii, jj)); + + double diff = + slantPlaneRows(ii, jj) - outputToSlantRow(row, col); + errorSumRow += diff * diff; + + diff = slantPlaneCols(ii, jj) - outputToSlantCol(row, col); + errorSumCol += diff * diff; + } + } + + const auto numPoints = static_cast(mNumPoints1D * mNumPoints1D); + if (meanResidualErrorRow) + { + *meanResidualErrorRow = errorSumRow / numPoints; + } + if (meanResidualErrorCol) + { + *meanResidualErrorCol = errorSumCol / numPoints; + } + } +} + +void ProjectionPolynomialFitter::fitSlantToOutputPolynomials( + const types::RowCol& inPixelStart, + const types::RowCol& inSceneCenter, + const types::RowCol& interimSceneCenter, + const types::RowCol& interimSampleSpacing, + size_t polyOrderX, + size_t polyOrderY, + math::poly::TwoD& slantToOutputRow, + math::poly::TwoD& slantToOutputCol, + double* meanResidualErrorRow, + double* meanResidualErrorCol) const +{ + // Collect up slant plane pixel locations for the output plane samples we + // have + math::linear::Matrix2D slantPlaneRows(mNumPoints1D, mNumPoints1D); + math::linear::Matrix2D slantPlaneCols(mNumPoints1D, mNumPoints1D); + getSlantPlaneSamples(inPixelStart, + inSceneCenter, + interimSceneCenter, + interimSampleSpacing, + slantPlaneRows, + slantPlaneCols); + + // Now fit the polynomials + slantToOutputRow = math::poly::fit(slantPlaneRows, + slantPlaneCols, + mOutputPlaneRows, + polyOrderX, polyOrderY); + + slantToOutputCol = math::poly::fit(slantPlaneRows, + slantPlaneCols, + mOutputPlaneCols, + polyOrderX, polyOrderY); + + // Optionally report the residual error + if (meanResidualErrorRow || meanResidualErrorCol) + { + double errorSumRow(0.0); + double errorSumCol(0.0); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + const double row(slantPlaneRows(ii, jj)); + const double col(slantPlaneCols(ii, jj)); + + double diff = + mOutputPlaneRows(ii, jj) - slantToOutputRow(row, col); + errorSumRow += diff * diff; + + diff = mOutputPlaneCols(ii, jj) - slantToOutputCol(row, col); + errorSumCol += diff * diff; + } + } + + const auto numPoints = static_cast(mNumPoints1D * mNumPoints1D); + if (meanResidualErrorRow) + { + *meanResidualErrorRow = errorSumRow / numPoints; + } + if (meanResidualErrorCol) + { + *meanResidualErrorCol = errorSumCol / numPoints; + } + } +} + +void ProjectionPolynomialFitter::fitTimeCOAPolynomial( + const types::RowCol& outSceneCenter, + const types::RowCol& outSampleSpacing, + size_t polyOrderX, + size_t polyOrderY, + math::poly::TwoD& timeCOAPoly, + double* meanResidualError) const +{ + math::linear::Matrix2D rowMapping(mNumPoints1D, mNumPoints1D); + math::linear::Matrix2D colMapping(mNumPoints1D, mNumPoints1D); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + // Need to map output plane pixels to meters from the output + // plane SCP + rowMapping(ii, jj) = + (mOutputPlaneRows(ii,jj) - outSceneCenter.row) * + outSampleSpacing.row; + + colMapping(ii, jj) = + (mOutputPlaneCols(ii,jj) - outSceneCenter.col) * + outSampleSpacing.col; + } + } + + // Now fit the polynomial + timeCOAPoly = math::poly::fit(rowMapping, colMapping, mTimeCOA, + polyOrderX, polyOrderY); + + // Optionally report the residual error + if (meanResidualError) + { + double errorSum(0.0); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + const double row(rowMapping(ii, jj)); + const double col(colMapping(ii, jj)); + + const double diff = mTimeCOA(ii, jj) - timeCOAPoly(row, col); + errorSum += diff * diff; + } + } + + *meanResidualError = errorSum / static_cast(mNumPoints1D * mNumPoints1D); + } +} + +void ProjectionPolynomialFitter::fitPixelBasedTimeCOAPolynomial( + const types::RowCol& outPixelShift, + size_t polyOrderX, + size_t polyOrderY, + math::poly::TwoD& timeCOAPoly, + double* meanResidualError) const +{ + fitPixelBasedTimeCOAPolynomial(Shift(outPixelShift.row), + Shift(outPixelShift.col), + polyOrderX, + polyOrderY, + timeCOAPoly, + meanResidualError); +} +} diff --git a/six/modules/c++/six.convert/six.convert.vcxproj b/six/modules/c++/six.convert/six.convert.vcxproj index 103c628b7a..f67abbbe44 100644 --- a/six/modules/c++/six.convert/six.convert.vcxproj +++ b/six/modules/c++/six.convert/six.convert.vcxproj @@ -1,138 +1,138 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - - - - - - - - - Create - Create - - - - - - - - {8f357a19-799e-4971-850e-3f28485c130b} - - - {1cfcde59-6410-4037-95eb-b37d31e10820} - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + + + + + + + + + Create + Create + + + + + + + + {8f357a19-799e-4971-850e-3f28485c130b} + + + {1cfcde59-6410-4037-95eb-b37d31e10820} + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + \ No newline at end of file diff --git a/six/modules/c++/six.ruleset b/six/modules/c++/six.ruleset index 5f1780c77b..f3bf8df8a1 100644 --- a/six/modules/c++/six.ruleset +++ b/six/modules/c++/six.ruleset @@ -1,32 +1,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/six/modules/c++/six.sicd/include/six/sicd/ImageCreation.h b/six/modules/c++/six.sicd/include/six/sicd/ImageCreation.h index a632c4bc11..c368953555 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/ImageCreation.h +++ b/six/modules/c++/six.sicd/include/six/sicd/ImageCreation.h @@ -19,67 +19,67 @@ * see . * */ -#ifndef __SIX_IMAGE_CREATION_H__ -#define __SIX_IMAGE_CREATION_H__ - -#include "six/Types.h" - -namespace six -{ -namespace sicd -{ -/*! - * \struct ImageCreation - * \brief Contains SICD ImageCreation parameters - * - * The ImageCreation block is the first sub-block under the 'SICD' - * tag. It is optional altogether, and contains, information about - * the image creation (and processing). - */ -struct ImageCreation -{ - /*! - * (Optional) The name and version of the application used to - * create the image - */ - std::string application; - - /*! - * (Optional) Date and time that the image creation application - * processed the image (UTC) - */ - DateTime dateTime; - - /*! - * (Optional) The creation site of this SICD product - */ - std::string site; - - /*! - * (Optional) Identifies what profile was used to create this - * SICD product - */ - std::string profile; - - ImageCreation* clone() const - { - return new ImageCreation(*this); - } - - //! Equality operator - bool operator==(const ImageCreation& rhs) const - { - return (application == rhs.application && - dateTime == rhs.dateTime && site == rhs.site && - profile == rhs.profile); - } - bool operator!=(const ImageCreation& rhs) const - { - return !(*this == rhs); - } -}; - -} -} -#endif +#ifndef __SIX_IMAGE_CREATION_H__ +#define __SIX_IMAGE_CREATION_H__ + +#include "six/Types.h" + +namespace six +{ +namespace sicd +{ +/*! + * \struct ImageCreation + * \brief Contains SICD ImageCreation parameters + * + * The ImageCreation block is the first sub-block under the 'SICD' + * tag. It is optional altogether, and contains, information about + * the image creation (and processing). + */ +struct ImageCreation +{ + /*! + * (Optional) The name and version of the application used to + * create the image + */ + std::string application; + + /*! + * (Optional) Date and time that the image creation application + * processed the image (UTC) + */ + DateTime dateTime; + + /*! + * (Optional) The creation site of this SICD product + */ + std::string site; + + /*! + * (Optional) Identifies what profile was used to create this + * SICD product + */ + std::string profile; + + ImageCreation* clone() const + { + return new ImageCreation(*this); + } + + //! Equality operator + bool operator==(const ImageCreation& rhs) const + { + return (application == rhs.application && + dateTime == rhs.dateTime && site == rhs.site && + profile == rhs.profile); + } + bool operator!=(const ImageCreation& rhs) const + { + return !(*this == rhs); + } +}; + +} +} +#endif diff --git a/six/modules/c++/six.sicd/include/six/sicd/NITFReadComplexXMLControl.h b/six/modules/c++/six.sicd/include/six/sicd/NITFReadComplexXMLControl.h index 97f8ee03fc..331d49b3d0 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/NITFReadComplexXMLControl.h +++ b/six/modules/c++/six.sicd/include/six/sicd/NITFReadComplexXMLControl.h @@ -1,107 +1,107 @@ -/* ========================================================================= - * This file is part of six.sicd-c++ - * ========================================================================= - * - * (C) Copyright 2021 Maxar Technologies, Inc. - * - * six.sicd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#ifndef SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ -#define SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ -#pragma once - -#include -#include -#include -#include - -#include -#include - -#include "six/XMLControlFactory.h" -#include "six/NITFReadControl.h" -#include "six/Region.h" -#include "six/sicd/ComplexData.h" -#include "six/sicd/SICDMesh.h" - -namespace six -{ - namespace sicd - { - class NITFReadComplexXMLControl final - { - six::XMLControlRegistry xmlRegistry; - six::NITFReadControl reader; - - public: - NITFReadComplexXMLControl(); - ~NITFReadComplexXMLControl() = default; - NITFReadComplexXMLControl(const NITFReadComplexXMLControl&) = delete; - NITFReadComplexXMLControl& operator=(const NITFReadComplexXMLControl&) = delete; - NITFReadComplexXMLControl(NITFReadComplexXMLControl&&) = delete; - NITFReadComplexXMLControl& operator=(NITFReadComplexXMLControl&&) = delete; - - template - void addCreator() - { - xmlRegistry.addCreator(); - reader.setXMLControlRegistry(&xmlRegistry); - } - - const six::NITFReadControl& NITFReadControl() const { return reader; } - six::NITFReadControl& NITFReadControl() { return reader; } - - void load(const std::string& fromFile, const std::vector* pSchemaPaths); - void load(const std::filesystem::path& fromFile, const std::vector* pSchemaPaths); - template - void load(const TPath& fromFile, const std::vector& schemaPaths) - { - load(fromFile, &schemaPaths); - } - void load(const std::filesystem::path& fromFile) - { - load(fromFile, nullptr /*schemaPaths*/); - } - - void load(io::FileInputStream&, const std::vector* pSchemaPaths); - void load(io::FileInputStream&, const std::vector* pSchemaPaths); - template - void load(io::FileInputStream& fis, const std::vector& schemaPaths) - { - load(fis, &schemaPaths); - } - - std::shared_ptr getContainer() const; - std::shared_ptr getContainer(); - - std::unique_ptr getComplexData(); - - std::vector getWidebandData(const ComplexData&); - void getWidebandData(const ComplexData&, const types::RowCol& offset, const types::RowCol& extent, - six::zfloat* buffer); - - void getMeshes(std::unique_ptr&, std::unique_ptr&) const; - - void setXMLControlRegistry(); - void setLogger(); - - void interleaved(Region& region); - std::vector interleaved(); - }; - } -} - +/* ========================================================================= + * This file is part of six.sicd-c++ + * ========================================================================= + * + * (C) Copyright 2021 Maxar Technologies, Inc. + * + * six.sicd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#ifndef SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ +#define SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ +#pragma once + +#include +#include +#include +#include + +#include +#include + +#include "six/XMLControlFactory.h" +#include "six/NITFReadControl.h" +#include "six/Region.h" +#include "six/sicd/ComplexData.h" +#include "six/sicd/SICDMesh.h" + +namespace six +{ + namespace sicd + { + class NITFReadComplexXMLControl final + { + six::XMLControlRegistry xmlRegistry; + six::NITFReadControl reader; + + public: + NITFReadComplexXMLControl(); + ~NITFReadComplexXMLControl() = default; + NITFReadComplexXMLControl(const NITFReadComplexXMLControl&) = delete; + NITFReadComplexXMLControl& operator=(const NITFReadComplexXMLControl&) = delete; + NITFReadComplexXMLControl(NITFReadComplexXMLControl&&) = delete; + NITFReadComplexXMLControl& operator=(NITFReadComplexXMLControl&&) = delete; + + template + void addCreator() + { + xmlRegistry.addCreator(); + reader.setXMLControlRegistry(&xmlRegistry); + } + + const six::NITFReadControl& NITFReadControl() const { return reader; } + six::NITFReadControl& NITFReadControl() { return reader; } + + void load(const std::string& fromFile, const std::vector* pSchemaPaths); + void load(const std::filesystem::path& fromFile, const std::vector* pSchemaPaths); + template + void load(const TPath& fromFile, const std::vector& schemaPaths) + { + load(fromFile, &schemaPaths); + } + void load(const std::filesystem::path& fromFile) + { + load(fromFile, nullptr /*schemaPaths*/); + } + + void load(io::FileInputStream&, const std::vector* pSchemaPaths); + void load(io::FileInputStream&, const std::vector* pSchemaPaths); + template + void load(io::FileInputStream& fis, const std::vector& schemaPaths) + { + load(fis, &schemaPaths); + } + + std::shared_ptr getContainer() const; + std::shared_ptr getContainer(); + + std::unique_ptr getComplexData(); + + std::vector getWidebandData(const ComplexData&); + void getWidebandData(const ComplexData&, const types::RowCol& offset, const types::RowCol& extent, + six::zfloat* buffer); + + void getMeshes(std::unique_ptr&, std::unique_ptr&) const; + + void setXMLControlRegistry(); + void setLogger(); + + void interleaved(Region& region); + std::vector interleaved(); + }; + } +} + #endif // SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ \ No newline at end of file diff --git a/six/modules/c++/six.sicd/include/six/sicd/PFA.h b/six/modules/c++/six.sicd/include/six/sicd/PFA.h index bd44dca4db..a9ea0dc513 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/PFA.h +++ b/six/modules/c++/six.sicd/include/six/sicd/PFA.h @@ -19,134 +19,134 @@ * see . * */ -#ifndef __SIX_PFA_H__ -#define __SIX_PFA_H__ - -#include "logging/Logger.h" -#include "six/Types.h" -#include "six/Init.h" -#include "six/Parameter.h" +#ifndef __SIX_PFA_H__ +#define __SIX_PFA_H__ + +#include "logging/Logger.h" +#include "six/Types.h" +#include "six/Init.h" +#include "six/Parameter.h" #include "six/sicd/GeoData.h" #include "six/sicd/Position.h" #include "six/sicd/SCPCOA.h" - -namespace six -{ -namespace sicd -{ -struct Grid; -/*! - * \struct SlowTimeDeskew - * \brief SICD STDeskew - * - * Parameters to describe image domain slow time - * deskew processing. Name changed for API consistency - */ -struct SlowTimeDeskew -{ - //! Constructor - SlowTimeDeskew(); - - //! Was slow time deskew phase function applied? - BooleanType applied; - - //! Slow time deskew phase function to perform the slow-time/Kaz - //! shift. 2D poly function of image range coord and az coord - Poly2D slowTimeDeskewPhasePoly; - - //! Equality operator - bool operator==(const SlowTimeDeskew& rhs) const - { - return (applied == rhs.applied && - slowTimeDeskewPhasePoly == rhs.slowTimeDeskewPhasePoly); - } - - bool operator!=(const SlowTimeDeskew& rhs) const - { - return !(*this == rhs); - } -}; - -/*! - * \struct PFA - * \brief SICD Polar format algorithm block - * - * Parameters used when the image is formed using the polar format - * algorithm (imageFormationAlgorithm = PFA). - * - * \note This is currently limited to a one item choice in SICD, - * which would make it hard to do anything else - */ -struct PFA -{ - //! Constructor, nothing defined - PFA(); - - /*! - * SICD FPN parameter. - * Focus plane normal (ECEF), pointing away from center of earth - */ - Vector3 focusPlaneNormal; - - /*! - * SICD IPN parameter. - * Image formation plane normal pointing away from center of earth - */ - Vector3 imagePlaneNormal; - - /*! - * SICD PolarAngRefTime (name change for API consistency) - * Polar image formation ref. time. Polar angle = 0 at the ref time - * Measured relative to collect start. Ref time is typically set - * to SCP COA time but may be different - */ - double polarAngleRefTime; - - /*! - * SICD PolarAngPoly (name change for API consistency) - * Poly that yields polar angle in radians as a function of slow time - * IOW, Time (sec) -> Polar angle (radians) - */ - Poly1D polarAnglePoly; - - /*! - * SICD SpatialFreqSFPoly parametr (name change for API consistency) - * Poly that yields the spatial frequency scale factor as a function - * of Polar angle - * Polar angle (radians) -> KSF - */ - Poly1D spatialFrequencyScaleFactorPoly; - - //! Minimum range spatial freq (Krg) output from polar->rect resampling - double krg1; - - //! Maximum range spatial freq (Krg) output from polar->rect resampling - double krg2; - - //! Minimum az spatial freq output from polar->rect resampling - double kaz1; - - //! Minimum az spatial freq output from polar->rect resampling - double kaz2; - - //! SICD STDeskew parameter - mem::ScopedCopyablePtr slowTimeDeskew; - - //! Equality operator - bool operator==(const PFA& rhs) const; - bool operator!=(const PFA& rhs) const - { - return !(*this == rhs); - } - - void fillDerivedFields(const Position& position); - void fillDefaultFields(const GeoData& geoData, const Grid&, - const SCPCOA& scpcoa); - - bool validate(const SCPCOA& scpcoa, logging::Logger& log); -}; - -} -} -#endif + +namespace six +{ +namespace sicd +{ +struct Grid; +/*! + * \struct SlowTimeDeskew + * \brief SICD STDeskew + * + * Parameters to describe image domain slow time + * deskew processing. Name changed for API consistency + */ +struct SlowTimeDeskew +{ + //! Constructor + SlowTimeDeskew(); + + //! Was slow time deskew phase function applied? + BooleanType applied; + + //! Slow time deskew phase function to perform the slow-time/Kaz + //! shift. 2D poly function of image range coord and az coord + Poly2D slowTimeDeskewPhasePoly; + + //! Equality operator + bool operator==(const SlowTimeDeskew& rhs) const + { + return (applied == rhs.applied && + slowTimeDeskewPhasePoly == rhs.slowTimeDeskewPhasePoly); + } + + bool operator!=(const SlowTimeDeskew& rhs) const + { + return !(*this == rhs); + } +}; + +/*! + * \struct PFA + * \brief SICD Polar format algorithm block + * + * Parameters used when the image is formed using the polar format + * algorithm (imageFormationAlgorithm = PFA). + * + * \note This is currently limited to a one item choice in SICD, + * which would make it hard to do anything else + */ +struct PFA +{ + //! Constructor, nothing defined + PFA(); + + /*! + * SICD FPN parameter. + * Focus plane normal (ECEF), pointing away from center of earth + */ + Vector3 focusPlaneNormal; + + /*! + * SICD IPN parameter. + * Image formation plane normal pointing away from center of earth + */ + Vector3 imagePlaneNormal; + + /*! + * SICD PolarAngRefTime (name change for API consistency) + * Polar image formation ref. time. Polar angle = 0 at the ref time + * Measured relative to collect start. Ref time is typically set + * to SCP COA time but may be different + */ + double polarAngleRefTime; + + /*! + * SICD PolarAngPoly (name change for API consistency) + * Poly that yields polar angle in radians as a function of slow time + * IOW, Time (sec) -> Polar angle (radians) + */ + Poly1D polarAnglePoly; + + /*! + * SICD SpatialFreqSFPoly parametr (name change for API consistency) + * Poly that yields the spatial frequency scale factor as a function + * of Polar angle + * Polar angle (radians) -> KSF + */ + Poly1D spatialFrequencyScaleFactorPoly; + + //! Minimum range spatial freq (Krg) output from polar->rect resampling + double krg1; + + //! Maximum range spatial freq (Krg) output from polar->rect resampling + double krg2; + + //! Minimum az spatial freq output from polar->rect resampling + double kaz1; + + //! Minimum az spatial freq output from polar->rect resampling + double kaz2; + + //! SICD STDeskew parameter + mem::ScopedCopyablePtr slowTimeDeskew; + + //! Equality operator + bool operator==(const PFA& rhs) const; + bool operator!=(const PFA& rhs) const + { + return !(*this == rhs); + } + + void fillDerivedFields(const Position& position); + void fillDefaultFields(const GeoData& geoData, const Grid&, + const SCPCOA& scpcoa); + + bool validate(const SCPCOA& scpcoa, logging::Logger& log); +}; + +} +} +#endif diff --git a/six/modules/c++/six.sicd/include/six/sicd/Position.h b/six/modules/c++/six.sicd/include/six/sicd/Position.h index 7b63c2e682..efb8c3e088 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/Position.h +++ b/six/modules/c++/six.sicd/include/six/sicd/Position.h @@ -19,103 +19,103 @@ * see . * */ -#ifndef __SIX_POSITION_H__ -#define __SIX_POSITION_H__ +#ifndef __SIX_POSITION_H__ +#define __SIX_POSITION_H__ #include -#include -#include "six/Types.h" -#include "six/Init.h" -#include "six/Parameter.h" - -namespace six -{ -namespace sicd -{ -struct SCPCOA; - -/*! - * \struct RcvAPC - * \brief SICD RcvAPC - * - * Receive aperture phase center (APC). The size of the vector - * of the vector the number of receive APC polys - */ -struct RcvAPC -{ - //! Constructor - RcvAPC() - { - } - - std::vector rcvAPCPolys; - - //! Equality operator - bool operator==(const RcvAPC& rhs) const - { - return rcvAPCPolys == rhs.rcvAPCPolys; - } - - bool operator!=(const RcvAPC& rhs) const - { - return !(*this == rhs); - } -}; - -/*! - * \struct Position - * \brief SICD Position - * - * This block describes the platform and ground reference - * positions vs. time. - */ -struct Position -{ - /*! - * Aperture reference point as a function of time in ECEF meters - * t = 0 at collection start - */ - PolyXYZ arpPoly; - - /*! - * Ground reference point as a function of time in ECEF meters. - * t = 0 at collection start - */ - PolyXYZ grpPoly; - - /*! - * Transmit aperture phase center (APC) in ECEF as a function of time - * t = 0 at collection start. - * Always included for bistatic collections - */ - PolyXYZ txAPCPoly; - - /*! - * (Optional) Receive aperture phase center. - * - */ - mem::ScopedCopyablePtr rcvAPC; - - //! Constructor - Position(); - - //! Equality operator - bool operator==(const Position& rhs) const - { - return (arpPoly == rhs.arpPoly && grpPoly == rhs.grpPoly && - txAPCPoly == rhs.txAPCPoly && rcvAPC == rhs.rcvAPC); - } - - bool operator!=(const Position& rhs) const - { - return !(*this == rhs); - } - - void fillDerivedFields(const SCPCOA& scpcoa); - bool validate(logging::Logger& log) const; -}; - -} -} -#endif +#include +#include "six/Types.h" +#include "six/Init.h" +#include "six/Parameter.h" + +namespace six +{ +namespace sicd +{ +struct SCPCOA; + +/*! + * \struct RcvAPC + * \brief SICD RcvAPC + * + * Receive aperture phase center (APC). The size of the vector + * of the vector the number of receive APC polys + */ +struct RcvAPC +{ + //! Constructor + RcvAPC() + { + } + + std::vector rcvAPCPolys; + + //! Equality operator + bool operator==(const RcvAPC& rhs) const + { + return rcvAPCPolys == rhs.rcvAPCPolys; + } + + bool operator!=(const RcvAPC& rhs) const + { + return !(*this == rhs); + } +}; + +/*! + * \struct Position + * \brief SICD Position + * + * This block describes the platform and ground reference + * positions vs. time. + */ +struct Position +{ + /*! + * Aperture reference point as a function of time in ECEF meters + * t = 0 at collection start + */ + PolyXYZ arpPoly; + + /*! + * Ground reference point as a function of time in ECEF meters. + * t = 0 at collection start + */ + PolyXYZ grpPoly; + + /*! + * Transmit aperture phase center (APC) in ECEF as a function of time + * t = 0 at collection start. + * Always included for bistatic collections + */ + PolyXYZ txAPCPoly; + + /*! + * (Optional) Receive aperture phase center. + * + */ + mem::ScopedCopyablePtr rcvAPC; + + //! Constructor + Position(); + + //! Equality operator + bool operator==(const Position& rhs) const + { + return (arpPoly == rhs.arpPoly && grpPoly == rhs.grpPoly && + txAPCPoly == rhs.txAPCPoly && rcvAPC == rhs.rcvAPC); + } + + bool operator!=(const Position& rhs) const + { + return !(*this == rhs); + } + + void fillDerivedFields(const SCPCOA& scpcoa); + bool validate(logging::Logger& log) const; +}; + +} +} +#endif diff --git a/six/modules/c++/six.sicd/include/six/sicd/Timeline.h b/six/modules/c++/six.sicd/include/six/sicd/Timeline.h index 89e9cfdae7..fda8daffbc 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/Timeline.h +++ b/six/modules/c++/six.sicd/include/six/sicd/Timeline.h @@ -19,121 +19,121 @@ * see . * */ -#ifndef __SIX_TIMELINE_H__ -#define __SIX_TIMELINE_H__ - -#include -#include "six/Types.h" -#include "six/Init.h" -#include "six/Parameter.h" - -namespace six -{ -namespace sicd -{ -/*! - * \class TimelineSet - * \brief SICD/Timeline/IPP/Set parameters - * - * Identifies a set of IPP parameters. Minimum of 1 set of - * parameters are required for IPP - */ -struct TimelineSet +#ifndef __SIX_TIMELINE_H__ +#define __SIX_TIMELINE_H__ + +#include +#include "six/Types.h" +#include "six/Init.h" +#include "six/Parameter.h" + +namespace six +{ +namespace sicd +{ +/*! + * \class TimelineSet + * \brief SICD/Timeline/IPP/Set parameters + * + * Identifies a set of IPP parameters. Minimum of 1 set of + * parameters are required for IPP + */ +struct TimelineSet { //! Constructor TimelineSet(); - - //! Start time for the period relative to collect start - double tStart; - - //! End time for the period relative to collect start - double tEnd; - - //! Starting ipp index for the period described - int interPulsePeriodStart; - - //! Ending ipp index for the period described - int interPulsePeriodEnd; - - /*! - * ipp index poly coefs yield IPP index as a function of time t - * Starting tStart to tEnd - */ - Poly1D interPulsePeriodPoly; - - //! Equality operators - bool operator==(const TimelineSet& rhs) const; - bool operator!=(const TimelineSet& rhs) const - { - return !(*this == rhs); - } -}; - -/*! - * \class InterPulsePeriod - * \brief SICD 'IPP' parameter - * Describes the interpulse period (IPP) parameters. This section - * of SICD is optional, and contains one or more Sets (TimelineSet) - */ -struct InterPulsePeriod -{ - /*! - * Constructor. - */ - InterPulsePeriod() - { - } - - //! Vector of TimelineSet objects - std::vector sets; - - //! Equality operators - bool operator==(const InterPulsePeriod& rhs) const - { - return sets == rhs.sets; - } - - bool operator!=(const InterPulsePeriod& rhs) const - { - return !(*this == rhs); - } -}; - -/*! - * \struct Timeline - * \brief SICD Timeline block - * - * Describes the imaging collection timeline. This is a required block, - * and it requires that collectStart and collectDuration are written (or - * read). The IPP parameter (referred to here as interPulsePeriod) is - * optional. - * - */ -struct Timeline + + //! Start time for the period relative to collect start + double tStart; + + //! End time for the period relative to collect start + double tEnd; + + //! Starting ipp index for the period described + int interPulsePeriodStart; + + //! Ending ipp index for the period described + int interPulsePeriodEnd; + + /*! + * ipp index poly coefs yield IPP index as a function of time t + * Starting tStart to tEnd + */ + Poly1D interPulsePeriodPoly; + + //! Equality operators + bool operator==(const TimelineSet& rhs) const; + bool operator!=(const TimelineSet& rhs) const + { + return !(*this == rhs); + } +}; + +/*! + * \class InterPulsePeriod + * \brief SICD 'IPP' parameter + * Describes the interpulse period (IPP) parameters. This section + * of SICD is optional, and contains one or more Sets (TimelineSet) + */ +struct InterPulsePeriod +{ + /*! + * Constructor. + */ + InterPulsePeriod() + { + } + + //! Vector of TimelineSet objects + std::vector sets; + + //! Equality operators + bool operator==(const InterPulsePeriod& rhs) const + { + return sets == rhs.sets; + } + + bool operator!=(const InterPulsePeriod& rhs) const + { + return !(*this == rhs); + } +}; + +/*! + * \struct Timeline + * \brief SICD Timeline block + * + * Describes the imaging collection timeline. This is a required block, + * and it requires that collectStart and collectDuration are written (or + * read). The IPP parameter (referred to here as interPulsePeriod) is + * optional. + * + */ +struct Timeline { //! Constructor Timeline(); - - //! Collection date/time UTC, measured from collection start - DateTime collectStart; - - //! Duration of collection period - double collectDuration; - - //! Optional IPP parameter description - mem::ScopedCopyablePtr interPulsePeriod; - - bool operator==(const Timeline& rhs) const - { - return (collectStart == rhs.collectStart && collectDuration == rhs.collectDuration && - interPulsePeriod == rhs.interPulsePeriod); - } - bool operator!=(const Timeline& rhs) const - { - return !(*this == rhs); - } -}; -} -} -#endif + + //! Collection date/time UTC, measured from collection start + DateTime collectStart; + + //! Duration of collection period + double collectDuration; + + //! Optional IPP parameter description + mem::ScopedCopyablePtr interPulsePeriod; + + bool operator==(const Timeline& rhs) const + { + return (collectStart == rhs.collectStart && collectDuration == rhs.collectDuration && + interPulsePeriod == rhs.interPulsePeriod); + } + bool operator!=(const Timeline& rhs) const + { + return !(*this == rhs); + } +}; +} +} +#endif diff --git a/six/modules/c++/six.sicd/six.sicd.vcxproj b/six/modules/c++/six.sicd/six.sicd.vcxproj index 7434cba31e..d96c1fae45 100644 --- a/six/modules/c++/six.sicd/six.sicd.vcxproj +++ b/six/modules/c++/six.sicd/six.sicd.vcxproj @@ -1,198 +1,198 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - true - - - - - - - - - - - - - - - true - ..\six.ruleset - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {1cfcde59-6410-4037-95eb-b37d31e10820} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + v143 + true + + + + + + + + + + + + + + + true + ..\six.ruleset + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {1cfcde59-6410-4037-95eb-b37d31e10820} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + \ No newline at end of file diff --git a/six/modules/c++/six.sicd/six.sicd.vcxproj.filters b/six/modules/c++/six.sicd/six.sicd.vcxproj.filters index 3196090413..2517c17120 100644 --- a/six/modules/c++/six.sicd/six.sicd.vcxproj.filters +++ b/six/modules/c++/six.sicd/six.sicd.vcxproj.filters @@ -1,249 +1,249 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + \ No newline at end of file diff --git a/six/modules/c++/six.sicd/source/Grid.cpp b/six/modules/c++/six.sicd/source/Grid.cpp index fc4cf5bbc7..7c9ce29dfe 100644 --- a/six/modules/c++/six.sicd/source/Grid.cpp +++ b/six/modules/c++/six.sicd/source/Grid.cpp @@ -19,23 +19,23 @@ * see . * */ -#include "six/sicd/Grid.h" +#include "six/sicd/Grid.h" #include #include "six/sicd/GeoData.h" -#include "six/sicd/ImageData.h" -#include "six/sicd/PFA.h" -#include "six/sicd/SCPCOA.h" -#include "six/sicd/RadarCollection.h" -#include "six/sicd/RgAzComp.h" -#include "six/sicd/RMA.h" -#include "six/sicd/Utilities.h" +#include "six/sicd/ImageData.h" +#include "six/sicd/PFA.h" +#include "six/sicd/SCPCOA.h" +#include "six/sicd/RadarCollection.h" +#include "six/sicd/RgAzComp.h" +#include "six/sicd/RMA.h" +#include "six/sicd/Utilities.h" #include - -using namespace six; -using namespace six::sicd; - + +using namespace six; +using namespace six::sicd; + const double DirectionParameters::WGT_TOL = 1e-3; const size_t DirectionParameters::DEFAULT_WEIGHT_SIZE = 512; const char DirectionParameters::BOUNDS_ERROR_MESSAGE[] = @@ -47,448 +47,448 @@ const char Grid::WF_INCONSISTENT_STR[] = "Waveform fields not consistent"; const char Grid::BOUNDS_ERROR_MESSAGE[] = "Violation of spatial frequency extent bounds"; -WeightType::WeightType() -{ -} - -DirectionParameters::DirectionParameters() : - unitVector(Init::undefined()), - sampleSpacing(Init::undefined()), - impulseResponseWidth(Init::undefined()), - sign(Init::undefined()), - impulseResponseBandwidth(Init::undefined()), - kCenter(Init::undefined()), - deltaK1(Init::undefined()), - deltaK2(Init::undefined()), - deltaKCOAPoly(Init::undefined()) -{ -} - -DirectionParameters* DirectionParameters::clone() const -{ - return new DirectionParameters(*this); -} - -bool DirectionParameters::operator==(const DirectionParameters& rhs) const -{ - return (unitVector == rhs.unitVector && - sampleSpacing == rhs.sampleSpacing && - impulseResponseWidth == rhs.impulseResponseWidth && - sign == rhs.sign && - impulseResponseBandwidth == rhs.impulseResponseBandwidth && - kCenter == rhs.kCenter && - deltaK1 == rhs.deltaK1 && - deltaK2 == rhs.deltaK2 && - deltaKCOAPoly == rhs.deltaKCOAPoly && - weightType == rhs.weightType && - weights == rhs.weights); -} - -std::pair DirectionParameters::calculateDeltaKs( - const ImageData& imageData) const -{ - //Here, we assume the min and max of DeltaKCOAPoly must be - // on the vertices of the image, since it is smooth and monotonic in most cases-- - // although in actuality this is not always the case. To be totally generic, - // we would have to search for an interior min and max as well - double derivedDeltaK1 = 0; - double derivedDeltaK2 = 0; - - std::vector vertices = calculateImageVertices(imageData); - - if (!Init::isUndefined(deltaKCOAPoly)) - { - derivedDeltaK1 = std::numeric_limits::infinity(); - derivedDeltaK2 = -std::numeric_limits::infinity(); - - for (size_t ii = 0; ii < vertices.size(); ++ii) - { - double currentDeltaK = deltaKCOAPoly.atY( - static_cast(vertices[ii].col))( - static_cast(vertices[ii].row)); - derivedDeltaK1 = std::min(currentDeltaK, derivedDeltaK1); - derivedDeltaK2 = std::max(currentDeltaK, derivedDeltaK2); - } - } - - derivedDeltaK1 -= (impulseResponseBandwidth / 2); - derivedDeltaK2 += (impulseResponseBandwidth / 2); - - if (derivedDeltaK1 < -(1 / sampleSpacing) / 2 || - derivedDeltaK2 > (1 / sampleSpacing) / 2) - { - derivedDeltaK1 = -(1 / sampleSpacing) / 2; - derivedDeltaK2 = -derivedDeltaK1; - } - - return std::pair(derivedDeltaK1, derivedDeltaK2); -} - -std::unique_ptr -DirectionParameters::calculateWeightFunction() const -{ - if (weightType.get() == nullptr) - { - return nullptr; - } - - std::string windowName(weightType->windowName); - str::upper(windowName); - - if (windowName == "UNIFORM") - { - return std::make_unique(); - } - if (windowName == "HAMMING") - { - double coef = 0.0; - if (weightType->parameters.empty() || weightType->parameters[0].str().empty()) - { - //A Hamming window is defined in many places as a raised cosine of weight .54, - //so this is the default. However, some data use a generalized raised cosine and - //call it HAMMING, so we allow for both uses. - coef = .54; - } - else - { +WeightType::WeightType() +{ +} + +DirectionParameters::DirectionParameters() : + unitVector(Init::undefined()), + sampleSpacing(Init::undefined()), + impulseResponseWidth(Init::undefined()), + sign(Init::undefined()), + impulseResponseBandwidth(Init::undefined()), + kCenter(Init::undefined()), + deltaK1(Init::undefined()), + deltaK2(Init::undefined()), + deltaKCOAPoly(Init::undefined()) +{ +} + +DirectionParameters* DirectionParameters::clone() const +{ + return new DirectionParameters(*this); +} + +bool DirectionParameters::operator==(const DirectionParameters& rhs) const +{ + return (unitVector == rhs.unitVector && + sampleSpacing == rhs.sampleSpacing && + impulseResponseWidth == rhs.impulseResponseWidth && + sign == rhs.sign && + impulseResponseBandwidth == rhs.impulseResponseBandwidth && + kCenter == rhs.kCenter && + deltaK1 == rhs.deltaK1 && + deltaK2 == rhs.deltaK2 && + deltaKCOAPoly == rhs.deltaKCOAPoly && + weightType == rhs.weightType && + weights == rhs.weights); +} + +std::pair DirectionParameters::calculateDeltaKs( + const ImageData& imageData) const +{ + //Here, we assume the min and max of DeltaKCOAPoly must be + // on the vertices of the image, since it is smooth and monotonic in most cases-- + // although in actuality this is not always the case. To be totally generic, + // we would have to search for an interior min and max as well + double derivedDeltaK1 = 0; + double derivedDeltaK2 = 0; + + std::vector vertices = calculateImageVertices(imageData); + + if (!Init::isUndefined(deltaKCOAPoly)) + { + derivedDeltaK1 = std::numeric_limits::infinity(); + derivedDeltaK2 = -std::numeric_limits::infinity(); + + for (size_t ii = 0; ii < vertices.size(); ++ii) + { + double currentDeltaK = deltaKCOAPoly.atY( + static_cast(vertices[ii].col))( + static_cast(vertices[ii].row)); + derivedDeltaK1 = std::min(currentDeltaK, derivedDeltaK1); + derivedDeltaK2 = std::max(currentDeltaK, derivedDeltaK2); + } + } + + derivedDeltaK1 -= (impulseResponseBandwidth / 2); + derivedDeltaK2 += (impulseResponseBandwidth / 2); + + if (derivedDeltaK1 < -(1 / sampleSpacing) / 2 || + derivedDeltaK2 > (1 / sampleSpacing) / 2) + { + derivedDeltaK1 = -(1 / sampleSpacing) / 2; + derivedDeltaK2 = -derivedDeltaK1; + } + + return std::pair(derivedDeltaK1, derivedDeltaK2); +} + +std::unique_ptr +DirectionParameters::calculateWeightFunction() const +{ + if (weightType.get() == nullptr) + { + return nullptr; + } + + std::string windowName(weightType->windowName); + str::upper(windowName); + + if (windowName == "UNIFORM") + { + return std::make_unique(); + } + if (windowName == "HAMMING") + { + double coef = 0.0; + if (weightType->parameters.empty() || weightType->parameters[0].str().empty()) + { + //A Hamming window is defined in many places as a raised cosine of weight .54, + //so this is the default. However, some data use a generalized raised cosine and + //call it HAMMING, so we allow for both uses. + coef = .54; + } + else + { coef = weightType->parameters[0]; - } - - return std::make_unique(coef); - } - if (windowName == "HANNING") - { - return std::make_unique(0.50); - } - if (windowName == "KAISER") - { + } + + return std::make_unique(coef); + } + if (windowName == "HANNING") + { + return std::make_unique(0.50); + } + if (windowName == "KAISER") + { return std::make_unique(double(weightType->parameters[0])); - } - - return nullptr; -} - -std::vector -DirectionParameters::calculateImageVertices(const ImageData& imageData) const -{ - std::vector vertices; - + } + + return nullptr; +} + +std::vector +DirectionParameters::calculateImageVertices(const ImageData& imageData) const +{ + std::vector vertices; + if (!imageData.validData.empty()) - { - vertices = imageData.validData; - } - else - { - vertices.resize(4); - //use edges of full image - vertices[0] = RowColInt(0, 0); - vertices[1] = RowColInt(static_cast(imageData.numCols) - 1, 0); - vertices[2] = RowColInt(static_cast(imageData.numCols) - 1, static_cast(imageData.numCols) - 1); - vertices[3] = RowColInt(0, static_cast(imageData.numCols) - 1); - } - return vertices; -} - -void DirectionParameters::fillDerivedFields(const ImageData& imageData) -{ - // Calulating resolution requires fzero and fft functions - - // DeltaK1/2 are approximated from DeltaKCOAPoly - if (!Init::isUndefined(deltaKCOAPoly) && - !Init::isUndefined(impulseResponseBandwidth) && - !Init::isUndefined(sampleSpacing) && - Init::isUndefined(deltaK1) && - Init::isUndefined(deltaK2)) - { - // Here, we assume the min and max of DeltaKCOAPoly must be on the vertices - // of the image, since it is smooth and monotonic in most cases--although in - // actuality this is not always the case. To be totally generic, we would - // have to search for an interior min and max as well. - const std::pair deltas = calculateDeltaKs(imageData); - deltaK1 = deltas.first; - deltaK2 = deltas.second; - } - - if (weightType.get() != nullptr && - weights.empty() && - weightType->windowName != "UNKNOWN") - { - std::unique_ptr weightFunction = calculateWeightFunction(); - if (weightFunction.get()) - { - weights = (*weightFunction)(DEFAULT_WEIGHT_SIZE); - } - } - return; -} - -bool DirectionParameters::validate(const ImageData& imageData, - logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - constexpr auto epsilon = std::numeric_limits::epsilon(); - //2.3.1, 2.3.5 - if (deltaK2 <= deltaK1) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "SICD.Grid.Row/Col.DeltaK1: " << deltaK1 << std::endl - << "SICD.Grid.Row/Col.DetalK2: " << deltaK2 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - else - { - // 2.3.2, 2.3.6 - if (deltaK2 > (1 / (2 * sampleSpacing)) + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Row/Col.SampleSpacing: " << - 0.5 / sampleSpacing << std::endl - << "SICD.Grid.Row/Col.DetalK2: " << deltaK2 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.3.3, 2.3.7 - if (deltaK1 < (-1 / (2 * sampleSpacing)) - epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Row/Col.SampleSpacing: " << - 0.5 / sampleSpacing << std::endl - << "SICD.Grid.Row/Col.DetalK1: " << deltaK1 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.3.4, 2.3.8 - if (impulseResponseBandwidth > (deltaK2 - deltaK1) + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "SICD.Grid.Row/Col.impulseResponseBandwidth: " << - impulseResponseBandwidth << std::endl - << "SICD.Grid.Row/Col.DeltaK2 - SICD.Grid.Row/COl.DeltaK1: " - << deltaK2 - deltaK1 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - } - - // 2.3.9. Compute our own DeltaK1/K2 and test for consistency with DelaKCOAPoly, - // ImpRespBW, and SS. - const auto deltas = calculateDeltaKs(imageData); - const double minDk = deltas.first; - const double maxDk = deltas.second; - - constexpr double DK_TOL = 1e-2; - - //2.3.9.1, 2.3.9.3 - if (std::abs((deltaK1 / minDk) - 1) > DK_TOL) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "SICD.Grid.Row/Col.DeltaK1: " << deltaK1 << std::endl - << "Derived DeltaK1: " << minDk << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - //2.3.9.2, 2.3.9.4 - if (std::abs((deltaK2 / maxDk) - 1) > DK_TOL) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "SICD.Grid.Row/Col.DeltaK2: " << deltaK2 << std::endl - << "Derived DeltaK2: " << maxDk << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - // Check weight functions - std::unique_ptr weightFunction; - - if (weightType.get()) - { - weightFunction.reset(calculateWeightFunction().release()); - - if (weightFunction.get()) - { - if (!weights.empty()) - { + { + vertices = imageData.validData; + } + else + { + vertices.resize(4); + //use edges of full image + vertices[0] = RowColInt(0, 0); + vertices[1] = RowColInt(static_cast(imageData.numCols) - 1, 0); + vertices[2] = RowColInt(static_cast(imageData.numCols) - 1, static_cast(imageData.numCols) - 1); + vertices[3] = RowColInt(0, static_cast(imageData.numCols) - 1); + } + return vertices; +} + +void DirectionParameters::fillDerivedFields(const ImageData& imageData) +{ + // Calulating resolution requires fzero and fft functions + + // DeltaK1/2 are approximated from DeltaKCOAPoly + if (!Init::isUndefined(deltaKCOAPoly) && + !Init::isUndefined(impulseResponseBandwidth) && + !Init::isUndefined(sampleSpacing) && + Init::isUndefined(deltaK1) && + Init::isUndefined(deltaK2)) + { + // Here, we assume the min and max of DeltaKCOAPoly must be on the vertices + // of the image, since it is smooth and monotonic in most cases--although in + // actuality this is not always the case. To be totally generic, we would + // have to search for an interior min and max as well. + const std::pair deltas = calculateDeltaKs(imageData); + deltaK1 = deltas.first; + deltaK2 = deltas.second; + } + + if (weightType.get() != nullptr && + weights.empty() && + weightType->windowName != "UNKNOWN") + { + std::unique_ptr weightFunction = calculateWeightFunction(); + if (weightFunction.get()) + { + weights = (*weightFunction)(DEFAULT_WEIGHT_SIZE); + } + } + return; +} + +bool DirectionParameters::validate(const ImageData& imageData, + logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + constexpr auto epsilon = std::numeric_limits::epsilon(); + //2.3.1, 2.3.5 + if (deltaK2 <= deltaK1) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "SICD.Grid.Row/Col.DeltaK1: " << deltaK1 << std::endl + << "SICD.Grid.Row/Col.DetalK2: " << deltaK2 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + else + { + // 2.3.2, 2.3.6 + if (deltaK2 > (1 / (2 * sampleSpacing)) + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Row/Col.SampleSpacing: " << + 0.5 / sampleSpacing << std::endl + << "SICD.Grid.Row/Col.DetalK2: " << deltaK2 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.3.3, 2.3.7 + if (deltaK1 < (-1 / (2 * sampleSpacing)) - epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Row/Col.SampleSpacing: " << + 0.5 / sampleSpacing << std::endl + << "SICD.Grid.Row/Col.DetalK1: " << deltaK1 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.3.4, 2.3.8 + if (impulseResponseBandwidth > (deltaK2 - deltaK1) + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "SICD.Grid.Row/Col.impulseResponseBandwidth: " << + impulseResponseBandwidth << std::endl + << "SICD.Grid.Row/Col.DeltaK2 - SICD.Grid.Row/COl.DeltaK1: " + << deltaK2 - deltaK1 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + } + + // 2.3.9. Compute our own DeltaK1/K2 and test for consistency with DelaKCOAPoly, + // ImpRespBW, and SS. + const auto deltas = calculateDeltaKs(imageData); + const double minDk = deltas.first; + const double maxDk = deltas.second; + + constexpr double DK_TOL = 1e-2; + + //2.3.9.1, 2.3.9.3 + if (std::abs((deltaK1 / minDk) - 1) > DK_TOL) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "SICD.Grid.Row/Col.DeltaK1: " << deltaK1 << std::endl + << "Derived DeltaK1: " << minDk << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + //2.3.9.2, 2.3.9.4 + if (std::abs((deltaK2 / maxDk) - 1) > DK_TOL) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "SICD.Grid.Row/Col.DeltaK2: " << deltaK2 << std::endl + << "Derived DeltaK2: " << maxDk << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + // Check weight functions + std::unique_ptr weightFunction; + + if (weightType.get()) + { + weightFunction.reset(calculateWeightFunction().release()); + + if (weightFunction.get()) + { + if (!weights.empty()) + { valid = validateWeights(*weightFunction, log) && valid; - } - } - else - { - messageBuilder.str(""); - messageBuilder << "Unrecognized weighting description" << std::endl - << "WeightType.WindowName: " - << weightType->windowName << std::endl; - log.warn(messageBuilder.str()); - valid = false; - } - } - - // 2.4.3, 2.4.4 - if (weightType.get() && - weightType->windowName != "UNIFORM" && - weightType->windowName != "UNKNOWN" && - weights.empty()) - { - messageBuilder.str(""); - messageBuilder << "Non-uniform weighting, but no WgtFunct provided" - << std::endl << "WgtType.WindowName: " << weightType->windowName - << std::endl; - log.warn(messageBuilder.str()); - } - - return valid; -} - -bool DirectionParameters::validateWeights(const Functor& weightFunction, - logging::Logger& log) const -{ - bool consistentValues = true; - bool valid = true; - std::ostringstream messageBuilder; - - //Arg doesn't matter. Just checking for Uniform-type Functor - if (weightFunction(5).empty()) - { - const auto key = weights[0]; - for (size_t ii = 0; ii < weights.size(); ++ii) - { - if (key != weights[ii]) - { - consistentValues = false; - } - } - } - else - { - std::vector expectedWeights = weightFunction(weights.size()); - for (size_t ii = 0; ii < weights.size(); ++ii) - { - if (std::abs(expectedWeights[ii] - weights[ii]) > WGT_TOL) - { - consistentValues = false; - break; - } - } - } - - if (!consistentValues) - { - messageBuilder.str(""); - messageBuilder << "DirectionParameters weights values " - << "inconsistent with weightType" << std::endl - << "WeightType.WindowName: " - << weightType->windowName << std::endl; - log.warn(messageBuilder.str()); - valid = false; - } - - return valid; -} - -void DirectionParameters::fillDerivedFields(const RgAzComp& rgAzComp, - double offset) -{ - if (Init::isUndefined(kCenter)) - { - kCenter = derivedKCenter(rgAzComp, offset); - } - - if (Init::isUndefined(deltaKCOAPoly) && - !Init::isUndefined(kCenter)) - { - deltaKCOAPoly = derivedKcoaPoly(rgAzComp, offset); - } -} - -double DirectionParameters::derivedKCenter(const RgAzComp& /*rgAzComp*/, - double offset) const -{ - double derivedCenter = offset; - if (!Init::isUndefined(deltaKCOAPoly)) - { - derivedCenter -= deltaKCOAPoly[0][0]; - } - return derivedCenter; -} - -Poly2D DirectionParameters::derivedKcoaPoly(const RgAzComp& /*rgAzComp*/, - double offset) const -{ - // Create a Poly2D with one term - std::vector coefs(1, offset - kCenter); - return Poly2D(0, 0, coefs); -} - -bool DirectionParameters::validate(const RgAzComp& rgAzComp, - logging::Logger& log, - double offset) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - // 2.12.1.8, 2.12.1.9 - if (std::abs(kCenter - derivedKCenter(rgAzComp, offset)) - > std::numeric_limits::epsilon()) - { - messageBuilder.str(""); - messageBuilder << "KCenter: " << kCenter << std::endl - << "DeltaKCOAPoly: " << deltaKCOAPoly[0][0]; - log.error(messageBuilder.str()); - valid = false; - } - - //2.12.1.10, 2.12.1.11 - if (!Init::isUndefined(deltaKCOAPoly) && deltaKCOAPoly.orderX() > 1) - { - messageBuilder.str(""); - messageBuilder << "DetlaKCOAPoly must be a single value for RGAZCOMP data"; - log.error(messageBuilder.str()); - valid = false; - } - return valid; -} - -Grid::Grid() : - // This is a good assumption, I think - imagePlane(ComplexImagePlaneType::SLANT), - // Not so sure about this one - type(ComplexImageGridType::RGAZIM), - row(new DirectionParameters()), - col(new DirectionParameters()) -{ -} - -Grid* Grid::clone() const -{ - return new Grid(*this); -} - -bool Grid::operator==(const Grid& rhs) const -{ - return (imagePlane == rhs.imagePlane && - type == rhs.type && - timeCOAPoly == rhs.timeCOAPoly && - row == rhs.row && col == rhs.col); -} - -bool Grid::validateTimeCOAPoly( - const CollectionInformation& collectionInformation, - logging::Logger& log) const -{ - const RadarModeType& mode = collectionInformation.radarMode; - - //2.1. Scalar TimeCOAPoly means SPOTLIGHT data - bool valid = true; + } + } + else + { + messageBuilder.str(""); + messageBuilder << "Unrecognized weighting description" << std::endl + << "WeightType.WindowName: " + << weightType->windowName << std::endl; + log.warn(messageBuilder.str()); + valid = false; + } + } + + // 2.4.3, 2.4.4 + if (weightType.get() && + weightType->windowName != "UNIFORM" && + weightType->windowName != "UNKNOWN" && + weights.empty()) + { + messageBuilder.str(""); + messageBuilder << "Non-uniform weighting, but no WgtFunct provided" + << std::endl << "WgtType.WindowName: " << weightType->windowName + << std::endl; + log.warn(messageBuilder.str()); + } + + return valid; +} + +bool DirectionParameters::validateWeights(const Functor& weightFunction, + logging::Logger& log) const +{ + bool consistentValues = true; + bool valid = true; + std::ostringstream messageBuilder; + + //Arg doesn't matter. Just checking for Uniform-type Functor + if (weightFunction(5).empty()) + { + const auto key = weights[0]; + for (size_t ii = 0; ii < weights.size(); ++ii) + { + if (key != weights[ii]) + { + consistentValues = false; + } + } + } + else + { + std::vector expectedWeights = weightFunction(weights.size()); + for (size_t ii = 0; ii < weights.size(); ++ii) + { + if (std::abs(expectedWeights[ii] - weights[ii]) > WGT_TOL) + { + consistentValues = false; + break; + } + } + } + + if (!consistentValues) + { + messageBuilder.str(""); + messageBuilder << "DirectionParameters weights values " + << "inconsistent with weightType" << std::endl + << "WeightType.WindowName: " + << weightType->windowName << std::endl; + log.warn(messageBuilder.str()); + valid = false; + } + + return valid; +} + +void DirectionParameters::fillDerivedFields(const RgAzComp& rgAzComp, + double offset) +{ + if (Init::isUndefined(kCenter)) + { + kCenter = derivedKCenter(rgAzComp, offset); + } + + if (Init::isUndefined(deltaKCOAPoly) && + !Init::isUndefined(kCenter)) + { + deltaKCOAPoly = derivedKcoaPoly(rgAzComp, offset); + } +} + +double DirectionParameters::derivedKCenter(const RgAzComp& /*rgAzComp*/, + double offset) const +{ + double derivedCenter = offset; + if (!Init::isUndefined(deltaKCOAPoly)) + { + derivedCenter -= deltaKCOAPoly[0][0]; + } + return derivedCenter; +} + +Poly2D DirectionParameters::derivedKcoaPoly(const RgAzComp& /*rgAzComp*/, + double offset) const +{ + // Create a Poly2D with one term + std::vector coefs(1, offset - kCenter); + return Poly2D(0, 0, coefs); +} + +bool DirectionParameters::validate(const RgAzComp& rgAzComp, + logging::Logger& log, + double offset) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + // 2.12.1.8, 2.12.1.9 + if (std::abs(kCenter - derivedKCenter(rgAzComp, offset)) + > std::numeric_limits::epsilon()) + { + messageBuilder.str(""); + messageBuilder << "KCenter: " << kCenter << std::endl + << "DeltaKCOAPoly: " << deltaKCOAPoly[0][0]; + log.error(messageBuilder.str()); + valid = false; + } + + //2.12.1.10, 2.12.1.11 + if (!Init::isUndefined(deltaKCOAPoly) && deltaKCOAPoly.orderX() > 1) + { + messageBuilder.str(""); + messageBuilder << "DetlaKCOAPoly must be a single value for RGAZCOMP data"; + log.error(messageBuilder.str()); + valid = false; + } + return valid; +} + +Grid::Grid() : + // This is a good assumption, I think + imagePlane(ComplexImagePlaneType::SLANT), + // Not so sure about this one + type(ComplexImageGridType::RGAZIM), + row(new DirectionParameters()), + col(new DirectionParameters()) +{ +} + +Grid* Grid::clone() const +{ + return new Grid(*this); +} + +bool Grid::operator==(const Grid& rhs) const +{ + return (imagePlane == rhs.imagePlane && + type == rhs.type && + timeCOAPoly == rhs.timeCOAPoly && + row == rhs.row && col == rhs.col); +} + +bool Grid::validateTimeCOAPoly( + const CollectionInformation& collectionInformation, + logging::Logger& log) const +{ + const RadarModeType& mode = collectionInformation.radarMode; + + //2.1. Scalar TimeCOAPoly means SPOTLIGHT data + bool valid = true; if (timeCOAPoly.empty()) { log.error("No timeCOAPoly for Grid."); @@ -497,70 +497,70 @@ bool Grid::validateTimeCOAPoly( else { const auto isScalar = timeCOAPoly.isScalar(); - - if (mode == RadarModeType::SPOTLIGHT && !isScalar) - { - log.error("SPOTLIGHT data should only have scalar TimeCOAPoly."); - valid = false; - } - - if (mode != RadarModeType::SPOTLIGHT && isScalar) - { + + if (mode == RadarModeType::SPOTLIGHT && !isScalar) + { + log.error("SPOTLIGHT data should only have scalar TimeCOAPoly."); + valid = false; + } + + if (mode != RadarModeType::SPOTLIGHT && isScalar) + { log.warn("Non-SPOTLIGHT data will generally have more than one " - "nonzero term in TimeCOAPoly unless \"formed as spotlight\"."); - valid = false; - } - } - - return valid; -} - -bool Grid::validateFFTSigns(logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - //2.2. FFT signs in both dimensions almost certainly have to be equal - if (row->sign != col->sign) - { - messageBuilder.str(""); - messageBuilder << - "FFT signs in row and column direction should be the same." << - std::endl << "Grid.Row.Sign: " << row->sign << std::endl - << "Grid.Col.Sign: " << col->sign << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - return valid; -} - -bool Grid::validate(const CollectionInformation& collectionInformation, - const ImageData& imageData, - logging::Logger& log) const -{ - bool valid = validateTimeCOAPoly(collectionInformation, log);//2.1 - valid = validateFFTSigns(log) && valid; //2.2 + "nonzero term in TimeCOAPoly unless \"formed as spotlight\"."); + valid = false; + } + } + + return valid; +} + +bool Grid::validateFFTSigns(logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + //2.2. FFT signs in both dimensions almost certainly have to be equal + if (row->sign != col->sign) + { + messageBuilder.str(""); + messageBuilder << + "FFT signs in row and column direction should be the same." << + std::endl << "Grid.Row.Sign: " << row->sign << std::endl + << "Grid.Col.Sign: " << col->sign << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + return valid; +} + +bool Grid::validate(const CollectionInformation& collectionInformation, + const ImageData& imageData, + logging::Logger& log) const +{ + bool valid = validateTimeCOAPoly(collectionInformation, log);//2.1 + valid = validateFFTSigns(log) && valid; //2.2 valid = row->validate(imageData, log) && valid; //2.3.1 - 2.3.9 - valid = col->validate(imageData, log) && valid; + valid = col->validate(imageData, log) && valid; return valid; -} - -void Grid::fillDerivedFields( - const CollectionInformation& collectionInformation, - const ImageData& imageData, - const SCPCOA& scpcoa) -{ - if (!Init::isUndefined(scpcoa.scpTime) && - collectionInformation.radarMode == RadarModeType::SPOTLIGHT && - Init::isUndefined(timeCOAPoly)) - { - timeCOAPoly = Poly2D(0, 0); - timeCOAPoly[0][0] = scpcoa.scpTime; - } - - row->fillDerivedFields(imageData); - col->fillDerivedFields(imageData); -} +} + +void Grid::fillDerivedFields( + const CollectionInformation& collectionInformation, + const ImageData& imageData, + const SCPCOA& scpcoa) +{ + if (!Init::isUndefined(scpcoa.scpTime) && + collectionInformation.radarMode == RadarModeType::SPOTLIGHT && + Init::isUndefined(timeCOAPoly)) + { + timeCOAPoly = Poly2D(0, 0); + timeCOAPoly[0][0] = scpcoa.scpTime; + } + + row->fillDerivedFields(imageData); + col->fillDerivedFields(imageData); +} void Grid::fillDerivedFields(const RMA& rma, const Vector3& scp, const PolyXYZ& arpPoly) @@ -580,48 +580,48 @@ void Grid::fillDerivedFields(const RMA& rma, const Vector3& scp, } void Grid::fillDerivedFields(const RMAT& rmat, const Vector3& scp) -{ - // Row/Col.UnitVector and Derived fields - if (Init::isUndefined(row->unitVector) && - Init::isUndefined(col->unitVector)) - { - row->unitVector = derivedRowUnitVector(rmat, scp); - col->unitVector = derivedColUnitVector(rmat, scp); +{ + // Row/Col.UnitVector and Derived fields + if (Init::isUndefined(row->unitVector) && + Init::isUndefined(col->unitVector)) + { + row->unitVector = derivedRowUnitVector(rmat, scp); + col->unitVector = derivedColUnitVector(rmat, scp); } } void Grid::fillDerivedFields(const RMCR& rmcr, const Vector3& scp) -{ - // Row/Col.UnitVector and Derived fields - if (Init::isUndefined(row->unitVector) && - Init::isUndefined(col->unitVector)) - { - row->unitVector = derivedRowUnitVector(rmcr, scp); - col->unitVector = derivedColUnitVector(rmcr, scp); +{ + // Row/Col.UnitVector and Derived fields + if (Init::isUndefined(row->unitVector) && + Init::isUndefined(col->unitVector)) + { + row->unitVector = derivedRowUnitVector(rmcr, scp); + col->unitVector = derivedColUnitVector(rmcr, scp); } } void Grid::fillDerivedFields(const INCA& inca, const Vector3& scp, const PolyXYZ& arpPoly) { - if (!Init::isUndefined(inca.timeCAPoly) && - !Init::isUndefined(arpPoly) && - Init::isUndefined(row->unitVector) && - Init::isUndefined(col->unitVector)) - { - row->unitVector = derivedRowUnitVector(inca, scp, arpPoly); - col->unitVector = derivedColUnitVector(inca, scp, arpPoly); + if (!Init::isUndefined(inca.timeCAPoly) && + !Init::isUndefined(arpPoly) && + Init::isUndefined(row->unitVector) && + Init::isUndefined(col->unitVector)) + { + row->unitVector = derivedRowUnitVector(inca, scp, arpPoly); + col->unitVector = derivedColUnitVector(inca, scp, arpPoly); } - if (Init::isUndefined(col->kCenter)) - { - col->kCenter = 0; + if (Init::isUndefined(col->kCenter)) + { + col->kCenter = 0; } - if (!Init::isUndefined(inca.freqZero) && - Init::isUndefined(row->kCenter)) - { - row->kCenter = derivedRowKCenter(inca); + if (!Init::isUndefined(inca.freqZero) && + Init::isUndefined(row->kCenter)) + { + row->kCenter = derivedRowKCenter(inca); } } @@ -632,21 +632,21 @@ void Grid::fillDerivedFields(const RgAzComp& rgAzComp, { const Vector3& scp = geoData.scp.ecf; - if (imagePlane == ComplexImagePlaneType::NOT_SET) - { - imagePlane = ComplexImagePlaneType::SLANT; - } - if (type == ComplexImageGridType::NOT_SET) - { - type = ComplexImageGridType::RGAZIM; - } - - if (Init::isUndefined(row->unitVector)) - { - row->unitVector = derivedRowUnitVector(scpcoa, scp); - } - if (Init::isUndefined(col->unitVector)) - { + if (imagePlane == ComplexImagePlaneType::NOT_SET) + { + imagePlane = ComplexImagePlaneType::SLANT; + } + if (type == ComplexImageGridType::NOT_SET) + { + type = ComplexImageGridType::RGAZIM; + } + + if (Init::isUndefined(row->unitVector)) + { + row->unitVector = derivedRowUnitVector(scpcoa, scp); + } + if (Init::isUndefined(col->unitVector)) + { col->unitVector = derivedColUnitVector(scpcoa, scp); } if (!Init::isUndefined(fc)) @@ -697,16 +697,16 @@ void Grid::fillDefaultFields(const RMA& rma, double fc) void Grid::fillDefaultFields(const RMAT& rmat, double fc) { - if (!Init::isUndefined(fc)) - { - if (Init::isUndefined(row->kCenter)) - { - row->kCenter = derivedRowKCenter(rmat, fc); - } - - if (Init::isUndefined(col->kCenter)) - { - col->kCenter = derivedColKCenter(rmat, fc); + if (!Init::isUndefined(fc)) + { + if (Init::isUndefined(row->kCenter)) + { + row->kCenter = derivedRowKCenter(rmat, fc); + } + + if (Init::isUndefined(col->kCenter)) + { + col->kCenter = derivedColKCenter(rmat, fc); } } } @@ -759,47 +759,47 @@ Vector3 Grid::derivedColUnitVector(const INCA& inca, const Vector3& scp, void Grid::fillDefaultFields(const RMCR& rmcr, double fc) { - if (!Init::isUndefined(fc)) - { - if (Init::isUndefined(row->kCenter)) - { - row->kCenter = derivedRowKCenter(rmcr, fc); - } - if (Init::isUndefined(col->kCenter)) - { - col->kCenter = 0; - } + if (!Init::isUndefined(fc)) + { + if (Init::isUndefined(row->kCenter)) + { + row->kCenter = derivedRowKCenter(rmcr, fc); + } + if (Init::isUndefined(col->kCenter)) + { + col->kCenter = 0; + } } } void Grid::fillDefaultFields(const PFA& pfa, double fc) { - if (type == ComplexImageGridType::NOT_SET) - { - type = ComplexImageGridType::RGAZIM; - } - - if (Init::isUndefined(col->kCenter)) - { - col->kCenter = 0; - } - if (Init::isUndefined(row->kCenter)) - { - if (!Init::isUndefined(pfa.krg1) && - !Init::isUndefined(pfa.krg2)) - { - // Default: the most reasonable way to compute this - row->kCenter = (pfa.krg1 + pfa.krg2) / 2; - } - else if (!Init::isUndefined(fc)) - { - // Approximation: this may not be quite right, due to - // rectangular inscription loss in PFA, but it should - // be close. - row->kCenter = fc * - (2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC) * - pfa.spatialFrequencyScaleFactorPoly[0]; - } + if (type == ComplexImageGridType::NOT_SET) + { + type = ComplexImageGridType::RGAZIM; + } + + if (Init::isUndefined(col->kCenter)) + { + col->kCenter = 0; + } + if (Init::isUndefined(row->kCenter)) + { + if (!Init::isUndefined(pfa.krg1) && + !Init::isUndefined(pfa.krg2)) + { + // Default: the most reasonable way to compute this + row->kCenter = (pfa.krg1 + pfa.krg2) / 2; + } + else if (!Init::isUndefined(fc)) + { + // Approximation: this may not be quite right, due to + // rectangular inscription loss in PFA, but it should + // be close. + row->kCenter = fc * + (2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC) * + pfa.spatialFrequencyScaleFactorPoly[0]; + } } } @@ -811,9 +811,9 @@ bool Grid::validate(const RMA& rma, const Vector3& scp, // 2.12.3.2.1, 2.12.3.4.1 if (type != defaultGridType(rma)) { - std::ostringstream messageBuilder; - messageBuilder << "Given image formation algorithm expects " - << defaultGridType(rma) << ".\nFound " << type; + std::ostringstream messageBuilder; + messageBuilder << "Given image formation algorithm expects " + << defaultGridType(rma) << ".\nFound " << type; log.error(messageBuilder.str()); valid = false; } @@ -842,49 +842,49 @@ bool Grid::validate(const RMAT& rmat, const Vector3& scp, std::ostringstream messageBuilder; bool valid = true; - // 2.12.3.2.3 - if ((row->unitVector - derivedRowUnitVector(rmat, scp)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl + // 2.12.3.2.3 + if ((row->unitVector - derivedRowUnitVector(rmat, scp)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl << "Grid.Row.UVectECF: " << row->unitVector << std::endl - << "Derived grid.Row.UVectECT: " - << derivedRowUnitVector(rmat, scp); - log.error(messageBuilder.str()); - valid = false; + << "Derived grid.Row.UVectECT: " + << derivedRowUnitVector(rmat, scp); + log.error(messageBuilder.str()); + valid = false; } - // 2.12.3.2.4 - if ((col->unitVector - derivedColUnitVector(rmat, scp)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl + // 2.12.3.2.4 + if ((col->unitVector - derivedColUnitVector(rmat, scp)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl << "Grid.Col.UVectECF: " << col->unitVector << std::endl - << "Derived Grid.Col.UVectECF: " - << derivedColUnitVector(rmat, scp); - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.2.6 - if (std::abs((derivedRowKCenter(rmat, fc) / row->kCenter) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR - << "Grid.Row.KCtr: " << row->kCenter << std::endl - << "Derived KCtr: " << derivedRowKCenter(rmat, fc); - log.warn(messageBuilder.str()); + << "Derived Grid.Col.UVectECF: " + << derivedColUnitVector(rmat, scp); + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.2.6 + if (std::abs((derivedRowKCenter(rmat, fc) / row->kCenter) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR + << "Grid.Row.KCtr: " << row->kCenter << std::endl + << "Derived KCtr: " << derivedRowKCenter(rmat, fc); + log.warn(messageBuilder.str()); valid = false; } //2.12.3.2.7 - if (std::abs((derivedColKCenter(rmat, fc) / col->kCenter) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR - << "Grid.Col.KCtr: " << col->kCenter << std::endl - << "Derived KCtr: " << derivedColKCenter(rmat, fc); - log.warn(messageBuilder.str()); + if (std::abs((derivedColKCenter(rmat, fc) / col->kCenter) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR + << "Grid.Col.KCtr: " << col->kCenter << std::endl + << "Derived KCtr: " << derivedColKCenter(rmat, fc); + log.warn(messageBuilder.str()); valid = false; } @@ -897,52 +897,52 @@ bool Grid::validate(const RMCR& rmcr, const Vector3& scp, bool valid = true; std::ostringstream messageBuilder; - //2.12.3.3.3 - if ((row->unitVector - derivedRowUnitVector(rmcr, scp)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl - << "Grid.Row.UVectECF: " << row->unitVector << std::endl - << "Derived Grid.Row.UVectECF: " - << derivedRowUnitVector(rmcr, scp); - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.3.4 - if ((col->unitVector - derivedColUnitVector(rmcr, scp)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl - << "Grid.Col.UVectECF: " << col->unitVector << std::endl - << "Derived Grid.Col.UVectECF: " + //2.12.3.3.3 + if ((row->unitVector - derivedRowUnitVector(rmcr, scp)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl + << "Grid.Row.UVectECF: " << row->unitVector << std::endl + << "Derived Grid.Row.UVectECF: " + << derivedRowUnitVector(rmcr, scp); + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.3.4 + if ((col->unitVector - derivedColUnitVector(rmcr, scp)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl + << "Grid.Col.UVectECF: " << col->unitVector << std::endl + << "Derived Grid.Col.UVectECF: " << derivedColUnitVector(rmcr, scp); - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.3.6 - if (col->kCenter != 0) - { - messageBuilder.str(""); - messageBuilder << "Grid.Col.KCtr must be zero for RMA/RMCR data." - << std::endl << "Grid.Col.KCtr = " << col->kCenter; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.3.7 - if (!Init::isUndefined(fc)) - { - if (std::abs(row->kCenter / derivedRowKCenter(rmcr, fc) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "Grid.Row.KCtr: " << row->kCenter << std::endl - << "Center frequency * 2/c: " << derivedRowKCenter(rmcr, fc); - log.warn(messageBuilder.str()); - valid = false; - } + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.3.6 + if (col->kCenter != 0) + { + messageBuilder.str(""); + messageBuilder << "Grid.Col.KCtr must be zero for RMA/RMCR data." + << std::endl << "Grid.Col.KCtr = " << col->kCenter; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.3.7 + if (!Init::isUndefined(fc)) + { + if (std::abs(row->kCenter / derivedRowKCenter(rmcr, fc) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "Grid.Row.KCtr: " << row->kCenter << std::endl + << "Center frequency * 2/c: " << derivedRowKCenter(rmcr, fc); + log.warn(messageBuilder.str()); + valid = false; + } } return valid; @@ -964,7 +964,7 @@ bool Grid::validate(const INCA& inca, const Vector3& scp, if (!Init::isUndefined(inca.dopplerCentroidPoly) && inca.dopplerCentroidCOA == BooleanType::IS_TRUE) { - const Poly2D& kcoaPoly = col->deltaKCOAPoly; + const Poly2D& kcoaPoly = col->deltaKCOAPoly; const Poly2D& centroidPoly = inca.dopplerCentroidPoly; if (kcoaPoly.orderX() != centroidPoly.orderX() && @@ -990,14 +990,14 @@ bool Grid::validate(const INCA& inca, const Vector3& scp, } norm = std::sqrt(norm); - if(norm > IFP_POLY_TOL) - { - messageBuilder.str(""); - messageBuilder << "RMA.INCA fields inconsistent." << std::endl - << "Compare Grid.Col.KCOAPoly to RMA.INCA.DopCentroidPoly " - << "* RMA.INCA.TimeCAPoly[1]."; - log.error(messageBuilder.str()); - valid = false; + if(norm > IFP_POLY_TOL) + { + messageBuilder.str(""); + messageBuilder << "RMA.INCA fields inconsistent." << std::endl + << "Compare Grid.Col.KCOAPoly to RMA.INCA.DopCentroidPoly " + << "* RMA.INCA.TimeCAPoly[1]."; + log.error(messageBuilder.str()); + valid = false; } } } @@ -1006,50 +1006,50 @@ bool Grid::validate(const INCA& inca, const Vector3& scp, if ((row->unitVector - derivedRowUnitVector(inca, scp, arpPoly)).norm() > UVECT_TOL) { - messageBuilder.str(""); - messageBuilder << "UVectFields inconsistent" << std::endl + messageBuilder.str(""); + messageBuilder << "UVectFields inconsistent" << std::endl << "Grid.Row.UVectECF: " << row->unitVector << std::endl - << "Derived Grid.Row.UVectECF: " - << derivedRowUnitVector(inca, scp, arpPoly); - log.error(messageBuilder.str()); + << "Derived Grid.Row.UVectECF: " + << derivedRowUnitVector(inca, scp, arpPoly); + log.error(messageBuilder.str()); valid = false; } - // 2.12.3.4.7 - if ((col->unitVector - - derivedRowUnitVector(inca, scp, arpPoly)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVectFields inconsistent" << std::endl + // 2.12.3.4.7 + if ((col->unitVector - + derivedRowUnitVector(inca, scp, arpPoly)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVectFields inconsistent" << std::endl << "Grid.Col.UVectECF: " << col->unitVector << std::endl - << "Derived Grid.Col.UVectECF: " - << derivedRowUnitVector(inca, scp, arpPoly); - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.4.8 - if (col->kCenter != 0) - { - messageBuilder.str(""); - messageBuilder << "Grid.Col.KCtr must be zero " - << "for RMA/INCA data." << std::endl - << "Grid.Col.KCtr: " << col->kCenter; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.4.11 - if (Init::isUndefined(fc) && - std::abs(row->kCenter - derivedRowKCenter(inca)) > - std::numeric_limits::epsilon()) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl + << "Derived Grid.Col.UVectECF: " + << derivedRowUnitVector(inca, scp, arpPoly); + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.4.8 + if (col->kCenter != 0) + { + messageBuilder.str(""); + messageBuilder << "Grid.Col.KCtr must be zero " + << "for RMA/INCA data." << std::endl + << "Grid.Col.KCtr: " << col->kCenter; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.4.11 + if (Init::isUndefined(fc) && + std::abs(row->kCenter - derivedRowKCenter(inca)) > + std::numeric_limits::epsilon()) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl << "RMA.INCA.FreqZero * 2 / c: " << derivedRowKCenter(inca) - << std::endl << "Grid.Row.KCenter: " << row->kCenter; - log.error(messageBuilder.str()); - valid = false; + << std::endl << "Grid.Row.KCenter: " << row->kCenter; + log.error(messageBuilder.str()); + valid = false; } return valid; } @@ -1061,138 +1061,138 @@ bool Grid::validate(const PFA& pfa, const RadarCollection& radarCollection, std::ostringstream messageBuilder; const double& epsilon = std::numeric_limits::epsilon(); - //2.12.2.1 - if (type != ComplexImageGridType::RGAZIM) - { - messageBuilder.str(""); - messageBuilder << "PFA image formation should result in a RGAZIM grid." - << std::endl << "Grid.Type: " << type; - log.error(messageBuilder.str()); - valid = false; - } - - // Make sure Row.kCtr is consistent with processed RF frequency bandwidth - if (Init::isUndefined(radarCollection.refFrequencyIndex) && - !Init::isUndefined(fc)) - { - // PFA.SpatialFreqSFPoly affects Row.KCtr - const auto kapCtr = fc * pfa.spatialFrequencyScaleFactorPoly[0] * - 2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC; - - // PFA inscription could cause kapCtr and Row.KCtr - // to be somewhat different - const auto theta = std::atan((col->impulseResponseBandwidth / 2) / - row->kCenter); - double kCtrTol = 1 - std::cos(theta); - kCtrTol = std::max(0.01, kCtrTol); - - if (std::abs(row->kCenter / kapCtr - 1) > kCtrTol) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR - << "Grid.Row.KCtr: " << row->kCenter << std::endl - << "Derived KapCtr: " << kapCtr; - log.error(messageBuilder.str()); - valid = false; - } - } - - //Slow-time deskew would allow for PFA.Kaz2-PFA.Kaz1>(1/Grid.Col.SS), - //since Kaz bandwidth is compressed from original polar annulus. + //2.12.2.1 + if (type != ComplexImageGridType::RGAZIM) + { + messageBuilder.str(""); + messageBuilder << "PFA image formation should result in a RGAZIM grid." + << std::endl << "Grid.Type: " << type; + log.error(messageBuilder.str()); + valid = false; + } + + // Make sure Row.kCtr is consistent with processed RF frequency bandwidth + if (Init::isUndefined(radarCollection.refFrequencyIndex) && + !Init::isUndefined(fc)) + { + // PFA.SpatialFreqSFPoly affects Row.KCtr + const auto kapCtr = fc * pfa.spatialFrequencyScaleFactorPoly[0] * + 2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC; + + // PFA inscription could cause kapCtr and Row.KCtr + // to be somewhat different + const auto theta = std::atan((col->impulseResponseBandwidth / 2) / + row->kCenter); + double kCtrTol = 1 - std::cos(theta); + kCtrTol = std::max(0.01, kCtrTol); + + if (std::abs(row->kCenter / kapCtr - 1) > kCtrTol) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR + << "Grid.Row.KCtr: " << row->kCenter << std::endl + << "Derived KapCtr: " << kapCtr; + log.error(messageBuilder.str()); + valid = false; + } + } + + //Slow-time deskew would allow for PFA.Kaz2-PFA.Kaz1>(1/Grid.Col.SS), + //since Kaz bandwidth is compressed from original polar annulus. if (pfa.slowTimeDeskew.get() != nullptr && - pfa.slowTimeDeskew->applied != BooleanType::IS_TRUE) - { - //2.3.10 - if ((pfa.kaz2 - col->kCenter) > - (1 / (2 * col->sampleSpacing)) + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Col.SampleSpacing: " - << 0.5 / col->sampleSpacing << std::endl - << "PFA.Kaz2 - Grid.Col.KCenter: " - << pfa.kaz2 - col->kCenter << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - //2.3.11 - if ((pfa.kaz1 - col->kCenter) < - (-1 / (2 * col->sampleSpacing)) - epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Col.SampleSpacing: " - << 0.5 / col->sampleSpacing << std::endl - << "PFA.Kaz1 - Grid.Col.KCenter: " - << pfa.kaz1 - col->kCenter << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - } - - //2.3.12 - if ((pfa.krg2 - row->kCenter) > - (1 / (2 * row->sampleSpacing)) + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Row.SampleSpacing: " - << 0.5 / row->sampleSpacing << std::endl - << "PFA.Krg2 - Grid.Row.KCenter: " - << pfa.krg2 - row->kCenter << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.3.13 - if (pfa.krg1 - row->kCenter < - (-1 / (2 * row->sampleSpacing)) - epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Row.SampleSpacing: " - << 0.5 / row->sampleSpacing << std::endl - << "PFA.Krg1 - Grid.Row.KCenter: " - << pfa.krg1 - row->kCenter << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.3.14 - if (col->impulseResponseBandwidth > pfa.kaz2 - pfa.kaz1 + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "Grid.Col.ImpulseResponseBandwidth: " - << col->impulseResponseBandwidth << std::endl - << "SICD.PFA.Kaz2 - SICD.PFA.Kaz1: " - << pfa.kaz2 - pfa.kaz1 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - //2.3.15 - if (row->impulseResponseBandwidth > pfa.krg2 - pfa.krg1 + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "Grid.Row.ImpulseResponseBandwidth: " - << row->impulseResponseBandwidth << std::endl - << "SICD.PFA.Krg2 - SICD.PFA.Krg1: " - << pfa.krg2 - pfa.krg1 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - //2.3.16 - if (col->kCenter != 0 && - std::abs(col->kCenter - (pfa.kaz1 + pfa.kaz2) / 2) > 1e-5) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "Grid.Col.KCenter: " << col->kCenter << std::endl - << "mean(SICD.PFA.Kaz1, SICD.PFA.Kaz2): " - << (pfa.kaz1 + pfa.kaz2) / 2 << std::endl; - log.error(messageBuilder.str()); - valid = false; + pfa.slowTimeDeskew->applied != BooleanType::IS_TRUE) + { + //2.3.10 + if ((pfa.kaz2 - col->kCenter) > + (1 / (2 * col->sampleSpacing)) + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Col.SampleSpacing: " + << 0.5 / col->sampleSpacing << std::endl + << "PFA.Kaz2 - Grid.Col.KCenter: " + << pfa.kaz2 - col->kCenter << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + //2.3.11 + if ((pfa.kaz1 - col->kCenter) < + (-1 / (2 * col->sampleSpacing)) - epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Col.SampleSpacing: " + << 0.5 / col->sampleSpacing << std::endl + << "PFA.Kaz1 - Grid.Col.KCenter: " + << pfa.kaz1 - col->kCenter << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + } + + //2.3.12 + if ((pfa.krg2 - row->kCenter) > + (1 / (2 * row->sampleSpacing)) + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Row.SampleSpacing: " + << 0.5 / row->sampleSpacing << std::endl + << "PFA.Krg2 - Grid.Row.KCenter: " + << pfa.krg2 - row->kCenter << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.3.13 + if (pfa.krg1 - row->kCenter < + (-1 / (2 * row->sampleSpacing)) - epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Row.SampleSpacing: " + << 0.5 / row->sampleSpacing << std::endl + << "PFA.Krg1 - Grid.Row.KCenter: " + << pfa.krg1 - row->kCenter << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.3.14 + if (col->impulseResponseBandwidth > pfa.kaz2 - pfa.kaz1 + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "Grid.Col.ImpulseResponseBandwidth: " + << col->impulseResponseBandwidth << std::endl + << "SICD.PFA.Kaz2 - SICD.PFA.Kaz1: " + << pfa.kaz2 - pfa.kaz1 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + //2.3.15 + if (row->impulseResponseBandwidth > pfa.krg2 - pfa.krg1 + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "Grid.Row.ImpulseResponseBandwidth: " + << row->impulseResponseBandwidth << std::endl + << "SICD.PFA.Krg2 - SICD.PFA.Krg1: " + << pfa.krg2 - pfa.krg1 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + //2.3.16 + if (col->kCenter != 0 && + std::abs(col->kCenter - (pfa.kaz1 + pfa.kaz2) / 2) > 1e-5) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "Grid.Col.KCenter: " << col->kCenter << std::endl + << "mean(SICD.PFA.Kaz1, SICD.PFA.Kaz2): " + << (pfa.kaz1 + pfa.kaz2) / 2 << std::endl; + log.error(messageBuilder.str()); + valid = false; } return valid; @@ -1206,59 +1206,59 @@ bool Grid::validate(const RgAzComp& rgAzComp, { bool valid = true; std::ostringstream messageBuilder; - - // 2.12.1.1 - if (imagePlane != ComplexImagePlaneType::SLANT) - { - messageBuilder.str(""); - messageBuilder << - "RGAZCOMP image formation should result in a SLANT plane image." - << std::endl << "Grid.ImagePlane: " << imagePlane; - log.error(messageBuilder.str()); - valid = false; - } - - //2.12.1.2 - if (type != ComplexImageGridType::RGAZIM) - { - messageBuilder.str(""); - messageBuilder << - "RGAZCOMP image formation should result in a RGAZIM grid." - << std::endl << "Grid.Type: " << type; - log.error(messageBuilder.str()); - valid = false; - } - - //2.12.1.8 - const Vector3& scp = geoData.scp.ecf; + + // 2.12.1.1 + if (imagePlane != ComplexImagePlaneType::SLANT) + { + messageBuilder.str(""); + messageBuilder << + "RGAZCOMP image formation should result in a SLANT plane image." + << std::endl << "Grid.ImagePlane: " << imagePlane; + log.error(messageBuilder.str()); + valid = false; + } + + //2.12.1.2 + if (type != ComplexImageGridType::RGAZIM) + { + messageBuilder.str(""); + messageBuilder << + "RGAZCOMP image formation should result in a RGAZIM grid." + << std::endl << "Grid.Type: " << type; + log.error(messageBuilder.str()); + valid = false; + } + + //2.12.1.8 + const Vector3& scp = geoData.scp.ecf; valid = col->validate(rgAzComp, log) && valid; valid = row->validate(rgAzComp, log, fc *(2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC)) && valid; - //2.12.1.6 - if ((derivedRowUnitVector(scpcoa, scp) - row->unitVector).norm() - > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl - << "Grid.Row.UVectECEF: " << row->unitVector << std::endl - << "Derived Grid.Row.UVectECEF: " << - derivedRowUnitVector(scpcoa, scp); - log.error(messageBuilder.str()); - valid = false; - } - - //2.12.1.7 - if ((derivedColUnitVector(scpcoa, scp) - col->unitVector).norm() - > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl - << "Grid.Col.UVectECF: " << col->unitVector << std::endl - << "Derived Grid.Col.UVectECF: " << - derivedColUnitVector(scpcoa, scp); - log.error(messageBuilder.str()); - valid = false; + //2.12.1.6 + if ((derivedRowUnitVector(scpcoa, scp) - row->unitVector).norm() + > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl + << "Grid.Row.UVectECEF: " << row->unitVector << std::endl + << "Derived Grid.Row.UVectECEF: " << + derivedRowUnitVector(scpcoa, scp); + log.error(messageBuilder.str()); + valid = false; + } + + //2.12.1.7 + if ((derivedColUnitVector(scpcoa, scp) - col->unitVector).norm() + > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl + << "Grid.Col.UVectECF: " << col->unitVector << std::endl + << "Derived Grid.Col.UVectECF: " << + derivedColUnitVector(scpcoa, scp); + log.error(messageBuilder.str()); + valid = false; } return valid; diff --git a/six/modules/c++/six.sicd/source/ImageData.cpp b/six/modules/c++/six.sicd/source/ImageData.cpp index 3e35f81d69..147383a979 100644 --- a/six/modules/c++/six.sicd/source/ImageData.cpp +++ b/six/modules/c++/six.sicd/source/ImageData.cpp @@ -1,278 +1,278 @@ -/* ========================================================================= - * This file is part of six.sicd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2014, MDA Information Systems LLC - * - * six.sicd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include "six/sicd/ImageData.h" - -#include -#include -#include -#include // std::ignore -#include -#include -#include - -#include -#include -#include -#if CODA_OSS_cpp17 - // is broken with the older version of GCC we're using - #if (__GNUC__ >= 10) || _MSC_VER - #include - #define SIX_six_sicd_ImageData_has_execution 1 - #endif -#endif - -#include "six/AmplitudeTable.h" -#include "six/sicd/GeoData.h" -#include "six/sicd/Utilities.h" - -using namespace six; -using namespace six::sicd; - - // This was in coda-oss, but I removed it. - // - // First of all, C++11's std::async() is now (in 2023) thought of as maybe a - // bit "half baked," and perhaps shouldn't be emulated. Then, C++17 added - // parallel algorithms which might be a better way of satisfying our immediate - // needs (below) ... although we're still at C++14. -template -static inline OutputIt transform_async(const InputIt first1, const InputIt last1, OutputIt d_first, TFunc f, - typename std::iterator_traits::difference_type cutoff) -{ - // https://en.cppreference.com/w/cpp/thread/async - const auto len = std::distance(first1, last1); - if (len < cutoff) - { - return std::transform(first1, last1, d_first, f); - } - - constexpr auto policy = std::launch::async; - - const auto mid1 = first1 + len / 2; - const auto d_mid = d_first + len / 2; - auto handle = std::async(policy, transform_async, mid1, last1, d_mid, f, cutoff); - transform_async(first1, mid1, d_first, f, cutoff); - return handle.get(); -} -template -static inline void transform(std::span inputs, std::span results, TFunc f) -{ -#if SIX_six_sicd_ImageData_has_execution - std::ignore = std::transform(std::execution::par, inputs.begin(), inputs.end(), results.begin(), f); -#else - constexpr ptrdiff_t cutoff_ = 0; // too slow w/o multi-threading - //if (cutoff_ < 0) - //{ - // std::ignore = std::transform(inputs.begin(), inputs.end(), results.begin(), f); - //} - //else - { - // The value of "default_cutoff" was determined by testing; there is nothing special about it, feel free to change it. - constexpr auto dimension = 128 * 8; - constexpr auto default_cutoff = dimension * dimension; - const auto cutoff = cutoff_ == 0 ? default_cutoff : cutoff_; - - std::ignore = transform_async(inputs.begin(), inputs.end(), results.begin(), f, cutoff); - } -#endif // CODA_OSS_cpp17 -} - -bool ImageData::operator==(const ImageData& rhs) const -{ - return (pixelType == rhs.pixelType && - amplitudeTable == rhs.amplitudeTable && - numRows == rhs.numRows && - numCols == rhs.numCols && - firstRow == rhs.firstRow && - firstCol == rhs.firstCol && - fullImage == rhs.fullImage && - scpPixel == rhs.scpPixel && - validData == rhs.validData); -} - -bool ImageData::validate(const GeoData& geoData, logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - // 2.11.1 - if (!validData.empty() && geoData.validData.empty()) - { - messageBuilder << "ImageData.ValidData/GeoData.ValidData " - << "required together." << std::endl - << "ImageData.ValidData exists, but GeoData.ValidData does not."; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.11.2 - if (validData.empty() && !geoData.validData.empty()) - { - messageBuilder << "ImageData.ValidData/GeoData.ValidData " - << "required together." << std::endl - << "GeoData.ValidData exists, but ImageData.ValidData does not."; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.11.3 In ValidData, first vertex should have (1) minimum row index - // and (2) minimum column index if 2 vertices exist with equal minimum - // row index. - if (!validData.empty()) - { - bool minimumRowComesFirst = true; - - for (size_t ii = 1; ii < validData.size(); ++ii) - { - if (validData[ii].row < validData[0].row) - { - minimumRowComesFirst = false; - break; - } - } - if (!minimumRowComesFirst) - { - messageBuilder << "ImageData.ValidData first row should have" - << "minimum row index"; - log.error(messageBuilder.str()); - valid = false; - } - else - { - bool minimumColComesFirst = true; - std::vector minimumIndices; - for (size_t ii = 0; ii < validData.size(); ++ii) - { - if (validData[0].row == validData[ii].row && - validData[ii].col < validData[0].col) - { - minimumColComesFirst = false; - break; - } - } - if (!minimumColComesFirst) - { - messageBuilder << "ImageData.ValidData first col of matching" - << "minimum row index should have minimum col index"; - log.error(messageBuilder.str()); - valid = false; - } - } - if (!Utilities::isClockwise(validData)) - { - messageBuilder << "ImageData.ValidData should be arrange clockwise"; - log.error(messageBuilder.str()); - valid = false; - } - } - - return valid; -} - -template -static auto createLookup(TToComplexFunc toComplex) -{ - auto retval = std::make_unique(); // too big for the stack - auto& values = *retval; - - // For all possible amp/phase values (there are "only" 256*256=65536), get and save the - // complex value. - for (const auto amplitude : Utilities::iota_0_256()) - { - for (const auto phase : Utilities::iota_0_256()) - { - values[amplitude][phase] = toComplex(amplitude, phase); - } - } - - return retval; -} -static auto createLookup(const six::AmplitudeTable& amplitudeTable) -{ - const auto toComplex = [&litudeTable](auto amplitude, auto phase) { - return six::sicd::Utilities::toComplex(amplitude, phase, amplitudeTable); - }; - return createLookup(toComplex); -} -static auto createLookup() -{ - static const auto toComplex = [](auto amplitude, auto phase) { - return six::sicd::Utilities::toComplex(amplitude, phase); - }; - return createLookup(toComplex); -} - -static const six::Amp8iPhs8iLookup_t* getCachedLookup(const six::AmplitudeTable* pAmplitudeTable) -{ - if (pAmplitudeTable == nullptr) - { - static const auto lookup_no_table = createLookup(); - return lookup_no_table.get(); - } - - // Maybe one has already been created and stored on the table? - return pAmplitudeTable->getLookup(); -} - -const six::Amp8iPhs8iLookup_t& ImageData::getLookup(const six::AmplitudeTable* pAmplitudeTable) -{ - auto pLookup = getCachedLookup(pAmplitudeTable); - if (pLookup == nullptr) - { - assert(pAmplitudeTable != nullptr); - auto& amplitudeTable = *pAmplitudeTable; - auto lookup = createLookup(amplitudeTable); - amplitudeTable.cacheLookup_(std::move(lookup)); - pLookup = amplitudeTable.getLookup(); - } - assert(pLookup != nullptr); - return *pLookup; -} - -void ImageData::toComplex(const six::Amp8iPhs8iLookup_t& values, std::span inputs, std::span results) -{ - const auto toComplex_ = [&values](const auto& v) - { - return values[v.amplitude][v.phase]; - }; - transform(inputs, results, toComplex_); -} -void ImageData::toComplex(std::span inputs, std::span results) const -{ - if (pixelType != PixelType::AMP8I_PHS8I) - { - throw std::runtime_error("pxielType must be AMP8I_PHS8I"); - } - - const auto& values = getLookup(amplitudeTable.get()); - toComplex(values, inputs, results); -} - -void ImageData::fromComplex(std::span inputs, std::span results) const -{ - six::sicd::details::ComplexToAMP8IPHS8I::nearest_neighbors(inputs, results, amplitudeTable.get()); -} -void ImageData::testing_fromComplex_(std::span inputs, std::span results) -{ - static const ImageData imageData; - assert(imageData.amplitudeTable.get() == nullptr); - imageData.fromComplex(inputs, results); -} +/* ========================================================================= + * This file is part of six.sicd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * six.sicd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include "six/sicd/ImageData.h" + +#include +#include +#include +#include // std::ignore +#include +#include +#include + +#include +#include +#include +#if CODA_OSS_cpp17 + // is broken with the older version of GCC we're using + #if (__GNUC__ >= 10) || _MSC_VER + #include + #define SIX_six_sicd_ImageData_has_execution 1 + #endif +#endif + +#include "six/AmplitudeTable.h" +#include "six/sicd/GeoData.h" +#include "six/sicd/Utilities.h" + +using namespace six; +using namespace six::sicd; + + // This was in coda-oss, but I removed it. + // + // First of all, C++11's std::async() is now (in 2023) thought of as maybe a + // bit "half baked," and perhaps shouldn't be emulated. Then, C++17 added + // parallel algorithms which might be a better way of satisfying our immediate + // needs (below) ... although we're still at C++14. +template +static inline OutputIt transform_async(const InputIt first1, const InputIt last1, OutputIt d_first, TFunc f, + typename std::iterator_traits::difference_type cutoff) +{ + // https://en.cppreference.com/w/cpp/thread/async + const auto len = std::distance(first1, last1); + if (len < cutoff) + { + return std::transform(first1, last1, d_first, f); + } + + constexpr auto policy = std::launch::async; + + const auto mid1 = first1 + len / 2; + const auto d_mid = d_first + len / 2; + auto handle = std::async(policy, transform_async, mid1, last1, d_mid, f, cutoff); + transform_async(first1, mid1, d_first, f, cutoff); + return handle.get(); +} +template +static inline void transform(std::span inputs, std::span results, TFunc f) +{ +#if SIX_six_sicd_ImageData_has_execution + std::ignore = std::transform(std::execution::par, inputs.begin(), inputs.end(), results.begin(), f); +#else + constexpr ptrdiff_t cutoff_ = 0; // too slow w/o multi-threading + //if (cutoff_ < 0) + //{ + // std::ignore = std::transform(inputs.begin(), inputs.end(), results.begin(), f); + //} + //else + { + // The value of "default_cutoff" was determined by testing; there is nothing special about it, feel free to change it. + constexpr auto dimension = 128 * 8; + constexpr auto default_cutoff = dimension * dimension; + const auto cutoff = cutoff_ == 0 ? default_cutoff : cutoff_; + + std::ignore = transform_async(inputs.begin(), inputs.end(), results.begin(), f, cutoff); + } +#endif // CODA_OSS_cpp17 +} + +bool ImageData::operator==(const ImageData& rhs) const +{ + return (pixelType == rhs.pixelType && + amplitudeTable == rhs.amplitudeTable && + numRows == rhs.numRows && + numCols == rhs.numCols && + firstRow == rhs.firstRow && + firstCol == rhs.firstCol && + fullImage == rhs.fullImage && + scpPixel == rhs.scpPixel && + validData == rhs.validData); +} + +bool ImageData::validate(const GeoData& geoData, logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + // 2.11.1 + if (!validData.empty() && geoData.validData.empty()) + { + messageBuilder << "ImageData.ValidData/GeoData.ValidData " + << "required together." << std::endl + << "ImageData.ValidData exists, but GeoData.ValidData does not."; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.11.2 + if (validData.empty() && !geoData.validData.empty()) + { + messageBuilder << "ImageData.ValidData/GeoData.ValidData " + << "required together." << std::endl + << "GeoData.ValidData exists, but ImageData.ValidData does not."; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.11.3 In ValidData, first vertex should have (1) minimum row index + // and (2) minimum column index if 2 vertices exist with equal minimum + // row index. + if (!validData.empty()) + { + bool minimumRowComesFirst = true; + + for (size_t ii = 1; ii < validData.size(); ++ii) + { + if (validData[ii].row < validData[0].row) + { + minimumRowComesFirst = false; + break; + } + } + if (!minimumRowComesFirst) + { + messageBuilder << "ImageData.ValidData first row should have" + << "minimum row index"; + log.error(messageBuilder.str()); + valid = false; + } + else + { + bool minimumColComesFirst = true; + std::vector minimumIndices; + for (size_t ii = 0; ii < validData.size(); ++ii) + { + if (validData[0].row == validData[ii].row && + validData[ii].col < validData[0].col) + { + minimumColComesFirst = false; + break; + } + } + if (!minimumColComesFirst) + { + messageBuilder << "ImageData.ValidData first col of matching" + << "minimum row index should have minimum col index"; + log.error(messageBuilder.str()); + valid = false; + } + } + if (!Utilities::isClockwise(validData)) + { + messageBuilder << "ImageData.ValidData should be arrange clockwise"; + log.error(messageBuilder.str()); + valid = false; + } + } + + return valid; +} + +template +static auto createLookup(TToComplexFunc toComplex) +{ + auto retval = std::make_unique(); // too big for the stack + auto& values = *retval; + + // For all possible amp/phase values (there are "only" 256*256=65536), get and save the + // complex value. + for (const auto amplitude : Utilities::iota_0_256()) + { + for (const auto phase : Utilities::iota_0_256()) + { + values[amplitude][phase] = toComplex(amplitude, phase); + } + } + + return retval; +} +static auto createLookup(const six::AmplitudeTable& amplitudeTable) +{ + const auto toComplex = [&litudeTable](auto amplitude, auto phase) { + return six::sicd::Utilities::toComplex(amplitude, phase, amplitudeTable); + }; + return createLookup(toComplex); +} +static auto createLookup() +{ + static const auto toComplex = [](auto amplitude, auto phase) { + return six::sicd::Utilities::toComplex(amplitude, phase); + }; + return createLookup(toComplex); +} + +static const six::Amp8iPhs8iLookup_t* getCachedLookup(const six::AmplitudeTable* pAmplitudeTable) +{ + if (pAmplitudeTable == nullptr) + { + static const auto lookup_no_table = createLookup(); + return lookup_no_table.get(); + } + + // Maybe one has already been created and stored on the table? + return pAmplitudeTable->getLookup(); +} + +const six::Amp8iPhs8iLookup_t& ImageData::getLookup(const six::AmplitudeTable* pAmplitudeTable) +{ + auto pLookup = getCachedLookup(pAmplitudeTable); + if (pLookup == nullptr) + { + assert(pAmplitudeTable != nullptr); + auto& amplitudeTable = *pAmplitudeTable; + auto lookup = createLookup(amplitudeTable); + amplitudeTable.cacheLookup_(std::move(lookup)); + pLookup = amplitudeTable.getLookup(); + } + assert(pLookup != nullptr); + return *pLookup; +} + +void ImageData::toComplex(const six::Amp8iPhs8iLookup_t& values, std::span inputs, std::span results) +{ + const auto toComplex_ = [&values](const auto& v) + { + return values[v.amplitude][v.phase]; + }; + transform(inputs, results, toComplex_); +} +void ImageData::toComplex(std::span inputs, std::span results) const +{ + if (pixelType != PixelType::AMP8I_PHS8I) + { + throw std::runtime_error("pxielType must be AMP8I_PHS8I"); + } + + const auto& values = getLookup(amplitudeTable.get()); + toComplex(values, inputs, results); +} + +void ImageData::fromComplex(std::span inputs, std::span results) const +{ + six::sicd::details::ComplexToAMP8IPHS8I::nearest_neighbors(inputs, results, amplitudeTable.get()); +} +void ImageData::testing_fromComplex_(std::span inputs, std::span results) +{ + static const ImageData imageData; + assert(imageData.amplitudeTable.get() == nullptr); + imageData.fromComplex(inputs, results); +} diff --git a/six/modules/c++/six.sicd/source/NITFReadComplexXMLControl.cpp b/six/modules/c++/six.sicd/source/NITFReadComplexXMLControl.cpp index 0f8327f01e..bad638fffc 100644 --- a/six/modules/c++/six.sicd/source/NITFReadComplexXMLControl.cpp +++ b/six/modules/c++/six.sicd/source/NITFReadComplexXMLControl.cpp @@ -1,129 +1,129 @@ -/* ========================================================================= - * This file is part of six.sicd-c++ - * ========================================================================= - * - * (C) Copyright 2021 Maxar Technologies, Inc. - * - * six.sicd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include "six/sicd/NITFReadComplexXMLControl.h" - -#include -#include -#include - -#include "six/sicd/ComplexXMLControl.h" -#include "six/sicd/Utilities.h" - -namespace fs = std::filesystem; - -six::sicd::NITFReadComplexXMLControl::NITFReadComplexXMLControl() -{ - // create an XML registry - // The reason to do this is to avoid adding XMLControlCreators to the - // XMLControlFactory singleton - this way has more fine-grained control - addCreator(); -} - -void six::sicd::NITFReadComplexXMLControl::load(const std::string& fromFile, - const std::vector* pSchemaPaths) -{ - reader.load(fromFile, pSchemaPaths); -} -void six::sicd::NITFReadComplexXMLControl::load(const std::filesystem::path& fromFile, - const std::vector* pSchemaPaths) -{ - reader.load(fromFile, pSchemaPaths); -} -void six::sicd::NITFReadComplexXMLControl::load(io::FileInputStream& fis, const std::vector* pSchemaPaths) -{ - reader.load(fis, pSchemaPaths); -} -void six::sicd::NITFReadComplexXMLControl::load(io::FileInputStream& fis, const std::vector* pSchemaPaths) -{ - reader.load(fis, pSchemaPaths); -} - - -std::shared_ptr six::sicd::NITFReadComplexXMLControl::getContainer() const -{ - return reader.getContainer(); -} -std::shared_ptr six::sicd::NITFReadComplexXMLControl::getContainer() -{ - return reader.getContainer(); -} - -void six::sicd::NITFReadComplexXMLControl::setXMLControlRegistry() -{ - // This tells the reader that it doesn't own an XMLControlRegistry - reader.setXMLControlRegistry(nullptr); -} - -std::unique_ptr six::sicd::NITFReadComplexXMLControl::getComplexData() -{ - auto result = Utilities::getComplexData(reader); - return std::unique_ptr< six::sicd::ComplexData>(result.release()); -} - -std::vector six::sicd::NITFReadComplexXMLControl::getWidebandData(const ComplexData& complexData) -{ - std::vector retval; - Utilities::getWidebandData(reader, complexData, retval); - return retval; -} -void six::sicd::NITFReadComplexXMLControl::getWidebandData(const ComplexData& complexData, - const types::RowCol& offset, const types::RowCol& extent, - six::zfloat* buffer) -{ - Utilities::getWidebandData(reader, complexData, offset, extent, buffer); -} - -void six::sicd::NITFReadComplexXMLControl::setLogger() -{ - reader.setLogger(std::make_unique()); -} - -void six::sicd::NITFReadComplexXMLControl::interleaved(Region& region) -{ - constexpr size_t imageNumber = 0; - (void)reader.interleaved(region, imageNumber); -} - -std::vector six::sicd::NITFReadComplexXMLControl::interleaved() -{ - auto pComplexData = getComplexData(); - const auto extent = getExtent(*pComplexData); - const auto numPixels = extent.area(); - const auto numBytesPerPixel = pComplexData->getNumBytesPerPixel(); - size_t offset = 0; - - std::vector buffer(numPixels * numBytesPerPixel); - - six::Region region; - setDims(region, extent); - region.setBuffer(buffer.data() + offset); - interleaved(region); - - return buffer; -} - -void six::sicd::NITFReadComplexXMLControl::getMeshes(std::unique_ptr& noiseMesh, - std::unique_ptr& scalarMesh) const -{ - noiseMesh = Utilities::getNoiseMesh(reader); - scalarMesh = Utilities::getScalarMesh(reader); -} +/* ========================================================================= + * This file is part of six.sicd-c++ + * ========================================================================= + * + * (C) Copyright 2021 Maxar Technologies, Inc. + * + * six.sicd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include "six/sicd/NITFReadComplexXMLControl.h" + +#include +#include +#include + +#include "six/sicd/ComplexXMLControl.h" +#include "six/sicd/Utilities.h" + +namespace fs = std::filesystem; + +six::sicd::NITFReadComplexXMLControl::NITFReadComplexXMLControl() +{ + // create an XML registry + // The reason to do this is to avoid adding XMLControlCreators to the + // XMLControlFactory singleton - this way has more fine-grained control + addCreator(); +} + +void six::sicd::NITFReadComplexXMLControl::load(const std::string& fromFile, + const std::vector* pSchemaPaths) +{ + reader.load(fromFile, pSchemaPaths); +} +void six::sicd::NITFReadComplexXMLControl::load(const std::filesystem::path& fromFile, + const std::vector* pSchemaPaths) +{ + reader.load(fromFile, pSchemaPaths); +} +void six::sicd::NITFReadComplexXMLControl::load(io::FileInputStream& fis, const std::vector* pSchemaPaths) +{ + reader.load(fis, pSchemaPaths); +} +void six::sicd::NITFReadComplexXMLControl::load(io::FileInputStream& fis, const std::vector* pSchemaPaths) +{ + reader.load(fis, pSchemaPaths); +} + + +std::shared_ptr six::sicd::NITFReadComplexXMLControl::getContainer() const +{ + return reader.getContainer(); +} +std::shared_ptr six::sicd::NITFReadComplexXMLControl::getContainer() +{ + return reader.getContainer(); +} + +void six::sicd::NITFReadComplexXMLControl::setXMLControlRegistry() +{ + // This tells the reader that it doesn't own an XMLControlRegistry + reader.setXMLControlRegistry(nullptr); +} + +std::unique_ptr six::sicd::NITFReadComplexXMLControl::getComplexData() +{ + auto result = Utilities::getComplexData(reader); + return std::unique_ptr< six::sicd::ComplexData>(result.release()); +} + +std::vector six::sicd::NITFReadComplexXMLControl::getWidebandData(const ComplexData& complexData) +{ + std::vector retval; + Utilities::getWidebandData(reader, complexData, retval); + return retval; +} +void six::sicd::NITFReadComplexXMLControl::getWidebandData(const ComplexData& complexData, + const types::RowCol& offset, const types::RowCol& extent, + six::zfloat* buffer) +{ + Utilities::getWidebandData(reader, complexData, offset, extent, buffer); +} + +void six::sicd::NITFReadComplexXMLControl::setLogger() +{ + reader.setLogger(std::make_unique()); +} + +void six::sicd::NITFReadComplexXMLControl::interleaved(Region& region) +{ + constexpr size_t imageNumber = 0; + (void)reader.interleaved(region, imageNumber); +} + +std::vector six::sicd::NITFReadComplexXMLControl::interleaved() +{ + auto pComplexData = getComplexData(); + const auto extent = getExtent(*pComplexData); + const auto numPixels = extent.area(); + const auto numBytesPerPixel = pComplexData->getNumBytesPerPixel(); + size_t offset = 0; + + std::vector buffer(numPixels * numBytesPerPixel); + + six::Region region; + setDims(region, extent); + region.setBuffer(buffer.data() + offset); + interleaved(region); + + return buffer; +} + +void six::sicd::NITFReadComplexXMLControl::getMeshes(std::unique_ptr& noiseMesh, + std::unique_ptr& scalarMesh) const +{ + noiseMesh = Utilities::getNoiseMesh(reader); + scalarMesh = Utilities::getScalarMesh(reader); +} diff --git a/six/modules/c++/six.sicd/source/PFA.cpp b/six/modules/c++/six.sicd/source/PFA.cpp index 892b415532..4e3d94d27c 100644 --- a/six/modules/c++/six.sicd/source/PFA.cpp +++ b/six/modules/c++/six.sicd/source/PFA.cpp @@ -21,13 +21,13 @@ */ #include "six/sicd/GeoData.h" #include "six/sicd/Grid.h" -#include "six/sicd/PFA.h" -#include "six/sicd/Position.h" -#include "six/sicd/SCPCOA.h" +#include "six/sicd/PFA.h" +#include "six/sicd/Position.h" +#include "six/sicd/SCPCOA.h" #include "six/sicd/Utilities.h" - + namespace six -{ +{ namespace sicd { SlowTimeDeskew::SlowTimeDeskew() : @@ -44,91 +44,91 @@ PFA::PFA() : kaz1(Init::undefined()), kaz2(Init::undefined()) { -} - -bool PFA::operator==(const PFA& rhs) const -{ - return (focusPlaneNormal == rhs.focusPlaneNormal && - imagePlaneNormal == rhs.imagePlaneNormal && - polarAngleRefTime == rhs.polarAngleRefTime && - polarAnglePoly == rhs.polarAnglePoly && - spatialFrequencyScaleFactorPoly == rhs.spatialFrequencyScaleFactorPoly && - krg1 == rhs.krg1 && - krg2 == rhs.krg2 && - kaz1 == rhs.kaz1 && - kaz2 == rhs.kaz2 && - slowTimeDeskew == rhs.slowTimeDeskew); -} - -void PFA::fillDerivedFields(const Position& position) -{ - if (!Init::isUndefined(position.arpPoly) && - !Init::isUndefined(polarAngleRefTime)) - { - // This doesn't actually do anything currently. - // Requires re-implemenation of polyfit, pfa_polar_coords, and bsxfun - const Vector3 polRefPos = position.arpPoly(polarAngleRefTime); - } -} - -void PFA::fillDefaultFields(const GeoData& geoData, - const Grid& grid, const SCPCOA& scpcoa) -{ - const Vector3& scp = geoData.scp.ecf; - if (Init::isUndefined(imagePlaneNormal)) - { +} + +bool PFA::operator==(const PFA& rhs) const +{ + return (focusPlaneNormal == rhs.focusPlaneNormal && + imagePlaneNormal == rhs.imagePlaneNormal && + polarAngleRefTime == rhs.polarAngleRefTime && + polarAnglePoly == rhs.polarAnglePoly && + spatialFrequencyScaleFactorPoly == rhs.spatialFrequencyScaleFactorPoly && + krg1 == rhs.krg1 && + krg2 == rhs.krg2 && + kaz1 == rhs.kaz1 && + kaz2 == rhs.kaz2 && + slowTimeDeskew == rhs.slowTimeDeskew); +} + +void PFA::fillDerivedFields(const Position& position) +{ + if (!Init::isUndefined(position.arpPoly) && + !Init::isUndefined(polarAngleRefTime)) + { + // This doesn't actually do anything currently. + // Requires re-implemenation of polyfit, pfa_polar_coords, and bsxfun + const Vector3 polRefPos = position.arpPoly(polarAngleRefTime); + } +} + +void PFA::fillDefaultFields(const GeoData& geoData, + const Grid& grid, const SCPCOA& scpcoa) +{ + const Vector3& scp = geoData.scp.ecf; + if (Init::isUndefined(imagePlaneNormal)) + { scene::WGS84EllipsoidModel model; - switch (grid.imagePlane) - { - case ComplexImagePlaneType::SLANT: - case ComplexImagePlaneType::NOT_SET: - imagePlaneNormal = scpcoa.slantPlaneNormal(scp); - break; - case ComplexImagePlaneType::GROUND: + switch (grid.imagePlane) + { + case ComplexImagePlaneType::SLANT: + case ComplexImagePlaneType::NOT_SET: + imagePlaneNormal = scpcoa.slantPlaneNormal(scp); + break; + case ComplexImagePlaneType::GROUND: imagePlaneNormal = model.getNormalVector(scp); - break; - case ComplexImagePlaneType::OTHER: - default: - // Nothing we can do - break; - } - } - - if (Init::isUndefined(focusPlaneNormal)) - { + break; + case ComplexImagePlaneType::OTHER: + default: + // Nothing we can do + break; + } + } + + if (Init::isUndefined(focusPlaneNormal)) + { scene::WGS84EllipsoidModel model; focusPlaneNormal = model.getNormalVector(scp); - } - - if (!Init::isUndefined(scpcoa.scpTime) && - Init::isUndefined(polarAngleRefTime)) - { - polarAngleRefTime = scpcoa.scpTime; - } - - //Vector3 polRefPos = arpPos; - //for when the other functions get implemented -} - -bool PFA::validate(const SCPCOA& scpcoa, logging::Logger& log) -{ - bool valid = true; - std::ostringstream messageBuilder; - - //2.12.2.3 - if (polarAngleRefTime - scpcoa.scpTime > - std::numeric_limits::epsilon()) - { - messageBuilder.str(""); - messageBuilder << "Polar angle reference time and center of aperture " - << "time for center are usuallly the same." << std::endl - << "PFA.PolarAngRefTime: " << polarAngleRefTime << std::endl - << "SCPCOA.SCPTime: " << scpcoa.scpTime; - log.warn(messageBuilder.str()); - valid = false; - } - - return valid; -} + } + + if (!Init::isUndefined(scpcoa.scpTime) && + Init::isUndefined(polarAngleRefTime)) + { + polarAngleRefTime = scpcoa.scpTime; + } + + //Vector3 polRefPos = arpPos; + //for when the other functions get implemented +} + +bool PFA::validate(const SCPCOA& scpcoa, logging::Logger& log) +{ + bool valid = true; + std::ostringstream messageBuilder; + + //2.12.2.3 + if (polarAngleRefTime - scpcoa.scpTime > + std::numeric_limits::epsilon()) + { + messageBuilder.str(""); + messageBuilder << "Polar angle reference time and center of aperture " + << "time for center are usuallly the same." << std::endl + << "PFA.PolarAngRefTime: " << polarAngleRefTime << std::endl + << "SCPCOA.SCPTime: " << scpcoa.scpTime; + log.warn(messageBuilder.str()); + valid = false; + } + + return valid; +} } } diff --git a/six/modules/c++/six.sicd/source/Position.cpp b/six/modules/c++/six.sicd/source/Position.cpp index cacde05b90..8dd5483628 100644 --- a/six/modules/c++/six.sicd/source/Position.cpp +++ b/six/modules/c++/six.sicd/source/Position.cpp @@ -19,11 +19,11 @@ * see . * */ -#include "six/sicd/Position.h" -#include "six/sicd/SCPCOA.h" +#include "six/sicd/Position.h" +#include "six/sicd/SCPCOA.h" #include - -namespace six + +namespace six { namespace sicd { @@ -32,47 +32,47 @@ Position::Position() : grpPoly(Init::undefined()), txAPCPoly(Init::undefined()) { -} - -void Position::fillDerivedFields(const SCPCOA& scpcoa) -{ - if (!Init::isUndefined(scpcoa.arpPos) && - !Init::isUndefined(scpcoa.arpVel) && - !Init::isUndefined(scpcoa.scpTime) && - (Init::isUndefined(arpPoly))) - { - const Vector3 tempArpAcc = Init::isUndefined(scpcoa.arpAcc) ? - Vector3(0.0) : scpcoa.arpAcc; - - std::vector coefs; - coefs.resize(3); - - //constant - coefs[0] = scpcoa.arpPos - - scpcoa.arpVel * scpcoa.scpTime + +} + +void Position::fillDerivedFields(const SCPCOA& scpcoa) +{ + if (!Init::isUndefined(scpcoa.arpPos) && + !Init::isUndefined(scpcoa.arpVel) && + !Init::isUndefined(scpcoa.scpTime) && + (Init::isUndefined(arpPoly))) + { + const Vector3 tempArpAcc = Init::isUndefined(scpcoa.arpAcc) ? + Vector3(0.0) : scpcoa.arpAcc; + + std::vector coefs; + coefs.resize(3); + + //constant + coefs[0] = scpcoa.arpPos - + scpcoa.arpVel * scpcoa.scpTime + (tempArpAcc / 2) * math::square(scpcoa.scpTime); - - //linear - coefs[1] = scpcoa.arpVel - - tempArpAcc * scpcoa.scpTime; - - //quadratic - coefs[2] = tempArpAcc / 2; - - arpPoly = PolyXYZ(coefs); - } -} - -bool Position::validate(logging::Logger& log) const -{ - // 2.6 - if (arpPoly.order() < 2) - { - log.error("Position.arpPoly should have at least position" - " and velocity terms."); - return false; - } - return true; -} -} + + //linear + coefs[1] = scpcoa.arpVel - + tempArpAcc * scpcoa.scpTime; + + //quadratic + coefs[2] = tempArpAcc / 2; + + arpPoly = PolyXYZ(coefs); + } +} + +bool Position::validate(logging::Logger& log) const +{ + // 2.6 + if (arpPoly.order() < 2) + { + log.error("Position.arpPoly should have at least position" + " and velocity terms."); + return false; + } + return true; +} +} } diff --git a/six/modules/c++/six.sicd/source/RadarCollection.cpp b/six/modules/c++/six.sicd/source/RadarCollection.cpp index cc598e4959..e90ea5b3b3 100644 --- a/six/modules/c++/six.sicd/source/RadarCollection.cpp +++ b/six/modules/c++/six.sicd/source/RadarCollection.cpp @@ -1,600 +1,600 @@ -/* ========================================================================= - * This file is part of six.sicd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2014, MDA Information Systems LLC - * - * six.sicd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include -#include - -#undef min -#undef max - -namespace -{ -template -types::RowCol rotatePixel(size_t origNumCols, const types::RowCol& pixel) -{ - types::RowCol rotatedPixel; - rotatedPixel.col = pixel.row; - rotatedPixel.row = static_cast(origNumCols) - pixel.col; - return rotatedPixel; -} -} - -namespace six -{ -namespace sicd -{ -TxStep::TxStep() : - waveformIndex(Init::undefined()), - txPolarization(PolarizationType::NOT_SET) -{ -} - -TxStep* TxStep::clone() const -{ - return new TxStep(*this); -} - -WaveformParameters::WaveformParameters() : - txPulseLength(Init::undefined()), - txRFBandwidth(Init::undefined()), - txFrequencyStart(Init::undefined()), - txFMRate(Init::undefined()), - rcvDemodType(DemodType::NOT_SET), - rcvWindowLength(Init::undefined()), - adcSampleRate(Init::undefined()), - rcvIFBandwidth(Init::undefined()), - rcvFrequencyStart(Init::undefined()), - rcvFMRate(Init::undefined()) -{ -} - -const double WaveformParameters::WF_TOL = 1e-3; -const double WaveformParameters::WGT_TOL = 1e-3; -const char WaveformParameters::WF_INCONSISTENT_STR[] = - "Waveform fields not consistent"; - -const double RadarCollection::WF_TOL = 1e-3; -const char RadarCollection::WF_INCONSISTENT_STR[] = - "Waveform fields not consistent"; - -bool WaveformParameters::operator==(const WaveformParameters& rhs) const -{ - return (txPulseLength == rhs.txPulseLength && - txRFBandwidth == rhs.txRFBandwidth && - txFrequencyStart == rhs.txFrequencyStart && - txFMRate == rhs.txFMRate && - rcvDemodType == rhs.rcvDemodType && - rcvWindowLength == rhs.rcvWindowLength && - adcSampleRate == rhs.adcSampleRate && - rcvIFBandwidth == rhs.rcvIFBandwidth && - rcvFrequencyStart == rhs.rcvFrequencyStart && - rcvFMRate == rhs.rcvFMRate); -} - -WaveformParameters* WaveformParameters::clone() const -{ - return new WaveformParameters(*this); -} - -void WaveformParameters::fillDerivedFields() -{ - if (rcvDemodType == DemodType::CHIRP && - Init::isUndefined(rcvFMRate)) - { - rcvFMRate = 0; - } - - if (rcvFMRate == 0 && - rcvDemodType == DemodType::NOT_SET) - { - rcvDemodType = DemodType::CHIRP; - } - - if (Init::isUndefined(txRFBandwidth) && - !Init::isUndefined(txPulseLength) && - !Init::isUndefined(txFMRate)) - { - txRFBandwidth = txPulseLength * txFMRate; - } - - if (!Init::isUndefined(txRFBandwidth) && - Init::isUndefined(txPulseLength) && - !Init::isUndefined(txFMRate)) - { - txPulseLength = txRFBandwidth / txFMRate; - } - - if (!Init::isUndefined(txRFBandwidth) && - !Init::isUndefined(txPulseLength) && - Init::isUndefined(txFMRate)) - { - txFMRate = txRFBandwidth / txPulseLength; - } -} - -bool WaveformParameters::validate(int refFrequencyIndex, - logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - //2.8.3 - if (std::abs(txRFBandwidth / (txPulseLength * txFMRate) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxFRBandwidth: " - << txRFBandwidth << std::endl - << "SICD.RadarCollection.TxFrequency.txFMRate * txPulseLength: " - << txFMRate * txPulseLength << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.4 - if (rcvDemodType == DemodType::CHIRP && - rcvFMRate != 0) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " - << rcvDemodType << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvFMRate: " - << rcvFMRate << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.5 - if (rcvDemodType == DemodType::STRETCH && - std::abs(rcvFMRate / txFMRate - 1) > WGT_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " - << rcvDemodType << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvFMRate: " - << rcvFMRate << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxFMRate: " - << txFMRate << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.7 - //Absolute frequencies must be positive - if (six::Init::isUndefined(refFrequencyIndex) && - txFrequencyStart <= 0) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.txFreqStart: " - << txFrequencyStart << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.8 - //Absolute frequencies must be positive - if (six::Init::isUndefined(refFrequencyIndex) && - rcvFrequencyStart <= 0) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.rcvFreqStart: " - << rcvFrequencyStart << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.9 - if (six::Init::isDefined(txPulseLength) && (txPulseLength > rcvWindowLength)) // TxPulseLength is optional - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxPulseLength: " - << txPulseLength << std::endl - << "SICD.RadarCollection.Waveform.WFPArameters.RcvWindowLength: " - << rcvWindowLength << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.10 - if (six::Init::isDefined(rcvIFBandwidth) && (rcvIFBandwidth > adcSampleRate)) // RcvIFBandwidth is optional - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvIFBandwidth: " - << rcvIFBandwidth << std::endl - << "SICD.RadarCollection.Waveform.WFPArameters.ADCSampleRate: " - << adcSampleRate << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.11 - if (rcvDemodType == DemodType::CHIRP && txRFBandwidth > adcSampleRate) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " - << rcvDemodType << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxRFBandwidth: " - << txRFBandwidth << std::endl - << "SICD.RadarCollection.Waveform.WFPArameters.ADCSampleRate: " - << adcSampleRate << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.12 - if (six::Init::isDefined(rcvFrequencyStart)) // RcvFreqStart is optional - { - const auto freq_tol = (rcvWindowLength - txPulseLength) * txFMRate; - if (rcvFrequencyStart >= (txFrequencyStart + txRFBandwidth + freq_tol) || - rcvFrequencyStart <= txFrequencyStart - freq_tol) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvFreqStart: " - << rcvFrequencyStart << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - } - - return valid; -} - -ChannelParameters::ChannelParameters() : - txRcvPolarization(DualPolarizationType::NOT_SET), - rcvAPCIndex(Init::undefined()) -{ -} - -ChannelParameters* ChannelParameters::clone() const -{ - return new ChannelParameters(*this); -} - -AreaDirectionParameters::AreaDirectionParameters() : - unitVector(Init::undefined()), - spacing(Init::undefined()), - elements(Init::undefined()), - first(Init::undefined()) -{ -} - -AreaDirectionParameters* AreaDirectionParameters::clone() const -{ - return new AreaDirectionParameters(*this); -} - -std::ostream& operator<< (std::ostream& os, const AreaDirectionParameters& d) -{ - os << "AreaDirectionParameters::\n" - << " unitVector: " << toString(d.unitVector) << "\n" - << " spacing : " << d.spacing << "\n" - << " elements : " << d.elements << "\n" - << " first : " << d.first << "\n"; - return os; -} - -Segment::Segment() : - startLine(Init::undefined()), - startSample(Init::undefined()), - endLine(Init::undefined()), - endSample(Init::undefined()) -{ -} - -bool Segment::operator==(const Segment& rhs) const -{ - return (startLine == rhs.startLine && - startSample == rhs.startSample && - endLine == rhs.endLine && - endSample == rhs.endSample && - identifier == rhs.identifier); -} - -Segment* Segment::clone() const -{ - return new Segment(*this); -} - -AreaPlane::AreaPlane() : - referencePoint(Init::undefined()), - xDirection(new AreaDirectionParameters()), - yDirection(new AreaDirectionParameters()), - orientation(OrientationType::NOT_SET) -{ -} - -AreaPlane* AreaPlane::clone() const -{ - return new AreaPlane(*this); -} - -types::RowCol AreaPlane::getAdjustedReferencePoint() const -{ - types::RowCol refPt = referencePoint.rowCol; - - // NOTE: The calculation done by SICD producers appears to be - // orpRow = (numRows + 1) / 2.0 - // This gives you a pixel-centered, 1-based ORP. We want - // pixel-centered 0-based. More generally than this, we need to - // account for the SICD FirstLine/FirstSample offset - // - refPt.row -= gsl::narrow_cast(xDirection->first); - refPt.col -= gsl::narrow_cast(yDirection->first); - - return refPt; -} - -const Segment& AreaPlane::getSegment(const std::string& segmentId) const -{ - for (size_t ii = 0; ii < segmentList.size(); ++ii) - { - if (segmentList[ii].get() && segmentList[ii]->identifier == segmentId) - { - return *segmentList[ii]; - } - } - throw except::Exception(Ctxt("No segment with identifier " + segmentId)); -} - -void AreaPlane::rotateToShadowsDown() -{ - switch(orientation) - { - case OrientationType::RIGHT: - rotateCCW(); - rotateCCW(); - rotateCCW(); - break; - case OrientationType::UP: - rotateCCW(); - rotateCCW(); - break; - case OrientationType::LEFT: - rotateCCW(); - break; - default: - break; - } -} - -void AreaPlane::rotateCCW() -{ - switch (orientation) - { - case OrientationType::LEFT: - orientation = OrientationType::DOWN; - break; - case OrientationType::DOWN: - orientation = OrientationType::RIGHT; - break; - case OrientationType::RIGHT: - orientation = OrientationType::UP; - break; - case OrientationType::UP: - orientation = OrientationType::LEFT; - break; - default: - break; - } - referencePoint.rowCol = rotatePixel(yDirection->elements, referencePoint.rowCol); - - std::swap(yDirection->elements, xDirection->elements); - std::swap(yDirection->spacing, xDirection->spacing); - std::swap(yDirection->unitVector, xDirection->unitVector); - xDirection->unitVector *= -1; - - for (size_t ii = 0; ii < segmentList.size(); ++ii) - { - segmentList[ii]->rotateCCW(xDirection->elements); - } -} - -void Segment::rotateCCW(size_t numColumns) -{ - /* - * 5 wth -- ! is reference corner - * !----- | | 2 right, 1 down becomes - * | . | 2 ht. --> | | 1 right, 2 up - * | | | | - * ------ |. | - * | | - * !-- - */ - - const auto numColumns_ = gsl::narrow(numColumns); - const six::RowColDouble start(types::RowCol(numColumns_ - 1 - endSample, startLine)); - const six::RowColDouble end(types::RowCol(numColumns_ - 1 - startSample, endLine)); - startLine = gsl::narrow_cast(start.row); - startSample = gsl::narrow_cast(start.col); - endLine = gsl::narrow_cast(end.row); - endSample = gsl::narrow_cast(end.col); -} - - -Area::Area() -{ - const LatLonAlt initial = Init::undefined(); - for (size_t ii = 0; ii < LatLonAltCorners::NUM_CORNERS; ++ii) - { - acpCorners.getCorner(ii) = initial; - } -} - -Area* Area::clone() const -{ - return new Area(*this); -} - -RadarCollection* RadarCollection::clone() const -{ - return new RadarCollection(*this); -} - -bool RadarCollection::operator==(const RadarCollection& rhs) const -{ - return (refFrequencyIndex == rhs.refFrequencyIndex && - txFrequencyMin == rhs.txFrequencyMin && - txFrequencyMax == rhs.txFrequencyMax && - txPolarization == rhs.txPolarization && - polarizationHVAnglePoly == rhs.polarizationHVAnglePoly && - txSequence == rhs.txSequence && - waveform == rhs.waveform && - rcvChannels == rhs.rcvChannels && - area == rhs.area && - parameters == rhs.parameters); -} - -double RadarCollection::waveformMax() const -{ - double derivedMax = -std::numeric_limits::infinity(); - for (size_t ii = 0; ii < waveform.size(); ++ii) - { - if (waveform[ii].get() != nullptr) - { - derivedMax = std::max(derivedMax, - waveform[ii]->txFrequencyStart + - waveform[ii]->txRFBandwidth); - } - } - return derivedMax; -} - -double RadarCollection::waveformMin() const -{ - double derivedMin = std::numeric_limits::infinity(); - for (size_t ii = 0; ii < waveform.size(); ++ii) - { - if (waveform[ii].get() != nullptr) - { - derivedMin = std::min(derivedMin, - waveform[ii]->txFrequencyStart); - } - } - return derivedMin; -} - -void RadarCollection::fillDerivedFields() -{ - // Transmit bandwidth - if (!waveform.empty()) - { - if (Init::isUndefined(txFrequencyMin)) - { - txFrequencyMin = waveformMin(); - } - if (Init::isUndefined(txFrequencyMax)) - { - txFrequencyMax = waveformMax(); - } - - for (size_t ii = 0; ii < waveform.size(); ++ii) - { - if (waveform[ii].get() != nullptr) - { - waveform[ii]->fillDerivedFields(); - } - } - } - - if (waveform.size() == 1 && - waveform[0].get() != nullptr) - { - if (Init::isUndefined(waveform[0]->txFrequencyStart)) - { - waveform[0]->txFrequencyStart = txFrequencyMin; - } - if (Init::isUndefined(waveform[0]->txRFBandwidth)) - { - waveform[0]->txRFBandwidth = txFrequencyMax - txFrequencyMin; - } - } -} - -bool RadarCollection::validate(logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - // 2.8 Waveform description consistency - const auto wfMin = waveformMin(); - const auto wfMax = waveformMax(); - - // 2.8.1 - if (wfMin != std::numeric_limits::infinity() && - std::abs((wfMin / txFrequencyMin) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxFreqStart: " - << wfMin << std::endl - << "SICD.RadarCollection.TxFrequency.Min: " << txFrequencyMin - << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.2 - if (wfMax != -std::numeric_limits::infinity() && - std::abs((wfMax / txFrequencyMax) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxFreqStart" - << " + TxFRBandwidth: " << wfMax << std::endl - << "SICD.RadarCollection.TxFrequency.Max: " - << txFrequencyMax << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.6 - //Absolute frequencies must be positive - if (six::Init::isUndefined(refFrequencyIndex) && txFrequencyMin <= 0) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.txFrequencyMin: " - << txFrequencyMin << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - for (size_t ii = 0; ii < waveform.size(); ++ii) - { - if (waveform[ii].get()) - { - valid = waveform[ii]->validate(refFrequencyIndex, log) && valid; - } - } - return valid; -} -} -} +/* ========================================================================= + * This file is part of six.sicd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * six.sicd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include +#include + +#undef min +#undef max + +namespace +{ +template +types::RowCol rotatePixel(size_t origNumCols, const types::RowCol& pixel) +{ + types::RowCol rotatedPixel; + rotatedPixel.col = pixel.row; + rotatedPixel.row = static_cast(origNumCols) - pixel.col; + return rotatedPixel; +} +} + +namespace six +{ +namespace sicd +{ +TxStep::TxStep() : + waveformIndex(Init::undefined()), + txPolarization(PolarizationType::NOT_SET) +{ +} + +TxStep* TxStep::clone() const +{ + return new TxStep(*this); +} + +WaveformParameters::WaveformParameters() : + txPulseLength(Init::undefined()), + txRFBandwidth(Init::undefined()), + txFrequencyStart(Init::undefined()), + txFMRate(Init::undefined()), + rcvDemodType(DemodType::NOT_SET), + rcvWindowLength(Init::undefined()), + adcSampleRate(Init::undefined()), + rcvIFBandwidth(Init::undefined()), + rcvFrequencyStart(Init::undefined()), + rcvFMRate(Init::undefined()) +{ +} + +const double WaveformParameters::WF_TOL = 1e-3; +const double WaveformParameters::WGT_TOL = 1e-3; +const char WaveformParameters::WF_INCONSISTENT_STR[] = + "Waveform fields not consistent"; + +const double RadarCollection::WF_TOL = 1e-3; +const char RadarCollection::WF_INCONSISTENT_STR[] = + "Waveform fields not consistent"; + +bool WaveformParameters::operator==(const WaveformParameters& rhs) const +{ + return (txPulseLength == rhs.txPulseLength && + txRFBandwidth == rhs.txRFBandwidth && + txFrequencyStart == rhs.txFrequencyStart && + txFMRate == rhs.txFMRate && + rcvDemodType == rhs.rcvDemodType && + rcvWindowLength == rhs.rcvWindowLength && + adcSampleRate == rhs.adcSampleRate && + rcvIFBandwidth == rhs.rcvIFBandwidth && + rcvFrequencyStart == rhs.rcvFrequencyStart && + rcvFMRate == rhs.rcvFMRate); +} + +WaveformParameters* WaveformParameters::clone() const +{ + return new WaveformParameters(*this); +} + +void WaveformParameters::fillDerivedFields() +{ + if (rcvDemodType == DemodType::CHIRP && + Init::isUndefined(rcvFMRate)) + { + rcvFMRate = 0; + } + + if (rcvFMRate == 0 && + rcvDemodType == DemodType::NOT_SET) + { + rcvDemodType = DemodType::CHIRP; + } + + if (Init::isUndefined(txRFBandwidth) && + !Init::isUndefined(txPulseLength) && + !Init::isUndefined(txFMRate)) + { + txRFBandwidth = txPulseLength * txFMRate; + } + + if (!Init::isUndefined(txRFBandwidth) && + Init::isUndefined(txPulseLength) && + !Init::isUndefined(txFMRate)) + { + txPulseLength = txRFBandwidth / txFMRate; + } + + if (!Init::isUndefined(txRFBandwidth) && + !Init::isUndefined(txPulseLength) && + Init::isUndefined(txFMRate)) + { + txFMRate = txRFBandwidth / txPulseLength; + } +} + +bool WaveformParameters::validate(int refFrequencyIndex, + logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + //2.8.3 + if (std::abs(txRFBandwidth / (txPulseLength * txFMRate) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxFRBandwidth: " + << txRFBandwidth << std::endl + << "SICD.RadarCollection.TxFrequency.txFMRate * txPulseLength: " + << txFMRate * txPulseLength << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.4 + if (rcvDemodType == DemodType::CHIRP && + rcvFMRate != 0) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " + << rcvDemodType << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvFMRate: " + << rcvFMRate << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.5 + if (rcvDemodType == DemodType::STRETCH && + std::abs(rcvFMRate / txFMRate - 1) > WGT_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " + << rcvDemodType << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvFMRate: " + << rcvFMRate << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxFMRate: " + << txFMRate << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.7 + //Absolute frequencies must be positive + if (six::Init::isUndefined(refFrequencyIndex) && + txFrequencyStart <= 0) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.txFreqStart: " + << txFrequencyStart << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.8 + //Absolute frequencies must be positive + if (six::Init::isUndefined(refFrequencyIndex) && + rcvFrequencyStart <= 0) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.rcvFreqStart: " + << rcvFrequencyStart << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.9 + if (six::Init::isDefined(txPulseLength) && (txPulseLength > rcvWindowLength)) // TxPulseLength is optional + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxPulseLength: " + << txPulseLength << std::endl + << "SICD.RadarCollection.Waveform.WFPArameters.RcvWindowLength: " + << rcvWindowLength << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.10 + if (six::Init::isDefined(rcvIFBandwidth) && (rcvIFBandwidth > adcSampleRate)) // RcvIFBandwidth is optional + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvIFBandwidth: " + << rcvIFBandwidth << std::endl + << "SICD.RadarCollection.Waveform.WFPArameters.ADCSampleRate: " + << adcSampleRate << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.11 + if (rcvDemodType == DemodType::CHIRP && txRFBandwidth > adcSampleRate) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " + << rcvDemodType << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxRFBandwidth: " + << txRFBandwidth << std::endl + << "SICD.RadarCollection.Waveform.WFPArameters.ADCSampleRate: " + << adcSampleRate << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.12 + if (six::Init::isDefined(rcvFrequencyStart)) // RcvFreqStart is optional + { + const auto freq_tol = (rcvWindowLength - txPulseLength) * txFMRate; + if (rcvFrequencyStart >= (txFrequencyStart + txRFBandwidth + freq_tol) || + rcvFrequencyStart <= txFrequencyStart - freq_tol) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvFreqStart: " + << rcvFrequencyStart << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + } + + return valid; +} + +ChannelParameters::ChannelParameters() : + txRcvPolarization(DualPolarizationType::NOT_SET), + rcvAPCIndex(Init::undefined()) +{ +} + +ChannelParameters* ChannelParameters::clone() const +{ + return new ChannelParameters(*this); +} + +AreaDirectionParameters::AreaDirectionParameters() : + unitVector(Init::undefined()), + spacing(Init::undefined()), + elements(Init::undefined()), + first(Init::undefined()) +{ +} + +AreaDirectionParameters* AreaDirectionParameters::clone() const +{ + return new AreaDirectionParameters(*this); +} + +std::ostream& operator<< (std::ostream& os, const AreaDirectionParameters& d) +{ + os << "AreaDirectionParameters::\n" + << " unitVector: " << toString(d.unitVector) << "\n" + << " spacing : " << d.spacing << "\n" + << " elements : " << d.elements << "\n" + << " first : " << d.first << "\n"; + return os; +} + +Segment::Segment() : + startLine(Init::undefined()), + startSample(Init::undefined()), + endLine(Init::undefined()), + endSample(Init::undefined()) +{ +} + +bool Segment::operator==(const Segment& rhs) const +{ + return (startLine == rhs.startLine && + startSample == rhs.startSample && + endLine == rhs.endLine && + endSample == rhs.endSample && + identifier == rhs.identifier); +} + +Segment* Segment::clone() const +{ + return new Segment(*this); +} + +AreaPlane::AreaPlane() : + referencePoint(Init::undefined()), + xDirection(new AreaDirectionParameters()), + yDirection(new AreaDirectionParameters()), + orientation(OrientationType::NOT_SET) +{ +} + +AreaPlane* AreaPlane::clone() const +{ + return new AreaPlane(*this); +} + +types::RowCol AreaPlane::getAdjustedReferencePoint() const +{ + types::RowCol refPt = referencePoint.rowCol; + + // NOTE: The calculation done by SICD producers appears to be + // orpRow = (numRows + 1) / 2.0 + // This gives you a pixel-centered, 1-based ORP. We want + // pixel-centered 0-based. More generally than this, we need to + // account for the SICD FirstLine/FirstSample offset + // + refPt.row -= gsl::narrow_cast(xDirection->first); + refPt.col -= gsl::narrow_cast(yDirection->first); + + return refPt; +} + +const Segment& AreaPlane::getSegment(const std::string& segmentId) const +{ + for (size_t ii = 0; ii < segmentList.size(); ++ii) + { + if (segmentList[ii].get() && segmentList[ii]->identifier == segmentId) + { + return *segmentList[ii]; + } + } + throw except::Exception(Ctxt("No segment with identifier " + segmentId)); +} + +void AreaPlane::rotateToShadowsDown() +{ + switch(orientation) + { + case OrientationType::RIGHT: + rotateCCW(); + rotateCCW(); + rotateCCW(); + break; + case OrientationType::UP: + rotateCCW(); + rotateCCW(); + break; + case OrientationType::LEFT: + rotateCCW(); + break; + default: + break; + } +} + +void AreaPlane::rotateCCW() +{ + switch (orientation) + { + case OrientationType::LEFT: + orientation = OrientationType::DOWN; + break; + case OrientationType::DOWN: + orientation = OrientationType::RIGHT; + break; + case OrientationType::RIGHT: + orientation = OrientationType::UP; + break; + case OrientationType::UP: + orientation = OrientationType::LEFT; + break; + default: + break; + } + referencePoint.rowCol = rotatePixel(yDirection->elements, referencePoint.rowCol); + + std::swap(yDirection->elements, xDirection->elements); + std::swap(yDirection->spacing, xDirection->spacing); + std::swap(yDirection->unitVector, xDirection->unitVector); + xDirection->unitVector *= -1; + + for (size_t ii = 0; ii < segmentList.size(); ++ii) + { + segmentList[ii]->rotateCCW(xDirection->elements); + } +} + +void Segment::rotateCCW(size_t numColumns) +{ + /* + * 5 wth -- ! is reference corner + * !----- | | 2 right, 1 down becomes + * | . | 2 ht. --> | | 1 right, 2 up + * | | | | + * ------ |. | + * | | + * !-- + */ + + const auto numColumns_ = gsl::narrow(numColumns); + const six::RowColDouble start(types::RowCol(numColumns_ - 1 - endSample, startLine)); + const six::RowColDouble end(types::RowCol(numColumns_ - 1 - startSample, endLine)); + startLine = gsl::narrow_cast(start.row); + startSample = gsl::narrow_cast(start.col); + endLine = gsl::narrow_cast(end.row); + endSample = gsl::narrow_cast(end.col); +} + + +Area::Area() +{ + const LatLonAlt initial = Init::undefined(); + for (size_t ii = 0; ii < LatLonAltCorners::NUM_CORNERS; ++ii) + { + acpCorners.getCorner(ii) = initial; + } +} + +Area* Area::clone() const +{ + return new Area(*this); +} + +RadarCollection* RadarCollection::clone() const +{ + return new RadarCollection(*this); +} + +bool RadarCollection::operator==(const RadarCollection& rhs) const +{ + return (refFrequencyIndex == rhs.refFrequencyIndex && + txFrequencyMin == rhs.txFrequencyMin && + txFrequencyMax == rhs.txFrequencyMax && + txPolarization == rhs.txPolarization && + polarizationHVAnglePoly == rhs.polarizationHVAnglePoly && + txSequence == rhs.txSequence && + waveform == rhs.waveform && + rcvChannels == rhs.rcvChannels && + area == rhs.area && + parameters == rhs.parameters); +} + +double RadarCollection::waveformMax() const +{ + double derivedMax = -std::numeric_limits::infinity(); + for (size_t ii = 0; ii < waveform.size(); ++ii) + { + if (waveform[ii].get() != nullptr) + { + derivedMax = std::max(derivedMax, + waveform[ii]->txFrequencyStart + + waveform[ii]->txRFBandwidth); + } + } + return derivedMax; +} + +double RadarCollection::waveformMin() const +{ + double derivedMin = std::numeric_limits::infinity(); + for (size_t ii = 0; ii < waveform.size(); ++ii) + { + if (waveform[ii].get() != nullptr) + { + derivedMin = std::min(derivedMin, + waveform[ii]->txFrequencyStart); + } + } + return derivedMin; +} + +void RadarCollection::fillDerivedFields() +{ + // Transmit bandwidth + if (!waveform.empty()) + { + if (Init::isUndefined(txFrequencyMin)) + { + txFrequencyMin = waveformMin(); + } + if (Init::isUndefined(txFrequencyMax)) + { + txFrequencyMax = waveformMax(); + } + + for (size_t ii = 0; ii < waveform.size(); ++ii) + { + if (waveform[ii].get() != nullptr) + { + waveform[ii]->fillDerivedFields(); + } + } + } + + if (waveform.size() == 1 && + waveform[0].get() != nullptr) + { + if (Init::isUndefined(waveform[0]->txFrequencyStart)) + { + waveform[0]->txFrequencyStart = txFrequencyMin; + } + if (Init::isUndefined(waveform[0]->txRFBandwidth)) + { + waveform[0]->txRFBandwidth = txFrequencyMax - txFrequencyMin; + } + } +} + +bool RadarCollection::validate(logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + // 2.8 Waveform description consistency + const auto wfMin = waveformMin(); + const auto wfMax = waveformMax(); + + // 2.8.1 + if (wfMin != std::numeric_limits::infinity() && + std::abs((wfMin / txFrequencyMin) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxFreqStart: " + << wfMin << std::endl + << "SICD.RadarCollection.TxFrequency.Min: " << txFrequencyMin + << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.2 + if (wfMax != -std::numeric_limits::infinity() && + std::abs((wfMax / txFrequencyMax) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxFreqStart" + << " + TxFRBandwidth: " << wfMax << std::endl + << "SICD.RadarCollection.TxFrequency.Max: " + << txFrequencyMax << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.6 + //Absolute frequencies must be positive + if (six::Init::isUndefined(refFrequencyIndex) && txFrequencyMin <= 0) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.txFrequencyMin: " + << txFrequencyMin << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + for (size_t ii = 0; ii < waveform.size(); ++ii) + { + if (waveform[ii].get()) + { + valid = waveform[ii]->validate(refFrequencyIndex, log) && valid; + } + } + return valid; +} +} +} From 89deb197ef8c8174e47a74fe87fc9f15a60baeef Mon Sep 17 00:00:00 2001 From: "J. Daniel Smith" Date: Mon, 21 Aug 2023 10:03:43 -0400 Subject: [PATCH 2/2] latest from CODA-OSS and NITRO (#686) * latest from CODA-OSS and NITRO * Squashed 'externals/coda-oss/' changes from e87c32b4d..168cbae01 168cbae01 reduce differences between 'main' and 'cpp17' (#724) 5b892bf5f release 2023-08-18 (#723) 0b1327d1e restore mem::AutoPtr; too much of a hassle moving it to numpyutils :-( (#722) 7691adb56 normalize line endings (#721) b7d50efdd update to HDF5 1.14.2 (#720) fcc96ec69 Update .gitattributes (#719) bb82a94c9 xerces-c 3.2.4 (#718) ef4ad7cf3 Update to e2fsprogs 1.47.0 (#717) b4ca18a11 fix compiler warning about order of operations a5df5b823 update to HighFive 2.7.1 (#716) 4109ee5d2 `mem::AutoPtr` is only for Python bindings (#715) 00d843f87 remove hdf5.lite (#714) 443dd3825 Reduce compiler warnings, speed up builds (#713) d60861821 get optional working with partial C++17 (#712) d5bd0d804 "warning STL4036: is removed in C++20." c19ece7f9 Don't interfere with a partial C++20 implementation (#711) 065e86ddc operator==() for QName (#710) 1c16380ce remove zint* typedefs; don't want to encourage use of types::Complex (#709) 6dd247991 our optional<> is now closer to C++17 (#708) 87ac61739 strict checking on `std::complex` is too much of a hassle for now 034d52c86 overloads to byte-swap type::Complex are too much trouble (#707) 42d449c33 sys::byteSwap overloads for types::Complex (#705) 4092fd8e7 remove work-around for NITRO bug (#704) e2472acfc build in NITRO and SIX (#703) 32ccf9105 Use same build paths as Visual Studio (#701) 366ac9f43 Another round of removing compiler warnings (#702) a7f8ef260 Fix compile warnings from building CODA (#700) f70b4202f account for coda-oss.vcxproj being in other SLNs af3faebfc Remove more compiler/code-analysis warnings (#699) 82be2a6db unittests should work w/o install (#698) dbb90a06d add msbuild for coda-oss.sln (#697) 5a417140a reduce compiler warnings (#696) 288619dfa all modules now part of coda-oss.vcxproj (#695) c2fc5fc66 add more projects to coda-oss-lite.vcxproj (#694) ceb86c186 support $(PlatformToolset) as a "special" environment variable (#693) d78a8595a OS::getSIMDInstructionSet() utility (#692) 2d2df467d fix `python3 waf dumplib` 54033e70e Merge branch 'main' into feature/complex_short 3c63f9f65 std::numbers from C++20 (#691) 892dd0e00 ComplexInteger and ComplexReal to better match existing naming conventions (#690) b3872181e match coda-oss naming conventions (#688) 704d6867f beef-up our complex type (#687) 47c1c1cd6 check is_absolute() for URLs (#686) c042373e1 be sure our Path::isAbolute() matches std::filesystem::path::absolute() (#684) ad10286bc volatile is about "special" memory, not threading (#685) f4d42005f fix build error in NITRO ff11a5557 keep using std::complex for now (#682) c88b9c053 types::complex (#681) d1244a080 don't need our own make_unique in C++14 (#680) aeec0131c assert()s for mem::CopyablePtr (#679) 72b0ebd60 add types::complex_short (#678) 932130a58 patch to build other projects c00c1f203 coda-oss release 2023-06-06 (#677) ef54bbcd5 remove more compiler warnings (#676) dadfc5ce6 distinguish between byte-swapping a buffer and single value (#674) 90187f6cd more xml.lite tweaks for SIDD-3.0/ISM (#675) eb9960772 stronger type-checking for byteSwap() (#673) ff4f820ed xml.lite tweaks to support SIDD 3.0 ISM (#672) b1de8c0e5 std::byte should be a unique type (#671) c05bf9a02 allow enums to be byte-swapped too 1f9fd88d6 remove spurious 47684c45b byteSwap now uses byte buffers (#670) cbc659db2 add swapBytes() utility from SIX (#669) 891481b64 simplify byte-swapping (#668) 540ae763e more byteSwap() tweaks 0774c03c4 threaded byteSwap() (#667) d156370d3 swapping a single-byte value makes no sense c120e3255 be sure parameter is used to avoid compiler warning e85ec9331 --output-on-failure for CTest (#666) e80376197 turn off "there is no warning number" warning c5f0a5d15 A C-string may not be NULL-terminated (#665) 0c5eb29ae use platform-specific routines for byteSwap() (#664) 0b7d581fa remove transform_async() (#663) f6489b6be Merge branch 'main' into feature/xml.lite_tweaks 836c426a2 use function-pointers so that isConsoleOutput is only checked once 56e3c45b1 move depthPrint() functionality into non-member function in preparation for future changes ddcd26d97 Merge branch 'main' into feature/xml.lite_tweaks 69cc0e506 use the more rigorous create_and_check_datatype() 9efb87558 Merge branch 'main' into feature/hdf5 4d2f2f417 more HighFive unittests (#662) 14191a844 HighFive::create_datatype() goes from C++ to HighFive 98583473f utility routines to read string attributes 1fa75ce81 use the C API to read a string attribute 71e7b69f5 still can't figure out how to read a string attribute :-( e96f37a69 test reading the file attributes a25244519 getAttribute() unittest 8f12a3000 getDataType() unittest 857ff0af3 HighFive utility routines (#661) 1d687db57 writeDataSet() utility overload 106aa6894 sigh ... H5Easy::dump() fill fails on Windows/WAF :-( 2641b60b2 Merge branch 'main' into feature/hdf5 35c19e7e8 change actions to @v3 (#660) 212bbd3a3 works on local machine, but not build server ... ? 7125118b0 dump of 1D vector doesn't work :-( c704db435 sigh ... WAF build still failing :-( 01aae4616 does dump() of a 1D vector work? 76a53c813 comment-out H5 writing :-( 0f0e19aff test_highfive_dump() cb8f73795 trying to get highfive_dump() unittest working w/Windows-WAF 6584a264a does test_highfive_create() work? cde6147ce tweak HighFive wrappers (#659) 316566854 Revert "trying HighFive "write" unittests again" a9ec24ca4 trying HighFive "write" unittests again 585ad49a5 tweak names of utility routines 4c91a4d97 make it easier to read a std::vector and std::vecotr 0217ffa26 readDataSet() now works for 1D data 95e8973f2 trying to get hdf5::lite::load() working 4d294611d "const" correctness 5e6305c3f fix load_complex() 4a134dc5f start work on utility routines to read complex data from HDF5 9d76a7f41 Merge branch 'main' into feature/hdf5 8f9667a24 whitepsace ebd3fc99e Merge branch 'main' into feature/hdf5 40091b069 comment-out writing tests for now ... need to figure our WAF bulid failure 935aa3459 be sure the dataset has real data 114b9bf33 update release notes bd9c0b26c tweak HighFive utility routines acda1ef57 turn off diagnostics around expected failures 22a748840 readDataSet() utility routine for HighFive bd88a8c25 HighFive writeDataSet() utility to work with our SpanRC 6142f5b33 use HighFive routines to write a HDF5 file 5bbf1abaf Use HiveFive routines to get info about the file 84fbc8378 duplicate unittests with H5Easy f1f054c03 Merge branch 'main' into feature/hdf5 9b63ca470 fix directory names f6f826689 fix directory names 7aeb82c33 Merge branch 'main' into feature/hdf5 d028baaeb hook up HighFive header-only library (#653) 3083b0a31 Revert "HighFive 2.6.2" 246985a7f Revert ""build" HighFive HDF5 library" a8b75a586 Revert "turn off HighFive Boost support" ec68d5f83 Revert "Add HighFive unittests" f1f85b9e7 Revert "get test_high_five_base more-or-less compiling" 5ea634ee1 Revert "more work on getting HighFive unittests to build" ecc45433c more work on getting HighFive unittests to build bb194788a get test_high_five_base more-or-less compiling d42bde000 Add HighFive unittests ddc86bb32 turn off HighFive Boost support b255122d4 "build" HighFive HDF5 library 396cc3ef2 HighFive 2.6.2 5e5f9d9c0 Merge branch 'main' into feature/hdf5 ee938b4a5 changes from SIX bb764df90 Merge branch 'main' into feature/xml.lite_tweaks de2a24380 make derived classes 'final' if possible 14e19bcd2 Change xml lite function to virtual (#645) 8f42ac8e9 Merge branch 'main' into feature/xml.lite_tweaks 18ad90645 hdf5Write unittest 3462e1179 createFile() and writeFile() overloads ecee81d53 fix typos 197eecfa6 sketch-out hdf5::lite::writeFile() bd2311795 use SpanRC for writeFile(), not yet implemented ea9af7510 simple SpanRC to hold a 2D-size and pointer 027c19ee8 createFile() unittest 1f9d07ecb hook up createFile() 8c7e4473f start hooking up HDF5 writing 146e0bea3 Merge branch 'main' into feature/hdf5 88ca9fcb7 Merge branch 'main' into feature/hdf5 42b604b46 Squashed commit of the following: 10ee602c2 Merge branch 'main' into feature/hdf5 67aa42b69 restore changes from "main" 8bbfcbfbf unittests can be simplified to match fewer "view" classes 126bb802e Merge branch 'main' into feature/hdf5 3f8ba7a42 again, don't need a class just to convert from std::vector<> to std::span<> 24c2b489c Squashed commit of the following: 2703c119d Squashed commit of the following: 9d5228a2b don't need an entire class just to convert a std::vector<> into std::span<> 51bc931dc Merge branch 'main' into feature/hdf5 a84f25816 Squashed commit of the following: c4d2ed696 add missing #include guards, fix type in existing #include guard d541525a0 use a single ComplexViewConstIterator for all views 86e6a459f CODA_OSS_disable_warning causes GCC errors :-( 5d4b9c2cb only need an custom iterator for ComplexSpansView d9f0fb128 hook up iterators b9329e4db initial pass at a ComplexViewConstIterator 635238873 remove compiler warning about unused "constexpr" variables b39f6096f use the casing from H5 to make copy/pasting code slightly easier 0887b13eb Merge branch 'main' into feature/hdf5 bd07df1ca Consistent casing for Dataset, Datatype, Dataspace 7acd30ee2 tweak hdf5.lite dependencies 38ab914df Jupyter notebook for creating H5 files 95a040e0b _small.h5 is now (correctly) FLOAT32 107e7c487 make a simple values() member function to avoid template magic e1feca919 use TEST_SPECIFIC_EXCEPTION macro instead of try/catch 738333688 readDatasetT() now throws for the wrong buffer type 6b2cc2529 Merge branch 'feature/hdf5' of github.com:mdaus/coda-oss into feature/hdf5 310f8fd3d can't get template magic right for copy_axis() 86b306d59 stepping through copy ctors in the debugger is annoying f243e92d6 trying to make wrong type of buffer fail 2b10d9652 read in new sample file a28e59d8c help the compiler with type deduction 49bf5e9bc nested_complex_float_data_small.h5 e029325fc utility routines to "deconstruct" and array of std::complex dede3bd39 Merge branch 'main' into feature/hdf5 904b1ef5e tweak class names, make_() and copy() utility routines 8237b9efb make it harder to pass the wrong types to ComplexViews 4d9aeda2c ComplexArrayView and ComplexParallelView utility classes f5e367dfa test std::span> a4a2844f2 read in the nested "i" and "r" data 115615265 sample file has subgroups 8e1b7869a Merge branch 'feature/hdf5' of github.com:mdaus/coda-oss into feature/hdf5 9f4232a1d update sample H5 file 8c55db73a walk through HDF5 sub-groups 7775ed9c4 Update 123_barfoo_catdog_cx.h5 677975d7c Matlab code to create sample H5 file a0e7dfe07 Update test_hdf5info.cpp 0b67e1602 pass __FILE__ and __LINE__ from calling site for a more accurate exception message 86a677321 skeleton for more sample data 85f79b099 Merge branch 'main' into feature/hdf5 18088e942 Merge branch 'main' into feature/hdf5 3a1d17692 Merge branch 'main' into feature/hdf5 1755c69d7 Merge branch 'main' into feature/hdf5 9ad015432 No more "11" suffix on exception names c20d96251 Squashed commit of the following: c88cee999 other values to be filled-in bca4a4ecd incorporation NamedObject from HDF5 docs 61fa68f72 groupInfo() 460e7d766 datasetInfo() 14eb9b764 start filling in DatasetInfo afe5f1c3a start to fill in DatasetInfo 77a968c72 start filling in GroupInfo d81bcdfd9 openGroup() to open groups (loc) a0cd29469 comment-out "dataset" unittest for now 86e006024 begin filling in FileInfo 366dda6ab a return_type_of utility is needed to deduce the return type e21928263 explicitly pass return type to template 4937ccd11 template to reduce boilerplate when calling try_catch_H5Exceptions b3b5ebde7 use new exception utility routines ea1c03ef0 put exception handling/conversion in a utility routine 819a99d39 utility routine for exception handling 6f34eea97 put utilities in a separate file for easier reuse fcbde4f24 break utility routines into smaller pieces for easier reuse 52358ea8a WIN32 no longer automatically defined? 5a4286472 Revert "build HDF5 with C89" 680e599e9 build HDF5 with C89 a87a07121 Merge branch 'main' into feature/hdf5 8447c1a90 Revert "sym-links instead of copying files" db3b5e12b Merge branch 'main' into feature/xml.lite_tweaks fb60b5696 Merge branch 'main' into feature/hdf5 5110a5cc8 Comments about _u and _q 1a937d32c Merge branch 'main' into feature/xml.lite_tweaks fa06f04d7 get ready for hdf5.lite enhancdements b040c7c43 sym-links instead of copying files aa431bb47 use _u for xml::lite::Uri 3d0c6d58c fix case-sensitive #include filename 93dcd0e52 operator() for getElementByName() 75a93af85 more operator[] overloads to make attribute management easier 4ab8216f8 user-defined string literals to remove some noise around xml::lite::QName f82f0b0fc Merge branch 'main' into feature/xml.lite_tweaks ae30e3644 Merge branch 'feature/xml.lite_tweaks' of github.com:mdaus/coda-oss into feature/xml.lite_tweaks ffdd9beb0 simplify attribute creation 9bf5414f5 simplify attribute creation 82d7a4e95 SWIG gets confused about namespaces 7a61d0741 fix bug on Element ctor uncovered by unittest fdd7e58c1 QName is also in the xerces namespace which confuses SWIG bindings a325b7053 operator+=() overload for addChild daf30e6c0 Merge branch 'feature/xml.lite_tweaks' of github.com:mdaus/coda-oss into feature/xml.lite_tweaks b887d2b47 provide overloads for Element& rather than creating new "reference" types 1fa6bba38 rename test_xmleasy.cpp 7c8c9e0f1 += overload 850da6f63 overload for std::string 4547fc5a7 use UIT-8 strings for characterData 4723462a3 convenient addChild() overloads e48720753 copy over ElementReference from xml.easy a4ca30a0d Merge branch 'main' into feature/xml.lite_tweaks 6ae9f0b71 Revert "check-in of new xml.easy (to move code between computers)" f7466a6d7 Revert "simple routines for single element" a5490230d Revert "make some operators simplier ways of calling functions" c9a25630a Revert "get document creation working" 8af8710b0 Revert "free functions instead of member functions" 16c3847cb Revert "ElementReference distinct from Element" 7d68e156f Revert "ElementMutableReference" 00eb2a282 Merge branch 'main' into feature/xml.lite_tweaks a42969c1f ElementMutableReference a20ae9355 ElementReference distinct from Element 14eeeea0b free functions instead of member functions 4aae014b3 get document creation working 883569269 make some operators simplier ways of calling functions 053bd1212 simple routines for single element 8bf701a2e check-in of new xml.easy (to move code between computers) 41f959051 unittests for creating XML documents from scratch 9752d50ae Merge branch 'main' into feature/xml.lite_tweaks 1531d5709 by default, don't validate strings passed to Uri() 46d13d4bf Merge branch 'master' into feature/xml.lite_tweaks 39b547d32 remove more vestiges of Expat and LibXML ec8274d52 remove LibXML and Expat as they're no longer used/supported. 20eeefeef Merge branch 'master' into feature/xml.lite_tweaks 95074b9b1 update for newer Intel compiler 7024f71e1 Merge branch 'master' into feature/xml.lite_tweaks 57b1cbc83 Merge branch 'master' into feature/xml.lite_tweaks 4b67561c3 remove validate() overload that nobody is using fa15f1e5d Squashed commit of the following: 1484a9090 test the new validate() API 470da70fb hookup StringStreamT routines 2cddf2504 begin hooking up validate() overloads 1b5d910f3 overload validate() for UTF-8 and Windows-1252 03309b8c9 Squashed commit of the following: b72c6c5bf older compiler doesn't like our make_unique af8f00307 validate UTF-8 XML on Linux 211188613 unit-test for LEGACY XML validation 3c1169d2b Squashed commit of the following: 3afff19ca std::filesystem::path for FileInputStreamOS 908d452f8 WIP: validate all of our sample XML files 00f9bb16b validate against a XML schema 243d8c356 Merge branch 'master' into feature/xml.lite_tweaks 2815d707d fix to work with SWIG bindings. :-( 460862132 trying (again) to remove vestiages of old code e3c83a858 Revert "new code should use UTF-8" 811207c92 new code should use UTF-8 0ffd835f9 Squashed commit of the following: 1e7e03ded Merge branch 'master' into feature/xml.lite_tweaks c1d806aff Merge branch 'master' into feature/xml.lite_tweaks 850d3c811 str::strip() that can be easier to use than str::trim() 580ba9c8c explicitly =delete move 2b39831a8 Squashed commit of the following: 39eebdc23 Merge branch 'master' into feature/xml.lite_tweaks 9adf86cba force calling new UTF-8 write() routines ea61b6204 Merge branch 'master' into feature/xml.lite_tweaks 8a34583fa overload to take schemaPaths as filesystem::path 8671b442f parse XML embedded in a binary file ec4a902f1 updates from xerces.lite 80dc4d963 updates from xerces.lite 549766d6c Attributes::contains() no longer catches an exception 8a645ceac need "sys/" when building in other environments 36af08269 super-simple URI validation 78ef28a3e SWIG bindings are a PITA! :-( e9cba8491 SWIG needs help with Uri 8a8d8dc07 another routines used by pre-build SWIG bindings 818e1ec5d pre-build SWIG bindings use getElementByTagName() member function 067cac5d8 old compiler gets confused on unadorned QName ba92c0ae7 more use of Uri and QName 446c7d17a use QName in new code d6f8b0c83 more direct use of QName 90fff1c73 use xml::lite::QName instead of tuple 646cbb5ed more direct use of QName and Uri ba589ea3b make QName more robust bab0ee8b5 createElement() -> addNewElement() e3a145747 grab changes from six-library 32285e95c Merge branch 'master' into feature/xml.lite_tweaks 9f79f0bf6 Merge branch 'master' into feature/xml.lite_tweaks a12bbc32c make it easier to create new Elements with a value fc9967f98 make it easy for callers to addChild() keep a reference to the Element 4627766b7 be sure test_xmlparser works in "externals" of other projects bf2276396 "private" is part of the name-mangling fad92bcc8 making sure copy-ctor is implemented f90fdcead consolidate common XML test code 9fc53f2d5 use str:: utility for casting 6da6f794b still trying to find the right macro for SWIG 0c1b86c56 still trying to fix SWIG fdc6fc9bd trying to fix SWIG build error 7835e8c27 SWIG needs copy-ctor 585695942 disable copy/assignment for Element, it's probably almost always wrong 391fed613 fix double-delete caused by copying 61790fe69 retry parsing XML with Windows-1252 if first parse() fails 63cffac59 change string_encoding to match coda-oss style of PascalCase 010479bbe read an XML file we know is wrongly encoded as Windows-1252 9a0505062 more references instead of pointers 2d44b6951 Reading Windows-1252 w/o "encoding" fails 63dc7b076 read Windows-1252 too c9434c9cb test as UIT-8 too f310ccf0c get reading from UTF-8 XML working on Windows 1fa39c2be get testReadUtf8XmlFile working on Linux 1a83cd815 sys::Path is too much trouble right now ed60aa22c unit-test to read XML from a file a9336db7c Squashed commit of the following: 0825beb0d Merge branch 'master' into feature/xml.lite_tweaks c618489be Merge branch 'master' into feature/xml.lite_tweaks e8e4b8fe1 determine string_encoding based on platform 1f43bcfc2 create a new Element by using the platform to determine "characterData" encoding 961bef66b Merge branch 'master' into feature/xml.lite_tweaks e9798a5cb fix static_assert() 6f7772874 Merge branch 'master' into feature/xml.lite_tweaks b98d4f5a9 Merge branch 'master' into feature/xml.lite_tweaks 1b5abba2a The (old) version of SWIG we're using doesn't like certain C++11 features. 53bdeabaf Merge branch 'master' into feature/xml.lite_tweaks 60cf8ae80 "" doesn't work with decltype() in older C++ 97e72477a reduce getValue() overloads by making "key" a template argument 5e6373e55 reduce code duplication f9e7cfeee provide castValue instead of getValue(T&) cbd0bd8f2 castValue throws instead of returning a bool like getValue(T&) 87c7514fc Merge branch 'master' into feature/xml.lite_tweaks 10cc61223 make getElement*() consistent for zero or >1 results f5b137e3c Merge branch 'master' into feature/xml.lite_tweaks 1765efc62 allow clients to specify toType() and toString() for getValue() and setValue() df8b746e1 allow clients to specify their own toType/toString routines 66702726a Merge branch 'master' into feature/xml.lite_tweaks 6956311f1 Merge branch 'master' into feature/xml.lite_tweaks d505f3593 Merge branch 'master' into feature/xml.lite_tweaks fbd106115 catch a BadCastException and return false from getValue() 3a78377b5 use a template to reduce duplicated code 0ad4b8606 Merge branch 'master' into feature/xml.lite_tweaks a848aa3a2 get & set the characer data as a type f3ee1ee12 utility routines to set an attribute value 595227683 templates to get an attribute value convert to a specific type 06639227b miised a change in last commit 1aa458ef8 add getValue() overloads that return true/false rather than throwing faa6d3075 added getElementByTagName() overloads as that's a very common use-case git-subtree-dir: externals/coda-oss git-subtree-split: 168cbae01bb1e5fc0a02c2d96e8b02619bf2831d * Squashed 'externals/nitro/' changes from c8ecbe9ae..547d0aa9f 547d0aa9f NITRO-2.11.4 (#575) fe309c4ba Merge branch 'main' of github.com:mdaus/nitro 10efa9990 latest from CODA-OSS (#574) d08f1c0a1 CRLF db5d3d484 latest from CODA-OSS 98c755048 CRLF aa1482543 CRLF bfdbe69a4 Latest from CODA-OSS (#573) 9e4ce0b58 latest from CODA-OSS (#572) 227a8a8f4 trust coda-oss for right -std flags 13869687e latest from CODA-OSS (#571) 5724d8c18 latest from CODA-OSS (#570) fb794f0fe latest from CODA-OSS (#569) 7a6132ba0 update files changes in cpp17 branch (#568) de91d4977 Fix bug creating NITFException (#567) 225273436 fix YAML for 'main' 5d1c83d11 single project for unittests (#566) 102a019db latest from CODA-OSS (known broken build) (#565) b4ae2d429 match YAML from coda-oss 176bcaf6d build NITRO.SLN using msbuild (#562) 85e9043b8 latest from CODA-OSS (#561) 49ec50325 use new "PlatformToolkit" special environment variable (#560) 6c06e3711 latest from CODA-OSS (#559) cee9feb42 latest from CODA-OSS (#558) 3f01809fa latest from coda-oss (#557) 471fb3fc1 Update test_j2k_loading++.cpp b12caf2fc latest from CODA-OSS (#556) 0cd432624 use sys::make_span (#555) 05dae18a3 patch to build other projects 8f974e995 NITRO-2.11.3 (#554) 870aa6afd update to coda-oss 2023-06-05 (#553) 2fd7a0bfa latest from coda-oss (#552) 0eecce004 invoke() utility to reduce code duplication (#550) 59fb02fe9 latest from coda-oss (#551) 9fbf2b7b8 Fill out adapter free block which is used for nitf decompression (#549) 089ba0b5b latest from coda-oss 3b52f0025 latest from coda-oss (#547) 90c6263e2 latest from coda-oss (#544) 90d513ac5 latest from coda-oss (#543) git-subtree-dir: externals/nitro git-subtree-split: 547d0aa9ffcf34ad94f9ea71aa415f39837b2e68 * CRLF * CRLF --- UnitTest/CppUnitTestAssert.cpp | 86 +- UnitTest/Test.cpp | 192 +- UnitTest/Test.h | 20 +- UnitTest/UnitTest.vcxproj | 630 +-- UnitTest/UnitTest.vcxproj.filters | 386 +- externals/coda-oss/ReleaseNotes.md | 18 +- externals/coda-oss/UnitTest/mem.cpp | 1 + externals/coda-oss/modules/c++/CMakeLists.txt | 1 - .../coda-oss/modules/c++/coda-oss.vcxproj | 1 + .../modules/c++/coda-oss.vcxproj.filters | 3 + .../coda_oss/include/coda_oss/type_traits.h | 5 +- .../c++/config/include/config/Version.h | 8 +- .../c++/io/include/io/FileInputStreamIOS.h | 14 +- .../c++/io/include/io/FileOutputStreamOS.h | 14 +- .../c++/logging/include/logging/Setup.h | 13 +- .../modules/c++/mt/include/mt/ThreadGroup.h | 2 +- .../numpyutils/include/numpyutils/AutoPtr.h | 130 - .../modules/c++/std/include/std/type_traits | 21 +- externals/nitro/CHANGES | 38 +- externals/nitro/ReleaseNotes.md | 4 + .../modules/c++/nitf/include/nitf/Version.hpp | 5 +- .../nitro/modules/c/nrt/include/nrt/Version.h | 2 +- processFiles.py | 198 +- six.sln | 262 +- six/modules/c++/cphd/cphd.vcxproj | 364 +- six/modules/c++/cphd/cphd.vcxproj.filters | 388 +- six/modules/c++/cphd/include/cphd/Antenna.h | 748 +-- six/modules/c++/cphd/include/cphd/Dwell.h | 256 +- .../c++/cphd/include/cphd/ErrorParameters.h | 480 +- .../c++/cphd/include/cphd/MetadataBase.h | 222 +- six/modules/c++/cphd/include/cphd/PVP.h | 1224 ++--- .../c++/cphd/include/cphd/ProductInfo.h | 234 +- .../c++/cphd/include/cphd/ReferenceGeometry.h | 700 +-- six/modules/c++/cphd/include/cphd/TxRcv.h | 368 +- six/modules/c++/cphd/source/Antenna.cpp | 296 +- six/modules/c++/cphd/source/CPHDXMLParser.cpp | 4844 ++++++++--------- six/modules/c++/cphd/source/Channel.cpp | 454 +- six/modules/c++/cphd/source/Dwell.cpp | 146 +- .../c++/cphd/source/ErrorParameters.cpp | 382 +- six/modules/c++/cphd/source/PVP.cpp | 560 +- six/modules/c++/cphd/source/ProductInfo.cpp | 126 +- .../c++/cphd/source/ReferenceGeometry.cpp | 348 +- six/modules/c++/cphd/source/TxRcv.cpp | 198 +- .../c++/cphd/unittests/test_channel.cpp | 170 +- .../cphd/unittests/test_cphd_xml_optional.cpp | 2256 ++++---- six/modules/c++/cphd/unittests/test_dwell.cpp | 240 +- six/modules/c++/cphd/unittests/test_pvp.cpp | 218 +- .../cphd/unittests/test_pvp_block_round.cpp | 506 +- .../unittests/test_reference_geometry.cpp | 126 +- .../unittests/test_signal_block_round.cpp | 448 +- .../unittests/test_support_block_round.cpp | 336 +- six/modules/c++/cphd03/cphd03.vcxproj | 300 +- six/modules/c++/samples/check_valid_six.cpp | 556 +- .../check_valid_six.vcxproj | 252 +- .../samples/crop_sicd.dir/crop_sicd.vcxproj | 252 +- six/modules/c++/samples/utils.h | 122 +- .../c++/scene/include/scene/sys_Conf.h | 30 +- six/modules/c++/scene/scene.ruleset | 62 +- six/modules/c++/scene/scene.vcxproj | 308 +- six/modules/c++/scene/scene.vcxproj.filters | 244 +- .../source/ProjectionPolynomialFitter.cpp | 978 ++-- .../c++/six.convert/six.convert.vcxproj | 274 +- six/modules/c++/six.ruleset | 62 +- .../six.sicd/include/six/sicd/ImageCreation.h | 126 +- .../six/sicd/NITFReadComplexXMLControl.h | 212 +- .../c++/six.sicd/include/six/sicd/PFA.h | 254 +- .../c++/six.sicd/include/six/sicd/Position.h | 194 +- .../c++/six.sicd/include/six/sicd/Timeline.h | 222 +- six/modules/c++/six.sicd/six.sicd.vcxproj | 394 +- .../c++/six.sicd/six.sicd.vcxproj.filters | 496 +- six/modules/c++/six.sicd/source/Grid.cpp | 1820 +++---- six/modules/c++/six.sicd/source/ImageData.cpp | 556 +- .../source/NITFReadComplexXMLControl.cpp | 258 +- six/modules/c++/six.sicd/source/PFA.cpp | 174 +- six/modules/c++/six.sicd/source/Position.cpp | 92 +- .../c++/six.sicd/source/RadarCollection.cpp | 1200 ++-- 76 files changed, 13977 insertions(+), 14153 deletions(-) delete mode 100644 externals/coda-oss/modules/c++/numpyutils/include/numpyutils/AutoPtr.h diff --git a/UnitTest/CppUnitTestAssert.cpp b/UnitTest/CppUnitTestAssert.cpp index fdcf5f92b5..9b2594ac58 100644 --- a/UnitTest/CppUnitTestAssert.cpp +++ b/UnitTest/CppUnitTestAssert.cpp @@ -1,43 +1,43 @@ -#include "pch.h" -#include "TestCase.h" - -#include "str/EncodedStringView.h" - -using namespace Microsoft::VisualStudio::CppUnitTestFramework; - -// EQUALS_MESSAGE() wants ToString() specializations (or overloads) for our types, which is a nusiance. -// This hooks up our existing str::toString() into the VC++ unit-test infrastructure - -// C++ hack to call private methods -// https://stackoverflow.com/a/71578383/8877 - -using FailOnCondition_t = void(bool condition, const unsigned short* message, const __LineInfo* pLineInfo); // declare method's type -using GetAssertMessage_t = std::wstring(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message); // declare method's type -template -struct caller final // helper structure to inject call() code -{ - friend void FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo) - { - fFailOnCondition(condition, message, pLineInfo); - } - - friend std::wstring GetAssertMessage(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message) - { - return fGetAssertMessage(equality, expected, actual, message); - } -}; -template struct caller<&Assert::FailOnCondition, &Assert::GetAssertMessage>; // even instantiation of the helper - -void FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo); // declare caller -void test::Assert::FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo) -{ - ::FailOnCondition(condition, message, pLineInfo); // and call! -} - -std::wstring GetAssertMessage(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message); // declare caller -std::wstring test::Assert::GetAssertMessage(bool equality, const std::string& expected, const std::string& actual, const wchar_t *message) -{ - const str::EncodedStringView vExpected(expected); - const str::EncodedStringView vActual(actual); - return ::GetAssertMessage(equality, vExpected.wstring(), vActual.wstring(), message); // and call! -} +#include "pch.h" +#include "TestCase.h" + +#include "str/EncodedStringView.h" + +using namespace Microsoft::VisualStudio::CppUnitTestFramework; + +// EQUALS_MESSAGE() wants ToString() specializations (or overloads) for our types, which is a nusiance. +// This hooks up our existing str::toString() into the VC++ unit-test infrastructure + +// C++ hack to call private methods +// https://stackoverflow.com/a/71578383/8877 + +using FailOnCondition_t = void(bool condition, const unsigned short* message, const __LineInfo* pLineInfo); // declare method's type +using GetAssertMessage_t = std::wstring(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message); // declare method's type +template +struct caller final // helper structure to inject call() code +{ + friend void FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo) + { + fFailOnCondition(condition, message, pLineInfo); + } + + friend std::wstring GetAssertMessage(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message) + { + return fGetAssertMessage(equality, expected, actual, message); + } +}; +template struct caller<&Assert::FailOnCondition, &Assert::GetAssertMessage>; // even instantiation of the helper + +void FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo); // declare caller +void test::Assert::FailOnCondition(bool condition, const unsigned short* message, const __LineInfo* pLineInfo) +{ + ::FailOnCondition(condition, message, pLineInfo); // and call! +} + +std::wstring GetAssertMessage(bool equality, const std::wstring& expected, const std::wstring& actual, const wchar_t *message); // declare caller +std::wstring test::Assert::GetAssertMessage(bool equality, const std::string& expected, const std::string& actual, const wchar_t *message) +{ + const str::EncodedStringView vExpected(expected); + const str::EncodedStringView vActual(actual); + return ::GetAssertMessage(equality, vExpected.wstring(), vActual.wstring(), message); // and call! +} diff --git a/UnitTest/Test.cpp b/UnitTest/Test.cpp index 1b5022b55b..288bc85ad2 100644 --- a/UnitTest/Test.cpp +++ b/UnitTest/Test.cpp @@ -1,96 +1,96 @@ -#include "pch.h" -#include "Test.h" - -#include - -#include - -namespace fs = std::filesystem; - -static bool is_x64_Configuration(const fs::path& path) // "Configuration" is typically "Debug" or "Release" -{ - const std::string build_configuration = -#if defined(NDEBUG) // i.e., release - "Release"; -#else - "Debug"; -#endif - - const auto Configuration = path.filename(); - const auto path_parent_path = path.parent_path(); - const auto x64 = path_parent_path.filename(); - return (Configuration == build_configuration) && (x64 == "x64"); -} - -static bool is_install_unittests(const fs::path& path) -{ - const auto unittests = path.filename(); - const auto path_parent_path = path.parent_path(); - const auto install = path_parent_path.filename(); - return (unittests == "unittests") && (install == "install"); -} -static bool is_install_tests(const fs::path& path) -{ - const auto tests = path.filename(); - const auto path_parent_path = path.parent_path(); - const auto install = path_parent_path.filename(); - return (tests == "tests") && (install == "install"); -} - -fs::path six::Test::buildSchemaDir() -{ - const auto cwd = fs::current_path(); - - const sys::OS os; - const auto exec = fs::path(os.getCurrentExecutable()); - const auto argv0 = exec.filename(); - if ((argv0 == "Test.exe") || (argv0 == "testhost.exe")) - { - // Running GTest unit-tests in Visual Studio on Windows - if (is_x64_Configuration(cwd)) - { - const auto root_path = cwd.parent_path().parent_path(); - return root_path / "six" / "modules" / "c++" / "six.sidd" / "conf" / "schema"; - } - } - - if (argv0 == "unittests.exe") - { - // stand-alone unittest executable on Windows (ends in .EXE) - const auto parent_path = exec.parent_path(); - if (is_x64_Configuration(parent_path)) - { - const auto parent_path_ = parent_path.parent_path().parent_path(); - return parent_path_ / "dev" / "tests" / "images"; - } - } - - // stand-alone unit-test on Linux - const auto exec_dir = exec.parent_path(); - if (is_install_unittests(exec_dir)) - { - const auto install = exec_dir.parent_path(); - return install / "unittests" / "data"; - } - if (is_install_tests(exec_dir)) - { - const auto install = exec_dir.parent_path(); - return install / "unittests" / "data"; - } - - if (argv0 == "unittests") - { - // stand-alone unittest executable on Linux - const auto bin = exec.parent_path(); - if (bin.filename() == "bin") - { - const auto unittests = bin.parent_path(); - return unittests / "unittests" / "data"; - } - } - - //fprintf(stderr, "cwd = %s\n", cwd.c_str()); - //fprintf(stderr, "exec = %s\n", exec.c_str()); - - return cwd; -} +#include "pch.h" +#include "Test.h" + +#include + +#include + +namespace fs = std::filesystem; + +static bool is_x64_Configuration(const fs::path& path) // "Configuration" is typically "Debug" or "Release" +{ + const std::string build_configuration = +#if defined(NDEBUG) // i.e., release + "Release"; +#else + "Debug"; +#endif + + const auto Configuration = path.filename(); + const auto path_parent_path = path.parent_path(); + const auto x64 = path_parent_path.filename(); + return (Configuration == build_configuration) && (x64 == "x64"); +} + +static bool is_install_unittests(const fs::path& path) +{ + const auto unittests = path.filename(); + const auto path_parent_path = path.parent_path(); + const auto install = path_parent_path.filename(); + return (unittests == "unittests") && (install == "install"); +} +static bool is_install_tests(const fs::path& path) +{ + const auto tests = path.filename(); + const auto path_parent_path = path.parent_path(); + const auto install = path_parent_path.filename(); + return (tests == "tests") && (install == "install"); +} + +fs::path six::Test::buildSchemaDir() +{ + const auto cwd = fs::current_path(); + + const sys::OS os; + const auto exec = fs::path(os.getCurrentExecutable()); + const auto argv0 = exec.filename(); + if ((argv0 == "Test.exe") || (argv0 == "testhost.exe")) + { + // Running GTest unit-tests in Visual Studio on Windows + if (is_x64_Configuration(cwd)) + { + const auto root_path = cwd.parent_path().parent_path(); + return root_path / "six" / "modules" / "c++" / "six.sidd" / "conf" / "schema"; + } + } + + if (argv0 == "unittests.exe") + { + // stand-alone unittest executable on Windows (ends in .EXE) + const auto parent_path = exec.parent_path(); + if (is_x64_Configuration(parent_path)) + { + const auto parent_path_ = parent_path.parent_path().parent_path(); + return parent_path_ / "dev" / "tests" / "images"; + } + } + + // stand-alone unit-test on Linux + const auto exec_dir = exec.parent_path(); + if (is_install_unittests(exec_dir)) + { + const auto install = exec_dir.parent_path(); + return install / "unittests" / "data"; + } + if (is_install_tests(exec_dir)) + { + const auto install = exec_dir.parent_path(); + return install / "unittests" / "data"; + } + + if (argv0 == "unittests") + { + // stand-alone unittest executable on Linux + const auto bin = exec.parent_path(); + if (bin.filename() == "bin") + { + const auto unittests = bin.parent_path(); + return unittests / "unittests" / "data"; + } + } + + //fprintf(stderr, "cwd = %s\n", cwd.c_str()); + //fprintf(stderr, "exec = %s\n", exec.c_str()); + + return cwd; +} diff --git a/UnitTest/Test.h b/UnitTest/Test.h index 232a94cf1b..057b8d5209 100644 --- a/UnitTest/Test.h +++ b/UnitTest/Test.h @@ -1,11 +1,11 @@ -#pragma once - -#include - -namespace six -{ - namespace Test - { - extern std::filesystem::path buildSchemaDir(); - } +#pragma once + +#include + +namespace six +{ + namespace Test + { + extern std::filesystem::path buildSchemaDir(); + } } \ No newline at end of file diff --git a/UnitTest/UnitTest.vcxproj b/UnitTest/UnitTest.vcxproj index a982b81e2c..d98ea5b10e 100644 --- a/UnitTest/UnitTest.vcxproj +++ b/UnitTest/UnitTest.vcxproj @@ -1,316 +1,316 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 17.0 - {F6888896-E658-414C-90CD-1208FA31A22E} - Win32Proj - UnitTest - 10.0 - NativeUnitTestProject - - - - DynamicLibrary - true - v143 - Unicode - false - - - DynamicLibrary - false - v143 - true - Unicode - false - - - - - - - - - - - - - - - true - - - false - - - - Use - Level3 - true - $(SolutionDir);$(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration);$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration);$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - _DEBUG;SIX_DEFAULT_SCHEMA_PATH=R"($(SolutionDir)install-$(Configuration)-$(Platform).$(PlatformToolset)\conf\schema\six)";%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - pch.h - true - AdvancedVectorExtensions2 - true - MultiThreadedDebugDLL - true - true - true - - - Windows - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - Use - Level3 - true - true - true - $(SolutionDir);$(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration);$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration);$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) - NDEBUG;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - pch.h - true - AdvancedVectorExtensions2 - true - true - true - - - Windows - true - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) - - - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - true - true - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - {016ef417-e41c-404c-b3b5-34b6cdd94bb3} - - - {01be4480-9620-4ded-b34f-d2e3ab4b7c8b} - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {ddc587c2-53ba-44a9-94e7-07be52af3d0b} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 17.0 + {F6888896-E658-414C-90CD-1208FA31A22E} + Win32Proj + UnitTest + 10.0 + NativeUnitTestProject + + + + DynamicLibrary + true + v143 + Unicode + false + + + DynamicLibrary + false + v143 + true + Unicode + false + + + + + + + + + + + + + + + true + + + false + + + + Use + Level3 + true + $(SolutionDir);$(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration);$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration);$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + _DEBUG;SIX_DEFAULT_SCHEMA_PATH=R"($(SolutionDir)install-$(Configuration)-$(Platform).$(PlatformToolset)\conf\schema\six)";%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + pch.h + true + AdvancedVectorExtensions2 + true + MultiThreadedDebugDLL + true + true + true + + + Windows + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + Use + Level3 + true + true + true + $(SolutionDir);$(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration);$(SolutionDir)out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration);$(VCInstallDir)UnitTest\include;%(AdditionalIncludeDirectories) + NDEBUG;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + pch.h + true + AdvancedVectorExtensions2 + true + true + true + + + Windows + true + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;$(VCInstallDir)UnitTest\lib;%(AdditionalLibraryDirectories) + + + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + true + true + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + {016ef417-e41c-404c-b3b5-34b6cdd94bb3} + + + {01be4480-9620-4ded-b34f-d2e3ab4b7c8b} + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {ddc587c2-53ba-44a9-94e7-07be52af3d0b} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + + + + + \ No newline at end of file diff --git a/UnitTest/UnitTest.vcxproj.filters b/UnitTest/UnitTest.vcxproj.filters index 924b309cfc..440a0297ed 100644 --- a/UnitTest/UnitTest.vcxproj.filters +++ b/UnitTest/UnitTest.vcxproj.filters @@ -1,194 +1,194 @@ - - - - - - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd - - - cphd03 - - - cphd03 - - - cphd03 - - - cphd03 - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sicd - - - sidd - - - sidd - - - sidd - - - sidd - - - sidd - - - sidd - - - six - - - six - - - six - - - six - - - six - - - - - - - - cphd - - - cphd03 - - - sicd - - - sidd - - - six - - - - - {004a37ca-2175-4642-988e-94516ea1a147} - - - {ef494548-4aed-4ebb-a93c-b56a11f17f5e} - - - {593807ae-bc84-424f-ba11-0537277cd2fc} - - - {f8053c57-ba04-41c4-8dd8-2056f5a19f25} - - - {8d8a73fb-96b1-4bdf-a055-2b34d7f94e14} - - - - - sidd - - - sidd - - + + + + + + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd + + + cphd03 + + + cphd03 + + + cphd03 + + + cphd03 + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sicd + + + sidd + + + sidd + + + sidd + + + sidd + + + sidd + + + sidd + + + six + + + six + + + six + + + six + + + six + + + + + + + + cphd + + + cphd03 + + + sicd + + + sidd + + + six + + + + + {004a37ca-2175-4642-988e-94516ea1a147} + + + {ef494548-4aed-4ebb-a93c-b56a11f17f5e} + + + {593807ae-bc84-424f-ba11-0537277cd2fc} + + + {f8053c57-ba04-41c4-8dd8-2056f5a19f25} + + + {8d8a73fb-96b1-4bdf-a055-2b34d7f94e14} + + + + + sidd + + + sidd + + \ No newline at end of file diff --git a/externals/coda-oss/ReleaseNotes.md b/externals/coda-oss/ReleaseNotes.md index a265066c08..845b919fc9 100644 --- a/externals/coda-oss/ReleaseNotes.md +++ b/externals/coda-oss/ReleaseNotes.md @@ -1,17 +1,6 @@ -``` - _________________________ - | ____ _||_ ___ __ | - | /___ \/_||_\| __\/ \ | - | // \// || \|| \\ _ \ | - | || [===||===] ||(_)| | - | || _|| || ||| ||__ | | - | \\ _/ |\_||_/||__/|| || | - | \___/ \_||_/|___/|| || | - |__________||_____________| - ``` -# coda-oss Release Notes +# coda-oss Release Notes -## [Release 202?-??-??](https://github.com/mdaus/coda-oss/releases/tag/202?-??-??) +## [Release 2023-08-18](https://github.com/mdaus/coda-oss/releases/tag/2023-08-18) * New `sys::OS::getSIMDInstructionSet()` utility routine; SSE2 is required (default with 64-bit builds). * `types::ComplexInteger` to work-around `std::complex` no longer being [valid C++](https://en.cppreference.com/w/cpp/numeric/complex). * Another round of reducing various compiler warnings (of note: `NULL` -> `nullptr`). @@ -20,6 +9,9 @@ * Update to [e2fsprogs 1.47.0](https://e2fsprogs.sourceforge.net/e2fsprogs-release.html#1.47.0). * Update to [xerces-c 3.2.4](https://issues.apache.org/jira/secure/ReleaseNote.jspa?version=12350542&styleName=Text&projectId=10510). * Update to [HDF5](https://www.hdfgroup.org/) [1.14.2](https://github.com/HDFGroup/hdf5/releases/tag/hdf5-1_14_2). +* `mem::ComplexView`s renamed to be more descriptive. +* **hdf5.lite** removed, use [HighFive](https://github.com/BlueBrain/HighFive/) (included). +* added **.gitattributes** and normalized line-endings (`\n` for most text files). ## [Release 2023-06-05](https://github.com/mdaus/coda-oss/releases/tag/2023-06-05) * *zlib* updated to [1.2.13](https://github.com/madler/zlib/releases/tag/v1.2.13). diff --git a/externals/coda-oss/UnitTest/mem.cpp b/externals/coda-oss/UnitTest/mem.cpp index ff1819486e..dba2dd8e24 100644 --- a/externals/coda-oss/UnitTest/mem.cpp +++ b/externals/coda-oss/UnitTest/mem.cpp @@ -5,6 +5,7 @@ #include #include #include +#include namespace mem { diff --git a/externals/coda-oss/modules/c++/CMakeLists.txt b/externals/coda-oss/modules/c++/CMakeLists.txt index d8f84e9f98..d30fb57661 100644 --- a/externals/coda-oss/modules/c++/CMakeLists.txt +++ b/externals/coda-oss/modules/c++/CMakeLists.txt @@ -1,6 +1,5 @@ set(TARGET_LANGUAGE c++) -# turn on maximum warnings if (MSVC) # By default, there is a /W3 on the command-line from somewhere (?); adding # /Wn results in a compiler warning. diff --git a/externals/coda-oss/modules/c++/coda-oss.vcxproj b/externals/coda-oss/modules/c++/coda-oss.vcxproj index cd29672ba9..224d107e98 100644 --- a/externals/coda-oss/modules/c++/coda-oss.vcxproj +++ b/externals/coda-oss/modules/c++/coda-oss.vcxproj @@ -127,6 +127,7 @@ + diff --git a/externals/coda-oss/modules/c++/coda-oss.vcxproj.filters b/externals/coda-oss/modules/c++/coda-oss.vcxproj.filters index 4d2be7e2a9..22f84d0e92 100644 --- a/externals/coda-oss/modules/c++/coda-oss.vcxproj.filters +++ b/externals/coda-oss/modules/c++/coda-oss.vcxproj.filters @@ -951,6 +951,9 @@ hdf5.lite + + mem + diff --git a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/type_traits.h b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/type_traits.h index 5c92c1d321..17f538ca4c 100644 --- a/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/type_traits.h +++ b/externals/coda-oss/modules/c++/coda_oss/include/coda_oss/type_traits.h @@ -18,15 +18,12 @@ * License along with this program; If not, http://www.gnu.org/licenses/. * */ +#pragma once #ifndef CODA_OSS_coda_oss_type_traits_h_INCLUDED_ #define CODA_OSS_coda_oss_type_traits_h_INCLUDED_ -#pragma once #include -#include "CPlusPlus.h" - -#include "coda_oss/namespace_.h" namespace coda_oss { using std::is_trivially_copyable; diff --git a/externals/coda-oss/modules/c++/config/include/config/Version.h b/externals/coda-oss/modules/c++/config/include/config/Version.h index 69944fc0b8..8e3b223c3d 100644 --- a/externals/coda-oss/modules/c++/config/include/config/Version.h +++ b/externals/coda-oss/modules/c++/config/include/config/Version.h @@ -42,13 +42,13 @@ static_assert(CODA_OSS_MAKE_VERSION_MMPB(9999, 9999, 9999, 9999) <= UINT64_MAX, // Do this ala C++ ... we don't currently have major/minor/patch //#define CODA_OSS_VERSION_ 20210910L // c.f. __cplusplus -#define CODA_OSS_VERSION_ 2023 ## 0006 ## 0005 ## 0000 ## L +#define CODA_OSS_VERSION_ 2023 ## 0008 ## 0018 ## 0000 ## L // Use the same macros other projects might want to use; overkill for us. #define CODA_OSS_VERSION_MAJOR 2023 -#define CODA_OSS_VERSION_MINOR 6 -#define CODA_OSS_VERSION_PATCH 5 -#define CODA_OSS_VERSION_BUILD 0 +#define CODA_OSS_VERSION_MINOR 8 +#define CODA_OSS_VERSION_PATCH 18 // a.k.a. "point," but too similar to "patch." +#define CODA_OSS_VERSION_BUILD 0 // a.k.a. "patch," but too similar to "point." #define CODA_OSS_VERSION CODA_OSS_MAKE_VERSION_MMPB(CODA_OSS_VERSION_MAJOR, CODA_OSS_VERSION_MINOR, CODA_OSS_VERSION_PATCH, CODA_OSS_VERSION_BUILD) namespace config diff --git a/externals/coda-oss/modules/c++/io/include/io/FileInputStreamIOS.h b/externals/coda-oss/modules/c++/io/include/io/FileInputStreamIOS.h index c23223edb0..897ce8c3f7 100644 --- a/externals/coda-oss/modules/c++/io/include/io/FileInputStreamIOS.h +++ b/externals/coda-oss/modules/c++/io/include/io/FileInputStreamIOS.h @@ -28,17 +28,14 @@ #include #include #include + #include "except/Exception.h" -#include "sys/filesystem.h" #include "io/InputStream.h" #include "io/SeekableStreams.h" +#include "sys/filesystem.h" -#include "sys/CPlusPlus.h" -#if CODA_OSS_cpp17 -#include -#endif -/*! + /*! * \file FileInputStreamIOS.h * \brief The InputStream representation of a file * \todo Redefine the readln function to use getline() @@ -72,11 +69,6 @@ class FileInputStreamIOS : public SeekableInputStream */ FileInputStreamIOS(const coda_oss::filesystem::path& inputFile, std::ios::openmode mode = std::ios::in); - #if CODA_OSS_cpp17 - FileInputStreamIOS(const std::filesystem::path& inputFile, - std::ios::openmode mode = std::ios::in); - #endif - /*! * Alternate Constructor. Takes an input file and a mode diff --git a/externals/coda-oss/modules/c++/io/include/io/FileOutputStreamOS.h b/externals/coda-oss/modules/c++/io/include/io/FileOutputStreamOS.h index b8e70b893d..704b1946ec 100644 --- a/externals/coda-oss/modules/c++/io/include/io/FileOutputStreamOS.h +++ b/externals/coda-oss/modules/c++/io/include/io/FileOutputStreamOS.h @@ -31,13 +31,8 @@ #if !defined(USE_IO_STREAMS) #include "io/SeekableStreams.h" -#include "sys/filesystem.h" #include "sys/File.h" - -#include "sys/CPlusPlus.h" -#if CODA_OSS_cpp17 -#include -#endif +#include "sys/filesystem.h" /*! * \file FileOutputStream.h @@ -64,16 +59,13 @@ class CODA_OSS_API FileOutputStreamOS : public SeekableOutputStream public: FileOutputStreamOS() = default; + using path = coda_oss::filesystem::path; // still used in SWIG bindings + /*! * Alternate Constructor. Takes an output file and a mode * \param outputFile The file name * \param creationFlags see sys::File */ - #if CODA_OSS_cpp17 - using path = std::filesystem::path; - #else - using path = coda_oss::filesystem::path; - #endif FileOutputStreamOS(const path& outputFile, int creationFlags = sys::File::CREATE | sys::File::TRUNCATE); diff --git a/externals/coda-oss/modules/c++/logging/include/logging/Setup.h b/externals/coda-oss/modules/c++/logging/include/logging/Setup.h index 1f1e960c6f..ed6334d6e4 100644 --- a/externals/coda-oss/modules/c++/logging/include/logging/Setup.h +++ b/externals/coda-oss/modules/c++/logging/include/logging/Setup.h @@ -26,17 +26,13 @@ #include #include -#include "sys/filesystem.h" #include "mem/SharedPtr.h" #include "logging/Logger.h" - -#include "sys/CPlusPlus.h" -#if CODA_OSS_cpp17 -#include -#endif +#include "sys/filesystem.h" namespace logging { +using path = coda_oss::filesystem::path; // still used in SWIG bindings /*! * \fn setupLogger @@ -52,11 +48,6 @@ namespace logging * \param logCount - number of rotating logs to keep (default: 0 no rotation) * \param logBytes - number of bytes per rotating log (default: 0 no rotation) */ -#if CODA_OSS_cpp17 -using path = std::filesystem::path; -#else -using path = coda_oss::filesystem::path; -#endif std::unique_ptr setupLogger( const path& program, const std::string& logLevel = "warning", diff --git a/externals/coda-oss/modules/c++/mt/include/mt/ThreadGroup.h b/externals/coda-oss/modules/c++/mt/include/mt/ThreadGroup.h index e12cbf8a9b..f54e29a129 100644 --- a/externals/coda-oss/modules/c++/mt/include/mt/ThreadGroup.h +++ b/externals/coda-oss/modules/c++/mt/include/mt/ThreadGroup.h @@ -81,7 +81,7 @@ struct CODA_OSS_API ThreadGroup /*! * Creates and starts a thread from a sys::Runnable. - * \param runnable auto_ptr to sys::Runnable + * \param runnable unique_ptr to sys::Runnable */ void createThread(std::unique_ptr&& runnable); diff --git a/externals/coda-oss/modules/c++/numpyutils/include/numpyutils/AutoPtr.h b/externals/coda-oss/modules/c++/numpyutils/include/numpyutils/AutoPtr.h deleted file mode 100644 index fb7c6c0e92..0000000000 --- a/externals/coda-oss/modules/c++/numpyutils/include/numpyutils/AutoPtr.h +++ /dev/null @@ -1,130 +0,0 @@ -/* ========================================================================= - * This file is part of numpyutils-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2018, MDA Information Systems LLC - * (C) Copyright 2022, Maxar Technologies, Inc. - * - * numpyutils-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#pragma once -#ifndef CODA_OSS_numpyutils_AutoPtr_h_INCLUDED_ -#define CODA_OSS_numpyutils_AutoPtr_h_INCLUDED_ - -#include - -namespace numpyutils -{ -// std::auto_ptr (deprecated in C++17) is copyable while -// std::unique_ptr (new in C++11) isn't. While unique_ptr -// is right, making the change doesn't always work well with -// legacy code. Using shared_ptr instead of unique_ptr is -// copyable, but that changes semantics: the "old" copied-from -// object is still valid. -// -// Thus, this class to help make the transition easier. -// Using (very) sparingly! - -template -class AutoPtr final -{ - std::unique_ptr ptr_; - -public: - // https://en.cppreference.com/w/cpp/memory/auto_ptr/auto_ptr - explicit AutoPtr(T* p = nullptr) noexcept : ptr_(p) - { - } - - AutoPtr& operator=(AutoPtr& r) noexcept - { - reset(r.release()); - return *this; - } - AutoPtr(AutoPtr& r) noexcept - { - *this = r; - } - AutoPtr& operator=(const AutoPtr&) = delete; // can't change a "const" object - AutoPtr(const AutoPtr&) = delete; - - ~AutoPtr() = default; - AutoPtr(AutoPtr&&) = default; - AutoPtr& operator=(AutoPtr&&) = default; - - template - AutoPtr& operator=(std::unique_ptr&& p) noexcept - { - ptr_ = std::move(p); - return *this; - } - template - AutoPtr(std::unique_ptr&& p) noexcept - { - *this = std::move(p); - } - - template // std::auto_ptr can cause deprecated warnings - AutoPtr& assign(TAutoPtr p) noexcept - { - ptr_.reset(p.release()); - return *this; - } - template // std::auto_ptr can cause deprecated warnings - AutoPtr& operator=(TAutoPtr p) noexcept - { - return assign(p); - } - template // std::auto_ptr can cause deprecated warnings - AutoPtr(TAutoPtr p) noexcept - { - *this = assign(p); - } - - - T* get() const noexcept - { - return ptr_.get(); - } - - T* release() noexcept - { - return ptr_.release(); - } - - template - void reset(U* p = nullptr) noexcept - { - ptr_.reset(p); - } - - T& operator*() const noexcept - { - return *get(); - } - T* operator->() const noexcept - { - return get(); - } - - operator std::unique_ptr& () { return ptr_; } - operator const std::unique_ptr& () const { return ptr_; } -}; - -} // namespace numpyutils - -#endif // CODA_OSS_numpyutils_AutoPtr_h_INCLUDED_ diff --git a/externals/coda-oss/modules/c++/std/include/std/type_traits b/externals/coda-oss/modules/c++/std/include/std/type_traits index 1aba653f96..cbcd0bfd8a 100644 --- a/externals/coda-oss/modules/c++/std/include/std/type_traits +++ b/externals/coda-oss/modules/c++/std/include/std/type_traits @@ -18,30 +18,11 @@ * License along with this program; If not, http://www.gnu.org/licenses/. * */ +#pragma once #ifndef CODA_OSS_std_type_traits_INCLUDED_ #define CODA_OSS_std_type_traits_INCLUDED_ -#pragma once #include -#include "coda_oss/type_traits.h" - -// Make it (too?) easy for clients to get our various std:: implementations -#ifndef CODA_OSS_NO_is_trivially_copyable - // https://stackoverflow.com/a/31798726/8877 - // workaround missing "is_trivially_copyable" in g++ < 5.0 - #if defined(__GNUC__) && (__GNUC__ < 5) - #define CODA_OSS_NO_is_trivially_copyable 0 // *need* our own - #else - #define CODA_OSS_NO_is_trivially_copyable 1 // *disabled*, unless explicitly enabled - #endif -#endif - -#if !CODA_OSS_NO_is_trivially_copyable -namespace std // This is slightly uncouth: we're not supposed to augment "std". -{ - using coda_oss::is_trivially_copyable; -} -#endif // CODA_OSS_NO_is_trivially_copyable #endif // CODA_OSS_std_type_traits_INCLUDED_ diff --git a/externals/nitro/CHANGES b/externals/nitro/CHANGES index 0be232971d..dd120e4686 100644 --- a/externals/nitro/CHANGES +++ b/externals/nitro/CHANGES @@ -1,19 +1,19 @@ -2.7 Changes -=========== -- 12 new TREs: CSCCGA, CSCRNA, CSEPHA, CSEXRA, CSPROA, CSSFAA, CSSHPA, GRDPSB, J2KLRA, PIXQLA, SENSRB, XML_DATA_CONTENT -- Variety of minor memory leaks, access errors, and other bug fixes -- Fixed IOInterface and BandSource C++ API so overriding methods works as expected -- Several complexity level bugs -- Fixed bug in Windows involving reading and writing files larger than 4 GB -- Build system upgrades: Among other thing, building Java bindings is now easier as it's done directly through waf automatically - -Please see our wiki for detailed change information on previous versions: - -2.5 Changes: http://nitro-nitf.sourceforge.net/wikka.php?wakka=ReleaseNotes25 - -2.0 Changes: http://nitro-nitf.sourceforge.net/wikka.php?wakka=ReleaseNotes20 - -1.5 Changes: http://nitro-nitf.sourceforge.net/wikka.php?wakka=ReleaseNotes15 - - -Wiki Home: http://nitro-nitf.sourceforge.net/ +2.7 Changes +=========== +- 12 new TREs: CSCCGA, CSCRNA, CSEPHA, CSEXRA, CSPROA, CSSFAA, CSSHPA, GRDPSB, J2KLRA, PIXQLA, SENSRB, XML_DATA_CONTENT +- Variety of minor memory leaks, access errors, and other bug fixes +- Fixed IOInterface and BandSource C++ API so overriding methods works as expected +- Several complexity level bugs +- Fixed bug in Windows involving reading and writing files larger than 4 GB +- Build system upgrades: Among other thing, building Java bindings is now easier as it's done directly through waf automatically + +Please see our wiki for detailed change information on previous versions: + +2.5 Changes: http://nitro-nitf.sourceforge.net/wikka.php?wakka=ReleaseNotes25 + +2.0 Changes: http://nitro-nitf.sourceforge.net/wikka.php?wakka=ReleaseNotes20 + +1.5 Changes: http://nitro-nitf.sourceforge.net/wikka.php?wakka=ReleaseNotes15 + + +Wiki Home: http://nitro-nitf.sourceforge.net/ diff --git a/externals/nitro/ReleaseNotes.md b/externals/nitro/ReleaseNotes.md index c158869648..061c950bc1 100644 --- a/externals/nitro/ReleaseNotes.md +++ b/externals/nitro/ReleaseNotes.md @@ -1,5 +1,9 @@ # NITRO (NITF i/o) Release Notes +## [Version 2.11.4](https://github.com/mdaus/nitro/releases/tag/NITRO-2.11.4); August 18 5, 2023 +* [coda-oss](https://github.com/mdaus/coda-oss) release [2023-08-18](https://github.com/mdaus/coda-oss/releases/tag/2023-08-18) +* added **.gitattributes** and normalized line-endings (`\n` for most text files). + ## [Version 2.11.3](https://github.com/mdaus/nitro/releases/tag/NITRO-2.11.3); June 5, 2023 * [coda-oss](https://github.com/mdaus/coda-oss) release [2023-06-05](https://github.com/mdaus/coda-oss/releases/tag/2023-06-05) * Fix display of [certain TREs](https://github.com/mdaus/nitro/issues/529). diff --git a/externals/nitro/modules/c++/nitf/include/nitf/Version.hpp b/externals/nitro/modules/c++/nitf/include/nitf/Version.hpp index 094ad93d75..74935b96b5 100644 --- a/externals/nitro/modules/c++/nitf/include/nitf/Version.hpp +++ b/externals/nitro/modules/c++/nitf/include/nitf/Version.hpp @@ -37,10 +37,11 @@ // 2.11.1 November 4, 2022 // 2.11.2 December 14, 2022 // 2.11.3 June 5, 2023 + // 2.11.4 August 18, 2023 #define NITF_VERSION_MAJOR 2 #define NITF_VERSION_MINOR 11 -#define NITF_VERSION_PATCH 3 -#define NITF_VERSION_BUILD 0 +#define NITF_VERSION_PATCH 4 // a.k.a. "point," but too similar to "patch." +#define NITF_VERSION_BUILD 0 // a.k.a. "patch," but too similar to "point." #define NITF_VERSION CODA_OSS_MAKE_VERSION_MMPB(NITF_VERSION_MAJOR, NITF_VERSION_MINOR, NITF_VERSION_PATCH, NITF_VERSION_BUILD) namespace nitf diff --git a/externals/nitro/modules/c/nrt/include/nrt/Version.h b/externals/nitro/modules/c/nrt/include/nrt/Version.h index ffce796775..1c142e91f3 100644 --- a/externals/nitro/modules/c/nrt/include/nrt/Version.h +++ b/externals/nitro/modules/c/nrt/include/nrt/Version.h @@ -1,5 +1,5 @@ #pragma once #if !defined(NRT_LIB_VERSION) -#define NRT_LIB_VERSION "2.11.3" +#define NRT_LIB_VERSION "2.11.4" #endif diff --git a/processFiles.py b/processFiles.py index 1e3904ec43..67d13fc9ab 100644 --- a/processFiles.py +++ b/processFiles.py @@ -1,99 +1,99 @@ -import sys, os, re, subprocess -from os.path import isdir, join, split, exists - - -def cosmoSkyMed(filename): - path, fname = split(filename) - if re.match(r'CSK.*.MBI.tif', fname): - xmlName = join(path, fname.rsplit('MBI.tif')[0] + 'attribs.xml') - if exists(xmlName): - return (xmlName, filename) - return None - -def radarsat2(filename): - path, fname = split(filename) -# if re.match(r'RS2_.*', split(path)[1]) and re.match(r'imagery_.*.tif', fname): - if re.match(r'imagery_.*.tif', fname): - xmlName = join(path, 'product.xml') - if exists(xmlName): - return (xmlName, filename) - return None - -def terraSAR(filename): - path, fname = split(filename) - if re.match(r'IMAGEDATA', split(path)[1]) and re.match(r'IMAGE_.*.tif', fname): - parDir, xmlName = split(split(path)[0]) - xmlName = join(parDir, xmlName, '%s.xml' % xmlName) - if exists(xmlName): - return (xmlName, filename) - return None - - -if __name__ == '__main__': - from optparse import OptionParser - parser = OptionParser(usage="usage: %prog [options] [path(s)]") - parser.add_option("-d", "--dir", dest='outDir', metavar='DIR', - help="specify the output directory (default=cwd)") - parser.add_option("-x", "--xml", dest='xml', action='store_true', - help="Write An XML output") - parser.add_option("-n", "--nitf", dest='nitf', action='store_true', - help="Write A NITF output") - parser.add_option("-t", "--tiff", dest='tiff', action='store_true', - help="Write A TIFF output") - parser.add_option("-k", "--kml", dest='kml', action='store_true', - help="Write A KML output") - parser.add_option("-l", "--level", dest='level', metavar='LEVEL', default=None, - help="Level at which to log ") - parser.add_option("--limit", dest='limit', metavar='NUM', default=0, type='int', - help="Specify a limit on the number of images to process") - (options, args) = parser.parse_args() - - #default to cwd if none provided - outDir = options.outDir or os.getcwd() - if not exists(outDir): - os.makedirs(outDir) - - inputs = [] - paths = args[:] - while paths: - path = paths.pop(0) - if isdir(path): - paths.extend(map(lambda x: join(path, x), os.listdir(path))) - else: - f = cosmoSkyMed(path) - if not f: - f = radarsat2(path) - if not f: - f = terraSAR(path) - if f: - inputs.append(f) - - appName = os.path.abspath(join(split(__file__)[0], './install/bin/ScanSARConverter')) - if 'win32' in sys.platform: - appName += '.exe' - - cmd = [appName] - cmd.extend(['-d', outDir]) - if options.xml: - cmd.append('-x') - if options.nitf: - cmd.append('-n') - if options.tiff: - cmd.append('-t') - if options.kml: - cmd.append('-k') - if options.level: - cmd.extend(['-l', options.level]) - - def process(xml, image): - command = cmd[:] - command.append('%s,%s' % (xml, image)) - print command - p = subprocess.Popen(command).communicate() - - limit = (options.limit > 0 and min(options.limit, len(inputs)) or len(inputs)) - print 'Processing %d files' % limit - for i, (xml, image) in enumerate(inputs): - if i >= limit: - break - process(xml, image) +import sys, os, re, subprocess +from os.path import isdir, join, split, exists + + +def cosmoSkyMed(filename): + path, fname = split(filename) + if re.match(r'CSK.*.MBI.tif', fname): + xmlName = join(path, fname.rsplit('MBI.tif')[0] + 'attribs.xml') + if exists(xmlName): + return (xmlName, filename) + return None + +def radarsat2(filename): + path, fname = split(filename) +# if re.match(r'RS2_.*', split(path)[1]) and re.match(r'imagery_.*.tif', fname): + if re.match(r'imagery_.*.tif', fname): + xmlName = join(path, 'product.xml') + if exists(xmlName): + return (xmlName, filename) + return None + +def terraSAR(filename): + path, fname = split(filename) + if re.match(r'IMAGEDATA', split(path)[1]) and re.match(r'IMAGE_.*.tif', fname): + parDir, xmlName = split(split(path)[0]) + xmlName = join(parDir, xmlName, '%s.xml' % xmlName) + if exists(xmlName): + return (xmlName, filename) + return None + + +if __name__ == '__main__': + from optparse import OptionParser + parser = OptionParser(usage="usage: %prog [options] [path(s)]") + parser.add_option("-d", "--dir", dest='outDir', metavar='DIR', + help="specify the output directory (default=cwd)") + parser.add_option("-x", "--xml", dest='xml', action='store_true', + help="Write An XML output") + parser.add_option("-n", "--nitf", dest='nitf', action='store_true', + help="Write A NITF output") + parser.add_option("-t", "--tiff", dest='tiff', action='store_true', + help="Write A TIFF output") + parser.add_option("-k", "--kml", dest='kml', action='store_true', + help="Write A KML output") + parser.add_option("-l", "--level", dest='level', metavar='LEVEL', default=None, + help="Level at which to log ") + parser.add_option("--limit", dest='limit', metavar='NUM', default=0, type='int', + help="Specify a limit on the number of images to process") + (options, args) = parser.parse_args() + + #default to cwd if none provided + outDir = options.outDir or os.getcwd() + if not exists(outDir): + os.makedirs(outDir) + + inputs = [] + paths = args[:] + while paths: + path = paths.pop(0) + if isdir(path): + paths.extend(map(lambda x: join(path, x), os.listdir(path))) + else: + f = cosmoSkyMed(path) + if not f: + f = radarsat2(path) + if not f: + f = terraSAR(path) + if f: + inputs.append(f) + + appName = os.path.abspath(join(split(__file__)[0], './install/bin/ScanSARConverter')) + if 'win32' in sys.platform: + appName += '.exe' + + cmd = [appName] + cmd.extend(['-d', outDir]) + if options.xml: + cmd.append('-x') + if options.nitf: + cmd.append('-n') + if options.tiff: + cmd.append('-t') + if options.kml: + cmd.append('-k') + if options.level: + cmd.extend(['-l', options.level]) + + def process(xml, image): + command = cmd[:] + command.append('%s,%s' % (xml, image)) + print command + p = subprocess.Popen(command).communicate() + + limit = (options.limit > 0 and min(options.limit, len(inputs)) or len(inputs)) + print 'Processing %d files' % limit + for i, (xml, image) in enumerate(inputs): + if i >= limit: + break + process(xml, image) diff --git a/six.sln b/six.sln index 258b1a0eb1..d4bf483ca1 100644 --- a/six.sln +++ b/six.sln @@ -1,131 +1,131 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 17 -VisualStudioVersion = 17.0.31903.59 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c", "externals\nitro\modules\c\nitf-c.vcxproj", "{F06550AD-CFC7-40B8-8727-6C82C69A8982}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c++", "externals\nitro\modules\c++\nitf-c++.vcxproj", "{8F357A19-799E-4971-850E-3F28485C130B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six", "six\modules\c++\six\six.vcxproj", "{62AAD4DD-35BA-41A0-8263-1F4DFD755689}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scene", "six\modules\c++\scene\scene.vcxproj", "{1CFCDE59-6410-4037-95EB-B37D31E10820}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cphd", "six\modules\c++\cphd\cphd.vcxproj", "{01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cphd03", "six\modules\c++\cphd03\cphd03.vcxproj", "{016EF417-E41C-404C-B3B5-34B6CDD94BB3}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.sicd", "six\modules\c++\six.sicd\six.sicd.vcxproj", "{34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.sidd", "six\modules\c++\six.sidd\six.sidd.vcxproj", "{DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.convert", "six\modules\c++\six.convert\six.convert.vcxproj", "{DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XML_DATA_CONTENT", "externals\nitro\modules\c\nitf\XML_DATA_CONTENT.vcxproj", "{78849481-D356-4CC7-B182-31C21F857ED1}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AD152C2-1F3D-4108-826C-79BA5011874F}" - ProjectSection(SolutionItems) = preProject - six\modules\c++\cpp_pch.h = six\modules\c++\cpp_pch.h - README.md = README.md - ReleaseNotes.md = ReleaseNotes.md - EndProjectSection -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "check_valid_six", "six\modules\c++\samples\check_valid_six.dir\check_valid_six.vcxproj", "{F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crop_sicd", "six\modules\c++\samples\crop_sicd.dir\crop_sicd.vcxproj", "{7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "csm", "six\projects\csm\csm.vcxproj", "{6E767B43-D1A9-4B02-8D08-42037B7C9262}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{F6888896-E658-414C-90CD-1208FA31A22E}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "externals", "externals", "{F033066A-4172-4AC0-96AD-BF5090F713C2}" -EndProject -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coda-oss", "externals\coda-oss\modules\c++\coda-oss.vcxproj", "{9997E895-5161-4DDF-8F3F-099894CB2F21}" -EndProject -Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github-workflows", ".github-workflows", "{DB2B94ED-952C-4794-A692-E6B64AA9EE5A}" - ProjectSection(SolutionItems) = preProject - .github\workflows\codeql.yml = .github\workflows\codeql.yml - .github\workflows\frequent_check.yml = .github\workflows\frequent_check.yml - EndProjectSection -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|x64 = Debug|x64 - Release|x64 = Release|x64 - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Debug|x64.ActiveCfg = Debug|x64 - {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Debug|x64.Build.0 = Debug|x64 - {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Release|x64.ActiveCfg = Release|x64 - {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Release|x64.Build.0 = Release|x64 - {8F357A19-799E-4971-850E-3F28485C130B}.Debug|x64.ActiveCfg = Debug|x64 - {8F357A19-799E-4971-850E-3F28485C130B}.Debug|x64.Build.0 = Debug|x64 - {8F357A19-799E-4971-850E-3F28485C130B}.Release|x64.ActiveCfg = Release|x64 - {8F357A19-799E-4971-850E-3F28485C130B}.Release|x64.Build.0 = Release|x64 - {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Debug|x64.ActiveCfg = Debug|x64 - {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Debug|x64.Build.0 = Debug|x64 - {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Release|x64.ActiveCfg = Release|x64 - {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Release|x64.Build.0 = Release|x64 - {1CFCDE59-6410-4037-95EB-B37D31E10820}.Debug|x64.ActiveCfg = Debug|x64 - {1CFCDE59-6410-4037-95EB-B37D31E10820}.Debug|x64.Build.0 = Debug|x64 - {1CFCDE59-6410-4037-95EB-B37D31E10820}.Release|x64.ActiveCfg = Release|x64 - {1CFCDE59-6410-4037-95EB-B37D31E10820}.Release|x64.Build.0 = Release|x64 - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Debug|x64.ActiveCfg = Debug|x64 - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Debug|x64.Build.0 = Debug|x64 - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Release|x64.ActiveCfg = Release|x64 - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Release|x64.Build.0 = Release|x64 - {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Debug|x64.ActiveCfg = Debug|x64 - {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Debug|x64.Build.0 = Debug|x64 - {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Release|x64.ActiveCfg = Release|x64 - {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Release|x64.Build.0 = Release|x64 - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Debug|x64.ActiveCfg = Debug|x64 - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Debug|x64.Build.0 = Debug|x64 - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Release|x64.ActiveCfg = Release|x64 - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Release|x64.Build.0 = Release|x64 - {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Debug|x64.ActiveCfg = Debug|x64 - {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Debug|x64.Build.0 = Debug|x64 - {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Release|x64.ActiveCfg = Release|x64 - {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Release|x64.Build.0 = Release|x64 - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Debug|x64.ActiveCfg = Debug|x64 - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Debug|x64.Build.0 = Debug|x64 - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Release|x64.ActiveCfg = Release|x64 - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Release|x64.Build.0 = Release|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.ActiveCfg = Debug|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.Build.0 = Debug|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.ActiveCfg = Release|x64 - {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.Build.0 = Release|x64 - {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Debug|x64.ActiveCfg = Debug|x64 - {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Debug|x64.Build.0 = Debug|x64 - {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Release|x64.ActiveCfg = Release|x64 - {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Release|x64.Build.0 = Release|x64 - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Debug|x64.ActiveCfg = Debug|x64 - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Debug|x64.Build.0 = Debug|x64 - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Release|x64.ActiveCfg = Release|x64 - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Release|x64.Build.0 = Release|x64 - {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Debug|x64.ActiveCfg = Debug|x64 - {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Debug|x64.Build.0 = Debug|x64 - {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Release|x64.ActiveCfg = Release|x64 - {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Release|x64.Build.0 = Release|x64 - {F6888896-E658-414C-90CD-1208FA31A22E}.Debug|x64.ActiveCfg = Debug|x64 - {F6888896-E658-414C-90CD-1208FA31A22E}.Debug|x64.Build.0 = Debug|x64 - {F6888896-E658-414C-90CD-1208FA31A22E}.Release|x64.ActiveCfg = Release|x64 - {F6888896-E658-414C-90CD-1208FA31A22E}.Release|x64.Build.0 = Release|x64 - {9997E895-5161-4DDF-8F3F-099894CB2F21}.Debug|x64.ActiveCfg = Debug|x64 - {9997E895-5161-4DDF-8F3F-099894CB2F21}.Debug|x64.Build.0 = Debug|x64 - {9997E895-5161-4DDF-8F3F-099894CB2F21}.Release|x64.ActiveCfg = Release|x64 - {9997E895-5161-4DDF-8F3F-099894CB2F21}.Release|x64.Build.0 = Release|x64 - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(NestedProjects) = preSolution - {F06550AD-CFC7-40B8-8727-6C82C69A8982} = {F033066A-4172-4AC0-96AD-BF5090F713C2} - {8F357A19-799E-4971-850E-3F28485C130B} = {F033066A-4172-4AC0-96AD-BF5090F713C2} - {78849481-D356-4CC7-B182-31C21F857ED1} = {F033066A-4172-4AC0-96AD-BF5090F713C2} - {9997E895-5161-4DDF-8F3F-099894CB2F21} = {F033066A-4172-4AC0-96AD-BF5090F713C2} - {DB2B94ED-952C-4794-A692-E6B64AA9EE5A} = {3AD152C2-1F3D-4108-826C-79BA5011874F} - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {E20E9FC7-D138-4517-8597-79C1FAC3E28D} - EndGlobalSection -EndGlobal + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 17 +VisualStudioVersion = 17.0.31903.59 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c", "externals\nitro\modules\c\nitf-c.vcxproj", "{F06550AD-CFC7-40B8-8727-6C82C69A8982}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nitf-c++", "externals\nitro\modules\c++\nitf-c++.vcxproj", "{8F357A19-799E-4971-850E-3F28485C130B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six", "six\modules\c++\six\six.vcxproj", "{62AAD4DD-35BA-41A0-8263-1F4DFD755689}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "scene", "six\modules\c++\scene\scene.vcxproj", "{1CFCDE59-6410-4037-95EB-B37D31E10820}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cphd", "six\modules\c++\cphd\cphd.vcxproj", "{01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "cphd03", "six\modules\c++\cphd03\cphd03.vcxproj", "{016EF417-E41C-404C-B3B5-34B6CDD94BB3}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.sicd", "six\modules\c++\six.sicd\six.sicd.vcxproj", "{34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.sidd", "six\modules\c++\six.sidd\six.sidd.vcxproj", "{DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "six.convert", "six\modules\c++\six.convert\six.convert.vcxproj", "{DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "XML_DATA_CONTENT", "externals\nitro\modules\c\nitf\XML_DATA_CONTENT.vcxproj", "{78849481-D356-4CC7-B182-31C21F857ED1}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{3AD152C2-1F3D-4108-826C-79BA5011874F}" + ProjectSection(SolutionItems) = preProject + six\modules\c++\cpp_pch.h = six\modules\c++\cpp_pch.h + README.md = README.md + ReleaseNotes.md = ReleaseNotes.md + EndProjectSection +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "check_valid_six", "six\modules\c++\samples\check_valid_six.dir\check_valid_six.vcxproj", "{F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "crop_sicd", "six\modules\c++\samples\crop_sicd.dir\crop_sicd.vcxproj", "{7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "csm", "six\projects\csm\csm.vcxproj", "{6E767B43-D1A9-4B02-8D08-42037B7C9262}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "UnitTest", "UnitTest\UnitTest.vcxproj", "{F6888896-E658-414C-90CD-1208FA31A22E}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "externals", "externals", "{F033066A-4172-4AC0-96AD-BF5090F713C2}" +EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "coda-oss", "externals\coda-oss\modules\c++\coda-oss.vcxproj", "{9997E895-5161-4DDF-8F3F-099894CB2F21}" +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".github-workflows", ".github-workflows", "{DB2B94ED-952C-4794-A692-E6B64AA9EE5A}" + ProjectSection(SolutionItems) = preProject + .github\workflows\codeql.yml = .github\workflows\codeql.yml + .github\workflows\frequent_check.yml = .github\workflows\frequent_check.yml + EndProjectSection +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|x64 = Debug|x64 + Release|x64 = Release|x64 + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Debug|x64.ActiveCfg = Debug|x64 + {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Debug|x64.Build.0 = Debug|x64 + {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Release|x64.ActiveCfg = Release|x64 + {F06550AD-CFC7-40B8-8727-6C82C69A8982}.Release|x64.Build.0 = Release|x64 + {8F357A19-799E-4971-850E-3F28485C130B}.Debug|x64.ActiveCfg = Debug|x64 + {8F357A19-799E-4971-850E-3F28485C130B}.Debug|x64.Build.0 = Debug|x64 + {8F357A19-799E-4971-850E-3F28485C130B}.Release|x64.ActiveCfg = Release|x64 + {8F357A19-799E-4971-850E-3F28485C130B}.Release|x64.Build.0 = Release|x64 + {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Debug|x64.ActiveCfg = Debug|x64 + {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Debug|x64.Build.0 = Debug|x64 + {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Release|x64.ActiveCfg = Release|x64 + {62AAD4DD-35BA-41A0-8263-1F4DFD755689}.Release|x64.Build.0 = Release|x64 + {1CFCDE59-6410-4037-95EB-B37D31E10820}.Debug|x64.ActiveCfg = Debug|x64 + {1CFCDE59-6410-4037-95EB-B37D31E10820}.Debug|x64.Build.0 = Debug|x64 + {1CFCDE59-6410-4037-95EB-B37D31E10820}.Release|x64.ActiveCfg = Release|x64 + {1CFCDE59-6410-4037-95EB-B37D31E10820}.Release|x64.Build.0 = Release|x64 + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Debug|x64.ActiveCfg = Debug|x64 + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Debug|x64.Build.0 = Debug|x64 + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Release|x64.ActiveCfg = Release|x64 + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B}.Release|x64.Build.0 = Release|x64 + {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Debug|x64.ActiveCfg = Debug|x64 + {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Debug|x64.Build.0 = Debug|x64 + {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Release|x64.ActiveCfg = Release|x64 + {016EF417-E41C-404C-B3B5-34B6CDD94BB3}.Release|x64.Build.0 = Release|x64 + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Debug|x64.ActiveCfg = Debug|x64 + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Debug|x64.Build.0 = Debug|x64 + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Release|x64.ActiveCfg = Release|x64 + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E}.Release|x64.Build.0 = Release|x64 + {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Debug|x64.ActiveCfg = Debug|x64 + {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Debug|x64.Build.0 = Debug|x64 + {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Release|x64.ActiveCfg = Release|x64 + {DDC587C2-53BA-44A9-94E7-07BE52AF3D0B}.Release|x64.Build.0 = Release|x64 + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Debug|x64.ActiveCfg = Debug|x64 + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Debug|x64.Build.0 = Debug|x64 + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Release|x64.ActiveCfg = Release|x64 + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B}.Release|x64.Build.0 = Release|x64 + {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.ActiveCfg = Debug|x64 + {78849481-D356-4CC7-B182-31C21F857ED1}.Debug|x64.Build.0 = Debug|x64 + {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.ActiveCfg = Release|x64 + {78849481-D356-4CC7-B182-31C21F857ED1}.Release|x64.Build.0 = Release|x64 + {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Debug|x64.ActiveCfg = Debug|x64 + {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Debug|x64.Build.0 = Debug|x64 + {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Release|x64.ActiveCfg = Release|x64 + {F0E2C8FF-57D4-4331-9BD2-76FF01CB54EB}.Release|x64.Build.0 = Release|x64 + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Debug|x64.ActiveCfg = Debug|x64 + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Debug|x64.Build.0 = Debug|x64 + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Release|x64.ActiveCfg = Release|x64 + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC}.Release|x64.Build.0 = Release|x64 + {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Debug|x64.ActiveCfg = Debug|x64 + {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Debug|x64.Build.0 = Debug|x64 + {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Release|x64.ActiveCfg = Release|x64 + {6E767B43-D1A9-4B02-8D08-42037B7C9262}.Release|x64.Build.0 = Release|x64 + {F6888896-E658-414C-90CD-1208FA31A22E}.Debug|x64.ActiveCfg = Debug|x64 + {F6888896-E658-414C-90CD-1208FA31A22E}.Debug|x64.Build.0 = Debug|x64 + {F6888896-E658-414C-90CD-1208FA31A22E}.Release|x64.ActiveCfg = Release|x64 + {F6888896-E658-414C-90CD-1208FA31A22E}.Release|x64.Build.0 = Release|x64 + {9997E895-5161-4DDF-8F3F-099894CB2F21}.Debug|x64.ActiveCfg = Debug|x64 + {9997E895-5161-4DDF-8F3F-099894CB2F21}.Debug|x64.Build.0 = Debug|x64 + {9997E895-5161-4DDF-8F3F-099894CB2F21}.Release|x64.ActiveCfg = Release|x64 + {9997E895-5161-4DDF-8F3F-099894CB2F21}.Release|x64.Build.0 = Release|x64 + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(NestedProjects) = preSolution + {F06550AD-CFC7-40B8-8727-6C82C69A8982} = {F033066A-4172-4AC0-96AD-BF5090F713C2} + {8F357A19-799E-4971-850E-3F28485C130B} = {F033066A-4172-4AC0-96AD-BF5090F713C2} + {78849481-D356-4CC7-B182-31C21F857ED1} = {F033066A-4172-4AC0-96AD-BF5090F713C2} + {9997E895-5161-4DDF-8F3F-099894CB2F21} = {F033066A-4172-4AC0-96AD-BF5090F713C2} + {DB2B94ED-952C-4794-A692-E6B64AA9EE5A} = {3AD152C2-1F3D-4108-826C-79BA5011874F} + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {E20E9FC7-D138-4517-8597-79C1FAC3E28D} + EndGlobalSection +EndGlobal diff --git a/six/modules/c++/cphd/cphd.vcxproj b/six/modules/c++/cphd/cphd.vcxproj index fc081ca05d..45aaa5e6a5 100644 --- a/six/modules/c++/cphd/cphd.vcxproj +++ b/six/modules/c++/cphd/cphd.vcxproj @@ -1,183 +1,183 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..\scene\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\six.sicd\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..\scene\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\six.sicd\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - {8f357a19-799e-4971-850e-3f28485c130b} - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {01BE4480-9620-4DED-B34F-D2E3AB4B7C8B} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..\scene\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\six.sicd\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..\scene\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\six.sicd\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + {8f357a19-799e-4971-850e-3f28485c130b} + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/six/modules/c++/cphd/cphd.vcxproj.filters b/six/modules/c++/cphd/cphd.vcxproj.filters index 0eace9d1af..5c6354173b 100644 --- a/six/modules/c++/cphd/cphd.vcxproj.filters +++ b/six/modules/c++/cphd/cphd.vcxproj.filters @@ -1,195 +1,195 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + \ No newline at end of file diff --git a/six/modules/c++/cphd/include/cphd/Antenna.h b/six/modules/c++/cphd/include/cphd/Antenna.h index 300936e05a..0e7a29b7e6 100644 --- a/six/modules/c++/cphd/include/cphd/Antenna.h +++ b/six/modules/c++/cphd/include/cphd/Antenna.h @@ -1,374 +1,374 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#pragma once -#ifndef SIX_cphd_Antenna_h_INCLUDED_ -#define SIX_cphd_Antenna_h_INCLUDED_ - -#include - -#include -#include -#include - -#include -#include - -#include -#include - -namespace cphd -{ -/* - * \struct AntCoordFrame - * \brief CPHD Antenna Coordinate Frame parameter - * - * Unit vectors that describe the orientation of an - * Antenna Coordinate Frame as a function of time. - * AntCoordFrame used by CPHD, representing the tag - * . - */ -struct AntCoordFrame final -{ - //! Constructor - AntCoordFrame(); - - //! Equality operators - bool operator==(const AntCoordFrame& other) const - { - return (identifier == other.identifier) - && (xAxisPoly == other.xAxisPoly) - && (yAxisPoly == other.yAxisPoly) - && (useACFPVP == other.useACFPVP); - } - bool operator!=(const AntCoordFrame& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this ACF - //! (ACF_ID) - std::string identifier; - - //!Antenna coordinate frame X-Axis unit vector in - //! ECF coordinates as a function time (sec). - PolyXYZ xAxisPoly; - - //!Antenna coordinate frame Y-Axis unit vector in - //! ECF coordinates as a function time (sec). - PolyXYZ yAxisPoly; - - //!Indicates the provided ACF PVP arrays provide a more accurate description the ACF orientation vs.time. - six::XsElement_minOccurs0 useACFPVP{ "UseACFPVP" }; // new in CPHD 1.1.0 -}; - -/* - * \struct AntPhaseCenter - * \brief Parameters that describe each Antenna Phase Center. - * - * AntPhaseCenter used by CPHD, representing the tag - * . - */ -struct AntPhaseCenter -{ - //! Constructor - AntPhaseCenter(); - - //! Equality operators - bool operator==(const AntPhaseCenter& other) const - { - return identifier == other.identifier && - acfId == other.acfId && apcXYZ == other.apcXYZ; - } - bool operator!=(const AntPhaseCenter& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this APC - //! (APC_ID). - std::string identifier; - - //! Identifier of Antenna Coordinate Frame used for - //! computing the antenna gain and phase patterns - std::string acfId; - - //! The APC location in the ACF XYZ coordinate - //! frame - Vector3 apcXYZ; -}; - -/* - * \struct AntPattern - * \brief CPHD Antenna Pattern parameter - * - * Parameter set that defines each Antenna Pattern - * as a function of time. - * AntPattern used by CPHD, representing the tag - * . - */ -struct AntPattern final -{ - /* - * \struct EBFreqShiftSF - * \brief Scale factors used compute the EB shift vs. frequency - * - * (Optional) Scale factors used compute the EB shift vs. frequency in DCX and DCY. - * - */ - struct EBFreqShiftSF final - { - bool operator==(const EBFreqShiftSF& other) const - { - return (dcxsf == other.dcxsf) - && (dcysf == other.dcysf); - } - bool operator!=(const EBFreqShiftSF& other) const - { - return !((*this) == other); - } - - //! Scale factor used to compute the ML dilation factor in DCX vs. frequency. - six::XsElement dcxsf{ "DCXSF" }; - - //! Scale factor used to compute the ML dilation factor in DCY vs. frequency. - six::XsElement dcysf{ "DCYSF" }; - }; - - /* - * \struct MLFreqDilationSF - * \brief Scale factors used to compute the array pattern - * - * (Optional) Scale factors used to compute the array pattern mainlobe dilation vs. frequency in DCX and DCY. - * - */ - struct MLFreqDilationSF final - { - bool operator==(const MLFreqDilationSF& other) const - { - return (dcxsf == other.dcxsf) - && (dcysf == other.dcysf); - } - bool operator!=(const MLFreqDilationSF& other) const - { - return !((*this) == other); - } - - //! Scale factor used to compute the ML dilation factor in DCX vs. frequency. - six::XsElement dcxsf{ "DCXSF" }; - - //! Scale factor used to compute the ML dilation factor in DCY vs. frequency. - six::XsElement dcysf{ "DCYSF" }; - }; - - /* - * \struct AntPolRef - * \brief Polarization parameters - * - * (Optional) Polarization parameters for the EB steered to mechanical boresight - * - */ - struct AntPolRef final - { - bool operator==(const AntPolRef& other) const - { - return (ampX == other.ampX) - && (ampY == other.ampY) - && (phaseY == other.phaseY); - } - bool operator!=(const AntPolRef& other) const - { - return !((*this) == other); - } - - //! E-field relative amplitude in ACF X direction at f = f_0. - six::XsElement ampX{ "AmpX" }; - - //! E-field relative amplitude in ACY direction at f = f_0. - six::XsElement ampY{ "AmpY" }; - - //! Relative phase of the Y E-field relative to the X E-field at f = f_0. - six::XsElement phaseY{ "PhaseY" }; - }; - - /* - * \struct GainPhaseArray - * \brief Gain Phase Array parameter - * - * (Optional) Parameters that identify 2-D sampled Grain & Phase patterns at - * a single frequency value. - * - */ - struct GainPhaseArray - { - //! Constructor - GainPhaseArray(); - - //! Equality operators - bool operator==(const GainPhaseArray& other) const - { - return freq == other.freq && arrayId == other.arrayId && - elementId == other.elementId; - } - bool operator!=(const GainPhaseArray& other) const - { - return !((*this) == other); - } - - //! Frequency value for which the sampled Array & - //! Element pattern(s) are provided. - double freq; - - //! Support Array identifier of the sampled - //! Gain/Phase of the Array at RefFrequency - std::string arrayId; - - //! (Optional) Support Array identifier of the sampled - //! Gain/Phase of the Element at RefFrequency - std::string elementId; - }; - - //! Default constructor - AntPattern(); - - //! Equality operators - bool operator==(const AntPattern& other) const - { - return identifier == other.identifier && - freqZero == other.freqZero && gainZero == other.gainZero && - ebFreqShift == other.ebFreqShift && - mlFreqDilation == other.mlFreqDilation && - gainBSPoly == other.gainBSPoly && eb == other.eb && - array == other.array && element == other.element && - gainPhaseArray == other.gainPhaseArray; - } - bool operator!=(const AntPattern& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this Antenna - //! Pattern (APAT_ID). - std::string identifier; - - //! The reference frequency (f_0) value for which - //! the Electrical Boresight and array pattern - //! polynomials are computed. - double freqZero; - - //! (Optional) The reference antenna gain (G_0) at zero steering - //! angle at the reference frequency (f_0) - double gainZero; - - //! (Optional) Parameter to indicate the EB steering direction - //! shifts with frequency. - six::BooleanType ebFreqShift; - - //! (Optional) Parameter to indicate the mainlobe width varies - //! with frequency. - six::BooleanType mlFreqDilation; - - //! (Optional) Gain polynomial (dB) vs. frequency for the array - //! pattern at boresight. Gain relative to gain at f_0. - //! Poly1D gainBSPoly; - Poly1D gainBSPoly; - - //! (Optional) Scale factors used compute the EB shift vs. frequency - six::XsElement_minOccurs0 ebFreqShiftSF{ "EBFreqShiftSF" }; // new in CPHD 1.1.0 - - //! (Optional) Scale factors used to compute the array pattern - six::XsElement_minOccurs0 mlFreqDilationSF{ "MLFreqDilationSF" }; // new in CPHD 1.1.0 - - //! (Optional) Polarization parameters for the EB steered to mechanical boresight - six::XsElement_minOccurs0 antPolRef{ "AntPolRef" }; // new in CPHD 1.1.0 - - //! The Electrical Boresight steering direction versus - //! time. Defines array pattern pointing direction - six::sicd::ElectricalBoresight eb; - - //! Array Pattern polynomials that describe the - //! mainlobe gain and phase patterns. Patterns - //! defined at f = f_0 - six::sicd::GainAndPhasePolys array; - - //! Element Pattern polynomials that describe the - //! gain and phase patterns - six::sicd::GainAndPhasePolys element; - - //! Parameters that identify 2-D sampled Gain & - //! Phase patterns at single frequency value. - std::vector gainPhaseArray; -}; - -/* - * \struct Antenna - * \brief (Optional) Antenna parameters - * - * Parameters that describe the transmit and - * receive antennas used to collect the signal array. - * See section 8.2 - */ -struct Antenna -{ - //! Default constructor - Antenna(); - - //! Equality operators - bool operator==(const Antenna& other) const - { - return antCoordFrame == other.antCoordFrame && - antPhaseCenter == other.antPhaseCenter && - antPattern == other.antPattern; - } - bool operator!=(const Antenna& other) const - { - return !((*this) == other); - } - - //! Unit vectors that describe the orientation of an - //! Antenna Coordinate Frame (ACF) as function of - //! time. - std::vector antCoordFrame; - - //! Parameters that describe each Antenna Phase - //! Center (APC). Parameter set repeated for each - //! APC - std::vector antPhaseCenter; - - //! Parameter set that defines each Antenna Pattern - //! as function time. Parameters set repeated for - //! each Antenna Pattern - std::vector antPattern; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const AntCoordFrame& a); -std::ostream& operator<< (std::ostream& os, const AntPhaseCenter& a); -std::ostream& operator<< (std::ostream& os, const AntPattern::EBFreqShiftSF&); -std::ostream& operator<< (std::ostream& os, const AntPattern::AntPolRef&); -std::ostream& operator<< (std::ostream& os, const AntPattern::MLFreqDilationSF&); -std::ostream& operator<< (std::ostream& os, const AntPattern::GainPhaseArray& g); -std::ostream& operator<< (std::ostream& os, const AntPattern& a); -std::ostream& operator<< (std::ostream& os, const Antenna& a); -} - -#endif // SIX_cphd_Antenna_h_INCLUDED_ +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#pragma once +#ifndef SIX_cphd_Antenna_h_INCLUDED_ +#define SIX_cphd_Antenna_h_INCLUDED_ + +#include + +#include +#include +#include + +#include +#include + +#include +#include + +namespace cphd +{ +/* + * \struct AntCoordFrame + * \brief CPHD Antenna Coordinate Frame parameter + * + * Unit vectors that describe the orientation of an + * Antenna Coordinate Frame as a function of time. + * AntCoordFrame used by CPHD, representing the tag + * . + */ +struct AntCoordFrame final +{ + //! Constructor + AntCoordFrame(); + + //! Equality operators + bool operator==(const AntCoordFrame& other) const + { + return (identifier == other.identifier) + && (xAxisPoly == other.xAxisPoly) + && (yAxisPoly == other.yAxisPoly) + && (useACFPVP == other.useACFPVP); + } + bool operator!=(const AntCoordFrame& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this ACF + //! (ACF_ID) + std::string identifier; + + //!Antenna coordinate frame X-Axis unit vector in + //! ECF coordinates as a function time (sec). + PolyXYZ xAxisPoly; + + //!Antenna coordinate frame Y-Axis unit vector in + //! ECF coordinates as a function time (sec). + PolyXYZ yAxisPoly; + + //!Indicates the provided ACF PVP arrays provide a more accurate description the ACF orientation vs.time. + six::XsElement_minOccurs0 useACFPVP{ "UseACFPVP" }; // new in CPHD 1.1.0 +}; + +/* + * \struct AntPhaseCenter + * \brief Parameters that describe each Antenna Phase Center. + * + * AntPhaseCenter used by CPHD, representing the tag + * . + */ +struct AntPhaseCenter +{ + //! Constructor + AntPhaseCenter(); + + //! Equality operators + bool operator==(const AntPhaseCenter& other) const + { + return identifier == other.identifier && + acfId == other.acfId && apcXYZ == other.apcXYZ; + } + bool operator!=(const AntPhaseCenter& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this APC + //! (APC_ID). + std::string identifier; + + //! Identifier of Antenna Coordinate Frame used for + //! computing the antenna gain and phase patterns + std::string acfId; + + //! The APC location in the ACF XYZ coordinate + //! frame + Vector3 apcXYZ; +}; + +/* + * \struct AntPattern + * \brief CPHD Antenna Pattern parameter + * + * Parameter set that defines each Antenna Pattern + * as a function of time. + * AntPattern used by CPHD, representing the tag + * . + */ +struct AntPattern final +{ + /* + * \struct EBFreqShiftSF + * \brief Scale factors used compute the EB shift vs. frequency + * + * (Optional) Scale factors used compute the EB shift vs. frequency in DCX and DCY. + * + */ + struct EBFreqShiftSF final + { + bool operator==(const EBFreqShiftSF& other) const + { + return (dcxsf == other.dcxsf) + && (dcysf == other.dcysf); + } + bool operator!=(const EBFreqShiftSF& other) const + { + return !((*this) == other); + } + + //! Scale factor used to compute the ML dilation factor in DCX vs. frequency. + six::XsElement dcxsf{ "DCXSF" }; + + //! Scale factor used to compute the ML dilation factor in DCY vs. frequency. + six::XsElement dcysf{ "DCYSF" }; + }; + + /* + * \struct MLFreqDilationSF + * \brief Scale factors used to compute the array pattern + * + * (Optional) Scale factors used to compute the array pattern mainlobe dilation vs. frequency in DCX and DCY. + * + */ + struct MLFreqDilationSF final + { + bool operator==(const MLFreqDilationSF& other) const + { + return (dcxsf == other.dcxsf) + && (dcysf == other.dcysf); + } + bool operator!=(const MLFreqDilationSF& other) const + { + return !((*this) == other); + } + + //! Scale factor used to compute the ML dilation factor in DCX vs. frequency. + six::XsElement dcxsf{ "DCXSF" }; + + //! Scale factor used to compute the ML dilation factor in DCY vs. frequency. + six::XsElement dcysf{ "DCYSF" }; + }; + + /* + * \struct AntPolRef + * \brief Polarization parameters + * + * (Optional) Polarization parameters for the EB steered to mechanical boresight + * + */ + struct AntPolRef final + { + bool operator==(const AntPolRef& other) const + { + return (ampX == other.ampX) + && (ampY == other.ampY) + && (phaseY == other.phaseY); + } + bool operator!=(const AntPolRef& other) const + { + return !((*this) == other); + } + + //! E-field relative amplitude in ACF X direction at f = f_0. + six::XsElement ampX{ "AmpX" }; + + //! E-field relative amplitude in ACY direction at f = f_0. + six::XsElement ampY{ "AmpY" }; + + //! Relative phase of the Y E-field relative to the X E-field at f = f_0. + six::XsElement phaseY{ "PhaseY" }; + }; + + /* + * \struct GainPhaseArray + * \brief Gain Phase Array parameter + * + * (Optional) Parameters that identify 2-D sampled Grain & Phase patterns at + * a single frequency value. + * + */ + struct GainPhaseArray + { + //! Constructor + GainPhaseArray(); + + //! Equality operators + bool operator==(const GainPhaseArray& other) const + { + return freq == other.freq && arrayId == other.arrayId && + elementId == other.elementId; + } + bool operator!=(const GainPhaseArray& other) const + { + return !((*this) == other); + } + + //! Frequency value for which the sampled Array & + //! Element pattern(s) are provided. + double freq; + + //! Support Array identifier of the sampled + //! Gain/Phase of the Array at RefFrequency + std::string arrayId; + + //! (Optional) Support Array identifier of the sampled + //! Gain/Phase of the Element at RefFrequency + std::string elementId; + }; + + //! Default constructor + AntPattern(); + + //! Equality operators + bool operator==(const AntPattern& other) const + { + return identifier == other.identifier && + freqZero == other.freqZero && gainZero == other.gainZero && + ebFreqShift == other.ebFreqShift && + mlFreqDilation == other.mlFreqDilation && + gainBSPoly == other.gainBSPoly && eb == other.eb && + array == other.array && element == other.element && + gainPhaseArray == other.gainPhaseArray; + } + bool operator!=(const AntPattern& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this Antenna + //! Pattern (APAT_ID). + std::string identifier; + + //! The reference frequency (f_0) value for which + //! the Electrical Boresight and array pattern + //! polynomials are computed. + double freqZero; + + //! (Optional) The reference antenna gain (G_0) at zero steering + //! angle at the reference frequency (f_0) + double gainZero; + + //! (Optional) Parameter to indicate the EB steering direction + //! shifts with frequency. + six::BooleanType ebFreqShift; + + //! (Optional) Parameter to indicate the mainlobe width varies + //! with frequency. + six::BooleanType mlFreqDilation; + + //! (Optional) Gain polynomial (dB) vs. frequency for the array + //! pattern at boresight. Gain relative to gain at f_0. + //! Poly1D gainBSPoly; + Poly1D gainBSPoly; + + //! (Optional) Scale factors used compute the EB shift vs. frequency + six::XsElement_minOccurs0 ebFreqShiftSF{ "EBFreqShiftSF" }; // new in CPHD 1.1.0 + + //! (Optional) Scale factors used to compute the array pattern + six::XsElement_minOccurs0 mlFreqDilationSF{ "MLFreqDilationSF" }; // new in CPHD 1.1.0 + + //! (Optional) Polarization parameters for the EB steered to mechanical boresight + six::XsElement_minOccurs0 antPolRef{ "AntPolRef" }; // new in CPHD 1.1.0 + + //! The Electrical Boresight steering direction versus + //! time. Defines array pattern pointing direction + six::sicd::ElectricalBoresight eb; + + //! Array Pattern polynomials that describe the + //! mainlobe gain and phase patterns. Patterns + //! defined at f = f_0 + six::sicd::GainAndPhasePolys array; + + //! Element Pattern polynomials that describe the + //! gain and phase patterns + six::sicd::GainAndPhasePolys element; + + //! Parameters that identify 2-D sampled Gain & + //! Phase patterns at single frequency value. + std::vector gainPhaseArray; +}; + +/* + * \struct Antenna + * \brief (Optional) Antenna parameters + * + * Parameters that describe the transmit and + * receive antennas used to collect the signal array. + * See section 8.2 + */ +struct Antenna +{ + //! Default constructor + Antenna(); + + //! Equality operators + bool operator==(const Antenna& other) const + { + return antCoordFrame == other.antCoordFrame && + antPhaseCenter == other.antPhaseCenter && + antPattern == other.antPattern; + } + bool operator!=(const Antenna& other) const + { + return !((*this) == other); + } + + //! Unit vectors that describe the orientation of an + //! Antenna Coordinate Frame (ACF) as function of + //! time. + std::vector antCoordFrame; + + //! Parameters that describe each Antenna Phase + //! Center (APC). Parameter set repeated for each + //! APC + std::vector antPhaseCenter; + + //! Parameter set that defines each Antenna Pattern + //! as function time. Parameters set repeated for + //! each Antenna Pattern + std::vector antPattern; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const AntCoordFrame& a); +std::ostream& operator<< (std::ostream& os, const AntPhaseCenter& a); +std::ostream& operator<< (std::ostream& os, const AntPattern::EBFreqShiftSF&); +std::ostream& operator<< (std::ostream& os, const AntPattern::AntPolRef&); +std::ostream& operator<< (std::ostream& os, const AntPattern::MLFreqDilationSF&); +std::ostream& operator<< (std::ostream& os, const AntPattern::GainPhaseArray& g); +std::ostream& operator<< (std::ostream& os, const AntPattern& a); +std::ostream& operator<< (std::ostream& os, const Antenna& a); +} + +#endif // SIX_cphd_Antenna_h_INCLUDED_ diff --git a/six/modules/c++/cphd/include/cphd/Dwell.h b/six/modules/c++/cphd/include/cphd/Dwell.h index 44c2537371..86092806f6 100644 --- a/six/modules/c++/cphd/include/cphd/Dwell.h +++ b/six/modules/c++/cphd/include/cphd/Dwell.h @@ -1,128 +1,128 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_DWELL_H__ -#define __CPHD_DWELL_H__ - -#include -#include - -#include -#include - -#include - -namespace cphd -{ - -/* - * \struct DwellTime - * - * \brief Dwell Time Polynomial - */ -struct DwellTime -{ - //! Constructor - DwellTime(); - - //! Equality operators - bool operator==(const DwellTime& other) const - { - return identifier == other.identifier && dwellTimePoly == other.dwellTimePoly; - } - bool operator!=(const DwellTime& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this Dwell Time polynomial (Dwell_ID) - std::string identifier; - - //! Polynomial that yields Dwell Time as a function of IAX and IAY - Poly2D dwellTimePoly; -}; - -/* - * \struct COD - * - * \brief Center of Dwell Time Polynomial - */ -struct COD -{ - //! Constructor - COD(); - - //! Equality operators - bool operator==(const COD& other) const - { - return identifier == other.identifier && codTimePoly == other.codTimePoly; - } - bool operator!=(const COD& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this COD Time polynomial (COD_ID) - std::string identifier; - - //! Polynomial that yields COD Time as a function of IAX and IAY - Poly2D codTimePoly; -}; - -/* - * \struct Dwell - * - * \brief Dwell Time parameters - * - * Parameters that specify the dwell time supported by the signal arrays - * contained in the CPHD product - * See section 7.3 - */ -struct Dwell -{ - //! Constructor - Dwell(); - - // Equality operator - bool operator==(const Dwell& other) const - { - return cod == other.cod && dtime == other.dtime; - } - bool operator!=(const Dwell& other) const - { - return !((*this) == other); - } - - //! Center of Dwell (COD) Time Polynomial - std::vector cod; - - //! Dwell Time Polynomial - std::vector dtime; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const DwellTime& d); -std::ostream& operator<< (std::ostream& os, const COD& c); -std::ostream& operator<< (std::ostream& os, const Dwell& d); -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_DWELL_H__ +#define __CPHD_DWELL_H__ + +#include +#include + +#include +#include + +#include + +namespace cphd +{ + +/* + * \struct DwellTime + * + * \brief Dwell Time Polynomial + */ +struct DwellTime +{ + //! Constructor + DwellTime(); + + //! Equality operators + bool operator==(const DwellTime& other) const + { + return identifier == other.identifier && dwellTimePoly == other.dwellTimePoly; + } + bool operator!=(const DwellTime& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this Dwell Time polynomial (Dwell_ID) + std::string identifier; + + //! Polynomial that yields Dwell Time as a function of IAX and IAY + Poly2D dwellTimePoly; +}; + +/* + * \struct COD + * + * \brief Center of Dwell Time Polynomial + */ +struct COD +{ + //! Constructor + COD(); + + //! Equality operators + bool operator==(const COD& other) const + { + return identifier == other.identifier && codTimePoly == other.codTimePoly; + } + bool operator!=(const COD& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this COD Time polynomial (COD_ID) + std::string identifier; + + //! Polynomial that yields COD Time as a function of IAX and IAY + Poly2D codTimePoly; +}; + +/* + * \struct Dwell + * + * \brief Dwell Time parameters + * + * Parameters that specify the dwell time supported by the signal arrays + * contained in the CPHD product + * See section 7.3 + */ +struct Dwell +{ + //! Constructor + Dwell(); + + // Equality operator + bool operator==(const Dwell& other) const + { + return cod == other.cod && dtime == other.dtime; + } + bool operator!=(const Dwell& other) const + { + return !((*this) == other); + } + + //! Center of Dwell (COD) Time Polynomial + std::vector cod; + + //! Dwell Time Polynomial + std::vector dtime; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const DwellTime& d); +std::ostream& operator<< (std::ostream& os, const COD& c); +std::ostream& operator<< (std::ostream& os, const Dwell& d); +} + +#endif diff --git a/six/modules/c++/cphd/include/cphd/ErrorParameters.h b/six/modules/c++/cphd/include/cphd/ErrorParameters.h index 0f4be81343..6bd94d91c7 100644 --- a/six/modules/c++/cphd/include/cphd/ErrorParameters.h +++ b/six/modules/c++/cphd/include/cphd/ErrorParameters.h @@ -1,240 +1,240 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#pragma once -#ifndef SIX_cphd_ErrorParameters_h_INCLUDED_ -#define SIX_cphd_ErrorParameters_h_INCLUDED_ - -#include - -#include -#include -#include - -#include -#include -#include - -#include -#include - -namespace cphd -{ - -/* - * \struct ErrorParameters - * - * \brief Describes error parameters - * - * (Optional) Parameters that describe the statistics of errors - * in measured or estimated parameters that describe - * the collection - */ -struct ErrorParameters -{ - /* - * \struct Monostatic - * - * \brief (Conditional) Parameters for CollectType = "MONOSTATIC" - */ - struct Monostatic - { - /* - * \struct RadarSensor - * - * \brief Position and velocity error statistics for the - * sensor platform - */ - struct RadarSensor - { - //! Constructor - RadarSensor(); - - //! Equality operators - bool operator==(const RadarSensor& other) const - { - return rangeBias == other.rangeBias && - clockFreqSF == other.clockFreqSF && - collectionStartTime == other.collectionStartTime && - rangeBiasDecorr == other.rangeBiasDecorr; - } - bool operator!=(const RadarSensor& other) const - { - return !((*this) == other); - } - - //! Range bias error standard deviation. - double rangeBias; - - //! (Optional) Payload clock frequency scale factor standard deviation - double clockFreqSF; - - //! (Optional) Collection Start time error standard deviation - double collectionStartTime; - - //! (Optional) Range Bias error decorrelation function - mem::ScopedCopyablePtr rangeBiasDecorr; - }; - - //! Equality operators - bool operator==(const Monostatic& other) const - { - return posVelErr == other.posVelErr && - radarSensor == other.radarSensor && - tropoError == other.tropoError && - ionoError == other.ionoError && - parameter == other.parameter; - } - bool operator!=(const Monostatic& other) const - { - return !((*this) == other); - } - - //! Position and velocity error statistics for the - //! Transmit platform. - six::PosVelError posVelErr; - - //! Radar sensor error statistics - RadarSensor radarSensor; - - //! (Optional) Error parameters related to the Troposphere - mem::ScopedCopyablePtr tropoError; - - //! (Optional) Error parameters related to the Ionosphere - mem::ScopedCopyablePtr ionoError; - - //! (Optional) Additional error parameters to be added for - //! Monostatic collections - six::ParameterCollection parameter; - }; - - /* - * \struct Bistatic - * - * \brief (Conditional) Parameters for CollectType = "BISTATIC" - */ - struct Bistatic final - { - /* - * \struct RadarSensor - * - * \brief Error statistics for the Transmit platform - */ - struct RadarSensor final - { - //! Constructor - RadarSensor(); - - //! Equality operators - bool operator==(const RadarSensor& other) const - { - return (delayBias == other.delayBias) - && (clockFreqSF == other.clockFreqSF) - && (collectionStartTime == other.collectionStartTime); - } - bool operator!=(const RadarSensor& other) const - { - return !((*this) == other); - } - - //! Transmit time delay bias error standard deviation - six::XsElement_minOccurs0 delayBias{ "DelayBias" }; // new in CPHD 1.1.0 - - //! (Optional) Payload clock frequency scale factor standard deviation - double clockFreqSF; - - //! Collection Start time error standard deviation. - double collectionStartTime; - }; - - /* - * \struct Platform - * - * \brief Error statisitcs of platforms - */ - struct Platform - { - //! Equality operators - bool operator==(const Platform& other) const - { - return posVelErr == other.posVelErr && - radarSensor == other.radarSensor; - } - bool operator!=(const Platform& other) const - { - return !((*this) == other); - } - - //! Position and velocity error statistics - six::PosVelError posVelErr; - - //! Transmit sensor error statistics - RadarSensor radarSensor; - }; - - //! Equality operators - bool operator==(const Bistatic& other) const - { - return txPlatform == other.txPlatform && - rcvPlatform == other.rcvPlatform && - parameter == other.parameter; - } - bool operator!=(const Bistatic& other) const - { - return !((*this) == other); - } - - //! Error statistics for the Transmit platform - Platform txPlatform; - - //! Error statistics for the Receive Only platform. - Platform rcvPlatform; - - //! Additional error parameters to be added for - //! Bistatic collections - six::ParameterCollection parameter; - }; - - //! Equality operators - bool operator==(const ErrorParameters& other) const - { - return monostatic == other.monostatic && - bistatic == other.bistatic; - } - bool operator!=(const ErrorParameters& other) const - { - return !((*this) == other); - } - - //! (Conditional) Parameters for CollectType = "MONOSTATIC" - mem::ScopedCopyablePtr monostatic; - - //! (Conditional) Parameters for CollectType = "BISTATIC" - mem::ScopedCopyablePtr bistatic; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const six::PosVelError& p); -std::ostream& operator<< (std::ostream& os, const ErrorParameters& e); -} - -#endif // SIX_cphd_ErrorParameters_h_INCLUDED_ +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#pragma once +#ifndef SIX_cphd_ErrorParameters_h_INCLUDED_ +#define SIX_cphd_ErrorParameters_h_INCLUDED_ + +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +namespace cphd +{ + +/* + * \struct ErrorParameters + * + * \brief Describes error parameters + * + * (Optional) Parameters that describe the statistics of errors + * in measured or estimated parameters that describe + * the collection + */ +struct ErrorParameters +{ + /* + * \struct Monostatic + * + * \brief (Conditional) Parameters for CollectType = "MONOSTATIC" + */ + struct Monostatic + { + /* + * \struct RadarSensor + * + * \brief Position and velocity error statistics for the + * sensor platform + */ + struct RadarSensor + { + //! Constructor + RadarSensor(); + + //! Equality operators + bool operator==(const RadarSensor& other) const + { + return rangeBias == other.rangeBias && + clockFreqSF == other.clockFreqSF && + collectionStartTime == other.collectionStartTime && + rangeBiasDecorr == other.rangeBiasDecorr; + } + bool operator!=(const RadarSensor& other) const + { + return !((*this) == other); + } + + //! Range bias error standard deviation. + double rangeBias; + + //! (Optional) Payload clock frequency scale factor standard deviation + double clockFreqSF; + + //! (Optional) Collection Start time error standard deviation + double collectionStartTime; + + //! (Optional) Range Bias error decorrelation function + mem::ScopedCopyablePtr rangeBiasDecorr; + }; + + //! Equality operators + bool operator==(const Monostatic& other) const + { + return posVelErr == other.posVelErr && + radarSensor == other.radarSensor && + tropoError == other.tropoError && + ionoError == other.ionoError && + parameter == other.parameter; + } + bool operator!=(const Monostatic& other) const + { + return !((*this) == other); + } + + //! Position and velocity error statistics for the + //! Transmit platform. + six::PosVelError posVelErr; + + //! Radar sensor error statistics + RadarSensor radarSensor; + + //! (Optional) Error parameters related to the Troposphere + mem::ScopedCopyablePtr tropoError; + + //! (Optional) Error parameters related to the Ionosphere + mem::ScopedCopyablePtr ionoError; + + //! (Optional) Additional error parameters to be added for + //! Monostatic collections + six::ParameterCollection parameter; + }; + + /* + * \struct Bistatic + * + * \brief (Conditional) Parameters for CollectType = "BISTATIC" + */ + struct Bistatic final + { + /* + * \struct RadarSensor + * + * \brief Error statistics for the Transmit platform + */ + struct RadarSensor final + { + //! Constructor + RadarSensor(); + + //! Equality operators + bool operator==(const RadarSensor& other) const + { + return (delayBias == other.delayBias) + && (clockFreqSF == other.clockFreqSF) + && (collectionStartTime == other.collectionStartTime); + } + bool operator!=(const RadarSensor& other) const + { + return !((*this) == other); + } + + //! Transmit time delay bias error standard deviation + six::XsElement_minOccurs0 delayBias{ "DelayBias" }; // new in CPHD 1.1.0 + + //! (Optional) Payload clock frequency scale factor standard deviation + double clockFreqSF; + + //! Collection Start time error standard deviation. + double collectionStartTime; + }; + + /* + * \struct Platform + * + * \brief Error statisitcs of platforms + */ + struct Platform + { + //! Equality operators + bool operator==(const Platform& other) const + { + return posVelErr == other.posVelErr && + radarSensor == other.radarSensor; + } + bool operator!=(const Platform& other) const + { + return !((*this) == other); + } + + //! Position and velocity error statistics + six::PosVelError posVelErr; + + //! Transmit sensor error statistics + RadarSensor radarSensor; + }; + + //! Equality operators + bool operator==(const Bistatic& other) const + { + return txPlatform == other.txPlatform && + rcvPlatform == other.rcvPlatform && + parameter == other.parameter; + } + bool operator!=(const Bistatic& other) const + { + return !((*this) == other); + } + + //! Error statistics for the Transmit platform + Platform txPlatform; + + //! Error statistics for the Receive Only platform. + Platform rcvPlatform; + + //! Additional error parameters to be added for + //! Bistatic collections + six::ParameterCollection parameter; + }; + + //! Equality operators + bool operator==(const ErrorParameters& other) const + { + return monostatic == other.monostatic && + bistatic == other.bistatic; + } + bool operator!=(const ErrorParameters& other) const + { + return !((*this) == other); + } + + //! (Conditional) Parameters for CollectType = "MONOSTATIC" + mem::ScopedCopyablePtr monostatic; + + //! (Conditional) Parameters for CollectType = "BISTATIC" + mem::ScopedCopyablePtr bistatic; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const six::PosVelError& p); +std::ostream& operator<< (std::ostream& os, const ErrorParameters& e); +} + +#endif // SIX_cphd_ErrorParameters_h_INCLUDED_ diff --git a/six/modules/c++/cphd/include/cphd/MetadataBase.h b/six/modules/c++/cphd/include/cphd/MetadataBase.h index abdac611bc..5852887e5f 100644 --- a/six/modules/c++/cphd/include/cphd/MetadataBase.h +++ b/six/modules/c++/cphd/include/cphd/MetadataBase.h @@ -1,111 +1,111 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_METADATA_BASE_H__ -#define __CPHD_METADATA_BASE_H__ - -#include -#include -#include - -namespace cphd -{ -/*! - * \class MetadataBase - * \brief Abstract base class for the CPHD and CPHD03 Metdata objects. - * - * The metadata object is derived for CPHD and CPHD03 - *. This class provides the interface needed - * to interact with the signal block reader Wideband, currently in CPHD - * - */ -struct MetadataBase -{ - //! Default constructor - MetadataBase() - { - } - - //! Destructor - virtual ~MetadataBase() - { - } - - /* - * Getter functions - */ - virtual size_t getNumChannels() const = 0; - virtual size_t getNumVectors(size_t channel) const = 0; // 0-based channel number - virtual size_t getNumSamples(size_t channel) const = 0; // 0-based channel number - virtual size_t getNumBytesPerSample() const = 0; // 2, 4, or 8 bytes/complex sample - - /* - * \func getCompressedSignalSize - * \brief Gets the size of compressed signal array - * if applicable - * - * This function returns default value. Can be overridden - * if required (Ex: CPHD::Metadata) - * - * \return undefined value by default - */ - virtual size_t getCompressedSignalSize(size_t /*channel*/) const - { - return six::Init::undefined(); - } - - /* - * \func isCompressed - * \brief Check if signal data is compressed - * - * This function returns default value false. Function can - * be overridden if required (Ex: CPHD::Metadata) - * - * \return false by default - */ - virtual bool isCompressed() const - { - return false; - } - - /*! - * Get domain type - * FX for frequency domain, - * TOA for time-of-arrival domain - */ - virtual DomainType getDomainType() const = 0; - - //! Is this CPHD formed in the transmit frequency domain? - bool isFX() const - { - return (getDomainType() == cphd::DomainType::FX); - } - - //! Is this CPHD formed in the Time of Arrival domain? - bool isTOA() const - { - return (getDomainType() == cphd::DomainType::TOA); - } -}; -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_METADATA_BASE_H__ +#define __CPHD_METADATA_BASE_H__ + +#include +#include +#include + +namespace cphd +{ +/*! + * \class MetadataBase + * \brief Abstract base class for the CPHD and CPHD03 Metdata objects. + * + * The metadata object is derived for CPHD and CPHD03 + *. This class provides the interface needed + * to interact with the signal block reader Wideband, currently in CPHD + * + */ +struct MetadataBase +{ + //! Default constructor + MetadataBase() + { + } + + //! Destructor + virtual ~MetadataBase() + { + } + + /* + * Getter functions + */ + virtual size_t getNumChannels() const = 0; + virtual size_t getNumVectors(size_t channel) const = 0; // 0-based channel number + virtual size_t getNumSamples(size_t channel) const = 0; // 0-based channel number + virtual size_t getNumBytesPerSample() const = 0; // 2, 4, or 8 bytes/complex sample + + /* + * \func getCompressedSignalSize + * \brief Gets the size of compressed signal array + * if applicable + * + * This function returns default value. Can be overridden + * if required (Ex: CPHD::Metadata) + * + * \return undefined value by default + */ + virtual size_t getCompressedSignalSize(size_t /*channel*/) const + { + return six::Init::undefined(); + } + + /* + * \func isCompressed + * \brief Check if signal data is compressed + * + * This function returns default value false. Function can + * be overridden if required (Ex: CPHD::Metadata) + * + * \return false by default + */ + virtual bool isCompressed() const + { + return false; + } + + /*! + * Get domain type + * FX for frequency domain, + * TOA for time-of-arrival domain + */ + virtual DomainType getDomainType() const = 0; + + //! Is this CPHD formed in the transmit frequency domain? + bool isFX() const + { + return (getDomainType() == cphd::DomainType::FX); + } + + //! Is this CPHD formed in the Time of Arrival domain? + bool isTOA() const + { + return (getDomainType() == cphd::DomainType::TOA); + } +}; +} + +#endif diff --git a/six/modules/c++/cphd/include/cphd/PVP.h b/six/modules/c++/cphd/include/cphd/PVP.h index f19341303c..d302b60a8c 100644 --- a/six/modules/c++/cphd/include/cphd/PVP.h +++ b/six/modules/c++/cphd/include/cphd/PVP.h @@ -1,612 +1,612 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#pragma once -#ifndef SIX_cphd_PVP_h_INCLUDED_ -#define SIX_cphd_PVP_h_INCLUDED_ - -#include - -#include -#include -#include - -#include -#include -#include -#include -#include - -#include "cphd/Types.h" - -namespace cphd -{ - -/*! - * \struct PVPType - * - * \brief Specifies a defined Per Vector Parameter. - * - * Size and Offset specify the size and placement of - * the binary parameter in the set of Per Vector - * parameters provided for each vector. - */ -struct PVPType -{ - static constexpr size_t WORD_BYTE_SIZE = 8; - - /*! - * \func PVPType - * - * \brief Default constructor - */ - PVPType(); - - //! Equality operators - bool operator==(const PVPType& other) const - { - return mSize == other.getSize() && - mOffset == other.getOffset() && - mFormat == other.getFormat(); - } - bool operator!=(const PVPType& other) const - { - return !((*this) == other); - } - - //! Setter Functions - void setOffset(size_t offset) - { - mOffset = offset; - } - void setSize(size_t size) - { - mSize = size; - } - void setFormat(const std::string& format) - { - mFormat = format; - } - - //! Get size - size_t getSize() const - { - return mSize; - } - //! Get size in bytes - size_t getByteSize() const - { - return mSize * WORD_BYTE_SIZE; - } - //! Get offset - size_t getOffset() const - { - return mOffset; - } - - //! Get offset in bytes - size_t getByteOffset() const - { - return mOffset * WORD_BYTE_SIZE; - } - - //! Get format - std::string getFormat() const - { - return mFormat; - } - -protected: - //! Size of parameter - XsPositiveInteger_fixed2 mSize; // txACX{ "TxACX" }; - - //! TxACY PVP Structure - six::XsElement txACY{ "TxACY" }; - - //! TxEB PVP Structure - six::XsElement txEB{ "TxEB" }; -}; - -/*! - * \struct RcvAntenna - * \brief Specify the Receive Antenna orientation and the Steering vector. - * - * Parameters included that specify the Receive Antenna ACF orientation and the EB Steering vector. - * (New in CPHD 1.1.0) - */ -struct RcvAntenna final -{ - bool operator==(const RcvAntenna& other) const - { - return (rcvACX == other.rcvACX) - && (rcvACY == other.rcvACY) - && (rcvEB == other.rcvEB); - } - bool operator!=(const RcvAntenna& other) const - { - return !((*this) == other); - } - - //! RcvACX PVP Structure - six::XsElement rcvACX{ "RcvACX" }; - - //! RcvACY PVP Structure - six::XsElement rcvACY{ "RcvACY" }; - - //! RcvEB PVP Structure - six::XsElement rcvEB{ "RcvEB" }; -}; - -/*! - * \struct Pvp - * - * \brief Structure used to specify the Per Vector - * parameters - * - * Provided for each channel of a given product. - */ -struct Pvp final -{ - /*! - * Transmit time for the center of the transmitted pulse relative to the - * transmit platform Collection Start Time (sec). - */ - PVPType txTime; - - /*! - * Transmit APC position at time txc(v) in Earth Centered Fixed - * (ECF) coordinates (meters). Components in X, Y, Z order. - * 3 8-byte floats required. - */ - PVPType txPos; - - /*! - * Transmit APC velocity at time txc(v) in ECF coordinates - * (meters/sec). - * 3 8-byte floats required. - */ - PVPType txVel; - - /*! - * Receive time for the center of the echo from the srp relative to the - * transmit platform Collection Start Time (sec). Time is the Time of - * Arrival (toa) of the received echo from the srp for the signal - * transmitted at txc(v). - */ - PVPType rcvTime; - - - /*! - * Receive APC position at time trc(v)srp in ECF coordinates - * (meters). - * 3 8-byte floats required. - */ - PVPType rcvPos; - - /*! - * Receive APC velocity at time trc(v)srp in ECF coordinates - * (meters/sec). - * 3 8-byte floats required - */ - PVPType rcvVel; - - /*! - * Stabilization Reference Point (srp) position in ECF coordinates - * (meters). - * 3 8-byte floats required. - */ - PVPType srpPos; - - /*! - * (Optional) Amplitude scale Factor to be applied to all samples of the signal - * vector. For signal vector v, each sample value is multiplied by - * Amp_SF(v) to yield the proper sample values for the vector. - */ - PVPType ampSF; - - /*! - * The DOPPLER shift micro parameter. Parameter accounts for the - * time dilation/Doppler shift for the echoes from all targets with the - * same time dilation/Doppler shift as the srp echo. - */ - PVPType aFDOP; - - /*! - * First order phase micro parameter (i.e. linear phase). Accounts for - * linear phase vs. FX frequency for targets with time - * dilation/Doppler shift different than the echo from the srp. - * Provides precise linear phase prediction for Linear FM waveforms. - */ - PVPType aFRR1; - - /*! - * Second order phase micro parameter (i.e. quadratic phase). - * Accounts for quadratic phase vs. FX frequency for targets with - * time dilation/Doppler shift different than the echo from the srp. - * Provides precise quadratic phase prediction for Linear FM - * waveforms. - */ - PVPType aFRR2; - - /*! - * The FX domain frequency limits of the transmitted waveform - * retained in the signal vector (Hz). - * Saved transmit band is from fx_1(v) < fx < fx_2(v) - * For the vector: FX_BW(v) = fx_2(v) – fx_1(v) - */ - PVPType fx1; - - /*! - * The FX domain frequency limits of the transmitted waveform - * retained in the signal vector (Hz). - * Saved transmit band is from fx_1(v) < fx < fx_2(v) - * For the vector: FX_BW(v) = fx_2(v) – fx_1(v) - */ - PVPType fx2; - - /*! - * (Optional) The FX domain frequency limits for out-of-band noise signal for - * frequencies below fx_1(v) and above fx_2(v). May ONLY be - * included for Domain_Type = FX. - * For any vector: fx_N1 < fx_1 & fx_2 < fx_N2 - * When included in a product, fx_N1 & fx_N2 are both included. - */ - PVPType fxN1; - - /*! - * (Optional) The FX domain frequency limits for out-of-band noise signal for - * frequencies below fx_1(v) and above fx_2(v). May ONLY be - * included for Domain_Type = FX. - * For any vector: fx_N1 < fx_1 & fx_2 < fx_N2 - * When included in a product, fx_N1 & fx_N2 are both included. - */ - PVPType fxN2; - - /*! - * The change in toa limits for the full resolution echoes retained in the - * signal vector (sec). Full resolution echoes are formed with - * FX_BW(v) saved bandwidth. - * Full resolution toa limits: Dtoa_1 < Dtoa < Dtoa_2 - */ - PVPType toa1; - - /*! - * The change in toa limits for the full resolution echoes retained in the - * signal vector (sec). Full resolution echoes are formed with - * FX_BW(v) saved bandwidth. - * Full resolution toa limits: Dtoa_1 < Dtoa < Dtoa_2 - */ - PVPType toa2; - - /*! - * (Optional) The TOA limits for all echoes retained in the signal vector (sec). - */ - PVPType toaE1; - - /*! - * (Optional) The TOA limits for all echoes retained in the signal vector (sec). - */ - PVPType toaE2; - - /*! - * Two-way time delay due to the troposphere (sec) that was added - * when computing the propagation time for the SRP - */ - PVPType tdTropoSRP; - - /*! - * (Optional) Two-way time delay due to the ionosphere (sec) that was added - * when computing the propagation time for the SRP - */ - PVPType tdIonoSRP; - - /*! - * FX DOMAIN & TOA DOMAIN: The domain signal vector coordinate value for - * sample s = 0 (Hz). - */ - PVPType sc0; - - /*! - * FX DOMAIN & TOA DOMAIN: The domain signal vector coordinate value for - * signal coordinate sample spacing (Hz). - */ - PVPType scss; - - /*! - * (Optional) Integer parameter that may be included to indicate the signal - * content for some vectors is known or is likely to be distorted. - */ - PVPType signal; - - //! (Optional) Parameters included that specify the Transmit Antenna ACF orientation and the EB Steering vector - six::XsElement_minOccurs0 txAntenna{ "TxAntenna" }; // new in CPHD 1.1.0 - - //! (Optional) Parameters included that specify the Receive Antenna ACF orientation and the EB Steering vector - six::XsElement_minOccurs0 rcvAntenna{ "RcvAntenna" }; // new in CPHD 1.1.0 - - /* - * (Optional) User defined PV parameters - */ - std::map addedPVP; - - /* - * \func Constructor - * \brief Initialize default values for each parameter - * - */ - Pvp(); - - //! Equality operators - bool operator==(const Pvp& other) const - { - return txTime == other.txTime && txPos == other.txPos && - txVel == other.txVel && rcvTime == other.rcvTime && - rcvPos == other.rcvPos && rcvVel == other.rcvVel && - srpPos == other.srpPos && aFDOP == other.aFDOP && - aFRR1 == other.aFRR1 && aFRR2 == other.aFRR2 && - fx1 == other.fx1 && fx2 == other.fx2 && - toa1 == other.toa1 && toa2 == other.toa2 && - tdTropoSRP == other.tdTropoSRP && sc0 == other.sc0 && - scss == other.scss && - ampSF == other.ampSF && fxN1 == other. fxN1 && - fxN2 == other.fxN2 && toaE1 == other.toaE1 && - toaE2 == other.toaE2 && tdIonoSRP == other.tdIonoSRP && - signal == other.signal - && txAntenna == other.txAntenna - && rcvAntenna == other.rcvAntenna - && addedPVP == other.addedPVP; - } - bool operator!=(const Pvp& other) const - { - return !((*this) == other); - } - - //! Get size of pvp set in blocks - size_t getReqSetSize() const; - - //! Get total byte size of pvp set - size_t sizeInBytes() const; - - /* - * \func setOffset - * - * \brief Validate and set the offset of parameters - * - * \param offset The offset of the parameter to be expected for the param - * \param[out] param The PVPType parameter that should be set - * - * \throws except::Exception If param offset or size overlaps another parameter, or - * if format is invalid - */ - void setOffset(size_t offset, PVPType& param); - - /* - * \func append - * - * \brief Validate and append parameter to the next available block - * - * \param[out] param The PVPType parameter that should be set - * - * \throws except::Exception If param offset or size overlaps another parameter, or - * if format is invalid - */ - void append(PVPType& param); - - /* - * \func setParameter - * - * \brief Validate and set the metadata of an additional parameter identified by name - * - * \param size The size of the parameter to be expected for the param - * \param offset The offset of the parameter to be expected for the param - * \param format The string format of the parameter to be expected for the param - * \param name The unique identifier of the additional parameter that should be set - * - * \throws except::Exception If param offset or size overlaps another parameter, - * if format is invalid or if name is not unique - */ - void setCustomParameter(size_t size, size_t offset, const std::string& format, const std::string& name); - - /* - * \func setCustomParameter - * - * \brief Validate and append additional parameter to the next available block - * - * \param size The size of the parameter to be expected for the param - * \param format The string format of the parameter to be expected for the param - * \param name The unique identifier of the additional parameter that should be set - * - * \throws except::Exception If param offset or size overlaps another parameter, - * if format is invalid or if name is not unique - */ - void appendCustomParameter(size_t size, const std::string& format, const std::string& name); - -private: - /* - * Validate parameter size and offset when setting parameter - */ - void validate(size_t size, size_t offset); - - /* - * Marks filled bytes - */ - std::vector mParamLocations; - - /* - * Set default size and format for each parameter - */ - void setDefaultValues(size_t size, const std::string& format, PVPType& param); - - /* - * Initializes default size and format for parameters - */ - void initialize(); -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const PVPType& p); -std::ostream& operator<< (std::ostream& os, const APVPType& a); -std::ostream& operator<< (std::ostream& os, const Pvp& p); -} -#endif // SIX_cphd_PVP_h_INCLUDED_ +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#pragma once +#ifndef SIX_cphd_PVP_h_INCLUDED_ +#define SIX_cphd_PVP_h_INCLUDED_ + +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "cphd/Types.h" + +namespace cphd +{ + +/*! + * \struct PVPType + * + * \brief Specifies a defined Per Vector Parameter. + * + * Size and Offset specify the size and placement of + * the binary parameter in the set of Per Vector + * parameters provided for each vector. + */ +struct PVPType +{ + static constexpr size_t WORD_BYTE_SIZE = 8; + + /*! + * \func PVPType + * + * \brief Default constructor + */ + PVPType(); + + //! Equality operators + bool operator==(const PVPType& other) const + { + return mSize == other.getSize() && + mOffset == other.getOffset() && + mFormat == other.getFormat(); + } + bool operator!=(const PVPType& other) const + { + return !((*this) == other); + } + + //! Setter Functions + void setOffset(size_t offset) + { + mOffset = offset; + } + void setSize(size_t size) + { + mSize = size; + } + void setFormat(const std::string& format) + { + mFormat = format; + } + + //! Get size + size_t getSize() const + { + return mSize; + } + //! Get size in bytes + size_t getByteSize() const + { + return mSize * WORD_BYTE_SIZE; + } + //! Get offset + size_t getOffset() const + { + return mOffset; + } + + //! Get offset in bytes + size_t getByteOffset() const + { + return mOffset * WORD_BYTE_SIZE; + } + + //! Get format + std::string getFormat() const + { + return mFormat; + } + +protected: + //! Size of parameter + XsPositiveInteger_fixed2 mSize; // txACX{ "TxACX" }; + + //! TxACY PVP Structure + six::XsElement txACY{ "TxACY" }; + + //! TxEB PVP Structure + six::XsElement txEB{ "TxEB" }; +}; + +/*! + * \struct RcvAntenna + * \brief Specify the Receive Antenna orientation and the Steering vector. + * + * Parameters included that specify the Receive Antenna ACF orientation and the EB Steering vector. + * (New in CPHD 1.1.0) + */ +struct RcvAntenna final +{ + bool operator==(const RcvAntenna& other) const + { + return (rcvACX == other.rcvACX) + && (rcvACY == other.rcvACY) + && (rcvEB == other.rcvEB); + } + bool operator!=(const RcvAntenna& other) const + { + return !((*this) == other); + } + + //! RcvACX PVP Structure + six::XsElement rcvACX{ "RcvACX" }; + + //! RcvACY PVP Structure + six::XsElement rcvACY{ "RcvACY" }; + + //! RcvEB PVP Structure + six::XsElement rcvEB{ "RcvEB" }; +}; + +/*! + * \struct Pvp + * + * \brief Structure used to specify the Per Vector + * parameters + * + * Provided for each channel of a given product. + */ +struct Pvp final +{ + /*! + * Transmit time for the center of the transmitted pulse relative to the + * transmit platform Collection Start Time (sec). + */ + PVPType txTime; + + /*! + * Transmit APC position at time txc(v) in Earth Centered Fixed + * (ECF) coordinates (meters). Components in X, Y, Z order. + * 3 8-byte floats required. + */ + PVPType txPos; + + /*! + * Transmit APC velocity at time txc(v) in ECF coordinates + * (meters/sec). + * 3 8-byte floats required. + */ + PVPType txVel; + + /*! + * Receive time for the center of the echo from the srp relative to the + * transmit platform Collection Start Time (sec). Time is the Time of + * Arrival (toa) of the received echo from the srp for the signal + * transmitted at txc(v). + */ + PVPType rcvTime; + + + /*! + * Receive APC position at time trc(v)srp in ECF coordinates + * (meters). + * 3 8-byte floats required. + */ + PVPType rcvPos; + + /*! + * Receive APC velocity at time trc(v)srp in ECF coordinates + * (meters/sec). + * 3 8-byte floats required + */ + PVPType rcvVel; + + /*! + * Stabilization Reference Point (srp) position in ECF coordinates + * (meters). + * 3 8-byte floats required. + */ + PVPType srpPos; + + /*! + * (Optional) Amplitude scale Factor to be applied to all samples of the signal + * vector. For signal vector v, each sample value is multiplied by + * Amp_SF(v) to yield the proper sample values for the vector. + */ + PVPType ampSF; + + /*! + * The DOPPLER shift micro parameter. Parameter accounts for the + * time dilation/Doppler shift for the echoes from all targets with the + * same time dilation/Doppler shift as the srp echo. + */ + PVPType aFDOP; + + /*! + * First order phase micro parameter (i.e. linear phase). Accounts for + * linear phase vs. FX frequency for targets with time + * dilation/Doppler shift different than the echo from the srp. + * Provides precise linear phase prediction for Linear FM waveforms. + */ + PVPType aFRR1; + + /*! + * Second order phase micro parameter (i.e. quadratic phase). + * Accounts for quadratic phase vs. FX frequency for targets with + * time dilation/Doppler shift different than the echo from the srp. + * Provides precise quadratic phase prediction for Linear FM + * waveforms. + */ + PVPType aFRR2; + + /*! + * The FX domain frequency limits of the transmitted waveform + * retained in the signal vector (Hz). + * Saved transmit band is from fx_1(v) < fx < fx_2(v) + * For the vector: FX_BW(v) = fx_2(v) – fx_1(v) + */ + PVPType fx1; + + /*! + * The FX domain frequency limits of the transmitted waveform + * retained in the signal vector (Hz). + * Saved transmit band is from fx_1(v) < fx < fx_2(v) + * For the vector: FX_BW(v) = fx_2(v) – fx_1(v) + */ + PVPType fx2; + + /*! + * (Optional) The FX domain frequency limits for out-of-band noise signal for + * frequencies below fx_1(v) and above fx_2(v). May ONLY be + * included for Domain_Type = FX. + * For any vector: fx_N1 < fx_1 & fx_2 < fx_N2 + * When included in a product, fx_N1 & fx_N2 are both included. + */ + PVPType fxN1; + + /*! + * (Optional) The FX domain frequency limits for out-of-band noise signal for + * frequencies below fx_1(v) and above fx_2(v). May ONLY be + * included for Domain_Type = FX. + * For any vector: fx_N1 < fx_1 & fx_2 < fx_N2 + * When included in a product, fx_N1 & fx_N2 are both included. + */ + PVPType fxN2; + + /*! + * The change in toa limits for the full resolution echoes retained in the + * signal vector (sec). Full resolution echoes are formed with + * FX_BW(v) saved bandwidth. + * Full resolution toa limits: Dtoa_1 < Dtoa < Dtoa_2 + */ + PVPType toa1; + + /*! + * The change in toa limits for the full resolution echoes retained in the + * signal vector (sec). Full resolution echoes are formed with + * FX_BW(v) saved bandwidth. + * Full resolution toa limits: Dtoa_1 < Dtoa < Dtoa_2 + */ + PVPType toa2; + + /*! + * (Optional) The TOA limits for all echoes retained in the signal vector (sec). + */ + PVPType toaE1; + + /*! + * (Optional) The TOA limits for all echoes retained in the signal vector (sec). + */ + PVPType toaE2; + + /*! + * Two-way time delay due to the troposphere (sec) that was added + * when computing the propagation time for the SRP + */ + PVPType tdTropoSRP; + + /*! + * (Optional) Two-way time delay due to the ionosphere (sec) that was added + * when computing the propagation time for the SRP + */ + PVPType tdIonoSRP; + + /*! + * FX DOMAIN & TOA DOMAIN: The domain signal vector coordinate value for + * sample s = 0 (Hz). + */ + PVPType sc0; + + /*! + * FX DOMAIN & TOA DOMAIN: The domain signal vector coordinate value for + * signal coordinate sample spacing (Hz). + */ + PVPType scss; + + /*! + * (Optional) Integer parameter that may be included to indicate the signal + * content for some vectors is known or is likely to be distorted. + */ + PVPType signal; + + //! (Optional) Parameters included that specify the Transmit Antenna ACF orientation and the EB Steering vector + six::XsElement_minOccurs0 txAntenna{ "TxAntenna" }; // new in CPHD 1.1.0 + + //! (Optional) Parameters included that specify the Receive Antenna ACF orientation and the EB Steering vector + six::XsElement_minOccurs0 rcvAntenna{ "RcvAntenna" }; // new in CPHD 1.1.0 + + /* + * (Optional) User defined PV parameters + */ + std::map addedPVP; + + /* + * \func Constructor + * \brief Initialize default values for each parameter + * + */ + Pvp(); + + //! Equality operators + bool operator==(const Pvp& other) const + { + return txTime == other.txTime && txPos == other.txPos && + txVel == other.txVel && rcvTime == other.rcvTime && + rcvPos == other.rcvPos && rcvVel == other.rcvVel && + srpPos == other.srpPos && aFDOP == other.aFDOP && + aFRR1 == other.aFRR1 && aFRR2 == other.aFRR2 && + fx1 == other.fx1 && fx2 == other.fx2 && + toa1 == other.toa1 && toa2 == other.toa2 && + tdTropoSRP == other.tdTropoSRP && sc0 == other.sc0 && + scss == other.scss && + ampSF == other.ampSF && fxN1 == other. fxN1 && + fxN2 == other.fxN2 && toaE1 == other.toaE1 && + toaE2 == other.toaE2 && tdIonoSRP == other.tdIonoSRP && + signal == other.signal + && txAntenna == other.txAntenna + && rcvAntenna == other.rcvAntenna + && addedPVP == other.addedPVP; + } + bool operator!=(const Pvp& other) const + { + return !((*this) == other); + } + + //! Get size of pvp set in blocks + size_t getReqSetSize() const; + + //! Get total byte size of pvp set + size_t sizeInBytes() const; + + /* + * \func setOffset + * + * \brief Validate and set the offset of parameters + * + * \param offset The offset of the parameter to be expected for the param + * \param[out] param The PVPType parameter that should be set + * + * \throws except::Exception If param offset or size overlaps another parameter, or + * if format is invalid + */ + void setOffset(size_t offset, PVPType& param); + + /* + * \func append + * + * \brief Validate and append parameter to the next available block + * + * \param[out] param The PVPType parameter that should be set + * + * \throws except::Exception If param offset or size overlaps another parameter, or + * if format is invalid + */ + void append(PVPType& param); + + /* + * \func setParameter + * + * \brief Validate and set the metadata of an additional parameter identified by name + * + * \param size The size of the parameter to be expected for the param + * \param offset The offset of the parameter to be expected for the param + * \param format The string format of the parameter to be expected for the param + * \param name The unique identifier of the additional parameter that should be set + * + * \throws except::Exception If param offset or size overlaps another parameter, + * if format is invalid or if name is not unique + */ + void setCustomParameter(size_t size, size_t offset, const std::string& format, const std::string& name); + + /* + * \func setCustomParameter + * + * \brief Validate and append additional parameter to the next available block + * + * \param size The size of the parameter to be expected for the param + * \param format The string format of the parameter to be expected for the param + * \param name The unique identifier of the additional parameter that should be set + * + * \throws except::Exception If param offset or size overlaps another parameter, + * if format is invalid or if name is not unique + */ + void appendCustomParameter(size_t size, const std::string& format, const std::string& name); + +private: + /* + * Validate parameter size and offset when setting parameter + */ + void validate(size_t size, size_t offset); + + /* + * Marks filled bytes + */ + std::vector mParamLocations; + + /* + * Set default size and format for each parameter + */ + void setDefaultValues(size_t size, const std::string& format, PVPType& param); + + /* + * Initializes default size and format for parameters + */ + void initialize(); +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const PVPType& p); +std::ostream& operator<< (std::ostream& os, const APVPType& a); +std::ostream& operator<< (std::ostream& os, const Pvp& p); +} +#endif // SIX_cphd_PVP_h_INCLUDED_ diff --git a/six/modules/c++/cphd/include/cphd/ProductInfo.h b/six/modules/c++/cphd/include/cphd/ProductInfo.h index bb520e7cd3..6abef48c6e 100644 --- a/six/modules/c++/cphd/include/cphd/ProductInfo.h +++ b/six/modules/c++/cphd/include/cphd/ProductInfo.h @@ -1,117 +1,117 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_PRODUCT_INFO_H__ -#define __CPHD_PRODUCT_INFO_H__ - -#include -#include -#include - -#include -#include - -namespace cphd -{ -/* - * \struct ProductInfo - * - * \brief Contains product information - * - * (Optional) Parameters that provide general information about the - * CPHD product and/or the derived products that may be created from it - */ -struct ProductInfo -{ - /* - * \struct CreationInfo - * - * \brief Contains creation information - * - * (Optional) Parameters that provide general information about - * the CPHD product generation - */ - struct CreationInfo - { - //! Constructor - CreationInfo(); - - //! Equality operators - bool operator==(const CreationInfo& other) const - { - return application == other.application && - dateTime == other.dateTime && site == other.site && - parameter == other.parameter; - } - bool operator!=(const CreationInfo& other) const - { - return !((*this) == other); - } - - //! (Optional) Name and version of the applications that created - //! the CPHD product - std::string application; - - //! Date and time the CPHD product was created (UTC). - DateTime dateTime; - - //! (Optional) Name of the site where the product was created - std::string site; - - //! (Optional) Text field that can be used for program specific - //! name and value - six::ParameterCollection parameter; - }; - - //! Constructor - ProductInfo(); - - //! Equality operators - bool operator==(const ProductInfo& other) const - { - return profile == other.profile && - creationInfo == other.creationInfo && - parameter == other.parameter; - } - bool operator!=(const ProductInfo& other) const - { - return !((*this) == other); - } - - //! (Optional) Identifies what profile was used to create this - //! CPHD product - std::string profile; - - //! (Optional) Parameters that provide general information - //! about the CPHD product generation. - std::vector creationInfo; - - //! (Optional) Text field that can be used for program specific - //! parameter name & value - six::ParameterCollection parameter; -}; - -//! Ostream operator -std::ostream& operator<< (std::ostream& os, const ProductInfo& p); -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_PRODUCT_INFO_H__ +#define __CPHD_PRODUCT_INFO_H__ + +#include +#include +#include + +#include +#include + +namespace cphd +{ +/* + * \struct ProductInfo + * + * \brief Contains product information + * + * (Optional) Parameters that provide general information about the + * CPHD product and/or the derived products that may be created from it + */ +struct ProductInfo +{ + /* + * \struct CreationInfo + * + * \brief Contains creation information + * + * (Optional) Parameters that provide general information about + * the CPHD product generation + */ + struct CreationInfo + { + //! Constructor + CreationInfo(); + + //! Equality operators + bool operator==(const CreationInfo& other) const + { + return application == other.application && + dateTime == other.dateTime && site == other.site && + parameter == other.parameter; + } + bool operator!=(const CreationInfo& other) const + { + return !((*this) == other); + } + + //! (Optional) Name and version of the applications that created + //! the CPHD product + std::string application; + + //! Date and time the CPHD product was created (UTC). + DateTime dateTime; + + //! (Optional) Name of the site where the product was created + std::string site; + + //! (Optional) Text field that can be used for program specific + //! name and value + six::ParameterCollection parameter; + }; + + //! Constructor + ProductInfo(); + + //! Equality operators + bool operator==(const ProductInfo& other) const + { + return profile == other.profile && + creationInfo == other.creationInfo && + parameter == other.parameter; + } + bool operator!=(const ProductInfo& other) const + { + return !((*this) == other); + } + + //! (Optional) Identifies what profile was used to create this + //! CPHD product + std::string profile; + + //! (Optional) Parameters that provide general information + //! about the CPHD product generation. + std::vector creationInfo; + + //! (Optional) Text field that can be used for program specific + //! parameter name & value + six::ParameterCollection parameter; +}; + +//! Ostream operator +std::ostream& operator<< (std::ostream& os, const ProductInfo& p); +} + +#endif diff --git a/six/modules/c++/cphd/include/cphd/ReferenceGeometry.h b/six/modules/c++/cphd/include/cphd/ReferenceGeometry.h index 13d73968ad..4bccc9203b 100644 --- a/six/modules/c++/cphd/include/cphd/ReferenceGeometry.h +++ b/six/modules/c++/cphd/include/cphd/ReferenceGeometry.h @@ -1,350 +1,350 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_REFERENCE_GEOMETRY_H__ -#define __CPHD_REFERENCE_GEOMETRY_H__ - -#include - -#include -#include -#include - -namespace cphd -{ - -/*! - * \struct SRP - * - * \brief The SRP position for the reference vector of the - * reference channel - */ -struct SRP -{ - //! Constructor - SRP(); - - //! Equality operator - bool operator==(const SRP& other) const - { - return ecf == other.ecf && iac == other.iac; - } - bool operator!=(const SRP& other) const - { - return !((*this) == other); - } - - //! SRP position in ECF coordinates. Value - //! included in the SRPPos PVP - Vector3 ecf; - - //! SRP position in Image Area Coordinates (IAX, - //! IAY, IAZ). - Vector3 iac; -}; - -/*! - * \struct ImagingType - * - * \brief Base class for both Monostatic and - * Bistatic imaging types - */ -struct ImagingType -{ - //! Constructor - ImagingType(); - - //! Equality operators - bool operator==(const ImagingType& other) const - { - return azimuthAngle == other.azimuthAngle && - grazeAngle == other.grazeAngle && - twistAngle == other.twistAngle && - slopeAngle == other.slopeAngle && - layoverAngle == other.layoverAngle; - } - bool operator!=(const ImagingType& other) const - { - return !((*this) == other); - } - - //! Destructor - virtual ~ImagingType() {} - - //! Angle from north to the line from the SRP to the - //! ARP ETP Nadir (i.e. North to +GPX). Measured - //! clockwise from +North toward +East. - double azimuthAngle; - - //! Grazing angle for the ARP to SRP LOS and the - //! Earth Tangent Plane (ETP) at the SRP. - double grazeAngle; - - //! Twist angle between cross range in the ETP and - //! cross range in the slant plane at the SRP - double twistAngle; - - //! Angle between the ETP normal (uUP) and the - //! slant plane normal (uSPN) at the SRP - double slopeAngle; - - //! Angle from north to the layover direction in the - //! ETP. Measured clockwise from +North toward - //! +East - double layoverAngle; -}; - -/*! - * \struct Monostatic - * - * \brief (Conditional) Collection Type Monostatic metadata. - * - * Single radar platform that is both the transmitter - * and the receiver - */ -struct Monostatic : public ImagingType -{ - //! Constructor - Monostatic(); - - //! Equality operators - bool operator==(const Monostatic& other) const - { - if((ImagingType)(*this) != (ImagingType)other) { - return false; - } - - return sideOfTrack == other.sideOfTrack && - slantRange == other.slantRange && - groundRange == other.groundRange && - dopplerConeAngle == other.dopplerConeAngle && - incidenceAngle == other.incidenceAngle && - arpPos == other.arpPos && arpVel == other.arpVel; - } - bool operator!=(const Monostatic& other) const - { - return !((*this) == other); - } - - //! Side of Track parameter for the collection. - //! L Left-looking or R Right-looking - six::SideOfTrackType sideOfTrack; - - //! Slant range from the ARP to the SRP - double slantRange; - - //! Ground range from the ARP nadir to the SRP. - //! Distance measured along spherical earth model - //! passing through the SRP. - double groundRange; - - //! Doppler Cone Angle between ARP velocity and - //! SRP Line of Sight (LOS). - double dopplerConeAngle; - - //! Incidence angle for the ARP to SRP LOS and the - //! Earth Tangent Plane (ETP) at the SRP - double incidenceAngle; - - //! ARP position in ECF coordinates (ARP) - Vector3 arpPos; - - //! ARP velocity in ECF coordinates (VARP). - Vector3 arpVel; -}; - -/*! - * \struct Bistatic - * - * \brief (Conditional) Collection Type Bistatic metadata. - * - * Pair of radar platforms, with a seperate transmitter - * and a passive receiver. - */ -struct Bistatic : public ImagingType -{ - /*! - * \struct PlatformParams - * - * \brief Describe transmit and recieve platform parameters - */ - struct PlatformParams - { - //! Constructor - PlatformParams(); - - //! Equality operator - bool operator==(const PlatformParams& other) const - { - return sideOfTrack == other.sideOfTrack && - azimuthAngle == other.azimuthAngle && - grazeAngle == other.grazeAngle && - dopplerConeAngle == other.dopplerConeAngle && - groundRange == other.groundRange && - slantRange == other.slantRange && - time == other.time && - pos == other.pos && vel == other.vel; - } - bool operator!=(const PlatformParams& other) const - { - return !((*this) == other); - } - - //! Side of Track parameter for the collection. - //! L Left-looking or R Right-looking - six::SideOfTrackType sideOfTrack; - - //! The transmit time for the vector (txc = TxTime). - double time; - - //! Angle from north to the line from the SCP to the - //! Pos Nadir in the ETP - double azimuthAngle; - - //! Grazing angle between the RefPt LOS and Earth - //! Tangent Plane (ETP - double grazeAngle; - - //! Incidence angle between the RefPt LOS and ETP - //! normal - double incidenceAngle; - - //! Doppler Cone Angle between VXmt and line of - //! sight to the ARP - double dopplerConeAngle; - - //! Ground range from the transmit APC to the SRP - //! (measured on the spherical surface containing the - //! SRP). - double groundRange; - - //! Slant range from the transmit APC to the SRP. - double slantRange; - - //! Transmit APC position (Xmt) in ECF - //! coordinates at txc - Vector3 pos; - - //! Transmit APC velocity (VXmt) in ECF - //! coordinates at txc. - Vector3 vel; - }; - - //! Constructor - Bistatic(); - - //! Equality operator - bool operator==(const Bistatic& other) const - { - if((ImagingType)(*this) != (ImagingType)other) { - return false; - } - - return azimuthAngleRate == other.azimuthAngleRate && - bistaticAngle == other.bistaticAngle && - bistaticAngleRate == other.bistaticAngleRate && - txPlatform == other.txPlatform && - rcvPlatform == other.rcvPlatform; - } - bool operator!=(const Bistatic& other) const - { - return !((*this) == other); - } - - //! Angle from north to the line from the SCP to the - //! Pos Nadir in the ETP - double azimuthAngleRate; - - //! Bistatic angle (Beta) between unit vector from - //! SRP to transmit APC (uXmt) and the unit vector - //! from the SRP to the receive APC (uRcv). - double bistaticAngle; - - //! Instantaneous rate of change of the bistatic angle - //! (d(Beta)/dt). - double bistaticAngleRate; - - //! Parameters that describe the Transmit platform. - PlatformParams txPlatform; - - //! Parameters that describe the Receive platform - PlatformParams rcvPlatform; - -}; - -/*! - * \struct ReferenceGeometry - * - * \brief Parameters that describe the collection geometry - */ -struct ReferenceGeometry -{ - //! Constructor - ReferenceGeometry(); - - //! Equality operator - bool operator==(const ReferenceGeometry& other) const - { - return referenceTime == other.referenceTime && - srpCODTime == other.srpCODTime && - srpDwellTime == other.srpDwellTime && - srp == other.srp && - monostatic == other.monostatic && - bistatic == other.bistatic; - } - bool operator!=(const ReferenceGeometry& other) const - { - return !((*this) == other); - } - - //! Reference time for the selected reference vector - double referenceTime; - - //! The COD Time for point on the reference surface - //! at (SRP_IAX, SRP_IAY). - double srpCODTime; - - //! The Dwell Time for point on the reference - //! surface at (SRP_IAX, SRP_IAY) - double srpDwellTime; - - //! The SRP position for the reference vector of the - //! reference channel. - SRP srp; - - //! Parameters for CollectType = "MONOSTATIC" - mem::ScopedCopyablePtr monostatic; - - //! Parameters for CollectType = "BISTATIC" - mem::ScopedCopyablePtr bistatic; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const SRP& s); -std::ostream& operator<< (std::ostream& os, const ImagingType& i); -std::ostream& operator<< (std::ostream& os, const Monostatic& m); -std::ostream& operator<< (std::ostream& os, const Bistatic::PlatformParams& p); -std::ostream& operator<< (std::ostream& os, const Bistatic& b); -std::ostream& operator<< (std::ostream& os, const ReferenceGeometry& r); -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_REFERENCE_GEOMETRY_H__ +#define __CPHD_REFERENCE_GEOMETRY_H__ + +#include + +#include +#include +#include + +namespace cphd +{ + +/*! + * \struct SRP + * + * \brief The SRP position for the reference vector of the + * reference channel + */ +struct SRP +{ + //! Constructor + SRP(); + + //! Equality operator + bool operator==(const SRP& other) const + { + return ecf == other.ecf && iac == other.iac; + } + bool operator!=(const SRP& other) const + { + return !((*this) == other); + } + + //! SRP position in ECF coordinates. Value + //! included in the SRPPos PVP + Vector3 ecf; + + //! SRP position in Image Area Coordinates (IAX, + //! IAY, IAZ). + Vector3 iac; +}; + +/*! + * \struct ImagingType + * + * \brief Base class for both Monostatic and + * Bistatic imaging types + */ +struct ImagingType +{ + //! Constructor + ImagingType(); + + //! Equality operators + bool operator==(const ImagingType& other) const + { + return azimuthAngle == other.azimuthAngle && + grazeAngle == other.grazeAngle && + twistAngle == other.twistAngle && + slopeAngle == other.slopeAngle && + layoverAngle == other.layoverAngle; + } + bool operator!=(const ImagingType& other) const + { + return !((*this) == other); + } + + //! Destructor + virtual ~ImagingType() {} + + //! Angle from north to the line from the SRP to the + //! ARP ETP Nadir (i.e. North to +GPX). Measured + //! clockwise from +North toward +East. + double azimuthAngle; + + //! Grazing angle for the ARP to SRP LOS and the + //! Earth Tangent Plane (ETP) at the SRP. + double grazeAngle; + + //! Twist angle between cross range in the ETP and + //! cross range in the slant plane at the SRP + double twistAngle; + + //! Angle between the ETP normal (uUP) and the + //! slant plane normal (uSPN) at the SRP + double slopeAngle; + + //! Angle from north to the layover direction in the + //! ETP. Measured clockwise from +North toward + //! +East + double layoverAngle; +}; + +/*! + * \struct Monostatic + * + * \brief (Conditional) Collection Type Monostatic metadata. + * + * Single radar platform that is both the transmitter + * and the receiver + */ +struct Monostatic : public ImagingType +{ + //! Constructor + Monostatic(); + + //! Equality operators + bool operator==(const Monostatic& other) const + { + if((ImagingType)(*this) != (ImagingType)other) { + return false; + } + + return sideOfTrack == other.sideOfTrack && + slantRange == other.slantRange && + groundRange == other.groundRange && + dopplerConeAngle == other.dopplerConeAngle && + incidenceAngle == other.incidenceAngle && + arpPos == other.arpPos && arpVel == other.arpVel; + } + bool operator!=(const Monostatic& other) const + { + return !((*this) == other); + } + + //! Side of Track parameter for the collection. + //! L Left-looking or R Right-looking + six::SideOfTrackType sideOfTrack; + + //! Slant range from the ARP to the SRP + double slantRange; + + //! Ground range from the ARP nadir to the SRP. + //! Distance measured along spherical earth model + //! passing through the SRP. + double groundRange; + + //! Doppler Cone Angle between ARP velocity and + //! SRP Line of Sight (LOS). + double dopplerConeAngle; + + //! Incidence angle for the ARP to SRP LOS and the + //! Earth Tangent Plane (ETP) at the SRP + double incidenceAngle; + + //! ARP position in ECF coordinates (ARP) + Vector3 arpPos; + + //! ARP velocity in ECF coordinates (VARP). + Vector3 arpVel; +}; + +/*! + * \struct Bistatic + * + * \brief (Conditional) Collection Type Bistatic metadata. + * + * Pair of radar platforms, with a seperate transmitter + * and a passive receiver. + */ +struct Bistatic : public ImagingType +{ + /*! + * \struct PlatformParams + * + * \brief Describe transmit and recieve platform parameters + */ + struct PlatformParams + { + //! Constructor + PlatformParams(); + + //! Equality operator + bool operator==(const PlatformParams& other) const + { + return sideOfTrack == other.sideOfTrack && + azimuthAngle == other.azimuthAngle && + grazeAngle == other.grazeAngle && + dopplerConeAngle == other.dopplerConeAngle && + groundRange == other.groundRange && + slantRange == other.slantRange && + time == other.time && + pos == other.pos && vel == other.vel; + } + bool operator!=(const PlatformParams& other) const + { + return !((*this) == other); + } + + //! Side of Track parameter for the collection. + //! L Left-looking or R Right-looking + six::SideOfTrackType sideOfTrack; + + //! The transmit time for the vector (txc = TxTime). + double time; + + //! Angle from north to the line from the SCP to the + //! Pos Nadir in the ETP + double azimuthAngle; + + //! Grazing angle between the RefPt LOS and Earth + //! Tangent Plane (ETP + double grazeAngle; + + //! Incidence angle between the RefPt LOS and ETP + //! normal + double incidenceAngle; + + //! Doppler Cone Angle between VXmt and line of + //! sight to the ARP + double dopplerConeAngle; + + //! Ground range from the transmit APC to the SRP + //! (measured on the spherical surface containing the + //! SRP). + double groundRange; + + //! Slant range from the transmit APC to the SRP. + double slantRange; + + //! Transmit APC position (Xmt) in ECF + //! coordinates at txc + Vector3 pos; + + //! Transmit APC velocity (VXmt) in ECF + //! coordinates at txc. + Vector3 vel; + }; + + //! Constructor + Bistatic(); + + //! Equality operator + bool operator==(const Bistatic& other) const + { + if((ImagingType)(*this) != (ImagingType)other) { + return false; + } + + return azimuthAngleRate == other.azimuthAngleRate && + bistaticAngle == other.bistaticAngle && + bistaticAngleRate == other.bistaticAngleRate && + txPlatform == other.txPlatform && + rcvPlatform == other.rcvPlatform; + } + bool operator!=(const Bistatic& other) const + { + return !((*this) == other); + } + + //! Angle from north to the line from the SCP to the + //! Pos Nadir in the ETP + double azimuthAngleRate; + + //! Bistatic angle (Beta) between unit vector from + //! SRP to transmit APC (uXmt) and the unit vector + //! from the SRP to the receive APC (uRcv). + double bistaticAngle; + + //! Instantaneous rate of change of the bistatic angle + //! (d(Beta)/dt). + double bistaticAngleRate; + + //! Parameters that describe the Transmit platform. + PlatformParams txPlatform; + + //! Parameters that describe the Receive platform + PlatformParams rcvPlatform; + +}; + +/*! + * \struct ReferenceGeometry + * + * \brief Parameters that describe the collection geometry + */ +struct ReferenceGeometry +{ + //! Constructor + ReferenceGeometry(); + + //! Equality operator + bool operator==(const ReferenceGeometry& other) const + { + return referenceTime == other.referenceTime && + srpCODTime == other.srpCODTime && + srpDwellTime == other.srpDwellTime && + srp == other.srp && + monostatic == other.monostatic && + bistatic == other.bistatic; + } + bool operator!=(const ReferenceGeometry& other) const + { + return !((*this) == other); + } + + //! Reference time for the selected reference vector + double referenceTime; + + //! The COD Time for point on the reference surface + //! at (SRP_IAX, SRP_IAY). + double srpCODTime; + + //! The Dwell Time for point on the reference + //! surface at (SRP_IAX, SRP_IAY) + double srpDwellTime; + + //! The SRP position for the reference vector of the + //! reference channel. + SRP srp; + + //! Parameters for CollectType = "MONOSTATIC" + mem::ScopedCopyablePtr monostatic; + + //! Parameters for CollectType = "BISTATIC" + mem::ScopedCopyablePtr bistatic; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const SRP& s); +std::ostream& operator<< (std::ostream& os, const ImagingType& i); +std::ostream& operator<< (std::ostream& os, const Monostatic& m); +std::ostream& operator<< (std::ostream& os, const Bistatic::PlatformParams& p); +std::ostream& operator<< (std::ostream& os, const Bistatic& b); +std::ostream& operator<< (std::ostream& os, const ReferenceGeometry& r); +} + +#endif diff --git a/six/modules/c++/cphd/include/cphd/TxRcv.h b/six/modules/c++/cphd/include/cphd/TxRcv.h index 856966ac88..7e80674ce2 100644 --- a/six/modules/c++/cphd/include/cphd/TxRcv.h +++ b/six/modules/c++/cphd/include/cphd/TxRcv.h @@ -1,184 +1,184 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#ifndef __CPHD_TXRCV_H__ -#define __CPHD_TXRCV_H__ - -#include -#include -#include - -#include -#include - - -namespace cphd -{ - -/*! - * \struct ParameterType - * - * \brief Base parameter class for both TxWF and Rcv type parameters - */ -struct ParameterType -{ - //! Constructor - ParameterType(); - - //! Equality operators - bool operator==(const ParameterType& other) const - { - return identifier == other.identifier && - freqCenter == other.freqCenter && - lfmRate == other.lfmRate && - polarization == other.polarization; - } - - bool operator!=(const ParameterType& other) const - { - return !((*this) == other); - } - - //! String that uniquely identifies this Transmit Waveform - std::string identifier; - - //! Center frequency of the transmitted waveform - double freqCenter; - - //! (Optional) Chirp rate of transmitted pulse if LFM - // Allowed lfmRate != 0 - double lfmRate; - - //! Transmit polarization - PolarizationType polarization; -}; - -/*! - * \struct TxWFParameters - * - * \brief Parameters that describe a Transmit Waveform - */ -struct TxWFParameters : public ParameterType -{ - //! Constructor - TxWFParameters(); - - //! Equality operators - bool operator==(const TxWFParameters& other) const - { - return pulseLength == other.pulseLength && - rfBandwidth == other.rfBandwidth && - power == other.power; - } - bool operator!=(const TxWFParameters& other) const - { - return !((*this) == other); - } - - //! Length of transmitted pulse - double pulseLength; - - //! Bandwidth if transmitted pulse - double rfBandwidth; - - //! Peak transmitted power at the interface to the - //! antenna - double power; -}; - -/* - * \struct RcvParameters - * - * \brief Parameters that describe a Receive configuration - */ -struct RcvParameters : public ParameterType -{ - //! Constructor - RcvParameters(); - - //! Equality operators - bool operator==(const RcvParameters& other) const - { - return windowLength == other.windowLength && - sampleRate == other.sampleRate && - ifFilterBW == other.ifFilterBW && - pathGain == other.pathGain; - } - bool operator!=(const RcvParameters& other) const - { - return !((*this) == other); - } - - //! Length of the receive window - double windowLength; - - //! Rate at which the signal in the receive window - //! is sampled - double sampleRate; - - //! Bandwidth of the anti-aliasing filter prior to - //! sampling - double ifFilterBW; - - //! Receiver gain from the antenna interface to the - //! ADC. - double pathGain; -}; - -/*! - * \struct TxRcv - * - * (Optional) Parameters that describe the transmitted - * waveform(s) and receiver configurations used in - * the collection - */ -struct TxRcv -{ - //! Constructor - TxRcv(); - - //! Equality operators - bool operator==(const TxRcv& other) const - { - return txWFParameters == other.txWFParameters && - rcvParameters == other.rcvParameters; - } - bool operator!=(const TxRcv& other) const - { - return !((*this) == other); - } - - //! Parameters that describe a Transmit Waveform - std::vector txWFParameters; - - //! Parameters that describe a Receive configuration - std::vector rcvParameters; -}; - -//! Ostream operators -std::ostream& operator<< (std::ostream& os, const ParameterType& p); -std::ostream& operator<< (std::ostream& os, const TxWFParameters& t); -std::ostream& operator<< (std::ostream& os, const RcvParameters& r); -std::ostream& operator<< (std::ostream& os, const TxRcv& t); -} - -#endif +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#ifndef __CPHD_TXRCV_H__ +#define __CPHD_TXRCV_H__ + +#include +#include +#include + +#include +#include + + +namespace cphd +{ + +/*! + * \struct ParameterType + * + * \brief Base parameter class for both TxWF and Rcv type parameters + */ +struct ParameterType +{ + //! Constructor + ParameterType(); + + //! Equality operators + bool operator==(const ParameterType& other) const + { + return identifier == other.identifier && + freqCenter == other.freqCenter && + lfmRate == other.lfmRate && + polarization == other.polarization; + } + + bool operator!=(const ParameterType& other) const + { + return !((*this) == other); + } + + //! String that uniquely identifies this Transmit Waveform + std::string identifier; + + //! Center frequency of the transmitted waveform + double freqCenter; + + //! (Optional) Chirp rate of transmitted pulse if LFM + // Allowed lfmRate != 0 + double lfmRate; + + //! Transmit polarization + PolarizationType polarization; +}; + +/*! + * \struct TxWFParameters + * + * \brief Parameters that describe a Transmit Waveform + */ +struct TxWFParameters : public ParameterType +{ + //! Constructor + TxWFParameters(); + + //! Equality operators + bool operator==(const TxWFParameters& other) const + { + return pulseLength == other.pulseLength && + rfBandwidth == other.rfBandwidth && + power == other.power; + } + bool operator!=(const TxWFParameters& other) const + { + return !((*this) == other); + } + + //! Length of transmitted pulse + double pulseLength; + + //! Bandwidth if transmitted pulse + double rfBandwidth; + + //! Peak transmitted power at the interface to the + //! antenna + double power; +}; + +/* + * \struct RcvParameters + * + * \brief Parameters that describe a Receive configuration + */ +struct RcvParameters : public ParameterType +{ + //! Constructor + RcvParameters(); + + //! Equality operators + bool operator==(const RcvParameters& other) const + { + return windowLength == other.windowLength && + sampleRate == other.sampleRate && + ifFilterBW == other.ifFilterBW && + pathGain == other.pathGain; + } + bool operator!=(const RcvParameters& other) const + { + return !((*this) == other); + } + + //! Length of the receive window + double windowLength; + + //! Rate at which the signal in the receive window + //! is sampled + double sampleRate; + + //! Bandwidth of the anti-aliasing filter prior to + //! sampling + double ifFilterBW; + + //! Receiver gain from the antenna interface to the + //! ADC. + double pathGain; +}; + +/*! + * \struct TxRcv + * + * (Optional) Parameters that describe the transmitted + * waveform(s) and receiver configurations used in + * the collection + */ +struct TxRcv +{ + //! Constructor + TxRcv(); + + //! Equality operators + bool operator==(const TxRcv& other) const + { + return txWFParameters == other.txWFParameters && + rcvParameters == other.rcvParameters; + } + bool operator!=(const TxRcv& other) const + { + return !((*this) == other); + } + + //! Parameters that describe a Transmit Waveform + std::vector txWFParameters; + + //! Parameters that describe a Receive configuration + std::vector rcvParameters; +}; + +//! Ostream operators +std::ostream& operator<< (std::ostream& os, const ParameterType& p); +std::ostream& operator<< (std::ostream& os, const TxWFParameters& t); +std::ostream& operator<< (std::ostream& os, const RcvParameters& r); +std::ostream& operator<< (std::ostream& os, const TxRcv& t); +} + +#endif diff --git a/six/modules/c++/cphd/source/Antenna.cpp b/six/modules/c++/cphd/source/Antenna.cpp index 5a5dc9e916..7dc9d1b781 100644 --- a/six/modules/c++/cphd/source/Antenna.cpp +++ b/six/modules/c++/cphd/source/Antenna.cpp @@ -1,148 +1,148 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include - -namespace cphd -{ - -AntCoordFrame::AntCoordFrame() -{ -} - -AntPhaseCenter::AntPhaseCenter() -{ -} - -AntPattern::AntPattern(): - freqZero(six::Init::undefined()), - gainZero(six::Init::undefined()), - ebFreqShift(six::Init::undefined()), - mlFreqDilation(six::Init::undefined()), - gainBSPoly(six::Init::undefined()) -{ -} - -AntPattern::GainPhaseArray::GainPhaseArray() : - freq(six::Init::undefined()) -{ -} - -Antenna::Antenna() -{ -} - -std::ostream& operator<< (std::ostream& os, const AntCoordFrame& a) -{ - os << " AntCoordFrame:: \n" - << " Identifier : " << a.identifier << "\n" - << " XAxisPoly : " << a.xAxisPoly << "\n" - << " YAxisPoly : " << a.yAxisPoly << "\n" - << a.useACFPVP; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPhaseCenter& a) -{ - os << " AntPhaseCenter:: \n" - << " Identifier : " << a.identifier << "\n" - << " ACFId : " << a.acfId << "\n" - << " APCXYZ : " << a.apcXYZ << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPattern::EBFreqShiftSF& v) -{ - os << " EBFreqShiftSF:: \n" - << v.dcxsf << v.dcysf << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPattern::MLFreqDilationSF& v) -{ - os << " MLFreqDilationSF:: \n" - << v.dcxsf << v.dcysf << "\n"; - return os; -} - - -std::ostream& operator<< (std::ostream& os, const AntPattern::AntPolRef& v) -{ - os << " AntPolRef:: \n" - << v.ampX << v.ampY << v.phaseY << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPattern::GainPhaseArray& g) -{ - os << " GainPhaseArray:: \n" - << " Freq : " << g.freq << "\n" - << " ArrayId : " << g.arrayId << "\n" - << " ElementId : " << g.elementId << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const AntPattern& a) -{ - os << " AntPattern \n" - << " Identifier : " << a.identifier << "\n" - << " FreqZero : " << a.freqZero << "\n" - << " GainZero : " << a.gainZero << "\n" - << " EBFreqShift : " << a.ebFreqShift << "\n" - << a.ebFreqShiftSF << "\n" - << " MLFreqDilation : " << a.mlFreqDilation << "\n" - << a.mlFreqDilationSF << "\n" - << " GainBSPoly : " << a.gainBSPoly << "\n" - << a.antPolRef << "\n" - << a.eb << "\n" - << " Array:: \n" - << a.array << "\n" - << " Element:: \n" - << a.element << "\n"; - for (const auto& gainPhase : a.gainPhaseArray) - { - os << gainPhase << "\n"; - } - return os; -} - -std::ostream& operator<< (std::ostream& os, const Antenna& a) -{ - os << "Antenna:: \n" - << " NumACFs : " << a.antCoordFrame.size() << "\n" - << " NumAPCs : " << a.antPhaseCenter.size() << "\n" - << " NumAntPats : " << a.antPattern.size() << "\n"; - for (size_t ii = 0; ii < a.antCoordFrame.size(); ++ii) - { - os << a.antCoordFrame[ii] << "\n"; - } - for (size_t ii = 0; ii < a.antPhaseCenter.size(); ++ii) - { - os << a.antPhaseCenter[ii] << "\n"; - } - for (size_t ii = 0; ii < a.antPattern.size(); ++ii) - { - os << a.antPattern[ii] << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include + +namespace cphd +{ + +AntCoordFrame::AntCoordFrame() +{ +} + +AntPhaseCenter::AntPhaseCenter() +{ +} + +AntPattern::AntPattern(): + freqZero(six::Init::undefined()), + gainZero(six::Init::undefined()), + ebFreqShift(six::Init::undefined()), + mlFreqDilation(six::Init::undefined()), + gainBSPoly(six::Init::undefined()) +{ +} + +AntPattern::GainPhaseArray::GainPhaseArray() : + freq(six::Init::undefined()) +{ +} + +Antenna::Antenna() +{ +} + +std::ostream& operator<< (std::ostream& os, const AntCoordFrame& a) +{ + os << " AntCoordFrame:: \n" + << " Identifier : " << a.identifier << "\n" + << " XAxisPoly : " << a.xAxisPoly << "\n" + << " YAxisPoly : " << a.yAxisPoly << "\n" + << a.useACFPVP; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPhaseCenter& a) +{ + os << " AntPhaseCenter:: \n" + << " Identifier : " << a.identifier << "\n" + << " ACFId : " << a.acfId << "\n" + << " APCXYZ : " << a.apcXYZ << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPattern::EBFreqShiftSF& v) +{ + os << " EBFreqShiftSF:: \n" + << v.dcxsf << v.dcysf << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPattern::MLFreqDilationSF& v) +{ + os << " MLFreqDilationSF:: \n" + << v.dcxsf << v.dcysf << "\n"; + return os; +} + + +std::ostream& operator<< (std::ostream& os, const AntPattern::AntPolRef& v) +{ + os << " AntPolRef:: \n" + << v.ampX << v.ampY << v.phaseY << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPattern::GainPhaseArray& g) +{ + os << " GainPhaseArray:: \n" + << " Freq : " << g.freq << "\n" + << " ArrayId : " << g.arrayId << "\n" + << " ElementId : " << g.elementId << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const AntPattern& a) +{ + os << " AntPattern \n" + << " Identifier : " << a.identifier << "\n" + << " FreqZero : " << a.freqZero << "\n" + << " GainZero : " << a.gainZero << "\n" + << " EBFreqShift : " << a.ebFreqShift << "\n" + << a.ebFreqShiftSF << "\n" + << " MLFreqDilation : " << a.mlFreqDilation << "\n" + << a.mlFreqDilationSF << "\n" + << " GainBSPoly : " << a.gainBSPoly << "\n" + << a.antPolRef << "\n" + << a.eb << "\n" + << " Array:: \n" + << a.array << "\n" + << " Element:: \n" + << a.element << "\n"; + for (const auto& gainPhase : a.gainPhaseArray) + { + os << gainPhase << "\n"; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const Antenna& a) +{ + os << "Antenna:: \n" + << " NumACFs : " << a.antCoordFrame.size() << "\n" + << " NumAPCs : " << a.antPhaseCenter.size() << "\n" + << " NumAntPats : " << a.antPattern.size() << "\n"; + for (size_t ii = 0; ii < a.antCoordFrame.size(); ++ii) + { + os << a.antCoordFrame[ii] << "\n"; + } + for (size_t ii = 0; ii < a.antPhaseCenter.size(); ++ii) + { + os << a.antPhaseCenter[ii] << "\n"; + } + for (size_t ii = 0; ii < a.antPattern.size(); ++ii) + { + os << a.antPattern[ii] << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/CPHDXMLParser.cpp b/six/modules/c++/cphd/source/CPHDXMLParser.cpp index 61a24d3d1e..1ea206ba35 100644 --- a/six/modules/c++/cphd/source/CPHDXMLParser.cpp +++ b/six/modules/c++/cphd/source/CPHDXMLParser.cpp @@ -1,2422 +1,2422 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include - - -#define ENFORCESPEC 0 - -namespace -{ -typedef xml::lite::Element* XMLElem; -} - -namespace cphd -{ - -CPHDXMLParser::CPHDXMLParser( - const std::string& uri, - bool addClassAttributes, - logging::Logger* log, - bool ownLog) : - six::XMLParser(uri, addClassAttributes, log, ownLog), - mCommon(getDefaultURI(), addClassAttributes, getDefaultURI(), log) -{ -} - -/* - * TO XML - */ -std::unique_ptr CPHDXMLParser::toXML( - const Metadata& metadata) -{ - std::unique_ptr doc(new xml::lite::Document()); - - XMLElem root = newElement("CPHD"); - doc->setRootElement(root); - - toXML(metadata.collectionID, root); - toXML(metadata.global, root); - toXML(metadata.sceneCoordinates, root); - toXML(metadata.data, root); - toXML(metadata.channel, root); - toXML(metadata.pvp, root); - toXML(metadata.dwell, root); - toXML(metadata.referenceGeometry, root); - - if (metadata.supportArray.get()) - { - toXML(*(metadata.supportArray), root); - } - if (metadata.antenna.get()) - { - toXML(*(metadata.antenna), root); - } - if (metadata.txRcv.get()) - { - toXML(*(metadata.txRcv), root); - } - if (metadata.errorParameters.get()) - { - toXML(*(metadata.errorParameters), root); - } - if (metadata.productInfo.get()) - { - toXML(*(metadata.productInfo), root); - } - for (const auto& geoInfo : metadata.geoInfo) - { - toXML(geoInfo, root); - } - if (metadata.matchInfo.get()) - { - toXML(*(metadata.matchInfo), root); - } - - //set the XMLNS - root->setNamespacePrefix("", getDefaultURI()); - - return doc; -} - -XMLElem CPHDXMLParser::toXML(const CollectionInformation& collectionID, XMLElem parent) -{ - XMLElem collectionXML = newElement("CollectionID", parent); - - createString("CollectorName", collectionID.collectorName, collectionXML); - if(!six::Init::isUndefined(collectionID.illuminatorName)) - { - createString("IlluminatorName", collectionID.illuminatorName, collectionXML); - } - createString("CoreName", collectionID.coreName, collectionXML); - createString("CollectType", collectionID.collectType, collectionXML); - - // RadarMode - XMLElem radarModeXML = newElement("RadarMode", collectionXML); - createSixString("ModeType", collectionID.radarMode, radarModeXML); - if(!six::Init::isUndefined(collectionID.radarModeID)) - { - createString("ModeID", collectionID.radarModeID, radarModeXML); - } - createString("Classification", collectionID.getClassificationLevel(), collectionXML); - createString("ReleaseInfo", collectionID.releaseInfo, collectionXML); - if (!collectionID.countryCodes.empty()) - { - std::string countryCodes = str::join(collectionID.countryCodes, ","); - createString("CountryCode", countryCodes, collectionXML); - } - mCommon.addParameters("Parameter", getDefaultURI(), collectionID.parameters, collectionXML); - return collectionXML; -} - -XMLElem CPHDXMLParser::toXML(const Global& global, XMLElem parent) -{ - XMLElem globalXML = newElement("Global", parent); - createString("DomainType", global.domainType, globalXML); - createString("SGN", global.sgn, globalXML); - - //Timeline - XMLElem timelineXML = newElement("Timeline", globalXML); - createDateTime("CollectionStart", global.timeline.collectionStart, timelineXML); - if (!six::Init::isUndefined(global.timeline.rcvCollectionStart)) - { - createDateTime("RcvCollectionStart", global.timeline.rcvCollectionStart, timelineXML); - } - createDouble("TxTime1", global.timeline.txTime1, timelineXML); - createDouble("TxTime2", global.timeline.txTime2, timelineXML); - - XMLElem fxBandXML = newElement("FxBand", globalXML); - createDouble("FxMin", global.fxBand.fxMin, fxBandXML); - createDouble("FxMax", global.fxBand.fxMax, fxBandXML); - - XMLElem toaSwathXML = newElement("TOASwath", globalXML); - createDouble("TOAMin", global.toaSwath.toaMin, toaSwathXML); - createDouble("TOAMax", global.toaSwath.toaMax, toaSwathXML); - - if (global.tropoParameters.get()) - { - XMLElem tropoXML = newElement("TropoParameters", globalXML); - createDouble("N0", global.tropoParameters->n0, tropoXML); - createString("RefHeight", global.tropoParameters->refHeight, tropoXML); - } - if (global.ionoParameters.get()) - { - XMLElem ionoXML = newElement("IonoParameters", globalXML); - createDouble("TECV", global.ionoParameters->tecv, ionoXML); - createOptionalDouble("F2Height", global.ionoParameters->f2Height, ionoXML); - } - return globalXML; -} - -XMLElem CPHDXMLParser::toXML(const SceneCoordinates& sceneCoords, XMLElem parent) -{ - XMLElem sceneCoordsXML = newElement("SceneCoordinates", parent); - createString("EarthModel", sceneCoords.earthModel, sceneCoordsXML); - - XMLElem iarpXML = newElement("IARP", sceneCoordsXML); - mCommon.createVector3D("ECF", sceneCoords.iarp.ecf, iarpXML); - mCommon.createLatLonAlt("LLH", sceneCoords.iarp.llh, iarpXML); - - XMLElem refSurfXML = newElement("ReferenceSurface", sceneCoordsXML); - if (sceneCoords.referenceSurface.planar.get()) - { - XMLElem planarXML = newElement("Planar", refSurfXML); - mCommon.createVector3D("uIAX", sceneCoords.referenceSurface.planar->uIax, planarXML); - mCommon.createVector3D("uIAY", sceneCoords.referenceSurface.planar->uIay, planarXML); - } - else if (sceneCoords.referenceSurface.hae.get()) - { - XMLElem haeXML = newElement("HAE", refSurfXML); - mCommon.createLatLon("uIAXLL", sceneCoords.referenceSurface.hae->uIax, haeXML); - mCommon.createLatLon("uIAYLL", sceneCoords.referenceSurface.hae->uIay, haeXML); - } - else - { - throw except::Exception(Ctxt( - "Reference Surface must be one of two types")); - } - - XMLElem imageAreaXML = newElement("ImageArea", sceneCoordsXML); - mCommon.createVector2D("X1Y1", sceneCoords.imageArea.x1y1, imageAreaXML); - mCommon.createVector2D("X2Y2", sceneCoords.imageArea.x2y2, imageAreaXML); - - if (!sceneCoords.imageArea.polygon.empty()) - { - XMLElem polygonXML = newElement("Polygon", imageAreaXML); - setAttribute(polygonXML, "size", sceneCoords.imageArea.polygon.size()); - for (size_t ii = 0; ii < sceneCoords.imageArea.polygon.size(); ++ii) - { - XMLElem vertexXML = mCommon.createVector2D("Vertex", sceneCoords.imageArea.polygon[ii], polygonXML); - setAttribute(vertexXML, "index", ii+1); - } - } - createLatLonFootprint("ImageAreaCornerPoints", "IACP", sceneCoords.imageAreaCorners, sceneCoordsXML); - - // Extended Area (Optional) - if(sceneCoords.extendedArea.get()) - { - XMLElem extendedAreaXML = newElement("ExtendedArea", sceneCoordsXML); - mCommon.createVector2D("X1Y1", sceneCoords.extendedArea->x1y1, extendedAreaXML); - mCommon.createVector2D("X2Y2", sceneCoords.extendedArea->x2y2, extendedAreaXML); - - if (!sceneCoords.extendedArea->polygon.empty()) - { - XMLElem polygonXML = newElement("Polygon", sceneCoordsXML); - setAttribute(polygonXML, "size", sceneCoords.extendedArea->polygon.size()); - for (size_t ii = 0; ii < sceneCoords.extendedArea->polygon.size(); ++ii) - { - XMLElem vertexXML = mCommon.createVector2D("Vertex", sceneCoords.extendedArea->polygon[ii], polygonXML); - setAttribute(vertexXML, "index", ii+1); - } - } - } - - // ImageGrid (Optional) - if(sceneCoords.imageGrid.get()) - { - XMLElem imageGridXML = newElement("ImageGrid", sceneCoordsXML); - if(!six::Init::isUndefined(sceneCoords.imageGrid->identifier)) - { - createString("Identifier", sceneCoords.imageGrid->identifier, imageGridXML); - } - XMLElem iarpLocationXML = newElement("IARPLocation", imageGridXML); - createDouble("Line", sceneCoords.imageGrid->iarpLocation.line, iarpLocationXML); - createDouble("Sample", sceneCoords.imageGrid->iarpLocation.sample, iarpLocationXML); - - XMLElem iaxExtentXML = newElement("IAXExtent", imageGridXML); - createDouble("LineSpacing", sceneCoords.imageGrid->xExtent.lineSpacing, iaxExtentXML); - createInt("FirstLine", sceneCoords.imageGrid->xExtent.firstLine, iaxExtentXML); - createInt("NumLines", sceneCoords.imageGrid->xExtent.numLines, iaxExtentXML); - - XMLElem iayExtentXML = newElement("IAYExtent", imageGridXML); - createDouble("SampleSpacing", sceneCoords.imageGrid->yExtent.sampleSpacing, iayExtentXML); - createInt("FirstSample", sceneCoords.imageGrid->yExtent.firstSample, iayExtentXML); - createInt("NumSamples", sceneCoords.imageGrid->yExtent.numSamples, iayExtentXML); - - if (!sceneCoords.imageGrid->segments.empty()) - { - XMLElem segmentListXML = newElement("SegmentList", imageGridXML); - createInt("NumSegments", sceneCoords.imageGrid->segments.size(), segmentListXML); - - for (size_t ii = 0; ii < sceneCoords.imageGrid->segments.size(); ++ii) - { - XMLElem segmentXML = newElement("Segment", segmentListXML); - createString("Identifier", sceneCoords.imageGrid->segments[ii].identifier, segmentXML); - createInt("StartLine", sceneCoords.imageGrid->segments[ii].startLine, segmentXML); - createInt("StartSample", sceneCoords.imageGrid->segments[ii].startSample, segmentXML); - createInt("EndLine", sceneCoords.imageGrid->segments[ii].endLine, segmentXML); - createInt("EndSample", sceneCoords.imageGrid->segments[ii].endSample, segmentXML); - - if (!sceneCoords.imageGrid->segments[ii].polygon.empty()) - { - XMLElem polygonXML = newElement("SegmentPolygon", segmentXML); - setAttribute(polygonXML, "size", sceneCoords.imageGrid->segments[ii].polygon.size()); - for (size_t jj = 0; jj < sceneCoords.imageGrid->segments[ii].polygon.size(); ++jj) - { - XMLElem svXML = newElement("SV", polygonXML); - setAttribute(svXML, "index", sceneCoords.imageGrid->segments[ii].polygon[jj].getIndex()); - createDouble("Line", sceneCoords.imageGrid->segments[ii].polygon[jj].line, svXML); - createDouble("Sample", sceneCoords.imageGrid->segments[ii].polygon[jj].sample, svXML); - } - } - } - } - } - return sceneCoordsXML; -} - -XMLElem CPHDXMLParser::toXML(const Data& data, XMLElem parent) -{ - XMLElem dataXML = newElement("Data", parent); - createString("SignalArrayFormat", data.signalArrayFormat, dataXML); - createInt("NumBytesPVP", data.numBytesPVP, dataXML); - createInt("NumCPHDChannels", data.channels.size(), dataXML); - if (!six::Init::isUndefined(data.signalCompressionID)) - { - createString("SignalCompressionID", data.signalCompressionID, dataXML); - } - - for (size_t ii = 0; ii < data.channels.size(); ++ii) - { - XMLElem channelXML = newElement("Channel", dataXML); - createString("Identifier", data.channels[ii].identifier, channelXML); - createInt("NumVectors", data.channels[ii].numVectors, channelXML); - createInt("NumSamples", data.channels[ii].numSamples, channelXML); - createInt("SignalArrayByteOffset", data.channels[ii].signalArrayByteOffset, channelXML); - createInt("PVPArrayByteOffset", data.channels[ii].pvpArrayByteOffset, channelXML); - if(!six::Init::isUndefined(data.channels[ii].compressedSignalSize)) - { - createInt("CompressedSignalSize", data.channels[ii].compressedSignalSize, channelXML); - } - } - createInt("NumSupportArrays", data.supportArrayMap.size(), dataXML); - for (const auto& entry : data.supportArrayMap) - { - XMLElem supportArrayXML = newElement("SupportArray", dataXML); - createString("Identifier", entry.second.identifier, supportArrayXML); - createInt("NumRows", entry.second.numRows, supportArrayXML); - createInt("NumCols", entry.second.numCols, supportArrayXML); - createInt("BytesPerElement", entry.second.bytesPerElement, supportArrayXML); - createInt("ArrayByteOffset", entry.second.arrayByteOffset, supportArrayXML); - } - return dataXML; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem pXML = nullptr; - if (has_value(o)) - { - pXML = newElement(o.tag(), &parent); - std::ignore = create(parser(), value(o).ampH, *pXML); - std::ignore = create(parser(), value(o).ampV, *pXML); - std::ignore = create(parser(), value(o).phaseV, *pXML); - } - - return pXML; -} - -XMLElem CPHDXMLParser::toXML(const Polarization& obj, xml::lite::Element& parent) -{ - auto polXML = newElement("Polarization", &parent); - createString("TxPol", obj.txPol, polXML); - createString("RcvPol", obj.rcvPol, polXML); - - toXML(obj.txPolRef, *polXML); // added in CPHD 1.1.0 - toXML(obj.rcvPolRef, *polXML); // added in CPHD 1.1.0 - - return polXML; -} - -XMLElem CPHDXMLParser::toXML(const Channel& channel, XMLElem parent) -{ - XMLElem channelXML = newElement("Channel", parent); - createString("RefChId", channel.refChId, channelXML); - createBooleanType("FXFixedCPHD", channel.fxFixedCphd, channelXML); - createBooleanType("TOAFixedCPHD", channel.toaFixedCphd, channelXML); - createBooleanType("SRPFixedCPHD", channel.srpFixedCphd, channelXML); - - for (size_t ii = 0; ii < channel.parameters.size(); ++ii) - { - XMLElem parametersXML = newElement("Parameters", channelXML); - createString("Identifier", channel.parameters[ii].identifier, parametersXML); - createInt("RefVectorIndex", channel.parameters[ii].refVectorIndex, parametersXML); - createBooleanType("FXFixed", channel.parameters[ii].fxFixed, parametersXML); - createBooleanType("TOAFixed", channel.parameters[ii].toaFixed, parametersXML); - createBooleanType("SRPFixed", channel.parameters[ii].srpFixed, parametersXML); - if (!six::Init::isUndefined(channel.parameters[ii].signalNormal)) - { - createBooleanType("SignalNormal", channel.parameters[ii].signalNormal, parametersXML); - } - std::ignore = toXML(channel.parameters[ii].polarization, *parametersXML); - - createDouble("FxC", channel.parameters[ii].fxC, parametersXML); - createDouble("FxBW", channel.parameters[ii].fxBW, parametersXML); - createOptionalDouble("FxBWNoise", channel.parameters[ii].fxBWNoise, parametersXML); - createDouble("TOASaved", channel.parameters[ii].toaSaved, parametersXML); - - if(channel.parameters[ii].toaExtended.get()) - { - XMLElem toaExtendedXML = newElement("TOAExtended", parametersXML); - createDouble("TOAExtSaved", channel.parameters[ii].toaExtended->toaExtSaved, toaExtendedXML); - if(channel.parameters[ii].toaExtended->lfmEclipse.get()) - { - XMLElem lfmEclipseXML = newElement("LFMEclipse", toaExtendedXML); - createDouble("FxEarlyLow", channel.parameters[ii].toaExtended->lfmEclipse->fxEarlyLow, lfmEclipseXML); - createDouble("FxEarlyHigh", channel.parameters[ii].toaExtended->lfmEclipse->fxEarlyHigh, lfmEclipseXML); - createDouble("FxLateLow", channel.parameters[ii].toaExtended->lfmEclipse->fxLateLow, lfmEclipseXML); - createDouble("FxLateHigh", channel.parameters[ii].toaExtended->lfmEclipse->fxLateHigh, lfmEclipseXML); - } - } - XMLElem dwellTimesXML = newElement("DwellTimes", parametersXML); - createString("CODId", channel.parameters[ii].dwellTimes.codId, dwellTimesXML); - createString("DwellId", channel.parameters[ii].dwellTimes.dwellId, dwellTimesXML); - std::ignore = create(parser(), channel.parameters[ii].dwellTimes.dtaId, *dwellTimesXML); - std::ignore = create(parser(), channel.parameters[ii].dwellTimes.useDTA, *dwellTimesXML); - - if(!six::Init::isUndefined(channel.parameters[ii].imageArea)) - { - XMLElem imageAreaXML = newElement("ImageArea", parametersXML); - mCommon.createVector2D("X1Y1", channel.parameters[ii].imageArea.x1y1, imageAreaXML); - mCommon.createVector2D("X2Y2", channel.parameters[ii].imageArea.x2y2, imageAreaXML); - if(!channel.parameters[ii].imageArea.polygon.empty()) - { - XMLElem polygonXML = newElement("Polygon", imageAreaXML); - setAttribute(polygonXML, "size", channel.parameters[ii].imageArea.polygon.size()); - for (size_t jj = 0; jj < channel.parameters[ii].imageArea.polygon.size(); ++jj) - { - XMLElem vertexXML = mCommon.createVector2D("Vertex", channel.parameters[ii].imageArea.polygon[jj], polygonXML); - setAttribute(vertexXML, "index", jj+1); - } - } - } - if(channel.parameters[ii].antenna.get()) - { - XMLElem antennaXML = newElement("Antenna", parametersXML); - createString("TxAPCId", channel.parameters[ii].antenna->txAPCId, antennaXML); - createString("TxAPATId", channel.parameters[ii].antenna->txAPATId, antennaXML); - createString("RcvAPCId", channel.parameters[ii].antenna->rcvAPCId, antennaXML); - createString("RcvAPATId", channel.parameters[ii].antenna->rcvAPATId, antennaXML); - } - if(channel.parameters[ii].txRcv.get()) - { - XMLElem txRcvXML = newElement("TxRcv", parametersXML); - for (size_t jj = 0; jj < channel.parameters[ii].txRcv->txWFId.size(); ++jj) - { - createString("TxWFId", channel.parameters[ii].txRcv->txWFId[jj], txRcvXML); - } - for (size_t jj = 0; jj < channel.parameters[ii].txRcv->rcvId.size(); ++jj) - { - createString("RcvId", channel.parameters[ii].txRcv->rcvId[jj], txRcvXML); - } - } - if(channel.parameters[ii].tgtRefLevel.get()) - { - XMLElem tgtRefXML = newElement("TgtRefLevel", parametersXML); - createDouble("PTRef", channel.parameters[ii].tgtRefLevel->ptRef, tgtRefXML); - } - if(channel.parameters[ii].noiseLevel.get()) - { - XMLElem noiseLevelXML = newElement("NoiseLevel", parametersXML); - createDouble("PNRef", channel.parameters[ii].noiseLevel->pnRef, noiseLevelXML); - createDouble("BNRef", channel.parameters[ii].noiseLevel->bnRef, noiseLevelXML); - if(channel.parameters[ii].noiseLevel->fxNoiseProfile.get()) - { - XMLElem fxNoiseProfileXML = newElement("FxNoiseProfile", noiseLevelXML); - for (size_t jj = 0; jj < channel.parameters[ii].noiseLevel->fxNoiseProfile->point.size(); ++jj) - { - XMLElem pointXML = newElement("Point", fxNoiseProfileXML); - createDouble("Fx", channel.parameters[ii].noiseLevel->fxNoiseProfile->point[jj].fx, pointXML); - createDouble("PN", channel.parameters[ii].noiseLevel->fxNoiseProfile->point[jj].pn, pointXML); - } - } - } - } - if(!channel.addedParameters.empty()) - { - XMLElem addedParamsXML = newElement("AddedParameters", channelXML); - mCommon.addParameters("Parameter", getDefaultURI(), channel.addedParameters, addedParamsXML); - } - return channelXML; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement& v, xml::lite::Element& parent) -{ - return createPVPType(v.tag(), v.value().param, &parent); -} -XMLElem CPHDXMLParser::toXML(const six::XsElement& v, xml::lite::Element& parent) -{ - return createPVPType(v.tag(), v.value().param, &parent); -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem pXML = nullptr; - if (has_value(o)) - { - pXML = newElement(o.tag(), &parent); - std::ignore = toXML(value(o).txACX, *pXML); - std::ignore = toXML(value(o).txACY, *pXML); - std::ignore = toXML(value(o).txEB, *pXML); - } - - return pXML; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem pXML = nullptr; - if (has_value(o)) - { - pXML = newElement(o.tag(), &parent); - std::ignore = toXML(value(o).rcvACX, *pXML); - std::ignore = toXML(value(o).rcvACY, *pXML); - std::ignore = toXML(value(o).rcvEB, *pXML); - } - - return pXML; -} - -XMLElem CPHDXMLParser::toXML(const Pvp& pvp, XMLElem parent) -{ - XMLElem pvpXML = newElement("PVP", parent); - createPVPType("TxTime", pvp.txTime, pvpXML); - createPVPType("TxPos", pvp.txPos, pvpXML); - createPVPType("TxVel", pvp.txVel, pvpXML); - createPVPType("RcvTime", pvp.rcvTime, pvpXML); - createPVPType("RcvPos", pvp.rcvPos, pvpXML); - createPVPType("RcvVel", pvp.rcvVel, pvpXML); - createPVPType("SRPPos", pvp.srpPos, pvpXML); - if (!six::Init::isUndefined(pvp.ampSF.getOffset())) - { - createPVPType("AmpSF", pvp.ampSF, pvpXML); - } - createPVPType("aFDOP", pvp.aFDOP, pvpXML); - createPVPType("aFRR1", pvp.aFRR1, pvpXML); - createPVPType("aFRR2", pvp.aFRR2, pvpXML); - createPVPType("FX1", pvp.fx1, pvpXML); - createPVPType("FX2", pvp.fx2, pvpXML); - if (!six::Init::isUndefined(pvp.fxN1.getOffset())) - { - createPVPType("FXN1", pvp.fxN1, pvpXML); - } - if (!six::Init::isUndefined(pvp.fxN2.getOffset())) - { - createPVPType("FXN2", pvp.fxN2, pvpXML); - } - createPVPType("TOA1", pvp.toa1, pvpXML); - createPVPType("TOA2", pvp.toa2, pvpXML); - if (!six::Init::isUndefined(pvp.toaE1.getOffset())) - { - createPVPType("TOAE1", pvp.toaE1, pvpXML); - } - if (!six::Init::isUndefined(pvp.toaE2.getOffset())) - { - createPVPType("TOAE2", pvp.toaE2, pvpXML); - } - createPVPType("TDTropoSRP", pvp.tdTropoSRP, pvpXML); - if (!six::Init::isUndefined(pvp.tdIonoSRP.getOffset())) - { - createPVPType("TDIonoSRP", pvp.tdIonoSRP, pvpXML); - } - createPVPType("SC0", pvp.sc0, pvpXML); - createPVPType("SCSS", pvp.scss, pvpXML); - if (!six::Init::isUndefined(pvp.signal.getOffset())) - { - createPVPType("SIGNAL", pvp.signal, pvpXML); - } - - std::ignore = toXML(pvp.txAntenna, *pvpXML); - std::ignore = toXML(pvp.rcvAntenna, *pvpXML); - - for (auto it = pvp.addedPVP.begin(); it != pvp.addedPVP.end(); ++it) - { - createAPVPType("AddedPVP", it->second, pvpXML); - } - - return pvpXML; -} - -void CPHDXMLParser::createSupportArray(const std::vector& supportArray, - const std::string& tag, xml::lite::Element& parent) -{ - for (auto&& param : supportArray) - { - XMLElem pXML = newElement(tag, &parent); - createInt("Identifier", param.getIdentifier(), pXML); - createString("ElementFormat", param.elementFormat, pXML); - createDouble("X0", param.x0, pXML); - createDouble("Y0", param.y0, pXML); - createDouble("XSS", param.xSS, pXML); - createDouble("YSS", param.ySS, pXML); - - } -} - -//Assumes optional handled by caller -XMLElem CPHDXMLParser::toXML(const SupportArray& supports, XMLElem parent) -{ - XMLElem supportsXML = newElement("SupportArray", parent); - createSupportArray(supports.iazArray, "IAZArray", *supportsXML); - createSupportArray(supports.antGainPhase, "AntGainPhase", *supportsXML); - createSupportArray(supports.dwellTimeArray, "DwellTimeArray", *supportsXML); // added in CPHD 1.1.0 - - if (!supports.addedSupportArray.empty()) - { - for (auto it = supports.addedSupportArray.begin(); it != supports.addedSupportArray.end(); ++it) - { - XMLElem addedSupportArrayXML = newElement("AddedSupportArray", supportsXML); - createString("Identifier", it->first, addedSupportArrayXML); - createString("ElementFormat", it->second.elementFormat, addedSupportArrayXML); - createDouble("X0", it->second.x0, addedSupportArrayXML); - createDouble("Y0", it->second.y0, addedSupportArrayXML); - createDouble("XSS", it->second.xSS, addedSupportArrayXML); - createDouble("YSS", it->second.ySS, addedSupportArrayXML); - createString("XUnits", it->second.xUnits, addedSupportArrayXML); - createString("YUnits", it->second.yUnits, addedSupportArrayXML); - createString("ZUnits", it->second.zUnits, addedSupportArrayXML); - mCommon.addParameters("Parameter", getDefaultURI(), it->second.parameter, addedSupportArrayXML); - } - } - return supportsXML; -} - -XMLElem CPHDXMLParser::toXML(const Dwell& dwell, XMLElem parent) -{ - XMLElem dwellXML = newElement("Dwell", parent); - createInt("NumCODTimes", dwell.cod.size(), dwellXML); - - for (size_t ii = 0; ii < dwell.cod.size(); ++ii) - { - XMLElem codTimeXML = newElement("CODTime", dwellXML); - createString("Identifier", dwell.cod[ii].identifier, codTimeXML); - mCommon.createPoly2D("CODTimePoly", dwell.cod[ii].codTimePoly, codTimeXML); - } - createInt("NumDwellTimes", dwell.dtime.size(), dwellXML); - for (size_t ii = 0; ii < dwell.dtime.size(); ++ii) - { - XMLElem dwellTimeXML = newElement("DwellTime", dwellXML); - createString("Identifier", dwell.dtime[ii].identifier, dwellTimeXML); - mCommon.createPoly2D("DwellTimePoly", dwell.dtime[ii].dwellTimePoly, dwellTimeXML); - } - return dwellXML; -} - -XMLElem CPHDXMLParser::toXML(const ReferenceGeometry& refGeo, XMLElem parent) -{ - XMLElem refGeoXML = newElement("ReferenceGeometry", parent); - XMLElem srpXML = newElement("SRP", refGeoXML); - mCommon.createVector3D("ECF", refGeo.srp.ecf, srpXML); - mCommon.createVector3D("IAC", refGeo.srp.iac, srpXML); - createDouble("ReferenceTime", refGeo.referenceTime, refGeoXML); - createDouble("SRPCODTime", refGeo.srpCODTime, refGeoXML); - createDouble("SRPDwellTime", refGeo.srpDwellTime, refGeoXML); - - if (refGeo.monostatic.get()) - { - XMLElem monoXML = newElement("Monostatic", refGeoXML); - mCommon.createVector3D("ARPPos", refGeo.monostatic->arpPos, monoXML); - mCommon.createVector3D("ARPVel", refGeo.monostatic->arpVel, monoXML); - const auto side = refGeo.monostatic->sideOfTrack.toString(); - createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), monoXML); - createDouble("SlantRange", refGeo.monostatic->slantRange, monoXML); - createDouble("GroundRange", refGeo.monostatic->groundRange, monoXML); - createDouble("DopplerConeAngle", refGeo.monostatic->dopplerConeAngle, monoXML); - createDouble("GrazeAngle", refGeo.monostatic->grazeAngle, monoXML); - createDouble("IncidenceAngle", refGeo.monostatic->incidenceAngle, monoXML); - createDouble("AzimuthAngle", refGeo.monostatic->azimuthAngle, monoXML); - createDouble("TwistAngle", refGeo.monostatic->twistAngle, monoXML); - createDouble("SlopeAngle", refGeo.monostatic->slopeAngle, monoXML); - createDouble("LayoverAngle", refGeo.monostatic->layoverAngle, monoXML); - } - else if(refGeo.bistatic.get()) - { - XMLElem biXML = newElement("Bistatic", refGeoXML); - createDouble("AzimuthAngle", refGeo.bistatic->azimuthAngle, biXML); - createDouble("AzimuthAngleRate", refGeo.bistatic->azimuthAngleRate, biXML); - createDouble("BistaticAngle", refGeo.bistatic->bistaticAngle, biXML); - createDouble("BistaticAngleRate", refGeo.bistatic->bistaticAngleRate, biXML); - createDouble("GrazeAngle", refGeo.bistatic->grazeAngle, biXML); - createDouble("TwistAngle", refGeo.bistatic->twistAngle, biXML); - createDouble("SlopeAngle", refGeo.bistatic->slopeAngle, biXML); - createDouble("LayoverAngle", refGeo.bistatic->layoverAngle, biXML); - XMLElem txPlatXML = newElement("TxPlatform", biXML); - createDouble("Time", refGeo.bistatic->txPlatform.time, txPlatXML); - mCommon.createVector3D("Pos", refGeo.bistatic->txPlatform.pos, txPlatXML); - mCommon.createVector3D("Vel", refGeo.bistatic->txPlatform.vel, txPlatXML); - - { - const auto side = refGeo.bistatic->txPlatform.sideOfTrack.toString(); - createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), txPlatXML); - } - createDouble("SlantRange", refGeo.bistatic->txPlatform.slantRange, txPlatXML); - createDouble("GroundRange", refGeo.bistatic->txPlatform.groundRange, txPlatXML); - createDouble("DopplerConeAngle", refGeo.bistatic->txPlatform.dopplerConeAngle, txPlatXML); - createDouble("GrazeAngle", refGeo.bistatic->txPlatform.grazeAngle, txPlatXML); - createDouble("IncidenceAngle", refGeo.bistatic->txPlatform.incidenceAngle, txPlatXML); - createDouble("AzimuthAngle", refGeo.bistatic->txPlatform.azimuthAngle, txPlatXML); - XMLElem rcvPlatXML = newElement("RcvPlatform", biXML); - createDouble("Time", refGeo.bistatic->rcvPlatform.time, rcvPlatXML); - mCommon.createVector3D("Pos", refGeo.bistatic->rcvPlatform.pos, rcvPlatXML); - mCommon.createVector3D("Vel", refGeo.bistatic->rcvPlatform.vel, rcvPlatXML); - - { - const auto side = refGeo.bistatic->rcvPlatform.sideOfTrack.toString(); - createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), rcvPlatXML); - } - createDouble("SlantRange", refGeo.bistatic->rcvPlatform.slantRange, rcvPlatXML); - createDouble("GroundRange", refGeo.bistatic->rcvPlatform.groundRange, rcvPlatXML); - createDouble("DopplerConeAngle", refGeo.bistatic->rcvPlatform.dopplerConeAngle, rcvPlatXML); - createDouble("GrazeAngle", refGeo.bistatic->rcvPlatform.grazeAngle, rcvPlatXML); - createDouble("IncidenceAngle", refGeo.bistatic->rcvPlatform.incidenceAngle, rcvPlatXML); - createDouble("AzimuthAngle", refGeo.bistatic->rcvPlatform.azimuthAngle, rcvPlatXML); - } - return refGeoXML; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem retval = nullptr; - if (has_value(o)) - { - retval = newElement(o.tag(), &parent); - std::ignore = create(parser(), value(o).dcxsf, *retval); - std::ignore = create(parser(), value(o).dcysf, *retval); - } - - return retval; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem retval = nullptr; - if (has_value(o)) - { - retval = newElement(o.tag(), &parent); - std::ignore = create(parser(), value(o).dcxsf, *retval); - std::ignore = create(parser(), value(o).dcysf, *retval); - } - - return retval; -} - -XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) -{ - XMLElem retval = nullptr; - if (has_value(o)) - { - retval = newElement(o.tag(), &parent); - std::ignore = create(parser(), value(o).ampX, *retval); - std::ignore = create(parser(), value(o).ampY, *retval); - std::ignore = create(parser(), value(o).phaseY, *retval); - } - - return retval; -} - -XMLElem CPHDXMLParser::toXML(const Antenna& antenna, XMLElem parent) -{ - XMLElem antennaXML = newElement("Antenna", parent); - createInt("NumACFs", antenna.antCoordFrame.size(), antennaXML); - createInt("NumAPCs", antenna.antPhaseCenter.size(), antennaXML); - createInt("NumAntPats", antenna.antPattern.size(), antennaXML); - for (size_t ii = 0; ii < antenna.antCoordFrame.size(); ++ii) - { - XMLElem antCoordFrameXML = newElement("AntCoordFrame", antennaXML); - createString("Identifier", antenna.antCoordFrame[ii].identifier, antCoordFrameXML); - mCommon.createPolyXYZ("XAxisPoly", antenna.antCoordFrame[ii].xAxisPoly, antCoordFrameXML); - mCommon.createPolyXYZ("YAxisPoly", antenna.antCoordFrame[ii].yAxisPoly, antCoordFrameXML); - create(parser(), antenna.antCoordFrame[ii].useACFPVP, *antCoordFrameXML); - } - for (size_t ii = 0; ii < antenna.antPhaseCenter.size(); ++ii) - { - XMLElem antPhaseCenterXML = newElement("AntPhaseCenter", antennaXML); - createString("Identifier", antenna.antPhaseCenter[ii].identifier, antPhaseCenterXML); - createString("ACFId", antenna.antPhaseCenter[ii].acfId, antPhaseCenterXML); - mCommon.createVector3D("APCXYZ", antenna.antPhaseCenter[ii].apcXYZ, antPhaseCenterXML); - } - for (size_t ii = 0; ii < antenna.antPattern.size(); ++ii) - { - XMLElem antPatternXML = newElement("AntPattern", antennaXML); - createString("Identifier", antenna.antPattern[ii].identifier, antPatternXML); - createDouble("FreqZero", antenna.antPattern[ii].freqZero, antPatternXML); - createOptionalDouble("GainZero", antenna.antPattern[ii].gainZero, antPatternXML); - if (!six::Init::isUndefined(antenna.antPattern[ii].ebFreqShift)) - { - createBooleanType("EBFreqShift", antenna.antPattern[ii].ebFreqShift, antPatternXML); - } - std::ignore = toXML(antenna.antPattern[ii].ebFreqShiftSF, *antPatternXML); - - if (!six::Init::isUndefined(antenna.antPattern[ii].mlFreqDilation)) - { - createBooleanType("MLFreqDilation", antenna.antPattern[ii].mlFreqDilation, antPatternXML); - } - std::ignore = toXML(antenna.antPattern[ii].mlFreqDilationSF, *antPatternXML); - - if (!six::Init::isUndefined(antenna.antPattern[ii].gainBSPoly)) - { - mCommon.createPoly1D("GainBSPoly", antenna.antPattern[ii].gainBSPoly, antPatternXML); - } - - std::ignore = toXML(antenna.antPattern[ii].antPolRef, *antPatternXML); - - XMLElem ebXML = newElement("EB", antPatternXML); - mCommon.createPoly1D("DCXPoly", antenna.antPattern[ii].eb.dcxPoly, ebXML); - mCommon.createPoly1D("DCYPoly", antenna.antPattern[ii].eb.dcyPoly, ebXML); - create(parser(), antenna.antPattern[ii].eb.useEBPVP, *ebXML); - - XMLElem arrayXML = newElement("Array", antPatternXML); - mCommon.createPoly2D("GainPoly", antenna.antPattern[ii].array.gainPoly, arrayXML); - mCommon.createPoly2D("PhasePoly", antenna.antPattern[ii].array.phasePoly, arrayXML); - create(parser(), antenna.antPattern[ii].array.antGPId, *arrayXML); - - XMLElem elementXML = newElement("Element", antPatternXML); - mCommon.createPoly2D("GainPoly", antenna.antPattern[ii].element.gainPoly, elementXML); - mCommon.createPoly2D("PhasePoly", antenna.antPattern[ii].element.phasePoly, elementXML); - for (size_t jj = 0; jj < antenna.antPattern[ii].gainPhaseArray.size(); ++jj) - { - XMLElem gainPhaseArrayXML = newElement("GainPhaseArray", antPatternXML); - createDouble("Freq", antenna.antPattern[ii].gainPhaseArray[jj].freq, gainPhaseArrayXML); - createString("ArrayId", antenna.antPattern[ii].gainPhaseArray[jj].arrayId, gainPhaseArrayXML); - if (!six::Init::isUndefined(antenna.antPattern[ii].gainPhaseArray[jj].elementId)) - { - createString("ElementId", antenna.antPattern[ii].gainPhaseArray[jj].elementId, gainPhaseArrayXML); - } - } - } - return antennaXML; -} - -XMLElem CPHDXMLParser::toXML(const TxRcv& txRcv, XMLElem parent) -{ - XMLElem txRcvXML = newElement("TxRcv", parent); - createInt("NumTxWFs", txRcv.txWFParameters.size(), txRcvXML); - for (size_t ii = 0; ii < txRcv.txWFParameters.size(); ++ii) - { - XMLElem txWFParamsXML = newElement("TxWFParameters", txRcvXML); - createString("Identifier", txRcv.txWFParameters[ii].identifier, txWFParamsXML); - createDouble("PulseLength", txRcv.txWFParameters[ii].pulseLength, txWFParamsXML); - createDouble("RFBandwidth", txRcv.txWFParameters[ii].rfBandwidth, txWFParamsXML); - createDouble("FreqCenter", txRcv.txWFParameters[ii].freqCenter, txWFParamsXML); - createOptionalDouble("LFMRate", txRcv.txWFParameters[ii].lfmRate, txWFParamsXML); - createString("Polarization", txRcv.txWFParameters[ii].polarization, txWFParamsXML); - createOptionalDouble("Power", txRcv.txWFParameters[ii].power, txWFParamsXML); - } - createInt("NumRcvs", txRcv.rcvParameters.size(), txRcvXML); - for (size_t ii = 0; ii < txRcv.rcvParameters.size(); ++ii) - { - XMLElem rcvParamsXML = newElement("RcvParameters", txRcvXML); - createString("Identifier", txRcv.rcvParameters[ii].identifier, rcvParamsXML); - createDouble("WindowLength", txRcv.rcvParameters[ii].windowLength, rcvParamsXML); - createDouble("SampleRate", txRcv.rcvParameters[ii].sampleRate, rcvParamsXML); - createDouble("IFFilterBW", txRcv.rcvParameters[ii].ifFilterBW, rcvParamsXML); - createDouble("FreqCenter", txRcv.rcvParameters[ii].freqCenter, rcvParamsXML); - createOptionalDouble("LFMRate", txRcv.rcvParameters[ii].lfmRate, rcvParamsXML); - createString("Polarization", txRcv.rcvParameters[ii].polarization, rcvParamsXML); - createOptionalDouble("PathGain", txRcv.rcvParameters[ii].pathGain, rcvParamsXML); - } - return txRcvXML; -} - -XMLElem CPHDXMLParser::toXML(const ErrorParameters& errParams, XMLElem parent) -{ - XMLElem errParamsXML = newElement("ErrorParameters", parent); - if (errParams.monostatic.get()) - { - XMLElem monoXML = newElement("Monostatic", errParamsXML); - XMLElem posVelErrXML = newElement("PosVelErr", monoXML); - createString("Frame", errParams.monostatic->posVelErr.frame, posVelErrXML); - createDouble("P1", errParams.monostatic->posVelErr.p1, posVelErrXML); - createDouble("P2", errParams.monostatic->posVelErr.p2, posVelErrXML); - createDouble("P3", errParams.monostatic->posVelErr.p3, posVelErrXML); - createDouble("V1", errParams.monostatic->posVelErr.v1, posVelErrXML); - createDouble("V2", errParams.monostatic->posVelErr.v2, posVelErrXML); - createDouble("V3", errParams.monostatic->posVelErr.v3, posVelErrXML); - if(errParams.monostatic->posVelErr.corrCoefs.get()) - { - XMLElem corrCoefsXML = newElement("CorrCoefs", posVelErrXML); - createDouble("P1P2", errParams.monostatic->posVelErr.corrCoefs->p1p2, corrCoefsXML); - createDouble("P1P3", errParams.monostatic->posVelErr.corrCoefs->p1p3, corrCoefsXML); - createDouble("P1V1", errParams.monostatic->posVelErr.corrCoefs->p1v1, corrCoefsXML); - createDouble("P1V2", errParams.monostatic->posVelErr.corrCoefs->p1v2, corrCoefsXML); - createDouble("P1V3", errParams.monostatic->posVelErr.corrCoefs->p1v3, corrCoefsXML); - createDouble("P2P3", errParams.monostatic->posVelErr.corrCoefs->p2p3, corrCoefsXML); - createDouble("P2V1", errParams.monostatic->posVelErr.corrCoefs->p2v1, corrCoefsXML); - createDouble("P2V2", errParams.monostatic->posVelErr.corrCoefs->p2v2, corrCoefsXML); - createDouble("P2V3", errParams.monostatic->posVelErr.corrCoefs->p2v3, corrCoefsXML); - createDouble("P3V1", errParams.monostatic->posVelErr.corrCoefs->p3v1, corrCoefsXML); - createDouble("P3V2", errParams.monostatic->posVelErr.corrCoefs->p3v2, corrCoefsXML); - createDouble("P3V3", errParams.monostatic->posVelErr.corrCoefs->p3v3, corrCoefsXML); - createDouble("V1V2", errParams.monostatic->posVelErr.corrCoefs->v1v2, corrCoefsXML); - createDouble("V1V3", errParams.monostatic->posVelErr.corrCoefs->v1v3, corrCoefsXML); - createDouble("V2V3", errParams.monostatic->posVelErr.corrCoefs->v2v3, corrCoefsXML); - } - createDecorrType("PositionDecorr", errParams.monostatic->posVelErr.positionDecorr, posVelErrXML); - - // RadarSensor - XMLElem radarXML = newElement("RadarSensor", monoXML); - createDouble("RangeBias", errParams.monostatic->radarSensor.rangeBias, radarXML); - createOptionalDouble("ClockFreqSF", errParams.monostatic->radarSensor.clockFreqSF, radarXML); - createOptionalDouble("CollectionStartTime", errParams.monostatic->radarSensor.collectionStartTime, radarXML); - if (errParams.monostatic->radarSensor.rangeBiasDecorr.get()) - { - XMLElem rangeBiasDecorrXML = newElement("RangeBiasDecorr", radarXML); - createDouble("CorrCoefZero", errParams.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero, rangeBiasDecorrXML); - createDouble("DecorrRate", errParams.monostatic->radarSensor.rangeBiasDecorr->decorrRate, rangeBiasDecorrXML); - } - - if (errParams.monostatic->tropoError.get()) - { - XMLElem tropoXML = newElement("TropoError", monoXML); - createOptionalDouble("TropoRangeVertical", errParams.monostatic->tropoError->tropoRangeVertical, tropoXML); - createOptionalDouble("TropoRangeSlant", errParams.monostatic->tropoError->tropoRangeSlant, tropoXML); - createDecorrType("TropoRangeDecorr", errParams.monostatic->tropoError->tropoRangeDecorr, tropoXML); - } - if (errParams.monostatic->ionoError.get()) - { - XMLElem ionoXML = newElement("IonoError", monoXML); - createDouble("IonoRangeVertical", errParams.monostatic->ionoError->ionoRangeVertical, ionoXML); - createOptionalDouble("IonoRangeRateVertical", errParams.monostatic->ionoError->ionoRangeRateVertical, ionoXML); - createOptionalDouble("IonoRgRgRateCC", errParams.monostatic->ionoError->ionoRgRgRateCC, ionoXML); - createDecorrType("IonoRangeVertDecorr", errParams.monostatic->tropoError->tropoRangeDecorr, ionoXML); - } - if (!errParams.monostatic->parameter.empty()) - { - XMLElem addedParamsXML = newElement("AddedParameters", monoXML); - mCommon.addParameters("Parameter", getDefaultURI(), errParams.monostatic->parameter, addedParamsXML); - } - } - else if (errParams.bistatic.get()) - { - XMLElem biXML = newElement("Bistatic", errParamsXML); - XMLElem txPlatXML = newElement("TxPlatform", biXML); - createErrorParamPlatform("TxPlatform", errParams.bistatic->txPlatform, txPlatXML); - XMLElem radarTxXML = newElement("RadarSensor", txPlatXML); - create(parser(), errParams.bistatic->txPlatform.radarSensor.delayBias, *radarTxXML); - createOptionalDouble("ClockFreqSF", errParams.bistatic->txPlatform.radarSensor.clockFreqSF, radarTxXML); - createDouble("CollectionStartTime", errParams.bistatic->txPlatform.radarSensor.collectionStartTime, radarTxXML); - - XMLElem rcvPlatXML = newElement("RcvPlatform", biXML); - createErrorParamPlatform("RcvPlatform", errParams.bistatic->rcvPlatform, rcvPlatXML); - XMLElem radarRcvXML = newElement("RadarSensor", rcvPlatXML); - createOptionalDouble("ClockFreqSF", errParams.bistatic->rcvPlatform.radarSensor.clockFreqSF, radarRcvXML); - createDouble("CollectionStartTime", errParams.bistatic->rcvPlatform.radarSensor.collectionStartTime, radarRcvXML); - - if (!errParams.bistatic->parameter.empty()) - { - XMLElem addedParamsXML = newElement("AddedParameters", biXML); - mCommon.addParameters("Parameter", getDefaultURI(), errParams.bistatic->parameter, addedParamsXML); - } - } - - return errParamsXML; -} - -XMLElem CPHDXMLParser::toXML(const ProductInfo& productInfo, XMLElem parent) -{ - XMLElem productInfoXML = newElement("ProductInfo", parent); - if(!six::Init::isUndefined(productInfo.profile)) - { - createString("Profile", productInfo.profile, productInfoXML); - } - for (size_t ii = 0; ii < productInfo.creationInfo.size(); ++ii) - { - XMLElem creationInfoXML = newElement("CreationInfo", productInfoXML); - if(!six::Init::isUndefined(productInfo.creationInfo[ii].application)) - { - createString("Application", productInfo.creationInfo[ii].application, creationInfoXML); - } - createDateTime("DateTime", productInfo.creationInfo[ii].dateTime, creationInfoXML); - if (!six::Init::isUndefined(productInfo.creationInfo[ii].site)) - { - createString("Site", productInfo.creationInfo[ii].site, creationInfoXML); - } - mCommon.addParameters("Parameter", getDefaultURI(), productInfo.creationInfo[ii].parameter, creationInfoXML); - } - mCommon.addParameters("Parameter", getDefaultURI(), productInfo.parameter, productInfoXML); - return productInfoXML; -} - -XMLElem CPHDXMLParser::toXML(const GeoInfo& geoInfo, XMLElem parent) -{ - XMLElem geoInfoXML = newElement("GeoInfo", parent); - - mCommon.addParameters("Desc", geoInfo.desc, geoInfoXML); - - const size_t numLatLons = geoInfo.geometryLatLon.size(); - if (numLatLons == 1) - { - mCommon.createLatLon("Point", geoInfo.geometryLatLon[0], geoInfoXML); - } - else if (numLatLons >= 2) - { - XMLElem linePolyXML = newElement(numLatLons == 2 ? "Line" : "Polygon", - geoInfoXML); - setAttribute(linePolyXML, "size", numLatLons); - - for (size_t ii = 0; ii < numLatLons; ++ii) - { - XMLElem v = mCommon.createLatLon(numLatLons == 2 ? "Endpoint" : "Vertex", - geoInfo.geometryLatLon[ii], linePolyXML); - setAttribute(v, "index", ii + 1); - } - } - - if (!geoInfo.name.empty()) - setAttribute(geoInfoXML, "name", geoInfo.name); - - for (size_t ii = 0; ii < geoInfo.geoInfos.size(); ++ii) - { - toXML(*geoInfo.geoInfos[ii], geoInfoXML); - } - - return geoInfoXML; -} - -XMLElem CPHDXMLParser::toXML(const MatchInformation& matchInfo, XMLElem parent) -{ - return mCommon.convertMatchInformationToXML(matchInfo, parent); -} - -/* - * FROM XML - */ - -std::unique_ptr CPHDXMLParser::fromXML( - const xml::lite::Document* doc) -{ - std::unique_ptr cphd(new Metadata()); - - const auto root = doc->getRootElement(); - - XMLElem collectionIDXML = getFirstAndOnly(root, "CollectionID"); - XMLElem globalXML = getFirstAndOnly(root, "Global"); - XMLElem sceneCoordsXML = getFirstAndOnly(root, "SceneCoordinates"); - XMLElem dataXML = getFirstAndOnly(root, "Data"); - XMLElem channelXML = getFirstAndOnly(root, "Channel"); - XMLElem pvpXML = getFirstAndOnly(root, "PVP"); - XMLElem dwellXML = getFirstAndOnly(root, "Dwell"); - XMLElem refGeoXML = getFirstAndOnly(root, "ReferenceGeometry"); - - XMLElem supportArrayXML = getOptional(root, "SupportArray"); - XMLElem antennaXML = getOptional(root, "Antenna"); - XMLElem txRcvXML = getOptional(root, "TxRcv"); - XMLElem errParamXML = getOptional(root, "ErrorParameters"); - XMLElem productInfoXML = getOptional(root, "ProductInfo"); - std::vector geoInfoXMLVec; - root->getElementsByTagName("GeoInfo", geoInfoXMLVec); - cphd->geoInfo.resize(geoInfoXMLVec.size()); - XMLElem matchInfoXML = getOptional(root, "MatchInfo"); - - // Parse XML for each section - fromXML(collectionIDXML, cphd->collectionID); - fromXML(globalXML, cphd->global); - fromXML(sceneCoordsXML, cphd->sceneCoordinates); - fromXML(dataXML, cphd->data); - fromXML(channelXML, cphd->channel); - fromXML(pvpXML, cphd->pvp); - fromXML(dwellXML, cphd->dwell); - fromXML(refGeoXML, cphd->referenceGeometry); - - if(supportArrayXML) - { - cphd->supportArray.reset(new SupportArray()); - fromXML(supportArrayXML, *(cphd->supportArray)); - } - if(antennaXML) - { - cphd->antenna.reset(new Antenna()); - fromXML(antennaXML, *(cphd->antenna)); - } - if(txRcvXML) - { - cphd->txRcv.reset(new TxRcv()); - fromXML(txRcvXML, *(cphd->txRcv)); - } - if(errParamXML) - { - cphd->errorParameters.reset(new ErrorParameters()); - fromXML(errParamXML, *(cphd->errorParameters)); - } - if(productInfoXML) - { - cphd->productInfo.reset(new ProductInfo()); - fromXML(productInfoXML, *(cphd->productInfo)); - } - for (size_t ii = 0; ii < geoInfoXMLVec.size(); ++ii) - { - fromXML(geoInfoXMLVec[ii], cphd->geoInfo[ii]); - } - if (matchInfoXML) - { - cphd->matchInfo.reset(new MatchInformation()); - fromXML(matchInfoXML, *(cphd->matchInfo)); - } - - return cphd; -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* collectionIDXML, CollectionInformation& collectionID) -{ - parseString(getFirstAndOnly(collectionIDXML, "CollectorName"), - collectionID.collectorName); - - XMLElem element = getOptional(collectionIDXML, "IlluminatorName"); - if (element) - { - parseString(element, collectionID.illuminatorName); - } - - element = getOptional(collectionIDXML, "CoreName"); - if (element) - { - parseString(element, collectionID.coreName); - } - - element = getOptional(collectionIDXML, "CollectType"); - if (element) - { - collectionID.collectType - = six::toType(element->getCharacterData()); - } - - XMLElem radarModeXML = getFirstAndOnly(collectionIDXML, "RadarMode"); - - collectionID.radarMode - = six::toType(getFirstAndOnly(radarModeXML, - "ModeType")->getCharacterData()); - - element = getOptional(radarModeXML, "ModeID"); - if (element) - { - parseString(element, collectionID.radarModeID); - } - - element = getFirstAndOnly(collectionIDXML, "ReleaseInfo"); - parseString(element, collectionID.releaseInfo); - - std::string classification; - parseString(getFirstAndOnly(collectionIDXML, "Classification"), - classification); - collectionID.setClassificationLevel(classification); - - // Optional - std::vector countryCodes; - element = getOptional(collectionIDXML, "CountryCode"); - if (element) - { - std::string countryCodeStr; - parseString(element, countryCodeStr); - collectionID.countryCodes = str::split(countryCodeStr, ","); - for (size_t ii = 0; ii < collectionID.countryCodes.size(); ++ii) - { - str::trim(collectionID.countryCodes[ii]); - } - } - - //optional - mCommon.parseParameters(collectionIDXML, "Parameter", collectionID.parameters); -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* globalXML, Global& global) -{ - global.domainType = DomainType::toType( - getFirstAndOnly(globalXML, "DomainType")->getCharacterData()); - global.sgn = PhaseSGN::toType( - getFirstAndOnly(globalXML, "SGN")->getCharacterData()); - - // Timeline - const xml::lite::Element* timelineXML = getFirstAndOnly(globalXML, "Timeline"); - parseDateTime( - getFirstAndOnly(timelineXML, "CollectionStart"), - global.timeline.collectionStart); - - // Optional - const xml::lite::Element* rcvCollectionXML = getOptional(timelineXML, - "RcvCollectionStart"); - if (rcvCollectionXML) - { - parseDateTime(rcvCollectionXML, - global.timeline.rcvCollectionStart); - } - - parseDouble( - getFirstAndOnly(timelineXML, "TxTime1"), global.timeline.txTime1); - parseDouble( - getFirstAndOnly(timelineXML, "TxTime2"), global.timeline.txTime2); - - // FxBand - const xml::lite::Element* fxBandXML = getFirstAndOnly(globalXML, "FxBand"); - parseDouble(getFirstAndOnly(fxBandXML, "FxMin"), global.fxBand.fxMin); - parseDouble(getFirstAndOnly(fxBandXML, "FxMax"), global.fxBand.fxMax); - - // TOASwath - const xml::lite::Element* toaSwathXML = getFirstAndOnly(globalXML, "TOASwath"); - parseDouble(getFirstAndOnly(toaSwathXML, "TOAMin"), global.toaSwath.toaMin); - parseDouble(getFirstAndOnly(toaSwathXML, "TOAMax"), global.toaSwath.toaMax); - - // TropoParameters - const xml::lite::Element* tropoXML = getOptional(globalXML, "TropoParameters"); - if (tropoXML) - { - // Optional - global.tropoParameters.reset(new TropoParameters()); - parseDouble(getFirstAndOnly(tropoXML, "N0"), global.tropoParameters->n0); - global.tropoParameters->refHeight = - RefHeight::toType(getFirstAndOnly(tropoXML, "RefHeight")->getCharacterData()); - } - - // IonoParameters - if (const auto ionoXML = getOptional(globalXML, "IonoParameters")) - { - // Optional - global.ionoParameters.reset(new IonoParameters()); - parseDouble(getFirstAndOnly(ionoXML, "TECV"), global.ionoParameters->tecv); - if (const auto f2HeightXML = getOptional(ionoXML, "F2Height")) - { - parseDouble(f2HeightXML, global.ionoParameters->f2Height); - } - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* sceneCoordsXML, - SceneCoordinates& scene) -{ - scene.earthModel = EarthModelType::toType( - getFirstAndOnly(sceneCoordsXML, "EarthModel")->getCharacterData()); - - // IARP - const xml::lite::Element* iarpXML = getFirstAndOnly(sceneCoordsXML, "IARP"); - mCommon.parseVector3D(getFirstAndOnly(iarpXML, "ECF"), scene.iarp.ecf); - mCommon.parseLatLonAlt(getFirstAndOnly(iarpXML, "LLH"), scene.iarp.llh); - - // ReferenceSurface - const xml::lite::Element* surfaceXML = getFirstAndOnly(sceneCoordsXML, "ReferenceSurface"); - const xml::lite::Element* planarXML = getOptional(surfaceXML, "Planar"); - const xml::lite::Element* haeXML = getOptional(surfaceXML, "HAE"); - if (planarXML && !haeXML) - { - // Choice type - scene.referenceSurface.planar.reset(new Planar()); - mCommon.parseVector3D(getFirstAndOnly(planarXML, "uIAX"), - scene.referenceSurface.planar->uIax); - mCommon.parseVector3D(getFirstAndOnly(planarXML, "uIAY"), - scene.referenceSurface.planar->uIay); - } - else if (haeXML && !planarXML) - { - // Choice type - scene.referenceSurface.hae.reset(new HAE()); - mCommon.parseLatLon(getFirstAndOnly(haeXML, "uIAXLL"), - scene.referenceSurface.hae->uIax); - mCommon.parseLatLon(getFirstAndOnly(haeXML, "uIAYLL"), - scene.referenceSurface.hae->uIay); - } - else - { - throw except::Exception(Ctxt( - "ReferenceSurface must exactly one of Planar or HAE element")); - } - - // ImageArea - const xml::lite::Element* imageAreaXML = getFirstAndOnly(sceneCoordsXML, "ImageArea"); - parseAreaType(imageAreaXML, scene.imageArea); - - // ImageAreaCorners - const xml::lite::Element* cornersXML = getFirstAndOnly(sceneCoordsXML, - "ImageAreaCornerPoints"); - mCommon.parseFootprint(cornersXML, "IACP", scene.imageAreaCorners); - - // Extended Area - const xml::lite::Element* extendedAreaXML = getOptional(sceneCoordsXML, "ExtendedArea"); - if (extendedAreaXML) - { - scene.extendedArea.reset(new AreaType()); - parseAreaType(extendedAreaXML, *scene.extendedArea); - } - - // Image Grid - const xml::lite::Element* gridXML = getOptional(sceneCoordsXML, "ImageGrid"); - if (gridXML) - { - // Optional - scene.imageGrid.reset(new ImageGrid()); - const xml::lite::Element* identifierXML = getOptional(gridXML, "Identifier"); - if (identifierXML) - { - parseString(identifierXML, scene.imageGrid->identifier); - } - parseLineSample(getFirstAndOnly(gridXML, "IARPLocation"), - scene.imageGrid->iarpLocation); - parseIAExtent(getFirstAndOnly(gridXML, "IAXExtent"), - scene.imageGrid->xExtent); - parseIAExtent(getFirstAndOnly(gridXML, "IAYExtent"), - scene.imageGrid->yExtent); - - // Segment List - const xml::lite::Element* segListXML = getOptional(gridXML, "SegmentList"); - if (segListXML) - { - // Optional - size_t numSegments; - parseUInt(getFirstAndOnly(segListXML, "NumSegments"), numSegments); - scene.imageGrid->segments.resize(numSegments); - - std::vector segmentsXML; - segListXML->getElementsByTagName("Segment", segmentsXML); - - for (size_t ii = 0; ii < segmentsXML.size(); ++ii) - { - const xml::lite::Element* segmentXML = segmentsXML[ii]; - parseString(getFirstAndOnly(segmentXML, "Identifier"), - scene.imageGrid->segments[ii].identifier); - parseInt(getFirstAndOnly(segmentXML, "StartLine"), - scene.imageGrid->segments[ii].startLine); - parseInt(getFirstAndOnly(segmentXML, "StartSample"), - scene.imageGrid->segments[ii].startSample); - parseInt(getFirstAndOnly(segmentXML, "EndLine"), - scene.imageGrid->segments[ii].endLine); - parseInt(getFirstAndOnly(segmentXML, "EndSample"), - scene.imageGrid->segments[ii].endSample); - - const xml::lite::Element* polygonXML = getOptional(segmentXML, - "SegmentPolygon"); - if (polygonXML) - { - // Optional - size_t polygonSize = 0; - sscanf(const_cast(polygonXML)->attribute("size").c_str(), "%zu", &polygonSize); - scene.imageGrid->segments[ii].polygon.resize(polygonSize); - std::vector polyVerticesXMLVec; - polygonXML->getElementsByTagName("SV", polyVerticesXMLVec); - if (scene.imageGrid->segments[ii].polygon.size() != polyVerticesXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect polygon vertices provided")); - } - if (polyVerticesXMLVec.size() < 3) - { - throw except::Exception(Ctxt( - "Polygon must have at least 3 vertices")); - } - std::vector& vertices = - scene.imageGrid->segments[ii].polygon; - vertices.resize(polyVerticesXMLVec.size()); - for (size_t jj = 0; jj < polyVerticesXMLVec.size(); ++jj) - { - size_t tempIdx; - sscanf(polyVerticesXMLVec[jj]->attribute("index").c_str(), "%zu", &tempIdx); - vertices[jj].setIndex(tempIdx); - parseLineSample(polyVerticesXMLVec[jj], vertices[jj]); - } - } - } - } - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* dataXML, Data& data) -{ - const xml::lite::Element* signalXML = getFirstAndOnly(dataXML, "SignalArrayFormat"); - data.signalArrayFormat = SignalArrayFormat::toType(signalXML->getCharacterData()); - - size_t numBytesPVP_temp = 0; - XMLElem numBytesPVPXML = getFirstAndOnly(dataXML, "NumBytesPVP"); - parseUInt(numBytesPVPXML, numBytesPVP_temp); - if(numBytesPVP_temp % 8 != 0) - { - throw except::Exception(Ctxt( - "Number of bytes must be multiple of 8")); - } - data.numBytesPVP = numBytesPVP_temp; - - // Channels - std::vector channelsXML; - dataXML->getElementsByTagName("Channel", channelsXML); - data.channels.resize(channelsXML.size()); - for (size_t ii = 0; ii < channelsXML.size(); ++ii) - { - parseString(getFirstAndOnly(channelsXML[ii], "Identifier"), - data.channels[ii].identifier); - parseUInt(getFirstAndOnly(channelsXML[ii], "NumVectors"), - data.channels[ii].numVectors); - parseUInt(getFirstAndOnly(channelsXML[ii], "NumSamples"), - data.channels[ii].numSamples); - parseUInt(getFirstAndOnly(channelsXML[ii], "SignalArrayByteOffset"), - data.channels[ii].signalArrayByteOffset); - parseUInt(getFirstAndOnly(channelsXML[ii], "PVPArrayByteOffset"), - data.channels[ii].pvpArrayByteOffset); - XMLElem compressionXML = getOptional(channelsXML[ii], "CompressedSignalSize"); - if (compressionXML) - { - parseUInt(compressionXML, data.channels[ii].compressedSignalSize); - } - } - XMLElem compressionXML = getOptional(dataXML, "SignalCompressionID"); - if (compressionXML) - { - parseString(compressionXML, - data.signalCompressionID); - } - - // Support Arrays - std::vector supportsXML; - dataXML->getElementsByTagName("SupportArray", supportsXML); - for (size_t ii = 0; ii < supportsXML.size(); ++ii) - { - std::string id; - size_t offset; - size_t numRows; - size_t numCols; - size_t numBytes; - parseString(getFirstAndOnly(supportsXML[ii], "Identifier"), id); - parseUInt(getFirstAndOnly(supportsXML[ii], "ArrayByteOffset"), offset); - parseUInt(getFirstAndOnly(supportsXML[ii], "NumRows"), numRows); - parseUInt(getFirstAndOnly(supportsXML[ii], "NumCols"), numCols); - parseUInt(getFirstAndOnly(supportsXML[ii], "BytesPerElement"), numBytes); - data.setSupportArray(id, numRows, numCols, numBytes, offset); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* channelXML, Channel& channel) -{ - parseString(getFirstAndOnly(channelXML, "RefChId"), channel.refChId); - parseBooleanType(getFirstAndOnly(channelXML, "FXFixedCPHD"), channel.fxFixedCphd); - parseBooleanType(getFirstAndOnly(channelXML, "TOAFixedCPHD"), channel.toaFixedCphd); - parseBooleanType(getFirstAndOnly(channelXML, "SRPFixedCPHD"), channel.srpFixedCphd); - - std::vector parametersXML; - channelXML->getElementsByTagName("Parameters", parametersXML); - channel.parameters.resize(parametersXML.size()); - for (size_t ii = 0; ii < parametersXML.size(); ++ii) - { - parseChannelParameters(parametersXML[ii], channel.parameters[ii]); - } - - XMLElem addedParametersXML = getOptional(channelXML, "AddedParameters"); - if(addedParametersXML) - { - mCommon.parseParameters(addedParametersXML, "Parameter", channel.addedParameters); - } -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement& v) const -{ - auto& param = value(v).param; - const auto offset = parsePVPType(parent, param); - setOffset(param, offset); -} -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement& v) const -{ - auto& param = value(v).param; - const auto offset = parsePVPType(parent, param); - setOffset(param, offset); -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = TxAntenna{}; - parse(*pXML, value(o).txACX); - parse(*pXML, value(o).txACY); - parse(*pXML, value(o).txEB); - } -} -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = RcvAntenna{}; - parse(*pXML, value(o).rcvACX); - parse(*pXML, value(o).rcvACY); - parse(*pXML, value(o).rcvEB); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* pvpXML, Pvp& pvp) -{ - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxTime"), pvp.txTime); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxPos"), pvp.txPos); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxVel"), pvp.txVel); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvTime"), pvp.rcvTime); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvPos"), pvp.rcvPos); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvVel"), pvp.rcvVel); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "SRPPos"), pvp.srpPos); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFDOP"), pvp.aFDOP); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFRR1"), pvp.aFRR1); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFRR2"), pvp.aFRR2); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "FX1"), pvp.fx1); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "FX2"), pvp.fx2); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TOA1"), pvp.toa1); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TOA2"), pvp.toa2); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "TDTropoSRP"), pvp.tdTropoSRP); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "SC0"), pvp.sc0); - parsePVPType(pvp, getFirstAndOnly(pvpXML, "SCSS"), pvp.scss); - - parseOptionalPVPType(pvpXML, "AmpSF", pvp, pvp.ampSF); - parseOptionalPVPType(pvpXML, "FXN1", pvp, pvp.fxN1); - parseOptionalPVPType(pvpXML, "FXN2", pvp, pvp.fxN2); - parseOptionalPVPType(pvpXML, "TOAE1", pvp, pvp.toaE1); - parseOptionalPVPType(pvpXML, "TOAE2", pvp, pvp.toaE2); - parseOptionalPVPType(pvpXML, "TDIonoSRP", pvp, pvp.tdIonoSRP); - parseOptionalPVPType(pvpXML, "SIGNAL", pvp, pvp.signal); - - parse(*pvpXML, pvp.txAntenna); - parse(*pvpXML, pvp.rcvAntenna); - - std::vector addedParamsXML; - const std::string str = "AddedPVP"; - pvpXML->getElementsByTagName(str, addedParamsXML); - if(addedParamsXML.empty()) - { - return; - } - for (size_t ii = 0; ii < addedParamsXML.size(); ++ii) - { - parsePVPType(pvp, addedParamsXML[ii]); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* DwellXML, - Dwell& dwell) -{ - // CODTime - size_t numCODTimes; - parseUInt(getFirstAndOnly(DwellXML, "NumCODTimes"), numCODTimes); - dwell.cod.resize(numCODTimes); - - std::vector codXMLVec; - DwellXML->getElementsByTagName("CODTime", codXMLVec); - for(size_t ii = 0; ii < codXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(codXMLVec[ii], "Identifier"), dwell.cod[ii].identifier); - mCommon.parsePoly2D(getFirstAndOnly(codXMLVec[ii], "CODTimePoly"), dwell.cod[ii].codTimePoly); - } - - // DwellTime - size_t numDwellTimes = 0; - parseUInt(getFirstAndOnly(DwellXML, "NumDwellTimes"), numDwellTimes); - dwell.dtime.resize(numDwellTimes); - - std::vector dtimeXMLVec; - DwellXML->getElementsByTagName("DwellTime", dtimeXMLVec); - for(size_t ii = 0; ii < dtimeXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(dtimeXMLVec[ii], "Identifier"), dwell.dtime[ii].identifier); - mCommon.parsePoly2D(getFirstAndOnly(dtimeXMLVec[ii], "DwellTimePoly"), dwell.dtime[ii].dwellTimePoly); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* refGeoXML, ReferenceGeometry& refGeo) -{ - XMLElem srpXML = getFirstAndOnly(refGeoXML, "SRP"); - mCommon.parseVector3D(getFirstAndOnly(srpXML, "ECF"), refGeo.srp.ecf); - mCommon.parseVector3D(getFirstAndOnly(srpXML, "IAC"), refGeo.srp.iac); - parseDouble(getFirstAndOnly(refGeoXML, "ReferenceTime"), refGeo.referenceTime); - parseDouble(getFirstAndOnly(refGeoXML, "SRPCODTime"), refGeo.srpCODTime); - parseDouble(getFirstAndOnly(refGeoXML, "SRPDwellTime"), refGeo.srpDwellTime); - - const xml::lite::Element* monoXML = getOptional(refGeoXML, "Monostatic"); - const xml::lite::Element* biXML = getOptional(refGeoXML, "Bistatic"); - if (monoXML && !biXML) - { - refGeo.monostatic.reset(new Monostatic()); - parseCommon(monoXML, (ImagingType*)refGeo.monostatic.get()); - parseDouble(getFirstAndOnly(monoXML, "SlantRange"), refGeo.monostatic->slantRange); - parseDouble(getFirstAndOnly(monoXML, "GroundRange"), refGeo.monostatic->groundRange); - parseDouble(getFirstAndOnly(monoXML, "DopplerConeAngle"), refGeo.monostatic->dopplerConeAngle); - parseDouble(getFirstAndOnly(monoXML, "IncidenceAngle"), refGeo.monostatic->incidenceAngle); - mCommon.parseVector3D(getFirstAndOnly(monoXML, "ARPPos"), refGeo.monostatic->arpPos); - mCommon.parseVector3D(getFirstAndOnly(monoXML, "ARPVel"), refGeo.monostatic->arpVel); - std::string side = ""; - parseString(getFirstAndOnly(monoXML, "SideOfTrack"), side); - refGeo.monostatic->sideOfTrack = (side == "L" ? six::SideOfTrackType::LEFT : six::SideOfTrackType::RIGHT); - - } - else if (!monoXML && biXML) - { - refGeo.bistatic.reset(new Bistatic()); - parseCommon(biXML, (ImagingType*)refGeo.bistatic.get()); - parseDouble(getFirstAndOnly(biXML, "AzimuthAngleRate"), refGeo.bistatic->azimuthAngleRate); - parseDouble(getFirstAndOnly(biXML, "BistaticAngle"), refGeo.bistatic->bistaticAngle); - parseDouble(getFirstAndOnly(biXML, "BistaticAngleRate"), refGeo.bistatic->bistaticAngleRate); - - parsePlatformParams(getFirstAndOnly(biXML, "TxPlatform"), refGeo.bistatic->txPlatform); - parsePlatformParams(getFirstAndOnly(biXML, "RcvPlatform"), refGeo.bistatic->rcvPlatform); - } - else - { - throw except::Exception(Ctxt( - "One of the two types Mono or Bi must be provided")); - } -} - -std::vector CPHDXMLParser::parseSupportArray(const std::string& tag, const xml::lite::Element& parent) const -{ - std::vector elements; - parent.getElementsByTagName(tag, elements); - std::vector supportArray; - supportArray.reserve(elements.size()); - for (const auto& element : elements) - { - SupportArrayParameter param; - parseSupportArrayParameter(element, param, false /*additionalFlag*/); - supportArray.push_back(std::move(param)); - } - return supportArray; -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* supportArrayXML, SupportArray& supportArray) -{ - supportArray.iazArray = parseSupportArray("IAZArray", *supportArrayXML); - supportArray.antGainPhase = parseSupportArray("AntGainPhase", *supportArrayXML); - supportArray.dwellTimeArray = parseSupportArray("DwellTimeArray", *supportArrayXML); - - std::vector addedSupportArrayXMLVec; - supportArrayXML->getElementsByTagName("AddedSupportArray", addedSupportArrayXMLVec); - for (size_t ii = 0; ii < addedSupportArrayXMLVec.size(); ++ii) - { - std::string id; - parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "Identifier"), id); - if (supportArray.addedSupportArray.count(id) == 0) - { - parseSupportArrayParameter(addedSupportArrayXMLVec[ii], supportArray.addedSupportArray[id], true); - parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "XUnits"), supportArray.addedSupportArray[id].xUnits); - parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "YUnits"), supportArray.addedSupportArray[id].yUnits); - parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "ZUnits"), supportArray.addedSupportArray[id].zUnits); - mCommon.parseParameters(addedSupportArrayXMLVec[ii], "Parameter", supportArray.addedSupportArray[id].parameter); - } - else - { - throw except::Exception(Ctxt( - "Support array identifier for support array is not unique: " + id)); - } - } -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = AntPattern::EBFreqShiftSF{}; - six::getFirstAndOnly(parser(), *pXML, value(o).dcxsf); - six::getFirstAndOnly(parser(), *pXML, value(o).dcysf); - } -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = AntPattern::MLFreqDilationSF{}; - six::getFirstAndOnly(parser(), *pXML, value(o).dcxsf); - six::getFirstAndOnly(parser(), *pXML, value(o).dcysf); - } -} - -void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(parent, o.tag())) - { - o = AntPattern::AntPolRef{}; - six::getFirstAndOnly(parser(), *pXML, value(o).ampX); - six::getFirstAndOnly(parser(), *pXML, value(o).ampY); - six::getFirstAndOnly(parser(), *pXML, value(o).phaseY); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* antennaXML, Antenna& antenna) -{ - size_t numACFs = 0; - size_t numAPCs = 0; - size_t numAntPats = 0; - parseUInt(getFirstAndOnly(antennaXML, "NumACFs"), numACFs); - antenna.antCoordFrame.resize(numACFs); - parseUInt(getFirstAndOnly(antennaXML, "NumAPCs"), numAPCs); - antenna.antPhaseCenter.resize(numAPCs); - parseUInt(getFirstAndOnly(antennaXML, "NumAntPats"), numAntPats); - antenna.antPattern.resize(numAntPats); - - // Parse AntCoordFrame - std::vector antCoordFrameXMLVec; - antennaXML->getElementsByTagName("AntCoordFrame", antCoordFrameXMLVec); - if(antenna.antCoordFrame.size() != antCoordFrameXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of AntCoordFrames provided")); - } - for( size_t ii = 0; ii < antCoordFrameXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(antCoordFrameXMLVec[ii], "Identifier"), antenna.antCoordFrame[ii].identifier); - mCommon.parsePolyXYZ(getFirstAndOnly(antCoordFrameXMLVec[ii], "XAxisPoly"), antenna.antCoordFrame[ii].xAxisPoly); - mCommon.parsePolyXYZ(getFirstAndOnly(antCoordFrameXMLVec[ii], "YAxisPoly"), antenna.antCoordFrame[ii].yAxisPoly); - std::ignore = six::parse(parser(), *antCoordFrameXMLVec[ii], antenna.antCoordFrame[ii].useACFPVP); - } - - // Parse AntPhaseCenter - std::vector antPhaseCenterXMLVec; - antennaXML->getElementsByTagName("AntPhaseCenter", antPhaseCenterXMLVec); - if(antenna.antPhaseCenter.size() != antPhaseCenterXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of AntPhaseCenters provided")); - } - for( size_t ii = 0; ii < antPhaseCenterXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(antPhaseCenterXMLVec[ii], "Identifier"), antenna.antPhaseCenter[ii].identifier); - parseString(getFirstAndOnly(antPhaseCenterXMLVec[ii], "ACFId"), antenna.antPhaseCenter[ii].acfId); - mCommon.parseVector3D(getFirstAndOnly(antPhaseCenterXMLVec[ii], "APCXYZ"), antenna.antPhaseCenter[ii].apcXYZ); - } - - std::vector antPatternXMLVec; - antennaXML->getElementsByTagName("AntPattern", antPatternXMLVec); - if(antenna.antPattern.size() != antPatternXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of AntPatterns provided")); - } - for( size_t ii = 0; ii < antPatternXMLVec.size(); ++ii) - { - parseString(getFirstAndOnly(antPatternXMLVec[ii], "Identifier"), antenna.antPattern[ii].identifier); - parseDouble(getFirstAndOnly(antPatternXMLVec[ii], "FreqZero"), antenna.antPattern[ii].freqZero); - parseOptionalDouble(antPatternXMLVec[ii], "GainZero", antenna.antPattern[ii].gainZero); - - XMLElem ebFreqShiftXML = getOptional(antPatternXMLVec[ii], "EBFreqShift"); - if(ebFreqShiftXML) - { - parseBooleanType(ebFreqShiftXML, antenna.antPattern[ii].ebFreqShift); - } - parse(*antPatternXMLVec[ii], antenna.antPattern[ii].ebFreqShiftSF); - - XMLElem mlFreqDilationXML = getOptional(antPatternXMLVec[ii], "MLFreqDilation"); - if(mlFreqDilationXML) - { - parseBooleanType(mlFreqDilationXML, antenna.antPattern[ii].mlFreqDilation); - } - parse(*antPatternXMLVec[ii], antenna.antPattern[ii].mlFreqDilationSF); - - XMLElem gainBSPoly = getOptional(antPatternXMLVec[ii], "GainBSPoly"); - if(gainBSPoly) - { - mCommon.parsePoly1D(gainBSPoly, antenna.antPattern[ii].gainBSPoly); - } - - parse(*antPatternXMLVec[ii], antenna.antPattern[ii].antPolRef); - - // Parse EB - XMLElem ebXML = getFirstAndOnly(antPatternXMLVec[ii], "EB"); - mCommon.parsePoly1D(getFirstAndOnly(ebXML, "DCXPoly"), antenna.antPattern[ii].eb.dcxPoly); - mCommon.parsePoly1D(getFirstAndOnly(ebXML, "DCYPoly"), antenna.antPattern[ii].eb.dcyPoly); - std::ignore = six::parse(parser(), *ebXML, antenna.antPattern[ii].eb.useEBPVP); - - // Parse Array - XMLElem arrayXML = getFirstAndOnly(antPatternXMLVec[ii], "Array"); - mCommon.parsePoly2D(getFirstAndOnly(arrayXML, "GainPoly"), antenna.antPattern[ii].array.gainPoly); - mCommon.parsePoly2D(getFirstAndOnly(arrayXML, "PhasePoly"), antenna.antPattern[ii].array.phasePoly); - - // Parse Element - XMLElem elementXML = getFirstAndOnly(antPatternXMLVec[ii], "Element"); - mCommon.parsePoly2D(getFirstAndOnly(elementXML, "GainPoly"), antenna.antPattern[ii].element.gainPoly); - mCommon.parsePoly2D(getFirstAndOnly(elementXML, "PhasePoly"), antenna.antPattern[ii].element.phasePoly); - std::ignore = six::parse(parser(), *elementXML, antenna.antPattern[ii].element.antGPId); - - // Parse GainPhaseArray - std::vector gainPhaseArrayXMLVec; - antPatternXMLVec[ii]->getElementsByTagName("GainPhaseArray", gainPhaseArrayXMLVec); - antenna.antPattern[ii].gainPhaseArray.resize(gainPhaseArrayXMLVec.size()); - for (size_t jj = 0; jj < gainPhaseArrayXMLVec.size(); ++jj) - { - parseDouble(getFirstAndOnly(gainPhaseArrayXMLVec[jj], "Freq"), antenna.antPattern[ii].gainPhaseArray[jj].freq); - parseString(getFirstAndOnly(gainPhaseArrayXMLVec[jj], "ArrayId"), antenna.antPattern[ii].gainPhaseArray[jj].arrayId); - XMLElem elementIdXML = getOptional(gainPhaseArrayXMLVec[jj], "ElementId"); - if(elementIdXML) - { - parseString(elementIdXML, antenna.antPattern[ii].gainPhaseArray[jj].elementId); - } - - } - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* txRcvXML, TxRcv& txRcv) -{ - size_t numTxWFs = 0; - size_t numRcvs = 0; - parseUInt(getFirstAndOnly(txRcvXML, "NumTxWFs"), numTxWFs); - txRcv.txWFParameters.resize(numTxWFs); - parseUInt(getFirstAndOnly(txRcvXML, "NumRcvs"), numRcvs); - txRcv.rcvParameters.resize(numRcvs); - - std::vector txWFXMLVec; - txRcvXML->getElementsByTagName("TxWFParameters", txWFXMLVec); - if(txRcv.txWFParameters.size() != txWFXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of TxWF parameters provided")); - } - for(size_t ii = 0; ii < txWFXMLVec.size(); ++ii) - { - parseTxRcvParameter(txWFXMLVec[ii], txRcv.txWFParameters[ii]); - parseDouble(getFirstAndOnly(txWFXMLVec[ii], "PulseLength"), txRcv.txWFParameters[ii].pulseLength); - parseDouble(getFirstAndOnly(txWFXMLVec[ii], "RFBandwidth"), txRcv.txWFParameters[ii].rfBandwidth); - parseOptionalDouble(txWFXMLVec[ii], "Power", txRcv.txWFParameters[ii].power); - } - - std::vector rcvXMLVec; - txRcvXML->getElementsByTagName("RcvParameters", rcvXMLVec); - if(txRcv.rcvParameters.size() != rcvXMLVec.size()) - { - throw except::Exception(Ctxt( - "Incorrect number of Rcv parameters provided")); - } - for(size_t ii = 0; ii < rcvXMLVec.size(); ++ii) - { - parseTxRcvParameter(rcvXMLVec[ii], txRcv.rcvParameters[ii]); - parseDouble(getFirstAndOnly(rcvXMLVec[ii], "WindowLength"), txRcv.rcvParameters[ii].windowLength); - parseDouble(getFirstAndOnly(rcvXMLVec[ii], "SampleRate"), txRcv.rcvParameters[ii].sampleRate); - parseDouble(getFirstAndOnly(rcvXMLVec[ii], "IFFilterBW"), txRcv.rcvParameters[ii].ifFilterBW); - parseOptionalDouble(rcvXMLVec[ii], "PathGain", txRcv.rcvParameters[ii].pathGain); - } - -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* errParamXML, ErrorParameters& errParam) -{ - XMLElem monostaticXML = getOptional(errParamXML, "Monostatic"); - XMLElem bistaticXML = getOptional(errParamXML, "Bistatic"); - - if(monostaticXML && !bistaticXML) - { - errParam.monostatic.reset(new ErrorParameters::Monostatic()); - parsePosVelErr(getFirstAndOnly(monostaticXML, "PosVelErr"), errParam.monostatic->posVelErr); - - XMLElem radarSensorXML = getFirstAndOnly(monostaticXML, "RadarSensor"); - parseDouble(getFirstAndOnly(radarSensorXML, "RangeBias"), errParam.monostatic->radarSensor.rangeBias); - - parseOptionalDouble(radarSensorXML, "ClockFreqSF", errParam.monostatic->radarSensor.clockFreqSF); - parseOptionalDouble(radarSensorXML, "CollectionStartTime", errParam.monostatic->radarSensor.collectionStartTime); - - XMLElem rangeBiasDecorrXML = getOptional(radarSensorXML, "RangeBiasDecorr"); - if(rangeBiasDecorrXML) - { - errParam.monostatic->radarSensor.rangeBiasDecorr.reset(new six::DecorrType()); - mCommon.parseDecorrType(rangeBiasDecorrXML, *(errParam.monostatic->radarSensor.rangeBiasDecorr)); - } - - XMLElem tropoErrorXML = getOptional(monostaticXML, "TropoError"); - if(tropoErrorXML) - { - errParam.monostatic->tropoError.reset(new six::TropoError()); - parseOptionalDouble(tropoErrorXML, "TropoRangeVertical", errParam.monostatic->tropoError->tropoRangeVertical); - parseOptionalDouble(tropoErrorXML, "TropoRangeSlant", errParam.monostatic->tropoError->tropoRangeSlant); - mCommon.parseOptionalDecorrType(tropoErrorXML, "TropoRangeDecorr", errParam.monostatic->tropoError->tropoRangeDecorr); - } - - XMLElem ionoErrorXML = getOptional(monostaticXML, "IonoError"); - if(ionoErrorXML) - { - errParam.monostatic->ionoError.reset(new six::IonoError()); - parseDouble(getFirstAndOnly(ionoErrorXML, "IonoRangeVertical"), errParam.monostatic->ionoError->ionoRangeVertical); - - parseOptionalDouble(ionoErrorXML, "IonoRangeRateVertical", errParam.monostatic->ionoError->ionoRangeRateVertical); - parseOptionalDouble(ionoErrorXML, "IonoRgRgRateCC", errParam.monostatic->ionoError->ionoRgRgRateCC); - mCommon.parseOptionalDecorrType(ionoErrorXML, "IonoRangeVertDecorr", errParam.monostatic->ionoError->ionoRangeVertDecorr); - } - mCommon.parseParameters(monostaticXML, "Parameter", errParam.monostatic->parameter); - } - else if(!monostaticXML && bistaticXML) - { - errParam.bistatic.reset(new ErrorParameters::Bistatic()); - parsePlatform(getFirstAndOnly(bistaticXML, "TxPlatform"), errParam.bistatic->txPlatform); - parsePlatform(getFirstAndOnly(bistaticXML, "RcvPlatform"), errParam.bistatic->rcvPlatform); - mCommon.parseParameters(bistaticXML, "Parameter", errParam.bistatic->parameter); - } - else - { - throw except::Exception(Ctxt( - "Must be one of monostatic or bistatic")); - } -} - - -void CPHDXMLParser::fromXML(const xml::lite::Element* productInfoXML, ProductInfo& productInfo) -{ - XMLElem profileXML = getOptional(productInfoXML, "Profile"); - if(profileXML) - { - parseString(profileXML, productInfo.profile); - } - - std::vector creationInfoXML; - productInfoXML->getElementsByTagName("CreationInfo", creationInfoXML); - productInfo.creationInfo.resize(creationInfoXML.size()); - - for (size_t ii = 0; ii < creationInfoXML.size(); ++ii) - { - XMLElem applicationXML = getOptional(creationInfoXML[ii], "Application"); - if(applicationXML) - { - parseString(applicationXML, productInfo.creationInfo[ii].application); - } - - parseDateTime(getFirstAndOnly(creationInfoXML[ii], "DateTime"), productInfo.creationInfo[ii].dateTime); - - XMLElem siteXML = getOptional(creationInfoXML[ii], "Site"); - if(siteXML) - { - parseString(siteXML, productInfo.creationInfo[ii].site); - } - mCommon.parseParameters(creationInfoXML[ii], "Parameter", productInfo.creationInfo[ii].parameter); - } - mCommon.parseParameters(productInfoXML, "Parameter", productInfo.parameter); - -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* geoInfoXML, GeoInfo& geoInfo) -{ - std::vector < XMLElem > geoInfosXML; - geoInfoXML->getElementsByTagName("GeoInfo", geoInfosXML); - geoInfo.name = geoInfoXML->getAttributes().getValue("name"); - - //optional - mCommon.parseParameters(geoInfoXML, "Desc", geoInfo.desc); - - XMLElem tmpElem = getOptional(geoInfoXML, "Point"); - if (tmpElem) - { - LatLon ll; - mCommon.parseLatLon(tmpElem, ll); - geoInfo.geometryLatLon.push_back(ll); - } - else - { - std::string pointName = "Endpoint"; - tmpElem = getOptional(geoInfoXML, "Line"); - if (!tmpElem) - { - pointName = "Vertex"; - tmpElem = getOptional(geoInfoXML, "Polygon"); - } - if (tmpElem) - { - mCommon.parseLatLons(tmpElem, pointName, geoInfo.geometryLatLon); - } - } - - //optional - size_t idx(geoInfo.geoInfos.size()); - geoInfo.geoInfos.resize(idx + geoInfosXML.size()); - - for (auto it = geoInfosXML.begin(); it - != geoInfosXML.end(); ++it, ++idx) - { - geoInfo.geoInfos[idx].reset(new GeoInfo()); - fromXML(*it, *geoInfo.geoInfos[idx]); - } -} - -void CPHDXMLParser::fromXML(const xml::lite::Element* matchInfoXML, MatchInformation& matchInfo) -{ - mCommon.parseMatchInformationFromXML(matchInfoXML, &matchInfo); -} - - -XMLElem CPHDXMLParser::createLatLonFootprint(const std::string& name, - const std::string& cornerName, - const cphd::LatLonCorners& corners, - XMLElem parent) const -{ - XMLElem footprint = newElement(name, parent); - - // Write the corners in CW order - XMLElem vertex = - mCommon.createLatLon(cornerName, corners.upperLeft, footprint); - setAttribute(vertex, "index", "1"); - - vertex = mCommon.createLatLon(cornerName, corners.upperRight, footprint); - setAttribute(vertex, "index", "2"); - - vertex = mCommon.createLatLon(cornerName, corners.lowerRight, footprint); - setAttribute(vertex, "index", "3"); - - vertex = mCommon.createLatLon(cornerName, corners.lowerLeft, footprint); - setAttribute(vertex, "index", "4"); - - return footprint; -} - -XMLElem CPHDXMLParser::createPVPType(const std::string& name, - const PVPType& p, - XMLElem parent) const -{ - XMLElem pvpXML = newElement(name, parent); - createInt("Offset", p.getOffset(), pvpXML); - createInt("Size", p.getSize(), pvpXML); - createString("Format", p.getFormat(), pvpXML); - return pvpXML; -} - -XMLElem CPHDXMLParser::createAPVPType(const std::string& name, - const APVPType& p, - XMLElem parent) const -{ - XMLElem apvpXML = newElement(name, parent); - createString("Name", p.getName(), apvpXML); - createInt("Offset", p.getOffset(), apvpXML); - createInt("Size", p.getSize(), apvpXML); - createString("Format", p.getFormat(), apvpXML); - return apvpXML; -} - -XMLElem CPHDXMLParser::createErrorParamPlatform( - const std::string& /*name*/, - const ErrorParameters::Bistatic::Platform p, - XMLElem parent) const -{ - XMLElem posVelErrXML = newElement("PosVelErr", parent); - createString("Frame", p.posVelErr.frame, posVelErrXML); - createDouble("P1", p.posVelErr.p1, posVelErrXML); - createDouble("P2", p.posVelErr.p2, posVelErrXML); - createDouble("P3", p.posVelErr.p3, posVelErrXML); - createDouble("V1", p.posVelErr.v1, posVelErrXML); - createDouble("V2", p.posVelErr.v2, posVelErrXML); - createDouble("V3", p.posVelErr.v3, posVelErrXML); - if(p.posVelErr.corrCoefs.get()) - { - XMLElem corrCoefsXML = newElement("CorrCoefs", posVelErrXML); - createDouble("P1P2", p.posVelErr.corrCoefs->p1p2, corrCoefsXML); - createDouble("P1P3", p.posVelErr.corrCoefs->p1p3, corrCoefsXML); - createDouble("P1V1", p.posVelErr.corrCoefs->p1v1, corrCoefsXML); - createDouble("P1V2", p.posVelErr.corrCoefs->p1v2, corrCoefsXML); - createDouble("P1V3", p.posVelErr.corrCoefs->p1v3, corrCoefsXML); - createDouble("P2P3", p.posVelErr.corrCoefs->p2p3, corrCoefsXML); - createDouble("P2V1", p.posVelErr.corrCoefs->p2v1, corrCoefsXML); - createDouble("P2V2", p.posVelErr.corrCoefs->p2v2, corrCoefsXML); - createDouble("P2V3", p.posVelErr.corrCoefs->p2v3, corrCoefsXML); - createDouble("P3V1", p.posVelErr.corrCoefs->p3v1, corrCoefsXML); - createDouble("P3V2", p.posVelErr.corrCoefs->p3v2, corrCoefsXML); - createDouble("P3V3", p.posVelErr.corrCoefs->p3v3, corrCoefsXML); - createDouble("V1V2", p.posVelErr.corrCoefs->v1v2, corrCoefsXML); - createDouble("V1V3", p.posVelErr.corrCoefs->v1v3, corrCoefsXML); - createDouble("V2V3", p.posVelErr.corrCoefs->v2v3, corrCoefsXML); - } - createDecorrType("PositionDecorr", p.posVelErr.positionDecorr, posVelErrXML); - return posVelErrXML; -} - -XMLElem CPHDXMLParser::createDecorrType(const std::string& name, const six::DecorrType& dt, - XMLElem parent) const -{ - if (six::Init::isDefined(dt)) - { - XMLElem element = newElement(name, parent); - createDouble("CorrCoefZero", dt.corrCoefZero, element); - createDouble("DecorrRate", dt.decorrRate, element); - return element; - } - return nullptr; -} -XMLElem CPHDXMLParser::createDecorrType(const std::string& name, const std::optional& dt, - XMLElem parent) const -{ - if (dt.has_value()) - { - return createDecorrType(name, *dt, parent); - } - return nullptr; -} - -/* - * Parser helper functions - */ -void CPHDXMLParser::parseAreaType(const xml::lite::Element* areaXML, AreaType& area) const -{ - mCommon.parseVector2D(getFirstAndOnly(areaXML, "X1Y1"), area.x1y1); - mCommon.parseVector2D(getFirstAndOnly(areaXML, "X2Y2"), area.x2y2); - const xml::lite::Element* polygonXML = getOptional(areaXML, "Polygon"); - if (polygonXML) - { - std::vector verticesXML; - polygonXML->getElementsByTagName("Vertex", verticesXML); - if (verticesXML.size() < 3) - { - throw except::Exception(Ctxt( - "Polygons must have at least 3 sides")); - } - area.polygon.resize(verticesXML.size()); - for (size_t ii = 0; ii < area.polygon.size(); ++ii) - { - Vector2& vertex = area.polygon[ii]; - const xml::lite::Element* vertexXML = verticesXML[ii]; - mCommon.parseVector2D(vertexXML, vertex); - } - } -} - -void CPHDXMLParser::parseLineSample(const xml::lite::Element* lsXML, LineSample& ls) const -{ - parseDouble(getFirstAndOnly(lsXML, "Line"), ls.line); - parseDouble(getFirstAndOnly(lsXML, "Sample"), ls.sample); -} - -void CPHDXMLParser::parseIAExtent(const xml::lite::Element* extentXML, - ImageAreaXExtent& extent) const -{ - parseDouble(getFirstAndOnly(extentXML, "LineSpacing"), - extent.lineSpacing); - parseInt(getFirstAndOnly(extentXML, "FirstLine"), - extent.firstLine); - parseUInt(getFirstAndOnly(extentXML, "NumLines"), - extent.numLines); -} - -void CPHDXMLParser::parseIAExtent(const xml::lite::Element* extentXML, - ImageAreaYExtent& extent) const -{ - parseDouble(getFirstAndOnly(extentXML, "SampleSpacing"), - extent.sampleSpacing); - parseInt(getFirstAndOnly(extentXML, "FirstSample"), - extent.firstSample); - parseUInt(getFirstAndOnly(extentXML, "NumSamples"), - extent.numSamples); -} - -void CPHDXMLParser::parseChannelParameters( - const xml::lite::Element* paramXML, ChannelParameter& param) const -{ - parseString(getFirstAndOnly(paramXML, "Identifier"), param.identifier); - parseUInt(getFirstAndOnly(paramXML, "RefVectorIndex"), param.refVectorIndex); - parseBooleanType(getFirstAndOnly(paramXML, "FXFixed"), param.fxFixed); - parseBooleanType(getFirstAndOnly(paramXML, "TOAFixed"), param.toaFixed); - parseBooleanType(getFirstAndOnly(paramXML, "SRPFixed"), param.srpFixed); - - XMLElem signalXML = getOptional(paramXML, "SignalNormal"); - if (signalXML) - { - parseBooleanType(signalXML, param.signalNormal); - } - - parseDouble(getFirstAndOnly(paramXML, "FxC"), param.fxC); - parseDouble(getFirstAndOnly(paramXML, "FxBW"), param.fxBW); - parseOptionalDouble(paramXML, "FxBWNoise", param.fxBWNoise); - parseDouble(getFirstAndOnly(paramXML, "TOASaved"), param.toaSaved); - - XMLElem toaExtendedXML = getOptional(paramXML, "TOAExtended"); - if(toaExtendedXML) - { - param.toaExtended.reset(new TOAExtended()); - parseDouble(getFirstAndOnly(toaExtendedXML, "TOAExtSaved"), param.toaExtended->toaExtSaved); - XMLElem lfmEclipseXML = getOptional(toaExtendedXML, "LFMEclipse"); - if(lfmEclipseXML) - { - param.toaExtended->lfmEclipse.reset(new TOAExtended::LFMEclipse()); - parseDouble(getFirstAndOnly(lfmEclipseXML, "FxEarlyLow"), param.toaExtended->lfmEclipse->fxEarlyLow); - parseDouble(getFirstAndOnly(lfmEclipseXML, "FxEarlyHigh"), param.toaExtended->lfmEclipse->fxEarlyHigh); - parseDouble(getFirstAndOnly(lfmEclipseXML, "FxLateLow"), param.toaExtended->lfmEclipse->fxLateLow); - parseDouble(getFirstAndOnly(lfmEclipseXML, "FxLateHigh"), param.toaExtended->lfmEclipse->fxLateHigh); - } - } - - XMLElem dwellTimesXML = getFirstAndOnly(paramXML, "DwellTimes"); - parseString(getFirstAndOnly(dwellTimesXML, "CODId"), param.dwellTimes.codId); - parseString(getFirstAndOnly(dwellTimesXML, "DwellId"), param.dwellTimes.dwellId); - std::ignore = six::parse(parser(), *dwellTimesXML, param.dwellTimes.dtaId); - std::ignore = six::parse(parser(), *dwellTimesXML, param.dwellTimes.useDTA); - - XMLElem imageAreaXML = getOptional(paramXML, "ImageArea"); - if(imageAreaXML) - { - parseAreaType(imageAreaXML, param.imageArea); - } - - XMLElem antennaXML = getOptional(paramXML, "Antenna"); - if(antennaXML) - { - param.antenna.reset(new ChannelParameter::Antenna()); - parseString(getFirstAndOnly(antennaXML, "TxAPCId"), param.antenna->txAPCId); - parseString(getFirstAndOnly(antennaXML, "TxAPATId"), param.antenna->txAPATId); - parseString(getFirstAndOnly(antennaXML, "RcvAPCId"), param.antenna->rcvAPCId); - parseString(getFirstAndOnly(antennaXML, "RcvAPATId"), param.antenna->rcvAPATId); - } - - XMLElem txRcvXML = getOptional(paramXML, "TxRcv"); - if(txRcvXML) - { - std::vector txWFIdXML; - txRcvXML->getElementsByTagName("TxWFId", txWFIdXML); - param.txRcv.reset(new ChannelParameter::TxRcv()); - param.txRcv->txWFId.resize(txWFIdXML.size()); - for(size_t ii = 0; ii < txWFIdXML.size(); ++ii) - { - parseString(txWFIdXML[ii], param.txRcv->txWFId[ii]); - } - - std::vector rcvIdXML; - txRcvXML->getElementsByTagName("RcvId", rcvIdXML); - param.txRcv->rcvId.resize(rcvIdXML.size()); - for(size_t ii = 0; ii < rcvIdXML.size(); ++ii) - { - parseString(rcvIdXML[ii], param.txRcv->rcvId[ii]); - } - } - - XMLElem tgtRefLevelXML = getOptional(paramXML, "TgtRefLevel"); - if(tgtRefLevelXML) - { - param.tgtRefLevel.reset(new TgtRefLevel()); - parseDouble(getFirstAndOnly(tgtRefLevelXML, "PTRef"), param.tgtRefLevel->ptRef); - } - - XMLElem noiseLevelXML = getOptional(paramXML, "NoiseLevel"); - if(noiseLevelXML) - { - param.noiseLevel.reset(new NoiseLevel()); - parseDouble(getFirstAndOnly(noiseLevelXML, "PNRef"), param.noiseLevel->pnRef); - parseDouble(getFirstAndOnly(noiseLevelXML, "BNRef"), param.noiseLevel->bnRef); - if(!(param.noiseLevel->bnRef > 0 && param.noiseLevel->bnRef <= 1)) - { - throw except::Exception(Ctxt( - "Noise equivalent BW value must be > 0.0 and <= 1.0")); - } - - XMLElem fxNoiseProfileXML = getOptional(noiseLevelXML, "FxNoiseProfile"); - if(fxNoiseProfileXML) - { - param.noiseLevel->fxNoiseProfile.reset(new FxNoiseProfile()); - std::vector pointXMLVec; - fxNoiseProfileXML->getElementsByTagName("Point", pointXMLVec); - if(pointXMLVec.size() < 2) - { - throw except::Exception(Ctxt( - "Atleast 2 noise profile points must be provided")); - } - param.noiseLevel->fxNoiseProfile->point.resize(pointXMLVec.size()); - double prevPoint = six::Init::undefined(); - for(size_t ii = 0; ii < pointXMLVec.size(); ++ii) - { - double fx; - parseDouble(getFirstAndOnly(pointXMLVec[ii], "Fx"), fx); - parseDouble(getFirstAndOnly(pointXMLVec[ii], "PN"), param.noiseLevel->fxNoiseProfile->point[ii].pn); - - if(!six::Init::isUndefined(prevPoint) && fx <= prevPoint) - { - throw except::Exception(Ctxt( - "Fx values are strictly increasing")); - } - param.noiseLevel->fxNoiseProfile->point[ii].fx = fx; - prevPoint = fx; - } - } - } - - // Polarization - parsePolarization(*paramXML, param.polarization); -} - -void CPHDXMLParser::parse(const xml::lite::Element& polarizationXML, six::XsElement_minOccurs0& o) const -{ - if (const auto pXML = getOptional(polarizationXML, o.tag())) - { - o = PolRef{}; - six::getFirstAndOnly(parser(), *pXML, value(o).ampH); - six::getFirstAndOnly(parser(), *pXML, value(o).ampV); - six::getFirstAndOnly(parser(), *pXML, value(o).phaseV); - } -} - -void CPHDXMLParser::parsePolarization(const xml::lite::Element& paramXML, Polarization& polarization) const -{ - std::vector PolarizationXML; - paramXML.getElementsByTagName("Polarization", PolarizationXML); - for (size_t ii = 0; ii < PolarizationXML.size(); ++ii) - { - const xml::lite::Element* TxPolXML = getFirstAndOnly(PolarizationXML[ii], "TxPol"); - polarization.txPol = PolarizationType::toType(TxPolXML->getCharacterData()); - - const xml::lite::Element* RcvPolXML = getFirstAndOnly(PolarizationXML[ii], "RcvPol"); - polarization.rcvPol = PolarizationType::toType(RcvPolXML->getCharacterData()); - - parse(*(PolarizationXML[ii]), polarization.txPolRef); // added in CPHD 1.1.0 - parse(*(PolarizationXML[ii]), polarization.rcvPolRef); // added in CPHD 1.1.0 - } -} - -size_t CPHDXMLParser::parsePVPType(const xml::lite::Element& paramXML, PVPType& param) const -{ - size_t size; - size_t offset; - std::string format; - parseUInt(getFirstAndOnly(paramXML, "Size"), size); - parseUInt(getFirstAndOnly(paramXML, "Offset"), offset); - parseString(getFirstAndOnly(paramXML, "Format"), format); - if (param.getSize() != size) - { - std::ostringstream ostr; - ostr << "Specified size: " << size << " does not match default size: " << param.getSize(); - throw except::Exception(Ctxt(ostr.str())); - } - if (param.getFormat() != format) - { - std::ostringstream ostr; - ostr << "Specified format: " << format << " does not match default format: " << param.getFormat(); - throw except::Exception(Ctxt(ostr.str())); - } - return offset; -} -void CPHDXMLParser::parsePVPType(Pvp& pvp, const xml::lite::Element* paramXML, PVPType& param) const -{ - const auto offset = parsePVPType(*paramXML, param); - pvp.setOffset(offset, param); -} - -void CPHDXMLParser::parsePVPType(Pvp& pvp, const xml::lite::Element* paramXML) const -{ - std::string name; - size_t size; - size_t offset; - std::string format; - parseString(getFirstAndOnly(paramXML, "Name"), name); - parseUInt(getFirstAndOnly(paramXML, "Size"), size); - parseUInt(getFirstAndOnly(paramXML, "Offset"), offset); - parseString(getFirstAndOnly(paramXML, "Format"), format); - pvp.setCustomParameter(size, offset, format, name); -} - -bool CPHDXMLParser::parseOptionalPVPType(const xml::lite::Element* parent, const std::string& tag, Pvp& pvp, PVPType& param) const -{ - if (const xml::lite::Element* const element = getOptional(parent, tag)) - { - parsePVPType(pvp, element, param); - return true; - } - return false; -} - -void CPHDXMLParser::parsePlatformParams(const xml::lite::Element* platXML, Bistatic::PlatformParams& plat) const -{ - parseDouble(getFirstAndOnly(platXML, "Time"), plat.time); - parseDouble(getFirstAndOnly(platXML, "SlantRange"), plat.slantRange); - parseDouble(getFirstAndOnly(platXML, "GroundRange"), plat.groundRange); - parseDouble(getFirstAndOnly(platXML, "DopplerConeAngle"), plat.dopplerConeAngle); - parseDouble(getFirstAndOnly(platXML, "AzimuthAngle"), plat.azimuthAngle); - parseDouble(getFirstAndOnly(platXML, "GrazeAngle"), plat.grazeAngle); - parseDouble(getFirstAndOnly(platXML, "IncidenceAngle"), plat.incidenceAngle); - mCommon.parseVector3D(getFirstAndOnly(platXML, "Pos"), plat.pos); - mCommon.parseVector3D(getFirstAndOnly(platXML, "Vel"), plat.vel); - std::string side = ""; - parseString(getFirstAndOnly(platXML, "SideOfTrack"), side); - plat.sideOfTrack = (side == "L" ? six::SideOfTrackType::LEFT : six::SideOfTrackType::RIGHT); - -} - -void CPHDXMLParser::parseCommon(const xml::lite::Element* imgTypeXML, ImagingType* imgType) const -{ - parseDouble(getFirstAndOnly(imgTypeXML, "TwistAngle"), imgType->twistAngle); - parseDouble(getFirstAndOnly(imgTypeXML, "SlopeAngle"), imgType->slopeAngle); - parseDouble(getFirstAndOnly(imgTypeXML, "LayoverAngle"), imgType->layoverAngle); - parseDouble(getFirstAndOnly(imgTypeXML, "AzimuthAngle"), imgType->azimuthAngle); - parseDouble(getFirstAndOnly(imgTypeXML, "GrazeAngle"), imgType->grazeAngle); -} - -void CPHDXMLParser::parsePosVelErr(const xml::lite::Element* posVelErrXML, six::PosVelError& posVelErr) const -{ - std::string frameStr; - parseString(getFirstAndOnly(posVelErrXML, "Frame"), frameStr); - posVelErr.frame.mValue = scene::FrameType::fromString(frameStr); - parseDouble(getFirstAndOnly(posVelErrXML, "P1"), posVelErr.p1); - parseDouble(getFirstAndOnly(posVelErrXML, "P2"), posVelErr.p2); - parseDouble(getFirstAndOnly(posVelErrXML, "P3"), posVelErr.p3); - parseDouble(getFirstAndOnly(posVelErrXML, "V1"), posVelErr.v1); - parseDouble(getFirstAndOnly(posVelErrXML, "V2"), posVelErr.v2); - parseDouble(getFirstAndOnly(posVelErrXML, "V3"), posVelErr.v3); - - XMLElem corrCoefsXML = getOptional(posVelErrXML, "CorrCoefs"); - - if(corrCoefsXML) - { - posVelErr.corrCoefs.reset(new six::CorrCoefs()); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1P2"), posVelErr.corrCoefs->p1p2); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1P3"), posVelErr.corrCoefs->p1p3); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1V1"), posVelErr.corrCoefs->p1v1); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1V2"), posVelErr.corrCoefs->p1v2); - parseDouble(getFirstAndOnly(corrCoefsXML, "P1V3"), posVelErr.corrCoefs->p1v3); - parseDouble(getFirstAndOnly(corrCoefsXML, "P2P3"), posVelErr.corrCoefs->p2p3); - parseDouble(getFirstAndOnly(corrCoefsXML, "P2V1"), posVelErr.corrCoefs->p2v1); - parseDouble(getFirstAndOnly(corrCoefsXML, "P2V2"), posVelErr.corrCoefs->p2v2); - parseDouble(getFirstAndOnly(corrCoefsXML, "P2V3"), posVelErr.corrCoefs->p2v3); - parseDouble(getFirstAndOnly(corrCoefsXML, "P3V1"), posVelErr.corrCoefs->p3v1); - parseDouble(getFirstAndOnly(corrCoefsXML, "P3V2"), posVelErr.corrCoefs->p3v2); - parseDouble(getFirstAndOnly(corrCoefsXML, "P3V3"), posVelErr.corrCoefs->p3v3); - parseDouble(getFirstAndOnly(corrCoefsXML, "V1V2"), posVelErr.corrCoefs->v1v2); - parseDouble(getFirstAndOnly(corrCoefsXML, "V1V3"), posVelErr.corrCoefs->v1v3); - parseDouble(getFirstAndOnly(corrCoefsXML, "V2V3"), posVelErr.corrCoefs->v2v3); - } - - // posVelErr.positionDecorr.reset(new six::DecorrType()); - mCommon.parseOptionalDecorrType(posVelErrXML, "PositionDecorr", posVelErr.positionDecorr); -} - -void CPHDXMLParser::parsePlatform(const xml::lite::Element* platXML, ErrorParameters::Bistatic::Platform& plat) const -{ - parsePosVelErr(getFirstAndOnly(platXML, "PosVelErr"), plat.posVelErr); - XMLElem radarSensorXML = getFirstAndOnly(platXML, "RadarSensor"); - six::parse(parser(), *radarSensorXML, plat.radarSensor.delayBias); - parseOptionalDouble(radarSensorXML, "ClockFreqSF", plat.radarSensor.clockFreqSF); - parseDouble(getFirstAndOnly(radarSensorXML, "CollectionStartTime"), plat.radarSensor.collectionStartTime); -} - -void CPHDXMLParser::parseSupportArrayParameter(const xml::lite::Element* paramXML, SupportArrayParameter& param, bool additionalFlag) const -{ - if(!additionalFlag) - { - size_t identifierVal; - parseUInt(getFirstAndOnly(paramXML, "Identifier"), identifierVal); - param.setIdentifier(identifierVal); - } - parseString(getFirstAndOnly(paramXML, "ElementFormat"), param.elementFormat); - parseDouble(getFirstAndOnly(paramXML, "X0"), param.x0); - parseDouble(getFirstAndOnly(paramXML, "Y0"), param.y0); - parseDouble(getFirstAndOnly(paramXML, "XSS"), param.xSS); - parseDouble(getFirstAndOnly(paramXML, "YSS"), param.ySS); -} - -void CPHDXMLParser::parseTxRcvParameter(const xml::lite::Element* paramXML, ParameterType& param) const -{ - parseString(getFirstAndOnly(paramXML, "Identifier"), param.identifier); - parseDouble(getFirstAndOnly(paramXML, "FreqCenter"), param.freqCenter); - parseOptionalDouble(paramXML, "LFMRate", param.lfmRate); - param.polarization = PolarizationType::toType(getFirstAndOnly(paramXML, "Polarization")->getCharacterData()); -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define ENFORCESPEC 0 + +namespace +{ +typedef xml::lite::Element* XMLElem; +} + +namespace cphd +{ + +CPHDXMLParser::CPHDXMLParser( + const std::string& uri, + bool addClassAttributes, + logging::Logger* log, + bool ownLog) : + six::XMLParser(uri, addClassAttributes, log, ownLog), + mCommon(getDefaultURI(), addClassAttributes, getDefaultURI(), log) +{ +} + +/* + * TO XML + */ +std::unique_ptr CPHDXMLParser::toXML( + const Metadata& metadata) +{ + std::unique_ptr doc(new xml::lite::Document()); + + XMLElem root = newElement("CPHD"); + doc->setRootElement(root); + + toXML(metadata.collectionID, root); + toXML(metadata.global, root); + toXML(metadata.sceneCoordinates, root); + toXML(metadata.data, root); + toXML(metadata.channel, root); + toXML(metadata.pvp, root); + toXML(metadata.dwell, root); + toXML(metadata.referenceGeometry, root); + + if (metadata.supportArray.get()) + { + toXML(*(metadata.supportArray), root); + } + if (metadata.antenna.get()) + { + toXML(*(metadata.antenna), root); + } + if (metadata.txRcv.get()) + { + toXML(*(metadata.txRcv), root); + } + if (metadata.errorParameters.get()) + { + toXML(*(metadata.errorParameters), root); + } + if (metadata.productInfo.get()) + { + toXML(*(metadata.productInfo), root); + } + for (const auto& geoInfo : metadata.geoInfo) + { + toXML(geoInfo, root); + } + if (metadata.matchInfo.get()) + { + toXML(*(metadata.matchInfo), root); + } + + //set the XMLNS + root->setNamespacePrefix("", getDefaultURI()); + + return doc; +} + +XMLElem CPHDXMLParser::toXML(const CollectionInformation& collectionID, XMLElem parent) +{ + XMLElem collectionXML = newElement("CollectionID", parent); + + createString("CollectorName", collectionID.collectorName, collectionXML); + if(!six::Init::isUndefined(collectionID.illuminatorName)) + { + createString("IlluminatorName", collectionID.illuminatorName, collectionXML); + } + createString("CoreName", collectionID.coreName, collectionXML); + createString("CollectType", collectionID.collectType, collectionXML); + + // RadarMode + XMLElem radarModeXML = newElement("RadarMode", collectionXML); + createSixString("ModeType", collectionID.radarMode, radarModeXML); + if(!six::Init::isUndefined(collectionID.radarModeID)) + { + createString("ModeID", collectionID.radarModeID, radarModeXML); + } + createString("Classification", collectionID.getClassificationLevel(), collectionXML); + createString("ReleaseInfo", collectionID.releaseInfo, collectionXML); + if (!collectionID.countryCodes.empty()) + { + std::string countryCodes = str::join(collectionID.countryCodes, ","); + createString("CountryCode", countryCodes, collectionXML); + } + mCommon.addParameters("Parameter", getDefaultURI(), collectionID.parameters, collectionXML); + return collectionXML; +} + +XMLElem CPHDXMLParser::toXML(const Global& global, XMLElem parent) +{ + XMLElem globalXML = newElement("Global", parent); + createString("DomainType", global.domainType, globalXML); + createString("SGN", global.sgn, globalXML); + + //Timeline + XMLElem timelineXML = newElement("Timeline", globalXML); + createDateTime("CollectionStart", global.timeline.collectionStart, timelineXML); + if (!six::Init::isUndefined(global.timeline.rcvCollectionStart)) + { + createDateTime("RcvCollectionStart", global.timeline.rcvCollectionStart, timelineXML); + } + createDouble("TxTime1", global.timeline.txTime1, timelineXML); + createDouble("TxTime2", global.timeline.txTime2, timelineXML); + + XMLElem fxBandXML = newElement("FxBand", globalXML); + createDouble("FxMin", global.fxBand.fxMin, fxBandXML); + createDouble("FxMax", global.fxBand.fxMax, fxBandXML); + + XMLElem toaSwathXML = newElement("TOASwath", globalXML); + createDouble("TOAMin", global.toaSwath.toaMin, toaSwathXML); + createDouble("TOAMax", global.toaSwath.toaMax, toaSwathXML); + + if (global.tropoParameters.get()) + { + XMLElem tropoXML = newElement("TropoParameters", globalXML); + createDouble("N0", global.tropoParameters->n0, tropoXML); + createString("RefHeight", global.tropoParameters->refHeight, tropoXML); + } + if (global.ionoParameters.get()) + { + XMLElem ionoXML = newElement("IonoParameters", globalXML); + createDouble("TECV", global.ionoParameters->tecv, ionoXML); + createOptionalDouble("F2Height", global.ionoParameters->f2Height, ionoXML); + } + return globalXML; +} + +XMLElem CPHDXMLParser::toXML(const SceneCoordinates& sceneCoords, XMLElem parent) +{ + XMLElem sceneCoordsXML = newElement("SceneCoordinates", parent); + createString("EarthModel", sceneCoords.earthModel, sceneCoordsXML); + + XMLElem iarpXML = newElement("IARP", sceneCoordsXML); + mCommon.createVector3D("ECF", sceneCoords.iarp.ecf, iarpXML); + mCommon.createLatLonAlt("LLH", sceneCoords.iarp.llh, iarpXML); + + XMLElem refSurfXML = newElement("ReferenceSurface", sceneCoordsXML); + if (sceneCoords.referenceSurface.planar.get()) + { + XMLElem planarXML = newElement("Planar", refSurfXML); + mCommon.createVector3D("uIAX", sceneCoords.referenceSurface.planar->uIax, planarXML); + mCommon.createVector3D("uIAY", sceneCoords.referenceSurface.planar->uIay, planarXML); + } + else if (sceneCoords.referenceSurface.hae.get()) + { + XMLElem haeXML = newElement("HAE", refSurfXML); + mCommon.createLatLon("uIAXLL", sceneCoords.referenceSurface.hae->uIax, haeXML); + mCommon.createLatLon("uIAYLL", sceneCoords.referenceSurface.hae->uIay, haeXML); + } + else + { + throw except::Exception(Ctxt( + "Reference Surface must be one of two types")); + } + + XMLElem imageAreaXML = newElement("ImageArea", sceneCoordsXML); + mCommon.createVector2D("X1Y1", sceneCoords.imageArea.x1y1, imageAreaXML); + mCommon.createVector2D("X2Y2", sceneCoords.imageArea.x2y2, imageAreaXML); + + if (!sceneCoords.imageArea.polygon.empty()) + { + XMLElem polygonXML = newElement("Polygon", imageAreaXML); + setAttribute(polygonXML, "size", sceneCoords.imageArea.polygon.size()); + for (size_t ii = 0; ii < sceneCoords.imageArea.polygon.size(); ++ii) + { + XMLElem vertexXML = mCommon.createVector2D("Vertex", sceneCoords.imageArea.polygon[ii], polygonXML); + setAttribute(vertexXML, "index", ii+1); + } + } + createLatLonFootprint("ImageAreaCornerPoints", "IACP", sceneCoords.imageAreaCorners, sceneCoordsXML); + + // Extended Area (Optional) + if(sceneCoords.extendedArea.get()) + { + XMLElem extendedAreaXML = newElement("ExtendedArea", sceneCoordsXML); + mCommon.createVector2D("X1Y1", sceneCoords.extendedArea->x1y1, extendedAreaXML); + mCommon.createVector2D("X2Y2", sceneCoords.extendedArea->x2y2, extendedAreaXML); + + if (!sceneCoords.extendedArea->polygon.empty()) + { + XMLElem polygonXML = newElement("Polygon", sceneCoordsXML); + setAttribute(polygonXML, "size", sceneCoords.extendedArea->polygon.size()); + for (size_t ii = 0; ii < sceneCoords.extendedArea->polygon.size(); ++ii) + { + XMLElem vertexXML = mCommon.createVector2D("Vertex", sceneCoords.extendedArea->polygon[ii], polygonXML); + setAttribute(vertexXML, "index", ii+1); + } + } + } + + // ImageGrid (Optional) + if(sceneCoords.imageGrid.get()) + { + XMLElem imageGridXML = newElement("ImageGrid", sceneCoordsXML); + if(!six::Init::isUndefined(sceneCoords.imageGrid->identifier)) + { + createString("Identifier", sceneCoords.imageGrid->identifier, imageGridXML); + } + XMLElem iarpLocationXML = newElement("IARPLocation", imageGridXML); + createDouble("Line", sceneCoords.imageGrid->iarpLocation.line, iarpLocationXML); + createDouble("Sample", sceneCoords.imageGrid->iarpLocation.sample, iarpLocationXML); + + XMLElem iaxExtentXML = newElement("IAXExtent", imageGridXML); + createDouble("LineSpacing", sceneCoords.imageGrid->xExtent.lineSpacing, iaxExtentXML); + createInt("FirstLine", sceneCoords.imageGrid->xExtent.firstLine, iaxExtentXML); + createInt("NumLines", sceneCoords.imageGrid->xExtent.numLines, iaxExtentXML); + + XMLElem iayExtentXML = newElement("IAYExtent", imageGridXML); + createDouble("SampleSpacing", sceneCoords.imageGrid->yExtent.sampleSpacing, iayExtentXML); + createInt("FirstSample", sceneCoords.imageGrid->yExtent.firstSample, iayExtentXML); + createInt("NumSamples", sceneCoords.imageGrid->yExtent.numSamples, iayExtentXML); + + if (!sceneCoords.imageGrid->segments.empty()) + { + XMLElem segmentListXML = newElement("SegmentList", imageGridXML); + createInt("NumSegments", sceneCoords.imageGrid->segments.size(), segmentListXML); + + for (size_t ii = 0; ii < sceneCoords.imageGrid->segments.size(); ++ii) + { + XMLElem segmentXML = newElement("Segment", segmentListXML); + createString("Identifier", sceneCoords.imageGrid->segments[ii].identifier, segmentXML); + createInt("StartLine", sceneCoords.imageGrid->segments[ii].startLine, segmentXML); + createInt("StartSample", sceneCoords.imageGrid->segments[ii].startSample, segmentXML); + createInt("EndLine", sceneCoords.imageGrid->segments[ii].endLine, segmentXML); + createInt("EndSample", sceneCoords.imageGrid->segments[ii].endSample, segmentXML); + + if (!sceneCoords.imageGrid->segments[ii].polygon.empty()) + { + XMLElem polygonXML = newElement("SegmentPolygon", segmentXML); + setAttribute(polygonXML, "size", sceneCoords.imageGrid->segments[ii].polygon.size()); + for (size_t jj = 0; jj < sceneCoords.imageGrid->segments[ii].polygon.size(); ++jj) + { + XMLElem svXML = newElement("SV", polygonXML); + setAttribute(svXML, "index", sceneCoords.imageGrid->segments[ii].polygon[jj].getIndex()); + createDouble("Line", sceneCoords.imageGrid->segments[ii].polygon[jj].line, svXML); + createDouble("Sample", sceneCoords.imageGrid->segments[ii].polygon[jj].sample, svXML); + } + } + } + } + } + return sceneCoordsXML; +} + +XMLElem CPHDXMLParser::toXML(const Data& data, XMLElem parent) +{ + XMLElem dataXML = newElement("Data", parent); + createString("SignalArrayFormat", data.signalArrayFormat, dataXML); + createInt("NumBytesPVP", data.numBytesPVP, dataXML); + createInt("NumCPHDChannels", data.channels.size(), dataXML); + if (!six::Init::isUndefined(data.signalCompressionID)) + { + createString("SignalCompressionID", data.signalCompressionID, dataXML); + } + + for (size_t ii = 0; ii < data.channels.size(); ++ii) + { + XMLElem channelXML = newElement("Channel", dataXML); + createString("Identifier", data.channels[ii].identifier, channelXML); + createInt("NumVectors", data.channels[ii].numVectors, channelXML); + createInt("NumSamples", data.channels[ii].numSamples, channelXML); + createInt("SignalArrayByteOffset", data.channels[ii].signalArrayByteOffset, channelXML); + createInt("PVPArrayByteOffset", data.channels[ii].pvpArrayByteOffset, channelXML); + if(!six::Init::isUndefined(data.channels[ii].compressedSignalSize)) + { + createInt("CompressedSignalSize", data.channels[ii].compressedSignalSize, channelXML); + } + } + createInt("NumSupportArrays", data.supportArrayMap.size(), dataXML); + for (const auto& entry : data.supportArrayMap) + { + XMLElem supportArrayXML = newElement("SupportArray", dataXML); + createString("Identifier", entry.second.identifier, supportArrayXML); + createInt("NumRows", entry.second.numRows, supportArrayXML); + createInt("NumCols", entry.second.numCols, supportArrayXML); + createInt("BytesPerElement", entry.second.bytesPerElement, supportArrayXML); + createInt("ArrayByteOffset", entry.second.arrayByteOffset, supportArrayXML); + } + return dataXML; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem pXML = nullptr; + if (has_value(o)) + { + pXML = newElement(o.tag(), &parent); + std::ignore = create(parser(), value(o).ampH, *pXML); + std::ignore = create(parser(), value(o).ampV, *pXML); + std::ignore = create(parser(), value(o).phaseV, *pXML); + } + + return pXML; +} + +XMLElem CPHDXMLParser::toXML(const Polarization& obj, xml::lite::Element& parent) +{ + auto polXML = newElement("Polarization", &parent); + createString("TxPol", obj.txPol, polXML); + createString("RcvPol", obj.rcvPol, polXML); + + toXML(obj.txPolRef, *polXML); // added in CPHD 1.1.0 + toXML(obj.rcvPolRef, *polXML); // added in CPHD 1.1.0 + + return polXML; +} + +XMLElem CPHDXMLParser::toXML(const Channel& channel, XMLElem parent) +{ + XMLElem channelXML = newElement("Channel", parent); + createString("RefChId", channel.refChId, channelXML); + createBooleanType("FXFixedCPHD", channel.fxFixedCphd, channelXML); + createBooleanType("TOAFixedCPHD", channel.toaFixedCphd, channelXML); + createBooleanType("SRPFixedCPHD", channel.srpFixedCphd, channelXML); + + for (size_t ii = 0; ii < channel.parameters.size(); ++ii) + { + XMLElem parametersXML = newElement("Parameters", channelXML); + createString("Identifier", channel.parameters[ii].identifier, parametersXML); + createInt("RefVectorIndex", channel.parameters[ii].refVectorIndex, parametersXML); + createBooleanType("FXFixed", channel.parameters[ii].fxFixed, parametersXML); + createBooleanType("TOAFixed", channel.parameters[ii].toaFixed, parametersXML); + createBooleanType("SRPFixed", channel.parameters[ii].srpFixed, parametersXML); + if (!six::Init::isUndefined(channel.parameters[ii].signalNormal)) + { + createBooleanType("SignalNormal", channel.parameters[ii].signalNormal, parametersXML); + } + std::ignore = toXML(channel.parameters[ii].polarization, *parametersXML); + + createDouble("FxC", channel.parameters[ii].fxC, parametersXML); + createDouble("FxBW", channel.parameters[ii].fxBW, parametersXML); + createOptionalDouble("FxBWNoise", channel.parameters[ii].fxBWNoise, parametersXML); + createDouble("TOASaved", channel.parameters[ii].toaSaved, parametersXML); + + if(channel.parameters[ii].toaExtended.get()) + { + XMLElem toaExtendedXML = newElement("TOAExtended", parametersXML); + createDouble("TOAExtSaved", channel.parameters[ii].toaExtended->toaExtSaved, toaExtendedXML); + if(channel.parameters[ii].toaExtended->lfmEclipse.get()) + { + XMLElem lfmEclipseXML = newElement("LFMEclipse", toaExtendedXML); + createDouble("FxEarlyLow", channel.parameters[ii].toaExtended->lfmEclipse->fxEarlyLow, lfmEclipseXML); + createDouble("FxEarlyHigh", channel.parameters[ii].toaExtended->lfmEclipse->fxEarlyHigh, lfmEclipseXML); + createDouble("FxLateLow", channel.parameters[ii].toaExtended->lfmEclipse->fxLateLow, lfmEclipseXML); + createDouble("FxLateHigh", channel.parameters[ii].toaExtended->lfmEclipse->fxLateHigh, lfmEclipseXML); + } + } + XMLElem dwellTimesXML = newElement("DwellTimes", parametersXML); + createString("CODId", channel.parameters[ii].dwellTimes.codId, dwellTimesXML); + createString("DwellId", channel.parameters[ii].dwellTimes.dwellId, dwellTimesXML); + std::ignore = create(parser(), channel.parameters[ii].dwellTimes.dtaId, *dwellTimesXML); + std::ignore = create(parser(), channel.parameters[ii].dwellTimes.useDTA, *dwellTimesXML); + + if(!six::Init::isUndefined(channel.parameters[ii].imageArea)) + { + XMLElem imageAreaXML = newElement("ImageArea", parametersXML); + mCommon.createVector2D("X1Y1", channel.parameters[ii].imageArea.x1y1, imageAreaXML); + mCommon.createVector2D("X2Y2", channel.parameters[ii].imageArea.x2y2, imageAreaXML); + if(!channel.parameters[ii].imageArea.polygon.empty()) + { + XMLElem polygonXML = newElement("Polygon", imageAreaXML); + setAttribute(polygonXML, "size", channel.parameters[ii].imageArea.polygon.size()); + for (size_t jj = 0; jj < channel.parameters[ii].imageArea.polygon.size(); ++jj) + { + XMLElem vertexXML = mCommon.createVector2D("Vertex", channel.parameters[ii].imageArea.polygon[jj], polygonXML); + setAttribute(vertexXML, "index", jj+1); + } + } + } + if(channel.parameters[ii].antenna.get()) + { + XMLElem antennaXML = newElement("Antenna", parametersXML); + createString("TxAPCId", channel.parameters[ii].antenna->txAPCId, antennaXML); + createString("TxAPATId", channel.parameters[ii].antenna->txAPATId, antennaXML); + createString("RcvAPCId", channel.parameters[ii].antenna->rcvAPCId, antennaXML); + createString("RcvAPATId", channel.parameters[ii].antenna->rcvAPATId, antennaXML); + } + if(channel.parameters[ii].txRcv.get()) + { + XMLElem txRcvXML = newElement("TxRcv", parametersXML); + for (size_t jj = 0; jj < channel.parameters[ii].txRcv->txWFId.size(); ++jj) + { + createString("TxWFId", channel.parameters[ii].txRcv->txWFId[jj], txRcvXML); + } + for (size_t jj = 0; jj < channel.parameters[ii].txRcv->rcvId.size(); ++jj) + { + createString("RcvId", channel.parameters[ii].txRcv->rcvId[jj], txRcvXML); + } + } + if(channel.parameters[ii].tgtRefLevel.get()) + { + XMLElem tgtRefXML = newElement("TgtRefLevel", parametersXML); + createDouble("PTRef", channel.parameters[ii].tgtRefLevel->ptRef, tgtRefXML); + } + if(channel.parameters[ii].noiseLevel.get()) + { + XMLElem noiseLevelXML = newElement("NoiseLevel", parametersXML); + createDouble("PNRef", channel.parameters[ii].noiseLevel->pnRef, noiseLevelXML); + createDouble("BNRef", channel.parameters[ii].noiseLevel->bnRef, noiseLevelXML); + if(channel.parameters[ii].noiseLevel->fxNoiseProfile.get()) + { + XMLElem fxNoiseProfileXML = newElement("FxNoiseProfile", noiseLevelXML); + for (size_t jj = 0; jj < channel.parameters[ii].noiseLevel->fxNoiseProfile->point.size(); ++jj) + { + XMLElem pointXML = newElement("Point", fxNoiseProfileXML); + createDouble("Fx", channel.parameters[ii].noiseLevel->fxNoiseProfile->point[jj].fx, pointXML); + createDouble("PN", channel.parameters[ii].noiseLevel->fxNoiseProfile->point[jj].pn, pointXML); + } + } + } + } + if(!channel.addedParameters.empty()) + { + XMLElem addedParamsXML = newElement("AddedParameters", channelXML); + mCommon.addParameters("Parameter", getDefaultURI(), channel.addedParameters, addedParamsXML); + } + return channelXML; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement& v, xml::lite::Element& parent) +{ + return createPVPType(v.tag(), v.value().param, &parent); +} +XMLElem CPHDXMLParser::toXML(const six::XsElement& v, xml::lite::Element& parent) +{ + return createPVPType(v.tag(), v.value().param, &parent); +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem pXML = nullptr; + if (has_value(o)) + { + pXML = newElement(o.tag(), &parent); + std::ignore = toXML(value(o).txACX, *pXML); + std::ignore = toXML(value(o).txACY, *pXML); + std::ignore = toXML(value(o).txEB, *pXML); + } + + return pXML; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem pXML = nullptr; + if (has_value(o)) + { + pXML = newElement(o.tag(), &parent); + std::ignore = toXML(value(o).rcvACX, *pXML); + std::ignore = toXML(value(o).rcvACY, *pXML); + std::ignore = toXML(value(o).rcvEB, *pXML); + } + + return pXML; +} + +XMLElem CPHDXMLParser::toXML(const Pvp& pvp, XMLElem parent) +{ + XMLElem pvpXML = newElement("PVP", parent); + createPVPType("TxTime", pvp.txTime, pvpXML); + createPVPType("TxPos", pvp.txPos, pvpXML); + createPVPType("TxVel", pvp.txVel, pvpXML); + createPVPType("RcvTime", pvp.rcvTime, pvpXML); + createPVPType("RcvPos", pvp.rcvPos, pvpXML); + createPVPType("RcvVel", pvp.rcvVel, pvpXML); + createPVPType("SRPPos", pvp.srpPos, pvpXML); + if (!six::Init::isUndefined(pvp.ampSF.getOffset())) + { + createPVPType("AmpSF", pvp.ampSF, pvpXML); + } + createPVPType("aFDOP", pvp.aFDOP, pvpXML); + createPVPType("aFRR1", pvp.aFRR1, pvpXML); + createPVPType("aFRR2", pvp.aFRR2, pvpXML); + createPVPType("FX1", pvp.fx1, pvpXML); + createPVPType("FX2", pvp.fx2, pvpXML); + if (!six::Init::isUndefined(pvp.fxN1.getOffset())) + { + createPVPType("FXN1", pvp.fxN1, pvpXML); + } + if (!six::Init::isUndefined(pvp.fxN2.getOffset())) + { + createPVPType("FXN2", pvp.fxN2, pvpXML); + } + createPVPType("TOA1", pvp.toa1, pvpXML); + createPVPType("TOA2", pvp.toa2, pvpXML); + if (!six::Init::isUndefined(pvp.toaE1.getOffset())) + { + createPVPType("TOAE1", pvp.toaE1, pvpXML); + } + if (!six::Init::isUndefined(pvp.toaE2.getOffset())) + { + createPVPType("TOAE2", pvp.toaE2, pvpXML); + } + createPVPType("TDTropoSRP", pvp.tdTropoSRP, pvpXML); + if (!six::Init::isUndefined(pvp.tdIonoSRP.getOffset())) + { + createPVPType("TDIonoSRP", pvp.tdIonoSRP, pvpXML); + } + createPVPType("SC0", pvp.sc0, pvpXML); + createPVPType("SCSS", pvp.scss, pvpXML); + if (!six::Init::isUndefined(pvp.signal.getOffset())) + { + createPVPType("SIGNAL", pvp.signal, pvpXML); + } + + std::ignore = toXML(pvp.txAntenna, *pvpXML); + std::ignore = toXML(pvp.rcvAntenna, *pvpXML); + + for (auto it = pvp.addedPVP.begin(); it != pvp.addedPVP.end(); ++it) + { + createAPVPType("AddedPVP", it->second, pvpXML); + } + + return pvpXML; +} + +void CPHDXMLParser::createSupportArray(const std::vector& supportArray, + const std::string& tag, xml::lite::Element& parent) +{ + for (auto&& param : supportArray) + { + XMLElem pXML = newElement(tag, &parent); + createInt("Identifier", param.getIdentifier(), pXML); + createString("ElementFormat", param.elementFormat, pXML); + createDouble("X0", param.x0, pXML); + createDouble("Y0", param.y0, pXML); + createDouble("XSS", param.xSS, pXML); + createDouble("YSS", param.ySS, pXML); + + } +} + +//Assumes optional handled by caller +XMLElem CPHDXMLParser::toXML(const SupportArray& supports, XMLElem parent) +{ + XMLElem supportsXML = newElement("SupportArray", parent); + createSupportArray(supports.iazArray, "IAZArray", *supportsXML); + createSupportArray(supports.antGainPhase, "AntGainPhase", *supportsXML); + createSupportArray(supports.dwellTimeArray, "DwellTimeArray", *supportsXML); // added in CPHD 1.1.0 + + if (!supports.addedSupportArray.empty()) + { + for (auto it = supports.addedSupportArray.begin(); it != supports.addedSupportArray.end(); ++it) + { + XMLElem addedSupportArrayXML = newElement("AddedSupportArray", supportsXML); + createString("Identifier", it->first, addedSupportArrayXML); + createString("ElementFormat", it->second.elementFormat, addedSupportArrayXML); + createDouble("X0", it->second.x0, addedSupportArrayXML); + createDouble("Y0", it->second.y0, addedSupportArrayXML); + createDouble("XSS", it->second.xSS, addedSupportArrayXML); + createDouble("YSS", it->second.ySS, addedSupportArrayXML); + createString("XUnits", it->second.xUnits, addedSupportArrayXML); + createString("YUnits", it->second.yUnits, addedSupportArrayXML); + createString("ZUnits", it->second.zUnits, addedSupportArrayXML); + mCommon.addParameters("Parameter", getDefaultURI(), it->second.parameter, addedSupportArrayXML); + } + } + return supportsXML; +} + +XMLElem CPHDXMLParser::toXML(const Dwell& dwell, XMLElem parent) +{ + XMLElem dwellXML = newElement("Dwell", parent); + createInt("NumCODTimes", dwell.cod.size(), dwellXML); + + for (size_t ii = 0; ii < dwell.cod.size(); ++ii) + { + XMLElem codTimeXML = newElement("CODTime", dwellXML); + createString("Identifier", dwell.cod[ii].identifier, codTimeXML); + mCommon.createPoly2D("CODTimePoly", dwell.cod[ii].codTimePoly, codTimeXML); + } + createInt("NumDwellTimes", dwell.dtime.size(), dwellXML); + for (size_t ii = 0; ii < dwell.dtime.size(); ++ii) + { + XMLElem dwellTimeXML = newElement("DwellTime", dwellXML); + createString("Identifier", dwell.dtime[ii].identifier, dwellTimeXML); + mCommon.createPoly2D("DwellTimePoly", dwell.dtime[ii].dwellTimePoly, dwellTimeXML); + } + return dwellXML; +} + +XMLElem CPHDXMLParser::toXML(const ReferenceGeometry& refGeo, XMLElem parent) +{ + XMLElem refGeoXML = newElement("ReferenceGeometry", parent); + XMLElem srpXML = newElement("SRP", refGeoXML); + mCommon.createVector3D("ECF", refGeo.srp.ecf, srpXML); + mCommon.createVector3D("IAC", refGeo.srp.iac, srpXML); + createDouble("ReferenceTime", refGeo.referenceTime, refGeoXML); + createDouble("SRPCODTime", refGeo.srpCODTime, refGeoXML); + createDouble("SRPDwellTime", refGeo.srpDwellTime, refGeoXML); + + if (refGeo.monostatic.get()) + { + XMLElem monoXML = newElement("Monostatic", refGeoXML); + mCommon.createVector3D("ARPPos", refGeo.monostatic->arpPos, monoXML); + mCommon.createVector3D("ARPVel", refGeo.monostatic->arpVel, monoXML); + const auto side = refGeo.monostatic->sideOfTrack.toString(); + createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), monoXML); + createDouble("SlantRange", refGeo.monostatic->slantRange, monoXML); + createDouble("GroundRange", refGeo.monostatic->groundRange, monoXML); + createDouble("DopplerConeAngle", refGeo.monostatic->dopplerConeAngle, monoXML); + createDouble("GrazeAngle", refGeo.monostatic->grazeAngle, monoXML); + createDouble("IncidenceAngle", refGeo.monostatic->incidenceAngle, monoXML); + createDouble("AzimuthAngle", refGeo.monostatic->azimuthAngle, monoXML); + createDouble("TwistAngle", refGeo.monostatic->twistAngle, monoXML); + createDouble("SlopeAngle", refGeo.monostatic->slopeAngle, monoXML); + createDouble("LayoverAngle", refGeo.monostatic->layoverAngle, monoXML); + } + else if(refGeo.bistatic.get()) + { + XMLElem biXML = newElement("Bistatic", refGeoXML); + createDouble("AzimuthAngle", refGeo.bistatic->azimuthAngle, biXML); + createDouble("AzimuthAngleRate", refGeo.bistatic->azimuthAngleRate, biXML); + createDouble("BistaticAngle", refGeo.bistatic->bistaticAngle, biXML); + createDouble("BistaticAngleRate", refGeo.bistatic->bistaticAngleRate, biXML); + createDouble("GrazeAngle", refGeo.bistatic->grazeAngle, biXML); + createDouble("TwistAngle", refGeo.bistatic->twistAngle, biXML); + createDouble("SlopeAngle", refGeo.bistatic->slopeAngle, biXML); + createDouble("LayoverAngle", refGeo.bistatic->layoverAngle, biXML); + XMLElem txPlatXML = newElement("TxPlatform", biXML); + createDouble("Time", refGeo.bistatic->txPlatform.time, txPlatXML); + mCommon.createVector3D("Pos", refGeo.bistatic->txPlatform.pos, txPlatXML); + mCommon.createVector3D("Vel", refGeo.bistatic->txPlatform.vel, txPlatXML); + + { + const auto side = refGeo.bistatic->txPlatform.sideOfTrack.toString(); + createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), txPlatXML); + } + createDouble("SlantRange", refGeo.bistatic->txPlatform.slantRange, txPlatXML); + createDouble("GroundRange", refGeo.bistatic->txPlatform.groundRange, txPlatXML); + createDouble("DopplerConeAngle", refGeo.bistatic->txPlatform.dopplerConeAngle, txPlatXML); + createDouble("GrazeAngle", refGeo.bistatic->txPlatform.grazeAngle, txPlatXML); + createDouble("IncidenceAngle", refGeo.bistatic->txPlatform.incidenceAngle, txPlatXML); + createDouble("AzimuthAngle", refGeo.bistatic->txPlatform.azimuthAngle, txPlatXML); + XMLElem rcvPlatXML = newElement("RcvPlatform", biXML); + createDouble("Time", refGeo.bistatic->rcvPlatform.time, rcvPlatXML); + mCommon.createVector3D("Pos", refGeo.bistatic->rcvPlatform.pos, rcvPlatXML); + mCommon.createVector3D("Vel", refGeo.bistatic->rcvPlatform.vel, rcvPlatXML); + + { + const auto side = refGeo.bistatic->rcvPlatform.sideOfTrack.toString(); + createString("SideOfTrack", (side == "LEFT" ? "L" : "R"), rcvPlatXML); + } + createDouble("SlantRange", refGeo.bistatic->rcvPlatform.slantRange, rcvPlatXML); + createDouble("GroundRange", refGeo.bistatic->rcvPlatform.groundRange, rcvPlatXML); + createDouble("DopplerConeAngle", refGeo.bistatic->rcvPlatform.dopplerConeAngle, rcvPlatXML); + createDouble("GrazeAngle", refGeo.bistatic->rcvPlatform.grazeAngle, rcvPlatXML); + createDouble("IncidenceAngle", refGeo.bistatic->rcvPlatform.incidenceAngle, rcvPlatXML); + createDouble("AzimuthAngle", refGeo.bistatic->rcvPlatform.azimuthAngle, rcvPlatXML); + } + return refGeoXML; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem retval = nullptr; + if (has_value(o)) + { + retval = newElement(o.tag(), &parent); + std::ignore = create(parser(), value(o).dcxsf, *retval); + std::ignore = create(parser(), value(o).dcysf, *retval); + } + + return retval; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem retval = nullptr; + if (has_value(o)) + { + retval = newElement(o.tag(), &parent); + std::ignore = create(parser(), value(o).dcxsf, *retval); + std::ignore = create(parser(), value(o).dcysf, *retval); + } + + return retval; +} + +XMLElem CPHDXMLParser::toXML(const six::XsElement_minOccurs0& o, xml::lite::Element& parent) +{ + XMLElem retval = nullptr; + if (has_value(o)) + { + retval = newElement(o.tag(), &parent); + std::ignore = create(parser(), value(o).ampX, *retval); + std::ignore = create(parser(), value(o).ampY, *retval); + std::ignore = create(parser(), value(o).phaseY, *retval); + } + + return retval; +} + +XMLElem CPHDXMLParser::toXML(const Antenna& antenna, XMLElem parent) +{ + XMLElem antennaXML = newElement("Antenna", parent); + createInt("NumACFs", antenna.antCoordFrame.size(), antennaXML); + createInt("NumAPCs", antenna.antPhaseCenter.size(), antennaXML); + createInt("NumAntPats", antenna.antPattern.size(), antennaXML); + for (size_t ii = 0; ii < antenna.antCoordFrame.size(); ++ii) + { + XMLElem antCoordFrameXML = newElement("AntCoordFrame", antennaXML); + createString("Identifier", antenna.antCoordFrame[ii].identifier, antCoordFrameXML); + mCommon.createPolyXYZ("XAxisPoly", antenna.antCoordFrame[ii].xAxisPoly, antCoordFrameXML); + mCommon.createPolyXYZ("YAxisPoly", antenna.antCoordFrame[ii].yAxisPoly, antCoordFrameXML); + create(parser(), antenna.antCoordFrame[ii].useACFPVP, *antCoordFrameXML); + } + for (size_t ii = 0; ii < antenna.antPhaseCenter.size(); ++ii) + { + XMLElem antPhaseCenterXML = newElement("AntPhaseCenter", antennaXML); + createString("Identifier", antenna.antPhaseCenter[ii].identifier, antPhaseCenterXML); + createString("ACFId", antenna.antPhaseCenter[ii].acfId, antPhaseCenterXML); + mCommon.createVector3D("APCXYZ", antenna.antPhaseCenter[ii].apcXYZ, antPhaseCenterXML); + } + for (size_t ii = 0; ii < antenna.antPattern.size(); ++ii) + { + XMLElem antPatternXML = newElement("AntPattern", antennaXML); + createString("Identifier", antenna.antPattern[ii].identifier, antPatternXML); + createDouble("FreqZero", antenna.antPattern[ii].freqZero, antPatternXML); + createOptionalDouble("GainZero", antenna.antPattern[ii].gainZero, antPatternXML); + if (!six::Init::isUndefined(antenna.antPattern[ii].ebFreqShift)) + { + createBooleanType("EBFreqShift", antenna.antPattern[ii].ebFreqShift, antPatternXML); + } + std::ignore = toXML(antenna.antPattern[ii].ebFreqShiftSF, *antPatternXML); + + if (!six::Init::isUndefined(antenna.antPattern[ii].mlFreqDilation)) + { + createBooleanType("MLFreqDilation", antenna.antPattern[ii].mlFreqDilation, antPatternXML); + } + std::ignore = toXML(antenna.antPattern[ii].mlFreqDilationSF, *antPatternXML); + + if (!six::Init::isUndefined(antenna.antPattern[ii].gainBSPoly)) + { + mCommon.createPoly1D("GainBSPoly", antenna.antPattern[ii].gainBSPoly, antPatternXML); + } + + std::ignore = toXML(antenna.antPattern[ii].antPolRef, *antPatternXML); + + XMLElem ebXML = newElement("EB", antPatternXML); + mCommon.createPoly1D("DCXPoly", antenna.antPattern[ii].eb.dcxPoly, ebXML); + mCommon.createPoly1D("DCYPoly", antenna.antPattern[ii].eb.dcyPoly, ebXML); + create(parser(), antenna.antPattern[ii].eb.useEBPVP, *ebXML); + + XMLElem arrayXML = newElement("Array", antPatternXML); + mCommon.createPoly2D("GainPoly", antenna.antPattern[ii].array.gainPoly, arrayXML); + mCommon.createPoly2D("PhasePoly", antenna.antPattern[ii].array.phasePoly, arrayXML); + create(parser(), antenna.antPattern[ii].array.antGPId, *arrayXML); + + XMLElem elementXML = newElement("Element", antPatternXML); + mCommon.createPoly2D("GainPoly", antenna.antPattern[ii].element.gainPoly, elementXML); + mCommon.createPoly2D("PhasePoly", antenna.antPattern[ii].element.phasePoly, elementXML); + for (size_t jj = 0; jj < antenna.antPattern[ii].gainPhaseArray.size(); ++jj) + { + XMLElem gainPhaseArrayXML = newElement("GainPhaseArray", antPatternXML); + createDouble("Freq", antenna.antPattern[ii].gainPhaseArray[jj].freq, gainPhaseArrayXML); + createString("ArrayId", antenna.antPattern[ii].gainPhaseArray[jj].arrayId, gainPhaseArrayXML); + if (!six::Init::isUndefined(antenna.antPattern[ii].gainPhaseArray[jj].elementId)) + { + createString("ElementId", antenna.antPattern[ii].gainPhaseArray[jj].elementId, gainPhaseArrayXML); + } + } + } + return antennaXML; +} + +XMLElem CPHDXMLParser::toXML(const TxRcv& txRcv, XMLElem parent) +{ + XMLElem txRcvXML = newElement("TxRcv", parent); + createInt("NumTxWFs", txRcv.txWFParameters.size(), txRcvXML); + for (size_t ii = 0; ii < txRcv.txWFParameters.size(); ++ii) + { + XMLElem txWFParamsXML = newElement("TxWFParameters", txRcvXML); + createString("Identifier", txRcv.txWFParameters[ii].identifier, txWFParamsXML); + createDouble("PulseLength", txRcv.txWFParameters[ii].pulseLength, txWFParamsXML); + createDouble("RFBandwidth", txRcv.txWFParameters[ii].rfBandwidth, txWFParamsXML); + createDouble("FreqCenter", txRcv.txWFParameters[ii].freqCenter, txWFParamsXML); + createOptionalDouble("LFMRate", txRcv.txWFParameters[ii].lfmRate, txWFParamsXML); + createString("Polarization", txRcv.txWFParameters[ii].polarization, txWFParamsXML); + createOptionalDouble("Power", txRcv.txWFParameters[ii].power, txWFParamsXML); + } + createInt("NumRcvs", txRcv.rcvParameters.size(), txRcvXML); + for (size_t ii = 0; ii < txRcv.rcvParameters.size(); ++ii) + { + XMLElem rcvParamsXML = newElement("RcvParameters", txRcvXML); + createString("Identifier", txRcv.rcvParameters[ii].identifier, rcvParamsXML); + createDouble("WindowLength", txRcv.rcvParameters[ii].windowLength, rcvParamsXML); + createDouble("SampleRate", txRcv.rcvParameters[ii].sampleRate, rcvParamsXML); + createDouble("IFFilterBW", txRcv.rcvParameters[ii].ifFilterBW, rcvParamsXML); + createDouble("FreqCenter", txRcv.rcvParameters[ii].freqCenter, rcvParamsXML); + createOptionalDouble("LFMRate", txRcv.rcvParameters[ii].lfmRate, rcvParamsXML); + createString("Polarization", txRcv.rcvParameters[ii].polarization, rcvParamsXML); + createOptionalDouble("PathGain", txRcv.rcvParameters[ii].pathGain, rcvParamsXML); + } + return txRcvXML; +} + +XMLElem CPHDXMLParser::toXML(const ErrorParameters& errParams, XMLElem parent) +{ + XMLElem errParamsXML = newElement("ErrorParameters", parent); + if (errParams.monostatic.get()) + { + XMLElem monoXML = newElement("Monostatic", errParamsXML); + XMLElem posVelErrXML = newElement("PosVelErr", monoXML); + createString("Frame", errParams.monostatic->posVelErr.frame, posVelErrXML); + createDouble("P1", errParams.monostatic->posVelErr.p1, posVelErrXML); + createDouble("P2", errParams.monostatic->posVelErr.p2, posVelErrXML); + createDouble("P3", errParams.monostatic->posVelErr.p3, posVelErrXML); + createDouble("V1", errParams.monostatic->posVelErr.v1, posVelErrXML); + createDouble("V2", errParams.monostatic->posVelErr.v2, posVelErrXML); + createDouble("V3", errParams.monostatic->posVelErr.v3, posVelErrXML); + if(errParams.monostatic->posVelErr.corrCoefs.get()) + { + XMLElem corrCoefsXML = newElement("CorrCoefs", posVelErrXML); + createDouble("P1P2", errParams.monostatic->posVelErr.corrCoefs->p1p2, corrCoefsXML); + createDouble("P1P3", errParams.monostatic->posVelErr.corrCoefs->p1p3, corrCoefsXML); + createDouble("P1V1", errParams.monostatic->posVelErr.corrCoefs->p1v1, corrCoefsXML); + createDouble("P1V2", errParams.monostatic->posVelErr.corrCoefs->p1v2, corrCoefsXML); + createDouble("P1V3", errParams.monostatic->posVelErr.corrCoefs->p1v3, corrCoefsXML); + createDouble("P2P3", errParams.monostatic->posVelErr.corrCoefs->p2p3, corrCoefsXML); + createDouble("P2V1", errParams.monostatic->posVelErr.corrCoefs->p2v1, corrCoefsXML); + createDouble("P2V2", errParams.monostatic->posVelErr.corrCoefs->p2v2, corrCoefsXML); + createDouble("P2V3", errParams.monostatic->posVelErr.corrCoefs->p2v3, corrCoefsXML); + createDouble("P3V1", errParams.monostatic->posVelErr.corrCoefs->p3v1, corrCoefsXML); + createDouble("P3V2", errParams.monostatic->posVelErr.corrCoefs->p3v2, corrCoefsXML); + createDouble("P3V3", errParams.monostatic->posVelErr.corrCoefs->p3v3, corrCoefsXML); + createDouble("V1V2", errParams.monostatic->posVelErr.corrCoefs->v1v2, corrCoefsXML); + createDouble("V1V3", errParams.monostatic->posVelErr.corrCoefs->v1v3, corrCoefsXML); + createDouble("V2V3", errParams.monostatic->posVelErr.corrCoefs->v2v3, corrCoefsXML); + } + createDecorrType("PositionDecorr", errParams.monostatic->posVelErr.positionDecorr, posVelErrXML); + + // RadarSensor + XMLElem radarXML = newElement("RadarSensor", monoXML); + createDouble("RangeBias", errParams.monostatic->radarSensor.rangeBias, radarXML); + createOptionalDouble("ClockFreqSF", errParams.monostatic->radarSensor.clockFreqSF, radarXML); + createOptionalDouble("CollectionStartTime", errParams.monostatic->radarSensor.collectionStartTime, radarXML); + if (errParams.monostatic->radarSensor.rangeBiasDecorr.get()) + { + XMLElem rangeBiasDecorrXML = newElement("RangeBiasDecorr", radarXML); + createDouble("CorrCoefZero", errParams.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero, rangeBiasDecorrXML); + createDouble("DecorrRate", errParams.monostatic->radarSensor.rangeBiasDecorr->decorrRate, rangeBiasDecorrXML); + } + + if (errParams.monostatic->tropoError.get()) + { + XMLElem tropoXML = newElement("TropoError", monoXML); + createOptionalDouble("TropoRangeVertical", errParams.monostatic->tropoError->tropoRangeVertical, tropoXML); + createOptionalDouble("TropoRangeSlant", errParams.monostatic->tropoError->tropoRangeSlant, tropoXML); + createDecorrType("TropoRangeDecorr", errParams.monostatic->tropoError->tropoRangeDecorr, tropoXML); + } + if (errParams.monostatic->ionoError.get()) + { + XMLElem ionoXML = newElement("IonoError", monoXML); + createDouble("IonoRangeVertical", errParams.monostatic->ionoError->ionoRangeVertical, ionoXML); + createOptionalDouble("IonoRangeRateVertical", errParams.monostatic->ionoError->ionoRangeRateVertical, ionoXML); + createOptionalDouble("IonoRgRgRateCC", errParams.monostatic->ionoError->ionoRgRgRateCC, ionoXML); + createDecorrType("IonoRangeVertDecorr", errParams.monostatic->tropoError->tropoRangeDecorr, ionoXML); + } + if (!errParams.monostatic->parameter.empty()) + { + XMLElem addedParamsXML = newElement("AddedParameters", monoXML); + mCommon.addParameters("Parameter", getDefaultURI(), errParams.monostatic->parameter, addedParamsXML); + } + } + else if (errParams.bistatic.get()) + { + XMLElem biXML = newElement("Bistatic", errParamsXML); + XMLElem txPlatXML = newElement("TxPlatform", biXML); + createErrorParamPlatform("TxPlatform", errParams.bistatic->txPlatform, txPlatXML); + XMLElem radarTxXML = newElement("RadarSensor", txPlatXML); + create(parser(), errParams.bistatic->txPlatform.radarSensor.delayBias, *radarTxXML); + createOptionalDouble("ClockFreqSF", errParams.bistatic->txPlatform.radarSensor.clockFreqSF, radarTxXML); + createDouble("CollectionStartTime", errParams.bistatic->txPlatform.radarSensor.collectionStartTime, radarTxXML); + + XMLElem rcvPlatXML = newElement("RcvPlatform", biXML); + createErrorParamPlatform("RcvPlatform", errParams.bistatic->rcvPlatform, rcvPlatXML); + XMLElem radarRcvXML = newElement("RadarSensor", rcvPlatXML); + createOptionalDouble("ClockFreqSF", errParams.bistatic->rcvPlatform.radarSensor.clockFreqSF, radarRcvXML); + createDouble("CollectionStartTime", errParams.bistatic->rcvPlatform.radarSensor.collectionStartTime, radarRcvXML); + + if (!errParams.bistatic->parameter.empty()) + { + XMLElem addedParamsXML = newElement("AddedParameters", biXML); + mCommon.addParameters("Parameter", getDefaultURI(), errParams.bistatic->parameter, addedParamsXML); + } + } + + return errParamsXML; +} + +XMLElem CPHDXMLParser::toXML(const ProductInfo& productInfo, XMLElem parent) +{ + XMLElem productInfoXML = newElement("ProductInfo", parent); + if(!six::Init::isUndefined(productInfo.profile)) + { + createString("Profile", productInfo.profile, productInfoXML); + } + for (size_t ii = 0; ii < productInfo.creationInfo.size(); ++ii) + { + XMLElem creationInfoXML = newElement("CreationInfo", productInfoXML); + if(!six::Init::isUndefined(productInfo.creationInfo[ii].application)) + { + createString("Application", productInfo.creationInfo[ii].application, creationInfoXML); + } + createDateTime("DateTime", productInfo.creationInfo[ii].dateTime, creationInfoXML); + if (!six::Init::isUndefined(productInfo.creationInfo[ii].site)) + { + createString("Site", productInfo.creationInfo[ii].site, creationInfoXML); + } + mCommon.addParameters("Parameter", getDefaultURI(), productInfo.creationInfo[ii].parameter, creationInfoXML); + } + mCommon.addParameters("Parameter", getDefaultURI(), productInfo.parameter, productInfoXML); + return productInfoXML; +} + +XMLElem CPHDXMLParser::toXML(const GeoInfo& geoInfo, XMLElem parent) +{ + XMLElem geoInfoXML = newElement("GeoInfo", parent); + + mCommon.addParameters("Desc", geoInfo.desc, geoInfoXML); + + const size_t numLatLons = geoInfo.geometryLatLon.size(); + if (numLatLons == 1) + { + mCommon.createLatLon("Point", geoInfo.geometryLatLon[0], geoInfoXML); + } + else if (numLatLons >= 2) + { + XMLElem linePolyXML = newElement(numLatLons == 2 ? "Line" : "Polygon", + geoInfoXML); + setAttribute(linePolyXML, "size", numLatLons); + + for (size_t ii = 0; ii < numLatLons; ++ii) + { + XMLElem v = mCommon.createLatLon(numLatLons == 2 ? "Endpoint" : "Vertex", + geoInfo.geometryLatLon[ii], linePolyXML); + setAttribute(v, "index", ii + 1); + } + } + + if (!geoInfo.name.empty()) + setAttribute(geoInfoXML, "name", geoInfo.name); + + for (size_t ii = 0; ii < geoInfo.geoInfos.size(); ++ii) + { + toXML(*geoInfo.geoInfos[ii], geoInfoXML); + } + + return geoInfoXML; +} + +XMLElem CPHDXMLParser::toXML(const MatchInformation& matchInfo, XMLElem parent) +{ + return mCommon.convertMatchInformationToXML(matchInfo, parent); +} + +/* + * FROM XML + */ + +std::unique_ptr CPHDXMLParser::fromXML( + const xml::lite::Document* doc) +{ + std::unique_ptr cphd(new Metadata()); + + const auto root = doc->getRootElement(); + + XMLElem collectionIDXML = getFirstAndOnly(root, "CollectionID"); + XMLElem globalXML = getFirstAndOnly(root, "Global"); + XMLElem sceneCoordsXML = getFirstAndOnly(root, "SceneCoordinates"); + XMLElem dataXML = getFirstAndOnly(root, "Data"); + XMLElem channelXML = getFirstAndOnly(root, "Channel"); + XMLElem pvpXML = getFirstAndOnly(root, "PVP"); + XMLElem dwellXML = getFirstAndOnly(root, "Dwell"); + XMLElem refGeoXML = getFirstAndOnly(root, "ReferenceGeometry"); + + XMLElem supportArrayXML = getOptional(root, "SupportArray"); + XMLElem antennaXML = getOptional(root, "Antenna"); + XMLElem txRcvXML = getOptional(root, "TxRcv"); + XMLElem errParamXML = getOptional(root, "ErrorParameters"); + XMLElem productInfoXML = getOptional(root, "ProductInfo"); + std::vector geoInfoXMLVec; + root->getElementsByTagName("GeoInfo", geoInfoXMLVec); + cphd->geoInfo.resize(geoInfoXMLVec.size()); + XMLElem matchInfoXML = getOptional(root, "MatchInfo"); + + // Parse XML for each section + fromXML(collectionIDXML, cphd->collectionID); + fromXML(globalXML, cphd->global); + fromXML(sceneCoordsXML, cphd->sceneCoordinates); + fromXML(dataXML, cphd->data); + fromXML(channelXML, cphd->channel); + fromXML(pvpXML, cphd->pvp); + fromXML(dwellXML, cphd->dwell); + fromXML(refGeoXML, cphd->referenceGeometry); + + if(supportArrayXML) + { + cphd->supportArray.reset(new SupportArray()); + fromXML(supportArrayXML, *(cphd->supportArray)); + } + if(antennaXML) + { + cphd->antenna.reset(new Antenna()); + fromXML(antennaXML, *(cphd->antenna)); + } + if(txRcvXML) + { + cphd->txRcv.reset(new TxRcv()); + fromXML(txRcvXML, *(cphd->txRcv)); + } + if(errParamXML) + { + cphd->errorParameters.reset(new ErrorParameters()); + fromXML(errParamXML, *(cphd->errorParameters)); + } + if(productInfoXML) + { + cphd->productInfo.reset(new ProductInfo()); + fromXML(productInfoXML, *(cphd->productInfo)); + } + for (size_t ii = 0; ii < geoInfoXMLVec.size(); ++ii) + { + fromXML(geoInfoXMLVec[ii], cphd->geoInfo[ii]); + } + if (matchInfoXML) + { + cphd->matchInfo.reset(new MatchInformation()); + fromXML(matchInfoXML, *(cphd->matchInfo)); + } + + return cphd; +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* collectionIDXML, CollectionInformation& collectionID) +{ + parseString(getFirstAndOnly(collectionIDXML, "CollectorName"), + collectionID.collectorName); + + XMLElem element = getOptional(collectionIDXML, "IlluminatorName"); + if (element) + { + parseString(element, collectionID.illuminatorName); + } + + element = getOptional(collectionIDXML, "CoreName"); + if (element) + { + parseString(element, collectionID.coreName); + } + + element = getOptional(collectionIDXML, "CollectType"); + if (element) + { + collectionID.collectType + = six::toType(element->getCharacterData()); + } + + XMLElem radarModeXML = getFirstAndOnly(collectionIDXML, "RadarMode"); + + collectionID.radarMode + = six::toType(getFirstAndOnly(radarModeXML, + "ModeType")->getCharacterData()); + + element = getOptional(radarModeXML, "ModeID"); + if (element) + { + parseString(element, collectionID.radarModeID); + } + + element = getFirstAndOnly(collectionIDXML, "ReleaseInfo"); + parseString(element, collectionID.releaseInfo); + + std::string classification; + parseString(getFirstAndOnly(collectionIDXML, "Classification"), + classification); + collectionID.setClassificationLevel(classification); + + // Optional + std::vector countryCodes; + element = getOptional(collectionIDXML, "CountryCode"); + if (element) + { + std::string countryCodeStr; + parseString(element, countryCodeStr); + collectionID.countryCodes = str::split(countryCodeStr, ","); + for (size_t ii = 0; ii < collectionID.countryCodes.size(); ++ii) + { + str::trim(collectionID.countryCodes[ii]); + } + } + + //optional + mCommon.parseParameters(collectionIDXML, "Parameter", collectionID.parameters); +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* globalXML, Global& global) +{ + global.domainType = DomainType::toType( + getFirstAndOnly(globalXML, "DomainType")->getCharacterData()); + global.sgn = PhaseSGN::toType( + getFirstAndOnly(globalXML, "SGN")->getCharacterData()); + + // Timeline + const xml::lite::Element* timelineXML = getFirstAndOnly(globalXML, "Timeline"); + parseDateTime( + getFirstAndOnly(timelineXML, "CollectionStart"), + global.timeline.collectionStart); + + // Optional + const xml::lite::Element* rcvCollectionXML = getOptional(timelineXML, + "RcvCollectionStart"); + if (rcvCollectionXML) + { + parseDateTime(rcvCollectionXML, + global.timeline.rcvCollectionStart); + } + + parseDouble( + getFirstAndOnly(timelineXML, "TxTime1"), global.timeline.txTime1); + parseDouble( + getFirstAndOnly(timelineXML, "TxTime2"), global.timeline.txTime2); + + // FxBand + const xml::lite::Element* fxBandXML = getFirstAndOnly(globalXML, "FxBand"); + parseDouble(getFirstAndOnly(fxBandXML, "FxMin"), global.fxBand.fxMin); + parseDouble(getFirstAndOnly(fxBandXML, "FxMax"), global.fxBand.fxMax); + + // TOASwath + const xml::lite::Element* toaSwathXML = getFirstAndOnly(globalXML, "TOASwath"); + parseDouble(getFirstAndOnly(toaSwathXML, "TOAMin"), global.toaSwath.toaMin); + parseDouble(getFirstAndOnly(toaSwathXML, "TOAMax"), global.toaSwath.toaMax); + + // TropoParameters + const xml::lite::Element* tropoXML = getOptional(globalXML, "TropoParameters"); + if (tropoXML) + { + // Optional + global.tropoParameters.reset(new TropoParameters()); + parseDouble(getFirstAndOnly(tropoXML, "N0"), global.tropoParameters->n0); + global.tropoParameters->refHeight = + RefHeight::toType(getFirstAndOnly(tropoXML, "RefHeight")->getCharacterData()); + } + + // IonoParameters + if (const auto ionoXML = getOptional(globalXML, "IonoParameters")) + { + // Optional + global.ionoParameters.reset(new IonoParameters()); + parseDouble(getFirstAndOnly(ionoXML, "TECV"), global.ionoParameters->tecv); + if (const auto f2HeightXML = getOptional(ionoXML, "F2Height")) + { + parseDouble(f2HeightXML, global.ionoParameters->f2Height); + } + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* sceneCoordsXML, + SceneCoordinates& scene) +{ + scene.earthModel = EarthModelType::toType( + getFirstAndOnly(sceneCoordsXML, "EarthModel")->getCharacterData()); + + // IARP + const xml::lite::Element* iarpXML = getFirstAndOnly(sceneCoordsXML, "IARP"); + mCommon.parseVector3D(getFirstAndOnly(iarpXML, "ECF"), scene.iarp.ecf); + mCommon.parseLatLonAlt(getFirstAndOnly(iarpXML, "LLH"), scene.iarp.llh); + + // ReferenceSurface + const xml::lite::Element* surfaceXML = getFirstAndOnly(sceneCoordsXML, "ReferenceSurface"); + const xml::lite::Element* planarXML = getOptional(surfaceXML, "Planar"); + const xml::lite::Element* haeXML = getOptional(surfaceXML, "HAE"); + if (planarXML && !haeXML) + { + // Choice type + scene.referenceSurface.planar.reset(new Planar()); + mCommon.parseVector3D(getFirstAndOnly(planarXML, "uIAX"), + scene.referenceSurface.planar->uIax); + mCommon.parseVector3D(getFirstAndOnly(planarXML, "uIAY"), + scene.referenceSurface.planar->uIay); + } + else if (haeXML && !planarXML) + { + // Choice type + scene.referenceSurface.hae.reset(new HAE()); + mCommon.parseLatLon(getFirstAndOnly(haeXML, "uIAXLL"), + scene.referenceSurface.hae->uIax); + mCommon.parseLatLon(getFirstAndOnly(haeXML, "uIAYLL"), + scene.referenceSurface.hae->uIay); + } + else + { + throw except::Exception(Ctxt( + "ReferenceSurface must exactly one of Planar or HAE element")); + } + + // ImageArea + const xml::lite::Element* imageAreaXML = getFirstAndOnly(sceneCoordsXML, "ImageArea"); + parseAreaType(imageAreaXML, scene.imageArea); + + // ImageAreaCorners + const xml::lite::Element* cornersXML = getFirstAndOnly(sceneCoordsXML, + "ImageAreaCornerPoints"); + mCommon.parseFootprint(cornersXML, "IACP", scene.imageAreaCorners); + + // Extended Area + const xml::lite::Element* extendedAreaXML = getOptional(sceneCoordsXML, "ExtendedArea"); + if (extendedAreaXML) + { + scene.extendedArea.reset(new AreaType()); + parseAreaType(extendedAreaXML, *scene.extendedArea); + } + + // Image Grid + const xml::lite::Element* gridXML = getOptional(sceneCoordsXML, "ImageGrid"); + if (gridXML) + { + // Optional + scene.imageGrid.reset(new ImageGrid()); + const xml::lite::Element* identifierXML = getOptional(gridXML, "Identifier"); + if (identifierXML) + { + parseString(identifierXML, scene.imageGrid->identifier); + } + parseLineSample(getFirstAndOnly(gridXML, "IARPLocation"), + scene.imageGrid->iarpLocation); + parseIAExtent(getFirstAndOnly(gridXML, "IAXExtent"), + scene.imageGrid->xExtent); + parseIAExtent(getFirstAndOnly(gridXML, "IAYExtent"), + scene.imageGrid->yExtent); + + // Segment List + const xml::lite::Element* segListXML = getOptional(gridXML, "SegmentList"); + if (segListXML) + { + // Optional + size_t numSegments; + parseUInt(getFirstAndOnly(segListXML, "NumSegments"), numSegments); + scene.imageGrid->segments.resize(numSegments); + + std::vector segmentsXML; + segListXML->getElementsByTagName("Segment", segmentsXML); + + for (size_t ii = 0; ii < segmentsXML.size(); ++ii) + { + const xml::lite::Element* segmentXML = segmentsXML[ii]; + parseString(getFirstAndOnly(segmentXML, "Identifier"), + scene.imageGrid->segments[ii].identifier); + parseInt(getFirstAndOnly(segmentXML, "StartLine"), + scene.imageGrid->segments[ii].startLine); + parseInt(getFirstAndOnly(segmentXML, "StartSample"), + scene.imageGrid->segments[ii].startSample); + parseInt(getFirstAndOnly(segmentXML, "EndLine"), + scene.imageGrid->segments[ii].endLine); + parseInt(getFirstAndOnly(segmentXML, "EndSample"), + scene.imageGrid->segments[ii].endSample); + + const xml::lite::Element* polygonXML = getOptional(segmentXML, + "SegmentPolygon"); + if (polygonXML) + { + // Optional + size_t polygonSize = 0; + sscanf(const_cast(polygonXML)->attribute("size").c_str(), "%zu", &polygonSize); + scene.imageGrid->segments[ii].polygon.resize(polygonSize); + std::vector polyVerticesXMLVec; + polygonXML->getElementsByTagName("SV", polyVerticesXMLVec); + if (scene.imageGrid->segments[ii].polygon.size() != polyVerticesXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect polygon vertices provided")); + } + if (polyVerticesXMLVec.size() < 3) + { + throw except::Exception(Ctxt( + "Polygon must have at least 3 vertices")); + } + std::vector& vertices = + scene.imageGrid->segments[ii].polygon; + vertices.resize(polyVerticesXMLVec.size()); + for (size_t jj = 0; jj < polyVerticesXMLVec.size(); ++jj) + { + size_t tempIdx; + sscanf(polyVerticesXMLVec[jj]->attribute("index").c_str(), "%zu", &tempIdx); + vertices[jj].setIndex(tempIdx); + parseLineSample(polyVerticesXMLVec[jj], vertices[jj]); + } + } + } + } + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* dataXML, Data& data) +{ + const xml::lite::Element* signalXML = getFirstAndOnly(dataXML, "SignalArrayFormat"); + data.signalArrayFormat = SignalArrayFormat::toType(signalXML->getCharacterData()); + + size_t numBytesPVP_temp = 0; + XMLElem numBytesPVPXML = getFirstAndOnly(dataXML, "NumBytesPVP"); + parseUInt(numBytesPVPXML, numBytesPVP_temp); + if(numBytesPVP_temp % 8 != 0) + { + throw except::Exception(Ctxt( + "Number of bytes must be multiple of 8")); + } + data.numBytesPVP = numBytesPVP_temp; + + // Channels + std::vector channelsXML; + dataXML->getElementsByTagName("Channel", channelsXML); + data.channels.resize(channelsXML.size()); + for (size_t ii = 0; ii < channelsXML.size(); ++ii) + { + parseString(getFirstAndOnly(channelsXML[ii], "Identifier"), + data.channels[ii].identifier); + parseUInt(getFirstAndOnly(channelsXML[ii], "NumVectors"), + data.channels[ii].numVectors); + parseUInt(getFirstAndOnly(channelsXML[ii], "NumSamples"), + data.channels[ii].numSamples); + parseUInt(getFirstAndOnly(channelsXML[ii], "SignalArrayByteOffset"), + data.channels[ii].signalArrayByteOffset); + parseUInt(getFirstAndOnly(channelsXML[ii], "PVPArrayByteOffset"), + data.channels[ii].pvpArrayByteOffset); + XMLElem compressionXML = getOptional(channelsXML[ii], "CompressedSignalSize"); + if (compressionXML) + { + parseUInt(compressionXML, data.channels[ii].compressedSignalSize); + } + } + XMLElem compressionXML = getOptional(dataXML, "SignalCompressionID"); + if (compressionXML) + { + parseString(compressionXML, + data.signalCompressionID); + } + + // Support Arrays + std::vector supportsXML; + dataXML->getElementsByTagName("SupportArray", supportsXML); + for (size_t ii = 0; ii < supportsXML.size(); ++ii) + { + std::string id; + size_t offset; + size_t numRows; + size_t numCols; + size_t numBytes; + parseString(getFirstAndOnly(supportsXML[ii], "Identifier"), id); + parseUInt(getFirstAndOnly(supportsXML[ii], "ArrayByteOffset"), offset); + parseUInt(getFirstAndOnly(supportsXML[ii], "NumRows"), numRows); + parseUInt(getFirstAndOnly(supportsXML[ii], "NumCols"), numCols); + parseUInt(getFirstAndOnly(supportsXML[ii], "BytesPerElement"), numBytes); + data.setSupportArray(id, numRows, numCols, numBytes, offset); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* channelXML, Channel& channel) +{ + parseString(getFirstAndOnly(channelXML, "RefChId"), channel.refChId); + parseBooleanType(getFirstAndOnly(channelXML, "FXFixedCPHD"), channel.fxFixedCphd); + parseBooleanType(getFirstAndOnly(channelXML, "TOAFixedCPHD"), channel.toaFixedCphd); + parseBooleanType(getFirstAndOnly(channelXML, "SRPFixedCPHD"), channel.srpFixedCphd); + + std::vector parametersXML; + channelXML->getElementsByTagName("Parameters", parametersXML); + channel.parameters.resize(parametersXML.size()); + for (size_t ii = 0; ii < parametersXML.size(); ++ii) + { + parseChannelParameters(parametersXML[ii], channel.parameters[ii]); + } + + XMLElem addedParametersXML = getOptional(channelXML, "AddedParameters"); + if(addedParametersXML) + { + mCommon.parseParameters(addedParametersXML, "Parameter", channel.addedParameters); + } +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement& v) const +{ + auto& param = value(v).param; + const auto offset = parsePVPType(parent, param); + setOffset(param, offset); +} +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement& v) const +{ + auto& param = value(v).param; + const auto offset = parsePVPType(parent, param); + setOffset(param, offset); +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = TxAntenna{}; + parse(*pXML, value(o).txACX); + parse(*pXML, value(o).txACY); + parse(*pXML, value(o).txEB); + } +} +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = RcvAntenna{}; + parse(*pXML, value(o).rcvACX); + parse(*pXML, value(o).rcvACY); + parse(*pXML, value(o).rcvEB); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* pvpXML, Pvp& pvp) +{ + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxTime"), pvp.txTime); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxPos"), pvp.txPos); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TxVel"), pvp.txVel); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvTime"), pvp.rcvTime); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvPos"), pvp.rcvPos); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "RcvVel"), pvp.rcvVel); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "SRPPos"), pvp.srpPos); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFDOP"), pvp.aFDOP); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFRR1"), pvp.aFRR1); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "aFRR2"), pvp.aFRR2); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "FX1"), pvp.fx1); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "FX2"), pvp.fx2); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TOA1"), pvp.toa1); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TOA2"), pvp.toa2); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "TDTropoSRP"), pvp.tdTropoSRP); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "SC0"), pvp.sc0); + parsePVPType(pvp, getFirstAndOnly(pvpXML, "SCSS"), pvp.scss); + + parseOptionalPVPType(pvpXML, "AmpSF", pvp, pvp.ampSF); + parseOptionalPVPType(pvpXML, "FXN1", pvp, pvp.fxN1); + parseOptionalPVPType(pvpXML, "FXN2", pvp, pvp.fxN2); + parseOptionalPVPType(pvpXML, "TOAE1", pvp, pvp.toaE1); + parseOptionalPVPType(pvpXML, "TOAE2", pvp, pvp.toaE2); + parseOptionalPVPType(pvpXML, "TDIonoSRP", pvp, pvp.tdIonoSRP); + parseOptionalPVPType(pvpXML, "SIGNAL", pvp, pvp.signal); + + parse(*pvpXML, pvp.txAntenna); + parse(*pvpXML, pvp.rcvAntenna); + + std::vector addedParamsXML; + const std::string str = "AddedPVP"; + pvpXML->getElementsByTagName(str, addedParamsXML); + if(addedParamsXML.empty()) + { + return; + } + for (size_t ii = 0; ii < addedParamsXML.size(); ++ii) + { + parsePVPType(pvp, addedParamsXML[ii]); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* DwellXML, + Dwell& dwell) +{ + // CODTime + size_t numCODTimes; + parseUInt(getFirstAndOnly(DwellXML, "NumCODTimes"), numCODTimes); + dwell.cod.resize(numCODTimes); + + std::vector codXMLVec; + DwellXML->getElementsByTagName("CODTime", codXMLVec); + for(size_t ii = 0; ii < codXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(codXMLVec[ii], "Identifier"), dwell.cod[ii].identifier); + mCommon.parsePoly2D(getFirstAndOnly(codXMLVec[ii], "CODTimePoly"), dwell.cod[ii].codTimePoly); + } + + // DwellTime + size_t numDwellTimes = 0; + parseUInt(getFirstAndOnly(DwellXML, "NumDwellTimes"), numDwellTimes); + dwell.dtime.resize(numDwellTimes); + + std::vector dtimeXMLVec; + DwellXML->getElementsByTagName("DwellTime", dtimeXMLVec); + for(size_t ii = 0; ii < dtimeXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(dtimeXMLVec[ii], "Identifier"), dwell.dtime[ii].identifier); + mCommon.parsePoly2D(getFirstAndOnly(dtimeXMLVec[ii], "DwellTimePoly"), dwell.dtime[ii].dwellTimePoly); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* refGeoXML, ReferenceGeometry& refGeo) +{ + XMLElem srpXML = getFirstAndOnly(refGeoXML, "SRP"); + mCommon.parseVector3D(getFirstAndOnly(srpXML, "ECF"), refGeo.srp.ecf); + mCommon.parseVector3D(getFirstAndOnly(srpXML, "IAC"), refGeo.srp.iac); + parseDouble(getFirstAndOnly(refGeoXML, "ReferenceTime"), refGeo.referenceTime); + parseDouble(getFirstAndOnly(refGeoXML, "SRPCODTime"), refGeo.srpCODTime); + parseDouble(getFirstAndOnly(refGeoXML, "SRPDwellTime"), refGeo.srpDwellTime); + + const xml::lite::Element* monoXML = getOptional(refGeoXML, "Monostatic"); + const xml::lite::Element* biXML = getOptional(refGeoXML, "Bistatic"); + if (monoXML && !biXML) + { + refGeo.monostatic.reset(new Monostatic()); + parseCommon(monoXML, (ImagingType*)refGeo.monostatic.get()); + parseDouble(getFirstAndOnly(monoXML, "SlantRange"), refGeo.monostatic->slantRange); + parseDouble(getFirstAndOnly(monoXML, "GroundRange"), refGeo.monostatic->groundRange); + parseDouble(getFirstAndOnly(monoXML, "DopplerConeAngle"), refGeo.monostatic->dopplerConeAngle); + parseDouble(getFirstAndOnly(monoXML, "IncidenceAngle"), refGeo.monostatic->incidenceAngle); + mCommon.parseVector3D(getFirstAndOnly(monoXML, "ARPPos"), refGeo.monostatic->arpPos); + mCommon.parseVector3D(getFirstAndOnly(monoXML, "ARPVel"), refGeo.monostatic->arpVel); + std::string side = ""; + parseString(getFirstAndOnly(monoXML, "SideOfTrack"), side); + refGeo.monostatic->sideOfTrack = (side == "L" ? six::SideOfTrackType::LEFT : six::SideOfTrackType::RIGHT); + + } + else if (!monoXML && biXML) + { + refGeo.bistatic.reset(new Bistatic()); + parseCommon(biXML, (ImagingType*)refGeo.bistatic.get()); + parseDouble(getFirstAndOnly(biXML, "AzimuthAngleRate"), refGeo.bistatic->azimuthAngleRate); + parseDouble(getFirstAndOnly(biXML, "BistaticAngle"), refGeo.bistatic->bistaticAngle); + parseDouble(getFirstAndOnly(biXML, "BistaticAngleRate"), refGeo.bistatic->bistaticAngleRate); + + parsePlatformParams(getFirstAndOnly(biXML, "TxPlatform"), refGeo.bistatic->txPlatform); + parsePlatformParams(getFirstAndOnly(biXML, "RcvPlatform"), refGeo.bistatic->rcvPlatform); + } + else + { + throw except::Exception(Ctxt( + "One of the two types Mono or Bi must be provided")); + } +} + +std::vector CPHDXMLParser::parseSupportArray(const std::string& tag, const xml::lite::Element& parent) const +{ + std::vector elements; + parent.getElementsByTagName(tag, elements); + std::vector supportArray; + supportArray.reserve(elements.size()); + for (const auto& element : elements) + { + SupportArrayParameter param; + parseSupportArrayParameter(element, param, false /*additionalFlag*/); + supportArray.push_back(std::move(param)); + } + return supportArray; +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* supportArrayXML, SupportArray& supportArray) +{ + supportArray.iazArray = parseSupportArray("IAZArray", *supportArrayXML); + supportArray.antGainPhase = parseSupportArray("AntGainPhase", *supportArrayXML); + supportArray.dwellTimeArray = parseSupportArray("DwellTimeArray", *supportArrayXML); + + std::vector addedSupportArrayXMLVec; + supportArrayXML->getElementsByTagName("AddedSupportArray", addedSupportArrayXMLVec); + for (size_t ii = 0; ii < addedSupportArrayXMLVec.size(); ++ii) + { + std::string id; + parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "Identifier"), id); + if (supportArray.addedSupportArray.count(id) == 0) + { + parseSupportArrayParameter(addedSupportArrayXMLVec[ii], supportArray.addedSupportArray[id], true); + parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "XUnits"), supportArray.addedSupportArray[id].xUnits); + parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "YUnits"), supportArray.addedSupportArray[id].yUnits); + parseString(getFirstAndOnly(addedSupportArrayXMLVec[ii], "ZUnits"), supportArray.addedSupportArray[id].zUnits); + mCommon.parseParameters(addedSupportArrayXMLVec[ii], "Parameter", supportArray.addedSupportArray[id].parameter); + } + else + { + throw except::Exception(Ctxt( + "Support array identifier for support array is not unique: " + id)); + } + } +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = AntPattern::EBFreqShiftSF{}; + six::getFirstAndOnly(parser(), *pXML, value(o).dcxsf); + six::getFirstAndOnly(parser(), *pXML, value(o).dcysf); + } +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = AntPattern::MLFreqDilationSF{}; + six::getFirstAndOnly(parser(), *pXML, value(o).dcxsf); + six::getFirstAndOnly(parser(), *pXML, value(o).dcysf); + } +} + +void CPHDXMLParser::parse(const xml::lite::Element& parent, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(parent, o.tag())) + { + o = AntPattern::AntPolRef{}; + six::getFirstAndOnly(parser(), *pXML, value(o).ampX); + six::getFirstAndOnly(parser(), *pXML, value(o).ampY); + six::getFirstAndOnly(parser(), *pXML, value(o).phaseY); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* antennaXML, Antenna& antenna) +{ + size_t numACFs = 0; + size_t numAPCs = 0; + size_t numAntPats = 0; + parseUInt(getFirstAndOnly(antennaXML, "NumACFs"), numACFs); + antenna.antCoordFrame.resize(numACFs); + parseUInt(getFirstAndOnly(antennaXML, "NumAPCs"), numAPCs); + antenna.antPhaseCenter.resize(numAPCs); + parseUInt(getFirstAndOnly(antennaXML, "NumAntPats"), numAntPats); + antenna.antPattern.resize(numAntPats); + + // Parse AntCoordFrame + std::vector antCoordFrameXMLVec; + antennaXML->getElementsByTagName("AntCoordFrame", antCoordFrameXMLVec); + if(antenna.antCoordFrame.size() != antCoordFrameXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of AntCoordFrames provided")); + } + for( size_t ii = 0; ii < antCoordFrameXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(antCoordFrameXMLVec[ii], "Identifier"), antenna.antCoordFrame[ii].identifier); + mCommon.parsePolyXYZ(getFirstAndOnly(antCoordFrameXMLVec[ii], "XAxisPoly"), antenna.antCoordFrame[ii].xAxisPoly); + mCommon.parsePolyXYZ(getFirstAndOnly(antCoordFrameXMLVec[ii], "YAxisPoly"), antenna.antCoordFrame[ii].yAxisPoly); + std::ignore = six::parse(parser(), *antCoordFrameXMLVec[ii], antenna.antCoordFrame[ii].useACFPVP); + } + + // Parse AntPhaseCenter + std::vector antPhaseCenterXMLVec; + antennaXML->getElementsByTagName("AntPhaseCenter", antPhaseCenterXMLVec); + if(antenna.antPhaseCenter.size() != antPhaseCenterXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of AntPhaseCenters provided")); + } + for( size_t ii = 0; ii < antPhaseCenterXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(antPhaseCenterXMLVec[ii], "Identifier"), antenna.antPhaseCenter[ii].identifier); + parseString(getFirstAndOnly(antPhaseCenterXMLVec[ii], "ACFId"), antenna.antPhaseCenter[ii].acfId); + mCommon.parseVector3D(getFirstAndOnly(antPhaseCenterXMLVec[ii], "APCXYZ"), antenna.antPhaseCenter[ii].apcXYZ); + } + + std::vector antPatternXMLVec; + antennaXML->getElementsByTagName("AntPattern", antPatternXMLVec); + if(antenna.antPattern.size() != antPatternXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of AntPatterns provided")); + } + for( size_t ii = 0; ii < antPatternXMLVec.size(); ++ii) + { + parseString(getFirstAndOnly(antPatternXMLVec[ii], "Identifier"), antenna.antPattern[ii].identifier); + parseDouble(getFirstAndOnly(antPatternXMLVec[ii], "FreqZero"), antenna.antPattern[ii].freqZero); + parseOptionalDouble(antPatternXMLVec[ii], "GainZero", antenna.antPattern[ii].gainZero); + + XMLElem ebFreqShiftXML = getOptional(antPatternXMLVec[ii], "EBFreqShift"); + if(ebFreqShiftXML) + { + parseBooleanType(ebFreqShiftXML, antenna.antPattern[ii].ebFreqShift); + } + parse(*antPatternXMLVec[ii], antenna.antPattern[ii].ebFreqShiftSF); + + XMLElem mlFreqDilationXML = getOptional(antPatternXMLVec[ii], "MLFreqDilation"); + if(mlFreqDilationXML) + { + parseBooleanType(mlFreqDilationXML, antenna.antPattern[ii].mlFreqDilation); + } + parse(*antPatternXMLVec[ii], antenna.antPattern[ii].mlFreqDilationSF); + + XMLElem gainBSPoly = getOptional(antPatternXMLVec[ii], "GainBSPoly"); + if(gainBSPoly) + { + mCommon.parsePoly1D(gainBSPoly, antenna.antPattern[ii].gainBSPoly); + } + + parse(*antPatternXMLVec[ii], antenna.antPattern[ii].antPolRef); + + // Parse EB + XMLElem ebXML = getFirstAndOnly(antPatternXMLVec[ii], "EB"); + mCommon.parsePoly1D(getFirstAndOnly(ebXML, "DCXPoly"), antenna.antPattern[ii].eb.dcxPoly); + mCommon.parsePoly1D(getFirstAndOnly(ebXML, "DCYPoly"), antenna.antPattern[ii].eb.dcyPoly); + std::ignore = six::parse(parser(), *ebXML, antenna.antPattern[ii].eb.useEBPVP); + + // Parse Array + XMLElem arrayXML = getFirstAndOnly(antPatternXMLVec[ii], "Array"); + mCommon.parsePoly2D(getFirstAndOnly(arrayXML, "GainPoly"), antenna.antPattern[ii].array.gainPoly); + mCommon.parsePoly2D(getFirstAndOnly(arrayXML, "PhasePoly"), antenna.antPattern[ii].array.phasePoly); + + // Parse Element + XMLElem elementXML = getFirstAndOnly(antPatternXMLVec[ii], "Element"); + mCommon.parsePoly2D(getFirstAndOnly(elementXML, "GainPoly"), antenna.antPattern[ii].element.gainPoly); + mCommon.parsePoly2D(getFirstAndOnly(elementXML, "PhasePoly"), antenna.antPattern[ii].element.phasePoly); + std::ignore = six::parse(parser(), *elementXML, antenna.antPattern[ii].element.antGPId); + + // Parse GainPhaseArray + std::vector gainPhaseArrayXMLVec; + antPatternXMLVec[ii]->getElementsByTagName("GainPhaseArray", gainPhaseArrayXMLVec); + antenna.antPattern[ii].gainPhaseArray.resize(gainPhaseArrayXMLVec.size()); + for (size_t jj = 0; jj < gainPhaseArrayXMLVec.size(); ++jj) + { + parseDouble(getFirstAndOnly(gainPhaseArrayXMLVec[jj], "Freq"), antenna.antPattern[ii].gainPhaseArray[jj].freq); + parseString(getFirstAndOnly(gainPhaseArrayXMLVec[jj], "ArrayId"), antenna.antPattern[ii].gainPhaseArray[jj].arrayId); + XMLElem elementIdXML = getOptional(gainPhaseArrayXMLVec[jj], "ElementId"); + if(elementIdXML) + { + parseString(elementIdXML, antenna.antPattern[ii].gainPhaseArray[jj].elementId); + } + + } + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* txRcvXML, TxRcv& txRcv) +{ + size_t numTxWFs = 0; + size_t numRcvs = 0; + parseUInt(getFirstAndOnly(txRcvXML, "NumTxWFs"), numTxWFs); + txRcv.txWFParameters.resize(numTxWFs); + parseUInt(getFirstAndOnly(txRcvXML, "NumRcvs"), numRcvs); + txRcv.rcvParameters.resize(numRcvs); + + std::vector txWFXMLVec; + txRcvXML->getElementsByTagName("TxWFParameters", txWFXMLVec); + if(txRcv.txWFParameters.size() != txWFXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of TxWF parameters provided")); + } + for(size_t ii = 0; ii < txWFXMLVec.size(); ++ii) + { + parseTxRcvParameter(txWFXMLVec[ii], txRcv.txWFParameters[ii]); + parseDouble(getFirstAndOnly(txWFXMLVec[ii], "PulseLength"), txRcv.txWFParameters[ii].pulseLength); + parseDouble(getFirstAndOnly(txWFXMLVec[ii], "RFBandwidth"), txRcv.txWFParameters[ii].rfBandwidth); + parseOptionalDouble(txWFXMLVec[ii], "Power", txRcv.txWFParameters[ii].power); + } + + std::vector rcvXMLVec; + txRcvXML->getElementsByTagName("RcvParameters", rcvXMLVec); + if(txRcv.rcvParameters.size() != rcvXMLVec.size()) + { + throw except::Exception(Ctxt( + "Incorrect number of Rcv parameters provided")); + } + for(size_t ii = 0; ii < rcvXMLVec.size(); ++ii) + { + parseTxRcvParameter(rcvXMLVec[ii], txRcv.rcvParameters[ii]); + parseDouble(getFirstAndOnly(rcvXMLVec[ii], "WindowLength"), txRcv.rcvParameters[ii].windowLength); + parseDouble(getFirstAndOnly(rcvXMLVec[ii], "SampleRate"), txRcv.rcvParameters[ii].sampleRate); + parseDouble(getFirstAndOnly(rcvXMLVec[ii], "IFFilterBW"), txRcv.rcvParameters[ii].ifFilterBW); + parseOptionalDouble(rcvXMLVec[ii], "PathGain", txRcv.rcvParameters[ii].pathGain); + } + +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* errParamXML, ErrorParameters& errParam) +{ + XMLElem monostaticXML = getOptional(errParamXML, "Monostatic"); + XMLElem bistaticXML = getOptional(errParamXML, "Bistatic"); + + if(monostaticXML && !bistaticXML) + { + errParam.monostatic.reset(new ErrorParameters::Monostatic()); + parsePosVelErr(getFirstAndOnly(monostaticXML, "PosVelErr"), errParam.monostatic->posVelErr); + + XMLElem radarSensorXML = getFirstAndOnly(monostaticXML, "RadarSensor"); + parseDouble(getFirstAndOnly(radarSensorXML, "RangeBias"), errParam.monostatic->radarSensor.rangeBias); + + parseOptionalDouble(radarSensorXML, "ClockFreqSF", errParam.monostatic->radarSensor.clockFreqSF); + parseOptionalDouble(radarSensorXML, "CollectionStartTime", errParam.monostatic->radarSensor.collectionStartTime); + + XMLElem rangeBiasDecorrXML = getOptional(radarSensorXML, "RangeBiasDecorr"); + if(rangeBiasDecorrXML) + { + errParam.monostatic->radarSensor.rangeBiasDecorr.reset(new six::DecorrType()); + mCommon.parseDecorrType(rangeBiasDecorrXML, *(errParam.monostatic->radarSensor.rangeBiasDecorr)); + } + + XMLElem tropoErrorXML = getOptional(monostaticXML, "TropoError"); + if(tropoErrorXML) + { + errParam.monostatic->tropoError.reset(new six::TropoError()); + parseOptionalDouble(tropoErrorXML, "TropoRangeVertical", errParam.monostatic->tropoError->tropoRangeVertical); + parseOptionalDouble(tropoErrorXML, "TropoRangeSlant", errParam.monostatic->tropoError->tropoRangeSlant); + mCommon.parseOptionalDecorrType(tropoErrorXML, "TropoRangeDecorr", errParam.monostatic->tropoError->tropoRangeDecorr); + } + + XMLElem ionoErrorXML = getOptional(monostaticXML, "IonoError"); + if(ionoErrorXML) + { + errParam.monostatic->ionoError.reset(new six::IonoError()); + parseDouble(getFirstAndOnly(ionoErrorXML, "IonoRangeVertical"), errParam.monostatic->ionoError->ionoRangeVertical); + + parseOptionalDouble(ionoErrorXML, "IonoRangeRateVertical", errParam.monostatic->ionoError->ionoRangeRateVertical); + parseOptionalDouble(ionoErrorXML, "IonoRgRgRateCC", errParam.monostatic->ionoError->ionoRgRgRateCC); + mCommon.parseOptionalDecorrType(ionoErrorXML, "IonoRangeVertDecorr", errParam.monostatic->ionoError->ionoRangeVertDecorr); + } + mCommon.parseParameters(monostaticXML, "Parameter", errParam.monostatic->parameter); + } + else if(!monostaticXML && bistaticXML) + { + errParam.bistatic.reset(new ErrorParameters::Bistatic()); + parsePlatform(getFirstAndOnly(bistaticXML, "TxPlatform"), errParam.bistatic->txPlatform); + parsePlatform(getFirstAndOnly(bistaticXML, "RcvPlatform"), errParam.bistatic->rcvPlatform); + mCommon.parseParameters(bistaticXML, "Parameter", errParam.bistatic->parameter); + } + else + { + throw except::Exception(Ctxt( + "Must be one of monostatic or bistatic")); + } +} + + +void CPHDXMLParser::fromXML(const xml::lite::Element* productInfoXML, ProductInfo& productInfo) +{ + XMLElem profileXML = getOptional(productInfoXML, "Profile"); + if(profileXML) + { + parseString(profileXML, productInfo.profile); + } + + std::vector creationInfoXML; + productInfoXML->getElementsByTagName("CreationInfo", creationInfoXML); + productInfo.creationInfo.resize(creationInfoXML.size()); + + for (size_t ii = 0; ii < creationInfoXML.size(); ++ii) + { + XMLElem applicationXML = getOptional(creationInfoXML[ii], "Application"); + if(applicationXML) + { + parseString(applicationXML, productInfo.creationInfo[ii].application); + } + + parseDateTime(getFirstAndOnly(creationInfoXML[ii], "DateTime"), productInfo.creationInfo[ii].dateTime); + + XMLElem siteXML = getOptional(creationInfoXML[ii], "Site"); + if(siteXML) + { + parseString(siteXML, productInfo.creationInfo[ii].site); + } + mCommon.parseParameters(creationInfoXML[ii], "Parameter", productInfo.creationInfo[ii].parameter); + } + mCommon.parseParameters(productInfoXML, "Parameter", productInfo.parameter); + +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* geoInfoXML, GeoInfo& geoInfo) +{ + std::vector < XMLElem > geoInfosXML; + geoInfoXML->getElementsByTagName("GeoInfo", geoInfosXML); + geoInfo.name = geoInfoXML->getAttributes().getValue("name"); + + //optional + mCommon.parseParameters(geoInfoXML, "Desc", geoInfo.desc); + + XMLElem tmpElem = getOptional(geoInfoXML, "Point"); + if (tmpElem) + { + LatLon ll; + mCommon.parseLatLon(tmpElem, ll); + geoInfo.geometryLatLon.push_back(ll); + } + else + { + std::string pointName = "Endpoint"; + tmpElem = getOptional(geoInfoXML, "Line"); + if (!tmpElem) + { + pointName = "Vertex"; + tmpElem = getOptional(geoInfoXML, "Polygon"); + } + if (tmpElem) + { + mCommon.parseLatLons(tmpElem, pointName, geoInfo.geometryLatLon); + } + } + + //optional + size_t idx(geoInfo.geoInfos.size()); + geoInfo.geoInfos.resize(idx + geoInfosXML.size()); + + for (auto it = geoInfosXML.begin(); it + != geoInfosXML.end(); ++it, ++idx) + { + geoInfo.geoInfos[idx].reset(new GeoInfo()); + fromXML(*it, *geoInfo.geoInfos[idx]); + } +} + +void CPHDXMLParser::fromXML(const xml::lite::Element* matchInfoXML, MatchInformation& matchInfo) +{ + mCommon.parseMatchInformationFromXML(matchInfoXML, &matchInfo); +} + + +XMLElem CPHDXMLParser::createLatLonFootprint(const std::string& name, + const std::string& cornerName, + const cphd::LatLonCorners& corners, + XMLElem parent) const +{ + XMLElem footprint = newElement(name, parent); + + // Write the corners in CW order + XMLElem vertex = + mCommon.createLatLon(cornerName, corners.upperLeft, footprint); + setAttribute(vertex, "index", "1"); + + vertex = mCommon.createLatLon(cornerName, corners.upperRight, footprint); + setAttribute(vertex, "index", "2"); + + vertex = mCommon.createLatLon(cornerName, corners.lowerRight, footprint); + setAttribute(vertex, "index", "3"); + + vertex = mCommon.createLatLon(cornerName, corners.lowerLeft, footprint); + setAttribute(vertex, "index", "4"); + + return footprint; +} + +XMLElem CPHDXMLParser::createPVPType(const std::string& name, + const PVPType& p, + XMLElem parent) const +{ + XMLElem pvpXML = newElement(name, parent); + createInt("Offset", p.getOffset(), pvpXML); + createInt("Size", p.getSize(), pvpXML); + createString("Format", p.getFormat(), pvpXML); + return pvpXML; +} + +XMLElem CPHDXMLParser::createAPVPType(const std::string& name, + const APVPType& p, + XMLElem parent) const +{ + XMLElem apvpXML = newElement(name, parent); + createString("Name", p.getName(), apvpXML); + createInt("Offset", p.getOffset(), apvpXML); + createInt("Size", p.getSize(), apvpXML); + createString("Format", p.getFormat(), apvpXML); + return apvpXML; +} + +XMLElem CPHDXMLParser::createErrorParamPlatform( + const std::string& /*name*/, + const ErrorParameters::Bistatic::Platform p, + XMLElem parent) const +{ + XMLElem posVelErrXML = newElement("PosVelErr", parent); + createString("Frame", p.posVelErr.frame, posVelErrXML); + createDouble("P1", p.posVelErr.p1, posVelErrXML); + createDouble("P2", p.posVelErr.p2, posVelErrXML); + createDouble("P3", p.posVelErr.p3, posVelErrXML); + createDouble("V1", p.posVelErr.v1, posVelErrXML); + createDouble("V2", p.posVelErr.v2, posVelErrXML); + createDouble("V3", p.posVelErr.v3, posVelErrXML); + if(p.posVelErr.corrCoefs.get()) + { + XMLElem corrCoefsXML = newElement("CorrCoefs", posVelErrXML); + createDouble("P1P2", p.posVelErr.corrCoefs->p1p2, corrCoefsXML); + createDouble("P1P3", p.posVelErr.corrCoefs->p1p3, corrCoefsXML); + createDouble("P1V1", p.posVelErr.corrCoefs->p1v1, corrCoefsXML); + createDouble("P1V2", p.posVelErr.corrCoefs->p1v2, corrCoefsXML); + createDouble("P1V3", p.posVelErr.corrCoefs->p1v3, corrCoefsXML); + createDouble("P2P3", p.posVelErr.corrCoefs->p2p3, corrCoefsXML); + createDouble("P2V1", p.posVelErr.corrCoefs->p2v1, corrCoefsXML); + createDouble("P2V2", p.posVelErr.corrCoefs->p2v2, corrCoefsXML); + createDouble("P2V3", p.posVelErr.corrCoefs->p2v3, corrCoefsXML); + createDouble("P3V1", p.posVelErr.corrCoefs->p3v1, corrCoefsXML); + createDouble("P3V2", p.posVelErr.corrCoefs->p3v2, corrCoefsXML); + createDouble("P3V3", p.posVelErr.corrCoefs->p3v3, corrCoefsXML); + createDouble("V1V2", p.posVelErr.corrCoefs->v1v2, corrCoefsXML); + createDouble("V1V3", p.posVelErr.corrCoefs->v1v3, corrCoefsXML); + createDouble("V2V3", p.posVelErr.corrCoefs->v2v3, corrCoefsXML); + } + createDecorrType("PositionDecorr", p.posVelErr.positionDecorr, posVelErrXML); + return posVelErrXML; +} + +XMLElem CPHDXMLParser::createDecorrType(const std::string& name, const six::DecorrType& dt, + XMLElem parent) const +{ + if (six::Init::isDefined(dt)) + { + XMLElem element = newElement(name, parent); + createDouble("CorrCoefZero", dt.corrCoefZero, element); + createDouble("DecorrRate", dt.decorrRate, element); + return element; + } + return nullptr; +} +XMLElem CPHDXMLParser::createDecorrType(const std::string& name, const std::optional& dt, + XMLElem parent) const +{ + if (dt.has_value()) + { + return createDecorrType(name, *dt, parent); + } + return nullptr; +} + +/* + * Parser helper functions + */ +void CPHDXMLParser::parseAreaType(const xml::lite::Element* areaXML, AreaType& area) const +{ + mCommon.parseVector2D(getFirstAndOnly(areaXML, "X1Y1"), area.x1y1); + mCommon.parseVector2D(getFirstAndOnly(areaXML, "X2Y2"), area.x2y2); + const xml::lite::Element* polygonXML = getOptional(areaXML, "Polygon"); + if (polygonXML) + { + std::vector verticesXML; + polygonXML->getElementsByTagName("Vertex", verticesXML); + if (verticesXML.size() < 3) + { + throw except::Exception(Ctxt( + "Polygons must have at least 3 sides")); + } + area.polygon.resize(verticesXML.size()); + for (size_t ii = 0; ii < area.polygon.size(); ++ii) + { + Vector2& vertex = area.polygon[ii]; + const xml::lite::Element* vertexXML = verticesXML[ii]; + mCommon.parseVector2D(vertexXML, vertex); + } + } +} + +void CPHDXMLParser::parseLineSample(const xml::lite::Element* lsXML, LineSample& ls) const +{ + parseDouble(getFirstAndOnly(lsXML, "Line"), ls.line); + parseDouble(getFirstAndOnly(lsXML, "Sample"), ls.sample); +} + +void CPHDXMLParser::parseIAExtent(const xml::lite::Element* extentXML, + ImageAreaXExtent& extent) const +{ + parseDouble(getFirstAndOnly(extentXML, "LineSpacing"), + extent.lineSpacing); + parseInt(getFirstAndOnly(extentXML, "FirstLine"), + extent.firstLine); + parseUInt(getFirstAndOnly(extentXML, "NumLines"), + extent.numLines); +} + +void CPHDXMLParser::parseIAExtent(const xml::lite::Element* extentXML, + ImageAreaYExtent& extent) const +{ + parseDouble(getFirstAndOnly(extentXML, "SampleSpacing"), + extent.sampleSpacing); + parseInt(getFirstAndOnly(extentXML, "FirstSample"), + extent.firstSample); + parseUInt(getFirstAndOnly(extentXML, "NumSamples"), + extent.numSamples); +} + +void CPHDXMLParser::parseChannelParameters( + const xml::lite::Element* paramXML, ChannelParameter& param) const +{ + parseString(getFirstAndOnly(paramXML, "Identifier"), param.identifier); + parseUInt(getFirstAndOnly(paramXML, "RefVectorIndex"), param.refVectorIndex); + parseBooleanType(getFirstAndOnly(paramXML, "FXFixed"), param.fxFixed); + parseBooleanType(getFirstAndOnly(paramXML, "TOAFixed"), param.toaFixed); + parseBooleanType(getFirstAndOnly(paramXML, "SRPFixed"), param.srpFixed); + + XMLElem signalXML = getOptional(paramXML, "SignalNormal"); + if (signalXML) + { + parseBooleanType(signalXML, param.signalNormal); + } + + parseDouble(getFirstAndOnly(paramXML, "FxC"), param.fxC); + parseDouble(getFirstAndOnly(paramXML, "FxBW"), param.fxBW); + parseOptionalDouble(paramXML, "FxBWNoise", param.fxBWNoise); + parseDouble(getFirstAndOnly(paramXML, "TOASaved"), param.toaSaved); + + XMLElem toaExtendedXML = getOptional(paramXML, "TOAExtended"); + if(toaExtendedXML) + { + param.toaExtended.reset(new TOAExtended()); + parseDouble(getFirstAndOnly(toaExtendedXML, "TOAExtSaved"), param.toaExtended->toaExtSaved); + XMLElem lfmEclipseXML = getOptional(toaExtendedXML, "LFMEclipse"); + if(lfmEclipseXML) + { + param.toaExtended->lfmEclipse.reset(new TOAExtended::LFMEclipse()); + parseDouble(getFirstAndOnly(lfmEclipseXML, "FxEarlyLow"), param.toaExtended->lfmEclipse->fxEarlyLow); + parseDouble(getFirstAndOnly(lfmEclipseXML, "FxEarlyHigh"), param.toaExtended->lfmEclipse->fxEarlyHigh); + parseDouble(getFirstAndOnly(lfmEclipseXML, "FxLateLow"), param.toaExtended->lfmEclipse->fxLateLow); + parseDouble(getFirstAndOnly(lfmEclipseXML, "FxLateHigh"), param.toaExtended->lfmEclipse->fxLateHigh); + } + } + + XMLElem dwellTimesXML = getFirstAndOnly(paramXML, "DwellTimes"); + parseString(getFirstAndOnly(dwellTimesXML, "CODId"), param.dwellTimes.codId); + parseString(getFirstAndOnly(dwellTimesXML, "DwellId"), param.dwellTimes.dwellId); + std::ignore = six::parse(parser(), *dwellTimesXML, param.dwellTimes.dtaId); + std::ignore = six::parse(parser(), *dwellTimesXML, param.dwellTimes.useDTA); + + XMLElem imageAreaXML = getOptional(paramXML, "ImageArea"); + if(imageAreaXML) + { + parseAreaType(imageAreaXML, param.imageArea); + } + + XMLElem antennaXML = getOptional(paramXML, "Antenna"); + if(antennaXML) + { + param.antenna.reset(new ChannelParameter::Antenna()); + parseString(getFirstAndOnly(antennaXML, "TxAPCId"), param.antenna->txAPCId); + parseString(getFirstAndOnly(antennaXML, "TxAPATId"), param.antenna->txAPATId); + parseString(getFirstAndOnly(antennaXML, "RcvAPCId"), param.antenna->rcvAPCId); + parseString(getFirstAndOnly(antennaXML, "RcvAPATId"), param.antenna->rcvAPATId); + } + + XMLElem txRcvXML = getOptional(paramXML, "TxRcv"); + if(txRcvXML) + { + std::vector txWFIdXML; + txRcvXML->getElementsByTagName("TxWFId", txWFIdXML); + param.txRcv.reset(new ChannelParameter::TxRcv()); + param.txRcv->txWFId.resize(txWFIdXML.size()); + for(size_t ii = 0; ii < txWFIdXML.size(); ++ii) + { + parseString(txWFIdXML[ii], param.txRcv->txWFId[ii]); + } + + std::vector rcvIdXML; + txRcvXML->getElementsByTagName("RcvId", rcvIdXML); + param.txRcv->rcvId.resize(rcvIdXML.size()); + for(size_t ii = 0; ii < rcvIdXML.size(); ++ii) + { + parseString(rcvIdXML[ii], param.txRcv->rcvId[ii]); + } + } + + XMLElem tgtRefLevelXML = getOptional(paramXML, "TgtRefLevel"); + if(tgtRefLevelXML) + { + param.tgtRefLevel.reset(new TgtRefLevel()); + parseDouble(getFirstAndOnly(tgtRefLevelXML, "PTRef"), param.tgtRefLevel->ptRef); + } + + XMLElem noiseLevelXML = getOptional(paramXML, "NoiseLevel"); + if(noiseLevelXML) + { + param.noiseLevel.reset(new NoiseLevel()); + parseDouble(getFirstAndOnly(noiseLevelXML, "PNRef"), param.noiseLevel->pnRef); + parseDouble(getFirstAndOnly(noiseLevelXML, "BNRef"), param.noiseLevel->bnRef); + if(!(param.noiseLevel->bnRef > 0 && param.noiseLevel->bnRef <= 1)) + { + throw except::Exception(Ctxt( + "Noise equivalent BW value must be > 0.0 and <= 1.0")); + } + + XMLElem fxNoiseProfileXML = getOptional(noiseLevelXML, "FxNoiseProfile"); + if(fxNoiseProfileXML) + { + param.noiseLevel->fxNoiseProfile.reset(new FxNoiseProfile()); + std::vector pointXMLVec; + fxNoiseProfileXML->getElementsByTagName("Point", pointXMLVec); + if(pointXMLVec.size() < 2) + { + throw except::Exception(Ctxt( + "Atleast 2 noise profile points must be provided")); + } + param.noiseLevel->fxNoiseProfile->point.resize(pointXMLVec.size()); + double prevPoint = six::Init::undefined(); + for(size_t ii = 0; ii < pointXMLVec.size(); ++ii) + { + double fx; + parseDouble(getFirstAndOnly(pointXMLVec[ii], "Fx"), fx); + parseDouble(getFirstAndOnly(pointXMLVec[ii], "PN"), param.noiseLevel->fxNoiseProfile->point[ii].pn); + + if(!six::Init::isUndefined(prevPoint) && fx <= prevPoint) + { + throw except::Exception(Ctxt( + "Fx values are strictly increasing")); + } + param.noiseLevel->fxNoiseProfile->point[ii].fx = fx; + prevPoint = fx; + } + } + } + + // Polarization + parsePolarization(*paramXML, param.polarization); +} + +void CPHDXMLParser::parse(const xml::lite::Element& polarizationXML, six::XsElement_minOccurs0& o) const +{ + if (const auto pXML = getOptional(polarizationXML, o.tag())) + { + o = PolRef{}; + six::getFirstAndOnly(parser(), *pXML, value(o).ampH); + six::getFirstAndOnly(parser(), *pXML, value(o).ampV); + six::getFirstAndOnly(parser(), *pXML, value(o).phaseV); + } +} + +void CPHDXMLParser::parsePolarization(const xml::lite::Element& paramXML, Polarization& polarization) const +{ + std::vector PolarizationXML; + paramXML.getElementsByTagName("Polarization", PolarizationXML); + for (size_t ii = 0; ii < PolarizationXML.size(); ++ii) + { + const xml::lite::Element* TxPolXML = getFirstAndOnly(PolarizationXML[ii], "TxPol"); + polarization.txPol = PolarizationType::toType(TxPolXML->getCharacterData()); + + const xml::lite::Element* RcvPolXML = getFirstAndOnly(PolarizationXML[ii], "RcvPol"); + polarization.rcvPol = PolarizationType::toType(RcvPolXML->getCharacterData()); + + parse(*(PolarizationXML[ii]), polarization.txPolRef); // added in CPHD 1.1.0 + parse(*(PolarizationXML[ii]), polarization.rcvPolRef); // added in CPHD 1.1.0 + } +} + +size_t CPHDXMLParser::parsePVPType(const xml::lite::Element& paramXML, PVPType& param) const +{ + size_t size; + size_t offset; + std::string format; + parseUInt(getFirstAndOnly(paramXML, "Size"), size); + parseUInt(getFirstAndOnly(paramXML, "Offset"), offset); + parseString(getFirstAndOnly(paramXML, "Format"), format); + if (param.getSize() != size) + { + std::ostringstream ostr; + ostr << "Specified size: " << size << " does not match default size: " << param.getSize(); + throw except::Exception(Ctxt(ostr.str())); + } + if (param.getFormat() != format) + { + std::ostringstream ostr; + ostr << "Specified format: " << format << " does not match default format: " << param.getFormat(); + throw except::Exception(Ctxt(ostr.str())); + } + return offset; +} +void CPHDXMLParser::parsePVPType(Pvp& pvp, const xml::lite::Element* paramXML, PVPType& param) const +{ + const auto offset = parsePVPType(*paramXML, param); + pvp.setOffset(offset, param); +} + +void CPHDXMLParser::parsePVPType(Pvp& pvp, const xml::lite::Element* paramXML) const +{ + std::string name; + size_t size; + size_t offset; + std::string format; + parseString(getFirstAndOnly(paramXML, "Name"), name); + parseUInt(getFirstAndOnly(paramXML, "Size"), size); + parseUInt(getFirstAndOnly(paramXML, "Offset"), offset); + parseString(getFirstAndOnly(paramXML, "Format"), format); + pvp.setCustomParameter(size, offset, format, name); +} + +bool CPHDXMLParser::parseOptionalPVPType(const xml::lite::Element* parent, const std::string& tag, Pvp& pvp, PVPType& param) const +{ + if (const xml::lite::Element* const element = getOptional(parent, tag)) + { + parsePVPType(pvp, element, param); + return true; + } + return false; +} + +void CPHDXMLParser::parsePlatformParams(const xml::lite::Element* platXML, Bistatic::PlatformParams& plat) const +{ + parseDouble(getFirstAndOnly(platXML, "Time"), plat.time); + parseDouble(getFirstAndOnly(platXML, "SlantRange"), plat.slantRange); + parseDouble(getFirstAndOnly(platXML, "GroundRange"), plat.groundRange); + parseDouble(getFirstAndOnly(platXML, "DopplerConeAngle"), plat.dopplerConeAngle); + parseDouble(getFirstAndOnly(platXML, "AzimuthAngle"), plat.azimuthAngle); + parseDouble(getFirstAndOnly(platXML, "GrazeAngle"), plat.grazeAngle); + parseDouble(getFirstAndOnly(platXML, "IncidenceAngle"), plat.incidenceAngle); + mCommon.parseVector3D(getFirstAndOnly(platXML, "Pos"), plat.pos); + mCommon.parseVector3D(getFirstAndOnly(platXML, "Vel"), plat.vel); + std::string side = ""; + parseString(getFirstAndOnly(platXML, "SideOfTrack"), side); + plat.sideOfTrack = (side == "L" ? six::SideOfTrackType::LEFT : six::SideOfTrackType::RIGHT); + +} + +void CPHDXMLParser::parseCommon(const xml::lite::Element* imgTypeXML, ImagingType* imgType) const +{ + parseDouble(getFirstAndOnly(imgTypeXML, "TwistAngle"), imgType->twistAngle); + parseDouble(getFirstAndOnly(imgTypeXML, "SlopeAngle"), imgType->slopeAngle); + parseDouble(getFirstAndOnly(imgTypeXML, "LayoverAngle"), imgType->layoverAngle); + parseDouble(getFirstAndOnly(imgTypeXML, "AzimuthAngle"), imgType->azimuthAngle); + parseDouble(getFirstAndOnly(imgTypeXML, "GrazeAngle"), imgType->grazeAngle); +} + +void CPHDXMLParser::parsePosVelErr(const xml::lite::Element* posVelErrXML, six::PosVelError& posVelErr) const +{ + std::string frameStr; + parseString(getFirstAndOnly(posVelErrXML, "Frame"), frameStr); + posVelErr.frame.mValue = scene::FrameType::fromString(frameStr); + parseDouble(getFirstAndOnly(posVelErrXML, "P1"), posVelErr.p1); + parseDouble(getFirstAndOnly(posVelErrXML, "P2"), posVelErr.p2); + parseDouble(getFirstAndOnly(posVelErrXML, "P3"), posVelErr.p3); + parseDouble(getFirstAndOnly(posVelErrXML, "V1"), posVelErr.v1); + parseDouble(getFirstAndOnly(posVelErrXML, "V2"), posVelErr.v2); + parseDouble(getFirstAndOnly(posVelErrXML, "V3"), posVelErr.v3); + + XMLElem corrCoefsXML = getOptional(posVelErrXML, "CorrCoefs"); + + if(corrCoefsXML) + { + posVelErr.corrCoefs.reset(new six::CorrCoefs()); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1P2"), posVelErr.corrCoefs->p1p2); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1P3"), posVelErr.corrCoefs->p1p3); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1V1"), posVelErr.corrCoefs->p1v1); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1V2"), posVelErr.corrCoefs->p1v2); + parseDouble(getFirstAndOnly(corrCoefsXML, "P1V3"), posVelErr.corrCoefs->p1v3); + parseDouble(getFirstAndOnly(corrCoefsXML, "P2P3"), posVelErr.corrCoefs->p2p3); + parseDouble(getFirstAndOnly(corrCoefsXML, "P2V1"), posVelErr.corrCoefs->p2v1); + parseDouble(getFirstAndOnly(corrCoefsXML, "P2V2"), posVelErr.corrCoefs->p2v2); + parseDouble(getFirstAndOnly(corrCoefsXML, "P2V3"), posVelErr.corrCoefs->p2v3); + parseDouble(getFirstAndOnly(corrCoefsXML, "P3V1"), posVelErr.corrCoefs->p3v1); + parseDouble(getFirstAndOnly(corrCoefsXML, "P3V2"), posVelErr.corrCoefs->p3v2); + parseDouble(getFirstAndOnly(corrCoefsXML, "P3V3"), posVelErr.corrCoefs->p3v3); + parseDouble(getFirstAndOnly(corrCoefsXML, "V1V2"), posVelErr.corrCoefs->v1v2); + parseDouble(getFirstAndOnly(corrCoefsXML, "V1V3"), posVelErr.corrCoefs->v1v3); + parseDouble(getFirstAndOnly(corrCoefsXML, "V2V3"), posVelErr.corrCoefs->v2v3); + } + + // posVelErr.positionDecorr.reset(new six::DecorrType()); + mCommon.parseOptionalDecorrType(posVelErrXML, "PositionDecorr", posVelErr.positionDecorr); +} + +void CPHDXMLParser::parsePlatform(const xml::lite::Element* platXML, ErrorParameters::Bistatic::Platform& plat) const +{ + parsePosVelErr(getFirstAndOnly(platXML, "PosVelErr"), plat.posVelErr); + XMLElem radarSensorXML = getFirstAndOnly(platXML, "RadarSensor"); + six::parse(parser(), *radarSensorXML, plat.radarSensor.delayBias); + parseOptionalDouble(radarSensorXML, "ClockFreqSF", plat.radarSensor.clockFreqSF); + parseDouble(getFirstAndOnly(radarSensorXML, "CollectionStartTime"), plat.radarSensor.collectionStartTime); +} + +void CPHDXMLParser::parseSupportArrayParameter(const xml::lite::Element* paramXML, SupportArrayParameter& param, bool additionalFlag) const +{ + if(!additionalFlag) + { + size_t identifierVal; + parseUInt(getFirstAndOnly(paramXML, "Identifier"), identifierVal); + param.setIdentifier(identifierVal); + } + parseString(getFirstAndOnly(paramXML, "ElementFormat"), param.elementFormat); + parseDouble(getFirstAndOnly(paramXML, "X0"), param.x0); + parseDouble(getFirstAndOnly(paramXML, "Y0"), param.y0); + parseDouble(getFirstAndOnly(paramXML, "XSS"), param.xSS); + parseDouble(getFirstAndOnly(paramXML, "YSS"), param.ySS); +} + +void CPHDXMLParser::parseTxRcvParameter(const xml::lite::Element* paramXML, ParameterType& param) const +{ + parseString(getFirstAndOnly(paramXML, "Identifier"), param.identifier); + parseDouble(getFirstAndOnly(paramXML, "FreqCenter"), param.freqCenter); + parseOptionalDouble(paramXML, "LFMRate", param.lfmRate); + param.polarization = PolarizationType::toType(getFirstAndOnly(paramXML, "Polarization")->getCharacterData()); +} +} diff --git a/six/modules/c++/cphd/source/Channel.cpp b/six/modules/c++/cphd/source/Channel.cpp index 351303a402..e9e6df6ad0 100644 --- a/six/modules/c++/cphd/source/Channel.cpp +++ b/six/modules/c++/cphd/source/Channel.cpp @@ -1,227 +1,227 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include - -#include - -namespace cphd -{ - -TOAExtended::TOAExtended() : - toaExtSaved(six::Init::undefined()) -{ -} - -TOAExtended::LFMEclipse::LFMEclipse() : - fxEarlyLow(six::Init::undefined()), - fxEarlyHigh(six::Init::undefined()), - fxLateLow(six::Init::undefined()), - fxLateHigh(six::Init::undefined()) -{ -} - -DwellTimes::DwellTimes() -{ -} - -TgtRefLevel::TgtRefLevel() : - ptRef(six::Init::undefined()) -{ -} - -Point::Point() : - fx(six::Init::undefined()), - pn(six::Init::undefined()) -{ -} - -NoiseLevel::NoiseLevel() : - pnRef(six::Init::undefined()), - bnRef(six::Init::undefined()) -{ -} - -ChannelParameter::ChannelParameter() : - refVectorIndex(six::Init::undefined()), - fxFixed(six::Init::undefined()), - toaFixed(six::Init::undefined()), - srpFixed(six::Init::undefined()), - signalNormal(six::Init::undefined()), - fxC(six::Init::undefined()), - fxBW(six::Init::undefined()), - fxBWNoise(six::Init::undefined()), - toaSaved(six::Init::undefined()) -{ -} - -ChannelParameter::Antenna::Antenna() -{ -} - -Channel::Channel() : - fxFixedCphd(six::Init::undefined()), - toaFixedCphd(six::Init::undefined()), - srpFixedCphd(six::Init::undefined()) -{ -} - -std::ostream& operator<< (std::ostream& os, const PolRef& v) -{ - os << v.ampH << v.ampV << v.phaseV << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Polarization& p) -{ - os << " TxPol : " << p.txPol << "\n" - << " RcvPol : " << p.rcvPol << "\n" - << p.txPolRef << p.rcvPolRef; - return os; -} - -std::ostream& operator<< (std::ostream& os, const TOAExtended& t) -{ - os << " TOAExtended:: \n" - << " TOAExtSaved : " << t.toaExtSaved << "\n" - << " LFMEclipse:: \n" - << " FxEarlyLow : " << t.lfmEclipse->fxEarlyLow << "\n" - << " FxEarlyHigh : " << t.lfmEclipse->fxEarlyHigh << "\n" - << " FxLateLow : " << t.lfmEclipse->fxLateLow << "\n" - << " FxLateHigh : " << t.lfmEclipse->fxLateHigh << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const DwellTimes& d) -{ - os << " DwellTimes:: \n" - << " CODId : " << d.codId << "\n" - << " DwellId : " << d.dwellId << "\n" - << d.dtaId - << d.useDTA; - return os; -} - -std::ostream& operator<< (std::ostream& os, const TgtRefLevel& t) -{ - os << " TgtRefLevel:: \n" - << " PtRef : " << t.ptRef << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Point& p) -{ - os << " Point:: \n" - << " Fx : " << p.fx << "\n" - << " Pn : " << p.pn << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const FxNoiseProfile& f) -{ - os << " FxNoiseProfile:: \n"; - for (const auto& point : f.point) - { - os << " Point : " << point << "\n"; - } - return os; -} - -std::ostream& operator<< (std::ostream& os, const NoiseLevel& n) -{ - os << " NoiseLevel:: \n" - << " PnRef : " << n.pnRef << "\n" - << " BnRef : " << n.bnRef << "\n"; - if(n.fxNoiseProfile.get()) - { - os << *(n.fxNoiseProfile) << "\n"; - } - return os; -} - -std::ostream& operator<< (std::ostream& os, const ChannelParameter& c) -{ - os << " ChannelParameter:: \n" - << " Identifier : " << c.identifier << "\n" - << " RefVectorIndex : " << c.refVectorIndex << "\n" - << " FxFixed : " << c.fxFixed << "\n" - << " TOAFixed : " << c.toaFixed << "\n" - << " SRPFixed : " << c.srpFixed << "\n" - << " SginalNormal : " << c.signalNormal << "\n" - << " Polarization:: \n" - << c.polarization << "\n" - << " FxC : " << c.fxC << "\n" - << " FxBW : " << c.fxBW << "\n" - << " FxBWNoise : " << c.fxBWNoise << "\n" - << " TOASaved : " << c.toaSaved << "\n"; - if (c.toaExtended.get()) - { - os << *(c.toaExtended) << "\n"; - } - os << c.dwellTimes << "\n" - << c.imageArea << "\n" - << " Antenna:: \n" - << " TxAPCId : " << c.antenna->txAPCId << "\n" - << " TxAPATId : " << c.antenna->txAPATId << "\n" - << " RcvAPCId : " << c.antenna->rcvAPCId << "\n" - << " RcvAPATId : " << c.antenna->rcvAPATId << "\n" - << " TxRcv:: \n"; - for (size_t ii = 0; ii < c.txRcv->txWFId.size(); ++ii) - { - os << " TxWFId : " << c.txRcv->txWFId[ii] << "\n"; - } - for (size_t ii = 0; ii < c.txRcv->rcvId.size(); ++ii) - { - os << " RcvId : " << c.txRcv->rcvId[ii] << "\n"; - } - if (c.tgtRefLevel.get()) - { - os << *(c.tgtRefLevel) << "\n"; - } - if (c.noiseLevel.get()) - { - os << *(c.noiseLevel) << "\n"; - } - return os; -} - -std::ostream& operator<< (std::ostream& os, const Channel& c) -{ - os << "Channel:: \n" - << " RefChId : " << c.refChId << "\n" - << " FxFixedCphd : " << c.fxFixedCphd << "\n" - << " TOAFixedCphd : " << c.toaFixedCphd << "\n" - << " SRPFixedCphd : " << c.srpFixedCphd << "\n" - << " Parameters:: \n"; - for (size_t ii = 0; ii < c.parameters.size(); ++ii) - { - os << c.parameters[ii] << "\n"; - } - for (size_t ii = 0; ii < c.addedParameters.size(); ++ii) - { - os << " Parameter name : " << c.addedParameters[ii].getName() << "\n"; - os << " Parameter value : " << c.addedParameters[ii].str() << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include + +#include + +namespace cphd +{ + +TOAExtended::TOAExtended() : + toaExtSaved(six::Init::undefined()) +{ +} + +TOAExtended::LFMEclipse::LFMEclipse() : + fxEarlyLow(six::Init::undefined()), + fxEarlyHigh(six::Init::undefined()), + fxLateLow(six::Init::undefined()), + fxLateHigh(six::Init::undefined()) +{ +} + +DwellTimes::DwellTimes() +{ +} + +TgtRefLevel::TgtRefLevel() : + ptRef(six::Init::undefined()) +{ +} + +Point::Point() : + fx(six::Init::undefined()), + pn(six::Init::undefined()) +{ +} + +NoiseLevel::NoiseLevel() : + pnRef(six::Init::undefined()), + bnRef(six::Init::undefined()) +{ +} + +ChannelParameter::ChannelParameter() : + refVectorIndex(six::Init::undefined()), + fxFixed(six::Init::undefined()), + toaFixed(six::Init::undefined()), + srpFixed(six::Init::undefined()), + signalNormal(six::Init::undefined()), + fxC(six::Init::undefined()), + fxBW(six::Init::undefined()), + fxBWNoise(six::Init::undefined()), + toaSaved(six::Init::undefined()) +{ +} + +ChannelParameter::Antenna::Antenna() +{ +} + +Channel::Channel() : + fxFixedCphd(six::Init::undefined()), + toaFixedCphd(six::Init::undefined()), + srpFixedCphd(six::Init::undefined()) +{ +} + +std::ostream& operator<< (std::ostream& os, const PolRef& v) +{ + os << v.ampH << v.ampV << v.phaseV << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Polarization& p) +{ + os << " TxPol : " << p.txPol << "\n" + << " RcvPol : " << p.rcvPol << "\n" + << p.txPolRef << p.rcvPolRef; + return os; +} + +std::ostream& operator<< (std::ostream& os, const TOAExtended& t) +{ + os << " TOAExtended:: \n" + << " TOAExtSaved : " << t.toaExtSaved << "\n" + << " LFMEclipse:: \n" + << " FxEarlyLow : " << t.lfmEclipse->fxEarlyLow << "\n" + << " FxEarlyHigh : " << t.lfmEclipse->fxEarlyHigh << "\n" + << " FxLateLow : " << t.lfmEclipse->fxLateLow << "\n" + << " FxLateHigh : " << t.lfmEclipse->fxLateHigh << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const DwellTimes& d) +{ + os << " DwellTimes:: \n" + << " CODId : " << d.codId << "\n" + << " DwellId : " << d.dwellId << "\n" + << d.dtaId + << d.useDTA; + return os; +} + +std::ostream& operator<< (std::ostream& os, const TgtRefLevel& t) +{ + os << " TgtRefLevel:: \n" + << " PtRef : " << t.ptRef << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Point& p) +{ + os << " Point:: \n" + << " Fx : " << p.fx << "\n" + << " Pn : " << p.pn << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const FxNoiseProfile& f) +{ + os << " FxNoiseProfile:: \n"; + for (const auto& point : f.point) + { + os << " Point : " << point << "\n"; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const NoiseLevel& n) +{ + os << " NoiseLevel:: \n" + << " PnRef : " << n.pnRef << "\n" + << " BnRef : " << n.bnRef << "\n"; + if(n.fxNoiseProfile.get()) + { + os << *(n.fxNoiseProfile) << "\n"; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const ChannelParameter& c) +{ + os << " ChannelParameter:: \n" + << " Identifier : " << c.identifier << "\n" + << " RefVectorIndex : " << c.refVectorIndex << "\n" + << " FxFixed : " << c.fxFixed << "\n" + << " TOAFixed : " << c.toaFixed << "\n" + << " SRPFixed : " << c.srpFixed << "\n" + << " SginalNormal : " << c.signalNormal << "\n" + << " Polarization:: \n" + << c.polarization << "\n" + << " FxC : " << c.fxC << "\n" + << " FxBW : " << c.fxBW << "\n" + << " FxBWNoise : " << c.fxBWNoise << "\n" + << " TOASaved : " << c.toaSaved << "\n"; + if (c.toaExtended.get()) + { + os << *(c.toaExtended) << "\n"; + } + os << c.dwellTimes << "\n" + << c.imageArea << "\n" + << " Antenna:: \n" + << " TxAPCId : " << c.antenna->txAPCId << "\n" + << " TxAPATId : " << c.antenna->txAPATId << "\n" + << " RcvAPCId : " << c.antenna->rcvAPCId << "\n" + << " RcvAPATId : " << c.antenna->rcvAPATId << "\n" + << " TxRcv:: \n"; + for (size_t ii = 0; ii < c.txRcv->txWFId.size(); ++ii) + { + os << " TxWFId : " << c.txRcv->txWFId[ii] << "\n"; + } + for (size_t ii = 0; ii < c.txRcv->rcvId.size(); ++ii) + { + os << " RcvId : " << c.txRcv->rcvId[ii] << "\n"; + } + if (c.tgtRefLevel.get()) + { + os << *(c.tgtRefLevel) << "\n"; + } + if (c.noiseLevel.get()) + { + os << *(c.noiseLevel) << "\n"; + } + return os; +} + +std::ostream& operator<< (std::ostream& os, const Channel& c) +{ + os << "Channel:: \n" + << " RefChId : " << c.refChId << "\n" + << " FxFixedCphd : " << c.fxFixedCphd << "\n" + << " TOAFixedCphd : " << c.toaFixedCphd << "\n" + << " SRPFixedCphd : " << c.srpFixedCphd << "\n" + << " Parameters:: \n"; + for (size_t ii = 0; ii < c.parameters.size(); ++ii) + { + os << c.parameters[ii] << "\n"; + } + for (size_t ii = 0; ii < c.addedParameters.size(); ++ii) + { + os << " Parameter name : " << c.addedParameters[ii].getName() << "\n"; + os << " Parameter value : " << c.addedParameters[ii].str() << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/Dwell.cpp b/six/modules/c++/cphd/source/Dwell.cpp index c3e5ef39c1..16d77eb0a5 100644 --- a/six/modules/c++/cphd/source/Dwell.cpp +++ b/six/modules/c++/cphd/source/Dwell.cpp @@ -1,73 +1,73 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include - -namespace cphd -{ - -DwellTime::DwellTime() : - dwellTimePoly(six::Init::undefined()) -{ -} - -COD::COD() : - codTimePoly(six::Init::undefined()) -{ -} - -Dwell::Dwell() -{ -} - -std::ostream& operator<< (std::ostream& os, const DwellTime& d) -{ - os << " DwellTime:: \n" - << " Identifier : " << d.identifier << "\n" - << " DwellTimePoly : " << d.dwellTimePoly << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const COD& c) -{ - os << " COD:: \n" - << " Identifier : " << c.identifier << "\n" - << " CODTimePoly : " << c.codTimePoly << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Dwell& d) -{ - os << "Dwell:: \n" - << " NumCODTimes : " << d.cod.size() << "\n" - << " NumDwellTimes : " << d.dtime.size() << "\n"; - for (const auto& cod : d.cod) - { - os << cod << "\n"; - } - for (const auto& dtime : d.dtime) - { - os << dtime << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include + +namespace cphd +{ + +DwellTime::DwellTime() : + dwellTimePoly(six::Init::undefined()) +{ +} + +COD::COD() : + codTimePoly(six::Init::undefined()) +{ +} + +Dwell::Dwell() +{ +} + +std::ostream& operator<< (std::ostream& os, const DwellTime& d) +{ + os << " DwellTime:: \n" + << " Identifier : " << d.identifier << "\n" + << " DwellTimePoly : " << d.dwellTimePoly << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const COD& c) +{ + os << " COD:: \n" + << " Identifier : " << c.identifier << "\n" + << " CODTimePoly : " << c.codTimePoly << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Dwell& d) +{ + os << "Dwell:: \n" + << " NumCODTimes : " << d.cod.size() << "\n" + << " NumDwellTimes : " << d.dtime.size() << "\n"; + for (const auto& cod : d.cod) + { + os << cod << "\n"; + } + for (const auto& dtime : d.dtime) + { + os << dtime << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/ErrorParameters.cpp b/six/modules/c++/cphd/source/ErrorParameters.cpp index 368773f7a2..4dfe3550b8 100644 --- a/six/modules/c++/cphd/source/ErrorParameters.cpp +++ b/six/modules/c++/cphd/source/ErrorParameters.cpp @@ -1,191 +1,191 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include -#include - -namespace cphd -{ -ErrorParameters::Monostatic::RadarSensor::RadarSensor() : - rangeBias(six::Init::undefined()), - clockFreqSF(six::Init::undefined()), - collectionStartTime(six::Init::undefined()) -{ -} - -ErrorParameters::Bistatic::RadarSensor::RadarSensor() : - clockFreqSF(six::Init::undefined()), - collectionStartTime(six::Init::undefined()) -{ -} - -static std::ostream& unchecked(std::ostream& os, const six::DecorrType& decorr_) -{ - const auto decorr = six::value(decorr_); - os << " CorrCoefZero : " << decorr.corrCoefZero << "\n" - << " DecorrRate : " << decorr.decorrRate << "\n"; - return os; -} -std::ostream& unchecked(std::ostream& os, const std::optional& decorr) -{ - return unchecked(os, *decorr); -} - -static std::ostream& checked(std::ostream& os, const std::string& s, const six::DecorrType& decorr) -{ - if (six::Init::isDefined(decorr)) - { - os << s; - return unchecked(os, decorr); - } - return os; -} -std::ostream& checked(std::ostream& os, const std::string& s, const std::optional& decorr) -{ - return decorr.has_value() ? checked(os, s, *decorr) : os; -} - - -static std::ostream& checked(std::ostream& os, const std::string& s, const double& v) -{ - if (six::Init::isDefined(v)) - { - os << s << v << "\n"; - } - return os; -} -std::ostream& checked(std::ostream& os, const std::string& s, const std::optional& v) -{ - return v.has_value() ? checked(os, s, *v) : os; -} - -std::ostream& operator<< (std::ostream& os, const six::PosVelError& p) -{ - os << " PosVelError:: \n" - << " Frame : " << p.frame << "\n" - << " P1 : " << p.p1 << "\n" - << " P2 : " << p.p2 << "\n" - << " P3 : " << p.p3 << "\n" - << " V1 : " << p.v1 << "\n" - << " V2 : " << p.v2 << "\n" - << " V3 : " << p.v3 << "\n"; - if (p.corrCoefs.get()) - { - os << " CorrCoefs:: \n" - << " p1p2 : " << p.corrCoefs->p1p2 << "\n" - << " p1p3 : " << p.corrCoefs->p1p3 << "\n" - << " p1v1 : " << p.corrCoefs->p1v1 << "\n" - << " p1v2 : " << p.corrCoefs->p1v2 << "\n" - << " p1v3 : " << p.corrCoefs->p1v3 << "\n" - << " p2p3 : " << p.corrCoefs->p2p3 << "\n" - << " p2v1 : " << p.corrCoefs->p2v1 << "\n" - << " p2v2 : " << p.corrCoefs->p2v2 << "\n" - << " p2v3 : " << p.corrCoefs->p2v3 << "\n" - << " p3v1 : " << p.corrCoefs->p3v1 << "\n" - << " p3v2 : " << p.corrCoefs->p3v2 << "\n" - << " p3v3 : " << p.corrCoefs->p3v3 << "\n" - << " v1v2 : " << p.corrCoefs->v1v2 << "\n" - << " v1v3 : " << p.corrCoefs->v1v3 << "\n" - << " v2v3 : " << p.corrCoefs->v2v3 << "\n"; - } - os << " Decorr:: \n"; - return unchecked(os, p.positionDecorr); -} - -static std::ostream& operator<< (std::ostream& os, const ErrorParameters::Bistatic::RadarSensor& v) -{ - os << " RadarSensor:: \n" - << v.delayBias - << " ClockFreqSF : " << v.clockFreqSF << "\n" - << " CollectionStartTime : " <posVelErr << "\n" - << " RadarSensor:: \n" - << " RangeBias : " << e.monostatic->radarSensor.rangeBias << "\n"; - if (!six::Init::isUndefined(e.monostatic->radarSensor.clockFreqSF)) - { - os << " ClockFreqSF : " << e.monostatic->radarSensor.clockFreqSF << "\n"; - } - if (!six::Init::isUndefined(e.monostatic->radarSensor.collectionStartTime)) - { - os << " CollectionStartTime : " << e.monostatic->radarSensor.collectionStartTime << "\n"; - } - if (e.monostatic->radarSensor.rangeBiasDecorr.get()) - { - os << " RangeBiasDecorr:: \n" - << " CorrCoefZero : " << e.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero << "\n" - << " DecorrRate : " << e.monostatic->radarSensor.rangeBiasDecorr->decorrRate << "\n"; - } - if (e.monostatic->tropoError.get()) - { - os << " TropoError:: \n"; - checked(os, " TropoRangeVertical : ", e.monostatic->tropoError->tropoRangeVertical); - checked(os, " TropoRangeSlant : ", e.monostatic->tropoError->tropoRangeSlant); - checked(os, " TropoRangeDecorr:: \n", e.monostatic->tropoError->tropoRangeDecorr); - } - if (e.monostatic->ionoError.get()) - { - os << " IonoError:: \n"; - checked(os, " IonoRangeVertical : ", e.monostatic->ionoError->ionoRangeVertical); - checked(os, " IonoRangeRateVertical : ", e.monostatic->ionoError->ionoRangeRateVertical); - os << " IonoRgRgRateCC : " << six::value(e.monostatic->ionoError->ionoRgRgRateCC) << "\n"; - checked(os, " IonoRangeDecorr:: \n", e.monostatic->ionoError->ionoRangeVertDecorr); - } - for (const auto& parameter : e.monostatic->parameter) - { - os << " Parameter Name : " << parameter.getName() << "\n" - << " Parameter Value : " << parameter.str() << "\n"; - } - } - else if (e.bistatic.get()) - { - os << " Bistatic:: \n" - << " TxPlatform:: \n" - << e.bistatic->txPlatform.posVelErr << "\n" - << e.bistatic->txPlatform.radarSensor - << "\n" - << " RcvPlatform:: \n" - << e.bistatic->rcvPlatform.posVelErr << "\n" - << e.bistatic->rcvPlatform.radarSensor; - for (const auto& parameter : e.bistatic->parameter) - { - os << " Parameter Name : " << parameter.getName() << "\n" - << " Parameter Value : " << parameter.str() << "\n"; - } - } - else - { - throw except::Exception(Ctxt( - "One of either monostatic or bistatic is required")); - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include +#include + +namespace cphd +{ +ErrorParameters::Monostatic::RadarSensor::RadarSensor() : + rangeBias(six::Init::undefined()), + clockFreqSF(six::Init::undefined()), + collectionStartTime(six::Init::undefined()) +{ +} + +ErrorParameters::Bistatic::RadarSensor::RadarSensor() : + clockFreqSF(six::Init::undefined()), + collectionStartTime(six::Init::undefined()) +{ +} + +static std::ostream& unchecked(std::ostream& os, const six::DecorrType& decorr_) +{ + const auto decorr = six::value(decorr_); + os << " CorrCoefZero : " << decorr.corrCoefZero << "\n" + << " DecorrRate : " << decorr.decorrRate << "\n"; + return os; +} +std::ostream& unchecked(std::ostream& os, const std::optional& decorr) +{ + return unchecked(os, *decorr); +} + +static std::ostream& checked(std::ostream& os, const std::string& s, const six::DecorrType& decorr) +{ + if (six::Init::isDefined(decorr)) + { + os << s; + return unchecked(os, decorr); + } + return os; +} +std::ostream& checked(std::ostream& os, const std::string& s, const std::optional& decorr) +{ + return decorr.has_value() ? checked(os, s, *decorr) : os; +} + + +static std::ostream& checked(std::ostream& os, const std::string& s, const double& v) +{ + if (six::Init::isDefined(v)) + { + os << s << v << "\n"; + } + return os; +} +std::ostream& checked(std::ostream& os, const std::string& s, const std::optional& v) +{ + return v.has_value() ? checked(os, s, *v) : os; +} + +std::ostream& operator<< (std::ostream& os, const six::PosVelError& p) +{ + os << " PosVelError:: \n" + << " Frame : " << p.frame << "\n" + << " P1 : " << p.p1 << "\n" + << " P2 : " << p.p2 << "\n" + << " P3 : " << p.p3 << "\n" + << " V1 : " << p.v1 << "\n" + << " V2 : " << p.v2 << "\n" + << " V3 : " << p.v3 << "\n"; + if (p.corrCoefs.get()) + { + os << " CorrCoefs:: \n" + << " p1p2 : " << p.corrCoefs->p1p2 << "\n" + << " p1p3 : " << p.corrCoefs->p1p3 << "\n" + << " p1v1 : " << p.corrCoefs->p1v1 << "\n" + << " p1v2 : " << p.corrCoefs->p1v2 << "\n" + << " p1v3 : " << p.corrCoefs->p1v3 << "\n" + << " p2p3 : " << p.corrCoefs->p2p3 << "\n" + << " p2v1 : " << p.corrCoefs->p2v1 << "\n" + << " p2v2 : " << p.corrCoefs->p2v2 << "\n" + << " p2v3 : " << p.corrCoefs->p2v3 << "\n" + << " p3v1 : " << p.corrCoefs->p3v1 << "\n" + << " p3v2 : " << p.corrCoefs->p3v2 << "\n" + << " p3v3 : " << p.corrCoefs->p3v3 << "\n" + << " v1v2 : " << p.corrCoefs->v1v2 << "\n" + << " v1v3 : " << p.corrCoefs->v1v3 << "\n" + << " v2v3 : " << p.corrCoefs->v2v3 << "\n"; + } + os << " Decorr:: \n"; + return unchecked(os, p.positionDecorr); +} + +static std::ostream& operator<< (std::ostream& os, const ErrorParameters::Bistatic::RadarSensor& v) +{ + os << " RadarSensor:: \n" + << v.delayBias + << " ClockFreqSF : " << v.clockFreqSF << "\n" + << " CollectionStartTime : " <posVelErr << "\n" + << " RadarSensor:: \n" + << " RangeBias : " << e.monostatic->radarSensor.rangeBias << "\n"; + if (!six::Init::isUndefined(e.monostatic->radarSensor.clockFreqSF)) + { + os << " ClockFreqSF : " << e.monostatic->radarSensor.clockFreqSF << "\n"; + } + if (!six::Init::isUndefined(e.monostatic->radarSensor.collectionStartTime)) + { + os << " CollectionStartTime : " << e.monostatic->radarSensor.collectionStartTime << "\n"; + } + if (e.monostatic->radarSensor.rangeBiasDecorr.get()) + { + os << " RangeBiasDecorr:: \n" + << " CorrCoefZero : " << e.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero << "\n" + << " DecorrRate : " << e.monostatic->radarSensor.rangeBiasDecorr->decorrRate << "\n"; + } + if (e.monostatic->tropoError.get()) + { + os << " TropoError:: \n"; + checked(os, " TropoRangeVertical : ", e.monostatic->tropoError->tropoRangeVertical); + checked(os, " TropoRangeSlant : ", e.monostatic->tropoError->tropoRangeSlant); + checked(os, " TropoRangeDecorr:: \n", e.monostatic->tropoError->tropoRangeDecorr); + } + if (e.monostatic->ionoError.get()) + { + os << " IonoError:: \n"; + checked(os, " IonoRangeVertical : ", e.monostatic->ionoError->ionoRangeVertical); + checked(os, " IonoRangeRateVertical : ", e.monostatic->ionoError->ionoRangeRateVertical); + os << " IonoRgRgRateCC : " << six::value(e.monostatic->ionoError->ionoRgRgRateCC) << "\n"; + checked(os, " IonoRangeDecorr:: \n", e.monostatic->ionoError->ionoRangeVertDecorr); + } + for (const auto& parameter : e.monostatic->parameter) + { + os << " Parameter Name : " << parameter.getName() << "\n" + << " Parameter Value : " << parameter.str() << "\n"; + } + } + else if (e.bistatic.get()) + { + os << " Bistatic:: \n" + << " TxPlatform:: \n" + << e.bistatic->txPlatform.posVelErr << "\n" + << e.bistatic->txPlatform.radarSensor + << "\n" + << " RcvPlatform:: \n" + << e.bistatic->rcvPlatform.posVelErr << "\n" + << e.bistatic->rcvPlatform.radarSensor; + for (const auto& parameter : e.bistatic->parameter) + { + os << " Parameter Name : " << parameter.getName() << "\n" + << " Parameter Value : " << parameter.str() << "\n"; + } + } + else + { + throw except::Exception(Ctxt( + "One of either monostatic or bistatic is required")); + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/PVP.cpp b/six/modules/c++/cphd/source/PVP.cpp index 7400ac4bd0..ab675012aa 100644 --- a/six/modules/c++/cphd/source/PVP.cpp +++ b/six/modules/c++/cphd/source/PVP.cpp @@ -1,280 +1,280 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include - -#include -#include - -#include -#include - -namespace cphd -{ -PVPType::PVPType() : - mSize(0), - mOffset(six::Init::undefined()) -{ -} - -APVPType::APVPType() -{ -} - -Pvp::Pvp() -{ - initialize(); -} - -void Pvp::initialize() -{ - // Default size and formats for each PVP - // listed in Table 11-6 CPHD1.0 Spec - setDefaultValues(1,"F8", txTime); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", txPos); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", txVel); - setDefaultValues(1,"F8", rcvTime); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvVel); - setDefaultValues(3,"X=F8;Y=F8;Z=F8;", srpPos); - setDefaultValues(1,"F8", ampSF); - setDefaultValues(1,"F8", aFDOP); - setDefaultValues(1,"F8", aFRR1); - setDefaultValues(1,"F8", aFRR2); - setDefaultValues(1,"F8", fx1); - setDefaultValues(1,"F8", fx2); - setDefaultValues(1,"F8", fxN1); - setDefaultValues(1,"F8", fxN2); - setDefaultValues(1,"F8", toa1); - setDefaultValues(1,"F8", toa2); - setDefaultValues(1,"F8", toaE1); - setDefaultValues(1,"F8", toaE2); - setDefaultValues(1,"F8", tdTropoSRP); - setDefaultValues(1,"F8", tdIonoSRP); - setDefaultValues(1,"F8", sc0); - setDefaultValues(1,"F8", scss); - setDefaultValues(1,"I8", signal); -} - -void Pvp::validate(size_t size, size_t offset) -{ - //Check if size of array is sufficient for write - if (offset + size > mParamLocations.size()) - { - mParamLocations.resize(offset+size); - } - - //Check if any blocks will be overwritten - for (size_t ii = 0; ii < size; ++ii) - { - if(mParamLocations.at(offset + ii) == true) - { - throw except::Exception(Ctxt("This byte block is occupied")); - } - } - - // Mark each block as written - for (size_t ii = 0; ii < size; ++ii) - { - mParamLocations.at(offset + ii) = true; - } -} - -void setOffset(PVPType& param, size_t offset) -{ - validateFormat(param.getFormat()); - param.setOffset(offset); -} - -void Pvp::setOffset(size_t offset, PVPType& param) -{ - validate(param.getSize(), offset); - cphd::setOffset(param, offset); -} - -void Pvp::append(PVPType& param) -{ - size_t currentOffset = mParamLocations.size(); - setOffset(currentOffset, param); -} - -// Assumes addedPVP is already correct size -void Pvp::setCustomParameter(size_t size, size_t offset, const std::string& format, const std::string& name) -{ - validate(size, offset); - validateFormat(format); - if (addedPVP.count(name) == 0) - { - addedPVP[name] = APVPType(); - addedPVP.find(name)->second.setData(size, offset, format, name); - return; - } - throw except::Exception(Ctxt( - "Additional parameter name is not unique")); -} - -void Pvp::appendCustomParameter(size_t size, const std::string& format, const std::string& name) -{ - size_t currentOffset = mParamLocations.size(); - setCustomParameter(size, currentOffset, format, name); -} - -void Pvp::setDefaultValues(size_t size, const std::string& format, PVPType& param) -{ - param.setSize(size); - param.setFormat(format); -} - -// Returns num blocks (not bytes) -size_t Pvp::getReqSetSize() const -{ - size_t res = txTime.getSize() + txPos.getSize() + txVel.getSize() + - rcvTime.getSize() + rcvPos.getSize() + rcvVel.getSize() + srpPos.getSize() + - aFDOP.getSize() + aFRR1.getSize() + aFRR2.getSize() + fx1.getSize() + - fx2.getSize() + toa1.getSize() + toa2.getSize() + tdTropoSRP.getSize() + - sc0.getSize() + scss.getSize(); - if(!six::Init::isUndefined(ampSF.getOffset())) - { - res += ampSF.getSize(); - } - if(!six::Init::isUndefined(fxN1.getOffset())) - { - res += fxN1.getSize(); - } - if(!six::Init::isUndefined(fxN2.getOffset())) - { - res += fxN2.getSize(); - } - if(!six::Init::isUndefined(toaE1.getOffset())) - { - res += toaE1.getSize(); - } - if(!six::Init::isUndefined(toaE2.getOffset())) - { - res += toaE2.getSize(); - } - if(!six::Init::isUndefined(tdIonoSRP.getOffset())) - { - res += tdIonoSRP.getSize(); - } - if(!six::Init::isUndefined(signal.getOffset())) - { - res += signal.getSize(); - } - for (auto it = addedPVP.begin(); it != addedPVP.end(); ++it) - { - res += it->second.getSize(); - } - return res; -} - -size_t Pvp::sizeInBytes() const -{ - return getReqSetSize() * PVPType::WORD_BYTE_SIZE; -} - -std::ostream& operator<< (std::ostream& os, const PVPType& p) -{ - os << " Size : " << p.getSize() << "\n" - << " Offset : " << p.getOffset() << "\n" - << " Format : " << p.getFormat() << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const APVPType& a) -{ - os << " Name : " << a.getName() << "\n" - << (PVPType)a; - - return os; -} - -std::ostream& operator<< (std::ostream& os, const Pvp& p) -{ - os << " TxTime : \n" << p.txTime << "\n" - << " TxPos : \n" << p.txPos << "\n" - << " TxVel : \n" << p.txVel << "\n" - << " RcvTime : \n" << p.rcvTime << "\n" - << " RcvPos : \n" << p.rcvPos << "\n" - << " RcvVel : \n" << p.rcvVel << "\n" - << " SRPPos : \n" << p.srpPos << "\n" - << " aFDOP : \n" << p.aFDOP << "\n" - << " aFRR1 : \n" << p.aFRR1 << "\n" - << " aFRR2 : \n" << p.aFRR2 << "\n" - << " Fx1 : \n" << p.fx1 << "\n" - << " Fx2 : \n" << p.fx2 << "\n" - << " TOA1 : \n" << p.toa1 << "\n" - << " TOA2 : \n" << p.toa2 << "\n" - << " TdTropoSRP : \n" << p.tdTropoSRP << "\n" - << " SC0 : \n" << p.sc0 << "\n" - << " SCSS : \n" << p.scss << "\n"; - - if(!six::Init::isUndefined(p.ampSF.getOffset())) - { - os << " AmpSF : \n" << p.ampSF << "\n"; - } - if(!six::Init::isUndefined(p.fxN1.getOffset())) - { - os << " FxN1 : \n" << p.fxN1 << "\n"; - } - if(!six::Init::isUndefined(p.fxN2.getOffset())) - { - os << " FxN2 : \n" << p.fxN2 << "\n"; - } - if(!six::Init::isUndefined(p.toaE1.getOffset())) - { - os << " TOAE1 : \n" << p.toaE1 << "\n"; - } - if(!six::Init::isUndefined(p.toaE2.getOffset())) - { - os << " TOAE2 : \n" << p.toaE2 << "\n"; - } - if(!six::Init::isUndefined(p.tdIonoSRP.getOffset())) - { - os << " TdIonoSRP : \n" << p.tdIonoSRP << "\n"; - } - if(!six::Init::isUndefined(p.signal.getOffset())) - { - os << " SIGNAL : \n" << p.signal << "\n"; - } - for (auto it = p.addedPVP.begin(); it != p.addedPVP.end(); ++it) - { - os << " Additional Parameter : " << it->second << "\n"; - } - return os; -} - -PerVectorParameterXYZ::PerVectorParameterXYZ() -{ - // setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); - param.setSize(3); // - param.setFormat("X=F8;Y=F8;Z=F8;"); // -} - -PerVectorParameterEB::PerVectorParameterEB() -{ - // setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); - param.setSize(2); // - param.setFormat("DCX=F8;DCY=F8;"); // -} - -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include + +#include +#include + +#include +#include + +namespace cphd +{ +PVPType::PVPType() : + mSize(0), + mOffset(six::Init::undefined()) +{ +} + +APVPType::APVPType() +{ +} + +Pvp::Pvp() +{ + initialize(); +} + +void Pvp::initialize() +{ + // Default size and formats for each PVP + // listed in Table 11-6 CPHD1.0 Spec + setDefaultValues(1,"F8", txTime); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", txPos); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", txVel); + setDefaultValues(1,"F8", rcvTime); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvVel); + setDefaultValues(3,"X=F8;Y=F8;Z=F8;", srpPos); + setDefaultValues(1,"F8", ampSF); + setDefaultValues(1,"F8", aFDOP); + setDefaultValues(1,"F8", aFRR1); + setDefaultValues(1,"F8", aFRR2); + setDefaultValues(1,"F8", fx1); + setDefaultValues(1,"F8", fx2); + setDefaultValues(1,"F8", fxN1); + setDefaultValues(1,"F8", fxN2); + setDefaultValues(1,"F8", toa1); + setDefaultValues(1,"F8", toa2); + setDefaultValues(1,"F8", toaE1); + setDefaultValues(1,"F8", toaE2); + setDefaultValues(1,"F8", tdTropoSRP); + setDefaultValues(1,"F8", tdIonoSRP); + setDefaultValues(1,"F8", sc0); + setDefaultValues(1,"F8", scss); + setDefaultValues(1,"I8", signal); +} + +void Pvp::validate(size_t size, size_t offset) +{ + //Check if size of array is sufficient for write + if (offset + size > mParamLocations.size()) + { + mParamLocations.resize(offset+size); + } + + //Check if any blocks will be overwritten + for (size_t ii = 0; ii < size; ++ii) + { + if(mParamLocations.at(offset + ii) == true) + { + throw except::Exception(Ctxt("This byte block is occupied")); + } + } + + // Mark each block as written + for (size_t ii = 0; ii < size; ++ii) + { + mParamLocations.at(offset + ii) = true; + } +} + +void setOffset(PVPType& param, size_t offset) +{ + validateFormat(param.getFormat()); + param.setOffset(offset); +} + +void Pvp::setOffset(size_t offset, PVPType& param) +{ + validate(param.getSize(), offset); + cphd::setOffset(param, offset); +} + +void Pvp::append(PVPType& param) +{ + size_t currentOffset = mParamLocations.size(); + setOffset(currentOffset, param); +} + +// Assumes addedPVP is already correct size +void Pvp::setCustomParameter(size_t size, size_t offset, const std::string& format, const std::string& name) +{ + validate(size, offset); + validateFormat(format); + if (addedPVP.count(name) == 0) + { + addedPVP[name] = APVPType(); + addedPVP.find(name)->second.setData(size, offset, format, name); + return; + } + throw except::Exception(Ctxt( + "Additional parameter name is not unique")); +} + +void Pvp::appendCustomParameter(size_t size, const std::string& format, const std::string& name) +{ + size_t currentOffset = mParamLocations.size(); + setCustomParameter(size, currentOffset, format, name); +} + +void Pvp::setDefaultValues(size_t size, const std::string& format, PVPType& param) +{ + param.setSize(size); + param.setFormat(format); +} + +// Returns num blocks (not bytes) +size_t Pvp::getReqSetSize() const +{ + size_t res = txTime.getSize() + txPos.getSize() + txVel.getSize() + + rcvTime.getSize() + rcvPos.getSize() + rcvVel.getSize() + srpPos.getSize() + + aFDOP.getSize() + aFRR1.getSize() + aFRR2.getSize() + fx1.getSize() + + fx2.getSize() + toa1.getSize() + toa2.getSize() + tdTropoSRP.getSize() + + sc0.getSize() + scss.getSize(); + if(!six::Init::isUndefined(ampSF.getOffset())) + { + res += ampSF.getSize(); + } + if(!six::Init::isUndefined(fxN1.getOffset())) + { + res += fxN1.getSize(); + } + if(!six::Init::isUndefined(fxN2.getOffset())) + { + res += fxN2.getSize(); + } + if(!six::Init::isUndefined(toaE1.getOffset())) + { + res += toaE1.getSize(); + } + if(!six::Init::isUndefined(toaE2.getOffset())) + { + res += toaE2.getSize(); + } + if(!six::Init::isUndefined(tdIonoSRP.getOffset())) + { + res += tdIonoSRP.getSize(); + } + if(!six::Init::isUndefined(signal.getOffset())) + { + res += signal.getSize(); + } + for (auto it = addedPVP.begin(); it != addedPVP.end(); ++it) + { + res += it->second.getSize(); + } + return res; +} + +size_t Pvp::sizeInBytes() const +{ + return getReqSetSize() * PVPType::WORD_BYTE_SIZE; +} + +std::ostream& operator<< (std::ostream& os, const PVPType& p) +{ + os << " Size : " << p.getSize() << "\n" + << " Offset : " << p.getOffset() << "\n" + << " Format : " << p.getFormat() << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const APVPType& a) +{ + os << " Name : " << a.getName() << "\n" + << (PVPType)a; + + return os; +} + +std::ostream& operator<< (std::ostream& os, const Pvp& p) +{ + os << " TxTime : \n" << p.txTime << "\n" + << " TxPos : \n" << p.txPos << "\n" + << " TxVel : \n" << p.txVel << "\n" + << " RcvTime : \n" << p.rcvTime << "\n" + << " RcvPos : \n" << p.rcvPos << "\n" + << " RcvVel : \n" << p.rcvVel << "\n" + << " SRPPos : \n" << p.srpPos << "\n" + << " aFDOP : \n" << p.aFDOP << "\n" + << " aFRR1 : \n" << p.aFRR1 << "\n" + << " aFRR2 : \n" << p.aFRR2 << "\n" + << " Fx1 : \n" << p.fx1 << "\n" + << " Fx2 : \n" << p.fx2 << "\n" + << " TOA1 : \n" << p.toa1 << "\n" + << " TOA2 : \n" << p.toa2 << "\n" + << " TdTropoSRP : \n" << p.tdTropoSRP << "\n" + << " SC0 : \n" << p.sc0 << "\n" + << " SCSS : \n" << p.scss << "\n"; + + if(!six::Init::isUndefined(p.ampSF.getOffset())) + { + os << " AmpSF : \n" << p.ampSF << "\n"; + } + if(!six::Init::isUndefined(p.fxN1.getOffset())) + { + os << " FxN1 : \n" << p.fxN1 << "\n"; + } + if(!six::Init::isUndefined(p.fxN2.getOffset())) + { + os << " FxN2 : \n" << p.fxN2 << "\n"; + } + if(!six::Init::isUndefined(p.toaE1.getOffset())) + { + os << " TOAE1 : \n" << p.toaE1 << "\n"; + } + if(!six::Init::isUndefined(p.toaE2.getOffset())) + { + os << " TOAE2 : \n" << p.toaE2 << "\n"; + } + if(!six::Init::isUndefined(p.tdIonoSRP.getOffset())) + { + os << " TdIonoSRP : \n" << p.tdIonoSRP << "\n"; + } + if(!six::Init::isUndefined(p.signal.getOffset())) + { + os << " SIGNAL : \n" << p.signal << "\n"; + } + for (auto it = p.addedPVP.begin(); it != p.addedPVP.end(); ++it) + { + os << " Additional Parameter : " << it->second << "\n"; + } + return os; +} + +PerVectorParameterXYZ::PerVectorParameterXYZ() +{ + // setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); + param.setSize(3); // + param.setFormat("X=F8;Y=F8;Z=F8;"); // +} + +PerVectorParameterEB::PerVectorParameterEB() +{ + // setDefaultValues(3,"X=F8;Y=F8;Z=F8;", rcvPos); + param.setSize(2); // + param.setFormat("DCX=F8;DCY=F8;"); // +} + +} diff --git a/six/modules/c++/cphd/source/ProductInfo.cpp b/six/modules/c++/cphd/source/ProductInfo.cpp index 44607d601f..caf266aaa1 100644 --- a/six/modules/c++/cphd/source/ProductInfo.cpp +++ b/six/modules/c++/cphd/source/ProductInfo.cpp @@ -1,63 +1,63 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include - -namespace cphd -{ -ProductInfo::ProductInfo() -{ -} - -ProductInfo::CreationInfo::CreationInfo(): - dateTime(six::Init::undefined()) -{ -} - -std::ostream& operator<< (std::ostream& os, const ProductInfo& p) -{ - os << "Product Information : \n" - << " Profile : " << p.profile << "\n"; - for (size_t ii = 0; ii < p.creationInfo.size(); ++ii) - { - os << " Creation Information : " << "\n" - << " Application : " << p.creationInfo[ii].application << "\n" - << " DateTime : " << p.creationInfo[ii].dateTime.getMonth() << "/" - << p.creationInfo[ii].dateTime.getDayOfMonth() << "/" - << p.creationInfo[ii].dateTime.getYear() << "\n" - << " Site : " << p.creationInfo[ii].site << "\n"; - for (size_t jj = 0; jj < p.creationInfo[ii].parameter.size(); ++jj) - { - os << " Parameter name : " - << p.creationInfo[ii].parameter[jj].getName() << "\n" - << " Parameter value : " << p.creationInfo[ii].parameter[jj].str() << "\n"; - } - } - for (size_t ii = 0; ii < p.parameter.size(); ++ii) - { - os << " Parameter name : " << p.parameter[ii].getName() << "\n" - << " Parameter value : " << p.parameter[ii].str() << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include + +namespace cphd +{ +ProductInfo::ProductInfo() +{ +} + +ProductInfo::CreationInfo::CreationInfo(): + dateTime(six::Init::undefined()) +{ +} + +std::ostream& operator<< (std::ostream& os, const ProductInfo& p) +{ + os << "Product Information : \n" + << " Profile : " << p.profile << "\n"; + for (size_t ii = 0; ii < p.creationInfo.size(); ++ii) + { + os << " Creation Information : " << "\n" + << " Application : " << p.creationInfo[ii].application << "\n" + << " DateTime : " << p.creationInfo[ii].dateTime.getMonth() << "/" + << p.creationInfo[ii].dateTime.getDayOfMonth() << "/" + << p.creationInfo[ii].dateTime.getYear() << "\n" + << " Site : " << p.creationInfo[ii].site << "\n"; + for (size_t jj = 0; jj < p.creationInfo[ii].parameter.size(); ++jj) + { + os << " Parameter name : " + << p.creationInfo[ii].parameter[jj].getName() << "\n" + << " Parameter value : " << p.creationInfo[ii].parameter[jj].str() << "\n"; + } + } + for (size_t ii = 0; ii < p.parameter.size(); ++ii) + { + os << " Parameter name : " << p.parameter[ii].getName() << "\n" + << " Parameter value : " << p.parameter[ii].str() << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/ReferenceGeometry.cpp b/six/modules/c++/cphd/source/ReferenceGeometry.cpp index 0823dd4950..7c6bb22b1e 100644 --- a/six/modules/c++/cphd/source/ReferenceGeometry.cpp +++ b/six/modules/c++/cphd/source/ReferenceGeometry.cpp @@ -1,174 +1,174 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include - -namespace cphd -{ - -SRP::SRP() : - ecf(six::Init::undefined()), - iac(six::Init::undefined()) -{ -} - -ImagingType::ImagingType() : - azimuthAngle(0), - grazeAngle(0), - twistAngle(0), - slopeAngle(0), - layoverAngle(0) -{ -} - -Monostatic::Monostatic() : - sideOfTrack(six::Init::undefined()), - slantRange(0), - groundRange(0), - dopplerConeAngle(0), - incidenceAngle(0), - arpPos(six::Init::undefined()), - arpVel(six::Init::undefined()) -{ -} - -Bistatic::Bistatic() : - azimuthAngleRate(0), - bistaticAngle(0), - bistaticAngleRate(0) -{ -} - -Bistatic::PlatformParams::PlatformParams() : - sideOfTrack(six::Init::undefined()), - time(0), - azimuthAngle(0), - grazeAngle(0), - incidenceAngle(0), - dopplerConeAngle(0), - groundRange(0), - slantRange(0), - pos(six::Init::undefined()), - vel(six::Init::undefined()) -{ -} - -ReferenceGeometry::ReferenceGeometry() : - referenceTime(0), - srpCODTime(0), - srpDwellTime(0) -{ -} - -std::ostream& operator<< (std::ostream& os, const SRP& s) -{ - os << "SRP:: \n" - << " ECF : " << s.ecf << "\n" - << " IAC : " << s.iac << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const ImagingType& i) -{ - os << " AzimuthAngle : " << i.azimuthAngle << "\n" - << " GrazeAngle : " << i.grazeAngle << "\n" - << " TwistAngle : " << i.twistAngle << "\n" - << " SlopeAngle : " << i.slopeAngle << "\n" - << " layoverAngle : " << i.layoverAngle << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Monostatic& m) -{ - os << "Monostatic:: \n" - << (ImagingType)m << "\n" - << " SideOfTrack : " << m.sideOfTrack << "\n" - << " SlantRange : " << m.slantRange << "\n" - << " GroundRange : " << m.groundRange << "\n" - << " DopplerConeAngle : " << m.dopplerConeAngle << "\n" - << " IncidenceAngle : " << m.incidenceAngle << "\n" - << " ArpPos:: \n" - << " X : " << m.arpPos[0] << "\n" - << " Y : " << m.arpPos[1] << "\n" - << " Z : " << m.arpPos[2] << "\n" - << " ArpVel:: \n" - << " X : " << m.arpVel[0] << "\n" - << " Y : " << m.arpVel[1] << "\n" - << " Z : " << m.arpVel[2] << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const Bistatic::PlatformParams& p) -{ - os << " SideOfTrack : " << p.sideOfTrack << "\n" - << " Time: : " << p.time << "\n" - << " AzimuthAngle : " << p.azimuthAngle << "\n" - << " GrazeAngle : " << p.grazeAngle << "\n" - << " IncidenceAngle : " << p.incidenceAngle << "\n" - << " DopplerConeAngle : " << p.dopplerConeAngle << "\n" - << " GroundRange : " << p.groundRange << "\n" - << " SlantRange : " << p.slantRange << "\n" - << " Pos:: \n" - << " X : " << p.pos[0] << "\n" - << " Y : " << p.pos[1] << "\n" - << " Z : " << p.pos[2] << "\n" - << " Vel:: \n" - << " X : " << p.vel[0] << "\n" - << " Y : " << p.vel[1] << "\n" - << " Z : " << p.vel[2] << "\n"; - - return os; -} - -std::ostream& operator<< (std::ostream& os, const Bistatic& b) -{ - os << "Bistatic:: \n" - << (ImagingType)b << "\n" - << " AzimuthAngleRate : " << b.azimuthAngleRate << "\n" - << " BistaticAngle : " << b.bistaticAngle << "\n" - << " BistaticAngleRate : " << b.bistaticAngleRate << "\n" - << " TxPlatform:: \n" - << b.txPlatform << "\n" - << b.rcvPlatform << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const ReferenceGeometry& r) -{ - os << "Reference Geometry:: \n" - << " ReferenceTime : " << r.referenceTime << "\n" - << " SRPCODTime : " << r.srpCODTime << "\n" - << " SRPDwellTime : " << r.srpDwellTime << "\n" - << r.srp; - - if (r.monostatic.get()) - { - os << *r.monostatic << "\n"; - } - else if (r.bistatic.get()) - { - os << *r.bistatic << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include + +namespace cphd +{ + +SRP::SRP() : + ecf(six::Init::undefined()), + iac(six::Init::undefined()) +{ +} + +ImagingType::ImagingType() : + azimuthAngle(0), + grazeAngle(0), + twistAngle(0), + slopeAngle(0), + layoverAngle(0) +{ +} + +Monostatic::Monostatic() : + sideOfTrack(six::Init::undefined()), + slantRange(0), + groundRange(0), + dopplerConeAngle(0), + incidenceAngle(0), + arpPos(six::Init::undefined()), + arpVel(six::Init::undefined()) +{ +} + +Bistatic::Bistatic() : + azimuthAngleRate(0), + bistaticAngle(0), + bistaticAngleRate(0) +{ +} + +Bistatic::PlatformParams::PlatformParams() : + sideOfTrack(six::Init::undefined()), + time(0), + azimuthAngle(0), + grazeAngle(0), + incidenceAngle(0), + dopplerConeAngle(0), + groundRange(0), + slantRange(0), + pos(six::Init::undefined()), + vel(six::Init::undefined()) +{ +} + +ReferenceGeometry::ReferenceGeometry() : + referenceTime(0), + srpCODTime(0), + srpDwellTime(0) +{ +} + +std::ostream& operator<< (std::ostream& os, const SRP& s) +{ + os << "SRP:: \n" + << " ECF : " << s.ecf << "\n" + << " IAC : " << s.iac << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const ImagingType& i) +{ + os << " AzimuthAngle : " << i.azimuthAngle << "\n" + << " GrazeAngle : " << i.grazeAngle << "\n" + << " TwistAngle : " << i.twistAngle << "\n" + << " SlopeAngle : " << i.slopeAngle << "\n" + << " layoverAngle : " << i.layoverAngle << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Monostatic& m) +{ + os << "Monostatic:: \n" + << (ImagingType)m << "\n" + << " SideOfTrack : " << m.sideOfTrack << "\n" + << " SlantRange : " << m.slantRange << "\n" + << " GroundRange : " << m.groundRange << "\n" + << " DopplerConeAngle : " << m.dopplerConeAngle << "\n" + << " IncidenceAngle : " << m.incidenceAngle << "\n" + << " ArpPos:: \n" + << " X : " << m.arpPos[0] << "\n" + << " Y : " << m.arpPos[1] << "\n" + << " Z : " << m.arpPos[2] << "\n" + << " ArpVel:: \n" + << " X : " << m.arpVel[0] << "\n" + << " Y : " << m.arpVel[1] << "\n" + << " Z : " << m.arpVel[2] << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const Bistatic::PlatformParams& p) +{ + os << " SideOfTrack : " << p.sideOfTrack << "\n" + << " Time: : " << p.time << "\n" + << " AzimuthAngle : " << p.azimuthAngle << "\n" + << " GrazeAngle : " << p.grazeAngle << "\n" + << " IncidenceAngle : " << p.incidenceAngle << "\n" + << " DopplerConeAngle : " << p.dopplerConeAngle << "\n" + << " GroundRange : " << p.groundRange << "\n" + << " SlantRange : " << p.slantRange << "\n" + << " Pos:: \n" + << " X : " << p.pos[0] << "\n" + << " Y : " << p.pos[1] << "\n" + << " Z : " << p.pos[2] << "\n" + << " Vel:: \n" + << " X : " << p.vel[0] << "\n" + << " Y : " << p.vel[1] << "\n" + << " Z : " << p.vel[2] << "\n"; + + return os; +} + +std::ostream& operator<< (std::ostream& os, const Bistatic& b) +{ + os << "Bistatic:: \n" + << (ImagingType)b << "\n" + << " AzimuthAngleRate : " << b.azimuthAngleRate << "\n" + << " BistaticAngle : " << b.bistaticAngle << "\n" + << " BistaticAngleRate : " << b.bistaticAngleRate << "\n" + << " TxPlatform:: \n" + << b.txPlatform << "\n" + << b.rcvPlatform << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const ReferenceGeometry& r) +{ + os << "Reference Geometry:: \n" + << " ReferenceTime : " << r.referenceTime << "\n" + << " SRPCODTime : " << r.srpCODTime << "\n" + << " SRPDwellTime : " << r.srpDwellTime << "\n" + << r.srp; + + if (r.monostatic.get()) + { + os << *r.monostatic << "\n"; + } + else if (r.bistatic.get()) + { + os << *r.bistatic << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/source/TxRcv.cpp b/six/modules/c++/cphd/source/TxRcv.cpp index 99e03aadac..11a9b9017f 100644 --- a/six/modules/c++/cphd/source/TxRcv.cpp +++ b/six/modules/c++/cphd/source/TxRcv.cpp @@ -1,99 +1,99 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include - -namespace cphd -{ - -ParameterType::ParameterType() : - freqCenter(six::Init::undefined()), - lfmRate(six::Init::undefined()) -{ -} - -TxWFParameters::TxWFParameters() : - pulseLength(six::Init::undefined()), - rfBandwidth(six::Init::undefined()), - power(six::Init::undefined()) -{ -} - -RcvParameters::RcvParameters() : - windowLength(six::Init::undefined()), - sampleRate(six::Init::undefined()), - ifFilterBW(six::Init::undefined()), - pathGain(six::Init::undefined()) -{ -} - -TxRcv::TxRcv() -{ -} - -std::ostream& operator<< (std::ostream& os, const ParameterType& p) -{ - os << " Identifier : " << p.identifier << "\n" - << " FreqCenter : " << p.freqCenter << "\n" - << " LFMRate : " << p.lfmRate << "\n" - << " Polarization : " << p.polarization << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const TxWFParameters& t) -{ - os << " TxWFParamters:: \n" - << (ParameterType)t - << " PulseLength : " << t.pulseLength << "\n" - << " RFBandwidth : " << t.rfBandwidth << "\n" - << " Power : " << t.power << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const RcvParameters& r) -{ - os << " RcvParamters:: \n" - << (ParameterType)r - << " WindowLength : " << r.windowLength << "\n" - << " SampleRate : " << r.sampleRate << "\n" - << " IFFilterBW : " << r.ifFilterBW << "\n" - << " PathGain : " << r.pathGain << "\n"; - return os; -} - -std::ostream& operator<< (std::ostream& os, const TxRcv& t) -{ - os << "TxRcv:: \n" - << " NumTxWFs : " << t.txWFParameters.size() << "\n" - << " NumRcvs : " << t.rcvParameters.size() << "\n"; - for (size_t ii = 0; ii < t.txWFParameters.size(); ++ii) - { - os << t.txWFParameters[ii] << "\n"; - } - for (size_t ii = 0; ii < t.rcvParameters.size(); ++ii) - { - os << t.rcvParameters[ii] << "\n"; - } - return os; -} -} +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include + +namespace cphd +{ + +ParameterType::ParameterType() : + freqCenter(six::Init::undefined()), + lfmRate(six::Init::undefined()) +{ +} + +TxWFParameters::TxWFParameters() : + pulseLength(six::Init::undefined()), + rfBandwidth(six::Init::undefined()), + power(six::Init::undefined()) +{ +} + +RcvParameters::RcvParameters() : + windowLength(six::Init::undefined()), + sampleRate(six::Init::undefined()), + ifFilterBW(six::Init::undefined()), + pathGain(six::Init::undefined()) +{ +} + +TxRcv::TxRcv() +{ +} + +std::ostream& operator<< (std::ostream& os, const ParameterType& p) +{ + os << " Identifier : " << p.identifier << "\n" + << " FreqCenter : " << p.freqCenter << "\n" + << " LFMRate : " << p.lfmRate << "\n" + << " Polarization : " << p.polarization << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const TxWFParameters& t) +{ + os << " TxWFParamters:: \n" + << (ParameterType)t + << " PulseLength : " << t.pulseLength << "\n" + << " RFBandwidth : " << t.rfBandwidth << "\n" + << " Power : " << t.power << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const RcvParameters& r) +{ + os << " RcvParamters:: \n" + << (ParameterType)r + << " WindowLength : " << r.windowLength << "\n" + << " SampleRate : " << r.sampleRate << "\n" + << " IFFilterBW : " << r.ifFilterBW << "\n" + << " PathGain : " << r.pathGain << "\n"; + return os; +} + +std::ostream& operator<< (std::ostream& os, const TxRcv& t) +{ + os << "TxRcv:: \n" + << " NumTxWFs : " << t.txWFParameters.size() << "\n" + << " NumRcvs : " << t.rcvParameters.size() << "\n"; + for (size_t ii = 0; ii < t.txWFParameters.size(); ++ii) + { + os << t.txWFParameters[ii] << "\n"; + } + for (size_t ii = 0; ii < t.rcvParameters.size(); ++ii) + { + os << t.rcvParameters[ii] << "\n"; + } + return os; +} +} diff --git a/six/modules/c++/cphd/unittests/test_channel.cpp b/six/modules/c++/cphd/unittests/test_channel.cpp index 00820eaf35..ae679bc374 100644 --- a/six/modules/c++/cphd/unittests/test_channel.cpp +++ b/six/modules/c++/cphd/unittests/test_channel.cpp @@ -1,85 +1,85 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include - -#include -#include -#include -#include - -#include "TestCase.h" - -TEST_CASE(EmptyChannel) -{ - cphd::Channel channel1, channel2; - channel1.parameters.resize(3); - channel2.parameters.resize(3); - TEST_ASSERT_TRUE((channel1.parameters == channel2.parameters)); - TEST_ASSERT_TRUE((channel1 == channel2)); -} - -TEST_CASE(TestPolygonInvalid) -{ - cphd::Channel channel; - - six::Vector2 vertex1, vertex2; - vertex1[0] = 0; - vertex1[1] = 0; - vertex2[0] = 5; - vertex2[1] = 5; - - channel.parameters.resize(1); - channel.parameters[0].imageArea.x1y1[0] = 0; - channel.parameters[0].imageArea.x1y1[1] = 0; - channel.parameters[0].imageArea.x2y2[0] = 10; - channel.parameters[0].imageArea.x2y2[1] = 10; - channel.parameters[0].imageArea.polygon.push_back(vertex1); - channel.parameters[0].imageArea.polygon.push_back(vertex2); - - TEST_ASSERT_FALSE(channel.parameters[0].imageArea.polygon.size() >= 3); -} - - -TEST_CASE(TxRcvMultIds) -{ - cphd::Channel channel; - channel.parameters.resize(2); - channel.parameters[0].txRcv.reset(new cphd::ChannelParameter::TxRcv()); - channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam1"); - channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam2"); - channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam3"); - - channel.parameters[0].txRcv->rcvId.push_back("ReceiverWaveformParam1"); - channel.parameters[0].txRcv->rcvId.push_back("ReceiverWaveformParam2"); - - TEST_ASSERT_EQ(channel.parameters[0].txRcv->txWFId.size(), static_cast(3)); - TEST_ASSERT_EQ(channel.parameters[0].txRcv->rcvId.size(), static_cast(2)); -} - -TEST_MAIN( - TEST_CHECK(EmptyChannel); - TEST_CHECK(TestPolygonInvalid); - TEST_CHECK(TxRcvMultIds); - ) - +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include + +#include +#include +#include +#include + +#include "TestCase.h" + +TEST_CASE(EmptyChannel) +{ + cphd::Channel channel1, channel2; + channel1.parameters.resize(3); + channel2.parameters.resize(3); + TEST_ASSERT_TRUE((channel1.parameters == channel2.parameters)); + TEST_ASSERT_TRUE((channel1 == channel2)); +} + +TEST_CASE(TestPolygonInvalid) +{ + cphd::Channel channel; + + six::Vector2 vertex1, vertex2; + vertex1[0] = 0; + vertex1[1] = 0; + vertex2[0] = 5; + vertex2[1] = 5; + + channel.parameters.resize(1); + channel.parameters[0].imageArea.x1y1[0] = 0; + channel.parameters[0].imageArea.x1y1[1] = 0; + channel.parameters[0].imageArea.x2y2[0] = 10; + channel.parameters[0].imageArea.x2y2[1] = 10; + channel.parameters[0].imageArea.polygon.push_back(vertex1); + channel.parameters[0].imageArea.polygon.push_back(vertex2); + + TEST_ASSERT_FALSE(channel.parameters[0].imageArea.polygon.size() >= 3); +} + + +TEST_CASE(TxRcvMultIds) +{ + cphd::Channel channel; + channel.parameters.resize(2); + channel.parameters[0].txRcv.reset(new cphd::ChannelParameter::TxRcv()); + channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam1"); + channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam2"); + channel.parameters[0].txRcv->txWFId.push_back("TransmitWaveformParam3"); + + channel.parameters[0].txRcv->rcvId.push_back("ReceiverWaveformParam1"); + channel.parameters[0].txRcv->rcvId.push_back("ReceiverWaveformParam2"); + + TEST_ASSERT_EQ(channel.parameters[0].txRcv->txWFId.size(), static_cast(3)); + TEST_ASSERT_EQ(channel.parameters[0].txRcv->rcvId.size(), static_cast(2)); +} + +TEST_MAIN( + TEST_CHECK(EmptyChannel); + TEST_CHECK(TestPolygonInvalid); + TEST_CHECK(TxRcvMultIds); + ) + diff --git a/six/modules/c++/cphd/unittests/test_cphd_xml_optional.cpp b/six/modules/c++/cphd/unittests/test_cphd_xml_optional.cpp index 2bfe76f733..ebc55372f2 100644 --- a/six/modules/c++/cphd/unittests/test_cphd_xml_optional.cpp +++ b/six/modules/c++/cphd/unittests/test_cphd_xml_optional.cpp @@ -1,1129 +1,1129 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include - -#include "TestCase.h" - -const char* test_cphd_xml_optional_XML = -"\n" -" \n" -" Collector\n" -" Core\n" -" MONOSTATIC\n" -" \n" -" STRIPMAP\n" -" Mode\n" -" \n" -" U\n" -" Release\n" -" US,GB,AZ\n" -" val\n" -" \n" -" \n" -" FX\n" -" +1\n" -" \n" -" 2013-04-10T08:52:09.000000Z\n" -" 2014-04-10T08:52:09.000000Z\n" -" 1.300000000000000E00\n" -" 1.500000000000000E00\n" -" \n" -" \n" -" 9.000000000000000E-01\n" -" 1.700000000000000E00\n" -" \n" -" \n" -" 3.400000000000000E00\n" -" 6.100000000000000E00\n" -" \n" -" \n" -" 6.520000000000000E01\n" -" IARP\n" -" \n" -" \n" -" 5.800000000000000E00\n" -" 3.000000000000000E00\n" -" \n" -" \n" -" \n" -" WGS_84\n" -" \n" -" \n" -" 1.200000000000000E00\n" -" 2.300000000000000E00\n" -" 3.400000000000000E00\n" -" \n" -" \n" -" 4.500000000000000E01\n" -" -1.020000000000000E02\n" -" 3.400000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 1.200000000000000E01\n" -" 2.400000000000000E01\n" -" \n" -" \n" -" 3.600000000000000E01\n" -" 4.800000000000000E01\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 3.500000000000000E00\n" -" 5.300000000000000E00\n" -" \n" -" \n" -" 5.300000000000000E00\n" -" 3.500000000000000E00\n" -" \n" -" \n" -" \n" -" 1.000000000000000E-01\n" -" 3.000000000000000E-01\n" -" \n" -" \n" -" 4.000000000000000E-01\n" -" 2.000000000000000E-01\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 9.000000000000000E-01\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E01\n" -" 1.100000000000000E01\n" -" \n" -" \n" -" 2.000000000000000E01\n" -" 2.100000000000000E01\n" -" \n" -" \n" -" 3.000000000000000E01\n" -" 3.100000000000000E01\n" -" \n" -" \n" -" 4.000000000000000E01\n" -" 4.100000000000000E01\n" -" \n" -" \n" -" \n" -" Grid\n" -" \n" -" 1.230000000000000E00\n" -" 3.210000000000000E00\n" -" \n" -" \n" -" 3.140000000000000E00\n" -" 4\n" -" 50\n" -" \n" -" \n" -" 6.280000000000000E00\n" -" 8\n" -" 100\n" -" \n" -" \n" -" 2\n" -" \n" -" Segment1\n" -" 0\n" -" 1\n" -" 2\n" -" 3\n" -" \n" -" \n" -" 4.000000000000000E-01\n" -" 6.000000000000000E-01\n" -" \n" -" \n" -" 8.000000000000000E-01\n" -" 1.200000000000000E00\n" -" \n" -" \n" -" 1.200000000000000E00\n" -" 1.800000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" Segment2\n" -" 1\n" -" 2\n" -" 3\n" -" 4\n" -" \n" -" \n" -" 4.000000000000000E-01\n" -" 6.000000000000000E-01\n" -" \n" -" \n" -" 8.000000000000000E-01\n" -" 1.200000000000000E00\n" -" \n" -" \n" -" 1.200000000000000E00\n" -" 1.800000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" CI4\n" -" 24\n" -" 2\n" -" Compress\n" -" \n" -" Channel\n" -" 2\n" -" 3\n" -" 0\n" -" 1\n" -" 3\n" -" \n" -" \n" -" Channel\n" -" 2\n" -" 3\n" -" 0\n" -" 1\n" -" 3\n" -" \n" -" 3\n" -" \n" -" 1.0\n" -" 3\n" -" 4\n" -" 8\n" -" 0\n" -" \n" -" \n" -" 2.0\n" -" 3\n" -" 4\n" -" 4\n" -" 96\n" -" \n" -" \n" -" AddedSupportArray\n" -" 3\n" -" 4\n" -" 4\n" -" 144\n" -" \n" -" \n" -" \n" -" ChId\n" -" true\n" -" false\n" -" true\n" -" \n" -" CPI\n" -" 1\n" -" false\n" -" true\n" -" true\n" -" false\n" -" \n" -" X\n" -" RHC\n" -" \n" -" 1.300000000000000E00\n" -" 8.000000000000000E-01\n" -" 5.000000000000000E-01\n" -" 2.700000000000000E00\n" -" \n" -" 1.000000000000000E00\n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" CODPolynomial\n" -" DwellPolynomial\n" -" \n" -" \n" -" \n" -" 3.500000000000000E00\n" -" 5.300000000000000E00\n" -" \n" -" \n" -" 5.300000000000000E00\n" -" 3.500000000000000E00\n" -" \n" -" \n" -" \n" -" 1.000000000000000E-01\n" -" 3.000000000000000E-01\n" -" \n" -" \n" -" 4.000000000000000E-01\n" -" 2.000000000000000E-01\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 9.000000000000000E-01\n" -" \n" -" \n" -" \n" -" \n" -" TxAPCId\n" -" TxAPATId\n" -" RcvAPCId\n" -" RcvAPATId\n" -" \n" -" \n" -" TxWFId\n" -" RcvId\n" -" \n" -" \n" -" 1.200000000000000E01\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" \n" -" \n" -" 3.000000000000000E-01\n" -" 2.700000000000000E00\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 2.700000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" Param\n" -" Param\n" -" \n" -" \n" -" \n" -" \n" -" 0\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 1\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 4\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 7\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 8\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 11\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 14\n" -" 3\n" -" X=F8;Y=F8;Z=F8;\n" -" \n" -" \n" -" 17\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 18\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 19\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 20\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 21\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 22\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 23\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 24\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 25\n" -" 1\n" -" F8\n" -" \n" -" \n" -" 26\n" -" 1\n" -" F8\n" -" \n" -" \n" -" newParam1\n" -" 27\n" -" 1\n" -" F8\n" -" \n" -" \n" -" newParam2\n" -" 28\n" -" 1\n" -" F8\n" -" \n" -" \n" -" \n" -" \n" -" 1\n" -" IAZ=F4;\n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" 2\n" -" Gain=F4;Phase=F4;\n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" AddedSupportArray\n" -" F4\n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" XUnits\n" -" YUnits\n" -" ZUnits\n" -" Additional parameter\n" -" Additional parameter\n" -" \n" -" \n" -" \n" -" 1\n" -" \n" -" codPolynomial1\n" -" \n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" 1\n" -" \n" -" dwellPolynomial1\n" -" \n" -" 0.000000000000000E00\n" -" 2.000000000000000E00\n" -" 3.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" 3.500000000000000E00\n" -" \n" -" \n" -" 1.500000000000000E00\n" -" 2.500000000000000E00\n" -" 4.000000000000000E00\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 2.300000000000000E01\n" -" 2.500000000000000E01\n" -" \n" -" \n" -" 1.000000000000000E01\n" -" 1.000000000000000E01\n" -" 1.000000000000000E01\n" -" \n" -" \n" -" 1.000000000000000E01\n" -" 1.000000000000000E01\n" -" 1.000000000000000E01\n" -" \n" -" L\n" -" 2.000000000000000E01\n" -" 2.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" 3.000000000000000E01\n" -" \n" -" \n" -" \n" -" 2\n" -" 1\n" -" 1\n" -" \n" -" ACF1\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" 3.000000000000000E00\n" -" 4.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" 3.000000000000000E00\n" -" 4.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 0.000000000000000E00\n" -" 3.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" ACF2\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" APC\n" -" ACF1\n" -" \n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" APAT\n" -" 2.300000000000000E00\n" -" 2.300000000000000E00\n" -" 1\n" -" 0\n" -" \n" -" 1.000000000000000E00\n" -" 2.000000000000000E00\n" -" \n" -" \n" -" \n" -" 5.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" 2.300000000000000E00\n" -" Parameter1\n" -" Parameter2\n" -" \n" -" \n" -" 2.800000000000000E00\n" -" Parameter1\n" -" Parameter2\n" -" \n" -" \n" -" \n" -" \n" -" 1\n" -" \n" -" TxWFParam\n" -" 3.000000000000000E00\n" -" 2.300000000000000E00\n" -" 1.800000000000000E00\n" -" 1.000000000000000E00\n" -" LHC\n" -" 5.000000000000000E00\n" -" \n" -" 2\n" -" \n" -" RcvParam1\n" -" 3.000000000000000E00\n" -" 2.300000000000000E00\n" -" 2.300000000000000E00\n" -" 1.800000000000000E00\n" -" 1.000000000000000E00\n" -" LHC\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" RcvParam2\n" -" 3.000000000000000E00\n" -" 2.300000000000000E00\n" -" 2.300000000000000E00\n" -" 1.800000000000000E00\n" -" 1.000000000000000E00\n" -" LHC\n" -" 5.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" ECF\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" 8.000000000000000E-01\n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" 5.000000000000000E00\n" -" 5.000000000000000E00\n" -" 5.000000000000000E-01\n" -" \n" -" 5.000000000000000E-01\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" Profile\n" -" \n" -" Application\n" -" 2014-04-10T08:52:09.000000Z\n" -" Area51\n" -" Value1\n" -" Value2\n" -" \n" -" Value1\n" -" \n" -" \n" -" 51\n" -" \n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E-01\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E-01\n" -" 1.000000000000000E-01\n" -" \n" -" \n" -" 0.000000000000000E00\n" -" 0.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 04/22\n" -" \n" -" \n" -" 2.000000000000000E-02\n" -" 3.000000000000000E-02\n" -" \n" -" \n" -" 8.000000000000000E-02\n" -" 8.000000000000000E-02\n" -" \n" -" \n" -" \n" -" \n" -" 09/27\n" -" \n" -" \n" -" 5.000000000000000E-02\n" -" 2.000000000000000E-02\n" -" \n" -" \n" -" 5.000000000000000E-02\n" -" 8.000000000000000E-02\n" -" \n" -" \n" -" \n" -" \n" -" Main\n" -" \n" -" 6.000000000000000E-01\n" -" 4.000000000000000E-01\n" -" \n" -" \n" -" \n" -" \n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" 1.100000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" 1.100000000000000E00\n" -" 1.100000000000000E00\n" -" \n" -" \n" -" 1.200000000000000E00\n" -" 1.200000000000000E00\n" -" \n" -" \n" -" 1.000000000000000E00\n" -" 1.000000000000000E00\n" -" \n" -" \n" -" \n" -" \n" -" 2\n" -" \n" -" STEREO\n" -" 1\n" -" 1\n" -" \n" -" CollectionName\n" -" 1\n" -" Match1\n" -" \n" -" \n" -" \n" -" COHERENT\n" -" 1\n" -" 1\n" -" \n" -" CollectionName\n" -" 1\n" -" Match1\n" -" \n" -" \n" -" \n" -"\n"; - -TEST_CASE(testOptional) -{ - io::StringStream cphdStream; - cphdStream.write(test_cphd_xml_optional_XML, strlen(test_cphd_xml_optional_XML)); - - xml::lite::MinidomParser xmlParser; - xmlParser.preserveCharacterData(true); - xmlParser.parse(cphdStream, cphdStream.available()); - const std::unique_ptr metadata = - cphd::CPHDXMLControl().fromXML(xmlParser.getDocument()); - - const cphd::SupportArray& supportArray = *(metadata->supportArray); - TEST_ASSERT_EQ(supportArray.iazArray.size(), static_cast(1)); - TEST_ASSERT_EQ(supportArray.iazArray[0].getIdentifier(), static_cast(1)); - TEST_ASSERT_EQ(supportArray.iazArray[0].elementFormat, "IAZ=F4;"); - TEST_ASSERT_EQ(supportArray.iazArray[0].x0, 0.0); - TEST_ASSERT_EQ(supportArray.iazArray[0].y0, 0.0); - TEST_ASSERT_EQ(supportArray.iazArray[0].xSS, 5.0); - TEST_ASSERT_EQ(supportArray.iazArray[0].ySS, 5.0); - - TEST_ASSERT_EQ(supportArray.antGainPhase.size(), static_cast(1)); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].getIdentifier(), static_cast(2)); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].elementFormat, "Gain=F4;Phase=F4;"); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].x0, 0.0); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].y0, 0.0); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].xSS, 5.0); - TEST_ASSERT_EQ(supportArray.antGainPhase[0].ySS, 5.0); - - TEST_ASSERT_EQ(supportArray.addedSupportArray.size(), static_cast(1)); - TEST_ASSERT_EQ(supportArray.addedSupportArray.count("AddedSupportArray"), static_cast(1)); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.elementFormat, "F4"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.x0, 0.0); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.y0, 0.0); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.xSS, 5.0); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.ySS, 5.0); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.xUnits, "XUnits"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.yUnits, "YUnits"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.zUnits, "ZUnits"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter.size(), static_cast(2)); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[0].getName(), "Parameter1"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[1].getName(), "Parameter2"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[0].str(), "Additional parameter"); - TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[1].str(), "Additional parameter"); - - const cphd::Antenna& antenna = *(metadata->antenna); - TEST_ASSERT_EQ(antenna.antCoordFrame.size(), static_cast(2)); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].identifier, "ACF1"); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.order(), static_cast(3)); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][0], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][0], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][0], 3); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][0], 4); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][1], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][1], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][1], 3); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][1], 4); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][2], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][2], 0); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][2], 3); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][2], 0); - - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[0][0], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[1][0], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[0][1], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[1][1], 2); - - TEST_ASSERT_EQ(antenna.antCoordFrame[1].identifier, "ACF2"); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[0][0], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[1][0], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[0][1], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[1][1], 2); - - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[0][0], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[1][0], 2); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[0][1], 1); - TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[1][1], 2); - - TEST_ASSERT_EQ(antenna.antPhaseCenter.size(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].identifier, "APC"); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].acfId, "ACF1"); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[0], 5.0); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[1], 5.0); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[2], 5.0); - - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].identifier, "APC"); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].acfId, "ACF1"); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[0], 5.0); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[1], 5.0); - TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[2], 5.0); - - TEST_ASSERT_EQ(antenna.antPattern.size(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].identifier, "APAT"); - TEST_ASSERT_EQ(antenna.antPattern[0].freqZero, 2.3); - TEST_ASSERT_EQ(antenna.antPattern[0].gainZero, 2.3); - TEST_ASSERT_EQ(antenna.antPattern[0].ebFreqShift, 1); - TEST_ASSERT_EQ(antenna.antPattern[0].mlFreqDilation, 0); - TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.coeffs()[0], 1.0); - TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.coeffs()[1], 2.0); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcxPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcxPoly.coeffs()[0], 5.0); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.order(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.coeffs()[0], 0.0); - TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.coeffs()[1], 5.0); - TEST_ASSERT_EQ(antenna.antPattern[0].array.gainPoly.orderX(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].array.gainPoly.orderY(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].array.phasePoly.orderX(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].array.phasePoly.orderY(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].element.gainPoly.orderX(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].element.gainPoly.orderY(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].element.phasePoly.orderX(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].element.phasePoly.orderY(), static_cast(1)); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].freq, 2.3); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].arrayId, "Parameter1"); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].elementId, "Parameter2"); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].freq, 2.8); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].arrayId, "Parameter1"); - TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].elementId, "Parameter2"); - - const cphd::TxRcv& txRcv = *(metadata->txRcv); - TEST_ASSERT_EQ(txRcv.txWFParameters.size(), static_cast(1)); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].identifier, "TxWFParam"); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].pulseLength, 3.0); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].rfBandwidth, 2.3); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].freqCenter, 1.8); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].lfmRate, 1.0); - TEST_ASSERT(txRcv.txWFParameters[0].polarization.toString() == "LHC"); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].polarization, cphd::PolarizationType::LHC); - TEST_ASSERT_EQ(txRcv.txWFParameters[0].power, 5.0); - - TEST_ASSERT_EQ(txRcv.rcvParameters.size(), static_cast(2)); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].identifier, "RcvParam1"); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].windowLength, 3.0); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].sampleRate, 2.3); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].ifFilterBW, 2.3); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].freqCenter, 1.8); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].lfmRate, 1.0); - TEST_ASSERT(txRcv.rcvParameters[0].polarization.toString() == "LHC"); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].polarization, cphd::PolarizationType::LHC); - TEST_ASSERT_EQ(txRcv.rcvParameters[0].pathGain, 5.0); - - TEST_ASSERT_EQ(txRcv.rcvParameters[1].identifier, "RcvParam2"); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].windowLength, 3.0); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].sampleRate, 2.3); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].ifFilterBW, 2.3); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].freqCenter, 1.8); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].lfmRate, 1.0); - TEST_ASSERT(txRcv.rcvParameters[1].polarization.toString() == "LHC"); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].polarization, cphd::PolarizationType::LHC); - TEST_ASSERT_EQ(txRcv.rcvParameters[1].pathGain, 5.0); - - const cphd::ErrorParameters& errorParams = *(metadata->errorParameters); - TEST_ASSERT(errorParams.monostatic->posVelErr.frame == "ECF"); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.frame, six::FrameType(six::FrameType::ECF)); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.p1, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.p2, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.corrCoefs->p1p2, 0.8); - TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.corrCoefs->v2v3, 0.8); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->posVelErr.positionDecorr).corrCoefZero, 0.5); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->posVelErr.positionDecorr).decorrRate, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBias, 0.5); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.clockFreqSF, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.collectionStartTime, 1.0); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero, 0.5); - TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBiasDecorr->decorrRate, 1.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->tropoError->tropoRangeVertical), 5.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->tropoError->tropoRangeSlant), 5.0); - const auto& tropoRangeDecorr = value(errorParams.monostatic->tropoError->tropoRangeDecorr); - TEST_ASSERT_EQ(tropoRangeDecorr.corrCoefZero, 0.5); - TEST_ASSERT_EQ(tropoRangeDecorr.decorrRate, 1.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRangeVertical), 5.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRangeRateVertical), 5.0); - TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRgRgRateCC), 0.5); - const auto& ionoRangeVertDecorr = six::value(errorParams.monostatic->ionoError->ionoRangeVertDecorr); - TEST_ASSERT_EQ(ionoRangeVertDecorr.corrCoefZero, 0.5); - TEST_ASSERT_EQ(ionoRangeVertDecorr.decorrRate, 1.0); - - const cphd::ProductInfo& productInfo = *(metadata->productInfo); - TEST_ASSERT_EQ(productInfo.profile, "Profile"); - TEST_ASSERT_EQ(productInfo.creationInfo[0].application, "Application"); - TEST_ASSERT_EQ(productInfo.creationInfo[0].dateTime.getYear(), 2014); - TEST_ASSERT_EQ(productInfo.creationInfo[0].site, "Area51"); - TEST_ASSERT_EQ(productInfo.creationInfo[0].parameter[0].getName(), "Param1"); - TEST_ASSERT_EQ(productInfo.creationInfo[0].parameter[1].getName(), "Param2"); - TEST_ASSERT_EQ(productInfo.parameter[0].getName(), "Param1"); - - std::vector geoInfo = metadata->geoInfo; - TEST_ASSERT_EQ(geoInfo[0].name, "Airport"); - TEST_ASSERT_EQ(geoInfo[0].desc[0].getName(), "Airport ID"); - TEST_ASSERT_EQ(geoInfo[0].desc[0].str(), "51"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->name, "Perimeter"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon.size(), static_cast(4)); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[0].getLat(), 0.0); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[0].getLon(), 0.0); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[1].getLat(), 0.1); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[1].getLon(), 0.0); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[2].getLat(), 0.1); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[2].getLon(), 0.1); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[3].getLat(), 0.0); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[3].getLon(), 0.0); - - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->name, "Runway"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->desc[0].getName(), "ID"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->desc[0].str(), "04/22"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon.size(), static_cast(2)); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[0].getLat(), 0.02); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[0].getLon(), 0.03); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[1].getLat(), 0.08); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[1].getLon(), 0.08); - - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->name, "Control Tower"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->desc[0].getName(), "ID"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->desc[0].str(), "Main"); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->geometryLatLon[0].getLat(), 0.6); - TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->geometryLatLon[0].getLon(), 0.4); - - TEST_ASSERT_EQ(geoInfo[1].name, "Farm"); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon.size(), static_cast(5)); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[0].getLat(), 1.0); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[0].getLon(), 1.0); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[1].getLat(), 1.1); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[1].getLon(), 1.0); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[4].getLat(), 1.0); - TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[4].getLon(), 1.0); - - const cphd::MatchInformation& matchInfo = *(metadata->matchInfo); - TEST_ASSERT_EQ(matchInfo.types.size(), static_cast(2)); - TEST_ASSERT_EQ(matchInfo.types[0].typeID, "STEREO"); - TEST_ASSERT_EQ(matchInfo.types[0].currentIndex, 1); - TEST_ASSERT_EQ(matchInfo.types[0].matchCollects.size(), static_cast(1)); - TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].coreName, "CollectionName"); - TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].matchIndex, 1); - TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].parameters[0].getName(), "param1"); - TEST_ASSERT_EQ(matchInfo.types[1].typeID, "COHERENT"); - TEST_ASSERT_EQ(matchInfo.types[1].currentIndex, 1); - TEST_ASSERT_EQ(matchInfo.types[1].matchCollects.size(), static_cast(1)); - TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].coreName, "CollectionName"); - TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].matchIndex, 1); - TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].parameters[0].getName(), "param1"); -} - -TEST_MAIN( - TEST_CHECK(testOptional); +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "TestCase.h" + +const char* test_cphd_xml_optional_XML = +"\n" +" \n" +" Collector\n" +" Core\n" +" MONOSTATIC\n" +" \n" +" STRIPMAP\n" +" Mode\n" +" \n" +" U\n" +" Release\n" +" US,GB,AZ\n" +" val\n" +" \n" +" \n" +" FX\n" +" +1\n" +" \n" +" 2013-04-10T08:52:09.000000Z\n" +" 2014-04-10T08:52:09.000000Z\n" +" 1.300000000000000E00\n" +" 1.500000000000000E00\n" +" \n" +" \n" +" 9.000000000000000E-01\n" +" 1.700000000000000E00\n" +" \n" +" \n" +" 3.400000000000000E00\n" +" 6.100000000000000E00\n" +" \n" +" \n" +" 6.520000000000000E01\n" +" IARP\n" +" \n" +" \n" +" 5.800000000000000E00\n" +" 3.000000000000000E00\n" +" \n" +" \n" +" \n" +" WGS_84\n" +" \n" +" \n" +" 1.200000000000000E00\n" +" 2.300000000000000E00\n" +" 3.400000000000000E00\n" +" \n" +" \n" +" 4.500000000000000E01\n" +" -1.020000000000000E02\n" +" 3.400000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 1.200000000000000E01\n" +" 2.400000000000000E01\n" +" \n" +" \n" +" 3.600000000000000E01\n" +" 4.800000000000000E01\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 3.500000000000000E00\n" +" 5.300000000000000E00\n" +" \n" +" \n" +" 5.300000000000000E00\n" +" 3.500000000000000E00\n" +" \n" +" \n" +" \n" +" 1.000000000000000E-01\n" +" 3.000000000000000E-01\n" +" \n" +" \n" +" 4.000000000000000E-01\n" +" 2.000000000000000E-01\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 9.000000000000000E-01\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E01\n" +" 1.100000000000000E01\n" +" \n" +" \n" +" 2.000000000000000E01\n" +" 2.100000000000000E01\n" +" \n" +" \n" +" 3.000000000000000E01\n" +" 3.100000000000000E01\n" +" \n" +" \n" +" 4.000000000000000E01\n" +" 4.100000000000000E01\n" +" \n" +" \n" +" \n" +" Grid\n" +" \n" +" 1.230000000000000E00\n" +" 3.210000000000000E00\n" +" \n" +" \n" +" 3.140000000000000E00\n" +" 4\n" +" 50\n" +" \n" +" \n" +" 6.280000000000000E00\n" +" 8\n" +" 100\n" +" \n" +" \n" +" 2\n" +" \n" +" Segment1\n" +" 0\n" +" 1\n" +" 2\n" +" 3\n" +" \n" +" \n" +" 4.000000000000000E-01\n" +" 6.000000000000000E-01\n" +" \n" +" \n" +" 8.000000000000000E-01\n" +" 1.200000000000000E00\n" +" \n" +" \n" +" 1.200000000000000E00\n" +" 1.800000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" Segment2\n" +" 1\n" +" 2\n" +" 3\n" +" 4\n" +" \n" +" \n" +" 4.000000000000000E-01\n" +" 6.000000000000000E-01\n" +" \n" +" \n" +" 8.000000000000000E-01\n" +" 1.200000000000000E00\n" +" \n" +" \n" +" 1.200000000000000E00\n" +" 1.800000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" CI4\n" +" 24\n" +" 2\n" +" Compress\n" +" \n" +" Channel\n" +" 2\n" +" 3\n" +" 0\n" +" 1\n" +" 3\n" +" \n" +" \n" +" Channel\n" +" 2\n" +" 3\n" +" 0\n" +" 1\n" +" 3\n" +" \n" +" 3\n" +" \n" +" 1.0\n" +" 3\n" +" 4\n" +" 8\n" +" 0\n" +" \n" +" \n" +" 2.0\n" +" 3\n" +" 4\n" +" 4\n" +" 96\n" +" \n" +" \n" +" AddedSupportArray\n" +" 3\n" +" 4\n" +" 4\n" +" 144\n" +" \n" +" \n" +" \n" +" ChId\n" +" true\n" +" false\n" +" true\n" +" \n" +" CPI\n" +" 1\n" +" false\n" +" true\n" +" true\n" +" false\n" +" \n" +" X\n" +" RHC\n" +" \n" +" 1.300000000000000E00\n" +" 8.000000000000000E-01\n" +" 5.000000000000000E-01\n" +" 2.700000000000000E00\n" +" \n" +" 1.000000000000000E00\n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" CODPolynomial\n" +" DwellPolynomial\n" +" \n" +" \n" +" \n" +" 3.500000000000000E00\n" +" 5.300000000000000E00\n" +" \n" +" \n" +" 5.300000000000000E00\n" +" 3.500000000000000E00\n" +" \n" +" \n" +" \n" +" 1.000000000000000E-01\n" +" 3.000000000000000E-01\n" +" \n" +" \n" +" 4.000000000000000E-01\n" +" 2.000000000000000E-01\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 9.000000000000000E-01\n" +" \n" +" \n" +" \n" +" \n" +" TxAPCId\n" +" TxAPATId\n" +" RcvAPCId\n" +" RcvAPATId\n" +" \n" +" \n" +" TxWFId\n" +" RcvId\n" +" \n" +" \n" +" 1.200000000000000E01\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" \n" +" \n" +" 3.000000000000000E-01\n" +" 2.700000000000000E00\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 2.700000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" Param\n" +" Param\n" +" \n" +" \n" +" \n" +" \n" +" 0\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 1\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 4\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 7\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 8\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 11\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 14\n" +" 3\n" +" X=F8;Y=F8;Z=F8;\n" +" \n" +" \n" +" 17\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 18\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 19\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 20\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 21\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 22\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 23\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 24\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 25\n" +" 1\n" +" F8\n" +" \n" +" \n" +" 26\n" +" 1\n" +" F8\n" +" \n" +" \n" +" newParam1\n" +" 27\n" +" 1\n" +" F8\n" +" \n" +" \n" +" newParam2\n" +" 28\n" +" 1\n" +" F8\n" +" \n" +" \n" +" \n" +" \n" +" 1\n" +" IAZ=F4;\n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" 2\n" +" Gain=F4;Phase=F4;\n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" AddedSupportArray\n" +" F4\n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" XUnits\n" +" YUnits\n" +" ZUnits\n" +" Additional parameter\n" +" Additional parameter\n" +" \n" +" \n" +" \n" +" 1\n" +" \n" +" codPolynomial1\n" +" \n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" 1\n" +" \n" +" dwellPolynomial1\n" +" \n" +" 0.000000000000000E00\n" +" 2.000000000000000E00\n" +" 3.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" 3.500000000000000E00\n" +" \n" +" \n" +" 1.500000000000000E00\n" +" 2.500000000000000E00\n" +" 4.000000000000000E00\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 2.300000000000000E01\n" +" 2.500000000000000E01\n" +" \n" +" \n" +" 1.000000000000000E01\n" +" 1.000000000000000E01\n" +" 1.000000000000000E01\n" +" \n" +" \n" +" 1.000000000000000E01\n" +" 1.000000000000000E01\n" +" 1.000000000000000E01\n" +" \n" +" L\n" +" 2.000000000000000E01\n" +" 2.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" 3.000000000000000E01\n" +" \n" +" \n" +" \n" +" 2\n" +" 1\n" +" 1\n" +" \n" +" ACF1\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" 3.000000000000000E00\n" +" 4.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" 3.000000000000000E00\n" +" 4.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 0.000000000000000E00\n" +" 3.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" ACF2\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" APC\n" +" ACF1\n" +" \n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" APAT\n" +" 2.300000000000000E00\n" +" 2.300000000000000E00\n" +" 1\n" +" 0\n" +" \n" +" 1.000000000000000E00\n" +" 2.000000000000000E00\n" +" \n" +" \n" +" \n" +" 5.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" 2.300000000000000E00\n" +" Parameter1\n" +" Parameter2\n" +" \n" +" \n" +" 2.800000000000000E00\n" +" Parameter1\n" +" Parameter2\n" +" \n" +" \n" +" \n" +" \n" +" 1\n" +" \n" +" TxWFParam\n" +" 3.000000000000000E00\n" +" 2.300000000000000E00\n" +" 1.800000000000000E00\n" +" 1.000000000000000E00\n" +" LHC\n" +" 5.000000000000000E00\n" +" \n" +" 2\n" +" \n" +" RcvParam1\n" +" 3.000000000000000E00\n" +" 2.300000000000000E00\n" +" 2.300000000000000E00\n" +" 1.800000000000000E00\n" +" 1.000000000000000E00\n" +" LHC\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" RcvParam2\n" +" 3.000000000000000E00\n" +" 2.300000000000000E00\n" +" 2.300000000000000E00\n" +" 1.800000000000000E00\n" +" 1.000000000000000E00\n" +" LHC\n" +" 5.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" ECF\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" 8.000000000000000E-01\n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" 5.000000000000000E00\n" +" 5.000000000000000E00\n" +" 5.000000000000000E-01\n" +" \n" +" 5.000000000000000E-01\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" Profile\n" +" \n" +" Application\n" +" 2014-04-10T08:52:09.000000Z\n" +" Area51\n" +" Value1\n" +" Value2\n" +" \n" +" Value1\n" +" \n" +" \n" +" 51\n" +" \n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E-01\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E-01\n" +" 1.000000000000000E-01\n" +" \n" +" \n" +" 0.000000000000000E00\n" +" 0.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 04/22\n" +" \n" +" \n" +" 2.000000000000000E-02\n" +" 3.000000000000000E-02\n" +" \n" +" \n" +" 8.000000000000000E-02\n" +" 8.000000000000000E-02\n" +" \n" +" \n" +" \n" +" \n" +" 09/27\n" +" \n" +" \n" +" 5.000000000000000E-02\n" +" 2.000000000000000E-02\n" +" \n" +" \n" +" 5.000000000000000E-02\n" +" 8.000000000000000E-02\n" +" \n" +" \n" +" \n" +" \n" +" Main\n" +" \n" +" 6.000000000000000E-01\n" +" 4.000000000000000E-01\n" +" \n" +" \n" +" \n" +" \n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" 1.100000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" 1.100000000000000E00\n" +" 1.100000000000000E00\n" +" \n" +" \n" +" 1.200000000000000E00\n" +" 1.200000000000000E00\n" +" \n" +" \n" +" 1.000000000000000E00\n" +" 1.000000000000000E00\n" +" \n" +" \n" +" \n" +" \n" +" 2\n" +" \n" +" STEREO\n" +" 1\n" +" 1\n" +" \n" +" CollectionName\n" +" 1\n" +" Match1\n" +" \n" +" \n" +" \n" +" COHERENT\n" +" 1\n" +" 1\n" +" \n" +" CollectionName\n" +" 1\n" +" Match1\n" +" \n" +" \n" +" \n" +"\n"; + +TEST_CASE(testOptional) +{ + io::StringStream cphdStream; + cphdStream.write(test_cphd_xml_optional_XML, strlen(test_cphd_xml_optional_XML)); + + xml::lite::MinidomParser xmlParser; + xmlParser.preserveCharacterData(true); + xmlParser.parse(cphdStream, cphdStream.available()); + const std::unique_ptr metadata = + cphd::CPHDXMLControl().fromXML(xmlParser.getDocument()); + + const cphd::SupportArray& supportArray = *(metadata->supportArray); + TEST_ASSERT_EQ(supportArray.iazArray.size(), static_cast(1)); + TEST_ASSERT_EQ(supportArray.iazArray[0].getIdentifier(), static_cast(1)); + TEST_ASSERT_EQ(supportArray.iazArray[0].elementFormat, "IAZ=F4;"); + TEST_ASSERT_EQ(supportArray.iazArray[0].x0, 0.0); + TEST_ASSERT_EQ(supportArray.iazArray[0].y0, 0.0); + TEST_ASSERT_EQ(supportArray.iazArray[0].xSS, 5.0); + TEST_ASSERT_EQ(supportArray.iazArray[0].ySS, 5.0); + + TEST_ASSERT_EQ(supportArray.antGainPhase.size(), static_cast(1)); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].getIdentifier(), static_cast(2)); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].elementFormat, "Gain=F4;Phase=F4;"); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].x0, 0.0); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].y0, 0.0); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].xSS, 5.0); + TEST_ASSERT_EQ(supportArray.antGainPhase[0].ySS, 5.0); + + TEST_ASSERT_EQ(supportArray.addedSupportArray.size(), static_cast(1)); + TEST_ASSERT_EQ(supportArray.addedSupportArray.count("AddedSupportArray"), static_cast(1)); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.elementFormat, "F4"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.x0, 0.0); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.y0, 0.0); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.xSS, 5.0); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.ySS, 5.0); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.xUnits, "XUnits"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.yUnits, "YUnits"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.zUnits, "ZUnits"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter.size(), static_cast(2)); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[0].getName(), "Parameter1"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[1].getName(), "Parameter2"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[0].str(), "Additional parameter"); + TEST_ASSERT_EQ(supportArray.addedSupportArray.find("AddedSupportArray")->second.parameter[1].str(), "Additional parameter"); + + const cphd::Antenna& antenna = *(metadata->antenna); + TEST_ASSERT_EQ(antenna.antCoordFrame.size(), static_cast(2)); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].identifier, "ACF1"); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.order(), static_cast(3)); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][0], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][0], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][0], 3); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][0], 4); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][1], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][1], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][1], 3); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][1], 4); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[0][2], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[1][2], 0); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[2][2], 3); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].xAxisPoly.coeffs()[3][2], 0); + + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[0][0], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[1][0], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[0][1], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[0].yAxisPoly.coeffs()[1][1], 2); + + TEST_ASSERT_EQ(antenna.antCoordFrame[1].identifier, "ACF2"); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[0][0], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[1][0], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[0][1], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].xAxisPoly.coeffs()[1][1], 2); + + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[0][0], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[1][0], 2); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[0][1], 1); + TEST_ASSERT_EQ(antenna.antCoordFrame[1].yAxisPoly.coeffs()[1][1], 2); + + TEST_ASSERT_EQ(antenna.antPhaseCenter.size(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].identifier, "APC"); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].acfId, "ACF1"); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[0], 5.0); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[1], 5.0); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[2], 5.0); + + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].identifier, "APC"); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].acfId, "ACF1"); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[0], 5.0); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[1], 5.0); + TEST_ASSERT_EQ(antenna.antPhaseCenter[0].apcXYZ[2], 5.0); + + TEST_ASSERT_EQ(antenna.antPattern.size(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].identifier, "APAT"); + TEST_ASSERT_EQ(antenna.antPattern[0].freqZero, 2.3); + TEST_ASSERT_EQ(antenna.antPattern[0].gainZero, 2.3); + TEST_ASSERT_EQ(antenna.antPattern[0].ebFreqShift, 1); + TEST_ASSERT_EQ(antenna.antPattern[0].mlFreqDilation, 0); + TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.coeffs()[0], 1.0); + TEST_ASSERT_EQ(antenna.antPattern[0].gainBSPoly.coeffs()[1], 2.0); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcxPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcxPoly.coeffs()[0], 5.0); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.order(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.coeffs()[0], 0.0); + TEST_ASSERT_EQ(antenna.antPattern[0].eb.dcyPoly.coeffs()[1], 5.0); + TEST_ASSERT_EQ(antenna.antPattern[0].array.gainPoly.orderX(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].array.gainPoly.orderY(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].array.phasePoly.orderX(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].array.phasePoly.orderY(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].element.gainPoly.orderX(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].element.gainPoly.orderY(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].element.phasePoly.orderX(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].element.phasePoly.orderY(), static_cast(1)); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].freq, 2.3); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].arrayId, "Parameter1"); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[0].elementId, "Parameter2"); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].freq, 2.8); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].arrayId, "Parameter1"); + TEST_ASSERT_EQ(antenna.antPattern[0].gainPhaseArray[1].elementId, "Parameter2"); + + const cphd::TxRcv& txRcv = *(metadata->txRcv); + TEST_ASSERT_EQ(txRcv.txWFParameters.size(), static_cast(1)); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].identifier, "TxWFParam"); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].pulseLength, 3.0); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].rfBandwidth, 2.3); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].freqCenter, 1.8); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].lfmRate, 1.0); + TEST_ASSERT(txRcv.txWFParameters[0].polarization.toString() == "LHC"); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].polarization, cphd::PolarizationType::LHC); + TEST_ASSERT_EQ(txRcv.txWFParameters[0].power, 5.0); + + TEST_ASSERT_EQ(txRcv.rcvParameters.size(), static_cast(2)); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].identifier, "RcvParam1"); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].windowLength, 3.0); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].sampleRate, 2.3); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].ifFilterBW, 2.3); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].freqCenter, 1.8); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].lfmRate, 1.0); + TEST_ASSERT(txRcv.rcvParameters[0].polarization.toString() == "LHC"); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].polarization, cphd::PolarizationType::LHC); + TEST_ASSERT_EQ(txRcv.rcvParameters[0].pathGain, 5.0); + + TEST_ASSERT_EQ(txRcv.rcvParameters[1].identifier, "RcvParam2"); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].windowLength, 3.0); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].sampleRate, 2.3); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].ifFilterBW, 2.3); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].freqCenter, 1.8); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].lfmRate, 1.0); + TEST_ASSERT(txRcv.rcvParameters[1].polarization.toString() == "LHC"); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].polarization, cphd::PolarizationType::LHC); + TEST_ASSERT_EQ(txRcv.rcvParameters[1].pathGain, 5.0); + + const cphd::ErrorParameters& errorParams = *(metadata->errorParameters); + TEST_ASSERT(errorParams.monostatic->posVelErr.frame == "ECF"); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.frame, six::FrameType(six::FrameType::ECF)); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.p1, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.p2, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.corrCoefs->p1p2, 0.8); + TEST_ASSERT_EQ(errorParams.monostatic->posVelErr.corrCoefs->v2v3, 0.8); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->posVelErr.positionDecorr).corrCoefZero, 0.5); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->posVelErr.positionDecorr).decorrRate, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBias, 0.5); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.clockFreqSF, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.collectionStartTime, 1.0); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBiasDecorr->corrCoefZero, 0.5); + TEST_ASSERT_EQ(errorParams.monostatic->radarSensor.rangeBiasDecorr->decorrRate, 1.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->tropoError->tropoRangeVertical), 5.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->tropoError->tropoRangeSlant), 5.0); + const auto& tropoRangeDecorr = value(errorParams.monostatic->tropoError->tropoRangeDecorr); + TEST_ASSERT_EQ(tropoRangeDecorr.corrCoefZero, 0.5); + TEST_ASSERT_EQ(tropoRangeDecorr.decorrRate, 1.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRangeVertical), 5.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRangeRateVertical), 5.0); + TEST_ASSERT_EQ(six::value(errorParams.monostatic->ionoError->ionoRgRgRateCC), 0.5); + const auto& ionoRangeVertDecorr = six::value(errorParams.monostatic->ionoError->ionoRangeVertDecorr); + TEST_ASSERT_EQ(ionoRangeVertDecorr.corrCoefZero, 0.5); + TEST_ASSERT_EQ(ionoRangeVertDecorr.decorrRate, 1.0); + + const cphd::ProductInfo& productInfo = *(metadata->productInfo); + TEST_ASSERT_EQ(productInfo.profile, "Profile"); + TEST_ASSERT_EQ(productInfo.creationInfo[0].application, "Application"); + TEST_ASSERT_EQ(productInfo.creationInfo[0].dateTime.getYear(), 2014); + TEST_ASSERT_EQ(productInfo.creationInfo[0].site, "Area51"); + TEST_ASSERT_EQ(productInfo.creationInfo[0].parameter[0].getName(), "Param1"); + TEST_ASSERT_EQ(productInfo.creationInfo[0].parameter[1].getName(), "Param2"); + TEST_ASSERT_EQ(productInfo.parameter[0].getName(), "Param1"); + + std::vector geoInfo = metadata->geoInfo; + TEST_ASSERT_EQ(geoInfo[0].name, "Airport"); + TEST_ASSERT_EQ(geoInfo[0].desc[0].getName(), "Airport ID"); + TEST_ASSERT_EQ(geoInfo[0].desc[0].str(), "51"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->name, "Perimeter"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon.size(), static_cast(4)); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[0].getLat(), 0.0); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[0].getLon(), 0.0); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[1].getLat(), 0.1); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[1].getLon(), 0.0); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[2].getLat(), 0.1); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[2].getLon(), 0.1); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[3].getLat(), 0.0); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[0]->geometryLatLon[3].getLon(), 0.0); + + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->name, "Runway"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->desc[0].getName(), "ID"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->desc[0].str(), "04/22"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon.size(), static_cast(2)); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[0].getLat(), 0.02); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[0].getLon(), 0.03); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[1].getLat(), 0.08); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[1]->geometryLatLon[1].getLon(), 0.08); + + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->name, "Control Tower"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->desc[0].getName(), "ID"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->desc[0].str(), "Main"); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->geometryLatLon[0].getLat(), 0.6); + TEST_ASSERT_EQ(geoInfo[0].geoInfos[3]->geometryLatLon[0].getLon(), 0.4); + + TEST_ASSERT_EQ(geoInfo[1].name, "Farm"); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon.size(), static_cast(5)); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[0].getLat(), 1.0); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[0].getLon(), 1.0); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[1].getLat(), 1.1); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[1].getLon(), 1.0); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[4].getLat(), 1.0); + TEST_ASSERT_EQ(geoInfo[1].geometryLatLon[4].getLon(), 1.0); + + const cphd::MatchInformation& matchInfo = *(metadata->matchInfo); + TEST_ASSERT_EQ(matchInfo.types.size(), static_cast(2)); + TEST_ASSERT_EQ(matchInfo.types[0].typeID, "STEREO"); + TEST_ASSERT_EQ(matchInfo.types[0].currentIndex, 1); + TEST_ASSERT_EQ(matchInfo.types[0].matchCollects.size(), static_cast(1)); + TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].coreName, "CollectionName"); + TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].matchIndex, 1); + TEST_ASSERT_EQ(matchInfo.types[0].matchCollects[0].parameters[0].getName(), "param1"); + TEST_ASSERT_EQ(matchInfo.types[1].typeID, "COHERENT"); + TEST_ASSERT_EQ(matchInfo.types[1].currentIndex, 1); + TEST_ASSERT_EQ(matchInfo.types[1].matchCollects.size(), static_cast(1)); + TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].coreName, "CollectionName"); + TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].matchIndex, 1); + TEST_ASSERT_EQ(matchInfo.types[1].matchCollects[0].parameters[0].getName(), "param1"); +} + +TEST_MAIN( + TEST_CHECK(testOptional); ) \ No newline at end of file diff --git a/six/modules/c++/cphd/unittests/test_dwell.cpp b/six/modules/c++/cphd/unittests/test_dwell.cpp index 7651f6b180..0f4dd45c6e 100644 --- a/six/modules/c++/cphd/unittests/test_dwell.cpp +++ b/six/modules/c++/cphd/unittests/test_dwell.cpp @@ -1,120 +1,120 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include - -#include -#include -#include -#include -#include - -#include "TestCase.h" - -TEST_CASE(testDerivativeCODValid) -{ - cphd::Dwell dwell; - cphd::COD cod1; - size_t numCODTimes = 1; - dwell.cod.resize(numCODTimes); - dwell.cod[0] = cod1; - - cphd::Poly2D p2D(1, 1); - dwell.cod[0].codTimePoly = p2D; - dwell.cod[0].codTimePoly[0][0] = 1; - dwell.cod[0].codTimePoly[1][0] = 2; - dwell.cod[0].codTimePoly[0][1] = 3; - dwell.cod[0].codTimePoly[1][1] = 4; - - // Test Derivative in terms of x - cphd::Poly2D derivativeX2D(1,1); - derivativeX2D[0][0] = 2; - derivativeX2D[0][1] = 4; - TEST_ASSERT_EQ(dwell.cod[0].codTimePoly.derivativeX(),derivativeX2D); -} - -TEST_CASE(testDerivativeDwellValid) -{ - cphd::Dwell dwell; - cphd::DwellTime dtime1; - size_t numDwellTimes = 1; - dwell.dtime.resize(numDwellTimes); - dwell.dtime[0] = dtime1; - - cphd::Poly2D p2D(1, 1); - dwell.dtime[0].dwellTimePoly = p2D; - dwell.dtime[0].dwellTimePoly[0][0] = 1; - dwell.dtime[0].dwellTimePoly[1][0] = 2; - dwell.dtime[0].dwellTimePoly[0][1] = 3; - dwell.dtime[0].dwellTimePoly[1][1] = 4; - - // Test Derivative in terms of x - cphd::Poly2D derivativeY2D(1,1); - derivativeY2D[0][0] = 3; - derivativeY2D[1][0] = 4; - TEST_ASSERT_EQ(dwell.dtime[0].dwellTimePoly.derivativeY(),derivativeY2D); -} - - -TEST_CASE(testEquality) -{ - cphd::Dwell dwell; - cphd::DwellTime dtime1, dtime2; - - size_t numDwellTimes = 2; - dwell.dtime.resize(numDwellTimes); - dwell.dtime[0] = dtime1; - dwell.dtime[1] = dtime2; - - cphd:: Poly2D p2D_1(2,1), p2D_2(2,1); - - dwell.dtime[0].dwellTimePoly = p2D_1; - dwell.dtime[1].dwellTimePoly = p2D_2; - for (size_t i = 0; i < dwell.dtime.size(); ++i) { - dwell.dtime[i].dwellTimePoly[0][0] = 1; - dwell.dtime[i].dwellTimePoly[0][1] = 2; - dwell.dtime[i].dwellTimePoly[1][0] = 3; - dwell.dtime[i].dwellTimePoly[1][1] = 4; - dwell.dtime[i].dwellTimePoly[2][0] = 5; - } - - cphd:: Poly2D derivX(1,1); - derivX[0][0] = 3; - derivX[0][1] = 4; - derivX[1][0] = 10; - - // Test identical polynomial vectors - TEST_ASSERT_EQ(dwell.dtime[0].dwellTimePoly.derivativeX(), derivX); - TEST_ASSERT_TRUE((dwell.dtime[0] == dwell.dtime[1])); - - dwell.dtime[1].dwellTimePoly = dwell.dtime[1].dwellTimePoly.flipXY(); - - // Test different polynomial vectors - TEST_ASSERT_NOT_EQ(dwell.dtime[0].dwellTimePoly.derivativeX(), dwell.dtime[1].dwellTimePoly.derivativeX()); - TEST_ASSERT_TRUE((dwell.dtime[0] != dwell.dtime[1])); -} - -TEST_MAIN( - TEST_CHECK(testDerivativeCODValid); - TEST_CHECK(testDerivativeDwellValid); - TEST_CHECK(testEquality); - ) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include + +#include +#include +#include +#include +#include + +#include "TestCase.h" + +TEST_CASE(testDerivativeCODValid) +{ + cphd::Dwell dwell; + cphd::COD cod1; + size_t numCODTimes = 1; + dwell.cod.resize(numCODTimes); + dwell.cod[0] = cod1; + + cphd::Poly2D p2D(1, 1); + dwell.cod[0].codTimePoly = p2D; + dwell.cod[0].codTimePoly[0][0] = 1; + dwell.cod[0].codTimePoly[1][0] = 2; + dwell.cod[0].codTimePoly[0][1] = 3; + dwell.cod[0].codTimePoly[1][1] = 4; + + // Test Derivative in terms of x + cphd::Poly2D derivativeX2D(1,1); + derivativeX2D[0][0] = 2; + derivativeX2D[0][1] = 4; + TEST_ASSERT_EQ(dwell.cod[0].codTimePoly.derivativeX(),derivativeX2D); +} + +TEST_CASE(testDerivativeDwellValid) +{ + cphd::Dwell dwell; + cphd::DwellTime dtime1; + size_t numDwellTimes = 1; + dwell.dtime.resize(numDwellTimes); + dwell.dtime[0] = dtime1; + + cphd::Poly2D p2D(1, 1); + dwell.dtime[0].dwellTimePoly = p2D; + dwell.dtime[0].dwellTimePoly[0][0] = 1; + dwell.dtime[0].dwellTimePoly[1][0] = 2; + dwell.dtime[0].dwellTimePoly[0][1] = 3; + dwell.dtime[0].dwellTimePoly[1][1] = 4; + + // Test Derivative in terms of x + cphd::Poly2D derivativeY2D(1,1); + derivativeY2D[0][0] = 3; + derivativeY2D[1][0] = 4; + TEST_ASSERT_EQ(dwell.dtime[0].dwellTimePoly.derivativeY(),derivativeY2D); +} + + +TEST_CASE(testEquality) +{ + cphd::Dwell dwell; + cphd::DwellTime dtime1, dtime2; + + size_t numDwellTimes = 2; + dwell.dtime.resize(numDwellTimes); + dwell.dtime[0] = dtime1; + dwell.dtime[1] = dtime2; + + cphd:: Poly2D p2D_1(2,1), p2D_2(2,1); + + dwell.dtime[0].dwellTimePoly = p2D_1; + dwell.dtime[1].dwellTimePoly = p2D_2; + for (size_t i = 0; i < dwell.dtime.size(); ++i) { + dwell.dtime[i].dwellTimePoly[0][0] = 1; + dwell.dtime[i].dwellTimePoly[0][1] = 2; + dwell.dtime[i].dwellTimePoly[1][0] = 3; + dwell.dtime[i].dwellTimePoly[1][1] = 4; + dwell.dtime[i].dwellTimePoly[2][0] = 5; + } + + cphd:: Poly2D derivX(1,1); + derivX[0][0] = 3; + derivX[0][1] = 4; + derivX[1][0] = 10; + + // Test identical polynomial vectors + TEST_ASSERT_EQ(dwell.dtime[0].dwellTimePoly.derivativeX(), derivX); + TEST_ASSERT_TRUE((dwell.dtime[0] == dwell.dtime[1])); + + dwell.dtime[1].dwellTimePoly = dwell.dtime[1].dwellTimePoly.flipXY(); + + // Test different polynomial vectors + TEST_ASSERT_NOT_EQ(dwell.dtime[0].dwellTimePoly.derivativeX(), dwell.dtime[1].dwellTimePoly.derivativeX()); + TEST_ASSERT_TRUE((dwell.dtime[0] != dwell.dtime[1])); +} + +TEST_MAIN( + TEST_CHECK(testDerivativeCODValid); + TEST_CHECK(testDerivativeDwellValid); + TEST_CHECK(testEquality); + ) diff --git a/six/modules/c++/cphd/unittests/test_pvp.cpp b/six/modules/c++/cphd/unittests/test_pvp.cpp index fe498fb10f..79a4128b7f 100644 --- a/six/modules/c++/cphd/unittests/test_pvp.cpp +++ b/six/modules/c++/cphd/unittests/test_pvp.cpp @@ -1,110 +1,110 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include -#include - -#include -#include - -#include - -#include "TestCase.h" - - -TEST_CASE(testSimpleEqualityOperatorTrue) -{ - cphd::Pvp pvp1, pvp2; - - pvp1.txTime.setOffset(0); - pvp2.txTime.setOffset(0); - - TEST_ASSERT_TRUE((pvp1 == pvp2)); -} - -TEST_CASE(testAppend) -{ - cphd::Pvp pvp; - pvp.append(pvp.txTime); - pvp.append(pvp.txPos); - pvp.append(pvp.txVel); - pvp.append(pvp.ampSF); - pvp.appendCustomParameter(8, "S8", "AddedParam1"); - pvp.append(pvp.signal); - - TEST_ASSERT_TRUE(pvp.txTime.getOffset() == 0); - TEST_ASSERT_TRUE(pvp.txPos.getOffset() == 1); - TEST_ASSERT_TRUE(pvp.txVel.getOffset() == 4); - TEST_ASSERT_TRUE(pvp.ampSF.getOffset() == 7); - TEST_ASSERT_TRUE(pvp.addedPVP["AddedParam1"].getOffset() == 8); - TEST_ASSERT_TRUE(pvp.signal.getOffset() == 16); -} - -TEST_CASE(testAddedParamsEqualityOperatorTrue) -{ - cphd::Pvp pvp1; - pvp1.setCustomParameter(1, 0, "F8", "AddedParam1"); - pvp1.setCustomParameter(1, 1, "F8", "AddedParam2"); - - cphd::Pvp pvp2; - pvp2.setCustomParameter(1, 0, "F8", "AddedParam1"); - pvp2.setCustomParameter(1, 1, "F8", "AddedParam2"); - - TEST_ASSERT_TRUE((pvp1 == pvp2)); -} - - -TEST_CASE(testSimpleEqualityOperatorFalse) -{ - cphd::Pvp pvp1; - pvp1.fxN1.setOffset(0); - - cphd::Pvp pvp2; - pvp2.txTime.setOffset(1); - - TEST_ASSERT_TRUE((pvp1 != pvp2)); - -} - -TEST_CASE(testAddedParamsEqualityOperatorFalse) -{ - cphd::Pvp pvp1; - pvp1.setCustomParameter(1, 0, "F8", "AddedParam1"); - pvp1.setCustomParameter(1, 1, "F8", "AddedParam2"); - - cphd::Pvp pvp2; - pvp2.setCustomParameter(1, 0, "F8", "AddedParam1"); - - cphd::Pvp pvp3; - pvp3.setCustomParameter(1, 0, "F8", "AddedParam1"); - pvp3.setCustomParameter(1, 1, "F8", "AddedParam3"); - - TEST_ASSERT_TRUE((pvp1 != pvp2)); - TEST_ASSERT_TRUE((pvp1 != pvp3)); -} - -TEST_MAIN( - TEST_CHECK(testSimpleEqualityOperatorTrue); - TEST_CHECK(testAppend); - TEST_CHECK(testAddedParamsEqualityOperatorTrue); - TEST_CHECK(testSimpleEqualityOperatorFalse); - TEST_CHECK(testAddedParamsEqualityOperatorFalse); +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include +#include + +#include +#include + +#include + +#include "TestCase.h" + + +TEST_CASE(testSimpleEqualityOperatorTrue) +{ + cphd::Pvp pvp1, pvp2; + + pvp1.txTime.setOffset(0); + pvp2.txTime.setOffset(0); + + TEST_ASSERT_TRUE((pvp1 == pvp2)); +} + +TEST_CASE(testAppend) +{ + cphd::Pvp pvp; + pvp.append(pvp.txTime); + pvp.append(pvp.txPos); + pvp.append(pvp.txVel); + pvp.append(pvp.ampSF); + pvp.appendCustomParameter(8, "S8", "AddedParam1"); + pvp.append(pvp.signal); + + TEST_ASSERT_TRUE(pvp.txTime.getOffset() == 0); + TEST_ASSERT_TRUE(pvp.txPos.getOffset() == 1); + TEST_ASSERT_TRUE(pvp.txVel.getOffset() == 4); + TEST_ASSERT_TRUE(pvp.ampSF.getOffset() == 7); + TEST_ASSERT_TRUE(pvp.addedPVP["AddedParam1"].getOffset() == 8); + TEST_ASSERT_TRUE(pvp.signal.getOffset() == 16); +} + +TEST_CASE(testAddedParamsEqualityOperatorTrue) +{ + cphd::Pvp pvp1; + pvp1.setCustomParameter(1, 0, "F8", "AddedParam1"); + pvp1.setCustomParameter(1, 1, "F8", "AddedParam2"); + + cphd::Pvp pvp2; + pvp2.setCustomParameter(1, 0, "F8", "AddedParam1"); + pvp2.setCustomParameter(1, 1, "F8", "AddedParam2"); + + TEST_ASSERT_TRUE((pvp1 == pvp2)); +} + + +TEST_CASE(testSimpleEqualityOperatorFalse) +{ + cphd::Pvp pvp1; + pvp1.fxN1.setOffset(0); + + cphd::Pvp pvp2; + pvp2.txTime.setOffset(1); + + TEST_ASSERT_TRUE((pvp1 != pvp2)); + +} + +TEST_CASE(testAddedParamsEqualityOperatorFalse) +{ + cphd::Pvp pvp1; + pvp1.setCustomParameter(1, 0, "F8", "AddedParam1"); + pvp1.setCustomParameter(1, 1, "F8", "AddedParam2"); + + cphd::Pvp pvp2; + pvp2.setCustomParameter(1, 0, "F8", "AddedParam1"); + + cphd::Pvp pvp3; + pvp3.setCustomParameter(1, 0, "F8", "AddedParam1"); + pvp3.setCustomParameter(1, 1, "F8", "AddedParam3"); + + TEST_ASSERT_TRUE((pvp1 != pvp2)); + TEST_ASSERT_TRUE((pvp1 != pvp3)); +} + +TEST_MAIN( + TEST_CHECK(testSimpleEqualityOperatorTrue); + TEST_CHECK(testAppend); + TEST_CHECK(testAddedParamsEqualityOperatorTrue); + TEST_CHECK(testSimpleEqualityOperatorFalse); + TEST_CHECK(testAddedParamsEqualityOperatorFalse); ) \ No newline at end of file diff --git a/six/modules/c++/cphd/unittests/test_pvp_block_round.cpp b/six/modules/c++/cphd/unittests/test_pvp_block_round.cpp index 3bb70ad502..93ec99c9c6 100644 --- a/six/modules/c++/cphd/unittests/test_pvp_block_round.cpp +++ b/six/modules/c++/cphd/unittests/test_pvp_block_round.cpp @@ -1,253 +1,253 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -template -auto generateComplexData(size_t length) -{ - using value_type = typename TComplex::value_type; - std::vector data(length); - srand(0); - for (size_t ii = 0; ii < data.size(); ++ii) - { - auto real = static_cast(rand() / 100); - auto imag = static_cast(rand() / 100); - data[ii] = TComplex(real, imag); - } - return data; -} - -void setPVPBlock(const types::RowCol dims, - cphd::PVPBlock& pvpBlock, - bool isAmpSF, - bool isFxN1, - bool isFxN2, - bool isTOAE1, - bool isTOAE2, - bool isSignal, - const std::vector& addedParams) -{ - const size_t numChannels = 1; - const std::vector numVectors(numChannels, dims.row); - - for (size_t ii = 0; ii < numChannels; ++ii) - { - for (size_t jj = 0; jj < numVectors[ii]; ++jj) - { - setVectorParameters(ii, jj, pvpBlock); - - if (isAmpSF) - { - const double ampSF = cphd::getRandom(); - pvpBlock.setAmpSF(ampSF, ii, jj); - } - if (isFxN1) - { - const double fxN1 = cphd::getRandom(); - pvpBlock.setFxN1(fxN1, ii, jj); - } - if (isFxN2) - { - const double fxN2 = cphd::getRandom(); - pvpBlock.setFxN2(fxN2, ii, jj); - } - if (isTOAE1) - { - const double toaE1 = cphd::getRandom(); - pvpBlock.setTOAE1(toaE1, ii, jj); - } - if (isTOAE2) - { - const double toaE2 = cphd::getRandom(); - pvpBlock.setTOAE2(toaE2, ii, jj); - } - if (isSignal) - { - const double signal = cphd::getRandom(); - pvpBlock.setTOAE2(signal, ii, jj); - } - - for (size_t idx = 0; idx < addedParams.size(); ++idx) - { - const double val = cphd::getRandom(); - pvpBlock.setAddedPVP(val, ii, jj, addedParams[idx]); - } - } - } -} - -template -void writeCPHD(const std::string& outPathname, - size_t numThreads, - const types::RowCol dims, - const TCxVector& writeData, - cphd::Metadata& metadata, - cphd::PVPBlock& pvpBlock) -{ - const size_t numChannels = 1; - - cphd::CPHDWriter writer(metadata, - outPathname, - std::vector(), - numThreads); - writer.writeMetadata(pvpBlock); - writer.writePVPData(pvpBlock); - for (size_t ii = 0; ii < numChannels; ++ii) - { - writer.writeCPHDData(writeData.data(), dims.area()); - } -} - -bool checkData(const std::string& pathname, - size_t numThreads, - cphd::Metadata& metadata, - cphd::PVPBlock& pvpBlock) -{ - cphd::CPHDReader reader(pathname, numThreads); - - if (metadata.pvp != reader.getMetadata().pvp) - { - return false; - } - if (pvpBlock != reader.getPVPBlock()) - { - return false; - } - return true; -} - -template -bool runTest(bool /*scale*/, - const TCxVector& writeData, - cphd::Metadata& meta, - cphd::PVPBlock& pvpBlock, - const types::RowCol dims) -{ - io::TempFile tempfile; - const size_t numThreads = std::thread::hardware_concurrency(); - writeCPHD(tempfile.pathname(), numThreads, dims, writeData, meta, pvpBlock); - return checkData(tempfile.pathname(), numThreads, meta, pvpBlock); -} - -TEST_CASE(testPVPBlockSimple) -{ - const types::RowCol dims(128, 256); - const auto writeData = generateComplexData(dims.area()); - const bool scale = false; - cphd::Metadata meta = cphd::Metadata(); - cphd::setUpData(meta, dims, writeData); - cphd::setPVPXML(meta.pvp); - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - std::vector addedParams; - setPVPBlock(dims, - pvpBlock, - false, - false, - false, - false, - false, - false, - addedParams); - - TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); -} - -TEST_CASE(testPVPBlockOptional) -{ - const types::RowCol dims(128, 256); - const auto writeData = generateComplexData(dims.area()); - const bool scale = false; - cphd::Metadata meta = cphd::Metadata(); - cphd::setUpData(meta, dims, writeData); - cphd::setPVPXML(meta.pvp); - meta.pvp.setOffset(27, meta.pvp.fxN1); - meta.pvp.setOffset(28, meta.pvp.fxN2); - meta.data.numBytesPVP += 2 * 8; - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - std::vector addedParams; - setPVPBlock(dims, - pvpBlock, - false, - true, - true, - false, - false, - false, - addedParams); - - TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); -} - -TEST_CASE(testPVPBlockAdditional) -{ - const types::RowCol dims(128, 256); - const auto writeData = generateComplexData(dims.area()); - const bool scale = false; - cphd::Metadata meta = cphd::Metadata(); - cphd::setUpData(meta, dims, writeData); - cphd::setPVPXML(meta.pvp); - meta.pvp.setCustomParameter(1, 27, "F8", "param1"); - meta.pvp.setCustomParameter(1, 28, "F8", "param2"); - meta.data.numBytesPVP += 2 * 8; - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - std::vector addedParams; - addedParams.push_back("param1"); - addedParams.push_back("param2"); - setPVPBlock(dims, - pvpBlock, - false, - false, - false, - false, - false, - false, - addedParams); - - TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); -} - -TEST_MAIN( - TEST_CHECK(testPVPBlockSimple); - TEST_CHECK(testPVPBlockOptional); - TEST_CHECK(testPVPBlockAdditional); - ) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +template +auto generateComplexData(size_t length) +{ + using value_type = typename TComplex::value_type; + std::vector data(length); + srand(0); + for (size_t ii = 0; ii < data.size(); ++ii) + { + auto real = static_cast(rand() / 100); + auto imag = static_cast(rand() / 100); + data[ii] = TComplex(real, imag); + } + return data; +} + +void setPVPBlock(const types::RowCol dims, + cphd::PVPBlock& pvpBlock, + bool isAmpSF, + bool isFxN1, + bool isFxN2, + bool isTOAE1, + bool isTOAE2, + bool isSignal, + const std::vector& addedParams) +{ + const size_t numChannels = 1; + const std::vector numVectors(numChannels, dims.row); + + for (size_t ii = 0; ii < numChannels; ++ii) + { + for (size_t jj = 0; jj < numVectors[ii]; ++jj) + { + setVectorParameters(ii, jj, pvpBlock); + + if (isAmpSF) + { + const double ampSF = cphd::getRandom(); + pvpBlock.setAmpSF(ampSF, ii, jj); + } + if (isFxN1) + { + const double fxN1 = cphd::getRandom(); + pvpBlock.setFxN1(fxN1, ii, jj); + } + if (isFxN2) + { + const double fxN2 = cphd::getRandom(); + pvpBlock.setFxN2(fxN2, ii, jj); + } + if (isTOAE1) + { + const double toaE1 = cphd::getRandom(); + pvpBlock.setTOAE1(toaE1, ii, jj); + } + if (isTOAE2) + { + const double toaE2 = cphd::getRandom(); + pvpBlock.setTOAE2(toaE2, ii, jj); + } + if (isSignal) + { + const double signal = cphd::getRandom(); + pvpBlock.setTOAE2(signal, ii, jj); + } + + for (size_t idx = 0; idx < addedParams.size(); ++idx) + { + const double val = cphd::getRandom(); + pvpBlock.setAddedPVP(val, ii, jj, addedParams[idx]); + } + } + } +} + +template +void writeCPHD(const std::string& outPathname, + size_t numThreads, + const types::RowCol dims, + const TCxVector& writeData, + cphd::Metadata& metadata, + cphd::PVPBlock& pvpBlock) +{ + const size_t numChannels = 1; + + cphd::CPHDWriter writer(metadata, + outPathname, + std::vector(), + numThreads); + writer.writeMetadata(pvpBlock); + writer.writePVPData(pvpBlock); + for (size_t ii = 0; ii < numChannels; ++ii) + { + writer.writeCPHDData(writeData.data(), dims.area()); + } +} + +bool checkData(const std::string& pathname, + size_t numThreads, + cphd::Metadata& metadata, + cphd::PVPBlock& pvpBlock) +{ + cphd::CPHDReader reader(pathname, numThreads); + + if (metadata.pvp != reader.getMetadata().pvp) + { + return false; + } + if (pvpBlock != reader.getPVPBlock()) + { + return false; + } + return true; +} + +template +bool runTest(bool /*scale*/, + const TCxVector& writeData, + cphd::Metadata& meta, + cphd::PVPBlock& pvpBlock, + const types::RowCol dims) +{ + io::TempFile tempfile; + const size_t numThreads = std::thread::hardware_concurrency(); + writeCPHD(tempfile.pathname(), numThreads, dims, writeData, meta, pvpBlock); + return checkData(tempfile.pathname(), numThreads, meta, pvpBlock); +} + +TEST_CASE(testPVPBlockSimple) +{ + const types::RowCol dims(128, 256); + const auto writeData = generateComplexData(dims.area()); + const bool scale = false; + cphd::Metadata meta = cphd::Metadata(); + cphd::setUpData(meta, dims, writeData); + cphd::setPVPXML(meta.pvp); + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + std::vector addedParams; + setPVPBlock(dims, + pvpBlock, + false, + false, + false, + false, + false, + false, + addedParams); + + TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); +} + +TEST_CASE(testPVPBlockOptional) +{ + const types::RowCol dims(128, 256); + const auto writeData = generateComplexData(dims.area()); + const bool scale = false; + cphd::Metadata meta = cphd::Metadata(); + cphd::setUpData(meta, dims, writeData); + cphd::setPVPXML(meta.pvp); + meta.pvp.setOffset(27, meta.pvp.fxN1); + meta.pvp.setOffset(28, meta.pvp.fxN2); + meta.data.numBytesPVP += 2 * 8; + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + std::vector addedParams; + setPVPBlock(dims, + pvpBlock, + false, + true, + true, + false, + false, + false, + addedParams); + + TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); +} + +TEST_CASE(testPVPBlockAdditional) +{ + const types::RowCol dims(128, 256); + const auto writeData = generateComplexData(dims.area()); + const bool scale = false; + cphd::Metadata meta = cphd::Metadata(); + cphd::setUpData(meta, dims, writeData); + cphd::setPVPXML(meta.pvp); + meta.pvp.setCustomParameter(1, 27, "F8", "param1"); + meta.pvp.setCustomParameter(1, 28, "F8", "param2"); + meta.data.numBytesPVP += 2 * 8; + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + std::vector addedParams; + addedParams.push_back("param1"); + addedParams.push_back("param2"); + setPVPBlock(dims, + pvpBlock, + false, + false, + false, + false, + false, + false, + addedParams); + + TEST_ASSERT_TRUE(runTest(scale, writeData, meta, pvpBlock, dims)); +} + +TEST_MAIN( + TEST_CHECK(testPVPBlockSimple); + TEST_CHECK(testPVPBlockOptional); + TEST_CHECK(testPVPBlockAdditional); + ) diff --git a/six/modules/c++/cphd/unittests/test_reference_geometry.cpp b/six/modules/c++/cphd/unittests/test_reference_geometry.cpp index 28fa51ffe8..f8ad96b91c 100644 --- a/six/modules/c++/cphd/unittests/test_reference_geometry.cpp +++ b/six/modules/c++/cphd/unittests/test_reference_geometry.cpp @@ -1,63 +1,63 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include -#include - -#include -#include -#include -#include - -#include "TestCase.h" - -TEST_CASE(testEquality) -{ - cphd::ReferenceGeometry refGeo; - cphd::ReferenceGeometry refGeoOther; - refGeo.monostatic.reset(new cphd::Monostatic()); - refGeoOther.monostatic.reset(new cphd::Monostatic()); - - // Fill Values - refGeo.monostatic->azimuthAngle = 1.0; - refGeo.monostatic->grazeAngle = 1.0; - refGeo.monostatic->twistAngle = 1.0; - refGeo.monostatic->slopeAngle = 1.0; - refGeo.monostatic->layoverAngle = 1.0; - refGeo.monostatic->sideOfTrack = six::SideOfTrackType::LEFT; - refGeo.monostatic->slantRange = 20.0; - - refGeoOther.monostatic->azimuthAngle = 2.0; - refGeoOther.monostatic->grazeAngle = 2.0; - refGeoOther.monostatic->twistAngle = 2.0; - refGeoOther.monostatic->slopeAngle = 2.0; - refGeoOther.monostatic->layoverAngle = 2.0; - refGeoOther.monostatic->sideOfTrack = six::SideOfTrackType::LEFT; - refGeoOther.monostatic->slantRange = 20.0; - - TEST_ASSERT_NOT_EQ(refGeo, refGeoOther); -} - -TEST_MAIN( - TEST_CHECK(testEquality); -) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include +#include + +#include +#include +#include +#include + +#include "TestCase.h" + +TEST_CASE(testEquality) +{ + cphd::ReferenceGeometry refGeo; + cphd::ReferenceGeometry refGeoOther; + refGeo.monostatic.reset(new cphd::Monostatic()); + refGeoOther.monostatic.reset(new cphd::Monostatic()); + + // Fill Values + refGeo.monostatic->azimuthAngle = 1.0; + refGeo.monostatic->grazeAngle = 1.0; + refGeo.monostatic->twistAngle = 1.0; + refGeo.monostatic->slopeAngle = 1.0; + refGeo.monostatic->layoverAngle = 1.0; + refGeo.monostatic->sideOfTrack = six::SideOfTrackType::LEFT; + refGeo.monostatic->slantRange = 20.0; + + refGeoOther.monostatic->azimuthAngle = 2.0; + refGeoOther.monostatic->grazeAngle = 2.0; + refGeoOther.monostatic->twistAngle = 2.0; + refGeoOther.monostatic->slopeAngle = 2.0; + refGeoOther.monostatic->layoverAngle = 2.0; + refGeoOther.monostatic->sideOfTrack = six::SideOfTrackType::LEFT; + refGeoOther.monostatic->slantRange = 20.0; + + TEST_ASSERT_NOT_EQ(refGeo, refGeoOther); +} + +TEST_MAIN( + TEST_CHECK(testEquality); +) diff --git a/six/modules/c++/cphd/unittests/test_signal_block_round.cpp b/six/modules/c++/cphd/unittests/test_signal_block_round.cpp index 197bc10698..3953c8bd63 100644 --- a/six/modules/c++/cphd/unittests/test_signal_block_round.cpp +++ b/six/modules/c++/cphd/unittests/test_signal_block_round.cpp @@ -1,224 +1,224 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/*! - * Tests write and read of Signal Block - * Fails if values don't match - */ - -template -auto generateData(size_t length) -{ - using value_type = typename TComplex::value_type; - std::vector data(length); - srand(0); - for (size_t ii = 0; ii < data.size(); ++ii) - { - auto real = static_cast(rand() / 100); - auto imag = static_cast(rand() / 100); - data[ii] = TComplex(real, imag); - } - return data; -} - -inline std::vector generateScaleFactors(size_t length, bool scale) -{ - std::vector scaleFactors(length, 1); - if (scale) - { - for (size_t ii = 0; ii < scaleFactors.size(); ++ii) - { - scaleFactors[ii] *= 2; - } - } - return scaleFactors; -} - -template -void writeCPHD(const std::string& outPathname, size_t /*numThreads*/, - const types::RowCol dims, - const TCxVector& writeData, - cphd::Metadata& metadata, - cphd::PVPBlock& pvpBlock) -{ - const size_t numChannels = 1; - const std::vector numVectors(numChannels, dims.row); - - for (size_t ii = 0; ii < numChannels; ++ii) - { - for (size_t jj = 0; jj < numVectors[ii]; ++jj) - { - cphd::setVectorParameters(ii, jj, pvpBlock); - } - } - - cphd::CPHDWriter writer(metadata, outPathname); - writer.writeMetadata(pvpBlock); - writer.writePVPData(pvpBlock); - for (size_t ii = 0; ii < numChannels; ++ii) - { - writer.writeCPHDData(writeData.data(),dims.area()); - } -} - -std::vector checkData(const std::string& pathname, - size_t numThreads, - const std::vector& scaleFactors, - const types::RowCol dims) -{ - cphd::CPHDReader reader(pathname, numThreads); - const cphd::Wideband& wideband = reader.getWideband(); - std::vector readData(dims.area()); - - size_t sizeInBytes = readData.size() * sizeof(readData[0]); - std::vector scratchData(sizeInBytes); - std::span scratch(scratchData.data(), scratchData.size()); - std::span data(readData.data(), readData.size()); - - wideband.read(0, 0, cphd::Wideband::ALL, 0, cphd::Wideband::ALL, - scaleFactors, numThreads, scratch, data); - - return readData; -} - -template -bool compareVectors(const std::vector& readData, - const TCxVector& writeData, - const std::vector& scaleFactors, - bool scale) -{ - size_t pointsPerScale = readData.size() / scaleFactors.size(); - for (size_t ii = 0; ii < readData.size(); ++ii) - { - cphd::zfloat val(writeData[ii].real(), writeData[ii].imag()); - if (scale) - { - val *= scaleFactors[ii / pointsPerScale]; - } - - if (val != readData[ii]) - { - std::cerr << "Value mismatch at index " << ii << std::endl; - return false; - } - } - return true; -} - -template -bool runTest(bool scale, const TCxVector& writeData) -{ - io::TempFile tempfile; - const size_t numThreads = std::thread::hardware_concurrency(); - const types::RowCol dims(128, 128); - const std::vector scaleFactors = - generateScaleFactors(dims.row, scale); - cphd::Metadata meta = cphd::Metadata(); - setUpData(meta, dims, writeData); - cphd::setPVPXML(meta.pvp); - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - - writeCPHD(tempfile.pathname(), numThreads, dims, writeData, meta, pvpBlock); - const std::vector readData = - checkData(tempfile.pathname(), numThreads, - scaleFactors, dims); - return compareVectors(readData, writeData, scaleFactors, scale); - return true; -} - -TEST_CASE(testUnscaledInt8) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = false; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testScaledInt8) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = true; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testUnscaledInt16) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = false; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testScaledInt16) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = true; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testUnscaledFloat) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = false; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_CASE(testScaledFloat) -{ - const types::RowCol dims(128, 128); - const auto writeData = generateData(dims.area()); - const bool scale = true; - TEST_ASSERT_TRUE(runTest(scale, writeData)); -} - -TEST_MAIN( - TEST_CHECK(testUnscaledInt8); - TEST_CHECK(testScaledInt8); - TEST_CHECK(testUnscaledInt16); - TEST_CHECK(testScaledInt16); - TEST_CHECK(testUnscaledFloat); - TEST_CHECK(testScaledFloat); - ) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/*! + * Tests write and read of Signal Block + * Fails if values don't match + */ + +template +auto generateData(size_t length) +{ + using value_type = typename TComplex::value_type; + std::vector data(length); + srand(0); + for (size_t ii = 0; ii < data.size(); ++ii) + { + auto real = static_cast(rand() / 100); + auto imag = static_cast(rand() / 100); + data[ii] = TComplex(real, imag); + } + return data; +} + +inline std::vector generateScaleFactors(size_t length, bool scale) +{ + std::vector scaleFactors(length, 1); + if (scale) + { + for (size_t ii = 0; ii < scaleFactors.size(); ++ii) + { + scaleFactors[ii] *= 2; + } + } + return scaleFactors; +} + +template +void writeCPHD(const std::string& outPathname, size_t /*numThreads*/, + const types::RowCol dims, + const TCxVector& writeData, + cphd::Metadata& metadata, + cphd::PVPBlock& pvpBlock) +{ + const size_t numChannels = 1; + const std::vector numVectors(numChannels, dims.row); + + for (size_t ii = 0; ii < numChannels; ++ii) + { + for (size_t jj = 0; jj < numVectors[ii]; ++jj) + { + cphd::setVectorParameters(ii, jj, pvpBlock); + } + } + + cphd::CPHDWriter writer(metadata, outPathname); + writer.writeMetadata(pvpBlock); + writer.writePVPData(pvpBlock); + for (size_t ii = 0; ii < numChannels; ++ii) + { + writer.writeCPHDData(writeData.data(),dims.area()); + } +} + +std::vector checkData(const std::string& pathname, + size_t numThreads, + const std::vector& scaleFactors, + const types::RowCol dims) +{ + cphd::CPHDReader reader(pathname, numThreads); + const cphd::Wideband& wideband = reader.getWideband(); + std::vector readData(dims.area()); + + size_t sizeInBytes = readData.size() * sizeof(readData[0]); + std::vector scratchData(sizeInBytes); + std::span scratch(scratchData.data(), scratchData.size()); + std::span data(readData.data(), readData.size()); + + wideband.read(0, 0, cphd::Wideband::ALL, 0, cphd::Wideband::ALL, + scaleFactors, numThreads, scratch, data); + + return readData; +} + +template +bool compareVectors(const std::vector& readData, + const TCxVector& writeData, + const std::vector& scaleFactors, + bool scale) +{ + size_t pointsPerScale = readData.size() / scaleFactors.size(); + for (size_t ii = 0; ii < readData.size(); ++ii) + { + cphd::zfloat val(writeData[ii].real(), writeData[ii].imag()); + if (scale) + { + val *= scaleFactors[ii / pointsPerScale]; + } + + if (val != readData[ii]) + { + std::cerr << "Value mismatch at index " << ii << std::endl; + return false; + } + } + return true; +} + +template +bool runTest(bool scale, const TCxVector& writeData) +{ + io::TempFile tempfile; + const size_t numThreads = std::thread::hardware_concurrency(); + const types::RowCol dims(128, 128); + const std::vector scaleFactors = + generateScaleFactors(dims.row, scale); + cphd::Metadata meta = cphd::Metadata(); + setUpData(meta, dims, writeData); + cphd::setPVPXML(meta.pvp); + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + + writeCPHD(tempfile.pathname(), numThreads, dims, writeData, meta, pvpBlock); + const std::vector readData = + checkData(tempfile.pathname(), numThreads, + scaleFactors, dims); + return compareVectors(readData, writeData, scaleFactors, scale); + return true; +} + +TEST_CASE(testUnscaledInt8) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = false; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testScaledInt8) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = true; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testUnscaledInt16) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = false; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testScaledInt16) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = true; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testUnscaledFloat) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = false; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_CASE(testScaledFloat) +{ + const types::RowCol dims(128, 128); + const auto writeData = generateData(dims.area()); + const bool scale = true; + TEST_ASSERT_TRUE(runTest(scale, writeData)); +} + +TEST_MAIN( + TEST_CHECK(testUnscaledInt8); + TEST_CHECK(testScaledInt8); + TEST_CHECK(testUnscaledInt16); + TEST_CHECK(testScaledInt16); + TEST_CHECK(testUnscaledFloat); + TEST_CHECK(testScaledFloat); + ) diff --git a/six/modules/c++/cphd/unittests/test_support_block_round.cpp b/six/modules/c++/cphd/unittests/test_support_block_round.cpp index 8dd52bbd82..0e075b58b3 100644 --- a/six/modules/c++/cphd/unittests/test_support_block_round.cpp +++ b/six/modules/c++/cphd/unittests/test_support_block_round.cpp @@ -1,168 +1,168 @@ -/* ========================================================================= - * This file is part of cphd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2019, MDA Information Systems LLC - * - * cphd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -static constexpr size_t NUM_SUPPORT = 3; -static constexpr size_t NUM_ROWS = 3; -static constexpr size_t NUM_COLS = 4; - -template -std::vector generateSupportData(size_t length) -{ - std::vector data(length); - srand(0); - for (size_t ii = 0; ii < data.size(); ++ii) - { - data[ii] = rand() % 16; - } - return data; -} - -template -void setSupport(cphd::Data& d) -{ - d.setSupportArray("1.0", NUM_ROWS, NUM_COLS, sizeof(T), 0); - d.setSupportArray("2.0", NUM_ROWS, NUM_COLS, sizeof(T), NUM_ROWS*NUM_COLS*sizeof(T)); - d.setSupportArray("AddedSupport", NUM_ROWS, NUM_COLS, sizeof(T), 2*NUM_ROWS*NUM_COLS*sizeof(T)); -} - -template -void writeSupportData(const std::string& outPathname, size_t numThreads, - const std::vector& writeData, - cphd::Metadata& metadata, - cphd::PVPBlock& pvpBlock) -{ - const size_t numChannels = 1; - // Required but doesn't matter - const std::vector numVectors(numChannels, 128); - - for (size_t ii = 0; ii < numChannels; ++ii) - { - for (size_t jj = 0; jj < numVectors[ii]; ++jj) - { - cphd::setVectorParameters(ii, jj, pvpBlock); - } - } - cphd::CPHDWriter writer(metadata, outPathname, std::vector(), numThreads); - writer.writeMetadata(pvpBlock); - writer.writeSupportData(writeData.data()); - writer.writePVPData(pvpBlock); -} - -std::vector checkSupportData( - const std::string& pathname, - size_t /*size*/, - size_t numThreads) -{ - cphd::CPHDReader reader(pathname, numThreads); - const cphd::SupportBlock& supportBlock = reader.getSupportBlock(); - - std::unique_ptr readPtr; - supportBlock.readAll(numThreads, readPtr); - - std::vector readData(readPtr.get(), readPtr.get() + reader.getMetadata().data.getAllSupportSize()); - return readData; -} - -template -bool compareVectors(const std::vector& readData, - const T* writeData, - size_t writeDataSize) -{ - if (writeDataSize * sizeof(T) != readData.size()) - { - std::cerr << "Size mismatch. Writedata size: "<< writeDataSize * sizeof(T) - << "ReadData size: " << readData.size() << "\n"; - return false; - } - const std::byte* ptr = reinterpret_cast(writeData); - for (size_t ii = 0; ii < readData.size(); ++ii, ++ptr) - { - if (*ptr != readData[ii]) - { - std::cerr << "Value mismatch at index " << ii << std::endl; - std::cerr << "readData: " << static_cast(readData[ii]) << " " << "writeData: " << static_cast(*ptr) << "\n"; - return false; - } - } - return true; -} - -template -bool runTest(const std::vector& writeData) -{ - io::TempFile tempfile; - const size_t numThreads = 1; - cphd::Metadata meta = cphd::Metadata(); - cphd::setUpData(meta, types::RowCol(128,256), std::vector()); - setSupport(meta.data); - cphd::setPVPXML(meta.pvp); - cphd::PVPBlock pvpBlock(meta.pvp, meta.data); - writeSupportData(tempfile.pathname(), numThreads, writeData, meta, pvpBlock); - const std::vector readData = - checkSupportData(tempfile.pathname(), NUM_SUPPORT*NUM_ROWS*NUM_COLS*sizeof(T), numThreads); - - return compareVectors(readData, writeData.data(), writeData.size()); -} - -TEST_CASE(testSupportsInt) -{ - const types::RowCol dims(NUM_ROWS, NUM_COLS); - const std::vector writeData = - generateSupportData(NUM_SUPPORT*dims.area()); - TEST_ASSERT_TRUE(runTest(writeData)); -} - -TEST_CASE(testSupportsDouble) -{ - const types::RowCol dims(NUM_ROWS, NUM_COLS); - const std::vector writeData = - generateSupportData(NUM_SUPPORT*dims.area()); - TEST_ASSERT_TRUE(runTest(writeData)); -} - -TEST_MAIN( - TEST_CHECK(testSupportsInt); - TEST_CHECK(testSupportsDouble); - ) +/* ========================================================================= + * This file is part of cphd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2019, MDA Information Systems LLC + * + * cphd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static constexpr size_t NUM_SUPPORT = 3; +static constexpr size_t NUM_ROWS = 3; +static constexpr size_t NUM_COLS = 4; + +template +std::vector generateSupportData(size_t length) +{ + std::vector data(length); + srand(0); + for (size_t ii = 0; ii < data.size(); ++ii) + { + data[ii] = rand() % 16; + } + return data; +} + +template +void setSupport(cphd::Data& d) +{ + d.setSupportArray("1.0", NUM_ROWS, NUM_COLS, sizeof(T), 0); + d.setSupportArray("2.0", NUM_ROWS, NUM_COLS, sizeof(T), NUM_ROWS*NUM_COLS*sizeof(T)); + d.setSupportArray("AddedSupport", NUM_ROWS, NUM_COLS, sizeof(T), 2*NUM_ROWS*NUM_COLS*sizeof(T)); +} + +template +void writeSupportData(const std::string& outPathname, size_t numThreads, + const std::vector& writeData, + cphd::Metadata& metadata, + cphd::PVPBlock& pvpBlock) +{ + const size_t numChannels = 1; + // Required but doesn't matter + const std::vector numVectors(numChannels, 128); + + for (size_t ii = 0; ii < numChannels; ++ii) + { + for (size_t jj = 0; jj < numVectors[ii]; ++jj) + { + cphd::setVectorParameters(ii, jj, pvpBlock); + } + } + cphd::CPHDWriter writer(metadata, outPathname, std::vector(), numThreads); + writer.writeMetadata(pvpBlock); + writer.writeSupportData(writeData.data()); + writer.writePVPData(pvpBlock); +} + +std::vector checkSupportData( + const std::string& pathname, + size_t /*size*/, + size_t numThreads) +{ + cphd::CPHDReader reader(pathname, numThreads); + const cphd::SupportBlock& supportBlock = reader.getSupportBlock(); + + std::unique_ptr readPtr; + supportBlock.readAll(numThreads, readPtr); + + std::vector readData(readPtr.get(), readPtr.get() + reader.getMetadata().data.getAllSupportSize()); + return readData; +} + +template +bool compareVectors(const std::vector& readData, + const T* writeData, + size_t writeDataSize) +{ + if (writeDataSize * sizeof(T) != readData.size()) + { + std::cerr << "Size mismatch. Writedata size: "<< writeDataSize * sizeof(T) + << "ReadData size: " << readData.size() << "\n"; + return false; + } + const std::byte* ptr = reinterpret_cast(writeData); + for (size_t ii = 0; ii < readData.size(); ++ii, ++ptr) + { + if (*ptr != readData[ii]) + { + std::cerr << "Value mismatch at index " << ii << std::endl; + std::cerr << "readData: " << static_cast(readData[ii]) << " " << "writeData: " << static_cast(*ptr) << "\n"; + return false; + } + } + return true; +} + +template +bool runTest(const std::vector& writeData) +{ + io::TempFile tempfile; + const size_t numThreads = 1; + cphd::Metadata meta = cphd::Metadata(); + cphd::setUpData(meta, types::RowCol(128,256), std::vector()); + setSupport(meta.data); + cphd::setPVPXML(meta.pvp); + cphd::PVPBlock pvpBlock(meta.pvp, meta.data); + writeSupportData(tempfile.pathname(), numThreads, writeData, meta, pvpBlock); + const std::vector readData = + checkSupportData(tempfile.pathname(), NUM_SUPPORT*NUM_ROWS*NUM_COLS*sizeof(T), numThreads); + + return compareVectors(readData, writeData.data(), writeData.size()); +} + +TEST_CASE(testSupportsInt) +{ + const types::RowCol dims(NUM_ROWS, NUM_COLS); + const std::vector writeData = + generateSupportData(NUM_SUPPORT*dims.area()); + TEST_ASSERT_TRUE(runTest(writeData)); +} + +TEST_CASE(testSupportsDouble) +{ + const types::RowCol dims(NUM_ROWS, NUM_COLS); + const std::vector writeData = + generateSupportData(NUM_SUPPORT*dims.area()); + TEST_ASSERT_TRUE(runTest(writeData)); +} + +TEST_MAIN( + TEST_CHECK(testSupportsInt); + TEST_CHECK(testSupportsDouble); + ) diff --git a/six/modules/c++/cphd03/cphd03.vcxproj b/six/modules/c++/cphd03/cphd03.vcxproj index cbdb44a2b7..129e159151 100644 --- a/six/modules/c++/cphd03/cphd03.vcxproj +++ b/six/modules/c++/cphd03/cphd03.vcxproj @@ -1,151 +1,151 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {016EF417-E41C-404C-B3B5-34B6CDD94BB3} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..\cphd\include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..\cphd\include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - {01be4480-9620-4ded-b34f-d2e3ab4b7c8b} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {016EF417-E41C-404C-B3B5-34B6CDD94BB3} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..\cphd\include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..\cphd\include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + {01be4480-9620-4ded-b34f-d2e3ab4b7c8b} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/six/modules/c++/samples/check_valid_six.cpp b/six/modules/c++/samples/check_valid_six.cpp index f6d6efecc9..0a9c287528 100644 --- a/six/modules/c++/samples/check_valid_six.cpp +++ b/six/modules/c++/samples/check_valid_six.cpp @@ -1,279 +1,279 @@ -/* ========================================================================= - * This file is part of six-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2014, MDA Information Systems LLC - * - * six-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include - -#include - -#include -#include -#include -#include -#include -#include "utils.h" - -namespace fs = std::filesystem; - -namespace -{ -// TODO: Does this belong in sys? -class ExtensionsPredicate : public sys::FileOnlyPredicate -{ -public: - ExtensionsPredicate(const std::vector& extensions, - bool ignoreCase = true) : - mExtensions(extensions), - mIgnoreCase(ignoreCase) - { - if (mIgnoreCase) - { - for (size_t ii = 0; ii < mExtensions.size(); ++ii) - { - str::lower(mExtensions[ii]); - } - } - } - - virtual bool operator()(const std::string& pathname) const - { - if (!sys::FileOnlyPredicate::operator()(pathname)) - { - return false; - } - - std::string ext = fs::path(pathname).extension().string(); - if (mIgnoreCase) - { - str::lower(ext); - } - - for (size_t ii = 0; ii < mExtensions.size(); ++ii) - { - if (ext == mExtensions[ii]) - { - return true; - } - } - - return false; - } - -private: - std::vector mExtensions; - const bool mIgnoreCase; -}; - -std::vector getPathnames(const std::string& dirname) -{ - std::vector extensions; - extensions.push_back(".nitf"); - extensions.push_back(".ntf"); - extensions.push_back(".xml"); - - return sys::FileFinder::search(ExtensionsPredicate(extensions), - std::vector(1, dirname), - false); -} - -bool runValidation(const std::unique_ptr& data, - std::unique_ptr& log) -{ - if (data->getDataType() == six::DataType::COMPLEX) - { - six::sicd::ComplexData* complexData = - static_cast( - data.get()); - - if (complexData->validate(*log)) - { - log->info(Ctxt("Successful: No Errors Found!")); - return true; - } - return false; - } - else - { - // Nothing to validate - log->info(Ctxt("Nothing done: not a SICD.")); - return true; - } -} -} - -// make it a little easier to use from MSVC -#if defined(_DEBUG) && defined(_MSC_VER) -static fs::path getNitfPath() -{ - const auto cwd = fs::current_path(); - const auto root_dir = cwd.parent_path().parent_path(); - return root_dir / "six" / "tests" / "nitf" / "sicd_1.1.0.nitf"; -} - -static void setNitfPluginPath() -{ - const auto cwd = fs::current_path(); - const auto root_dir = cwd.parent_path().parent_path().parent_path().parent_path().parent_path(); - - const std::string configuration = -#if defined(NDEBUG) // i.e., release - "Release"; -#else - "Debug"; -#endif - const std::string platform = "x64"; - - const auto path = root_dir / "externals" / "nitro" / platform / configuration / "share" / "nitf" / "plugins"; - sys::OS().setEnv("NITF_PLUGIN_PATH", path.string(), true /*overwrite*/); -} -#endif - -static int main_(int argc, char** argv) -{ - // make it a little easier to use from MSVC - #if defined(_DEBUG) && defined(_MSC_VER) - if (argc == 1) - { - setNitfPluginPath(); - - // ./six/modules/c++/six/tests/nitf/sidd_1.0.0.nitf - static const std::string nitf_path = getNitfPath().string(); - argc = 2; - auto argv_ = static_cast(malloc(argc * sizeof(char*))); - argv_[0] = argv[0]; - argv_[1] = const_cast(nitf_path.c_str()); - //argv[1] - argv = argv_; - } - #endif - - - // create a parser and add our options to it - cli::ArgumentParser parser; - parser.setDescription("This program reads a SIDD/SICD along with a "\ - "directory of schemas, and returns any error messages "\ - "that may be contained in the DES XML"); - parser.addArgument("-f --log", "Specify a log file", cli::STORE, "log", - "FILE")->setDefault("console"); - parser.addArgument("-l --level", "Specify log level", cli::STORE, - "level", "LEVEL")->setChoices( - str::split("debug info warn error"))->setDefault( - "info"); - parser.addArgument("-s --schema", - "Specify a schema or directory of schemas", - cli::STORE, "schema", "FILE"); - parser.addArgument("input", "Input SICD/SIDD file or directory of files", cli::STORE, "input", - "INPUT", 1, 1); - - const std::unique_ptr - options(parser.parse(argc, (const char**) argv)); - - const std::string inputPath(options->get("input")); - std::vector inputPathnames = getPathnames(inputPath); - const std::string logFile(options->get("log")); - std::string level(options->get("level")); - std::vector schemaPaths; - getSchemaPaths(*options, "--schema", "schema", schemaPaths); - - // create an XML registry - // The reason to do this is to avoid adding XMLControlCreators to the - // XMLControlFactory singleton - this way has more fine-grained control - six::XMLControlRegistry xmlRegistry; - xmlRegistry.addCreator(); - xmlRegistry.addCreator(); - - str::upper(level); - str::trim(level); - std::unique_ptr log = - logging::setupLogger(fs::path(argv[0]).filename().string(), level, logFile); - - // this validates the DES of the input against the - // best available schema - six::NITFReadControl reader; - reader.setLogger(*log); - reader.setXMLControlRegistry(&xmlRegistry); - bool allValid = true; - for (size_t ii = 0; ii < inputPathnames.size(); ++ii) - { - const std::string& inputPathname(inputPathnames[ii]); - log->info(Ctxt("Reading " + inputPathname)); - std::unique_ptr data; - try - { - if (nitf::Reader::getNITFVersion(inputPathname) == - NITF_VER_UNKNOWN) - { - data = six::parseDataFromFile(xmlRegistry, - inputPathname, - schemaPaths, - *log); - allValid = allValid && runValidation(data, log); - } - else - { - reader.load(inputPathname, schemaPaths); - auto container = reader.getContainer(); - for (size_t jj = 0; jj < container->size(); ++jj) - { - data.reset(container->getData(jj)->clone()); - allValid = allValid && runValidation(data, log); - } - } - - } - catch (const six::DESValidationException& ex) - { - log->error(ex); - log->error(Ctxt("Unsuccessful: Please contact your product " - "vendor with these details!")); - allValid = false; - } - catch (const except::Exception& ex) - { - log->error(ex); - allValid = false; - } - } - - return allValid ? EXIT_SUCCESS : EXIT_FAILURE; -} -int main(int argc, char** argv) -{ - try - { - return main_(argc, argv); - } - catch (const std::exception& ex) - { - std::cerr << ex.what() << std::endl; - } - catch (const except::Exception& ex) - { - std::cerr << ex.toString() << std::endl; - return 1; - } - catch (...) - { - std::cerr << "Unknown exception\n"; - } - - return EXIT_FAILURE; +/* ========================================================================= + * This file is part of six-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * six-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include + +#include + +#include +#include +#include +#include +#include +#include "utils.h" + +namespace fs = std::filesystem; + +namespace +{ +// TODO: Does this belong in sys? +class ExtensionsPredicate : public sys::FileOnlyPredicate +{ +public: + ExtensionsPredicate(const std::vector& extensions, + bool ignoreCase = true) : + mExtensions(extensions), + mIgnoreCase(ignoreCase) + { + if (mIgnoreCase) + { + for (size_t ii = 0; ii < mExtensions.size(); ++ii) + { + str::lower(mExtensions[ii]); + } + } + } + + virtual bool operator()(const std::string& pathname) const + { + if (!sys::FileOnlyPredicate::operator()(pathname)) + { + return false; + } + + std::string ext = fs::path(pathname).extension().string(); + if (mIgnoreCase) + { + str::lower(ext); + } + + for (size_t ii = 0; ii < mExtensions.size(); ++ii) + { + if (ext == mExtensions[ii]) + { + return true; + } + } + + return false; + } + +private: + std::vector mExtensions; + const bool mIgnoreCase; +}; + +std::vector getPathnames(const std::string& dirname) +{ + std::vector extensions; + extensions.push_back(".nitf"); + extensions.push_back(".ntf"); + extensions.push_back(".xml"); + + return sys::FileFinder::search(ExtensionsPredicate(extensions), + std::vector(1, dirname), + false); +} + +bool runValidation(const std::unique_ptr& data, + std::unique_ptr& log) +{ + if (data->getDataType() == six::DataType::COMPLEX) + { + six::sicd::ComplexData* complexData = + static_cast( + data.get()); + + if (complexData->validate(*log)) + { + log->info(Ctxt("Successful: No Errors Found!")); + return true; + } + return false; + } + else + { + // Nothing to validate + log->info(Ctxt("Nothing done: not a SICD.")); + return true; + } +} +} + +// make it a little easier to use from MSVC +#if defined(_DEBUG) && defined(_MSC_VER) +static fs::path getNitfPath() +{ + const auto cwd = fs::current_path(); + const auto root_dir = cwd.parent_path().parent_path(); + return root_dir / "six" / "tests" / "nitf" / "sicd_1.1.0.nitf"; +} + +static void setNitfPluginPath() +{ + const auto cwd = fs::current_path(); + const auto root_dir = cwd.parent_path().parent_path().parent_path().parent_path().parent_path(); + + const std::string configuration = +#if defined(NDEBUG) // i.e., release + "Release"; +#else + "Debug"; +#endif + const std::string platform = "x64"; + + const auto path = root_dir / "externals" / "nitro" / platform / configuration / "share" / "nitf" / "plugins"; + sys::OS().setEnv("NITF_PLUGIN_PATH", path.string(), true /*overwrite*/); +} +#endif + +static int main_(int argc, char** argv) +{ + // make it a little easier to use from MSVC + #if defined(_DEBUG) && defined(_MSC_VER) + if (argc == 1) + { + setNitfPluginPath(); + + // ./six/modules/c++/six/tests/nitf/sidd_1.0.0.nitf + static const std::string nitf_path = getNitfPath().string(); + argc = 2; + auto argv_ = static_cast(malloc(argc * sizeof(char*))); + argv_[0] = argv[0]; + argv_[1] = const_cast(nitf_path.c_str()); + //argv[1] + argv = argv_; + } + #endif + + + // create a parser and add our options to it + cli::ArgumentParser parser; + parser.setDescription("This program reads a SIDD/SICD along with a "\ + "directory of schemas, and returns any error messages "\ + "that may be contained in the DES XML"); + parser.addArgument("-f --log", "Specify a log file", cli::STORE, "log", + "FILE")->setDefault("console"); + parser.addArgument("-l --level", "Specify log level", cli::STORE, + "level", "LEVEL")->setChoices( + str::split("debug info warn error"))->setDefault( + "info"); + parser.addArgument("-s --schema", + "Specify a schema or directory of schemas", + cli::STORE, "schema", "FILE"); + parser.addArgument("input", "Input SICD/SIDD file or directory of files", cli::STORE, "input", + "INPUT", 1, 1); + + const std::unique_ptr + options(parser.parse(argc, (const char**) argv)); + + const std::string inputPath(options->get("input")); + std::vector inputPathnames = getPathnames(inputPath); + const std::string logFile(options->get("log")); + std::string level(options->get("level")); + std::vector schemaPaths; + getSchemaPaths(*options, "--schema", "schema", schemaPaths); + + // create an XML registry + // The reason to do this is to avoid adding XMLControlCreators to the + // XMLControlFactory singleton - this way has more fine-grained control + six::XMLControlRegistry xmlRegistry; + xmlRegistry.addCreator(); + xmlRegistry.addCreator(); + + str::upper(level); + str::trim(level); + std::unique_ptr log = + logging::setupLogger(fs::path(argv[0]).filename().string(), level, logFile); + + // this validates the DES of the input against the + // best available schema + six::NITFReadControl reader; + reader.setLogger(*log); + reader.setXMLControlRegistry(&xmlRegistry); + bool allValid = true; + for (size_t ii = 0; ii < inputPathnames.size(); ++ii) + { + const std::string& inputPathname(inputPathnames[ii]); + log->info(Ctxt("Reading " + inputPathname)); + std::unique_ptr data; + try + { + if (nitf::Reader::getNITFVersion(inputPathname) == + NITF_VER_UNKNOWN) + { + data = six::parseDataFromFile(xmlRegistry, + inputPathname, + schemaPaths, + *log); + allValid = allValid && runValidation(data, log); + } + else + { + reader.load(inputPathname, schemaPaths); + auto container = reader.getContainer(); + for (size_t jj = 0; jj < container->size(); ++jj) + { + data.reset(container->getData(jj)->clone()); + allValid = allValid && runValidation(data, log); + } + } + + } + catch (const six::DESValidationException& ex) + { + log->error(ex); + log->error(Ctxt("Unsuccessful: Please contact your product " + "vendor with these details!")); + allValid = false; + } + catch (const except::Exception& ex) + { + log->error(ex); + allValid = false; + } + } + + return allValid ? EXIT_SUCCESS : EXIT_FAILURE; +} +int main(int argc, char** argv) +{ + try + { + return main_(argc, argv); + } + catch (const std::exception& ex) + { + std::cerr << ex.what() << std::endl; + } + catch (const except::Exception& ex) + { + std::cerr << ex.toString() << std::endl; + return 1; + } + catch (...) + { + std::cerr << "Unknown exception\n"; + } + + return EXIT_FAILURE; } \ No newline at end of file diff --git a/six/modules/c++/samples/check_valid_six.dir/check_valid_six.vcxproj b/six/modules/c++/samples/check_valid_six.dir/check_valid_six.vcxproj index 7ce7e498dd..eb0e48d067 100644 --- a/six/modules/c++/samples/check_valid_six.dir/check_valid_six.vcxproj +++ b/six/modules/c++/samples/check_valid_six.dir/check_valid_six.vcxproj @@ -1,127 +1,127 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {f0e2c8ff-57d4-4331-9bd2-76ff01cb54eb} - checkvalidsix - 10.0 - - - - Application - true - v143 - - - Application - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include - Use - pch.h - pch.h - true - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - Console - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include - Use - pch.h - pch.h - true - true - AdvancedVectorExtensions2 - Speed - Guard - true - - - Console - true - true - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) - - - - - - Create - Create - - - - - - - - - - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {ddc587c2-53ba-44a9-94e7-07be52af3d0b} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {f0e2c8ff-57d4-4331-9bd2-76ff01cb54eb} + checkvalidsix + 10.0 + + + + Application + true + v143 + + + Application + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include + Use + pch.h + pch.h + true + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + Console + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include + Use + pch.h + pch.h + true + true + AdvancedVectorExtensions2 + Speed + Guard + true + + + Console + true + true + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) + + + + + + Create + Create + + + + + + + + + + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {ddc587c2-53ba-44a9-94e7-07be52af3d0b} + + + + + \ No newline at end of file diff --git a/six/modules/c++/samples/crop_sicd.dir/crop_sicd.vcxproj b/six/modules/c++/samples/crop_sicd.dir/crop_sicd.vcxproj index 51253b9f63..5b8ed9267e 100644 --- a/six/modules/c++/samples/crop_sicd.dir/crop_sicd.vcxproj +++ b/six/modules/c++/samples/crop_sicd.dir/crop_sicd.vcxproj @@ -1,127 +1,127 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC} - checkvalidsix - 10.0 - - - - Application - true - v143 - - - Application - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include - Use - pch.h - pch.h - true - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - Console - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) - - - - - Level3 - true - true - true - NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include - Use - pch.h - pch.h - true - true - AdvancedVectorExtensions2 - Speed - Guard - true - - - Console - true - true - true - $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) - - - - - - Create - Create - - - - - - - - - - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {ddc587c2-53ba-44a9-94e7-07be52af3d0b} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {7DCFF6D2-72E8-43E8-8085-35C1721E8DAC} + checkvalidsix + 10.0 + + + + Application + true + v143 + + + Application + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include + Use + pch.h + pch.h + true + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + Console + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) + + + + + Level3 + true + true + true + NDEBUG;_CONSOLE;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + $(SolutionDir)six\modules\c++\scene\include;$(SolutionDir)six\modules\c++\six\include;$(SolutionDir)six\modules\c++\six.sidd\include;$(SolutionDir)six\modules\c++\six.sicd\include;$(SolutionDir)six\modules\c++\cphd\include;$(SolutionDir)six\modules\c++\cphd03\include;$(SolutionDir)externals\nitro\modules\c\nrt\include;$(SolutionDir)externals\nitro\modules\c\nitf\include;$(SolutionDir)externals\nitro\modules\c++\nitf\include;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include + Use + pch.h + pch.h + true + true + AdvancedVectorExtensions2 + Speed + Guard + true + + + Console + true + true + true + $(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\lib;$(SolutionDir)out\install\$(Platform)-$(Configuration)\lib;%(AdditionalLibraryDirectories) + + + + + + Create + Create + + + + + + + + + + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {ddc587c2-53ba-44a9-94e7-07be52af3d0b} + + + + + \ No newline at end of file diff --git a/six/modules/c++/samples/utils.h b/six/modules/c++/samples/utils.h index 52e6cd4ced..a6c47df222 100644 --- a/six/modules/c++/samples/utils.h +++ b/six/modules/c++/samples/utils.h @@ -1,61 +1,61 @@ -#ifndef __SIX_TEST_UTILS_H__ -#define __SIX_TEST_UTILS_H__ - -#include -#include -#include - -/*! - * This function converts DMS corners into decimal degrees using NITRO, - * and then puts them into a lat-lon - */ -inline -six::LatLonCorners makeUpCornersFromDMS() -{ - int latTopDMS[3] = { 42, 17, 50 }; - int latBottomDMS[3] = { 42, 15, 14 }; - int lonEastDMS[3] = { -83, 42, 12 }; - int lonWestDMS[3] = { -83, 45, 44 }; - - const double latTopDecimal = - nitf::Utils::geographicToDecimal(latTopDMS[0], - latTopDMS[1], - latTopDMS[2]); - - const double latBottomDecimal = - nitf::Utils::geographicToDecimal(latBottomDMS[0], - latBottomDMS[1], - latBottomDMS[2]); - - const double lonEastDecimal = - nitf::Utils::geographicToDecimal(lonEastDMS[0], - lonEastDMS[1], - lonEastDMS[2]); - - const double lonWestDecimal = - nitf::Utils::geographicToDecimal(lonWestDMS[0], - lonWestDMS[1], - lonWestDMS[2]); - - six::LatLonCorners corners; - corners.upperLeft = six::LatLon(latTopDecimal, lonWestDecimal); - corners.upperRight = six::LatLon(latTopDecimal, lonEastDecimal); - corners.lowerRight = six::LatLon(latBottomDecimal, lonEastDecimal); - corners.lowerLeft = six::LatLon(latBottomDecimal, lonWestDecimal); - return corners; -} - -inline -void getSchemaPaths(const cli::Results& options, - const std::string& /*commandLineArg*/, - const std::string& cliArgName, - std::vector& schemaPaths) -{ - if(options.hasValue(cliArgName)) - { - schemaPaths.push_back(options.get(cliArgName)); - } - six::XMLControl::loadSchemaPaths(schemaPaths); -} - -#endif +#ifndef __SIX_TEST_UTILS_H__ +#define __SIX_TEST_UTILS_H__ + +#include +#include +#include + +/*! + * This function converts DMS corners into decimal degrees using NITRO, + * and then puts them into a lat-lon + */ +inline +six::LatLonCorners makeUpCornersFromDMS() +{ + int latTopDMS[3] = { 42, 17, 50 }; + int latBottomDMS[3] = { 42, 15, 14 }; + int lonEastDMS[3] = { -83, 42, 12 }; + int lonWestDMS[3] = { -83, 45, 44 }; + + const double latTopDecimal = + nitf::Utils::geographicToDecimal(latTopDMS[0], + latTopDMS[1], + latTopDMS[2]); + + const double latBottomDecimal = + nitf::Utils::geographicToDecimal(latBottomDMS[0], + latBottomDMS[1], + latBottomDMS[2]); + + const double lonEastDecimal = + nitf::Utils::geographicToDecimal(lonEastDMS[0], + lonEastDMS[1], + lonEastDMS[2]); + + const double lonWestDecimal = + nitf::Utils::geographicToDecimal(lonWestDMS[0], + lonWestDMS[1], + lonWestDMS[2]); + + six::LatLonCorners corners; + corners.upperLeft = six::LatLon(latTopDecimal, lonWestDecimal); + corners.upperRight = six::LatLon(latTopDecimal, lonEastDecimal); + corners.lowerRight = six::LatLon(latBottomDecimal, lonEastDecimal); + corners.lowerLeft = six::LatLon(latBottomDecimal, lonWestDecimal); + return corners; +} + +inline +void getSchemaPaths(const cli::Results& options, + const std::string& /*commandLineArg*/, + const std::string& cliArgName, + std::vector& schemaPaths) +{ + if(options.hasValue(cliArgName)) + { + schemaPaths.push_back(options.get(cliArgName)); + } + six::XMLControl::loadSchemaPaths(schemaPaths); +} + +#endif diff --git a/six/modules/c++/scene/include/scene/sys_Conf.h b/six/modules/c++/scene/include/scene/sys_Conf.h index 4828d27d57..46a06c3260 100644 --- a/six/modules/c++/scene/include/scene/sys_Conf.h +++ b/six/modules/c++/scene/include/scene/sys_Conf.h @@ -1,15 +1,15 @@ -#ifndef SIX_scene_sys_Conf_h_INCLUDED_ -#define SIX_scene_sys_Conf_h_INCLUDED_ -#pragma once - -#include -#include -#include -#include -#include -#include -#include - -#include - -#endif // SIX_scene_sys_Conf_h_INCLUDED_ +#ifndef SIX_scene_sys_Conf_h_INCLUDED_ +#define SIX_scene_sys_Conf_h_INCLUDED_ +#pragma once + +#include +#include +#include +#include +#include +#include +#include + +#include + +#endif // SIX_scene_sys_Conf_h_INCLUDED_ diff --git a/six/modules/c++/scene/scene.ruleset b/six/modules/c++/scene/scene.ruleset index 2a2edcef36..598fbdbd65 100644 --- a/six/modules/c++/scene/scene.ruleset +++ b/six/modules/c++/scene/scene.ruleset @@ -1,32 +1,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/six/modules/c++/scene/scene.vcxproj b/six/modules/c++/scene/scene.vcxproj index 52b4731862..62eb7adb3c 100644 --- a/six/modules/c++/scene/scene.vcxproj +++ b/six/modules/c++/scene/scene.vcxproj @@ -1,155 +1,155 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {1CFCDE59-6410-4037-95EB-B37D31E10820} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - true - v143 - - - - - - - - - - - - - - - true - ..\six.ruleset - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - true - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - - {8f357a19-799e-4971-850e-3f28485c130b} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {1CFCDE59-6410-4037-95EB-B37D31E10820} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + true + v143 + + + + + + + + + + + + + + + true + ..\six.ruleset + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + true + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + {8f357a19-799e-4971-850e-3f28485c130b} + + + + + \ No newline at end of file diff --git a/six/modules/c++/scene/scene.vcxproj.filters b/six/modules/c++/scene/scene.vcxproj.filters index ca51817fe9..61d0fcdcbc 100644 --- a/six/modules/c++/scene/scene.vcxproj.filters +++ b/six/modules/c++/scene/scene.vcxproj.filters @@ -1,123 +1,123 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + \ No newline at end of file diff --git a/six/modules/c++/scene/source/ProjectionPolynomialFitter.cpp b/six/modules/c++/scene/source/ProjectionPolynomialFitter.cpp index 233d7f8b93..10f3fb9654 100644 --- a/six/modules/c++/scene/source/ProjectionPolynomialFitter.cpp +++ b/six/modules/c++/scene/source/ProjectionPolynomialFitter.cpp @@ -1,489 +1,489 @@ -/* ========================================================================= - * This file is part of scene-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2014, MDA Information Systems LLC - * - * scene-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ - -#include - -#include -#include - -#undef min -#undef max - -namespace -{ -struct Shift final -{ - Shift(double shift) : - mShift(shift) - { - } - Shift(const Shift& other) = delete; - Shift& operator=(const Shift& other) = delete; - - inline double operator()(double input) const - { - return (input - mShift); - } - -private: - const double mShift; -}; -} - -namespace scene -{ -const size_t ProjectionPolynomialFitter::DEFAULTS_POINTS_1D = 10; - -ProjectionPolynomialFitter::ProjectionPolynomialFitter( - const ProjectionModel& projModel, - const GridECEFTransform& gridTransform, - const types::RowCol& outPixelStart, - const types::RowCol& outExtent, - size_t numPoints1D) : - mNumPoints1D(numPoints1D), - mOutputPlaneRows(numPoints1D, numPoints1D), - mOutputPlaneCols(numPoints1D, numPoints1D), - mSceneCoordinates(numPoints1D, - numPoints1D, - types::RowCol(0.0, 0.0)), - mTimeCOA(numPoints1D, numPoints1D) -{ - // Want to sample [outPixelStart, outPixelStart + outExtent) in the loop - // below. That is, we are marching through the portion of interest of the - // output grid in pixel space. In the case of multi-segment SICDs, we'll - // only sample our part of the grid defined by outPixelStart and - // outExtent. - const types::RowCol skip( - static_cast(outExtent.row - 1) / static_cast(mNumPoints1D - 1), - static_cast(outExtent.col - 1) / static_cast(mNumPoints1D - 1)); - - types::RowCol currentOffset(outPixelStart); - - for (size_t ii = 0; - ii < mNumPoints1D; - ++ii, currentOffset.row += skip.row) - { - currentOffset.col = outPixelStart.col; - - for (size_t jj = 0; - jj < mNumPoints1D; - ++jj, currentOffset.col += skip.col) - { - projectToSlantPlane(projModel, gridTransform, outPixelStart, - currentOffset, ii, jj); - } - } -} - -ProjectionPolynomialFitter::ProjectionPolynomialFitter( - const ProjectionModel& projModel, - const GridECEFTransform& gridTransform, - const types::RowCol& fullExtent, - const types::RowCol& outPixelStart, - const types::RowCol& /*outExtent*/, - const std::vector >& polygon, - size_t numPoints1D) : - mNumPoints1D(numPoints1D), - mOutputPlaneRows(numPoints1D, numPoints1D), - mOutputPlaneCols(numPoints1D, numPoints1D), - mSceneCoordinates(numPoints1D, - numPoints1D, - types::RowCol(0.0, 0.0)), - mTimeCOA(numPoints1D, numPoints1D) -{ - // Get bounding rectangle of output plane polygon. - double minRow = std::numeric_limits::max(); - double maxRow = -std::numeric_limits::max(); - double minCol = std::numeric_limits::max(); - double maxCol = -std::numeric_limits::max(); - - for (size_t ii = 0; ii < polygon.size(); ++ii) - { - minRow = std::min(minRow, polygon[ii].row); - maxRow = std::max(maxRow, polygon[ii].row); - minCol = std::min(minCol, polygon[ii].col); - maxCol = std::max(maxCol, polygon[ii].col); - } - - if (minRow > static_cast(fullExtent.row) || - maxRow < 0 || - minCol > static_cast(fullExtent.col) || - maxCol < 0) - { - throw except::Exception(Ctxt( - "Bounding rectangle is outside of output extent")); - } - - // Only interested in pixels inside the fullExtent. - minRow = std::max(minRow, 0.0); - minCol = std::max(minCol, 0.0); - maxRow = std::min(maxRow, static_cast(fullExtent.row) - 1); - maxCol = std::min(maxCol, static_cast(fullExtent.col) - 1); - - // Get size_t extent of the set of points. - const auto minRowI = gsl::narrow_cast(std::ceil(minRow)); - const auto minColI = gsl::narrow_cast(std::ceil(minCol)); - const auto maxRowI = gsl::narrow_cast(std::floor(maxRow)); - const auto maxColI = gsl::narrow_cast(std::floor(maxCol)); - - if (minRowI > maxRowI || minColI > maxColI) - { - throw except::Exception(Ctxt( - "Bounding rectangle has no area")); - } - - // The offset and extent are relative to the entire global output plane. - const types::RowCol boundingOffset(types::RowCol(minRowI, minColI)); - const types::RowCol boundingExtent(maxRowI - minRowI + 1, - maxColI - minColI + 1); - - // Get the PolygonMas. For each row of the polygon this will determine - // the first and last column of the row inside the convex hull of the - // polygon sent in. - const polygon::PolygonMask polygonMask(polygon, fullExtent); - - // Compute a delta in the row direction as if the entire bounding row - // extent will be covered by the point grid. - const double initialDeltaRow = - static_cast(boundingExtent.row - 1) / static_cast(numPoints1D - 1); - - // Scale factor for shrinking the row extent. - constexpr double shrinkFactor = 0.1; - - // Shring the row extent a bit. - const double deltaToRemove = initialDeltaRow * shrinkFactor; - - // Get the new row start and end values. - const size_t newStartRow = gsl::narrow_cast( - std::ceil(boundingOffset.row + deltaToRemove)); - const size_t newEndRow = gsl::narrow_cast( - std::floor(boundingOffset.row + static_cast(boundingExtent.row) - 1 - - deltaToRemove)); - - // Check the new row extent. - if (newStartRow > newEndRow) - { - throw except::Exception(Ctxt( - "New bounding rectangle has no area")); - } - - // Compute the row exent. - const size_t newExtentRow = (newEndRow - newStartRow + 1); - - // Compute the delta in the row direction for the new extent. - const double newDeltaRow = - static_cast(newExtentRow - 1) / - static_cast(numPoints1D - 1); - - double currentOffsetRow = static_cast(newStartRow); - for (size_t ii = 0; ii < numPoints1D; ++ii, currentOffsetRow += newDeltaRow) - { - const double currentRow = std::floor(currentOffsetRow); - const auto row = gsl::narrow_cast(currentRow); - - // Get the start column and number of columns inside the polygon row - // the current row. - const types::Range colRange = polygonMask.getRange(row); - - // Check that there are internal points. - if (colRange.mNumElements == 0) - { - throw except::Exception(Ctxt( - "Column range has no elements")); - } - - // Compute the delta in the column direction to cover the internal - // points. - const double newDeltaCol = - static_cast(colRange.mNumElements - 1) / - static_cast(numPoints1D - 1); - - double currentCol = static_cast(colRange.mStartElement); - for (size_t jj = 0; jj < numPoints1D; ++jj, currentCol += newDeltaCol) - { - const types::RowCol currentOffset(currentRow, currentCol); - projectToSlantPlane(projModel, gridTransform, outPixelStart, - currentOffset, ii, jj); - } - } -} - -void ProjectionPolynomialFitter::projectToSlantPlane( - const ProjectionModel& projModel, - const GridECEFTransform& gridTransform, - const types::RowCol& outPixelStart, - const types::RowCol& currentOffset, - size_t row, - size_t col) -{ - // Get the coordinate relative to the outPixelStart. - mOutputPlaneRows(row, col) = currentOffset.row - outPixelStart.row; - mOutputPlaneCols(row, col) = currentOffset.col - outPixelStart.col; - - // Find ECEF of the output plane pixel. - const scene::Vector3 ecef = - gridTransform.rowColToECEF(currentOffset); - - // Project ECEF coordinate into the slant plane and get meters from - // the slant plane scene center point. - double timeCOA(0.0); - mSceneCoordinates(row, col) = projModel.sceneToImage(ecef, &timeCOA); - mTimeCOA(row, col) = timeCOA; -} - -void ProjectionPolynomialFitter::getSlantPlaneSamples( - const types::RowCol& inPixelStart, - const types::RowCol& inSceneCenter, - const types::RowCol& interimSceneCenter, - const types::RowCol& interimSampleSpacing, - math::linear::Matrix2D& slantPlaneRows, - math::linear::Matrix2D& slantPlaneCols) const -{ - const types::RowCol ratio(interimSceneCenter / inSceneCenter); - - const types::RowCol aoiOffset(static_cast(inPixelStart.row) * ratio.row, - static_cast(inPixelStart.col) * ratio.col); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - // sceneCoord is in meters from the slant plane SCP - // So, divide by the sample spacing to get it in pixels, then - // offset by the slant plane SCP pixel. Need to further offset to - // take non-zero inPixelStart into account. - const types::RowCol sceneCoord(mSceneCoordinates(ii, jj)); - - slantPlaneRows(ii, jj) = - sceneCoord.row / interimSampleSpacing.row + - interimSceneCenter.row - aoiOffset.row; - - slantPlaneCols(ii, jj) = - sceneCoord.col / interimSampleSpacing.col + - interimSceneCenter.col - aoiOffset.col; - } - } -} - -void ProjectionPolynomialFitter::fitOutputToSlantPolynomials( - const types::RowCol& inPixelStart, - const types::RowCol& inSceneCenter, - const types::RowCol& interimSceneCenter, - const types::RowCol& interimSampleSpacing, - size_t polyOrderX, - size_t polyOrderY, - math::poly::TwoD& outputToSlantRow, - math::poly::TwoD& outputToSlantCol, - double* meanResidualErrorRow, - double* meanResidualErrorCol) const -{ - // Collect up slant plane pixel locations for the output plane samples we - // have - math::linear::Matrix2D slantPlaneRows(mNumPoints1D, mNumPoints1D); - math::linear::Matrix2D slantPlaneCols(mNumPoints1D, mNumPoints1D); - getSlantPlaneSamples(inPixelStart, - inSceneCenter, - interimSceneCenter, - interimSampleSpacing, - slantPlaneRows, - slantPlaneCols); - - // Now fit the polynomials - outputToSlantRow = math::poly::fit(mOutputPlaneRows, - mOutputPlaneCols, - slantPlaneRows, - polyOrderX, polyOrderY); - - outputToSlantCol = math::poly::fit(mOutputPlaneRows, - mOutputPlaneCols, - slantPlaneCols, - polyOrderX, polyOrderY); - - // Optionally report the residual error - if (meanResidualErrorRow || meanResidualErrorCol) - { - double errorSumRow(0.0); - double errorSumCol(0.0); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - const double row(mOutputPlaneRows(ii, jj)); - const double col(mOutputPlaneCols(ii, jj)); - - double diff = - slantPlaneRows(ii, jj) - outputToSlantRow(row, col); - errorSumRow += diff * diff; - - diff = slantPlaneCols(ii, jj) - outputToSlantCol(row, col); - errorSumCol += diff * diff; - } - } - - const auto numPoints = static_cast(mNumPoints1D * mNumPoints1D); - if (meanResidualErrorRow) - { - *meanResidualErrorRow = errorSumRow / numPoints; - } - if (meanResidualErrorCol) - { - *meanResidualErrorCol = errorSumCol / numPoints; - } - } -} - -void ProjectionPolynomialFitter::fitSlantToOutputPolynomials( - const types::RowCol& inPixelStart, - const types::RowCol& inSceneCenter, - const types::RowCol& interimSceneCenter, - const types::RowCol& interimSampleSpacing, - size_t polyOrderX, - size_t polyOrderY, - math::poly::TwoD& slantToOutputRow, - math::poly::TwoD& slantToOutputCol, - double* meanResidualErrorRow, - double* meanResidualErrorCol) const -{ - // Collect up slant plane pixel locations for the output plane samples we - // have - math::linear::Matrix2D slantPlaneRows(mNumPoints1D, mNumPoints1D); - math::linear::Matrix2D slantPlaneCols(mNumPoints1D, mNumPoints1D); - getSlantPlaneSamples(inPixelStart, - inSceneCenter, - interimSceneCenter, - interimSampleSpacing, - slantPlaneRows, - slantPlaneCols); - - // Now fit the polynomials - slantToOutputRow = math::poly::fit(slantPlaneRows, - slantPlaneCols, - mOutputPlaneRows, - polyOrderX, polyOrderY); - - slantToOutputCol = math::poly::fit(slantPlaneRows, - slantPlaneCols, - mOutputPlaneCols, - polyOrderX, polyOrderY); - - // Optionally report the residual error - if (meanResidualErrorRow || meanResidualErrorCol) - { - double errorSumRow(0.0); - double errorSumCol(0.0); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - const double row(slantPlaneRows(ii, jj)); - const double col(slantPlaneCols(ii, jj)); - - double diff = - mOutputPlaneRows(ii, jj) - slantToOutputRow(row, col); - errorSumRow += diff * diff; - - diff = mOutputPlaneCols(ii, jj) - slantToOutputCol(row, col); - errorSumCol += diff * diff; - } - } - - const auto numPoints = static_cast(mNumPoints1D * mNumPoints1D); - if (meanResidualErrorRow) - { - *meanResidualErrorRow = errorSumRow / numPoints; - } - if (meanResidualErrorCol) - { - *meanResidualErrorCol = errorSumCol / numPoints; - } - } -} - -void ProjectionPolynomialFitter::fitTimeCOAPolynomial( - const types::RowCol& outSceneCenter, - const types::RowCol& outSampleSpacing, - size_t polyOrderX, - size_t polyOrderY, - math::poly::TwoD& timeCOAPoly, - double* meanResidualError) const -{ - math::linear::Matrix2D rowMapping(mNumPoints1D, mNumPoints1D); - math::linear::Matrix2D colMapping(mNumPoints1D, mNumPoints1D); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - // Need to map output plane pixels to meters from the output - // plane SCP - rowMapping(ii, jj) = - (mOutputPlaneRows(ii,jj) - outSceneCenter.row) * - outSampleSpacing.row; - - colMapping(ii, jj) = - (mOutputPlaneCols(ii,jj) - outSceneCenter.col) * - outSampleSpacing.col; - } - } - - // Now fit the polynomial - timeCOAPoly = math::poly::fit(rowMapping, colMapping, mTimeCOA, - polyOrderX, polyOrderY); - - // Optionally report the residual error - if (meanResidualError) - { - double errorSum(0.0); - - for (size_t ii = 0; ii < mNumPoints1D; ++ii) - { - for (size_t jj = 0; jj < mNumPoints1D; ++jj) - { - const double row(rowMapping(ii, jj)); - const double col(colMapping(ii, jj)); - - const double diff = mTimeCOA(ii, jj) - timeCOAPoly(row, col); - errorSum += diff * diff; - } - } - - *meanResidualError = errorSum / static_cast(mNumPoints1D * mNumPoints1D); - } -} - -void ProjectionPolynomialFitter::fitPixelBasedTimeCOAPolynomial( - const types::RowCol& outPixelShift, - size_t polyOrderX, - size_t polyOrderY, - math::poly::TwoD& timeCOAPoly, - double* meanResidualError) const -{ - fitPixelBasedTimeCOAPolynomial(Shift(outPixelShift.row), - Shift(outPixelShift.col), - polyOrderX, - polyOrderY, - timeCOAPoly, - meanResidualError); -} -} +/* ========================================================================= + * This file is part of scene-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * scene-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ + +#include + +#include +#include + +#undef min +#undef max + +namespace +{ +struct Shift final +{ + Shift(double shift) : + mShift(shift) + { + } + Shift(const Shift& other) = delete; + Shift& operator=(const Shift& other) = delete; + + inline double operator()(double input) const + { + return (input - mShift); + } + +private: + const double mShift; +}; +} + +namespace scene +{ +const size_t ProjectionPolynomialFitter::DEFAULTS_POINTS_1D = 10; + +ProjectionPolynomialFitter::ProjectionPolynomialFitter( + const ProjectionModel& projModel, + const GridECEFTransform& gridTransform, + const types::RowCol& outPixelStart, + const types::RowCol& outExtent, + size_t numPoints1D) : + mNumPoints1D(numPoints1D), + mOutputPlaneRows(numPoints1D, numPoints1D), + mOutputPlaneCols(numPoints1D, numPoints1D), + mSceneCoordinates(numPoints1D, + numPoints1D, + types::RowCol(0.0, 0.0)), + mTimeCOA(numPoints1D, numPoints1D) +{ + // Want to sample [outPixelStart, outPixelStart + outExtent) in the loop + // below. That is, we are marching through the portion of interest of the + // output grid in pixel space. In the case of multi-segment SICDs, we'll + // only sample our part of the grid defined by outPixelStart and + // outExtent. + const types::RowCol skip( + static_cast(outExtent.row - 1) / static_cast(mNumPoints1D - 1), + static_cast(outExtent.col - 1) / static_cast(mNumPoints1D - 1)); + + types::RowCol currentOffset(outPixelStart); + + for (size_t ii = 0; + ii < mNumPoints1D; + ++ii, currentOffset.row += skip.row) + { + currentOffset.col = outPixelStart.col; + + for (size_t jj = 0; + jj < mNumPoints1D; + ++jj, currentOffset.col += skip.col) + { + projectToSlantPlane(projModel, gridTransform, outPixelStart, + currentOffset, ii, jj); + } + } +} + +ProjectionPolynomialFitter::ProjectionPolynomialFitter( + const ProjectionModel& projModel, + const GridECEFTransform& gridTransform, + const types::RowCol& fullExtent, + const types::RowCol& outPixelStart, + const types::RowCol& /*outExtent*/, + const std::vector >& polygon, + size_t numPoints1D) : + mNumPoints1D(numPoints1D), + mOutputPlaneRows(numPoints1D, numPoints1D), + mOutputPlaneCols(numPoints1D, numPoints1D), + mSceneCoordinates(numPoints1D, + numPoints1D, + types::RowCol(0.0, 0.0)), + mTimeCOA(numPoints1D, numPoints1D) +{ + // Get bounding rectangle of output plane polygon. + double minRow = std::numeric_limits::max(); + double maxRow = -std::numeric_limits::max(); + double minCol = std::numeric_limits::max(); + double maxCol = -std::numeric_limits::max(); + + for (size_t ii = 0; ii < polygon.size(); ++ii) + { + minRow = std::min(minRow, polygon[ii].row); + maxRow = std::max(maxRow, polygon[ii].row); + minCol = std::min(minCol, polygon[ii].col); + maxCol = std::max(maxCol, polygon[ii].col); + } + + if (minRow > static_cast(fullExtent.row) || + maxRow < 0 || + minCol > static_cast(fullExtent.col) || + maxCol < 0) + { + throw except::Exception(Ctxt( + "Bounding rectangle is outside of output extent")); + } + + // Only interested in pixels inside the fullExtent. + minRow = std::max(minRow, 0.0); + minCol = std::max(minCol, 0.0); + maxRow = std::min(maxRow, static_cast(fullExtent.row) - 1); + maxCol = std::min(maxCol, static_cast(fullExtent.col) - 1); + + // Get size_t extent of the set of points. + const auto minRowI = gsl::narrow_cast(std::ceil(minRow)); + const auto minColI = gsl::narrow_cast(std::ceil(minCol)); + const auto maxRowI = gsl::narrow_cast(std::floor(maxRow)); + const auto maxColI = gsl::narrow_cast(std::floor(maxCol)); + + if (minRowI > maxRowI || minColI > maxColI) + { + throw except::Exception(Ctxt( + "Bounding rectangle has no area")); + } + + // The offset and extent are relative to the entire global output plane. + const types::RowCol boundingOffset(types::RowCol(minRowI, minColI)); + const types::RowCol boundingExtent(maxRowI - minRowI + 1, + maxColI - minColI + 1); + + // Get the PolygonMas. For each row of the polygon this will determine + // the first and last column of the row inside the convex hull of the + // polygon sent in. + const polygon::PolygonMask polygonMask(polygon, fullExtent); + + // Compute a delta in the row direction as if the entire bounding row + // extent will be covered by the point grid. + const double initialDeltaRow = + static_cast(boundingExtent.row - 1) / static_cast(numPoints1D - 1); + + // Scale factor for shrinking the row extent. + constexpr double shrinkFactor = 0.1; + + // Shring the row extent a bit. + const double deltaToRemove = initialDeltaRow * shrinkFactor; + + // Get the new row start and end values. + const size_t newStartRow = gsl::narrow_cast( + std::ceil(boundingOffset.row + deltaToRemove)); + const size_t newEndRow = gsl::narrow_cast( + std::floor(boundingOffset.row + static_cast(boundingExtent.row) - 1 - + deltaToRemove)); + + // Check the new row extent. + if (newStartRow > newEndRow) + { + throw except::Exception(Ctxt( + "New bounding rectangle has no area")); + } + + // Compute the row exent. + const size_t newExtentRow = (newEndRow - newStartRow + 1); + + // Compute the delta in the row direction for the new extent. + const double newDeltaRow = + static_cast(newExtentRow - 1) / + static_cast(numPoints1D - 1); + + double currentOffsetRow = static_cast(newStartRow); + for (size_t ii = 0; ii < numPoints1D; ++ii, currentOffsetRow += newDeltaRow) + { + const double currentRow = std::floor(currentOffsetRow); + const auto row = gsl::narrow_cast(currentRow); + + // Get the start column and number of columns inside the polygon row + // the current row. + const types::Range colRange = polygonMask.getRange(row); + + // Check that there are internal points. + if (colRange.mNumElements == 0) + { + throw except::Exception(Ctxt( + "Column range has no elements")); + } + + // Compute the delta in the column direction to cover the internal + // points. + const double newDeltaCol = + static_cast(colRange.mNumElements - 1) / + static_cast(numPoints1D - 1); + + double currentCol = static_cast(colRange.mStartElement); + for (size_t jj = 0; jj < numPoints1D; ++jj, currentCol += newDeltaCol) + { + const types::RowCol currentOffset(currentRow, currentCol); + projectToSlantPlane(projModel, gridTransform, outPixelStart, + currentOffset, ii, jj); + } + } +} + +void ProjectionPolynomialFitter::projectToSlantPlane( + const ProjectionModel& projModel, + const GridECEFTransform& gridTransform, + const types::RowCol& outPixelStart, + const types::RowCol& currentOffset, + size_t row, + size_t col) +{ + // Get the coordinate relative to the outPixelStart. + mOutputPlaneRows(row, col) = currentOffset.row - outPixelStart.row; + mOutputPlaneCols(row, col) = currentOffset.col - outPixelStart.col; + + // Find ECEF of the output plane pixel. + const scene::Vector3 ecef = + gridTransform.rowColToECEF(currentOffset); + + // Project ECEF coordinate into the slant plane and get meters from + // the slant plane scene center point. + double timeCOA(0.0); + mSceneCoordinates(row, col) = projModel.sceneToImage(ecef, &timeCOA); + mTimeCOA(row, col) = timeCOA; +} + +void ProjectionPolynomialFitter::getSlantPlaneSamples( + const types::RowCol& inPixelStart, + const types::RowCol& inSceneCenter, + const types::RowCol& interimSceneCenter, + const types::RowCol& interimSampleSpacing, + math::linear::Matrix2D& slantPlaneRows, + math::linear::Matrix2D& slantPlaneCols) const +{ + const types::RowCol ratio(interimSceneCenter / inSceneCenter); + + const types::RowCol aoiOffset(static_cast(inPixelStart.row) * ratio.row, + static_cast(inPixelStart.col) * ratio.col); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + // sceneCoord is in meters from the slant plane SCP + // So, divide by the sample spacing to get it in pixels, then + // offset by the slant plane SCP pixel. Need to further offset to + // take non-zero inPixelStart into account. + const types::RowCol sceneCoord(mSceneCoordinates(ii, jj)); + + slantPlaneRows(ii, jj) = + sceneCoord.row / interimSampleSpacing.row + + interimSceneCenter.row - aoiOffset.row; + + slantPlaneCols(ii, jj) = + sceneCoord.col / interimSampleSpacing.col + + interimSceneCenter.col - aoiOffset.col; + } + } +} + +void ProjectionPolynomialFitter::fitOutputToSlantPolynomials( + const types::RowCol& inPixelStart, + const types::RowCol& inSceneCenter, + const types::RowCol& interimSceneCenter, + const types::RowCol& interimSampleSpacing, + size_t polyOrderX, + size_t polyOrderY, + math::poly::TwoD& outputToSlantRow, + math::poly::TwoD& outputToSlantCol, + double* meanResidualErrorRow, + double* meanResidualErrorCol) const +{ + // Collect up slant plane pixel locations for the output plane samples we + // have + math::linear::Matrix2D slantPlaneRows(mNumPoints1D, mNumPoints1D); + math::linear::Matrix2D slantPlaneCols(mNumPoints1D, mNumPoints1D); + getSlantPlaneSamples(inPixelStart, + inSceneCenter, + interimSceneCenter, + interimSampleSpacing, + slantPlaneRows, + slantPlaneCols); + + // Now fit the polynomials + outputToSlantRow = math::poly::fit(mOutputPlaneRows, + mOutputPlaneCols, + slantPlaneRows, + polyOrderX, polyOrderY); + + outputToSlantCol = math::poly::fit(mOutputPlaneRows, + mOutputPlaneCols, + slantPlaneCols, + polyOrderX, polyOrderY); + + // Optionally report the residual error + if (meanResidualErrorRow || meanResidualErrorCol) + { + double errorSumRow(0.0); + double errorSumCol(0.0); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + const double row(mOutputPlaneRows(ii, jj)); + const double col(mOutputPlaneCols(ii, jj)); + + double diff = + slantPlaneRows(ii, jj) - outputToSlantRow(row, col); + errorSumRow += diff * diff; + + diff = slantPlaneCols(ii, jj) - outputToSlantCol(row, col); + errorSumCol += diff * diff; + } + } + + const auto numPoints = static_cast(mNumPoints1D * mNumPoints1D); + if (meanResidualErrorRow) + { + *meanResidualErrorRow = errorSumRow / numPoints; + } + if (meanResidualErrorCol) + { + *meanResidualErrorCol = errorSumCol / numPoints; + } + } +} + +void ProjectionPolynomialFitter::fitSlantToOutputPolynomials( + const types::RowCol& inPixelStart, + const types::RowCol& inSceneCenter, + const types::RowCol& interimSceneCenter, + const types::RowCol& interimSampleSpacing, + size_t polyOrderX, + size_t polyOrderY, + math::poly::TwoD& slantToOutputRow, + math::poly::TwoD& slantToOutputCol, + double* meanResidualErrorRow, + double* meanResidualErrorCol) const +{ + // Collect up slant plane pixel locations for the output plane samples we + // have + math::linear::Matrix2D slantPlaneRows(mNumPoints1D, mNumPoints1D); + math::linear::Matrix2D slantPlaneCols(mNumPoints1D, mNumPoints1D); + getSlantPlaneSamples(inPixelStart, + inSceneCenter, + interimSceneCenter, + interimSampleSpacing, + slantPlaneRows, + slantPlaneCols); + + // Now fit the polynomials + slantToOutputRow = math::poly::fit(slantPlaneRows, + slantPlaneCols, + mOutputPlaneRows, + polyOrderX, polyOrderY); + + slantToOutputCol = math::poly::fit(slantPlaneRows, + slantPlaneCols, + mOutputPlaneCols, + polyOrderX, polyOrderY); + + // Optionally report the residual error + if (meanResidualErrorRow || meanResidualErrorCol) + { + double errorSumRow(0.0); + double errorSumCol(0.0); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + const double row(slantPlaneRows(ii, jj)); + const double col(slantPlaneCols(ii, jj)); + + double diff = + mOutputPlaneRows(ii, jj) - slantToOutputRow(row, col); + errorSumRow += diff * diff; + + diff = mOutputPlaneCols(ii, jj) - slantToOutputCol(row, col); + errorSumCol += diff * diff; + } + } + + const auto numPoints = static_cast(mNumPoints1D * mNumPoints1D); + if (meanResidualErrorRow) + { + *meanResidualErrorRow = errorSumRow / numPoints; + } + if (meanResidualErrorCol) + { + *meanResidualErrorCol = errorSumCol / numPoints; + } + } +} + +void ProjectionPolynomialFitter::fitTimeCOAPolynomial( + const types::RowCol& outSceneCenter, + const types::RowCol& outSampleSpacing, + size_t polyOrderX, + size_t polyOrderY, + math::poly::TwoD& timeCOAPoly, + double* meanResidualError) const +{ + math::linear::Matrix2D rowMapping(mNumPoints1D, mNumPoints1D); + math::linear::Matrix2D colMapping(mNumPoints1D, mNumPoints1D); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + // Need to map output plane pixels to meters from the output + // plane SCP + rowMapping(ii, jj) = + (mOutputPlaneRows(ii,jj) - outSceneCenter.row) * + outSampleSpacing.row; + + colMapping(ii, jj) = + (mOutputPlaneCols(ii,jj) - outSceneCenter.col) * + outSampleSpacing.col; + } + } + + // Now fit the polynomial + timeCOAPoly = math::poly::fit(rowMapping, colMapping, mTimeCOA, + polyOrderX, polyOrderY); + + // Optionally report the residual error + if (meanResidualError) + { + double errorSum(0.0); + + for (size_t ii = 0; ii < mNumPoints1D; ++ii) + { + for (size_t jj = 0; jj < mNumPoints1D; ++jj) + { + const double row(rowMapping(ii, jj)); + const double col(colMapping(ii, jj)); + + const double diff = mTimeCOA(ii, jj) - timeCOAPoly(row, col); + errorSum += diff * diff; + } + } + + *meanResidualError = errorSum / static_cast(mNumPoints1D * mNumPoints1D); + } +} + +void ProjectionPolynomialFitter::fitPixelBasedTimeCOAPolynomial( + const types::RowCol& outPixelShift, + size_t polyOrderX, + size_t polyOrderY, + math::poly::TwoD& timeCOAPoly, + double* meanResidualError) const +{ + fitPixelBasedTimeCOAPolynomial(Shift(outPixelShift.row), + Shift(outPixelShift.col), + polyOrderX, + polyOrderY, + timeCOAPoly, + meanResidualError); +} +} diff --git a/six/modules/c++/six.convert/six.convert.vcxproj b/six/modules/c++/six.convert/six.convert.vcxproj index 103c628b7a..f67abbbe44 100644 --- a/six/modules/c++/six.convert/six.convert.vcxproj +++ b/six/modules/c++/six.convert/six.convert.vcxproj @@ -1,138 +1,138 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - true - - - - - - - - - - - - - - - true - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - true - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - - - - - - - - - Create - Create - - - - - - - - {8f357a19-799e-4971-850e-3f28485c130b} - - - {1cfcde59-6410-4037-95eb-b37d31e10820} - - - {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {DB4ECC28-A862-4CF4-8A03-69B3CC0C4E8B} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + v143 + true + + + + + + + + + + + + + + + true + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + true + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..\six.sicd\include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + + + + + + + + + Create + Create + + + + + + + + {8f357a19-799e-4971-850e-3f28485c130b} + + + {1cfcde59-6410-4037-95eb-b37d31e10820} + + + {34ac2314-fbd1-42ad-aaf4-0cebc6bf737e} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + \ No newline at end of file diff --git a/six/modules/c++/six.ruleset b/six/modules/c++/six.ruleset index 5f1780c77b..f3bf8df8a1 100644 --- a/six/modules/c++/six.ruleset +++ b/six/modules/c++/six.ruleset @@ -1,32 +1,32 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/six/modules/c++/six.sicd/include/six/sicd/ImageCreation.h b/six/modules/c++/six.sicd/include/six/sicd/ImageCreation.h index a632c4bc11..c368953555 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/ImageCreation.h +++ b/six/modules/c++/six.sicd/include/six/sicd/ImageCreation.h @@ -19,67 +19,67 @@ * see . * */ -#ifndef __SIX_IMAGE_CREATION_H__ -#define __SIX_IMAGE_CREATION_H__ - -#include "six/Types.h" - -namespace six -{ -namespace sicd -{ -/*! - * \struct ImageCreation - * \brief Contains SICD ImageCreation parameters - * - * The ImageCreation block is the first sub-block under the 'SICD' - * tag. It is optional altogether, and contains, information about - * the image creation (and processing). - */ -struct ImageCreation -{ - /*! - * (Optional) The name and version of the application used to - * create the image - */ - std::string application; - - /*! - * (Optional) Date and time that the image creation application - * processed the image (UTC) - */ - DateTime dateTime; - - /*! - * (Optional) The creation site of this SICD product - */ - std::string site; - - /*! - * (Optional) Identifies what profile was used to create this - * SICD product - */ - std::string profile; - - ImageCreation* clone() const - { - return new ImageCreation(*this); - } - - //! Equality operator - bool operator==(const ImageCreation& rhs) const - { - return (application == rhs.application && - dateTime == rhs.dateTime && site == rhs.site && - profile == rhs.profile); - } - bool operator!=(const ImageCreation& rhs) const - { - return !(*this == rhs); - } -}; - -} -} -#endif +#ifndef __SIX_IMAGE_CREATION_H__ +#define __SIX_IMAGE_CREATION_H__ + +#include "six/Types.h" + +namespace six +{ +namespace sicd +{ +/*! + * \struct ImageCreation + * \brief Contains SICD ImageCreation parameters + * + * The ImageCreation block is the first sub-block under the 'SICD' + * tag. It is optional altogether, and contains, information about + * the image creation (and processing). + */ +struct ImageCreation +{ + /*! + * (Optional) The name and version of the application used to + * create the image + */ + std::string application; + + /*! + * (Optional) Date and time that the image creation application + * processed the image (UTC) + */ + DateTime dateTime; + + /*! + * (Optional) The creation site of this SICD product + */ + std::string site; + + /*! + * (Optional) Identifies what profile was used to create this + * SICD product + */ + std::string profile; + + ImageCreation* clone() const + { + return new ImageCreation(*this); + } + + //! Equality operator + bool operator==(const ImageCreation& rhs) const + { + return (application == rhs.application && + dateTime == rhs.dateTime && site == rhs.site && + profile == rhs.profile); + } + bool operator!=(const ImageCreation& rhs) const + { + return !(*this == rhs); + } +}; + +} +} +#endif diff --git a/six/modules/c++/six.sicd/include/six/sicd/NITFReadComplexXMLControl.h b/six/modules/c++/six.sicd/include/six/sicd/NITFReadComplexXMLControl.h index 97f8ee03fc..331d49b3d0 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/NITFReadComplexXMLControl.h +++ b/six/modules/c++/six.sicd/include/six/sicd/NITFReadComplexXMLControl.h @@ -1,107 +1,107 @@ -/* ========================================================================= - * This file is part of six.sicd-c++ - * ========================================================================= - * - * (C) Copyright 2021 Maxar Technologies, Inc. - * - * six.sicd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#ifndef SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ -#define SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ -#pragma once - -#include -#include -#include -#include - -#include -#include - -#include "six/XMLControlFactory.h" -#include "six/NITFReadControl.h" -#include "six/Region.h" -#include "six/sicd/ComplexData.h" -#include "six/sicd/SICDMesh.h" - -namespace six -{ - namespace sicd - { - class NITFReadComplexXMLControl final - { - six::XMLControlRegistry xmlRegistry; - six::NITFReadControl reader; - - public: - NITFReadComplexXMLControl(); - ~NITFReadComplexXMLControl() = default; - NITFReadComplexXMLControl(const NITFReadComplexXMLControl&) = delete; - NITFReadComplexXMLControl& operator=(const NITFReadComplexXMLControl&) = delete; - NITFReadComplexXMLControl(NITFReadComplexXMLControl&&) = delete; - NITFReadComplexXMLControl& operator=(NITFReadComplexXMLControl&&) = delete; - - template - void addCreator() - { - xmlRegistry.addCreator(); - reader.setXMLControlRegistry(&xmlRegistry); - } - - const six::NITFReadControl& NITFReadControl() const { return reader; } - six::NITFReadControl& NITFReadControl() { return reader; } - - void load(const std::string& fromFile, const std::vector* pSchemaPaths); - void load(const std::filesystem::path& fromFile, const std::vector* pSchemaPaths); - template - void load(const TPath& fromFile, const std::vector& schemaPaths) - { - load(fromFile, &schemaPaths); - } - void load(const std::filesystem::path& fromFile) - { - load(fromFile, nullptr /*schemaPaths*/); - } - - void load(io::FileInputStream&, const std::vector* pSchemaPaths); - void load(io::FileInputStream&, const std::vector* pSchemaPaths); - template - void load(io::FileInputStream& fis, const std::vector& schemaPaths) - { - load(fis, &schemaPaths); - } - - std::shared_ptr getContainer() const; - std::shared_ptr getContainer(); - - std::unique_ptr getComplexData(); - - std::vector getWidebandData(const ComplexData&); - void getWidebandData(const ComplexData&, const types::RowCol& offset, const types::RowCol& extent, - six::zfloat* buffer); - - void getMeshes(std::unique_ptr&, std::unique_ptr&) const; - - void setXMLControlRegistry(); - void setLogger(); - - void interleaved(Region& region); - std::vector interleaved(); - }; - } -} - +/* ========================================================================= + * This file is part of six.sicd-c++ + * ========================================================================= + * + * (C) Copyright 2021 Maxar Technologies, Inc. + * + * six.sicd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#ifndef SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ +#define SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ +#pragma once + +#include +#include +#include +#include + +#include +#include + +#include "six/XMLControlFactory.h" +#include "six/NITFReadControl.h" +#include "six/Region.h" +#include "six/sicd/ComplexData.h" +#include "six/sicd/SICDMesh.h" + +namespace six +{ + namespace sicd + { + class NITFReadComplexXMLControl final + { + six::XMLControlRegistry xmlRegistry; + six::NITFReadControl reader; + + public: + NITFReadComplexXMLControl(); + ~NITFReadComplexXMLControl() = default; + NITFReadComplexXMLControl(const NITFReadComplexXMLControl&) = delete; + NITFReadComplexXMLControl& operator=(const NITFReadComplexXMLControl&) = delete; + NITFReadComplexXMLControl(NITFReadComplexXMLControl&&) = delete; + NITFReadComplexXMLControl& operator=(NITFReadComplexXMLControl&&) = delete; + + template + void addCreator() + { + xmlRegistry.addCreator(); + reader.setXMLControlRegistry(&xmlRegistry); + } + + const six::NITFReadControl& NITFReadControl() const { return reader; } + six::NITFReadControl& NITFReadControl() { return reader; } + + void load(const std::string& fromFile, const std::vector* pSchemaPaths); + void load(const std::filesystem::path& fromFile, const std::vector* pSchemaPaths); + template + void load(const TPath& fromFile, const std::vector& schemaPaths) + { + load(fromFile, &schemaPaths); + } + void load(const std::filesystem::path& fromFile) + { + load(fromFile, nullptr /*schemaPaths*/); + } + + void load(io::FileInputStream&, const std::vector* pSchemaPaths); + void load(io::FileInputStream&, const std::vector* pSchemaPaths); + template + void load(io::FileInputStream& fis, const std::vector& schemaPaths) + { + load(fis, &schemaPaths); + } + + std::shared_ptr getContainer() const; + std::shared_ptr getContainer(); + + std::unique_ptr getComplexData(); + + std::vector getWidebandData(const ComplexData&); + void getWidebandData(const ComplexData&, const types::RowCol& offset, const types::RowCol& extent, + six::zfloat* buffer); + + void getMeshes(std::unique_ptr&, std::unique_ptr&) const; + + void setXMLControlRegistry(); + void setLogger(); + + void interleaved(Region& region); + std::vector interleaved(); + }; + } +} + #endif // SIX_sicd_NITFReadComplexXMLControl_h_INCLUDED_ \ No newline at end of file diff --git a/six/modules/c++/six.sicd/include/six/sicd/PFA.h b/six/modules/c++/six.sicd/include/six/sicd/PFA.h index bd44dca4db..a9ea0dc513 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/PFA.h +++ b/six/modules/c++/six.sicd/include/six/sicd/PFA.h @@ -19,134 +19,134 @@ * see . * */ -#ifndef __SIX_PFA_H__ -#define __SIX_PFA_H__ - -#include "logging/Logger.h" -#include "six/Types.h" -#include "six/Init.h" -#include "six/Parameter.h" +#ifndef __SIX_PFA_H__ +#define __SIX_PFA_H__ + +#include "logging/Logger.h" +#include "six/Types.h" +#include "six/Init.h" +#include "six/Parameter.h" #include "six/sicd/GeoData.h" #include "six/sicd/Position.h" #include "six/sicd/SCPCOA.h" - -namespace six -{ -namespace sicd -{ -struct Grid; -/*! - * \struct SlowTimeDeskew - * \brief SICD STDeskew - * - * Parameters to describe image domain slow time - * deskew processing. Name changed for API consistency - */ -struct SlowTimeDeskew -{ - //! Constructor - SlowTimeDeskew(); - - //! Was slow time deskew phase function applied? - BooleanType applied; - - //! Slow time deskew phase function to perform the slow-time/Kaz - //! shift. 2D poly function of image range coord and az coord - Poly2D slowTimeDeskewPhasePoly; - - //! Equality operator - bool operator==(const SlowTimeDeskew& rhs) const - { - return (applied == rhs.applied && - slowTimeDeskewPhasePoly == rhs.slowTimeDeskewPhasePoly); - } - - bool operator!=(const SlowTimeDeskew& rhs) const - { - return !(*this == rhs); - } -}; - -/*! - * \struct PFA - * \brief SICD Polar format algorithm block - * - * Parameters used when the image is formed using the polar format - * algorithm (imageFormationAlgorithm = PFA). - * - * \note This is currently limited to a one item choice in SICD, - * which would make it hard to do anything else - */ -struct PFA -{ - //! Constructor, nothing defined - PFA(); - - /*! - * SICD FPN parameter. - * Focus plane normal (ECEF), pointing away from center of earth - */ - Vector3 focusPlaneNormal; - - /*! - * SICD IPN parameter. - * Image formation plane normal pointing away from center of earth - */ - Vector3 imagePlaneNormal; - - /*! - * SICD PolarAngRefTime (name change for API consistency) - * Polar image formation ref. time. Polar angle = 0 at the ref time - * Measured relative to collect start. Ref time is typically set - * to SCP COA time but may be different - */ - double polarAngleRefTime; - - /*! - * SICD PolarAngPoly (name change for API consistency) - * Poly that yields polar angle in radians as a function of slow time - * IOW, Time (sec) -> Polar angle (radians) - */ - Poly1D polarAnglePoly; - - /*! - * SICD SpatialFreqSFPoly parametr (name change for API consistency) - * Poly that yields the spatial frequency scale factor as a function - * of Polar angle - * Polar angle (radians) -> KSF - */ - Poly1D spatialFrequencyScaleFactorPoly; - - //! Minimum range spatial freq (Krg) output from polar->rect resampling - double krg1; - - //! Maximum range spatial freq (Krg) output from polar->rect resampling - double krg2; - - //! Minimum az spatial freq output from polar->rect resampling - double kaz1; - - //! Minimum az spatial freq output from polar->rect resampling - double kaz2; - - //! SICD STDeskew parameter - mem::ScopedCopyablePtr slowTimeDeskew; - - //! Equality operator - bool operator==(const PFA& rhs) const; - bool operator!=(const PFA& rhs) const - { - return !(*this == rhs); - } - - void fillDerivedFields(const Position& position); - void fillDefaultFields(const GeoData& geoData, const Grid&, - const SCPCOA& scpcoa); - - bool validate(const SCPCOA& scpcoa, logging::Logger& log); -}; - -} -} -#endif + +namespace six +{ +namespace sicd +{ +struct Grid; +/*! + * \struct SlowTimeDeskew + * \brief SICD STDeskew + * + * Parameters to describe image domain slow time + * deskew processing. Name changed for API consistency + */ +struct SlowTimeDeskew +{ + //! Constructor + SlowTimeDeskew(); + + //! Was slow time deskew phase function applied? + BooleanType applied; + + //! Slow time deskew phase function to perform the slow-time/Kaz + //! shift. 2D poly function of image range coord and az coord + Poly2D slowTimeDeskewPhasePoly; + + //! Equality operator + bool operator==(const SlowTimeDeskew& rhs) const + { + return (applied == rhs.applied && + slowTimeDeskewPhasePoly == rhs.slowTimeDeskewPhasePoly); + } + + bool operator!=(const SlowTimeDeskew& rhs) const + { + return !(*this == rhs); + } +}; + +/*! + * \struct PFA + * \brief SICD Polar format algorithm block + * + * Parameters used when the image is formed using the polar format + * algorithm (imageFormationAlgorithm = PFA). + * + * \note This is currently limited to a one item choice in SICD, + * which would make it hard to do anything else + */ +struct PFA +{ + //! Constructor, nothing defined + PFA(); + + /*! + * SICD FPN parameter. + * Focus plane normal (ECEF), pointing away from center of earth + */ + Vector3 focusPlaneNormal; + + /*! + * SICD IPN parameter. + * Image formation plane normal pointing away from center of earth + */ + Vector3 imagePlaneNormal; + + /*! + * SICD PolarAngRefTime (name change for API consistency) + * Polar image formation ref. time. Polar angle = 0 at the ref time + * Measured relative to collect start. Ref time is typically set + * to SCP COA time but may be different + */ + double polarAngleRefTime; + + /*! + * SICD PolarAngPoly (name change for API consistency) + * Poly that yields polar angle in radians as a function of slow time + * IOW, Time (sec) -> Polar angle (radians) + */ + Poly1D polarAnglePoly; + + /*! + * SICD SpatialFreqSFPoly parametr (name change for API consistency) + * Poly that yields the spatial frequency scale factor as a function + * of Polar angle + * Polar angle (radians) -> KSF + */ + Poly1D spatialFrequencyScaleFactorPoly; + + //! Minimum range spatial freq (Krg) output from polar->rect resampling + double krg1; + + //! Maximum range spatial freq (Krg) output from polar->rect resampling + double krg2; + + //! Minimum az spatial freq output from polar->rect resampling + double kaz1; + + //! Minimum az spatial freq output from polar->rect resampling + double kaz2; + + //! SICD STDeskew parameter + mem::ScopedCopyablePtr slowTimeDeskew; + + //! Equality operator + bool operator==(const PFA& rhs) const; + bool operator!=(const PFA& rhs) const + { + return !(*this == rhs); + } + + void fillDerivedFields(const Position& position); + void fillDefaultFields(const GeoData& geoData, const Grid&, + const SCPCOA& scpcoa); + + bool validate(const SCPCOA& scpcoa, logging::Logger& log); +}; + +} +} +#endif diff --git a/six/modules/c++/six.sicd/include/six/sicd/Position.h b/six/modules/c++/six.sicd/include/six/sicd/Position.h index 7b63c2e682..efb8c3e088 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/Position.h +++ b/six/modules/c++/six.sicd/include/six/sicd/Position.h @@ -19,103 +19,103 @@ * see . * */ -#ifndef __SIX_POSITION_H__ -#define __SIX_POSITION_H__ +#ifndef __SIX_POSITION_H__ +#define __SIX_POSITION_H__ #include -#include -#include "six/Types.h" -#include "six/Init.h" -#include "six/Parameter.h" - -namespace six -{ -namespace sicd -{ -struct SCPCOA; - -/*! - * \struct RcvAPC - * \brief SICD RcvAPC - * - * Receive aperture phase center (APC). The size of the vector - * of the vector the number of receive APC polys - */ -struct RcvAPC -{ - //! Constructor - RcvAPC() - { - } - - std::vector rcvAPCPolys; - - //! Equality operator - bool operator==(const RcvAPC& rhs) const - { - return rcvAPCPolys == rhs.rcvAPCPolys; - } - - bool operator!=(const RcvAPC& rhs) const - { - return !(*this == rhs); - } -}; - -/*! - * \struct Position - * \brief SICD Position - * - * This block describes the platform and ground reference - * positions vs. time. - */ -struct Position -{ - /*! - * Aperture reference point as a function of time in ECEF meters - * t = 0 at collection start - */ - PolyXYZ arpPoly; - - /*! - * Ground reference point as a function of time in ECEF meters. - * t = 0 at collection start - */ - PolyXYZ grpPoly; - - /*! - * Transmit aperture phase center (APC) in ECEF as a function of time - * t = 0 at collection start. - * Always included for bistatic collections - */ - PolyXYZ txAPCPoly; - - /*! - * (Optional) Receive aperture phase center. - * - */ - mem::ScopedCopyablePtr rcvAPC; - - //! Constructor - Position(); - - //! Equality operator - bool operator==(const Position& rhs) const - { - return (arpPoly == rhs.arpPoly && grpPoly == rhs.grpPoly && - txAPCPoly == rhs.txAPCPoly && rcvAPC == rhs.rcvAPC); - } - - bool operator!=(const Position& rhs) const - { - return !(*this == rhs); - } - - void fillDerivedFields(const SCPCOA& scpcoa); - bool validate(logging::Logger& log) const; -}; - -} -} -#endif +#include +#include "six/Types.h" +#include "six/Init.h" +#include "six/Parameter.h" + +namespace six +{ +namespace sicd +{ +struct SCPCOA; + +/*! + * \struct RcvAPC + * \brief SICD RcvAPC + * + * Receive aperture phase center (APC). The size of the vector + * of the vector the number of receive APC polys + */ +struct RcvAPC +{ + //! Constructor + RcvAPC() + { + } + + std::vector rcvAPCPolys; + + //! Equality operator + bool operator==(const RcvAPC& rhs) const + { + return rcvAPCPolys == rhs.rcvAPCPolys; + } + + bool operator!=(const RcvAPC& rhs) const + { + return !(*this == rhs); + } +}; + +/*! + * \struct Position + * \brief SICD Position + * + * This block describes the platform and ground reference + * positions vs. time. + */ +struct Position +{ + /*! + * Aperture reference point as a function of time in ECEF meters + * t = 0 at collection start + */ + PolyXYZ arpPoly; + + /*! + * Ground reference point as a function of time in ECEF meters. + * t = 0 at collection start + */ + PolyXYZ grpPoly; + + /*! + * Transmit aperture phase center (APC) in ECEF as a function of time + * t = 0 at collection start. + * Always included for bistatic collections + */ + PolyXYZ txAPCPoly; + + /*! + * (Optional) Receive aperture phase center. + * + */ + mem::ScopedCopyablePtr rcvAPC; + + //! Constructor + Position(); + + //! Equality operator + bool operator==(const Position& rhs) const + { + return (arpPoly == rhs.arpPoly && grpPoly == rhs.grpPoly && + txAPCPoly == rhs.txAPCPoly && rcvAPC == rhs.rcvAPC); + } + + bool operator!=(const Position& rhs) const + { + return !(*this == rhs); + } + + void fillDerivedFields(const SCPCOA& scpcoa); + bool validate(logging::Logger& log) const; +}; + +} +} +#endif diff --git a/six/modules/c++/six.sicd/include/six/sicd/Timeline.h b/six/modules/c++/six.sicd/include/six/sicd/Timeline.h index 89e9cfdae7..fda8daffbc 100644 --- a/six/modules/c++/six.sicd/include/six/sicd/Timeline.h +++ b/six/modules/c++/six.sicd/include/six/sicd/Timeline.h @@ -19,121 +19,121 @@ * see . * */ -#ifndef __SIX_TIMELINE_H__ -#define __SIX_TIMELINE_H__ - -#include -#include "six/Types.h" -#include "six/Init.h" -#include "six/Parameter.h" - -namespace six -{ -namespace sicd -{ -/*! - * \class TimelineSet - * \brief SICD/Timeline/IPP/Set parameters - * - * Identifies a set of IPP parameters. Minimum of 1 set of - * parameters are required for IPP - */ -struct TimelineSet +#ifndef __SIX_TIMELINE_H__ +#define __SIX_TIMELINE_H__ + +#include +#include "six/Types.h" +#include "six/Init.h" +#include "six/Parameter.h" + +namespace six +{ +namespace sicd +{ +/*! + * \class TimelineSet + * \brief SICD/Timeline/IPP/Set parameters + * + * Identifies a set of IPP parameters. Minimum of 1 set of + * parameters are required for IPP + */ +struct TimelineSet { //! Constructor TimelineSet(); - - //! Start time for the period relative to collect start - double tStart; - - //! End time for the period relative to collect start - double tEnd; - - //! Starting ipp index for the period described - int interPulsePeriodStart; - - //! Ending ipp index for the period described - int interPulsePeriodEnd; - - /*! - * ipp index poly coefs yield IPP index as a function of time t - * Starting tStart to tEnd - */ - Poly1D interPulsePeriodPoly; - - //! Equality operators - bool operator==(const TimelineSet& rhs) const; - bool operator!=(const TimelineSet& rhs) const - { - return !(*this == rhs); - } -}; - -/*! - * \class InterPulsePeriod - * \brief SICD 'IPP' parameter - * Describes the interpulse period (IPP) parameters. This section - * of SICD is optional, and contains one or more Sets (TimelineSet) - */ -struct InterPulsePeriod -{ - /*! - * Constructor. - */ - InterPulsePeriod() - { - } - - //! Vector of TimelineSet objects - std::vector sets; - - //! Equality operators - bool operator==(const InterPulsePeriod& rhs) const - { - return sets == rhs.sets; - } - - bool operator!=(const InterPulsePeriod& rhs) const - { - return !(*this == rhs); - } -}; - -/*! - * \struct Timeline - * \brief SICD Timeline block - * - * Describes the imaging collection timeline. This is a required block, - * and it requires that collectStart and collectDuration are written (or - * read). The IPP parameter (referred to here as interPulsePeriod) is - * optional. - * - */ -struct Timeline + + //! Start time for the period relative to collect start + double tStart; + + //! End time for the period relative to collect start + double tEnd; + + //! Starting ipp index for the period described + int interPulsePeriodStart; + + //! Ending ipp index for the period described + int interPulsePeriodEnd; + + /*! + * ipp index poly coefs yield IPP index as a function of time t + * Starting tStart to tEnd + */ + Poly1D interPulsePeriodPoly; + + //! Equality operators + bool operator==(const TimelineSet& rhs) const; + bool operator!=(const TimelineSet& rhs) const + { + return !(*this == rhs); + } +}; + +/*! + * \class InterPulsePeriod + * \brief SICD 'IPP' parameter + * Describes the interpulse period (IPP) parameters. This section + * of SICD is optional, and contains one or more Sets (TimelineSet) + */ +struct InterPulsePeriod +{ + /*! + * Constructor. + */ + InterPulsePeriod() + { + } + + //! Vector of TimelineSet objects + std::vector sets; + + //! Equality operators + bool operator==(const InterPulsePeriod& rhs) const + { + return sets == rhs.sets; + } + + bool operator!=(const InterPulsePeriod& rhs) const + { + return !(*this == rhs); + } +}; + +/*! + * \struct Timeline + * \brief SICD Timeline block + * + * Describes the imaging collection timeline. This is a required block, + * and it requires that collectStart and collectDuration are written (or + * read). The IPP parameter (referred to here as interPulsePeriod) is + * optional. + * + */ +struct Timeline { //! Constructor Timeline(); - - //! Collection date/time UTC, measured from collection start - DateTime collectStart; - - //! Duration of collection period - double collectDuration; - - //! Optional IPP parameter description - mem::ScopedCopyablePtr interPulsePeriod; - - bool operator==(const Timeline& rhs) const - { - return (collectStart == rhs.collectStart && collectDuration == rhs.collectDuration && - interPulsePeriod == rhs.interPulsePeriod); - } - bool operator!=(const Timeline& rhs) const - { - return !(*this == rhs); - } -}; -} -} -#endif + + //! Collection date/time UTC, measured from collection start + DateTime collectStart; + + //! Duration of collection period + double collectDuration; + + //! Optional IPP parameter description + mem::ScopedCopyablePtr interPulsePeriod; + + bool operator==(const Timeline& rhs) const + { + return (collectStart == rhs.collectStart && collectDuration == rhs.collectDuration && + interPulsePeriod == rhs.interPulsePeriod); + } + bool operator!=(const Timeline& rhs) const + { + return !(*this == rhs); + } +}; +} +} +#endif diff --git a/six/modules/c++/six.sicd/six.sicd.vcxproj b/six/modules/c++/six.sicd/six.sicd.vcxproj index 7434cba31e..d96c1fae45 100644 --- a/six/modules/c++/six.sicd/six.sicd.vcxproj +++ b/six/modules/c++/six.sicd/six.sicd.vcxproj @@ -1,198 +1,198 @@ - - - - - Debug - x64 - - - Release - x64 - - - - 16.0 - Win32Proj - {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E} - six - 10.0 - - - - StaticLibrary - true - v143 - - - StaticLibrary - false - v143 - true - - - - - - - - - - - - - - - true - ..\six.ruleset - - - false - - - - true - _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - pch.h - $(ProjectDir)include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - true - %(AdditionalOptions) - true - AdvancedVectorExtensions2 - ProgramDatabase - Guard - EnableAllWarnings - MultiThreadedDebugDLL - true - - - - - true - - - - - Level3 - true - true - true - NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING - true - Use - pch.h - $(ProjectDir)include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ - Speed - true - /Zc:__cplusplus %(AdditionalOptions) - true - AdvancedVectorExtensions2 - pch.h - Guard - true - - - - - true - true - true - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Create - Create - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {1cfcde59-6410-4037-95eb-b37d31e10820} - - - {62aad4dd-35ba-41a0-8263-1f4dfd755689} - - - - - + + + + + Debug + x64 + + + Release + x64 + + + + 16.0 + Win32Proj + {34AC2314-FBD1-42AD-AAF4-0CEBC6BF737E} + six + 10.0 + + + + StaticLibrary + true + v143 + + + StaticLibrary + false + v143 + true + + + + + + + + + + + + + + + true + ..\six.ruleset + + + false + + + + true + _DEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + pch.h + $(ProjectDir)include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + true + %(AdditionalOptions) + true + AdvancedVectorExtensions2 + ProgramDatabase + Guard + EnableAllWarnings + MultiThreadedDebugDLL + true + + + + + true + + + + + Level3 + true + true + true + NDEBUG;_LIB;%(PreprocessorDefinitions);_SILENCE_NONFLOATING_COMPLEX_DEPRECATION_WARNING + true + Use + pch.h + $(ProjectDir)include\;$(ProjectDir)..\six\include\;$(ProjectDir)..\scene\include\;$(SolutionDir)externals\nitro\modules\c\nrt\include\;$(SolutionDir)externals\nitro\modules\c\nitf\include\;$(SolutionDir)externals\nitro\modules\c++\nitf\include\;$(SolutionDir)externals\coda-oss\out\install\$(Platform)-$(Configuration)\include\;$(SolutionDir)out\install\$(Platform)-$(Configuration)\include\ + Speed + true + /Zc:__cplusplus %(AdditionalOptions) + true + AdvancedVectorExtensions2 + pch.h + Guard + true + + + + + true + true + true + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Create + Create + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {1cfcde59-6410-4037-95eb-b37d31e10820} + + + {62aad4dd-35ba-41a0-8263-1f4dfd755689} + + + + + \ No newline at end of file diff --git a/six/modules/c++/six.sicd/six.sicd.vcxproj.filters b/six/modules/c++/six.sicd/six.sicd.vcxproj.filters index 3196090413..2517c17120 100644 --- a/six/modules/c++/six.sicd/six.sicd.vcxproj.filters +++ b/six/modules/c++/six.sicd/six.sicd.vcxproj.filters @@ -1,249 +1,249 @@ - - - - - {4FC737F1-C7A5-4376-A066-2A32D752A2FF} - cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx - - - {93995380-89BD-4b04-88EB-625FBE52EBFB} - h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd - - - {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} - rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms - - - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - - Source Files - - + + + + + {4FC737F1-C7A5-4376-A066-2A32D752A2FF} + cpp;c;cc;cxx;c++;cppm;ixx;def;odl;idl;hpj;bat;asm;asmx + + + {93995380-89BD-4b04-88EB-625FBE52EBFB} + h;hh;hpp;hxx;h++;hm;inl;inc;ipp;xsd + + + {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} + rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms + + + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + Header Files + + + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + + Source Files + + \ No newline at end of file diff --git a/six/modules/c++/six.sicd/source/Grid.cpp b/six/modules/c++/six.sicd/source/Grid.cpp index fc4cf5bbc7..7c9ce29dfe 100644 --- a/six/modules/c++/six.sicd/source/Grid.cpp +++ b/six/modules/c++/six.sicd/source/Grid.cpp @@ -19,23 +19,23 @@ * see . * */ -#include "six/sicd/Grid.h" +#include "six/sicd/Grid.h" #include #include "six/sicd/GeoData.h" -#include "six/sicd/ImageData.h" -#include "six/sicd/PFA.h" -#include "six/sicd/SCPCOA.h" -#include "six/sicd/RadarCollection.h" -#include "six/sicd/RgAzComp.h" -#include "six/sicd/RMA.h" -#include "six/sicd/Utilities.h" +#include "six/sicd/ImageData.h" +#include "six/sicd/PFA.h" +#include "six/sicd/SCPCOA.h" +#include "six/sicd/RadarCollection.h" +#include "six/sicd/RgAzComp.h" +#include "six/sicd/RMA.h" +#include "six/sicd/Utilities.h" #include - -using namespace six; -using namespace six::sicd; - + +using namespace six; +using namespace six::sicd; + const double DirectionParameters::WGT_TOL = 1e-3; const size_t DirectionParameters::DEFAULT_WEIGHT_SIZE = 512; const char DirectionParameters::BOUNDS_ERROR_MESSAGE[] = @@ -47,448 +47,448 @@ const char Grid::WF_INCONSISTENT_STR[] = "Waveform fields not consistent"; const char Grid::BOUNDS_ERROR_MESSAGE[] = "Violation of spatial frequency extent bounds"; -WeightType::WeightType() -{ -} - -DirectionParameters::DirectionParameters() : - unitVector(Init::undefined()), - sampleSpacing(Init::undefined()), - impulseResponseWidth(Init::undefined()), - sign(Init::undefined()), - impulseResponseBandwidth(Init::undefined()), - kCenter(Init::undefined()), - deltaK1(Init::undefined()), - deltaK2(Init::undefined()), - deltaKCOAPoly(Init::undefined()) -{ -} - -DirectionParameters* DirectionParameters::clone() const -{ - return new DirectionParameters(*this); -} - -bool DirectionParameters::operator==(const DirectionParameters& rhs) const -{ - return (unitVector == rhs.unitVector && - sampleSpacing == rhs.sampleSpacing && - impulseResponseWidth == rhs.impulseResponseWidth && - sign == rhs.sign && - impulseResponseBandwidth == rhs.impulseResponseBandwidth && - kCenter == rhs.kCenter && - deltaK1 == rhs.deltaK1 && - deltaK2 == rhs.deltaK2 && - deltaKCOAPoly == rhs.deltaKCOAPoly && - weightType == rhs.weightType && - weights == rhs.weights); -} - -std::pair DirectionParameters::calculateDeltaKs( - const ImageData& imageData) const -{ - //Here, we assume the min and max of DeltaKCOAPoly must be - // on the vertices of the image, since it is smooth and monotonic in most cases-- - // although in actuality this is not always the case. To be totally generic, - // we would have to search for an interior min and max as well - double derivedDeltaK1 = 0; - double derivedDeltaK2 = 0; - - std::vector vertices = calculateImageVertices(imageData); - - if (!Init::isUndefined(deltaKCOAPoly)) - { - derivedDeltaK1 = std::numeric_limits::infinity(); - derivedDeltaK2 = -std::numeric_limits::infinity(); - - for (size_t ii = 0; ii < vertices.size(); ++ii) - { - double currentDeltaK = deltaKCOAPoly.atY( - static_cast(vertices[ii].col))( - static_cast(vertices[ii].row)); - derivedDeltaK1 = std::min(currentDeltaK, derivedDeltaK1); - derivedDeltaK2 = std::max(currentDeltaK, derivedDeltaK2); - } - } - - derivedDeltaK1 -= (impulseResponseBandwidth / 2); - derivedDeltaK2 += (impulseResponseBandwidth / 2); - - if (derivedDeltaK1 < -(1 / sampleSpacing) / 2 || - derivedDeltaK2 > (1 / sampleSpacing) / 2) - { - derivedDeltaK1 = -(1 / sampleSpacing) / 2; - derivedDeltaK2 = -derivedDeltaK1; - } - - return std::pair(derivedDeltaK1, derivedDeltaK2); -} - -std::unique_ptr -DirectionParameters::calculateWeightFunction() const -{ - if (weightType.get() == nullptr) - { - return nullptr; - } - - std::string windowName(weightType->windowName); - str::upper(windowName); - - if (windowName == "UNIFORM") - { - return std::make_unique(); - } - if (windowName == "HAMMING") - { - double coef = 0.0; - if (weightType->parameters.empty() || weightType->parameters[0].str().empty()) - { - //A Hamming window is defined in many places as a raised cosine of weight .54, - //so this is the default. However, some data use a generalized raised cosine and - //call it HAMMING, so we allow for both uses. - coef = .54; - } - else - { +WeightType::WeightType() +{ +} + +DirectionParameters::DirectionParameters() : + unitVector(Init::undefined()), + sampleSpacing(Init::undefined()), + impulseResponseWidth(Init::undefined()), + sign(Init::undefined()), + impulseResponseBandwidth(Init::undefined()), + kCenter(Init::undefined()), + deltaK1(Init::undefined()), + deltaK2(Init::undefined()), + deltaKCOAPoly(Init::undefined()) +{ +} + +DirectionParameters* DirectionParameters::clone() const +{ + return new DirectionParameters(*this); +} + +bool DirectionParameters::operator==(const DirectionParameters& rhs) const +{ + return (unitVector == rhs.unitVector && + sampleSpacing == rhs.sampleSpacing && + impulseResponseWidth == rhs.impulseResponseWidth && + sign == rhs.sign && + impulseResponseBandwidth == rhs.impulseResponseBandwidth && + kCenter == rhs.kCenter && + deltaK1 == rhs.deltaK1 && + deltaK2 == rhs.deltaK2 && + deltaKCOAPoly == rhs.deltaKCOAPoly && + weightType == rhs.weightType && + weights == rhs.weights); +} + +std::pair DirectionParameters::calculateDeltaKs( + const ImageData& imageData) const +{ + //Here, we assume the min and max of DeltaKCOAPoly must be + // on the vertices of the image, since it is smooth and monotonic in most cases-- + // although in actuality this is not always the case. To be totally generic, + // we would have to search for an interior min and max as well + double derivedDeltaK1 = 0; + double derivedDeltaK2 = 0; + + std::vector vertices = calculateImageVertices(imageData); + + if (!Init::isUndefined(deltaKCOAPoly)) + { + derivedDeltaK1 = std::numeric_limits::infinity(); + derivedDeltaK2 = -std::numeric_limits::infinity(); + + for (size_t ii = 0; ii < vertices.size(); ++ii) + { + double currentDeltaK = deltaKCOAPoly.atY( + static_cast(vertices[ii].col))( + static_cast(vertices[ii].row)); + derivedDeltaK1 = std::min(currentDeltaK, derivedDeltaK1); + derivedDeltaK2 = std::max(currentDeltaK, derivedDeltaK2); + } + } + + derivedDeltaK1 -= (impulseResponseBandwidth / 2); + derivedDeltaK2 += (impulseResponseBandwidth / 2); + + if (derivedDeltaK1 < -(1 / sampleSpacing) / 2 || + derivedDeltaK2 > (1 / sampleSpacing) / 2) + { + derivedDeltaK1 = -(1 / sampleSpacing) / 2; + derivedDeltaK2 = -derivedDeltaK1; + } + + return std::pair(derivedDeltaK1, derivedDeltaK2); +} + +std::unique_ptr +DirectionParameters::calculateWeightFunction() const +{ + if (weightType.get() == nullptr) + { + return nullptr; + } + + std::string windowName(weightType->windowName); + str::upper(windowName); + + if (windowName == "UNIFORM") + { + return std::make_unique(); + } + if (windowName == "HAMMING") + { + double coef = 0.0; + if (weightType->parameters.empty() || weightType->parameters[0].str().empty()) + { + //A Hamming window is defined in many places as a raised cosine of weight .54, + //so this is the default. However, some data use a generalized raised cosine and + //call it HAMMING, so we allow for both uses. + coef = .54; + } + else + { coef = weightType->parameters[0]; - } - - return std::make_unique(coef); - } - if (windowName == "HANNING") - { - return std::make_unique(0.50); - } - if (windowName == "KAISER") - { + } + + return std::make_unique(coef); + } + if (windowName == "HANNING") + { + return std::make_unique(0.50); + } + if (windowName == "KAISER") + { return std::make_unique(double(weightType->parameters[0])); - } - - return nullptr; -} - -std::vector -DirectionParameters::calculateImageVertices(const ImageData& imageData) const -{ - std::vector vertices; - + } + + return nullptr; +} + +std::vector +DirectionParameters::calculateImageVertices(const ImageData& imageData) const +{ + std::vector vertices; + if (!imageData.validData.empty()) - { - vertices = imageData.validData; - } - else - { - vertices.resize(4); - //use edges of full image - vertices[0] = RowColInt(0, 0); - vertices[1] = RowColInt(static_cast(imageData.numCols) - 1, 0); - vertices[2] = RowColInt(static_cast(imageData.numCols) - 1, static_cast(imageData.numCols) - 1); - vertices[3] = RowColInt(0, static_cast(imageData.numCols) - 1); - } - return vertices; -} - -void DirectionParameters::fillDerivedFields(const ImageData& imageData) -{ - // Calulating resolution requires fzero and fft functions - - // DeltaK1/2 are approximated from DeltaKCOAPoly - if (!Init::isUndefined(deltaKCOAPoly) && - !Init::isUndefined(impulseResponseBandwidth) && - !Init::isUndefined(sampleSpacing) && - Init::isUndefined(deltaK1) && - Init::isUndefined(deltaK2)) - { - // Here, we assume the min and max of DeltaKCOAPoly must be on the vertices - // of the image, since it is smooth and monotonic in most cases--although in - // actuality this is not always the case. To be totally generic, we would - // have to search for an interior min and max as well. - const std::pair deltas = calculateDeltaKs(imageData); - deltaK1 = deltas.first; - deltaK2 = deltas.second; - } - - if (weightType.get() != nullptr && - weights.empty() && - weightType->windowName != "UNKNOWN") - { - std::unique_ptr weightFunction = calculateWeightFunction(); - if (weightFunction.get()) - { - weights = (*weightFunction)(DEFAULT_WEIGHT_SIZE); - } - } - return; -} - -bool DirectionParameters::validate(const ImageData& imageData, - logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - constexpr auto epsilon = std::numeric_limits::epsilon(); - //2.3.1, 2.3.5 - if (deltaK2 <= deltaK1) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "SICD.Grid.Row/Col.DeltaK1: " << deltaK1 << std::endl - << "SICD.Grid.Row/Col.DetalK2: " << deltaK2 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - else - { - // 2.3.2, 2.3.6 - if (deltaK2 > (1 / (2 * sampleSpacing)) + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Row/Col.SampleSpacing: " << - 0.5 / sampleSpacing << std::endl - << "SICD.Grid.Row/Col.DetalK2: " << deltaK2 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.3.3, 2.3.7 - if (deltaK1 < (-1 / (2 * sampleSpacing)) - epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Row/Col.SampleSpacing: " << - 0.5 / sampleSpacing << std::endl - << "SICD.Grid.Row/Col.DetalK1: " << deltaK1 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.3.4, 2.3.8 - if (impulseResponseBandwidth > (deltaK2 - deltaK1) + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "SICD.Grid.Row/Col.impulseResponseBandwidth: " << - impulseResponseBandwidth << std::endl - << "SICD.Grid.Row/Col.DeltaK2 - SICD.Grid.Row/COl.DeltaK1: " - << deltaK2 - deltaK1 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - } - - // 2.3.9. Compute our own DeltaK1/K2 and test for consistency with DelaKCOAPoly, - // ImpRespBW, and SS. - const auto deltas = calculateDeltaKs(imageData); - const double minDk = deltas.first; - const double maxDk = deltas.second; - - constexpr double DK_TOL = 1e-2; - - //2.3.9.1, 2.3.9.3 - if (std::abs((deltaK1 / minDk) - 1) > DK_TOL) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "SICD.Grid.Row/Col.DeltaK1: " << deltaK1 << std::endl - << "Derived DeltaK1: " << minDk << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - //2.3.9.2, 2.3.9.4 - if (std::abs((deltaK2 / maxDk) - 1) > DK_TOL) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "SICD.Grid.Row/Col.DeltaK2: " << deltaK2 << std::endl - << "Derived DeltaK2: " << maxDk << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - // Check weight functions - std::unique_ptr weightFunction; - - if (weightType.get()) - { - weightFunction.reset(calculateWeightFunction().release()); - - if (weightFunction.get()) - { - if (!weights.empty()) - { + { + vertices = imageData.validData; + } + else + { + vertices.resize(4); + //use edges of full image + vertices[0] = RowColInt(0, 0); + vertices[1] = RowColInt(static_cast(imageData.numCols) - 1, 0); + vertices[2] = RowColInt(static_cast(imageData.numCols) - 1, static_cast(imageData.numCols) - 1); + vertices[3] = RowColInt(0, static_cast(imageData.numCols) - 1); + } + return vertices; +} + +void DirectionParameters::fillDerivedFields(const ImageData& imageData) +{ + // Calulating resolution requires fzero and fft functions + + // DeltaK1/2 are approximated from DeltaKCOAPoly + if (!Init::isUndefined(deltaKCOAPoly) && + !Init::isUndefined(impulseResponseBandwidth) && + !Init::isUndefined(sampleSpacing) && + Init::isUndefined(deltaK1) && + Init::isUndefined(deltaK2)) + { + // Here, we assume the min and max of DeltaKCOAPoly must be on the vertices + // of the image, since it is smooth and monotonic in most cases--although in + // actuality this is not always the case. To be totally generic, we would + // have to search for an interior min and max as well. + const std::pair deltas = calculateDeltaKs(imageData); + deltaK1 = deltas.first; + deltaK2 = deltas.second; + } + + if (weightType.get() != nullptr && + weights.empty() && + weightType->windowName != "UNKNOWN") + { + std::unique_ptr weightFunction = calculateWeightFunction(); + if (weightFunction.get()) + { + weights = (*weightFunction)(DEFAULT_WEIGHT_SIZE); + } + } + return; +} + +bool DirectionParameters::validate(const ImageData& imageData, + logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + constexpr auto epsilon = std::numeric_limits::epsilon(); + //2.3.1, 2.3.5 + if (deltaK2 <= deltaK1) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "SICD.Grid.Row/Col.DeltaK1: " << deltaK1 << std::endl + << "SICD.Grid.Row/Col.DetalK2: " << deltaK2 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + else + { + // 2.3.2, 2.3.6 + if (deltaK2 > (1 / (2 * sampleSpacing)) + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Row/Col.SampleSpacing: " << + 0.5 / sampleSpacing << std::endl + << "SICD.Grid.Row/Col.DetalK2: " << deltaK2 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.3.3, 2.3.7 + if (deltaK1 < (-1 / (2 * sampleSpacing)) - epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Row/Col.SampleSpacing: " << + 0.5 / sampleSpacing << std::endl + << "SICD.Grid.Row/Col.DetalK1: " << deltaK1 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.3.4, 2.3.8 + if (impulseResponseBandwidth > (deltaK2 - deltaK1) + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "SICD.Grid.Row/Col.impulseResponseBandwidth: " << + impulseResponseBandwidth << std::endl + << "SICD.Grid.Row/Col.DeltaK2 - SICD.Grid.Row/COl.DeltaK1: " + << deltaK2 - deltaK1 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + } + + // 2.3.9. Compute our own DeltaK1/K2 and test for consistency with DelaKCOAPoly, + // ImpRespBW, and SS. + const auto deltas = calculateDeltaKs(imageData); + const double minDk = deltas.first; + const double maxDk = deltas.second; + + constexpr double DK_TOL = 1e-2; + + //2.3.9.1, 2.3.9.3 + if (std::abs((deltaK1 / minDk) - 1) > DK_TOL) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "SICD.Grid.Row/Col.DeltaK1: " << deltaK1 << std::endl + << "Derived DeltaK1: " << minDk << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + //2.3.9.2, 2.3.9.4 + if (std::abs((deltaK2 / maxDk) - 1) > DK_TOL) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "SICD.Grid.Row/Col.DeltaK2: " << deltaK2 << std::endl + << "Derived DeltaK2: " << maxDk << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + // Check weight functions + std::unique_ptr weightFunction; + + if (weightType.get()) + { + weightFunction.reset(calculateWeightFunction().release()); + + if (weightFunction.get()) + { + if (!weights.empty()) + { valid = validateWeights(*weightFunction, log) && valid; - } - } - else - { - messageBuilder.str(""); - messageBuilder << "Unrecognized weighting description" << std::endl - << "WeightType.WindowName: " - << weightType->windowName << std::endl; - log.warn(messageBuilder.str()); - valid = false; - } - } - - // 2.4.3, 2.4.4 - if (weightType.get() && - weightType->windowName != "UNIFORM" && - weightType->windowName != "UNKNOWN" && - weights.empty()) - { - messageBuilder.str(""); - messageBuilder << "Non-uniform weighting, but no WgtFunct provided" - << std::endl << "WgtType.WindowName: " << weightType->windowName - << std::endl; - log.warn(messageBuilder.str()); - } - - return valid; -} - -bool DirectionParameters::validateWeights(const Functor& weightFunction, - logging::Logger& log) const -{ - bool consistentValues = true; - bool valid = true; - std::ostringstream messageBuilder; - - //Arg doesn't matter. Just checking for Uniform-type Functor - if (weightFunction(5).empty()) - { - const auto key = weights[0]; - for (size_t ii = 0; ii < weights.size(); ++ii) - { - if (key != weights[ii]) - { - consistentValues = false; - } - } - } - else - { - std::vector expectedWeights = weightFunction(weights.size()); - for (size_t ii = 0; ii < weights.size(); ++ii) - { - if (std::abs(expectedWeights[ii] - weights[ii]) > WGT_TOL) - { - consistentValues = false; - break; - } - } - } - - if (!consistentValues) - { - messageBuilder.str(""); - messageBuilder << "DirectionParameters weights values " - << "inconsistent with weightType" << std::endl - << "WeightType.WindowName: " - << weightType->windowName << std::endl; - log.warn(messageBuilder.str()); - valid = false; - } - - return valid; -} - -void DirectionParameters::fillDerivedFields(const RgAzComp& rgAzComp, - double offset) -{ - if (Init::isUndefined(kCenter)) - { - kCenter = derivedKCenter(rgAzComp, offset); - } - - if (Init::isUndefined(deltaKCOAPoly) && - !Init::isUndefined(kCenter)) - { - deltaKCOAPoly = derivedKcoaPoly(rgAzComp, offset); - } -} - -double DirectionParameters::derivedKCenter(const RgAzComp& /*rgAzComp*/, - double offset) const -{ - double derivedCenter = offset; - if (!Init::isUndefined(deltaKCOAPoly)) - { - derivedCenter -= deltaKCOAPoly[0][0]; - } - return derivedCenter; -} - -Poly2D DirectionParameters::derivedKcoaPoly(const RgAzComp& /*rgAzComp*/, - double offset) const -{ - // Create a Poly2D with one term - std::vector coefs(1, offset - kCenter); - return Poly2D(0, 0, coefs); -} - -bool DirectionParameters::validate(const RgAzComp& rgAzComp, - logging::Logger& log, - double offset) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - // 2.12.1.8, 2.12.1.9 - if (std::abs(kCenter - derivedKCenter(rgAzComp, offset)) - > std::numeric_limits::epsilon()) - { - messageBuilder.str(""); - messageBuilder << "KCenter: " << kCenter << std::endl - << "DeltaKCOAPoly: " << deltaKCOAPoly[0][0]; - log.error(messageBuilder.str()); - valid = false; - } - - //2.12.1.10, 2.12.1.11 - if (!Init::isUndefined(deltaKCOAPoly) && deltaKCOAPoly.orderX() > 1) - { - messageBuilder.str(""); - messageBuilder << "DetlaKCOAPoly must be a single value for RGAZCOMP data"; - log.error(messageBuilder.str()); - valid = false; - } - return valid; -} - -Grid::Grid() : - // This is a good assumption, I think - imagePlane(ComplexImagePlaneType::SLANT), - // Not so sure about this one - type(ComplexImageGridType::RGAZIM), - row(new DirectionParameters()), - col(new DirectionParameters()) -{ -} - -Grid* Grid::clone() const -{ - return new Grid(*this); -} - -bool Grid::operator==(const Grid& rhs) const -{ - return (imagePlane == rhs.imagePlane && - type == rhs.type && - timeCOAPoly == rhs.timeCOAPoly && - row == rhs.row && col == rhs.col); -} - -bool Grid::validateTimeCOAPoly( - const CollectionInformation& collectionInformation, - logging::Logger& log) const -{ - const RadarModeType& mode = collectionInformation.radarMode; - - //2.1. Scalar TimeCOAPoly means SPOTLIGHT data - bool valid = true; + } + } + else + { + messageBuilder.str(""); + messageBuilder << "Unrecognized weighting description" << std::endl + << "WeightType.WindowName: " + << weightType->windowName << std::endl; + log.warn(messageBuilder.str()); + valid = false; + } + } + + // 2.4.3, 2.4.4 + if (weightType.get() && + weightType->windowName != "UNIFORM" && + weightType->windowName != "UNKNOWN" && + weights.empty()) + { + messageBuilder.str(""); + messageBuilder << "Non-uniform weighting, but no WgtFunct provided" + << std::endl << "WgtType.WindowName: " << weightType->windowName + << std::endl; + log.warn(messageBuilder.str()); + } + + return valid; +} + +bool DirectionParameters::validateWeights(const Functor& weightFunction, + logging::Logger& log) const +{ + bool consistentValues = true; + bool valid = true; + std::ostringstream messageBuilder; + + //Arg doesn't matter. Just checking for Uniform-type Functor + if (weightFunction(5).empty()) + { + const auto key = weights[0]; + for (size_t ii = 0; ii < weights.size(); ++ii) + { + if (key != weights[ii]) + { + consistentValues = false; + } + } + } + else + { + std::vector expectedWeights = weightFunction(weights.size()); + for (size_t ii = 0; ii < weights.size(); ++ii) + { + if (std::abs(expectedWeights[ii] - weights[ii]) > WGT_TOL) + { + consistentValues = false; + break; + } + } + } + + if (!consistentValues) + { + messageBuilder.str(""); + messageBuilder << "DirectionParameters weights values " + << "inconsistent with weightType" << std::endl + << "WeightType.WindowName: " + << weightType->windowName << std::endl; + log.warn(messageBuilder.str()); + valid = false; + } + + return valid; +} + +void DirectionParameters::fillDerivedFields(const RgAzComp& rgAzComp, + double offset) +{ + if (Init::isUndefined(kCenter)) + { + kCenter = derivedKCenter(rgAzComp, offset); + } + + if (Init::isUndefined(deltaKCOAPoly) && + !Init::isUndefined(kCenter)) + { + deltaKCOAPoly = derivedKcoaPoly(rgAzComp, offset); + } +} + +double DirectionParameters::derivedKCenter(const RgAzComp& /*rgAzComp*/, + double offset) const +{ + double derivedCenter = offset; + if (!Init::isUndefined(deltaKCOAPoly)) + { + derivedCenter -= deltaKCOAPoly[0][0]; + } + return derivedCenter; +} + +Poly2D DirectionParameters::derivedKcoaPoly(const RgAzComp& /*rgAzComp*/, + double offset) const +{ + // Create a Poly2D with one term + std::vector coefs(1, offset - kCenter); + return Poly2D(0, 0, coefs); +} + +bool DirectionParameters::validate(const RgAzComp& rgAzComp, + logging::Logger& log, + double offset) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + // 2.12.1.8, 2.12.1.9 + if (std::abs(kCenter - derivedKCenter(rgAzComp, offset)) + > std::numeric_limits::epsilon()) + { + messageBuilder.str(""); + messageBuilder << "KCenter: " << kCenter << std::endl + << "DeltaKCOAPoly: " << deltaKCOAPoly[0][0]; + log.error(messageBuilder.str()); + valid = false; + } + + //2.12.1.10, 2.12.1.11 + if (!Init::isUndefined(deltaKCOAPoly) && deltaKCOAPoly.orderX() > 1) + { + messageBuilder.str(""); + messageBuilder << "DetlaKCOAPoly must be a single value for RGAZCOMP data"; + log.error(messageBuilder.str()); + valid = false; + } + return valid; +} + +Grid::Grid() : + // This is a good assumption, I think + imagePlane(ComplexImagePlaneType::SLANT), + // Not so sure about this one + type(ComplexImageGridType::RGAZIM), + row(new DirectionParameters()), + col(new DirectionParameters()) +{ +} + +Grid* Grid::clone() const +{ + return new Grid(*this); +} + +bool Grid::operator==(const Grid& rhs) const +{ + return (imagePlane == rhs.imagePlane && + type == rhs.type && + timeCOAPoly == rhs.timeCOAPoly && + row == rhs.row && col == rhs.col); +} + +bool Grid::validateTimeCOAPoly( + const CollectionInformation& collectionInformation, + logging::Logger& log) const +{ + const RadarModeType& mode = collectionInformation.radarMode; + + //2.1. Scalar TimeCOAPoly means SPOTLIGHT data + bool valid = true; if (timeCOAPoly.empty()) { log.error("No timeCOAPoly for Grid."); @@ -497,70 +497,70 @@ bool Grid::validateTimeCOAPoly( else { const auto isScalar = timeCOAPoly.isScalar(); - - if (mode == RadarModeType::SPOTLIGHT && !isScalar) - { - log.error("SPOTLIGHT data should only have scalar TimeCOAPoly."); - valid = false; - } - - if (mode != RadarModeType::SPOTLIGHT && isScalar) - { + + if (mode == RadarModeType::SPOTLIGHT && !isScalar) + { + log.error("SPOTLIGHT data should only have scalar TimeCOAPoly."); + valid = false; + } + + if (mode != RadarModeType::SPOTLIGHT && isScalar) + { log.warn("Non-SPOTLIGHT data will generally have more than one " - "nonzero term in TimeCOAPoly unless \"formed as spotlight\"."); - valid = false; - } - } - - return valid; -} - -bool Grid::validateFFTSigns(logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - //2.2. FFT signs in both dimensions almost certainly have to be equal - if (row->sign != col->sign) - { - messageBuilder.str(""); - messageBuilder << - "FFT signs in row and column direction should be the same." << - std::endl << "Grid.Row.Sign: " << row->sign << std::endl - << "Grid.Col.Sign: " << col->sign << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - return valid; -} - -bool Grid::validate(const CollectionInformation& collectionInformation, - const ImageData& imageData, - logging::Logger& log) const -{ - bool valid = validateTimeCOAPoly(collectionInformation, log);//2.1 - valid = validateFFTSigns(log) && valid; //2.2 + "nonzero term in TimeCOAPoly unless \"formed as spotlight\"."); + valid = false; + } + } + + return valid; +} + +bool Grid::validateFFTSigns(logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + //2.2. FFT signs in both dimensions almost certainly have to be equal + if (row->sign != col->sign) + { + messageBuilder.str(""); + messageBuilder << + "FFT signs in row and column direction should be the same." << + std::endl << "Grid.Row.Sign: " << row->sign << std::endl + << "Grid.Col.Sign: " << col->sign << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + return valid; +} + +bool Grid::validate(const CollectionInformation& collectionInformation, + const ImageData& imageData, + logging::Logger& log) const +{ + bool valid = validateTimeCOAPoly(collectionInformation, log);//2.1 + valid = validateFFTSigns(log) && valid; //2.2 valid = row->validate(imageData, log) && valid; //2.3.1 - 2.3.9 - valid = col->validate(imageData, log) && valid; + valid = col->validate(imageData, log) && valid; return valid; -} - -void Grid::fillDerivedFields( - const CollectionInformation& collectionInformation, - const ImageData& imageData, - const SCPCOA& scpcoa) -{ - if (!Init::isUndefined(scpcoa.scpTime) && - collectionInformation.radarMode == RadarModeType::SPOTLIGHT && - Init::isUndefined(timeCOAPoly)) - { - timeCOAPoly = Poly2D(0, 0); - timeCOAPoly[0][0] = scpcoa.scpTime; - } - - row->fillDerivedFields(imageData); - col->fillDerivedFields(imageData); -} +} + +void Grid::fillDerivedFields( + const CollectionInformation& collectionInformation, + const ImageData& imageData, + const SCPCOA& scpcoa) +{ + if (!Init::isUndefined(scpcoa.scpTime) && + collectionInformation.radarMode == RadarModeType::SPOTLIGHT && + Init::isUndefined(timeCOAPoly)) + { + timeCOAPoly = Poly2D(0, 0); + timeCOAPoly[0][0] = scpcoa.scpTime; + } + + row->fillDerivedFields(imageData); + col->fillDerivedFields(imageData); +} void Grid::fillDerivedFields(const RMA& rma, const Vector3& scp, const PolyXYZ& arpPoly) @@ -580,48 +580,48 @@ void Grid::fillDerivedFields(const RMA& rma, const Vector3& scp, } void Grid::fillDerivedFields(const RMAT& rmat, const Vector3& scp) -{ - // Row/Col.UnitVector and Derived fields - if (Init::isUndefined(row->unitVector) && - Init::isUndefined(col->unitVector)) - { - row->unitVector = derivedRowUnitVector(rmat, scp); - col->unitVector = derivedColUnitVector(rmat, scp); +{ + // Row/Col.UnitVector and Derived fields + if (Init::isUndefined(row->unitVector) && + Init::isUndefined(col->unitVector)) + { + row->unitVector = derivedRowUnitVector(rmat, scp); + col->unitVector = derivedColUnitVector(rmat, scp); } } void Grid::fillDerivedFields(const RMCR& rmcr, const Vector3& scp) -{ - // Row/Col.UnitVector and Derived fields - if (Init::isUndefined(row->unitVector) && - Init::isUndefined(col->unitVector)) - { - row->unitVector = derivedRowUnitVector(rmcr, scp); - col->unitVector = derivedColUnitVector(rmcr, scp); +{ + // Row/Col.UnitVector and Derived fields + if (Init::isUndefined(row->unitVector) && + Init::isUndefined(col->unitVector)) + { + row->unitVector = derivedRowUnitVector(rmcr, scp); + col->unitVector = derivedColUnitVector(rmcr, scp); } } void Grid::fillDerivedFields(const INCA& inca, const Vector3& scp, const PolyXYZ& arpPoly) { - if (!Init::isUndefined(inca.timeCAPoly) && - !Init::isUndefined(arpPoly) && - Init::isUndefined(row->unitVector) && - Init::isUndefined(col->unitVector)) - { - row->unitVector = derivedRowUnitVector(inca, scp, arpPoly); - col->unitVector = derivedColUnitVector(inca, scp, arpPoly); + if (!Init::isUndefined(inca.timeCAPoly) && + !Init::isUndefined(arpPoly) && + Init::isUndefined(row->unitVector) && + Init::isUndefined(col->unitVector)) + { + row->unitVector = derivedRowUnitVector(inca, scp, arpPoly); + col->unitVector = derivedColUnitVector(inca, scp, arpPoly); } - if (Init::isUndefined(col->kCenter)) - { - col->kCenter = 0; + if (Init::isUndefined(col->kCenter)) + { + col->kCenter = 0; } - if (!Init::isUndefined(inca.freqZero) && - Init::isUndefined(row->kCenter)) - { - row->kCenter = derivedRowKCenter(inca); + if (!Init::isUndefined(inca.freqZero) && + Init::isUndefined(row->kCenter)) + { + row->kCenter = derivedRowKCenter(inca); } } @@ -632,21 +632,21 @@ void Grid::fillDerivedFields(const RgAzComp& rgAzComp, { const Vector3& scp = geoData.scp.ecf; - if (imagePlane == ComplexImagePlaneType::NOT_SET) - { - imagePlane = ComplexImagePlaneType::SLANT; - } - if (type == ComplexImageGridType::NOT_SET) - { - type = ComplexImageGridType::RGAZIM; - } - - if (Init::isUndefined(row->unitVector)) - { - row->unitVector = derivedRowUnitVector(scpcoa, scp); - } - if (Init::isUndefined(col->unitVector)) - { + if (imagePlane == ComplexImagePlaneType::NOT_SET) + { + imagePlane = ComplexImagePlaneType::SLANT; + } + if (type == ComplexImageGridType::NOT_SET) + { + type = ComplexImageGridType::RGAZIM; + } + + if (Init::isUndefined(row->unitVector)) + { + row->unitVector = derivedRowUnitVector(scpcoa, scp); + } + if (Init::isUndefined(col->unitVector)) + { col->unitVector = derivedColUnitVector(scpcoa, scp); } if (!Init::isUndefined(fc)) @@ -697,16 +697,16 @@ void Grid::fillDefaultFields(const RMA& rma, double fc) void Grid::fillDefaultFields(const RMAT& rmat, double fc) { - if (!Init::isUndefined(fc)) - { - if (Init::isUndefined(row->kCenter)) - { - row->kCenter = derivedRowKCenter(rmat, fc); - } - - if (Init::isUndefined(col->kCenter)) - { - col->kCenter = derivedColKCenter(rmat, fc); + if (!Init::isUndefined(fc)) + { + if (Init::isUndefined(row->kCenter)) + { + row->kCenter = derivedRowKCenter(rmat, fc); + } + + if (Init::isUndefined(col->kCenter)) + { + col->kCenter = derivedColKCenter(rmat, fc); } } } @@ -759,47 +759,47 @@ Vector3 Grid::derivedColUnitVector(const INCA& inca, const Vector3& scp, void Grid::fillDefaultFields(const RMCR& rmcr, double fc) { - if (!Init::isUndefined(fc)) - { - if (Init::isUndefined(row->kCenter)) - { - row->kCenter = derivedRowKCenter(rmcr, fc); - } - if (Init::isUndefined(col->kCenter)) - { - col->kCenter = 0; - } + if (!Init::isUndefined(fc)) + { + if (Init::isUndefined(row->kCenter)) + { + row->kCenter = derivedRowKCenter(rmcr, fc); + } + if (Init::isUndefined(col->kCenter)) + { + col->kCenter = 0; + } } } void Grid::fillDefaultFields(const PFA& pfa, double fc) { - if (type == ComplexImageGridType::NOT_SET) - { - type = ComplexImageGridType::RGAZIM; - } - - if (Init::isUndefined(col->kCenter)) - { - col->kCenter = 0; - } - if (Init::isUndefined(row->kCenter)) - { - if (!Init::isUndefined(pfa.krg1) && - !Init::isUndefined(pfa.krg2)) - { - // Default: the most reasonable way to compute this - row->kCenter = (pfa.krg1 + pfa.krg2) / 2; - } - else if (!Init::isUndefined(fc)) - { - // Approximation: this may not be quite right, due to - // rectangular inscription loss in PFA, but it should - // be close. - row->kCenter = fc * - (2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC) * - pfa.spatialFrequencyScaleFactorPoly[0]; - } + if (type == ComplexImageGridType::NOT_SET) + { + type = ComplexImageGridType::RGAZIM; + } + + if (Init::isUndefined(col->kCenter)) + { + col->kCenter = 0; + } + if (Init::isUndefined(row->kCenter)) + { + if (!Init::isUndefined(pfa.krg1) && + !Init::isUndefined(pfa.krg2)) + { + // Default: the most reasonable way to compute this + row->kCenter = (pfa.krg1 + pfa.krg2) / 2; + } + else if (!Init::isUndefined(fc)) + { + // Approximation: this may not be quite right, due to + // rectangular inscription loss in PFA, but it should + // be close. + row->kCenter = fc * + (2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC) * + pfa.spatialFrequencyScaleFactorPoly[0]; + } } } @@ -811,9 +811,9 @@ bool Grid::validate(const RMA& rma, const Vector3& scp, // 2.12.3.2.1, 2.12.3.4.1 if (type != defaultGridType(rma)) { - std::ostringstream messageBuilder; - messageBuilder << "Given image formation algorithm expects " - << defaultGridType(rma) << ".\nFound " << type; + std::ostringstream messageBuilder; + messageBuilder << "Given image formation algorithm expects " + << defaultGridType(rma) << ".\nFound " << type; log.error(messageBuilder.str()); valid = false; } @@ -842,49 +842,49 @@ bool Grid::validate(const RMAT& rmat, const Vector3& scp, std::ostringstream messageBuilder; bool valid = true; - // 2.12.3.2.3 - if ((row->unitVector - derivedRowUnitVector(rmat, scp)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl + // 2.12.3.2.3 + if ((row->unitVector - derivedRowUnitVector(rmat, scp)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl << "Grid.Row.UVectECF: " << row->unitVector << std::endl - << "Derived grid.Row.UVectECT: " - << derivedRowUnitVector(rmat, scp); - log.error(messageBuilder.str()); - valid = false; + << "Derived grid.Row.UVectECT: " + << derivedRowUnitVector(rmat, scp); + log.error(messageBuilder.str()); + valid = false; } - // 2.12.3.2.4 - if ((col->unitVector - derivedColUnitVector(rmat, scp)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl + // 2.12.3.2.4 + if ((col->unitVector - derivedColUnitVector(rmat, scp)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl << "Grid.Col.UVectECF: " << col->unitVector << std::endl - << "Derived Grid.Col.UVectECF: " - << derivedColUnitVector(rmat, scp); - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.2.6 - if (std::abs((derivedRowKCenter(rmat, fc) / row->kCenter) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR - << "Grid.Row.KCtr: " << row->kCenter << std::endl - << "Derived KCtr: " << derivedRowKCenter(rmat, fc); - log.warn(messageBuilder.str()); + << "Derived Grid.Col.UVectECF: " + << derivedColUnitVector(rmat, scp); + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.2.6 + if (std::abs((derivedRowKCenter(rmat, fc) / row->kCenter) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR + << "Grid.Row.KCtr: " << row->kCenter << std::endl + << "Derived KCtr: " << derivedRowKCenter(rmat, fc); + log.warn(messageBuilder.str()); valid = false; } //2.12.3.2.7 - if (std::abs((derivedColKCenter(rmat, fc) / col->kCenter) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR - << "Grid.Col.KCtr: " << col->kCenter << std::endl - << "Derived KCtr: " << derivedColKCenter(rmat, fc); - log.warn(messageBuilder.str()); + if (std::abs((derivedColKCenter(rmat, fc) / col->kCenter) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR + << "Grid.Col.KCtr: " << col->kCenter << std::endl + << "Derived KCtr: " << derivedColKCenter(rmat, fc); + log.warn(messageBuilder.str()); valid = false; } @@ -897,52 +897,52 @@ bool Grid::validate(const RMCR& rmcr, const Vector3& scp, bool valid = true; std::ostringstream messageBuilder; - //2.12.3.3.3 - if ((row->unitVector - derivedRowUnitVector(rmcr, scp)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl - << "Grid.Row.UVectECF: " << row->unitVector << std::endl - << "Derived Grid.Row.UVectECF: " - << derivedRowUnitVector(rmcr, scp); - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.3.4 - if ((col->unitVector - derivedColUnitVector(rmcr, scp)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl - << "Grid.Col.UVectECF: " << col->unitVector << std::endl - << "Derived Grid.Col.UVectECF: " + //2.12.3.3.3 + if ((row->unitVector - derivedRowUnitVector(rmcr, scp)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl + << "Grid.Row.UVectECF: " << row->unitVector << std::endl + << "Derived Grid.Row.UVectECF: " + << derivedRowUnitVector(rmcr, scp); + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.3.4 + if ((col->unitVector - derivedColUnitVector(rmcr, scp)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl + << "Grid.Col.UVectECF: " << col->unitVector << std::endl + << "Derived Grid.Col.UVectECF: " << derivedColUnitVector(rmcr, scp); - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.3.6 - if (col->kCenter != 0) - { - messageBuilder.str(""); - messageBuilder << "Grid.Col.KCtr must be zero for RMA/RMCR data." - << std::endl << "Grid.Col.KCtr = " << col->kCenter; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.3.7 - if (!Init::isUndefined(fc)) - { - if (std::abs(row->kCenter / derivedRowKCenter(rmcr, fc) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "Grid.Row.KCtr: " << row->kCenter << std::endl - << "Center frequency * 2/c: " << derivedRowKCenter(rmcr, fc); - log.warn(messageBuilder.str()); - valid = false; - } + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.3.6 + if (col->kCenter != 0) + { + messageBuilder.str(""); + messageBuilder << "Grid.Col.KCtr must be zero for RMA/RMCR data." + << std::endl << "Grid.Col.KCtr = " << col->kCenter; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.3.7 + if (!Init::isUndefined(fc)) + { + if (std::abs(row->kCenter / derivedRowKCenter(rmcr, fc) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "Grid.Row.KCtr: " << row->kCenter << std::endl + << "Center frequency * 2/c: " << derivedRowKCenter(rmcr, fc); + log.warn(messageBuilder.str()); + valid = false; + } } return valid; @@ -964,7 +964,7 @@ bool Grid::validate(const INCA& inca, const Vector3& scp, if (!Init::isUndefined(inca.dopplerCentroidPoly) && inca.dopplerCentroidCOA == BooleanType::IS_TRUE) { - const Poly2D& kcoaPoly = col->deltaKCOAPoly; + const Poly2D& kcoaPoly = col->deltaKCOAPoly; const Poly2D& centroidPoly = inca.dopplerCentroidPoly; if (kcoaPoly.orderX() != centroidPoly.orderX() && @@ -990,14 +990,14 @@ bool Grid::validate(const INCA& inca, const Vector3& scp, } norm = std::sqrt(norm); - if(norm > IFP_POLY_TOL) - { - messageBuilder.str(""); - messageBuilder << "RMA.INCA fields inconsistent." << std::endl - << "Compare Grid.Col.KCOAPoly to RMA.INCA.DopCentroidPoly " - << "* RMA.INCA.TimeCAPoly[1]."; - log.error(messageBuilder.str()); - valid = false; + if(norm > IFP_POLY_TOL) + { + messageBuilder.str(""); + messageBuilder << "RMA.INCA fields inconsistent." << std::endl + << "Compare Grid.Col.KCOAPoly to RMA.INCA.DopCentroidPoly " + << "* RMA.INCA.TimeCAPoly[1]."; + log.error(messageBuilder.str()); + valid = false; } } } @@ -1006,50 +1006,50 @@ bool Grid::validate(const INCA& inca, const Vector3& scp, if ((row->unitVector - derivedRowUnitVector(inca, scp, arpPoly)).norm() > UVECT_TOL) { - messageBuilder.str(""); - messageBuilder << "UVectFields inconsistent" << std::endl + messageBuilder.str(""); + messageBuilder << "UVectFields inconsistent" << std::endl << "Grid.Row.UVectECF: " << row->unitVector << std::endl - << "Derived Grid.Row.UVectECF: " - << derivedRowUnitVector(inca, scp, arpPoly); - log.error(messageBuilder.str()); + << "Derived Grid.Row.UVectECF: " + << derivedRowUnitVector(inca, scp, arpPoly); + log.error(messageBuilder.str()); valid = false; } - // 2.12.3.4.7 - if ((col->unitVector - - derivedRowUnitVector(inca, scp, arpPoly)).norm() > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVectFields inconsistent" << std::endl + // 2.12.3.4.7 + if ((col->unitVector - + derivedRowUnitVector(inca, scp, arpPoly)).norm() > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVectFields inconsistent" << std::endl << "Grid.Col.UVectECF: " << col->unitVector << std::endl - << "Derived Grid.Col.UVectECF: " - << derivedRowUnitVector(inca, scp, arpPoly); - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.4.8 - if (col->kCenter != 0) - { - messageBuilder.str(""); - messageBuilder << "Grid.Col.KCtr must be zero " - << "for RMA/INCA data." << std::endl - << "Grid.Col.KCtr: " << col->kCenter; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.12.3.4.11 - if (Init::isUndefined(fc) && - std::abs(row->kCenter - derivedRowKCenter(inca)) > - std::numeric_limits::epsilon()) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl + << "Derived Grid.Col.UVectECF: " + << derivedRowUnitVector(inca, scp, arpPoly); + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.4.8 + if (col->kCenter != 0) + { + messageBuilder.str(""); + messageBuilder << "Grid.Col.KCtr must be zero " + << "for RMA/INCA data." << std::endl + << "Grid.Col.KCtr: " << col->kCenter; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.12.3.4.11 + if (Init::isUndefined(fc) && + std::abs(row->kCenter - derivedRowKCenter(inca)) > + std::numeric_limits::epsilon()) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl << "RMA.INCA.FreqZero * 2 / c: " << derivedRowKCenter(inca) - << std::endl << "Grid.Row.KCenter: " << row->kCenter; - log.error(messageBuilder.str()); - valid = false; + << std::endl << "Grid.Row.KCenter: " << row->kCenter; + log.error(messageBuilder.str()); + valid = false; } return valid; } @@ -1061,138 +1061,138 @@ bool Grid::validate(const PFA& pfa, const RadarCollection& radarCollection, std::ostringstream messageBuilder; const double& epsilon = std::numeric_limits::epsilon(); - //2.12.2.1 - if (type != ComplexImageGridType::RGAZIM) - { - messageBuilder.str(""); - messageBuilder << "PFA image formation should result in a RGAZIM grid." - << std::endl << "Grid.Type: " << type; - log.error(messageBuilder.str()); - valid = false; - } - - // Make sure Row.kCtr is consistent with processed RF frequency bandwidth - if (Init::isUndefined(radarCollection.refFrequencyIndex) && - !Init::isUndefined(fc)) - { - // PFA.SpatialFreqSFPoly affects Row.KCtr - const auto kapCtr = fc * pfa.spatialFrequencyScaleFactorPoly[0] * - 2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC; - - // PFA inscription could cause kapCtr and Row.KCtr - // to be somewhat different - const auto theta = std::atan((col->impulseResponseBandwidth / 2) / - row->kCenter); - double kCtrTol = 1 - std::cos(theta); - kCtrTol = std::max(0.01, kCtrTol); - - if (std::abs(row->kCenter / kapCtr - 1) > kCtrTol) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR - << "Grid.Row.KCtr: " << row->kCenter << std::endl - << "Derived KapCtr: " << kapCtr; - log.error(messageBuilder.str()); - valid = false; - } - } - - //Slow-time deskew would allow for PFA.Kaz2-PFA.Kaz1>(1/Grid.Col.SS), - //since Kaz bandwidth is compressed from original polar annulus. + //2.12.2.1 + if (type != ComplexImageGridType::RGAZIM) + { + messageBuilder.str(""); + messageBuilder << "PFA image formation should result in a RGAZIM grid." + << std::endl << "Grid.Type: " << type; + log.error(messageBuilder.str()); + valid = false; + } + + // Make sure Row.kCtr is consistent with processed RF frequency bandwidth + if (Init::isUndefined(radarCollection.refFrequencyIndex) && + !Init::isUndefined(fc)) + { + // PFA.SpatialFreqSFPoly affects Row.KCtr + const auto kapCtr = fc * pfa.spatialFrequencyScaleFactorPoly[0] * + 2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC; + + // PFA inscription could cause kapCtr and Row.KCtr + // to be somewhat different + const auto theta = std::atan((col->impulseResponseBandwidth / 2) / + row->kCenter); + double kCtrTol = 1 - std::cos(theta); + kCtrTol = std::max(0.01, kCtrTol); + + if (std::abs(row->kCenter / kapCtr - 1) > kCtrTol) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR + << "Grid.Row.KCtr: " << row->kCenter << std::endl + << "Derived KapCtr: " << kapCtr; + log.error(messageBuilder.str()); + valid = false; + } + } + + //Slow-time deskew would allow for PFA.Kaz2-PFA.Kaz1>(1/Grid.Col.SS), + //since Kaz bandwidth is compressed from original polar annulus. if (pfa.slowTimeDeskew.get() != nullptr && - pfa.slowTimeDeskew->applied != BooleanType::IS_TRUE) - { - //2.3.10 - if ((pfa.kaz2 - col->kCenter) > - (1 / (2 * col->sampleSpacing)) + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Col.SampleSpacing: " - << 0.5 / col->sampleSpacing << std::endl - << "PFA.Kaz2 - Grid.Col.KCenter: " - << pfa.kaz2 - col->kCenter << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - //2.3.11 - if ((pfa.kaz1 - col->kCenter) < - (-1 / (2 * col->sampleSpacing)) - epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Col.SampleSpacing: " - << 0.5 / col->sampleSpacing << std::endl - << "PFA.Kaz1 - Grid.Col.KCenter: " - << pfa.kaz1 - col->kCenter << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - } - - //2.3.12 - if ((pfa.krg2 - row->kCenter) > - (1 / (2 * row->sampleSpacing)) + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Row.SampleSpacing: " - << 0.5 / row->sampleSpacing << std::endl - << "PFA.Krg2 - Grid.Row.KCenter: " - << pfa.krg2 - row->kCenter << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.3.13 - if (pfa.krg1 - row->kCenter < - (-1 / (2 * row->sampleSpacing)) - epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "0.5/SICD.Grid.Row.SampleSpacing: " - << 0.5 / row->sampleSpacing << std::endl - << "PFA.Krg1 - Grid.Row.KCenter: " - << pfa.krg1 - row->kCenter << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.3.14 - if (col->impulseResponseBandwidth > pfa.kaz2 - pfa.kaz1 + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "Grid.Col.ImpulseResponseBandwidth: " - << col->impulseResponseBandwidth << std::endl - << "SICD.PFA.Kaz2 - SICD.PFA.Kaz1: " - << pfa.kaz2 - pfa.kaz1 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - //2.3.15 - if (row->impulseResponseBandwidth > pfa.krg2 - pfa.krg1 + epsilon) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "Grid.Row.ImpulseResponseBandwidth: " - << row->impulseResponseBandwidth << std::endl - << "SICD.PFA.Krg2 - SICD.PFA.Krg1: " - << pfa.krg2 - pfa.krg1 << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - //2.3.16 - if (col->kCenter != 0 && - std::abs(col->kCenter - (pfa.kaz1 + pfa.kaz2) / 2) > 1e-5) - { - messageBuilder.str(""); - messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl - << "Grid.Col.KCenter: " << col->kCenter << std::endl - << "mean(SICD.PFA.Kaz1, SICD.PFA.Kaz2): " - << (pfa.kaz1 + pfa.kaz2) / 2 << std::endl; - log.error(messageBuilder.str()); - valid = false; + pfa.slowTimeDeskew->applied != BooleanType::IS_TRUE) + { + //2.3.10 + if ((pfa.kaz2 - col->kCenter) > + (1 / (2 * col->sampleSpacing)) + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Col.SampleSpacing: " + << 0.5 / col->sampleSpacing << std::endl + << "PFA.Kaz2 - Grid.Col.KCenter: " + << pfa.kaz2 - col->kCenter << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + //2.3.11 + if ((pfa.kaz1 - col->kCenter) < + (-1 / (2 * col->sampleSpacing)) - epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Col.SampleSpacing: " + << 0.5 / col->sampleSpacing << std::endl + << "PFA.Kaz1 - Grid.Col.KCenter: " + << pfa.kaz1 - col->kCenter << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + } + + //2.3.12 + if ((pfa.krg2 - row->kCenter) > + (1 / (2 * row->sampleSpacing)) + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Row.SampleSpacing: " + << 0.5 / row->sampleSpacing << std::endl + << "PFA.Krg2 - Grid.Row.KCenter: " + << pfa.krg2 - row->kCenter << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.3.13 + if (pfa.krg1 - row->kCenter < + (-1 / (2 * row->sampleSpacing)) - epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "0.5/SICD.Grid.Row.SampleSpacing: " + << 0.5 / row->sampleSpacing << std::endl + << "PFA.Krg1 - Grid.Row.KCenter: " + << pfa.krg1 - row->kCenter << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.3.14 + if (col->impulseResponseBandwidth > pfa.kaz2 - pfa.kaz1 + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "Grid.Col.ImpulseResponseBandwidth: " + << col->impulseResponseBandwidth << std::endl + << "SICD.PFA.Kaz2 - SICD.PFA.Kaz1: " + << pfa.kaz2 - pfa.kaz1 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + //2.3.15 + if (row->impulseResponseBandwidth > pfa.krg2 - pfa.krg1 + epsilon) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "Grid.Row.ImpulseResponseBandwidth: " + << row->impulseResponseBandwidth << std::endl + << "SICD.PFA.Krg2 - SICD.PFA.Krg1: " + << pfa.krg2 - pfa.krg1 << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + //2.3.16 + if (col->kCenter != 0 && + std::abs(col->kCenter - (pfa.kaz1 + pfa.kaz2) / 2) > 1e-5) + { + messageBuilder.str(""); + messageBuilder << BOUNDS_ERROR_MESSAGE << std::endl + << "Grid.Col.KCenter: " << col->kCenter << std::endl + << "mean(SICD.PFA.Kaz1, SICD.PFA.Kaz2): " + << (pfa.kaz1 + pfa.kaz2) / 2 << std::endl; + log.error(messageBuilder.str()); + valid = false; } return valid; @@ -1206,59 +1206,59 @@ bool Grid::validate(const RgAzComp& rgAzComp, { bool valid = true; std::ostringstream messageBuilder; - - // 2.12.1.1 - if (imagePlane != ComplexImagePlaneType::SLANT) - { - messageBuilder.str(""); - messageBuilder << - "RGAZCOMP image formation should result in a SLANT plane image." - << std::endl << "Grid.ImagePlane: " << imagePlane; - log.error(messageBuilder.str()); - valid = false; - } - - //2.12.1.2 - if (type != ComplexImageGridType::RGAZIM) - { - messageBuilder.str(""); - messageBuilder << - "RGAZCOMP image formation should result in a RGAZIM grid." - << std::endl << "Grid.Type: " << type; - log.error(messageBuilder.str()); - valid = false; - } - - //2.12.1.8 - const Vector3& scp = geoData.scp.ecf; + + // 2.12.1.1 + if (imagePlane != ComplexImagePlaneType::SLANT) + { + messageBuilder.str(""); + messageBuilder << + "RGAZCOMP image formation should result in a SLANT plane image." + << std::endl << "Grid.ImagePlane: " << imagePlane; + log.error(messageBuilder.str()); + valid = false; + } + + //2.12.1.2 + if (type != ComplexImageGridType::RGAZIM) + { + messageBuilder.str(""); + messageBuilder << + "RGAZCOMP image formation should result in a RGAZIM grid." + << std::endl << "Grid.Type: " << type; + log.error(messageBuilder.str()); + valid = false; + } + + //2.12.1.8 + const Vector3& scp = geoData.scp.ecf; valid = col->validate(rgAzComp, log) && valid; valid = row->validate(rgAzComp, log, fc *(2 / math::Constants::SPEED_OF_LIGHT_METERS_PER_SEC)) && valid; - //2.12.1.6 - if ((derivedRowUnitVector(scpcoa, scp) - row->unitVector).norm() - > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl - << "Grid.Row.UVectECEF: " << row->unitVector << std::endl - << "Derived Grid.Row.UVectECEF: " << - derivedRowUnitVector(scpcoa, scp); - log.error(messageBuilder.str()); - valid = false; - } - - //2.12.1.7 - if ((derivedColUnitVector(scpcoa, scp) - col->unitVector).norm() - > UVECT_TOL) - { - messageBuilder.str(""); - messageBuilder << "UVect fields inconsistent." << std::endl - << "Grid.Col.UVectECF: " << col->unitVector << std::endl - << "Derived Grid.Col.UVectECF: " << - derivedColUnitVector(scpcoa, scp); - log.error(messageBuilder.str()); - valid = false; + //2.12.1.6 + if ((derivedRowUnitVector(scpcoa, scp) - row->unitVector).norm() + > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl + << "Grid.Row.UVectECEF: " << row->unitVector << std::endl + << "Derived Grid.Row.UVectECEF: " << + derivedRowUnitVector(scpcoa, scp); + log.error(messageBuilder.str()); + valid = false; + } + + //2.12.1.7 + if ((derivedColUnitVector(scpcoa, scp) - col->unitVector).norm() + > UVECT_TOL) + { + messageBuilder.str(""); + messageBuilder << "UVect fields inconsistent." << std::endl + << "Grid.Col.UVectECF: " << col->unitVector << std::endl + << "Derived Grid.Col.UVectECF: " << + derivedColUnitVector(scpcoa, scp); + log.error(messageBuilder.str()); + valid = false; } return valid; diff --git a/six/modules/c++/six.sicd/source/ImageData.cpp b/six/modules/c++/six.sicd/source/ImageData.cpp index 3e35f81d69..147383a979 100644 --- a/six/modules/c++/six.sicd/source/ImageData.cpp +++ b/six/modules/c++/six.sicd/source/ImageData.cpp @@ -1,278 +1,278 @@ -/* ========================================================================= - * This file is part of six.sicd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2014, MDA Information Systems LLC - * - * six.sicd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include "six/sicd/ImageData.h" - -#include -#include -#include -#include // std::ignore -#include -#include -#include - -#include -#include -#include -#if CODA_OSS_cpp17 - // is broken with the older version of GCC we're using - #if (__GNUC__ >= 10) || _MSC_VER - #include - #define SIX_six_sicd_ImageData_has_execution 1 - #endif -#endif - -#include "six/AmplitudeTable.h" -#include "six/sicd/GeoData.h" -#include "six/sicd/Utilities.h" - -using namespace six; -using namespace six::sicd; - - // This was in coda-oss, but I removed it. - // - // First of all, C++11's std::async() is now (in 2023) thought of as maybe a - // bit "half baked," and perhaps shouldn't be emulated. Then, C++17 added - // parallel algorithms which might be a better way of satisfying our immediate - // needs (below) ... although we're still at C++14. -template -static inline OutputIt transform_async(const InputIt first1, const InputIt last1, OutputIt d_first, TFunc f, - typename std::iterator_traits::difference_type cutoff) -{ - // https://en.cppreference.com/w/cpp/thread/async - const auto len = std::distance(first1, last1); - if (len < cutoff) - { - return std::transform(first1, last1, d_first, f); - } - - constexpr auto policy = std::launch::async; - - const auto mid1 = first1 + len / 2; - const auto d_mid = d_first + len / 2; - auto handle = std::async(policy, transform_async, mid1, last1, d_mid, f, cutoff); - transform_async(first1, mid1, d_first, f, cutoff); - return handle.get(); -} -template -static inline void transform(std::span inputs, std::span results, TFunc f) -{ -#if SIX_six_sicd_ImageData_has_execution - std::ignore = std::transform(std::execution::par, inputs.begin(), inputs.end(), results.begin(), f); -#else - constexpr ptrdiff_t cutoff_ = 0; // too slow w/o multi-threading - //if (cutoff_ < 0) - //{ - // std::ignore = std::transform(inputs.begin(), inputs.end(), results.begin(), f); - //} - //else - { - // The value of "default_cutoff" was determined by testing; there is nothing special about it, feel free to change it. - constexpr auto dimension = 128 * 8; - constexpr auto default_cutoff = dimension * dimension; - const auto cutoff = cutoff_ == 0 ? default_cutoff : cutoff_; - - std::ignore = transform_async(inputs.begin(), inputs.end(), results.begin(), f, cutoff); - } -#endif // CODA_OSS_cpp17 -} - -bool ImageData::operator==(const ImageData& rhs) const -{ - return (pixelType == rhs.pixelType && - amplitudeTable == rhs.amplitudeTable && - numRows == rhs.numRows && - numCols == rhs.numCols && - firstRow == rhs.firstRow && - firstCol == rhs.firstCol && - fullImage == rhs.fullImage && - scpPixel == rhs.scpPixel && - validData == rhs.validData); -} - -bool ImageData::validate(const GeoData& geoData, logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - // 2.11.1 - if (!validData.empty() && geoData.validData.empty()) - { - messageBuilder << "ImageData.ValidData/GeoData.ValidData " - << "required together." << std::endl - << "ImageData.ValidData exists, but GeoData.ValidData does not."; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.11.2 - if (validData.empty() && !geoData.validData.empty()) - { - messageBuilder << "ImageData.ValidData/GeoData.ValidData " - << "required together." << std::endl - << "GeoData.ValidData exists, but ImageData.ValidData does not."; - log.error(messageBuilder.str()); - valid = false; - } - - // 2.11.3 In ValidData, first vertex should have (1) minimum row index - // and (2) minimum column index if 2 vertices exist with equal minimum - // row index. - if (!validData.empty()) - { - bool minimumRowComesFirst = true; - - for (size_t ii = 1; ii < validData.size(); ++ii) - { - if (validData[ii].row < validData[0].row) - { - minimumRowComesFirst = false; - break; - } - } - if (!minimumRowComesFirst) - { - messageBuilder << "ImageData.ValidData first row should have" - << "minimum row index"; - log.error(messageBuilder.str()); - valid = false; - } - else - { - bool minimumColComesFirst = true; - std::vector minimumIndices; - for (size_t ii = 0; ii < validData.size(); ++ii) - { - if (validData[0].row == validData[ii].row && - validData[ii].col < validData[0].col) - { - minimumColComesFirst = false; - break; - } - } - if (!minimumColComesFirst) - { - messageBuilder << "ImageData.ValidData first col of matching" - << "minimum row index should have minimum col index"; - log.error(messageBuilder.str()); - valid = false; - } - } - if (!Utilities::isClockwise(validData)) - { - messageBuilder << "ImageData.ValidData should be arrange clockwise"; - log.error(messageBuilder.str()); - valid = false; - } - } - - return valid; -} - -template -static auto createLookup(TToComplexFunc toComplex) -{ - auto retval = std::make_unique(); // too big for the stack - auto& values = *retval; - - // For all possible amp/phase values (there are "only" 256*256=65536), get and save the - // complex value. - for (const auto amplitude : Utilities::iota_0_256()) - { - for (const auto phase : Utilities::iota_0_256()) - { - values[amplitude][phase] = toComplex(amplitude, phase); - } - } - - return retval; -} -static auto createLookup(const six::AmplitudeTable& amplitudeTable) -{ - const auto toComplex = [&litudeTable](auto amplitude, auto phase) { - return six::sicd::Utilities::toComplex(amplitude, phase, amplitudeTable); - }; - return createLookup(toComplex); -} -static auto createLookup() -{ - static const auto toComplex = [](auto amplitude, auto phase) { - return six::sicd::Utilities::toComplex(amplitude, phase); - }; - return createLookup(toComplex); -} - -static const six::Amp8iPhs8iLookup_t* getCachedLookup(const six::AmplitudeTable* pAmplitudeTable) -{ - if (pAmplitudeTable == nullptr) - { - static const auto lookup_no_table = createLookup(); - return lookup_no_table.get(); - } - - // Maybe one has already been created and stored on the table? - return pAmplitudeTable->getLookup(); -} - -const six::Amp8iPhs8iLookup_t& ImageData::getLookup(const six::AmplitudeTable* pAmplitudeTable) -{ - auto pLookup = getCachedLookup(pAmplitudeTable); - if (pLookup == nullptr) - { - assert(pAmplitudeTable != nullptr); - auto& amplitudeTable = *pAmplitudeTable; - auto lookup = createLookup(amplitudeTable); - amplitudeTable.cacheLookup_(std::move(lookup)); - pLookup = amplitudeTable.getLookup(); - } - assert(pLookup != nullptr); - return *pLookup; -} - -void ImageData::toComplex(const six::Amp8iPhs8iLookup_t& values, std::span inputs, std::span results) -{ - const auto toComplex_ = [&values](const auto& v) - { - return values[v.amplitude][v.phase]; - }; - transform(inputs, results, toComplex_); -} -void ImageData::toComplex(std::span inputs, std::span results) const -{ - if (pixelType != PixelType::AMP8I_PHS8I) - { - throw std::runtime_error("pxielType must be AMP8I_PHS8I"); - } - - const auto& values = getLookup(amplitudeTable.get()); - toComplex(values, inputs, results); -} - -void ImageData::fromComplex(std::span inputs, std::span results) const -{ - six::sicd::details::ComplexToAMP8IPHS8I::nearest_neighbors(inputs, results, amplitudeTable.get()); -} -void ImageData::testing_fromComplex_(std::span inputs, std::span results) -{ - static const ImageData imageData; - assert(imageData.amplitudeTable.get() == nullptr); - imageData.fromComplex(inputs, results); -} +/* ========================================================================= + * This file is part of six.sicd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * six.sicd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include "six/sicd/ImageData.h" + +#include +#include +#include +#include // std::ignore +#include +#include +#include + +#include +#include +#include +#if CODA_OSS_cpp17 + // is broken with the older version of GCC we're using + #if (__GNUC__ >= 10) || _MSC_VER + #include + #define SIX_six_sicd_ImageData_has_execution 1 + #endif +#endif + +#include "six/AmplitudeTable.h" +#include "six/sicd/GeoData.h" +#include "six/sicd/Utilities.h" + +using namespace six; +using namespace six::sicd; + + // This was in coda-oss, but I removed it. + // + // First of all, C++11's std::async() is now (in 2023) thought of as maybe a + // bit "half baked," and perhaps shouldn't be emulated. Then, C++17 added + // parallel algorithms which might be a better way of satisfying our immediate + // needs (below) ... although we're still at C++14. +template +static inline OutputIt transform_async(const InputIt first1, const InputIt last1, OutputIt d_first, TFunc f, + typename std::iterator_traits::difference_type cutoff) +{ + // https://en.cppreference.com/w/cpp/thread/async + const auto len = std::distance(first1, last1); + if (len < cutoff) + { + return std::transform(first1, last1, d_first, f); + } + + constexpr auto policy = std::launch::async; + + const auto mid1 = first1 + len / 2; + const auto d_mid = d_first + len / 2; + auto handle = std::async(policy, transform_async, mid1, last1, d_mid, f, cutoff); + transform_async(first1, mid1, d_first, f, cutoff); + return handle.get(); +} +template +static inline void transform(std::span inputs, std::span results, TFunc f) +{ +#if SIX_six_sicd_ImageData_has_execution + std::ignore = std::transform(std::execution::par, inputs.begin(), inputs.end(), results.begin(), f); +#else + constexpr ptrdiff_t cutoff_ = 0; // too slow w/o multi-threading + //if (cutoff_ < 0) + //{ + // std::ignore = std::transform(inputs.begin(), inputs.end(), results.begin(), f); + //} + //else + { + // The value of "default_cutoff" was determined by testing; there is nothing special about it, feel free to change it. + constexpr auto dimension = 128 * 8; + constexpr auto default_cutoff = dimension * dimension; + const auto cutoff = cutoff_ == 0 ? default_cutoff : cutoff_; + + std::ignore = transform_async(inputs.begin(), inputs.end(), results.begin(), f, cutoff); + } +#endif // CODA_OSS_cpp17 +} + +bool ImageData::operator==(const ImageData& rhs) const +{ + return (pixelType == rhs.pixelType && + amplitudeTable == rhs.amplitudeTable && + numRows == rhs.numRows && + numCols == rhs.numCols && + firstRow == rhs.firstRow && + firstCol == rhs.firstCol && + fullImage == rhs.fullImage && + scpPixel == rhs.scpPixel && + validData == rhs.validData); +} + +bool ImageData::validate(const GeoData& geoData, logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + // 2.11.1 + if (!validData.empty() && geoData.validData.empty()) + { + messageBuilder << "ImageData.ValidData/GeoData.ValidData " + << "required together." << std::endl + << "ImageData.ValidData exists, but GeoData.ValidData does not."; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.11.2 + if (validData.empty() && !geoData.validData.empty()) + { + messageBuilder << "ImageData.ValidData/GeoData.ValidData " + << "required together." << std::endl + << "GeoData.ValidData exists, but ImageData.ValidData does not."; + log.error(messageBuilder.str()); + valid = false; + } + + // 2.11.3 In ValidData, first vertex should have (1) minimum row index + // and (2) minimum column index if 2 vertices exist with equal minimum + // row index. + if (!validData.empty()) + { + bool minimumRowComesFirst = true; + + for (size_t ii = 1; ii < validData.size(); ++ii) + { + if (validData[ii].row < validData[0].row) + { + minimumRowComesFirst = false; + break; + } + } + if (!minimumRowComesFirst) + { + messageBuilder << "ImageData.ValidData first row should have" + << "minimum row index"; + log.error(messageBuilder.str()); + valid = false; + } + else + { + bool minimumColComesFirst = true; + std::vector minimumIndices; + for (size_t ii = 0; ii < validData.size(); ++ii) + { + if (validData[0].row == validData[ii].row && + validData[ii].col < validData[0].col) + { + minimumColComesFirst = false; + break; + } + } + if (!minimumColComesFirst) + { + messageBuilder << "ImageData.ValidData first col of matching" + << "minimum row index should have minimum col index"; + log.error(messageBuilder.str()); + valid = false; + } + } + if (!Utilities::isClockwise(validData)) + { + messageBuilder << "ImageData.ValidData should be arrange clockwise"; + log.error(messageBuilder.str()); + valid = false; + } + } + + return valid; +} + +template +static auto createLookup(TToComplexFunc toComplex) +{ + auto retval = std::make_unique(); // too big for the stack + auto& values = *retval; + + // For all possible amp/phase values (there are "only" 256*256=65536), get and save the + // complex value. + for (const auto amplitude : Utilities::iota_0_256()) + { + for (const auto phase : Utilities::iota_0_256()) + { + values[amplitude][phase] = toComplex(amplitude, phase); + } + } + + return retval; +} +static auto createLookup(const six::AmplitudeTable& amplitudeTable) +{ + const auto toComplex = [&litudeTable](auto amplitude, auto phase) { + return six::sicd::Utilities::toComplex(amplitude, phase, amplitudeTable); + }; + return createLookup(toComplex); +} +static auto createLookup() +{ + static const auto toComplex = [](auto amplitude, auto phase) { + return six::sicd::Utilities::toComplex(amplitude, phase); + }; + return createLookup(toComplex); +} + +static const six::Amp8iPhs8iLookup_t* getCachedLookup(const six::AmplitudeTable* pAmplitudeTable) +{ + if (pAmplitudeTable == nullptr) + { + static const auto lookup_no_table = createLookup(); + return lookup_no_table.get(); + } + + // Maybe one has already been created and stored on the table? + return pAmplitudeTable->getLookup(); +} + +const six::Amp8iPhs8iLookup_t& ImageData::getLookup(const six::AmplitudeTable* pAmplitudeTable) +{ + auto pLookup = getCachedLookup(pAmplitudeTable); + if (pLookup == nullptr) + { + assert(pAmplitudeTable != nullptr); + auto& amplitudeTable = *pAmplitudeTable; + auto lookup = createLookup(amplitudeTable); + amplitudeTable.cacheLookup_(std::move(lookup)); + pLookup = amplitudeTable.getLookup(); + } + assert(pLookup != nullptr); + return *pLookup; +} + +void ImageData::toComplex(const six::Amp8iPhs8iLookup_t& values, std::span inputs, std::span results) +{ + const auto toComplex_ = [&values](const auto& v) + { + return values[v.amplitude][v.phase]; + }; + transform(inputs, results, toComplex_); +} +void ImageData::toComplex(std::span inputs, std::span results) const +{ + if (pixelType != PixelType::AMP8I_PHS8I) + { + throw std::runtime_error("pxielType must be AMP8I_PHS8I"); + } + + const auto& values = getLookup(amplitudeTable.get()); + toComplex(values, inputs, results); +} + +void ImageData::fromComplex(std::span inputs, std::span results) const +{ + six::sicd::details::ComplexToAMP8IPHS8I::nearest_neighbors(inputs, results, amplitudeTable.get()); +} +void ImageData::testing_fromComplex_(std::span inputs, std::span results) +{ + static const ImageData imageData; + assert(imageData.amplitudeTable.get() == nullptr); + imageData.fromComplex(inputs, results); +} diff --git a/six/modules/c++/six.sicd/source/NITFReadComplexXMLControl.cpp b/six/modules/c++/six.sicd/source/NITFReadComplexXMLControl.cpp index 0f8327f01e..bad638fffc 100644 --- a/six/modules/c++/six.sicd/source/NITFReadComplexXMLControl.cpp +++ b/six/modules/c++/six.sicd/source/NITFReadComplexXMLControl.cpp @@ -1,129 +1,129 @@ -/* ========================================================================= - * This file is part of six.sicd-c++ - * ========================================================================= - * - * (C) Copyright 2021 Maxar Technologies, Inc. - * - * six.sicd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include "six/sicd/NITFReadComplexXMLControl.h" - -#include -#include -#include - -#include "six/sicd/ComplexXMLControl.h" -#include "six/sicd/Utilities.h" - -namespace fs = std::filesystem; - -six::sicd::NITFReadComplexXMLControl::NITFReadComplexXMLControl() -{ - // create an XML registry - // The reason to do this is to avoid adding XMLControlCreators to the - // XMLControlFactory singleton - this way has more fine-grained control - addCreator(); -} - -void six::sicd::NITFReadComplexXMLControl::load(const std::string& fromFile, - const std::vector* pSchemaPaths) -{ - reader.load(fromFile, pSchemaPaths); -} -void six::sicd::NITFReadComplexXMLControl::load(const std::filesystem::path& fromFile, - const std::vector* pSchemaPaths) -{ - reader.load(fromFile, pSchemaPaths); -} -void six::sicd::NITFReadComplexXMLControl::load(io::FileInputStream& fis, const std::vector* pSchemaPaths) -{ - reader.load(fis, pSchemaPaths); -} -void six::sicd::NITFReadComplexXMLControl::load(io::FileInputStream& fis, const std::vector* pSchemaPaths) -{ - reader.load(fis, pSchemaPaths); -} - - -std::shared_ptr six::sicd::NITFReadComplexXMLControl::getContainer() const -{ - return reader.getContainer(); -} -std::shared_ptr six::sicd::NITFReadComplexXMLControl::getContainer() -{ - return reader.getContainer(); -} - -void six::sicd::NITFReadComplexXMLControl::setXMLControlRegistry() -{ - // This tells the reader that it doesn't own an XMLControlRegistry - reader.setXMLControlRegistry(nullptr); -} - -std::unique_ptr six::sicd::NITFReadComplexXMLControl::getComplexData() -{ - auto result = Utilities::getComplexData(reader); - return std::unique_ptr< six::sicd::ComplexData>(result.release()); -} - -std::vector six::sicd::NITFReadComplexXMLControl::getWidebandData(const ComplexData& complexData) -{ - std::vector retval; - Utilities::getWidebandData(reader, complexData, retval); - return retval; -} -void six::sicd::NITFReadComplexXMLControl::getWidebandData(const ComplexData& complexData, - const types::RowCol& offset, const types::RowCol& extent, - six::zfloat* buffer) -{ - Utilities::getWidebandData(reader, complexData, offset, extent, buffer); -} - -void six::sicd::NITFReadComplexXMLControl::setLogger() -{ - reader.setLogger(std::make_unique()); -} - -void six::sicd::NITFReadComplexXMLControl::interleaved(Region& region) -{ - constexpr size_t imageNumber = 0; - (void)reader.interleaved(region, imageNumber); -} - -std::vector six::sicd::NITFReadComplexXMLControl::interleaved() -{ - auto pComplexData = getComplexData(); - const auto extent = getExtent(*pComplexData); - const auto numPixels = extent.area(); - const auto numBytesPerPixel = pComplexData->getNumBytesPerPixel(); - size_t offset = 0; - - std::vector buffer(numPixels * numBytesPerPixel); - - six::Region region; - setDims(region, extent); - region.setBuffer(buffer.data() + offset); - interleaved(region); - - return buffer; -} - -void six::sicd::NITFReadComplexXMLControl::getMeshes(std::unique_ptr& noiseMesh, - std::unique_ptr& scalarMesh) const -{ - noiseMesh = Utilities::getNoiseMesh(reader); - scalarMesh = Utilities::getScalarMesh(reader); -} +/* ========================================================================= + * This file is part of six.sicd-c++ + * ========================================================================= + * + * (C) Copyright 2021 Maxar Technologies, Inc. + * + * six.sicd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include "six/sicd/NITFReadComplexXMLControl.h" + +#include +#include +#include + +#include "six/sicd/ComplexXMLControl.h" +#include "six/sicd/Utilities.h" + +namespace fs = std::filesystem; + +six::sicd::NITFReadComplexXMLControl::NITFReadComplexXMLControl() +{ + // create an XML registry + // The reason to do this is to avoid adding XMLControlCreators to the + // XMLControlFactory singleton - this way has more fine-grained control + addCreator(); +} + +void six::sicd::NITFReadComplexXMLControl::load(const std::string& fromFile, + const std::vector* pSchemaPaths) +{ + reader.load(fromFile, pSchemaPaths); +} +void six::sicd::NITFReadComplexXMLControl::load(const std::filesystem::path& fromFile, + const std::vector* pSchemaPaths) +{ + reader.load(fromFile, pSchemaPaths); +} +void six::sicd::NITFReadComplexXMLControl::load(io::FileInputStream& fis, const std::vector* pSchemaPaths) +{ + reader.load(fis, pSchemaPaths); +} +void six::sicd::NITFReadComplexXMLControl::load(io::FileInputStream& fis, const std::vector* pSchemaPaths) +{ + reader.load(fis, pSchemaPaths); +} + + +std::shared_ptr six::sicd::NITFReadComplexXMLControl::getContainer() const +{ + return reader.getContainer(); +} +std::shared_ptr six::sicd::NITFReadComplexXMLControl::getContainer() +{ + return reader.getContainer(); +} + +void six::sicd::NITFReadComplexXMLControl::setXMLControlRegistry() +{ + // This tells the reader that it doesn't own an XMLControlRegistry + reader.setXMLControlRegistry(nullptr); +} + +std::unique_ptr six::sicd::NITFReadComplexXMLControl::getComplexData() +{ + auto result = Utilities::getComplexData(reader); + return std::unique_ptr< six::sicd::ComplexData>(result.release()); +} + +std::vector six::sicd::NITFReadComplexXMLControl::getWidebandData(const ComplexData& complexData) +{ + std::vector retval; + Utilities::getWidebandData(reader, complexData, retval); + return retval; +} +void six::sicd::NITFReadComplexXMLControl::getWidebandData(const ComplexData& complexData, + const types::RowCol& offset, const types::RowCol& extent, + six::zfloat* buffer) +{ + Utilities::getWidebandData(reader, complexData, offset, extent, buffer); +} + +void six::sicd::NITFReadComplexXMLControl::setLogger() +{ + reader.setLogger(std::make_unique()); +} + +void six::sicd::NITFReadComplexXMLControl::interleaved(Region& region) +{ + constexpr size_t imageNumber = 0; + (void)reader.interleaved(region, imageNumber); +} + +std::vector six::sicd::NITFReadComplexXMLControl::interleaved() +{ + auto pComplexData = getComplexData(); + const auto extent = getExtent(*pComplexData); + const auto numPixels = extent.area(); + const auto numBytesPerPixel = pComplexData->getNumBytesPerPixel(); + size_t offset = 0; + + std::vector buffer(numPixels * numBytesPerPixel); + + six::Region region; + setDims(region, extent); + region.setBuffer(buffer.data() + offset); + interleaved(region); + + return buffer; +} + +void six::sicd::NITFReadComplexXMLControl::getMeshes(std::unique_ptr& noiseMesh, + std::unique_ptr& scalarMesh) const +{ + noiseMesh = Utilities::getNoiseMesh(reader); + scalarMesh = Utilities::getScalarMesh(reader); +} diff --git a/six/modules/c++/six.sicd/source/PFA.cpp b/six/modules/c++/six.sicd/source/PFA.cpp index 892b415532..4e3d94d27c 100644 --- a/six/modules/c++/six.sicd/source/PFA.cpp +++ b/six/modules/c++/six.sicd/source/PFA.cpp @@ -21,13 +21,13 @@ */ #include "six/sicd/GeoData.h" #include "six/sicd/Grid.h" -#include "six/sicd/PFA.h" -#include "six/sicd/Position.h" -#include "six/sicd/SCPCOA.h" +#include "six/sicd/PFA.h" +#include "six/sicd/Position.h" +#include "six/sicd/SCPCOA.h" #include "six/sicd/Utilities.h" - + namespace six -{ +{ namespace sicd { SlowTimeDeskew::SlowTimeDeskew() : @@ -44,91 +44,91 @@ PFA::PFA() : kaz1(Init::undefined()), kaz2(Init::undefined()) { -} - -bool PFA::operator==(const PFA& rhs) const -{ - return (focusPlaneNormal == rhs.focusPlaneNormal && - imagePlaneNormal == rhs.imagePlaneNormal && - polarAngleRefTime == rhs.polarAngleRefTime && - polarAnglePoly == rhs.polarAnglePoly && - spatialFrequencyScaleFactorPoly == rhs.spatialFrequencyScaleFactorPoly && - krg1 == rhs.krg1 && - krg2 == rhs.krg2 && - kaz1 == rhs.kaz1 && - kaz2 == rhs.kaz2 && - slowTimeDeskew == rhs.slowTimeDeskew); -} - -void PFA::fillDerivedFields(const Position& position) -{ - if (!Init::isUndefined(position.arpPoly) && - !Init::isUndefined(polarAngleRefTime)) - { - // This doesn't actually do anything currently. - // Requires re-implemenation of polyfit, pfa_polar_coords, and bsxfun - const Vector3 polRefPos = position.arpPoly(polarAngleRefTime); - } -} - -void PFA::fillDefaultFields(const GeoData& geoData, - const Grid& grid, const SCPCOA& scpcoa) -{ - const Vector3& scp = geoData.scp.ecf; - if (Init::isUndefined(imagePlaneNormal)) - { +} + +bool PFA::operator==(const PFA& rhs) const +{ + return (focusPlaneNormal == rhs.focusPlaneNormal && + imagePlaneNormal == rhs.imagePlaneNormal && + polarAngleRefTime == rhs.polarAngleRefTime && + polarAnglePoly == rhs.polarAnglePoly && + spatialFrequencyScaleFactorPoly == rhs.spatialFrequencyScaleFactorPoly && + krg1 == rhs.krg1 && + krg2 == rhs.krg2 && + kaz1 == rhs.kaz1 && + kaz2 == rhs.kaz2 && + slowTimeDeskew == rhs.slowTimeDeskew); +} + +void PFA::fillDerivedFields(const Position& position) +{ + if (!Init::isUndefined(position.arpPoly) && + !Init::isUndefined(polarAngleRefTime)) + { + // This doesn't actually do anything currently. + // Requires re-implemenation of polyfit, pfa_polar_coords, and bsxfun + const Vector3 polRefPos = position.arpPoly(polarAngleRefTime); + } +} + +void PFA::fillDefaultFields(const GeoData& geoData, + const Grid& grid, const SCPCOA& scpcoa) +{ + const Vector3& scp = geoData.scp.ecf; + if (Init::isUndefined(imagePlaneNormal)) + { scene::WGS84EllipsoidModel model; - switch (grid.imagePlane) - { - case ComplexImagePlaneType::SLANT: - case ComplexImagePlaneType::NOT_SET: - imagePlaneNormal = scpcoa.slantPlaneNormal(scp); - break; - case ComplexImagePlaneType::GROUND: + switch (grid.imagePlane) + { + case ComplexImagePlaneType::SLANT: + case ComplexImagePlaneType::NOT_SET: + imagePlaneNormal = scpcoa.slantPlaneNormal(scp); + break; + case ComplexImagePlaneType::GROUND: imagePlaneNormal = model.getNormalVector(scp); - break; - case ComplexImagePlaneType::OTHER: - default: - // Nothing we can do - break; - } - } - - if (Init::isUndefined(focusPlaneNormal)) - { + break; + case ComplexImagePlaneType::OTHER: + default: + // Nothing we can do + break; + } + } + + if (Init::isUndefined(focusPlaneNormal)) + { scene::WGS84EllipsoidModel model; focusPlaneNormal = model.getNormalVector(scp); - } - - if (!Init::isUndefined(scpcoa.scpTime) && - Init::isUndefined(polarAngleRefTime)) - { - polarAngleRefTime = scpcoa.scpTime; - } - - //Vector3 polRefPos = arpPos; - //for when the other functions get implemented -} - -bool PFA::validate(const SCPCOA& scpcoa, logging::Logger& log) -{ - bool valid = true; - std::ostringstream messageBuilder; - - //2.12.2.3 - if (polarAngleRefTime - scpcoa.scpTime > - std::numeric_limits::epsilon()) - { - messageBuilder.str(""); - messageBuilder << "Polar angle reference time and center of aperture " - << "time for center are usuallly the same." << std::endl - << "PFA.PolarAngRefTime: " << polarAngleRefTime << std::endl - << "SCPCOA.SCPTime: " << scpcoa.scpTime; - log.warn(messageBuilder.str()); - valid = false; - } - - return valid; -} + } + + if (!Init::isUndefined(scpcoa.scpTime) && + Init::isUndefined(polarAngleRefTime)) + { + polarAngleRefTime = scpcoa.scpTime; + } + + //Vector3 polRefPos = arpPos; + //for when the other functions get implemented +} + +bool PFA::validate(const SCPCOA& scpcoa, logging::Logger& log) +{ + bool valid = true; + std::ostringstream messageBuilder; + + //2.12.2.3 + if (polarAngleRefTime - scpcoa.scpTime > + std::numeric_limits::epsilon()) + { + messageBuilder.str(""); + messageBuilder << "Polar angle reference time and center of aperture " + << "time for center are usuallly the same." << std::endl + << "PFA.PolarAngRefTime: " << polarAngleRefTime << std::endl + << "SCPCOA.SCPTime: " << scpcoa.scpTime; + log.warn(messageBuilder.str()); + valid = false; + } + + return valid; +} } } diff --git a/six/modules/c++/six.sicd/source/Position.cpp b/six/modules/c++/six.sicd/source/Position.cpp index cacde05b90..8dd5483628 100644 --- a/six/modules/c++/six.sicd/source/Position.cpp +++ b/six/modules/c++/six.sicd/source/Position.cpp @@ -19,11 +19,11 @@ * see . * */ -#include "six/sicd/Position.h" -#include "six/sicd/SCPCOA.h" +#include "six/sicd/Position.h" +#include "six/sicd/SCPCOA.h" #include - -namespace six + +namespace six { namespace sicd { @@ -32,47 +32,47 @@ Position::Position() : grpPoly(Init::undefined()), txAPCPoly(Init::undefined()) { -} - -void Position::fillDerivedFields(const SCPCOA& scpcoa) -{ - if (!Init::isUndefined(scpcoa.arpPos) && - !Init::isUndefined(scpcoa.arpVel) && - !Init::isUndefined(scpcoa.scpTime) && - (Init::isUndefined(arpPoly))) - { - const Vector3 tempArpAcc = Init::isUndefined(scpcoa.arpAcc) ? - Vector3(0.0) : scpcoa.arpAcc; - - std::vector coefs; - coefs.resize(3); - - //constant - coefs[0] = scpcoa.arpPos - - scpcoa.arpVel * scpcoa.scpTime + +} + +void Position::fillDerivedFields(const SCPCOA& scpcoa) +{ + if (!Init::isUndefined(scpcoa.arpPos) && + !Init::isUndefined(scpcoa.arpVel) && + !Init::isUndefined(scpcoa.scpTime) && + (Init::isUndefined(arpPoly))) + { + const Vector3 tempArpAcc = Init::isUndefined(scpcoa.arpAcc) ? + Vector3(0.0) : scpcoa.arpAcc; + + std::vector coefs; + coefs.resize(3); + + //constant + coefs[0] = scpcoa.arpPos - + scpcoa.arpVel * scpcoa.scpTime + (tempArpAcc / 2) * math::square(scpcoa.scpTime); - - //linear - coefs[1] = scpcoa.arpVel - - tempArpAcc * scpcoa.scpTime; - - //quadratic - coefs[2] = tempArpAcc / 2; - - arpPoly = PolyXYZ(coefs); - } -} - -bool Position::validate(logging::Logger& log) const -{ - // 2.6 - if (arpPoly.order() < 2) - { - log.error("Position.arpPoly should have at least position" - " and velocity terms."); - return false; - } - return true; -} -} + + //linear + coefs[1] = scpcoa.arpVel - + tempArpAcc * scpcoa.scpTime; + + //quadratic + coefs[2] = tempArpAcc / 2; + + arpPoly = PolyXYZ(coefs); + } +} + +bool Position::validate(logging::Logger& log) const +{ + // 2.6 + if (arpPoly.order() < 2) + { + log.error("Position.arpPoly should have at least position" + " and velocity terms."); + return false; + } + return true; +} +} } diff --git a/six/modules/c++/six.sicd/source/RadarCollection.cpp b/six/modules/c++/six.sicd/source/RadarCollection.cpp index cc598e4959..e90ea5b3b3 100644 --- a/six/modules/c++/six.sicd/source/RadarCollection.cpp +++ b/six/modules/c++/six.sicd/source/RadarCollection.cpp @@ -1,600 +1,600 @@ -/* ========================================================================= - * This file is part of six.sicd-c++ - * ========================================================================= - * - * (C) Copyright 2004 - 2014, MDA Information Systems LLC - * - * six.sicd-c++ is free software; you can redistribute it and/or modify - * it under the terms of the GNU Lesser General Public License as published by - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this program; If not, - * see . - * - */ -#include - -#include -#include - -#undef min -#undef max - -namespace -{ -template -types::RowCol rotatePixel(size_t origNumCols, const types::RowCol& pixel) -{ - types::RowCol rotatedPixel; - rotatedPixel.col = pixel.row; - rotatedPixel.row = static_cast(origNumCols) - pixel.col; - return rotatedPixel; -} -} - -namespace six -{ -namespace sicd -{ -TxStep::TxStep() : - waveformIndex(Init::undefined()), - txPolarization(PolarizationType::NOT_SET) -{ -} - -TxStep* TxStep::clone() const -{ - return new TxStep(*this); -} - -WaveformParameters::WaveformParameters() : - txPulseLength(Init::undefined()), - txRFBandwidth(Init::undefined()), - txFrequencyStart(Init::undefined()), - txFMRate(Init::undefined()), - rcvDemodType(DemodType::NOT_SET), - rcvWindowLength(Init::undefined()), - adcSampleRate(Init::undefined()), - rcvIFBandwidth(Init::undefined()), - rcvFrequencyStart(Init::undefined()), - rcvFMRate(Init::undefined()) -{ -} - -const double WaveformParameters::WF_TOL = 1e-3; -const double WaveformParameters::WGT_TOL = 1e-3; -const char WaveformParameters::WF_INCONSISTENT_STR[] = - "Waveform fields not consistent"; - -const double RadarCollection::WF_TOL = 1e-3; -const char RadarCollection::WF_INCONSISTENT_STR[] = - "Waveform fields not consistent"; - -bool WaveformParameters::operator==(const WaveformParameters& rhs) const -{ - return (txPulseLength == rhs.txPulseLength && - txRFBandwidth == rhs.txRFBandwidth && - txFrequencyStart == rhs.txFrequencyStart && - txFMRate == rhs.txFMRate && - rcvDemodType == rhs.rcvDemodType && - rcvWindowLength == rhs.rcvWindowLength && - adcSampleRate == rhs.adcSampleRate && - rcvIFBandwidth == rhs.rcvIFBandwidth && - rcvFrequencyStart == rhs.rcvFrequencyStart && - rcvFMRate == rhs.rcvFMRate); -} - -WaveformParameters* WaveformParameters::clone() const -{ - return new WaveformParameters(*this); -} - -void WaveformParameters::fillDerivedFields() -{ - if (rcvDemodType == DemodType::CHIRP && - Init::isUndefined(rcvFMRate)) - { - rcvFMRate = 0; - } - - if (rcvFMRate == 0 && - rcvDemodType == DemodType::NOT_SET) - { - rcvDemodType = DemodType::CHIRP; - } - - if (Init::isUndefined(txRFBandwidth) && - !Init::isUndefined(txPulseLength) && - !Init::isUndefined(txFMRate)) - { - txRFBandwidth = txPulseLength * txFMRate; - } - - if (!Init::isUndefined(txRFBandwidth) && - Init::isUndefined(txPulseLength) && - !Init::isUndefined(txFMRate)) - { - txPulseLength = txRFBandwidth / txFMRate; - } - - if (!Init::isUndefined(txRFBandwidth) && - !Init::isUndefined(txPulseLength) && - Init::isUndefined(txFMRate)) - { - txFMRate = txRFBandwidth / txPulseLength; - } -} - -bool WaveformParameters::validate(int refFrequencyIndex, - logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - //2.8.3 - if (std::abs(txRFBandwidth / (txPulseLength * txFMRate) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxFRBandwidth: " - << txRFBandwidth << std::endl - << "SICD.RadarCollection.TxFrequency.txFMRate * txPulseLength: " - << txFMRate * txPulseLength << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.4 - if (rcvDemodType == DemodType::CHIRP && - rcvFMRate != 0) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " - << rcvDemodType << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvFMRate: " - << rcvFMRate << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.5 - if (rcvDemodType == DemodType::STRETCH && - std::abs(rcvFMRate / txFMRate - 1) > WGT_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " - << rcvDemodType << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvFMRate: " - << rcvFMRate << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxFMRate: " - << txFMRate << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.7 - //Absolute frequencies must be positive - if (six::Init::isUndefined(refFrequencyIndex) && - txFrequencyStart <= 0) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.txFreqStart: " - << txFrequencyStart << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.8 - //Absolute frequencies must be positive - if (six::Init::isUndefined(refFrequencyIndex) && - rcvFrequencyStart <= 0) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.rcvFreqStart: " - << rcvFrequencyStart << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.9 - if (six::Init::isDefined(txPulseLength) && (txPulseLength > rcvWindowLength)) // TxPulseLength is optional - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxPulseLength: " - << txPulseLength << std::endl - << "SICD.RadarCollection.Waveform.WFPArameters.RcvWindowLength: " - << rcvWindowLength << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.10 - if (six::Init::isDefined(rcvIFBandwidth) && (rcvIFBandwidth > adcSampleRate)) // RcvIFBandwidth is optional - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvIFBandwidth: " - << rcvIFBandwidth << std::endl - << "SICD.RadarCollection.Waveform.WFPArameters.ADCSampleRate: " - << adcSampleRate << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.11 - if (rcvDemodType == DemodType::CHIRP && txRFBandwidth > adcSampleRate) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " - << rcvDemodType << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxRFBandwidth: " - << txRFBandwidth << std::endl - << "SICD.RadarCollection.Waveform.WFPArameters.ADCSampleRate: " - << adcSampleRate << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.12 - if (six::Init::isDefined(rcvFrequencyStart)) // RcvFreqStart is optional - { - const auto freq_tol = (rcvWindowLength - txPulseLength) * txFMRate; - if (rcvFrequencyStart >= (txFrequencyStart + txRFBandwidth + freq_tol) || - rcvFrequencyStart <= txFrequencyStart - freq_tol) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.RcvFreqStart: " - << rcvFrequencyStart << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - } - - return valid; -} - -ChannelParameters::ChannelParameters() : - txRcvPolarization(DualPolarizationType::NOT_SET), - rcvAPCIndex(Init::undefined()) -{ -} - -ChannelParameters* ChannelParameters::clone() const -{ - return new ChannelParameters(*this); -} - -AreaDirectionParameters::AreaDirectionParameters() : - unitVector(Init::undefined()), - spacing(Init::undefined()), - elements(Init::undefined()), - first(Init::undefined()) -{ -} - -AreaDirectionParameters* AreaDirectionParameters::clone() const -{ - return new AreaDirectionParameters(*this); -} - -std::ostream& operator<< (std::ostream& os, const AreaDirectionParameters& d) -{ - os << "AreaDirectionParameters::\n" - << " unitVector: " << toString(d.unitVector) << "\n" - << " spacing : " << d.spacing << "\n" - << " elements : " << d.elements << "\n" - << " first : " << d.first << "\n"; - return os; -} - -Segment::Segment() : - startLine(Init::undefined()), - startSample(Init::undefined()), - endLine(Init::undefined()), - endSample(Init::undefined()) -{ -} - -bool Segment::operator==(const Segment& rhs) const -{ - return (startLine == rhs.startLine && - startSample == rhs.startSample && - endLine == rhs.endLine && - endSample == rhs.endSample && - identifier == rhs.identifier); -} - -Segment* Segment::clone() const -{ - return new Segment(*this); -} - -AreaPlane::AreaPlane() : - referencePoint(Init::undefined()), - xDirection(new AreaDirectionParameters()), - yDirection(new AreaDirectionParameters()), - orientation(OrientationType::NOT_SET) -{ -} - -AreaPlane* AreaPlane::clone() const -{ - return new AreaPlane(*this); -} - -types::RowCol AreaPlane::getAdjustedReferencePoint() const -{ - types::RowCol refPt = referencePoint.rowCol; - - // NOTE: The calculation done by SICD producers appears to be - // orpRow = (numRows + 1) / 2.0 - // This gives you a pixel-centered, 1-based ORP. We want - // pixel-centered 0-based. More generally than this, we need to - // account for the SICD FirstLine/FirstSample offset - // - refPt.row -= gsl::narrow_cast(xDirection->first); - refPt.col -= gsl::narrow_cast(yDirection->first); - - return refPt; -} - -const Segment& AreaPlane::getSegment(const std::string& segmentId) const -{ - for (size_t ii = 0; ii < segmentList.size(); ++ii) - { - if (segmentList[ii].get() && segmentList[ii]->identifier == segmentId) - { - return *segmentList[ii]; - } - } - throw except::Exception(Ctxt("No segment with identifier " + segmentId)); -} - -void AreaPlane::rotateToShadowsDown() -{ - switch(orientation) - { - case OrientationType::RIGHT: - rotateCCW(); - rotateCCW(); - rotateCCW(); - break; - case OrientationType::UP: - rotateCCW(); - rotateCCW(); - break; - case OrientationType::LEFT: - rotateCCW(); - break; - default: - break; - } -} - -void AreaPlane::rotateCCW() -{ - switch (orientation) - { - case OrientationType::LEFT: - orientation = OrientationType::DOWN; - break; - case OrientationType::DOWN: - orientation = OrientationType::RIGHT; - break; - case OrientationType::RIGHT: - orientation = OrientationType::UP; - break; - case OrientationType::UP: - orientation = OrientationType::LEFT; - break; - default: - break; - } - referencePoint.rowCol = rotatePixel(yDirection->elements, referencePoint.rowCol); - - std::swap(yDirection->elements, xDirection->elements); - std::swap(yDirection->spacing, xDirection->spacing); - std::swap(yDirection->unitVector, xDirection->unitVector); - xDirection->unitVector *= -1; - - for (size_t ii = 0; ii < segmentList.size(); ++ii) - { - segmentList[ii]->rotateCCW(xDirection->elements); - } -} - -void Segment::rotateCCW(size_t numColumns) -{ - /* - * 5 wth -- ! is reference corner - * !----- | | 2 right, 1 down becomes - * | . | 2 ht. --> | | 1 right, 2 up - * | | | | - * ------ |. | - * | | - * !-- - */ - - const auto numColumns_ = gsl::narrow(numColumns); - const six::RowColDouble start(types::RowCol(numColumns_ - 1 - endSample, startLine)); - const six::RowColDouble end(types::RowCol(numColumns_ - 1 - startSample, endLine)); - startLine = gsl::narrow_cast(start.row); - startSample = gsl::narrow_cast(start.col); - endLine = gsl::narrow_cast(end.row); - endSample = gsl::narrow_cast(end.col); -} - - -Area::Area() -{ - const LatLonAlt initial = Init::undefined(); - for (size_t ii = 0; ii < LatLonAltCorners::NUM_CORNERS; ++ii) - { - acpCorners.getCorner(ii) = initial; - } -} - -Area* Area::clone() const -{ - return new Area(*this); -} - -RadarCollection* RadarCollection::clone() const -{ - return new RadarCollection(*this); -} - -bool RadarCollection::operator==(const RadarCollection& rhs) const -{ - return (refFrequencyIndex == rhs.refFrequencyIndex && - txFrequencyMin == rhs.txFrequencyMin && - txFrequencyMax == rhs.txFrequencyMax && - txPolarization == rhs.txPolarization && - polarizationHVAnglePoly == rhs.polarizationHVAnglePoly && - txSequence == rhs.txSequence && - waveform == rhs.waveform && - rcvChannels == rhs.rcvChannels && - area == rhs.area && - parameters == rhs.parameters); -} - -double RadarCollection::waveformMax() const -{ - double derivedMax = -std::numeric_limits::infinity(); - for (size_t ii = 0; ii < waveform.size(); ++ii) - { - if (waveform[ii].get() != nullptr) - { - derivedMax = std::max(derivedMax, - waveform[ii]->txFrequencyStart + - waveform[ii]->txRFBandwidth); - } - } - return derivedMax; -} - -double RadarCollection::waveformMin() const -{ - double derivedMin = std::numeric_limits::infinity(); - for (size_t ii = 0; ii < waveform.size(); ++ii) - { - if (waveform[ii].get() != nullptr) - { - derivedMin = std::min(derivedMin, - waveform[ii]->txFrequencyStart); - } - } - return derivedMin; -} - -void RadarCollection::fillDerivedFields() -{ - // Transmit bandwidth - if (!waveform.empty()) - { - if (Init::isUndefined(txFrequencyMin)) - { - txFrequencyMin = waveformMin(); - } - if (Init::isUndefined(txFrequencyMax)) - { - txFrequencyMax = waveformMax(); - } - - for (size_t ii = 0; ii < waveform.size(); ++ii) - { - if (waveform[ii].get() != nullptr) - { - waveform[ii]->fillDerivedFields(); - } - } - } - - if (waveform.size() == 1 && - waveform[0].get() != nullptr) - { - if (Init::isUndefined(waveform[0]->txFrequencyStart)) - { - waveform[0]->txFrequencyStart = txFrequencyMin; - } - if (Init::isUndefined(waveform[0]->txRFBandwidth)) - { - waveform[0]->txRFBandwidth = txFrequencyMax - txFrequencyMin; - } - } -} - -bool RadarCollection::validate(logging::Logger& log) const -{ - bool valid = true; - std::ostringstream messageBuilder; - - // 2.8 Waveform description consistency - const auto wfMin = waveformMin(); - const auto wfMax = waveformMax(); - - // 2.8.1 - if (wfMin != std::numeric_limits::infinity() && - std::abs((wfMin / txFrequencyMin) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxFreqStart: " - << wfMin << std::endl - << "SICD.RadarCollection.TxFrequency.Min: " << txFrequencyMin - << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.2 - if (wfMax != -std::numeric_limits::infinity() && - std::abs((wfMax / txFrequencyMax) - 1) > WF_TOL) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.Waveform.WFParameters.TxFreqStart" - << " + TxFRBandwidth: " << wfMax << std::endl - << "SICD.RadarCollection.TxFrequency.Max: " - << txFrequencyMax << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - //2.8.6 - //Absolute frequencies must be positive - if (six::Init::isUndefined(refFrequencyIndex) && txFrequencyMin <= 0) - { - messageBuilder.str(""); - messageBuilder << WF_INCONSISTENT_STR << std::endl - << "SICD.RadarCollection.txFrequencyMin: " - << txFrequencyMin << std::endl; - log.error(messageBuilder.str()); - valid = false; - } - - for (size_t ii = 0; ii < waveform.size(); ++ii) - { - if (waveform[ii].get()) - { - valid = waveform[ii]->validate(refFrequencyIndex, log) && valid; - } - } - return valid; -} -} -} +/* ========================================================================= + * This file is part of six.sicd-c++ + * ========================================================================= + * + * (C) Copyright 2004 - 2014, MDA Information Systems LLC + * + * six.sicd-c++ is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; If not, + * see . + * + */ +#include + +#include +#include + +#undef min +#undef max + +namespace +{ +template +types::RowCol rotatePixel(size_t origNumCols, const types::RowCol& pixel) +{ + types::RowCol rotatedPixel; + rotatedPixel.col = pixel.row; + rotatedPixel.row = static_cast(origNumCols) - pixel.col; + return rotatedPixel; +} +} + +namespace six +{ +namespace sicd +{ +TxStep::TxStep() : + waveformIndex(Init::undefined()), + txPolarization(PolarizationType::NOT_SET) +{ +} + +TxStep* TxStep::clone() const +{ + return new TxStep(*this); +} + +WaveformParameters::WaveformParameters() : + txPulseLength(Init::undefined()), + txRFBandwidth(Init::undefined()), + txFrequencyStart(Init::undefined()), + txFMRate(Init::undefined()), + rcvDemodType(DemodType::NOT_SET), + rcvWindowLength(Init::undefined()), + adcSampleRate(Init::undefined()), + rcvIFBandwidth(Init::undefined()), + rcvFrequencyStart(Init::undefined()), + rcvFMRate(Init::undefined()) +{ +} + +const double WaveformParameters::WF_TOL = 1e-3; +const double WaveformParameters::WGT_TOL = 1e-3; +const char WaveformParameters::WF_INCONSISTENT_STR[] = + "Waveform fields not consistent"; + +const double RadarCollection::WF_TOL = 1e-3; +const char RadarCollection::WF_INCONSISTENT_STR[] = + "Waveform fields not consistent"; + +bool WaveformParameters::operator==(const WaveformParameters& rhs) const +{ + return (txPulseLength == rhs.txPulseLength && + txRFBandwidth == rhs.txRFBandwidth && + txFrequencyStart == rhs.txFrequencyStart && + txFMRate == rhs.txFMRate && + rcvDemodType == rhs.rcvDemodType && + rcvWindowLength == rhs.rcvWindowLength && + adcSampleRate == rhs.adcSampleRate && + rcvIFBandwidth == rhs.rcvIFBandwidth && + rcvFrequencyStart == rhs.rcvFrequencyStart && + rcvFMRate == rhs.rcvFMRate); +} + +WaveformParameters* WaveformParameters::clone() const +{ + return new WaveformParameters(*this); +} + +void WaveformParameters::fillDerivedFields() +{ + if (rcvDemodType == DemodType::CHIRP && + Init::isUndefined(rcvFMRate)) + { + rcvFMRate = 0; + } + + if (rcvFMRate == 0 && + rcvDemodType == DemodType::NOT_SET) + { + rcvDemodType = DemodType::CHIRP; + } + + if (Init::isUndefined(txRFBandwidth) && + !Init::isUndefined(txPulseLength) && + !Init::isUndefined(txFMRate)) + { + txRFBandwidth = txPulseLength * txFMRate; + } + + if (!Init::isUndefined(txRFBandwidth) && + Init::isUndefined(txPulseLength) && + !Init::isUndefined(txFMRate)) + { + txPulseLength = txRFBandwidth / txFMRate; + } + + if (!Init::isUndefined(txRFBandwidth) && + !Init::isUndefined(txPulseLength) && + Init::isUndefined(txFMRate)) + { + txFMRate = txRFBandwidth / txPulseLength; + } +} + +bool WaveformParameters::validate(int refFrequencyIndex, + logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + //2.8.3 + if (std::abs(txRFBandwidth / (txPulseLength * txFMRate) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxFRBandwidth: " + << txRFBandwidth << std::endl + << "SICD.RadarCollection.TxFrequency.txFMRate * txPulseLength: " + << txFMRate * txPulseLength << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.4 + if (rcvDemodType == DemodType::CHIRP && + rcvFMRate != 0) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " + << rcvDemodType << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvFMRate: " + << rcvFMRate << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.5 + if (rcvDemodType == DemodType::STRETCH && + std::abs(rcvFMRate / txFMRate - 1) > WGT_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " + << rcvDemodType << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvFMRate: " + << rcvFMRate << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxFMRate: " + << txFMRate << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.7 + //Absolute frequencies must be positive + if (six::Init::isUndefined(refFrequencyIndex) && + txFrequencyStart <= 0) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.txFreqStart: " + << txFrequencyStart << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.8 + //Absolute frequencies must be positive + if (six::Init::isUndefined(refFrequencyIndex) && + rcvFrequencyStart <= 0) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.rcvFreqStart: " + << rcvFrequencyStart << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.9 + if (six::Init::isDefined(txPulseLength) && (txPulseLength > rcvWindowLength)) // TxPulseLength is optional + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxPulseLength: " + << txPulseLength << std::endl + << "SICD.RadarCollection.Waveform.WFPArameters.RcvWindowLength: " + << rcvWindowLength << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.10 + if (six::Init::isDefined(rcvIFBandwidth) && (rcvIFBandwidth > adcSampleRate)) // RcvIFBandwidth is optional + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvIFBandwidth: " + << rcvIFBandwidth << std::endl + << "SICD.RadarCollection.Waveform.WFPArameters.ADCSampleRate: " + << adcSampleRate << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.11 + if (rcvDemodType == DemodType::CHIRP && txRFBandwidth > adcSampleRate) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvDemodType: " + << rcvDemodType << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxRFBandwidth: " + << txRFBandwidth << std::endl + << "SICD.RadarCollection.Waveform.WFPArameters.ADCSampleRate: " + << adcSampleRate << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.12 + if (six::Init::isDefined(rcvFrequencyStart)) // RcvFreqStart is optional + { + const auto freq_tol = (rcvWindowLength - txPulseLength) * txFMRate; + if (rcvFrequencyStart >= (txFrequencyStart + txRFBandwidth + freq_tol) || + rcvFrequencyStart <= txFrequencyStart - freq_tol) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.RcvFreqStart: " + << rcvFrequencyStart << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + } + + return valid; +} + +ChannelParameters::ChannelParameters() : + txRcvPolarization(DualPolarizationType::NOT_SET), + rcvAPCIndex(Init::undefined()) +{ +} + +ChannelParameters* ChannelParameters::clone() const +{ + return new ChannelParameters(*this); +} + +AreaDirectionParameters::AreaDirectionParameters() : + unitVector(Init::undefined()), + spacing(Init::undefined()), + elements(Init::undefined()), + first(Init::undefined()) +{ +} + +AreaDirectionParameters* AreaDirectionParameters::clone() const +{ + return new AreaDirectionParameters(*this); +} + +std::ostream& operator<< (std::ostream& os, const AreaDirectionParameters& d) +{ + os << "AreaDirectionParameters::\n" + << " unitVector: " << toString(d.unitVector) << "\n" + << " spacing : " << d.spacing << "\n" + << " elements : " << d.elements << "\n" + << " first : " << d.first << "\n"; + return os; +} + +Segment::Segment() : + startLine(Init::undefined()), + startSample(Init::undefined()), + endLine(Init::undefined()), + endSample(Init::undefined()) +{ +} + +bool Segment::operator==(const Segment& rhs) const +{ + return (startLine == rhs.startLine && + startSample == rhs.startSample && + endLine == rhs.endLine && + endSample == rhs.endSample && + identifier == rhs.identifier); +} + +Segment* Segment::clone() const +{ + return new Segment(*this); +} + +AreaPlane::AreaPlane() : + referencePoint(Init::undefined()), + xDirection(new AreaDirectionParameters()), + yDirection(new AreaDirectionParameters()), + orientation(OrientationType::NOT_SET) +{ +} + +AreaPlane* AreaPlane::clone() const +{ + return new AreaPlane(*this); +} + +types::RowCol AreaPlane::getAdjustedReferencePoint() const +{ + types::RowCol refPt = referencePoint.rowCol; + + // NOTE: The calculation done by SICD producers appears to be + // orpRow = (numRows + 1) / 2.0 + // This gives you a pixel-centered, 1-based ORP. We want + // pixel-centered 0-based. More generally than this, we need to + // account for the SICD FirstLine/FirstSample offset + // + refPt.row -= gsl::narrow_cast(xDirection->first); + refPt.col -= gsl::narrow_cast(yDirection->first); + + return refPt; +} + +const Segment& AreaPlane::getSegment(const std::string& segmentId) const +{ + for (size_t ii = 0; ii < segmentList.size(); ++ii) + { + if (segmentList[ii].get() && segmentList[ii]->identifier == segmentId) + { + return *segmentList[ii]; + } + } + throw except::Exception(Ctxt("No segment with identifier " + segmentId)); +} + +void AreaPlane::rotateToShadowsDown() +{ + switch(orientation) + { + case OrientationType::RIGHT: + rotateCCW(); + rotateCCW(); + rotateCCW(); + break; + case OrientationType::UP: + rotateCCW(); + rotateCCW(); + break; + case OrientationType::LEFT: + rotateCCW(); + break; + default: + break; + } +} + +void AreaPlane::rotateCCW() +{ + switch (orientation) + { + case OrientationType::LEFT: + orientation = OrientationType::DOWN; + break; + case OrientationType::DOWN: + orientation = OrientationType::RIGHT; + break; + case OrientationType::RIGHT: + orientation = OrientationType::UP; + break; + case OrientationType::UP: + orientation = OrientationType::LEFT; + break; + default: + break; + } + referencePoint.rowCol = rotatePixel(yDirection->elements, referencePoint.rowCol); + + std::swap(yDirection->elements, xDirection->elements); + std::swap(yDirection->spacing, xDirection->spacing); + std::swap(yDirection->unitVector, xDirection->unitVector); + xDirection->unitVector *= -1; + + for (size_t ii = 0; ii < segmentList.size(); ++ii) + { + segmentList[ii]->rotateCCW(xDirection->elements); + } +} + +void Segment::rotateCCW(size_t numColumns) +{ + /* + * 5 wth -- ! is reference corner + * !----- | | 2 right, 1 down becomes + * | . | 2 ht. --> | | 1 right, 2 up + * | | | | + * ------ |. | + * | | + * !-- + */ + + const auto numColumns_ = gsl::narrow(numColumns); + const six::RowColDouble start(types::RowCol(numColumns_ - 1 - endSample, startLine)); + const six::RowColDouble end(types::RowCol(numColumns_ - 1 - startSample, endLine)); + startLine = gsl::narrow_cast(start.row); + startSample = gsl::narrow_cast(start.col); + endLine = gsl::narrow_cast(end.row); + endSample = gsl::narrow_cast(end.col); +} + + +Area::Area() +{ + const LatLonAlt initial = Init::undefined(); + for (size_t ii = 0; ii < LatLonAltCorners::NUM_CORNERS; ++ii) + { + acpCorners.getCorner(ii) = initial; + } +} + +Area* Area::clone() const +{ + return new Area(*this); +} + +RadarCollection* RadarCollection::clone() const +{ + return new RadarCollection(*this); +} + +bool RadarCollection::operator==(const RadarCollection& rhs) const +{ + return (refFrequencyIndex == rhs.refFrequencyIndex && + txFrequencyMin == rhs.txFrequencyMin && + txFrequencyMax == rhs.txFrequencyMax && + txPolarization == rhs.txPolarization && + polarizationHVAnglePoly == rhs.polarizationHVAnglePoly && + txSequence == rhs.txSequence && + waveform == rhs.waveform && + rcvChannels == rhs.rcvChannels && + area == rhs.area && + parameters == rhs.parameters); +} + +double RadarCollection::waveformMax() const +{ + double derivedMax = -std::numeric_limits::infinity(); + for (size_t ii = 0; ii < waveform.size(); ++ii) + { + if (waveform[ii].get() != nullptr) + { + derivedMax = std::max(derivedMax, + waveform[ii]->txFrequencyStart + + waveform[ii]->txRFBandwidth); + } + } + return derivedMax; +} + +double RadarCollection::waveformMin() const +{ + double derivedMin = std::numeric_limits::infinity(); + for (size_t ii = 0; ii < waveform.size(); ++ii) + { + if (waveform[ii].get() != nullptr) + { + derivedMin = std::min(derivedMin, + waveform[ii]->txFrequencyStart); + } + } + return derivedMin; +} + +void RadarCollection::fillDerivedFields() +{ + // Transmit bandwidth + if (!waveform.empty()) + { + if (Init::isUndefined(txFrequencyMin)) + { + txFrequencyMin = waveformMin(); + } + if (Init::isUndefined(txFrequencyMax)) + { + txFrequencyMax = waveformMax(); + } + + for (size_t ii = 0; ii < waveform.size(); ++ii) + { + if (waveform[ii].get() != nullptr) + { + waveform[ii]->fillDerivedFields(); + } + } + } + + if (waveform.size() == 1 && + waveform[0].get() != nullptr) + { + if (Init::isUndefined(waveform[0]->txFrequencyStart)) + { + waveform[0]->txFrequencyStart = txFrequencyMin; + } + if (Init::isUndefined(waveform[0]->txRFBandwidth)) + { + waveform[0]->txRFBandwidth = txFrequencyMax - txFrequencyMin; + } + } +} + +bool RadarCollection::validate(logging::Logger& log) const +{ + bool valid = true; + std::ostringstream messageBuilder; + + // 2.8 Waveform description consistency + const auto wfMin = waveformMin(); + const auto wfMax = waveformMax(); + + // 2.8.1 + if (wfMin != std::numeric_limits::infinity() && + std::abs((wfMin / txFrequencyMin) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxFreqStart: " + << wfMin << std::endl + << "SICD.RadarCollection.TxFrequency.Min: " << txFrequencyMin + << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.2 + if (wfMax != -std::numeric_limits::infinity() && + std::abs((wfMax / txFrequencyMax) - 1) > WF_TOL) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.Waveform.WFParameters.TxFreqStart" + << " + TxFRBandwidth: " << wfMax << std::endl + << "SICD.RadarCollection.TxFrequency.Max: " + << txFrequencyMax << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + //2.8.6 + //Absolute frequencies must be positive + if (six::Init::isUndefined(refFrequencyIndex) && txFrequencyMin <= 0) + { + messageBuilder.str(""); + messageBuilder << WF_INCONSISTENT_STR << std::endl + << "SICD.RadarCollection.txFrequencyMin: " + << txFrequencyMin << std::endl; + log.error(messageBuilder.str()); + valid = false; + } + + for (size_t ii = 0; ii < waveform.size(); ++ii) + { + if (waveform[ii].get()) + { + valid = waveform[ii]->validate(refFrequencyIndex, log) && valid; + } + } + return valid; +} +} +}