mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-07 04:00:37 -06:00
Code formatting to match style guide
This commit is contained in:
File diff suppressed because it is too large
Load Diff
@@ -34,169 +34,185 @@
|
||||
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "FieldlinesSequence[ Web FLs Manager ]";
|
||||
constexpr const char* _loggerCat = "WebFieldlinesManager";
|
||||
|
||||
} // namepace
|
||||
|
||||
|
||||
namespace openspace{
|
||||
|
||||
// --------------------------- PUBLIC FUNCTIONS --------------------------- //
|
||||
void WebFieldlinesManager::initializeWebFieldlinesManager(std::string identifier, std::string url, size_t& _nStates, std::vector<std::string>& _sourceFiles,
|
||||
std::vector<double>& _startTimes)
|
||||
// --------------------------- PUBLIC FUNCTIONS --------------------------- //
|
||||
void WebFieldlinesManager::initializeWebFieldlinesManager(std::string identifier,
|
||||
std::string url,
|
||||
size_t& _nStates,
|
||||
std::vector<std::string>& _sourceFiles,
|
||||
std::vector<double>& _startTimes)
|
||||
{
|
||||
// Initialize the sliding window
|
||||
_webFieldlinesWindow =
|
||||
WebFieldlinesWindow(_syncDir, url, _sourceFiles, _startTimes, _nStates);
|
||||
|
||||
LTRACE("WebFieldlinesManager initialized " + identifier);
|
||||
}
|
||||
|
||||
bool WebFieldlinesManager::isConnected() {
|
||||
return _connected;
|
||||
}
|
||||
|
||||
// Make sure that the sync directory exists
|
||||
// Also creates a new directory in the web_fieldlines directory corresponding to the
|
||||
// field line identifier
|
||||
std::string WebFieldlinesManager::initializeSyncDirectory(std::string identifier) {
|
||||
std::string path =
|
||||
absPath("${BASE}/sync/http/web_fieldlines") + FileSys.PathSeparator;
|
||||
|
||||
if (!FileSys.directoryExists(path)) {
|
||||
FileSys.createDirectory(path);
|
||||
}
|
||||
|
||||
path = absPath(path + identifier);
|
||||
if(!FileSys.directoryExists(path)) {
|
||||
FileSys.createDirectory(path);
|
||||
}
|
||||
|
||||
_syncDir = path;
|
||||
return _syncDir;
|
||||
}
|
||||
|
||||
// Temporary function - this should be moved to the worker. It's to download
|
||||
// the start latest line
|
||||
// this could be used to test the connection too
|
||||
void WebFieldlinesManager::preDownload(std::string dUrl){
|
||||
|
||||
int ID = std::stoi(dUrl.substr(dUrl.size() - 4));
|
||||
std::string type = "";
|
||||
switch (ID)
|
||||
{
|
||||
// Initialize the sliding window
|
||||
_webFieldlinesWindow = WebFieldlinesWindow(_syncDir, url, _sourceFiles, _startTimes, _nStates);
|
||||
case 1176:
|
||||
type = "trace_sun_earth";
|
||||
break;
|
||||
case 1177:
|
||||
type = "trace_scs_outtoin";
|
||||
break;
|
||||
case 1178:
|
||||
type = "trace_pfss_intoout";
|
||||
break;
|
||||
case 1179:
|
||||
type = "trace_pfss_outtoin";
|
||||
break;
|
||||
case 1180:
|
||||
type = "WSA_OUT";
|
||||
break;
|
||||
|
||||
LTRACE("WebFieldlinesManager initialized " + identifier);
|
||||
// Parker solar probe endpoints
|
||||
case 1192:
|
||||
type = "trace_sub_psp";
|
||||
break;
|
||||
case 1193:
|
||||
type = "trace_scs_outtoin";
|
||||
break;
|
||||
case 1194:
|
||||
type = "trace_pfss_intoout";
|
||||
break;
|
||||
case 1195:
|
||||
type = "trace_pfss_outtoin";
|
||||
break;
|
||||
case 1196:
|
||||
type = "ADAPT_WSA_OUT";
|
||||
break;
|
||||
}
|
||||
|
||||
bool WebFieldlinesManager::isConnected() {
|
||||
return _connected;
|
||||
}
|
||||
|
||||
// Make sure that the sync directory exists
|
||||
// Also creates a new directory in the web_fieldlines directory corresponding to the field line identifier
|
||||
std::string WebFieldlinesManager::initializeSyncDirectory(std::string identifier) {
|
||||
std::string path = absPath("${BASE}/sync/http/web_fieldlines") + FileSys.PathSeparator;
|
||||
|
||||
if (!FileSys.directoryExists(path)) {
|
||||
FileSys.createDirectory(path);
|
||||
}
|
||||
path = absPath(path + identifier);
|
||||
if(!FileSys.directoryExists(path)) {
|
||||
FileSys.createDirectory(path);
|
||||
}
|
||||
|
||||
_syncDir = path;
|
||||
return _syncDir;
|
||||
}
|
||||
|
||||
// Temporary function - this should be moved to the worker. It's to download
|
||||
// the start latest line
|
||||
// this could be used to test the connection too
|
||||
void WebFieldlinesManager::preDownload(std::string dUrl){
|
||||
|
||||
int ID = std::stoi(dUrl.substr(dUrl.size() - 4));
|
||||
std::string type = "";
|
||||
switch (ID)
|
||||
{
|
||||
case 1176:
|
||||
type = "trace_sun_earth";
|
||||
break;
|
||||
case 1177:
|
||||
type = "trace_scs_outtoin";
|
||||
break;
|
||||
case 1178:
|
||||
type = "trace_pfss_intoout";
|
||||
break;
|
||||
case 1179:
|
||||
type = "trace_pfss_outtoin";
|
||||
break;
|
||||
case 1180:
|
||||
type = "WSA_OUT";
|
||||
break;
|
||||
|
||||
// Parker solar probe endpoints
|
||||
case 1192:
|
||||
type = "trace_sub_psp";
|
||||
break;
|
||||
case 1193:
|
||||
type = "trace_scs_outtoin";
|
||||
break;
|
||||
case 1194:
|
||||
type = "trace_pfss_intoout";
|
||||
break;
|
||||
case 1195:
|
||||
type = "trace_pfss_outtoin";
|
||||
break;
|
||||
case 1196:
|
||||
type = "ADAPT_WSA_OUT";
|
||||
break;
|
||||
}
|
||||
|
||||
// TODO(Axel): Change this endpoint to be dynamic for each dataset
|
||||
std::string url = "https://iswa.ccmc.gsfc.nasa.gov/iswa_data_tree/model/solar/WSA4.5/WSA4.5_fieldlines/" + type + "/2017/09/2017-09-28T00-23-22.000.osfls";
|
||||
std::string destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + "2017-09-28T00-23-22.000.osfls"); // what the downloaded filename is to be
|
||||
// TODO(Axel): Change this endpoint to be dynamic for each dataset
|
||||
std::string url = "https://iswa.ccmc.gsfc.nasa.gov/iswa_data_tree/model/solar/WSA4.5/WSA4.5_fieldlines/" + type + "/2017/09/2017-09-28T00-23-22.000.osfls";
|
||||
std::string destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + "2017-09-28T00-23-22.000.osfls"); // what the downloaded filename is to be
|
||||
|
||||
|
||||
/* For experimentation with suntexturemanager & parker solor probe, hopefully this hardcoding can go away */
|
||||
if (ID == 1180) {
|
||||
url = "https://iswa.ccmc.gsfc.nasa.gov/iswa_data_tree/model/solar/WSA4.5/" + type + "/2017/09/wsa_201709280023R000_gong.fits";
|
||||
destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + "wsa_201709280023R000_gong.fits"); // what the downloaded filename is to be
|
||||
}
|
||||
// For parker solar probe
|
||||
if (ID > 1190) {
|
||||
url = "https://iswa.ccmc.gsfc.nasa.gov/iswa_data_tree/model/solar/ADAPT_WSA4.5/ADAPT_WSA4.5_fieldlines/" + type + "/2018/11/2018-11-01T00-00-00.000.osfls";
|
||||
destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + "2018-11-01T00-00-00.000.osfls"); // what the downloaded filename is to be
|
||||
}
|
||||
|
||||
if (ID == 1196) {
|
||||
url = "https://iswa.ccmc.gsfc.nasa.gov/iswa_data_tree/model/solar/ADAPT_WSA4.5/" + type + "/2018/11/wsa_201811010000R007_agong.fits";
|
||||
destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + "wsa_201811010000R007_agong.fits"); // what the downloaded filename is to be
|
||||
}
|
||||
/* End of experiment */
|
||||
|
||||
AsyncHttpFileDownload ashd = AsyncHttpFileDownload(url, destinationpath, HttpFileDownload::Overwrite::Yes);
|
||||
HttpRequest::RequestOptions opt = {};
|
||||
opt.requestTimeoutSeconds = 0;
|
||||
ashd.start(opt);
|
||||
ashd.wait();
|
||||
/* For experimentation with suntexturemanager & parker solor probe, hopefully this hardcoding can go away */
|
||||
if (ID == 1180) {
|
||||
url = "https://iswa.ccmc.gsfc.nasa.gov/iswa_data_tree/model/solar/WSA4.5/" + type + "/2017/09/wsa_201709280023R000_gong.fits";
|
||||
destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + "wsa_201709280023R000_gong.fits"); // what the downloaded filename is to be
|
||||
}
|
||||
// For parker solar probe
|
||||
if (ID > 1190) {
|
||||
url = "https://iswa.ccmc.gsfc.nasa.gov/iswa_data_tree/model/solar/ADAPT_WSA4.5/ADAPT_WSA4.5_fieldlines/" + type + "/2018/11/2018-11-01T00-00-00.000.osfls";
|
||||
destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + "2018-11-01T00-00-00.000.osfls"); // what the downloaded filename is to be
|
||||
}
|
||||
|
||||
if (ID == 1196) {
|
||||
url = "https://iswa.ccmc.gsfc.nasa.gov/iswa_data_tree/model/solar/ADAPT_WSA4.5/" + type + "/2018/11/wsa_201811010000R007_agong.fits";
|
||||
destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + "wsa_201811010000R007_agong.fits"); // what the downloaded filename is to be
|
||||
}
|
||||
/* End of experiment */
|
||||
|
||||
AsyncHttpFileDownload ashd = AsyncHttpFileDownload(url, destinationpath, HttpFileDownload::Overwrite::Yes);
|
||||
HttpRequest::RequestOptions opt = {};
|
||||
opt.requestTimeoutSeconds = 0;
|
||||
ashd.start(opt);
|
||||
ashd.wait();
|
||||
}
|
||||
|
||||
|
||||
void WebFieldlinesManager::update(){
|
||||
const double openspaceTime = global::timeManager.time().j2000Seconds();
|
||||
const auto deltaTime = global::timeManager.deltaTime();
|
||||
const int speedThreshhold = 7200; // More than 2hrs a second would generally be unfeasable for a regular internet connection to operate at
|
||||
void WebFieldlinesManager::update(){
|
||||
const double openspaceTime = global::timeManager.time().j2000Seconds();
|
||||
const auto deltaTime = global::timeManager.deltaTime();
|
||||
|
||||
// More than 2hrs a second would generally be unfeasable
|
||||
// for a regular internet connection to operate at
|
||||
const int speedThreshhold = 7200;
|
||||
|
||||
// Hold your horses, we don't want to do anything while deltatime is too high
|
||||
if (abs(deltaTime) < speedThreshhold){
|
||||
|
||||
|
||||
// First it checks the time against the "bigger window" aka the long list of
|
||||
// timesteps we know are available online. If it's outside that we're gonna need a new one
|
||||
if (_webFieldlinesWindow.timeIsInTriggerTimesWebList(openspaceTime) && !_webFieldlinesWindow.expectedWindowIsOutOfBounds(openspaceTime) || _webFieldlinesWindow.checkWorkerEdgeMode()){
|
||||
|
||||
// Check if in window
|
||||
if (_webFieldlinesWindow.edgeWindowReady() || _webFieldlinesWindow.timeIsInWindow(openspaceTime)) {
|
||||
|
||||
// Check if in the edge of the window, so we can start downloading a new one
|
||||
if (!_webFieldlinesWindow.edgeWindowReady() && _webFieldlinesWindow.timeIsInWindowMargin(openspaceTime, deltaTime)) {
|
||||
// get new window
|
||||
_webFieldlinesWindow.newWindow(openspaceTime);
|
||||
hasUpdated = false;
|
||||
}
|
||||
else {
|
||||
// If it's in the middle of the window, we can just sit back and relax and let the worker work
|
||||
_webFieldlinesWindow.executeDownloadWorker();
|
||||
}
|
||||
}
|
||||
else {
|
||||
// Hold your horses, we don't want to do anything while deltatime is too high
|
||||
if (abs(deltaTime) < speedThreshhold) {
|
||||
// First it checks the time against the "bigger window" aka the long list of
|
||||
// timesteps we know are available online.
|
||||
// If it's outside that we're gonna need a new one
|
||||
if (_webFieldlinesWindow.timeIsInTriggerTimesWebList(openspaceTime) &&
|
||||
!_webFieldlinesWindow.expectedWindowIsOutOfBounds(openspaceTime) ||
|
||||
_webFieldlinesWindow.checkWorkerEdgeMode())
|
||||
{
|
||||
// Check if in window
|
||||
if (_webFieldlinesWindow.edgeWindowReady() ||
|
||||
_webFieldlinesWindow.timeIsInWindow(openspaceTime))
|
||||
{
|
||||
// Check if in the edge of the window,
|
||||
// so we can start downloading a new one
|
||||
if (!_webFieldlinesWindow.edgeWindowReady() &&
|
||||
_webFieldlinesWindow.timeIsInWindowMargin(openspaceTime, deltaTime))
|
||||
{
|
||||
// get new window
|
||||
_webFieldlinesWindow.newWindow(openspaceTime);
|
||||
hasUpdated = false;
|
||||
}
|
||||
else {
|
||||
// If it's in the middle of the window,
|
||||
// we can just sit back and relax and let the worker work
|
||||
_webFieldlinesWindow.executeDownloadWorker();
|
||||
}
|
||||
}
|
||||
else {
|
||||
_webFieldlinesWindow.getNewTriggerTimesWebList(openspaceTime);
|
||||
// get new window
|
||||
_webFieldlinesWindow.newWindow(openspaceTime);
|
||||
hasUpdated = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
_webFieldlinesWindow.getNewTriggerTimesWebList(openspaceTime);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool WebFieldlinesManager::checkIfWindowIsReadyToLoad()
|
||||
{
|
||||
return _webFieldlinesWindow.workerWindowIsReady();
|
||||
}
|
||||
bool WebFieldlinesManager::checkIfWindowIsReadyToLoad()
|
||||
{
|
||||
return _webFieldlinesWindow.workerWindowIsReady();
|
||||
}
|
||||
|
||||
void WebFieldlinesManager::resetWorker() {
|
||||
_webFieldlinesWindow.rfsHasUpdated();
|
||||
}
|
||||
void WebFieldlinesManager::resetWorker() {
|
||||
_webFieldlinesWindow.rfsHasUpdated();
|
||||
}
|
||||
|
||||
// --------------------------- PRIVATE FUNCTIONS --------------------------- //
|
||||
// --------------------------- PRIVATE FUNCTIONS --------------------------- //
|
||||
|
||||
std::string WebFieldlinesManager::getDirectory(){
|
||||
return _syncDir;
|
||||
}
|
||||
std::string WebFieldlinesManager::getDirectory(){
|
||||
return _syncDir;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -34,160 +34,176 @@
|
||||
|
||||
|
||||
namespace {
|
||||
constexpr const char* _loggerCat = "FieldlinesSequence[ Web FLs Window ]";
|
||||
constexpr const char* _loggerCat = "WebFieldlinesWindow";
|
||||
|
||||
} // namespace
|
||||
|
||||
namespace openspace{
|
||||
// --------------------------- CONSTRUCTORS ---------------------------------------//
|
||||
WebFieldlinesWindow::WebFieldlinesWindow(std::string syncDir, std::string serverUrl,
|
||||
std::vector<std::string>& _sourceFiles,
|
||||
std::vector<double>& _startTimes, size_t& _nStates)
|
||||
{
|
||||
_window.backWidth = 3;
|
||||
_window.forwardWidth = 3;
|
||||
|
||||
WebFieldlinesWindow::WebFieldlinesWindow(std::string syncDir, std::string serverUrl,
|
||||
std::vector<std::string>& _sourceFiles,
|
||||
std::vector<double>& _startTimes, size_t& _nStates)
|
||||
{
|
||||
_window.backWidth = 3;
|
||||
_window.forwardWidth = 3;
|
||||
|
||||
_window.nTriggerTimes = static_cast<int>(_nStates);
|
||||
_window.nTriggerTimes = static_cast<int>(_nStates);
|
||||
|
||||
for(int i = 0; i < _window.nTriggerTimes ; i++){
|
||||
_window.triggerTimes.push_back(std::make_pair(_startTimes[i], _sourceFiles[i]));
|
||||
}
|
||||
|
||||
rfs_nStates = &_nStates;
|
||||
rfs_sourceFiles = &_sourceFiles;
|
||||
rfs_startTimes = &_startTimes;
|
||||
|
||||
_nAvailableWeb = 0; // haven't downloaded that list yet
|
||||
|
||||
_worker = WebFieldlinesWorker(syncDir, serverUrl);
|
||||
|
||||
for(int i = 0; i < _window.nTriggerTimes ; i++){
|
||||
_window.triggerTimes.push_back(
|
||||
std::make_pair(_startTimes[i], _sourceFiles[i])
|
||||
);
|
||||
}
|
||||
|
||||
rfs_nStates = &_nStates;
|
||||
rfs_sourceFiles = &_sourceFiles;
|
||||
rfs_startTimes = &_startTimes;
|
||||
|
||||
_nAvailableWeb = 0; // haven't downloaded that list yet
|
||||
|
||||
_worker = WebFieldlinesWorker(syncDir, serverUrl);
|
||||
|
||||
}
|
||||
|
||||
// Returns true if time is inside the current window
|
||||
bool WebFieldlinesWindow::timeIsInWindow(double time) {
|
||||
return time >= windowStart() && time <= windowEnd();
|
||||
}
|
||||
|
||||
// -------------------------- PUBLIC FUNCTIONS -----------------------------------//
|
||||
|
||||
// Returns true if time is inside the current window
|
||||
bool WebFieldlinesWindow::timeIsInWindow(double time){
|
||||
if(time >= windowStart() && time <= windowEnd())
|
||||
// Returns true if time is at edge of the current window,
|
||||
// and will probably need to update window
|
||||
bool WebFieldlinesWindow::timeIsInWindowMargin(double time, double direction) {
|
||||
const int threshold = 2; // base this on speed later
|
||||
|
||||
if (direction > 0){ // If time is moving forward
|
||||
if (time >= _window.triggerTimes[_window.nTriggerTimes - threshold].first) {
|
||||
if (time > windowEnd()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
|
||||
// Returns true if time is at edge of the current window,
|
||||
// and will probably need to update window
|
||||
bool WebFieldlinesWindow::timeIsInWindowMargin(double time, double direction){
|
||||
int threshold = 2; // base this on speed later
|
||||
|
||||
if (direction > 0){ // If time is moving forward
|
||||
if(time >= _window.triggerTimes[_window.nTriggerTimes - threshold].first){
|
||||
if(time > windowEnd()){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
else{ // If time is moving backwards
|
||||
if (time <= _window.triggerTimes[threshold].first){
|
||||
if (time < windowStart()) {
|
||||
return false;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
else{ // If time is moving backwards
|
||||
if(time <= _window.triggerTimes[threshold].first){
|
||||
if(time < windowStart()){
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* Release the worker for execution,
|
||||
Pick up a timestep to request for download,
|
||||
Check if that timestep is already on disk,
|
||||
repeated until a proper timestep to download is found, and start download */
|
||||
void WebFieldlinesWindow::executeDownloadWorker(){
|
||||
_worker.downloadWindow(_window.triggerTimes);
|
||||
_worker.updateRFSSourceFiles(*rfs_sourceFiles);
|
||||
_edgeWindowReady = false;
|
||||
}
|
||||
|
||||
void WebFieldlinesWindow::newWindow(double time){
|
||||
|
||||
auto it = std::find_if(_triggerTimesWeb.rbegin(), _triggerTimesWeb.rend(), [time](auto element) {
|
||||
return time > element.first;
|
||||
});
|
||||
|
||||
const int index = static_cast<int>(std::distance(it, _triggerTimesWeb.rend())) - 1;
|
||||
_window.triggerTimes.clear();
|
||||
_window.nTriggerTimes = 0;
|
||||
|
||||
// This should be safe, because in the manager, it is checked wether the current position is within
|
||||
// the boundaries with respect to back & forward width
|
||||
for(int i = std::max(index - _window.backWidth,0); i <= std::min(index + _window.forwardWidth, static_cast<int>(_triggerTimesWeb.size() -1)); i++){
|
||||
_window.triggerTimes.push_back(std::make_pair(_triggerTimesWeb[i].first, _triggerTimesWeb[i].second));
|
||||
_window.nTriggerTimes++;
|
||||
}
|
||||
|
||||
if (_worker.edgeMode())
|
||||
_edgeWindowReady = true;
|
||||
|
||||
_worker.newWindowToDownload();
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::timeIsInTriggerTimesWebList(double time){
|
||||
// There are no files to compare with, just going to be false.
|
||||
if(_nAvailableWeb == 0) return false;
|
||||
|
||||
// Most cases, we are currently in the middle of a bunch of datasets, if we are not, lets get some new ones.
|
||||
if(time >= (_triggerTimesWeb.front().first) && time <= (_triggerTimesWeb.back().first))
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
else return false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
Release the worker for execution,
|
||||
Pick up a timestep to request for download,
|
||||
Check if that timestep is already on disk,
|
||||
repeated until a proper timestep to download is found, and start download
|
||||
*/
|
||||
void WebFieldlinesWindow::executeDownloadWorker() {
|
||||
_worker.downloadWindow(_window.triggerTimes);
|
||||
_worker.updateRFSSourceFiles(*rfs_sourceFiles);
|
||||
_edgeWindowReady = false;
|
||||
}
|
||||
|
||||
void WebFieldlinesWindow::getNewTriggerTimesWebList(double time){
|
||||
_worker.getRangeOfAvailableTriggerTimes(time, time, _triggerTimesWeb);
|
||||
_nAvailableWeb = static_cast<int>(_triggerTimesWeb.size());
|
||||
void WebFieldlinesWindow::newWindow(double time) {
|
||||
|
||||
auto it = std::find_if(
|
||||
_triggerTimesWeb.rbegin(),
|
||||
_triggerTimesWeb.rend(),
|
||||
[time](auto element) {
|
||||
return time > element.first;
|
||||
}
|
||||
);
|
||||
|
||||
const int index = static_cast<int>(std::distance(it, _triggerTimesWeb.rend())) - 1;
|
||||
_window.triggerTimes.clear();
|
||||
_window.nTriggerTimes = 0;
|
||||
|
||||
// This should be safe, because in the manager,
|
||||
// it is checked wether the current position is within
|
||||
// the boundaries with respect to back & forward width
|
||||
for(int i = std::max(index - _window.backWidth,0);
|
||||
i <= std::min(index + _window.forwardWidth,
|
||||
static_cast<int>(_triggerTimesWeb.size() -1));
|
||||
i++) {
|
||||
_window.triggerTimes.push_back(
|
||||
std::make_pair(_triggerTimesWeb[i].first, _triggerTimesWeb[i].second)
|
||||
);
|
||||
_window.nTriggerTimes++;
|
||||
}
|
||||
|
||||
|
||||
bool WebFieldlinesWindow::workerWindowIsReady()
|
||||
{
|
||||
return _worker.windowIsComplete();
|
||||
if (_worker.edgeMode()) {
|
||||
_edgeWindowReady = true;
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::expectedWindowIsOutOfBounds(double time) {
|
||||
auto resultForwards = std::find_if(_triggerTimesWeb.rbegin(), _triggerTimesWeb.rbegin() + _window.forwardWidth, [time](auto pair) {
|
||||
_worker.newWindowToDownload();
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::timeIsInTriggerTimesWebList(double time) {
|
||||
// There are no files to compare with, just going to be false.
|
||||
if (_nAvailableWeb == 0) return false;
|
||||
|
||||
// Most cases, we are currently in the middle of a bunch of datasets,
|
||||
// if we are not, lets get some new ones.
|
||||
return (
|
||||
time >= (_triggerTimesWeb.front().first) &&
|
||||
time <= (_triggerTimesWeb.back().first)
|
||||
);
|
||||
}
|
||||
|
||||
void WebFieldlinesWindow::getNewTriggerTimesWebList(double time) {
|
||||
_worker.getRangeOfAvailableTriggerTimes(time, time, _triggerTimesWeb);
|
||||
_nAvailableWeb = static_cast<int>(_triggerTimesWeb.size());
|
||||
}
|
||||
|
||||
|
||||
bool WebFieldlinesWindow::workerWindowIsReady() {
|
||||
return _worker.windowIsComplete();
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::expectedWindowIsOutOfBounds(double time) {
|
||||
auto resultForwards = std::find_if(
|
||||
_triggerTimesWeb.rbegin(),
|
||||
_triggerTimesWeb.rbegin() + _window.forwardWidth,
|
||||
[time](auto pair) {
|
||||
return time > pair.first;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
auto resultBackwards = std::find_if(_triggerTimesWeb.begin(), _triggerTimesWeb.begin() + _window.backWidth, [time](auto pair) {
|
||||
auto resultBackwards = std::find_if(
|
||||
_triggerTimesWeb.begin(),
|
||||
_triggerTimesWeb.begin() + _window.backWidth,
|
||||
[time](auto pair) {
|
||||
return time < pair.first;
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
return resultForwards != _triggerTimesWeb.rbegin() + _window.forwardWidth || resultBackwards != _triggerTimesWeb.begin() + _window.backWidth;
|
||||
}
|
||||
return resultForwards != _triggerTimesWeb.rbegin() + _window.forwardWidth ||
|
||||
resultBackwards != _triggerTimesWeb.begin() + _window.backWidth;
|
||||
}
|
||||
|
||||
void WebFieldlinesWindow::rfsHasUpdated() {
|
||||
_worker.flagUpdated();
|
||||
}
|
||||
void WebFieldlinesWindow::rfsHasUpdated() {
|
||||
_worker.flagUpdated();
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::checkWorkerEdgeMode(){
|
||||
return _worker.edgeMode();
|
||||
}
|
||||
bool WebFieldlinesWindow::checkWorkerEdgeMode(){
|
||||
return _worker.edgeMode();
|
||||
}
|
||||
|
||||
bool WebFieldlinesWindow::edgeWindowReady(){
|
||||
return _edgeWindowReady;
|
||||
}
|
||||
|
||||
// -------------------------- PRIVATE FUNCTIONS -----------------------------------//
|
||||
// Returns first trigger of window
|
||||
double WebFieldlinesWindow::windowStart(){
|
||||
return _window.triggerTimes.front().first;
|
||||
}
|
||||
// Returns last trigger of window
|
||||
double WebFieldlinesWindow::windowEnd(){
|
||||
return _window.triggerTimes.back().first;
|
||||
}
|
||||
bool WebFieldlinesWindow::edgeWindowReady(){
|
||||
return _edgeWindowReady;
|
||||
}
|
||||
|
||||
// Returns first trigger of window
|
||||
double WebFieldlinesWindow::windowStart(){
|
||||
return _window.triggerTimes.front().first;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Returns last trigger of window
|
||||
double WebFieldlinesWindow::windowEnd(){
|
||||
return _window.triggerTimes.back().first;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -39,156 +39,218 @@ namespace {
|
||||
} // namespace
|
||||
|
||||
namespace openspace{
|
||||
// CONSTRUCTOR
|
||||
WebFieldlinesWorker::WebFieldlinesWorker(std::string syncDir, std::string serverUrl)
|
||||
: _syncDir(syncDir), _serverUrl(serverUrl) {
|
||||
// Maybe to be used
|
||||
_endpointSingleDownload = _serverUrl; // should be set by argument to be more general [DEPRICATED FOR NOW, DO WE NEED THIS?]
|
||||
}
|
||||
|
||||
// Destructor, deleting all files that were downloaded during the run.
|
||||
WebFieldlinesWorker::~WebFieldlinesWorker() {
|
||||
// Cancel any potential download
|
||||
if (_downloading && _downloading->hasStarted())
|
||||
_downloading->wait();
|
||||
// Remove all files
|
||||
std::vector<std::string> temp = ghoul::filesystem::Directory(_syncDir).readFiles();
|
||||
// Sneaky check, just want to make sure it is only deleting fieldlines for now
|
||||
if (temp.back().substr(temp.back().size() - 5) == "osfls" && temp.front().substr(temp.front().size() - 5) == "osfls") {
|
||||
std::for_each(temp.begin(), temp.end(), [&](auto it) {
|
||||
FileSys.deleteFile(it);
|
||||
});
|
||||
}
|
||||
WebFieldlinesWorker::WebFieldlinesWorker(std::string syncDir, std::string serverUrl)
|
||||
: _syncDir(syncDir), _serverUrl(serverUrl) {
|
||||
// Maybe to be used
|
||||
_endpointSingleDownload = _serverUrl;
|
||||
// should be set by argument to be more general
|
||||
// [DEPRICATED FOR NOW, DO WE NEED THIS?]
|
||||
}
|
||||
|
||||
WebFieldlinesWorker::~WebFieldlinesWorker() {
|
||||
// Deleting all files that were downloaded during the run.
|
||||
// Cancel any potential download
|
||||
if (_downloading && _downloading->hasStarted())
|
||||
_downloading->wait();
|
||||
// Remove all files
|
||||
std::vector<std::string> temp =
|
||||
ghoul::filesystem::Directory(_syncDir).readFiles();
|
||||
// Sneaky check, just want to make sure it is only deleting fieldlines for now
|
||||
if (temp.back().substr(temp.back().size() - 5) == "osfls" &&
|
||||
temp.front().substr(temp.front().size() - 5) == "osfls")
|
||||
{
|
||||
std::for_each(temp.begin(), temp.end(), [&](auto it) {
|
||||
FileSys.deleteFile(it);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// PUBLIC FUNCTIONS
|
||||
void WebFieldlinesWorker::getRangeOfAvailableTriggerTimes(double startTime, double endTime, std::vector<std::pair<double, std::string>> &_triggerTimesWeb){
|
||||
// PUBLIC FUNCTIONS
|
||||
void WebFieldlinesWorker::getRangeOfAvailableTriggerTimes(double startTime,
|
||||
double endTime,
|
||||
std::vector<std::pair<double,
|
||||
std::string>> &_triggerTimesWeb)
|
||||
{
|
||||
// We don't want to keep sending request, if we just get empty responses.
|
||||
if (!_noMoreRequests) {
|
||||
auto time = global::timeManager.time().ISO8601();
|
||||
Time maxTime;
|
||||
Time minTime;
|
||||
|
||||
// We don't want to keep sending request, if we just get empty responses.
|
||||
if (!_noMoreRequests) {
|
||||
auto time = global::timeManager.time().ISO8601();
|
||||
Time maxTime;
|
||||
Time minTime;
|
||||
const int timeSpann = 2*86400; // The timespann we would like to request (in seconds) [ 1 day = 86400, 1 week = 604800 ]
|
||||
const std::string dataID = "dataID";
|
||||
const std::string files = "files";
|
||||
std::string stringResult;
|
||||
std::vector<std::string> urlList;
|
||||
std::vector<std::string> timeList;
|
||||
// The timespan we would like to request (in seconds)
|
||||
// [ 1 day = 86400, 1 week = 604800 ]
|
||||
const int timeSpan = 2*86400;
|
||||
|
||||
maxTime.setTime(time);
|
||||
minTime.setTime(time);
|
||||
maxTime.advanceTime(timeSpann);
|
||||
minTime.advanceTime(-timeSpann);
|
||||
const std::string dataID = "dataID";
|
||||
const std::string files = "files";
|
||||
std::string stringResult;
|
||||
std::vector<std::string> urlList;
|
||||
std::vector<std::string> timeList;
|
||||
|
||||
std::string url = _serverUrl + "&time.min=" + minTime.ISO8601() + "&time.max=" + maxTime.ISO8601();
|
||||
SyncHttpMemoryDownload mmryDld = SyncHttpMemoryDownload(url);
|
||||
HttpRequest::RequestOptions opt = {};
|
||||
opt.requestTimeoutSeconds = 0;
|
||||
mmryDld.download(opt);
|
||||
maxTime.setTime(time);
|
||||
minTime.setTime(time);
|
||||
maxTime.advanceTime(timeSpan);
|
||||
minTime.advanceTime(-timeSpan);
|
||||
|
||||
std::transform(mmryDld.downloadedData().begin(), mmryDld.downloadedData().end(), std::back_inserter(stringResult),
|
||||
[](char c) {
|
||||
std::string url = _serverUrl +
|
||||
"&time.min=" + minTime.ISO8601() +
|
||||
"&time.max=" + maxTime.ISO8601();
|
||||
|
||||
SyncHttpMemoryDownload mmryDld = SyncHttpMemoryDownload(url);
|
||||
HttpRequest::RequestOptions opt = {};
|
||||
opt.requestTimeoutSeconds = 0;
|
||||
mmryDld.download(opt);
|
||||
|
||||
// TODO emiax: std::copy or similar should be possible here
|
||||
std::transform(
|
||||
mmryDld.downloadedData().begin(),
|
||||
mmryDld.downloadedData().end(),
|
||||
std::back_inserter(stringResult),
|
||||
[](char c) {
|
||||
return c;
|
||||
});
|
||||
|
||||
auto res = json::parse(stringResult);
|
||||
auto temp = std::move(_triggerTimesWeb);
|
||||
_triggerTimesWeb.clear(); // Clear old big window
|
||||
|
||||
for (auto& elem : res[files]) {
|
||||
timeList.push_back(elem["timestamp"]);
|
||||
urlList.push_back(elem["url"]);
|
||||
}
|
||||
);
|
||||
|
||||
// Just want to make sure there is no error in the parsing, so taking the smallest dimension, but should be the same
|
||||
for (int i = 0; i < std::min(timeList.size(), urlList.size()); i++) {
|
||||
_triggerTimesWeb.push_back(std::make_pair(triggerTimeString2Double(timeList[i]), urlList[i]));
|
||||
}
|
||||
auto res = json::parse(stringResult);
|
||||
auto temp = std::move(_triggerTimesWeb);
|
||||
_triggerTimesWeb.clear(); // Clear old big window
|
||||
|
||||
std::sort(_triggerTimesWeb.begin(), _triggerTimesWeb.end()); // If by any chance it would not sort in properly
|
||||
|
||||
if (_triggerTimesWeb.size() == 0 || std::equal(temp.begin(),temp.end(),_triggerTimesWeb.begin(), _triggerTimesWeb.end())) // We got an empty response or the same response twice, stahp it
|
||||
_strikes++;
|
||||
|
||||
if (_strikes % 2 == 0){ // We have got 2 strikes, no more requests for you, Mr.Sir.
|
||||
_bigWindowHasData = (_triggerTimesWeb.size() > 0);
|
||||
_noMoreRequests = true;
|
||||
acceptableToStartRequestingAgain = std::make_pair(minTime.j2000Seconds(), maxTime.j2000Seconds());
|
||||
}
|
||||
for (auto& elem : res[files]) {
|
||||
timeList.push_back(elem["timestamp"]);
|
||||
urlList.push_back(elem["url"]);
|
||||
}
|
||||
|
||||
// Just want to make sure there is no error in the parsing,
|
||||
// so taking the smallest dimension, but should be the same
|
||||
for (int i = 0; i < std::min(timeList.size(), urlList.size()); i++) {
|
||||
_triggerTimesWeb.push_back(
|
||||
std::make_pair(triggerTimeString2Double(timeList[i]), urlList[i])
|
||||
);
|
||||
}
|
||||
|
||||
std::sort(_triggerTimesWeb.begin(), _triggerTimesWeb.end());
|
||||
// If by any chance it would not sort in properly
|
||||
|
||||
if (_triggerTimesWeb.size() == 0 ||
|
||||
std::equal(temp.begin(),
|
||||
temp.end(),
|
||||
_triggerTimesWeb.begin(),
|
||||
_triggerTimesWeb.end()
|
||||
)
|
||||
) { // We got an empty response or the same response twice, stahp it
|
||||
_strikes++;
|
||||
}
|
||||
|
||||
// We have got 2 strikes, no more requests for you, Mr.Sir.
|
||||
if (_strikes % 2 == 0) {
|
||||
_bigWindowHasData = (_triggerTimesWeb.size() > 0);
|
||||
_noMoreRequests = true;
|
||||
acceptableToStartRequestingAgain =
|
||||
std::make_pair(minTime.j2000Seconds(), maxTime.j2000Seconds());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Download all files in the current window
|
||||
// This function starts usually in the middle of the window and proceeds to download all
|
||||
// future timesteps, then steps backwards from the startingpoint
|
||||
// TODO(Axel): Different behaviour depending on direction the user is moving in,
|
||||
// might be wanted?
|
||||
void WebFieldlinesWorker::downloadWindow(
|
||||
std::vector<std::pair<double, std::string>> triggerTimes)
|
||||
{
|
||||
// Helper variables
|
||||
int startingPoint = triggerTimes.size() / 2;
|
||||
bool downloaded = false;
|
||||
bool oneUpdate = false;
|
||||
bool fastDownload = global::timeManager.deltaTime() > 1800.0;
|
||||
|
||||
if (fastDownload) {
|
||||
startingPoint = triggerTimes.size() - 1;
|
||||
}
|
||||
|
||||
// Download all files in the current window
|
||||
// This function starts usually in the middle of the window and proceeds to download all future timesteps,
|
||||
// then steps backwards from the startingpoint
|
||||
//TODO(Axel): Different behaviour depending on direction the user is moving in, might be wanted?
|
||||
void WebFieldlinesWorker::downloadWindow(std::vector<std::pair<double, std::string>> triggerTimes) {
|
||||
|
||||
// Helper variables
|
||||
int startingPoint = triggerTimes.size() / 2;
|
||||
bool downloaded = false;
|
||||
bool oneUpdate = false;
|
||||
bool fastDownload = global::timeManager.deltaTime() > 1800.0;
|
||||
// Is there a download thread to be joined and added to the list?
|
||||
if (_downloading && _downloading->hasSucceeded() && _newWindow) {
|
||||
_downloading->wait();
|
||||
addToDownloadedList(_latestDownload);
|
||||
_readyToDownload = true;
|
||||
// This is to trigger one update of the fieldline timestamp that the user is
|
||||
// currently on, while the rest of them will be downloaded in the background,
|
||||
// and updated once ready
|
||||
if (_latestDownload.second == triggerTimes[startingPoint].second)
|
||||
oneUpdate = true;
|
||||
}
|
||||
|
||||
if (fastDownload) startingPoint = triggerTimes.size() - 1;
|
||||
if (_readyToDownload) {
|
||||
// Forwards
|
||||
std::vector<std::pair<double, std::string>>::iterator forwardIt =
|
||||
triggerTimes.begin();
|
||||
|
||||
// Is there a download thread to be joined and added to the list?
|
||||
if (_downloading && _downloading->hasSucceeded() && _newWindow) {
|
||||
_downloading->wait();
|
||||
addToDownloadedList(_latestDownload);
|
||||
_readyToDownload = true;
|
||||
// This is to trigger one update of the fieldline timestamp that the user is currently on,
|
||||
// while the rest of them will be downloaded in the background, and updated once ready
|
||||
if (_latestDownload.second == triggerTimes[startingPoint].second)
|
||||
oneUpdate = true;
|
||||
}
|
||||
std::advance(forwardIt, startingPoint);
|
||||
std::for_each(forwardIt, triggerTimes.end(), [this, &downloaded](auto it) {
|
||||
if (!downloaded && !fileIsOnDisk(it.first)) {
|
||||
downloadOsfls(it);
|
||||
downloaded = true;
|
||||
_doneUpdating = false;
|
||||
}
|
||||
});
|
||||
|
||||
if (_readyToDownload) {
|
||||
// Forwards
|
||||
std::vector<std::pair<double, std::string>>::iterator forwardIt = triggerTimes.begin();
|
||||
std::advance(forwardIt, startingPoint);
|
||||
std::for_each(forwardIt, triggerTimes.end(), [this, &downloaded](auto it) {
|
||||
if (!downloaded && !fileIsOnDisk(it.first)) {
|
||||
downloadOsfls(it);
|
||||
downloaded = true;
|
||||
_doneUpdating = false;
|
||||
}
|
||||
});
|
||||
|
||||
// Backwards
|
||||
if (!downloaded) {
|
||||
std::for_each(triggerTimes.rbegin(), triggerTimes.rend(), [this, &downloaded](auto it) {
|
||||
// Backwards
|
||||
if (!downloaded) {
|
||||
std::for_each(
|
||||
triggerTimes.rbegin(),
|
||||
triggerTimes.rend(),
|
||||
[this, &downloaded](auto it) {
|
||||
if (!downloaded && !fileIsOnDisk(it.first)) {
|
||||
downloadOsfls(it);
|
||||
downloaded = true;
|
||||
_doneUpdating = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if ((!downloaded && !_doneUpdating && _newWindow && _readyToDownload && _downloadedSomething) || oneUpdate && _downloadedSomething) {
|
||||
// If reach this point, we now know that we have downloaded all the sets
|
||||
_readyToUpdateSourceFiles = true;
|
||||
if(!oneUpdate)
|
||||
_newWindow = false;
|
||||
oneUpdate = false;
|
||||
}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the list of available sourcefiles, owned by renderablefieldlinessequence.
|
||||
void WebFieldlinesWorker::updateRFSSourceFiles(std::vector<std::string>& _sourceFiles) {
|
||||
if (_readyToUpdateSourceFiles) {
|
||||
std::vector<std::string> toInsert;
|
||||
std::transform(_downloadedTriggerTimes.begin(), _downloadedTriggerTimes.end(), std::back_inserter(toInsert), [this](auto const& pair) { return _syncDir + FileSys.PathSeparator + pair.second; });
|
||||
auto sourcePtr = _sourceFiles.begin();
|
||||
std::for_each(toInsert.begin(), toInsert.end(), [&sourcePtr, &_sourceFiles](auto insertableElement) {
|
||||
if ((!downloaded &&
|
||||
!_doneUpdating &&
|
||||
_newWindow &&
|
||||
_readyToDownload &&
|
||||
_downloadedSomething) ||
|
||||
oneUpdate && _downloadedSomething)
|
||||
{
|
||||
// If reach this point, we now know that we have downloaded all the sets
|
||||
_readyToUpdateSourceFiles = true;
|
||||
if (!oneUpdate) {
|
||||
_newWindow = false;
|
||||
}
|
||||
oneUpdate = false;
|
||||
}
|
||||
}
|
||||
|
||||
// Updates the list of available sourcefiles, owned by renderablefieldlinessequence.
|
||||
void WebFieldlinesWorker::updateRFSSourceFiles(std::vector<std::string>& _sourceFiles) {
|
||||
if (_readyToUpdateSourceFiles) {
|
||||
std::vector<std::string> toInsert;
|
||||
std::transform(
|
||||
_downloadedTriggerTimes.begin(),
|
||||
_downloadedTriggerTimes.end(),
|
||||
std::back_inserter(toInsert),
|
||||
[this] (auto const& pair) {
|
||||
return _syncDir + FileSys.PathSeparator + pair.second;
|
||||
}
|
||||
);
|
||||
|
||||
auto sourcePtr = _sourceFiles.begin();
|
||||
std::for_each(
|
||||
toInsert.begin(),
|
||||
toInsert.end(),
|
||||
[&sourcePtr, &_sourceFiles] (auto insertableElement) {
|
||||
for (sourcePtr; sourcePtr != _sourceFiles.end(); sourcePtr++) {
|
||||
|
||||
if (sourcePtr != (--_sourceFiles.end())) {
|
||||
if (insertableElement > *sourcePtr && insertableElement < *sourcePtr++) {
|
||||
if (insertableElement > *sourcePtr &&
|
||||
insertableElement < *sourcePtr++)
|
||||
{
|
||||
_sourceFiles.insert(sourcePtr++, insertableElement);
|
||||
break;
|
||||
}
|
||||
@@ -204,122 +266,158 @@ namespace openspace{
|
||||
if (sourcePtr == _sourceFiles.end()) {
|
||||
sourcePtr = _sourceFiles.insert(sourcePtr, insertableElement);
|
||||
}
|
||||
});
|
||||
}
|
||||
);
|
||||
|
||||
// Set flags to let anyone interested know that this has been done.
|
||||
_readyToUpdateSourceFiles = false;
|
||||
_doneUpdating = true;
|
||||
}
|
||||
// Set flags to let anyone interested know that this has been done.
|
||||
_readyToUpdateSourceFiles = false;
|
||||
_doneUpdating = true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
bool WebFieldlinesWorker::windowIsComplete(){
|
||||
return _doneUpdating;
|
||||
}
|
||||
bool WebFieldlinesWorker::windowIsComplete() {
|
||||
return _doneUpdating;
|
||||
}
|
||||
|
||||
void WebFieldlinesWorker::flagUpdated() {
|
||||
_doneUpdating = false;
|
||||
}
|
||||
void WebFieldlinesWorker::flagUpdated() {
|
||||
_doneUpdating = false;
|
||||
}
|
||||
|
||||
void WebFieldlinesWorker::newWindowToDownload(){
|
||||
_newWindow = true;
|
||||
_downloadedSomething = false;
|
||||
}
|
||||
void WebFieldlinesWorker::newWindowToDownload() {
|
||||
_newWindow = true;
|
||||
_downloadedSomething = false;
|
||||
}
|
||||
|
||||
bool WebFieldlinesWorker::edgeMode(){
|
||||
if (global::timeManager.time().j2000Seconds() < acceptableToStartRequestingAgain.first || global::timeManager.time().j2000Seconds() > acceptableToStartRequestingAgain.second) {
|
||||
_noMoreRequests = false;
|
||||
_bigWindowHasData = false;
|
||||
}
|
||||
return _noMoreRequests && _bigWindowHasData;
|
||||
bool WebFieldlinesWorker::edgeMode() {
|
||||
const double currentTime = global::timeManager.time().j2000Seconds();
|
||||
|
||||
if (currentTime < acceptableToStartRequestingAgain.first ||
|
||||
currentTime > acceptableToStartRequestingAgain.second)
|
||||
{
|
||||
_noMoreRequests = false;
|
||||
_bigWindowHasData = false;
|
||||
}
|
||||
return _noMoreRequests && _bigWindowHasData;
|
||||
}
|
||||
|
||||
std::string WebFieldlinesWorker::downloadOsfls(std::pair<double,std::string> downloadKey){
|
||||
_downloadedSomething = true;
|
||||
_latestDownload = downloadKey;
|
||||
// YYYY-MM-DDTHH-MM-SS.sss.osfls - Might change
|
||||
const int fileNameLength = 29;
|
||||
const std::string fileName = downloadKey.second.substr(downloadKey.second.size()-fileNameLength);
|
||||
std::string url = downloadKey.second;
|
||||
std::string destinationpath = absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + fileName); // what the downloaded filename is to be
|
||||
_downloading = std::make_unique<AsyncHttpFileDownload>(url, destinationpath, HttpFileDownload::Overwrite::Yes);
|
||||
HttpRequest::RequestOptions opt = {};
|
||||
opt.requestTimeoutSeconds = 0;
|
||||
_downloading->start(opt);
|
||||
_readyToDownload = false;
|
||||
return destinationpath;
|
||||
}
|
||||
std::string WebFieldlinesWorker::downloadOsfls(std::pair<double,std::string> downloadKey)
|
||||
{
|
||||
_downloadedSomething = true;
|
||||
_latestDownload = downloadKey;
|
||||
|
||||
// This function searches for triggerTime in _downloadedTriggerTimes,
|
||||
// to see weather a file has already been downloaded or not
|
||||
bool WebFieldlinesWorker::fileIsOnDisk(double triggerTime){
|
||||
if(std::find_if(_downloadedTriggerTimes.begin(), _downloadedTriggerTimes.end(),
|
||||
[&triggerTime](std::pair<double, std::string> const &element){
|
||||
// YYYY-MM-DDTHH-MM-SS.sss.osfls - Might change
|
||||
const int fileNameLength = 29;
|
||||
const std::string fileName =
|
||||
downloadKey.second.substr(downloadKey.second.size() - fileNameLength);
|
||||
|
||||
std::string url = downloadKey.second;
|
||||
std::string destinationPath =
|
||||
absPath(_syncDir + ghoul::filesystem::FileSystem::PathSeparator + fileName);
|
||||
// what the downloaded filename is to be
|
||||
|
||||
_downloading = std::make_unique<AsyncHttpFileDownload>(
|
||||
url, destinationPath, HttpFileDownload::Overwrite::Yes
|
||||
);
|
||||
|
||||
HttpRequest::RequestOptions opt = {};
|
||||
opt.requestTimeoutSeconds = 0;
|
||||
|
||||
_downloading->start(opt);
|
||||
_readyToDownload = false;
|
||||
|
||||
return destinationPath;
|
||||
}
|
||||
|
||||
// This function searches for triggerTime in _downloadedTriggerTimes,
|
||||
// to see weather a file has already been downloaded or not
|
||||
bool WebFieldlinesWorker::fileIsOnDisk(double triggerTime) {
|
||||
return std::find_if(
|
||||
_downloadedTriggerTimes.begin(),
|
||||
_downloadedTriggerTimes.end(),
|
||||
[&triggerTime] (std::pair<double, std::string> const &element) {
|
||||
return element.first == triggerTime;
|
||||
}) != _downloadedTriggerTimes.end())
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
}) != _downloadedTriggerTimes.end();
|
||||
}
|
||||
|
||||
void WebFieldlinesWorker::checkForExistingData(std::vector<std::tuple<double, std::string, int>>& _triggerTimesWeb,
|
||||
std::vector<std::pair<double, std::string>>& _triggerTimesOnDisk){
|
||||
int indexWeb = 0;
|
||||
int indexDisk = 0;
|
||||
|
||||
while(true){
|
||||
if(compareTimetriggersEqual(std::get<0>(_triggerTimesWeb[indexWeb]), _triggerTimesOnDisk[indexDisk].first)){
|
||||
std::get<1>(_triggerTimesWeb[indexWeb]) = _triggerTimesOnDisk[indexDisk].second;
|
||||
}
|
||||
void WebFieldlinesWorker::checkForExistingData(
|
||||
std::vector<std::tuple<double, std::string, int>>& _triggerTimesWeb,
|
||||
std::vector<std::pair<double, std::string>>& _triggerTimesOnDisk)
|
||||
{
|
||||
int indexWeb = 0;
|
||||
int indexDisk = 0;
|
||||
|
||||
// TODO emiax: This looks like an infinite loop.
|
||||
// Need a way to break out from this when destroying the worker..?
|
||||
while (true) {
|
||||
if (compareTimetriggersEqual(
|
||||
std::get<0>(_triggerTimesWeb[indexWeb]),
|
||||
_triggerTimesOnDisk[indexDisk].first
|
||||
)) {
|
||||
std::get<1>(_triggerTimesWeb[indexWeb]) =
|
||||
_triggerTimesOnDisk[indexDisk].second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PRIVATE FUNCTIONS
|
||||
void WebFieldlinesWorker::parseTriggerTimesList(std::string s, std::vector<std::tuple<double, std::string, int>> &_triggerTimesWeb){
|
||||
// Turn into stringstream to parse the comma-delimited string into vector
|
||||
std::stringstream ss(s);
|
||||
char c;
|
||||
std::string sub;
|
||||
while(ss >> c)
|
||||
{
|
||||
if (c == '[' || c == ']' || c == '"' ) continue;
|
||||
else if (c == ','){
|
||||
_triggerTimesWeb.push_back(std::make_tuple(triggerTimeString2Double(sub), sub, -1));
|
||||
sub.clear();
|
||||
}
|
||||
else sub += c;
|
||||
void WebFieldlinesWorker::parseTriggerTimesList(std::string s,
|
||||
std::vector<std::tuple<double, std::string, int>> &_triggerTimesWeb)
|
||||
{
|
||||
// Turn into stringstream to parse the comma-delimited string into vector
|
||||
std::stringstream ss(s);
|
||||
char c;
|
||||
std::string sub;
|
||||
while(ss >> c) {
|
||||
if (c == '[' || c == ']' || c == '"') {
|
||||
continue;
|
||||
}
|
||||
|
||||
_triggerTimesWeb.push_back(std::make_tuple(triggerTimeString2Double(sub), sub, -1));
|
||||
}
|
||||
|
||||
double WebFieldlinesWorker::triggerTimeString2Double(std::string s){
|
||||
s.replace(13, 1, ":");
|
||||
s.replace(16, 1, ":");
|
||||
Time time = Time();
|
||||
time.setTime(s);
|
||||
return (time.j2000Seconds() /*- 69.185013294*/); // openspace timeconverter gives an error. but we're gonna be consistent with the error
|
||||
}
|
||||
|
||||
void WebFieldlinesWorker::triggerTimeDouble2String(double i, std::string& s){
|
||||
double temp = i /*+ 69.185013294*/;
|
||||
Time time = Time();
|
||||
time.setTime(temp);
|
||||
s = time.ISO8601();
|
||||
s.replace(13, 1, "-");
|
||||
s.replace(16, 1, "-");
|
||||
}
|
||||
|
||||
// Inserts the pair in sorted order
|
||||
void WebFieldlinesWorker::addToDownloadedList(std::pair<double, std::string> pair){
|
||||
const std::string fileName = pair.second.substr(pair.second.size() - 29);
|
||||
_downloadedTriggerTimes.insert(std::upper_bound(_downloadedTriggerTimes.begin(),_downloadedTriggerTimes.end(),pair),std::make_pair(pair.first, fileName));
|
||||
if (c == ',') {
|
||||
_triggerTimesWeb.push_back(
|
||||
std::make_tuple(triggerTimeString2Double(sub), sub, -1)
|
||||
);
|
||||
sub.clear();
|
||||
}
|
||||
else {
|
||||
sub += c;
|
||||
}
|
||||
}
|
||||
|
||||
bool WebFieldlinesWorker::compareTimetriggersEqual(double first, double second){
|
||||
double eps = 100.0;
|
||||
if(first > second - eps && first < second + eps) return true;
|
||||
return false;
|
||||
}
|
||||
_triggerTimesWeb.push_back(std::make_tuple(triggerTimeString2Double(sub), sub, -1));
|
||||
}
|
||||
|
||||
double WebFieldlinesWorker::triggerTimeString2Double(std::string s){
|
||||
s.replace(13, 1, ":");
|
||||
s.replace(16, 1, ":");
|
||||
Time time = Time();
|
||||
time.setTime(s);
|
||||
return time.j2000Seconds() /*- 69.185013294*/;
|
||||
// openspace timeconverter gives an error.
|
||||
// but we're gonna be consistent with the error
|
||||
}
|
||||
|
||||
void WebFieldlinesWorker::triggerTimeDouble2String(double i, std::string& s) {
|
||||
double temp = i /*+ 69.185013294*/;
|
||||
Time time = Time();
|
||||
time.setTime(temp);
|
||||
s = time.ISO8601();
|
||||
s.replace(13, 1, "-");
|
||||
s.replace(16, 1, "-");
|
||||
}
|
||||
|
||||
// Inserts the pair in sorted order
|
||||
void WebFieldlinesWorker::addToDownloadedList(std::pair<double, std::string> pair) {
|
||||
const std::string fileName = pair.second.substr(pair.second.size() - 29);
|
||||
_downloadedTriggerTimes.insert(
|
||||
std::upper_bound(
|
||||
_downloadedTriggerTimes.begin(), _downloadedTriggerTimes.end(), pair
|
||||
), std::make_pair(pair.first, fileName)
|
||||
);
|
||||
}
|
||||
|
||||
bool WebFieldlinesWorker::compareTimetriggersEqual(double first, double second) {
|
||||
const double eps = 100.0;
|
||||
return first > second - eps && first < second + eps;
|
||||
}
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
Reference in New Issue
Block a user