mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Several performance fixes (#9026)
* #9023 Performance: Use count instead of for loop * #9023 Analyzer: Cache vector names for categories * #9023 Performance : Use cached ensemble analyzer * #9023 Performance : Add min/max values to ensemble statistics * #9023 Performance : Improve statistics calculator * #9023 Performance : Use high performance toInt() * #9023 Performance : Build summary addresses in parallell
This commit is contained in:
parent
fa1f189709
commit
d36bf11c62
@ -182,7 +182,7 @@ std::set<int> RiaSummaryAddressAnalyzer::aquifers() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseSummaryAddress::SummaryVarCategory> RiaSummaryAddressAnalyzer::categories() const
|
||||
{
|
||||
return m_categories;
|
||||
return keysInMap( m_categories );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -312,6 +312,18 @@ std::string RiaSummaryAddressAnalyzer::correspondingHistorySummaryCurveName( con
|
||||
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 {};
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -433,7 +445,12 @@ void RiaSummaryAddressAnalyzer::analyzeSingleAddress( const RifEclipseSummaryAdd
|
||||
|
||||
if ( address.category() != RifEclipseSummaryAddress::SUMMARY_INVALID )
|
||||
{
|
||||
m_categories.insert( address.category() );
|
||||
if ( m_categories.count( address.category() ) == 0 )
|
||||
{
|
||||
m_categories[address.category()] = { address.vectorName() };
|
||||
}
|
||||
else
|
||||
m_categories[address.category()].insert( address.vectorName() );
|
||||
}
|
||||
}
|
||||
|
||||
@ -463,6 +480,20 @@ std::set<int> RiaSummaryAddressAnalyzer::keysInMap( const std::multimap<int, Rif
|
||||
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;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -69,6 +69,8 @@ public:
|
||||
|
||||
static std::string correspondingHistorySummaryCurveName( const std::string& curveName );
|
||||
|
||||
std::set<std::string> vectorNamesForCategory( RifEclipseSummaryAddress::SummaryVarCategory category );
|
||||
|
||||
private:
|
||||
void assignCategoryToQuantities() const;
|
||||
void computeQuantityNamesWithHistory() const;
|
||||
@ -77,6 +79,8 @@ private:
|
||||
|
||||
static std::set<std::string> keysInMap( const std::multimap<std::string, RifEclipseSummaryAddress>& map );
|
||||
static std::set<int> keysInMap( const std::multimap<int, RifEclipseSummaryAddress>& map );
|
||||
static std::set<RifEclipseSummaryAddress::SummaryVarCategory>
|
||||
keysInMap( const std::map<RifEclipseSummaryAddress::SummaryVarCategory, std::set<std::string>>& map );
|
||||
|
||||
static std::vector<std::vector<RifEclipseSummaryAddress>>
|
||||
valuesInMap( const std::multimap<std::string, RifEclipseSummaryAddress>& map );
|
||||
@ -98,5 +102,5 @@ private:
|
||||
std::multimap<std::string, RifEclipseSummaryAddress> m_blocks;
|
||||
std::multimap<int, RifEclipseSummaryAddress> m_aquifers;
|
||||
|
||||
std::set<RifEclipseSummaryAddress::SummaryVarCategory> m_categories;
|
||||
std::map<RifEclipseSummaryAddress::SummaryVarCategory, std::set<std::string>> m_categories;
|
||||
};
|
||||
|
@ -727,6 +727,10 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector
|
||||
std::string token1;
|
||||
std::string token2;
|
||||
|
||||
int intValue0 = 0;
|
||||
int intValue1 = 0;
|
||||
int intValue2 = 0;
|
||||
|
||||
vectorName = tokens[0];
|
||||
|
||||
if ( tokens.size() > 1 ) token1 = tokens[1];
|
||||
@ -740,7 +744,11 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector
|
||||
return fieldAddress( vectorName );
|
||||
|
||||
case SUMMARY_AQUIFER:
|
||||
if ( !token1.empty() ) return aquiferAddress( vectorName, RiaStdStringTools::toInt( token1 ) );
|
||||
if ( !token1.empty() )
|
||||
{
|
||||
RiaStdStringTools::toInt( token1, intValue0 );
|
||||
return aquiferAddress( vectorName, intValue0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case SUMMARY_NETWORK:
|
||||
@ -752,7 +760,11 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector
|
||||
break;
|
||||
|
||||
case SUMMARY_REGION:
|
||||
if ( !token1.empty() ) return regionAddress( vectorName, RiaStdStringTools::toInt( token1 ) );
|
||||
if ( !token1.empty() )
|
||||
{
|
||||
RiaStdStringTools::toInt( token1, intValue0 );
|
||||
return regionAddress( vectorName, intValue0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case SUMMARY_REGION_2_REGION:
|
||||
@ -761,9 +773,10 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector
|
||||
auto regions = RiaStdStringTools::splitString( token1, '-' );
|
||||
if ( regions.size() == 2 )
|
||||
{
|
||||
return regionToRegionAddress( vectorName,
|
||||
RiaStdStringTools::toInt( regions[0] ),
|
||||
RiaStdStringTools::toInt( regions[1] ) );
|
||||
RiaStdStringTools::toInt( regions[0], intValue0 );
|
||||
RiaStdStringTools::toInt( regions[1], intValue1 );
|
||||
|
||||
return regionToRegionAddress( vectorName, intValue0, intValue1 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -782,11 +795,11 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector
|
||||
auto ijk = RiaStdStringTools::splitString( token2, ',' );
|
||||
if ( ijk.size() == 3 )
|
||||
{
|
||||
return wellCompletionAddress( vectorName,
|
||||
token1,
|
||||
RiaStdStringTools::toInt( ijk[0] ),
|
||||
RiaStdStringTools::toInt( ijk[1] ),
|
||||
RiaStdStringTools::toInt( ijk[2] ) );
|
||||
RiaStdStringTools::toInt( ijk[0], intValue0 );
|
||||
RiaStdStringTools::toInt( ijk[1], intValue1 );
|
||||
RiaStdStringTools::toInt( ijk[2], intValue2 );
|
||||
|
||||
return wellCompletionAddress( vectorName, token1, intValue0, intValue1, intValue2 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -802,18 +815,23 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector
|
||||
auto ijk = RiaStdStringTools::splitString( token3, ',' );
|
||||
if ( ijk.size() == 3 )
|
||||
{
|
||||
return wellCompletionLgrAddress( vectorName,
|
||||
token1,
|
||||
token2,
|
||||
RiaStdStringTools::toInt( ijk[0] ),
|
||||
RiaStdStringTools::toInt( ijk[1] ),
|
||||
RiaStdStringTools::toInt( ijk[2] ) );
|
||||
RiaStdStringTools::toInt( ijk[0], intValue0 );
|
||||
RiaStdStringTools::toInt( ijk[1], intValue1 );
|
||||
RiaStdStringTools::toInt( ijk[2], intValue2 );
|
||||
|
||||
return wellCompletionLgrAddress( vectorName, token1, token2, intValue0, intValue1, intValue2 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case SUMMARY_WELL_SEGMENT:
|
||||
if ( !token2.empty() ) return wellSegmentAddress( vectorName, token1, RiaStdStringTools::toInt( token2 ) );
|
||||
|
||||
if ( !token2.empty() )
|
||||
{
|
||||
RiaStdStringTools::toInt( token2, intValue0 );
|
||||
|
||||
return wellSegmentAddress( vectorName, token1, intValue0 );
|
||||
}
|
||||
break;
|
||||
|
||||
case SUMMARY_BLOCK:
|
||||
@ -822,10 +840,11 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector
|
||||
auto ijk = RiaStdStringTools::splitString( token1, ',' );
|
||||
if ( ijk.size() == 3 )
|
||||
{
|
||||
return blockAddress( vectorName,
|
||||
RiaStdStringTools::toInt( ijk[0] ),
|
||||
RiaStdStringTools::toInt( ijk[1] ),
|
||||
RiaStdStringTools::toInt( ijk[2] ) );
|
||||
RiaStdStringTools::toInt( ijk[0], intValue0 );
|
||||
RiaStdStringTools::toInt( ijk[1], intValue1 );
|
||||
RiaStdStringTools::toInt( ijk[2], intValue2 );
|
||||
|
||||
return blockAddress( vectorName, intValue0, intValue1, intValue2 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -836,11 +855,11 @@ RifEclipseSummaryAddress RifEclipseSummaryAddress::fromTokens( const std::vector
|
||||
auto ijk = RiaStdStringTools::splitString( token2, ',' );
|
||||
if ( ijk.size() == 3 )
|
||||
{
|
||||
return blockLgrAddress( vectorName,
|
||||
token1,
|
||||
RiaStdStringTools::toInt( ijk[0] ),
|
||||
RiaStdStringTools::toInt( ijk[1] ),
|
||||
RiaStdStringTools::toInt( ijk[2] ) );
|
||||
RiaStdStringTools::toInt( ijk[0], intValue0 );
|
||||
RiaStdStringTools::toInt( ijk[1], intValue1 );
|
||||
RiaStdStringTools::toInt( ijk[2], intValue2 );
|
||||
|
||||
return blockLgrAddress( vectorName, token1, intValue0, intValue1, intValue2 );
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
@ -395,32 +395,49 @@ std::pair<std::set<RifEclipseSummaryAddress>, std::map<RifEclipseSummaryAddress,
|
||||
|
||||
std::vector<std::string> invalidKeywords;
|
||||
|
||||
for ( const auto& keyword : keywords )
|
||||
#pragma omp parallel
|
||||
{
|
||||
auto eclAdr = RifEclipseSummaryAddress::fromEclipseTextAddress( keyword );
|
||||
if ( !eclAdr.isValid() )
|
||||
{
|
||||
invalidKeywords.push_back( keyword );
|
||||
std::set<RifEclipseSummaryAddress> threadAddresses;
|
||||
std::map<RifEclipseSummaryAddress, std::string> threadAddressToNodeIndexMap;
|
||||
std::vector<std::string> threadInvalidKeywords;
|
||||
|
||||
// If a category is not found, use the MISC category
|
||||
eclAdr = RifEclipseSummaryAddress::miscAddress( keyword );
|
||||
#pragma omp for
|
||||
for ( int index = 0; index < (int)keywords.size(); index++ )
|
||||
{
|
||||
auto keyword = keywords[index];
|
||||
|
||||
auto eclAdr = RifEclipseSummaryAddress::fromEclipseTextAddress( keyword );
|
||||
if ( !eclAdr.isValid() )
|
||||
{
|
||||
threadInvalidKeywords.push_back( keyword );
|
||||
|
||||
// If a category is not found, use the MISC category
|
||||
eclAdr = RifEclipseSummaryAddress::miscAddress( keyword );
|
||||
}
|
||||
|
||||
if ( eclAdr.isValid() )
|
||||
{
|
||||
threadAddresses.insert( eclAdr );
|
||||
threadAddressToNodeIndexMap[eclAdr] = keyword;
|
||||
}
|
||||
}
|
||||
|
||||
if ( eclAdr.isValid() )
|
||||
#pragma omp critical
|
||||
{
|
||||
addresses.insert( eclAdr );
|
||||
addressToNodeIndexMap[eclAdr] = keyword;
|
||||
addresses.insert( threadAddresses.begin(), threadAddresses.end() );
|
||||
addressToNodeIndexMap.insert( threadAddressToNodeIndexMap.begin(), threadAddressToNodeIndexMap.end() );
|
||||
invalidKeywords.insert( invalidKeywords.end(), threadInvalidKeywords.begin(), threadInvalidKeywords.end() );
|
||||
}
|
||||
|
||||
// DEBUG code
|
||||
// Used to print keywords not being categorized correctly
|
||||
/*
|
||||
for ( const auto& kw : invalidKeywords )
|
||||
{
|
||||
RiaLogging::warning( QString::fromStdString( kw ) );
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
// DEBUG code
|
||||
// Used to print keywords not being categorized correctly
|
||||
/*
|
||||
for ( const auto& kw : invalidKeywords )
|
||||
{
|
||||
RiaLogging::warning( QString::fromStdString( kw ) );
|
||||
}
|
||||
*/
|
||||
|
||||
return { addresses, addressToNodeIndexMap };
|
||||
}
|
||||
|
@ -57,13 +57,5 @@ bool RifSummaryReaderInterface::hasAddress( const RifEclipseSummaryAddress& resu
|
||||
static const RifEclipseSummaryAddress defaultAdr = RifEclipseSummaryAddress();
|
||||
if ( resultAddress == defaultAdr ) return true;
|
||||
|
||||
for ( const RifEclipseSummaryAddress& summaryAddress : m_allResultAddresses )
|
||||
{
|
||||
if ( summaryAddress == resultAddress )
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
return ( m_allResultAddresses.count( resultAddress ) > 0 );
|
||||
}
|
||||
|
@ -1967,6 +1967,14 @@ bool RimEnsembleCurveSet::hasMeanData() const
|
||||
return m_ensembleStatCase->hasMeanData();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<double, double> RimEnsembleCurveSet::minimumAndMaximumValues() const
|
||||
{
|
||||
return m_ensembleStatCase->minimumAndMaximumValues();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -155,6 +155,8 @@ public:
|
||||
bool hasP90Data() const override;
|
||||
bool hasMeanData() const override;
|
||||
|
||||
std::pair<double, double> minimumAndMaximumValues() const;
|
||||
|
||||
void appendColorGroup( caf::PdmUiOrdering& uiOrdering );
|
||||
|
||||
static void appendOptionItemsForSummaryAddresses( QList<caf::PdmOptionItemInfo>* options,
|
||||
|
@ -39,6 +39,8 @@
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEnsembleStatisticsCase::RimEnsembleStatisticsCase( RimEnsembleCurveSet* curveSet )
|
||||
: m_minimumValue( DOUBLE_INF )
|
||||
, m_maximumValue( -DOUBLE_INF )
|
||||
{
|
||||
m_curveSet = curveSet;
|
||||
}
|
||||
@ -83,6 +85,14 @@ const std::vector<double>& RimEnsembleStatisticsCase::mean() const
|
||||
return m_meanData;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::pair<double, double> RimEnsembleStatisticsCase::minimumAndMaximumValues() const
|
||||
{
|
||||
return { m_minimumValue, m_maximumValue };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -195,6 +205,11 @@ void RimEnsembleStatisticsCase::calculate( const std::vector<RimSummaryCase*> su
|
||||
m_p50Data.push_back( p50 );
|
||||
m_p90Data.push_back( p90 );
|
||||
m_meanData.push_back( mean );
|
||||
|
||||
const auto [min, max] = std::minmax_element( begin( valuesAtTimeStep ), end( valuesAtTimeStep ) );
|
||||
|
||||
m_maximumValue = std::max( m_maximumValue, *max );
|
||||
m_minimumValue = std::min( m_minimumValue, *min );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -40,6 +40,8 @@ public:
|
||||
const std::vector<double>& p90() const;
|
||||
const std::vector<double>& mean() const;
|
||||
|
||||
const std::pair<double, double> minimumAndMaximumValues() const;
|
||||
|
||||
bool hasP10Data() const { return !m_p10Data.empty(); }
|
||||
bool hasP50Data() const { return !m_p50Data.empty(); }
|
||||
bool hasP90Data() const { return !m_p90Data.empty(); }
|
||||
@ -72,4 +74,7 @@ private:
|
||||
std::vector<double> m_p50Data;
|
||||
std::vector<double> m_p90Data;
|
||||
std::vector<double> m_meanData;
|
||||
|
||||
double m_maximumValue;
|
||||
double m_minimumValue;
|
||||
};
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaStatisticsTools.h"
|
||||
#include "RiaStdStringTools.h"
|
||||
#include "RiaSummaryAddressAnalyzer.h"
|
||||
#include "RiaWeightedMeanCalculator.h"
|
||||
|
||||
#include "RicfCommandObject.h"
|
||||
@ -158,6 +159,7 @@ void RimSummaryCaseCollection::removeCase( RimSummaryCase* summaryCase, bool not
|
||||
m_cases.removeChild( summaryCase );
|
||||
|
||||
m_cachedSortedEnsembleParameters.clear();
|
||||
m_analyzer.reset();
|
||||
|
||||
caseRemoved.send( summaryCase );
|
||||
|
||||
@ -184,6 +186,7 @@ void RimSummaryCaseCollection::addCase( RimSummaryCase* summaryCase )
|
||||
|
||||
m_cases.push_back( summaryCase );
|
||||
m_cachedSortedEnsembleParameters.clear();
|
||||
m_analyzer.reset();
|
||||
|
||||
// Update derived ensemble cases (if any)
|
||||
std::vector<RimDerivedEnsembleCaseCollection*> referringObjects;
|
||||
@ -344,6 +347,7 @@ std::set<time_t> RimSummaryCaseCollection::ensembleTimeSteps() const
|
||||
}
|
||||
return allTimeSteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -929,6 +933,21 @@ void RimSummaryCaseCollection::updateReferringCurveSets()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaSummaryAddressAnalyzer* RimSummaryCaseCollection::addressAnalyzer()
|
||||
{
|
||||
if ( !m_analyzer )
|
||||
{
|
||||
m_analyzer = std::make_unique<RiaSummaryAddressAnalyzer>();
|
||||
|
||||
m_analyzer->appendAddresses( ensembleSummaryAddresses() );
|
||||
}
|
||||
|
||||
return m_analyzer.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -35,6 +35,7 @@
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <memory>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
@ -42,6 +43,7 @@ class RifReaderRftInterface;
|
||||
class RifReaderEnsembleStatisticsRft;
|
||||
class RimSummaryCase;
|
||||
class RimSummaryAddressCollection;
|
||||
class RiaSummaryAddressAnalyzer;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -110,6 +112,8 @@ public:
|
||||
|
||||
void updateReferringCurveSets();
|
||||
|
||||
RiaSummaryAddressAnalyzer* addressAnalyzer();
|
||||
|
||||
private:
|
||||
RigEnsembleParameter createEnsembleParameter( const QString& paramName ) const;
|
||||
static void sortByBinnedVariation( std::vector<RigEnsembleParameter>& parameterVector );
|
||||
@ -146,5 +150,6 @@ private:
|
||||
|
||||
size_t m_commonAddressCount; // if different address count among cases, set to 0
|
||||
|
||||
mutable std::vector<RigEnsembleParameter> m_cachedSortedEnsembleParameters;
|
||||
mutable std::vector<RigEnsembleParameter> m_cachedSortedEnsembleParameters;
|
||||
std::unique_ptr<RiaSummaryAddressAnalyzer> m_analyzer;
|
||||
};
|
||||
|
@ -981,7 +981,7 @@ void RimSummaryMultiPlot::computeAggregatedAxisRange()
|
||||
|
||||
for ( auto axis : plot->plotAxes() )
|
||||
{
|
||||
for ( auto curve : plot->summaryAndEnsembleCurves() )
|
||||
for ( auto curve : plot->summaryCurves() )
|
||||
{
|
||||
if ( curve->axisY() == axis->plotAxisType() )
|
||||
{
|
||||
@ -1002,6 +1002,25 @@ void RimSummaryMultiPlot::computeAggregatedAxisRange()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( auto curveSet : plot->curveSets() )
|
||||
{
|
||||
if ( curveSet->axisY() == axis->plotAxisType() )
|
||||
{
|
||||
auto [minimum, maximum] = curveSet->minimumAndMaximumValues();
|
||||
|
||||
if ( axisRanges.count( axis->plotAxisType() ) == 0 )
|
||||
{
|
||||
axisRanges[axis->plotAxisType()] = std::make_pair( minimum, maximum );
|
||||
}
|
||||
else
|
||||
{
|
||||
auto& [currentMin, currentMax] = axisRanges[axis->plotAxisType()];
|
||||
axisRanges[axis->plotAxisType()] =
|
||||
std::make_pair( std::min( currentMin, minimum ), std::max( currentMax, maximum ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// set all plots to use the global min/max values for each category
|
||||
|
@ -211,12 +211,29 @@ QList<caf::PdmOptionItemInfo>
|
||||
return options;
|
||||
}
|
||||
|
||||
auto addresses = adressesForSourceStepping();
|
||||
if ( !addresses.empty() )
|
||||
RiaSummaryAddressAnalyzer fallbackAnalyzer;
|
||||
RiaSummaryAddressAnalyzer* analyzer = nullptr;
|
||||
if ( !dataSourceSteppingObject()->curveSets().empty() )
|
||||
{
|
||||
auto first = dataSourceSteppingObject()->curveSets().front();
|
||||
analyzer = first->summaryCaseCollection()->addressAnalyzer();
|
||||
}
|
||||
|
||||
if ( !analyzer )
|
||||
{
|
||||
// No cached analyzer found. Fallback to population of a local analyzer. Try to avoid this, as the analysis
|
||||
// operation is quite expensive.
|
||||
|
||||
auto addresses = adressesForSourceStepping();
|
||||
fallbackAnalyzer.appendAddresses( addresses );
|
||||
analyzer = &fallbackAnalyzer;
|
||||
}
|
||||
|
||||
if ( analyzer )
|
||||
{
|
||||
if ( fieldNeedingOptions == &m_vectorName )
|
||||
{
|
||||
std::map<QString, QString> displayAndValueStrings = optionsForQuantity( addresses );
|
||||
auto displayAndValueStrings = optionsForQuantity( analyzer );
|
||||
|
||||
for ( const auto& displayAndValue : displayAndValueStrings )
|
||||
{
|
||||
@ -268,10 +285,7 @@ QList<caf::PdmOptionItemInfo>
|
||||
|
||||
if ( category != RifEclipseSummaryAddress::SUMMARY_INVALID )
|
||||
{
|
||||
RiaSummaryAddressAnalyzer analyzer;
|
||||
analyzer.appendAddresses( addresses );
|
||||
|
||||
identifierTexts = analyzer.identifierTexts( category, secondaryIdentifier );
|
||||
identifierTexts = analyzer->identifierTexts( category, secondaryIdentifier );
|
||||
}
|
||||
|
||||
if ( !identifierTexts.empty() )
|
||||
@ -1175,9 +1189,6 @@ std::map<QString, QString> RimSummaryPlotSourceStepping::optionsForQuantity( std
|
||||
auto subset = RiaSummaryAddressAnalyzer::addressesForCategory( addresses, category );
|
||||
quantityAnalyzer.appendAddresses( subset );
|
||||
|
||||
RiaSummaryAddressAnalyzer analyzerForVisibleCurves;
|
||||
analyzerForVisibleCurves.appendAddresses( visibleCurveAddresses );
|
||||
|
||||
auto quantities = quantityAnalyzer.quantities();
|
||||
for ( const auto& s : quantities )
|
||||
{
|
||||
@ -1190,6 +1201,36 @@ std::map<QString, QString> RimSummaryPlotSourceStepping::optionsForQuantity( std
|
||||
return displayAndValueStrings;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::map<QString, QString> RimSummaryPlotSourceStepping::optionsForQuantity( RiaSummaryAddressAnalyzer* analyzser )
|
||||
{
|
||||
RifEclipseSummaryAddress::SummaryVarCategory category = RifEclipseSummaryAddress::SUMMARY_FIELD;
|
||||
|
||||
auto visibleCurveAddresses = addressesForCurvesInPlot();
|
||||
if ( !visibleCurveAddresses.empty() )
|
||||
{
|
||||
category = visibleCurveAddresses.begin()->category();
|
||||
}
|
||||
|
||||
std::map<QString, QString> displayAndValueStrings;
|
||||
|
||||
if ( analyzser )
|
||||
{
|
||||
auto vectorNames = analyzser->vectorNamesForCategory( category );
|
||||
|
||||
for ( const auto& s : vectorNames )
|
||||
{
|
||||
QString valueString = QString::fromStdString( s );
|
||||
|
||||
displayAndValueStrings[valueString] = valueString;
|
||||
}
|
||||
}
|
||||
|
||||
return displayAndValueStrings;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -35,6 +35,7 @@ class RimSummaryCurve;
|
||||
class RifSummaryReaderInterface;
|
||||
class RimSummaryCaseCollection;
|
||||
class RifEclipseSummaryAddress;
|
||||
class RiaSummaryAddressAnalyzer;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
@ -98,6 +99,7 @@ private:
|
||||
RimSummaryDataSourceStepping* dataSourceSteppingObject() const;
|
||||
|
||||
std::map<QString, QString> optionsForQuantity( std::set<RifEclipseSummaryAddress> addresses );
|
||||
std::map<QString, QString> optionsForQuantity( RiaSummaryAddressAnalyzer* analyzser );
|
||||
|
||||
private:
|
||||
caf::PdmPointer<caf::PdmObject> m_objectForSourceStepping;
|
||||
|
@ -105,20 +105,16 @@ void RigStatisticsMath::calculateStatisticsCurves( const std::vector<double>& va
|
||||
P90
|
||||
};
|
||||
|
||||
std::vector<double> sortedValues;
|
||||
double valueSum = 0;
|
||||
std::vector<double> sortedValues = values;
|
||||
|
||||
{
|
||||
std::multiset<double> vSet( values.begin(), values.end() );
|
||||
for ( double v : vSet )
|
||||
{
|
||||
if ( RiaStatisticsTools::isValidNumber( v ) )
|
||||
{
|
||||
sortedValues.push_back( v );
|
||||
valueSum += v;
|
||||
}
|
||||
}
|
||||
}
|
||||
sortedValues.erase( std::remove_if( sortedValues.begin(),
|
||||
sortedValues.end(),
|
||||
[]( double x ) { return !RiaStatisticsTools::isValidNumber( x ); } ),
|
||||
sortedValues.end() );
|
||||
|
||||
std::sort( sortedValues.begin(), sortedValues.end() );
|
||||
|
||||
double valueSum = std::accumulate( sortedValues.begin(), sortedValues.end(), 0.0 );
|
||||
|
||||
int valueCount = (int)sortedValues.size();
|
||||
double percentiles[] = { 0.1, 0.5, 0.9 };
|
||||
|
@ -138,3 +138,42 @@ TEST( RiaSummaryAddressAnalyzer, CellBlocks )
|
||||
auto blocks = analyzer.blocks();
|
||||
EXPECT_EQ( 3u, blocks.size() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RiaSummaryAddressAnalyzer, QuantitiesPerCategory )
|
||||
{
|
||||
std::vector<RifEclipseSummaryAddress> addresses;
|
||||
|
||||
{
|
||||
RifEclipseSummaryAddress adr = RifEclipseSummaryAddress::fieldAddress( "FOPT" );
|
||||
addresses.push_back( adr );
|
||||
}
|
||||
{
|
||||
RifEclipseSummaryAddress adr = RifEclipseSummaryAddress::fieldAddress( "FOPR" );
|
||||
addresses.push_back( adr );
|
||||
}
|
||||
|
||||
{
|
||||
RifEclipseSummaryAddress adr = RifEclipseSummaryAddress::wellAddress( "WOPT", "WellA" );
|
||||
addresses.push_back( adr );
|
||||
}
|
||||
{
|
||||
RifEclipseSummaryAddress adr = RifEclipseSummaryAddress::wellAddress( "WOPR", "WellB" );
|
||||
addresses.push_back( adr );
|
||||
}
|
||||
{
|
||||
RifEclipseSummaryAddress adr = RifEclipseSummaryAddress::wellAddress( "WWPR", "WellA" );
|
||||
addresses.push_back( adr );
|
||||
}
|
||||
|
||||
RiaSummaryAddressAnalyzer analyzer;
|
||||
analyzer.appendAddresses( addresses );
|
||||
|
||||
auto categories = analyzer.categories();
|
||||
EXPECT_EQ( 2u, categories.size() );
|
||||
|
||||
auto vectorNamesForWells = analyzer.vectorNamesForCategory( RifEclipseSummaryAddress::SUMMARY_WELL );
|
||||
EXPECT_EQ( 3u, vectorNamesForWells.size() );
|
||||
}
|
||||
|
@ -20,6 +20,7 @@
|
||||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
#include "QElapsedTimer"
|
||||
#include "RigStatisticsMath.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -295,3 +296,37 @@ TEST( RigStatisticsMath, calculateStatisticsCurves )
|
||||
EXPECT_DOUBLE_EQ( 1.0, mean );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
TEST( RigStatisticsMath, DISABLED_performanceTesting )
|
||||
{
|
||||
RigStatisticsMath::PercentileStyle percentileStyle = RigStatisticsMath::PercentileStyle::REGULAR;
|
||||
{
|
||||
size_t timerCount = 10;
|
||||
for ( size_t t = 0; t < timerCount; t++ )
|
||||
{
|
||||
QElapsedTimer timer;
|
||||
timer.start();
|
||||
|
||||
size_t iterationCount = 10000;
|
||||
for ( size_t i = 0; i < iterationCount; i++ )
|
||||
{
|
||||
size_t numberOfValues = 200;
|
||||
std::vector<double> values( numberOfValues );
|
||||
std::iota( values.begin(), values.end(), numberOfValues );
|
||||
|
||||
double mean = HUGE_VAL;
|
||||
double p10 = HUGE_VAL;
|
||||
double p50 = HUGE_VAL;
|
||||
double p90 = HUGE_VAL;
|
||||
|
||||
RigStatisticsMath::calculateStatisticsCurves( values, &p10, &p50, &p90, &mean, percentileStyle );
|
||||
}
|
||||
|
||||
auto testDuration = timer.elapsed();
|
||||
std::cout << testDuration << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user