diff --git a/ApplicationCode/FileInterface/RifReaderRmspecColumnBasedData.cpp b/ApplicationCode/FileInterface/RifReaderRmspecColumnBasedData.cpp index f631902851..f8efddb22a 100644 --- a/ApplicationCode/FileInterface/RifReaderRmspecColumnBasedData.cpp +++ b/ApplicationCode/FileInterface/RifReaderRmspecColumnBasedData.cpp @@ -112,7 +112,7 @@ bool RifReaderRmspecColumnBasedData::open(const QString& headerFileName) const ColumnInfo& ci = m_parser->tables()[tableIndex][columIndex]; if (ci.isAVector) { - RifEclipseSummaryAddress sumAddress = address(ci); + RifEclipseSummaryAddress sumAddress = ci.summaryAddress; m_allResultAddresses.push_back(sumAddress); m_mapFromAddressToTimeStepIndex[sumAddress] = m_timeSteps.size() - 1; @@ -161,25 +161,6 @@ const std::vector& RifReaderRmspecColumnBasedData::timeSteps(const RifEc return emptyVector; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RifEclipseSummaryAddress RifReaderRmspecColumnBasedData::address(const ColumnInfo& columnInfo) -{ - return RifEclipseSummaryAddress(columnInfo.category, - columnInfo.quantityName, - columnInfo.regionNumber, - columnInfo.regionNumber2, - columnInfo.wellGroupName, - columnInfo.wellName, - columnInfo.wellSegmentNumber, - columnInfo.lgrName, - columnInfo.cellI, - columnInfo.cellJ, - columnInfo.cellK); - -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/FileInterface/RifReaderRmspecColumnBasedData.h b/ApplicationCode/FileInterface/RifReaderRmspecColumnBasedData.h index dab73da02e..e5b72f968e 100644 --- a/ApplicationCode/FileInterface/RifReaderRmspecColumnBasedData.h +++ b/ApplicationCode/FileInterface/RifReaderRmspecColumnBasedData.h @@ -32,10 +32,6 @@ class QString; class RifColumnBasedRsmspecParser; class RifEclipseSummaryAddress; -struct ColumnInfo; - - - //================================================================================================== // // @@ -55,9 +51,6 @@ public: std::string unitName(const RifEclipseSummaryAddress& resultAddress) const override; -private: - static RifEclipseSummaryAddress address(const ColumnInfo& columnInfo); - private: std::unique_ptr m_parser; std::vector< std::vector > m_timeSteps; diff --git a/ApplicationCode/FileInterface/RifRsmspecParserTools.cpp b/ApplicationCode/FileInterface/RifRsmspecParserTools.cpp index 1267b005b3..1b9bffb15f 100644 --- a/ApplicationCode/FileInterface/RifRsmspecParserTools.cpp +++ b/ApplicationCode/FileInterface/RifRsmspecParserTools.cpp @@ -67,7 +67,40 @@ std::vector RifRsmspecParserTools::splitLine(const std::string& lin //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RifRsmspecParserTools::isAMnemonic(const std::string& word) +bool RifRsmspecParserTools::isAComment(const std::string& word) +{ + if (word.size() > 1 && word[0] == '-' && word[1] == '-') + { + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifRsmspecParserTools::splitLineAndRemoveComments(const std::string& line) +{ + std::istringstream iss(line); + std::vector words{ std::istream_iterator{iss}, + std::istream_iterator{} }; + + for(auto wordsIterator = words.begin(); wordsIterator != words.end(); ++wordsIterator) + { + if (isAComment(*wordsIterator)) + { + words.erase(wordsIterator, words.end()); + break; + } + } + + return words; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifRsmspecParserTools::canBeAMnemonic(const std::string& word) { if (word.size() < 1) return false; @@ -140,6 +173,91 @@ RifEclipseSummaryAddress::SummaryVarCategory RifRsmspecParserTools::identifyCate return RifEclipseSummaryAddress::SUMMARY_INVALID; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RifRsmspecParserTools::findFirstNonEmptyEntryIndex(std::vector& list) +{ + for (size_t i = 0; i < list.size(); i++) + { + if (!list[i].empty()) + { + return i; + } + } + return list.size(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress RifRsmspecParserTools::makeAndFillAddress(std::string scaleFactor, std::string quantityName, std::vector< std::string > headerColumn) +{ + int regionNumber = -1; + int regionNumber2 = -1; + std::string wellGroupName = ""; + std::string wellName = ""; + int wellSegmentNumber = -1; + std::string lgrName = ""; + int cellI = -1; + int cellJ = -1; + int cellK = -1; + + RifEclipseSummaryAddress::SummaryVarCategory category = identifyCategory(quantityName); + + switch (category) //TODO: More categories + { + case (RifEclipseSummaryAddress::SUMMARY_INVALID): + { + break; + } + case (RifEclipseSummaryAddress::SUMMARY_WELL): + { + size_t index = findFirstNonEmptyEntryIndex(headerColumn); + if (index < headerColumn.size()) + { + wellName = headerColumn[index]; + } + break; + } + case (RifEclipseSummaryAddress::SUMMARY_WELL_GROUP): + { + size_t index = findFirstNonEmptyEntryIndex(headerColumn); + if (index < headerColumn.size()) + { + wellGroupName = headerColumn[index]; + } + break; + } + case (RifEclipseSummaryAddress::SUMMARY_REGION): + { + size_t index = findFirstNonEmptyEntryIndex(headerColumn); + if (index < headerColumn.size()) + { + try + { + regionNumber = std::stoi(headerColumn[index]); + } + catch (...){} + } + break; + } + default: + break; + } + + return RifEclipseSummaryAddress(category, + quantityName, + regionNumber, + regionNumber2, + wellGroupName, + wellName, + wellSegmentNumber, + lgrName, + cellI, + cellJ, + cellK); +} //-------------------------------------------------------------------------------------------------- /// @@ -147,83 +265,80 @@ RifEclipseSummaryAddress::SummaryVarCategory RifRsmspecParserTools::identifyCate std::vector RifRsmspecParserTools::columnInfoForTable(std::stringstream& streamData, std::string& line) { size_t columnCount = 0; - size_t vectorCount = 0; std::vector table; + + while (isLineSkippable(line)) + { + if (!streamData.good()) return table; + std::getline(streamData, line); + } + + std::vector quantityNames = splitLineAndRemoveComments(line); + std::getline(streamData, line); + std::vector unitNames = splitLineAndRemoveComments(line); + std::getline(streamData, line); + std::vector scaleFactors = splitLineAndRemoveComments(line); + + std::vector categories; + columnCount = quantityNames.size(); + + for (std::string unit : unitNames) + { + ColumnInfo columnInfo; + columnInfo.unitName = unit; + table.push_back(columnInfo); + } + + if (scaleFactors.size() < columnCount) + { + int diff = columnCount - scaleFactors.size(); + for (int i = 0; i < diff; i++) + { + scaleFactors.push_back("1.0"); + } + } + + std::vector< std::vector< std::string > > restOfHeader; + bool header = true; while (header) { - while (isLineSkippable(line)) - { - if (!streamData.good()) return table; - std::getline(streamData, line); - } - - std::vector words = splitLine(line); - if (!words.empty()) - { - if (words[0] == "TIME") - { - for (std::string word : words) - { - ColumnInfo columnInfo; - if (isAMnemonic(word)) - { - columnInfo.isAVector = true; - columnInfo.category = identifyCategory(word); - ++vectorCount; - } - columnInfo.quantityName = word; - table.push_back(columnInfo); - } - columnCount = table.size(); - } - else if (words[0] == "DAYS") - { - if (words.size() == columnCount) - { - for (int i = 0; i < words.size(); i++) - { - table[i].unitName = words[i]; - } - } - } - else if (words.size() == vectorCount) - { - for (int i = 0; i < words.size(); i++) - { - switch (table[i].category) //TODO: More categories - { - case (RifEclipseSummaryAddress::SUMMARY_INVALID): - break; - case (RifEclipseSummaryAddress::SUMMARY_WELL): - table[i].wellName = words[i]; - break; - case (RifEclipseSummaryAddress::SUMMARY_WELL_GROUP): - table[i].wellGroupName = words[i]; - break; - case (RifEclipseSummaryAddress::SUMMARY_REGION): - table[i].regionNumber = std::stoi(words[i]); - break; - default: - break; - } - } - } - else if (words.size() == columnCount) - { - /* TODO: Scale factor - for (int i = 0; i < words.size(); i++) - { - table[i].scaleFactor = words[i]; - }*/ - - header = false; - break; - } - } - std::getline(streamData, line); + + std::vector words = splitLineAndRemoveComments(line); + + if (words.size() == columnCount) + { + header = false; + break; + } + else + { + int diff = columnCount - words.size(); + + if (diff == columnCount) + { + std::vector< std::string > vectorOfEmptyStrings(columnCount, ""); + restOfHeader.push_back(vectorOfEmptyStrings); + } + else + { + std::vector< std::string > wordsWithEmptyStrings(diff, ""); + wordsWithEmptyStrings.insert(wordsWithEmptyStrings.begin(), words.begin(), words.end()); + restOfHeader.push_back(wordsWithEmptyStrings); + } + } + } + + for (size_t i = 0; i < columnCount; i++) + { + std::vector< std::string > restOfHeaderColumn; + for (std::vector< std::string > restOfHeaderRow : restOfHeader) + { + restOfHeaderColumn.push_back(restOfHeaderRow.at(i)); + } + table[i].summaryAddress = makeAndFillAddress(scaleFactors.at(i), quantityNames.at(i), restOfHeaderColumn); } return table; diff --git a/ApplicationCode/FileInterface/RifRsmspecParserTools.h b/ApplicationCode/FileInterface/RifRsmspecParserTools.h index 012cef3146..1932236b58 100644 --- a/ApplicationCode/FileInterface/RifRsmspecParserTools.h +++ b/ApplicationCode/FileInterface/RifRsmspecParserTools.h @@ -31,18 +31,7 @@ struct ColumnInfo { bool isAVector = false; - RifEclipseSummaryAddress::SummaryVarCategory category; - std::string quantityName; - std::string scaleFactor; - int regionNumber; - int regionNumber2; - std::string wellGroupName; - std::string wellName; - int wellSegmentNumber; - std::string lgrName; - int cellI; - int cellJ; - int cellK; + RifEclipseSummaryAddress summaryAddress; std::string unitName; std::vector values; }; @@ -55,9 +44,13 @@ class RifRsmspecParserTools public: static bool isLineSkippable(const std::string& line); static std::vector splitLine(const std::string& line); - static bool isAMnemonic(const std::string& word); + static bool isAComment(const std::string& word); + static std::vector splitLineAndRemoveComments(const std::string& line); + static bool canBeAMnemonic(const std::string& word); static RifEclipseSummaryAddress::SummaryVarCategory identifyCategory(const std::string& word); static void splitLineToDoubles(const std::string& line, std::vector& values); + static size_t findFirstNonEmptyEntryIndex(std::vector& list); + static RifEclipseSummaryAddress makeAndFillAddress(std::string scaleFactor, std::string quantityName, std::vector< std::string > headerColumn); static std::vector columnInfoForTable(std::stringstream& data, std::string& line); static bool isANumber(const std::string& line); static std::vector headerReader(std::stringstream& streamData, std::string& line); diff --git a/ApplicationCode/UnitTests/ObservedDataParser-Test.cpp b/ApplicationCode/UnitTests/ObservedDataParser-Test.cpp index 0d6265eaaa..d5a946bdb4 100644 --- a/ApplicationCode/UnitTests/ObservedDataParser-Test.cpp +++ b/ApplicationCode/UnitTests/ObservedDataParser-Test.cpp @@ -266,9 +266,9 @@ TEST(RifColumnBasedRsmspecParserTest, TestTableValues) EXPECT_EQ(3, tables.at(1).at(0).values.at(2)); EXPECT_EQ(370, tables.at(1).at(3).values.at(3)); - EXPECT_EQ("WLVP", tables.at(0).at(1).quantityName); - EXPECT_EQ("P-9P", tables.at(1).at(1).wellName); - EXPECT_NE("P-9P", tables.at(1).at(0).wellName); + EXPECT_EQ("WLVP", tables.at(0).at(1).summaryAddress.quantityName()); + EXPECT_EQ("P-9P", tables.at(1).at(1).summaryAddress.wellName()); + EXPECT_NE("P-9P", tables.at(1).at(0).summaryAddress.wellName()); }