Program Listing for File tai_utc.cc¶
↰ Return to documentation for file (data/tai_utc.cc)
#include "lupnt/data/tai_utc.h"
#include <fstream>
#include <iostream>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>
#include "lupnt/core/constants.h"
#include "lupnt/core/file.h"
namespace lupnt {
std::mutex tai_utc_mutex;
UniquePtr<TaiUtcFileData> tai_utc_data;
void LoadTaiUtcFileData(const std::filesystem::path& filepath) {
std::lock_guard<std::mutex> lock(tai_utc_mutex);
if (tai_utc_data) return; // Data already loaded
size_t n_lines = CountLines(filepath.string());
std::ifstream file = OpenFile<std::ifstream>(filepath);
// Initialize TaiUtcFileData struct
tai_utc_data = MakeUnique<TaiUtcFileData>();
tai_utc_data->jd.resize(n_lines);
tai_utc_data->tai_utc.resize(n_lines);
tai_utc_data->mjd0.resize(n_lines);
tai_utc_data->scale.resize(n_lines);
std::string line;
size_t index = 0;
while (std::getline(file, line)) {
if (line.empty()) continue;
double jd, tai_utc, mjd0, scale;
std::istringstream iss(line);
std::string year, month, day, eq_jd, tai_utc_eq, s1, plus, paren_mjd, minus, paren, times, s2;
iss >> year >> month >> day >> eq_jd >> jd >> tai_utc_eq >> tai_utc >> s1 >> plus >> paren_mjd
>> minus >> mjd0 >> paren >> times >> scale >> s2;
tai_utc_data->jd(index) = jd;
tai_utc_data->tai_utc(index) = tai_utc;
tai_utc_data->mjd0(index) = mjd0;
tai_utc_data->scale(index) = scale;
++index;
}
file.close();
return;
}
double Evaluate(double mjd, int i) {
return tai_utc_data->tai_utc(i) + tai_utc_data->scale(i) * (mjd - tai_utc_data->mjd0(i));
}
double GetTaiUtcDifference(double mjd) {
if (!tai_utc_data) LoadTaiUtcFileData(GetFilePath(TAI_UTC_FILENAME));
double jd = mjd + JD_MJD_OFFSET;
if (jd < tai_utc_data->jd(0)) {
return 0.0;
} else if (jd > tai_utc_data->jd(tai_utc_data->jd.size() - 1)) {
int index = tai_utc_data->jd.size() - 1;
return Evaluate(mjd, index);
}
// Find closest MJD for the immediate smaller date
double* start = tai_utc_data->jd.data();
double* end = tai_utc_data->jd.data() + tai_utc_data->jd.size();
auto it = std::upper_bound(start, end, jd);
int index = (it - tai_utc_data->jd.data()) - 1;
if (index < 0) index = 0;
return Evaluate(mjd, index);
}
} // namespace lupnt