Skip to content

Commit

Permalink
Add regression curves to ensemble statistics curves
Browse files Browse the repository at this point in the history
* Add statistics enum
* Support ensemble statistics curve as data source for regression curves
* Allow creation of regression curves from statistics curves
* Make sure regression curves are updated after source curves
* Add state to use full or user defined range for regression source data
* Add isRegressionCurve
* Make sure source stepping works when regression curves are present
  • Loading branch information
magnesj authored Sep 30, 2023
1 parent 31596e0 commit 263e39b
Show file tree
Hide file tree
Showing 16 changed files with 561 additions and 142 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ void RiaSummaryAddressAnalyzer::computeQuantityNamesWithHistory() const
//--------------------------------------------------------------------------------------------------
void RiaSummaryAddressAnalyzer::analyzeSingleAddress( const RifEclipseSummaryAddress& address )
{
if ( !address.isValid() ) return;

if ( address.category() == SummaryCategory::SUMMARY_TIME )
{
m_onlyCrossPlotCurves = false;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,15 @@

#include "RicCreateRegressionAnalysisCurveFeature.h"

#include "RiaColorTools.h"
#include "RiaSummaryTools.h"

#include "RimEnsembleCurveSet.h"
#include "RimSummaryCurve.h"
#include "RimSummaryMultiPlot.h"
#include "RimSummaryPlot.h"
#include "RimSummaryRegressionAnalysisCurve.h"

#include "RiuPlotMainWindowTools.h"

#include "cafSelectionManagerTools.h"
Expand All @@ -39,20 +42,28 @@ CAF_CMD_SOURCE_INIT( RicCreateRegressionAnalysisCurveFeature, "RicCreateRegressi
//--------------------------------------------------------------------------------------------------
bool RicCreateRegressionAnalysisCurveFeature::isCommandEnabled() const
{
RimSummaryPlot* selectedPlot = caf::firstAncestorOfTypeFromSelectedObject<RimSummaryPlot>();
return ( selectedPlot && !RiaSummaryTools::isSummaryCrossPlot( selectedPlot ) );
return caf::firstAncestorOfTypeFromSelectedObject<RimSummaryPlot>();
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicCreateRegressionAnalysisCurveFeature::onActionTriggered( bool isChecked )
{
RimSummaryCurve* curve = caf::firstAncestorOfTypeFromSelectedObject<RimSummaryCurve>();
if ( curve )
RimSummaryRegressionAnalysisCurve* newCurve = nullptr;

if ( auto summaryCurve = caf::firstAncestorOfTypeFromSelectedObject<RimSummaryCurve>() )
{
newCurve = createRegressionAnalysisCurveAndAddToPlot( summaryCurve );
}

if ( auto curveSet = caf::firstAncestorOfTypeFromSelectedObject<RimEnsembleCurveSet>() )
{
RimSummaryRegressionAnalysisCurve* newCurve = createRegressionAnalysisCurveAndAddToPlot( curve );
newCurve = createRegressionAnalysisCurveAndAddToPlot( curveSet );
}

if ( newCurve )
{
RiuPlotMainWindowTools::showPlotMainWindow();
RiuPlotMainWindowTools::selectAsCurrentItem( newCurve );
}
Expand All @@ -75,9 +86,7 @@ RimSummaryRegressionAnalysisCurve*
{
RimSummaryPlot* summaryPlot = caf::firstAncestorOfTypeFromSelectedObject<RimSummaryPlot>();

RimSummaryRegressionAnalysisCurve* newCurve = new RimSummaryRegressionAnalysisCurve();
CVF_ASSERT( newCurve );

auto newCurve = new RimSummaryRegressionAnalysisCurve();
RiaSummaryTools::copyCurveDataSources( *newCurve, *sourceCurve );

newCurve->setColor( sourceCurve->color() );
Expand All @@ -88,7 +97,47 @@ RimSummaryRegressionAnalysisCurve*

RiaSummaryTools::copyCurveAxisData( *newCurve, *sourceCurve );

newCurve->updateDefaultValues();
newCurve->loadDataAndUpdate( true );
newCurve->updateConnectedEditors();

RimSummaryMultiPlot* summaryMultiPlot = summaryPlot->firstAncestorOrThisOfType<RimSummaryMultiPlot>();
if ( summaryMultiPlot )
{
summaryMultiPlot->updatePlotTitles();
}
else
{
summaryPlot->updatePlotTitle();
}

summaryPlot->updateAllRequiredEditors();

return newCurve;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryRegressionAnalysisCurve*
RicCreateRegressionAnalysisCurveFeature::createRegressionAnalysisCurveAndAddToPlot( RimEnsembleCurveSet* sourceCurveSet )
{
RimSummaryPlot* summaryPlot = caf::firstAncestorOfTypeFromSelectedObject<RimSummaryPlot>();

auto newCurve = new RimSummaryRegressionAnalysisCurve();

newCurve->setEnsembleCurveSet( sourceCurveSet );

auto color = RiaColorTools::fromQColorTo3f( sourceCurveSet->mainEnsembleColor() );
newCurve->setColor( color );
newCurve->setSymbol( RiuPlotCurveSymbol::PointSymbolEnum::SYMBOL_RECT );
newCurve->setSymbolSkipDistance( 50 );

summaryPlot->addCurveAndUpdate( newCurve );

newCurve->setAxisTypeX( sourceCurveSet->xAxisType() );
newCurve->setTopOrBottomAxisX( sourceCurveSet->axisX() );
newCurve->setLeftOrRightAxisY( sourceCurveSet->axisY() );

newCurve->loadDataAndUpdate( true );
newCurve->updateConnectedEditors();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

class RimSummaryPlot;
class RimSummaryCurve;
class RimEnsembleCurveSet;

//==================================================================================================
///
Expand All @@ -38,4 +39,5 @@ class RicCreateRegressionAnalysisCurveFeature : public caf::CmdFeature
void setupActionLook( QAction* actionToSetup ) override;

static RimSummaryRegressionAnalysisCurve* createRegressionAnalysisCurveAndAddToPlot( RimSummaryCurve* sourceCurve );
static RimSummaryRegressionAnalysisCurve* createRegressionAnalysisCurveAndAddToPlot( RimEnsembleCurveSet* sourceCurveSet );
};
2 changes: 2 additions & 0 deletions ApplicationLibCode/FileInterface/CMakeLists_files.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,7 @@ set(SOURCE_GROUP_HEADER_FILES
${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.h
${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.h
${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.h
${CMAKE_CURRENT_LIST_DIR}/RifEclipseSummaryAddressDefines.h
)

set(SOURCE_GROUP_SOURCE_FILES
Expand Down Expand Up @@ -177,6 +178,7 @@ set(SOURCE_GROUP_SOURCE_FILES
${CMAKE_CURRENT_LIST_DIR}/RifInpExportTools.cpp
${CMAKE_CURRENT_LIST_DIR}/RifFaultReactivationModelExporter.cpp
${CMAKE_CURRENT_LIST_DIR}/RifThermalToStimPlanFractureXmlOutput.cpp
${CMAKE_CURRENT_LIST_DIR}/RifEclipseSummaryAddressDefines.cpp
)

list(APPEND CODE_HEADER_FILES ${SOURCE_GROUP_HEADER_FILES})
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2023- 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 "RifEclipseSummaryAddressDefines.h"

#include "cafAppEnum.h"

namespace caf
{
template <>
void caf::AppEnum<RifEclipseSummaryAddressDefines::StatisticsType>::setUp()
{
addItem( RifEclipseSummaryAddressDefines::StatisticsType::NONE, "NONE", "None" );
addItem( RifEclipseSummaryAddressDefines::StatisticsType::P10, "P10", "P10" );
addItem( RifEclipseSummaryAddressDefines::StatisticsType::P50, "P50", "P50" );
addItem( RifEclipseSummaryAddressDefines::StatisticsType::P90, "P90", "P90" );
addItem( RifEclipseSummaryAddressDefines::StatisticsType::MEAN, "MEAN", "Mean" );
setDefault( RifEclipseSummaryAddressDefines::StatisticsType::NONE );
}
} // namespace caf

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifEclipseSummaryAddressDefines::statisticsNameP10()
{
return statisticsTypeToString( StatisticsType::P10 );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifEclipseSummaryAddressDefines::statisticsNameP50()
{
return statisticsTypeToString( StatisticsType::P50 );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifEclipseSummaryAddressDefines::statisticsNameP90()
{
return statisticsTypeToString( StatisticsType::P90 );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifEclipseSummaryAddressDefines::statisticsNameMean()
{
return statisticsTypeToString( StatisticsType::MEAN );
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::string RifEclipseSummaryAddressDefines::statisticsTypeToString( StatisticsType type )
{
caf::AppEnum<StatisticsType> enumType( type );
return enumType.uiText().toStdString();
}
24 changes: 19 additions & 5 deletions ApplicationLibCode/FileInterface/RifEclipseSummaryAddressDefines.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) Statoil ASA
// Copyright (C) 2023- 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
Expand All @@ -15,12 +15,10 @@
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////

#pragma once

#define ENSEMBLE_STAT_P10_QUANTITY_NAME "P10"
#define ENSEMBLE_STAT_P50_QUANTITY_NAME "P50"
#define ENSEMBLE_STAT_P90_QUANTITY_NAME "P90"
#define ENSEMBLE_STAT_MEAN_QUANTITY_NAME "MEAN"
#include <string>

//==================================================================================================
//
Expand Down Expand Up @@ -65,4 +63,20 @@ enum class SummaryIdentifierType
INPUT_VECTOR_NAME,
INPUT_ID
};

enum class StatisticsType
{
NONE,
P10,
P50,
P90,
MEAN
};

std::string statisticsNameP10();
std::string statisticsNameP50();
std::string statisticsNameP90();
std::string statisticsNameMean();
std::string statisticsTypeToString( StatisticsType type );

}; // namespace RifEclipseSummaryAddressDefines
Original file line number Diff line number Diff line change
Expand Up @@ -773,6 +773,7 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
menuBuilder << "RicClearSourceSteppingEnsembleCurveSetFeature";
menuBuilder << "Separator";
menuBuilder << "RicNewEnsembleCurveFilterFeature";
menuBuilder << "RicCreateRegressionAnalysisCurveFeature";
}
else if ( dynamic_cast<RimCustomObjectiveFunctionCollection*>( firstUiItem ) )
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@
#include "RiaSummaryTools.h"
#include "RiaTimeHistoryCurveResampler.h"

#include "RifEclipseSummaryAddressDefines.h"

#include "RigStatisticsMath.h"

#include "RimEnsembleCurveSet.h"
Expand Down Expand Up @@ -49,13 +51,13 @@ bool RimEnsembleCrossPlotStatisticsCase::values( const RifEclipseSummaryAddress&

auto quantityName = resultAddress.ensembleStatisticsVectorName();

if ( quantityName == ENSEMBLE_STAT_P10_QUANTITY_NAME )
if ( quantityName == RifEclipseSummaryAddressDefines::statisticsNameP10() )
*values = m_p10Data;
else if ( quantityName == ENSEMBLE_STAT_P50_QUANTITY_NAME )
else if ( quantityName == RifEclipseSummaryAddressDefines::statisticsNameP50() )
*values = m_p50Data;
else if ( quantityName == ENSEMBLE_STAT_P90_QUANTITY_NAME )
else if ( quantityName == RifEclipseSummaryAddressDefines::statisticsNameP90() )
*values = m_p90Data;
else if ( quantityName == ENSEMBLE_STAT_MEAN_QUANTITY_NAME )
else if ( quantityName == RifEclipseSummaryAddressDefines::statisticsNameMean() )
*values = m_meanData;

return true;
Expand Down
36 changes: 24 additions & 12 deletions ApplicationLibCode/ProjectDataModel/Summary/RimEnsembleCurveSet.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -473,6 +473,14 @@ bool RimEnsembleCurveSet::isXAxisSummaryVector() const
return m_xAxisType() == RiaDefines::HorizontalAxisType::SUMMARY_VECTOR;
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiaDefines::HorizontalAxisType RimEnsembleCurveSet::xAxisType() const
{
return m_xAxisType();
}

//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Expand Down Expand Up @@ -2093,13 +2101,13 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
};

if ( m_statistics->showP10Curve() && m_ensembleStatCaseXY->hasP10Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P10_QUANTITY_NAME, dataAddressX, dataAddressY ) );
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::statisticsNameP10(), dataAddressX, dataAddressY ) );
if ( m_statistics->showP50Curve() && m_ensembleStatCaseXY->hasP50Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P50_QUANTITY_NAME, dataAddressX, dataAddressY ) );
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::statisticsNameP50(), dataAddressX, dataAddressY ) );
if ( m_statistics->showP90Curve() && m_ensembleStatCaseXY->hasP90Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P90_QUANTITY_NAME, dataAddressX, dataAddressY ) );
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::statisticsNameP90(), dataAddressX, dataAddressY ) );
if ( m_statistics->showMeanCurve() && m_ensembleStatCaseXY->hasMeanData() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_MEAN_QUANTITY_NAME, dataAddressX, dataAddressY ) );
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::statisticsNameMean(), dataAddressX, dataAddressY ) );
}
else
{
Expand All @@ -2114,13 +2122,13 @@ void RimEnsembleCurveSet::updateStatisticsCurves( const std::vector<RimSummaryCa
};

if ( m_statistics->showP10Curve() && m_ensembleStatCaseY->hasP10Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P10_QUANTITY_NAME, dataAddressY ) );
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::statisticsNameP10(), dataAddressY ) );
if ( m_statistics->showP50Curve() && m_ensembleStatCaseY->hasP50Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P50_QUANTITY_NAME, dataAddressY ) );
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::statisticsNameP50(), dataAddressY ) );
if ( m_statistics->showP90Curve() && m_ensembleStatCaseY->hasP90Data() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_P90_QUANTITY_NAME, dataAddressY ) );
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::statisticsNameP90(), dataAddressY ) );
if ( m_statistics->showMeanCurve() && m_ensembleStatCaseY->hasMeanData() )
addresses.push_back( getStatisticsAddress( ENSEMBLE_STAT_MEAN_QUANTITY_NAME, dataAddressY ) );
addresses.push_back( getStatisticsAddress( RifEclipseSummaryAddressDefines::statisticsNameMean(), dataAddressY ) );
}
}

