Skip to content

Instantly share code, notes, and snippets.

@komasaru
Last active June 8, 2021 02:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save komasaru/7b8fa4da835920d78c2c5f4742acaee9 to your computer and use it in GitHub Desktop.
Save komasaru/7b8fa4da835920d78c2c5f4742acaee9 to your computer and use it in GitHub Desktop.
C++ source code to make an EOP(Earth Orientation Parameters) file.
/***********************************************************
IERS の Buttelin A テキストデータから
EOP(Polar Motion etc.) テキストファイルを生成
* 予め [こちら](ftp://ftp.iers.org/products/eop/rapid/) か
らダウンロードしておいたものを使用する。
(IAU 2000A 章動理論によるデータ
finals2000A.all", "finals2000A.daily")
* 1日のデータに速報値(区分"I")と確定値がある場合は、確定値
を優先。
* 2ファイルで重複する日付のデータは "finals2000A.daily" を
優先。
* 取得する項目:
date, flag_pm, pm_x, pm_x_e, pm_y, pm_y_e,
flag_dut, dut1, dut1_e, lod, lod_e,
flag_nut, nut_x, nut_x_e, nut_y, nut_y_e
DATE AUTHOR VERSION
2021.05.27 mk-mode.com 1.00 新規作成
Copyright(C) 2021 mk-mode.com All Rights Reserved.
------------------------------------------------------------
引数 : なし
------------------------------------------------------------
$ g++102 -std=c++17 -Wall -O2 --pedantic-errors -o make_eop make_eop.cpp
***********************************************************/
#include <cstdlib> // for EXIT_XXXX
#include <fstream>
#include <iomanip>
#include <iostream>
#include <map>
#include <string>
namespace make_eop {
// 定数
static constexpr char kFAll[] = "finals2000A.all";
static constexpr char kFDaily[] = "finals2000A.daily";
static constexpr char kFEop[] = "eop.txt";
static constexpr char kS6[] = " ";
static constexpr char kS7[] = " ";
static constexpr char kS8[] = " ";
static constexpr char kS9[] = " ";
static constexpr char kS10[] = " ";
static constexpr char kZ3[] = " 0.000";
static constexpr char kZ6[] = "0.000000";
static constexpr char kZ7[] = "0.0000000";
/*
* @brief データ取得
*
* @param[in] ファイル名 (char)
* @param[ref] データ (map<string, string>)
* @return true|false
*/
bool get_data(std::string f, std::map<std::string, std::string>& data) {
std::string l;
std::string s;
char flag_pm;
char flag_dut;
char flag_nut;
unsigned int y;
unsigned int m;
unsigned int d;
std::string date;
std::string mjd;
std::string pm_x;
std::string pm_x_e;
std::string pm_y;
std::string pm_y_e;
std::string pm_x_f;
std::string pm_y_f;
std::string dut1;
std::string dut1_e;
std::string lod;
std::string lod_e;
std::string dut1_f;
std::string nut_x;
std::string nut_x_e;
std::string nut_y;
std::string nut_y_e;
std::string nut_x_f;
std::string nut_y_f;
std::stringstream ss;
try {
// File open
std::ifstream ifs(f);
if (!ifs) return false;
// File read
while (getline(ifs, l)) {
flag_pm = l[16];
flag_dut = l[57];
flag_nut = l[95];
y = stoi(l.substr(0, 2));
m = stoi(l.substr(2, 2));
d = stoi(l.substr(4, 2));
mjd = l.substr( 7, 8);
pm_x = l.substr( 18, 9);
pm_x_e = l.substr( 28, 8);
pm_y = l.substr( 37, 9);
pm_y_e = l.substr( 47, 8);
dut1 = l.substr( 58, 10);
dut1_e = l.substr( 69, 9);
lod = l.substr( 79, 7);
lod_e = l.substr( 87, 6);
nut_x = l.substr( 97, 9);
nut_x_e = l.substr(107, 8);
nut_y = l.substr(116, 9);
nut_y_e = l.substr(126, 8);
pm_x_f = l.substr(135, 9);
pm_y_f = l.substr(145, 9);
dut1_f = l.substr(155, 10);
nut_x_f = l.substr(167, 8);
nut_y_f = l.substr(177, 8);
// Flag check
if (f == kFAll &&
flag_pm == 'P' && flag_dut == 'P' && flag_nut == 'P') {
break;
}
// Date
if (y > 72) { y += 1900; } else { y += 2000; }
ss.str("");
ss.clear();
ss << std::setfill('0')
<< std::setw(2) << y << "-"
<< std::setw(2) << m << "-"
<< std::setw(2) << d << std::setfill(' ');
date = ss.str();
// Polar Motion
if (pm_x != kS9) {
ss.str("");
ss.clear();
ss << std::setw(9) << std::fixed << std::setprecision(6)
<< stod(pm_x);
pm_x = ss.str();
}
if (pm_x_e != kS8) {
ss.str("");
ss.clear();
ss << std::setw(8) << std::fixed << std::setprecision(6)
<< stod(pm_x_e);
pm_x_e = ss.str();
}
if (pm_y != kS9) {
ss.str("");
ss.clear();
ss << std::setw(9) << std::fixed << std::setprecision(6)
<< stod(pm_y);
pm_y = ss.str();
}
if (pm_y_e != kS8) {
ss.str("");
ss.clear();
ss << std::setw(8) << std::fixed << std::setprecision(6)
<< stod(pm_y_e);
pm_y_e = ss.str();
}
if (pm_x_f != kS9) {
ss.str("");
ss.clear();
ss << std::setw(9) << std::fixed << std::setprecision(6)
<< stod(pm_x_f);
pm_x_f = ss.str();
}
if (pm_y_f != kS9) {
ss.str("");
ss.clear();
ss << std::setw(9) << std::fixed << std::setprecision(6)
<< stod(pm_y_f);
pm_y_f = ss.str();
}
if (pm_x_f != kS9 && pm_y_f != kS9) { flag_pm = 'F'; }
if (pm_x_f != kS9) {
pm_x = pm_x_f;
pm_x_e = kZ6;
}
if (pm_y_f != kS9) {
pm_y = pm_y_f;
pm_y_e = kZ6;
}
// UT1 - UTC, LOD
if (lod != kS7) {
ss.str("");
ss.clear();
ss << std::setw(7) << std::fixed << std::setprecision(4)
<< stod(lod);
lod = ss.str();
}
if (lod_e != kS6) {
ss.str("");
ss.clear();
ss << std::setw(6) << std::fixed << std::setprecision(4)
<< stod(lod_e);
lod_e = ss.str();
}
if (dut1_f != kS10) {
ss.str("");
ss << std::setw(10) << std::fixed << std::setprecision(7)
<< stod(dut1_f);
dut1_f = ss.str();
}
if (dut1_f != kS10) {
flag_dut = 'F';
dut1 = dut1_f;
dut1_e = kZ7;
}
// Nutation
if (nut_x != kS9) {
ss.str("");
ss.clear();
ss << std::setw(9) << std::fixed << std::setprecision(3)
<< stod(nut_x);
nut_x = ss.str();
}
if (nut_x_e != kS8) {
ss.str("");
ss.clear();
ss << std::setw(8) << std::fixed << std::setprecision(3)
<< stod(nut_x_e);
nut_x_e = ss.str();
}
if (nut_y != kS9) {
ss.str("");
ss.clear();
ss << std::setw(9) << std::fixed << std::setprecision(3)
<< stod(nut_y);
nut_y = ss.str();
}
if (nut_y_e != kS8) {
ss.str("");
ss.clear();
ss << std::setw(8) << std::fixed << std::setprecision(3)
<< stod(nut_y_e);
nut_y_e = ss.str();
}
if (nut_x_f != kS8) {
ss.str("");
ss.clear();
ss << std::setw(8) << std::fixed << std::setprecision(3)
<< stod(nut_x_f);
nut_x_f = ss.str();
}
if (nut_y_f != kS8) {
ss.str("");
ss.clear();
ss << std::setw(8) << std::fixed << std::setprecision(3)
<< stod(nut_y_f);
nut_y_f = ss.str();
}
if (nut_x_f != kS8 && nut_y_f != kS8) { flag_nut = 'F'; }
if (nut_x_f != kS8) {
nut_x = " " + nut_x_f;
nut_x_e = kZ3;
}
if (nut_y_f != kS8) {
nut_y = " " + nut_y_f;
nut_y_e = kZ3;
}
// 1行整形
data[date] =
mjd + " " +
flag_pm + " " +
pm_x + " " + pm_x_e + " " +
pm_y + " " + pm_y_e + " " +
flag_dut + " " +
dut1 + " " + dut1_e + " " +
lod + " " + lod_e + " " +
flag_nut + " " +
nut_x + " " + nut_x_e + " " +
nut_y + " " + nut_y_e;
}
} catch (...) {
return false;
}
return true;
}
/*
* @brief テキストファイル書き込み
*
* @param[ref] データ (map<string, string>)
* @return true|false
*/
bool write_data(std::map<std::string, std::string>& data) {
std::string f(kFEop);
try {
// File open
std::ofstream ofs(f);
if (!ofs) return 0;
// 書き込み
for (auto& [k, v]: data) { ofs << k + " " + v << std::endl; }
// File close
ofs.close();
} catch (...) {
return false;
}
return true;
}
} // namespace make_eop
int main(int argc, char* argv[]) {
namespace ns = make_eop;
std::map<std::string, std::string> data;
try {
// "finals2000A.all" 読み込み
if (!ns::get_data(ns::kFAll, data)) {
std::cout << "[ERROR] Could not read '" << ns::kFAll << "'!" << std::endl;
return EXIT_FAILURE;
}
// "finals2000A.daily" 読み込み
if (!ns::get_data(ns::kFDaily, data)) {
std::cout << "[ERROR] Could not read '" << ns::kFDaily << "'!" << std::endl;
return EXIT_FAILURE;
}
// "eop.txt" 書き込み
if (!ns::write_data(data)) {
std::cout << "[ERROR] Could not write '" << ns::kFEop << "'!" << std::endl;
return EXIT_FAILURE;
}
} catch (...) {
std::cerr << "EXCEPTION!" << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment