Refactoring to prepare for renaming of RimSummaryCaseCollection

Move functions into RimSummaryEnsembleTools
Use enum class instead of plain enum
This commit is contained in:
Magne Sjaastad 2024-06-24 14:20:54 +02:00
parent 09efbb8439
commit 16215585be
14 changed files with 633 additions and 600 deletions

View File

@ -28,9 +28,9 @@
#include "RimRftPlotCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryEnsembleTools.h"
#include "RimWellLogPlotNameConfig.h"
#include "RimWellLogTrack.h"
#include "RimWellPlotTools.h"
#include "RimWellRftPlot.h"
#include "RiuPlotMainWindowTools.h"
@ -58,7 +58,7 @@ void RicCreateRftPlotsFeature::onActionTriggered( bool isChecked )
auto dataSource = sourcePlot->dataSource();
if ( auto summaryCollection = std::get_if<RimSummaryCaseCollection*>( &dataSource ) )
{
wellsWithRftData = ( *summaryCollection )->wellsWithRftData();
wellsWithRftData = RimSummaryEnsembleTools::wellsWithRftData( ( *summaryCollection )->allSummaryCases() );
}
else if ( auto summaryCase = std::get_if<RimSummaryCase*>( &dataSource ) )
{

View File

@ -32,6 +32,7 @@
#include "RimSummaryAddress.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryEnsembleTools.h"
#include "RiuContextMenuLauncher.h"
#include "RiuPlotMainWindowTools.h"
@ -465,7 +466,7 @@ std::set<RigEnsembleParameter> RimAbstractCorrelationPlot::ensembleParameters()
for ( RimSummaryCaseCollection* ensemble : analyserOfSelectedCurveDefs->m_ensembles )
{
std::vector<RigEnsembleParameter> parameters = ensemble->alphabeticEnsembleParameters();
std::vector<RigEnsembleParameter> parameters = RimSummaryEnsembleTools::alphabeticEnsembleParameters( ensemble->allSummaryCases() );
ensembleParms.insert( parameters.begin(), parameters.end() );
}
return ensembleParms;

View File

@ -26,6 +26,7 @@
#include "RimParameterResultCrossPlot.h"
#include "RimProject.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryEnsembleTools.h"
CAF_PDM_SOURCE_INIT( RimCorrelationPlotCollection, "CorrelationPlotCollection" );
@ -247,7 +248,8 @@ void RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToPlot( RimAb
auto crossPlot = dynamic_cast<RimParameterResultCrossPlot*>( plot );
if ( crossPlot )
{
crossPlot->setEnsembleParameter( ensembles.front()->alphabeticEnsembleParameters().front().name );
crossPlot->setEnsembleParameter(
RimSummaryEnsembleTools::alphabeticEnsembleParameters( ensembles.front()->allSummaryCases() ).front().name );
}
}
}

View File

