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

View File

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

View File

@ -26,6 +26,7 @@
#include "RimParameterResultCrossPlot.h" #include "RimParameterResultCrossPlot.h"
#include "RimProject.h" #include "RimProject.h"
#include "RimSummaryCaseCollection.h" #include "RimSummaryCaseCollection.h"
#include "RimSummaryEnsembleTools.h"
CAF_PDM_SOURCE_INIT( RimCorrelationPlotCollection, "CorrelationPlotCollection" ); CAF_PDM_SOURCE_INIT( RimCorrelationPlotCollection, "CorrelationPlotCollection" );
@ -247,7 +248,8 @@ void RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToPlot( RimAb
auto crossPlot = dynamic_cast<RimParameterResultCrossPlot*>( plot ); auto crossPlot = dynamic_cast<RimParameterResultCrossPlot*>( plot );
if ( crossPlot ) 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 "RimWellPlotTools.h"
#include "RiaQDateTimeTools.h" #include "RiaQDateTimeTools.h"
#include "RiaWellNameComparer.h"
#include "RifReaderEclipseRft.h"
#include "RigCaseCellResultsData.h" #include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h" #include "RigEclipseCaseData.h"
@ -37,6 +34,7 @@
#include "RimProject.h" #include "RimProject.h"
#include "RimSummaryCase.h" #include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h" #include "RimSummaryCaseCollection.h"
#include "RimSummaryEnsembleTools.h"
#include "RimWellLogChannel.h" #include "RimWellLogChannel.h"
#include "RimWellLogExtractionCurve.h" #include "RimWellLogExtractionCurve.h"
#include "RimWellLogLasFile.h" #include "RimWellLogLasFile.h"
@ -47,17 +45,42 @@
#include <regex> #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> OIL_CHANNEL_NAMES = { "QOZT", "QOIL", "^.*\\D_QOIL" };
const std::set<QString> RimWellPlotTools::GAS_CHANNEL_NAMES = { "QGZT", "QGAS", "^.*\\D_QGAS" }; const std::set<QString> GAS_CHANNEL_NAMES = { "QGZT", "QGAS", "^.*\\D_QGAS" };
const std::set<QString> RimWellPlotTools::WATER_CHANNEL_NAMES = { "QWZT", "QWAT", "^.*\\D_QWAT" }; const std::set<QString> WATER_CHANNEL_NAMES = { "QWZT", "QWAT", "^.*\\D_QWAT" };
const std::set<QString> RimWellPlotTools::TOTAL_CHANNEL_NAMES = { "QTZT", "QTOT", "^.*\\D_QTOT" }; 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() StaticFieldsInitializer()
{ {
// Init static list // Init static list
RimWellPlotTools::FLOW_DATA_NAMES.insert( RimWellPlotTools::OIL_CHANNEL_NAMES.begin(), RimWellPlotTools::OIL_CHANNEL_NAMES.end() ); FLOW_DATA_NAMES.insert( OIL_CHANNEL_NAMES.begin(), OIL_CHANNEL_NAMES.end() );
RimWellPlotTools::FLOW_DATA_NAMES.insert( RimWellPlotTools::GAS_CHANNEL_NAMES.begin(), RimWellPlotTools::GAS_CHANNEL_NAMES.end() ); FLOW_DATA_NAMES.insert( GAS_CHANNEL_NAMES.begin(), GAS_CHANNEL_NAMES.end() );
RimWellPlotTools::FLOW_DATA_NAMES.insert( RimWellPlotTools::WATER_CHANNEL_NAMES.begin(), RimWellPlotTools::WATER_CHANNEL_NAMES.end() ); FLOW_DATA_NAMES.insert( WATER_CHANNEL_NAMES.begin(), WATER_CHANNEL_NAMES.end() );
RimWellPlotTools::FLOW_DATA_NAMES.insert( RimWellPlotTools::TOTAL_CHANNEL_NAMES.begin(), RimWellPlotTools::TOTAL_CHANNEL_NAMES.end() ); FLOW_DATA_NAMES.insert( TOTAL_CHANNEL_NAMES.begin(), TOTAL_CHANNEL_NAMES.end() );
} }
} staticFieldsInitializer; } 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() ) 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() ) 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 ) 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 ) return pressureResultDataInfo( gridCase->eclipseCaseData() ).first.isValid();
{
if ( QString::compare( channel->name(), pressureDataName, Qt::CaseInsensitive ) == 0 ) return true;
}
return false;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
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() ) 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() ) 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(); RimProject* proj = RimProject::current();
RimWellPath* wellPath = proj->wellPathByName( wellName ); RimWellPath* wellPath = proj->wellPathByName( wellName );
@ -182,15 +214,7 @@ bool RimWellPlotTools::hasAssociatedWellPath( const QString& wellName )
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::isFlowChannel( RimWellLogChannel* channel ) bool isOilFlowChannel( const QString& channelName )
{
return tryMatchChannelName( FLOW_DATA_NAMES, channel->name() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimWellPlotTools::isOilFlowChannel( const QString& channelName )
{ {
return tryMatchChannelName( OIL_CHANNEL_NAMES, 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 ); 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 ); 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 ); 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(); 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( OIL_CHANNEL_NAMES, channelName ) ) return FlowPhase::FLOW_PHASE_OIL;
if ( tryMatchChannelName( GAS_CHANNEL_NAMES, channelName ) ) return FLOW_PHASE_GAS; if ( tryMatchChannelName( GAS_CHANNEL_NAMES, channelName ) ) return FlowPhase::FLOW_PHASE_GAS;
if ( tryMatchChannelName( WATER_CHANNEL_NAMES, channelName ) ) return FLOW_PHASE_WATER; if ( tryMatchChannelName( WATER_CHANNEL_NAMES, channelName ) ) return FlowPhase::FLOW_PHASE_WATER;
if ( tryMatchChannelName( TOTAL_CHANNEL_NAMES, channelName ) ) return FLOW_PHASE_TOTAL; if ( tryMatchChannelName( TOTAL_CHANNEL_NAMES, channelName ) ) return FlowPhase::FLOW_PHASE_TOTAL;
return FLOW_PHASE_NONE; return FlowPhase::FLOW_PHASE_NONE;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimWellPlotTools::addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& destMap, void addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& destMap,
const std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepsToAdd ) const std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepsToAdd )
{ {
for ( const auto& timeStepPair : 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; std::vector<RimWellLogFile*> wellLogFiles;
const RimProject* const project = RimProject::current(); 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 ) 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; std::vector<RimWellLogFile*> wellLogFiles;
const RimProject* const project = RimProject::current(); 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(); RimProject* const project = RimProject::current();
for ( const auto& oilField : project->oilFields ) 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; std::vector<RimEclipseResultCase*> cases;
const RimProject* project = RimProject::current(); 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; std::vector<RimEclipseResultCase*> cases;
const RimProject* project = RimProject::current(); 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(); const RimProject* project = RimProject::current();
@ -417,7 +459,8 @@ std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsemblesForWell( co
for ( RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections ) 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 ); 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(); const RimProject* project = RimProject::current();
@ -438,7 +481,8 @@ std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsembles()
for ( RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections ) for ( RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections )
{ {
if ( summaryCaseColl && summaryCaseColl->isEnsemble() && !summaryCaseColl->wellsWithRftData().empty() ) if ( summaryCaseColl && summaryCaseColl->isEnsemble() &&
!RimSummaryEnsembleTools::wellsWithRftData( summaryCaseColl->allSummaryCases() ).empty() )
{ {
rftEnsembles.push_back( summaryCaseColl ); 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*> observedDataForWell;
std::vector<RimObservedFmuRftData*> allObservedData = observedFmuRftData(); 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(); const RimProject* project = RimProject::current();
RimObservedDataCollection* observedDataCollection = project->activeOilField() ? project->activeOilField()->observedDataCollection() 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*> observedDataForWell;
std::vector<RimPressureDepthData*> allObservedData = pressureDepthData(); 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(); const RimProject* project = RimProject::current();
RimObservedDataCollection* observedDataCollection = project->activeOilField() ? project->activeOilField()->observedDataCollection() 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(); const RigEclipseCaseData* const eclipseCaseData = gridCase->eclipseCaseData();
std::pair<RigEclipseResultAddress, QString> resultDataInfo = pressureResultDataInfo( 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, std::set<QDateTime> findMatchingOrAdjacentTimeSteps( const std::set<QDateTime>& baseTimeLine, const std::set<QDateTime>& availableTimeSteps )
const std::set<QDateTime>& availableTimeSteps )
{ {
std::set<QDateTime> resultTimeSteps; std::set<QDateTime> resultTimeSteps;
for ( const QDateTime& baseTimeStep : baseTimeLine ) 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 {}; 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 ); 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 RimWellLogRftCurve* rftCurve = dynamic_cast<const RimWellLogRftCurve*>( curve );
const RimWellLogExtractionCurve* gridCurve = dynamic_cast<const RimWellLogExtractionCurve*>( 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(); RimProject* proj = RimProject::current();
RimWellPath* wellPath = proj->wellPathByName( wellPathNameOrSimwellName ); 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; std::vector<RimWellPath*> wellPaths;
for ( RimWellPath* wellPath : RimProject::current()->allWellPaths() ) 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; 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 ); RimWellPath* wellPath = wellPathByWellPathNameOrSimWellName( wellPathNameOrSimWellName );
return wellPath != nullptr ? wellPath->associatedSimulationWellName() : 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 ) std::set<RiaRftPltCurveDefinition> curveDefsFromTimesteps( const QString& wellPathNameOrSimWellName,
{ const std::vector<QDateTime>& selectedTimeSteps,
auto itr = std::find_if( channelNames.begin(), bool firstSimWellTimeStepIsValid,
channelNames.end(), const std::vector<RifDataSourceForRftPlt>& selectedSourcesExpanded,
[&]( const QString& channelName ) const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults )
{
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> curveDefs; std::set<RiaRftPltCurveDefinition> curveDefs;
@ -781,8 +801,7 @@ std::set<RiaRftPltCurveDefinition>
} }
else if ( addr.sourceType() == RifDataSourceForRftPlt::SourceType::GRID_MODEL_CELL_DATA && addr.eclCase() ) else if ( addr.sourceType() == RifDataSourceForRftPlt::SourceType::GRID_MODEL_CELL_DATA && addr.eclCase() )
{ {
std::set<QDateTime> timeSteps = std::set<QDateTime> timeSteps = availableSimWellTimesteps( addr.eclCase(), simWellName, firstSimWellTimeStepIsValid );
RimWellPlotTools::availableSimWellTimesteps( addr.eclCase(), simWellName, firstSimWellTimeStepIsValid );
for ( const QDateTime& time : timeSteps ) for ( const QDateTime& time : timeSteps )
{ {
@ -852,7 +871,7 @@ std::set<RiaRftPltCurveDefinition>
// Add statistics curves // Add statistics curves
if ( addr.sourceType() == RifDataSourceForRftPlt::SourceType::ENSEMBLE_RFT ) 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 ) for ( const QDateTime& time : statTimeSteps )
{ {
if ( selectedTimeStepSet.count( time ) ) 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; QString axisTitle;
if ( condition == RimWellLogLasFile::WELL_FLOW_COND_RESERVOIR ) if ( condition == RimWellLogLasFile::WELL_FLOW_COND_RESERVOIR )
{ {
QString unitText = RimWellPlotTools::flowUnitText( condition, unitSystem ); QString unitText = flowUnitText( condition, unitSystem );
axisTitle = "Reservoir Flow Rate " + unitText; axisTitle = "Reservoir Flow Rate " + unitText;
} }
else else
{ {
QString unitText = RimWellPlotTools::flowUnitText( condition, unitSystem ); QString unitText = flowUnitText( condition, unitSystem );
axisTitle = "Surface Flow Rate " + unitText; 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; 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; QString axisTitle;
if ( condition == RimWellLogLasFile::WELL_FLOW_COND_RESERVOIR ) if ( condition == RimWellLogLasFile::WELL_FLOW_COND_RESERVOIR )
{ {
QString unitText = RimWellPlotTools::flowVolumeUnitText( condition, unitSystem ); QString unitText = flowVolumeUnitText( condition, unitSystem );
axisTitle = "Reservoir Flow Volume " + unitText; axisTitle = "Reservoir Flow Volume " + unitText;
} }
else else
{ {
QString unitText = RimWellPlotTools::flowVolumeUnitText( condition, unitSystem ); QString unitText = flowVolumeUnitText( condition, unitSystem );
axisTitle = "Surface Flow Volume " + unitText; 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; QString unitText;
@ -1045,9 +1064,7 @@ QString RimWellPlotTools::flowVolumeUnitText( RimWellLogLasFile::WellFlowConditi
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString RimWellPlotTools::curveUnitText( RimWellLogLasFile::WellFlowCondition condition, QString curveUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem, FlowPhase flowPhase )
RiaDefines::EclipseUnitSystem unitSystem,
FlowPhase flowPhase )
{ {
QString unitText; QString unitText;
@ -1062,11 +1079,11 @@ QString RimWellPlotTools::curveUnitText( RimWellLogLasFile::WellFlowCondition co
case RiaDefines::EclipseUnitSystem::UNITS_METRIC: case RiaDefines::EclipseUnitSystem::UNITS_METRIC:
switch ( flowPhase ) switch ( flowPhase )
{ {
case FLOW_PHASE_GAS: case FlowPhase::FLOW_PHASE_GAS:
unitText = "[kSm<sup>3</sup>/day]"; unitText = "[kSm<sup>3</sup>/day]";
break; break;
case FLOW_PHASE_WATER: // Intentionally fall through, water and oil have same unit case FlowPhase::FLOW_PHASE_WATER: // Intentionally fall through, water and oil have same unit
case FLOW_PHASE_OIL: case FlowPhase::FLOW_PHASE_OIL:
unitText = "[Sm<sup>3</sup>/day]"; unitText = "[Sm<sup>3</sup>/day]";
break; break;
default: default:
@ -1078,11 +1095,11 @@ QString RimWellPlotTools::curveUnitText( RimWellLogLasFile::WellFlowCondition co
case RiaDefines::EclipseUnitSystem::UNITS_FIELD: case RiaDefines::EclipseUnitSystem::UNITS_FIELD:
switch ( flowPhase ) switch ( flowPhase )
{ {
case FLOW_PHASE_GAS: case FlowPhase::FLOW_PHASE_GAS:
unitText = "[BOE/day]"; unitText = "[BOE/day]";
break; break;
case FLOW_PHASE_WATER: // Intentionally fall through, water and oil have same unit case FlowPhase::FLOW_PHASE_WATER: // Intentionally fall through, water and oil have same unit
case FLOW_PHASE_OIL: case FlowPhase::FLOW_PHASE_OIL:
unitText = "[BBL/day]"; unitText = "[BBL/day]";
break; break;
default: default:
@ -1105,9 +1122,9 @@ QString RimWellPlotTools::curveUnitText( RimWellLogLasFile::WellFlowCondition co
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
RimWellPlotTools::calculateRelevantTimeStepsFromCases( const QString& wellPathNameOrSimWellName, calculateRelevantTimeStepsFromCases( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources, const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults ) const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults )
{ {
bool addFirstTimestep = ( interestingRFTResults.count( RifEclipseRftAddress::RftWellLogChannelType::PRESSURE ) == 1 ); 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() ) if ( source.sourceType() == RifDataSourceForRftPlt::SourceType::GRID_MODEL_CELL_DATA && source.eclCase() )
{ {
std::set<QDateTime> wellTimeSteps = std::set<QDateTime> wellTimeSteps = availableSimWellTimesteps( source.eclCase(), simWellName, addFirstTimestep );
RimWellPlotTools::availableSimWellTimesteps( source.eclCase(), simWellName, addFirstTimestep );
for ( const QDateTime& date : wellTimeSteps ) for ( const QDateTime& date : wellTimeSteps )
{ {
@ -1246,7 +1262,7 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
{ {
if ( source.sourceType() == RifDataSourceForRftPlt::SourceType::ENSEMBLE_RFT && source.ensemble() ) 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 ) for ( const QDateTime& date : wellTimeSteps )
{ {
@ -1302,12 +1318,10 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
for ( const auto& dateSourceSetPair : ensembleTimeStepsWithSources ) for ( const auto& dateSourceSetPair : ensembleTimeStepsWithSources )
ensembleRftTimeSteps.insert( dateSourceSetPair.first ); ensembleRftTimeSteps.insert( dateSourceSetPair.first );
std::set<QDateTime> filteredRftTimeSteps = RimWellPlotTools::findMatchingOrAdjacentTimeSteps( baseTimeSteps, rftTimeSteps ); std::set<QDateTime> filteredRftTimeSteps = findMatchingOrAdjacentTimeSteps( baseTimeSteps, rftTimeSteps );
std::set<QDateTime> filteredGridTimeSteps = RimWellPlotTools::findMatchingOrAdjacentTimeSteps( baseTimeSteps, gridTimeSteps ); std::set<QDateTime> filteredGridTimeSteps = findMatchingOrAdjacentTimeSteps( baseTimeSteps, gridTimeSteps );
std::set<QDateTime> filteredEnsembleRftTimeSteps = std::set<QDateTime> filteredEnsembleRftTimeSteps = findMatchingOrAdjacentTimeSteps( baseTimeSteps, ensembleRftTimeSteps );
RimWellPlotTools::findMatchingOrAdjacentTimeSteps( baseTimeSteps, ensembleRftTimeSteps ); std::set<QDateTime> filteredSummaryRftTimeSteps = findMatchingOrAdjacentTimeSteps( baseTimeSteps, summaryRftTimeSteps );
std::set<QDateTime> filteredSummaryRftTimeSteps =
RimWellPlotTools::findMatchingOrAdjacentTimeSteps( baseTimeSteps, summaryRftTimeSteps );
if ( addFirstTimestep && !gridTimeSteps.empty() ) if ( addFirstTimestep && !gridTimeSteps.empty() )
{ {
@ -1364,10 +1378,10 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimWellPlotTools::calculateValueOptionsForTimeSteps( const QString& wellPathNameOrSimWellName, void calculateValueOptionsForTimeSteps( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources, const std::vector<RifDataSourceForRftPlt>& selSources,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults, const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults,
QList<caf::PdmOptionItemInfo>& options ) QList<caf::PdmOptionItemInfo>& options )
{ {
auto timestepsToShowWithSources = calculateRelevantTimeStepsFromCases( wellPathNameOrSimWellName, selSources, interestingRFTResults ); auto timestepsToShowWithSources = calculateRelevantTimeStepsFromCases( wellPathNameOrSimWellName, selSources, interestingRFTResults );
@ -1424,3 +1438,5 @@ void RimWellPlotTools::calculateValueOptionsForTimeSteps( const QString&
options.push_back( caf::PdmOptionItemInfo( optionText, timeStepPair.first ) ); options.push_back( caf::PdmOptionItemInfo( optionText, timeStepPair.first ) );
} }
} }
} // namespace RimWellPlotTools

View File

@ -21,13 +21,10 @@
#include "RiaDefines.h" #include "RiaDefines.h"
#include "RiaRftPltCurveDefinition.h" #include "RiaRftPltCurveDefinition.h"
#include "RifDataSourceForRftPltQMetaType.h"
#include "RifEclipseRftAddress.h" #include "RifEclipseRftAddress.h"
#include "RimWellLogLasFile.h" #include "RimWellLogLasFile.h"
#include <QMetaType>
#include <map> #include <map>
#include <set> #include <set>
@ -45,15 +42,15 @@ class RigEclipseCaseData;
class RigEclipseResultAddress; class RigEclipseResultAddress;
class RifReaderRftInterface; class RifReaderRftInterface;
//================================================================================================== namespace RimWellPlotTools
/// {
//==================================================================================================
enum FlowType enum class FlowType
{ {
FLOW_TYPE_PHASE_SPLIT, FLOW_TYPE_PHASE_SPLIT,
FLOW_TYPE_TOTAL FLOW_TYPE_TOTAL
}; };
enum FlowPhase enum class FlowPhase
{ {
FLOW_PHASE_NONE, FLOW_PHASE_NONE,
FLOW_PHASE_OIL, FLOW_PHASE_OIL,
@ -62,100 +59,61 @@ enum FlowPhase
FLOW_PHASE_TOTAL FLOW_PHASE_TOTAL
}; };
//================================================================================================== bool isOilFlowChannel( const QString& channelName );
/// bool isGasFlowChannel( const QString& channelName );
//================================================================================================== bool isWaterFlowChannel( const QString& channelName );
class RimWellPlotTools bool isTotalFlowChannel( const QString& channelName );
{ FlowPhase flowPhaseFromChannelName( const QString& channelName );
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 );
static std::vector<RimWellLogFile*> wellLogFilesContainingFlow( const QString& wellName ); std::vector<RimWellLogFile*> wellLogFilesContainingFlow( const QString& wellName );
static RimWellPath* wellPathByWellPathNameOrSimWellName( const QString& wellPathNameOrSimwellName ); RimWellPath* wellPathByWellPathNameOrSimWellName( const QString& wellPathNameOrSimwellName );
static std::vector<RimWellPath*> wellPathsContainingFlow(); std::vector<RimWellPath*> wellPathsContainingFlow();
// RFT Only void addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& destMap,
private: const std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepsToAdd );
static std::pair<RigEclipseResultAddress, QString> pressureResultDataInfo( const RigEclipseCaseData* eclipseCaseData ); 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: bool hasFlowData( const RimWellLog* wellLog );
static void addTimeStepsToMap( std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& destMap, bool hasAssociatedWellPath( const QString& wellName );
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 );
// others std::vector<RimEclipseResultCase*> gridCasesForWell( const QString& simWellName );
static bool hasFlowData( const RimWellLog* wellLog ); std::vector<RimEclipseResultCase*> rftCasesForWell( const QString& simWellName );
static bool hasAssociatedWellPath( const QString& wellName ); 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 std::map<QDateTime, std::set<RifDataSourceForRftPlt>>
static std::vector<RimEclipseResultCase*> gridCasesForWell( const QString& simWellName ); calculateRelevantTimeStepsFromCases( const QString& wellPathNameOrSimWellName,
static std::vector<RimEclipseResultCase*> rftCasesForWell( const QString& simWellName ); const std::vector<RifDataSourceForRftPlt>& selSources,
static std::vector<RimSummaryCaseCollection*> rftEnsemblesForWell( const QString& simWellName ); const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults );
static std::vector<RimSummaryCaseCollection*> rftEnsembles();
static std::vector<RimObservedFmuRftData*> observedFmuRftDataForWell( const QString& simWellName );
static std::vector<RimObservedFmuRftData*> observedFmuRftData();
static QString simWellName( const QString& wellPathNameOrSimWellName );
static std::map<QDateTime, std::set<RifDataSourceForRftPlt>> void calculateValueOptionsForTimeSteps( const QString& wellPathNameOrSimWellName,
calculateRelevantTimeStepsFromCases( const QString& wellPathNameOrSimWellName, const std::vector<RifDataSourceForRftPlt>& selSources,
const std::vector<RifDataSourceForRftPlt>& selSources, const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults ); QList<caf::PdmOptionItemInfo>& options );
static void calculateValueOptionsForTimeSteps( const QString& wellPathNameOrSimWellName, std::set<RiaRftPltCurveDefinition> curveDefsFromTimesteps( const QString& wellPathNameOrSimWellName,
const std::vector<RifDataSourceForRftPlt>& selSources, const std::vector<QDateTime>& selectedTimeStepVector,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults, bool firstReportTimeStepIsValid,
QList<caf::PdmOptionItemInfo>& options ); const std::vector<RifDataSourceForRftPlt>& selectedSourcesExpanded,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults );
static std::set<RiaRftPltCurveDefinition> QString flowPlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
curveDefsFromTimesteps( const QString& wellPathNameOrSimWellName, QString flowUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
const std::vector<QDateTime>& selectedTimeStepVector, QString flowVolumePlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
bool firstReportTimeStepIsValid, QString flowVolumeUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem );
const std::vector<RifDataSourceForRftPlt>& selectedSourcesExpanded,
const std::set<RifEclipseRftAddress::RftWellLogChannelType>& interestingRFTResults );
static QString flowPlotAxisTitle( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem ); QString curveUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem, FlowPhase flowPhase );
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 );
static QString bool hasFlowData( const RimWellPath* wellPath );
curveUnitText( RimWellLogLasFile::WellFlowCondition condition, RiaDefines::EclipseUnitSystem unitSystem, FlowPhase flowPhase );
static bool hasFlowData( const RimWellPath* wellPath ); std::vector<RimPressureDepthData*> pressureDepthData();
std::vector<RimPressureDepthData*> pressureDepthDataForWell( const QString& simWellName );
static std::vector<RimPressureDepthData*> pressureDepthData(); }; // namespace RimWellPlotTools
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 );
};

View File

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

View File

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

View File

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

View File

@ -24,7 +24,6 @@
#include "RiaStatisticsTools.h" #include "RiaStatisticsTools.h"
#include "RiaSummaryAddressAnalyzer.h" #include "RiaSummaryAddressAnalyzer.h"
#include "RifReaderRftInterface.h"
#include "RifSummaryReaderInterface.h" #include "RifSummaryReaderInterface.h"
#include "RimDerivedEnsembleCaseCollection.h" #include "RimDerivedEnsembleCaseCollection.h"
@ -32,6 +31,7 @@
#include "RimProject.h" #include "RimProject.h"
#include "RimSummaryAddressCollection.h" #include "RimSummaryAddressCollection.h"
#include "RimSummaryCase.h" #include "RimSummaryCase.h"
#include "RimSummaryEnsembleTools.h"
#include "cafPdmFieldScriptingCapability.h" #include "cafPdmFieldScriptingCapability.h"
#include "cafPdmObjectScriptingCapability.h" #include "cafPdmObjectScriptingCapability.h"
@ -43,56 +43,6 @@
CAF_PDM_SOURCE_INIT( RimSummaryCaseCollection, "SummaryCaseSubCollection" ); 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; 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() ) if ( m_cachedSortedEnsembleParameters.empty() )
{ {
std::set<QString> paramSet; m_cachedSortedEnsembleParameters = RimSummaryEnsembleTools::createVariationSortedEnsembleParameters( allSummaryCases() );
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 );
} }
if ( !excludeNoVariation ) if ( !excludeNoVariation )
{ {
return m_cachedSortedEnsembleParameters; return m_cachedSortedEnsembleParameters;
} }
else
const double epsilon = 1e-9;
std::vector<RigEnsembleParameter> parametersWithVariation;
for ( const auto& p : m_cachedSortedEnsembleParameters )
{ {
const double epsilon = 1e-9; if ( std::abs( p.normalizedStdDeviation() ) > epsilon )
std::vector<RigEnsembleParameter> parametersWithVariation;
for ( const auto& p : m_cachedSortedEnsembleParameters )
{ {
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]; 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 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 : variationSortedEnsembleParameters() )
for ( const RigEnsembleParameter& ensParam : ensembleParams )
{ {
if ( ensParam.name == paramName ) return ensParam; if ( ensParam.name == paramName ) return ensParam;
} }
return RigEnsembleParameter(); return {};
}
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;
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -740,72 +508,7 @@ RigEnsembleParameter RimSummaryCaseCollection::createEnsembleParameter( const QS
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
void RimSummaryCaseCollection::calculateEnsembleParametersIntersectionHash() void RimSummaryCaseCollection::calculateEnsembleParametersIntersectionHash()
{ {
clearEnsembleParametersHashes(); m_commonAddressCount = RimSummaryEnsembleTools::calculateEnsembleParametersIntersectionHash( allSummaryCases() );
// 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();
}
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -997,8 +700,9 @@ std::pair<double, double> RimSummaryCaseCollection::minMax( const RifEclipseSumm
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString RimSummaryCaseCollection::nameAndItemCount() const QString RimSummaryCaseCollection::nameAndItemCount() const
{ {
size_t itemCount = m_cases.size(); size_t itemCount = m_cases.size();
if ( itemCount > 20 ) const size_t itemCountThreshold = 20;
if ( itemCount > itemCountThreshold )
{ {
return QString( "%1 (%2)" ).arg( m_name() ).arg( itemCount ); 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<RifEclipseSummaryAddress> ensembleSummaryAddresses() const;
virtual std::set<time_t> ensembleTimeSteps() const; virtual std::set<time_t> ensembleTimeSteps() const;
std::set<QString> wellsWithRftData() const; void setEnsembleId( int ensembleId );
std::set<QDateTime> rftTimeStepsForWell( const QString& wellName ) const; int ensembleId() const;
void setEnsembleId( int ensembleId ); bool hasEnsembleParameters() const;
int ensembleId() const;
bool hasEnsembleParameters() const;
std::vector<RigEnsembleParameter> variationSortedEnsembleParameters( bool excludeNoVariation = false ) const; std::vector<RigEnsembleParameter> variationSortedEnsembleParameters( bool excludeNoVariation = false ) const;
std::vector<std::pair<RigEnsembleParameter, double>> correlationSortedEnsembleParameters( const RifEclipseSummaryAddress& address ) const; std::vector<std::pair<RigEnsembleParameter, double>> correlationSortedEnsembleParameters( const RifEclipseSummaryAddress& address ) const;
@ -87,11 +85,8 @@ public:
std::vector<std::pair<RigEnsembleParameter, double>> std::vector<std::pair<RigEnsembleParameter, double>>
parameterCorrelationsAllTimeSteps( const RifEclipseSummaryAddress& address, const std::vector<QString>& selectedParameters = {} ) const; parameterCorrelationsAllTimeSteps( const RifEclipseSummaryAddress& address, const std::vector<QString>& selectedParameters = {} ) const;
std::vector<RigEnsembleParameter> alphabeticEnsembleParameters() const;
RigEnsembleParameter ensembleParameter( const QString& paramName ) const; RigEnsembleParameter ensembleParameter( const QString& paramName ) const;
void calculateEnsembleParametersIntersectionHash(); void calculateEnsembleParametersIntersectionHash();
void clearEnsembleParametersHashes();
void loadDataAndUpdate(); void loadDataAndUpdate();
@ -111,10 +106,6 @@ public:
std::pair<double, double> minMax( const RifEclipseSummaryAddress& address ); std::pair<double, double> minMax( const RifEclipseSummaryAddress& address );
private: private:
RigEnsembleParameter createEnsembleParameter( const QString& paramName ) const;
static void sortByBinnedVariation( std::vector<RigEnsembleParameter>& parameterVector );
friend class RimSummaryCaseCollection_TESTER;
caf::PdmFieldHandle* userDescriptionField() override; caf::PdmFieldHandle* userDescriptionField() override;
QString nameAndItemCount() const; QString nameAndItemCount() const;
void updateIcon(); 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 "gtest/gtest.h"
#include "RigEnsembleParameter.h" #include "RigEnsembleParameter.h"
#include "RimSummaryCaseCollection.h" #include "RimSummaryEnsembleTools.h"
#include <random> #include <random>
#include <QDebug>
class RimSummaryCaseCollection_TESTER class RimSummaryCaseCollection_TESTER
{ {
public: public:
@ -74,7 +72,7 @@ void RimSummaryCaseCollection_TESTER::test1()
} }
size_t previousSize = parameters.size(); size_t previousSize = parameters.size();
RimSummaryCaseCollection::sortByBinnedVariation( parameters ); RimSummaryEnsembleTools::sortByBinnedVariation( parameters );
size_t currentSize = parameters.size(); size_t currentSize = parameters.size();
EXPECT_EQ( previousSize, currentSize ); EXPECT_EQ( previousSize, currentSize );