mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-27 05:37:21 -05:00
#12235 Correlation Plot: Add range filter for x and y values
Add range filter for x and y axis, and compute the correlation based on the values inside the range window. Show the excluded realizations as text.
This commit is contained in:
+23
-2
@@ -419,6 +419,11 @@ std::set<RimSummaryCase*> RimAbstractCorrelationPlot::filterEnsembleCases( RimSu
|
||||
setOfCases.insert( summaryCasesVector.begin(), summaryCasesVector.end() );
|
||||
}
|
||||
|
||||
for ( auto excludedCase : m_excludedCases )
|
||||
{
|
||||
setOfCases.erase( excludedCase );
|
||||
}
|
||||
|
||||
return setOfCases;
|
||||
}
|
||||
|
||||
@@ -458,7 +463,23 @@ void RimAbstractCorrelationPlot::setCaseFilterDataSource( RimEnsembleCurveSet* e
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigEnsembleParameter> RimAbstractCorrelationPlot::ensembleParameters()
|
||||
void RimAbstractCorrelationPlot::setExcludedSummaryCases( const std::vector<RimSummaryCase*>& summaryCases )
|
||||
{
|
||||
m_excludedCases = summaryCases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCase*> RimAbstractCorrelationPlot::excludedSummaryCases() const
|
||||
{
|
||||
return m_excludedCases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RigEnsembleParameter> RimAbstractCorrelationPlot::ensembleParameters() const
|
||||
{
|
||||
std::set<RigEnsembleParameter> ensembleParms;
|
||||
|
||||
@@ -492,7 +513,7 @@ std::set<RigEnsembleParameter> RimAbstractCorrelationPlot::variationSortedEnsemb
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RigEnsembleParameter RimAbstractCorrelationPlot::ensembleParameter( const QString& ensembleParameterName )
|
||||
RigEnsembleParameter RimAbstractCorrelationPlot::ensembleParameter( const QString& ensembleParameterName ) const
|
||||
{
|
||||
std::set<RigEnsembleParameter> ensembleParms = ensembleParameters();
|
||||
for ( const RigEnsembleParameter& eParam : ensembleParms )
|
||||
|
||||
@@ -61,6 +61,9 @@ public:
|
||||
RimEnsembleCurveSet* caseFilterDataSource() const;
|
||||
void setCaseFilterDataSource( RimEnsembleCurveSet* ensemble );
|
||||
|
||||
void setExcludedSummaryCases( const std::vector<RimSummaryCase*>& summaryCases );
|
||||
std::vector<RimSummaryCase*> excludedSummaryCases() const;
|
||||
|
||||
RiuQwtPlotWidget* viewer();
|
||||
RiuPlotWidget* plotWidget() override;
|
||||
void detachAllCurves() override;
|
||||
@@ -86,9 +89,9 @@ protected:
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
||||
|
||||
std::set<RifEclipseSummaryAddress> addresses() const;
|
||||
std::set<RigEnsembleParameter> ensembleParameters();
|
||||
std::set<RigEnsembleParameter> ensembleParameters() const;
|
||||
std::set<RigEnsembleParameter> variationSortedEnsembleParameters();
|
||||
RigEnsembleParameter ensembleParameter( const QString& ensembleParameterName );
|
||||
RigEnsembleParameter ensembleParameter( const QString& ensembleParameterName ) const;
|
||||
|
||||
// RimViewWindow overrides
|
||||
QWidget* viewWidget() override;
|
||||
@@ -153,4 +156,6 @@ private:
|
||||
caf::PdmField<bool> m_useCaseFilter;
|
||||
caf::PdmPtrField<RimEnsembleCurveSet*> m_curveSetForFiltering;
|
||||
caf::PdmField<bool> m_editCaseFilter;
|
||||
|
||||
std::vector<RimSummaryCase*> m_excludedCases;
|
||||
};
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
// for more details.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "RimCorrelationReportPlot.h"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
@@ -304,6 +305,10 @@ void RimCorrelationReportPlot::onLoadDataAndUpdate()
|
||||
|
||||
if ( m_showWindow )
|
||||
{
|
||||
auto cases = m_parameterResultCrossPlot->summaryCasesExcludedByFilter();
|
||||
m_correlationMatrixPlot->setExcludedSummaryCases( cases );
|
||||
m_correlationPlot->setExcludedSummaryCases( cases );
|
||||
|
||||
m_correlationMatrixPlot->setLabelFontSize( m_labelFontSize() );
|
||||
m_correlationMatrixPlot->setAxisTitleFontSize( m_axisTitleFontSize() );
|
||||
m_correlationMatrixPlot->setAxisValueFontSize( m_axisValueFontSize() );
|
||||
@@ -358,6 +363,10 @@ void RimCorrelationReportPlot::defineUiOrdering( QString uiConfigName, caf::PdmU
|
||||
plotGroup->add( &m_axisTitleFontSize );
|
||||
plotGroup->add( &m_axisValueFontSize );
|
||||
m_correlationMatrixPlot->legendConfig()->uiOrdering( "ColorsOnly", *plotGroup );
|
||||
|
||||
auto filterGroup = uiOrdering.addNewGroup( "Filter" );
|
||||
m_parameterResultCrossPlot->appendFilterFields( *filterGroup );
|
||||
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
@@ -406,6 +415,9 @@ QList<caf::PdmOptionItemInfo> RimCorrelationReportPlot::calculateValueOptions( c
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::onDataSelection( const caf::SignalEmitter* emitter,
|
||||
std::pair<QString, RiaSummaryCurveDefinition> parameterAndCurveDef )
|
||||
{
|
||||
@@ -421,4 +433,6 @@ void RimCorrelationReportPlot::onDataSelection( const caf::SignalEmitter*
|
||||
{
|
||||
m_viewer->updateSubTitles();
|
||||
}
|
||||
|
||||
updateConnectedEditors();
|
||||
}
|
||||
|
||||
+227
-59
@@ -32,17 +32,22 @@
|
||||
|
||||
#include "RiuPlotCurve.h"
|
||||
#include "RiuQwtPlotCurve.h"
|
||||
#include "RiuQwtPlotRectAnnotation.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
#include "RiuQwtSymbol.h"
|
||||
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
#include "cafPdmUiTextEditor.h"
|
||||
#include "cafPdmUiValueRangeEditor.h"
|
||||
|
||||
#include "qwt_picker_machine.h"
|
||||
#include "qwt_plot.h"
|
||||
#include "qwt_plot_curve.h"
|
||||
#include "qwt_plot_marker.h"
|
||||
#include "qwt_plot_picker.h"
|
||||
#include "qwt_text.h"
|
||||
|
||||
#include <QColor>
|
||||
#include <QStringList>
|
||||
|
||||
#include <limits>
|
||||
@@ -61,12 +66,20 @@ RimParameterResultCrossPlot::RimParameterResultCrossPlot()
|
||||
CAF_PDM_InitField( &m_ensembleParameter, "EnsembleParameter", QString( "" ), "Ensemble Parameter" );
|
||||
m_ensembleParameter.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitField( &m_useParameterFilter, "UseParameterFilter", false, "Use Parameter Filter" );
|
||||
CAF_PDM_InitField( &m_summaryFilterRange, "SummaryFilterRange", std::make_pair( 0.0, 0.0 ), "Summary Value Range", "", "", "" );
|
||||
CAF_PDM_InitField( &m_parameterFilterRange, "ParameterFilterRange", std::make_pair( 0.0, 0.0 ), "Parameter Value Range", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_excludedCasesText, "ExcludedCasesText", "Excluded Cases" );
|
||||
m_excludedCasesText.uiCapability()->setUiEditorTypeName( caf::PdmUiTextEditor::uiEditorTypeName() );
|
||||
m_excludedCasesText.registerGetMethod( this, &RimParameterResultCrossPlot::excludedCasesText );
|
||||
|
||||
m_selectMultipleVectors = true;
|
||||
|
||||
m_legendFontSize = caf::FontTools::RelativeSize::Small;
|
||||
|
||||
m_xRange = std::make_pair( std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity() );
|
||||
m_yRange = std::make_pair( std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity() );
|
||||
m_xValueRange = std::make_pair( std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity() );
|
||||
m_yValueRange = std::make_pair( std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity() );
|
||||
|
||||
m_showPlotLegends = false;
|
||||
}
|
||||
@@ -86,6 +99,47 @@ RimParameterResultCrossPlot::~RimParameterResultCrossPlot()
|
||||
void RimParameterResultCrossPlot::setEnsembleParameter( const QString& ensembleParameter )
|
||||
{
|
||||
m_ensembleParameter = ensembleParameter;
|
||||
|
||||
updateValueRanges();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCase*> RimParameterResultCrossPlot::summaryCasesExcludedByFilter() const
|
||||
{
|
||||
if ( ensembles().size() != 1 ) return {};
|
||||
|
||||
if ( !m_useParameterFilter() ) return {};
|
||||
|
||||
std::vector<RimSummaryCase*> cases;
|
||||
|
||||
auto plotValues = createCaseData();
|
||||
for ( const auto& caseData : plotValues )
|
||||
{
|
||||
if ( caseData.summaryValue < m_summaryFilterRange().first || caseData.summaryValue > m_summaryFilterRange().second ||
|
||||
caseData.parameterValue < m_parameterFilterRange().first || caseData.parameterValue > m_parameterFilterRange().second )
|
||||
{
|
||||
cases.push_back( caseData.summaryCase );
|
||||
}
|
||||
}
|
||||
|
||||
return cases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::appendFilterFields( caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_useParameterFilter );
|
||||
if ( m_useParameterFilter )
|
||||
{
|
||||
uiOrdering.add( &m_summaryFilterRange );
|
||||
uiOrdering.add( &m_parameterFilterRange );
|
||||
uiOrdering.add( &m_excludedCasesText );
|
||||
}
|
||||
uiOrdering.skipRemainingFields();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -122,6 +176,10 @@ void RimParameterResultCrossPlot::defineUiOrdering( QString uiConfigName, caf::P
|
||||
plotGroup->add( &m_axisValueFontSize );
|
||||
|
||||
m_description.uiCapability()->setUiReadOnly( m_useAutoPlotTitle() );
|
||||
|
||||
auto filterGroup = uiOrdering.addNewGroup( "Filter" );
|
||||
appendFilterFields( *filterGroup );
|
||||
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
@@ -141,6 +199,37 @@ QList<caf::PdmOptionItemInfo> RimParameterResultCrossPlot::calculateValueOptions
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
if ( field == &m_summaryFilterRange )
|
||||
{
|
||||
if ( auto attr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute ) )
|
||||
{
|
||||
attr->m_decimals = 2;
|
||||
attr->m_sliderTickCount = 100;
|
||||
|
||||
attr->m_minimum = m_yValueRange.first;
|
||||
attr->m_maximum = m_yValueRange.second;
|
||||
}
|
||||
}
|
||||
else if ( field == &m_parameterFilterRange )
|
||||
{
|
||||
if ( auto attr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute ) )
|
||||
{
|
||||
attr->m_decimals = 2;
|
||||
attr->m_sliderTickCount = 100;
|
||||
|
||||
attr->m_minimum = m_xValueRange.first;
|
||||
attr->m_maximum = m_xValueRange.second;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -153,6 +242,32 @@ void RimParameterResultCrossPlot::onLoadDataAndUpdate()
|
||||
if ( m_plotWidget && m_analyserOfSelectedCurveDefs )
|
||||
{
|
||||
createPoints();
|
||||
|
||||
if ( m_useParameterFilter )
|
||||
{
|
||||
if ( !m_rectAnnotation )
|
||||
{
|
||||
m_rectAnnotation = std::make_unique<RiuQwtPlotRectAnnotation>();
|
||||
}
|
||||
|
||||
m_rectAnnotation->setInterval( m_parameterFilterRange().first,
|
||||
m_parameterFilterRange().second,
|
||||
m_summaryFilterRange().first,
|
||||
m_summaryFilterRange().second );
|
||||
|
||||
QColor penColor( "orange" );
|
||||
QPen pen( penColor );
|
||||
m_rectAnnotation->setPen( pen );
|
||||
|
||||
QColor brushColor = penColor;
|
||||
double transparency = 0.3;
|
||||
brushColor.setAlphaF( transparency );
|
||||
QBrush brush( brushColor );
|
||||
m_rectAnnotation->setBrush( brush );
|
||||
|
||||
m_rectAnnotation->attach( m_plotWidget->qwtPlot() );
|
||||
}
|
||||
|
||||
updateAxes();
|
||||
updatePlotTitle();
|
||||
m_plotWidget->scheduleReplot();
|
||||
@@ -169,16 +284,12 @@ void RimParameterResultCrossPlot::updateAxes()
|
||||
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultLeft(), completeAddressText() );
|
||||
m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultLeft(), true );
|
||||
m_plotWidget->setAxisFontsAndAlignment( RiuPlotAxis::defaultLeft(), axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
|
||||
|
||||
double yRangeWidth = m_yRange.second - m_yRange.first;
|
||||
m_plotWidget->setAxisRange( RiuPlotAxis::defaultLeft(), m_yRange.first - yRangeWidth * 0.1, m_yRange.second + yRangeWidth * 0.1 );
|
||||
m_plotWidget->setAxisRange( RiuPlotAxis::defaultLeft(), m_yValueRange.first, m_yValueRange.second );
|
||||
|
||||
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultBottom(), m_ensembleParameter );
|
||||
m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultBottom(), true );
|
||||
m_plotWidget->setAxisFontsAndAlignment( RiuPlotAxis::defaultBottom(), axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
|
||||
|
||||
double xRangeWidth = m_xRange.second - m_xRange.first;
|
||||
m_plotWidget->setAxisRange( RiuPlotAxis::defaultBottom(), m_xRange.first - xRangeWidth * 0.1, m_xRange.second + xRangeWidth * 0.1 );
|
||||
m_plotWidget->setAxisRange( RiuPlotAxis::defaultBottom(), m_xValueRange.first, m_xValueRange.second );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -205,9 +316,6 @@ QStringList caseNamesOfValidEnsembleCases( const RimSummaryEnsemble* ensemble )
|
||||
void RimParameterResultCrossPlot::createPoints()
|
||||
{
|
||||
detachAllCurves();
|
||||
m_valuesForTextReport.clear();
|
||||
|
||||
time_t selectedTimestep = m_timeStep().toSecsSinceEpoch();
|
||||
|
||||
caf::ColorTable colorTable = RiaColorTables::categoryPaletteColors();
|
||||
|
||||
@@ -216,18 +324,104 @@ void RimParameterResultCrossPlot::createPoints()
|
||||
|
||||
bool showEnsembleName = ensembles().size() > 1u;
|
||||
|
||||
m_xRange = std::make_pair( std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity() );
|
||||
m_yRange = std::make_pair( std::numeric_limits<double>::infinity(), -std::numeric_limits<double>::infinity() );
|
||||
int idx = 0;
|
||||
auto caseData = createCaseData();
|
||||
for ( const auto& [paramValue, closestValue, summaryCase] : caseData )
|
||||
{
|
||||
RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve;
|
||||
plotCurve->setSamplesValues( { paramValue }, { closestValue } );
|
||||
plotCurve->setStyle( QwtPlotCurve::NoCurve );
|
||||
|
||||
RiuQwtSymbol* symbol = new RiuQwtSymbol( RiuPlotCurveSymbol::SYMBOL_ELLIPSE );
|
||||
symbol->setSize( legendFontSize(), legendFontSize() );
|
||||
symbol->setColor( colorTable.cycledQColor( idx++ ) );
|
||||
plotCurve->setSymbol( symbol );
|
||||
|
||||
QStringList curveName;
|
||||
if ( showEnsembleName && summaryCase->ensemble() )
|
||||
{
|
||||
curveName += summaryCase->ensemble()->name();
|
||||
}
|
||||
curveName += summaryCase->displayCaseName();
|
||||
|
||||
plotCurve->setTitle( curveName.join( " - " ) );
|
||||
|
||||
plotCurve->attach( m_plotWidget->qwtPlot() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::updateValueRanges()
|
||||
{
|
||||
auto parameterMin = std::numeric_limits<double>::infinity();
|
||||
auto parameterMax = -std::numeric_limits<double>::infinity();
|
||||
auto summaryMin = std::numeric_limits<double>::infinity();
|
||||
auto summaryMax = -std::numeric_limits<double>::infinity();
|
||||
|
||||
auto caseData = createCaseData();
|
||||
for ( const auto& [paramValue, summaryValue, summaryCase] : caseData )
|
||||
{
|
||||
parameterMin = std::min( parameterMin, paramValue );
|
||||
parameterMax = std::max( parameterMax, paramValue );
|
||||
summaryMin = std::min( summaryMin, summaryValue );
|
||||
summaryMax = std::max( summaryMax, summaryValue );
|
||||
}
|
||||
|
||||
double parameterRange = parameterMax - parameterMin;
|
||||
double summaryRange = summaryMax - summaryMin;
|
||||
|
||||
m_xValueRange = { parameterMin - parameterRange * 0.1, parameterMax + parameterRange * 0.1 };
|
||||
m_yValueRange = { summaryMin - summaryRange * 0.1, summaryMax + summaryRange * 0.1 };
|
||||
|
||||
m_summaryFilterRange = { m_yValueRange.first, m_yValueRange.second };
|
||||
m_parameterFilterRange = { m_xValueRange.first, m_xValueRange.second };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimParameterResultCrossPlot::excludedCasesText() const
|
||||
{
|
||||
auto cases = summaryCasesExcludedByFilter();
|
||||
QStringList caseNames;
|
||||
for ( auto summaryCase : cases )
|
||||
{
|
||||
caseNames.push_back( summaryCase->displayCaseName() );
|
||||
}
|
||||
return caseNames.join( ", " );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::detachAllCurves()
|
||||
{
|
||||
if ( m_plotWidget && m_rectAnnotation )
|
||||
{
|
||||
m_rectAnnotation->detach();
|
||||
}
|
||||
|
||||
RimAbstractCorrelationPlot::detachAllCurves();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimParameterResultCrossPlot::CaseData> RimParameterResultCrossPlot::createCaseData() const
|
||||
{
|
||||
RigEnsembleParameter parameter = ensembleParameter( m_ensembleParameter );
|
||||
if ( !( parameter.isNumeric() && parameter.isValid() ) ) return {};
|
||||
|
||||
std::vector<RimParameterResultCrossPlot::CaseData> caseData;
|
||||
|
||||
time_t selectedTimestep = m_timeStep().toSecsSinceEpoch();
|
||||
|
||||
int ensembleIdx = 0;
|
||||
for ( auto ensemble : ensembles() )
|
||||
{
|
||||
int addressIdx = 0;
|
||||
for ( auto address : addresses() )
|
||||
{
|
||||
RigEnsembleParameter parameter = ensembleParameter( m_ensembleParameter );
|
||||
if ( !( parameter.isNumeric() && parameter.isValid() ) ) return;
|
||||
|
||||
std::set<RimSummaryCase*> activeCases = filterEnsembleCases( ensemble );
|
||||
|
||||
for ( size_t caseIdx = 0u; caseIdx < ensemble->allSummaryCases().size(); ++caseIdx )
|
||||
@@ -240,9 +434,9 @@ void RimParameterResultCrossPlot::createPoints()
|
||||
|
||||
if ( !summaryCase->caseRealizationParameters() ) continue;
|
||||
|
||||
double closestValue = std::numeric_limits<double>::infinity();
|
||||
time_t closestTimeStep = 0;
|
||||
auto [isOk, values] = reader->values( address );
|
||||
double summaryValue = std::numeric_limits<double>::infinity();
|
||||
time_t closestTimeStep = 0;
|
||||
auto [isOk, summaryValues] = reader->values( address );
|
||||
if ( isOk )
|
||||
{
|
||||
const std::vector<time_t>& timeSteps = reader->timeSteps( address );
|
||||
@@ -250,50 +444,21 @@ void RimParameterResultCrossPlot::createPoints()
|
||||
{
|
||||
if ( timeDiff( timeSteps[i], selectedTimestep ) < timeDiff( selectedTimestep, closestTimeStep ) )
|
||||
{
|
||||
closestValue = values[i];
|
||||
summaryValue = summaryValues[i];
|
||||
closestTimeStep = timeSteps[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( closestValue != std::numeric_limits<double>::infinity() )
|
||||
|
||||
if ( summaryValue != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
std::vector<double> caseValuesAtTimestep;
|
||||
std::vector<double> parameterValues;
|
||||
|
||||
caseValuesAtTimestep.push_back( closestValue );
|
||||
double paramValue = parameter.values[caseIdx].toDouble();
|
||||
parameterValues.push_back( paramValue );
|
||||
|
||||
m_valuesForTextReport.push_back( { paramValue, closestValue } );
|
||||
|
||||
m_xRange.first = std::min( m_xRange.first, paramValue );
|
||||
m_xRange.second = std::max( m_xRange.second, paramValue );
|
||||
|
||||
m_yRange.first = std::min( m_yRange.first, closestValue );
|
||||
m_yRange.second = std::max( m_yRange.second, closestValue );
|
||||
|
||||
RiuQwtPlotCurve* plotCurve = new RiuQwtPlotCurve;
|
||||
plotCurve->setSamplesValues( parameterValues, caseValuesAtTimestep );
|
||||
plotCurve->setStyle( QwtPlotCurve::NoCurve );
|
||||
|
||||
RiuQwtSymbol* symbol = new RiuQwtSymbol( RiuPlotCurveSymbol::cycledSymbolStyle( ensembleIdx, addressIdx ), "" );
|
||||
symbol->setSize( legendFontSize(), legendFontSize() );
|
||||
symbol->setColor( colorTable.cycledQColor( caseIdx ) );
|
||||
plotCurve->setSymbol( symbol );
|
||||
|
||||
QStringList curveName;
|
||||
if ( showEnsembleName ) curveName += ensemble->name();
|
||||
curveName += summaryCase->displayCaseName();
|
||||
|
||||
plotCurve->setTitle( curveName.join( " - " ) );
|
||||
|
||||
plotCurve->attach( m_plotWidget->qwtPlot() );
|
||||
caseData.push_back(
|
||||
{ .parameterValue = parameter.values[caseIdx].toDouble(), .summaryValue = summaryValue, .summaryCase = summaryCase } );
|
||||
}
|
||||
}
|
||||
addressIdx++;
|
||||
}
|
||||
ensembleIdx++;
|
||||
}
|
||||
return caseData;
|
||||
}
|
||||
|
||||
namespace internal
|
||||
@@ -370,10 +535,13 @@ QString RimParameterResultCrossPlot::asciiDataForPlotExport() const
|
||||
{
|
||||
QString asciiData;
|
||||
|
||||
asciiData += "Parameter\tResult\n";
|
||||
for ( const auto& valuePair : m_valuesForTextReport )
|
||||
auto data = createCaseData();
|
||||
|
||||
asciiData += "Realization\tParameter\tResult\n";
|
||||
for ( const auto& [parameterValue, summaryValue, summaryCase] : data )
|
||||
{
|
||||
asciiData += QString( "%1\t%2\n" ).arg( valuePair.first ).arg( valuePair.second );
|
||||
auto caseName = summaryCase->displayCaseName();
|
||||
asciiData += QString( "%1\t%2\t%3\n" ).arg( caseName ).arg( parameterValue ).arg( summaryValue );
|
||||
}
|
||||
|
||||
return asciiData;
|
||||
|
||||
@@ -20,6 +20,8 @@
|
||||
|
||||
#include "RimAbstractCorrelationPlot.h"
|
||||
|
||||
class RiuQwtPlotRectAnnotation;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
@@ -33,10 +35,16 @@ public:
|
||||
~RimParameterResultCrossPlot() override;
|
||||
void setEnsembleParameter( const QString& ensembleParameter );
|
||||
|
||||
std::vector<RimSummaryCase*> summaryCasesExcludedByFilter() const;
|
||||
void appendFilterFields( caf::PdmUiOrdering& uiOrdering );
|
||||
|
||||
void detachAllCurves() override;
|
||||
|
||||
private:
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions ) override;
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
RiuPlotWidget* doCreatePlotViewWidget( QWidget* mainWindowParent = nullptr ) override;
|
||||
|
||||
@@ -45,12 +53,29 @@ private:
|
||||
QString asciiDataForPlotExport() const override;
|
||||
void updatePlotTitle() override;
|
||||
void createPoints();
|
||||
void updateValueRanges();
|
||||
|
||||
QString excludedCasesText() const;
|
||||
|
||||
struct CaseData
|
||||
{
|
||||
double parameterValue;
|
||||
double summaryValue;
|
||||
RimSummaryCase* summaryCase;
|
||||
};
|
||||
|
||||
std::vector<CaseData> createCaseData() const;
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_ensembleParameter;
|
||||
|
||||
std::pair<double, double> m_xRange;
|
||||
std::pair<double, double> m_yRange;
|
||||
caf::PdmField<bool> m_useParameterFilter;
|
||||
caf::PdmField<std::pair<double, double>> m_summaryFilterRange;
|
||||
caf::PdmField<std::pair<double, double>> m_parameterFilterRange;
|
||||
caf::PdmProxyValueField<QString> m_excludedCasesText;
|
||||
|
||||
std::vector<std::pair<double, double>> m_valuesForTextReport;
|
||||
std::pair<double, double> m_xValueRange;
|
||||
std::pair<double, double> m_yValueRange;
|
||||
|
||||
std::unique_ptr<RiuQwtPlotRectAnnotation> m_rectAnnotation;
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user