Expand Down Expand Up @@ -2453,11 +2461,15 @@ void RimEnsembleCurveSet::updateLegendMappingMode()
//--------------------------------------------------------------------------------------------------
RiuPlotCurveSymbol::PointSymbolEnum statisticsCurveSymbolFromAddress( const RifEclipseSummaryAddress& address )
{
auto qName = QString::fromStdString( address.vectorName() );
auto qName = address.vectorName();

if ( qName.find( RifEclipseSummaryAddressDefines::statisticsNameP10() ) != std::string::npos )
return RiuPlotCurveSymbol::SYMBOL_DOWN_TRIANGLE;
if ( qName.find( RifEclipseSummaryAddressDefines::statisticsNameP50() ) != std::string::npos )
return RiuPlotCurveSymbol::SYMBOL_DIAMOND;
if ( qName.find( RifEclipseSummaryAddressDefines::statisticsNameP90() ) != std::string::npos )
return RiuPlotCurveSymbol::SYMBOL_TRIANGLE;

if ( qName.contains( ENSEMBLE_STAT_P10_QUANTITY_NAME ) ) return RiuPlotCurveSymbol::SYMBOL_DOWN_TRIANGLE;
if ( qName.contains( ENSEMBLE_STAT_P90_QUANTITY_NAME ) ) return RiuPlotCurveSymbol::SYMBOL_TRIANGLE;
if ( qName.contains( ENSEMBLE_STAT_P50_QUANTITY_NAME ) ) return RiuPlotCurveSymbol::SYMBOL_DIAMOND;
return RiuPlotCurveSymbol::SYMBOL_ELLIPSE;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,10 +189,12 @@ class RimEnsembleCurveSet : public caf::PdmObject, public RimEnsembleCurveSetInt

std::vector<cvf::Color3f> generateColorsForCases( const std::vector<RimSummaryCase*>& summaryCases ) const;

RiuPlotAxis axisY() const;
RiuPlotAxis axisX() const;
void setLeftOrRightAxisY( RiuPlotAxis plotAxis );
void setBottomOrTopAxisX( RiuPlotAxis plotAxis );
RiuPlotAxis axisY() const;
RiuPlotAxis axisX() const;
void setLeftOrRightAxisY( RiuPlotAxis plotAxis );
void setBottomOrTopAxisX( RiuPlotAxis plotAxis );
bool isXAxisSummaryVector() const;
RiaDefines::HorizontalAxisType xAxisType() const;

protected:
void initAfterRead() override;
Expand Down Expand Up @@ -237,7 +239,6 @@ class RimEnsembleCurveSet : public caf::PdmObject, public RimEnsembleCurveSetInt
void onColorTagClicked( const SignalEmitter* emitter, size_t index );

void setSummaryAddressX( RifEclipseSummaryAddress address );
bool isXAxisSummaryVector() const;

private:
caf::PdmField<bool> m_showCurves;
Expand Down
Loading

0 comments on commit 263e39b

Please sign in to comment.