mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3096 Implemented ensemble calulations
This commit is contained in:
@@ -36,6 +36,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilter.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilterCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleStatistics.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleStatisticsCase.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCase.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCaseCollection.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
@@ -75,6 +77,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilter.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilterCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleStatistics.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleStatisticsCase.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCase.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimDerivedEnsembleCaseCollection.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
|
||||
@@ -86,7 +86,7 @@ void RifCalculatedSummaryCurveReader::buildMetaData()
|
||||
|
||||
for (RimSummaryCalculation* calc : m_calculationCollection->calculations())
|
||||
{
|
||||
m_allResultAddresses.push_back(RifEclipseSummaryAddress::calculatedAddress(calc->description().toStdString()));
|
||||
m_allResultAddresses.insert(RifEclipseSummaryAddress::calculatedAddress(calc->description().toStdString()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,220 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2016- 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 "RimDerivedEnsembleCase.h"
|
||||
|
||||
#include "RiaSummaryTools.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
#include "RifDerivedEnsembleReader.h"
|
||||
|
||||
#include "RimDerivedEnsembleCaseCollection.h"
|
||||
#include "RimMainPlotCollection.h"
|
||||
#include "RimOilField.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCaseMainCollection.h"
|
||||
#include "RimSummaryPlotCollection.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "cvfAssert.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
|
||||
CAF_PDM_ABSTRACT_SOURCE_INIT(RimDerivedEnsembleCase, "RimDerivedEnsembleCase");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
static const std::vector<time_t> EMPTY_TIME_STEPS_VECTOR;
|
||||
static const std::vector<double> EMPTY_VALUES_VECTOR;
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimDerivedEnsembleCase::RimDerivedEnsembleCase() : m_summaryCase1(nullptr), m_summaryCase2(nullptr)
|
||||
{
|
||||
CAF_PDM_InitObject("Summary Case",":/SummaryCase16x16.png","","");
|
||||
CAF_PDM_InitFieldNoDefault(&m_summaryCase1, "SummaryCase1", "SummaryCase1", "", "", "");
|
||||
CAF_PDM_InitFieldNoDefault(&m_summaryCase2, "SummaryCase2", "SummaryCase2", "", "", "");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCase::setInUse(bool inUse)
|
||||
{
|
||||
m_inUse = inUse;
|
||||
|
||||
if (!m_inUse)
|
||||
{
|
||||
m_summaryCase1 = nullptr;
|
||||
m_summaryCase2 = nullptr;
|
||||
m_data.clear();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimDerivedEnsembleCase::isInUse() const
|
||||
{
|
||||
return m_inUse;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCase::setSummaryCases(RimSummaryCase* sumCase1, RimSummaryCase* sumCase2)
|
||||
{
|
||||
if (!sumCase1 || !sumCase2) return;
|
||||
m_summaryCase1 = sumCase1;
|
||||
m_summaryCase2 = sumCase2;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimDerivedEnsembleCase::needsCalculation(const RifEclipseSummaryAddress& address) const
|
||||
{
|
||||
return m_data.count(address) == 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<time_t>& RimDerivedEnsembleCase::timeSteps(const RifEclipseSummaryAddress& address) const
|
||||
{
|
||||
if (m_data.count(address) == 0) return EMPTY_TIME_STEPS_VECTOR;
|
||||
return m_data.at(address).first;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
const std::vector<double>& RimDerivedEnsembleCase::values(const RifEclipseSummaryAddress& address) const
|
||||
{
|
||||
if (m_data.count(address) == 0) return EMPTY_VALUES_VECTOR;
|
||||
return m_data.at(address).second;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCase::calculate(const RifEclipseSummaryAddress& address)
|
||||
{
|
||||
clearData(address);
|
||||
|
||||
RifSummaryReaderInterface* reader1 = m_summaryCase1 ? m_summaryCase1->summaryReader() : nullptr;
|
||||
RifSummaryReaderInterface* reader2 = m_summaryCase2 ? m_summaryCase2->summaryReader() : nullptr;
|
||||
if (!reader1 || !reader2 || !parentEnsemble()) return;
|
||||
|
||||
RiaTimeHistoryCurveMerger merger;
|
||||
std::vector<double> values1;
|
||||
std::vector<double> values2;
|
||||
DerivedEnsembleOperator op = parentEnsemble()->op();
|
||||
|
||||
reader1->values(address, &values1);
|
||||
reader2->values(address, &values2);
|
||||
|
||||
merger.addCurveData(values1, reader1->timeSteps(address));
|
||||
merger.addCurveData(values2, reader2->timeSteps(address));
|
||||
merger.computeInterpolatedValues();
|
||||
|
||||
size_t sampleCount = merger.allTimeSteps().size();
|
||||
std::vector<double> calculatedValues;
|
||||
calculatedValues.reserve(sampleCount);
|
||||
for (size_t i = 0; i < sampleCount; i++)
|
||||
{
|
||||
if (op == DERIVED_ENSEMBLE_SUB)
|
||||
{
|
||||
calculatedValues.push_back(values1[i] - values2[i]);
|
||||
}
|
||||
else if (op == DERIVED_ENSEMBLE_ADD)
|
||||
{
|
||||
calculatedValues.push_back(values1[i] + values2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
auto& dataItem = m_data[address];
|
||||
dataItem.first = merger.allTimeSteps();
|
||||
dataItem.second = calculatedValues;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimDerivedEnsembleCase::caseName()
|
||||
{
|
||||
auto case1Name = m_summaryCase1->caseName();
|
||||
auto case2Name = m_summaryCase2->caseName();
|
||||
|
||||
if (case1Name == case2Name) return case1Name;
|
||||
else return QString("%1/%2").arg(case1Name).arg(case2Name);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCase::createSummaryReaderInterface()
|
||||
{
|
||||
m_reader.reset(new RifDerivedEnsembleReader(this));
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifSummaryReaderInterface* RimDerivedEnsembleCase::summaryReader()
|
||||
{
|
||||
return m_reader.get();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCase::updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath)
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimDerivedEnsembleCaseCollection * RimDerivedEnsembleCase::parentEnsemble() const
|
||||
{
|
||||
RimDerivedEnsembleCaseCollection* ensemble;
|
||||
firstAncestorOrThisOfType(ensemble);
|
||||
return ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<std::vector<time_t>, std::vector<double>> RimDerivedEnsembleCase::lookupCachedData(const RifEclipseSummaryAddress& address)
|
||||
{
|
||||
auto itr = m_data.find(address);
|
||||
if (itr == m_data.end()) return std::make_pair(std::vector<time_t>(), std::vector<double>());
|
||||
return itr->second;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCase::clearData(const RifEclipseSummaryAddress& address)
|
||||
{
|
||||
m_data.erase(address);
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2016 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
#pragma once
|
||||
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
class RifEclipseSummaryAddress;
|
||||
class RifSummaryReaderInterface;
|
||||
class RifDerivedEnsembleReader;
|
||||
class RimDerivedEnsembleCaseCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
enum DerivedEnsembleOperator
|
||||
{
|
||||
DERIVED_ENSEMBLE_SUB,
|
||||
DERIVED_ENSEMBLE_ADD
|
||||
};
|
||||
|
||||
//==================================================================================================
|
||||
//
|
||||
//==================================================================================================
|
||||
|
||||
class RimDerivedEnsembleCase : public RimSummaryCase
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
public:
|
||||
RimDerivedEnsembleCase();
|
||||
|
||||
void setInUse(bool inUse);
|
||||
bool isInUse() const;
|
||||
void setSummaryCases(RimSummaryCase* sumCase1, RimSummaryCase* sumCase2);
|
||||
bool needsCalculation(const RifEclipseSummaryAddress& address) const;
|
||||
const std::vector<time_t>& timeSteps(const RifEclipseSummaryAddress& address) const;
|
||||
const std::vector<double>& values(const RifEclipseSummaryAddress& address) const;
|
||||
|
||||
void calculate(const RifEclipseSummaryAddress& address);
|
||||
|
||||
virtual QString caseName() override;
|
||||
virtual void createSummaryReaderInterface() override;
|
||||
virtual RifSummaryReaderInterface* summaryReader() override;
|
||||
virtual void updateFilePathsFromProjectPath(const QString& newProjectPath, const QString& oldProjectPath) override;
|
||||
|
||||
RimDerivedEnsembleCaseCollection* parentEnsemble() const;
|
||||
|
||||
private:
|
||||
std::pair<std::vector<time_t>, std::vector<double>> lookupCachedData(const RifEclipseSummaryAddress& address);
|
||||
void clearData(const RifEclipseSummaryAddress& address);
|
||||
|
||||
std::unique_ptr<RifDerivedEnsembleReader> m_reader;
|
||||
|
||||
bool m_inUse;
|
||||
caf::PdmPtrField<RimSummaryCase*> m_summaryCase1;
|
||||
caf::PdmPtrField<RimSummaryCase*> m_summaryCase2;
|
||||
std::map<RifEclipseSummaryAddress, std::pair<std::vector<time_t>, std::vector<double>>> m_data;
|
||||
};
|
||||
@@ -0,0 +1,440 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// 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 "RiaApplication.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
#include "RimDerivedEnsembleCaseCollection.h"
|
||||
#include "RimDerivedEnsembleCase.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimSummaryCaseMainCollection.h"
|
||||
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include <cafPdmUiPushButtonEditor.h>
|
||||
|
||||
#include <cmath>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template<>
|
||||
void caf::AppEnum<DerivedEnsembleOperator>::setUp()
|
||||
{
|
||||
addItem(DERIVED_ENSEMBLE_SUB, "Sub", "-");
|
||||
addItem(DERIVED_ENSEMBLE_ADD, "Add", "+");
|
||||
setDefault(DERIVED_ENSEMBLE_SUB);
|
||||
}
|
||||
}
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimDerivedEnsembleCaseCollection, "RimDerivedEnsembleCaseCollection");
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimDerivedEnsembleCaseCollection::RimDerivedEnsembleCaseCollection()
|
||||
{
|
||||
CAF_PDM_InitObject("Derived Ensemble", ":/SummaryEnsemble16x16.png", "", "");
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_ensemble1, "Ensemble1", "Ensemble 1", "", "", "");
|
||||
m_ensemble1.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
m_ensemble1.uiCapability()->setAutoAddingOptionFromValue(false);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_ensemble2, "Ensemble2", "Ensemble 2", "", "", "");
|
||||
m_ensemble1.uiCapability()->setUiTreeChildrenHidden(true);
|
||||
m_ensemble2.uiCapability()->setAutoAddingOptionFromValue(false);
|
||||
|
||||
CAF_PDM_InitFieldNoDefault(&m_operator, "Operator", "Operator", "", "", "");
|
||||
|
||||
CAF_PDM_InitField(&m_swapEnsemblesButton, "SwapEnsembles", false, "SwapEnsembles", "", "", "");
|
||||
m_swapEnsemblesButton.uiCapability()->setUiEditorTypeName(caf::PdmUiPushButtonEditor::uiEditorTypeName());
|
||||
m_swapEnsemblesButton.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
||||
m_swapEnsemblesButton.xmlCapability()->disableIO();
|
||||
|
||||
CAF_PDM_InitField(&m_caseCount, "CaseCount", 0, "Number of Cases", "", "", "");
|
||||
m_caseCount.uiCapability()->setUiReadOnly(true);
|
||||
|
||||
// Do not show child cases
|
||||
uiCapability()->setUiTreeChildrenHidden(true);
|
||||
|
||||
// Do not store child cases to project file
|
||||
m_cases.xmlCapability()->disableIO();
|
||||
|
||||
setNameAsReadOnly();
|
||||
setName("Derived Ensemble");
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimDerivedEnsembleCaseCollection::~RimDerivedEnsembleCaseCollection()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::setEnsemble1(RimSummaryCaseCollection* ensemble)
|
||||
{
|
||||
m_ensemble1 = ensemble;
|
||||
updateAutoName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::setEnsemble2(RimSummaryCaseCollection* ensemble)
|
||||
{
|
||||
m_ensemble2 = ensemble;
|
||||
updateAutoName();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCase*> RimDerivedEnsembleCaseCollection::allSummaryCases() const
|
||||
{
|
||||
std::vector<RimSummaryCase*> cases;
|
||||
for (auto sumCase : allDerivedCases(true)) cases.push_back(sumCase);
|
||||
return cases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<RifEclipseSummaryAddress> RimDerivedEnsembleCaseCollection::calculateUnionOfSummaryAddresses() const
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> addresses;
|
||||
if (!m_ensemble1 || !m_ensemble2) return addresses;
|
||||
|
||||
addresses = m_ensemble1->calculateUnionOfSummaryAddresses();
|
||||
auto addrs2 = m_ensemble2->calculateUnionOfSummaryAddresses();
|
||||
addresses.insert(addrs2.begin(), addrs2.end());
|
||||
return addresses;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::updateDerivedEnsembleCases()
|
||||
{
|
||||
if (!m_ensemble1 || !m_ensemble2) return;
|
||||
|
||||
setAllCasesNotInUse();
|
||||
|
||||
const auto cases1 = m_ensemble1->allSummaryCases();
|
||||
const auto cases2 = m_ensemble2->allSummaryCases();
|
||||
|
||||
for (auto& sumCase1 : cases1)
|
||||
{
|
||||
auto crp = sumCase1->caseRealizationParameters();
|
||||
if (!crp) continue;
|
||||
|
||||
const auto& sumCase2 = findCaseByParametersHash(cases2, crp->parametersHash());
|
||||
if (!sumCase2) continue;
|
||||
|
||||
auto derivedCase = firstCaseNotInUse();
|
||||
derivedCase->createSummaryReaderInterface();
|
||||
derivedCase->setSummaryCases(sumCase1, sumCase2);
|
||||
derivedCase->setCaseRealizationParameters(crp);
|
||||
derivedCase->setInUse(true);
|
||||
}
|
||||
|
||||
// If other derived ensembles are referring to this ensemble, update their cases as well
|
||||
for (auto referring : findReferringEnsembles())
|
||||
{
|
||||
referring->updateDerivedEnsembleCases();
|
||||
}
|
||||
|
||||
deleteCasesNoInUse();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimDerivedEnsembleCaseCollection::hasCaseReference(const RimSummaryCase* sumCase) const
|
||||
{
|
||||
for (auto currCase : m_ensemble1->allSummaryCases())
|
||||
{
|
||||
if (currCase == sumCase) return true;
|
||||
}
|
||||
for (auto currCase : m_ensemble2->allSummaryCases())
|
||||
{
|
||||
if (currCase == sumCase) return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::onLoadDataAndUpdate()
|
||||
{
|
||||
updateDerivedEnsembleCases();
|
||||
updateReferringCurveSets();
|
||||
updateConnectedEditors();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo> RimDerivedEnsembleCaseCollection::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly)
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
|
||||
if (fieldNeedingOptions == &m_ensemble1 || fieldNeedingOptions == &m_ensemble2)
|
||||
{
|
||||
for (auto ensemble : allEnsembles())
|
||||
{
|
||||
if(ensemble != this) options.push_back(caf::PdmOptionItemInfo(ensemble->name(), ensemble));
|
||||
}
|
||||
}
|
||||
else if (fieldNeedingOptions == &m_caseCount)
|
||||
{
|
||||
m_caseCount = (int)m_cases.size();
|
||||
}
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
RimSummaryCaseCollection::defineUiOrdering(uiConfigName, uiOrdering);
|
||||
|
||||
uiOrdering.add(&m_caseCount);
|
||||
uiOrdering.add(&m_ensemble1);
|
||||
uiOrdering.add(&m_operator);
|
||||
uiOrdering.add(&m_ensemble2);
|
||||
uiOrdering.add(&m_swapEnsemblesButton);
|
||||
|
||||
uiOrdering.skipRemainingFields(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
||||
{
|
||||
bool doUpdate = false;
|
||||
bool doUpdateCases = false;
|
||||
bool doClearAllData = false;
|
||||
|
||||
if (changedField == &m_ensemble1 || changedField == &m_ensemble2)
|
||||
{
|
||||
doUpdate = true;
|
||||
doUpdateCases = true;
|
||||
}
|
||||
else if (changedField == &m_operator)
|
||||
{
|
||||
doUpdate = true;
|
||||
doUpdateCases = true;
|
||||
}
|
||||
else if (changedField == &m_swapEnsemblesButton)
|
||||
{
|
||||
m_swapEnsemblesButton = false;
|
||||
auto temp = m_ensemble1();
|
||||
m_ensemble1 = m_ensemble2();
|
||||
m_ensemble2 = temp;
|
||||
|
||||
doUpdate = true;
|
||||
doUpdateCases = true;
|
||||
}
|
||||
|
||||
if (doUpdate)
|
||||
{
|
||||
updateAutoName();
|
||||
//if (doClearAllData) clearAllData();
|
||||
|
||||
if (doUpdateCases)
|
||||
{
|
||||
updateDerivedEnsembleCases();
|
||||
updateConnectedEditors();
|
||||
}
|
||||
|
||||
updateReferringCurveSets();
|
||||
|
||||
// If other derived ensembles are referring to this ensemble, update their cases as well
|
||||
for (auto refering : findReferringEnsembles())
|
||||
{
|
||||
refering->updateReferringCurveSets();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
|
||||
{
|
||||
if (field == &m_swapEnsemblesButton)
|
||||
{
|
||||
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*>(attribute);
|
||||
if (attrib)
|
||||
{
|
||||
attrib->m_buttonText = "Swap Ensembles";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::setAllCasesNotInUse()
|
||||
{
|
||||
for (auto derCase : allDerivedCases(true)) derCase->setInUse(false);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::deleteCasesNoInUse()
|
||||
{
|
||||
std::vector<RimDerivedEnsembleCase*> inactiveCases;
|
||||
auto allCases = allDerivedCases(false);
|
||||
std::copy_if(allCases.begin(), allCases.end(), std::back_inserter(inactiveCases), [](RimDerivedEnsembleCase* derCase) { return !derCase->isInUse(); });
|
||||
|
||||
for (auto derCase : inactiveCases)
|
||||
{
|
||||
removeCase(derCase);
|
||||
delete derCase;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimDerivedEnsembleCase* RimDerivedEnsembleCaseCollection::firstCaseNotInUse()
|
||||
{
|
||||
auto allCases = allDerivedCases(false);
|
||||
auto itr = std::find_if(allCases.begin(), allCases.end(), [](RimDerivedEnsembleCase* derCase) { return !derCase->isInUse(); });
|
||||
if (itr != allCases.end())
|
||||
{
|
||||
return *itr;
|
||||
}
|
||||
|
||||
// If no active case was found, add a new case to the collection
|
||||
auto newCase = new RimDerivedEnsembleCase();
|
||||
m_cases.push_back(newCase);
|
||||
return newCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimDerivedEnsembleCase*> RimDerivedEnsembleCaseCollection::allDerivedCases(bool activeOnly) const
|
||||
{
|
||||
std::vector<RimDerivedEnsembleCase*> activeCases;
|
||||
for (auto sumCase : RimSummaryCaseCollection::allSummaryCases())
|
||||
{
|
||||
auto derivedCase = dynamic_cast<RimDerivedEnsembleCase*>(sumCase);
|
||||
if (derivedCase && (!activeOnly || derivedCase->isInUse()))
|
||||
{
|
||||
activeCases.push_back(derivedCase);
|
||||
}
|
||||
}
|
||||
return activeCases;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimDerivedEnsembleCaseCollection::updateAutoName()
|
||||
{
|
||||
QString op = caf::AppEnum<DerivedEnsembleOperator>::uiText(m_operator());
|
||||
|
||||
auto derivedEnsemble1 = dynamic_cast<RimDerivedEnsembleCaseCollection*>(m_ensemble1());
|
||||
auto derivedEnsemble2 = dynamic_cast<RimDerivedEnsembleCaseCollection*>(m_ensemble2());
|
||||
bool isDerived1 = derivedEnsemble1 != nullptr;
|
||||
bool isDerived2 = derivedEnsemble2 != nullptr;
|
||||
|
||||
QString name =
|
||||
(isDerived1 ? "(" : "") +
|
||||
(m_ensemble1 ? m_ensemble1->name() : "") +
|
||||
(isDerived1 ? ")" : "") +
|
||||
" " + op + " " +
|
||||
(isDerived2 ? "(" : "") +
|
||||
(m_ensemble2 ? m_ensemble2->name() : "") +
|
||||
(isDerived2 ? ")" : "");
|
||||
setName(name);
|
||||
|
||||
// If other derived ensembles are referring to this ensemble, update theirs name as well
|
||||
for (auto refering : findReferringEnsembles())
|
||||
{
|
||||
refering->updateAutoName();
|
||||
refering->updateConnectedEditors();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCase* RimDerivedEnsembleCaseCollection::findCaseByParametersHash(const std::vector<RimSummaryCase*>& cases, size_t hash) const
|
||||
{
|
||||
for (auto sumCase : cases)
|
||||
{
|
||||
auto ensembleParameters = sumCase->caseRealizationParameters();
|
||||
if (ensembleParameters && ensembleParameters->parametersHash() == hash) return sumCase;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimDerivedEnsembleCaseCollection*> RimDerivedEnsembleCaseCollection::findReferringEnsembles() const
|
||||
{
|
||||
std::vector<RimDerivedEnsembleCaseCollection*> referringEnsembles;
|
||||
RimSummaryCaseMainCollection* mainColl;
|
||||
|
||||
firstAncestorOrThisOfType(mainColl);
|
||||
if (mainColl)
|
||||
{
|
||||
for (auto group : mainColl->summaryCaseCollections())
|
||||
{
|
||||
auto derivedEnsemble = dynamic_cast<RimDerivedEnsembleCaseCollection*>(group);
|
||||
if (derivedEnsemble)
|
||||
{
|
||||
if (derivedEnsemble->m_ensemble1() == this || derivedEnsemble->m_ensemble2() == this)
|
||||
{
|
||||
referringEnsembles.push_back(derivedEnsemble);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return referringEnsembles;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimSummaryCaseCollection*> RimDerivedEnsembleCaseCollection::allEnsembles() const
|
||||
{
|
||||
std::vector<RimSummaryCaseCollection*> ensembles;
|
||||
|
||||
auto project = RiaApplication::instance()->project();
|
||||
|
||||
for (auto group : project->summaryGroups())
|
||||
{
|
||||
if (group->isEnsemble()) ensembles.push_back(group);
|
||||
}
|
||||
return ensembles;
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2016- 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.
|
||||
//
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
|
||||
#include "RimDerivedEnsembleCase.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmProxyValueField.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
class RimSummaryCase;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimDerivedEnsembleCaseCollection : public RimSummaryCaseCollection
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimDerivedEnsembleCaseCollection();
|
||||
virtual ~RimDerivedEnsembleCaseCollection();
|
||||
|
||||
RimSummaryCaseCollection* ensemble1() const { return m_ensemble1; }
|
||||
RimSummaryCaseCollection* ensemble2() const { return m_ensemble2; }
|
||||
DerivedEnsembleOperator op() const { return m_operator(); }
|
||||
|
||||
void setEnsemble1(RimSummaryCaseCollection* ensemble);
|
||||
void setEnsemble2(RimSummaryCaseCollection* ensemble);
|
||||
|
||||
virtual std::vector<RimSummaryCase*> allSummaryCases() const override;
|
||||
virtual std::set<RifEclipseSummaryAddress> calculateUnionOfSummaryAddresses() const override;
|
||||
void updateDerivedEnsembleCases();
|
||||
bool hasCaseReference(const RimSummaryCase* sumCase) const;
|
||||
|
||||
virtual void onLoadDataAndUpdate() override;
|
||||
|
||||
private:
|
||||
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute) override;
|
||||
|
||||
void setAllCasesNotInUse();
|
||||
void deleteCasesNoInUse();
|
||||
RimDerivedEnsembleCase* firstCaseNotInUse();
|
||||
std::vector<RimDerivedEnsembleCase*> allDerivedCases(bool activeOnly) const;
|
||||
void updateAutoName();
|
||||
RimSummaryCase* findCaseByParametersHash(const std::vector<RimSummaryCase*>& cases, size_t hash) const;
|
||||
std::vector<RimDerivedEnsembleCaseCollection*> findReferringEnsembles() const;
|
||||
|
||||
private:
|
||||
std::vector<RimSummaryCaseCollection*> allEnsembles() const;
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimSummaryCaseCollection*> m_ensemble1;
|
||||
caf::PdmPtrField<RimSummaryCaseCollection*> m_ensemble2;
|
||||
caf::PdmField<caf::AppEnum<DerivedEnsembleOperator>> m_operator;
|
||||
caf::PdmField<bool> m_swapEnsemblesButton;
|
||||
caf::PdmField<int> m_caseCount;
|
||||
};
|
||||
@@ -29,6 +29,7 @@
|
||||
#include "RigStatisticsMath.h"
|
||||
#include "RiaTimeHistoryCurveMerger.h"
|
||||
|
||||
#include "RimDerivedEnsembleCaseCollection.h"
|
||||
#include "RimEnsembleCurveFilter.h"
|
||||
#include "RimEnsembleCurveFilterCollection.h"
|
||||
#include "RimEnsembleCurveSetCollection.h"
|
||||
@@ -735,7 +736,7 @@ void RimEnsembleCurveSet::appendOptionItemsForSummaryAddresses(QList<caf::PdmOpt
|
||||
for (RimSummaryCase* summaryCase : summaryCaseGroup->allSummaryCases())
|
||||
{
|
||||
RifSummaryReaderInterface* reader = summaryCase->summaryReader();
|
||||
const std::vector<RifEclipseSummaryAddress>& addrs = reader ? reader->allResultAddresses() : std::vector<RifEclipseSummaryAddress>();
|
||||
const std::set<RifEclipseSummaryAddress>& addrs = reader ? reader->allResultAddresses() : std::set<RifEclipseSummaryAddress>();
|
||||
|
||||
for (auto& addr : addrs)
|
||||
{
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "RimDerivedEnsembleCaseCollection.h"
|
||||
#include "RimEnsembleCurveSet.h"
|
||||
#include "RimGridSummaryCase.h"
|
||||
#include "RimProject.h"
|
||||
@@ -68,13 +69,34 @@ void RimSummaryCaseCollection::removeCase(RimSummaryCase* summaryCase)
|
||||
updateReferringCurveSets();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::deleteAllCases()
|
||||
{
|
||||
m_cases.deleteAllChildObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::addCase(RimSummaryCase* summaryCase)
|
||||
void RimSummaryCaseCollection::addCase(RimSummaryCase* summaryCase, bool updateCurveSets)
|
||||
{
|
||||
m_cases.push_back(summaryCase);
|
||||
updateReferringCurveSets();
|
||||
|
||||
// Update derived ensemble cases (if any)
|
||||
std::vector<caf::PdmObjectHandle*> referringObjects;
|
||||
objectsWithReferringPtrFields(referringObjects);
|
||||
for (auto refObj : referringObjects)
|
||||
{
|
||||
auto derEnsemble = dynamic_cast<RimDerivedEnsembleCaseCollection*>(refObj);
|
||||
if (!derEnsemble) continue;
|
||||
|
||||
derEnsemble->updateDerivedEnsembleCases();
|
||||
if (updateCurveSets) derEnsemble->updateReferringCurveSets();
|
||||
}
|
||||
|
||||
if(updateCurveSets) updateReferringCurveSets();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -133,11 +155,9 @@ std::set<RifEclipseSummaryAddress> RimSummaryCaseCollection::calculateUnionOfSum
|
||||
|
||||
if ( !reader ) continue;
|
||||
|
||||
const std::vector<RifEclipseSummaryAddress>& readerAddresses = reader->allResultAddresses();
|
||||
const std::set<RifEclipseSummaryAddress>& readerAddresses = reader->allResultAddresses();
|
||||
addressUnion.insert(readerAddresses.begin(), readerAddresses.end());
|
||||
|
||||
}
|
||||
|
||||
return addressUnion;
|
||||
}
|
||||
|
||||
@@ -234,6 +254,14 @@ EnsembleParameter RimSummaryCaseCollection::ensembleParameter(const QString& par
|
||||
return eParam;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::loadDataAndUpdate()
|
||||
{
|
||||
onLoadDataAndUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -242,10 +270,18 @@ caf::PdmFieldHandle* RimSummaryCaseCollection::userDescriptionField()
|
||||
return &m_name;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::onLoadDataAndUpdate()
|
||||
{
|
||||
// NOP
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::updateReferringCurveSets() const
|
||||
void RimSummaryCaseCollection::updateReferringCurveSets()
|
||||
{
|
||||
// Update curve set referring to this group
|
||||
std::vector<PdmObjectHandle*> referringObjects;
|
||||
@@ -299,3 +335,20 @@ void RimSummaryCaseCollection::fieldChangedByUi(const caf::PdmFieldHandle* chang
|
||||
updateIcon();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
||||
{
|
||||
uiOrdering.add(&m_name);
|
||||
uiOrdering.skipRemainingFields(true);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::setNameAsReadOnly()
|
||||
{
|
||||
m_name.uiCapability()->setUiReadOnly(true);
|
||||
}
|
||||
|
||||
@@ -65,26 +65,35 @@ public:
|
||||
virtual ~RimSummaryCaseCollection();
|
||||
|
||||
void removeCase(RimSummaryCase* summaryCase);
|
||||
void addCase(RimSummaryCase* summaryCase);
|
||||
std::vector<RimSummaryCase*> allSummaryCases() const;
|
||||
void deleteAllCases();
|
||||
void addCase(RimSummaryCase* summaryCase, bool updateCurveSets = true);
|
||||
virtual std::vector<RimSummaryCase*> allSummaryCases() const;
|
||||
void setName(const QString& name);
|
||||
QString name() const;
|
||||
bool isEnsemble() const;
|
||||
void setAsEnsemble(bool isEnsemble);
|
||||
std::set<RifEclipseSummaryAddress> calculateUnionOfSummaryAddresses() const;
|
||||
virtual std::set<RifEclipseSummaryAddress> calculateUnionOfSummaryAddresses() const;
|
||||
EnsembleParameter ensembleParameter(const QString& paramName) const;
|
||||
|
||||
void loadDataAndUpdate();
|
||||
|
||||
private:
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
void updateReferringCurveSets() const;
|
||||
QString nameAndItemCount() const;
|
||||
void updateIcon();
|
||||
|
||||
virtual void initAfterRead() override;
|
||||
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
|
||||
|
||||
private:
|
||||
protected:
|
||||
virtual void onLoadDataAndUpdate();
|
||||
void updateReferringCurveSets();
|
||||
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
|
||||
void setNameAsReadOnly();
|
||||
|
||||
caf::PdmChildArrayField<RimSummaryCase*> m_cases;
|
||||
|
||||
private:
|
||||
caf::PdmField<QString> m_name;
|
||||
caf::PdmProxyValueField<QString> m_nameAndItemCount;
|
||||
caf::PdmField<bool> m_isEnsemble;
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "RifSummaryCaseRestartSelector.h"
|
||||
#include "RifCaseRealizationParametersReader.h"
|
||||
|
||||
#include "RimDerivedEnsembleCaseCollection.h"
|
||||
#include "RimEclipseResultCase.h"
|
||||
#include "RimFileSummaryCase.h"
|
||||
#include "RimGridSummaryCase.h"
|
||||
@@ -201,19 +202,43 @@ void RimSummaryCaseMainCollection::addCase(RimSummaryCase* summaryCase)
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseMainCollection::removeCase(RimSummaryCase* summaryCase)
|
||||
{
|
||||
std::vector<RimDerivedEnsembleCaseCollection*> derivedEnsembles;
|
||||
|
||||
// Build a list of derived ensembles that must be updated after delete
|
||||
for (auto group : summaryCaseCollections())
|
||||
{
|
||||
auto derEnsemble = dynamic_cast<RimDerivedEnsembleCaseCollection*>(group);
|
||||
if (derEnsemble)
|
||||
{
|
||||
if (derEnsemble->hasCaseReference(summaryCase))
|
||||
{
|
||||
derivedEnsembles.push_back(derEnsemble);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_cases.removeChildObject(summaryCase);
|
||||
for (RimSummaryCaseCollection* summaryCaseCollection : m_caseCollections)
|
||||
{
|
||||
summaryCaseCollection->removeCase(summaryCase);
|
||||
}
|
||||
|
||||
// Update derived ensemble cases (if any)
|
||||
for (auto derEnsemble : derivedEnsembles)
|
||||
{
|
||||
derEnsemble->updateDerivedEnsembleCases();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseMainCollection::addCaseCollection(std::vector<RimSummaryCase*> summaryCases, const QString& collectionName, bool isEnsemble)
|
||||
RimSummaryCaseCollection* RimSummaryCaseMainCollection::addCaseCollection(std::vector<RimSummaryCase*> summaryCases,
|
||||
const QString& collectionName,
|
||||
bool isEnsemble,
|
||||
std::function<RimSummaryCaseCollection* ()> allocator)
|
||||
{
|
||||
RimSummaryCaseCollection* summaryCaseCollection = new RimSummaryCaseCollection();
|
||||
RimSummaryCaseCollection* summaryCaseCollection = allocator();
|
||||
if(!collectionName.isEmpty()) summaryCaseCollection->setName(collectionName);
|
||||
summaryCaseCollection->setAsEnsemble(isEnsemble);
|
||||
|
||||
@@ -235,6 +260,8 @@ void RimSummaryCaseMainCollection::addCaseCollection(std::vector<RimSummaryCase*
|
||||
}
|
||||
|
||||
m_caseCollections.push_back(summaryCaseCollection);
|
||||
|
||||
return summaryCaseCollection;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@@ -330,6 +357,14 @@ void RimSummaryCaseMainCollection::loadSummaryCaseData(std::vector<RimSummaryCas
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCaseCollection* RimSummaryCaseMainCollection::defaultAllocator()
|
||||
{
|
||||
return new RimSummaryCaseCollection();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
||||
@@ -21,6 +21,7 @@
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
class RimGridSummaryCase;
|
||||
class RimSummaryCase;
|
||||
@@ -56,7 +57,10 @@ public:
|
||||
void addCase(RimSummaryCase* summaryCase);
|
||||
void removeCase(RimSummaryCase* summaryCase);
|
||||
|
||||
void addCaseCollection(std::vector<RimSummaryCase*> summaryCases, const QString& coolectionName, bool isEnsemble);
|
||||
RimSummaryCaseCollection* addCaseCollection(std::vector<RimSummaryCase*> summaryCases,
|
||||
const QString& coolectionName,
|
||||
bool isEnsemble,
|
||||
std::function<RimSummaryCaseCollection* ()> allocator = defaultAllocator);
|
||||
void removeCaseCollection(RimSummaryCaseCollection* caseCollection);
|
||||
|
||||
void loadAllSummaryCaseData();
|
||||
@@ -67,6 +71,7 @@ public:
|
||||
|
||||
private:
|
||||
static void loadSummaryCaseData(std::vector<RimSummaryCase*> summaryCases);
|
||||
static RimSummaryCaseCollection* defaultAllocator();
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimSummaryCase*> m_cases;
|
||||
|
||||
@@ -593,7 +593,7 @@ void RimSummaryCurve::appendOptionItemsForSummaryAddresses(QList<caf::PdmOptionI
|
||||
RifSummaryReaderInterface* reader = summaryCase->summaryReader();
|
||||
if (reader)
|
||||
{
|
||||
const std::vector<RifEclipseSummaryAddress> allAddresses = reader->allResultAddresses();
|
||||
const std::set<RifEclipseSummaryAddress> allAddresses = reader->allResultAddresses();
|
||||
|
||||
for (auto& address : allAddresses)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user