ResInsight/ApplicationLibCode/Application/Tools/RiaSummaryAddressAnalyzer.cpp
Magne Sjaastad 945f1b1902
Use field auto values for summary plots
Use auto value concept in summary plot configuration. Default behavior is unchanged, but it is now possible to unlink a field to specify a custom value for this field.

Other changes:
* Add missing requirement for Svg in test application
* Use calculator icon and rename panel text
Use icon and relevant text to make it clear that the content in Calculator Data can be used for Grid Property Calculator and nothing else.
* Add example with scoped enum and auto value
* Use enum value starting av 10 to make sure enum values (not option item index) are working as expected
2022-09-05 14:12:49 +02:00

559 lines
20 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#include "RiaSummaryAddressAnalyzer.h"
#include "RiaStdStringTools.h"
#include "RiaSummaryCurveDefinition.h"
#include "RimSummaryCurve.h"
#include "RimSummaryCurveCollection.h"
#include <QString>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaSummaryAddressAnalyzer::RiaSummaryAddressAnalyzer()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaSummaryAddressAnalyzer::appendAddresses( const std::vector<RifEclipseSummaryAddress>& allAddresses )
{
for ( const auto& adr : allAddresses )
{
analyzeSingleAddress( adr );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaSummaryAddressAnalyzer::appendAddresses( const std::set<RifEclipseSummaryAddress>& allAddresses )
{
for ( const auto& adr : allAddresses )
{
analyzeSingleAddress( adr );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RiaSummaryAddressAnalyzer::quantities() const
{
return m_quantities;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RiaSummaryAddressAnalyzer::quantityNamesWithHistory() const
{
assignCategoryToQuantities();
return m_quantitiesWithMatchingHistory;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RiaSummaryAddressAnalyzer::quantityNamesNoHistory() const
{
assignCategoryToQuantities();
return m_quantitiesNoMatchingHistory;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RiaSummaryAddressAnalyzer::isSingleQuantityIgnoreHistory() const
{
if ( quantities().size() == 1 ) return true;
if ( quantities().size() == 2 && quantityNamesWithHistory().size() == 1 )
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RiaSummaryAddressAnalyzer::quantityNameForTitle() const
{
if ( quantities().size() == 1 )
{
return *quantities().begin();
}
if ( quantities().size() == 2 && quantityNamesWithHistory().size() == 1 )
{
return *quantityNamesWithHistory().begin();
}
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RiaSummaryAddressAnalyzer::wellNames() const
{
return keysInMap( m_wellNames );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RiaSummaryAddressAnalyzer::groupNames() const
{
return keysInMap( m_groupNames );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<int> RiaSummaryAddressAnalyzer::regionNumbers() const
{
return keysInMap( m_regionNumbers );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RiaSummaryAddressAnalyzer::wellCompletions( const std::string& wellName ) const
{
std::set<std::string> connections;
for ( const auto& conn : m_wellCompletions )
{
if ( conn.first == wellName )
{
connections.insert( conn.second );
}
}
return connections;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<int> RiaSummaryAddressAnalyzer::wellSegmentNumbers( const std::string& wellName ) const
{
std::set<int> segmentNumberForWell;
for ( const auto& wellSegment : m_wellSegmentNumbers )
{
if ( wellName.empty() || std::get<0>( wellSegment ) == wellName )
{
segmentNumberForWell.insert( std::get<1>( wellSegment ) );
}
}
return segmentNumberForWell;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RiaSummaryAddressAnalyzer::blocks() const
{
return keysInMap( m_blocks );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<int> RiaSummaryAddressAnalyzer::aquifers() const
{
return keysInMap( m_aquifers );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress::SummaryVarCategory> RiaSummaryAddressAnalyzer::categories() const
{
return keysInMap( m_categories );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<RifEclipseSummaryAddress>> RiaSummaryAddressAnalyzer::addressesGroupedByObject() const
{
auto wellAdr = valuesInMap( m_wellNames );
auto groupAdr = valuesInMap( m_groupNames );
auto regionAdr = valuesInMap( m_regionNumbers );
auto blockAdr = valuesInMap( m_blocks );
auto aquiferAdr = valuesInMap( m_aquifers );
std::vector<std::vector<RifEclipseSummaryAddress>> groupedByObject;
groupedByObject.insert( groupedByObject.end(), wellAdr.begin(), wellAdr.end() );
groupedByObject.insert( groupedByObject.end(), groupAdr.begin(), groupAdr.end() );
groupedByObject.insert( groupedByObject.end(), regionAdr.begin(), regionAdr.end() );
groupedByObject.insert( groupedByObject.end(), blockAdr.begin(), blockAdr.end() );
groupedByObject.insert( groupedByObject.end(), aquiferAdr.begin(), aquiferAdr.end() );
groupedByObject.push_back( m_otherCategory );
return groupedByObject;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RiaSummaryAddressAnalyzer::identifierTexts( RifEclipseSummaryAddress::SummaryVarCategory category,
const std::string& secondaryIdentifier ) const
{
std::vector<QString> identifierStrings;
if ( category == RifEclipseSummaryAddress::SUMMARY_REGION )
{
auto keys = keysInMap( m_regionNumbers );
for ( const auto& key : keys )
{
identifierStrings.push_back( QString::number( key ) );
}
}
else if ( category == RifEclipseSummaryAddress::SUMMARY_WELL )
{
auto keys = keysInMap( m_wellNames );
for ( const auto& key : keys )
{
identifierStrings.push_back( QString::fromStdString( key ) );
}
}
else if ( category == RifEclipseSummaryAddress::SUMMARY_GROUP )
{
auto keys = keysInMap( m_groupNames );
for ( const auto& key : keys )
{
identifierStrings.push_back( QString::fromStdString( key ) );
}
}
else if ( category == RifEclipseSummaryAddress::SUMMARY_BLOCK )
{
auto keys = keysInMap( m_blocks );
for ( const auto& key : keys )
{
identifierStrings.push_back( QString::fromStdString( key ) );
}
}
else if ( category == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT )
{
auto segmentNumbers = wellSegmentNumbers( secondaryIdentifier );
for ( const auto& segment : segmentNumbers )
{
identifierStrings.push_back( QString::number( segment ) );
}
}
else if ( category == RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION )
{
auto connections = wellCompletions( secondaryIdentifier );
for ( const auto& conn : connections )
{
identifierStrings.push_back( QString::fromStdString( conn ) );
}
}
else if ( category == RifEclipseSummaryAddress::SUMMARY_AQUIFER )
{
auto keys = keysInMap( m_aquifers );
for ( const auto& key : keys )
{
identifierStrings.push_back( QString::number( key ) );
}
}
return identifierStrings;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RifEclipseSummaryAddress>
RiaSummaryAddressAnalyzer::addressesForCategory( const std::set<RifEclipseSummaryAddress>& addresses,
RifEclipseSummaryAddress::SummaryVarCategory category )
{
std::vector<RifEclipseSummaryAddress> filteredAddresses;
for ( const auto& adr : addresses )
{
if ( adr.category() == category )
{
filteredAddresses.push_back( adr );
}
}
return filteredAddresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RiaSummaryAddressAnalyzer::correspondingHistorySummaryCurveName( const std::string& curveName )
{
static std::string historyIdentifier = "H";
if ( RiaStdStringTools::endsWith( curveName, historyIdentifier ) )
{
std::string candidate = curveName.substr( 0, curveName.size() - 1 );
return candidate;
}
return curveName + historyIdentifier;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string>
RiaSummaryAddressAnalyzer::vectorNamesForCategory( RifEclipseSummaryAddress::SummaryVarCategory category )
{
auto it = m_categories.find( category );
if ( it != m_categories.end() ) return it->second;
return {};
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaSummaryAddressAnalyzer::clear()
{
m_quantities.clear();
m_wellNames.clear();
m_groupNames.clear();
m_regionNumbers.clear();
m_categories.clear();
m_wellCompletions.clear();
m_wellSegmentNumbers.clear();
m_blocks.clear();
m_aquifers.clear();
m_quantitiesNoMatchingHistory.clear();
m_quantitiesWithMatchingHistory.clear();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaSummaryAddressAnalyzer::assignCategoryToQuantities() const
{
if ( !m_quantities.empty() )
{
if ( m_quantitiesWithMatchingHistory.empty() && m_quantitiesNoMatchingHistory.empty() )
{
computeQuantityNamesWithHistory();
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaSummaryAddressAnalyzer::computeQuantityNamesWithHistory() const
{
m_quantitiesNoMatchingHistory.clear();
m_quantitiesWithMatchingHistory.clear();
const std::string historyIdentifier( "H" );
for ( const auto& s : m_quantities )
{
std::string correspondingHistoryCurve = correspondingHistorySummaryCurveName( s );
if ( m_quantities.find( correspondingHistoryCurve ) != m_quantities.end() )
{
// Insert the curve name without H
if ( RiaStdStringTools::endsWith( s, historyIdentifier ) )
{
m_quantitiesWithMatchingHistory.insert( correspondingHistoryCurve );
}
else
{
m_quantitiesWithMatchingHistory.insert( s );
}
}
else
{
m_quantitiesNoMatchingHistory.insert( s );
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiaSummaryAddressAnalyzer::analyzeSingleAddress( const RifEclipseSummaryAddress& address )
{
const std::string& wellName = address.wellName();
if ( !wellName.empty() )
{
m_wellNames.insert( { wellName, address } );
}
if ( !address.vectorName().empty() )
{
m_quantities.insert( address.vectorName() );
}
if ( !address.groupName().empty() )
{
m_groupNames.insert( { address.groupName(), address } );
}
if ( address.regionNumber() != -1 )
{
m_regionNumbers.insert( { address.regionNumber(), address } );
}
if ( address.category() == RifEclipseSummaryAddress::SUMMARY_WELL_COMPLETION )
{
auto wellNameAndCompletion = std::make_pair( wellName, address.blockAsString() );
m_wellCompletions.insert( wellNameAndCompletion );
}
else if ( address.category() == RifEclipseSummaryAddress::SUMMARY_WELL_SEGMENT )
{
auto wellNameAndSegment = std::make_pair( wellName, address.wellSegmentNumber() );
m_wellSegmentNumbers.insert( wellNameAndSegment );
}
else if ( address.category() == RifEclipseSummaryAddress::SUMMARY_BLOCK )
{
auto text = address.blockAsString();
m_blocks.insert( { text, address } );
}
else if ( address.category() == RifEclipseSummaryAddress::SUMMARY_AQUIFER )
{
m_aquifers.insert( { address.aquiferNumber(), address } );
}
else if ( address.category() == RifEclipseSummaryAddress::SUMMARY_FIELD ||
address.category() == RifEclipseSummaryAddress::SUMMARY_MISC )
{
m_otherCategory.push_back( address );
}
if ( address.category() != RifEclipseSummaryAddress::SUMMARY_INVALID )
{
if ( m_categories.count( address.category() ) == 0 )
{
m_categories[address.category()] = { address.vectorName() };
}
else
m_categories[address.category()].insert( address.vectorName() );
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<std::string> RiaSummaryAddressAnalyzer::keysInMap( const std::multimap<std::string, RifEclipseSummaryAddress>& map )
{
std::set<std::string> keys;
for ( const auto& [key, value] : map )
{
keys.insert( key );
}
return keys;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<int> RiaSummaryAddressAnalyzer::keysInMap( const std::multimap<int, RifEclipseSummaryAddress>& map )
{
std::set<int> keys;
for ( const auto& [key, value] : map )
{
keys.insert( key );
}
return keys;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RifEclipseSummaryAddress::SummaryVarCategory> RiaSummaryAddressAnalyzer::keysInMap(
const std::map<RifEclipseSummaryAddress::SummaryVarCategory, std::set<std::string>>& map )
{
std::set<RifEclipseSummaryAddress::SummaryVarCategory> keys;
for ( const auto& [key, value] : map )
{
keys.insert( key );
}
return keys;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<RifEclipseSummaryAddress>>
RiaSummaryAddressAnalyzer::valuesInMap( const std::multimap<std::string, RifEclipseSummaryAddress>& map )
{
std::vector<std::vector<RifEclipseSummaryAddress>> groupedAddresses;
auto uniqueKeys = keysInMap( map );
for ( const auto& key : uniqueKeys )
{
auto range = map.equal_range( key );
std::vector<RifEclipseSummaryAddress> addresses;
for ( auto i = range.first; i != range.second; ++i )
{
addresses.push_back( i->second );
}
groupedAddresses.push_back( addresses );
}
return groupedAddresses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<std::vector<RifEclipseSummaryAddress>>
RiaSummaryAddressAnalyzer::valuesInMap( const std::multimap<int, RifEclipseSummaryAddress>& map )
{
std::vector<std::vector<RifEclipseSummaryAddress>> groupedAddresses;
auto uniqueKeys = keysInMap( map );
for ( const auto& key : uniqueKeys )
{
auto range = map.equal_range( key );
std::vector<RifEclipseSummaryAddress> addresses;
for ( auto i = range.first; i != range.second; ++i )
{
addresses.push_back( i->second );
}
groupedAddresses.push_back( addresses );
}
return groupedAddresses;
}