From 96cf21dbf7178049381059b8e3779f3a74b029ad Mon Sep 17 00:00:00 2001 From: "Timur A. Fatkhullin" Date: Sun, 9 Mar 2025 21:47:46 +0300 Subject: [PATCH] ... --- cxx/CMakeLists.txt | 3 ++ cxx/mount_astrom.h | 107 ++++++++++++-------------------------- cxx/tests/astrom_test.cpp | 98 ++++++++++++++++++++++++++++++++++ 3 files changed, 135 insertions(+), 73 deletions(-) create mode 100644 cxx/tests/astrom_test.cpp diff --git a/cxx/CMakeLists.txt b/cxx/CMakeLists.txt index 2a880d4..69ddf8b 100644 --- a/cxx/CMakeLists.txt +++ b/cxx/CMakeLists.txt @@ -100,4 +100,7 @@ if (WITH_TESTS) set(CFGFILE_TEST_APP configfile_test) add_executable(${CFGFILE_TEST_APP} tests/configfile_test.cpp) + + set(ASTROM_TEST_APP astrom_test) + add_executable(${ASTROM_TEST_APP} tests/astrom_test.cpp) endif() diff --git a/cxx/mount_astrom.h b/cxx/mount_astrom.h index 67bc35a..ddc11fb 100644 --- a/cxx/mount_astrom.h +++ b/cxx/mount_astrom.h @@ -170,6 +170,7 @@ struct leapsecond_db_elem_t { double mjd; unsigned day, month; int year; + // std::chrono::year_month_day ymd; double tai_utc; // TAI-UTC in seconds }; @@ -209,11 +210,11 @@ static leapsecond_db_t CURRENT_LEAPSECONDS_DB = { static earth_orient_db_t CURRENT_EARTH_ORIENT_DB; -bool mcc_parse_bulletinA(std::derived_from> auto& stream, char comment_sym = '*') +static bool mcc_parse_bulletinA(std::derived_from> auto& stream, char comment_sym = '*') { const std::regex bull_date_rx{ - "^ *[0-9]{1,2} +(January|Febraury|March|April|May|June|July|August|September|October|November|December) " - "+[0-9]{4,} + Vol\\.[XMLCDVI]+ +No\\. +[0-9]+ *$"}; + "^ *[0-9]{1,2} +(January|February|March|April|May|June|July|August|September|October|November|December) " + "+[0-9]{4,} +Vol\\. +[XMLCDVI]+ +No\\. +[0-9]+ *$"}; const std::regex bull_tab_title_rx{"^ *MJD +x\\(arcsec\\) +y\\(arcsec\\) +UT1-UTC\\(sec\\) *$"}; @@ -235,7 +236,7 @@ bool mcc_parse_bulletinA(std::derived_from> auto& strea continue; } - auto sv = utils::trimSpaces(line, utils::TrimType::TRIM_BOTH); + auto sv = utils::trimSpaces(line, utils::TrimType::TRIM_LEFT); if (sv.size()) { if (sv[0] == comment_sym) { // comment string @@ -244,9 +245,11 @@ bool mcc_parse_bulletinA(std::derived_from> auto& strea if (tab_state == TAB_STATE_START) { if (std::regex_match(sv.begin(), sv.end(), bull_tab_vals_rx)) { - is.str({sv.begin(), sv.end()}); + // is.str({sv.begin(), sv.end()}); + is.str(line); is >> year >> month >> day >> mjd >> x >> y >> dut1; db.db.emplace_back(year, month, day, mjd, x, y, dut1); + is.clear(); } else { // end of the table - just stop parsing break; } @@ -280,22 +283,27 @@ bool mcc_parse_bulletinA(std::derived_from> auto& strea } -bool mcc_parse_leapsecs(std::derived_from> auto& stream, char comment_sym = '#') +static bool mcc_parse_leapsecs(std::derived_from> auto& stream, char comment_sym = '#') { - size_t n; - std::optional vd; - std::optional vui; - std::optional vi; + // # File expires on 28 December 2025 + const std::regex expr_date_rx{ + "^ *# *File +expires +on +[0-8]{1,2} " + "+(January|February|March|April|May|June|July|August|September|October|November|December) +[0-9]{4} *$"}; + + const std::regex data_rx{"^ *[0-9]{5,}(\\.?[0-9]+) +[0-9]{1,2} +[0-9]{1,2} +[0-9]{4} +[0-9]{1,} *$"}; + + std::istringstream is; + double mjd; + unsigned day, month; + int year; + double tai_utc; + leapsecond_db_t db; - leapsecond_db_elem_t db_elem; + // leapsecond_db_elem_t db_elem; for (std::string line; std::getline(stream, line);) { - if (line.empty()) { - continue; - } - - auto sv = utils::trimSpaces(line, utils::TrimType::TRIM_BOTH); + auto sv = utils::trimSpaces(line, utils::TrimType::TRIM_LEFT); if (sv.size()) { if (sv[0] == comment_sym) { // comment string @@ -305,65 +313,16 @@ bool mcc_parse_leapsecs(std::derived_from> auto& stream continue; } - n = 0; - for (auto const& el : std::views::split(sv, std::string_view(" "))) { - if (std::ranges::size(el) == 0) { - continue; - } - - switch (n) { - case 0: - vd = utils::numFromStr(el); - if (!vd) { - return false; - } - db_elem.mjd = vd.value(); - break; - case 1: - vui = utils::numFromStr(el); - if (!vui) { - return false; - } - db_elem.day = vui.value(); - break; - case 2: - vui = utils::numFromStr(el); - if (!vui) { - return false; - } - db_elem.month = vui.value(); - break; - case 3: - vi = utils::numFromStr(el); - if (!vi) { - return false; - } - db_elem.year = vi.value(); - break; - case 4: - vd = utils::numFromStr(el); - if (!vd) { - return false; - } - db_elem.tai_utc = vd.value(); - break; - default: - // just ignore??!!! - break; - } - - ++n; - - if (n == 5) { - break; - } + if (std::regex_match(line, data_rx)) { + is.str(std::move(line)); + is >> mjd >> day >> month >> year >> tai_utc; + db.emplace_back(mjd, day, month, year, tai_utc); + is.clear(); } + } - if (n < 5) { // not enough elements - return false; - } - - db.emplace_back(std::move(db_elem)); + if (db.empty()) { + return false; } CURRENT_LEAPSECONDS_DB = std::move(db); @@ -371,4 +330,6 @@ bool mcc_parse_leapsecs(std::derived_from> auto& stream return true; } + + } // namespace mcc::astro diff --git a/cxx/tests/astrom_test.cpp b/cxx/tests/astrom_test.cpp new file mode 100644 index 0000000..7b11987 --- /dev/null +++ b/cxx/tests/astrom_test.cpp @@ -0,0 +1,98 @@ +#include +#include + +#include "../mount_astrom.h" + + +static std::string leap_secs_file = R"--( +# Value of TAI-UTC in second valid beetween the initial value until +# the epoch given on the next line. The last line reads that NO +# leap second was introduced since the corresponding date +# Updated through IERS Bulletin 69 issued in January 2025 +# +# +# File expires on 28 December 2025 +# +# +# MJD Date TAI-UTC (s) +# day month year +# --- -------------- ------ +# + 41317.0 1 1 1972 10 + 41499.0 1 7 1972 11 + 41683.0 1 1 1973 12 + 42048.0 1 1 1974 13 + 42413.0 1 1 1975 14 + 42778.0 1 1 1976 15 + 43144.0 1 1 1977 16 + 43509.0 1 1 1978 17 + 43874.0 1 1 1979 18 + 44239.0 1 1 1980 19 + 44786.0 1 7 1981 20 + 45151.0 1 7 1982 21 + 45516.0 1 7 1983 22 + 46247.0 1 7 1985 23 + 47161.0 1 1 1988 24 + 47892.0 1 1 1990 25 + 48257.0 1 1 1991 26 + 48804.0 1 7 1992 27 + 49169.0 1 7 1993 28 + 49534.0 1 7 1994 29 + 50083.0 1 1 1996 30 + 50630.0 1 7 1997 31 + 51179.0 1 1 1999 32 + 53736.0 1 1 2006 33 + 54832.0 1 1 2009 34 + 56109.0 1 7 2012 35 + 57204.0 1 7 2015 36 + 57754.0 1 1 2017 37 +)--"; + + +int main(int argc, char* argv[]) +{ + int ecode = 0; + + if (argc < 2) { + std::cerr << "Usage: " << argv[0] << " bulletinA-filename\n"; + exit(1); + } + + std::ifstream ist(argv[1]); + if (!ist) { + std::cerr << "Invalid filename!\n"; + exit(1); + } + + bool ok = mcc::astro::mcc_parse_bulletinA(ist); + + if (!ok) { + std::cout << "Cannot parse input IERS Bulletin A file!\n"; + ecode = 1; + } else { + std::cout << "IERS Bulletin A data:\n"; + std::cout << "Date: " << mcc::astro::CURRENT_EARTH_ORIENT_DB.bulletinDate << "\n"; + for (auto& el : mcc::astro::CURRENT_EARTH_ORIENT_DB.db) { + std::cout << "MJD: " << el.mjd << "\tDUT1 = " << el.dut1 << "\n"; + } + } + + ist.close(); + + std::cout << "\n\n\n"; + + std::istringstream isst(leap_secs_file); + ok = mcc::astro::mcc_parse_leapsecs(isst); + + if (!ok) { + std::cout << "Cannot parse input IERS leap seconds file!\n"; + ecode = 1; + } else { + std::cout << "IERS leap seconds data:\n"; + for (auto& el : mcc::astro::CURRENT_LEAPSECONDS_DB) { + std::cout << "MJD: " << el.mjd << "\tTAI-UTC = " << el.tai_utc << "\n"; + } + } + + return ecode; +}