Files
ResInsight/ApplicationLibCode/ProjectDataModel/Summary/RimDeltaSummaryEnsemble.cpp
T

609 lines
22 KiB
C++
Raw Normal View History

2018-06-25 15:14:47 +02:00
/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2017- Statoil 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 "RiaQDateTimeTools.h"
2018-06-25 15:14:47 +02:00
#include "Summary/RiaSummaryTools.h"
#include "SummaryPlotCommands/RicNewDerivedEnsembleFeature.h"
#include "RifSummaryReaderInterface.h"
2024-11-13 11:26:06 +01:00
#include "RimDeltaSummaryCase.h"
#include "RimDeltaSummaryEnsemble.h"
2018-06-25 15:14:47 +02:00
#include "RimProject.h"
#include "RimSummaryCaseMainCollection.h"
#include "RimSummaryEnsemble.h"
2018-06-25 15:14:47 +02:00
#include "cafPdmUiCheckBoxEditor.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTreeSelectionEditor.h"
2018-06-25 15:14:47 +02:00
#include <QDateTime>
2018-06-25 15:14:47 +02:00
#include <cmath>
namespace caf
{
template <>
2024-11-13 11:26:06 +01:00
void caf::AppEnum<RimDeltaSummaryEnsemble::FixedTimeStepMode>::setUp()
{
2024-11-13 11:26:06 +01:00
addItem( RimDeltaSummaryEnsemble::FixedTimeStepMode::FIXED_TIME_STEP_NONE, "FIXED_TIME_STEP_NONE", "None" );
addItem( RimDeltaSummaryEnsemble::FixedTimeStepMode::FIXED_TIME_STEP_CASE_1, "FIXED_TIME_STEP_CASE_1", "Ensemble 1" );
addItem( RimDeltaSummaryEnsemble::FixedTimeStepMode::FIXED_TIME_STEP_CASE_2, "FIXED_TIME_STEP_CASE_2", "Ensemble 2" );
setDefault( RimDeltaSummaryEnsemble::FixedTimeStepMode::FIXED_TIME_STEP_NONE );
}
} // namespace caf
2024-11-13 11:26:06 +01:00
CAF_PDM_SOURCE_INIT( RimDeltaSummaryEnsemble, "RimDeltaSummaryEnsemble", "RimDerivedEnsembleCaseCollection" );
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
RimDeltaSummaryEnsemble::RimDeltaSummaryEnsemble()
2018-06-25 15:14:47 +02:00
{
CAF_PDM_InitObject( "Delta Ensemble", ":/SummaryEnsemble.svg" );
2018-06-25 15:14:47 +02:00
CAF_PDM_InitFieldNoDefault( &m_ensemble1, "Ensemble1", "Ensemble 1" );
m_ensemble1.uiCapability()->setUiTreeChildrenHidden( true );
m_ensemble1.uiCapability()->setAutoAddingOptionFromValue( false );
2018-06-25 15:14:47 +02:00
CAF_PDM_InitFieldNoDefault( &m_ensemble2, "Ensemble2", "Ensemble 2" );
m_ensemble1.uiCapability()->setUiTreeChildrenHidden( true );
m_ensemble2.uiCapability()->setAutoAddingOptionFromValue( false );
2018-06-25 15:14:47 +02:00
CAF_PDM_InitFieldNoDefault( &m_operator, "Operator", "Operator" );
2018-06-25 15:14:47 +02:00
CAF_PDM_InitField( &m_swapEnsemblesButton, "SwapEnsembles", false, "SwapEnsembles" );
caf::PdmUiPushButtonEditor::configureEditorLabelHidden( &m_swapEnsemblesButton );
2018-06-25 15:14:47 +02:00
CAF_PDM_InitField( &m_caseCount, "CaseCount", QString( "" ), "Matching Cases" );
m_caseCount.uiCapability()->setUiReadOnly( true );
2018-06-25 15:14:47 +02:00
CAF_PDM_InitField( &m_matchOnParameters, "MatchOnParameters", false, "Match On Parameters" );
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_matchOnParameters );
CAF_PDM_InitField( &m_discardMissingOrIncompleteRealizations,
"DiscardMissingOrIncompleteRealizations",
true,
"Discard Missing or Incomplete Realizations" );
caf::PdmUiNativeCheckBoxEditor::configureFieldForEditor( &m_discardMissingOrIncompleteRealizations );
CAF_PDM_InitFieldNoDefault( &m_useFixedTimeStep, "UseFixedTimeStep", "Use Fixed Time Step" );
CAF_PDM_InitField( &m_fixedTimeStepIndex, "FixedTimeStepIndex", 0, "Time Step" );
m_fixedTimeStepIndex.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
m_fixedTimeStepIndex.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
setNameTemplate( "Delta Ensemble" );
2020-05-18 16:02:27 +02:00
setAsEnsemble( true );
2020-05-18 16:02:27 +02:00
setDeletable( true );
2018-06-25 15:14:47 +02:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
RimDeltaSummaryEnsemble::~RimDeltaSummaryEnsemble()
{
}
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::setEnsemble1( RimSummaryEnsemble* ensemble )
2018-06-25 15:14:47 +02:00
{
m_ensemble1 = ensemble;
RiaSummaryTools::updateSummaryEnsembleNames();
2018-06-25 15:14:47 +02:00
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::setEnsemble2( RimSummaryEnsemble* ensemble )
2018-06-25 15:14:47 +02:00
{
m_ensemble2 = ensemble;
RiaSummaryTools::updateSummaryEnsembleNames();
2018-06-25 15:14:47 +02:00
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
std::vector<RimSummaryCase*> RimDeltaSummaryEnsemble::allSummaryCases() const
2018-06-25 15:14:47 +02:00
{
std::vector<RimSummaryCase*> cases;
for ( auto sumCase : allDerivedCases( true ) )
cases.push_back( sumCase );
2018-06-25 15:14:47 +02:00
return cases;
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
std::set<RifEclipseSummaryAddress> RimDeltaSummaryEnsemble::ensembleSummaryAddresses() const
2018-06-25 15:14:47 +02:00
{
std::set<RifEclipseSummaryAddress> addresses;
if ( !m_ensemble1 || !m_ensemble2 ) return addresses;
2018-06-25 15:14:47 +02:00
addresses = m_ensemble1->ensembleSummaryAddresses();
auto addrs2 = m_ensemble2->ensembleSummaryAddresses();
addresses.insert( addrs2.begin(), addrs2.end() );
2018-06-25 15:14:47 +02:00
return addresses;
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::createDerivedEnsembleCases()
2018-06-25 15:14:47 +02:00
{
if ( !m_ensemble1 || !m_ensemble2 ) return;
2018-06-25 15:14:47 +02:00
setAllCasesNotInUse();
const auto cases1 = m_ensemble1->allSummaryCases();
const auto cases2 = m_ensemble2->allSummaryCases();
for ( auto& sumCase1 : cases1 )
2018-06-25 15:14:47 +02:00
{
auto crp = sumCase1->caseRealizationParameters();
if ( !crp ) continue;
2018-06-25 15:14:47 +02:00
RimSummaryCase* summaryCase2 = nullptr;
if ( m_matchOnParameters )
{
summaryCase2 = findCaseByParametersHash( cases2, crp->parametersHash() );
}
else
{
summaryCase2 = findCaseByRealizationNumber( cases2, crp->realizationNumber() );
}
if ( !summaryCase2 ) continue;
2018-06-25 15:14:47 +02:00
auto derivedCase = firstCaseNotInUse();
derivedCase->setSummaryCases( sumCase1, summaryCase2 );
2020-02-10 07:13:04 +01:00
derivedCase->setOperator( m_operator() );
int fixedTimeStepCase1 = -1;
int fixedTimeStepCase2 = -1;
if ( m_useFixedTimeStep == FixedTimeStepMode::FIXED_TIME_STEP_CASE_1 )
{
fixedTimeStepCase1 = m_fixedTimeStepIndex;
}
else if ( m_useFixedTimeStep == FixedTimeStepMode::FIXED_TIME_STEP_CASE_2 )
{
fixedTimeStepCase2 = m_fixedTimeStepIndex;
}
derivedCase->setFixedTimeSteps( fixedTimeStepCase1, fixedTimeStepCase2 );
derivedCase->createSummaryReaderInterface();
derivedCase->setCaseRealizationParameters( crp );
derivedCase->setInUse( true );
derivedCase->updateDisplayNameFromCases();
2018-06-25 15:14:47 +02:00
}
// If other derived ensembles are referring to this ensemble, update their cases as well
for ( auto referring : findReferringEnsembles() )
2018-06-25 15:14:47 +02:00
{
referring->createDerivedEnsembleCases();
2018-06-25 15:14:47 +02:00
}
deleteCasesNoInUse();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimDeltaSummaryEnsemble::discardMissingOrIncompleteRealizations() const
{
return m_discardMissingOrIncompleteRealizations();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::pair<std::string, std::string> RimDeltaSummaryEnsemble::nameKeys() const
{
QString nameCase1 = "None";
if ( m_ensemble1 )
{
nameCase1 = m_ensemble1->name();
}
QString nameCase2 = "None";
if ( m_ensemble2 )
{
nameCase2 = m_ensemble2->name();
}
return std::make_pair( nameCase1.toStdString(), nameCase2.toStdString() );
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimDeltaSummaryEnsemble::nameTemplateText() const
{
return "Delta: " + RiaDefines::key1VariableName() + " - " + RiaDefines::key2VariableName();
}
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
bool RimDeltaSummaryEnsemble::hasCaseReference( const RimSummaryCase* sumCase ) const
2018-06-25 15:14:47 +02:00
{
2020-12-10 10:44:23 +01:00
if ( m_ensemble1 )
2018-06-25 15:14:47 +02:00
{
2020-12-10 10:44:23 +01:00
for ( auto currCase : m_ensemble1->allSummaryCases() )
{
if ( currCase == sumCase ) return true;
}
2018-06-25 15:14:47 +02:00
}
2020-12-10 10:44:23 +01:00
if ( m_ensemble2 )
2018-06-25 15:14:47 +02:00
{
2020-12-10 10:44:23 +01:00
for ( auto currCase : m_ensemble2->allSummaryCases() )
{
if ( currCase == sumCase ) return true;
}
2018-06-25 15:14:47 +02:00
}
2020-12-10 10:44:23 +01:00
2018-06-25 15:14:47 +02:00
return false;
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::onLoadDataAndUpdate()
2018-06-25 15:14:47 +02:00
{
updateDerivedEnsembleCases();
updateReferringCurveSets();
updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
QList<caf::PdmOptionItemInfo> RimDeltaSummaryEnsemble::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions )
2018-06-25 15:14:47 +02:00
{
QList<caf::PdmOptionItemInfo> options;
if ( fieldNeedingOptions == &m_ensemble1 || fieldNeedingOptions == &m_ensemble2 )
2018-06-25 15:14:47 +02:00
{
for ( auto ensemble : allEnsembles() )
2018-06-25 15:14:47 +02:00
{
if ( ensemble != this ) options.push_back( caf::PdmOptionItemInfo( ensemble->name(), ensemble ) );
2018-06-25 15:14:47 +02:00
}
}
else if ( fieldNeedingOptions == &m_caseCount )
2018-06-25 15:14:47 +02:00
{
size_t caseCount1 = m_ensemble1 ? m_ensemble1->allSummaryCases().size() : 0;
size_t caseCount2 = m_ensemble2 ? m_ensemble2->allSummaryCases().size() : 0;
m_caseCount = QString( "%1 / %2" ).arg( (int)m_cases.size() ).arg( std::max( caseCount1, caseCount2 ) );
2018-06-25 15:14:47 +02:00
}
if ( fieldNeedingOptions == &m_fixedTimeStepIndex )
{
RimSummaryEnsemble* sourceEnsemble = nullptr;
if ( m_useFixedTimeStep() == FixedTimeStepMode::FIXED_TIME_STEP_CASE_1 )
{
sourceEnsemble = m_ensemble1;
}
else if ( m_useFixedTimeStep() == FixedTimeStepMode::FIXED_TIME_STEP_CASE_2 )
{
sourceEnsemble = m_ensemble2;
}
if ( sourceEnsemble && !sourceEnsemble->allSummaryCases().empty() )
{
auto firstCase = sourceEnsemble->allSummaryCases().front();
auto summaryReader = firstCase->summaryReader();
const std::vector<time_t>& timeSteps = summaryReader->timeSteps( RifEclipseSummaryAddress() );
options = RiaQDateTimeTools::createOptionItems( timeSteps );
}
}
2018-06-25 15:14:47 +02:00
return options;
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
2018-06-25 15:14:47 +02:00
{
auto nameGroup = uiOrdering.addNewGroup( "Name" );
RimSummaryEnsemble::defineUiOrdering( uiConfigName, *nameGroup );
2018-06-25 15:14:47 +02:00
auto caseGroup = uiOrdering.addNewGroup( "Delta Configuration" );
caseGroup->add( &m_caseCount );
caseGroup->add( &m_ensemble1 );
caseGroup->add( &m_operator );
caseGroup->add( &m_ensemble2 );
caseGroup->add( &m_swapEnsemblesButton );
2018-06-25 15:14:47 +02:00
caseGroup->add( &m_useFixedTimeStep );
2024-11-13 11:26:06 +01:00
if ( m_useFixedTimeStep() != RimDeltaSummaryEnsemble::FixedTimeStepMode::FIXED_TIME_STEP_NONE )
{
caseGroup->add( &m_fixedTimeStepIndex );
}
caseGroup->add( &m_matchOnParameters );
caseGroup->add( &m_discardMissingOrIncompleteRealizations );
uiOrdering.skipRemainingFields( true );
if ( !isValid() ) m_caseCount = "";
2018-06-25 15:14:47 +02:00
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue )
2018-06-25 15:14:47 +02:00
{
bool doUpdate = false;
2018-06-25 15:14:47 +02:00
bool doUpdateCases = false;
bool doShowDialog = false;
2018-06-25 15:14:47 +02:00
if ( changedField == &m_ensemble1 || changedField == &m_ensemble2 || changedField == &m_matchOnParameters )
2018-06-25 15:14:47 +02:00
{
doUpdate = true;
2018-06-25 15:14:47 +02:00
doUpdateCases = true;
doShowDialog = true;
2018-06-25 15:14:47 +02:00
}
else if ( changedField == &m_operator || changedField == &m_useFixedTimeStep || changedField == &m_fixedTimeStepIndex ||
changedField == &m_discardMissingOrIncompleteRealizations )
2018-06-25 15:14:47 +02:00
{
doUpdate = true;
2018-06-25 15:14:47 +02:00
doUpdateCases = true;
doShowDialog = false;
2018-06-25 15:14:47 +02:00
}
else if ( changedField == &m_swapEnsemblesButton )
2018-06-25 15:14:47 +02:00
{
m_swapEnsemblesButton = false;
auto temp = m_ensemble1();
m_ensemble1 = m_ensemble2();
m_ensemble2 = temp;
2018-06-25 15:14:47 +02:00
doUpdate = true;
2018-06-25 15:14:47 +02:00
doUpdateCases = true;
doShowDialog = false;
2018-06-25 15:14:47 +02:00
}
if ( doUpdate )
2018-06-25 15:14:47 +02:00
{
RiaSummaryTools::updateSummaryEnsembleNames();
2018-06-25 15:14:47 +02:00
if ( doUpdateCases )
2018-06-25 15:14:47 +02:00
{
createDerivedEnsembleCases();
2018-06-25 15:14:47 +02:00
updateConnectedEditors();
if ( doShowDialog && m_ensemble1 != nullptr && m_ensemble2 != nullptr && allSummaryCases().empty() )
{
RicNewDerivedEnsembleFeature::showWarningDialog();
}
2018-06-25 15:14:47 +02:00
}
updateReferringCurveSetsZoomAll();
2018-06-25 15:14:47 +02:00
// If other derived ensembles are referring to this ensemble, update their cases as well
for ( auto refering : findReferringEnsembles() )
2018-06-25 15:14:47 +02:00
{
refering->updateReferringCurveSetsZoomAll();
2018-06-25 15:14:47 +02:00
}
}
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::defineEditorAttribute( const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute )
2018-06-25 15:14:47 +02:00
{
if ( field == &m_swapEnsemblesButton )
2018-06-25 15:14:47 +02:00
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>( attribute );
if ( attrib )
2018-06-25 15:14:47 +02:00
{
attrib->m_buttonText = "Swap Ensembles";
}
}
if ( &m_fixedTimeStepIndex == field )
{
auto a = dynamic_cast<caf::PdmUiTreeSelectionEditorAttribute*>( attribute );
if ( a )
{
a->singleSelectionMode = true;
a->showTextFilter = true;
}
}
2018-06-25 15:14:47 +02:00
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::setAllCasesNotInUse()
2018-06-25 15:14:47 +02:00
{
for ( auto derCase : allDerivedCases( true ) )
derCase->setInUse( false );
2018-06-25 15:14:47 +02:00
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::deleteCasesNoInUse()
2018-06-25 15:14:47 +02:00
{
2024-11-13 11:26:06 +01:00
std::vector<RimDeltaSummaryCase*> inactiveCases;
auto allCases = allDerivedCases( false );
2023-04-13 07:05:53 +02:00
std::copy_if( allCases.begin(),
allCases.end(),
std::back_inserter( inactiveCases ),
2024-11-13 11:26:06 +01:00
[]( RimDeltaSummaryCase* derCase ) { return !derCase->isInUse(); } );
2018-06-25 15:14:47 +02:00
for ( auto derCase : inactiveCases )
2018-06-25 15:14:47 +02:00
{
removeCase( derCase );
2018-06-25 15:14:47 +02:00
delete derCase;
}
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
RimDeltaSummaryCase* RimDeltaSummaryEnsemble::firstCaseNotInUse()
2018-06-25 15:14:47 +02:00
{
auto allCases = allDerivedCases( false );
2024-11-13 11:26:06 +01:00
auto itr = std::find_if( allCases.begin(), allCases.end(), []( RimDeltaSummaryCase* derCase ) { return !derCase->isInUse(); } );
if ( itr != allCases.end() )
2018-06-25 15:14:47 +02:00
{
return *itr;
}
// If no active case was found, add a new case to the collection
2024-11-13 11:26:06 +01:00
auto newCase = new RimDeltaSummaryCase();
2024-07-05 09:06:16 +02:00
// Show realization data source for the first case. If we create for all, the performance will be bad
newCase->setShowVectorItemsInProjectTree( m_cases.empty() );
m_cases.push_back( newCase );
2018-06-25 15:14:47 +02:00
return newCase;
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
std::vector<RimDeltaSummaryCase*> RimDeltaSummaryEnsemble::allDerivedCases( bool activeOnly ) const
2018-06-25 15:14:47 +02:00
{
2024-11-13 11:26:06 +01:00
std::vector<RimDeltaSummaryCase*> activeCases;
for ( auto sumCase : RimSummaryEnsemble::allSummaryCases() )
2018-06-25 15:14:47 +02:00
{
2024-11-13 11:26:06 +01:00
auto derivedCase = dynamic_cast<RimDeltaSummaryCase*>( sumCase );
if ( derivedCase && ( !activeOnly || derivedCase->isInUse() ) )
2018-06-25 15:14:47 +02:00
{
activeCases.push_back( derivedCase );
2018-06-25 15:14:47 +02:00
}
}
return activeCases;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
void RimDeltaSummaryEnsemble::updateDerivedEnsembleCases()
{
for ( auto& derivedCase : allDerivedCases( true ) )
{
derivedCase->createSummaryReaderInterface();
auto crp = derivedCase->summaryCase1()->caseRealizationParameters();
if ( !crp ) continue;
derivedCase->setCaseRealizationParameters( crp );
}
// If other derived ensembles are referring to this ensemble, update their cases as well
for ( auto referring : findReferringEnsembles() )
{
referring->updateDerivedEnsembleCases();
}
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
bool RimDeltaSummaryEnsemble::isValid() const
{
return m_ensemble1 != nullptr && m_ensemble2 != nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimSummaryCase* RimDeltaSummaryEnsemble::findCaseByParametersHash( const std::vector<RimSummaryCase*>& cases, size_t hash )
2018-06-25 15:14:47 +02:00
{
for ( auto sumCase : cases )
2018-06-25 15:14:47 +02:00
{
auto ensembleParameters = sumCase->caseRealizationParameters();
if ( ensembleParameters && ensembleParameters->parametersHash() == hash ) return sumCase;
2018-06-25 15:14:47 +02:00
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
RimSummaryCase* RimDeltaSummaryEnsemble::findCaseByRealizationNumber( const std::vector<RimSummaryCase*>& cases, int realizationNumber )
{
for ( auto sumCase : cases )
{
auto ensembleParameters = sumCase->caseRealizationParameters();
if ( ensembleParameters && ensembleParameters->realizationNumber() == realizationNumber ) return sumCase;
}
return nullptr;
}
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
std::vector<RimDeltaSummaryEnsemble*> RimDeltaSummaryEnsemble::findReferringEnsembles() const
2018-06-25 15:14:47 +02:00
{
2024-11-13 11:26:06 +01:00
std::vector<RimDeltaSummaryEnsemble*> referringEnsembles;
2018-06-25 15:14:47 +02:00
auto mainColl = firstAncestorOrThisOfType<RimSummaryCaseMainCollection>();
if ( mainColl )
2018-06-25 15:14:47 +02:00
{
for ( auto ensemble : mainColl->summaryEnsembles() )
2018-06-25 15:14:47 +02:00
{
auto derivedEnsemble = dynamic_cast<RimDeltaSummaryEnsemble*>( ensemble );
if ( derivedEnsemble )
2018-06-25 15:14:47 +02:00
{
if ( derivedEnsemble->m_ensemble1() == this || derivedEnsemble->m_ensemble2() == this )
2018-06-25 15:14:47 +02:00
{
referringEnsembles.push_back( derivedEnsemble );
2018-06-25 15:14:47 +02:00
}
}
}
}
return referringEnsembles;
}
//--------------------------------------------------------------------------------------------------
///
2018-06-25 15:14:47 +02:00
//--------------------------------------------------------------------------------------------------
2024-11-13 11:26:06 +01:00
std::vector<RimSummaryEnsemble*> RimDeltaSummaryEnsemble::allEnsembles() const
2018-06-25 15:14:47 +02:00
{
std::vector<RimSummaryEnsemble*> ensembles;
2018-06-25 15:14:47 +02:00
auto project = RimProject::current();
2018-06-25 15:14:47 +02:00
2025-04-25 11:06:02 +02:00
for ( auto ensemble : project->summaryEnsembles() )
2018-06-25 15:14:47 +02:00
{
2025-04-25 11:06:02 +02:00
if ( ensemble == this ) continue;
2025-04-25 11:06:02 +02:00
if ( !ensemble->isEnsemble() ) continue;
2025-04-25 11:06:02 +02:00
auto derivedEnsemble = dynamic_cast<const RimDeltaSummaryEnsemble*>( ensemble );
if ( derivedEnsemble && !derivedEnsemble->isValid() ) continue;
2025-04-25 11:06:02 +02:00
ensembles.push_back( ensemble );
2018-06-25 15:14:47 +02:00
}
return ensembles;
}