Support ensemble cross plot curves

* Remove use of RifEnsembleStatisticsReader
* Add RimSummaryAddressSelector and RimEnsembleCrossPlotStatisticsCase
* Remove RifEnsembleStatisticsReader
* Add support for cross plot x-axis selection
* Support source stepping on ensemble cross plot curves
* Add isXAxisSummaryVector
This commit is contained in:
Magne Sjaastad
2023-09-25 12:45:47 +02:00
committed by GitHub
parent 55687c4e3e
commit fb288f602d
21 changed files with 1219 additions and 352 deletions

View File

@@ -30,8 +30,6 @@
#include "RimSummaryCalculationCollection.h"
#include "SummaryPlotCommands/RicSummaryPlotEditorUi.h"
#include "RifEnsembleStatisticsReader.h"
#include "RimCustomObjectiveFunction.h"
#include "RimCustomObjectiveFunctionCollection.h"
#include "RimDerivedEnsembleCaseCollection.h"
@@ -43,10 +41,12 @@
#include "RimEnsembleStatisticsCase.h"
#include "RimObjectiveFunction.h"
#include "RimObjectiveFunctionTools.h"
#include "RimPlotAxisProperties.h"
#include "RimPlotAxisPropertiesInterface.h"
#include "RimProject.h"
#include "RimRegularLegendConfig.h"
#include "RimSummaryAddress.h"
#include "RimSummaryAddressSelector.h"
#include "RimSummaryCalculationCollection.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
@@ -139,6 +139,19 @@ RimEnsembleCurveSet::RimEnsembleCurveSet()
CAF_PDM_InitFieldNoDefault( &m_resampling, "Resampling", "Resampling" );
// X Axis
CAF_PDM_InitField( &m_xAxisType,
"HorizontalAxisType",
caf::AppEnum<RiaDefines::HorizontalAxisType>( RiaDefines::HorizontalAxisType::TIME ),
"Axis Type" );
CAF_PDM_InitFieldNoDefault( &m_xAddressSelector, "XAddressSelector", "" );
m_xAddressSelector = new RimSummaryAddressSelector;
m_xAddressSelector.uiCapability()->setUiTreeHidden( true );
m_xAddressSelector.uiCapability()->setUiTreeChildrenHidden( true );
m_xAddressSelector->addressChanged.connect( this, &RimEnsembleCurveSet::onXAxisAddressChanged );
CAF_PDM_InitField( &m_colorMode, "ColorMode", caf::AppEnum<ColorMode>( ColorMode::SINGLE_COLOR_WITH_ALPHA ), "Coloring Mode" );
CAF_PDM_InitField( &m_colorForRealizations, "Color", RiaColorTools::textColor3f(), "Color" );
@@ -228,9 +241,8 @@ RimEnsembleCurveSet::RimEnsembleCurveSet()
m_summaryAddressNameTools = new RimSummaryCurveAutoName;
m_ensembleStatCase.reset( new RimEnsembleStatisticsCase( this ) );
m_ensembleStatCase->createSummaryReaderInterface();
m_ensembleStatCase->createRftReaderInterface();
m_ensembleStatCaseY.reset( new RimEnsembleStatisticsCase() );
m_ensembleStatCaseXY.reset( new RimEnsembleCrossPlotStatisticsCase() );
m_disableStatisticCurves = false;
m_isCurveSetFiltered = false;
@@ -406,6 +418,31 @@ void RimEnsembleCurveSet::setSummaryAddress( RifEclipseSummaryAddress address )
m_objectiveValuesSummaryAddresses.push_back( summaryAddress );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveSet::setCurveAddress( RiaSummaryCurveAddress address )
{
setSummaryAddress( address.summaryAddressY() );
setSummaryAddressX( address.summaryAddressX() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveSet::setSummaryAddressX( RifEclipseSummaryAddress address )
{
m_xAddressSelector->setAddress( address );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCurveSet::isXAxisSummaryVector() const
{
return m_xAxisType() == RiaDefines::HorizontalAxisType::SUMMARY_VECTOR;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -429,7 +466,12 @@ RifEclipseSummaryAddress RimEnsembleCurveSet::summaryAddress() const
//--------------------------------------------------------------------------------------------------
RiaSummaryCurveAddress RimEnsembleCurveSet::curveAddress() const
{
return RiaSummaryCurveAddress( summaryAddress(), RifEclipseSummaryAddress::timeAddress() );
if ( m_xAxisType() == RiaDefines::HorizontalAxisType::TIME )
{
return RiaSummaryCurveAddress( RifEclipseSummaryAddress::timeAddress(), summaryAddress() );
}
return RiaSummaryCurveAddress( m_xAddressSelector->summaryAddress(), summaryAddress() );
}
//--------------------------------------------------------------------------------------------------
@@ -678,6 +720,42 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
updateTextInPlot = true;
}
else if ( &m_xAxisType == changedField )
{
if ( m_xAxisType() == RiaDefines::HorizontalAxisType::TIME )
{
// TODO: How to handle this?
// m_xPlotAxisProperties = plot->timeAxisProperties();
}
else if ( isXAxisSummaryVector() )
{
if ( !m_xAddressSelector->ensemble() )
{
m_xAddressSelector->setEnsemble( summaryCaseCollection() );
m_xAddressSelector->setAddress( summaryAddress() );
}
if ( !m_xAddressSelector->plotAxisProperties() )
{
RiuPlotAxis plotAxis = RiuPlotAxis::defaultBottomForSummaryVectors();
if ( auto axis = plot->axisPropertiesForPlotAxis( plotAxis ) )
{
m_xAddressSelector->setPlotAxisProperties( axis );
}
else
{
RimPlotAxisProperties* newPlotAxisProperties =
plot->addNewAxisProperties( RiaDefines::PlotAxis::PLOT_AXIS_BOTTOM, "Bottom Axis" );
plot->updateConnectedEditors();
m_xAddressSelector->setPlotAxisProperties( newPlotAxisProperties );
}
}
}
plot->updateAxes();
plot->updatePlotTitle();
updateAllCurves();
}
else if ( changedField == &m_resampling )
{
updateAllCurves();
@@ -914,8 +992,10 @@ void RimEnsembleCurveSet::defineObjectEditorAttribute( QString uiConfigName, caf
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveSet::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
{
m_yValuesSummaryAddressUiField = m_yValuesSummaryAddress->address();
{
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector Y" );
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector" );
curveDataGroup->add( &m_yValuesSummaryCaseCollection );
curveDataGroup->add( &m_yValuesSummaryAddressUiField );
curveDataGroup->add( &m_yPushButtonSelectSummaryAddress, { false, 1, 0 } );
@@ -923,6 +1003,16 @@ void RimEnsembleCurveSet::defineUiOrdering( QString uiConfigName, caf::PdmUiOrde
curveDataGroup->add( &m_plotAxisProperties );
}
{
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector X Axis" );
curveDataGroup->add( &m_xAxisType );
if ( isXAxisSummaryVector() )
{
m_xAddressSelector->uiOrdering( uiConfigName, *curveDataGroup );
}
}
appendColorGroup( uiOrdering );
{
@@ -986,6 +1076,14 @@ void RimEnsembleCurveSet::onCustomObjectiveFunctionChanged( const caf::SignalEmi
updateObjectiveFunctionLegend();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveSet::onXAxisAddressChanged( const caf::SignalEmitter* emitter )
{
updateAllCurves();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -1790,8 +1888,6 @@ void RimEnsembleCurveSet::updateEnsembleCurves( const std::vector<RimSummaryCase
if ( m_statistics->hideEnsembleCurves() ) return;
setLeftOrRightAxisY( axisY() );
RimSummaryAddress* addr = m_yValuesSummaryAddress();
if ( plot && addr->address().category() != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID )
{
@@ -1817,6 +1913,14 @@ void RimEnsembleCurveSet::updateEnsembleCurves( const std::vector<RimSummaryCase
addCurve( curve );
curve->setLeftOrRightAxisY( axisY() );
if ( isXAxisSummaryVector() )
{
curve->setAxisTypeX( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR );
curve->setSummaryCaseX( sumCase );
curve->setSummaryAddressX( m_xAddressSelector->summaryAddress() );
if ( m_xAddressSelector->plotAxisProperties() )
curve->setTopOrBottomAxisX( m_xAddressSelector->plotAxisProperties()->plotAxis() );
}
newSummaryCurves.push_back( curve );
}
@@ -1877,22 +1981,70 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
else
statCases = group->allSummaryCases();
}
m_ensembleStatCase->calculate( statCases, m_statistics->includeIncompleteCurves() );
if ( isXAxisSummaryVector() )
{
m_ensembleStatCaseXY->calculate( statCases,
m_xAddressSelector->summaryAddress(),
summaryAddress(),
m_statistics->includeIncompleteCurves(),
m_statistics->crossPlotCurvesBinCount(),
m_statistics->crossPlotCurvesSampleCountThresholdPerBin() );
}
else
{
m_ensembleStatCaseY->calculate( statCases, summaryAddress(), m_statistics->includeIncompleteCurves() );
}
}
std::vector<RifEclipseSummaryAddress> addresses;
std::vector<RiaSummaryCurveAddress> addresses;
if ( m_statistics->isActive() )
{
RifEclipseSummaryAddress dataAddress = m_yValuesSummaryAddress->address();
if ( isXAxisSummaryVector() )
{
RifEclipseSummaryAddress dataAddressY = m_yValuesSummaryAddress->address();
RifEclipseSummaryAddress dataAddressX = m_xAddressSelector->summaryAddress();
if ( m_statistics->showP10Curve() && m_ensembleStatCase->hasP10Data() )
addresses.push_back( SAddr::ensembleStatisticsAddress( ENSEMBLE_STAT_P10_QUANTITY_NAME, dataAddress.vectorName() ) );
if ( m_statistics->showP50Curve() && m_ensembleStatCase->hasP50Data() )
addresses.push_back( SAddr::ensembleStatisticsAddress( ENSEMBLE_STAT_P50_QUANTITY_NAME, dataAddress.vectorName() ) );
if ( m_statistics->showP90Curve() && m_ensembleStatCase->hasP90Data() )
addresses.push_back( SAddr::ensembleStatisticsAddress( ENSEMBLE_STAT_P90_QUANTITY_NAME, dataAddress.vectorName() ) );
if ( m_statistics->showMeanCurve() && m_ensembleStatCase->hasMeanData() )
addresses.push_back( SAddr::ensembleStatisticsAddress( ENSEMBLE_STAT_MEAN_QUANTITY_NAME, dataAddress.vectorName() ) );
auto getStatisticsAddress = []( const std::string& statisticsVectorName,
const RifEclipseSummaryAddress& addrX,
const RifEclipseSummaryAddress& addrY ) -> RiaSummaryCurveAddress
{
auto xStatAddress = SAddr::ensembleStatisticsAddress( statisticsVectorName, addrX.vectorName() );
auto yStatAddress = SAddr::ensembleStatisticsAddress( statisticsVectorName, addrY.vectorName() );
return RiaSummaryCurveAddress( xStatAddress, yStatAddress );
};
if ( m_statistics->showP10Curve() && m_ensembleStatCaseXY->hasP10Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P10_QUANTITY_NAME, dataAddressX, dataAddressY ) );
if ( m_statistics->showP50Curve() && m_ensembleStatCaseXY->hasP50Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P50_QUANTITY_NAME, dataAddressX, dataAddressY ) );
if ( m_statistics->showP90Curve() && m_ensembleStatCaseXY->hasP90Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P90_QUANTITY_NAME, dataAddressX, dataAddressY ) );
if ( m_statistics->showMeanCurve() && m_ensembleStatCaseXY->hasMeanData() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_MEAN_QUANTITY_NAME, dataAddressX, dataAddressY ) );
}
else
{
RifEclipseSummaryAddress dataAddressY = m_yValuesSummaryAddress->address();
auto getStatisticsAddress = []( const std::string& statisticsVectorName, const RifEclipseSummaryAddress& addrY ) -> RiaSummaryCurveAddress
{
auto xStatAddress = RifEclipseSummaryAddress::timeAddress();
auto yStatAddress = SAddr::ensembleStatisticsAddress( statisticsVectorName, addrY.vectorName() );
return RiaSummaryCurveAddress( xStatAddress, yStatAddress );
};
if ( m_statistics->showP10Curve() && m_ensembleStatCaseY->hasP10Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P10_QUANTITY_NAME, dataAddressY ) );
if ( m_statistics->showP50Curve() && m_ensembleStatCaseY->hasP50Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P50_QUANTITY_NAME, dataAddressY ) );
if ( m_statistics->showP90Curve() && m_ensembleStatCaseY->hasP90Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P90_QUANTITY_NAME, dataAddressY ) );
if ( m_statistics->showMeanCurve() && m_ensembleStatCaseY->hasMeanData() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_MEAN_QUANTITY_NAME, dataAddressY ) );
}
}
deleteStatisticsCurves();
@@ -1900,6 +2052,13 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
auto plot = firstAncestorOrThisOfType<RimSummaryPlot>();
if ( plot && plot->plotWidget() )
{
RimSummaryCase* summaryCase = nullptr;
if ( isXAxisSummaryVector() )
summaryCase = m_ensembleStatCaseXY.get();
else
summaryCase = m_ensembleStatCaseY.get();
for ( auto address : addresses )
{
auto curve = new RimSummaryCurve();
@@ -1908,19 +2067,28 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
curve->setColor( m_statistics->color() );
curve->setResampling( m_resampling() );
auto symbol = statisticsCurveSymbolFromAddress( address );
auto symbol = statisticsCurveSymbolFromAddress( address.summaryAddressY() );
curve->setSymbol( symbol );
curve->setSymbolSize( statisticsCurveSymbolSize( symbol ) );
curve->setSymbolSkipDistance( 150 );
if ( m_statistics->showCurveLabels() )
{
curve->setSymbolLabel( QString::fromStdString( address.ensembleStatisticsVectorName() ) );
curve->setSymbolLabel( QString::fromStdString( address.summaryAddressY().ensembleStatisticsVectorName() ) );
}
curve->setLineStyle( RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID );
curve->setSummaryCaseY( m_ensembleStatCase.get() );
curve->setSummaryAddressYAndApplyInterpolation( address );
curve->setSummaryCaseY( summaryCase );
curve->setSummaryAddressYAndApplyInterpolation( address.summaryAddressY() );
curve->setLeftOrRightAxisY( axisY() );
if ( isXAxisSummaryVector() )
{
curve->setAxisTypeX( RiaDefines::HorizontalAxisType::SUMMARY_VECTOR );
curve->setSummaryCaseX( summaryCase );
curve->setSummaryAddressX( address.summaryAddressX() );
if ( m_xAddressSelector->plotAxisProperties() )
curve->setTopOrBottomAxisX( m_xAddressSelector->plotAxisProperties()->plotAxis() );
}
curve->setShowInLegend( m_statistics->showStatisticsCurveLegends() );
curve->updateCurveVisibility();
@@ -2058,7 +2226,9 @@ bool RimEnsembleCurveSet::isFiltered() const
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCurveSet::hasP10Data() const
{
return m_ensembleStatCase->hasP10Data();
if ( isXAxisSummaryVector() ) return m_ensembleStatCaseXY->hasP10Data();
return m_ensembleStatCaseY->hasP10Data();
}
//--------------------------------------------------------------------------------------------------
@@ -2066,7 +2236,9 @@ bool RimEnsembleCurveSet::hasP10Data() const
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCurveSet::hasP50Data() const
{
return m_ensembleStatCase->hasP50Data();
if ( isXAxisSummaryVector() ) return m_ensembleStatCaseXY->hasP50Data();
return m_ensembleStatCaseY->hasP50Data();
}
//--------------------------------------------------------------------------------------------------
@@ -2074,7 +2246,9 @@ bool RimEnsembleCurveSet::hasP50Data() const
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCurveSet::hasP90Data() const
{
return m_ensembleStatCase->hasP90Data();
if ( isXAxisSummaryVector() ) return m_ensembleStatCaseXY->hasP90Data();
return m_ensembleStatCaseY->hasP90Data();
}
//--------------------------------------------------------------------------------------------------
@@ -2082,7 +2256,9 @@ bool RimEnsembleCurveSet::hasP90Data() const
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCurveSet::hasMeanData() const
{
return m_ensembleStatCase->hasMeanData();
if ( isXAxisSummaryVector() ) return m_ensembleStatCaseXY->hasMeanData();
return m_ensembleStatCaseY->hasMeanData();
}
//--------------------------------------------------------------------------------------------------