mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#7761 Objective Function : Change formula and add several options
This commit is contained in:
parent
c89e00b966
commit
4de91e885b
@ -20,8 +20,7 @@
|
||||
|
||||
#include "RimCustomObjectiveFunction.h"
|
||||
#include "RimCustomObjectiveFunctionCollection.h"
|
||||
#include "RimCustomObjectiveFunctionWeight.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimObjectiveFunctionTools.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
@ -53,8 +52,7 @@ void RicNewCustomObjectiveFunctionFeature::onActionTriggered( bool isChecked )
|
||||
if ( coll.size() == 1 )
|
||||
{
|
||||
RimCustomObjectiveFunction* newFunc = coll[0]->addObjectiveFunction();
|
||||
RimCustomObjectiveFunctionWeight* newWeight = newFunc->addWeight();
|
||||
newWeight->setSummaryAddress( newWeight->parentCurveSet()->summaryAddress() );
|
||||
RimCustomObjectiveFunctionWeight* newWeight = RimObjectiveFunctionTools::addWeight( newFunc );
|
||||
coll[0]->updateConnectedEditors();
|
||||
RiuPlotMainWindowTools::selectAsCurrentItem( newFunc );
|
||||
RiuPlotMainWindowTools::setExpanded( coll.front() );
|
||||
|
@ -20,7 +20,7 @@
|
||||
|
||||
#include "RimCustomObjectiveFunction.h"
|
||||
#include "RimCustomObjectiveFunctionWeight.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimObjectiveFunctionTools.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
@ -51,16 +51,11 @@ void RicNewCustomObjectiveFunctionWeightFeature::onActionTriggered( bool isCheck
|
||||
|
||||
if ( func.size() == 1 )
|
||||
{
|
||||
RimCustomObjectiveFunctionWeight* newWeight = func[0]->addWeight();
|
||||
if ( func[0]->weights().size() > 1 )
|
||||
{
|
||||
newWeight->setSummaryAddress( func[0]->weights()[0]->summaryAddresses().front() );
|
||||
}
|
||||
else
|
||||
{
|
||||
newWeight->setSummaryAddress( newWeight->parentCurveSet()->summaryAddress() );
|
||||
}
|
||||
func[0]->updateConnectedEditors();
|
||||
auto firstObjectiveFunction = func.front();
|
||||
|
||||
auto newWeight = RimObjectiveFunctionTools::addWeight( firstObjectiveFunction );
|
||||
|
||||
firstObjectiveFunction->updateConnectedEditors();
|
||||
RiuPlotMainWindowTools::selectAsCurrentItem( newWeight );
|
||||
RiuPlotMainWindowTools::setExpanded( func.front() );
|
||||
}
|
||||
|
@ -28,8 +28,7 @@ class RicNewCustomObjectiveFunctionWeightFeature : public caf::CmdFeature
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
protected:
|
||||
// Overrides
|
||||
bool isCommandEnabled() override;
|
||||
void onActionTriggered(bool isChecked) override;
|
||||
void setupActionLook(QAction* actionToSetup) override;
|
||||
void onActionTriggered( bool isChecked ) override;
|
||||
void setupActionLook( QAction* actionToSetup ) override;
|
||||
};
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "RimEnsembleCurveFilter.h"
|
||||
#include "RimEnsembleCurveFilterCollection.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimObjectiveFunctionTools.h"
|
||||
|
||||
#include "RiuPlotMainWindowTools.h"
|
||||
|
||||
@ -67,7 +68,11 @@ void RicNewEnsembleCurveFilterFeature::onActionTriggered( bool isChecked )
|
||||
else
|
||||
{
|
||||
std::vector<RifEclipseSummaryAddress> addresses;
|
||||
addresses.push_back( newFilter->parentCurveSet()->summaryAddress() );
|
||||
|
||||
auto candidateAdr = newFilter->parentCurveSet()->summaryAddress();
|
||||
auto nativeQuantityName = RimObjectiveFunctionTools::nativeQuantityName( candidateAdr.quantityName() );
|
||||
candidateAdr.setQuantityName( nativeQuantityName );
|
||||
addresses.push_back( candidateAdr );
|
||||
newFilter->setSummaryAddresses( addresses );
|
||||
}
|
||||
newFilter->loadDataAndUpdate();
|
||||
|
@ -45,6 +45,21 @@ RimCustomObjectiveFunction::RimCustomObjectiveFunction()
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_weights, "Weights", "", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_objectiveFunctions, "ObjectiveFunctions", "Objective Functions", "", "", "" );
|
||||
|
||||
{
|
||||
auto objFunc1 = new RimObjectiveFunction();
|
||||
objFunc1->setFunctionType( RimObjectiveFunction::FunctionType::F1 );
|
||||
m_objectiveFunctions.push_back( objFunc1 );
|
||||
objFunc1->changed.connect( this, &RimCustomObjectiveFunction::onObjectiveFunctionChanged );
|
||||
}
|
||||
{
|
||||
auto objFunc1 = new RimObjectiveFunction();
|
||||
objFunc1->setFunctionType( RimObjectiveFunction::FunctionType::F2 );
|
||||
m_objectiveFunctions.push_back( objFunc1 );
|
||||
objFunc1->changed.connect( this, &RimCustomObjectiveFunction::onObjectiveFunctionChanged );
|
||||
}
|
||||
|
||||
m_isValid = true;
|
||||
|
||||
setDeletable( true );
|
||||
@ -71,32 +86,21 @@ std::vector<RimCustomObjectiveFunctionWeight*> RimCustomObjectiveFunction::weigh
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimCustomObjectiveFunction::values() const
|
||||
std::vector<double> RimCustomObjectiveFunction::functionValueForAllCases() const
|
||||
{
|
||||
std::vector<double> values;
|
||||
if ( m_weights.empty() ) return {};
|
||||
|
||||
RimSummaryCaseCollection* caseCollection = parentCurveSet()->summaryCaseCollection();
|
||||
for ( auto weight : m_weights )
|
||||
if ( !caseCollection || caseCollection->allSummaryCases().empty() ) return {};
|
||||
|
||||
std::vector<double> values;
|
||||
|
||||
for ( auto sumCase : caseCollection->allSummaryCases() )
|
||||
{
|
||||
std::vector<double> functionValues =
|
||||
caseCollection->objectiveFunction( weight->objectiveFunction() )->values( weight->summaryAddresses() );
|
||||
if ( values.size() == 0 )
|
||||
{
|
||||
for ( size_t i = 0; i < functionValues.size(); i++ )
|
||||
{
|
||||
values.push_back( weight->weightValue() * functionValues[i] );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( size_t i = 0; i < functionValues.size(); i++ )
|
||||
{
|
||||
if ( values.size() > i + 1 )
|
||||
{
|
||||
values[i] += weight->weightValue() * functionValues[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
auto functionValue = value( sumCase );
|
||||
values.push_back( functionValue );
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
@ -105,15 +109,23 @@ std::vector<double> RimCustomObjectiveFunction::values() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimCustomObjectiveFunction::value( RimSummaryCase* summaryCase ) const
|
||||
{
|
||||
double value = 0.0;
|
||||
RimSummaryCaseCollection* caseCollection = parentCurveSet()->summaryCaseCollection();
|
||||
if ( m_functionValueForAllCases.count( summaryCase ) > 0 )
|
||||
{
|
||||
return m_functionValueForAllCases[summaryCase];
|
||||
}
|
||||
|
||||
double value = 0.0;
|
||||
for ( auto weight : m_weights )
|
||||
{
|
||||
double functionValue =
|
||||
caseCollection->objectiveFunction( weight->objectiveFunction() )->value( summaryCase, weight->summaryAddresses() );
|
||||
objectiveFunction( weight->objectiveFunction() )
|
||||
->value( summaryCase, weight->summaryAddresses(), parentCurveSet()->objectiveFunctionTimeConfig() );
|
||||
|
||||
value += weight->weightValue() * functionValue;
|
||||
}
|
||||
|
||||
m_functionValueForAllCases[summaryCase] = value;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
@ -125,7 +137,7 @@ std::pair<double, double> RimCustomObjectiveFunction::minMaxValues() const
|
||||
double minValue = std::numeric_limits<double>::infinity();
|
||||
double maxValue = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for ( auto value : values() )
|
||||
for ( auto value : functionValueForAllCases() )
|
||||
{
|
||||
if ( value != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
@ -196,6 +208,7 @@ bool RimCustomObjectiveFunction::isValid() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCustomObjectiveFunction::onWeightChanged()
|
||||
{
|
||||
m_functionValueForAllCases.clear();
|
||||
parentCollection()->onObjectiveFunctionChanged( this );
|
||||
}
|
||||
|
||||
@ -220,17 +233,23 @@ QString RimCustomObjectiveFunction::formulaString( std::vector<RifEclipseSummary
|
||||
QStringList weightFormulae;
|
||||
for ( auto weight : weights() )
|
||||
{
|
||||
weightFormulae << QString( "%0 * %1" )
|
||||
.arg( weight->weightValue() )
|
||||
.arg( parentCurveSet()
|
||||
->summaryCaseCollection()
|
||||
->objectiveFunction( weight->objectiveFunction() )
|
||||
->formulaString( vectorSummaryAddresses ) );
|
||||
weightFormulae
|
||||
<< QString( "%0 * %1" )
|
||||
.arg( weight->weightValue() )
|
||||
.arg( objectiveFunction( weight->objectiveFunction() )->formulaString( vectorSummaryAddresses ) );
|
||||
}
|
||||
formula += weightFormulae.join( " + " );
|
||||
return formula;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCustomObjectiveFunction::clearCache()
|
||||
{
|
||||
m_functionValueForAllCases.clear();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -239,6 +258,14 @@ caf::PdmFieldHandle* RimCustomObjectiveFunction::userDescriptionField()
|
||||
return &m_functionTitle;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCustomObjectiveFunction::onObjectiveFunctionChanged( const caf::SignalEmitter* emitter )
|
||||
{
|
||||
onWeightChanged();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -269,6 +296,35 @@ void RimCustomObjectiveFunction::defineEditorAttribute( const caf::PdmFieldHandl
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimCustomObjectiveFunction::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_customFunctionTitle );
|
||||
|
||||
{
|
||||
auto objFunc1 = objectiveFunction( RimObjectiveFunction::FunctionType::F1 );
|
||||
if ( objFunc1 )
|
||||
{
|
||||
auto equationGroup = uiOrdering.addNewGroup( "Equation for Time Range" );
|
||||
|
||||
objFunc1->hideFunctionSelection();
|
||||
objFunc1->uiOrdering( "", *equationGroup );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto objFunc2 = objectiveFunction( RimObjectiveFunction::FunctionType::F2 );
|
||||
{
|
||||
auto equationGroup = uiOrdering.addNewGroup( "Equation for Selected Time Range" );
|
||||
|
||||
objFunc2->hideFunctionSelection();
|
||||
objFunc2->uiOrdering( "", *equationGroup );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -288,3 +344,18 @@ RimCustomObjectiveFunctionCollection* RimCustomObjectiveFunction::parentCollecti
|
||||
firstAncestorOrThisOfType( collection );
|
||||
return collection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimObjectiveFunction* RimCustomObjectiveFunction::objectiveFunction( RimObjectiveFunction::FunctionType functionType ) const
|
||||
{
|
||||
for ( auto objectiveFunc : m_objectiveFunctions.childObjects() )
|
||||
{
|
||||
if ( objectiveFunc->functionType() == functionType )
|
||||
{
|
||||
return objectiveFunc;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "RimObjectiveFunction.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
@ -44,7 +45,7 @@ public:
|
||||
|
||||
RimCustomObjectiveFunctionWeight* addWeight();
|
||||
std::vector<RimCustomObjectiveFunctionWeight*> weights() const;
|
||||
std::vector<double> values() const;
|
||||
std::vector<double> functionValueForAllCases() const;
|
||||
double value( RimSummaryCase* summaryCase ) const;
|
||||
std::pair<double, double> minMaxValues() const;
|
||||
bool weightContainsFunctionType( RimObjectiveFunction::FunctionType functionType ) const;
|
||||
@ -55,20 +56,31 @@ public:
|
||||
void invalidate();
|
||||
QString formulaString( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses ) const;
|
||||
|
||||
void clearCache();
|
||||
|
||||
private:
|
||||
void defineUiTreeOrdering( caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName /* = "" */ ) override;
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
|
||||
RimEnsembleCurveSet* parentCurveSet() const;
|
||||
RimCustomObjectiveFunctionCollection* parentCollection() const;
|
||||
|
||||
RimObjectiveFunction* objectiveFunction( RimObjectiveFunction::FunctionType functionType ) const;
|
||||
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
|
||||
void onObjectiveFunctionChanged( const caf::SignalEmitter* emitter );
|
||||
|
||||
private:
|
||||
caf::PdmProxyValueField<QString> m_functionTitle;
|
||||
caf::PdmField<QString> m_customFunctionTitle;
|
||||
caf::PdmChildArrayField<RimCustomObjectiveFunctionWeight*> m_weights;
|
||||
bool m_isValid;
|
||||
caf::PdmChildArrayField<RimObjectiveFunction*> m_objectiveFunctions;
|
||||
|
||||
mutable std::map<RimSummaryCase*, double> m_functionValueForAllCases;
|
||||
|
||||
bool m_isValid;
|
||||
};
|
||||
|
@ -23,6 +23,7 @@
|
||||
|
||||
#include "RimCustomObjectiveFunction.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimObjectiveFunctionTools.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
|
||||
#include "RiuSummaryVectorSelectionDialog.h"
|
||||
@ -83,7 +84,7 @@ QString RimCustomObjectiveFunctionWeight::title() const
|
||||
}
|
||||
return QString( "%0 * %1::%2%3%4" )
|
||||
.arg( m_weightValue, 0, 'f', 2 )
|
||||
.arg( caf::AppEnum<RimObjectiveFunction::FunctionType>( m_objectiveFunction() ).uiText() )
|
||||
.arg( caf::AppEnum<RimObjectiveFunction::FunctionType>( m_objectiveFunction() ).text() )
|
||||
.arg( addressVector.size() > 1 ? "(" : "" )
|
||||
.arg( QString::fromStdString( RifEclipseSummaryAddress::generateStringFromAddresses( addressVector, " + " ) ) )
|
||||
.arg( addressVector.size() > 1 ? ")" : "" );
|
||||
@ -156,7 +157,7 @@ void RimCustomObjectiveFunctionWeight::fieldChangedByUi( const caf::PdmFieldHand
|
||||
else if ( changedField == &m_objectiveValuesSelectSummaryAddressPushButton )
|
||||
{
|
||||
RiuSummaryVectorSelectionDialog dlg( nullptr );
|
||||
dlg.enableMultiSelect( true );
|
||||
RimObjectiveFunctionTools::configureDialogForObjectiveFunctions( &dlg );
|
||||
RimSummaryCaseCollection* candidateEnsemble = parentCurveSet()->summaryCaseCollection();
|
||||
|
||||
std::vector<RifEclipseSummaryAddress> candidateAddresses;
|
||||
@ -165,7 +166,6 @@ void RimCustomObjectiveFunctionWeight::fieldChangedByUi( const caf::PdmFieldHand
|
||||
candidateAddresses.push_back( address->address() );
|
||||
}
|
||||
|
||||
dlg.hideSummaryCases();
|
||||
dlg.setEnsembleAndAddresses( candidateEnsemble, candidateAddresses );
|
||||
|
||||
if ( dlg.exec() == QDialog::Accepted )
|
||||
|
@ -38,6 +38,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimDerivedSummaryCase.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCaseCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSummaryPlotFilterTextCurveSetEditor.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimObjectiveFunction.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimObjectiveFunctionTools.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@ -79,6 +80,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RimDerivedSummaryCase.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCaseCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimSummaryPlotFilterTextCurveSetEditor.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimObjectiveFunction.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimObjectiveFunctionTools.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
@ -25,6 +25,7 @@
|
||||
#include "RimCustomObjectiveFunctionCollection.h"
|
||||
#include "RimEnsembleCurveFilterCollection.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimObjectiveFunctionTools.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
@ -98,7 +99,11 @@ RimEnsembleCurveFilter::RimEnsembleCurveFilter()
|
||||
m_objectiveValuesSelectSummaryAddressPushButton = false;
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_objectiveFunction, "ObjectiveFunction", "Objective Function", "", "", "" );
|
||||
m_objectiveFunction.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||
m_objectiveFunction = new RimObjectiveFunction();
|
||||
m_objectiveFunction.uiCapability()->setUiHidden( true );
|
||||
m_objectiveFunction.uiCapability()->setUiTreeHidden( true );
|
||||
m_objectiveFunction.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_objectiveFunction->changed.connect( this, &RimEnsembleCurveFilter::onObjectionFunctionChanged );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_customObjectiveFunction, "CustomObjectiveFunction", "Custom Objective Function", "", "", "" );
|
||||
m_customObjectiveFunction.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||
@ -202,7 +207,7 @@ QString RimEnsembleCurveFilter::description() const
|
||||
}
|
||||
descriptor =
|
||||
QString( "%1::%2%3%4" )
|
||||
.arg( caf::AppEnum<RimObjectiveFunction::FunctionType>( m_objectiveFunction() ).uiText() )
|
||||
.arg( m_objectiveFunction()->shortName() )
|
||||
.arg( addressVector.size() > 1 ? "(" : "" )
|
||||
.arg( QString::fromStdString( RifEclipseSummaryAddress::generateStringFromAddresses( addressVector, "+" ) ) )
|
||||
.arg( addressVector.size() > 1 ? ")" : "" );
|
||||
@ -359,7 +364,12 @@ void RimEnsembleCurveFilter::fieldChangedByUi( const caf::PdmFieldHandle* change
|
||||
if ( m_objectiveValuesSummaryAddresses.size() == 0 )
|
||||
{
|
||||
RimSummaryAddress* summaryAddress = new RimSummaryAddress();
|
||||
summaryAddress->setAddress( parentCurveSet()->summaryAddress() );
|
||||
|
||||
RifEclipseSummaryAddress candidateAdr = parentCurveSet()->summaryAddress();
|
||||
|
||||
auto nativeQuantityName = RimObjectiveFunctionTools::nativeQuantityName( candidateAdr.quantityName() );
|
||||
candidateAdr.setQuantityName( nativeQuantityName );
|
||||
summaryAddress->setAddress( candidateAdr );
|
||||
m_objectiveValuesSummaryAddresses.push_back( summaryAddress );
|
||||
updateAddressesUiField();
|
||||
}
|
||||
@ -377,7 +387,7 @@ void RimEnsembleCurveFilter::fieldChangedByUi( const caf::PdmFieldHandle* change
|
||||
else if ( changedField == &m_objectiveValuesSelectSummaryAddressPushButton )
|
||||
{
|
||||
RiuSummaryVectorSelectionDialog dlg( nullptr );
|
||||
dlg.enableMultiSelect( true );
|
||||
RimObjectiveFunctionTools::configureDialogForObjectiveFunctions( &dlg );
|
||||
RimSummaryCaseCollection* candidateEnsemble = parentCurveSet()->summaryCaseCollection();
|
||||
|
||||
std::vector<RifEclipseSummaryAddress> candidateAddresses;
|
||||
@ -386,7 +396,6 @@ void RimEnsembleCurveFilter::fieldChangedByUi( const caf::PdmFieldHandle* change
|
||||
candidateAddresses.push_back( address->address() );
|
||||
}
|
||||
|
||||
dlg.hideSummaryCases();
|
||||
dlg.setEnsembleAndAddresses( candidateEnsemble, candidateAddresses );
|
||||
|
||||
if ( dlg.exec() == QDialog::Accepted )
|
||||
@ -394,10 +403,11 @@ void RimEnsembleCurveFilter::fieldChangedByUi( const caf::PdmFieldHandle* change
|
||||
auto curveSelection = dlg.curveSelection();
|
||||
if ( !curveSelection.empty() )
|
||||
{
|
||||
m_objectiveValuesSummaryAddresses.clear();
|
||||
for ( auto address : curveSelection )
|
||||
{
|
||||
RimSummaryAddress* summaryAddress = new RimSummaryAddress();
|
||||
summaryAddress->setAddress( parentCurveSet()->summaryAddress() );
|
||||
summaryAddress->setAddress( address.summaryAddress() );
|
||||
m_objectiveValuesSummaryAddresses.push_back( summaryAddress );
|
||||
}
|
||||
this->loadDataAndUpdate();
|
||||
@ -455,6 +465,11 @@ void RimEnsembleCurveFilter::defineUiOrdering( QString uiConfigName, caf::PdmUiO
|
||||
{
|
||||
uiOrdering.add( &m_objectiveValuesSummaryAddressesUiField );
|
||||
uiOrdering.add( &m_objectiveValuesSelectSummaryAddressPushButton, { false, 1, 0 } );
|
||||
{
|
||||
auto equationGroup = uiOrdering.addNewGroup( "Equation" );
|
||||
m_objectiveFunction->uiOrdering( "", *equationGroup );
|
||||
}
|
||||
|
||||
uiOrdering.add( &m_objectiveFunction );
|
||||
}
|
||||
else if ( m_filterMode() == FilterMode::BY_CUSTOM_OBJECTIVE_FUNCTION )
|
||||
@ -543,8 +558,7 @@ std::vector<RimSummaryCase*> RimEnsembleCurveFilter::applyFilter( const std::vec
|
||||
}
|
||||
else if ( m_filterMode() == FilterMode::BY_OBJECTIVE_FUNCTION )
|
||||
{
|
||||
auto objectiveFunction = ensemble->objectiveFunction( m_objectiveFunction() );
|
||||
bool hasWarning = false;
|
||||
bool hasWarning = false;
|
||||
|
||||
std::vector<RifEclipseSummaryAddress> addresses;
|
||||
for ( auto address : m_objectiveValuesSummaryAddresses() )
|
||||
@ -552,7 +566,8 @@ std::vector<RimSummaryCase*> RimEnsembleCurveFilter::applyFilter( const std::vec
|
||||
addresses.push_back( address->address() );
|
||||
}
|
||||
|
||||
double value = objectiveFunction->value( sumCase, addresses, &hasWarning );
|
||||
double value =
|
||||
m_objectiveFunction->value( sumCase, addresses, curveSet->objectiveFunctionTimeConfig(), &hasWarning );
|
||||
if ( hasWarning ) continue;
|
||||
|
||||
if ( value < m_minValue() || value > m_maxValue )
|
||||
@ -610,6 +625,25 @@ RimEnsembleCurveSet* RimEnsembleCurveFilter::parentCurveSet() const
|
||||
return curveSet;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveFilter::onObjectionFunctionChanged( const caf::SignalEmitter* emitter )
|
||||
{
|
||||
updateMaxMinAndDefaultValues( true );
|
||||
|
||||
parentCurveSet()->updateAllCurves();
|
||||
parentCurveSet()->updateFilterLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveFilter::updateMaxMinAndDefaultValuesFromParent()
|
||||
{
|
||||
updateMaxMinAndDefaultValues( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -653,18 +687,20 @@ void RimEnsembleCurveFilter::updateMaxMinAndDefaultValues( bool forceDefault )
|
||||
}
|
||||
else if ( m_filterMode() == FilterMode::BY_OBJECTIVE_FUNCTION )
|
||||
{
|
||||
auto objectiveFunction = parentCurveSet()->summaryCaseCollection()->objectiveFunction( m_objectiveFunction() );
|
||||
auto objectiveFunction = m_objectiveFunction();
|
||||
std::vector<RifEclipseSummaryAddress> addresses;
|
||||
for ( auto address : m_objectiveValuesSummaryAddresses() )
|
||||
{
|
||||
addresses.push_back( address->address() );
|
||||
}
|
||||
if ( objectiveFunction->isValid( addresses ) )
|
||||
{
|
||||
std::pair<double, double> minMaxValues = objectiveFunction->minMaxValues( addresses );
|
||||
auto summaryCases = parentCurveSet()->summaryCaseCollection()->allSummaryCases();
|
||||
|
||||
m_lowerLimit = minMaxValues.first;
|
||||
m_upperLimit = minMaxValues.second;
|
||||
auto [minObjValue, maxObjValue] =
|
||||
objectiveFunction->minMaxValues( summaryCases, addresses, parentCurveSet()->objectiveFunctionTimeConfig() );
|
||||
|
||||
m_lowerLimit = minObjValue;
|
||||
m_upperLimit = maxObjValue;
|
||||
|
||||
if ( forceDefault || !( m_minValue >= m_lowerLimit && m_minValue <= m_upperLimit ) )
|
||||
m_minValue = m_lowerLimit;
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include "RimObjectiveFunction.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
@ -84,6 +85,9 @@ public:
|
||||
|
||||
RimEnsembleCurveSet* parentCurveSet() const;
|
||||
|
||||
void onObjectionFunctionChanged( const caf::SignalEmitter* emitter );
|
||||
void updateMaxMinAndDefaultValuesFromParent();
|
||||
|
||||
protected:
|
||||
caf::PdmFieldHandle* objectToggleField() override;
|
||||
|
||||
@ -92,18 +96,20 @@ private:
|
||||
void updateMaxMinAndDefaultValues( bool forceDefault );
|
||||
|
||||
private:
|
||||
caf::PdmProxyValueField<QString> m_filterTitle;
|
||||
caf::PdmField<bool> m_active;
|
||||
caf::PdmField<caf::AppEnum<FilterMode>> m_filterMode;
|
||||
caf::PdmField<QString> m_ensembleParameterName;
|
||||
caf::PdmChildArrayField<RimSummaryAddress*> m_objectiveValuesSummaryAddresses;
|
||||
caf::PdmField<QString> m_objectiveValuesSummaryAddressesUiField;
|
||||
caf::PdmField<bool> m_objectiveValuesSelectSummaryAddressPushButton;
|
||||
caf::PdmField<caf::AppEnum<RimObjectiveFunction::FunctionType>> m_objectiveFunction;
|
||||
caf::PdmPtrField<RimCustomObjectiveFunction*> m_customObjectiveFunction;
|
||||
caf::PdmField<double> m_minValue;
|
||||
caf::PdmField<double> m_maxValue;
|
||||
caf::PdmField<std::vector<QString>> m_categories;
|
||||
caf::PdmProxyValueField<QString> m_filterTitle;
|
||||
caf::PdmField<bool> m_active;
|
||||
caf::PdmField<caf::AppEnum<FilterMode>> m_filterMode;
|
||||
caf::PdmField<QString> m_ensembleParameterName;
|
||||
|
||||
caf::PdmChildArrayField<RimSummaryAddress*> m_objectiveValuesSummaryAddresses;
|
||||
caf::PdmField<QString> m_objectiveValuesSummaryAddressesUiField;
|
||||
caf::PdmField<bool> m_objectiveValuesSelectSummaryAddressPushButton;
|
||||
caf::PdmChildField<RimObjectiveFunction*> m_objectiveFunction;
|
||||
caf::PdmPtrField<RimCustomObjectiveFunction*> m_customObjectiveFunction;
|
||||
|
||||
caf::PdmField<double> m_minValue;
|
||||
caf::PdmField<double> m_maxValue;
|
||||
caf::PdmField<std::vector<QString>> m_categories;
|
||||
|
||||
double m_lowerLimit;
|
||||
double m_upperLimit;
|
||||
|
@ -43,6 +43,7 @@
|
||||
#include "RimEnsembleStatistics.h"
|
||||
#include "RimEnsembleStatisticsCase.h"
|
||||
#include "RimObjectiveFunction.h"
|
||||
#include "RimObjectiveFunctionTools.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimRegularLegendConfig.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
@ -155,13 +156,10 @@ RimEnsembleCurveSet::RimEnsembleCurveSet()
|
||||
m_objectiveValuesSelectSummaryAddressPushButton.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
m_objectiveValuesSelectSummaryAddressPushButton = false;
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_objectiveFunction, "ObjectiveFunction", "Objective Function", "", "", "" );
|
||||
m_objectiveFunction.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_customObjectiveFunction, "CustomObjectiveFunction", "Objective Function", "", "", "" );
|
||||
m_customObjectiveFunction.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitField( &m_showObjectiveFunctionFormula, "ShowObjectiveFunctionFormula", true, "Show Formula in Plot", "", "", "" );
|
||||
CAF_PDM_InitField( &m_showObjectiveFunctionFormula, "ShowObjectiveFunctionFormula", true, "Show Text Box in Plot", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_minDateRange, "MinDateRange", "From", "", "", "" );
|
||||
m_minDateRange.uiCapability()->setUiEditorTypeName( caf::PdmUiDateEditor::uiEditorTypeName() );
|
||||
@ -200,7 +198,13 @@ RimEnsembleCurveSet::RimEnsembleCurveSet()
|
||||
"",
|
||||
"" );
|
||||
m_customObjectiveFunctions = new RimCustomObjectiveFunctionCollection();
|
||||
m_customObjectiveFunctions->objectiveFunctionChanged.connect( this, &RimEnsembleCurveSet::onObjectiveFunctionChanged );
|
||||
m_customObjectiveFunctions->objectiveFunctionChanged.connect( this,
|
||||
&RimEnsembleCurveSet::onCustomObjectiveFunctionChanged );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_objectiveFunction, "ObjectiveFunction", "Objective Function", "", "", "" );
|
||||
m_objectiveFunction = new RimObjectiveFunction();
|
||||
m_objectiveFunction.uiCapability()->setUiHidden( true );
|
||||
m_objectiveFunction->changed.connect( this, &RimEnsembleCurveSet::onObjectiveFunctionChanged );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_statistics, "Statistics", "Statistics", "", "", "" );
|
||||
m_statistics = new RimEnsembleStatistics();
|
||||
@ -309,6 +313,7 @@ void RimEnsembleCurveSet::loadDataAndUpdate( bool updateParentPlot )
|
||||
updateAllCurves();
|
||||
updateFilterLegend();
|
||||
updateObjectiveFunctionLegend();
|
||||
updateTimeAnnotations();
|
||||
|
||||
if ( updateParentPlot )
|
||||
{
|
||||
@ -602,7 +607,7 @@ void RimEnsembleCurveSet::setTimeSteps( const std::vector<size_t>& timeStepIndic
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<time_t> RimEnsembleCurveSet::selectedTimeSteps()
|
||||
std::vector<time_t> RimEnsembleCurveSet::selectedTimeSteps() const
|
||||
{
|
||||
std::vector<time_t> selectedTimeTTimeSteps;
|
||||
for ( const QDateTime& dateTime : m_selectedTimeSteps.v() )
|
||||
@ -648,8 +653,6 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
|
||||
}
|
||||
else if ( changedField == &m_yValuesSummaryCaseCollection )
|
||||
{
|
||||
// Empty address cache
|
||||
// m_allAddressesCache.clear();
|
||||
updateAllCurves();
|
||||
|
||||
updateTextInPlot = true;
|
||||
@ -669,19 +672,12 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
|
||||
updateLegendMappingMode();
|
||||
updateCurveColors();
|
||||
}
|
||||
else if ( changedField == &m_objectiveFunction )
|
||||
{
|
||||
updateLegendMappingMode();
|
||||
updateCurveColors();
|
||||
updateTimeAnnotations();
|
||||
updateObjectiveFunctionLegend();
|
||||
}
|
||||
else if ( changedField == &m_objectiveValuesSummaryAddressesUiField )
|
||||
{
|
||||
updateAddressesUiField();
|
||||
|
||||
std::vector<size_t> indices;
|
||||
indices.push_back( summaryCaseCollection()->objectiveFunction( m_objectiveFunction() )->range().first );
|
||||
indices.push_back( 0 );
|
||||
setTimeSteps( indices );
|
||||
|
||||
updateMaxMinAndDefaultValues();
|
||||
@ -697,7 +693,6 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
|
||||
else if ( changedField == &m_colorMode )
|
||||
{
|
||||
m_ensembleParameter.uiCapability()->setUiHidden( m_colorMode() != ColorMode::BY_ENSEMBLE_PARAM );
|
||||
m_objectiveFunction.uiCapability()->setUiHidden( m_colorMode() != ColorMode::BY_OBJECTIVE_FUNCTION );
|
||||
|
||||
if ( m_colorMode() == ColorMode::BY_ENSEMBLE_PARAM )
|
||||
{
|
||||
@ -736,10 +731,10 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
|
||||
}
|
||||
else if ( changedField == &m_selectedTimeSteps )
|
||||
{
|
||||
summaryCaseCollection()->objectiveFunction( m_objectiveFunction() )->setTimeStepList( selectedTimeSteps() );
|
||||
updateCurveColors();
|
||||
updateTimeAnnotations();
|
||||
updateObjectiveFunctionLegend();
|
||||
updateMaxMinAndDefaultValues();
|
||||
}
|
||||
else if ( changedField == &m_minTimeStep || changedField == &m_maxTimeStep )
|
||||
{
|
||||
@ -812,7 +807,7 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
|
||||
else if ( changedField == &m_objectiveValuesSelectSummaryAddressPushButton )
|
||||
{
|
||||
RiuSummaryVectorSelectionDialog dlg( nullptr );
|
||||
dlg.enableMultiSelect( true );
|
||||
RimObjectiveFunctionTools::configureDialogForObjectiveFunctions( &dlg );
|
||||
RimSummaryCaseCollection* candidateEnsemble = m_yValuesSummaryCaseCollection();
|
||||
|
||||
std::vector<RifEclipseSummaryAddress> candidateAddresses;
|
||||
@ -821,7 +816,6 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
|
||||
candidateAddresses.push_back( address->address() );
|
||||
}
|
||||
|
||||
dlg.hideSummaryCases();
|
||||
dlg.setEnsembleAndAddresses( candidateEnsemble, candidateAddresses );
|
||||
|
||||
if ( dlg.exec() == QDialog::Accepted )
|
||||
@ -846,11 +840,10 @@ void RimEnsembleCurveSet::fieldChangedByUi( const caf::PdmFieldHandle* changedFi
|
||||
{
|
||||
if ( m_customObjectiveFunction() )
|
||||
{
|
||||
if ( m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::M2 ) )
|
||||
if ( m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::F2 ) )
|
||||
{
|
||||
std::vector<size_t> indices;
|
||||
indices.push_back(
|
||||
summaryCaseCollection()->objectiveFunction( RimObjectiveFunction::FunctionType::M2 )->range().first );
|
||||
indices.push_back( 0 );
|
||||
setTimeSteps( indices );
|
||||
}
|
||||
|
||||
@ -915,7 +908,25 @@ void RimEnsembleCurveSet::updateMaxMinAndDefaultValues()
|
||||
m_minDateRange = QDateTime::fromSecsSinceEpoch( m_minTimeStep ).date();
|
||||
m_maxDateRange = QDateTime::fromSecsSinceEpoch( m_maxTimeStep ).date();
|
||||
|
||||
summaryCaseCollection()->objectiveFunction( m_objectiveFunction() )->setTimeStepRange( m_minTimeStep(), m_maxTimeStep() );
|
||||
for ( auto filter : m_curveFilters->filters() )
|
||||
{
|
||||
filter->updateMaxMinAndDefaultValuesFromParent();
|
||||
}
|
||||
|
||||
for ( auto objFunc : m_customObjectiveFunctions->objectiveFunctions() )
|
||||
{
|
||||
objFunc->clearCache();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSet::onCustomObjectiveFunctionChanged( const caf::SignalEmitter* emitter )
|
||||
{
|
||||
updateCurveColors();
|
||||
updateFilterLegend();
|
||||
updateObjectiveFunctionLegend();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -926,6 +937,7 @@ void RimEnsembleCurveSet::onObjectiveFunctionChanged( const caf::SignalEmitter*
|
||||
updateCurveColors();
|
||||
updateFilterLegend();
|
||||
updateObjectiveFunctionLegend();
|
||||
updateTimeAnnotations();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -950,32 +962,41 @@ void RimEnsembleCurveSet::appendColorGroup( caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
if ( m_colorMode == ColorMode::BY_OBJECTIVE_FUNCTION )
|
||||
{
|
||||
m_objectiveFunction.uiCapability()->setUiReadOnly( !m_yValuesSummaryCaseCollection() );
|
||||
colorsGroup->add( &m_objectiveValuesSummaryAddressesUiField );
|
||||
colorsGroup->add( &m_objectiveValuesSelectSummaryAddressPushButton, { false, 1, 0 } );
|
||||
colorsGroup->add( &m_objectiveFunction );
|
||||
|
||||
{
|
||||
auto equationGroup = colorsGroup->addNewGroup( "Equation" );
|
||||
m_objectiveFunction->uiOrdering( "", *equationGroup );
|
||||
equationGroup->add( &m_showObjectiveFunctionFormula );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
colorsGroup->add( &m_customObjectiveFunction );
|
||||
colorsGroup->add( &m_showObjectiveFunctionFormula );
|
||||
}
|
||||
colorsGroup->add( &m_showObjectiveFunctionFormula );
|
||||
if ( ( m_colorMode == ColorMode::BY_OBJECTIVE_FUNCTION &&
|
||||
m_objectiveFunction() == RimObjectiveFunction::FunctionType::M1 ) ||
|
||||
( m_colorMode == ColorMode::BY_CUSTOM_OBJECTIVE_FUNCTION && m_customObjectiveFunction() &&
|
||||
m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::M1 ) ) )
|
||||
|
||||
{
|
||||
colorsGroup->add( &m_minDateRange );
|
||||
colorsGroup->add( &m_minTimeStep );
|
||||
colorsGroup->add( &m_maxDateRange );
|
||||
colorsGroup->add( &m_maxTimeStep );
|
||||
}
|
||||
if ( m_objectiveFunction() == RimObjectiveFunction::FunctionType::M2 ||
|
||||
( m_customObjectiveFunction() &&
|
||||
m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::M2 ) ) )
|
||||
{
|
||||
colorsGroup->add( &m_timeStepFilter );
|
||||
colorsGroup->add( &m_selectedTimeSteps );
|
||||
auto timeSelectionGroup = colorsGroup->addNewGroup( "Time Selection" );
|
||||
|
||||
if ( ( m_colorMode == ColorMode::BY_OBJECTIVE_FUNCTION &&
|
||||
m_objectiveFunction()->functionType() == RimObjectiveFunction::FunctionType::F1 ) ||
|
||||
( m_colorMode == ColorMode::BY_CUSTOM_OBJECTIVE_FUNCTION && m_customObjectiveFunction() &&
|
||||
m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::F1 ) ) )
|
||||
{
|
||||
timeSelectionGroup->add( &m_minDateRange );
|
||||
timeSelectionGroup->add( &m_minTimeStep );
|
||||
timeSelectionGroup->add( &m_maxDateRange );
|
||||
timeSelectionGroup->add( &m_maxTimeStep );
|
||||
}
|
||||
if ( m_objectiveFunction()->functionType() == RimObjectiveFunction::FunctionType::F2 ||
|
||||
( m_customObjectiveFunction() &&
|
||||
m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::F2 ) ) )
|
||||
{
|
||||
timeSelectionGroup->add( &m_timeStepFilter );
|
||||
timeSelectionGroup->add( &m_selectedTimeSteps );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1354,13 +1375,10 @@ void RimEnsembleCurveSet::updateObjectiveFunctionLegend()
|
||||
addresses.push_back( address->address() );
|
||||
}
|
||||
|
||||
title = "Objective Function";
|
||||
description =
|
||||
QString( "%0 = %1" )
|
||||
.arg( m_yValuesSummaryCaseCollection()->objectiveFunction( m_objectiveFunction() )->uiName() )
|
||||
.arg( m_yValuesSummaryCaseCollection()
|
||||
->objectiveFunction( m_objectiveFunction() )
|
||||
->formulaString( addresses ) );
|
||||
title = "Objective Function";
|
||||
description = QString( "%0::%1" )
|
||||
.arg( m_objectiveFunction()->shortName() )
|
||||
.arg( m_objectiveFunction()->formulaString( addresses ) );
|
||||
}
|
||||
else if ( m_colorMode() == ColorMode::BY_CUSTOM_OBJECTIVE_FUNCTION && m_customObjectiveFunction() )
|
||||
{
|
||||
@ -1391,6 +1409,14 @@ void RimEnsembleCurveSet::updateObjectiveFunctionLegend()
|
||||
plot->viewer()->scheduleReplot();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
ObjectiveFunctionTimeConfig RimEnsembleCurveSet::objectiveFunctionTimeConfig() const
|
||||
{
|
||||
return { m_minTimeStep(), m_maxTimeStep(), selectedTimeSteps() };
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1403,16 +1429,7 @@ void RimEnsembleCurveSet::updateCurveColors()
|
||||
QString parameterName = m_ensembleParameter();
|
||||
|
||||
{
|
||||
QString legendTitle;
|
||||
if ( m_isUsingAutoName )
|
||||
{
|
||||
legendTitle = m_autoGeneratedName();
|
||||
}
|
||||
else
|
||||
{
|
||||
legendTitle += m_userDefinedName();
|
||||
}
|
||||
|
||||
QString legendTitle = "Ensemble Parameter";
|
||||
legendTitle += "\n";
|
||||
legendTitle += parameterName;
|
||||
|
||||
@ -1454,33 +1471,29 @@ void RimEnsembleCurveSet::updateCurveColors()
|
||||
RimSummaryCaseCollection* group = m_yValuesSummaryCaseCollection();
|
||||
|
||||
{
|
||||
QString legendTitle;
|
||||
if ( m_isUsingAutoName )
|
||||
{
|
||||
legendTitle = m_autoGeneratedName();
|
||||
}
|
||||
else
|
||||
{
|
||||
legendTitle += m_userDefinedName();
|
||||
}
|
||||
QString legendTitle = "Objective Function";
|
||||
|
||||
legendTitle += "\n";
|
||||
legendTitle += caf::AppEnum<RimObjectiveFunction::FunctionType>( m_objectiveFunction() ).uiText();
|
||||
legendTitle +=
|
||||
caf::AppEnum<RimObjectiveFunction::FunctionType>( m_objectiveFunction()->functionType() ).uiText();
|
||||
|
||||
m_legendConfig->setTitle( legendTitle );
|
||||
}
|
||||
|
||||
if ( group && !group->allSummaryCases().empty() )
|
||||
{
|
||||
auto objectiveFunction = group->objectiveFunction( m_objectiveFunction() );
|
||||
auto objectiveFunction = m_objectiveFunction();
|
||||
std::vector<RifEclipseSummaryAddress> summaryAddresses;
|
||||
for ( auto address : m_objectiveValuesSummaryAddresses() )
|
||||
{
|
||||
summaryAddresses.push_back( address->address() );
|
||||
}
|
||||
if ( objectiveFunction->isValid( summaryAddresses ) )
|
||||
{
|
||||
RimEnsembleCurveSetColorManager::initializeLegendConfig( m_legendConfig, objectiveFunction, summaryAddresses );
|
||||
RimEnsembleCurveSetColorManager::initializeLegendConfig( m_legendConfig,
|
||||
objectiveFunction,
|
||||
group->allSummaryCases(),
|
||||
summaryAddresses,
|
||||
objectiveFunctionTimeConfig() );
|
||||
for ( auto& curve : m_curves )
|
||||
{
|
||||
if ( curve->summaryAddressY().category() == RifEclipseSummaryAddress::SUMMARY_ENSEMBLE_STATISTICS )
|
||||
@ -1489,15 +1502,12 @@ void RimEnsembleCurveSet::updateCurveColors()
|
||||
cvf::Color3f curveColor = RimEnsembleCurveSetColorManager::caseColor( m_legendConfig,
|
||||
rimCase,
|
||||
objectiveFunction,
|
||||
summaryAddresses );
|
||||
summaryAddresses,
|
||||
objectiveFunctionTimeConfig() );
|
||||
curve->setColor( curveColor );
|
||||
curve->updateCurveAppearance();
|
||||
}
|
||||
}
|
||||
else if ( m_legendOverlayFrame )
|
||||
{
|
||||
m_legendOverlayFrame->hide();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( m_colorMode == ColorMode::BY_CUSTOM_OBJECTIVE_FUNCTION )
|
||||
@ -1505,16 +1515,7 @@ void RimEnsembleCurveSet::updateCurveColors()
|
||||
RimSummaryCaseCollection* group = m_yValuesSummaryCaseCollection();
|
||||
|
||||
{
|
||||
QString legendTitle;
|
||||
if ( m_isUsingAutoName )
|
||||
{
|
||||
legendTitle = m_autoGeneratedName();
|
||||
}
|
||||
else
|
||||
{
|
||||
legendTitle += m_userDefinedName();
|
||||
}
|
||||
|
||||
QString legendTitle = "Custom\nObjective Function";
|
||||
legendTitle += "\n";
|
||||
if ( m_customObjectiveFunction() && m_customObjectiveFunction()->isValid() )
|
||||
{
|
||||
@ -1589,17 +1590,17 @@ void RimEnsembleCurveSet::updateTimeAnnotations()
|
||||
plot->removeAllTimeAnnotations();
|
||||
|
||||
if ( ( m_colorMode() == ColorMode::BY_OBJECTIVE_FUNCTION &&
|
||||
m_objectiveFunction() == RimObjectiveFunction::FunctionType::M1 ) ||
|
||||
m_objectiveFunction()->functionType() == RimObjectiveFunction::FunctionType::F1 ) ||
|
||||
( m_colorMode() == ColorMode::BY_CUSTOM_OBJECTIVE_FUNCTION && m_customObjectiveFunction() &&
|
||||
m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::M1 ) ) )
|
||||
m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::F1 ) ) )
|
||||
{
|
||||
plot->addTimeRangeAnnotation( m_minTimeStep, m_maxTimeStep );
|
||||
}
|
||||
|
||||
if ( ( m_colorMode() == ColorMode::BY_OBJECTIVE_FUNCTION &&
|
||||
m_objectiveFunction() == RimObjectiveFunction::FunctionType::M2 ) ||
|
||||
m_objectiveFunction()->functionType() == RimObjectiveFunction::FunctionType::F2 ) ||
|
||||
( m_colorMode() == ColorMode::BY_CUSTOM_OBJECTIVE_FUNCTION && m_customObjectiveFunction() &&
|
||||
m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::M2 ) ) )
|
||||
m_customObjectiveFunction()->weightContainsFunctionType( RimObjectiveFunction::FunctionType::F2 ) ) )
|
||||
{
|
||||
for ( QDateTime timeStep : m_selectedTimeSteps() )
|
||||
{
|
||||
@ -1801,7 +1802,7 @@ RimEnsembleCurveSet* RimEnsembleCurveSet::clone() const
|
||||
{
|
||||
RimEnsembleCurveSet* copy = dynamic_cast<RimEnsembleCurveSet*>(
|
||||
this->xmlCapability()->copyByXmlSerialization( caf::PdmDefaultObjectFactory::instance() ) );
|
||||
copy->m_yValuesSummaryCaseCollection = m_yValuesSummaryCaseCollection();
|
||||
copy->setSummaryCaseCollection( m_yValuesSummaryCaseCollection() );
|
||||
|
||||
// Update summary case references
|
||||
for ( size_t i = 0; i < m_curves.size(); i++ )
|
||||
|
@ -59,6 +59,7 @@ class RimObjectiveFunction;
|
||||
class RiuDraggableOverlayFrame;
|
||||
class RiaSummaryCurveDefinitionAnalyser;
|
||||
class RiaSummaryCurveDefinition;
|
||||
class RiuSummaryVectorSelectionDialog;
|
||||
|
||||
class QwtPlot;
|
||||
class QwtPlotCurve;
|
||||
@ -125,7 +126,7 @@ public:
|
||||
|
||||
void updateAllCurves();
|
||||
void setTimeSteps( const std::vector<size_t>& timeStepIndices );
|
||||
std::vector<time_t> selectedTimeSteps();
|
||||
std::vector<time_t> selectedTimeSteps() const;
|
||||
void updateStatisticsCurves();
|
||||
|
||||
RimEnsembleCurveSet* clone() const;
|
||||
@ -153,6 +154,8 @@ public:
|
||||
void updateFilterLegend();
|
||||
void updateObjectiveFunctionLegend();
|
||||
|
||||
ObjectiveFunctionTimeConfig objectiveFunctionTimeConfig() const;
|
||||
|
||||
private:
|
||||
void updateEnsembleCurves( const std::vector<RimSummaryCase*>& sumCases );
|
||||
void updateStatisticsCurves( const std::vector<RimSummaryCase*>& sumCases );
|
||||
@ -186,6 +189,7 @@ private:
|
||||
void updateAddressesUiField();
|
||||
|
||||
void onObjectiveFunctionChanged( const caf::SignalEmitter* emitter );
|
||||
void onCustomObjectiveFunctionChanged( const caf::SignalEmitter* emitter );
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_showCurves;
|
||||
@ -203,25 +207,26 @@ private:
|
||||
caf::PdmField<cvf::Color3f> m_color;
|
||||
caf::PdmField<QString> m_ensembleParameter;
|
||||
|
||||
caf::PdmChildArrayField<RimSummaryAddress*> m_objectiveValuesSummaryAddresses;
|
||||
caf::PdmField<QString> m_objectiveValuesSummaryAddressesUiField;
|
||||
caf::PdmField<bool> m_objectiveValuesSelectSummaryAddressPushButton;
|
||||
caf::PdmField<caf::AppEnum<RimObjectiveFunction::FunctionType>> m_objectiveFunction;
|
||||
caf::PdmPtrField<RimCustomObjectiveFunction*> m_customObjectiveFunction;
|
||||
caf::PdmField<time_t> m_minTimeStep;
|
||||
caf::PdmField<time_t> m_maxTimeStep;
|
||||
caf::PdmField<QDate> m_minDateRange;
|
||||
caf::PdmField<QDate> m_maxDateRange;
|
||||
caf::PdmField<TimeStepFilterEnum> m_timeStepFilter;
|
||||
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
|
||||
caf::PdmChildArrayField<RimSummaryAddress*> m_objectiveValuesSummaryAddresses;
|
||||
caf::PdmField<QString> m_objectiveValuesSummaryAddressesUiField;
|
||||
caf::PdmField<bool> m_objectiveValuesSelectSummaryAddressPushButton;
|
||||
caf::PdmPtrField<RimCustomObjectiveFunction*> m_customObjectiveFunction;
|
||||
caf::PdmField<time_t> m_minTimeStep;
|
||||
caf::PdmField<time_t> m_maxTimeStep;
|
||||
caf::PdmField<QDate> m_minDateRange;
|
||||
caf::PdmField<QDate> m_maxDateRange;
|
||||
caf::PdmField<TimeStepFilterEnum> m_timeStepFilter;
|
||||
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
|
||||
|
||||
caf::PdmField<caf::AppEnum<RiaDefines::PlotAxis>> m_plotAxis;
|
||||
|
||||
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
|
||||
caf::PdmChildField<RimEnsembleCurveFilterCollection*> m_curveFilters;
|
||||
caf::PdmChildField<RimEnsembleStatistics*> m_statistics;
|
||||
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
|
||||
caf::PdmChildField<RimEnsembleCurveFilterCollection*> m_curveFilters;
|
||||
caf::PdmChildField<RimEnsembleStatistics*> m_statistics;
|
||||
|
||||
caf::PdmChildField<RimCustomObjectiveFunctionCollection*> m_customObjectiveFunctions;
|
||||
caf::PdmField<bool> m_showObjectiveFunctionFormula;
|
||||
caf::PdmChildField<RimObjectiveFunction*> m_objectiveFunction;
|
||||
|
||||
caf::PdmField<bool> m_isUsingAutoName;
|
||||
caf::PdmField<QString> m_userDefinedName;
|
||||
|
@ -133,21 +133,13 @@ void RimEnsembleCurveSetColorManager::initializeLegendConfig( RimRegularLegendCo
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimEnsembleCurveSetColorManager::initializeLegendConfig( RimRegularLegendConfig* legendConfig,
|
||||
std::shared_ptr<RimObjectiveFunction> objectiveFunction,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses )
|
||||
void RimEnsembleCurveSetColorManager::initializeLegendConfig( RimRegularLegendConfig* legendConfig,
|
||||
RimObjectiveFunction* objectiveFunction,
|
||||
const std::vector<RimSummaryCase*>& summaryCases,
|
||||
const std::vector<RifEclipseSummaryAddress>& vectorSummaryAddresses,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig )
|
||||
{
|
||||
double minValue = std::numeric_limits<double>::infinity();
|
||||
double maxValue = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for ( auto value : objectiveFunction->values( vectorSummaryAddresses ) )
|
||||
{
|
||||
if ( value != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
if ( value < minValue ) minValue = value;
|
||||
if ( value > maxValue ) maxValue = value;
|
||||
}
|
||||
}
|
||||
auto [minValue, maxValue] = objectiveFunction->minMaxValues( summaryCases, vectorSummaryAddresses, timeConfig );
|
||||
|
||||
legendConfig->setAutomaticRanges( minValue, maxValue, minValue, maxValue );
|
||||
}
|
||||
@ -161,7 +153,7 @@ void RimEnsembleCurveSetColorManager::initializeLegendConfig( RimRegularLegendCo
|
||||
double minValue = std::numeric_limits<double>::infinity();
|
||||
double maxValue = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for ( auto value : customObjectiveFunction->values() )
|
||||
for ( auto value : customObjectiveFunction->functionValueForAllCases() )
|
||||
{
|
||||
if ( value != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
@ -210,10 +202,11 @@ cvf::Color3f RimEnsembleCurveSetColorManager::caseColor( const RimRegularLegendC
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
cvf::Color3f RimEnsembleCurveSetColorManager::caseColor( const RimRegularLegendConfig* legendConfig,
|
||||
RimSummaryCase* summaryCase,
|
||||
std::shared_ptr<RimObjectiveFunction> objectiveFunction,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses )
|
||||
RimObjectiveFunction* objectiveFunction,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig )
|
||||
{
|
||||
double value = objectiveFunction->value( summaryCase, vectorSummaryAddresses );
|
||||
double value = objectiveFunction->value( summaryCase, vectorSummaryAddresses, timeConfig );
|
||||
if ( value != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
return cvf::Color3f( legendConfig->scalarMapper()->mapToColor( value ) );
|
||||
|
@ -59,9 +59,11 @@ public:
|
||||
}
|
||||
|
||||
static void initializeLegendConfig( RimRegularLegendConfig* legendConfig, const EnsembleParameter& parameter );
|
||||
static void initializeLegendConfig( RimRegularLegendConfig* legendConfig,
|
||||
std::shared_ptr<RimObjectiveFunction> objectiveFunction,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses );
|
||||
static void initializeLegendConfig( RimRegularLegendConfig* legendConfig,
|
||||
RimObjectiveFunction* objectiveFunction,
|
||||
const std::vector<RimSummaryCase*>& summaryCases,
|
||||
const std::vector<RifEclipseSummaryAddress>& vectorSummaryAddresses,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig );
|
||||
|
||||
static void initializeLegendConfig( RimRegularLegendConfig* legendConfig,
|
||||
caf::PdmPointer<RimCustomObjectiveFunction> customObjectiveFunction );
|
||||
@ -72,8 +74,9 @@ public:
|
||||
|
||||
static cvf::Color3f caseColor( const RimRegularLegendConfig* legendConfig,
|
||||
RimSummaryCase* summaryCase,
|
||||
std::shared_ptr<RimObjectiveFunction> objectiveFunction,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses );
|
||||
RimObjectiveFunction* objectiveFunction,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig );
|
||||
|
||||
static cvf::Color3f caseColor( const RimRegularLegendConfig* legendConfig,
|
||||
RimSummaryCase* summaryCase,
|
||||
|
@ -37,244 +37,145 @@ namespace caf
|
||||
template <>
|
||||
void caf::AppEnum<RimObjectiveFunction::FunctionType>::setUp()
|
||||
{
|
||||
addItem( RimObjectiveFunction::FunctionType::M1, "M1", "M1" );
|
||||
addItem( RimObjectiveFunction::FunctionType::M2, "M2", "M2" );
|
||||
setDefault( RimObjectiveFunction::FunctionType::M1 );
|
||||
addItem( RimObjectiveFunction::FunctionType::F1, "F1", "Time Range (F1)" );
|
||||
addItem( RimObjectiveFunction::FunctionType::F2, "F2", "Selected Time Steps (F2)" );
|
||||
setDefault( RimObjectiveFunction::FunctionType::F1 );
|
||||
}
|
||||
|
||||
} // namespace caf
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimObjectiveFunction, "RimObjectiveFunction" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimObjectiveFunction::uiName() const
|
||||
RimObjectiveFunction::RimObjectiveFunction()
|
||||
: changed( this )
|
||||
|
||||
{
|
||||
if ( m_functionType == FunctionType::M1 )
|
||||
{
|
||||
return QString( "M1" );
|
||||
}
|
||||
else if ( m_functionType == FunctionType::M2 )
|
||||
{
|
||||
return QString( "M2" );
|
||||
}
|
||||
return QString();
|
||||
CAF_PDM_InitObject( "Objective Function", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_functionType, "FunctionType", "Function Type", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_normalizeByNumberOfObservations,
|
||||
"NormalizeByNumberOfObservations",
|
||||
true,
|
||||
"Normalize by Number of Observations",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitField( &m_normalizeByNumberOfVectors,
|
||||
"NormalizeByNumberOfVectors",
|
||||
true,
|
||||
"Normalize by Number of Vectors",
|
||||
"",
|
||||
"",
|
||||
"" );
|
||||
|
||||
CAF_PDM_InitField( &m_errorEstimatePercentage, "ErrorEstimatePercentage", 100.0, "Error Estimate [0..100 %]", "", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_useSquaredError, "UseSquaredError", true, "Use Squared Error Term", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimObjectiveFunction::FunctionType RimObjectiveFunction::functionType()
|
||||
void RimObjectiveFunction::setFunctionType( FunctionType functionType )
|
||||
{
|
||||
return m_functionType;
|
||||
m_functionType = functionType;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimObjectiveFunction::setTimeStepRange( time_t startTimeStep, time_t endTimeStep )
|
||||
QString RimObjectiveFunction::shortName() const
|
||||
{
|
||||
m_startTimeStep = startTimeStep;
|
||||
m_endTimeStep = endTimeStep;
|
||||
return caf::AppEnum<FunctionType>::text( m_functionType() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimObjectiveFunction::setTimeStepList( std::vector<time_t> timeSteps )
|
||||
RimObjectiveFunction::FunctionType RimObjectiveFunction::functionType() const
|
||||
{
|
||||
m_timeSteps = timeSteps;
|
||||
return m_functionType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimObjectiveFunction::RimObjectiveFunction( const RimSummaryCaseCollection* summaryCaseCollection, FunctionType type )
|
||||
{
|
||||
m_summaryCaseCollection = summaryCaseCollection;
|
||||
m_functionType = type;
|
||||
m_startTimeStep = 0;
|
||||
m_endTimeStep = INT_MAX;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimObjectiveFunction::value( size_t caseIndex,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses,
|
||||
bool* hasWarning ) const
|
||||
{
|
||||
auto summaryCases = m_summaryCaseCollection->allSummaryCases();
|
||||
|
||||
if ( caseIndex < summaryCases.size() )
|
||||
{
|
||||
return value( summaryCases[caseIndex], vectorSummaryAddresses, hasWarning );
|
||||
}
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimObjectiveFunction::value( RimSummaryCase* summaryCase,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses,
|
||||
bool* hasWarning ) const
|
||||
double RimObjectiveFunction::value( RimSummaryCase* summaryCase,
|
||||
const std::vector<RifEclipseSummaryAddress>& vectorSummaryAddresses,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig,
|
||||
bool* hasWarning ) const
|
||||
{
|
||||
RifSummaryReaderInterface* readerInterface = summaryCase->summaryReader();
|
||||
if ( readerInterface )
|
||||
{
|
||||
if ( m_functionType == FunctionType::M1 )
|
||||
double aggregatedObjectiveFunctionValue = 0.0;
|
||||
|
||||
for ( auto vectorSummaryAddress : vectorSummaryAddresses )
|
||||
{
|
||||
double sumValues = 0.0;
|
||||
double sumValuesSquared = 0.0;
|
||||
double N = 0.0;
|
||||
for ( auto vectorSummaryAddress : vectorSummaryAddresses )
|
||||
std::string s = vectorSummaryAddress.quantityName() + RifReaderEclipseSummary::differenceIdentifier();
|
||||
if ( !vectorSummaryAddress.quantityName().empty() )
|
||||
{
|
||||
std::string s = vectorSummaryAddress.quantityName() + RifReaderEclipseSummary::differenceIdentifier();
|
||||
if ( !vectorSummaryAddress.quantityName().empty() )
|
||||
if ( vectorSummaryAddress.quantityName().find( RifReaderEclipseSummary::differenceIdentifier() ) !=
|
||||
std::string::npos )
|
||||
{
|
||||
if ( vectorSummaryAddress.quantityName().find( RifReaderEclipseSummary::differenceIdentifier() ) !=
|
||||
std::string::npos )
|
||||
{
|
||||
s = vectorSummaryAddress.quantityName();
|
||||
}
|
||||
RifEclipseSummaryAddress vectorSummaryAddressDiff = vectorSummaryAddress;
|
||||
vectorSummaryAddressDiff.setQuantityName( s );
|
||||
s = vectorSummaryAddress.quantityName();
|
||||
}
|
||||
RifEclipseSummaryAddress vectorSummaryAddressDiff = vectorSummaryAddress;
|
||||
vectorSummaryAddressDiff.setQuantityName( s );
|
||||
|
||||
if ( readerInterface->allResultAddresses().count( vectorSummaryAddressDiff ) )
|
||||
RifEclipseSummaryAddress vectorSummaryAddressHistory = vectorSummaryAddress;
|
||||
vectorSummaryAddressDiff.setQuantityName( vectorSummaryAddress.quantityName() +
|
||||
RifReaderEclipseSummary::differenceIdentifier() );
|
||||
|
||||
if ( readerInterface->allResultAddresses().count( vectorSummaryAddressDiff ) )
|
||||
{
|
||||
const std::vector<time_t>& allTimeSteps = readerInterface->timeSteps( vectorSummaryAddressDiff );
|
||||
std::vector<size_t> timeStepsForEvaluation = timeStepIndicesForEvaluation( allTimeSteps, timeConfig );
|
||||
|
||||
std::vector<double> summaryDiffValues;
|
||||
std::vector<double> summaryHistoryValues;
|
||||
|
||||
if ( readerInterface->values( vectorSummaryAddressDiff, &summaryDiffValues ) &&
|
||||
readerInterface->values( vectorSummaryAddressHistory, &summaryHistoryValues ) )
|
||||
{
|
||||
std::vector<double> values;
|
||||
if ( readerInterface->values( vectorSummaryAddressDiff, &values ) )
|
||||
const double functionValue =
|
||||
computeFunctionValue( summaryDiffValues, summaryHistoryValues, timeStepsForEvaluation );
|
||||
|
||||
if ( functionValue != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
const std::vector<time_t>& timeSteps = readerInterface->timeSteps( vectorSummaryAddressDiff );
|
||||
|
||||
size_t index = 0;
|
||||
|
||||
N += static_cast<double>( values.size() );
|
||||
if ( values.size() > 1 )
|
||||
{
|
||||
for ( time_t t : timeSteps )
|
||||
{
|
||||
if ( t >= m_startTimeStep && t <= m_endTimeStep )
|
||||
{
|
||||
const double& value = values[index];
|
||||
sumValues += std::abs( value );
|
||||
sumValuesSquared += value * value;
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::info( "The selected summary address does not have a related difference address." );
|
||||
if ( hasWarning )
|
||||
{
|
||||
*hasWarning = true;
|
||||
aggregatedObjectiveFunctionValue += functionValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::info( "Invalid summary address." );
|
||||
if ( hasWarning )
|
||||
{
|
||||
*hasWarning = true;
|
||||
}
|
||||
}
|
||||
if ( sumValues != 0 )
|
||||
{
|
||||
return sumValues / std::sqrt( ( N * sumValuesSquared - sumValues * sumValues ) / ( N * ( N - 1.0 ) ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( m_functionType == FunctionType::M2 )
|
||||
{
|
||||
double value = 0;
|
||||
for ( auto vectorSummaryAddress : vectorSummaryAddresses )
|
||||
{
|
||||
std::string s = vectorSummaryAddress.quantityName() + RifReaderEclipseSummary::differenceIdentifier();
|
||||
if ( !vectorSummaryAddress.quantityName().empty() )
|
||||
{
|
||||
if ( vectorSummaryAddress.quantityName().find( RifReaderEclipseSummary::differenceIdentifier() ) !=
|
||||
std::string::npos )
|
||||
{
|
||||
s = vectorSummaryAddress.quantityName();
|
||||
}
|
||||
RifEclipseSummaryAddress vectorSummaryAddressDiff = vectorSummaryAddress;
|
||||
vectorSummaryAddressDiff.setQuantityName( s );
|
||||
|
||||
if ( readerInterface->allResultAddresses().count( vectorSummaryAddressDiff ) )
|
||||
{
|
||||
std::vector<double> values;
|
||||
if ( readerInterface->values( vectorSummaryAddressDiff, &values ) )
|
||||
{
|
||||
const std::vector<time_t>& timeSteps = readerInterface->timeSteps( vectorSummaryAddressDiff );
|
||||
|
||||
size_t index = 0;
|
||||
|
||||
std::vector<time_t> xValues( 2, 0 );
|
||||
std::vector<double> yValues( 2, 0.0 );
|
||||
for ( time_t t : timeSteps )
|
||||
{
|
||||
if ( t >= m_startTimeStep && t <= m_endTimeStep )
|
||||
{
|
||||
if ( xValues.front() == 0 )
|
||||
{
|
||||
xValues[0] = t;
|
||||
yValues[0] = values[index];
|
||||
}
|
||||
else if ( xValues.back() == 0 )
|
||||
{
|
||||
xValues[1] = t;
|
||||
yValues[1] = values[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
xValues[0] = xValues[1];
|
||||
xValues[1] = t;
|
||||
yValues[0] = yValues[1];
|
||||
yValues[1] = values[index];
|
||||
}
|
||||
if ( xValues.back() != 0 )
|
||||
{
|
||||
for ( time_t timeStep : m_timeSteps )
|
||||
{
|
||||
if ( xValues[0] <= timeStep && xValues[1] >= timeStep )
|
||||
{
|
||||
double interpValue = std::abs(
|
||||
RiaCurveMerger<time_t>::interpolatedYValue( timeStep, xValues, yValues ) );
|
||||
if ( interpValue != HUGE_VAL )
|
||||
{
|
||||
value += interpValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
index++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::info( "The selected summary address does not have a related difference address." );
|
||||
if ( hasWarning )
|
||||
{
|
||||
*hasWarning = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
RiaLogging::info( "Invalid summary address." );
|
||||
RiaLogging::info( "The selected summary address does not have a related difference address." );
|
||||
if ( hasWarning )
|
||||
{
|
||||
*hasWarning = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
return value;
|
||||
else
|
||||
{
|
||||
RiaLogging::info( "Invalid summary address." );
|
||||
if ( hasWarning )
|
||||
{
|
||||
*hasWarning = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_normalizeByNumberOfVectors && vectorSummaryAddresses.size() > 0 )
|
||||
{
|
||||
aggregatedObjectiveFunctionValue /= vectorSummaryAddresses.size();
|
||||
}
|
||||
|
||||
return aggregatedObjectiveFunctionValue;
|
||||
}
|
||||
}
|
||||
return 0.0;
|
||||
@ -284,102 +185,40 @@ double RimObjectiveFunction::value( RimSummaryCase* summar
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<double, double>
|
||||
RimObjectiveFunction::minMaxValues( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses ) const
|
||||
RimObjectiveFunction::minMaxValues( const std::vector<RimSummaryCase*>& summaryCases,
|
||||
const std::vector<RifEclipseSummaryAddress>& vectorSummaryAddresses,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig ) const
|
||||
{
|
||||
double minValue = std::numeric_limits<double>::infinity();
|
||||
double maxValue = -std::numeric_limits<double>::infinity();
|
||||
|
||||
for ( auto value : values( vectorSummaryAddresses ) )
|
||||
for ( auto sumCase : summaryCases )
|
||||
{
|
||||
if ( value != std::numeric_limits<double>::infinity() )
|
||||
auto objValue = value( sumCase, vectorSummaryAddresses, timeConfig );
|
||||
{
|
||||
if ( value < minValue ) minValue = value;
|
||||
if ( value > maxValue ) maxValue = value;
|
||||
if ( objValue != std::numeric_limits<double>::infinity() )
|
||||
{
|
||||
if ( objValue < minValue ) minValue = objValue;
|
||||
if ( objValue > maxValue ) maxValue = objValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
return std::make_pair( minValue, maxValue );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<time_t, time_t> RimObjectiveFunction::range() const
|
||||
{
|
||||
return std::make_pair( m_startTimeStep, m_endTimeStep );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<double> RimObjectiveFunction::values( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses ) const
|
||||
{
|
||||
std::vector<double> values;
|
||||
auto summaryCases = m_summaryCaseCollection->allSummaryCases();
|
||||
|
||||
bool hasWarning = false;
|
||||
|
||||
for ( size_t index = 0; index < summaryCases.size(); index++ )
|
||||
{
|
||||
values.push_back( value( index, vectorSummaryAddresses, &hasWarning ) );
|
||||
if ( hasWarning )
|
||||
{
|
||||
return std::vector<double>();
|
||||
}
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimObjectiveFunction::isValid( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses ) const
|
||||
{
|
||||
bool hasWarning = false;
|
||||
if ( m_summaryCaseCollection && m_summaryCaseCollection->allSummaryCases().size() > 0 &&
|
||||
m_summaryCaseCollection->allSummaryCases().front() )
|
||||
{
|
||||
value( m_summaryCaseCollection->allSummaryCases().front(), vectorSummaryAddresses, &hasWarning );
|
||||
if ( hasWarning )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimObjectiveFunction::formulaString( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses )
|
||||
{
|
||||
QString formula;
|
||||
if ( m_functionType == FunctionType::M1 )
|
||||
|
||||
for ( RifEclipseSummaryAddress address : vectorSummaryAddresses )
|
||||
{
|
||||
formula += "(" + QString::fromWCharArray( L"\u03A3" ) + "(|";
|
||||
QStringList addresses;
|
||||
for ( RifEclipseSummaryAddress address : vectorSummaryAddresses )
|
||||
{
|
||||
addresses << QString::fromStdString( address.uiText() );
|
||||
}
|
||||
formula += addresses.join( "| + |" );
|
||||
formula += "|))/(stdv)";
|
||||
}
|
||||
else if ( m_functionType == FunctionType::M2 )
|
||||
{
|
||||
formula += QString::fromWCharArray( L"\u03A3" ) + "(|";
|
||||
QStringList addresses;
|
||||
for ( RifEclipseSummaryAddress address : vectorSummaryAddresses )
|
||||
{
|
||||
addresses << QString::fromStdString( address.uiText() );
|
||||
}
|
||||
formula += addresses.join( "| + |" );
|
||||
formula += "|)";
|
||||
QString text = QString::fromStdString( address.uiText() );
|
||||
formula += text + "\n";
|
||||
}
|
||||
|
||||
return formula;
|
||||
}
|
||||
|
||||
@ -388,5 +227,164 @@ QString RimObjectiveFunction::formulaString( std::vector<RifEclipseSummaryAddres
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimObjectiveFunction::operator<( const RimObjectiveFunction& other ) const
|
||||
{
|
||||
return this->uiName() < other.uiName();
|
||||
return this->shortName() < other.shortName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimObjectiveFunction::hideFunctionSelection()
|
||||
{
|
||||
m_functionType.uiCapability()->setUiHidden( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimObjectiveFunction::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
uiOrdering.add( &m_functionType );
|
||||
uiOrdering.add( &m_normalizeByNumberOfObservations );
|
||||
uiOrdering.add( &m_normalizeByNumberOfVectors );
|
||||
uiOrdering.add( &m_errorEstimatePercentage );
|
||||
uiOrdering.add( &m_useSquaredError );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimObjectiveFunction::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
double estimate = m_errorEstimatePercentage;
|
||||
m_errorEstimatePercentage = std::clamp( estimate, 0.0, 100.0 );
|
||||
|
||||
changed.send();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimObjectiveFunction::errorEstimate() const
|
||||
{
|
||||
return std::clamp( ( m_errorEstimatePercentage / 100.0 ), 0.0, 1.0 );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<size_t> RimObjectiveFunction::timeStepIndicesForEvaluation( const std::vector<time_t>& allTimeSteps,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig ) const
|
||||
{
|
||||
std::vector<size_t> timeStepIndices;
|
||||
if ( functionType() == FunctionType::F1 )
|
||||
{
|
||||
for ( size_t i = 0; i < allTimeSteps.size(); i++ )
|
||||
{
|
||||
const auto& t = allTimeSteps[i];
|
||||
if ( t >= timeConfig.m_startTimeStep && t <= timeConfig.m_endTimeStep )
|
||||
{
|
||||
timeStepIndices.push_back( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( functionType() == FunctionType::F2 )
|
||||
{
|
||||
for ( const auto& t : timeConfig.m_timeSteps )
|
||||
{
|
||||
for ( size_t i = 0; i < allTimeSteps.size(); i++ )
|
||||
{
|
||||
const auto& candidateTime = allTimeSteps[i];
|
||||
if ( t == candidateTime )
|
||||
{
|
||||
timeStepIndices.push_back( i );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return timeStepIndices;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
double RimObjectiveFunction::computeFunctionValue( const std::vector<double>& summaryDiffValues,
|
||||
const std::vector<double>& summaryHistoryValues,
|
||||
const std::vector<size_t>& evaluationIndices ) const
|
||||
{
|
||||
if ( summaryHistoryValues.size() != summaryDiffValues.size() ) return std::numeric_limits<double>::infinity();
|
||||
|
||||
const double epsilonErrorEstimate = errorEstimate();
|
||||
|
||||
double sumValues = 0.0;
|
||||
double sumValuesSquared = 0.0;
|
||||
size_t valueCount = evaluationIndices.size();
|
||||
|
||||
double averageHistoryValue = 0.0;
|
||||
if ( !summaryHistoryValues.empty() )
|
||||
{
|
||||
for ( auto val : summaryHistoryValues )
|
||||
{
|
||||
averageHistoryValue += val;
|
||||
}
|
||||
|
||||
averageHistoryValue /= summaryHistoryValues.size();
|
||||
}
|
||||
|
||||
//
|
||||
// 1 ( |ti - tHi| ) n
|
||||
// value = - * SUM ( ---------- )
|
||||
// N ( eps * tHi )
|
||||
//
|
||||
// N : observation count
|
||||
// ti : simulated value at time step i
|
||||
// Hti : observed (history) value at time step i
|
||||
// eps : error estimate (0..1)
|
||||
// n : 2 - squared error term
|
||||
//
|
||||
// https://github.com/OPM/ResInsight/issues/7761
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
const double epsilon = 1e-67;
|
||||
|
||||
for ( size_t timeStepIndex : evaluationIndices )
|
||||
{
|
||||
const double diffValue = std::abs( summaryDiffValues[timeStepIndex] );
|
||||
|
||||
double historyValue = summaryHistoryValues[timeStepIndex];
|
||||
double nominator = std::abs( epsilonErrorEstimate * historyValue );
|
||||
if ( nominator < epsilon )
|
||||
{
|
||||
if ( averageHistoryValue > epsilon )
|
||||
nominator = averageHistoryValue;
|
||||
else if ( diffValue > epsilon )
|
||||
nominator = diffValue;
|
||||
else
|
||||
nominator = 1.0;
|
||||
}
|
||||
|
||||
const double normalizedDiff = diffValue / nominator;
|
||||
|
||||
sumValues += std::abs( normalizedDiff );
|
||||
sumValuesSquared += normalizedDiff * normalizedDiff;
|
||||
}
|
||||
|
||||
if ( valueCount > 0 )
|
||||
{
|
||||
double functionValue = 0.0;
|
||||
if ( m_useSquaredError )
|
||||
functionValue = sumValuesSquared;
|
||||
else
|
||||
functionValue = sumValues;
|
||||
|
||||
if ( m_normalizeByNumberOfObservations ) functionValue /= valueCount;
|
||||
|
||||
return functionValue;
|
||||
}
|
||||
|
||||
return std::numeric_limits<double>::infinity();
|
||||
}
|
||||
|
@ -18,6 +18,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "cafAppEnum.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <QString>
|
||||
#include <QVariant>
|
||||
|
||||
@ -27,51 +31,71 @@ class RimSummaryCase;
|
||||
class RimSummaryCaseCollection;
|
||||
class RifEclipseSummaryAddress;
|
||||
|
||||
class ObjectiveFunctionTimeConfig
|
||||
{
|
||||
public:
|
||||
time_t m_startTimeStep;
|
||||
time_t m_endTimeStep;
|
||||
std::vector<time_t> m_timeSteps;
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimObjectiveFunction
|
||||
class RimObjectiveFunction : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::Signal<> changed;
|
||||
|
||||
public:
|
||||
enum class FunctionType
|
||||
{
|
||||
M1 = 0,
|
||||
M2
|
||||
F1 = 0,
|
||||
F2
|
||||
};
|
||||
|
||||
QString uiName() const;
|
||||
RimObjectiveFunction::FunctionType functionType();
|
||||
QString shortName() const;
|
||||
RimObjectiveFunction::FunctionType functionType() const;
|
||||
|
||||
void setTimeStepRange( time_t startTime, time_t endTime );
|
||||
void setTimeStepList( std::vector<time_t> timeSteps );
|
||||
RimObjectiveFunction();
|
||||
void setFunctionType( RimObjectiveFunction::FunctionType functionType );
|
||||
|
||||
RimObjectiveFunction( const RimSummaryCaseCollection* summaryCaseCollection, FunctionType type );
|
||||
double value( RimSummaryCase* summaryCase,
|
||||
const std::vector<RifEclipseSummaryAddress>& vectorSummaryAddresses,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig,
|
||||
bool* hasWarning = nullptr ) const;
|
||||
|
||||
double value( size_t caseIndex,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses,
|
||||
bool* hasWarning = nullptr ) const;
|
||||
|
||||
double value( RimSummaryCase* summaryCase,
|
||||
std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses,
|
||||
bool* hasWarning = nullptr ) const;
|
||||
|
||||
std::pair<double, double> minMaxValues( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses ) const;
|
||||
|
||||
std::pair<time_t, time_t> range() const;
|
||||
|
||||
std::vector<double> values( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses ) const;
|
||||
|
||||
bool isValid( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses ) const;
|
||||
std::pair<double, double> minMaxValues( const std::vector<RimSummaryCase*>& summaryCases,
|
||||
const std::vector<RifEclipseSummaryAddress>& vectorSummaryAddresses,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig ) const;
|
||||
|
||||
QString formulaString( std::vector<RifEclipseSummaryAddress> vectorSummaryAddresses );
|
||||
|
||||
bool operator<( const RimObjectiveFunction& other ) const;
|
||||
|
||||
private:
|
||||
const RimSummaryCaseCollection* m_summaryCaseCollection;
|
||||
void hideFunctionSelection();
|
||||
|
||||
time_t m_startTimeStep;
|
||||
time_t m_endTimeStep;
|
||||
std::vector<time_t> m_timeSteps;
|
||||
FunctionType m_functionType;
|
||||
protected:
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
|
||||
private:
|
||||
double errorEstimate() const;
|
||||
|
||||
std::vector<size_t> timeStepIndicesForEvaluation( const std::vector<time_t>& allTimeSteps,
|
||||
const ObjectiveFunctionTimeConfig& timeConfig ) const;
|
||||
|
||||
double computeFunctionValue( const std::vector<double>& summaryDiffValues,
|
||||
const std::vector<double>& summaryHistoryValues,
|
||||
const std::vector<size_t>& evaluationIndices ) const;
|
||||
|
||||
private:
|
||||
caf::PdmField<caf::AppEnum<RimObjectiveFunction::FunctionType>> m_functionType;
|
||||
|
||||
caf::PdmField<bool> m_normalizeByNumberOfObservations;
|
||||
caf::PdmField<double> m_errorEstimatePercentage;
|
||||
caf::PdmField<bool> m_useSquaredError;
|
||||
caf::PdmField<bool> m_normalizeByNumberOfVectors;
|
||||
};
|
||||
|
@ -0,0 +1,95 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021 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 "RimObjectiveFunctionTools.h"
|
||||
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
|
||||
#include "RiaStdStringTools.h"
|
||||
#include "RifReaderEclipseSummary.h"
|
||||
#include "RimCustomObjectiveFunction.h"
|
||||
#include "RimCustomObjectiveFunctionWeight.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RiuSummaryVectorSelectionDialog.h"
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimCustomObjectiveFunctionWeight* RimObjectiveFunctionTools::addWeight( RimCustomObjectiveFunction* customObjectiveFunction )
|
||||
{
|
||||
if ( !customObjectiveFunction ) return nullptr;
|
||||
|
||||
RimCustomObjectiveFunctionWeight* newWeight = customObjectiveFunction->addWeight();
|
||||
|
||||
RifEclipseSummaryAddress candidateAdr;
|
||||
if ( customObjectiveFunction->weights().size() > 1 )
|
||||
{
|
||||
candidateAdr = customObjectiveFunction->weights().front()->summaryAddresses().front();
|
||||
}
|
||||
else
|
||||
{
|
||||
candidateAdr = newWeight->parentCurveSet()->summaryAddress();
|
||||
}
|
||||
|
||||
auto nativeQuantityName = RimObjectiveFunctionTools::nativeQuantityName( candidateAdr.quantityName() );
|
||||
|
||||
candidateAdr.setQuantityName( nativeQuantityName );
|
||||
newWeight->setSummaryAddress( candidateAdr );
|
||||
|
||||
return newWeight;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::string RimObjectiveFunctionTools::nativeQuantityName( const std::string& quantityName )
|
||||
{
|
||||
std::string nativeName = quantityName;
|
||||
|
||||
{
|
||||
auto stringToRemove = RifReaderEclipseSummary::differenceIdentifier();
|
||||
if ( RiaStdStringTools::endsWith( nativeName, stringToRemove ) )
|
||||
{
|
||||
nativeName = nativeName.substr( 0, nativeName.size() - stringToRemove.size() );
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
auto stringToRemove = RifReaderEclipseSummary::historyIdentifier();
|
||||
if ( RiaStdStringTools::endsWith( nativeName, stringToRemove ) )
|
||||
{
|
||||
nativeName = nativeName.substr( 0, nativeName.size() - stringToRemove.size() );
|
||||
}
|
||||
}
|
||||
|
||||
return nativeName;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimObjectiveFunctionTools::configureDialogForObjectiveFunctions( RiuSummaryVectorSelectionDialog* dialog )
|
||||
{
|
||||
if ( !dialog ) return;
|
||||
|
||||
dialog->enableMultiSelect( true );
|
||||
dialog->hideDifferenceVectors();
|
||||
dialog->hideHistoryVectors();
|
||||
dialog->hideVectorsWithNoHistory();
|
||||
dialog->hideSummaryCases();
|
||||
}
|
@ -0,0 +1,36 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2021 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 <string>
|
||||
|
||||
class RimCustomObjectiveFunctionWeight;
|
||||
class RimCustomObjectiveFunction;
|
||||
class RiuSummaryVectorSelectionDialog;
|
||||
|
||||
namespace RimObjectiveFunctionTools
|
||||
{
|
||||
RimCustomObjectiveFunctionWeight* addWeight( RimCustomObjectiveFunction* customObjectiveFunction );
|
||||
|
||||
// Returns a string without string endings 'H' and '_DIFF'
|
||||
std::string nativeQuantityName( const std::string& quantityName );
|
||||
|
||||
void configureDialogForObjectiveFunctions( RiuSummaryVectorSelectionDialog* dialog );
|
||||
|
||||
}; // namespace RimObjectiveFunctionTools
|
@ -213,9 +213,6 @@ RimSummaryCaseCollection::RimSummaryCaseCollection()
|
||||
m_statisticsEclipseRftReader = new RifReaderEnsembleStatisticsRft( this );
|
||||
|
||||
m_commonAddressCount = 0;
|
||||
|
||||
m_objectiveFunctions.push_back( std::make_shared<RimObjectiveFunction>( this, RimObjectiveFunction::FunctionType::M1 ) );
|
||||
m_objectiveFunctions.push_back( std::make_shared<RimObjectiveFunction>( this, RimObjectiveFunction::FunctionType::M2 ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -865,30 +862,6 @@ void RimSummaryCaseCollection::clearEnsembleParametersHashes()
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<std::shared_ptr<RimObjectiveFunction>> RimSummaryCaseCollection::objectiveFunctions() const
|
||||
{
|
||||
return m_objectiveFunctions;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::shared_ptr<RimObjectiveFunction>
|
||||
RimSummaryCaseCollection::objectiveFunction( RimObjectiveFunction::FunctionType functionType )
|
||||
{
|
||||
for ( auto objectiveFunc : m_objectiveFunctions )
|
||||
{
|
||||
if ( objectiveFunc->functionType() == functionType )
|
||||
{
|
||||
return objectiveFunc;
|
||||
}
|
||||
}
|
||||
return m_objectiveFunctions.front();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -138,9 +138,6 @@ public:
|
||||
void calculateEnsembleParametersIntersectionHash();
|
||||
void clearEnsembleParametersHashes();
|
||||
|
||||
std::vector<std::shared_ptr<RimObjectiveFunction>> objectiveFunctions() const;
|
||||
std::shared_ptr<RimObjectiveFunction> objectiveFunction( RimObjectiveFunction::FunctionType functionType );
|
||||
|
||||
void loadDataAndUpdate();
|
||||
|
||||
static bool validateEnsembleCases( const std::vector<RimSummaryCase*> cases );
|
||||
@ -181,6 +178,4 @@ private:
|
||||
size_t m_commonAddressCount; // if different address count among cases, set to 0
|
||||
|
||||
mutable std::vector<EnsembleParameter> m_cachedSortedEnsembleParameters;
|
||||
|
||||
std::vector<std::shared_ptr<RimObjectiveFunction>> m_objectiveFunctions;
|
||||
};
|
||||
|
@ -186,6 +186,30 @@ void RiuSummaryVectorSelectionDialog::enableIndividualEnsembleCaseSelection( boo
|
||||
summaryAddressSelection()->enableIndividualEnsembleCaseSelection( enable );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuSummaryVectorSelectionDialog::hideHistoryVectors()
|
||||
{
|
||||
summaryAddressSelection()->hideHistoryVectors( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuSummaryVectorSelectionDialog::hideDifferenceVectors()
|
||||
{
|
||||
summaryAddressSelection()->hideDifferenceVectors( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuSummaryVectorSelectionDialog::hideVectorsWithNoHistory()
|
||||
{
|
||||
summaryAddressSelection()->hideVectorsWithoutHistory( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -52,6 +52,10 @@ public:
|
||||
void enableMultiSelect( bool enable );
|
||||
void enableIndividualEnsembleCaseSelection( bool enable );
|
||||
|
||||
void hideHistoryVectors();
|
||||
void hideDifferenceVectors();
|
||||
void hideVectorsWithNoHistory();
|
||||
|
||||
private:
|
||||
RiuSummaryVectorSelectionUi* summaryAddressSelection() const;
|
||||
void updateLabel();
|
||||
|
@ -23,6 +23,7 @@
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "RifReaderEclipseSummary.h"
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include "RimCalculatedSummaryCase.h"
|
||||
@ -383,6 +384,10 @@ RiuSummaryVectorSelectionUi::RiuSummaryVectorSelectionUi()
|
||||
m_hideEnsembles = false;
|
||||
m_hideSummaryCases = false;
|
||||
|
||||
m_hideDifferenceVectors = false;
|
||||
m_hideHistoryVectors = false;
|
||||
m_hideVectorsWithoutHistory = false;
|
||||
|
||||
m_prevCurveCount = 0;
|
||||
m_prevCurveSetCount = 0;
|
||||
}
|
||||
@ -566,6 +571,30 @@ void RiuSummaryVectorSelectionUi::enableIndividualEnsembleCaseSelection( bool en
|
||||
m_showIndividualEnsembleCases = enable;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuSummaryVectorSelectionUi::hideDifferenceVectors( bool hide )
|
||||
{
|
||||
m_hideDifferenceVectors = hide;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuSummaryVectorSelectionUi::hideHistoryVectors( bool hide )
|
||||
{
|
||||
m_hideHistoryVectors = hide;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RiuSummaryVectorSelectionUi::hideVectorsWithoutHistory( bool hide )
|
||||
{
|
||||
m_hideVectorsWithoutHistory = hide;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -1128,6 +1157,40 @@ std::set<RifEclipseSummaryAddress>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_hideHistoryVectors || m_hideDifferenceVectors )
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> filteredAddresses;
|
||||
|
||||
for ( const auto& adr : addrUnion )
|
||||
{
|
||||
if ( m_hideHistoryVectors && adr.isHistoryQuantity() ) continue;
|
||||
|
||||
if ( m_hideDifferenceVectors )
|
||||
{
|
||||
const auto diffText = RifReaderEclipseSummary::differenceIdentifier();
|
||||
if ( RiaStdStringTools::endsWith( adr.quantityName(), diffText ) ) continue;
|
||||
}
|
||||
|
||||
if ( m_hideVectorsWithoutHistory )
|
||||
{
|
||||
auto candidateName = adr.quantityName() + RifReaderEclipseSummary::historyIdentifier();
|
||||
|
||||
bool found = false;
|
||||
for ( const auto& ad : addrUnion )
|
||||
{
|
||||
if ( ad.quantityName() == candidateName ) found = true;
|
||||
}
|
||||
|
||||
if ( !found ) continue;
|
||||
}
|
||||
|
||||
filteredAddresses.insert( adr );
|
||||
}
|
||||
|
||||
addrUnion.swap( filteredAddresses );
|
||||
}
|
||||
|
||||
return addrUnion;
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,10 @@ public:
|
||||
void hideSummaryCases( bool hide );
|
||||
void enableIndividualEnsembleCaseSelection( bool enable );
|
||||
|
||||
void hideDifferenceVectors( bool hide );
|
||||
void hideHistoryVectors( bool hide );
|
||||
void hideVectorsWithoutHistory( bool hide );
|
||||
|
||||
void setFieldChangedHandler( const std::function<void()>& handlerFunc );
|
||||
|
||||
void setDefaultSelection( const std::vector<SummarySource*>& defaultCases );
|
||||
@ -129,6 +133,10 @@ private:
|
||||
bool m_hideSummaryCases;
|
||||
bool m_showIndividualEnsembleCases;
|
||||
|
||||
bool m_hideHistoryVectors;
|
||||
bool m_hideVectorsWithoutHistory;
|
||||
bool m_hideDifferenceVectors;
|
||||
|
||||
std::function<void()> m_toggleChangedHandler;
|
||||
|
||||
size_t m_prevCurveCount;
|
||||
|
Loading…
Reference in New Issue
Block a user