From 65f1f0b009fa95d16bd1efc1632b6cfcda6121bf Mon Sep 17 00:00:00 2001 From: Jon Jenssen Date: Tue, 17 Dec 2024 19:35:51 +0100 Subject: [PATCH] Work in progress --- .../RimEclipseStatisticsCase.cpp | 9 +- .../RimEclipseStatisticsCase.h | 2 + .../RimStatisticsContourMap.cpp | 148 ++++++++++++------ .../RimStatisticsContourMap.h | 14 +- .../RimStatisticsContourMapProjection.cpp | 5 +- .../RimStatisticsContourMapView.cpp | 29 ++++ .../RimStatisticsContourMapView.h | 3 + 7 files changed, 150 insertions(+), 60 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp index fcb48f1f76..cf6fce3dc7 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.cpp @@ -561,7 +561,10 @@ void RimEclipseStatisticsCase::defineUiOrdering( QString uiConfigName, caf::PdmU uiOrdering.skipRemainingFields(); } -QList toOptionList( const QStringList& varList ) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList RimEclipseStatisticsCase::toOptionList( const QStringList& varList ) { QList optionList; int i; @@ -904,9 +907,7 @@ void RimEclipseStatisticsCase::updateSelectionListVisibilities() { bool isLocked = hasComputedStatistics(); m_resultType.uiCapability()->setUiHidden( isLocked ); - m_porosityModel.uiCapability()->setUiHidden( - isLocked ); // || - // !caseGroup()->mainCase()->reservoirData()->results(RiaDefines::FRACTURE_MODEL)->resultCount() + m_porosityModel.uiCapability()->setUiHidden( isLocked ); m_selectedDynamicProperties.uiCapability()->setUiHidden( isLocked || m_porosityModel() != RiaDefines::PorosityModelType::MATRIX_MODEL || m_resultType() != RiaDefines::ResultCatType::DYNAMIC_NATIVE ); diff --git a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h index f7c2fa04a3..2f518f749d 100644 --- a/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h +++ b/ApplicationLibCode/ProjectDataModel/RimEclipseStatisticsCase.h @@ -106,6 +106,8 @@ private: void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override; void initializeSelectedTimeSteps(); + static QList toOptionList( const QStringList& varList ); + private: caf::PdmField> m_dataSourceForStatistics; diff --git a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.cpp b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.cpp index 64583e3fb2..7e0d73d8be 100644 --- a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.cpp @@ -43,6 +43,7 @@ #include "cafCmdFeatureMenuBuilder.h" #include "cafPdmUiDoubleSliderEditor.h" #include "cafPdmUiPushButtonEditor.h" +#include "cafPdmUiTreeSelectionEditor.h" #include "cafProgressInfo.h" #include @@ -79,7 +80,8 @@ RimStatisticsContourMap::RimStatisticsContourMap() CAF_PDM_InitFieldNoDefault( &m_resultAggregation, "ResultAggregation", "Result Aggregation" ); - CAF_PDM_InitField( &m_timeStep, "TimeStep", 0, "Time Step" ); + CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "SelectedTimeSteps", "Time Step Selection" ); + m_selectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() ); CAF_PDM_InitFieldNoDefault( &m_resultDefinition, "ResultDefinition", "" ); m_resultDefinition.uiCapability()->setUiTreeChildrenHidden( true ); @@ -104,7 +106,13 @@ void RimStatisticsContourMap::defineUiOrdering( QString uiConfigName, caf::PdmUi { uiOrdering.add( nameField() ); uiOrdering.add( &m_resultAggregation ); - uiOrdering.add( &m_timeStep ); + + { + auto group = uiOrdering.addNewGroup( "Time Step Selection" ); + group->setCollapsedByDefault(); + group->add( &m_selectedTimeSteps ); + } + uiOrdering.add( &m_relativeSampleSpacing ); uiOrdering.add( &m_boundingBoxExpPercent ); @@ -150,14 +158,23 @@ QList RimStatisticsContourMap::calculateValueOptions( co { QList options; - if ( fieldNeedingOptions == &m_timeStep ) + auto eCase = m_resultDefinition->eclipseCase(); + + if ( eCase == nullptr ) return options; + + if ( &m_selectedTimeSteps == fieldNeedingOptions ) { - auto ensemble = firstAncestorOrThisOfType(); - if ( ensemble && !ensemble->cases().empty() ) + QList options; + + const auto timeStepStrings = eCase->timeStepStrings(); + + int index = 0; + for ( const auto& text : timeStepStrings ) { - RimEclipseCase* firstEclipseCase = ensemble->cases().front(); - RimTools::timeStepsForCase( firstEclipseCase, &options ); + options.push_back( caf::PdmOptionItemInfo( text, index++ ) ); } + + return options; } return options; @@ -252,7 +269,10 @@ void RimStatisticsContourMap::computeStatistics() caf::ProgressInfo progInfo( ensemble->cases().size() + 1, "Reading Eclipse Ensemble" ); - std::vector> results; + // std::vector> results; + + std::map>> timestep_results; + for ( RimEclipseCase* eclipseCase : ensemble->cases() ) { if ( eclipseCase->ensureReservoirCaseIsOpen() ) @@ -265,57 +285,76 @@ void RimStatisticsContourMap::computeStatistics() RigEclipseContourMapProjection contourMapProjection( *contourMapGrid, *eclipseCaseData, *resultData ); contourMapProjection.generateGridMapping( resultAggregation, {} ); - std::vector result = - contourMapProjection.generateResults( m_resultDefinition()->eclipseResultAddress(), resultAggregation, m_timeStep() ); - results.push_back( result ); + if ( m_resultDefinition()->hasDynamicResult() ) + { + for ( auto ts : m_selectedTimeSteps() ) + { + std::vector result = + contourMapProjection.generateResults( m_resultDefinition()->eclipseResultAddress(), resultAggregation, ts ); + timestep_results[ts].push_back( result ); + } + } + else + { + std::vector result = + contourMapProjection.generateResults( m_resultDefinition()->eclipseResultAddress(), resultAggregation, 0 ); + timestep_results[0].push_back( result ); + } } progInfo.incrementProgress(); } - if ( !results.empty() ) + m_contourMapGrid = std::move( contourMapGrid ); + m_timeResults.clear(); + + for ( auto [timeStep, results] : timestep_results ) { - int nCells = static_cast( results[0].size() ); - std::vector p10Results( nCells, std::numeric_limits::infinity() ); - std::vector p50Results( nCells, std::numeric_limits::infinity() ); - std::vector p90Results( nCells, std::numeric_limits::infinity() ); - std::vector meanResults( nCells, std::numeric_limits::infinity() ); - std::vector minResults( nCells, std::numeric_limits::infinity() ); - std::vector maxResults( nCells, std::numeric_limits::infinity() ); + if ( !results.empty() ) + { + int nCells = static_cast( results[0].size() ); + std::vector p10Results( nCells, std::numeric_limits::infinity() ); + std::vector p50Results( nCells, std::numeric_limits::infinity() ); + std::vector p90Results( nCells, std::numeric_limits::infinity() ); + std::vector meanResults( nCells, std::numeric_limits::infinity() ); + std::vector minResults( nCells, std::numeric_limits::infinity() ); + std::vector maxResults( nCells, std::numeric_limits::infinity() ); #pragma omp parallel for - for ( int i = 0; i < nCells; i++ ) - { - size_t numSamples = results.size(); - std::vector samples( numSamples, 0.0 ); - for ( size_t s = 0; s < numSamples; s++ ) - samples[s] = results[s][i]; + for ( int i = 0; i < nCells; i++ ) + { + size_t numSamples = results.size(); + std::vector samples( numSamples, 0.0 ); + for ( size_t s = 0; s < numSamples; s++ ) + samples[s] = results[s][i]; - double p10 = std::numeric_limits::infinity(); - double p50 = std::numeric_limits::infinity(); - double p90 = std::numeric_limits::infinity(); - double mean = std::numeric_limits::infinity(); + double p10 = std::numeric_limits::infinity(); + double p50 = std::numeric_limits::infinity(); + double p90 = std::numeric_limits::infinity(); + double mean = std::numeric_limits::infinity(); - RigStatisticsMath::calculateStatisticsCurves( samples, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED ); + RigStatisticsMath::calculateStatisticsCurves( samples, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED ); - if ( RiaStatisticsTools::isValidNumber( p10 ) ) p10Results[i] = p10; - if ( RiaStatisticsTools::isValidNumber( p50 ) ) p50Results[i] = p50; - if ( RiaStatisticsTools::isValidNumber( p90 ) ) p90Results[i] = p90; - if ( RiaStatisticsTools::isValidNumber( mean ) ) meanResults[i] = mean; + if ( RiaStatisticsTools::isValidNumber( p10 ) ) p10Results[i] = p10; + if ( RiaStatisticsTools::isValidNumber( p50 ) ) p50Results[i] = p50; + if ( RiaStatisticsTools::isValidNumber( p90 ) ) p90Results[i] = p90; + if ( RiaStatisticsTools::isValidNumber( mean ) ) meanResults[i] = mean; - double minValue = RiaStatisticsTools::minimumValue( samples ); - if ( RiaStatisticsTools::isValidNumber( minValue ) && minValue < std::numeric_limits::max() ) minResults[i] = minValue; + double minValue = RiaStatisticsTools::minimumValue( samples ); + if ( RiaStatisticsTools::isValidNumber( minValue ) && minValue < std::numeric_limits::max() ) + minResults[i] = minValue; - double maxValue = RiaStatisticsTools::maximumValue( samples ); - if ( RiaStatisticsTools::isValidNumber( maxValue ) && maxValue > -std::numeric_limits::max() ) maxResults[i] = maxValue; + double maxValue = RiaStatisticsTools::maximumValue( samples ); + if ( RiaStatisticsTools::isValidNumber( maxValue ) && maxValue > -std::numeric_limits::max() ) + maxResults[i] = maxValue; + } + + m_timeResults[timeStep][StatisticsType::P10] = p10Results; + m_timeResults[timeStep][StatisticsType::P50] = p50Results; + m_timeResults[timeStep][StatisticsType::P90] = p90Results; + m_timeResults[timeStep][StatisticsType::MEAN] = meanResults; + m_timeResults[timeStep][StatisticsType::MIN] = minResults; + m_timeResults[timeStep][StatisticsType::MAX] = maxResults; } - - m_contourMapGrid = std::move( contourMapGrid ); - m_result[StatisticsType::P10] = p10Results; - m_result[StatisticsType::P50] = p50Results; - m_result[StatisticsType::P90] = p90Results; - m_result[StatisticsType::MEAN] = meanResults; - m_result[StatisticsType::MIN] = minResults; - m_result[StatisticsType::MAX] = maxResults; } } @@ -349,10 +388,21 @@ RigContourMapGrid* RimStatisticsContourMap::contourMapGrid() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimStatisticsContourMap::result( StatisticsType statisticsType ) const +int RimStatisticsContourMap::maxTimeStepCount() const { - if ( auto it = m_result.find( statisticsType ); it != m_result.end() ) return it->second; - return {}; + return m_selectedTimeSteps().size(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimStatisticsContourMap::result( size_t timeStep, StatisticsType statisticsType ) const +{ + if ( !m_timeResults.contains( timeStep ) ) return {}; + + if ( !m_timeResults.at( timeStep ).contains( statisticsType ) ) return {}; + + return m_timeResults.at( timeStep ).at( statisticsType ); } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.h b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.h index fb5c99aff7..3775c55116 100644 --- a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.h +++ b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMap.h @@ -60,7 +60,7 @@ public: RimEclipseCaseEnsemble* ensemble() const; RigContourMapGrid* contourMapGrid() const; - std::vector result( StatisticsType statisticsType ) const; + std::vector result( size_t timeStep, StatisticsType statisticsType ) const; void addView( RimStatisticsContourMapView* view ); @@ -73,6 +73,8 @@ public: double sampleSpacingFactor() const; bool isColumnResult() const; + int maxTimeStepCount() const; + protected: void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; @@ -84,16 +86,18 @@ protected: private: void computeStatistics(); + caf::PdmField m_boundingBoxExpPercent; caf::PdmField m_relativeSampleSpacing; caf::PdmField m_resultAggregation; - caf::PdmField m_timeStep; - caf::PdmField m_boundingBoxExpPercent; + caf::PdmField> m_selectedTimeSteps; caf::PdmChildField m_resultDefinition; caf::PdmField m_computeStatisticsButton; - std::unique_ptr m_contourMapGrid; - std::map> m_result; + std::unique_ptr m_contourMapGrid; + // std::map> m_result; + std::map>> m_timeResults; + std::vector>> m_gridMapping; caf::PdmChildArrayField m_views; diff --git a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapProjection.cpp b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapProjection.cpp index bb72331264..0dd8f26151 100644 --- a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapProjection.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapProjection.cpp @@ -165,7 +165,7 @@ void RimStatisticsContourMapProjection::generateAndSaveResults( int timeStep ) if ( auto statistics = statisticsContourMap() ) { dynamic_cast( m_contourMapProjection.get() ) - ->generateAndSaveResults( statistics->result( m_statisticsType() ) ); + ->generateAndSaveResults( statistics->result( timeStep, m_statisticsType() ) ); } } @@ -260,7 +260,8 @@ std::pair RimStatisticsContourMapProjection::minmaxValuesAllTime { clearTimeStepRange(); - std::vector aggregatedResults = statisticsContourMap()->result( m_statisticsType() ); + // TODO - step through all time steps here! + std::vector aggregatedResults = statisticsContourMap()->result( 0, m_statisticsType() ); m_minResultAllTimeSteps = RigContourMapProjection::minValue( aggregatedResults ); m_maxResultAllTimeSteps = RigContourMapProjection::maxValue( aggregatedResults ); } diff --git a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapView.cpp b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapView.cpp index 937008cb3a..51311b0f06 100644 --- a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapView.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapView.cpp @@ -210,3 +210,32 @@ RimStatisticsContourMap* RimStatisticsContourMapView::statisticsContourMap() con { return m_statisticsContourMap; } + +//-------------------------------------------------------------------------------------------------- +/// Clamp the current timestep to actual possibilities +//-------------------------------------------------------------------------------------------------- +void RimStatisticsContourMapView::onClampCurrentTimestep() +{ + if ( statisticsContourMap() ) + { + if ( m_currentTimeStep() >= statisticsContourMap()->maxTimeStepCount() ) + { + m_currentTimeStep = statisticsContourMap()->maxTimeStepCount() - 1; + } + } + + if ( m_currentTimeStep < 0 ) m_currentTimeStep = 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +size_t RimStatisticsContourMapView::onTimeStepCountRequested() +{ + if ( statisticsContourMap() ) + { + return (size_t)statisticsContourMap()->maxTimeStepCount(); + } + + return 0; +} diff --git a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapView.h b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapView.h index 511d71327a..0199c1c852 100644 --- a/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapView.h +++ b/ApplicationLibCode/ProjectDataModel/RimStatisticsContourMapView.h @@ -39,6 +39,9 @@ protected: void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override; void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override; + void onClampCurrentTimestep() override; + size_t onTimeStepCountRequested() override; + // void createContourMapGeometry(); void onUpdateLegends() override;