From 2472f4697cd7568e4dcc65cfcd5884e0036576aa Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Fri, 3 Jun 2022 13:54:15 +0200 Subject: [PATCH] Improve summary category detection for opm-common reader (#9018) * Move code to quantitynameinforprovider * Use some region-to-region helper function from opm-common * Add more fallbacks --- .../RifEclipseSummaryAddress.cpp | 32 +------ .../FileInterface/RifEclipseSummaryAddress.h | 2 - .../RifEclipseUserDataKeywordTools.cpp | 5 +- .../RiuSummaryVectorDescriptionMap-Test.cpp | 12 +-- .../RiuSummaryQuantityNameInfoProvider.cpp | 86 +++++++++++++++++++ .../RiuSummaryQuantityNameInfoProvider.h | 6 +- 6 files changed, 101 insertions(+), 42 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.cpp b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.cpp index 3516e79b08..bb522a0584 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.cpp @@ -152,36 +152,6 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromEclipseTextAddress( const return fromTokens( tokens ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RifEclipseSummaryAddress::SummaryVarCategory RifEclipseSummaryAddress::identifyCategory( const std::string& vectorName ) -{ - // Try to an exact match on the vector name first in the vector table. - bool exactMatch = true; - auto exactCategory = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( vectorName, exactMatch ); - if ( exactCategory != SUMMARY_INVALID ) return exactCategory; - - if ( vectorName.size() < 3 || vectorName.size() > 8 ) return SUMMARY_INVALID; - - // Try to match the base vector name with more heuristics - auto strippedQuantityName = baseVectorName( vectorName ); - - // First, try to lookup vector in vector table - auto category = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( strippedQuantityName ); - if ( category != SUMMARY_INVALID ) return category; - - // Then check LGR categories - std::string firstTwoLetters = strippedQuantityName.substr( 0, 2 ); - - if ( firstTwoLetters == "LB" ) return SUMMARY_BLOCK_LGR; - if ( firstTwoLetters == "LC" ) return SUMMARY_WELL_COMPLETION_LGR; - if ( firstTwoLetters == "LW" ) return SUMMARY_WELL_LGR; - - if ( strippedQuantityName[0] == 'N' ) return SUMMARY_NETWORK; - return SUMMARY_INVALID; -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -762,7 +732,7 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector if ( tokens.size() > 1 ) token1 = tokens[1]; if ( tokens.size() > 2 ) token2 = tokens[2]; - SummaryVarCategory category = identifyCategory( vectorName ); + SummaryVarCategory category = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( vectorName ); switch ( category ) { diff --git a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.h b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.h index 718447567e..c85579d2b2 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.h +++ b/ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.h @@ -127,8 +127,6 @@ public: static RifEclipseSummaryAddress fromEclipseTextAddress( const std::string& textAddress ); static RifEclipseSummaryAddress fromEclipseTextAddressParseErrorTokens( const std::string& textAddress ); - static SummaryVarCategory identifyCategory( const std::string& vectorName ); - static RifEclipseSummaryAddress fieldAddress( const std::string& vectorName ); static RifEclipseSummaryAddress aquiferAddress( const std::string& vectorName, int aquiferNumber ); static RifEclipseSummaryAddress networkAddress( const std::string& vectorName ); diff --git a/ApplicationLibCode/FileInterface/RifEclipseUserDataKeywordTools.cpp b/ApplicationLibCode/FileInterface/RifEclipseUserDataKeywordTools.cpp index 61bcdefbfb..f73b1303c1 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseUserDataKeywordTools.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseUserDataKeywordTools.cpp @@ -23,6 +23,8 @@ #include "RifEclipseUserDataParserTools.h" +#include "RiuSummaryQuantityNameInfoProvider.h" + #include //-------------------------------------------------------------------------------------------------- @@ -164,7 +166,8 @@ bool RifEclipseUserDataKeywordTools::isYearX( const std::string& identifier ) RifEclipseSummaryAddress RifEclipseUserDataKeywordTools::makeAndFillAddress( const std::string quantityName, const std::vector& columnHeaderText ) { - RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseSummaryAddress::identifyCategory( quantityName ); + RifEclipseSummaryAddress::SummaryVarCategory category = + RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( quantityName ); if ( category == RifEclipseSummaryAddress::SUMMARY_INVALID ) { diff --git a/ApplicationLibCode/UnitTests/RiuSummaryVectorDescriptionMap-Test.cpp b/ApplicationLibCode/UnitTests/RiuSummaryVectorDescriptionMap-Test.cpp index ed1437e5cf..b4cf28c5cb 100644 --- a/ApplicationLibCode/UnitTests/RiuSummaryVectorDescriptionMap-Test.cpp +++ b/ApplicationLibCode/UnitTests/RiuSummaryVectorDescriptionMap-Test.cpp @@ -10,7 +10,7 @@ TEST( RiuSummaryQuantityNameInfoProvider, TestInit ) { { std::string s( "SRSFC" ); - auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); + auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT ); auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s ); @@ -26,7 +26,7 @@ TEST( RiuSummaryQuantityNameInfoProvider, TestInit ) { std::string s( "does not exist" ); - auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); + auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_INVALID ); auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s ); @@ -56,7 +56,7 @@ TEST( RiuSummaryQuantityNameInfoProvider, TestCustomNaming ) { { std::string s( "SRSFCABC" ); - auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); + auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT ); auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s ); @@ -78,13 +78,13 @@ TEST( RiuSummaryQuantityNameInfoProvider, Test6x ) { { std::string s( "GLIT" ); - auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); + auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_GROUP ); } { std::string s( "WSBVPROP" ); - auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); + auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL ); } } @@ -108,7 +108,7 @@ TEST( DISABLED_RiuSummaryQuantityNameInfoProvider, PerformanceLookup ) { for ( const auto& s : values ) { - RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); + RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s ); } } diff --git a/ApplicationLibCode/UserInterface/RiuSummaryQuantityNameInfoProvider.cpp b/ApplicationLibCode/UserInterface/RiuSummaryQuantityNameInfoProvider.cpp index 5b4079f0e0..c7c779dd9c 100644 --- a/ApplicationLibCode/UserInterface/RiuSummaryQuantityNameInfoProvider.cpp +++ b/ApplicationLibCode/UserInterface/RiuSummaryQuantityNameInfoProvider.cpp @@ -18,8 +18,37 @@ #include "RiuSummaryQuantityNameInfoProvider.h" +#include #include +// The region_to_region helper functions are taken from +// https://github.com/OPM/opm-common/blob/e1e0edba7da2d3b30f1f009511a62be073c27eb0/src/opm/input/eclipse/EclipseState/SummaryConfig/SummaryConfig.cpp#L317-L342 + +namespace ParseHelpers +{ +bool is_supported_region_to_region( const std::string& keyword ) +{ + static const auto supported_kw = std::regex{ R"~~(R[OGW]F[RT][-+GL_]?([A-Z0-9_]{3})?)~~" }; + + // R[OGW]F[RT][-+GL]? (e.g., "ROFTG", "RGFR+", or "RWFT") + return std::regex_match( keyword, supported_kw ); +} + +bool is_unsupported_region_to_region( const std::string& keyword ) +{ + static const auto unsupported_kw = std::regex{ R"~~(R([EK]|NL)F[RT][-+_]?([A-Z0-9_]{3})?)~~" }; + + // R[EK]F[RT][-+]? (e.g., "REFT" or "RKFR+") + // RNLF[RT][-+]? (e.g., "RNLFR-" or "RNLFT") + return std::regex_match( keyword, unsupported_kw ); +} + +bool is_region_to_region( const std::string& keyword ) +{ + return is_supported_region_to_region( keyword ) || is_unsupported_region_to_region( keyword ); +} +} // namespace ParseHelpers + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -29,6 +58,63 @@ RiuSummaryQuantityNameInfoProvider* RiuSummaryQuantityNameInfoProvider::instance return singleton; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RifEclipseSummaryAddress::SummaryVarCategory + RiuSummaryQuantityNameInfoProvider::identifyCategory( const std::string& vectorName ) +{ + // Try to an exact match on the vector name first in the vector table. + bool exactMatch = true; + auto exactCategory = categoryFromVectorName( vectorName, exactMatch ); + if ( exactCategory != RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_INVALID ) return exactCategory; + + if ( vectorName.size() < 3 || vectorName.size() > 8 ) + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_INVALID; + + // Try to match the base vector name with more heuristics + auto strippedQuantityName = RifEclipseSummaryAddress::baseVectorName( vectorName ); + + // First, try to lookup vector in vector table + auto category = categoryFromVectorName( strippedQuantityName ); + if ( category != RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_INVALID ) return category; + + switch ( strippedQuantityName[0] ) + { + case 'A': + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_AQUIFER; + case 'B': + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_BLOCK; + case 'F': + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_FIELD; + case 'N': + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_NETWORK; + case 'S': + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_WELL_SEGMENT; + case 'W': + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_WELL; + default: + break; + } + + if ( strippedQuantityName[0] == 'R' ) + { + if ( ParseHelpers::is_region_to_region( strippedQuantityName ) ) + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_REGION_2_REGION; + + return RifEclipseSummaryAddress::SUMMARY_REGION; + } + + // Then check LGR categories + std::string firstTwoLetters = strippedQuantityName.substr( 0, 2 ); + + if ( firstTwoLetters == "LB" ) return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_BLOCK_LGR; + if ( firstTwoLetters == "LC" ) return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_WELL_COMPLETION_LGR; + if ( firstTwoLetters == "LW" ) return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_WELL_LGR; + + return RifEclipseSummaryAddress::SummaryVarCategory::SUMMARY_INVALID; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/UserInterface/RiuSummaryQuantityNameInfoProvider.h b/ApplicationLibCode/UserInterface/RiuSummaryQuantityNameInfoProvider.h index cbe66dccf3..f0bfb31e2d 100644 --- a/ApplicationLibCode/UserInterface/RiuSummaryQuantityNameInfoProvider.h +++ b/ApplicationLibCode/UserInterface/RiuSummaryQuantityNameInfoProvider.h @@ -31,8 +31,8 @@ class RiuSummaryQuantityNameInfoProvider public: static RiuSummaryQuantityNameInfoProvider* instance(); - RifEclipseSummaryAddress::SummaryVarCategory categoryFromVectorName( const std::string& vectorName, - bool exactMatch = false ) const; + RifEclipseSummaryAddress::SummaryVarCategory identifyCategory( const std::string& vectorName ); + std::string longNameFromVectorName( const std::string& vectorName, bool returnVectorNameIfNotFound = false ) const; private: @@ -57,6 +57,8 @@ private: RiuSummaryQuantityNameInfoProvider(); RiuSummaryQuantityInfo quantityInfo( const std::string& vectorName, bool exactMatch = false ) const; + RifEclipseSummaryAddress::SummaryVarCategory categoryFromVectorName( const std::string& vectorName, + bool exactMatch = false ) const; static std::unordered_map createInfoForEclipseKeywords(); static std::unordered_map createInfoFor6xKeywords();