Files

412 lines
17 KiB
C++
Raw Permalink Normal View History

2020-04-17 09:31:42 +02:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2020 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 "RimCorrelationPlot.h"
2023-06-09 14:09:08 +02:00
#include "RiaColorTools.h"
2020-04-17 09:31:42 +02:00
#include "RiaPreferences.h"
#include "RiaQDateTimeTools.h"
2023-06-09 14:09:08 +02:00
2020-04-17 09:31:42 +02:00
#include "RiuGroupedBarChartBuilder.h"
#include "RiuPlotMainWindowTools.h"
2020-04-17 19:24:12 +02:00
#include "RiuQwtPlotWidget.h"
2020-04-17 09:31:42 +02:00
#include "RifSummaryReaderInterface.h"
#include "RimCorrelationBarChartTools.h"
2024-11-13 11:26:06 +01:00
#include "RimDeltaSummaryCase.h"
2020-04-17 09:31:42 +02:00
#include "RimEnsembleCurveSet.h"
#include "RimPlotAxisProperties.h"
#include "RimPlotAxisPropertiesInterface.h"
#include "RimPlotDataFilterCollection.h"
#include "RimSummaryAddress.h"
#include "RimSummaryCase.h"
#include "RimSummaryEnsemble.h"
2020-04-17 09:31:42 +02:00
#include "RimSummaryPlotAxisFormatter.h"
2020-05-27 12:58:21 +02:00
#include "cafFontTools.h"
2020-04-17 09:31:42 +02:00
#include "cafPdmUiComboBoxEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
2020-04-17 09:31:42 +02:00
#include "qwt_plot.h"
2022-03-18 13:16:07 +01:00
#include "qwt_text.h"
2020-05-05 12:43:44 +02:00
2020-04-17 09:31:42 +02:00
#include <limits>
#include <map>
#include <set>
CAF_PDM_SOURCE_INIT( RimCorrelationPlot, "CorrelationPlot" );
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCorrelationPlot::RimCorrelationPlot()
2020-04-17 19:24:12 +02:00
: RimAbstractCorrelationPlot()
, tornadoItemSelected( this )
2020-04-17 09:31:42 +02:00
{
CAF_PDM_InitObject( "Correlation Tornado Plot", ":/CorrelationTornadoPlot16x16.png" );
2020-04-17 09:31:42 +02:00
CAF_PDM_InitField( &m_showAbsoluteValues, "CorrelationAbsValues", false, "Show Absolute Values" );
CAF_PDM_InitField( &m_sortByAbsoluteValues, "CorrelationAbsSorting", true, "Sort by Absolute Values" );
2023-02-26 10:48:40 +01:00
CAF_PDM_InitField( &m_excludeParametersWithoutVariation, "ExcludeParamsWithoutVariation", true, "Exclude Parameters Without Variation" );
CAF_PDM_InitField( &m_showOnlyTopNCorrelations, "ShowOnlyTopNCorrelations", true, "Show Only Top Correlations" );
CAF_PDM_InitField( &m_topNFilterCount, "TopNFilterCount", 20, "Number rows/columns" );
2020-05-18 16:02:27 +02:00
CAF_PDM_InitFieldNoDefault( &m_selectedParametersList, "SelectedParameters", "Select Parameters" );
2026-01-08 19:06:38 +01:00
m_selectedParametersList.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::LabelPosition::TOP );
m_selectedParametersList.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
2023-06-09 14:09:08 +02:00
// Color taken from https://webviz-subsurface-example.azurewebsites.net/parameters-vs-rft
QColor qColor = QColor( "#3173b2" );
CAF_PDM_InitField( &m_barColor, "BarColor", RiaColorTools::fromQColorTo3f( qColor ), "Bar Color" );
QColor highlightColor = QColor( "#f5a623" );
CAF_PDM_InitField( &m_highlightBarColor, "HighlightBarColor", RiaColorTools::fromQColorTo3f( highlightColor ), "Bar Color (Selected)" );
2023-06-09 14:09:08 +02:00
setLegendsVisible( false );
2020-05-18 16:02:27 +02:00
setDeletable( true );
2020-04-17 09:31:42 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCorrelationPlot::~RimCorrelationPlot()
{
if ( isMainDockedWindow() ) removeWindowFromDock();
2020-04-17 09:31:42 +02:00
cleanupBeforeClose();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2023-02-26 10:48:40 +01:00
void RimCorrelationPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
2020-04-17 09:31:42 +02:00
{
2020-04-17 19:24:12 +02:00
RimAbstractCorrelationPlot::fieldChangedByUi( changedField, oldValue, newValue );
2023-06-09 14:09:08 +02:00
2020-09-23 15:48:19 +02:00
if ( changedField == &m_showAbsoluteValues || changedField == &m_sortByAbsoluteValues ||
changedField == &m_excludeParametersWithoutVariation || changedField == &m_selectedParametersList ||
changedField == &m_showOnlyTopNCorrelations || changedField == &m_topNFilterCount || changedField == &m_barColor ||
changedField == &m_highlightBarColor )
2020-04-17 09:31:42 +02:00
{
if ( changedField == &m_excludeParametersWithoutVariation )
{
selectAllParameters();
}
loadDataAndUpdate();
updateAllRequiredEditors();
2020-04-17 09:31:42 +02:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
// When used as a sub-plot of a correlation report, the data source and correlation settings are controlled
// from the report plot, so only the plot settings are exposed here.
if ( !isContainedInReportPlot() )
2020-04-17 19:24:12 +02:00
{
caf::PdmUiGroup* correlationGroup = uiOrdering.addNewGroup( "Correlation Settings" );
correlationGroup->add( &m_excludeParametersWithoutVariation );
correlationGroup->add( &m_selectedParametersList );
2020-04-17 19:24:12 +02:00
correlationGroup->add( &m_showAbsoluteValues );
if ( !m_showAbsoluteValues() )
{
correlationGroup->add( &m_sortByAbsoluteValues );
}
correlationGroup->add( &m_showOnlyTopNCorrelations );
if ( m_showOnlyTopNCorrelations() )
{
correlationGroup->add( &m_topNFilterCount );
}
2020-07-29 12:41:41 +02:00
appendDataSourceFields( uiConfigName, uiOrdering );
}
2020-04-17 09:31:42 +02:00
caf::PdmUiGroup* plotGroup = uiOrdering.addNewGroup( "Plot Settings" );
plotGroup->add( &m_showPlotTitle );
plotGroup->add( &m_useAutoPlotTitle );
plotGroup->add( &m_description );
2020-04-21 08:56:27 +02:00
RimPlot::defineUiOrdering( uiConfigName, *plotGroup );
plotGroup->add( &m_titleFontSize );
2020-05-27 12:58:21 +02:00
plotGroup->add( &m_axisTitleFontSize );
plotGroup->add( &m_axisValueFontSize );
2023-06-09 14:09:08 +02:00
plotGroup->add( &m_barColor );
plotGroup->add( &m_highlightBarColor );
2020-04-21 08:56:27 +02:00
2020-04-17 09:31:42 +02:00
m_description.uiCapability()->setUiReadOnly( m_useAutoPlotTitle() );
uiOrdering.skipRemainingFields( true );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimCorrelationPlot::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
2020-04-17 09:31:42 +02:00
{
QList<caf::PdmOptionItemInfo> options = RimAbstractCorrelationPlot::calculateValueOptions( fieldNeedingOptions );
2020-04-17 09:31:42 +02:00
if ( fieldNeedingOptions == &m_selectedParametersList )
{
std::set<RigEnsembleParameter> params = variationSortedEnsembleParameters();
for ( auto param : params )
{
if ( !m_excludeParametersWithoutVariation() || param.variationBin > RigEnsembleParameter::NO_VARIATION )
{
options.push_back( caf::PdmOptionItemInfo( param.uiName(), param.name ) );
}
}
}
2020-04-17 19:24:12 +02:00
return options;
2020-04-17 09:31:42 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::onLoadDataAndUpdate()
{
updateDockWindowVisibility();
2020-04-17 09:31:42 +02:00
2022-05-06 16:34:37 +02:00
m_selectedVarsUiField = selectedVectorNamesText();
2020-04-17 09:31:42 +02:00
2020-04-21 08:56:27 +02:00
if ( m_plotWidget && m_analyserOfSelectedCurveDefs )
2020-04-17 09:31:42 +02:00
{
m_plotWidget->qwtPlot()->detachItems( QwtPlotItem::Rtti_PlotBarChart );
m_plotWidget->qwtPlot()->detachItems( QwtPlotItem::Rtti_PlotScale );
2020-04-17 09:31:42 +02:00
RiuGroupedBarChartBuilder chartBuilder;
2023-06-09 14:09:08 +02:00
chartBuilder.setBarColor( RiaColorTools::toQColor( m_barColor() ) );
2020-04-17 09:31:42 +02:00
addDataToChartBuilder( chartBuilder );
2023-02-26 10:48:40 +01:00
chartBuilder.addBarChartToPlot( m_plotWidget->qwtPlot(), Qt::Horizontal, m_showOnlyTopNCorrelations() ? m_topNFilterCount() : -1 );
chartBuilder.setLabelFontSize( labelFontSize() );
RimCorrelationBarChartTools::highlightSelectedParameterBar( m_plotWidget,
m_selectedParameter,
RiaColorTools::toQColor( m_barColor() ),
RiaColorTools::toQColor( m_highlightBarColor() ) );
2020-04-17 09:31:42 +02:00
m_plotWidget->qwtPlot()->insertLegend( nullptr );
2020-04-17 09:31:42 +02:00
m_plotWidget->updateLegend();
updateAxes();
updatePlotTitle();
2020-04-17 09:31:42 +02:00
m_plotWidget->scheduleReplot();
}
}
//--------------------------------------------------------------------------------------------------
/// When the selected summary vector changes, notify listeners so the sibling plots in a correlation
/// report are updated with the new data source.
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::onDataSourceChanged()
{
auto curves = curveDefinitions();
if ( curves.empty() ) return;
if ( m_selectedParametersList().empty() ) selectAllParameters();
auto parameters = m_selectedParametersList();
if ( parameters.empty() ) return;
tornadoItemSelected.send( { parameters.front(), curves.front() } );
}
2020-04-17 09:31:42 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::updateAxes()
{
if ( !m_plotWidget ) return;
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultLeft(), "Parameter" );
m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultLeft(), true );
2023-02-26 10:48:40 +01:00
m_plotWidget->setAxisFontsAndAlignment( RiuPlotAxis::defaultLeft(), axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultBottom(), "Pearson Correlation Coefficient" );
m_plotWidget->setAxisTitleEnabled( RiuPlotAxis::defaultBottom(), true );
2023-02-26 10:48:40 +01:00
m_plotWidget->setAxisFontsAndAlignment( RiuPlotAxis::defaultBottom(), axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
if ( m_showAbsoluteValues )
{
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultBottom(), "Pearson Correlation Coefficient ABS" );
m_plotWidget->setAxisRange( RiuPlotAxis::defaultBottom(), 0.0, 1.0 );
}
else
{
m_plotWidget->setAxisTitleText( RiuPlotAxis::defaultBottom(), "Pearson Correlation Coefficient" );
m_plotWidget->setAxisRange( RiuPlotAxis::defaultBottom(), -1.0, 1.0 );
}
2020-04-17 09:31:42 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2023-10-11 08:54:52 +02:00
void RimCorrelationPlot::addDataToChartBuilder( RiuGroupedBarChartBuilder& chartBuilder ) const
2020-04-17 09:31:42 +02:00
{
time_t selectedTimestep = m_timeStep().toSecsSinceEpoch();
2020-04-17 09:31:42 +02:00
2020-04-21 08:56:27 +02:00
if ( ensembles().empty() ) return;
if ( addresses().empty() ) return;
2020-04-17 09:31:42 +02:00
2020-04-21 08:56:27 +02:00
auto ensemble = *ensembles().begin();
auto address = *addresses().begin();
2021-03-29 15:45:53 +02:00
std::set<RimSummaryCase*> activeCases = filterEnsembleCases( ensemble );
std::vector<std::pair<RigEnsembleParameter, double>> correlations =
2021-03-29 15:45:53 +02:00
ensemble->parameterCorrelations( address, selectedTimestep, m_selectedParametersList(), activeCases );
2020-04-17 09:31:42 +02:00
for ( auto parameterCorrPair : correlations )
2020-04-17 09:31:42 +02:00
{
RimCorrelationBarChartTools::addCorrelationBar( chartBuilder,
parameterCorrPair.first.name,
parameterCorrPair.second,
m_showAbsoluteValues(),
m_sortByAbsoluteValues() );
2020-04-17 09:31:42 +02:00
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::updatePlotTitle()
{
if ( m_useAutoPlotTitle && !ensembles().empty() )
2020-04-17 09:31:42 +02:00
{
QString vectorName = completeAddressText();
auto ensemble = *ensembles().begin();
2025-03-17 12:53:22 +01:00
m_description = QString( "%1, %2 at %3" ).arg( vectorName ).arg( ensemble->name() ).arg( timeStepString() );
2020-04-17 09:31:42 +02:00
}
m_plotWidget->setPlotTitle( m_description );
2026-03-30 11:35:51 +02:00
m_plotWidget->setPlotTitleEnabled( m_showPlotTitle );
m_plotWidget->setPlotTitleFontSize( titleFontSize() );
2020-04-17 09:31:42 +02:00
}
2020-04-29 08:11:30 +02:00
2020-05-05 12:43:44 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::onPlotItemSelected( std::shared_ptr<RiuPlotItem> plotItem, bool /*toggle*/, int /*sampleIndex*/ )
2020-05-05 12:43:44 +02:00
{
const QString paramName = RimCorrelationBarChartTools::parameterNameFromPlotItem( plotItem );
if ( paramName.isEmpty() || curveDefinitions().empty() ) return;
tornadoItemSelected.send( std::make_pair( paramName, curveDefinitions().front() ) );
2020-05-05 12:43:44 +02:00
}
2023-10-11 08:54:52 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimCorrelationPlot::asciiDataForPlotExport() const
{
RiuGroupedBarChartBuilder chartBuilder;
addDataToChartBuilder( chartBuilder );
return chartBuilder.plotContentAsText();
}
2020-04-29 08:11:30 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimCorrelationPlot::showAbsoluteValues() const
{
return m_showAbsoluteValues;
2020-04-29 08:11:30 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::setShowAbsoluteValues( bool showAbsoluteValues )
{
m_showAbsoluteValues = showAbsoluteValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimCorrelationPlot::sortByAbsoluteValues() const
{
return m_sortByAbsoluteValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::setSortByAbsoluteValues( bool sortByAbsoluteValues )
{
m_sortByAbsoluteValues = sortByAbsoluteValues;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::selectAllParameters()
{
m_selectedParametersList.v().clear();
std::set<RigEnsembleParameter> params = variationSortedEnsembleParameters();
for ( auto param : params )
{
if ( !m_excludeParametersWithoutVariation() || param.variationBin > RigEnsembleParameter::NO_VARIATION )
{
m_selectedParametersList.v().push_back( param.name );
}
}
}
2020-07-29 12:41:41 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimCorrelationPlot::showOnlyTopNCorrelations() const
{
return m_showOnlyTopNCorrelations;
}
2020-07-29 12:41:41 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::setShowOnlyTopNCorrelations( bool showOnlyTopNCorrelations )
{
m_showOnlyTopNCorrelations = showOnlyTopNCorrelations;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RimCorrelationPlot::topNFilterCount() const
{
return m_topNFilterCount;
}
2020-07-29 12:41:41 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::setTopNFilterCount( int filterCount )
{
m_topNFilterCount = filterCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimCorrelationPlot::setSelectedParameter( const QString& paramName )
{
m_selectedParameter = paramName;
}