From bdf859cd3c6b914dce2772e5936f5cd942fe84eb Mon Sep 17 00:00:00 2001 From: GPayne Date: Fri, 20 Mar 2020 17:27:39 -0600 Subject: [PATCH] Modified sbdb file read to handle line errors while keeping other data lines --- .../rendering/renderableorbitalkepler.cpp | 8 +-- .../space/rendering/renderableorbitalkepler.h | 3 + .../space/rendering/renderablesmallbody.cpp | 70 +++++++++++++------ 3 files changed, 54 insertions(+), 27 deletions(-) diff --git a/modules/space/rendering/renderableorbitalkepler.cpp b/modules/space/rendering/renderableorbitalkepler.cpp index d530f3f4c0..6efa17e4a4 100644 --- a/modules/space/rendering/renderableorbitalkepler.cpp +++ b/modules/space/rendering/renderableorbitalkepler.cpp @@ -391,20 +391,14 @@ RenderableOrbitalKepler::RenderableOrbitalKepler(const ghoul::Dictionary& dictio else { _appearance.lineWidth = 2.0; } - - auto reinitializeTrailBuffers = [this]() { - initializeGL(); - }; - + reinitializeTrailBuffers = std::function([this] { initializeGL(); }); _path.onChange(reinitializeTrailBuffers); _nSegments.onChange(reinitializeTrailBuffers); - _upperLimit.onChange(reinitializeTrailBuffers); addPropertySubOwner(_appearance); addProperty(_path); addProperty(_nSegments); addProperty(_opacity); - addProperty(_upperLimit); setRenderBin(Renderable::RenderBin::Overlay); } diff --git a/modules/space/rendering/renderableorbitalkepler.h b/modules/space/rendering/renderableorbitalkepler.h index e99b2c47a9..65fad29b56 100644 --- a/modules/space/rendering/renderableorbitalkepler.h +++ b/modules/space/rendering/renderableorbitalkepler.h @@ -68,6 +68,8 @@ protected: double epochFromSubstring(const std::string& epochString); double epochFromYMDdSubstring(const std::string& epochString); int daysIntoGivenYear(int month, int dayOfMonth); + std::function reinitializeTrailBuffers; + const std::vector LeapYears = { 1956, 1960, 1964, 1968, 1972, 1976, 1980, 1984, 1988, 1992, 1996, 2000, 2004, 2008, 2012, 2016, 2020, 2024, 2028, 2032, 2036, 2040, @@ -105,6 +107,7 @@ protected: const double convertDaysToSecs = 86400.; std::vector _data; properties::UIntProperty _upperLimit; + properties::Property::OnChangeHandle _upperLimitCallbackHandle; private: struct Vertex { diff --git a/modules/space/rendering/renderablesmallbody.cpp b/modules/space/rendering/renderablesmallbody.cpp index 97d6ed12ec..7a1b018f0c 100644 --- a/modules/space/rendering/renderablesmallbody.cpp +++ b/modules/space/rendering/renderablesmallbody.cpp @@ -135,6 +135,8 @@ documentation::Documentation RenderableSmallBody::Documentation() { RenderableSmallBody::RenderableSmallBody(const ghoul::Dictionary& dictionary) : RenderableOrbitalKepler(dictionary) { + _upperLimitCallbackHandle = _upperLimit.onChange(reinitializeTrailBuffers); + addProperty(_upperLimit); } void RenderableSmallBody::readDataFile(const std::string& filename) { @@ -168,8 +170,12 @@ void RenderableSmallBody::readDataFile(const std::string& filename) { std::getline(file, line); // get rid of first line (header) numberOfLines -= 1; if (_upperLimit == 0 || _upperLimit > numberOfLines) { - //If limit wasn't specified in dictionary, set to lines in file (-header) + //If a limit wasn't specified in dictionary, set it to # lines in file + // minus the header line (but temporarily disable callback to avoid 2nd call) + _upperLimit.removeOnChange(_upperLimitCallbackHandle); + _upperLimit.setMaxValue(numberOfLines); _upperLimit = static_cast(numberOfLines); + _upperLimitCallbackHandle = _upperLimit.onChange(reinitializeTrailBuffers); } else { lineSkipFraction = static_cast(_upperLimit) / @@ -184,31 +190,48 @@ void RenderableSmallBody::readDataFile(const std::string& filename) { return; } - for (csvLine = 1; csvLine <= numberOfLines; csvLine++) { + unsigned int sequentialLineErrors = 0; + for (csvLine = 1; csvLine <= numberOfLines; csvLine++, sequentialLineErrors++) { currLineFraction = static_cast(csvLine - 1) * lineSkipFraction; currLineCount = static_cast(currLineFraction); if (currLineCount > lastLineCount) { - readOrbitalParamsFromThisLine(fieldCount, csvLine, file); + try { + readOrbitalParamsFromThisLine(fieldCount, csvLine, file); + sequentialLineErrors = 0; + } + catch (std::invalid_argument&) { + const char* errMsg = "Unable to convert field {} to double value "\ + "(invalid_argument exception) at line {}/{} of {}"; + LERROR(fmt::format( + errMsg, + fieldCount, csvLine + 1, numberOfLines, filename + )); + } + catch (std::out_of_range&) { + const char* errMsg = "Unable to convert field {} to double value "\ + "(out_of_range exception) at line {}/{} of {}"; + LERROR(fmt::format( + errMsg, + fieldCount, csvLine + 1, numberOfLines, filename + )); + } + catch (std::ios_base::failure& f) { + throw f; + } + + if (sequentialLineErrors == 4) { + _data.clear(); + _sbNames.clear(); + LERROR(fmt::format( + "Abandoning data file {} (too many sequential line errors).", + filename + )); + break; + } } lastLineCount = currLineCount; } } - catch (std::invalid_argument&) { - const char* errMsg = "Unable to convert field {} to double value "\ - "(invalid_argument exception) at line {}/{} of {}"; - LERROR(fmt::format( - errMsg, - fieldCount, csvLine + 1, numberOfLines, filename - )); - } - catch (std::out_of_range&) { - const char* errMsg = "Unable to convert field {} to double value "\ - "(out_of_range exception) at line {}/{} of {}"; - LERROR(fmt::format( - errMsg, - fieldCount, csvLine + 1, numberOfLines, filename - )); - } catch (std::ios_base::failure&) { const char* errMsg = "File read exception (ios_base::failure) while trying "\ "to read field {} at line {}/{} of {}"; @@ -225,11 +248,18 @@ void RenderableSmallBody::readOrbitalParamsFromThisLine(int& fieldCount, std::streamoff& csvLine, std::ifstream& file) { + const int numDataFields = 8; std::string name; std::string field; - fieldCount = 0; KeplerParameters keplerElements; + //If there was a read/conversion error in the previous line, then read the remainder + // of that line and throw it out first before proceeding with the next line. + if (fieldCount != (numDataFields + 1) && csvLine != 1) { + std::getline(file, field); + } + fieldCount = 0; + // Object designator string std::getline(file, name, ','); fieldCount++;