@ -19,9 +19,6 @@
#include "RimWellPlotTools.h"
#include "RiaQDateTimeTools.h"
#include "RiaWellNameComparer.h"
#include "RifReaderEclipseRft.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
@ -37,6 +34,7 @@
#include "RimProject.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryEnsembleTools.h"
#include "RimWellLogChannel.h"
#include "RimWellLogExtractionCurve.h"
#include "RimWellLogLasFile.h"
@ -47,17 +45,42 @@
#include <regex>
namespace RimWellPlotTools
{
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const std::set<QString> RimWellPlotTools::PRESSURE_DATA_NAMES = { "PRESSURE", "PRES_FORM" };
const std::set<QString> PRESSURE_DATA_NAMES = { "PRESSURE", "PRES_FORM" };
const std::set<QString> RimWellPlotTools::OIL_CHANNEL_NAMES = { "QOZT", "QOIL", "^.*\\D_QOIL" };
const std::set<QString> RimWellPlotTools::GAS_CHANNEL_NAMES = { "QGZT", "QGAS", "^.*\\D_QGAS" };
const std::set<QString> RimWellPlotTools::WATER_CHANNEL_NAMES = { "QWZT", "QWAT", "^.*\\D_QWAT" };
const std::set<QString> RimWellPlotTools::TOTAL_CHANNEL_NAMES = { "QTZT", "QTOT", "^.*\\D_QTOT" };
const std::set<QString> OIL_CHANNEL_NAMES = { "QOZT", "QOIL", "^.*\\D_QOIL" };
const std::set<QString> GAS_CHANNEL_NAMES = { "QGZT", "QGAS", "^.*\\D_QGAS" };
const std::set<QString> WATER_CHANNEL_NAMES = { "QWZT", "QWAT", "^.*\\D_QWAT" };
const std::set<QString> TOTAL_CHANNEL_NAMES = { "QTZT", "QTOT", "^.*\\D_QTOT" };
std::set<QString> RimWellPlotTools::FLOW_DATA_NAMES = {};
std::set<QString> FLOW_DATA_NAMES = {};
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool tryMatchChannelName( const std::set<QString>& channelNames, const QString& channelNameToMatch )
{
auto itr = std::find_if( channelNames.begin(),
channelNames.end(),
[&]( const QString& channelName )
{
if ( channelName.startsWith( '^' ) )
{
std::regex pattern( channelName.toStdString() );
return std::regex_match( channelNameToMatch.toStdString(), pattern );
}
else
{
return (bool)channelName.contains( channelNameToMatch, Qt::CaseInsensitive );
}
} );
return itr != channelNames.end();
}
//--------------------------------------------------------------------------------------------------
///
@ -68,17 +91,29 @@ public:
StaticFieldsInitializer()
{
// Init static list
RimWellPlotTools::FLOW_DATA_NAMES.insert( RimWellPlotTools::OIL_CHANNEL_NAMES.begin(), RimWellPlotTools::OIL_CHANNEL_NAMES.end() );
RimWellPlotTools::FLOW_DATA_NAMES.insert( RimWellPlotTools::GAS_CHANNEL_NAMES.begin(), RimWellPlotTools::GAS_CHANNEL_NAMES.end() );
RimWellPlotTools::FLOW_DATA_NAMES.insert( RimWellPlotTools::WATER_CHANNEL_NAMES.begin(), RimWellPlotTools::WATER_CHANNEL_NAMES.end() );
RimWellPlotTools::FLOW_DATA_NAMES.insert( RimWellPlotTools::TOTAL_CHANNEL_NAMES.begin(), RimWellPlotTools::TOTAL_CHANNEL_NAMES.end() );
FLOW_DATA_NAMES.insert( OIL_CHANNEL_NAMES.begin(), OIL_CHANNEL_NAMES.end() );
FLOW_DATA_NAMES.insert( GAS_CHANNEL_NAMES.begin(), GAS_CHANNEL_NAMES.end() );
FLOW_DATA_NAMES.insert( WATER_CHANNEL_NAMES.begin(), WATER_CHANNEL_NAMES.end() );
FLOW_DATA_NAMES.insert( TOTAL_CHANNEL_NAMES.begin(), TOTAL_CHANNEL_NAMES.end() );
}
} staticFieldsInitializer;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::hasPressureData( const RimWellLogFile* wellLogFile )
bool isPressureChannel( RimWellLogChannel* channel )
{
for ( const auto& pressureDataName : PRESSURE_DATA_NAMES )
{
if ( QString::compare( channel->name(), pressureDataName, Qt::CaseInsensitive ) == 0 ) return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool hasPressureData( const RimWellLogFile* wellLogFile )
{
for ( RimWellLogChannel* const wellLogChannel : wellLogFile->wellLogChannels() )
{
@ -90,7 +125,7 @@ bool RimWellPlotTools::hasPressureData( const RimWellLogFile* wellLogFile )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::hasPressureData( RimWellPath* wellPath )
bool hasPressureData( RimWellPath* wellPath )
{
for ( RimWellLogFile* const wellLogFile : wellPath->wellLogFiles() )
{
@ -105,7 +140,7 @@ bool RimWellPlotTools::hasPressureData( RimWellPath* wellPath )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<RigEclipseResultAddress, QString> RimWellPlotTools::pressureResultDataInfo( const RigEclipseCaseData* eclipseCaseData )
std::pair<RigEclipseResultAddress, QString> pressureResultDataInfo( const RigEclipseCaseData* eclipseCaseData )
{
if ( eclipseCaseData != nullptr )
{
@ -125,26 +160,23 @@ std::pair<RigEclipseResultAddress, QString> RimWellPlotTools::pressureResultData
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::isPressureChannel( RimWellLogChannel* channel )
bool hasPressureData( RimEclipseResultCase* gridCase )
{
for ( const auto& pressureDataName : PRESSURE_DATA_NAMES )
{
if ( QString::compare( channel->name(), pressureDataName, Qt::CaseInsensitive ) == 0 ) return true;
}
return false;
return pressureResultDataInfo( gridCase->eclipseCaseData() ).first.isValid();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::hasPressureData( RimEclipseResultCase* gridCase )
bool isFlowChannel( RimWellLogChannel* channel )
{
return pressureResultDataInfo( gridCase->eclipseCaseData() ).first.isValid();
return tryMatchChannelName( FLOW_DATA_NAMES, channel->name() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::hasFlowData( const RimWellLog* wellLog )
bool hasFlowData( const RimWellLog* wellLog )
{
for ( RimWellLogChannel* const wellLogChannel : wellLog->wellLogChannels() )
{
@ -156,7 +188,7 @@ bool RimWellPlotTools::hasFlowData( const RimWellLog* wellLog )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::hasFlowData( const RimWellPath* wellPath )
bool hasFlowData( const RimWellPath* wellPath )
{
for ( RimWellLogFile* const wellLogFile : wellPath->wellLogFiles() )
{
@ -171,7 +203,7 @@ bool RimWellPlotTools::hasFlowData( const RimWellPath* wellPath )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::hasAssociatedWellPath( const QString& wellName )
bool hasAssociatedWellPath( const QString& wellName )
{
RimProject* proj = RimProject::current();
RimWellPath* wellPath = proj->wellPathByName( wellName );
@ -182,15 +214,7 @@ bool RimWellPlotTools::hasAssociatedWellPath( const QString& wellName )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::isFlowChannel( RimWellLogChannel* channel )
{
return tryMatchChannelName( FLOW_DATA_NAMES, channel->name() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::isOilFlowChannel( const QString& channelName )
bool isOilFlowChannel( const QString& channelName )
{
return tryMatchChannelName( OIL_CHANNEL_NAMES, channelName );
}
@ -198,7 +222,7 @@ bool RimWellPlotTools::isOilFlowChannel( const QString& channelName )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::isGasFlowChannel( const QString& channelName )
bool isGasFlowChannel( const QString& channelName )
{
return tryMatchChannelName( GAS_CHANNEL_NAMES, channelName );
}
@ -206,7 +230,7 @@ bool RimWellPlotTools::isGasFlowChannel( const QString& channelName )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::isWaterFlowChannel( const QString& channelName )
bool isWaterFlowChannel( const QString& channelName )
{
return tryMatchChannelName( WATER_CHANNEL_NAMES, channelName );
}
@ -214,7 +238,7 @@ bool RimWellPlotTools::isWaterFlowChannel( const QString& channelName )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::isTotalFlowChannel( const QString& channelName )
bool isTotalFlowChannel( const QString& channelName )
{
return tryMatchChannelName( TOTAL_CHANNEL_NAMES, channelName );
}
@ -222,7 +246,7 @@ bool RimWellPlotTools::isTotalFlowChannel( const QString& channelName )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::hasFlowData( RimEclipseResultCase* gridCase )
bool hasFlowData( RimEclipseResultCase* gridCase )
{
const RigEclipseCaseData* const eclipseCaseData = gridCase->eclipseCaseData();
@ -240,20 +264,20 @@ bool RimWellPlotTools::hasFlowData( RimEclipseResultCase* gridCase )
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
FlowPhase RimWellPlotTools::flowPhaseFromChannelName( const QString& channelName )
FlowPhase flowPhaseFromChannelName( const QString& channelName )
{
if ( tryMatchChannelName( OIL_CHANNEL_NAMES, channelName ) ) return FLOW_PHASE_OIL;
if ( tryMatchChannelName( GAS_CHANNEL_NAMES, channelName ) ) return FLOW_PHASE_GAS;
if ( tryMatchChannelName( WATER_CHANNEL_NAMES, channelName ) ) return FLOW_PHASE_WATER;
if ( tryMatchChannelName( TOTAL_CHANNEL_NAMES, channelName ) ) return FLOW_PHASE_TOTAL;
return FLOW_PHASE_NONE;
if ( tryMatchChannelName( OIL_CHANNEL_NAMES, channelName ) ) return FlowPhase::FLOW_PHASE_OIL;
if ( tryMatchChannelName( GAS_CHANNEL_NAMES, channelName ) ) return FlowPhase::FLOW_PHASE_GAS;
if ( tryMatchChannelName( WATER_CHANNEL_NAMES, channelName ) ) return FlowPhase::FLOW_PHASE_WATER;
if ( tryMatchChannelName( TOTAL_CHANNEL_NAMES, channelName ) ) return FlowPhase::FLOW_PHASE_TOTAL;
return FlowPhase::FLOW_PHASE_NONE;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPlotTools::addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& destMap,
const std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepsToAdd )
void addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& destMap,
const std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepsToAdd )
{
for ( const auto& timeStepPair : timeStepsToAdd )
{
@ -268,7 +292,7 @@ void RimWellPlotTools::addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSo
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellLogFile*> RimWellPlotTools::wellLogFilesContainingPressure( const QString& wellPathNameOrSimWellName )
std::vector<RimWellLogFile*> wellLogFilesContainingPressure( const QString& wellPathNameOrSimWellName )
{
std::vector<RimWellLogFile*> wellLogFiles;
const RimProject* const project = RimProject::current();
@ -297,7 +321,7 @@ std::vector<RimWellLogFile*> RimWellPlotTools::wellLogFilesContainingPressure( c
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellLogChannel* RimWellPlotTools::getPressureChannelFromWellFile( const RimWellLogFile* wellLogFile )
RimWellLogChannel* getPressureChannelFromWellFile( const RimWellLogFile* wellLogFile )
{
if ( wellLogFile != nullptr )
{
@ -315,7 +339,7 @@ RimWellLogChannel* RimWellPlotTools::getPressureChannelFromWellFile( const RimWe
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellLogFile*> RimWellPlotTools::wellLogFilesContainingFlow( const QString& wellPathName )
std::vector<RimWellLogFile*> wellLogFilesContainingFlow( const QString& wellPathName )
{
std::vector<RimWellLogFile*> wellLogFiles;
const RimProject* const project = RimProject::current();
@ -342,7 +366,7 @@ std::vector<RimWellLogFile*> RimWellPlotTools::wellLogFilesContainingFlow( const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPath* RimWellPlotTools::wellPathFromWellLogFile( const RimWellLogFile* wellLogFile )
RimWellPath* wellPathFromWellLogFile( const RimWellLogFile* wellLogFile )
{
RimProject* const project = RimProject::current();
for ( const auto& oilField : project->oilFields )
@ -365,7 +389,7 @@ RimWellPath* RimWellPlotTools::wellPathFromWellLogFile( const RimWellLogFile* we
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimEclipseResultCase*> RimWellPlotTools::gridCasesForWell( const QString& simWellName )
std::vector<RimEclipseResultCase*> gridCasesForWell( const QString& simWellName )
{
std::vector<RimEclipseResultCase*> cases;
const RimProject* project = RimProject::current();
@ -387,7 +411,7 @@ std::vector<RimEclipseResultCase*> RimWellPlotTools::gridCasesForWell( const QSt
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimEclipseResultCase*> RimWellPlotTools::rftCasesForWell( const QString& simWellName )
std::vector<RimEclipseResultCase*> rftCasesForWell( const QString& simWellName )
{
std::vector<RimEclipseResultCase*> cases;
const RimProject* project = RimProject::current();
@ -407,7 +431,25 @@ std::vector<RimEclipseResultCase*> RimWellPlotTools::rftCasesForWell( const QStr
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsemblesForWell( const QString& simWellName )
std::set<QDateTime> rftTimeStepsForWell( const std::vector<RimSummaryCase*>& summaryCases, const QString& wellName )
{
std::set<QDateTime> allTimeSteps;
for ( RimSummaryCase* summaryCase : summaryCases )
{
RifReaderRftInterface* reader = summaryCase->rftReader();
if ( reader )
{
std::set<QDateTime> timeStep = reader->availableTimeSteps( wellName );
allTimeSteps.insert( timeStep.begin(), timeStep.end() );
}
}
return allTimeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCaseCollection*> rftEnsemblesForWell( const QString& simWellName )
{
const RimProject* project = RimProject::current();
@ -417,7 +459,8 @@ std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsemblesForWell( co
for ( RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections )
{
if ( summaryCaseColl && summaryCaseColl->isEnsemble() && !summaryCaseColl->rftTimeStepsForWell( simWellName ).empty() )
if ( summaryCaseColl && summaryCaseColl->isEnsemble() &&
!rftTimeStepsForWell( summaryCaseColl->allSummaryCases(), simWellName ).empty() )
{
rftEnsembles.push_back( summaryCaseColl );
}
@ -428,7 +471,7 @@ std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsemblesForWell( co
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsembles()
std::vector<RimSummaryCaseCollection*> rftEnsembles()
{
const RimProject* project = RimProject::current();
@ -438,7 +481,8 @@ std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsembles()
for ( RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections )
{
if ( summaryCaseColl && summaryCaseColl->isEnsemble() && !summaryCaseColl->wellsWithRftData().empty() )
if ( summaryCaseColl && summaryCaseColl->isEnsemble() &&
!RimSummaryEnsembleTools::wellsWithRftData( summaryCaseColl->allSummaryCases() ).empty() )
{
rftEnsembles.push_back( summaryCaseColl );
}
@ -449,7 +493,7 @@ std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsembles()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimObservedFmuRftData*> RimWellPlotTools::observedFmuRftDataForWell( const QString& simWellName )
std::vector<RimObservedFmuRftData*> observedFmuRftDataForWell( const QString& simWellName )
{
std::vector<RimObservedFmuRftData*> observedDataForWell;
std::vector<RimObservedFmuRftData*> allObservedData = observedFmuRftData();
@ -466,7 +510,7 @@ std::vector<RimObservedFmuRftData*> RimWellPlotTools::observedFmuRftDataForWell(
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimObservedFmuRftData*> RimWellPlotTools::observedFmuRftData()
std::vector<RimObservedFmuRftData*> observedFmuRftData()
{
const RimProject* project = RimProject::current();
RimObservedDataCollection* observedDataCollection = project->activeOilField() ? project->activeOilField()->observedDataCollection()
@ -482,7 +526,7 @@ std::vector<RimObservedFmuRftData*> RimWellPlotTools::observedFmuRftData()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimPressureDepthData*> RimWellPlotTools::pressureDepthDataForWell( const QString& simWellName )
std::vector<RimPressureDepthData*> pressureDepthDataForWell( const QString& simWellName )
{
std::vector<RimPressureDepthData*> observedDataForWell;
std::vector<RimPressureDepthData*> allObservedData = pressureDepthData();
@ -499,7 +543,7 @@ std::vector<RimPressureDepthData*> RimWellPlotTools::pressureDepthDataForWell( c
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimPressureDepthData*> RimWellPlotTools::pressureDepthData()
std::vector<RimPressureDepthData*> pressureDepthData()
{
const RimProject* project = RimProject::current();
RimObservedDataCollection* observedDataCollection = project->activeOilField() ? project->activeOilField()->observedDataCollection()
@ -515,7 +559,7 @@ std::vector<RimPressureDepthData*> RimWellPlotTools::pressureDepthData()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::timeStepsMapFromGridCase( RimEclipseCase* gridCase )
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> timeStepsMapFromGridCase( RimEclipseCase* gridCase )
{
const RigEclipseCaseData* const eclipseCaseData = gridCase->eclipseCaseData();
std::pair<RigEclipseResultAddress, QString> resultDataInfo = pressureResultDataInfo( eclipseCaseData );
@ -539,8 +583,7 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::timeStep
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QDateTime> RimWellPlotTools::findMatchingOrAdjacentTimeSteps( const std::set<QDateTime>& baseTimeLine,
const std::set<QDateTime>& availableTimeSteps )
std::set<QDateTime> findMatchingOrAdjacentTimeSteps( const std::set<QDateTime>& baseTimeLine, const std::set<QDateTime>& availableTimeSteps )
{
std::set<QDateTime> resultTimeSteps;
for ( const QDateTime& baseTimeStep : baseTimeLine )
@ -572,7 +615,7 @@ std::set<QDateTime> RimWellPlotTools::findMatchingOrAdjacentTimeSteps( const std
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QDateTime> RimWellPlotTools::availableSimWellTimesteps( RimEclipseCase* eclCase, const QString& simWellName, bool addFirstReportTimestep )
std::set<QDateTime> availableSimWellTimesteps( RimEclipseCase* eclCase, const QString& simWellName, bool addFirstReportTimestep )
{
if ( !eclCase || !eclCase->eclipseCaseData() ) return {};
@ -600,7 +643,7 @@ std::set<QDateTime> RimWellPlotTools::availableSimWellTimesteps( RimEclipseCase*
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RifReaderRftInterface* RimWellPlotTools::rftReaderInterface( RimEclipseCase* eclipseCase )
RifReaderRftInterface* rftReaderInterface( RimEclipseCase* eclipseCase )
{
auto eclResCase = dynamic_cast<RimEclipseResultCase*>( eclipseCase );
@ -612,7 +655,7 @@ RifReaderRftInterface* RimWellPlotTools::rftReaderInterface( RimEclipseCase* ecl
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve( const RimWellLogCurve* curve )
RiaRftPltCurveDefinition curveDefFromCurve( const RimWellLogCurve* curve )
{
const RimWellLogRftCurve* rftCurve = dynamic_cast<const RimWellLogRftCurve*>( curve );
const RimWellLogExtractionCurve* gridCurve = dynamic_cast<const RimWellLogExtractionCurve*>( curve );
@ -696,7 +739,7 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve( const RimWellLogCu
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimWellPath* RimWellPlotTools::wellPathByWellPathNameOrSimWellName( const QString& wellPathNameOrSimwellName )
RimWellPath* wellPathByWellPathNameOrSimWellName( const QString& wellPathNameOrSimwellName )
{
RimProject* proj = RimProject::current();
RimWellPath* wellPath = proj->wellPathByName( wellPathNameOrSimwellName );
@ -707,12 +750,12 @@ RimWellPath* RimWellPlotTools::wellPathByWellPathNameOrSimWellName( const QStrin
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimWellPath*> RimWellPlotTools::wellPathsContainingFlow()
std::vector<RimWellPath*> wellPathsContainingFlow()
{
std::vector<RimWellPath*> wellPaths;
for ( RimWellPath* wellPath : RimProject::current()->allWellPaths() )
{
if ( wellPath->wellPathGeometry() || RimWellPlotTools::hasFlowData( wellPath ) ) wellPaths.push_back( wellPath );
if ( wellPath->wellPathGeometry() || hasFlowData( wellPath ) ) wellPaths.push_back( wellPath );
}
return wellPaths;
@ -721,7 +764,7 @@ std::vector<RimWellPath*> RimWellPlotTools::wellPathsContainingFlow()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellPlotTools::simWellName( const QString& wellPathNameOrSimWellName )
QString simWellName( const QString& wellPathNameOrSimWellName )
{
RimWellPath* wellPath = wellPathByWellPathNameOrSimWellName( wellPathNameOrSimWellName );
return wellPath != nullptr ? wellPath->associatedSimulationWellName() : wellPathNameOrSimWellName;
@ -730,34 +773,11 @@ QString RimWellPlotTools::simWellName( const QString& wellPathNameOrSimWellName
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::tryMatchChannelName( const std::set<QString>& channelNames, const QString& channelNameToMatch )
{
auto itr = std::find_if( channelNames.begin(),
channelNames.end(),
[&]( const QString& channelName )
{
if ( channelName.startsWith( '^' ) )
{
std::regex pattern( channelName.toStdString() );
return std::regex_match( channelNameToMatch.toStdString(), pattern );
}
else
{
return (bool)channelName.contains( channelNameToMatch, Qt::CaseInsensitive );
}
} );
return itr != channelNames.end();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<RiaRftPltCurveDefinition>
RimWellPlotTools::curveDefsFromTimesteps( const QString& wellPathNameOrSimWellName,
const std::vector<QDateTime>& selectedTimeSteps,
bool firstSimWellTimeStepIsValid,
const std::vector<RifDataSourceForRftPlt>& selectedSourcesExpanded,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults )
std::set<RiaRftPltCurveDefinition> curveDefsFromTimesteps( const QString& wellPathNameOrSimWellName,
const std::vector<QDateTime>& selectedTimeSteps,
bool firstSimWellTimeStepIsValid,
const std::vector<RifDataSourceForRftPlt>& selectedSourcesExpanded,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults )
{
std::set<RiaRftPltCurveDefinition> curveDefs;
@ -781,8 +801,7 @@ std::set<RiaRftPltCurveDefinition>
}
else if ( addr.sourceType() == RifDataSourceForRftPlt::SourceType::GRID_MODEL_CELL_DATA && addr.eclCase() )
{
std::set<QDateTime> timeSteps =
RimWellPlotTools::availableSimWellTimesteps( addr.eclCase(), simWellName, firstSimWellTimeStepIsValid );
std::set<QDateTime> timeSteps = availableSimWellTimesteps( addr.eclCase(), simWellName, firstSimWellTimeStepIsValid );
for ( const QDateTime& time : timeSteps )
{
@ -852,7 +871,7 @@ std::set<RiaRftPltCurveDefinition>
// Add statistics curves
if ( addr.sourceType() == RifDataSourceForRftPlt::SourceType::ENSEMBLE_RFT )
{
std::set<QDateTime> statTimeSteps = addr.ensemble()->rftTimeStepsForWell( wellPathNameOrSimWellName );
std::set<QDateTime> statTimeSteps = rftTimeStepsForWell( addr.ensemble()->allSummaryCases(), wellPathNameOrSimWellName );
for ( const QDateTime& time : statTimeSteps )
{
if ( selectedTimeStepSet.count( time ) )
@ -885,19 +904,19 @@ std::set<RiaRftPltCurveDefinition>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellPlotTools::flowPlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem )
QString flowPlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem )
{
QString axisTitle;
if ( condition == RimWellLogLasFile::WELL_FLOW_COND_RESERVOIR )
{
QString unitText = RimWellPlotTools::flowUnitText( condition, unitSystem );
QString unitText = flowUnitText( condition, unitSystem );
axisTitle = "Reservoir Flow Rate " + unitText;
}
else
{
QString unitText = RimWellPlotTools::flowUnitText( condition, unitSystem );
QString unitText = flowUnitText( condition, unitSystem );
axisTitle = "Surface Flow Rate " + unitText;
}
@ -933,7 +952,7 @@ QString flowConditionReservoirUnitText( RiaDefines::EclipseUnitSystem unitSystem
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellPlotTools::flowUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem )
QString flowUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem )
{
QString unitText;
@ -965,19 +984,19 @@ QString RimWellPlotTools::flowUnitText( RimWellLogLasFile::WellFlowCondition con
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellPlotTools::flowVolumePlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem )
QString flowVolumePlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem )
{
QString axisTitle;
if ( condition == RimWellLogLasFile::WELL_FLOW_COND_RESERVOIR )
{
QString unitText = RimWellPlotTools::flowVolumeUnitText( condition, unitSystem );
QString unitText = flowVolumeUnitText( condition, unitSystem );
axisTitle = "Reservoir Flow Volume " + unitText;
}
else
{
QString unitText = RimWellPlotTools::flowVolumeUnitText( condition, unitSystem );
QString unitText = flowVolumeUnitText( condition, unitSystem );
axisTitle = "Surface Flow Volume " + unitText;
}
@ -1013,7 +1032,7 @@ QString flowVolumeConditionReservoirUnitText( RiaDefines::EclipseUnitSystem unit
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellPlotTools::flowVolumeUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem )
QString flowVolumeUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem )
{
QString unitText;
@ -1045,9 +1064,7 @@ QString RimWellPlotTools::flowVolumeUnitText( RimWellLogLasFile::WellFlowConditi
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimWellPlotTools::curveUnitText( RimWellLogLasFile::WellFlowCondition condition,
RiaDefines::EclipseUnitSystem unitSystem,
FlowPhase flowPhase )
QString curveUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem, FlowPhase flowPhase )
{
QString unitText;
@ -1062,11 +1079,11 @@ QString RimWellPlotTools::curveUnitText( RimWellLogLasFile::WellFlowCondition co
case RiaDefines::EclipseUnitSystem::UNITS_METRIC:
switch ( flowPhase )
{
case FLOW_PHASE_GAS:
case FlowPhase::FLOW_PHASE_GAS:
unitText = "[kSm<sup>3</sup>/day]";
break;
case FLOW_PHASE_WATER: // Intentionally fall through, water and oil have same unit
case FLOW_PHASE_OIL:
case FlowPhase::FLOW_PHASE_WATER: // Intentionally fall through, water and oil have same unit
case FlowPhase::FLOW_PHASE_OIL:
unitText = "[Sm<sup>3</sup>/day]";
break;
default:
@ -1078,11 +1095,11 @@ QString RimWellPlotTools::curveUnitText( RimWellLogLasFile::WellFlowCondition co
case RiaDefines::EclipseUnitSystem::UNITS_FIELD:
switch ( flowPhase )
{
case FLOW_PHASE_GAS:
case FlowPhase::FLOW_PHASE_GAS:
unitText = "[BOE/day]";
break;
case FLOW_PHASE_WATER: // Intentionally fall through, water and oil have same unit
case FLOW_PHASE_OIL:
case FlowPhase::FLOW_PHASE_WATER: // Intentionally fall through, water and oil have same unit
case FlowPhase::FLOW_PHASE_OIL:
unitText = "[BBL/day]";
break;
default:
@ -1105,9 +1122,9 @@ QString RimWellPlotTools::curveUnitText( RimWellLogLasFile::WellFlowCondition co
///
//--------------------------------------------------------------------------------------------------
std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
RimWellPlotTools::calculateRelevantTimeStepsFromCases( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults )
calculateRelevantTimeStepsFromCases( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults )
{
bool addFirstTimestep = ( interestingRFTResults.count( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) == 1 );
@ -1208,8 +1225,7 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
{
if ( source.sourceType() == RifDataSourceForRftPlt::SourceType::GRID_MODEL_CELL_DATA && source.eclCase() )
{
std::set<QDateTime> wellTimeSteps =
RimWellPlotTools::availableSimWellTimesteps( source.eclCase(), simWellName, addFirstTimestep );
std::set<QDateTime> wellTimeSteps = availableSimWellTimesteps( source.eclCase(), simWellName, addFirstTimestep );
for ( const QDateTime& date : wellTimeSteps )
{
@ -1246,7 +1262,7 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
{
if ( source.sourceType() == RifDataSourceForRftPlt::SourceType::ENSEMBLE_RFT && source.ensemble() )
{
std::set<QDateTime> wellTimeSteps = source.ensemble()->rftTimeStepsForWell( wellPathNameOrSimWellName );
std::set<QDateTime> wellTimeSteps = rftTimeStepsForWell( source.ensemble()->allSummaryCases(), wellPathNameOrSimWellName );
for ( const QDateTime& date : wellTimeSteps )
{
@ -1302,12 +1318,10 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
for ( const auto& dateSourceSetPair : ensembleTimeStepsWithSources )
ensembleRftTimeSteps.insert( dateSourceSetPair.first );
std::set<QDateTime> filteredRftTimeSteps = RimWellPlotTools::findMatchingOrAdjacentTimeSteps( baseTimeSteps, rftTimeSteps );
std::set<QDateTime> filteredGridTimeSteps = RimWellPlotTools::findMatchingOrAdjacentTimeSteps( baseTimeSteps, gridTimeSteps );
std::set<QDateTime> filteredEnsembleRftTimeSteps =
RimWellPlotTools::findMatchingOrAdjacentTimeSteps( baseTimeSteps, ensembleRftTimeSteps );
std::set<QDateTime> filteredSummaryRftTimeSteps =
RimWellPlotTools::findMatchingOrAdjacentTimeSteps( baseTimeSteps, summaryRftTimeSteps );
std::set<QDateTime> filteredRftTimeSteps = findMatchingOrAdjacentTimeSteps( baseTimeSteps, rftTimeSteps );
std::set<QDateTime> filteredGridTimeSteps = findMatchingOrAdjacentTimeSteps( baseTimeSteps, gridTimeSteps );
std::set<QDateTime> filteredEnsembleRftTimeSteps = findMatchingOrAdjacentTimeSteps( baseTimeSteps, ensembleRftTimeSteps );
std::set<QDateTime> filteredSummaryRftTimeSteps = findMatchingOrAdjacentTimeSteps( baseTimeSteps, summaryRftTimeSteps );
if ( addFirstTimestep && !gridTimeSteps.empty() )
{
@ -1364,10 +1378,10 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellPlotTools::calculateValueOptionsForTimeSteps( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults,
QList<caf::PdmOptionItemInfo>& options )
void calculateValueOptionsForTimeSteps( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults,
QList<caf::PdmOptionItemInfo>& options )
{
auto timestepsToShowWithSources = calculateRelevantTimeStepsFromCases( wellPathNameOrSimWellName, selSources, interestingRFTResults );
@ -1424,3 +1438,5 @@ void RimWellPlotTools::calculateValueOptionsForTimeSteps( const QString&
options.push_back( caf::PdmOptionItemInfo( optionText, timeStepPair.first ) );
}
}
} // namespace RimWellPlotTools

View File

@ -21,13 +21,10 @@
#include "RiaDefines.h"
#include "RiaRftPltCurveDefinition.h"
#include "RifDataSourceForRftPltQMetaType.h"
#include "RifEclipseRftAddress.h"
#include "RimWellLogLasFile.h"
#include <QMetaType>
#include <map>
#include <set>
@ -45,15 +42,15 @@ class RigEclipseCaseData;
class RigEclipseResultAddress;
class RifReaderRftInterface;
//==================================================================================================
///
//==================================================================================================
enum FlowType
namespace RimWellPlotTools
{
enum class FlowType
{
FLOW_TYPE_PHASE_SPLIT,
FLOW_TYPE_TOTAL
};
enum FlowPhase
enum class FlowPhase
{
FLOW_PHASE_NONE,
FLOW_PHASE_OIL,
@ -62,100 +59,61 @@ enum FlowPhase
FLOW_PHASE_TOTAL
};
//==================================================================================================
///
//==================================================================================================
class RimWellPlotTools
{
public:
// PLT Only
static bool isOilFlowChannel( const QString& channelName );
static bool isGasFlowChannel( const QString& channelName );
static bool isWaterFlowChannel( const QString& channelName );
static bool isTotalFlowChannel( const QString& channelName );
static FlowPhase flowPhaseFromChannelName( const QString& channelName );
bool isOilFlowChannel( const QString& channelName );
bool isGasFlowChannel( const QString& channelName );
bool isWaterFlowChannel( const QString& channelName );
bool isTotalFlowChannel( const QString& channelName );
FlowPhase flowPhaseFromChannelName( const QString& channelName );
static std::vector<RimWellLogFile*> wellLogFilesContainingFlow( const QString& wellName );
static RimWellPath* wellPathByWellPathNameOrSimWellName( const QString& wellPathNameOrSimwellName );
static std::vector<RimWellPath*> wellPathsContainingFlow();
std::vector<RimWellLogFile*> wellLogFilesContainingFlow( const QString& wellName );
RimWellPath* wellPathByWellPathNameOrSimWellName( const QString& wellPathNameOrSimwellName );
std::vector<RimWellPath*> wellPathsContainingFlow();
// RFT Only
private:
static std::pair<RigEclipseResultAddress, QString> pressureResultDataInfo( const RigEclipseCaseData* eclipseCaseData );
void addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& destMap,
const std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepsToAdd );
std::vector<RimWellLogFile*> wellLogFilesContainingPressure( const QString& wellPathNameOrSimWellName );
RimWellLogChannel* getPressureChannelFromWellFile( const RimWellLogFile* wellLogFile );
RimWellPath* wellPathFromWellLogFile( const RimWellLogFile* wellLogFile );
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> timeStepsMapFromGridCase( RimEclipseCase* gridCase );
RiaRftPltCurveDefinition curveDefFromCurve( const RimWellLogCurve* curve );
public:
static void addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& destMap,
const std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepsToAdd );
static std::vector<RimWellLogFile*> wellLogFilesContainingPressure( const QString& wellPathNameOrSimWellName );
static RimWellLogChannel* getPressureChannelFromWellFile( const RimWellLogFile* wellLogFile );
static RimWellPath* wellPathFromWellLogFile( const RimWellLogFile* wellLogFile );
static std::map<QDateTime, std::set<RifDataSourceForRftPlt>> timeStepsMapFromGridCase( RimEclipseCase* gridCase );
static RiaRftPltCurveDefinition curveDefFromCurve( const RimWellLogCurve* curve );
bool hasFlowData( const RimWellLog* wellLog );
bool hasAssociatedWellPath( const QString& wellName );
// others
static bool hasFlowData( const RimWellLog* wellLog );
static bool hasAssociatedWellPath( const QString& wellName );
std::vector<RimEclipseResultCase*> gridCasesForWell( const QString& simWellName );
std::vector<RimEclipseResultCase*> rftCasesForWell( const QString& simWellName );
std::vector<RimSummaryCaseCollection*> rftEnsemblesForWell( const QString& simWellName );
std::vector<RimSummaryCaseCollection*> rftEnsembles();
std::vector<RimObservedFmuRftData*> observedFmuRftDataForWell( const QString& simWellName );
std::vector<RimObservedFmuRftData*> observedFmuRftData();
QString simWellName( const QString& wellPathNameOrSimWellName );
// Both
static std::vector<RimEclipseResultCase*> gridCasesForWell( const QString& simWellName );
static std::vector<RimEclipseResultCase*> rftCasesForWell( const QString& simWellName );
static std::vector<RimSummaryCaseCollection*> rftEnsemblesForWell( const QString& simWellName );
static std::vector<RimSummaryCaseCollection*> rftEnsembles();
static std::vector<RimObservedFmuRftData*> observedFmuRftDataForWell( const QString& simWellName );
static std::vector<RimObservedFmuRftData*> observedFmuRftData();
static QString simWellName( const QString& wellPathNameOrSimWellName );
std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
calculateRelevantTimeStepsFromCases( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults );
static std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
calculateRelevantTimeStepsFromCases( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults );
void calculateValueOptionsForTimeSteps( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults,
QList<caf::PdmOptionItemInfo>& options );
static void calculateValueOptionsForTimeSteps( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults,
QList<caf::PdmOptionItemInfo>& options );
std::set<RiaRftPltCurveDefinition> curveDefsFromTimesteps( const QString& wellPathNameOrSimWellName,
const std::vector<QDateTime>& selectedTimeStepVector,
bool firstReportTimeStepIsValid,
const std::vector<RifDataSourceForRftPlt>& selectedSourcesExpanded,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults );
static std::set<RiaRftPltCurveDefinition>
curveDefsFromTimesteps( const QString& wellPathNameOrSimWellName,
const std::vector<QDateTime>& selectedTimeStepVector,
bool firstReportTimeStepIsValid,
const std::vector<RifDataSourceForRftPlt>& selectedSourcesExpanded,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults );
QString flowPlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
QString flowUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
QString flowVolumePlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
QString flowVolumeUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
static QString flowPlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
static QString flowUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
static QString flowVolumePlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
static QString flowVolumeUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
QString curveUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem, FlowPhase flowPhase );
static QString
curveUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem, FlowPhase flowPhase );
bool hasFlowData( const RimWellPath* wellPath );
static bool hasFlowData( const RimWellPath* wellPath );
std::vector<RimPressureDepthData*> pressureDepthData();
std::vector<RimPressureDepthData*> pressureDepthDataForWell( const QString& simWellName );
static std::vector<RimPressureDepthData*> pressureDepthData();
static std::vector<RimPressureDepthData*> pressureDepthDataForWell( const QString& simWellName );
private:
friend class StaticFieldsInitializer;
static const std::set<QString> PRESSURE_DATA_NAMES;
static const std::set<QString> OIL_CHANNEL_NAMES;
static const std::set<QString> GAS_CHANNEL_NAMES;
static const std::set<QString> WATER_CHANNEL_NAMES;
static const std::set<QString> TOTAL_CHANNEL_NAMES;
static std::set<QString> FLOW_DATA_NAMES;
static bool hasPressureData( const RimWellLogFile* wellLogFile );
static bool isPressureChannel( RimWellLogChannel* channel );
static bool hasPressureData( RimEclipseResultCase* gridCase );
static bool hasPressureData( RimWellPath* wellPath );
static bool hasFlowData( RimEclipseResultCase* gridCase );
static bool isFlowChannel( RimWellLogChannel* channel );
static bool tryMatchChannelName( const std::set<QString>& channelNames, const QString& channelNameToMatch );
static std::set<QDateTime> findMatchingOrAdjacentTimeSteps( const std::set<QDateTime>& baseTimeLine,
const std::set<QDateTime>& availableTimeSteps );
static std::set<QDateTime> availableSimWellTimesteps( RimEclipseCase* eclCase, const QString& simWellName, bool addFirstReportTimeStep );
static RifReaderRftInterface* rftReaderInterface( RimEclipseCase* eclipseCase );
};
}; // namespace RimWellPlotTools

View File

@ -74,20 +74,20 @@ CAF_PDM_SOURCE_INIT( RimWellPltPlot, "WellPltPlot" );
namespace caf
{
template <>
void caf::AppEnum<FlowType>::setUp()
void caf::AppEnum<RimWellPlotTools::FlowType>::setUp()
{
addItem( FLOW_TYPE_PHASE_SPLIT, "PHASE_SPLIT", "Phase Split" );
addItem( FLOW_TYPE_TOTAL, "TOTAL", "Total Flow" );
setDefault( FLOW_TYPE_PHASE_SPLIT );
addItem( RimWellPlotTools::FlowType::FLOW_TYPE_PHASE_SPLIT, "PHASE_SPLIT", "Phase Split" );
addItem( RimWellPlotTools::FlowType::FLOW_TYPE_TOTAL, "TOTAL", "Total Flow" );
setDefault( RimWellPlotTools::FlowType::FLOW_TYPE_PHASE_SPLIT );
}
template <>
void caf::AppEnum<FlowPhase>::setUp()
void caf::AppEnum<RimWellPlotTools::FlowPhase>::setUp()
{
addItem( FLOW_PHASE_OIL, "PHASE_OIL", "Oil" );
addItem( FLOW_PHASE_GAS, "PHASE_GAS", "Gas" );
addItem( FLOW_PHASE_WATER, "PHASE_WATER", "Water" );
addItem( FLOW_PHASE_TOTAL, "PHASE_TOTAL", "Total" );
addItem( RimWellPlotTools::FlowPhase::FLOW_PHASE_OIL, "PHASE_OIL", "Oil" );
addItem( RimWellPlotTools::FlowPhase::FLOW_PHASE_GAS, "PHASE_GAS", "Gas" );
addItem( RimWellPlotTools::FlowPhase::FLOW_PHASE_WATER, "PHASE_WATER", "Water" );
addItem( RimWellPlotTools::FlowPhase::FLOW_PHASE_TOTAL, "PHASE_TOTAL", "Total" );
}
} // namespace caf
@ -127,7 +127,9 @@ RimWellPltPlot::RimWellPltPlot()
CAF_PDM_InitFieldNoDefault( &m_phases, "Phases", "Phases" );
m_phases.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
m_phases = std::vector<caf::AppEnum<FlowPhase>>( { FLOW_PHASE_OIL, FLOW_PHASE_GAS, FLOW_PHASE_WATER } );
m_phases = std::vector<caf::AppEnum<RimWellPlotTools::FlowPhase>>( { RimWellPlotTools::FlowPhase::FLOW_PHASE_OIL,
RimWellPlotTools::FlowPhase::FLOW_PHASE_GAS,
RimWellPlotTools::FlowPhase::FLOW_PHASE_WATER } );
m_phases.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
m_nameConfig->setCustomName( "PLT Plot" );
@ -484,7 +486,7 @@ void RimWellPltPlot::syncCurvesFromUiSelection()
// Add curves
for ( const RiaRftPltCurveDefinition& curveDefToAdd : curveDefs )
{
std::set<FlowPhase> selectedPhases = std::set<FlowPhase>( m_phases().begin(), m_phases().end() );
std::set<RimWellPlotTools::FlowPhase> selectedPhases = std::set<RimWellPlotTools::FlowPhase>( m_phases().begin(), m_phases().end() );
RifDataSourceForRftPlt sourceDef = curveDefToAdd.address();
QDateTime timeStep = curveDefToAdd.timeStep();
@ -522,7 +524,7 @@ void RimWellPltPlot::syncCurvesFromUiSelection()
{
if ( !resultPointCalc->pipeBranchCLCoords().empty() )
{
if ( selectedPhases.count( FLOW_PHASE_TOTAL ) && m_useReservoirConditionCurves() &&
if ( selectedPhases.count( RimWellPlotTools::FlowPhase::FLOW_PHASE_TOTAL ) && m_useReservoirConditionCurves() &&
sourceDef.sourceType() == RifDataSourceForRftPlt::SourceType::GRID_MODEL_CELL_DATA )
{
RigAccWellFlowCalculator wfTotalAccumulator( resultPointCalc->pipeBranchCLCoords(),
@ -561,17 +563,17 @@ void RimWellPltPlot::syncCurvesFromUiSelection()
: tracerName == RIG_FLOW_WATER_NAME ? cvf::Color3f::BLUE
: cvf::Color3f::DARK_GRAY;
if ( ( tracerName == RIG_FLOW_OIL_NAME && selectedPhases.count( FLOW_PHASE_OIL ) ) ||
( tracerName == RIG_FLOW_GAS_NAME && selectedPhases.count( FLOW_PHASE_GAS ) ) ||
( tracerName == RIG_FLOW_WATER_NAME && selectedPhases.count( FLOW_PHASE_WATER ) ) )
if ( ( tracerName == RIG_FLOW_OIL_NAME && selectedPhases.count( RimWellPlotTools::FlowPhase::FLOW_PHASE_OIL ) ) ||
( tracerName == RIG_FLOW_GAS_NAME && selectedPhases.count( RimWellPlotTools::FlowPhase::FLOW_PHASE_GAS ) ) ||
( tracerName == RIG_FLOW_WATER_NAME && selectedPhases.count( RimWellPlotTools::FlowPhase::FLOW_PHASE_WATER ) ) )
{
FlowPhase flowPhase = FLOW_PHASE_NONE;
RimWellPlotTools::FlowPhase flowPhase = RimWellPlotTools::FlowPhase::FLOW_PHASE_NONE;
if ( tracerName == RIG_FLOW_OIL_NAME )
flowPhase = FLOW_PHASE_OIL;
flowPhase = RimWellPlotTools::FlowPhase::FLOW_PHASE_OIL;
else if ( tracerName == RIG_FLOW_GAS_NAME )
flowPhase = FLOW_PHASE_GAS;
flowPhase = RimWellPlotTools::FlowPhase::FLOW_PHASE_GAS;
else if ( tracerName == RIG_FLOW_WATER_NAME )
flowPhase = FLOW_PHASE_WATER;
flowPhase = RimWellPlotTools::FlowPhase::FLOW_PHASE_WATER;
QString curveUnitText =
RimWellPlotTools::curveUnitText( RimWellLogLasFile::WELL_FLOW_COND_STANDARD, unitSet, flowPhase );
@ -631,13 +633,13 @@ void RimWellPltPlot::syncCurvesFromUiSelection()
: RimWellPlotTools::isWaterFlowChannel( channelName ) ? cvf::Color3f::BLUE
: cvf::Color3f::DARK_GRAY;
FlowPhase flowPhase = FLOW_PHASE_NONE;
RimWellPlotTools::FlowPhase flowPhase = RimWellPlotTools::FlowPhase::FLOW_PHASE_NONE;
if ( RimWellPlotTools::isOilFlowChannel( channelName ) )
flowPhase = FLOW_PHASE_OIL;
flowPhase = RimWellPlotTools::FlowPhase::FLOW_PHASE_OIL;
else if ( RimWellPlotTools::isGasFlowChannel( channelName ) )
flowPhase = FLOW_PHASE_GAS;
flowPhase = RimWellPlotTools::FlowPhase::FLOW_PHASE_GAS;
else if ( RimWellPlotTools::isWaterFlowChannel( channelName ) )
flowPhase = FLOW_PHASE_WATER;
flowPhase = RimWellPlotTools::FlowPhase::FLOW_PHASE_WATER;
QString curveUnitText = RimWellPlotTools::curveUnitText( flowCondition, unitSystem, flowPhase );
addStackedCurve( curveName + ", " + channelName + " " + curveUnitText,
@ -801,10 +803,10 @@ QList<caf::PdmOptionItemInfo> RimWellPltPlot::calculateValueOptions( const caf::
if ( fieldNeedingOptions == &m_phases )
{
options.push_back( caf::PdmOptionItemInfo( "Oil", FLOW_PHASE_OIL ) );
options.push_back( caf::PdmOptionItemInfo( "Gas", FLOW_PHASE_GAS ) );
options.push_back( caf::PdmOptionItemInfo( "Water", FLOW_PHASE_WATER ) );
options.push_back( caf::PdmOptionItemInfo( "Total", FLOW_PHASE_TOTAL ) );
options.push_back( caf::PdmOptionItemInfo( "Oil", RimWellPlotTools::FlowPhase::FLOW_PHASE_OIL ) );
options.push_back( caf::PdmOptionItemInfo( "Gas", RimWellPlotTools::FlowPhase::FLOW_PHASE_GAS ) );
options.push_back( caf::PdmOptionItemInfo( "Water", RimWellPlotTools::FlowPhase::FLOW_PHASE_WATER ) );
options.push_back( caf::PdmOptionItemInfo( "Total", RimWellPlotTools::FlowPhase::FLOW_PHASE_TOTAL ) );
}
return options;

View File

@ -118,9 +118,10 @@ private:
caf::PdmChildField<RimWellLogPlot*> m_wellLogPlot_OBSOLETE;
caf::PdmField<bool> m_useStandardConditionCurves;
caf::PdmField<bool> m_useReservoirConditionCurves;
caf::PdmField<std::vector<caf::AppEnum<FlowPhase>>> m_phases;
caf::PdmField<bool> m_useStandardConditionCurves;
caf::PdmField<bool> m_useReservoirConditionCurves;
caf::PdmField<std::vector<caf::AppEnum<RimWellPlotTools::FlowPhase>>> m_phases;
bool m_doInitAfterLoad;
bool m_isOnLoad;

View File

@ -20,7 +20,6 @@
#include "RiaColorTables.h"
#include "RiaColorTools.h"
#include "RiaDateStringParser.h"
#include "RiaPlotDefines.h"
#include "RiaSimWellBranchTools.h"
#include "RiaSummaryTools.h"
@ -29,22 +28,18 @@
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigSimWellData.h"
#include "RigWellPath.h"
#include "RimEclipseCase.h"
#include "RimEclipseCaseCollection.h"
#include "RimEclipseResultCase.h"
#include "RimEclipseResultDefinition.h"
#include "RimEnsembleCurveSetColorManager.h"
#include "RimObservedFmuRftData.h"
#include "RimOilField.h"
#include "RimPressureDepthData.h"
#include "RimProject.h"
#include "RimRegularLegendConfig.h"
#include "RimReloadCaseTools.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryEnsembleTools.h"
#include "RimTools.h"
#include "RimWellLogChannel.h"
#include "RimWellLogExtractionCurve.h"
@ -57,11 +52,9 @@
#include "RimWellPath.h"
#include "RimWellPathCollection.h"
#include "RimWellPlotTools.h"
#include "RimWellPltPlot.h"
#include "RimWellRftEnsembleCurveSet.h"
#include "RiuAbstractLegendFrame.h"
#include "RiuAbstractOverlayContentFrame.h"
#include "RiuDraggableOverlayFrame.h"
#include "RiuQwtPlotCurveDefines.h"
#include "RiuQwtPlotWidget.h"
@ -1161,7 +1154,7 @@ std::map<QString, QStringList> RimWellRftPlot::findWellSources()
{
for ( RimSummaryCaseCollection* summaryCaseColl : rftEnsembles )
{
std::set<QString> wellsWithRftData = summaryCaseColl->wellsWithRftData();
std::set<QString> wellsWithRftData = RimSummaryEnsembleTools::wellsWithRftData( summaryCaseColl->allSummaryCases() );
for ( const QString& wellName : wellsWithRftData )
{
wellNames[wellName].push_back( "Ensemble" );

View File

@ -54,6 +54,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RimSummaryRegressionAnalysisCurve.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryAddressSelector.h
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCrossPlotStatisticsCase.h
${CMAKE_CURRENT_LIST_DIR}/RimSummaryEnsembleTools.h
)
set(SOURCE_GROUP_SOURCE_FILES
@ -112,6 +113,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RimSummaryRegressionAnalysisCurve.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryAddressSelector.cpp
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCrossPlotStatisticsCase.cpp
${CMAKE_CURRENT_LIST_DIR}/RimSummaryEnsembleTools.cpp
)
list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})

View File

@ -24,7 +24,6 @@
#include "RiaStatisticsTools.h"
#include "RiaSummaryAddressAnalyzer.h"
#include "RifReaderRftInterface.h"
#include "RifSummaryReaderInterface.h"
#include "RimDerivedEnsembleCaseCollection.h"
@ -32,6 +31,7 @@
#include "RimProject.h"
#include "RimSummaryAddressCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryEnsembleTools.h"
#include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h"
@ -43,56 +43,6 @@
CAF_PDM_SOURCE_INIT( RimSummaryCaseCollection, "SummaryCaseSubCollection" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseCollection::sortByBinnedVariation( std::vector<RigEnsembleParameter>& parameterVector )
{
double minStdDev = std::numeric_limits<double>::infinity();
double maxStdDev = 0.0;
for ( const auto& paramPair : parameterVector )
{
double stdDev = paramPair.normalizedStdDeviation();
if ( stdDev != 0.0 )
{
minStdDev = std::min( minStdDev, stdDev );
maxStdDev = std::max( maxStdDev, stdDev );
}
}
if ( ( maxStdDev - minStdDev ) <= 0.0 )
{
return;
}
double delta = ( maxStdDev - minStdDev ) / (float)( RigEnsembleParameter::NR_OF_VARIATION_BINS );
std::vector<double> bins;
bins.push_back( 0.0 );
for ( int i = 0; i < RigEnsembleParameter::NR_OF_VARIATION_BINS - 1; ++i )
{
bins.push_back( minStdDev + ( i + 1 ) * delta );
}
for ( RigEnsembleParameter& nameParamPair : parameterVector )
{
int binNumber = -1;
for ( double bin : bins )
{
if ( nameParamPair.normalizedStdDeviation() > bin )
{
binNumber++;
}
}
nameParamPair.variationBin = binNumber;
}
// Sort by variation bin (highest first) but keep name as sorting parameter when parameters have the same variation
// index
std::stable_sort( parameterVector.begin(),
parameterVector.end(),
[]( const RigEnsembleParameter& lhs, const RigEnsembleParameter& rhs ) { return lhs.variationBin > rhs.variationBin; } );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -360,42 +310,6 @@ std::set<time_t> RimSummaryCaseCollection::ensembleTimeSteps() const
return allTimeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QString> RimSummaryCaseCollection::wellsWithRftData() const
{
std::set<QString> allWellNames;
for ( RimSummaryCase* summaryCase : m_cases )
{
RifReaderRftInterface* reader = summaryCase->rftReader();
if ( reader )
{
std::set<QString> wellNames = reader->wellNames();
allWellNames.insert( wellNames.begin(), wellNames.end() );
}
}
return allWellNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QDateTime> RimSummaryCaseCollection::rftTimeStepsForWell( const QString& wellName ) const
{
std::set<QDateTime> allTimeSteps;
for ( RimSummaryCase* summaryCase : m_cases )
{
RifReaderRftInterface* reader = summaryCase->rftReader();
if ( reader )
{
std::set<QDateTime> timeStep = reader->availableTimeSteps( wellName );
allTimeSteps.insert( timeStep.begin(), timeStep.end() );
}
}
return allTimeSteps;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -403,45 +317,24 @@ std::vector<RigEnsembleParameter> RimSummaryCaseCollection::variationSortedEnsem
{
if ( m_cachedSortedEnsembleParameters.empty() )
{
std::set<QString> paramSet;
for ( RimSummaryCase* rimCase : allSummaryCases() )
{
if ( rimCase->caseRealizationParameters() != nullptr )
{
auto ps = rimCase->caseRealizationParameters()->parameters();
for ( const auto& p : ps )
{
paramSet.insert( p.first );
}
}
}
m_cachedSortedEnsembleParameters.reserve( paramSet.size() );
for ( const QString& parameterName : paramSet )
{
auto ensembleParameter = createEnsembleParameter( parameterName );
m_cachedSortedEnsembleParameters.push_back( ensembleParameter );
}
RimSummaryCaseCollection::sortByBinnedVariation( m_cachedSortedEnsembleParameters );
m_cachedSortedEnsembleParameters = RimSummaryEnsembleTools::createVariationSortedEnsembleParameters( allSummaryCases() );
}
if ( !excludeNoVariation )
{
return m_cachedSortedEnsembleParameters;
}
else
const double epsilon = 1e-9;
std::vector<RigEnsembleParameter> parametersWithVariation;
for ( const auto& p : m_cachedSortedEnsembleParameters )
{
const double epsilon = 1e-9;
std::vector<RigEnsembleParameter> parametersWithVariation;
for ( const auto& p : m_cachedSortedEnsembleParameters )
if ( std::abs( p.normalizedStdDeviation() ) > epsilon )
{
if ( std::abs( p.normalizedStdDeviation() ) > epsilon )
{
parametersWithVariation.push_back( p );
}
parametersWithVariation.push_back( p );
}
return parametersWithVariation;
}
return parametersWithVariation;
}
//--------------------------------------------------------------------------------------------------
@ -595,144 +488,19 @@ std::vector<std::pair<RigEnsembleParameter, double>>
return correlationsForChosenTimeSteps[0];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigEnsembleParameter> RimSummaryCaseCollection::alphabeticEnsembleParameters() const
{
std::set<QString> paramSet;
for ( RimSummaryCase* rimCase : allSummaryCases() )
{
if ( rimCase->caseRealizationParameters() != nullptr )
{
auto ps = rimCase->caseRealizationParameters()->parameters();
for ( auto p : ps )
{
paramSet.insert( p.first );
}
}
}
std::vector<RigEnsembleParameter> sortedEnsembleParameters;
sortedEnsembleParameters.reserve( paramSet.size() );
for ( const QString& parameterName : paramSet )
{
sortedEnsembleParameters.push_back( createEnsembleParameter( parameterName ) );
}
return sortedEnsembleParameters;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEnsembleParameter RimSummaryCaseCollection::ensembleParameter( const QString& paramName ) const
{
if ( !isEnsemble() || paramName.isEmpty() ) return RigEnsembleParameter();
if ( !isEnsemble() || paramName.isEmpty() ) return {};
const std::vector<RigEnsembleParameter>& ensembleParams = variationSortedEnsembleParameters();
for ( const RigEnsembleParameter& ensParam : ensembleParams )
for ( const RigEnsembleParameter& ensParam : variationSortedEnsembleParameters() )
{
if ( ensParam.name == paramName ) return ensParam;
}
return RigEnsembleParameter();
}
RigEnsembleParameter RimSummaryCaseCollection::createEnsembleParameter( const QString& paramName ) const
{
RigEnsembleParameter eParam;
eParam.name = paramName;
size_t numericValuesCount = 0;
size_t textValuesCount = 0;
auto summaryCases = allSummaryCases();
// Make sure the values list exactly matches the case count
// And use an invalid value (infinity) for invalid cases.
eParam.values.resize( summaryCases.size(), std::numeric_limits<double>::infinity() );
// Prepare case realization params, and check types
for ( size_t caseIdx = 0; caseIdx < summaryCases.size(); ++caseIdx )
{
auto rimCase = summaryCases[caseIdx];
auto crp = rimCase->caseRealizationParameters();
if ( !crp ) continue;
auto value = crp->parameterValue( paramName );
if ( !value.isValid() ) continue;
if ( value.isNumeric() )
{
double numVal = value.numericValue();
eParam.values[caseIdx] = QVariant( numVal );
if ( numVal < eParam.minValue ) eParam.minValue = numVal;
if ( numVal > eParam.maxValue ) eParam.maxValue = numVal;
numericValuesCount++;
}
else if ( value.isText() )
{
eParam.values[caseIdx] = QVariant( value.textValue() );
textValuesCount++;
}
}
if ( numericValuesCount && !textValuesCount )
{
eParam.type = RigEnsembleParameter::TYPE_NUMERIC;
}
else if ( textValuesCount && !numericValuesCount )
{
eParam.type = RigEnsembleParameter::TYPE_TEXT;
}
if ( numericValuesCount && textValuesCount )
{
// A mix of types have been added to parameter values
if ( numericValuesCount > textValuesCount )
{
// Use numeric type
for ( auto& val : eParam.values )
{
if ( val.type() == QVariant::String )
{
val.setValue( std::numeric_limits<double>::infinity() );
}
}
eParam.type = RigEnsembleParameter::TYPE_NUMERIC;
}
else
{
// Use text type
for ( auto& val : eParam.values )
{
if ( val.type() == QVariant::Double )
{
val.setValue( QString::number( val.value<double>() ) );
}
}
eParam.type = RigEnsembleParameter::TYPE_TEXT;
eParam.minValue = std::numeric_limits<double>::infinity();
eParam.maxValue = -std::numeric_limits<double>::infinity();
}
}
if ( eParam.isText() )
{
// Remove duplicate texts
std::set<QString> valueSet;
for ( const auto& val : eParam.values )
{
valueSet.insert( val.toString() );
}
eParam.values.clear();
for ( const auto& val : valueSet )
{
eParam.values.push_back( QVariant( val ) );
}
}
return eParam;
return {};
}
//--------------------------------------------------------------------------------------------------
@ -740,72 +508,7 @@ RigEnsembleParameter RimSummaryCaseCollection::createEnsembleParameter( const QS
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseCollection::calculateEnsembleParametersIntersectionHash()
{
clearEnsembleParametersHashes();
// Find ensemble parameters intersection
std::set<QString> paramNames;
auto sumCases = allSummaryCases();
for ( size_t i = 0; i < sumCases.size(); i++ )
{
auto crp = sumCases[i]->caseRealizationParameters();
if ( !crp ) continue;
auto caseParamNames = crp->parameterNames();
if ( i == 0 )
paramNames = caseParamNames;
else
{
std::set<QString> newIntersection;
std::set_intersection( paramNames.begin(),
paramNames.end(),
caseParamNames.begin(),
caseParamNames.end(),
std::inserter( newIntersection, newIntersection.end() ) );
if ( paramNames.size() != newIntersection.size() ) paramNames = newIntersection;
}
}
for ( auto sumCase : sumCases )
{
auto crp = sumCase->caseRealizationParameters();
if ( crp ) crp->calculateParametersHash( paramNames );
}
// Find common addess count
for ( const auto sumCase : sumCases )
{
const auto reader = sumCase->summaryReader();
if ( !reader ) continue;
auto currAddrCount = reader->allResultAddresses().size();
if ( m_commonAddressCount == 0 )
{
m_commonAddressCount = currAddrCount;
}
else
{
if ( currAddrCount != m_commonAddressCount )
{
m_commonAddressCount = 0;
break;
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryCaseCollection::clearEnsembleParametersHashes()
{
for ( auto sumCase : allSummaryCases() )
{
auto crp = sumCase->caseRealizationParameters();
if ( crp ) crp->clearParametersHash();
}
m_commonAddressCount = RimSummaryEnsembleTools::calculateEnsembleParametersIntersectionHash( allSummaryCases() );
}
//--------------------------------------------------------------------------------------------------
@ -997,8 +700,9 @@ std::pair<double, double> RimSummaryCaseCollection::minMax( const RifEclipseSumm
//--------------------------------------------------------------------------------------------------
QString RimSummaryCaseCollection::nameAndItemCount() const
{
size_t itemCount = m_cases.size();
if ( itemCount > 20 )
size_t itemCount = m_cases.size();
const size_t itemCountThreshold = 20;
if ( itemCount > itemCountThreshold )
{
return QString( "%1 (%2)" ).arg( m_name() ).arg( itemCount );
}

View File

@ -69,11 +69,9 @@ public:
virtual std::set<RifEclipseSummaryAddress> ensembleSummaryAddresses() const;
virtual std::set<time_t> ensembleTimeSteps() const;
std::set<QString> wellsWithRftData() const;
std::set<QDateTime> rftTimeStepsForWell( const QString& wellName ) const;
void setEnsembleId( int ensembleId );
int ensembleId() const;
bool hasEnsembleParameters() const;
void setEnsembleId( int ensembleId );
int ensembleId() const;
bool hasEnsembleParameters() const;
std::vector<RigEnsembleParameter> variationSortedEnsembleParameters( bool excludeNoVariation = false ) const;
std::vector<std::pair<RigEnsembleParameter, double>> correlationSortedEnsembleParameters( const RifEclipseSummaryAddress& address ) const;
@ -87,11 +85,8 @@ public:
std::vector<std::pair<RigEnsembleParameter, double>>
parameterCorrelationsAllTimeSteps( const RifEclipseSummaryAddress& address, const std::vector<QString>& selectedParameters = {} ) const;
std::vector<RigEnsembleParameter> alphabeticEnsembleParameters() const;
RigEnsembleParameter ensembleParameter( const QString& paramName ) const;
void calculateEnsembleParametersIntersectionHash();
void clearEnsembleParametersHashes();
void loadDataAndUpdate();
@ -111,10 +106,6 @@ public:
std::pair<double, double> minMax( const RifEclipseSummaryAddress& address );
private:
RigEnsembleParameter createEnsembleParameter( const QString& paramName ) const;
static void sortByBinnedVariation( std::vector<RigEnsembleParameter>& parameterVector );
friend class RimSummaryCaseCollection_TESTER;
caf::PdmFieldHandle* userDescriptionField() override;
QString nameAndItemCount() const;
void updateIcon();

View File

@ -0,0 +1,325 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024- Equinor 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 "RimSummaryEnsembleTools.h"
#include "RifReaderRftInterface.h"
#include "RifSummaryReaderInterface.h"
#include "RigEnsembleParameter.h"
#include "RimSummaryCase.h"
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QString> RimSummaryEnsembleTools::wellsWithRftData( const std::vector<RimSummaryCase*>& summaryCases )
{
std::set<QString> allWellNames;
for ( auto summaryCase : summaryCases )
{
if ( auto reader = summaryCase->rftReader() )
{
std::set<QString> wellNames = reader->wellNames();
allWellNames.insert( wellNames.begin(), wellNames.end() );
}
}
return allWellNames;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RigEnsembleParameter RimSummaryEnsembleTools::createEnsembleParameter( const std::vector<RimSummaryCase*>& summaryCases,
const QString& paramName )
{
RigEnsembleParameter eParam;
eParam.name = paramName;
size_t numericValuesCount = 0;
size_t textValuesCount = 0;
// Make sure the values list exactly matches the case count
// And use an invalid value (infinity) for invalid cases.
eParam.values.resize( summaryCases.size(), std::numeric_limits<double>::infinity() );
// Prepare case realization params, and check types
for ( size_t caseIdx = 0; caseIdx < summaryCases.size(); ++caseIdx )
{
auto rimCase = summaryCases[caseIdx];
auto crp = rimCase->caseRealizationParameters();
if ( !crp ) continue;
auto value = crp->parameterValue( paramName );
if ( !value.isValid() ) continue;
if ( value.isNumeric() )
{
double numVal = value.numericValue();
eParam.values[caseIdx] = QVariant( numVal );
if ( numVal < eParam.minValue ) eParam.minValue = numVal;
if ( numVal > eParam.maxValue ) eParam.maxValue = numVal;
numericValuesCount++;
}
else if ( value.isText() )
{
eParam.values[caseIdx] = QVariant( value.textValue() );
textValuesCount++;
}
}
if ( numericValuesCount && !textValuesCount )
{
eParam.type = RigEnsembleParameter::TYPE_NUMERIC;
}
else if ( textValuesCount && !numericValuesCount )
{
eParam.type = RigEnsembleParameter::TYPE_TEXT;
}
if ( numericValuesCount && textValuesCount )
{
// A mix of types have been added to parameter values
if ( numericValuesCount > textValuesCount )
{
// Use numeric type
for ( auto& val : eParam.values )
{
if ( val.type() == QVariant::String )
{
val.setValue( std::numeric_limits<double>::infinity() );
}
}
eParam.type = RigEnsembleParameter::TYPE_NUMERIC;
}
else
{
// Use text type
for ( auto& val : eParam.values )
{
if ( val.type() == QVariant::Double )
{
val.setValue( QString::number( val.value<double>() ) );
}
}
eParam.type = RigEnsembleParameter::TYPE_TEXT;
eParam.minValue = std::numeric_limits<double>::infinity();
eParam.maxValue = -std::numeric_limits<double>::infinity();
}
}
if ( eParam.isText() )
{
// Remove duplicate texts
std::set<QString> valueSet;
for ( const auto& val : eParam.values )
{
valueSet.insert( val.toString() );
}
eParam.values.clear();
for ( const auto& val : valueSet )
{
eParam.values.push_back( QVariant( val ) );
}
}
return eParam;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimSummaryEnsembleTools::sortByBinnedVariation( std::vector<RigEnsembleParameter>& parameterVector )
{
double minStdDev = std::numeric_limits<double>::infinity();
double maxStdDev = 0.0;
for ( const auto& paramPair : parameterVector )
{
double stdDev = paramPair.normalizedStdDeviation();
if ( stdDev != 0.0 )
{
minStdDev = std::min( minStdDev, stdDev );
maxStdDev = std::max( maxStdDev, stdDev );
}
}
if ( ( maxStdDev - minStdDev ) <= 0.0 )
{
return;
}
double delta = ( maxStdDev - minStdDev ) / (float)( RigEnsembleParameter::NR_OF_VARIATION_BINS );
std::vector<double> bins;
bins.push_back( 0.0 );
for ( int i = 0; i < RigEnsembleParameter::NR_OF_VARIATION_BINS - 1; ++i )
{
bins.push_back( minStdDev + ( i + 1 ) * delta );
}
for ( RigEnsembleParameter& nameParamPair : parameterVector )
{
int binNumber = -1;
for ( double bin : bins )
{
if ( nameParamPair.normalizedStdDeviation() > bin )
{
binNumber++;
}
}
nameParamPair.variationBin = binNumber;
}
// Sort by variation bin (highest first) but keep name as sorting parameter when parameters have the same variation
// index
std::stable_sort( parameterVector.begin(),
parameterVector.end(),
[]( const RigEnsembleParameter& lhs, const RigEnsembleParameter& rhs ) { return lhs.variationBin > rhs.variationBin; } );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigEnsembleParameter> RimSummaryEnsembleTools::alphabeticEnsembleParameters( const std::vector<RimSummaryCase*>& summaryCases )
{
std::set<QString> paramSet;
for ( RimSummaryCase* rimCase : summaryCases )
{
if ( rimCase->caseRealizationParameters() != nullptr )
{
auto ps = rimCase->caseRealizationParameters()->parameters();
for ( auto p : ps )
{
paramSet.insert( p.first );
}
}
}
std::vector<RigEnsembleParameter> sortedEnsembleParameters;
sortedEnsembleParameters.reserve( paramSet.size() );
for ( const QString& parameterName : paramSet )
{
sortedEnsembleParameters.push_back( RimSummaryEnsembleTools::createEnsembleParameter( summaryCases, parameterName ) );
}
return sortedEnsembleParameters;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RigEnsembleParameter>
RimSummaryEnsembleTools::createVariationSortedEnsembleParameters( const std::vector<RimSummaryCase*>& summaryCases )
{
std::set<QString> paramSet;
for ( RimSummaryCase* rimCase : summaryCases )
{
if ( rimCase->caseRealizationParameters() != nullptr )
{
auto ps = rimCase->caseRealizationParameters()->parameters();
for ( const auto& p : ps )
{
paramSet.insert( p.first );
}
}
}
std::vector<RigEnsembleParameter> parameters;
parameters.reserve( paramSet.size() );
for ( const QString& parameterName : paramSet )
{
auto ensembleParameter = RimSummaryEnsembleTools::createEnsembleParameter( summaryCases, parameterName );
parameters.push_back( ensembleParameter );
}
RimSummaryEnsembleTools::sortByBinnedVariation( parameters );
return parameters;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void clearEnsembleParametersHashes( const std::vector<RimSummaryCase*>& summaryCases )
{
for ( auto sumCase : summaryCases )
{
auto crp = sumCase->caseRealizationParameters();
if ( crp ) crp->clearParametersHash();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
size_t RimSummaryEnsembleTools::calculateEnsembleParametersIntersectionHash( const std::vector<RimSummaryCase*>& summaryCases )
{
clearEnsembleParametersHashes( summaryCases );
// Find ensemble parameters intersection
std::set<QString> paramNames;
for ( size_t i = 0; i < summaryCases.size(); i++ )
{
auto crp = summaryCases[i]->caseRealizationParameters();
if ( !crp ) continue;
auto caseParamNames = crp->parameterNames();
if ( i == 0 )
paramNames = caseParamNames;
else
{
std::set<QString> newIntersection;
std::set_intersection( paramNames.begin(),
paramNames.end(),
caseParamNames.begin(),
caseParamNames.end(),
std::inserter( newIntersection, newIntersection.end() ) );
if ( paramNames.size() != newIntersection.size() ) paramNames = newIntersection;
}
}
for ( auto sumCase : summaryCases )
{
auto crp = sumCase->caseRealizationParameters();
if ( crp ) crp->calculateParametersHash( paramNames );
}
size_t commonAddressCount = 0;
// Find common addess count
for ( const auto sumCase : summaryCases )
{
const auto reader = sumCase->summaryReader();
if ( !reader ) continue;
auto currAddrCount = reader->allResultAddresses().size();
if ( commonAddressCount == 0 )
{
commonAddressCount = currAddrCount;
}
else
{
if ( currAddrCount != commonAddressCount )
{
commonAddressCount = 0;
break;
}
}
}
return commonAddressCount;
}

View File

@ -0,0 +1,40 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2024- Equinor 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include <QString>
#include <set>
#include <vector>
class RimSummaryCase;
class RigEnsembleParameter;
namespace RimSummaryEnsembleTools
{
std::set<QString> wellsWithRftData( const std::vector<RimSummaryCase*>& summaryCases );
RigEnsembleParameter createEnsembleParameter( const std::vector<RimSummaryCase*>& summaryCases, const QString& paramName );
void sortByBinnedVariation( std::vector<RigEnsembleParameter>& parameterVector );
std::vector<RigEnsembleParameter> alphabeticEnsembleParameters( const std::vector<RimSummaryCase*>& summaryCases );
std::vector<RigEnsembleParameter> createVariationSortedEnsembleParameters( const std::vector<RimSummaryCase*>& summaryCases );
size_t calculateEnsembleParametersIntersectionHash( const std::vector<RimSummaryCase*>& summaryCases );
} // namespace RimSummaryEnsembleTools

View File

@ -1,12 +1,10 @@
#include "gtest/gtest.h"
#include "RigEnsembleParameter.h"
#include "RimSummaryCaseCollection.h"
#include "RimSummaryEnsembleTools.h"
#include <random>
#include <QDebug>
class RimSummaryCaseCollection_TESTER
{
public:
@ -74,7 +72,7 @@ void RimSummaryCaseCollection_TESTER::test1()
}
size_t previousSize = parameters.size();
RimSummaryCaseCollection::sortByBinnedVariation( parameters );
RimSummaryEnsembleTools::sortByBinnedVariation( parameters );
size_t currentSize = parameters.size();
EXPECT_EQ( previousSize, currentSize );