mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Rename ApplicationCode to ApplicationLibCode
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAbstractCorrelationPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCorrelationPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCorrelationMatrixPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimParameterResultCrossPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCorrelationPlotCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCorrelationReportPlot.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAbstractCorrelationPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCorrelationPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCorrelationMatrixPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimParameterResultCrossPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCorrelationPlotCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimCorrelationReportPlot.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
${SOURCE_GROUP_HEADER_FILES}
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
source_group( "ProjectDataModel\\CorrelationPlots" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
||||
@@ -0,0 +1,603 @@
|
||||
#include "RimAbstractCorrelationPlot.h"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaQDateTimeTools.h"
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include "RimAnalysisPlotDataEntry.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
#include "RiuSummaryVectorSelectionDialog.h"
|
||||
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
#include "cafPdmUiLineEditor.h"
|
||||
#include "cafPdmUiPushButtonEditor.h"
|
||||
|
||||
CAF_PDM_ABSTRACT_SOURCE_INIT( RimAbstractCorrelationPlot, "AbstractCorrelationPlot" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAbstractCorrelationPlot::RimAbstractCorrelationPlot()
|
||||
: m_selectMultipleVectors( false )
|
||||
{
|
||||
CAF_PDM_InitObject( "Abstract Correlation Plot", ":/CorrelationPlot16x16.png", "", "" );
|
||||
this->setDeletable( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_selectedVarsUiField, "SelectedVariableDisplayVar", "Vector", "", "", "" );
|
||||
m_selectedVarsUiField.xmlCapability()->disableIO();
|
||||
m_selectedVarsUiField.uiCapability()->setUiReadOnly( true );
|
||||
m_selectedVarsUiField.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_analysisPlotDataSelection, "AnalysisPlotData", "", "", "", "" );
|
||||
m_analysisPlotDataSelection.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_analysisPlotDataSelection.uiCapability()->setUiTreeHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_pushButtonSelectSummaryAddress, "SelectAddress", "", "", "", "" );
|
||||
caf::PdmUiPushButtonEditor::configureEditorForField( &m_pushButtonSelectSummaryAddress );
|
||||
m_pushButtonSelectSummaryAddress.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
m_pushButtonSelectSummaryAddress = false;
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_timeStepFilter, "TimeStepFilter", "Available Time Steps", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_timeStep, "TimeStep", "Time Step", "", "", "" );
|
||||
m_timeStep.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitField( &m_useAutoPlotTitle, "AutoTitle", true, "Automatic Plot Title", "", "", "" );
|
||||
CAF_PDM_InitField( &m_description, "PlotTitle", QString( "Correlation Plot" ), "Custom Plot Title", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_labelFontSize, "LabelFontSize", "Label Font Size", "", "", "" );
|
||||
m_labelFontSize = caf::FontTools::RelativeSize::XSmall;
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_axisTitleFontSize, "AxisTitleFontSize", "Axis Title Font Size", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_axisValueFontSize, "AxisValueFontSize", "Axis Value Font Size", "", "", "" );
|
||||
m_axisValueFontSize = caf::FontTools::RelativeSize::XSmall;
|
||||
|
||||
m_legendFontSize = caf::FontTools::RelativeSize::XSmall;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAbstractCorrelationPlot::~RimAbstractCorrelationPlot()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::setCurveDefinitions( const std::vector<RiaSummaryCurveDefinition>& curveDefinitions )
|
||||
{
|
||||
m_analysisPlotDataSelection.deleteAllChildObjects();
|
||||
for ( auto curveDef : curveDefinitions )
|
||||
{
|
||||
auto dataEntry = new RimAnalysisPlotDataEntry();
|
||||
dataEntry->setFromCurveDefinition( curveDef );
|
||||
m_analysisPlotDataSelection.push_back( dataEntry );
|
||||
}
|
||||
connectAllCaseSignals();
|
||||
|
||||
auto timeSteps = allAvailableTimeSteps();
|
||||
if ( m_timeStep().isNull() && !timeSteps.empty() )
|
||||
{
|
||||
m_timeStep = RiaQDateTimeTools::fromTime_t( *timeSteps.rbegin() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::setTimeStep( std::time_t timeStep )
|
||||
{
|
||||
m_timeStep = RiaQDateTimeTools::fromTime_t( timeStep );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
RimPlot::fieldChangedByUi( changedField, oldValue, newValue );
|
||||
if ( changedField == &m_pushButtonSelectSummaryAddress )
|
||||
{
|
||||
RiuSummaryVectorSelectionDialog dlg( nullptr );
|
||||
|
||||
if ( m_selectMultipleVectors )
|
||||
{
|
||||
dlg.enableMultiSelect( true );
|
||||
}
|
||||
|
||||
dlg.hideSummaryCases();
|
||||
dlg.setCurveSelection( curveDefinitions() );
|
||||
|
||||
if ( dlg.exec() == QDialog::Accepted )
|
||||
{
|
||||
auto curveSelection = dlg.curveSelection();
|
||||
if ( !curveSelection.empty() )
|
||||
{
|
||||
std::vector<RiaSummaryCurveDefinition> summaryVectorDefinitions = dlg.curveSelection();
|
||||
m_analysisPlotDataSelection.deleteAllChildObjects();
|
||||
for ( const RiaSummaryCurveDefinition& vectorDef : summaryVectorDefinitions )
|
||||
{
|
||||
auto plotEntry = new RimAnalysisPlotDataEntry();
|
||||
plotEntry->setFromCurveDefinition( vectorDef );
|
||||
m_analysisPlotDataSelection.push_back( plotEntry );
|
||||
}
|
||||
connectAllCaseSignals();
|
||||
this->loadDataAndUpdate();
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
m_pushButtonSelectSummaryAddress = false;
|
||||
}
|
||||
else if ( changedField == &m_timeStep )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
else if ( changedField == &m_showPlotTitle || changedField == &m_useAutoPlotTitle || changedField == &m_description )
|
||||
{
|
||||
this->updatePlotTitle();
|
||||
}
|
||||
else if ( changedField == &m_labelFontSize || changedField == &m_axisTitleFontSize ||
|
||||
changedField == &m_axisValueFontSize || changedField == &m_legendFontSize || changedField == &m_titleFontSize )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
}
|
||||
else if ( changedField == &m_timeStepFilter )
|
||||
{
|
||||
std::vector<QDateTime> allDateTimes;
|
||||
for ( time_t timeStep : allAvailableTimeSteps() )
|
||||
{
|
||||
QDateTime dateTime = RiaQDateTimeTools::fromTime_t( timeStep );
|
||||
allDateTimes.push_back( dateTime );
|
||||
}
|
||||
|
||||
std::vector<int> filteredTimeStepIndices =
|
||||
RimTimeStepFilter::filteredTimeStepIndices( allDateTimes, 0, (int)allDateTimes.size() - 1, m_timeStepFilter(), 1 );
|
||||
|
||||
m_timeStep = allDateTimes[filteredTimeStepIndices.back()];
|
||||
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
|
||||
if ( attrib )
|
||||
{
|
||||
attrib->m_buttonText = "...";
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimAbstractCorrelationPlot::userDescriptionField()
|
||||
{
|
||||
return &m_description;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo>
|
||||
RimAbstractCorrelationPlot::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options = RimPlot::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
||||
|
||||
if ( fieldNeedingOptions == &m_timeStep )
|
||||
{
|
||||
std::set<time_t> allTimeSteps = allAvailableTimeSteps();
|
||||
if ( allTimeSteps.empty() )
|
||||
{
|
||||
return options;
|
||||
}
|
||||
|
||||
std::vector<QDateTime> allDateTimes;
|
||||
for ( time_t timeStep : allTimeSteps )
|
||||
{
|
||||
QDateTime dateTime = RiaQDateTimeTools::fromTime_t( timeStep );
|
||||
allDateTimes.push_back( dateTime );
|
||||
}
|
||||
|
||||
std::vector<int> filteredTimeStepIndices =
|
||||
RimTimeStepFilter::filteredTimeStepIndices( allDateTimes, 0, (int)allDateTimes.size() - 1, m_timeStepFilter(), 1 );
|
||||
|
||||
QString dateFormatString = RiaQDateTimeTools::dateFormatString( RiaPreferences::current()->dateFormat(),
|
||||
RiaQDateTimeTools::DATE_FORMAT_YEAR_MONTH_DAY );
|
||||
QString timeFormatString =
|
||||
RiaQDateTimeTools::timeFormatString( RiaPreferences::current()->timeFormat(),
|
||||
RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_HOUR_MINUTE );
|
||||
QString dateTimeFormatString = QString( "%1 %2" ).arg( dateFormatString ).arg( timeFormatString );
|
||||
|
||||
bool showTime = m_timeStepFilter == RimTimeStepFilter::TS_ALL || RimTimeStepFilter::TS_INTERVAL_DAYS;
|
||||
|
||||
for ( auto timeStepIndex : filteredTimeStepIndices )
|
||||
{
|
||||
QDateTime dateTime = allDateTimes[timeStepIndex];
|
||||
|
||||
if ( showTime && dateTime.time() != QTime( 0, 0, 0 ) )
|
||||
{
|
||||
options.push_back(
|
||||
caf::PdmOptionItemInfo( RiaQDateTimeTools::toStringUsingApplicationLocale( dateTime,
|
||||
dateTimeFormatString ),
|
||||
dateTime ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
options.push_back(
|
||||
caf::PdmOptionItemInfo( RiaQDateTimeTools::toStringUsingApplicationLocale( dateTime, dateFormatString ),
|
||||
dateTime ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_labelFontSize || fieldNeedingOptions == &m_axisTitleFontSize ||
|
||||
fieldNeedingOptions == &m_axisValueFontSize )
|
||||
{
|
||||
options = caf::FontTools::relativeSizeValueOptions( RiaPreferences::current()->defaultPlotFontSize() );
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<time_t> RimAbstractCorrelationPlot::allAvailableTimeSteps()
|
||||
{
|
||||
std::set<time_t> timeStepUnion;
|
||||
|
||||
RiaSummaryCurveDefinitionAnalyser* analyserOfSelectedCurveDefs = getOrCreateSelectedCurveDefAnalyser();
|
||||
for ( RimSummaryCaseCollection* ensemble : analyserOfSelectedCurveDefs->m_ensembles )
|
||||
{
|
||||
const std::set<time_t>& timeSteps = ensemble->ensembleTimeSteps();
|
||||
timeStepUnion.insert( timeSteps.begin(), timeSteps.end() );
|
||||
}
|
||||
|
||||
return timeStepUnion;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RiaSummaryCurveDefinition> RimAbstractCorrelationPlot::curveDefinitions() const
|
||||
{
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefs;
|
||||
for ( auto dataEntry : m_analysisPlotDataSelection )
|
||||
{
|
||||
curveDefs.push_back( dataEntry->curveDefinition() );
|
||||
}
|
||||
|
||||
return curveDefs;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaSummaryCurveDefinitionAnalyser* RimAbstractCorrelationPlot::getOrCreateSelectedCurveDefAnalyser()
|
||||
{
|
||||
if ( !m_analyserOfSelectedCurveDefs )
|
||||
{
|
||||
m_analyserOfSelectedCurveDefs =
|
||||
std::unique_ptr<RiaSummaryCurveDefinitionAnalyser>( new RiaSummaryCurveDefinitionAnalyser );
|
||||
}
|
||||
|
||||
m_analyserOfSelectedCurveDefs->setCurveDefinitions( this->curveDefinitions() );
|
||||
return m_analyserOfSelectedCurveDefs.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseSummaryAddress> RimAbstractCorrelationPlot::addresses()
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> addresses;
|
||||
|
||||
for ( auto dataEntry : m_analysisPlotDataSelection )
|
||||
{
|
||||
addresses.insert( dataEntry->summaryAddress() );
|
||||
}
|
||||
|
||||
return addresses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RimSummaryCaseCollection*> RimAbstractCorrelationPlot::ensembles()
|
||||
{
|
||||
RiaSummaryCurveDefinitionAnalyser* analyserOfSelectedCurveDefs = getOrCreateSelectedCurveDefAnalyser();
|
||||
return analyserOfSelectedCurveDefs->m_ensembles;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<EnsembleParameter> RimAbstractCorrelationPlot::ensembleParameters()
|
||||
{
|
||||
std::set<EnsembleParameter> ensembleParms;
|
||||
|
||||
RiaSummaryCurveDefinitionAnalyser* analyserOfSelectedCurveDefs = getOrCreateSelectedCurveDefAnalyser();
|
||||
|
||||
for ( RimSummaryCaseCollection* ensemble : analyserOfSelectedCurveDefs->m_ensembles )
|
||||
{
|
||||
std::vector<EnsembleParameter> parameters = ensemble->alphabeticEnsembleParameters();
|
||||
ensembleParms.insert( parameters.begin(), parameters.end() );
|
||||
}
|
||||
return ensembleParms;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<EnsembleParameter> RimAbstractCorrelationPlot::variationSortedEnsembleParameters()
|
||||
{
|
||||
std::set<EnsembleParameter> ensembleParms;
|
||||
|
||||
RiaSummaryCurveDefinitionAnalyser* analyserOfSelectedCurveDefs = getOrCreateSelectedCurveDefAnalyser();
|
||||
|
||||
for ( RimSummaryCaseCollection* ensemble : analyserOfSelectedCurveDefs->m_ensembles )
|
||||
{
|
||||
std::vector<EnsembleParameter> parameters = ensemble->variationSortedEnsembleParameters();
|
||||
ensembleParms.insert( parameters.begin(), parameters.end() );
|
||||
}
|
||||
return ensembleParms;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
EnsembleParameter RimAbstractCorrelationPlot::ensembleParameter( const QString& ensembleParameterName )
|
||||
{
|
||||
std::set<EnsembleParameter> ensembleParms = ensembleParameters();
|
||||
for ( const EnsembleParameter& eParam : ensembleParms )
|
||||
{
|
||||
if ( eParam.name == ensembleParameterName ) return eParam;
|
||||
}
|
||||
|
||||
return EnsembleParameter();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* RimAbstractCorrelationPlot::viewWidget()
|
||||
{
|
||||
return m_plotWidget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::deleteViewWidget()
|
||||
{
|
||||
cleanupBeforeClose();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QImage RimAbstractCorrelationPlot::snapshotWindowContent()
|
||||
{
|
||||
QImage image;
|
||||
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
QPixmap pix = m_plotWidget->grab();
|
||||
image = pix.toImage();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimAbstractCorrelationPlot::description() const
|
||||
{
|
||||
return m_description();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuQwtPlotWidget* RimAbstractCorrelationPlot::doCreatePlotViewWidget( QWidget* mainWindowParent /*= nullptr */ )
|
||||
{
|
||||
if ( !m_plotWidget )
|
||||
{
|
||||
m_plotWidget = new RiuQwtPlotWidget( this, mainWindowParent );
|
||||
updatePlotTitle();
|
||||
}
|
||||
|
||||
return m_plotWidget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiuQwtPlotWidget* RimAbstractCorrelationPlot::viewer()
|
||||
{
|
||||
return m_plotWidget;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::detachAllCurves()
|
||||
{
|
||||
if ( m_plotWidget ) m_plotWidget->detachItems();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QDateTime RimAbstractCorrelationPlot::timeStep() const
|
||||
{
|
||||
return m_timeStep();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimAbstractCorrelationPlot::timeStepString() const
|
||||
{
|
||||
QString dateFormatString = RiaQDateTimeTools::dateFormatString( RiaPreferences::current()->dateFormat(),
|
||||
RiaQDateTimeTools::DATE_FORMAT_YEAR_MONTH_DAY );
|
||||
QString timeFormatString =
|
||||
RiaQDateTimeTools::timeFormatString( RiaPreferences::current()->timeFormat(),
|
||||
RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_HOUR_MINUTE );
|
||||
|
||||
return timeStep().toString( dateFormatString ) + " " + timeStep().toString( timeFormatString );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimAbstractCorrelationPlot::labelFontSize() const
|
||||
{
|
||||
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_labelFontSize() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimAbstractCorrelationPlot::axisTitleFontSize() const
|
||||
{
|
||||
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisTitleFontSize() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimAbstractCorrelationPlot::axisValueFontSize() const
|
||||
{
|
||||
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisValueFontSize() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::setLabelFontSize( caf::FontTools::RelativeSize fontSize )
|
||||
{
|
||||
m_labelFontSize = fontSize;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::setAxisTitleFontSize( caf::FontTools::RelativeSize fontSize )
|
||||
{
|
||||
m_axisTitleFontSize = fontSize;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::setAxisValueFontSize( caf::FontTools::RelativeSize fontSize )
|
||||
{
|
||||
m_axisValueFontSize = fontSize;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::updateLegend()
|
||||
{
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
m_plotWidget->insertLegend( nullptr );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::cleanupBeforeClose()
|
||||
{
|
||||
detachAllCurves();
|
||||
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
m_plotWidget->setParent( nullptr );
|
||||
delete m_plotWidget;
|
||||
m_plotWidget = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
time_t RimAbstractCorrelationPlot::timeDiff( time_t lhs, time_t rhs )
|
||||
{
|
||||
if ( lhs >= rhs )
|
||||
{
|
||||
return lhs - rhs;
|
||||
}
|
||||
return rhs - lhs;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimAbstractCorrelationPlot::selectedVarsText()
|
||||
{
|
||||
QString vectorNames;
|
||||
for ( const std::string& quantityName : getOrCreateSelectedCurveDefAnalyser()->m_quantityNames )
|
||||
{
|
||||
vectorNames += QString::fromStdString( quantityName ) + ", ";
|
||||
}
|
||||
|
||||
if ( !vectorNames.isEmpty() )
|
||||
{
|
||||
vectorNames.chop( 2 );
|
||||
}
|
||||
|
||||
return vectorNames;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::initAfterRead()
|
||||
{
|
||||
connectAllCaseSignals();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::onCaseRemoved( const SignalEmitter* emitter, RimSummaryCase* summaryCase )
|
||||
{
|
||||
loadDataAndUpdate();
|
||||
if ( m_plotWidget ) m_plotWidget->scheduleReplot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAbstractCorrelationPlot::connectAllCaseSignals()
|
||||
{
|
||||
for ( auto dataEntry : m_analysisPlotDataSelection )
|
||||
{
|
||||
if ( dataEntry->ensemble() )
|
||||
{
|
||||
dataEntry->ensemble()->caseRemoved.connect( this, &RimAbstractCorrelationPlot::onCaseRemoved );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,143 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "RifEclipseSummaryAddressQMetaType.h"
|
||||
|
||||
#include "RimPlot.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimTimeStepFilter.h"
|
||||
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include <QString>
|
||||
|
||||
#include <ctime>
|
||||
|
||||
class RiaSummaryCurveDefinition;
|
||||
class RiaSummaryCurveDefinitionAnalyser;
|
||||
class RimAnalysisPlotDataEntry;
|
||||
class RimSummaryAddress;
|
||||
|
||||
class RimAbstractCorrelationPlot : public RimPlot
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
using TimeStepFilterEnum = caf::AppEnum<RimTimeStepFilter::TimeStepFilterTypeEnum>;
|
||||
|
||||
public:
|
||||
RimAbstractCorrelationPlot();
|
||||
~RimAbstractCorrelationPlot() override;
|
||||
|
||||
public:
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefinitions() const;
|
||||
void setCurveDefinitions( const std::vector<RiaSummaryCurveDefinition>& curveDefinitions );
|
||||
void setTimeStep( std::time_t timeStep );
|
||||
std::set<RimSummaryCaseCollection*> ensembles();
|
||||
RiuQwtPlotWidget* viewer() override;
|
||||
void detachAllCurves() override;
|
||||
QDateTime timeStep() const;
|
||||
QString timeStepString() const;
|
||||
|
||||
int labelFontSize() const;
|
||||
int axisTitleFontSize() const;
|
||||
int axisValueFontSize() const;
|
||||
|
||||
void setLabelFontSize( caf::FontTools::RelativeSize fontSize );
|
||||
void setAxisTitleFontSize( caf::FontTools::RelativeSize fontSize );
|
||||
void setAxisValueFontSize( caf::FontTools::RelativeSize fontSize );
|
||||
std::set<time_t> allAvailableTimeSteps();
|
||||
|
||||
protected:
|
||||
// Overridden PDM methods
|
||||
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly ) override;
|
||||
|
||||
RiaSummaryCurveDefinitionAnalyser* getOrCreateSelectedCurveDefAnalyser();
|
||||
|
||||
std::set<RifEclipseSummaryAddress> addresses();
|
||||
std::set<EnsembleParameter> ensembleParameters();
|
||||
std::set<EnsembleParameter> variationSortedEnsembleParameters();
|
||||
EnsembleParameter ensembleParameter( const QString& ensembleParameterName );
|
||||
|
||||
// RimViewWindow overrides
|
||||
QWidget* viewWidget() override;
|
||||
void deleteViewWidget() override;
|
||||
void zoomAll() override {}
|
||||
QImage snapshotWindowContent() override;
|
||||
|
||||
// RimPlotWindow overrides
|
||||
QString description() const override;
|
||||
void doUpdateLayout() override {}
|
||||
|
||||
// RimPlot Overrides
|
||||
RiuQwtPlotWidget* doCreatePlotViewWidget( QWidget* mainWindowParent = nullptr ) override;
|
||||
|
||||
void reattachAllCurves() override {}
|
||||
void updateZoomInQwt() override {}
|
||||
void updateZoomFromQwt() override {}
|
||||
void setAutoScaleXEnabled( bool enabled ) override {}
|
||||
void setAutoScaleYEnabled( bool enabled ) override {}
|
||||
void updateLegend() override;
|
||||
|
||||
QString asciiDataForPlotExport() const override { return ""; }
|
||||
caf::PdmObject* findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const override { return nullptr; }
|
||||
|
||||
void cleanupBeforeClose();
|
||||
virtual void updatePlotTitle() = 0;
|
||||
|
||||
static time_t timeDiff( time_t lhs, time_t rhs );
|
||||
|
||||
QString selectedVarsText();
|
||||
|
||||
void initAfterRead() final;
|
||||
|
||||
private:
|
||||
void onCaseRemoved( const SignalEmitter* emitter, RimSummaryCase* summaryCase );
|
||||
void connectAllCaseSignals();
|
||||
|
||||
protected:
|
||||
std::unique_ptr<RiaSummaryCurveDefinitionAnalyser> m_analyserOfSelectedCurveDefs;
|
||||
QPointer<RiuQwtPlotWidget> m_plotWidget;
|
||||
|
||||
bool m_selectMultipleVectors;
|
||||
|
||||
// Fields
|
||||
caf::PdmChildArrayField<RimAnalysisPlotDataEntry*> m_analysisPlotDataSelection;
|
||||
|
||||
caf::PdmField<QString> m_selectedVarsUiField;
|
||||
caf::PdmField<bool> m_pushButtonSelectSummaryAddress;
|
||||
caf::PdmField<TimeStepFilterEnum> m_timeStepFilter;
|
||||
caf::PdmField<QDateTime> m_timeStep;
|
||||
|
||||
caf::PdmField<bool> m_useAutoPlotTitle;
|
||||
caf::PdmField<QString> m_description;
|
||||
|
||||
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_labelFontSize;
|
||||
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_axisTitleFontSize;
|
||||
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_axisValueFontSize;
|
||||
};
|
||||
@@ -0,0 +1,694 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimCorrelationMatrixPlot.h"
|
||||
|
||||
#include "RiaColorTools.h"
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaQDateTimeTools.h"
|
||||
#include "RiaStatisticsTools.h"
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
#include "RiuQwtLinearScaleEngine.h"
|
||||
#include "RiuQwtPlotTools.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include "RimDerivedSummaryCase.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimPlotAxisProperties.h"
|
||||
#include "RimPlotAxisPropertiesInterface.h"
|
||||
#include "RimPlotDataFilterCollection.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimSummaryPlotAxisFormatter.h"
|
||||
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
#include "cafPdmUiTreeSelectionEditor.h"
|
||||
|
||||
#include "cvfScalarMapper.h"
|
||||
|
||||
#include "qwt_plot_marker.h"
|
||||
#include "qwt_plot_shapeitem.h"
|
||||
#include "qwt_scale_draw.h"
|
||||
#include "qwt_text.h"
|
||||
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void caf::AppEnum<RimCorrelationMatrixPlot::Sorting>::setUp()
|
||||
{
|
||||
addItem( RimCorrelationMatrixPlot::Sorting::NO_SORTING, "NO_SORTING", "No Sorting" );
|
||||
addItem( RimCorrelationMatrixPlot::Sorting::ROWS, "SORT_ROWS", "Sort Rows" );
|
||||
addItem( RimCorrelationMatrixPlot::Sorting::COLUMNS, "SORT_COLUMNS", "Sort Columns" );
|
||||
addItem( RimCorrelationMatrixPlot::Sorting::BOTH, "SORT_BOTH", "Sort Both Rows/Columns" );
|
||||
setDefault( RimCorrelationMatrixPlot::Sorting::BOTH );
|
||||
}
|
||||
} // namespace caf
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimCorrelationMatrixPlot, "CorrelationMatrixPlot" );
|
||||
|
||||
class CorrelationMatrixShapeItem : public QwtPlotShapeItem
|
||||
{
|
||||
public:
|
||||
CorrelationMatrixShapeItem( const QString& title = QString() )
|
||||
: QwtPlotShapeItem( title )
|
||||
{
|
||||
}
|
||||
|
||||
public:
|
||||
QString parameter;
|
||||
RiaSummaryCurveDefinition curveDef;
|
||||
};
|
||||
|
||||
class TextScaleDraw : public QwtScaleDraw
|
||||
{
|
||||
public:
|
||||
TextScaleDraw( const std::map<size_t, QString>& tickLabels )
|
||||
: m_tickLabels( tickLabels )
|
||||
{
|
||||
}
|
||||
|
||||
QwtText label( double value ) const override
|
||||
{
|
||||
size_t intValue = static_cast<size_t>( value + 0.25 );
|
||||
auto it = m_tickLabels.find( intValue );
|
||||
return it != m_tickLabels.end() ? it->second : "";
|
||||
}
|
||||
|
||||
private:
|
||||
std::map<size_t, QString> m_tickLabels;
|
||||
};
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
class CorrelationMatrixRowOrColumn
|
||||
{
|
||||
public:
|
||||
CorrelationMatrixRowOrColumn( const KeyType& key,
|
||||
const std::vector<double>& correlations,
|
||||
const std::vector<ValueType>& values )
|
||||
: m_key( key )
|
||||
, m_correlations( correlations )
|
||||
, m_values( values )
|
||||
, m_correlationSum( 0.0 )
|
||||
, m_correlationAbsSum( 0.0 )
|
||||
{
|
||||
bool anyValid = false;
|
||||
for ( auto value : correlations )
|
||||
{
|
||||
if ( RiaCurveDataTools::isValidValue( value, false ) )
|
||||
{
|
||||
m_correlationSum += value;
|
||||
m_correlationAbsSum += std::abs( value );
|
||||
anyValid = true;
|
||||
}
|
||||
}
|
||||
if ( !anyValid )
|
||||
{
|
||||
m_correlationSum = std::numeric_limits<double>::infinity();
|
||||
m_correlationAbsSum = std::numeric_limits<double>::infinity();
|
||||
}
|
||||
}
|
||||
|
||||
KeyType m_key;
|
||||
std::vector<double> m_correlations;
|
||||
std::vector<ValueType> m_values;
|
||||
double m_correlationSum;
|
||||
double m_correlationAbsSum;
|
||||
};
|
||||
|
||||
using CorrelationMatrixColumn = CorrelationMatrixRowOrColumn<QString, RiaSummaryCurveDefinition>;
|
||||
using CorrelationMatrixRow = CorrelationMatrixRowOrColumn<RiaSummaryCurveDefinition, QString>;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationMatrixPlot::RimCorrelationMatrixPlot()
|
||||
: RimAbstractCorrelationPlot()
|
||||
, matrixCellSelected( this )
|
||||
{
|
||||
CAF_PDM_InitObject( "Correlation Plot", ":/CorrelationMatrixPlot16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_showAbsoluteValues, "CorrelationAbsValues", false, "Show Absolute Values", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_sortByValues, "CorrelationSorting", "Sort Matrix by Values", "", "", "" );
|
||||
CAF_PDM_InitField( &m_sortByAbsoluteValues, "CorrelationAbsSorting", true, "Sort by Absolute Values", "", "", "" );
|
||||
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", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_legendConfig, "LegendConfig", "", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_selectedParametersList, "SelectedParameters", "Select Parameters", "", "", "" );
|
||||
m_selectedParametersList.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
|
||||
m_selectedParametersList.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
|
||||
|
||||
m_legendConfig = new RimRegularLegendConfig();
|
||||
m_legendConfig->setAutomaticRanges( -1.0, 1.0, -1.0, 1.0 );
|
||||
m_legendConfig->setColorLegend(
|
||||
RimRegularLegendConfig::mapToColorLegend( RimRegularLegendConfig::ColorRangesType::RED_WHITE_BLUE ) );
|
||||
|
||||
setLegendsVisible( false );
|
||||
|
||||
this->uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_selectMultipleVectors = true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationMatrixPlot::~RimCorrelationMatrixPlot()
|
||||
{
|
||||
if ( isMdiWindow() ) removeMdiWindowFromMdiArea();
|
||||
|
||||
cleanupBeforeClose();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCorrelationMatrixPlot::showAbsoluteValues() const
|
||||
{
|
||||
return m_showAbsoluteValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCorrelationMatrixPlot::sortByAbsoluteValues() const
|
||||
{
|
||||
return m_sortByAbsoluteValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimRegularLegendConfig* RimCorrelationMatrixPlot::legendConfig()
|
||||
{
|
||||
return m_legendConfig();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::selectAllParameters()
|
||||
{
|
||||
m_selectedParametersList.v().clear();
|
||||
std::set<EnsembleParameter> params = variationSortedEnsembleParameters();
|
||||
for ( auto param : params )
|
||||
{
|
||||
if ( !m_excludeParametersWithoutVariation() || param.variationBin > EnsembleParameter::NO_VARIATION )
|
||||
{
|
||||
m_selectedParametersList.v().push_back( param.name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCorrelationMatrixPlot::showTopNCorrelations() const
|
||||
{
|
||||
return m_showOnlyTopNCorrelations();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimCorrelationMatrixPlot::topNFilterCount() const
|
||||
{
|
||||
return m_topNFilterCount();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
RimAbstractCorrelationPlot::fieldChangedByUi( changedField, oldValue, newValue );
|
||||
|
||||
bool sendSelectedSignal = false;
|
||||
|
||||
if ( changedField == &m_showAbsoluteValues || changedField == &m_sortByValues ||
|
||||
changedField == &m_sortByAbsoluteValues || changedField == &m_showOnlyTopNCorrelations ||
|
||||
changedField == &m_topNFilterCount || changedField == &m_excludeParametersWithoutVariation ||
|
||||
changedField == &m_selectedParametersList )
|
||||
{
|
||||
if ( changedField == &m_excludeParametersWithoutVariation )
|
||||
{
|
||||
selectAllParameters();
|
||||
}
|
||||
updateLegend();
|
||||
loadDataAndUpdate();
|
||||
updateConnectedEditors();
|
||||
sendSelectedSignal = true;
|
||||
}
|
||||
|
||||
if ( changedField == &m_pushButtonSelectSummaryAddress )
|
||||
{
|
||||
sendSelectedSignal = true;
|
||||
}
|
||||
|
||||
if ( sendSelectedSignal )
|
||||
{
|
||||
auto curves = curveDefinitions();
|
||||
auto parameters = m_selectedParametersList();
|
||||
if ( !curves.empty() && !parameters.empty() )
|
||||
{
|
||||
auto firstCurve = curves.front();
|
||||
auto firstParameter = parameters.front();
|
||||
|
||||
matrixCellSelected.send( { firstParameter, firstCurve } );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
caf::PdmUiGroup* correlationGroup = uiOrdering.addNewGroup( "Correlation Settings" );
|
||||
correlationGroup->add( &m_excludeParametersWithoutVariation );
|
||||
correlationGroup->add( &m_selectedParametersList );
|
||||
correlationGroup->add( &m_showAbsoluteValues );
|
||||
correlationGroup->add( &m_sortByValues );
|
||||
if ( !m_showAbsoluteValues() && m_sortByValues() != Sorting::NO_SORTING )
|
||||
{
|
||||
correlationGroup->add( &m_sortByAbsoluteValues );
|
||||
}
|
||||
if ( m_sortByValues() != Sorting::NO_SORTING )
|
||||
{
|
||||
correlationGroup->add( &m_showOnlyTopNCorrelations );
|
||||
if ( m_showOnlyTopNCorrelations() )
|
||||
{
|
||||
correlationGroup->add( &m_topNFilterCount );
|
||||
}
|
||||
}
|
||||
|
||||
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector" );
|
||||
m_selectedVarsUiField = selectedVarsText();
|
||||
|
||||
curveDataGroup->add( &m_selectedVarsUiField );
|
||||
curveDataGroup->add( &m_pushButtonSelectSummaryAddress, { false, 1, 0 } );
|
||||
curveDataGroup->add( &m_timeStepFilter );
|
||||
curveDataGroup->add( &m_timeStep );
|
||||
|
||||
if ( uiConfigName != "report" )
|
||||
{
|
||||
caf::PdmUiGroup* plotGroup = uiOrdering.addNewGroup( "Plot Settings" );
|
||||
plotGroup->add( &m_showPlotTitle );
|
||||
plotGroup->add( &m_useAutoPlotTitle );
|
||||
plotGroup->add( &m_description );
|
||||
m_description.uiCapability()->setUiReadOnly( m_useAutoPlotTitle() );
|
||||
RimPlot::defineUiOrdering( uiConfigName, *plotGroup );
|
||||
|
||||
plotGroup->add( &m_titleFontSize );
|
||||
plotGroup->add( &m_labelFontSize );
|
||||
plotGroup->add( &m_axisTitleFontSize );
|
||||
plotGroup->add( &m_axisValueFontSize );
|
||||
m_legendConfig->uiOrdering( "ColorsOnly", *plotGroup );
|
||||
}
|
||||
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo>
|
||||
RimCorrelationMatrixPlot::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options =
|
||||
RimAbstractCorrelationPlot::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
||||
|
||||
if ( fieldNeedingOptions == &m_selectedParametersList )
|
||||
{
|
||||
std::set<EnsembleParameter> params = variationSortedEnsembleParameters();
|
||||
for ( auto param : params )
|
||||
{
|
||||
if ( !m_excludeParametersWithoutVariation() || param.variationBin > EnsembleParameter::NO_VARIATION )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( param.uiName(), param.name ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::onLoadDataAndUpdate()
|
||||
{
|
||||
updateMdiWindowVisibility();
|
||||
|
||||
m_selectedVarsUiField = selectedVarsText();
|
||||
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
m_plotWidget->detachItems( QwtPlotItem::Rtti_PlotBarChart );
|
||||
m_plotWidget->detachItems( QwtPlotItem::Rtti_PlotScale );
|
||||
m_plotWidget->detachItems( QwtPlotItem::Rtti_PlotItem );
|
||||
|
||||
updateLegend();
|
||||
createMatrix();
|
||||
|
||||
m_plotWidget->insertLegend( nullptr );
|
||||
|
||||
this->updateAxes();
|
||||
this->updatePlotTitle();
|
||||
m_plotWidget->scheduleReplot();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::childFieldChangedByUi( const caf::PdmFieldHandle* changedChildField )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::updateAxes()
|
||||
{
|
||||
if ( !m_plotWidget ) return;
|
||||
|
||||
m_plotWidget->setAxisScaleDraw( QwtPlot::yLeft, new TextScaleDraw( m_resultLabels ) );
|
||||
m_plotWidget->setAxisScaleEngine( QwtPlot::yLeft, new RiuQwtLinearScaleEngine );
|
||||
m_plotWidget->setAxisTitleText( QwtPlot::yLeft, "Result Vector" );
|
||||
m_plotWidget->setAxisTitleEnabled( QwtPlot::yLeft, true );
|
||||
m_plotWidget->setAxisFontsAndAlignment( QwtPlot::yLeft, axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
|
||||
m_plotWidget->setAxisLabelsAndTicksEnabled( QwtPlot::yLeft, true, false );
|
||||
m_plotWidget->setAxisRange( QwtPlot::yLeft, 0.0, (double)m_resultLabels.size() + 1 );
|
||||
m_plotWidget->setMajorAndMinorTickIntervalsAndRange( QwtPlot::yLeft,
|
||||
1.0,
|
||||
0.0,
|
||||
0.5,
|
||||
(double)m_resultLabels.size() - 0.5,
|
||||
0.0,
|
||||
m_resultLabels.size() );
|
||||
|
||||
auto scaleDraw = new TextScaleDraw( m_paramLabels );
|
||||
scaleDraw->setLabelRotation( 30.0 );
|
||||
m_plotWidget->setAxisScaleDraw( QwtPlot::xBottom, scaleDraw );
|
||||
|
||||
m_plotWidget->setAxisScaleEngine( QwtPlot::xBottom, new RiuQwtLinearScaleEngine );
|
||||
m_plotWidget->setAxisTitleText( QwtPlot::xBottom, "Ensemble Parameter" );
|
||||
m_plotWidget->setAxisTitleEnabled( QwtPlot::xBottom, true );
|
||||
m_plotWidget->setAxisFontsAndAlignment( QwtPlot::xBottom,
|
||||
axisTitleFontSize(),
|
||||
axisValueFontSize(),
|
||||
false,
|
||||
Qt::AlignCenter | Qt::AlignTop );
|
||||
m_plotWidget->setAxisLabelsAndTicksEnabled( QwtPlot::xBottom, true, false );
|
||||
m_plotWidget->setAxisRange( QwtPlot::xBottom, 0.0, (double)m_paramLabels.size() + 1 );
|
||||
m_plotWidget->setMajorAndMinorTickIntervalsAndRange( QwtPlot::xBottom,
|
||||
1.0,
|
||||
0.0,
|
||||
0.5,
|
||||
(double)m_paramLabels.size() - 0.5,
|
||||
0.0,
|
||||
(double)m_paramLabels.size() );
|
||||
|
||||
m_plotWidget->setAxisLabelAlignment( QwtPlot::xBottom, Qt::AlignRight );
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
void eraseInvalidEntries( std::vector<CorrelationMatrixRowOrColumn<KeyType, ValueType>>& matrix )
|
||||
{
|
||||
matrix.erase( std::remove_if( matrix.begin(),
|
||||
matrix.end(),
|
||||
[=]( const CorrelationMatrixRowOrColumn<KeyType, ValueType>& entry ) {
|
||||
bool isValid = RiaCurveDataTools::isValidValue( entry.m_correlationSum, false );
|
||||
return !isValid;
|
||||
} ),
|
||||
matrix.end() );
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
void sortEntries( std::vector<CorrelationMatrixRowOrColumn<KeyType, ValueType>>& matrix, bool sortByAbsoluteValues )
|
||||
{
|
||||
std::sort( matrix.begin(),
|
||||
matrix.end(),
|
||||
[&sortByAbsoluteValues]( const CorrelationMatrixRowOrColumn<KeyType, ValueType>& lhs,
|
||||
const CorrelationMatrixRowOrColumn<KeyType, ValueType>& rhs ) -> bool {
|
||||
if ( sortByAbsoluteValues )
|
||||
return lhs.m_correlationAbsSum > rhs.m_correlationAbsSum;
|
||||
else
|
||||
return lhs.m_correlationSum > rhs.m_correlationSum;
|
||||
} );
|
||||
}
|
||||
|
||||
template <typename KeyType, typename ValueType>
|
||||
std::vector<CorrelationMatrixRowOrColumn<ValueType, KeyType>>
|
||||
transpose( const std::vector<CorrelationMatrixRowOrColumn<KeyType, ValueType>>& matrix )
|
||||
{
|
||||
std::vector<CorrelationMatrixRowOrColumn<ValueType, KeyType>> transposedMatrix;
|
||||
|
||||
for ( size_t rowIdx = 0u; !matrix.empty() && rowIdx < matrix[0].m_correlations.size(); ++rowIdx )
|
||||
{
|
||||
ValueType key = matrix[0].m_values[rowIdx];
|
||||
std::vector<double> correlations;
|
||||
std::vector<KeyType> values;
|
||||
for ( size_t colIdx = 0u; colIdx < matrix.size(); ++colIdx )
|
||||
{
|
||||
correlations.push_back( matrix[colIdx].m_correlations[rowIdx] );
|
||||
values.push_back( matrix[colIdx].m_key );
|
||||
}
|
||||
transposedMatrix.push_back( CorrelationMatrixRowOrColumn<ValueType, KeyType>( key, correlations, values ) );
|
||||
}
|
||||
return transposedMatrix;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::createMatrix()
|
||||
{
|
||||
time_t selectedTimestep = m_timeStep().toTime_t();
|
||||
|
||||
m_paramLabels.clear();
|
||||
m_resultLabels.clear();
|
||||
|
||||
auto curveDefs = curveDefinitions();
|
||||
if ( curveDefs.empty() ) return;
|
||||
|
||||
QStringList ensembleNames;
|
||||
|
||||
std::vector<CorrelationMatrixColumn> correlationMatrixColumns;
|
||||
|
||||
for ( QString paramName : m_selectedParametersList() )
|
||||
{
|
||||
bool anyValidResults = false;
|
||||
std::vector<double> correlations;
|
||||
std::vector<RiaSummaryCurveDefinition> selectedCurveDefs;
|
||||
|
||||
for ( auto curveDef : curveDefs )
|
||||
{
|
||||
auto ensemble = curveDef.ensemble();
|
||||
auto address = curveDef.summaryAddress();
|
||||
|
||||
if ( ensemble )
|
||||
{
|
||||
std::vector<double> caseValuesAtTimestep;
|
||||
std::vector<double> parameterValues;
|
||||
|
||||
EnsembleParameter parameter = ensemble->ensembleParameter( paramName );
|
||||
|
||||
if ( parameter.isValid() )
|
||||
{
|
||||
double correlation = std::numeric_limits<double>::infinity();
|
||||
|
||||
for ( size_t caseIdx = 0u; caseIdx < ensemble->allSummaryCases().size(); ++caseIdx )
|
||||
{
|
||||
auto summaryCase = ensemble->allSummaryCases()[caseIdx];
|
||||
RifSummaryReaderInterface* reader = summaryCase->summaryReader();
|
||||
if ( reader )
|
||||
{
|
||||
std::vector<double> values;
|
||||
double closestValue = std::numeric_limits<double>::infinity();
|
||||
time_t closestTimeStep = 0;
|
||||
if ( reader->values( address, &values ) )
|
||||
{
|
||||
const std::vector<time_t>& timeSteps = reader->timeSteps( address );
|
||||
for ( size_t i = 0; i < timeSteps.size(); ++i )
|
||||
{
|
||||
if ( timeDiff( timeSteps[i], selectedTimestep ) <
|
||||
timeDiff( selectedTimestep, closestTimeStep ) )
|
||||
{
|
||||
closestValue = values[i];
|
||||
closestTimeStep = timeSteps[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( closestValue != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
caseValuesAtTimestep.push_back( closestValue );
|
||||
double paramValue = parameter.values[caseIdx].toDouble();
|
||||
parameterValues.push_back( paramValue );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( parameterValues.empty() ) continue;
|
||||
|
||||
correlation = RiaStatisticsTools::pearsonCorrelation( parameterValues, caseValuesAtTimestep );
|
||||
|
||||
bool validResult = RiaCurveDataTools::isValidValue( correlation, false );
|
||||
if ( validResult )
|
||||
{
|
||||
if ( m_showAbsoluteValues() ) correlation = std::abs( correlation );
|
||||
anyValidResults = true;
|
||||
}
|
||||
correlations.push_back( correlation );
|
||||
selectedCurveDefs.push_back( curveDef );
|
||||
ensembleNames.push_back( ensemble->name() );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( anyValidResults )
|
||||
{
|
||||
correlationMatrixColumns.push_back( CorrelationMatrixColumn( paramName, correlations, selectedCurveDefs ) );
|
||||
}
|
||||
}
|
||||
|
||||
eraseInvalidEntries( correlationMatrixColumns );
|
||||
if ( m_sortByValues() == Sorting::COLUMNS || m_sortByValues() == Sorting::BOTH )
|
||||
{
|
||||
sortEntries( correlationMatrixColumns, m_sortByAbsoluteValues() || m_showAbsoluteValues() );
|
||||
|
||||
if ( m_showOnlyTopNCorrelations && (size_t)m_topNFilterCount < correlationMatrixColumns.size() )
|
||||
{
|
||||
correlationMatrixColumns.erase( correlationMatrixColumns.begin() + m_topNFilterCount(),
|
||||
correlationMatrixColumns.end() );
|
||||
}
|
||||
}
|
||||
|
||||
auto correlationMatrixRows = transpose( correlationMatrixColumns );
|
||||
|
||||
eraseInvalidEntries( correlationMatrixRows );
|
||||
if ( m_sortByValues() == Sorting::ROWS || m_sortByValues() == Sorting::BOTH )
|
||||
{
|
||||
sortEntries( correlationMatrixRows, m_sortByAbsoluteValues() || m_showAbsoluteValues() );
|
||||
|
||||
if ( m_showOnlyTopNCorrelations && (size_t)m_topNFilterCount < correlationMatrixRows.size() )
|
||||
{
|
||||
correlationMatrixRows.erase( correlationMatrixRows.begin() + m_topNFilterCount(), correlationMatrixRows.end() );
|
||||
}
|
||||
}
|
||||
|
||||
ensembleNames.removeDuplicates();
|
||||
QString combinedEnsembleNames = ensembleNames.join( ";; " );
|
||||
for ( size_t rowIdx = 0u; rowIdx < correlationMatrixRows.size(); ++rowIdx )
|
||||
{
|
||||
for ( size_t colIdx = 0u; colIdx < correlationMatrixRows[rowIdx].m_correlations.size(); ++colIdx )
|
||||
{
|
||||
double correlation = correlationMatrixRows[rowIdx].m_correlations[colIdx];
|
||||
auto label = QString( "%1" ).arg( correlation, 0, 'f', 2 );
|
||||
|
||||
cvf::Color3ub color = m_legendConfig->scalarMapper()->mapToColor( correlation );
|
||||
QColor qColor( color.r(), color.g(), color.b() );
|
||||
auto rectangle = RiuQwtPlotTools::createBoxShapeT<CorrelationMatrixShapeItem>( label,
|
||||
(double)colIdx,
|
||||
(double)colIdx + 1.0,
|
||||
(double)rowIdx,
|
||||
(double)rowIdx + 1,
|
||||
qColor );
|
||||
rectangle->curveDef = correlationMatrixRows[rowIdx].m_key;
|
||||
rectangle->parameter = correlationMatrixRows[rowIdx].m_values[colIdx];
|
||||
QwtText textLabel( label );
|
||||
cvf::Color3f contrastColor = RiaColorTools::contrastColor( cvf::Color3f( color ) );
|
||||
textLabel.setColor( RiaColorTools::toQColor( contrastColor ) );
|
||||
QFont font = textLabel.font();
|
||||
font.setPixelSize( caf::FontTools::pointSizeToPixelSize( labelFontSize() ) );
|
||||
textLabel.setFont( font );
|
||||
QwtPlotMarker* marker = new QwtPlotMarker();
|
||||
marker->setLabel( textLabel );
|
||||
marker->setXValue( colIdx + 0.5 );
|
||||
marker->setYValue( rowIdx + 0.5 );
|
||||
rectangle->attach( m_plotWidget );
|
||||
marker->attach( m_plotWidget );
|
||||
|
||||
m_paramLabels[colIdx] = correlationMatrixRows[rowIdx].m_values[colIdx];
|
||||
}
|
||||
// Remove ensemble name from label if we only have one ensemble
|
||||
// If we have multiple ensembles, no labels contain the combined ensemble names.
|
||||
QString resultLabel = correlationMatrixRows[rowIdx].m_key.curveDefinitionText();
|
||||
resultLabel.remove( combinedEnsembleNames + ", " );
|
||||
|
||||
m_resultLabels[rowIdx] = resultLabel;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::updatePlotTitle()
|
||||
{
|
||||
if ( m_useAutoPlotTitle )
|
||||
{
|
||||
m_description = QString( "Correlation Matrix for Parameters vs Result Vectors at %2" ).arg( timeStepString() );
|
||||
}
|
||||
|
||||
if ( m_plotWidget )
|
||||
{
|
||||
m_plotWidget->setPlotTitle( m_description );
|
||||
m_plotWidget->setPlotTitleEnabled( m_showPlotTitle && !isSubPlot() );
|
||||
if ( isMdiWindow() )
|
||||
{
|
||||
m_plotWidget->setPlotTitleFontSize( titleFontSize() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::updateLegend()
|
||||
{
|
||||
if ( m_legendConfig ) m_legendConfig->recreateLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationMatrixPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex )
|
||||
{
|
||||
CorrelationMatrixShapeItem* matrixItem = dynamic_cast<CorrelationMatrixShapeItem*>( plotItem );
|
||||
if ( matrixItem )
|
||||
{
|
||||
matrixCellSelected.send( std::make_pair( matrixItem->parameter, matrixItem->curveDef ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimCorrelationPlot.h"
|
||||
#include "cafAppEnum.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
class RimRegularLegendConfig;
|
||||
class RimSummaryAddress;
|
||||
class RiuGroupedBarChartBuilder;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCorrelationMatrixPlot : public RimAbstractCorrelationPlot
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::Signal<std::pair<QString, RiaSummaryCurveDefinition>> matrixCellSelected;
|
||||
|
||||
public:
|
||||
enum class Sorting
|
||||
{
|
||||
NO_SORTING,
|
||||
ROWS,
|
||||
COLUMNS,
|
||||
BOTH,
|
||||
};
|
||||
using SortingEnum = caf::AppEnum<Sorting>;
|
||||
|
||||
public:
|
||||
RimCorrelationMatrixPlot();
|
||||
~RimCorrelationMatrixPlot() override;
|
||||
|
||||
bool showAbsoluteValues() const;
|
||||
bool sortByAbsoluteValues() const;
|
||||
RimRegularLegendConfig* legendConfig();
|
||||
void selectAllParameters();
|
||||
bool showTopNCorrelations() const;
|
||||
int topNFilterCount() const;
|
||||
|
||||
private:
|
||||
// Overridden PDM methods
|
||||
|
||||
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,
|
||||
bool* useOptionsOnly ) override;
|
||||
|
||||
void onLoadDataAndUpdate() override;
|
||||
|
||||
void childFieldChangedByUi( const caf::PdmFieldHandle* changedChildField ) override;
|
||||
|
||||
void updateAxes() override;
|
||||
|
||||
// Private methods
|
||||
void createMatrix();
|
||||
void updatePlotTitle() override;
|
||||
void updateLegend() override;
|
||||
void onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex ) override;
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showAbsoluteValues;
|
||||
caf::PdmField<SortingEnum> m_sortByValues;
|
||||
caf::PdmField<bool> m_sortByAbsoluteValues;
|
||||
caf::PdmField<bool> m_excludeParametersWithoutVariation;
|
||||
caf::PdmField<bool> m_showOnlyTopNCorrelations;
|
||||
caf::PdmField<int> m_topNFilterCount;
|
||||
caf::PdmField<std::vector<QString>> m_selectedParametersList;
|
||||
|
||||
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
|
||||
|
||||
std::map<size_t, QString> m_paramLabels;
|
||||
std::map<size_t, QString> m_resultLabels;
|
||||
};
|
||||
@@ -0,0 +1,361 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaQDateTimeTools.h"
|
||||
#include "RiaStatisticsTools.h"
|
||||
#include "RiuGroupedBarChartBuilder.h"
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
#include "RiuQwtPlotWidget.h"
|
||||
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include "RimDerivedSummaryCase.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimPlotAxisProperties.h"
|
||||
#include "RimPlotAxisPropertiesInterface.h"
|
||||
#include "RimPlotDataFilterCollection.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimSummaryPlotAxisFormatter.h"
|
||||
|
||||
#include "cafFontTools.h"
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
#include "cafPdmUiTreeSelectionEditor.h"
|
||||
|
||||
#include "qwt_plot_barchart.h"
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimCorrelationPlot, "CorrelationPlot" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationPlot::RimCorrelationPlot()
|
||||
: RimAbstractCorrelationPlot()
|
||||
, tornadoItemSelected( this )
|
||||
{
|
||||
CAF_PDM_InitObject( "Correlation Tornado Plot", ":/CorrelationTornadoPlot16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_showAbsoluteValues, "CorrelationAbsValues", false, "Show Absolute Values", "", "", "" );
|
||||
CAF_PDM_InitField( &m_sortByAbsoluteValues, "CorrelationAbsSorting", true, "Sort by Absolute Values", "", "", "" );
|
||||
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", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_selectedParametersList, "SelectedParameters", "Select Parameters", "", "", "" );
|
||||
m_selectedParametersList.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
|
||||
m_selectedParametersList.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
|
||||
|
||||
setLegendsVisible( false );
|
||||
setDeletable( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationPlot::~RimCorrelationPlot()
|
||||
{
|
||||
if ( isMdiWindow() ) removeMdiWindowFromMdiArea();
|
||||
|
||||
cleanupBeforeClose();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
RimAbstractCorrelationPlot::fieldChangedByUi( changedField, oldValue, newValue );
|
||||
if ( changedField == &m_showAbsoluteValues || changedField == &m_sortByAbsoluteValues ||
|
||||
changedField == &m_excludeParametersWithoutVariation || changedField == &m_selectedParametersList ||
|
||||
changedField == &m_showOnlyTopNCorrelations || changedField == &m_topNFilterCount )
|
||||
{
|
||||
if ( changedField == &m_excludeParametersWithoutVariation )
|
||||
{
|
||||
selectAllParameters();
|
||||
}
|
||||
loadDataAndUpdate();
|
||||
updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
caf::PdmUiGroup* correlationGroup = uiOrdering.addNewGroup( "Correlation Settings" );
|
||||
correlationGroup->add( &m_excludeParametersWithoutVariation );
|
||||
correlationGroup->add( &m_selectedParametersList );
|
||||
|
||||
correlationGroup->add( &m_showAbsoluteValues );
|
||||
if ( !m_showAbsoluteValues() )
|
||||
{
|
||||
correlationGroup->add( &m_sortByAbsoluteValues );
|
||||
}
|
||||
|
||||
correlationGroup->add( &m_showOnlyTopNCorrelations );
|
||||
if ( m_showOnlyTopNCorrelations() )
|
||||
{
|
||||
correlationGroup->add( &m_topNFilterCount );
|
||||
}
|
||||
|
||||
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector" );
|
||||
|
||||
curveDataGroup->add( &m_selectedVarsUiField );
|
||||
curveDataGroup->add( &m_pushButtonSelectSummaryAddress, { false, 1, 0 } );
|
||||
curveDataGroup->add( &m_timeStepFilter );
|
||||
curveDataGroup->add( &m_timeStep );
|
||||
|
||||
caf::PdmUiGroup* plotGroup = uiOrdering.addNewGroup( "Plot Settings" );
|
||||
plotGroup->add( &m_showPlotTitle );
|
||||
plotGroup->add( &m_useAutoPlotTitle );
|
||||
plotGroup->add( &m_description );
|
||||
RimPlot::defineUiOrdering( uiConfigName, *plotGroup );
|
||||
plotGroup->add( &m_titleFontSize );
|
||||
plotGroup->add( &m_axisTitleFontSize );
|
||||
plotGroup->add( &m_axisValueFontSize );
|
||||
|
||||
m_description.uiCapability()->setUiReadOnly( m_useAutoPlotTitle() );
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimCorrelationPlot::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options =
|
||||
RimAbstractCorrelationPlot::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
||||
|
||||
if ( fieldNeedingOptions == &m_selectedParametersList )
|
||||
{
|
||||
std::set<EnsembleParameter> params = variationSortedEnsembleParameters();
|
||||
for ( auto param : params )
|
||||
{
|
||||
if ( !m_excludeParametersWithoutVariation() || param.variationBin > EnsembleParameter::NO_VARIATION )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( param.uiName(), param.name ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::onLoadDataAndUpdate()
|
||||
{
|
||||
updateMdiWindowVisibility();
|
||||
|
||||
m_selectedVarsUiField = selectedVarsText();
|
||||
|
||||
if ( m_plotWidget && m_analyserOfSelectedCurveDefs )
|
||||
{
|
||||
m_plotWidget->detachItems( QwtPlotItem::Rtti_PlotBarChart );
|
||||
m_plotWidget->detachItems( QwtPlotItem::Rtti_PlotScale );
|
||||
|
||||
RiuGroupedBarChartBuilder chartBuilder;
|
||||
|
||||
// buildTestPlot( chartBuilder );
|
||||
addDataToChartBuilder( chartBuilder );
|
||||
|
||||
chartBuilder.addBarChartToPlot( m_plotWidget,
|
||||
Qt::Horizontal,
|
||||
m_showOnlyTopNCorrelations() ? m_topNFilterCount() : -1 );
|
||||
chartBuilder.setLabelFontSize( labelFontSize() );
|
||||
|
||||
m_plotWidget->insertLegend( nullptr );
|
||||
m_plotWidget->updateLegend();
|
||||
|
||||
this->updateAxes();
|
||||
this->updatePlotTitle();
|
||||
m_plotWidget->scheduleReplot();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::updateAxes()
|
||||
{
|
||||
if ( !m_plotWidget ) return;
|
||||
|
||||
m_plotWidget->setAxisTitleText( QwtPlot::yLeft, "Parameter" );
|
||||
m_plotWidget->setAxisTitleEnabled( QwtPlot::yLeft, true );
|
||||
m_plotWidget->setAxisFontsAndAlignment( QwtPlot::yLeft, axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
|
||||
|
||||
m_plotWidget->setAxisTitleText( QwtPlot::xBottom, "Pearson Correlation Coefficient" );
|
||||
m_plotWidget->setAxisTitleEnabled( QwtPlot::xBottom, true );
|
||||
m_plotWidget->setAxisFontsAndAlignment( QwtPlot::xBottom, axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
|
||||
if ( m_showAbsoluteValues )
|
||||
{
|
||||
m_plotWidget->setAxisTitleText( QwtPlot::xBottom, "Pearson Correlation Coefficient ABS" );
|
||||
m_plotWidget->setAxisRange( QwtPlot::xBottom, 0.0, 1.0 );
|
||||
}
|
||||
else
|
||||
{
|
||||
m_plotWidget->setAxisTitleText( QwtPlot::xBottom, "Pearson Correlation Coefficient" );
|
||||
m_plotWidget->setAxisRange( QwtPlot::xBottom, -1.0, 1.0 );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::addDataToChartBuilder( RiuGroupedBarChartBuilder& chartBuilder )
|
||||
{
|
||||
time_t selectedTimestep = m_timeStep().toTime_t();
|
||||
|
||||
if ( ensembles().empty() ) return;
|
||||
if ( addresses().empty() ) return;
|
||||
|
||||
auto ensemble = *ensembles().begin();
|
||||
auto address = *addresses().begin();
|
||||
|
||||
std::vector<std::pair<EnsembleParameter, double>> correlations =
|
||||
ensemble->parameterCorrelations( address, selectedTimestep, m_selectedParametersList() );
|
||||
|
||||
for ( auto parameterCorrPair : correlations )
|
||||
{
|
||||
double value = m_showAbsoluteValues() ? std::abs( parameterCorrPair.second ) : parameterCorrPair.second;
|
||||
double sortValue = m_sortByAbsoluteValues() ? std::abs( value ) : value;
|
||||
QString barText =
|
||||
QString( "%1 (%2)" ).arg( parameterCorrPair.first.name ).arg( parameterCorrPair.second, 5, 'f', 2 );
|
||||
QString majorText = "", medText = "", minText = "", legendText = barText;
|
||||
chartBuilder.addBarEntry( majorText, medText, minText, sortValue, legendText, barText, value );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::updatePlotTitle()
|
||||
{
|
||||
if ( m_useAutoPlotTitle && !ensembles().empty() )
|
||||
{
|
||||
auto ensemble = *ensembles().begin();
|
||||
m_description =
|
||||
QString( "Correlations for %2, %3 at %4" ).arg( ensemble->name() ).arg( m_selectedVarsUiField ).arg( timeStepString() );
|
||||
}
|
||||
m_plotWidget->setPlotTitle( m_description );
|
||||
m_plotWidget->setPlotTitleEnabled( m_showPlotTitle && !isSubPlot() );
|
||||
m_plotWidget->setPlotTitleFontSize( titleFontSize() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex )
|
||||
{
|
||||
QwtPlotBarChart* barChart = dynamic_cast<QwtPlotBarChart*>( plotItem );
|
||||
if ( barChart && !curveDefinitions().empty() )
|
||||
{
|
||||
auto curveDef = curveDefinitions().front();
|
||||
auto barTitle = barChart->title();
|
||||
for ( auto param : ensembleParameters() )
|
||||
{
|
||||
if ( barTitle.text() == param.name )
|
||||
{
|
||||
tornadoItemSelected.send( std::make_pair( param.name, curveDef ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimCorrelationPlot::showAbsoluteValues() const
|
||||
{
|
||||
return m_showAbsoluteValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
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<EnsembleParameter> params = variationSortedEnsembleParameters();
|
||||
for ( auto param : params )
|
||||
{
|
||||
if ( !m_excludeParametersWithoutVariation() || param.variationBin > EnsembleParameter::NO_VARIATION )
|
||||
{
|
||||
m_selectedParametersList.v().push_back( param.name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::setShowOnlyTopNCorrelations( bool showOnlyTopNCorrelations )
|
||||
{
|
||||
m_showOnlyTopNCorrelations = showOnlyTopNCorrelations;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlot::setTopNFilterCount( int filterCount )
|
||||
{
|
||||
m_topNFilterCount = filterCount;
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
#include "RimAbstractCorrelationPlot.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
class RimSummaryAddress;
|
||||
class RiuGroupedBarChartBuilder;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCorrelationPlot : public RimAbstractCorrelationPlot
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::Signal<std::pair<QString, RiaSummaryCurveDefinition>> tornadoItemSelected;
|
||||
|
||||
public:
|
||||
RimCorrelationPlot();
|
||||
~RimCorrelationPlot() override;
|
||||
|
||||
bool showAbsoluteValues() const;
|
||||
void setShowAbsoluteValues( bool showAbsoluteValues );
|
||||
|
||||
bool sortByAbsoluteValues() const;
|
||||
void setSortByAbsoluteValues( bool sortByAbsoluteValues );
|
||||
void selectAllParameters();
|
||||
|
||||
void setShowOnlyTopNCorrelations( bool showOnlyTopNCorrelations );
|
||||
void setTopNFilterCount( int filterCount );
|
||||
|
||||
private:
|
||||
// Overridden PDM methods
|
||||
|
||||
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,
|
||||
bool* useOptionsOnly ) override;
|
||||
|
||||
void onLoadDataAndUpdate() override;
|
||||
|
||||
void updateAxes() override;
|
||||
|
||||
// Private methods
|
||||
void addDataToChartBuilder( RiuGroupedBarChartBuilder& chartBuilder );
|
||||
void updatePlotTitle() override;
|
||||
void onPlotItemSelected( QwtPlotItem* plotItem, bool toggle, int sampleIndex ) override;
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showAbsoluteValues;
|
||||
caf::PdmField<bool> m_sortByAbsoluteValues;
|
||||
caf::PdmField<bool> m_excludeParametersWithoutVariation;
|
||||
caf::PdmField<bool> m_showOnlyTopNCorrelations;
|
||||
caf::PdmField<int> m_topNFilterCount;
|
||||
caf::PdmField<std::vector<QString>> m_selectedParametersList;
|
||||
};
|
||||
@@ -0,0 +1,387 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimCorrelationPlotCollection.h"
|
||||
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
#include "RimCorrelationMatrixPlot.h"
|
||||
#include "RimCorrelationPlot.h"
|
||||
#include "RimCorrelationReportPlot.h"
|
||||
#include "RimParameterResultCrossPlot.h"
|
||||
#include "RimProject.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimCorrelationPlotCollection, "CorrelationPlotCollection" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationPlotCollection::RimCorrelationPlotCollection()
|
||||
{
|
||||
CAF_PDM_InitObject( "Ensemble Correlation Plots", ":/CorrelationPlots16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_correlationPlots, "CorrelationPlots", "Correlation Plots", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_correlationReports, "CorrelationReports", "Correlation Reports", "", "", "" );
|
||||
|
||||
m_correlationPlots.uiCapability()->setUiHidden( true );
|
||||
m_correlationReports.uiCapability()->setUiHidden( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationPlotCollection::~RimCorrelationPlotCollection()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationPlot* RimCorrelationPlotCollection::createCorrelationPlot( bool defaultToFirstEnsembleFopt )
|
||||
{
|
||||
RimCorrelationPlot* plot = new RimCorrelationPlot();
|
||||
plot->setAsPlotMdiWindow();
|
||||
|
||||
if ( defaultToFirstEnsembleFopt ) applyFirstEnsembleFieldAddressesToPlot( plot, { "FOPT" } );
|
||||
plot->selectAllParameters();
|
||||
|
||||
addPlot( plot );
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationPlot* RimCorrelationPlotCollection::createCorrelationPlot( RimSummaryCaseCollection* ensemble,
|
||||
const QString& quantityName,
|
||||
std::time_t timeStep )
|
||||
{
|
||||
RimCorrelationPlot* plot = new RimCorrelationPlot();
|
||||
plot->setAsPlotMdiWindow();
|
||||
|
||||
applyEnsembleFieldAndTimeStepToPlot( plot, ensemble, { quantityName }, timeStep );
|
||||
plot->selectAllParameters();
|
||||
|
||||
addPlot( plot );
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationMatrixPlot* RimCorrelationPlotCollection::createCorrelationMatrixPlot( bool defaultToFirstEnsembleField )
|
||||
{
|
||||
RimCorrelationMatrixPlot* plot = new RimCorrelationMatrixPlot();
|
||||
plot->setAsPlotMdiWindow();
|
||||
if ( defaultToFirstEnsembleField ) applyFirstEnsembleFieldAddressesToPlot( plot, { "FOPT", "FWPT", "FGPT" } );
|
||||
plot->selectAllParameters();
|
||||
|
||||
addPlot( plot );
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationMatrixPlot* RimCorrelationPlotCollection::createCorrelationMatrixPlot( RimSummaryCaseCollection* ensemble,
|
||||
const std::vector<QString>& quantityNames,
|
||||
std::time_t timeStep )
|
||||
{
|
||||
RimCorrelationMatrixPlot* plot = new RimCorrelationMatrixPlot();
|
||||
plot->setAsPlotMdiWindow();
|
||||
applyEnsembleFieldAndTimeStepToPlot( plot, ensemble, quantityNames, timeStep );
|
||||
plot->selectAllParameters();
|
||||
|
||||
addPlot( plot );
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimParameterResultCrossPlot* RimCorrelationPlotCollection::createParameterResultCrossPlot( bool defaultToFirstEnsembleFopt )
|
||||
{
|
||||
RimParameterResultCrossPlot* plot = new RimParameterResultCrossPlot;
|
||||
plot->setAsPlotMdiWindow();
|
||||
if ( defaultToFirstEnsembleFopt ) applyFirstEnsembleFieldAddressesToPlot( plot, { "FOPT" } );
|
||||
|
||||
addPlot( plot );
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimParameterResultCrossPlot* RimCorrelationPlotCollection::createParameterResultCrossPlot( RimSummaryCaseCollection* ensemble,
|
||||
const QString& paramName,
|
||||
const QString& quantityName,
|
||||
std::time_t timeStep )
|
||||
{
|
||||
RimParameterResultCrossPlot* plot = new RimParameterResultCrossPlot;
|
||||
plot->setAsPlotMdiWindow();
|
||||
applyEnsembleFieldAndTimeStepToPlot( plot, ensemble, { quantityName }, timeStep );
|
||||
plot->setEnsembleParameter( paramName );
|
||||
|
||||
addPlot( plot );
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationReportPlot*
|
||||
RimCorrelationPlotCollection::createCorrelationReportPlot( bool defaultToFirstEnsembleField /*= true */ )
|
||||
{
|
||||
RimCorrelationReportPlot* report = new RimCorrelationReportPlot;
|
||||
report->setAsPlotMdiWindow();
|
||||
if ( defaultToFirstEnsembleField )
|
||||
applyFirstEnsembleFieldAddressesToReport( report, { "FOPT", "FWPT", "FGPT" }, "FOPT" );
|
||||
report->matrixPlot()->selectAllParameters();
|
||||
report->correlationPlot()->selectAllParameters();
|
||||
m_correlationReports.push_back( report );
|
||||
return report;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationReportPlot*
|
||||
RimCorrelationPlotCollection::createCorrelationReportPlot( RimSummaryCaseCollection* ensemble,
|
||||
const std::vector<QString>& matrixQuantityNames,
|
||||
const QString& tornadoAndCrossPlotQuantityName,
|
||||
std::time_t timeStep )
|
||||
{
|
||||
RimCorrelationReportPlot* report = new RimCorrelationReportPlot;
|
||||
report->setAsPlotMdiWindow();
|
||||
applyEnsembleFieldAndTimeStepToReport( report, ensemble, matrixQuantityNames, tornadoAndCrossPlotQuantityName, timeStep );
|
||||
report->matrixPlot()->selectAllParameters();
|
||||
report->correlationPlot()->selectAllParameters();
|
||||
m_correlationReports.push_back( report );
|
||||
return report;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlotCollection::insertPlot( RimAbstractCorrelationPlot* plot, size_t index )
|
||||
{
|
||||
m_correlationPlots.insert( index, plot );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlotCollection::removePlot( RimAbstractCorrelationPlot* plot )
|
||||
{
|
||||
m_correlationPlots.removeChildObject( plot );
|
||||
updateAllRequiredEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimAbstractCorrelationPlot*> RimCorrelationPlotCollection::plots() const
|
||||
{
|
||||
return m_correlationPlots.childObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RimCorrelationPlotCollection::plotCount() const
|
||||
{
|
||||
return m_correlationPlots.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimCorrelationReportPlot*> RimCorrelationPlotCollection::reports() const
|
||||
{
|
||||
return m_correlationReports.childObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlotCollection::deleteAllPlots()
|
||||
{
|
||||
RimTypedPlotCollection<RimAbstractCorrelationPlot>::deleteAllPlots();
|
||||
m_correlationReports.deleteAllChildObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToPlot( RimAbstractCorrelationPlot* plot,
|
||||
const std::vector<QString>& quantityNames /*= {} */ )
|
||||
{
|
||||
std::vector<RimSummaryCaseCollection*> ensembles;
|
||||
RimProject::current()->descendantsIncludingThisOfType( ensembles );
|
||||
if ( !ensembles.empty() )
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> allAddresses = ensembles.front()->ensembleSummaryAddresses();
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefs;
|
||||
for ( auto address : allAddresses )
|
||||
{
|
||||
auto it = std::find( quantityNames.begin(), quantityNames.end(), QString::fromStdString( address.uiText() ) );
|
||||
if ( it != quantityNames.end() || quantityNames.empty() )
|
||||
{
|
||||
curveDefs.push_back( RiaSummaryCurveDefinition( ensembles.front(), address ) );
|
||||
}
|
||||
}
|
||||
plot->setCurveDefinitions( curveDefs );
|
||||
|
||||
auto crossPlot = dynamic_cast<RimParameterResultCrossPlot*>( plot );
|
||||
if ( crossPlot )
|
||||
{
|
||||
crossPlot->setEnsembleParameter( ensembles.front()->alphabeticEnsembleParameters().front().name );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlotCollection::applyEnsembleFieldAndTimeStepToPlot( RimAbstractCorrelationPlot* plot,
|
||||
RimSummaryCaseCollection* ensemble,
|
||||
const std::vector<QString>& quantityNames,
|
||||
std::time_t timeStep )
|
||||
{
|
||||
if ( ensemble )
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> allAddresses = ensemble->ensembleSummaryAddresses();
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefs;
|
||||
std::vector<QString> highestCorrelationParameters;
|
||||
for ( auto address : allAddresses )
|
||||
{
|
||||
auto it = std::find( quantityNames.begin(), quantityNames.end(), QString::fromStdString( address.uiText() ) );
|
||||
if ( it != quantityNames.end() || quantityNames.empty() )
|
||||
{
|
||||
curveDefs.push_back( RiaSummaryCurveDefinition( ensemble, address ) );
|
||||
auto correlationSortedEnsembleParameters =
|
||||
ensemble->correlationSortedEnsembleParameters( address, timeStep );
|
||||
highestCorrelationParameters.push_back( correlationSortedEnsembleParameters.front().first.name );
|
||||
}
|
||||
}
|
||||
plot->setCurveDefinitions( curveDefs );
|
||||
plot->setTimeStep( timeStep );
|
||||
|
||||
auto crossPlot = dynamic_cast<RimParameterResultCrossPlot*>( plot );
|
||||
if ( crossPlot && !highestCorrelationParameters.empty() )
|
||||
{
|
||||
crossPlot->setEnsembleParameter( highestCorrelationParameters.front() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToReport( RimCorrelationReportPlot* plot,
|
||||
const std::vector<QString>& matrixQuantityNames,
|
||||
const QString& tornadoAndCrossPlotQuantityName )
|
||||
{
|
||||
std::vector<RimSummaryCaseCollection*> ensembles;
|
||||
RimProject::current()->descendantsIncludingThisOfType( ensembles );
|
||||
if ( !ensembles.empty() )
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> allAddresses = ensembles.front()->ensembleSummaryAddresses();
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefsMatrix;
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefsTornadoAndCrossPlot;
|
||||
for ( auto address : allAddresses )
|
||||
{
|
||||
auto it = std::find( matrixQuantityNames.begin(),
|
||||
matrixQuantityNames.end(),
|
||||
QString::fromStdString( address.uiText() ) );
|
||||
if ( it != matrixQuantityNames.end() || matrixQuantityNames.empty() )
|
||||
{
|
||||
curveDefsMatrix.push_back( RiaSummaryCurveDefinition( ensembles.front(), address ) );
|
||||
}
|
||||
|
||||
if ( tornadoAndCrossPlotQuantityName.isEmpty() ||
|
||||
tornadoAndCrossPlotQuantityName == QString::fromStdString( address.uiText() ) )
|
||||
{
|
||||
curveDefsTornadoAndCrossPlot.push_back( RiaSummaryCurveDefinition( ensembles.front(), address ) );
|
||||
}
|
||||
}
|
||||
|
||||
plot->matrixPlot()->setCurveDefinitions( curveDefsMatrix );
|
||||
plot->correlationPlot()->setCurveDefinitions( curveDefsTornadoAndCrossPlot );
|
||||
plot->crossPlot()->setCurveDefinitions( curveDefsTornadoAndCrossPlot );
|
||||
|
||||
time_t timeStep = *( plot->matrixPlot()->allAvailableTimeSteps().rbegin() );
|
||||
auto correlationSortedEnsembleParameters =
|
||||
ensembles.front()->correlationSortedEnsembleParameters( curveDefsTornadoAndCrossPlot.front().summaryAddress(),
|
||||
timeStep );
|
||||
if ( !correlationSortedEnsembleParameters.empty() )
|
||||
{
|
||||
QString crossPlotEnsembleParameterName = correlationSortedEnsembleParameters.front().first.name;
|
||||
plot->crossPlot()->setEnsembleParameter( crossPlotEnsembleParameterName );
|
||||
}
|
||||
plot->matrixPlot()->setTimeStep( timeStep );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationPlotCollection::applyEnsembleFieldAndTimeStepToReport( RimCorrelationReportPlot* plot,
|
||||
RimSummaryCaseCollection* ensemble,
|
||||
const std::vector<QString>& matrixQuantityNames,
|
||||
const QString& tornadoAndCrossPlotQuantityName,
|
||||
std::time_t timeStep )
|
||||
{
|
||||
if ( ensemble )
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> allAddresses = ensemble->ensembleSummaryAddresses();
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefsMatrix;
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefsTornadoAndCrossPlot;
|
||||
for ( auto address : allAddresses )
|
||||
{
|
||||
auto it = std::find( matrixQuantityNames.begin(),
|
||||
matrixQuantityNames.end(),
|
||||
QString::fromStdString( address.uiText() ) );
|
||||
if ( it != matrixQuantityNames.end() || matrixQuantityNames.empty() )
|
||||
{
|
||||
curveDefsMatrix.push_back( RiaSummaryCurveDefinition( ensemble, address ) );
|
||||
}
|
||||
|
||||
if ( tornadoAndCrossPlotQuantityName.isEmpty() ||
|
||||
tornadoAndCrossPlotQuantityName == QString::fromStdString( address.uiText() ) )
|
||||
{
|
||||
curveDefsTornadoAndCrossPlot.push_back( RiaSummaryCurveDefinition( ensemble, address ) );
|
||||
}
|
||||
}
|
||||
|
||||
plot->matrixPlot()->setCurveDefinitions( curveDefsMatrix );
|
||||
plot->matrixPlot()->setTimeStep( timeStep );
|
||||
plot->correlationPlot()->setCurveDefinitions( curveDefsTornadoAndCrossPlot );
|
||||
plot->correlationPlot()->setTimeStep( timeStep );
|
||||
plot->crossPlot()->setCurveDefinitions( curveDefsTornadoAndCrossPlot );
|
||||
plot->crossPlot()->setTimeStep( timeStep );
|
||||
|
||||
auto correlationSortedEnsembleParameters =
|
||||
ensemble->correlationSortedEnsembleParameters( curveDefsTornadoAndCrossPlot.front().summaryAddress(), timeStep );
|
||||
QString crossPlotEnsembleParameterName = correlationSortedEnsembleParameters.front().first.name;
|
||||
plot->crossPlot()->setEnsembleParameter( crossPlotEnsembleParameterName );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimAbstractCorrelationPlot.h"
|
||||
#include "RimAbstractPlotCollection.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <ctime>
|
||||
#include <vector>
|
||||
|
||||
class RimCorrelationPlot;
|
||||
class RimCorrelationMatrixPlot;
|
||||
class RimCorrelationReportPlot;
|
||||
class RimParameterResultCrossPlot;
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimCorrelationPlotCollection : public caf::PdmObject, public RimTypedPlotCollection<RimAbstractCorrelationPlot>
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimCorrelationPlotCollection();
|
||||
~RimCorrelationPlotCollection() override;
|
||||
|
||||
RimCorrelationPlot* createCorrelationPlot( bool defaultToFirstEnsembleFopt = true );
|
||||
RimCorrelationPlot*
|
||||
createCorrelationPlot( RimSummaryCaseCollection* ensemble, const QString& quantityName, std::time_t timeStep );
|
||||
|
||||
RimCorrelationMatrixPlot* createCorrelationMatrixPlot( bool defaultToFirstEnsembleField = true );
|
||||
RimCorrelationMatrixPlot* createCorrelationMatrixPlot( RimSummaryCaseCollection* ensemble,
|
||||
const std::vector<QString>& quantityNames,
|
||||
std::time_t timeStep );
|
||||
|
||||
RimParameterResultCrossPlot* createParameterResultCrossPlot( bool defaultToFirstEnsembleFopt = true );
|
||||
RimParameterResultCrossPlot* createParameterResultCrossPlot( RimSummaryCaseCollection* ensemble,
|
||||
const QString& paramName,
|
||||
const QString& quantityName,
|
||||
std::time_t timeStep );
|
||||
|
||||
RimCorrelationReportPlot* createCorrelationReportPlot( bool defaultToFirstEnsembleField = true );
|
||||
RimCorrelationReportPlot* createCorrelationReportPlot( RimSummaryCaseCollection* ensemble,
|
||||
const std::vector<QString>& matrixQuantityNames,
|
||||
const QString& tornadoAndCrossPlotQuantityName,
|
||||
std::time_t timeStep );
|
||||
|
||||
void removeReport( RimCorrelationReportPlot* correlationReport );
|
||||
|
||||
std::vector<RimAbstractCorrelationPlot*> plots() const final;
|
||||
size_t plotCount() const final;
|
||||
void insertPlot( RimAbstractCorrelationPlot* plot, size_t index ) final;
|
||||
void removePlot( RimAbstractCorrelationPlot* correlationPlot ) final;
|
||||
void deleteAllPlots() final;
|
||||
|
||||
std::vector<RimCorrelationReportPlot*> reports() const;
|
||||
|
||||
private:
|
||||
void applyFirstEnsembleFieldAddressesToPlot( RimAbstractCorrelationPlot* plot,
|
||||
const std::vector<QString>& quantityNames = {} );
|
||||
void applyEnsembleFieldAndTimeStepToPlot( RimAbstractCorrelationPlot* plot,
|
||||
RimSummaryCaseCollection* ensemble,
|
||||
const std::vector<QString>& quantityNames,
|
||||
std::time_t timeStep );
|
||||
void applyFirstEnsembleFieldAddressesToReport( RimCorrelationReportPlot* plot,
|
||||
const std::vector<QString>& matrixQuantityNames,
|
||||
const QString& tornadoAndCrossPlotQuantityName );
|
||||
void applyEnsembleFieldAndTimeStepToReport( RimCorrelationReportPlot* plot,
|
||||
RimSummaryCaseCollection* ensemble,
|
||||
const std::vector<QString>& matrixQuantityNames,
|
||||
const QString& tornadoAndCrossPlotQuantityName,
|
||||
std::time_t timeStep );
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimAbstractCorrelationPlot*> m_correlationPlots;
|
||||
caf::PdmChildArrayField<RimCorrelationReportPlot*> m_correlationReports;
|
||||
};
|
||||
@@ -0,0 +1,414 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimCorrelationReportPlot.h"
|
||||
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaQDateTimeTools.h"
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
|
||||
#include "RimCorrelationMatrixPlot.h"
|
||||
#include "RimParameterResultCrossPlot.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
|
||||
#include "RiuMultiPlotPage.h"
|
||||
|
||||
#include "cafAssert.h"
|
||||
#include "cafPdmUiOrdering.h"
|
||||
#include "cafPdmUiTreeOrdering.h"
|
||||
|
||||
#include <QDebug>
|
||||
#include <QImage>
|
||||
#include <QPixmap>
|
||||
#include <QStringList>
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//
|
||||
//
|
||||
//==================================================================================================
|
||||
CAF_PDM_SOURCE_INIT( RimCorrelationReportPlot, "CorrelationReportPlot" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationReportPlot::RimCorrelationReportPlot()
|
||||
{
|
||||
CAF_PDM_InitObject( "Correlation Report Plot", ":/CorrelationReportPlot16x16.png", "", "" );
|
||||
this->setDeletable( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_plotWindowTitle, "PlotWindowTitle", "Title", "", "", "" );
|
||||
m_plotWindowTitle.registerGetMethod( this, &RimCorrelationReportPlot::createPlotWindowTitle );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_correlationMatrixPlot, "MatrixPlot", "Matrix Plot", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_correlationPlot, "CorrelationPlot", "Correlation Plot", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_parameterResultCrossPlot, "CrossPlot", "Cross Plot", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_subTitleFontSize, "SubTitleFontSize", "Sub Plot Title Font Size", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_labelFontSize, "LabelFontSize", "Label Font Size", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_axisTitleFontSize, "AxisTitleFontSize", "Axis Title Font Size", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_axisValueFontSize, "AxisValueFontSize", "Axis Value Font Size", "", "", "" );
|
||||
|
||||
setAsPlotMdiWindow();
|
||||
|
||||
m_showWindow = true;
|
||||
m_showPlotLegends = false;
|
||||
|
||||
m_titleFontSize = caf::FontTools::RelativeSize::XLarge;
|
||||
m_subTitleFontSize = caf::FontTools::RelativeSize::Large;
|
||||
m_labelFontSize = caf::FontTools::RelativeSize::XSmall;
|
||||
m_axisTitleFontSize = caf::FontTools::RelativeSize::Small;
|
||||
m_axisValueFontSize = caf::FontTools::RelativeSize::XSmall;
|
||||
|
||||
m_correlationMatrixPlot = new RimCorrelationMatrixPlot;
|
||||
m_correlationMatrixPlot->setLegendsVisible( false );
|
||||
m_correlationMatrixPlot->setColSpan( RimPlot::TWO );
|
||||
m_correlationMatrixPlot->setRowSpan( RimPlot::TWO );
|
||||
|
||||
m_correlationPlot = new RimCorrelationPlot;
|
||||
m_correlationPlot->setLegendsVisible( false );
|
||||
|
||||
m_parameterResultCrossPlot = new RimParameterResultCrossPlot;
|
||||
m_parameterResultCrossPlot->setLegendsVisible( true );
|
||||
|
||||
this->uiCapability()->setUiTreeChildrenHidden( true );
|
||||
|
||||
m_correlationMatrixPlot->matrixCellSelected.connect( this, &RimCorrelationReportPlot::onDataSelection );
|
||||
m_correlationPlot->tornadoItemSelected.connect( this, &RimCorrelationReportPlot::onDataSelection );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationReportPlot::~RimCorrelationReportPlot()
|
||||
{
|
||||
removeMdiWindowFromMdiArea();
|
||||
cleanupBeforeClose();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* RimCorrelationReportPlot::viewWidget()
|
||||
{
|
||||
return m_viewer;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimCorrelationReportPlot::description() const
|
||||
{
|
||||
return m_plotWindowTitle();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QImage RimCorrelationReportPlot::snapshotWindowContent()
|
||||
{
|
||||
QImage image;
|
||||
|
||||
if ( m_viewer )
|
||||
{
|
||||
QPixmap pix( m_viewer->size() );
|
||||
m_viewer->renderTo( &pix );
|
||||
image = pix.toImage();
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::zoomAll()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimCorrelationReportPlot::userDescriptionField()
|
||||
{
|
||||
return &m_plotWindowTitle;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationMatrixPlot* RimCorrelationReportPlot::matrixPlot() const
|
||||
{
|
||||
return m_correlationMatrixPlot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCorrelationPlot* RimCorrelationReportPlot::correlationPlot() const
|
||||
{
|
||||
return m_correlationPlot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimParameterResultCrossPlot* RimCorrelationReportPlot::crossPlot() const
|
||||
{
|
||||
return m_parameterResultCrossPlot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimCorrelationReportPlot::columnCount() const
|
||||
{
|
||||
return 3;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimCorrelationReportPlot::subTitleFontSize() const
|
||||
{
|
||||
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_subTitleFontSize() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimCorrelationReportPlot::axisTitleFontSize() const
|
||||
{
|
||||
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisTitleFontSize() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimCorrelationReportPlot::axisValueFontSize() const
|
||||
{
|
||||
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_axisValueFontSize() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimCorrelationReportPlot::createPlotWindowTitle() const
|
||||
{
|
||||
QStringList ensembles;
|
||||
for ( auto entry : m_correlationMatrixPlot->curveDefinitions() )
|
||||
{
|
||||
if ( entry.ensemble() )
|
||||
{
|
||||
ensembles.push_back( entry.ensemble()->name() );
|
||||
}
|
||||
}
|
||||
ensembles.removeDuplicates();
|
||||
QString ensembleNames = ensembles.join( ", " );
|
||||
QString timeStep = m_correlationMatrixPlot->timeStepString();
|
||||
|
||||
return QString( "Correlation Report for %1 at %2" ).arg( ensembleNames ).arg( timeStep );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::recreatePlotWidgets()
|
||||
{
|
||||
CAF_ASSERT( m_viewer );
|
||||
m_correlationMatrixPlot->createPlotWidget();
|
||||
m_correlationPlot->createPlotWidget();
|
||||
m_parameterResultCrossPlot->createPlotWidget();
|
||||
|
||||
m_viewer->addPlot( m_correlationMatrixPlot->viewer() );
|
||||
m_viewer->addPlot( m_correlationPlot->viewer() );
|
||||
m_viewer->addPlot( m_parameterResultCrossPlot->viewer() );
|
||||
|
||||
m_viewer->scheduleUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::cleanupBeforeClose()
|
||||
{
|
||||
m_correlationMatrixPlot->detachAllCurves();
|
||||
m_correlationPlot->detachAllCurves();
|
||||
m_parameterResultCrossPlot->detachAllCurves();
|
||||
|
||||
if ( m_viewer )
|
||||
{
|
||||
m_viewer->setParent( nullptr );
|
||||
delete m_viewer;
|
||||
m_viewer = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::doRenderWindowContent( QPaintDevice* paintDevice )
|
||||
{
|
||||
if ( m_viewer )
|
||||
{
|
||||
m_viewer->renderTo( paintDevice );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QWidget* RimCorrelationReportPlot::createViewWidget( QWidget* mainWindowParent /*= nullptr */ )
|
||||
{
|
||||
m_viewer = new RiuMultiPlotPage( this, mainWindowParent );
|
||||
m_viewer->setPlotTitle( m_plotWindowTitle() );
|
||||
recreatePlotWidgets();
|
||||
|
||||
return m_viewer;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::deleteViewWidget()
|
||||
{
|
||||
cleanupBeforeClose();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::onLoadDataAndUpdate()
|
||||
{
|
||||
updateMdiWindowVisibility();
|
||||
if ( m_showWindow )
|
||||
{
|
||||
auto timeStep = m_correlationMatrixPlot->timeStep().toTime_t();
|
||||
bool showOnlyTopNCorrelations = m_correlationMatrixPlot->showTopNCorrelations();
|
||||
int topNFilterCount = m_correlationMatrixPlot->topNFilterCount();
|
||||
|
||||
m_correlationPlot->setTimeStep( timeStep );
|
||||
m_correlationPlot->setShowOnlyTopNCorrelations( showOnlyTopNCorrelations );
|
||||
m_correlationPlot->setTopNFilterCount( topNFilterCount );
|
||||
m_parameterResultCrossPlot->setTimeStep( timeStep );
|
||||
|
||||
m_correlationMatrixPlot->setLabelFontSize( m_labelFontSize() );
|
||||
m_correlationMatrixPlot->setAxisTitleFontSize( m_axisTitleFontSize() );
|
||||
m_correlationMatrixPlot->setAxisValueFontSize( m_axisValueFontSize() );
|
||||
|
||||
m_correlationPlot->setLabelFontSize( m_labelFontSize() );
|
||||
m_correlationPlot->setAxisTitleFontSize( m_axisTitleFontSize() );
|
||||
m_correlationPlot->setAxisValueFontSize( m_axisValueFontSize() );
|
||||
|
||||
m_parameterResultCrossPlot->setLabelFontSize( m_labelFontSize() );
|
||||
m_parameterResultCrossPlot->setLegendFontSize( m_legendFontSize() );
|
||||
m_parameterResultCrossPlot->setAxisTitleFontSize( m_axisTitleFontSize() );
|
||||
m_parameterResultCrossPlot->setAxisValueFontSize( m_axisValueFontSize() );
|
||||
|
||||
m_correlationPlot->setShowAbsoluteValues( m_correlationMatrixPlot->showAbsoluteValues() );
|
||||
m_correlationPlot->setSortByAbsoluteValues( m_correlationMatrixPlot->sortByAbsoluteValues() );
|
||||
|
||||
m_correlationMatrixPlot->loadDataAndUpdate();
|
||||
m_correlationPlot->loadDataAndUpdate();
|
||||
m_parameterResultCrossPlot->loadDataAndUpdate();
|
||||
m_viewer->setPlotTitle( m_plotWindowTitle() );
|
||||
}
|
||||
updateLayout();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
m_correlationMatrixPlot->uiOrdering( "report", uiOrdering );
|
||||
auto plotGroup = uiOrdering.addNewGroup( "Plot Settings" );
|
||||
plotGroup->add( &m_titleFontSize );
|
||||
plotGroup->add( &m_subTitleFontSize );
|
||||
plotGroup->add( &m_labelFontSize );
|
||||
plotGroup->add( &m_legendFontSize );
|
||||
plotGroup->add( &m_axisTitleFontSize );
|
||||
plotGroup->add( &m_axisValueFontSize );
|
||||
m_correlationMatrixPlot->legendConfig()->uiOrdering( "ColorsOnly", *plotGroup );
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::childFieldChangedByUi( const caf::PdmFieldHandle* changedChildField )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCorrelationReportPlot::doUpdateLayout()
|
||||
{
|
||||
if ( m_showWindow && m_viewer )
|
||||
{
|
||||
m_viewer->setTitleFontSizes( titleFontSize(), subTitleFontSize() );
|
||||
m_viewer->setLegendFontSize( legendFontSize() );
|
||||
m_viewer->setAxisFontSizes( axisTitleFontSize(), axisValueFontSize() );
|
||||
m_viewer->setSubTitlesVisible( true );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo>
|
||||
RimCorrelationReportPlot::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options = RimPlotWindow::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
||||
|
||||
if ( fieldNeedingOptions == &m_subTitleFontSize || fieldNeedingOptions == &m_labelFontSize ||
|
||||
fieldNeedingOptions == &m_axisTitleFontSize || fieldNeedingOptions == &m_axisValueFontSize )
|
||||
{
|
||||
options = caf::FontTools::relativeSizeValueOptions( RiaPreferences::current()->defaultPlotFontSize() );
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
void RimCorrelationReportPlot::onDataSelection( const caf::SignalEmitter* emitter,
|
||||
std::pair<QString, RiaSummaryCurveDefinition> parameterAndCurveDef )
|
||||
{
|
||||
auto paramName = parameterAndCurveDef.first;
|
||||
auto curveDef = parameterAndCurveDef.second;
|
||||
|
||||
m_correlationPlot->setCurveDefinitions( { curveDef } );
|
||||
m_correlationPlot->loadDataAndUpdate();
|
||||
m_parameterResultCrossPlot->setCurveDefinitions( { curveDef } );
|
||||
m_parameterResultCrossPlot->setEnsembleParameter( paramName );
|
||||
m_parameterResultCrossPlot->loadDataAndUpdate();
|
||||
if ( m_viewer )
|
||||
{
|
||||
m_viewer->updateSubTitles();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimCorrelationPlot.h"
|
||||
#include "RimPlotWindow.h"
|
||||
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QObject>
|
||||
#include <QPointer>
|
||||
|
||||
class RimAnalysisPlotDataEntry;
|
||||
class RimCorrelationMatrixPlot;
|
||||
class RimParameterResultCrossPlot;
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
class RiuMultiPlotPage;
|
||||
|
||||
class RimCorrelationReportPlot : public QObject, public RimPlotWindow
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimCorrelationReportPlot();
|
||||
~RimCorrelationReportPlot() override;
|
||||
|
||||
QWidget* viewWidget() override;
|
||||
QString description() const override;
|
||||
QImage snapshotWindowContent() override;
|
||||
void zoomAll() override;
|
||||
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
|
||||
RimCorrelationMatrixPlot* matrixPlot() const;
|
||||
RimCorrelationPlot* correlationPlot() const;
|
||||
RimParameterResultCrossPlot* crossPlot() const;
|
||||
|
||||
int columnCount() const override;
|
||||
int subTitleFontSize() const;
|
||||
int axisTitleFontSize() const;
|
||||
int axisValueFontSize() const;
|
||||
|
||||
private:
|
||||
QString createPlotWindowTitle() const;
|
||||
void recreatePlotWidgets();
|
||||
void cleanupBeforeClose();
|
||||
|
||||
void doRenderWindowContent( QPaintDevice* paintDevice ) override;
|
||||
QWidget* createViewWidget( QWidget* mainWindowParent = nullptr ) override;
|
||||
void deleteViewWidget() override;
|
||||
void onLoadDataAndUpdate() override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void childFieldChangedByUi( const caf::PdmFieldHandle* changedChildField ) override;
|
||||
void doUpdateLayout() override;
|
||||
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly ) override;
|
||||
void onDataSelection( const caf::SignalEmitter* emitter,
|
||||
std::pair<QString, RiaSummaryCurveDefinition> parameterAndCurveDef );
|
||||
|
||||
private:
|
||||
caf::PdmProxyValueField<QString> m_plotWindowTitle;
|
||||
|
||||
caf::PdmChildField<RimCorrelationMatrixPlot*> m_correlationMatrixPlot;
|
||||
caf::PdmChildField<RimCorrelationPlot*> m_correlationPlot;
|
||||
caf::PdmChildField<RimParameterResultCrossPlot*> m_parameterResultCrossPlot;
|
||||
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_subTitleFontSize;
|
||||
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_labelFontSize;
|
||||
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_axisTitleFontSize;
|
||||
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_axisValueFontSize;
|
||||
|
||||
QPointer<RiuMultiPlotPage> m_viewer;
|
||||
};
|
||||
@@ -0,0 +1,337 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RimParameterResultCrossPlot.h"
|
||||
|
||||
#include "RiaColorTables.h"
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaQDateTimeTools.h"
|
||||
#include "RiaStatisticsTools.h"
|
||||
#include "RiaTextStringTools.h"
|
||||
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include "RimDerivedSummaryCase.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimMultiPlot.h"
|
||||
#include "RimPlotAxisProperties.h"
|
||||
#include "RimPlotAxisPropertiesInterface.h"
|
||||
#include "RimPlotDataFilterCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
#include "RimSummaryCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimSummaryPlotAxisFormatter.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
#include "RiuQwtPlotCurve.h"
|
||||
#include "RiuSummaryQwtPlot.h"
|
||||
#include "RiuSummaryVectorSelectionDialog.h"
|
||||
|
||||
#include "cafPdmUiComboBoxEditor.h"
|
||||
#include "cafPdmUiLineEditor.h"
|
||||
#include "cafPdmUiPushButtonEditor.h"
|
||||
|
||||
#include "qwt_legend.h"
|
||||
#include "qwt_plot_curve.h"
|
||||
#include "qwt_scale_engine.h"
|
||||
|
||||
#include <QStringList>
|
||||
|
||||
#include <limits>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimParameterResultCrossPlot, "ParameterResultCrossPlot" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimParameterResultCrossPlot::RimParameterResultCrossPlot()
|
||||
: RimAbstractCorrelationPlot()
|
||||
{
|
||||
CAF_PDM_InitObject( "ParameterResultCross Plot", ":/CorrelationCrossPlot16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_ensembleParameter, "EnsembleParameter", QString( "" ), "Ensemble Parameter", "", "", "" );
|
||||
m_ensembleParameter.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
|
||||
|
||||
m_selectMultipleVectors = true;
|
||||
|
||||
m_legendFontSize = caf::FontTools::RelativeSize::XSmall;
|
||||
|
||||
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() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimParameterResultCrossPlot::~RimParameterResultCrossPlot()
|
||||
{
|
||||
if ( isMdiWindow() ) removeMdiWindowFromMdiArea();
|
||||
cleanupBeforeClose();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::setEnsembleParameter( const QString& ensembleParameter )
|
||||
{
|
||||
m_ensembleParameter = ensembleParameter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
RimAbstractCorrelationPlot::fieldChangedByUi( changedField, oldValue, newValue );
|
||||
if ( changedField == &m_ensembleParameter )
|
||||
{
|
||||
this->loadDataAndUpdate();
|
||||
this->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
m_selectedVarsUiField = selectedVarsText();
|
||||
|
||||
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector" );
|
||||
curveDataGroup->add( &m_selectedVarsUiField );
|
||||
curveDataGroup->add( &m_pushButtonSelectSummaryAddress, { false, 1, 0 } );
|
||||
curveDataGroup->add( &m_timeStepFilter );
|
||||
curveDataGroup->add( &m_timeStep );
|
||||
|
||||
caf::PdmUiGroup* crossPlotGroup = uiOrdering.addNewGroup( "Cross Plot Parameters" );
|
||||
crossPlotGroup->add( &m_ensembleParameter );
|
||||
|
||||
caf::PdmUiGroup* plotGroup = uiOrdering.addNewGroup( "Plot Settings" );
|
||||
plotGroup->add( &m_showPlotTitle );
|
||||
plotGroup->add( &m_useAutoPlotTitle );
|
||||
plotGroup->add( &m_description );
|
||||
RimPlot::defineUiOrdering( uiConfigName, *plotGroup );
|
||||
plotGroup->add( &m_titleFontSize );
|
||||
plotGroup->add( &m_legendFontSize );
|
||||
plotGroup->add( &m_axisTitleFontSize );
|
||||
plotGroup->add( &m_axisValueFontSize );
|
||||
|
||||
m_description.uiCapability()->setUiReadOnly( m_useAutoPlotTitle() );
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo>
|
||||
RimParameterResultCrossPlot::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options =
|
||||
RimAbstractCorrelationPlot::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
||||
if ( fieldNeedingOptions == &m_ensembleParameter )
|
||||
{
|
||||
for ( const auto& param : ensembleParameters() )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( param.uiName(), param.name ) );
|
||||
}
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::onLoadDataAndUpdate()
|
||||
{
|
||||
updateMdiWindowVisibility();
|
||||
|
||||
m_selectedVarsUiField = selectedVarsText();
|
||||
|
||||
if ( m_plotWidget && m_analyserOfSelectedCurveDefs )
|
||||
{
|
||||
createPoints();
|
||||
if ( m_showPlotLegends && !isSubPlot<RimMultiPlot>() )
|
||||
{
|
||||
QwtLegend* legend = new QwtLegend( m_plotWidget );
|
||||
m_plotWidget->insertLegend( legend, QwtPlot::RightLegend );
|
||||
m_plotWidget->setLegendFontSize( legendFontSize() );
|
||||
m_plotWidget->updateLegend();
|
||||
}
|
||||
|
||||
this->updateAxes();
|
||||
this->updatePlotTitle();
|
||||
m_plotWidget->scheduleReplot();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::updateAxes()
|
||||
{
|
||||
if ( !m_plotWidget ) return;
|
||||
|
||||
m_plotWidget->setAxisTitleText( QwtPlot::yLeft, m_selectedVarsUiField );
|
||||
m_plotWidget->setAxisTitleEnabled( QwtPlot::yLeft, true );
|
||||
m_plotWidget->setAxisFontsAndAlignment( QwtPlot::yLeft, axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
|
||||
|
||||
double yRangeWidth = m_yRange.second - m_yRange.first;
|
||||
m_plotWidget->setAxisRange( QwtPlot::yLeft, m_yRange.first - yRangeWidth * 0.1, m_yRange.second + yRangeWidth * 0.1 );
|
||||
|
||||
m_plotWidget->setAxisTitleText( QwtPlot::xBottom, m_ensembleParameter );
|
||||
m_plotWidget->setAxisTitleEnabled( QwtPlot::xBottom, true );
|
||||
m_plotWidget->setAxisFontsAndAlignment( QwtPlot::xBottom, axisTitleFontSize(), axisValueFontSize(), false, Qt::AlignCenter );
|
||||
|
||||
double xRangeWidth = m_xRange.second - m_xRange.first;
|
||||
m_plotWidget->setAxisRange( QwtPlot::xBottom, m_xRange.first - xRangeWidth * 0.1, m_xRange.second + xRangeWidth * 0.1 );
|
||||
}
|
||||
|
||||
QStringList caseNamesOfValidEnsembleCases( const RimSummaryCaseCollection* ensemble )
|
||||
{
|
||||
QStringList caseNames;
|
||||
for ( auto summaryCase : ensemble->allSummaryCases() )
|
||||
{
|
||||
RifSummaryReaderInterface* reader = summaryCase->summaryReader();
|
||||
|
||||
if ( !reader ) continue;
|
||||
if ( !summaryCase->caseRealizationParameters() ) continue;
|
||||
|
||||
caseNames.push_back( summaryCase->displayCaseName() );
|
||||
}
|
||||
return caseNames;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::createPoints()
|
||||
{
|
||||
detachAllCurves();
|
||||
|
||||
time_t selectedTimestep = m_timeStep().toTime_t();
|
||||
|
||||
caf::ColorTable colorTable = RiaColorTables::categoryPaletteColors();
|
||||
|
||||
if ( ensembles().empty() ) return;
|
||||
if ( addresses().empty() ) return;
|
||||
|
||||
bool showEnsembleName = ensembles().size() > 1u;
|
||||
bool showAddressName = addresses().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 ensembleIdx = 0;
|
||||
for ( auto ensemble : ensembles() )
|
||||
{
|
||||
int addressIdx = 0;
|
||||
for ( auto address : addresses() )
|
||||
{
|
||||
EnsembleParameter parameter = ensembleParameter( m_ensembleParameter );
|
||||
if ( !( parameter.isNumeric() && parameter.isValid() ) ) return;
|
||||
|
||||
QStringList caseNames = caseNamesOfValidEnsembleCases( ensemble );
|
||||
QString commonCaseRoot = RiaTextStringTools::commonRoot( caseNames );
|
||||
|
||||
for ( size_t caseIdx = 0u; caseIdx < ensemble->allSummaryCases().size(); ++caseIdx )
|
||||
{
|
||||
auto summaryCase = ensemble->allSummaryCases()[caseIdx];
|
||||
|
||||
RifSummaryReaderInterface* reader = summaryCase->summaryReader();
|
||||
if ( !reader ) continue;
|
||||
|
||||
if ( !summaryCase->caseRealizationParameters() ) continue;
|
||||
|
||||
std::vector<double> values;
|
||||
|
||||
double closestValue = std::numeric_limits<double>::infinity();
|
||||
time_t closestTimeStep = 0;
|
||||
if ( reader->values( address, &values ) )
|
||||
{
|
||||
const std::vector<time_t>& timeSteps = reader->timeSteps( address );
|
||||
for ( size_t i = 0; i < timeSteps.size(); ++i )
|
||||
{
|
||||
if ( timeDiff( timeSteps[i], selectedTimestep ) < timeDiff( selectedTimestep, closestTimeStep ) )
|
||||
{
|
||||
closestValue = values[i];
|
||||
closestTimeStep = timeSteps[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( closestValue != 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_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->setSamples( parameterValues.data(), caseValuesAtTimestep.data(), (int)parameterValues.size() );
|
||||
plotCurve->setStyle( QwtPlotCurve::NoCurve );
|
||||
RiuQwtSymbol* symbol =
|
||||
new RiuQwtSymbol( RiuQwtSymbol::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().replace( commonCaseRoot, "" );
|
||||
if ( showAddressName ) curveName += QString::fromStdString( address.uiText() );
|
||||
|
||||
plotCurve->setTitle( curveName.join( " - " ) );
|
||||
|
||||
plotCurve->attach( m_plotWidget );
|
||||
}
|
||||
}
|
||||
addressIdx++;
|
||||
}
|
||||
ensembleIdx++;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimParameterResultCrossPlot::updatePlotTitle()
|
||||
{
|
||||
if ( m_useAutoPlotTitle && !ensembles().empty() )
|
||||
{
|
||||
auto ensemble = *ensembles().begin();
|
||||
m_description = QString( "Cross Plot %1, %2 x %3 at %4" )
|
||||
.arg( ensemble->name() )
|
||||
.arg( m_ensembleParameter )
|
||||
.arg( m_selectedVarsUiField )
|
||||
.arg( timeStepString() );
|
||||
}
|
||||
m_plotWidget->setPlotTitle( m_description );
|
||||
m_plotWidget->setPlotTitleEnabled( m_showPlotTitle && !isSubPlot() );
|
||||
m_plotWidget->setPlotTitleFontSize( titleFontSize() );
|
||||
}
|
||||
@@ -0,0 +1,58 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RimAbstractCorrelationPlot.h"
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimParameterResultCrossPlot : public RimAbstractCorrelationPlot
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimParameterResultCrossPlot();
|
||||
~RimParameterResultCrossPlot() override;
|
||||
void setEnsembleParameter( const QString& ensembleParameter );
|
||||
|
||||
private:
|
||||
// Overridden PDM methods
|
||||
|
||||
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,
|
||||
bool* useOptionsOnly ) override;
|
||||
|
||||
void onLoadDataAndUpdate() override;
|
||||
|
||||
void updateAxes() override;
|
||||
|
||||
// Private methods
|
||||
void updatePlotTitle() override;
|
||||
void createPoints();
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_ensembleParameter;
|
||||
|
||||
std::pair<double, double> m_xRange;
|
||||
std::pair<double, double> m_yRange;
|
||||
};
|
||||
Reference in New Issue
Block a user