Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions ApplicationLibCode/Application/Tools/RiaHashTools.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include <cstddef>
#include <functional>
#include <ranges>
#include <string>
#include <type_traits>

//==================================================================================================
//
Expand All @@ -31,14 +33,29 @@ namespace RiaHashTools
{
//--------------------------------------------------------------------------------------------------
/// Variadic template function to combine multiple parameters into a single hash
/// Constrained to non-range types (std::string is excluded as it has std::hash specialization)
//--------------------------------------------------------------------------------------------------
template <typename T>
requires( !std::ranges::range<T> || std::is_same_v<std::decay_t<T>, std::string> )
void combineHash( size_t& seed, const T& value )
{
// Based on https://www.boost.org/doc/libs/1_84_0/libs/container_hash/doc/html/hash.html#notes_hash_combine
seed ^= std::hash<T>()( value ) + 0x9e3779b9 + ( seed << 6 ) + ( seed >> 2 );
}

//--------------------------------------------------------------------------------------------------
/// Overload for range types (excluding std::string)
//--------------------------------------------------------------------------------------------------
template <std::ranges::range Range>
requires( !std::is_same_v<std::decay_t<Range>, std::string> )
void combineHash( size_t& seed, const Range& range )
{
for ( const auto& elem : range )
{
combineHash( seed, elem );
}
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Expand Down
41 changes: 39 additions & 2 deletions ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ RifEclipseSummaryAddress::RifEclipseSummaryAddress( SummaryCategory category, st
, m_number2( -1 )
, m_isErrorResult( false )
, m_id( -1 )
, m_percentile( -1 )
{
std::pair<int, int> reg2regPair;
switch ( category )
Expand Down Expand Up @@ -132,6 +133,7 @@ RifEclipseSummaryAddress::RifEclipseSummaryAddress( SummaryCategory category,
, m_number2( -1 )
, m_isErrorResult( isErrorResult )
, m_id( id )
, m_percentile( -1 )
{
switch ( category )
{
Expand Down Expand Up @@ -196,6 +198,7 @@ RifEclipseSummaryAddress::RifEclipseSummaryAddress()
, m_number2( -1 )
, m_isErrorResult( false )
, m_id( -1 )
, m_percentile( -1 )
{
}

Expand Down Expand Up @@ -669,8 +672,17 @@ std::string RifEclipseSummaryAddress::uiText() const

if ( isStatistics() )
{
auto prefix = RifEclipseSummaryAddressDefines::statisticsTypeToString( statisticsType() );
text = prefix + ":" + text;
std::string prefix;
if ( statisticsType() == RifEclipseSummaryAddressDefines::StatisticsType::CUSTOM && m_percentile >= MIN_PERCENTILE &&
m_percentile <= MAX_PERCENTILE )
{
prefix = "P" + std::to_string( m_percentile );
}
else
{
prefix = RifEclipseSummaryAddressDefines::statisticsTypeToString( statisticsType() );
}
text = prefix + ":" + text;
}

return text;
Expand Down Expand Up @@ -1027,6 +1039,31 @@ void RifEclipseSummaryAddress::setId( int id )
m_id = id;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RifEclipseSummaryAddress::percentile() const
{
return m_percentile;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RifEclipseSummaryAddress::setPercentile( int percentile )
{
// Validate percentile value: must be in valid range [0, 100] or -1 (unset)
if ( ( percentile >= MIN_PERCENTILE && percentile <= MAX_PERCENTILE ) || percentile == -1 )
{
m_percentile = percentile;
}
else
{
// Invalid percentile value, set to -1 (unset)
m_percentile = -1;
}
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Expand Down
7 changes: 7 additions & 0 deletions ApplicationLibCode/FileInterface/RifEclipseSummaryAddress.h
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ class RifEclipseSummaryAddress
bool isStatistics() const;
StatisticsType statisticsType() const;
void setStatisticsType( StatisticsType type );
int percentile() const;
void setPercentile( int percentile );

int regionNumber() const;
int regionNumber2() const;
Expand Down Expand Up @@ -166,6 +168,10 @@ class RifEclipseSummaryAddress
std::string formatUiTextRegionToRegion() const;
static std::pair<int, int> regionToRegionPairFromUiText( const std::string& s );

// Percentile constants
static constexpr int MIN_PERCENTILE = 0;
static constexpr int MAX_PERCENTILE = 100;

private:
static RifEclipseSummaryAddress fromTokens( const std::vector<std::string>& tokens );

Expand All @@ -188,6 +194,7 @@ class RifEclipseSummaryAddress
int m_number2;
bool m_isErrorResult;
int m_id;
int m_percentile;
};

QTextStream& operator<<( QTextStream& str, const RifEclipseSummaryAddress& sobj );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ void caf::AppEnum<RifEclipseSummaryAddressDefines::StatisticsType>::setUp()
addItem( RifEclipseSummaryAddressDefines::StatisticsType::P50, "P50", "P50" );
addItem( RifEclipseSummaryAddressDefines::StatisticsType::P90, "P90", "P90" );
addItem( RifEclipseSummaryAddressDefines::StatisticsType::MEAN, "MEAN", "Mean" );
addItem( RifEclipseSummaryAddressDefines::StatisticsType::CUSTOM, "CUSTOM", "Custom" );
setDefault( RifEclipseSummaryAddressDefines::StatisticsType::NONE );
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,8 @@ enum class StatisticsType
P10,
P50,
P90,
MEAN
MEAN,
CUSTOM
};

enum class CurveType
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,9 @@ class RimEnsembleCurveSetInterface
virtual void updateAllCurves() = 0;
virtual void updateStatisticsCurves() = 0;

virtual bool hasP10Data() const = 0;
virtual bool hasP50Data() const = 0;
virtual bool hasP90Data() const = 0;
virtual bool hasMeanData() const = 0;
virtual bool hasP10Data() const = 0;
virtual bool hasP50Data() const = 0;
virtual bool hasP90Data() const = 0;
virtual bool hasMeanData() const = 0;
virtual bool hasPercentileData( int p ) const = 0;
};
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,15 @@ bool RimEnsembleCrossPlotStatisticsCase::hasMeanData() const
return !m_meanData.empty();
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCrossPlotStatisticsCase::hasPercentileData( int /*percentile*/ ) const
{
// Custom percentiles are not supported for cross-plot statistics
return false;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ class RimEnsembleCrossPlotStatisticsCase : public RimSummaryCase, public RifSumm
bool hasP50Data() const;
bool hasP90Data() const;
bool hasMeanData() const;
bool hasPercentileData( int percentile ) const;

QString caseName() const override;
void createSummaryReaderInterface() override;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2231,6 +2231,8 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
statCases = group->allSummaryCases();
}

auto percentiles = m_statistics->allPercentiles();

if ( isXAxisSummaryVector() )
{
m_ensembleStatCaseXY->calculate( statCases,
Expand All @@ -2242,7 +2244,7 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
}
else
{
m_ensembleStatCaseY->calculate( statCases, summaryAddressY(), m_statistics->includeIncompleteCurves() );
m_ensembleStatCaseY->calculate( statCases, summaryAddressY(), m_statistics->includeIncompleteCurves(), percentiles );
}
}

Expand Down Expand Up @@ -2289,6 +2291,16 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
return RiaSummaryCurveAddress( xStatAddress, yStatAddress );
};

auto getPercentileAddress = []( int percentile, const RifEclipseSummaryAddress& addrY ) -> RiaSummaryCurveAddress
{
auto xStatAddress = RifEclipseSummaryAddress::timeAddress();
auto yStatAddress = addrY;
yStatAddress.setStatisticsType( RifEclipseSummaryAddressDefines::StatisticsType::CUSTOM );
yStatAddress.setPercentile( percentile );

return RiaSummaryCurveAddress( xStatAddress, yStatAddress );
};

if ( m_statistics->showP10Curve() && m_ensembleStatCaseY->hasP10Data() )
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::StatisticsType::P10, dataAddressY ) );
if ( m_statistics->showP50Curve() && m_ensembleStatCaseY->hasP50Data() )
Expand All @@ -2297,6 +2309,18 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::StatisticsType::P90, dataAddressY ) );
if ( m_statistics->showMeanCurve() && m_ensembleStatCaseY->hasMeanData() )
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::StatisticsType::MEAN, dataAddressY ) );

