From 7f35fb23c4694d850d8fa9e931d4958b0c26d557 Mon Sep 17 00:00:00 2001 From: Kristian Bendiksen Date: Fri, 9 Apr 2021 18:56:57 +0200 Subject: [PATCH] #7561 Ensemble Fracture Statistics: Select subset of statistics to compute. --- .../RimEnsembleFractureStatistics.cpp | 136 ++++++++++++++---- .../RimEnsembleFractureStatistics.h | 8 +- 2 files changed, 112 insertions(+), 32 deletions(-) diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimEnsembleFractureStatistics.cpp b/ApplicationLibCode/ProjectDataModel/Completions/RimEnsembleFractureStatistics.cpp index e8f31a7f4f..833f96eb87 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimEnsembleFractureStatistics.cpp +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimEnsembleFractureStatistics.cpp @@ -36,6 +36,7 @@ #include "cafAppEnum.h" #include "cafPdmUiTextEditor.h" #include "cafPdmUiToolButtonEditor.h" +#include "cafPdmUiTreeSelectionEditor.h" #include @@ -76,13 +77,20 @@ RimEnsembleFractureStatistics::RimEnsembleFractureStatistics() m_filePathsTable.uiCapability()->setUiReadOnly( true ); m_filePathsTable.xmlCapability()->disableIO(); + CAF_PDM_InitField( &m_numSamplesX, "NumberOfSamplesX", 100, "X", "", "", "" ); + CAF_PDM_InitField( &m_numSamplesY, "NumberOfSamplesY", 200, "Y", "", "", "" ); + + std::vector> defaultStatisticsTypes = { + caf::AppEnum( RimEnsembleFractureStatistics::StatisticsType::MEAN ) }; + + CAF_PDM_InitField( &m_selectedStatisticsType, "SelectedStatisticsType", defaultStatisticsTypes, "Statistics Type", "", "", "" ); + m_selectedStatisticsType.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() ); + m_selectedStatisticsType.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP ); + CAF_PDM_InitFieldNoDefault( &m_computeStatistics, "ComputeStatistics", "Compute", "", "", "" ); m_computeStatistics.uiCapability()->setUiEditorTypeName( caf::PdmUiToolButtonEditor::uiEditorTypeName() ); m_computeStatistics.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); - CAF_PDM_InitField( &m_numSamplesX, "NumberOfSamplesX", 100, "X", "", "", "" ); - CAF_PDM_InitField( &m_numSamplesY, "NumberOfSamplesY", 200, "Y", "", "", "" ); - setDeletable( true ); } @@ -116,6 +124,29 @@ QString RimEnsembleFractureStatistics::generateFilePathsTable() return body; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QList + RimEnsembleFractureStatistics::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly ) +{ + QList options; + if ( fieldNeedingOptions == &m_selectedStatisticsType ) + { + for ( size_t i = 0; i < caf::AppEnum::size(); ++i ) + { + caf::AppEnum t = + caf::AppEnum::fromIndex( i ); + t.uiText(); + + options.push_back( caf::PdmOptionItemInfo( t.uiText(), t.value() ) ); + } + } + + return options; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -132,6 +163,16 @@ void RimEnsembleFractureStatistics::defineEditorAttribute( const caf::PdmFieldHa myAttr->textMode = caf::PdmUiTextEditorAttribute::HTML; } } + else if ( field == &m_selectedStatisticsType ) + { + caf::PdmUiTreeSelectionEditorAttribute* attrib = dynamic_cast( attribute ); + if ( attrib ) + { + attrib->showTextFilter = false; + attrib->showToggleAllCheckbox = false; + attrib->singleSelectionMode = false; + } + } } //-------------------------------------------------------------------------------------------------- @@ -171,6 +212,8 @@ std::vector RimEnsembleFractureStatistics::computeStatistics() std::map, std::shared_ptr> statisticsGridsAll; + auto selectedStatistics = m_selectedStatisticsType.value(); + // TODO: take from an incoming xml? double timeStep = 1.0; @@ -223,7 +266,7 @@ std::vector RimEnsembleFractureStatistics::computeStatistics() sampleAllGrids( fractureGrids, samples, minX, minY, numSamplesX, numSamplesY, sampleDistanceX, sampleDistanceY ); std::map> statisticsGrids; - generateStatisticsGrids( samples, numSamplesX, numSamplesY, statisticsGrids ); + generateStatisticsGrids( samples, numSamplesX, numSamplesY, statisticsGrids, selectedStatistics ); for ( auto [statType, slice] : statisticsGrids ) { @@ -243,10 +286,8 @@ std::vector RimEnsembleFractureStatistics::computeStatistics() outputDirectory.mkpath( outputDirectoryPath ); } - for ( size_t i = 0; i < caf::AppEnum::size(); ++i ) + for ( auto t : selectedStatistics ) { - caf::AppEnum t = - caf::AppEnum::fromIndex( i ); QString text = t.text(); // Get the all the properties for this statistics type @@ -504,44 +545,77 @@ void RimEnsembleFractureStatistics::generateStatisticsGrids( const std::vector>& samples, int numSamplesX, int numSamplesY, - std::map>& statisticsGrids ) + std::map>& statisticsGrids, + const std::vector>& statisticsTypes ) { - for ( size_t i = 0; i < caf::AppEnum::size(); ++i ) + for ( auto t : statisticsTypes ) { std::shared_ptr grid = std::make_shared( numSamplesX, numSamplesY ); - - caf::AppEnum t = - caf::AppEnum::fromIndex( i ); - statisticsGrids[t.value()] = grid; + statisticsGrids[t.value()] = grid; } + auto isCalculationEnabled = []( StatisticsType t, auto statisticsTypes ) { + return std::find( statisticsTypes.begin(), statisticsTypes.end(), t ) != statisticsTypes.end(); + }; + + bool calculateMin = isCalculationEnabled( StatisticsType::MIN, statisticsTypes ); + bool calculateMax = isCalculationEnabled( StatisticsType::MAX, statisticsTypes ); + bool calculateMean = isCalculationEnabled( StatisticsType::MEAN, statisticsTypes ); + bool calculateP10 = isCalculationEnabled( StatisticsType::P10, statisticsTypes ); + bool calculateP50 = isCalculationEnabled( StatisticsType::P50, statisticsTypes ); + bool calculateP90 = isCalculationEnabled( StatisticsType::P90, statisticsTypes ); + bool calculateOccurrence = isCalculationEnabled( StatisticsType::OCCURRENCE, statisticsTypes ); + for ( int y = 0; y < numSamplesY; y++ ) { for ( int x = 0; x < numSamplesX; x++ ) { size_t idx = y * numSamplesX + x; - double min; - double max; - double sum; - double range; - double mean; - double dev; - RigStatisticsMath::calculateBasicStatistics( samples[idx], &min, &max, &sum, &range, &mean, &dev ); - statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::MEAN]->setValue( x, y, mean ); - statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::MIN]->setValue( x, y, min ); - statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::MAX]->setValue( x, y, max ); + if ( calculateMin || calculateMax || calculateMean ) + { + double min; + double max; + double sum; + double range; + double mean; + double dev; + RigStatisticsMath::calculateBasicStatistics( samples[idx], &min, &max, &sum, &range, &mean, &dev ); - double p10; - double p50; - double p90; - RigStatisticsMath::calculateStatisticsCurves( samples[idx], &p10, &p50, &p90, &mean ); + if ( calculateMean ) + statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::MEAN]->setValue( x, y, mean ); - statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::P10]->setValue( x, y, p10 ); - statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::P50]->setValue( x, y, p50 ); - statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::P90]->setValue( x, y, p90 ); + if ( calculateMin ) + statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::MIN]->setValue( x, y, min ); - statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::OCCURRENCE]->setValue( x, y, samples[idx].size() ); + if ( calculateMax ) + statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::MAX]->setValue( x, y, max ); + } + + if ( calculateP10 || calculateP50 || calculateP90 ) + { + double p10; + double p50; + double p90; + double mean; + RigStatisticsMath::calculateStatisticsCurves( samples[idx], &p10, &p50, &p90, &mean ); + + if ( calculateP10 ) + statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::P10]->setValue( x, y, p10 ); + + if ( calculateP50 ) + statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::P50]->setValue( x, y, p50 ); + + if ( calculateP90 ) + statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::P90]->setValue( x, y, p90 ); + } + + if ( calculateOccurrence ) + { + statisticsGrids[RimEnsembleFractureStatistics::StatisticsType::OCCURRENCE]->setValue( x, + y, + samples[idx].size() ); + } } } } diff --git a/ApplicationLibCode/ProjectDataModel/Completions/RimEnsembleFractureStatistics.h b/ApplicationLibCode/ProjectDataModel/Completions/RimEnsembleFractureStatistics.h index fbae5dd8b2..cbf8387c0f 100644 --- a/ApplicationLibCode/ProjectDataModel/Completions/RimEnsembleFractureStatistics.h +++ b/ApplicationLibCode/ProjectDataModel/Completions/RimEnsembleFractureStatistics.h @@ -56,6 +56,9 @@ protected: caf::PdmUiEditorAttribute* attribute ) override; void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override; + QList calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, + bool* useOptionsOnly ) override; + QString generateFilePathsTable(); std::vector computeStatistics(); @@ -90,7 +93,8 @@ protected: const std::vector>& samples, int numSamplesX, int numSamplesY, - std::map>& statisticsGrids ); + std::map>& statisticsGrids, + const std::vector>& statisticsTypes ); static bool writeStatisticsToCsv( const QString& filePath, const RigSlice2D& samples ); @@ -99,4 +103,6 @@ protected: caf::PdmField m_computeStatistics; caf::PdmField m_numSamplesX; caf::PdmField m_numSamplesY; + + caf::PdmField>> m_selectedStatisticsType; };