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
This commit is contained in:
Magne Sjaastad 2022-06-03 13:54:15 +02:00 committed by GitHub
parent 95e9ef8bf1
commit 2472f4697c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 101 additions and 42 deletions

View File

@ -152,36 +152,6 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromEclipseTextAddress( const
return fromTokens( tokens ); 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() > 1 ) token1 = tokens[1];
if ( tokens.size() > 2 ) token2 = tokens[2]; if ( tokens.size() > 2 ) token2 = tokens[2];
SummaryVarCategory category = identifyCategory( vectorName ); SummaryVarCategory category = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( vectorName );
switch ( category ) switch ( category )
{ {

View File

@ -127,8 +127,6 @@ public:
static RifEclipseSummaryAddress fromEclipseTextAddress( const std::string& textAddress ); static RifEclipseSummaryAddress fromEclipseTextAddress( const std::string& textAddress );
static RifEclipseSummaryAddress fromEclipseTextAddressParseErrorTokens( 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 fieldAddress( const std::string& vectorName );
static RifEclipseSummaryAddress aquiferAddress( const std::string& vectorName, int aquiferNumber ); static RifEclipseSummaryAddress aquiferAddress( const std::string& vectorName, int aquiferNumber );
static RifEclipseSummaryAddress networkAddress( const std::string& vectorName ); static RifEclipseSummaryAddress networkAddress( const std::string& vectorName );

View File

@ -23,6 +23,8 @@
#include "RifEclipseUserDataParserTools.h" #include "RifEclipseUserDataParserTools.h"
#include "RiuSummaryQuantityNameInfoProvider.h"
#include <QStringList> #include <QStringList>
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -164,7 +166,8 @@ bool RifEclipseUserDataKeywordTools::isYearX( const std::string& identifier )
RifEclipseSummaryAddress RifEclipseUserDataKeywordTools::makeAndFillAddress( const std::string quantityName, RifEclipseSummaryAddress RifEclipseUserDataKeywordTools::makeAndFillAddress( const std::string quantityName,
const std::vector<std::string>& columnHeaderText ) const std::vector<std::string>& columnHeaderText )
{ {
RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseSummaryAddress::identifyCategory( quantityName ); RifEclipseSummaryAddress::SummaryVarCategory category =
RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( quantityName );
if ( category == RifEclipseSummaryAddress::SUMMARY_INVALID ) if ( category == RifEclipseSummaryAddress::SUMMARY_INVALID )
{ {

View File

@ -10,7 +10,7 @@ TEST( RiuSummaryQuantityNameInfoProvider, TestInit )
{ {
{ {
std::string s( "SRSFC" ); std::string s( "SRSFC" );
auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s );
EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT );
auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s ); auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s );
@ -26,7 +26,7 @@ TEST( RiuSummaryQuantityNameInfoProvider, TestInit )
{ {
std::string s( "does not exist" ); std::string s( "does not exist" );
auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s );
EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_INVALID ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_INVALID );
auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s ); auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s );
@ -56,7 +56,7 @@ TEST( RiuSummaryQuantityNameInfoProvider, TestCustomNaming )
{ {
{ {
std::string s( "SRSFCABC" ); std::string s( "SRSFCABC" );
auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s );
EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT );
auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s ); auto longName = RiuSummaryQuantityNameInfoProvider::instance()->longNameFromVectorName( s );
@ -78,13 +78,13 @@ TEST( RiuSummaryQuantityNameInfoProvider, Test6x )
{ {
{ {
std::string s( "GLIT" ); std::string s( "GLIT" );
auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s );
EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_GROUP ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_GROUP );
} }
{ {
std::string s( "WSBVPROP" ); std::string s( "WSBVPROP" );
auto cat = RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); auto cat = RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s );
EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL ); EXPECT_TRUE( cat == RifEclipseSummaryAddress::SUMMARY_WELL );
} }
} }
@ -108,7 +108,7 @@ TEST( DISABLED_RiuSummaryQuantityNameInfoProvider, PerformanceLookup )
{ {
for ( const auto& s : values ) for ( const auto& s : values )
{ {
RiuSummaryQuantityNameInfoProvider::instance()->categoryFromVectorName( s ); RiuSummaryQuantityNameInfoProvider::instance()->identifyCategory( s );
} }
} }

View File

@ -18,8 +18,37 @@
#include "RiuSummaryQuantityNameInfoProvider.h" #include "RiuSummaryQuantityNameInfoProvider.h"
#include <regex>
#include <sstream> #include <sstream>
// 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; 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;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -31,8 +31,8 @@ class RiuSummaryQuantityNameInfoProvider
public: public:
static RiuSummaryQuantityNameInfoProvider* instance(); static RiuSummaryQuantityNameInfoProvider* instance();
RifEclipseSummaryAddress::SummaryVarCategory categoryFromVectorName( const std::string& vectorName, RifEclipseSummaryAddress::SummaryVarCategory identifyCategory( const std::string& vectorName );
bool exactMatch = false ) const;
std::string longNameFromVectorName( const std::string& vectorName, bool returnVectorNameIfNotFound = false ) const; std::string longNameFromVectorName( const std::string& vectorName, bool returnVectorNameIfNotFound = false ) const;
private: private:
@ -57,6 +57,8 @@ private:
RiuSummaryQuantityNameInfoProvider(); RiuSummaryQuantityNameInfoProvider();
RiuSummaryQuantityInfo quantityInfo( const std::string& vectorName, bool exactMatch = false ) const; 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<std::string, RiuSummaryQuantityInfo> createInfoForEclipseKeywords(); static std::unordered_map<std::string, RiuSummaryQuantityInfo> createInfoForEclipseKeywords();
static std::unordered_map<std::string, RiuSummaryQuantityInfo> createInfoFor6xKeywords(); static std::unordered_map<std::string, RiuSummaryQuantityInfo> createInfoFor6xKeywords();