mirror of
https://github.com/OPM/ResInsight.git
synced 2026-08-27 05:37:21 -05:00
Enhances ensemble curve handling and performance
* Removes obsolete code * Return first non-empty return value from reader * Simplifies water cut curve visibility check * Defers the page update until after all plots have been added. * Add settings to control number of threads * Refactors ensemble curve handling and visibility Improves the efficiency of ensemble curve set management by separating realization and statistics curves into distinct collections. This allows for more targeted operations, such as selectively showing/hiding realization curves without affecting statistics. Also defers data loading of curves until they are actually displayed, optimizing performance. The visibility updates are modified to optionally skip updating the parent plot, providing more control over replotting behavior and preventing unnecessary updates.
This commit is contained in:
@@ -30,6 +30,7 @@
|
||||
#include "RiaFontCache.h"
|
||||
#include "RiaImportEclipseCaseTools.h"
|
||||
#include "RiaLogging.h"
|
||||
#include "RiaOpenMPTools.h"
|
||||
#include "RiaPlotWindowRedrawScheduler.h"
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaPreferencesOsdu.h"
|
||||
@@ -1590,6 +1591,12 @@ void RiaApplication::initialize()
|
||||
caf::SelectionManager::instance()->setPdmRootObject( project() );
|
||||
|
||||
initializeDataLoadController();
|
||||
|
||||
const auto& [enabled, maxThreads] = RiaPreferencesSystem::current()->maximumNumberOfThreads();
|
||||
if ( enabled )
|
||||
{
|
||||
RiaOpenMPTools::setMaxThreads( maxThreads );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "RiaPreferences.h"
|
||||
#include "RiaPreferencesSystem.h"
|
||||
|
||||
#include "cafPdmUiCheckBoxAndTextEditor.h"
|
||||
#include "cafPdmUiCheckBoxEditor.h"
|
||||
#include "cafPdmUiFilePathEditor.h"
|
||||
|
||||
@@ -100,6 +101,9 @@ RiaPreferencesSystem::RiaPreferencesSystem()
|
||||
"KeywordsForLogging",
|
||||
QString(),
|
||||
"Keywords to enable debug logging, separated by semicolon.\nType 'enable-all' to enable logging for all objects." );
|
||||
|
||||
CAF_PDM_InitField( &m_maximumNumberOfThreads, "maximumNumberOfThreads", std::make_pair( false, QString( "4" ) ), "Maximum Number of Threads" );
|
||||
m_maximumNumberOfThreads.uiCapability()->setUiEditorTypeName( caf::PdmUiCheckBoxAndTextEditor::uiEditorTypeName() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -248,6 +252,16 @@ bool RiaPreferencesSystem::useMultiThreadingForSummaryImport() const
|
||||
return m_useMultiThreadingForSummary_TEMPORARY();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<bool, int> RiaPreferencesSystem::maximumNumberOfThreads() const
|
||||
{
|
||||
const auto& [enabled, text] = m_maximumNumberOfThreads();
|
||||
|
||||
return { enabled, text.toInt() };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -318,6 +332,8 @@ void RiaPreferencesSystem::defineUiOrdering( QString uiConfigName, caf::PdmUiOrd
|
||||
group->add( &m_useImprovedSummaryImport );
|
||||
group->add( &m_useMultiThreadingForSummary_TEMPORARY );
|
||||
}
|
||||
|
||||
uiOrdering.add( &m_maximumNumberOfThreads );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -60,6 +60,8 @@ public:
|
||||
bool useImprovedSummaryImport() const;
|
||||
bool useMultiThreadingForSummaryImport() const;
|
||||
|
||||
std::pair<bool, int> maximumNumberOfThreads() const;
|
||||
|
||||
bool logToFile() const;
|
||||
|
||||
EclipseTextFileReaderMode eclipseTextFileReaderMode() const;
|
||||
@@ -97,4 +99,6 @@ private:
|
||||
caf::PdmField<EclipseTextFileReaderModeType> m_eclipseReaderMode;
|
||||
|
||||
caf::PdmField<QString> m_keywordsForLogging;
|
||||
|
||||
caf::PdmField<std::pair<bool, QString>> m_maximumNumberOfThreads;
|
||||
};
|
||||
|
||||
@@ -48,3 +48,13 @@ int RiaOpenMPTools::currentThreadIndex()
|
||||
|
||||
return myThread;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiaOpenMPTools::setMaxThreads( int numberOfThreads )
|
||||
{
|
||||
#ifdef USE_OPENMP
|
||||
omp_set_num_threads( numberOfThreads );
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
//==================================================================================================
|
||||
namespace RiaOpenMPTools
|
||||
{
|
||||
int availableThreadCount();
|
||||
int currentThreadIndex();
|
||||
int availableThreadCount();
|
||||
int currentThreadIndex();
|
||||
void setMaxThreads( int numberOfThreads );
|
||||
}; // namespace RiaOpenMPTools
|
||||
|
||||
@@ -610,11 +610,6 @@ void RicSummaryPlotEditorUi::updateTargetPlot()
|
||||
|
||||
RimEnsembleCurveSet* newCurveSet = editedCurveSet->clone();
|
||||
m_targetPlot->ensembleCurveSetCollection()->addCurveSet( newCurveSet );
|
||||
for ( const auto& editedCurve : newCurveSet->curves() )
|
||||
{
|
||||
copyEnsembleCurveAndAddToCurveSet( editedCurve, editedCurveSet );
|
||||
}
|
||||
|
||||
newCurveSet->setParentPlotNoReplot( m_targetPlot->plotWidget() );
|
||||
}
|
||||
|
||||
@@ -646,27 +641,6 @@ void RicSummaryPlotEditorUi::copyCurveAndAddToPlot( const RimSummaryCurve* curve
|
||||
curveCopy->loadDataAndUpdate( false );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RicSummaryPlotEditorUi::copyEnsembleCurveAndAddToCurveSet( const RimSummaryCurve* curve, RimEnsembleCurveSet* curveSet, bool forceVisible )
|
||||
{
|
||||
auto curveCopy = curve->copyObject<RimSummaryCurve>();
|
||||
CVF_ASSERT( curveCopy );
|
||||
|
||||
if ( forceVisible )
|
||||
{
|
||||
curveCopy->setCheckState( true );
|
||||
}
|
||||
|
||||
curveSet->addCurve( curveCopy );
|
||||
|
||||
// The curve creator is not a descendant of the project, and need to be set manually
|
||||
curveCopy->setSummaryCaseY( curve->summaryCaseY() );
|
||||
curveCopy->initAfterReadRecursively();
|
||||
curveCopy->loadDataAndUpdate( false );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -88,7 +88,6 @@ private:
|
||||
void populateCurveCreator( const RimSummaryPlot& sourceSummaryPlot );
|
||||
void updateTargetPlot();
|
||||
static void copyCurveAndAddToPlot( const RimSummaryCurve* curve, RimSummaryPlot* plot, bool forceVisible = false );
|
||||
static void copyEnsembleCurveAndAddToCurveSet( const RimSummaryCurve* curve, RimEnsembleCurveSet* curveSet, bool forceVisible = false );
|
||||
void setDefaultCurveSelection( const std::vector<caf::PdmObject*>& defaultCases );
|
||||
|
||||
void resetAllFields();
|
||||
|
||||
@@ -74,7 +74,8 @@ std::vector<time_t> RifMultipleSummaryReaders::timeSteps( const RifEclipseSummar
|
||||
{
|
||||
for ( const auto& r : m_readers )
|
||||
{
|
||||
if ( r->hasAddress( resultAddress ) ) return r->timeSteps( resultAddress );
|
||||
const auto& timeSteps = r->timeSteps( resultAddress );
|
||||
if ( !timeSteps.empty() ) return timeSteps;
|
||||
}
|
||||
|
||||
return {};
|
||||
@@ -87,7 +88,8 @@ std::pair<bool, std::vector<double>> RifMultipleSummaryReaders::values( const Ri
|
||||
{
|
||||
for ( const auto& r : m_readers )
|
||||
{
|
||||
if ( r->hasAddress( resultAddress ) ) return r->values( resultAddress );
|
||||
const auto& okAndValues = r->values( resultAddress );
|
||||
if ( okAndValues.first && !okAndValues.second.empty() ) return okAndValues;
|
||||
}
|
||||
|
||||
return { false, {} };
|
||||
@@ -100,7 +102,8 @@ std::string RifMultipleSummaryReaders::unitName( const RifEclipseSummaryAddress&
|
||||
{
|
||||
for ( const auto& r : m_readers )
|
||||
{
|
||||
if ( r->hasAddress( resultAddress ) ) return r->unitName( resultAddress );
|
||||
auto name = r->unitName( resultAddress );
|
||||
if ( !name.empty() ) return name;
|
||||
}
|
||||
|
||||
return {};
|
||||
|
||||
@@ -296,7 +296,7 @@ void RimPlotCurve::initAfterRead()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotCurve::updateCurvePresentation( bool updatePlotLegendAndTitle )
|
||||
{
|
||||
updateCurveVisibility();
|
||||
updateCurveVisibility( updatePlotLegendAndTitle );
|
||||
|
||||
if ( updatePlotLegendAndTitle )
|
||||
{
|
||||
@@ -1078,15 +1078,15 @@ void RimPlotCurve::updateUiIconFromPlotSymbol()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotCurve::updateCurveVisibility()
|
||||
void RimPlotCurve::updateCurveVisibility( bool updateParentPlot )
|
||||
{
|
||||
if ( canCurveBeAttached() )
|
||||
{
|
||||
reattach();
|
||||
reattach( updateParentPlot );
|
||||
}
|
||||
else
|
||||
{
|
||||
detach();
|
||||
detach( updateParentPlot );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -101,7 +101,7 @@ public:
|
||||
void setCustomName( const QString& customName );
|
||||
void setLegendEntryText( const QString& legendEntryText );
|
||||
|
||||
virtual void updateCurveVisibility();
|
||||
void updateCurveVisibility( bool updateParentPlot = true );
|
||||
void updateLegendEntryVisibilityAndPlotLegend();
|
||||
virtual void updateLegendEntryVisibilityNoPlotUpdate();
|
||||
virtual void replotParentPlot();
|
||||
|
||||
@@ -94,40 +94,28 @@ int statisticsCurveSymbolSize( RiuPlotCurveSymbo
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimEnsembleCurveSet, "RimEnsembleCurveSet" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
|
||||
{
|
||||
if ( isFiltered() )
|
||||
{
|
||||
menuBuilder << "RicCreateEnsembleFromFilteredCasesFeature";
|
||||
}
|
||||
|
||||
menuBuilder << "RicNewSummaryEnsembleCurveSetFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicSetSourceSteppingEnsembleCurveSetFeature";
|
||||
menuBuilder << "RicClearSourceSteppingEnsembleCurveSetFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicNewEnsembleCurveFilterFeature";
|
||||
menuBuilder << "RicCreateRegressionAnalysisCurveFeature";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEnsembleCurveSet::RimEnsembleCurveSet()
|
||||
: filterChanged( this )
|
||||
, m_hash( 0 )
|
||||
, m_realizationHash( 0 )
|
||||
|
||||
{
|
||||
CAF_PDM_InitObject( "Ensemble Curve Set", ":/EnsembleCurveSet16x16.png" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_curves, "EnsembleCurveSet", "Ensemble Curve Set" );
|
||||
m_curves.uiCapability()->setUiTreeChildrenHidden( false );
|
||||
CAF_PDM_InitFieldNoDefault( &m_realizationCurves, "EnsembleCurveSet", "Ensemble Curve Set" );
|
||||
m_realizationCurves.uiCapability()->setUiTreeChildrenHidden( false );
|
||||
// The summary curves are always recreated in loadDataAndUpdate(), so we can disable IO for curves. This will reduce the size of the
|
||||
// project files.
|
||||
m_curves.xmlCapability()->disableIO();
|
||||
m_realizationCurves.xmlCapability()->disableIO();
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_statisticsCurves, "StatisticsCurves", "Statistics Curves" );
|
||||
m_statisticsCurves.uiCapability()->setUiTreeChildrenHidden( false );
|
||||
// The summary curves are always recreated in loadDataAndUpdate(), so we can disable IO for curves. This will reduce the size of the
|
||||
// project files.
|
||||
m_statisticsCurves.xmlCapability()->disableIO();
|
||||
|
||||
CAF_PDM_InitField( &m_showCurves, "IsActive", true, "Show Curves" );
|
||||
m_showCurves.uiCapability()->setUiHidden( true );
|
||||
@@ -277,7 +265,8 @@ RimEnsembleCurveSet::RimEnsembleCurveSet()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimEnsembleCurveSet::~RimEnsembleCurveSet()
|
||||
{
|
||||
m_curves.deleteChildren();
|
||||
m_realizationCurves.deleteChildren();
|
||||
m_statisticsCurves.deleteChildren();
|
||||
|
||||
auto parentPlot = firstAncestorOrThisOfType<RimSummaryPlot>();
|
||||
if ( parentPlot && parentPlot->plotWidget() )
|
||||
@@ -368,8 +357,9 @@ void RimEnsembleCurveSet::loadDataAndUpdate( bool updateParentPlot )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::setParentPlotNoReplot( RiuPlotWidget* plot )
|
||||
{
|
||||
for ( RimSummaryCurve* curve : m_curves )
|
||||
for ( RimSummaryCurve* curve : curves() )
|
||||
{
|
||||
// This operation will recreate the plot curve if not present, but no data is loaded
|
||||
curve->setParentPlotNoReplot( plot );
|
||||
}
|
||||
}
|
||||
@@ -379,7 +369,7 @@ void RimEnsembleCurveSet::setParentPlotNoReplot( RiuPlotWidget* plot )
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::deletePlotCurves()
|
||||
{
|
||||
for ( RimSummaryCurve* curve : m_curves )
|
||||
for ( RimSummaryCurve* curve : curves() )
|
||||
{
|
||||
curve->deletePlotCurve();
|
||||
}
|
||||
@@ -396,15 +386,15 @@ void RimEnsembleCurveSet::deletePlotCurves()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::reattachPlotCurves()
|
||||
{
|
||||
for ( RimSummaryCurve* curve : m_curves )
|
||||
for ( RimSummaryCurve* curve : curves() )
|
||||
{
|
||||
bool updateParentPlot = false;
|
||||
curve->reattach( updateParentPlot );
|
||||
}
|
||||
|
||||
if ( !m_curves.empty() )
|
||||
if ( !curves().empty() )
|
||||
{
|
||||
auto firstCurve = m_curves[0];
|
||||
auto firstCurve = curves()[0];
|
||||
|
||||
firstCurve->replotParentPlot();
|
||||
}
|
||||
@@ -413,7 +403,7 @@ void RimEnsembleCurveSet::reattachPlotCurves()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::addCurve( RimSummaryCurve* curve )
|
||||
void RimEnsembleCurveSet::addRealizationCurve( RimSummaryCurve* curve )
|
||||
{
|
||||
if ( curve )
|
||||
{
|
||||
@@ -421,19 +411,7 @@ void RimEnsembleCurveSet::addCurve( RimSummaryCurve* curve )
|
||||
if ( plot && plot->plotWidget() ) curve->setParentPlotNoReplot( plot->plotWidget() );
|
||||
|
||||
curve->setColor( m_colorForRealizations );
|
||||
m_curves.push_back( curve );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::deleteCurve( RimSummaryCurve* curve )
|
||||
{
|
||||
if ( curve )
|
||||
{
|
||||
m_curves.removeChild( curve );
|
||||
delete curve;
|
||||
m_realizationCurves.push_back( curve );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -677,7 +655,10 @@ RiaSummaryCurveAddress RimEnsembleCurveSet::curveAddress() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCurve*> RimEnsembleCurveSet::curves() const
|
||||
{
|
||||
return m_curves.childrenByType();
|
||||
std::vector<RimSummaryCurve*> allCurves = m_realizationCurves.childrenByType();
|
||||
auto statCurves = m_statisticsCurves.childrenByType();
|
||||
allCurves.insert( allCurves.end(), statCurves.begin(), statCurves.end() );
|
||||
return allCurves;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -693,20 +674,7 @@ RimCustomObjectiveFunctionCollection* RimEnsembleCurveSet::customObjectiveFuncti
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::deleteEnsembleCurves()
|
||||
{
|
||||
std::vector<size_t> curvesIndexesToDelete;
|
||||
for ( size_t c = 0; c < m_curves.size(); c++ )
|
||||
{
|
||||
RimSummaryCurve* curve = m_curves[c];
|
||||
if ( !curve->summaryAddressY().isStatistics() ) curvesIndexesToDelete.push_back( c );
|
||||
}
|
||||
|
||||
while ( !curvesIndexesToDelete.empty() )
|
||||
{
|
||||
size_t currIndex = curvesIndexesToDelete.back();
|
||||
delete m_curves[currIndex];
|
||||
m_curves.erase( currIndex );
|
||||
curvesIndexesToDelete.pop_back();
|
||||
}
|
||||
m_realizationCurves.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -714,20 +682,7 @@ void RimEnsembleCurveSet::deleteEnsembleCurves()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::deleteStatisticsCurves()
|
||||
{
|
||||
std::vector<size_t> curvesIndexesToDelete;
|
||||
for ( size_t c = 0; c < m_curves.size(); c++ )
|
||||
{
|
||||
RimSummaryCurve* curve = m_curves[c];
|
||||
if ( curve->summaryAddressY().isStatistics() ) curvesIndexesToDelete.push_back( c );
|
||||
}
|
||||
|
||||
while ( !curvesIndexesToDelete.empty() )
|
||||
{
|
||||
size_t currIndex = curvesIndexesToDelete.back();
|
||||
delete m_curves[currIndex];
|
||||
m_curves.erase( currIndex );
|
||||
curvesIndexesToDelete.pop_back();
|
||||
}
|
||||
m_statisticsCurves.deleteChildren();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -1323,6 +1278,26 @@ void RimEnsembleCurveSet::defineUiOrdering( QString uiConfigName, caf::PdmUiOrde
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCurve*> RimEnsembleCurveSet::realizationCurves() const
|
||||
{
|
||||
return m_realizationCurves.childrenByType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::deleteRealizationCurve( RimSummaryCurve* curve )
|
||||
{
|
||||
if ( curve )
|
||||
{
|
||||
m_realizationCurves.removeChild( curve );
|
||||
delete curve;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -1780,9 +1755,9 @@ RiaSummaryCurveDefinitionAnalyser* RimEnsembleCurveSet::getOrCreateSelectedCurve
|
||||
std::vector<RiaSummaryCurveDefinition> RimEnsembleCurveSet::curveDefinitions() const
|
||||
{
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefs;
|
||||
for ( auto dataEntry : m_curves() )
|
||||
for ( auto curve : curves() )
|
||||
{
|
||||
curveDefs.push_back( dataEntry->curveDefinition() );
|
||||
curveDefs.push_back( curve->curveDefinition() );
|
||||
}
|
||||
|
||||
return curveDefs;
|
||||
@@ -2054,14 +2029,10 @@ void RimEnsembleCurveSet::updateCurveColors()
|
||||
{
|
||||
updateLegendTitle();
|
||||
|
||||
// Find the curves to color (skip the statistics)
|
||||
std::vector<RimSummaryCurve*> curvesToColor;
|
||||
std::vector<RimSummaryCurve*> curvesToColor = realizationCurves();
|
||||
std::vector<RimSummaryCase*> summaryCases;
|
||||
for ( auto& curve : m_curves )
|
||||
for ( auto& curve : curvesToColor )
|
||||
{
|
||||
if ( curve->summaryAddressY().isStatistics() ) continue;
|
||||
|
||||
curvesToColor.push_back( curve );
|
||||
summaryCases.push_back( curve->summaryCaseY() );
|
||||
}
|
||||
|
||||
@@ -2148,91 +2119,87 @@ void RimEnsembleCurveSet::updateEnsembleCurves( const std::vector<RimSummaryCase
|
||||
{
|
||||
auto plot = firstAncestorOrThisOfTypeAsserted<RimSummaryPlot>();
|
||||
|
||||
deleteEnsembleCurves();
|
||||
deleteStatisticsCurves();
|
||||
|
||||
if ( plot && plot->plotWidget() )
|
||||
auto addressText = m_yValuesSummaryAddress()->address().toEclipseTextAddress();
|
||||
auto newRealizationHash = RiaHashTools::hash( sumCases, addressText );
|
||||
if ( newRealizationHash != m_realizationHash )
|
||||
{
|
||||
if ( plot->legendsVisible() ) plot->plotWidget()->updateLegend();
|
||||
plot->scheduleReplotIfVisible();
|
||||
plot->updateAxes();
|
||||
plot->updatePlotInfoLabel();
|
||||
|
||||
// Always recreate the plot curve for the legend text to ensure the ordering is correct
|
||||
// The ordering of legend items depends on the order the curves are added to the plot
|
||||
//
|
||||
// https://github.com/OPM/ResInsight/issues/12259
|
||||
//
|
||||
m_plotCurveForLegendText.reset( plot->plotWidget()->createPlotCurve( nullptr, "" ) );
|
||||
|
||||
int curveThickness = 3;
|
||||
m_plotCurveForLegendText->setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID,
|
||||
RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_POINT_TO_POINT,
|
||||
curveThickness,
|
||||
RiaColorTools::toQColor( m_mainEnsembleColor() ) );
|
||||
m_plotCurveForLegendText->attachToPlot( plot->plotWidget() );
|
||||
updateEnsembleLegendItem();
|
||||
deleteEnsembleCurves();
|
||||
}
|
||||
|
||||
if ( m_statistics->hideEnsembleCurves() ) return;
|
||||
|
||||
RimSummaryAddress* addr = m_yValuesSummaryAddress();
|
||||
if ( plot && addr->address().category() != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID )
|
||||
const bool showRealizationCurves = !m_statistics->hideEnsembleCurves() && isCurvesVisible();
|
||||
if ( !showRealizationCurves )
|
||||
{
|
||||
if ( isCurvesVisible() )
|
||||
for ( auto c : realizationCurves() )
|
||||
{
|
||||
std::vector<RimSummaryCurve*> newSummaryCurves;
|
||||
|
||||
for ( auto& sumCase : sumCases )
|
||||
{
|
||||
auto curve = RiaSummaryPlotTools::createCurve( sumCase, addr->address() );
|
||||
curve->setResampling( m_resampling() );
|
||||
|
||||
int lineThickness = 1;
|
||||
if ( addr->address().isHistoryVector() )
|
||||
{
|
||||
lineThickness = 2;
|
||||
curve->setCurveAppearanceFromCaseType();
|
||||
}
|
||||
curve->setLineThickness( lineThickness );
|
||||
|
||||
if ( m_useCustomAppearance() == RimCurveAppearanceDefines::AppearanceMode::CUSTOM )
|
||||
{
|
||||
curve->setLineStyle( m_lineStyle() );
|
||||
curve->setSymbol( m_pointSymbol() );
|
||||
curve->setSymbolSize( m_symbolSize() );
|
||||
}
|
||||
|
||||
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 );
|
||||
}
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int i = 0; i < (int)newSummaryCurves.size(); ++i )
|
||||
{
|
||||
newSummaryCurves[i]->valuesX();
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)newSummaryCurves.size(); ++i )
|
||||
{
|
||||
newSummaryCurves[i]->loadDataAndUpdate( false );
|
||||
newSummaryCurves[i]->updatePlotAxis();
|
||||
newSummaryCurves[i]->setShowInLegend( false );
|
||||
}
|
||||
c->setCheckState( false );
|
||||
bool updatePlot = false;
|
||||
c->updateCurveVisibility( updatePlot );
|
||||
}
|
||||
}
|
||||
updateCurveColors();
|
||||
|
||||
deleteStatisticsCurves();
|
||||
|
||||
recreatePlotCurveForLegend( plot );
|
||||
|
||||
if ( showRealizationCurves )
|
||||
{
|
||||
RimSummaryAddress* addr = m_yValuesSummaryAddress();
|
||||
if ( plot && addr->address().category() != RifEclipseSummaryAddressDefines::SummaryCategory::SUMMARY_INVALID )
|
||||
{
|
||||
if ( newRealizationHash != m_realizationHash )
|
||||
{
|
||||
deleteEnsembleCurves();
|
||||
|
||||
createCurves( sumCases, *addr );
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( auto c : realizationCurves() )
|
||||
{
|
||||
c->setCheckState( true );
|
||||
bool updatePlot = false;
|
||||
c->updateCurveVisibility( updatePlot );
|
||||
}
|
||||
}
|
||||
|
||||
auto curves = realizationCurves();
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int i = 0; i < (int)curves.size(); ++i )
|
||||
{
|
||||
// When the curves are created, they contain no data. Curves can be reattached to the plot without loading of data in
|
||||
// setParentPlotNoReplot(). Check if the curves need to load data. Read data from file reader in parallell.
|
||||
if ( auto plotCurve = curves[i]->plotCurve() )
|
||||
{
|
||||
auto sampleCount = plotCurve->numSamples();
|
||||
if ( sampleCount == 0 )
|
||||
{
|
||||
curves[i]->valuesY();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for ( int i = 0; i < (int)curves.size(); ++i )
|
||||
{
|
||||
// Check if the curve objects contains data.
|
||||
if ( auto plotCurve = curves[i]->plotCurve() )
|
||||
{
|
||||
auto sampleCount = plotCurve->numSamples();
|
||||
if ( sampleCount == 0 )
|
||||
{
|
||||
curves[i]->loadDataAndUpdate( false );
|
||||
}
|
||||
}
|
||||
|
||||
curves[i]->updatePlotAxis();
|
||||
curves[i]->setShowInLegend( false );
|
||||
}
|
||||
}
|
||||
updateCurveColors();
|
||||
|
||||
// Set hash when curves has been created or updated
|
||||
m_realizationHash = newRealizationHash;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -2342,7 +2309,8 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
|
||||
{
|
||||
auto curve = RiaSummaryPlotTools::createCurve( summaryCase, address.summaryAddressY() );
|
||||
curve->setParentPlotNoReplot( plot->plotWidget() );
|
||||
m_curves.push_back( curve );
|
||||
m_statisticsCurves.push_back( curve );
|
||||
|
||||
curve->setColor( m_statistics->color() );
|
||||
curve->setResampling( m_resampling() );
|
||||
|
||||
@@ -2382,8 +2350,9 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
|
||||
|
||||
curve->setShowInLegend( m_statistics->showStatisticsCurveLegends() );
|
||||
|
||||
curve->updateCurveVisibility();
|
||||
curve->loadDataAndUpdate( false );
|
||||
bool updatePlot = false;
|
||||
curve->updateCurveVisibility( updatePlot );
|
||||
curve->loadDataAndUpdate( updatePlot );
|
||||
curve->updatePlotAxis();
|
||||
}
|
||||
|
||||
@@ -2751,3 +2720,114 @@ void RimEnsembleCurveSet::initAfterRead()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const
|
||||
{
|
||||
if ( isFiltered() )
|
||||
{
|
||||
menuBuilder << "RicCreateEnsembleFromFilteredCasesFeature";
|
||||
}
|
||||
|
||||
menuBuilder << "RicNewSummaryEnsembleCurveSetFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicSetSourceSteppingEnsembleCurveSetFeature";
|
||||
menuBuilder << "RicClearSourceSteppingEnsembleCurveSetFeature";
|
||||
menuBuilder << "Separator";
|
||||
menuBuilder << "RicNewEnsembleCurveFilterFeature";
|
||||
menuBuilder << "RicCreateRegressionAnalysisCurveFeature";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::createCurves( const std::vector<RimSummaryCase*>& sumCases, const RimSummaryAddress& addr )
|
||||
{
|
||||
std::vector<RimSummaryCurve*> newSummaryCurves;
|
||||
newSummaryCurves.resize( sumCases.size() );
|
||||
|
||||
{
|
||||
// Make sure static CAF data for the summary curve is initialized. This is required before we create curves in the multi-threaded
|
||||
// loop below.
|
||||
RimSummaryCurve dummy;
|
||||
}
|
||||
|
||||
#pragma omp parallel for
|
||||
for ( int i = 0; i < static_cast<int>( sumCases.size() ); i++ )
|
||||
{
|
||||
auto* sumCase = sumCases[i];
|
||||
auto curve = RiaSummaryPlotTools::createCurve( sumCase, addr.address() );
|
||||
curve->setResampling( m_resampling() );
|
||||
|
||||
int lineThickness = 1;
|
||||
if ( addr.address().isHistoryVector() )
|
||||
{
|
||||
lineThickness = 2;
|
||||
curve->setCurveAppearanceFromCaseType();
|
||||
}
|
||||
curve->setLineThickness( lineThickness );
|
||||
|
||||
if ( m_useCustomAppearance() == RimCurveAppearanceDefines::AppearanceMode::CUSTOM )
|
||||
{
|
||||
curve->setLineStyle( m_lineStyle() );
|
||||
curve->setSymbol( m_pointSymbol() );
|
||||
curve->setSymbolSize( m_symbolSize() );
|
||||
}
|
||||
|
||||
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() );
|
||||
}
|
||||
|
||||
curve->setColor( m_colorForRealizations );
|
||||
|
||||
newSummaryCurves[i] = curve;
|
||||
}
|
||||
|
||||
auto plot = firstAncestorOrThisOfType<RimSummaryPlot>();
|
||||
auto plotWidget = plot ? plot->plotWidget() : nullptr;
|
||||
|
||||
// These operations are not thread safe. They will update the parent plot and manipulate structures in Qwt that are not thread safe.
|
||||
for ( auto* curve : newSummaryCurves )
|
||||
{
|
||||
curve->setParentPlotNoReplot( plotWidget );
|
||||
m_realizationCurves.push_back( curve );
|
||||
|
||||
curve->setLeftOrRightAxisY( axisY() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::recreatePlotCurveForLegend( RimSummaryPlot* plot )
|
||||
{
|
||||
if ( plot && plot->plotWidget() )
|
||||
{
|
||||
if ( plot->legendsVisible() ) plot->plotWidget()->updateLegend();
|
||||
plot->scheduleReplotIfVisible();
|
||||
plot->updateAxes();
|
||||
plot->updatePlotInfoLabel();
|
||||
|
||||
// Always recreate the plot curve for the legend text to ensure the ordering is correct
|
||||
// The ordering of legend items depends on the order the curves are added to the plot
|
||||
//
|
||||
// https://github.com/OPM/ResInsight/issues/12259
|
||||
//
|
||||
m_plotCurveForLegendText.reset( plot->plotWidget()->createPlotCurve( nullptr, "" ) );
|
||||
|
||||
int curveThickness = 3;
|
||||
m_plotCurveForLegendText->setAppearance( RiuQwtPlotCurveDefines::LineStyleEnum::STYLE_SOLID,
|
||||
RiuQwtPlotCurveDefines::CurveInterpolationEnum::INTERPOLATION_POINT_TO_POINT,
|
||||
curveThickness,
|
||||
RiaColorTools::toQColor( m_mainEnsembleColor() ) );
|
||||
m_plotCurveForLegendText->attachToPlot( plot->plotWidget() );
|
||||
updateEnsembleLegendItem();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -66,6 +66,7 @@ class RiuPlotWidget;
|
||||
class RiuPlotCurve;
|
||||
class RimPlotAxisPropertiesInterface;
|
||||
class RimSummaryAddressSelector;
|
||||
class RimSummaryPlot;
|
||||
class RimTimeAxisAnnotation;
|
||||
|
||||
class QwtPlot;
|
||||
@@ -106,8 +107,8 @@ public:
|
||||
void deletePlotCurves();
|
||||
void reattachPlotCurves();
|
||||
|
||||
void addCurve( RimSummaryCurve* curve );
|
||||
void deleteCurve( RimSummaryCurve* curve );
|
||||
void addRealizationCurve( RimSummaryCurve* curve );
|
||||
void deleteRealizationCurve( RimSummaryCurve* curve );
|
||||
|
||||
void setSummaryAddressY( RifEclipseSummaryAddress address );
|
||||
void setCurveAddress( RiaSummaryCurveAddress address );
|
||||
@@ -207,6 +208,8 @@ private:
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefinitions() const;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
std::vector<RimSummaryCurve*> realizationCurves() const;
|
||||
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName = "" ) override;
|
||||
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
@@ -238,9 +241,13 @@ private:
|
||||
|
||||
void appendMenuItems( caf::CmdFeatureMenuBuilder& menuBuilder ) const override;
|
||||
|
||||
void createCurves( const std::vector<RimSummaryCase*>& sumCases, const RimSummaryAddress& addr );
|
||||
void recreatePlotCurveForLegend( RimSummaryPlot* plot );
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showCurves;
|
||||
caf::PdmChildArrayField<RimSummaryCurve*> m_curves;
|
||||
caf::PdmChildArrayField<RimSummaryCurve*> m_realizationCurves;
|
||||
caf::PdmChildArrayField<RimSummaryCurve*> m_statisticsCurves;
|
||||
|
||||
caf::PdmPointer<RimSummaryCurve> m_currentSummaryCurve;
|
||||
|
||||
@@ -312,4 +319,5 @@ private:
|
||||
|
||||
QList<caf::PdmOptionItemInfo> m_cachedAddressOptions;
|
||||
size_t m_hash;
|
||||
size_t m_realizationHash;
|
||||
};
|
||||
|
||||
@@ -1103,15 +1103,12 @@ bool RimSummaryPlot::isOnlyWaterCutCurvesVisible( RiuPlotAxis plotAxis )
|
||||
auto curves = visibleSummaryCurvesForAxis( plotAxis );
|
||||
if ( curves.empty() ) return false;
|
||||
|
||||
size_t waterCutCurveCount = 0;
|
||||
for ( auto c : curves )
|
||||
for ( const auto& c : curves )
|
||||
{
|
||||
auto quantityName = c->summaryAddressY().vectorName();
|
||||
|
||||
if ( RiaStdStringTools::endsWith( quantityName, "WCT" ) ) waterCutCurveCount++;
|
||||
if ( !RiaStdStringTools::endsWith( quantityName, "WCT" ) ) return false;
|
||||
}
|
||||
|
||||
return ( waterCutCurveCount == curves.size() );
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -1436,14 +1433,6 @@ void RimSummaryPlot::removeCurve( RimSummaryCurve* curve )
|
||||
m_summaryCurveCollection->removeCurve( curve );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryPlot::deleteCurve( RimSummaryCurve* curve )
|
||||
{
|
||||
deleteCurves( { curve } );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -1471,7 +1460,7 @@ void RimSummaryPlot::deleteCurves( const std::vector<RimSummaryCurve*>& curves )
|
||||
{
|
||||
if ( c == curve )
|
||||
{
|
||||
curveSet->deleteCurve( curve );
|
||||
curveSet->deleteRealizationCurve( curve );
|
||||
if ( curveSet->curves().empty() )
|
||||
{
|
||||
if ( curveSet->colorMode() == RimEnsembleCurveSet::ColorMode::BY_ENSEMBLE_PARAM && plotWidget() &&
|
||||
|
||||
@@ -104,7 +104,6 @@ public:
|
||||
|
||||
void removeCurve( RimSummaryCurve* curve );
|
||||
|
||||
void deleteCurve( RimSummaryCurve* curve );
|
||||
void deleteCurves( const std::vector<RimSummaryCurve*>& curves );
|
||||
|
||||
void deleteCurvesAssosiatedWithCase( RimSummaryCase* summaryCase );
|
||||
|
||||
@@ -73,7 +73,6 @@ void RiuSummaryMultiPlotBook::createPages()
|
||||
}
|
||||
|
||||
page->addPlot( plotWidgets[visibleIndex] );
|
||||
page->performUpdate( RiaDefines::MultiPlotPageUpdateType::ALL );
|
||||
|
||||
col += colSpan;
|
||||
if ( col >= columns )
|
||||
|
||||
Reference in New Issue
Block a user