mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-06 03:29:44 -06:00
Merge-in all updates from master
This commit is contained in:
@@ -28,8 +28,7 @@
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/stringhelper.h>
|
||||
#include <scn/scn.h>
|
||||
#include <scn/tuple_return.h>
|
||||
#include <scn/scan.h>
|
||||
#include <fstream>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
@@ -127,7 +126,7 @@ namespace {
|
||||
LeapSecond { .year = 2017, .dayOfYear = 1 }
|
||||
};
|
||||
// Get the position of the last leap second before the desired date
|
||||
LeapSecond date{ year, dayOfYear };
|
||||
const LeapSecond date = { year, dayOfYear };
|
||||
const auto it = std::lower_bound(LeapSeconds.begin(), LeapSeconds.end(), date);
|
||||
|
||||
// Get the position of the Epoch
|
||||
@@ -209,10 +208,13 @@ namespace {
|
||||
if (e.find('.') == std::string::npos) {
|
||||
e += ".0";
|
||||
}
|
||||
auto [res, year, daysInYear] = scn::scan_tuple<int, double>(e, "{:2}{}");
|
||||
// @TODO(abock) The 'd' suffix can be removed when
|
||||
// https://github.com/eliaskosunen/scnlib/issues/104 is fixed
|
||||
auto res = scn::scan<int, double>(e, "{:2d}{}");
|
||||
if (!res) {
|
||||
throw ghoul::RuntimeError(fmt::format("Error parsing epoch '{}'", epoch));
|
||||
throw ghoul::RuntimeError(std::format("Error parsing epoch '{}'", epoch));
|
||||
}
|
||||
auto [year, daysInYear] = res->values();
|
||||
year += year > 57 ? 1900 : 2000;
|
||||
const int daysSince2000 = countDays(year);
|
||||
|
||||
@@ -259,20 +261,20 @@ namespace {
|
||||
e += ".0";
|
||||
}
|
||||
// 1, 2
|
||||
size_t nDashes = std::count_if(
|
||||
const size_t nDashes = std::count_if(
|
||||
epoch.begin(),
|
||||
epoch.end(),
|
||||
[](char c) { return c == '-'; }
|
||||
);
|
||||
std::string formatString = (nDashes == 2) ? "{:4}-{:2}-{:2}{}" : "{:4}{:2}{:2}{}";
|
||||
auto [res, year, monthNum, dayOfMonthNum, fractionOfDay] =
|
||||
scn::scan_tuple<int, int, int, double>(e, formatString);
|
||||
const std::string format = (nDashes == 2) ? "{:4}-{:2}-{:2}{}" : "{:4}{:2}{:2}{}";
|
||||
auto res = scn::scan<int, int, int, double>(e, scn::runtime_format(format));
|
||||
if (!res) {
|
||||
throw ghoul::RuntimeError(fmt::format("Error parsing epoch '{}'", epoch));
|
||||
throw ghoul::RuntimeError(std::format("Error parsing epoch '{}'", epoch));
|
||||
}
|
||||
auto [year, monthNum, dayOfMonthNum, fractionOfDay] = res->values();
|
||||
const int daysSince2000 = countDays(year);
|
||||
int wholeDaysInto = daysIntoGivenYear(year, monthNum, dayOfMonthNum);
|
||||
double daysInYear = static_cast<double>(wholeDaysInto) + fractionOfDay;
|
||||
const int wholeDaysInto = daysIntoGivenYear(year, monthNum, dayOfMonthNum);
|
||||
const double daysInYear = static_cast<double>(wholeDaysInto) + fractionOfDay;
|
||||
|
||||
// 3
|
||||
using namespace std::chrono;
|
||||
@@ -328,30 +330,37 @@ namespace {
|
||||
const size_t pos = epoch.find('T');
|
||||
if (pos == 10) {
|
||||
// We have the first form
|
||||
int month;
|
||||
int days;
|
||||
auto res = scn::scan(
|
||||
epoch, "{:4}-{:2}-{:2}T{:2}:{:2}:{}",
|
||||
date.year, month, days, date.hours, date.minutes, date.seconds
|
||||
int month = 0;
|
||||
int days = 0;
|
||||
// @TODO(abock) The 'd' suffix can be removed when
|
||||
// https://github.com/eliaskosunen/scnlib/issues/104 is fixed
|
||||
auto res = scn::scan<int, int, int, int, int, double>(
|
||||
epoch, "{:4d}-{:2d}-{:2d}T{:2d}:{:2d}:{}"
|
||||
);
|
||||
if (!res) {
|
||||
throw ghoul::RuntimeError(fmt::format("Error parsing epoch '{}'", epoch));
|
||||
throw ghoul::RuntimeError(std::format("Error parsing epoch '{}'", epoch));
|
||||
}
|
||||
std::tie(date.year, month, days, date.hours, date.minutes, date.seconds) =
|
||||
res->values();
|
||||
date.nDays = daysIntoGivenYear(date.year, month, days);
|
||||
}
|
||||
else if (pos == 8) {
|
||||
// We have the second form
|
||||
|
||||
auto res = scn::scan(
|
||||
epoch, "{:4}-{:3}T{:2}:{:2}:{}",
|
||||
date.year, date.nDays, date.hours, date.minutes, date.seconds
|
||||
// @TODO(abock) The 'd' suffix can be removed when
|
||||
// https://github.com/eliaskosunen/scnlib/issues/104 is fixed
|
||||
auto res = scn::scan<int, int, int, int, double>(
|
||||
epoch, "{:4d}-{:3d}T{:2d}:{:2d}:{}"
|
||||
//date.year, date.nDays, date.hours, date.minutes, date.seconds
|
||||
);
|
||||
if (!res) {
|
||||
throw ghoul::RuntimeError(fmt::format("Error parsing epoch '{}'", epoch));
|
||||
throw ghoul::RuntimeError(std::format("Error parsing epoch '{}'", epoch));
|
||||
}
|
||||
std::tie(date.year, date.nDays, date.hours, date.minutes, date.seconds) =
|
||||
res->values();
|
||||
}
|
||||
else {
|
||||
throw ghoul::RuntimeError(fmt::format("Malformed epoch string '{}'", epoch));
|
||||
throw ghoul::RuntimeError(std::format("Malformed epoch string '{}'", epoch));
|
||||
}
|
||||
|
||||
const int daysSince2000 = countDays(date.year);
|
||||
@@ -385,7 +394,7 @@ namespace {
|
||||
|
||||
namespace openspace::kepler {
|
||||
|
||||
std::vector<Parameters> readTleFile(std::filesystem::path file) {
|
||||
std::vector<Parameters> readTleFile(const std::filesystem::path& file) {
|
||||
ghoul_assert(std::filesystem::is_regular_file(file), "File must exist");
|
||||
|
||||
std::vector<Parameters> result;
|
||||
@@ -421,19 +430,19 @@ std::vector<Parameters> readTleFile(std::filesystem::path file) {
|
||||
std::string firstLine;
|
||||
ghoul::getline(f, firstLine);
|
||||
if (f.bad() || firstLine[0] != '1') {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Malformed TLE file '{}' at line {}", file, lineNum + 1
|
||||
));
|
||||
}
|
||||
// The id only contains the last two digits of the launch year, so we have to
|
||||
// patch it to the full year
|
||||
{
|
||||
std::string id = firstLine.substr(9, 6);
|
||||
std::string prefix = [y = id.substr(0, 2)](){
|
||||
int year = std::atoi(y.c_str());
|
||||
const std::string id = firstLine.substr(9, 6);
|
||||
const std::string prefix = [y = id.substr(0, 2)](){
|
||||
const int year = std::atoi(y.c_str());
|
||||
return year >= 57 ? "19" : "20";
|
||||
}();
|
||||
p.id = fmt::format("{}{}-{}", prefix, id.substr(0, 2), id.substr(3));
|
||||
p.id = std::format("{}{}-{}", prefix, id.substr(0, 2), id.substr(3));
|
||||
}
|
||||
p.epoch = epochFromSubstring(firstLine.substr(18, 14)); // should be 13?
|
||||
|
||||
@@ -453,7 +462,7 @@ std::vector<Parameters> readTleFile(std::filesystem::path file) {
|
||||
std::string secondLine;
|
||||
ghoul::getline(f, secondLine);
|
||||
if (f.bad() || secondLine[0] != '2') {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Malformed TLE file '{}' at line {}", file, lineNum + 1
|
||||
));
|
||||
}
|
||||
@@ -488,7 +497,7 @@ std::vector<Parameters> readTleFile(std::filesystem::path file) {
|
||||
|
||||
// Get mean motion
|
||||
stream.str(secondLine.substr(52, 11));
|
||||
float meanMotion;
|
||||
float meanMotion = 0.f;
|
||||
stream >> meanMotion;
|
||||
|
||||
p.semiMajorAxis = calculateSemiMajorAxis(meanMotion);
|
||||
@@ -502,7 +511,7 @@ std::vector<Parameters> readTleFile(std::filesystem::path file) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<Parameters> readOmmFile(std::filesystem::path file) {
|
||||
std::vector<Parameters> readOmmFile(const std::filesystem::path& file) {
|
||||
ghoul_assert(std::filesystem::is_regular_file(file), "File must exist");
|
||||
|
||||
std::vector<Parameters> result;
|
||||
@@ -525,7 +534,7 @@ std::vector<Parameters> readOmmFile(std::filesystem::path file) {
|
||||
}
|
||||
|
||||
if (parts.size() != 2) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Malformed line '{}' at {}", line, lineNum
|
||||
));
|
||||
}
|
||||
@@ -534,7 +543,7 @@ std::vector<Parameters> readOmmFile(std::filesystem::path file) {
|
||||
if (parts[1] != "2.0") {
|
||||
LWARNINGC(
|
||||
"OMM",
|
||||
fmt::format(
|
||||
std::format(
|
||||
"Only version 2.0 is currently supported but found {}. "
|
||||
"Parsing might fail",
|
||||
parts[1]
|
||||
@@ -563,7 +572,7 @@ std::vector<Parameters> readOmmFile(std::filesystem::path file) {
|
||||
current->epoch = epochFromOmmString(parts[1]);
|
||||
}
|
||||
else if (parts[0] == "MEAN_MOTION") {
|
||||
float mm = std::stof(parts[1]);
|
||||
const float mm = std::stof(parts[1]);
|
||||
current->semiMajorAxis = calculateSemiMajorAxis(mm);
|
||||
current->period = std::chrono::seconds(std::chrono::hours(24)).count() / mm;
|
||||
}
|
||||
@@ -594,7 +603,7 @@ std::vector<Parameters> readOmmFile(std::filesystem::path file) {
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<Parameters> readSbdbFile(std::filesystem::path file) {
|
||||
std::vector<Parameters> readSbdbFile(const std::filesystem::path& file) {
|
||||
constexpr int NDataFields = 9;
|
||||
constexpr std::string_view ExpectedHeader = "full_name,epoch_cal,e,a,i,om,w,ma,per";
|
||||
|
||||
@@ -608,7 +617,7 @@ std::vector<Parameters> readSbdbFile(std::filesystem::path file) {
|
||||
// Newer versions downloaded from the JPL SBDB website have " around variables
|
||||
line.erase(remove(line.begin(), line.end(), '\"'), line.end());
|
||||
if (line != ExpectedHeader) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Expected JPL SBDB file to start with '{}' but found '{}' instead",
|
||||
ExpectedHeader, line.substr(0, 100)
|
||||
));
|
||||
@@ -620,7 +629,7 @@ std::vector<Parameters> readSbdbFile(std::filesystem::path file) {
|
||||
|
||||
std::vector<std::string> parts = ghoul::tokenizeString(line, ',');
|
||||
if (parts.size() != NDataFields) {
|
||||
throw ghoul::RuntimeError(fmt::format(
|
||||
throw ghoul::RuntimeError(std::format(
|
||||
"Malformed line {}, expected 8 data fields, got {}", line, parts.size()
|
||||
));
|
||||
}
|
||||
@@ -658,7 +667,7 @@ std::vector<Parameters> readSbdbFile(std::filesystem::path file) {
|
||||
return result;
|
||||
}
|
||||
|
||||
void saveCache(const std::vector<Parameters>& params, std::filesystem::path file) {
|
||||
void saveCache(const std::vector<Parameters>& params, const std::filesystem::path& file) {
|
||||
std::ofstream stream(file, std::ofstream::binary);
|
||||
|
||||
stream.write(reinterpret_cast<const char*>(&CurrentCacheVersion), sizeof(int8_t));
|
||||
@@ -688,7 +697,7 @@ void saveCache(const std::vector<Parameters>& params, std::filesystem::path file
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<std::vector<Parameters>> loadCache(std::filesystem::path file) {
|
||||
std::optional<std::vector<Parameters>> loadCache(const std::filesystem::path& file) {
|
||||
std::ifstream stream(file, std::ifstream::binary);
|
||||
|
||||
int8_t version = 0;
|
||||
@@ -733,8 +742,8 @@ std::optional<std::vector<Parameters>> loadCache(std::filesystem::path file) {
|
||||
std::vector<Parameters> readFile(std::filesystem::path file, Format format) {
|
||||
std::filesystem::path cachedFile = FileSys.cacheManager()->cachedFilename(file);
|
||||
if (std::filesystem::is_regular_file(cachedFile)) {
|
||||
LINFO(fmt::format(
|
||||
"Cached file {} used for Kepler file {}", cachedFile, file
|
||||
LINFO(std::format(
|
||||
"Cached file '{}' used for Kepler file '{}'", cachedFile, file
|
||||
));
|
||||
|
||||
std::optional<std::vector<Parameters>> res = loadCache(cachedFile);
|
||||
@@ -758,7 +767,7 @@ std::vector<Parameters> readFile(std::filesystem::path file, Format format) {
|
||||
break;
|
||||
}
|
||||
|
||||
LINFO(fmt::format("Saving cache {} for Kepler file {}", cachedFile, file));
|
||||
LINFO(std::format("Saving cache '{}' for Kepler file '{}'", cachedFile, file));
|
||||
saveCache(res, cachedFile);
|
||||
return res;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user