// Add custom percentiles (excluding standard P10/P50/P90 if their checkbox is checked)
for ( int p : m_statistics->allPercentiles() )
{
bool isHandledByCheckbox = ( p == 10 && m_statistics->showP10Curve() ) || ( p == 50 && m_statistics->showP50Curve() ) ||
( p == 90 && m_statistics->showP90Curve() );

if ( !isHandledByCheckbox && m_ensembleStatCaseY->hasPercentileData( p ) )
{
addresses.push_back( getPercentileAddress( p, dataAddressY ) );
}
}
}
}

Expand Down Expand Up @@ -2332,8 +2356,17 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa

if ( m_statistics->showCurveLabels() )
{
curve->setSymbolLabel( QString::fromStdString(
RifEclipseSummaryAddressDefines::statisticsTypeToString( address.summaryAddressY().statisticsType() ) ) );
QString label;
auto yAddr = address.summaryAddressY();
if ( yAddr.statisticsType() == RifEclipseSummaryAddressDefines::StatisticsType::CUSTOM && yAddr.percentile() >= 0 )
{
label = QString( "P%1" ).arg( yAddr.percentile() );
}
else
{
label = QString::fromStdString( RifEclipseSummaryAddressDefines::statisticsTypeToString( yAddr.statisticsType() ) );
}
curve->setSymbolLabel( label );
}
curve->setLineStyle( RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID );
}
Expand Down Expand Up @@ -2523,6 +2556,16 @@ bool RimEnsembleCurveSet::hasMeanData() const
return m_ensembleStatCaseY->hasMeanData();
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCurveSet::hasPercentileData( int p ) const
{
if ( isXAxisSummaryVector() ) return m_ensembleStatCaseXY->hasPercentileData( p );

return m_ensembleStatCaseY->hasPercentileData( p );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ class RimEnsembleCurveSet : public caf::PdmObject, public RimEnsembleCurveSetInt
bool hasP50Data() const override;
bool hasP90Data() const override;
bool hasMeanData() const override;
bool hasPercentileData( int p ) const override;

const RimEnsembleStatistics* statisticsOptions() const;

Expand Down
Loading