diff --git a/ApplicationCode/FileInterface/CMakeLists_files.cmake b/ApplicationCode/FileInterface/CMakeLists_files.cmake index cfd15c7dd2..a005e08085 100644 --- a/ApplicationCode/FileInterface/CMakeLists_files.cmake +++ b/ApplicationCode/FileInterface/CMakeLists_files.cmake @@ -17,6 +17,7 @@ ${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.h ${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.h ${CEE_CURRENT_LIST_DIR}RifSummaryReaderInterface.h ${CEE_CURRENT_LIST_DIR}RifColumnBasedAsciiParser.h +${CEE_CURRENT_LIST_DIR}RifRsmspecParserTools.h ${CEE_CURRENT_LIST_DIR}RifColumnBasedRsmspecParser.h ${CEE_CURRENT_LIST_DIR}RifReaderObservedData.h ${CEE_CURRENT_LIST_DIR}RifReaderEclipseSummary.h @@ -52,6 +53,7 @@ ${CEE_CURRENT_LIST_DIR}RifReaderEclipseInput.cpp ${CEE_CURRENT_LIST_DIR}RifReaderEclipseOutput.cpp ${CEE_CURRENT_LIST_DIR}RifSummaryReaderInterface.cpp ${CEE_CURRENT_LIST_DIR}RifColumnBasedAsciiParser.cpp +${CEE_CURRENT_LIST_DIR}RifRsmspecParserTools.cpp ${CEE_CURRENT_LIST_DIR}RifColumnBasedRsmspecParser.cpp ${CEE_CURRENT_LIST_DIR}RifReaderObservedData.cpp ${CEE_CURRENT_LIST_DIR}RifReaderEclipseSummary.cpp diff --git a/ApplicationCode/FileInterface/RifColumnBasedRsmspecParser.cpp b/ApplicationCode/FileInterface/RifColumnBasedRsmspecParser.cpp index 76f044c4ad..78e61bb842 100644 --- a/ApplicationCode/FileInterface/RifColumnBasedRsmspecParser.cpp +++ b/ApplicationCode/FileInterface/RifColumnBasedRsmspecParser.cpp @@ -18,6 +18,8 @@ #include "RifColumnBasedRsmspecParser.h" +#include "RifRsmspecParserTools.h" + #include "RiaLogging.h" #include "cvfAssert.h" @@ -43,227 +45,6 @@ const std::vector< std::vector >& RifColumnBasedRsmspecParser::table return m_tables; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifColumnBasedRsmspecParser::isLineSkippable(const std::string& line) -{ - if (line.size() == 0) - { - return true; - } - else if (line[0] == '-') - { - return true; - } - else if (line.size() == 1 && line[0] == '1') - { - return true; - } - - std::string str(line); - - if (str.find("SUMMARY") < str.size()) - { - return true; - } - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RifColumnBasedRsmspecParser::splitLine(const std::string& line) -{ - std::istringstream iss(line); - std::vector words{ std::istream_iterator{iss}, - std::istream_iterator{} }; - return words; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifColumnBasedRsmspecParser::isAMnemonic(const std::string& word) -{ - if (word.size() < 1) return false; - - char firstLetter = word.at(0); - - if (firstLetter == 'A' || - firstLetter == 'B' || - firstLetter == 'C' || - firstLetter == 'F' || - firstLetter == 'G' || - firstLetter == 'N' || - firstLetter == 'R' || - firstLetter == 'S' || - firstLetter == 'W' ) - { - return true; - } - - if (word.size() < 2) return false; - - std::string firstTwoLetters; - firstTwoLetters.push_back(word.at(0)); - firstTwoLetters.push_back(word.at(1)); - - if (firstTwoLetters == "LB" || - firstTwoLetters == "LC" || - firstTwoLetters == "LW" ) - { - return true; - } - - return false; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RifEclipseSummaryAddress::SummaryVarCategory RifColumnBasedRsmspecParser::identifyCategory(const std::string& word) -{ - if (word.size() == 0) return RifEclipseSummaryAddress::SUMMARY_INVALID; - - char firstLetter = word.at(0); - - if (firstLetter == 'A') return RifEclipseSummaryAddress::SUMMARY_AQUIFER; - if (firstLetter == 'B') return RifEclipseSummaryAddress::SUMMARY_BLOCK; - if (firstLetter == 'C') return RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION; - if (firstLetter == 'F') return RifEclipseSummaryAddress::SUMMARY_FIELD; - if (firstLetter == 'G') return RifEclipseSummaryAddress::SUMMARY_WELL_GROUP; - if (firstLetter == 'N') return RifEclipseSummaryAddress::SUMMARY_NETWORK; - if (firstLetter == 'R') return RifEclipseSummaryAddress::SUMMARY_REGION; //TODO: CAN BE REGION2REGION OR MISC!! - if (firstLetter == 'S') return RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT; - if (firstLetter == 'W') return RifEclipseSummaryAddress::SUMMARY_WELL; - - if (word.size() < 2) return RifEclipseSummaryAddress::SUMMARY_INVALID; - - std::string firstTwoLetters; - firstTwoLetters.push_back(word.at(0)); - firstTwoLetters.push_back(word.at(1)); - - if (firstTwoLetters == "LB") return RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR; - if (firstTwoLetters == "LC") return RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION_LGR; - if (firstTwoLetters == "LW") return RifEclipseSummaryAddress::SUMMARY_WELL_LGR; - - /* - TODO - return RifEclipseSummaryAddress::SUMMARY_MISC - return RifEclipseSummaryAddress::SUMMARY_REGION_2_REGION - */ - - return RifEclipseSummaryAddress::SUMMARY_INVALID; -} - - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RifColumnBasedRsmspecParser::columnInfoForTable(std::stringstream& streamData, std::string& line) -{ - size_t columnCount = 0; - size_t vectorCount = 0; - - std::vector table; - 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); - } - - return table; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RifColumnBasedRsmspecParser::splitLineToDoubles(const std::string& line, std::vector& values) -{ - std::istringstream iss(line); - values.clear(); - - while (iss.good()) - { - double d; - iss >> d; - values.push_back(d); - } - - return !iss.fail(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -276,15 +57,15 @@ void RifColumnBasedRsmspecParser::parseData(const QString& data) do { - std::vector table = columnInfoForTable(streamData, line); - int columnCount = table.size(); + std::vector table = RifRsmspecParserTools::columnInfoForTable(streamData, line); + size_t columnCount = table.size(); if (columnCount == 0) break; std::vector values; do { - if (!splitLineToDoubles(line, values)) break; + RifRsmspecParserTools::splitLineToDoubles(line, values); if (values.size() != columnCount) break; for (size_t i = 0; i < columnCount; i++) diff --git a/ApplicationCode/FileInterface/RifColumnBasedRsmspecParser.h b/ApplicationCode/FileInterface/RifColumnBasedRsmspecParser.h index 4a5d851a74..e1daee5594 100644 --- a/ApplicationCode/FileInterface/RifColumnBasedRsmspecParser.h +++ b/ApplicationCode/FileInterface/RifColumnBasedRsmspecParser.h @@ -24,28 +24,11 @@ #include #include +#include #include #include -#include -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; - std::string unitName; - std::vector values; -}; +struct ColumnInfo; //================================================================================================== /// @@ -57,14 +40,7 @@ public: const std::vector< std::vector >& tables() const; private: - static bool isLineSkippable(const std::string& line); - static std::vector splitLine(const std::string& line); - static bool isAMnemonic(const std::string& word); - static RifEclipseSummaryAddress::SummaryVarCategory identifyCategory(const std::string& word); - bool splitLineToDoubles(const std::string& line, std::vector& values); - static std::vector columnInfoForTable(std::stringstream& data, std::string& line); - - void parseData(const QString& data); + void parseData(const QString& data); private: std::vector< std::vector > m_tables; diff --git a/ApplicationCode/FileInterface/RifRsmspecParserTools.cpp b/ApplicationCode/FileInterface/RifRsmspecParserTools.cpp new file mode 100644 index 0000000000..c5bda0826c --- /dev/null +++ b/ApplicationCode/FileInterface/RifRsmspecParserTools.cpp @@ -0,0 +1,246 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RifRsmspecParserTools.h" + +#include "RiaLogging.h" + +#include "cvfAssert.h" + +#include +#include +#include + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifRsmspecParserTools::isLineSkippable(const std::string& line) +{ + if (line.size() == 0) + { + return true; + } + else if (line[0] == '-') + { + return true; + } + else if (line.size() == 1 && line[0] == '1') + { + return true; + } + + std::string str(line); + + if (str.find("SUMMARY") < str.size()) + { + return true; + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifRsmspecParserTools::splitLine(const std::string& line) +{ + std::istringstream iss(line); + std::vector words{ std::istream_iterator{iss}, + std::istream_iterator{} }; + return words; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RifRsmspecParserTools::isAMnemonic(const std::string& word) +{ + if (word.size() < 1) return false; + + char firstLetter = word.at(0); + + if (firstLetter == 'A' || + firstLetter == 'B' || + firstLetter == 'C' || + firstLetter == 'F' || + firstLetter == 'G' || + firstLetter == 'N' || + firstLetter == 'R' || + firstLetter == 'S' || + firstLetter == 'W' ) + { + return true; + } + + if (word.size() < 2) return false; + + std::string firstTwoLetters; + firstTwoLetters.push_back(word.at(0)); + firstTwoLetters.push_back(word.at(1)); + + if (firstTwoLetters == "LB" || + firstTwoLetters == "LC" || + firstTwoLetters == "LW" ) + { + return true; + } + + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress::SummaryVarCategory RifRsmspecParserTools::identifyCategory(const std::string& word) +{ + if (word.size() == 0) return RifEclipseSummaryAddress::SUMMARY_INVALID; + + char firstLetter = word.at(0); + + if (firstLetter == 'A') return RifEclipseSummaryAddress::SUMMARY_AQUIFER; + if (firstLetter == 'B') return RifEclipseSummaryAddress::SUMMARY_BLOCK; + if (firstLetter == 'C') return RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION; + if (firstLetter == 'F') return RifEclipseSummaryAddress::SUMMARY_FIELD; + if (firstLetter == 'G') return RifEclipseSummaryAddress::SUMMARY_WELL_GROUP; + if (firstLetter == 'N') return RifEclipseSummaryAddress::SUMMARY_NETWORK; + if (firstLetter == 'R') return RifEclipseSummaryAddress::SUMMARY_REGION; //TODO: CAN BE REGION2REGION OR MISC!! + if (firstLetter == 'S') return RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT; + if (firstLetter == 'W') return RifEclipseSummaryAddress::SUMMARY_WELL; + + if (word.size() < 2) return RifEclipseSummaryAddress::SUMMARY_INVALID; + + std::string firstTwoLetters; + firstTwoLetters.push_back(word.at(0)); + firstTwoLetters.push_back(word.at(1)); + + if (firstTwoLetters == "LB") return RifEclipseSummaryAddress::SUMMARY_BLOCK_LGR; + if (firstTwoLetters == "LC") return RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION_LGR; + if (firstTwoLetters == "LW") return RifEclipseSummaryAddress::SUMMARY_WELL_LGR; + + /* + TODO + return RifEclipseSummaryAddress::SUMMARY_MISC + return RifEclipseSummaryAddress::SUMMARY_REGION_2_REGION + */ + + return RifEclipseSummaryAddress::SUMMARY_INVALID; +} + + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RifRsmspecParserTools::columnInfoForTable(std::stringstream& streamData, std::string& line) +{ + size_t columnCount = 0; + size_t vectorCount = 0; + + std::vector table; + 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); + } + + return table; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RifRsmspecParserTools::splitLineToDoubles(const std::string& line, std::vector& values) +{ + std::istringstream iss(line); + values.clear(); + + while (iss.good()) + { + double d; + iss >> d; + values.push_back(d); + } +} diff --git a/ApplicationCode/FileInterface/RifRsmspecParserTools.h b/ApplicationCode/FileInterface/RifRsmspecParserTools.h new file mode 100644 index 0000000000..fbda03d184 --- /dev/null +++ b/ApplicationCode/FileInterface/RifRsmspecParserTools.h @@ -0,0 +1,62 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// Copyright (C) 2017- Statoil ASA +// +// ResInsight is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY +// WARRANTY; without even the implied warranty of MERCHANTABILITY or +// FITNESS FOR A PARTICULAR PURPOSE. +// +// See the GNU General Public License at +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + +#include "RifEclipseSummaryAddress.h" + +#include +#include +#include + +#include +#include +#include + +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; + std::string unitName; + std::vector values; +}; + +//================================================================================================== +/// +//================================================================================================== +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 RifEclipseSummaryAddress::SummaryVarCategory identifyCategory(const std::string& word); + static void splitLineToDoubles(const std::string& line, std::vector& values); + static std::vector columnInfoForTable(std::stringstream& data, std::string& line); +};