#7670 Show Ensemble Fracture Statistics as table

This commit is contained in:
Kristian Bendiksen 2021-05-10 17:40:44 +02:00 committed by Magne Sjaastad
parent 4b75dd4d6a
commit 7c7f319e41
4 changed files with 93 additions and 45 deletions

View File

@ -26,12 +26,15 @@
#include "RiaWeightedGeometricMeanCalculator.h" #include "RiaWeightedGeometricMeanCalculator.h"
#include "RiaWeightedHarmonicMeanCalculator.h" #include "RiaWeightedHarmonicMeanCalculator.h"
#include "RigEnsembleFractureStatisticsCalculator.h"
#include "RigFractureGrid.h" #include "RigFractureGrid.h"
#include "RigHistogramData.h"
#include "RigSlice2D.h" #include "RigSlice2D.h"
#include "RigStatisticsMath.h" #include "RigStatisticsMath.h"
#include "RigStimPlanFractureDefinition.h" #include "RigStimPlanFractureDefinition.h"
#include "RimFractureTemplateCollection.h" #include "RimFractureTemplateCollection.h"
#include "RimHistogramCalculator.h"
#include "RimProject.h" #include "RimProject.h"
#include "RimStimPlanFractureTemplate.h" #include "RimStimPlanFractureTemplate.h"
@ -122,11 +125,11 @@ RimEnsembleFractureStatistics::RimEnsembleFractureStatistics()
m_filePathsTable.uiCapability()->setUiReadOnly( true ); m_filePathsTable.uiCapability()->setUiReadOnly( true );
m_filePathsTable.xmlCapability()->disableIO(); m_filePathsTable.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_formationDipStatistics, "FormationDipStatistics", "Formation Dip Statistics", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_statisticsTable, "StatisticsTable", "Statistics Table", "", "", "" );
m_formationDipStatistics.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() ); m_statisticsTable.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
m_formationDipStatistics.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN ); m_statisticsTable.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
m_formationDipStatistics.uiCapability()->setUiReadOnly( true ); m_statisticsTable.uiCapability()->setUiReadOnly( true );
m_formationDipStatistics.xmlCapability()->disableIO(); m_statisticsTable.xmlCapability()->disableIO();
CAF_PDM_InitFieldNoDefault( &m_meshAlignmentType, "MeshAlignmentType", "Mesh Alignment", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_meshAlignmentType, "MeshAlignmentType", "Mesh Alignment", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_meshType, "MeshType", "Mesh Type", "", "", "" ); CAF_PDM_InitFieldNoDefault( &m_meshType, "MeshType", "Mesh Type", "", "", "" );
@ -167,7 +170,7 @@ RimEnsembleFractureStatistics::~RimEnsembleFractureStatistics()
void RimEnsembleFractureStatistics::addFilePath( const QString& filePath ) void RimEnsembleFractureStatistics::addFilePath( const QString& filePath )
{ {
m_filePaths.v().push_back( filePath ); m_filePaths.v().push_back( filePath );
m_filePathsTable = generateFilePathsTable(); loadAndUpdateData();
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -233,7 +236,7 @@ void RimEnsembleFractureStatistics::defineEditorAttribute( const caf::PdmFieldHa
attrib->singleSelectionMode = false; attrib->singleSelectionMode = false;
} }
} }
else if ( field == &m_formationDipStatistics ) else if ( field == &m_statisticsTable )
{ {
auto myAttr = dynamic_cast<caf::PdmUiTextEditorAttribute*>( attribute ); auto myAttr = dynamic_cast<caf::PdmUiTextEditorAttribute*>( attribute );
if ( myAttr ) if ( myAttr )
@ -301,7 +304,7 @@ void RimEnsembleFractureStatistics::defineUiOrdering( QString uiConfigName, caf:
settingsGroup->add( &m_computeStatistics ); settingsGroup->add( &m_computeStatistics );
caf::PdmUiOrdering* statisticsGroup = uiOrdering.addNewGroup( "Statistics" ); caf::PdmUiOrdering* statisticsGroup = uiOrdering.addNewGroup( "Statistics" );
statisticsGroup->add( &m_formationDipStatistics ); statisticsGroup->add( &m_statisticsTable );
uiOrdering.add( &m_filePathsTable ); uiOrdering.add( &m_filePathsTable );
} }
@ -318,7 +321,7 @@ void RimEnsembleFractureStatistics::loadAndUpdateData()
std::vector<cvf::ref<RigStimPlanFractureDefinition>> stimPlanFractureDefinitions = std::vector<cvf::ref<RigStimPlanFractureDefinition>> stimPlanFractureDefinitions =
readFractureDefinitions( m_filePaths.v(), unitSystem ); readFractureDefinitions( m_filePaths.v(), unitSystem );
m_formationDipStatistics = generateFormationDipStatisticsString( stimPlanFractureDefinitions ); m_statisticsTable = generateStatisticsTable( stimPlanFractureDefinitions );
} }
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
@ -1125,38 +1128,60 @@ void RimEnsembleFractureStatistics::generateStatisticsGrids(
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
QString RimEnsembleFractureStatistics::generateFormationDipStatisticsString( QString RimEnsembleFractureStatistics::generateStatisticsTable(
const std::vector<cvf::ref<RigStimPlanFractureDefinition>> stimPlanFractureDefinitions ) const std::vector<cvf::ref<RigStimPlanFractureDefinition>>& stimPlanFractureDefinitions ) const
{ {
std::vector<double> formationDips; std::vector<RigEnsembleFractureStatisticsCalculator::PropertyType> propertyTypes = {
for ( auto def : stimPlanFractureDefinitions ) RigEnsembleFractureStatisticsCalculator::PropertyType::HEIGHT,
{ RigEnsembleFractureStatisticsCalculator::PropertyType::AREA,
formationDips.push_back( def->formationDip() ); RigEnsembleFractureStatisticsCalculator::PropertyType::WIDTH,
} RigEnsembleFractureStatisticsCalculator::PropertyType::XF,
RigEnsembleFractureStatisticsCalculator::PropertyType::KFWF,
double min; RigEnsembleFractureStatisticsCalculator::PropertyType::PERMEABILITY,
double max; RigEnsembleFractureStatisticsCalculator::PropertyType::FORMATION_DIP,
double sum;
double range;
double mean;
double dev;
RigStatisticsMath::calculateBasicStatistics( formationDips, &min, &max, &sum, &range, &mean, &dev );
double p10;
double p50;
double p90;
RigStatisticsMath::calculateStatisticsCurves( formationDips, &p10, &p50, &p90, &mean );
auto appendTextIfValidValue = []( QString& body, const QString& title, double value ) {
if ( !std::isinf( value ) ) body += QString( "%1: %2<br>" ).arg( title ).arg( value );
}; };
QString text = "Formation Dip:<br>"; QString text;
appendTextIfValidValue( text, "Mean", mean ); text += "<table border=1><thead><tr bgcolor=lightblue>";
appendTextIfValidValue( text, "Minimum", min ); std::vector<QString> statisticsTypes = { "Name", "Mean", "Minimum", "Maximum", "P10", "P90" };
appendTextIfValidValue( text, "Maximum", max ); for ( auto statType : statisticsTypes )
appendTextIfValidValue( text, "P10", p10 ); {
appendTextIfValidValue( text, "P50", p50 ); text += QString( "<th>%1</th>" ).arg( statType );
appendTextIfValidValue( text, "P90", p90 ); }
text += "</thead>";
text += "<tbody>";
auto emptyTextOnInf = []( double value ) {
if ( std::isinf( value ) )
return QString( "" );
else
return QString::number( value );
};
for ( auto propertyType : propertyTypes )
{
QString name = caf::AppEnum<RigEnsembleFractureStatisticsCalculator::PropertyType>::uiText( propertyType );
RigHistogramData histogramData =
RigEnsembleFractureStatisticsCalculator::createStatisticsData( this, propertyType );
text += QString( "<tr>"
"<td>%1</td>"
"<td align=right>%2</td>"
"<td align=right>%3</td>"
"<td align=right>%4</td>"
"<td align=right>%5</td>"
"<td align=right>%6</td>"
"</tr>" )
.arg( name )
.arg( emptyTextOnInf( histogramData.mean ) )
.arg( emptyTextOnInf( histogramData.min ) )
.arg( emptyTextOnInf( histogramData.max ) )
.arg( emptyTextOnInf( histogramData.p10 ) )
.arg( emptyTextOnInf( histogramData.p90 ) );
}
text += "</tbody>";
text += "</table>";
return text; return text;
} }

View File

@ -189,12 +189,12 @@ protected:
static double linearSampling( double minValue, double maxValue, int numSamples, std::vector<double>& samples ); static double linearSampling( double minValue, double maxValue, int numSamples, std::vector<double>& samples );
static QString generateFormationDipStatisticsString( QString generateStatisticsTable(
const std::vector<cvf::ref<RigStimPlanFractureDefinition>> stimPlanFractureDefinitions ); const std::vector<cvf::ref<RigStimPlanFractureDefinition>>& stimPlanFractureDefinitions ) const;
caf::PdmField<std::vector<caf::FilePath>> m_filePaths; caf::PdmField<std::vector<caf::FilePath>> m_filePaths;
caf::PdmField<QString> m_filePathsTable; caf::PdmField<QString> m_filePathsTable;
caf::PdmField<QString> m_formationDipStatistics; caf::PdmField<QString> m_statisticsTable;
caf::PdmField<bool> m_computeStatistics; caf::PdmField<bool> m_computeStatistics;
caf::PdmField<int> m_numSamplesX; caf::PdmField<int> m_numSamplesX;
caf::PdmField<int> m_numSamplesY; caf::PdmField<int> m_numSamplesY;

View File

@ -49,6 +49,7 @@ void caf::AppEnum<RigEnsembleFractureStatisticsCalculator::PropertyType>::setUp(
addItem( RigEnsembleFractureStatisticsCalculator::PropertyType::XF, "XF", "Halflength (Xf)" ); addItem( RigEnsembleFractureStatisticsCalculator::PropertyType::XF, "XF", "Halflength (Xf)" );
addItem( RigEnsembleFractureStatisticsCalculator::PropertyType::KFWF, "KFWF", "Conductivity (KfWf)" ); addItem( RigEnsembleFractureStatisticsCalculator::PropertyType::KFWF, "KFWF", "Conductivity (KfWf)" );
addItem( RigEnsembleFractureStatisticsCalculator::PropertyType::PERMEABILITY, "PERMEABILITY", "Permeability" ); addItem( RigEnsembleFractureStatisticsCalculator::PropertyType::PERMEABILITY, "PERMEABILITY", "Permeability" );
addItem( RigEnsembleFractureStatisticsCalculator::PropertyType::FORMATION_DIP, "FORMATION_DIP", "Formation Dip" );
setDefault( RigEnsembleFractureStatisticsCalculator::PropertyType::HEIGHT ); setDefault( RigEnsembleFractureStatisticsCalculator::PropertyType::HEIGHT );
} }
}; // namespace caf }; // namespace caf
@ -56,7 +57,7 @@ void caf::AppEnum<RigEnsembleFractureStatisticsCalculator::PropertyType>::setUp(
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
RigHistogramData RigEnsembleFractureStatisticsCalculator::createStatisticsData( RimEnsembleFractureStatistics* esf, RigHistogramData RigEnsembleFractureStatisticsCalculator::createStatisticsData( const RimEnsembleFractureStatistics* esf,
PropertyType propertyType ) PropertyType propertyType )
{ {
std::vector<cvf::ref<RigStimPlanFractureDefinition>> defs = esf->readFractureDefinitions(); std::vector<cvf::ref<RigStimPlanFractureDefinition>> defs = esf->readFractureDefinitions();
@ -89,6 +90,10 @@ RigHistogramData RigEnsembleFractureStatisticsCalculator::createStatisticsData(
{ {
samples = calculateGridStatistics( defs, &RigEnsembleFractureStatisticsCalculator::calculateKfWf ); samples = calculateGridStatistics( defs, &RigEnsembleFractureStatisticsCalculator::calculateKfWf );
} }
else if ( propertyType == PropertyType::FORMATION_DIP )
{
samples = calculateFormationDip( defs );
}
RigHistogramData histogramData; RigHistogramData histogramData;
@ -327,6 +332,21 @@ double RigEnsembleFractureStatisticsCalculator::calculateXf( cvf::cref<RigFractu
return 0.0; return 0.0;
} }
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<double> RigEnsembleFractureStatisticsCalculator::calculateFormationDip(
const std::vector<cvf::ref<RigStimPlanFractureDefinition>>& defs )
{
std::vector<double> formationDips;
for ( auto def : defs )
{
formationDips.push_back( def->formationDip() );
}
return formationDips;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------
/// ///
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -45,10 +45,11 @@ public:
WIDTH, WIDTH,
XF, XF,
KFWF, KFWF,
PERMEABILITY PERMEABILITY,
FORMATION_DIP
}; };
static RigHistogramData createStatisticsData( RimEnsembleFractureStatistics* esf, PropertyType propertyType ); static RigHistogramData createStatisticsData( const RimEnsembleFractureStatistics* esf, PropertyType propertyType );
private: private:
static std::vector<double> calculateGridStatistics( const std::vector<cvf::ref<RigStimPlanFractureDefinition>>& defs, static std::vector<double> calculateGridStatistics( const std::vector<cvf::ref<RigStimPlanFractureDefinition>>& defs,
@ -61,6 +62,8 @@ private:
RiaDefines::EclipseUnitSystem, RiaDefines::EclipseUnitSystem,
const QString& ) ); const QString& ) );
static std::vector<double> calculateFormationDip( const std::vector<cvf::ref<RigStimPlanFractureDefinition>>& defs );
static double calculateHeight( cvf::cref<RigFractureGrid> fractureGrid ); static double calculateHeight( cvf::cref<RigFractureGrid> fractureGrid );
static double calculateArea( cvf::cref<RigFractureGrid> fractureGrid ); static double calculateArea( cvf::cref<RigFractureGrid> fractureGrid );
static double calculateXf( cvf::cref<RigFractureGrid> fractureGrid ); static double calculateXf( cvf::cref<RigFractureGrid> fractureGrid );