mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
#3106 Ensemble calculations. Hash only ensemble parameters common to all cases. Move cases validation
This commit is contained in:
parent
224f379ea6
commit
cc87da2ae0
@ -76,7 +76,6 @@ void RicConvertGroupToEnsembleFeature::onActionTriggered(bool isChecked)
|
||||
{
|
||||
if (group->isEnsemble()) continue;
|
||||
|
||||
RicImportEnsembleFeature::validateEnsembleCases(group->allSummaryCases());
|
||||
group->setAsEnsemble(true);
|
||||
}
|
||||
}
|
||||
|
@ -49,66 +49,6 @@
|
||||
CAF_CMD_SOURCE_INIT(RicImportEnsembleFeature, "RicImportEnsembleFeature");
|
||||
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RicImportEnsembleFeature::validateEnsembleCases(std::vector<RimSummaryCase*> cases)
|
||||
{
|
||||
// Validate ensemble parameters
|
||||
try
|
||||
{
|
||||
QString errors;
|
||||
std::hash<std::string> paramsHasher;
|
||||
size_t paramsHash = 0;
|
||||
|
||||
for (RimSummaryCase* rimCase : cases)
|
||||
{
|
||||
if (rimCase->caseRealizationParameters() == nullptr || rimCase->caseRealizationParameters()->parameters().empty())
|
||||
{
|
||||
errors.append(QString("The case %1 has no ensemble parameters\n").arg(QFileInfo(rimCase->summaryHeaderFilename()).fileName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
QString paramNames;
|
||||
for (std::pair<QString, RigCaseRealizationParameters::Value> paramPair : rimCase->caseRealizationParameters()->parameters())
|
||||
{
|
||||
paramNames.append(paramPair.first);
|
||||
}
|
||||
|
||||
size_t currHash = paramsHasher(paramNames.toStdString());
|
||||
if (paramsHash == 0)
|
||||
{
|
||||
paramsHash = currHash;
|
||||
}
|
||||
else if (paramsHash != currHash)
|
||||
{
|
||||
throw QString("Ensemble parameters differ between cases");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!errors.isEmpty())
|
||||
{
|
||||
errors.append("\n");
|
||||
errors.append("No parameters file (parameters.txt or runspecification.xml) was found in \n");
|
||||
errors.append("the searched folders. ResInsight searches the home folder of the summary \n");
|
||||
errors.append("case file and the three folder levels above that.\n");
|
||||
|
||||
throw errors;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (QString errorMessage)
|
||||
{
|
||||
QMessageBox mbox;
|
||||
mbox.setIcon(QMessageBox::Icon::Warning);
|
||||
mbox.setInformativeText(errorMessage);
|
||||
mbox.exec();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -133,8 +73,6 @@ void RicImportEnsembleFeature::onActionTriggered(bool isChecked)
|
||||
std::vector<RimSummaryCase*> cases;
|
||||
RicImportSummaryCasesFeature::createSummaryCasesFromFiles(fileNames, &cases, true);
|
||||
|
||||
validateEnsembleCases(cases);
|
||||
|
||||
RicImportSummaryCasesFeature::addSummaryCases(cases);
|
||||
auto newGroup = RicCreateSummaryCaseCollectionFeature::groupSummaryCases(cases, ensembleName, true);
|
||||
|
||||
|
@ -35,9 +35,6 @@ class RicImportEnsembleFeature : public caf::CmdFeature
|
||||
{
|
||||
CAF_CMD_HEADER_INIT;
|
||||
|
||||
public:
|
||||
static bool validateEnsembleCases(std::vector<RimSummaryCase*> cases);
|
||||
|
||||
protected:
|
||||
// Overrides
|
||||
virtual bool isCommandEnabled() override;
|
||||
|
@ -231,6 +231,9 @@ void RimDerivedEnsembleCaseCollection::defineUiOrdering(QString uiConfigName, ca
|
||||
uiOrdering.add(&m_swapEnsemblesButton);
|
||||
|
||||
uiOrdering.skipRemainingFields(true);
|
||||
|
||||
updateAutoName();
|
||||
if (!isValid()) m_caseCount = "";
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -26,7 +26,11 @@
|
||||
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
|
||||
#include <cmath>
|
||||
#include <algorithm>
|
||||
|
||||
CAF_PDM_SOURCE_INIT(RimSummaryCaseCollection, "SummaryCaseSubCollection");
|
||||
|
||||
@ -65,8 +69,15 @@ RimSummaryCaseCollection::~RimSummaryCaseCollection()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::removeCase(RimSummaryCase* summaryCase)
|
||||
{
|
||||
size_t caseCountBeforeRemove = m_cases.size();
|
||||
m_cases.removeChildObject(summaryCase);
|
||||
updateReferringCurveSets();
|
||||
|
||||
if (m_isEnsemble && m_cases.size() != caseCountBeforeRemove)
|
||||
{
|
||||
if(dynamic_cast<RimDerivedEnsembleCase*>(summaryCase) == nullptr)
|
||||
calculateEnsembleParametersIntersectionHash();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -96,6 +107,12 @@ void RimSummaryCaseCollection::addCase(RimSummaryCase* summaryCase, bool updateC
|
||||
if (updateCurveSets) derEnsemble->updateReferringCurveSets();
|
||||
}
|
||||
|
||||
if (m_isEnsemble)
|
||||
{
|
||||
validateEnsembleCases({ summaryCase });
|
||||
calculateEnsembleParametersIntersectionHash();
|
||||
}
|
||||
|
||||
if(updateCurveSets) updateReferringCurveSets();
|
||||
}
|
||||
|
||||
@ -136,8 +153,17 @@ bool RimSummaryCaseCollection::isEnsemble() const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::setAsEnsemble(bool isEnsemble)
|
||||
{
|
||||
m_isEnsemble = isEnsemble;
|
||||
updateIcon();
|
||||
if (isEnsemble != m_isEnsemble)
|
||||
{
|
||||
m_isEnsemble = isEnsemble;
|
||||
updateIcon();
|
||||
|
||||
if (m_isEnsemble && dynamic_cast<RimDerivedEnsembleCaseCollection*>(this) == nullptr)
|
||||
{
|
||||
validateEnsembleCases(allSummaryCases());
|
||||
calculateEnsembleParametersIntersectionHash();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -254,6 +280,55 @@ EnsembleParameter RimSummaryCaseCollection::ensembleParameter(const QString& par
|
||||
return eParam;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::calculateEnsembleParametersIntersectionHash()
|
||||
{
|
||||
clearEnsembleParametersHashes();
|
||||
|
||||
// Find ensemble parameters intersection
|
||||
std::set<QString> paramNames;
|
||||
auto sumCases = allSummaryCases();
|
||||
|
||||
for (int i = 0; i < sumCases.size(); i++)
|
||||
{
|
||||
auto crp = sumCases[i]->caseRealizationParameters();
|
||||
if (!crp) continue;
|
||||
|
||||
auto caseParamNames = crp->parameterNames();
|
||||
|
||||
if (i == 0) paramNames = caseParamNames;
|
||||
else
|
||||
{
|
||||
std::set<QString> newIntersection;
|
||||
std::set_intersection(paramNames.begin(), paramNames.end(),
|
||||
caseParamNames.begin(), caseParamNames.end(),
|
||||
std::inserter(newIntersection, newIntersection.end()));
|
||||
|
||||
if(paramNames.size() != newIntersection.size()) paramNames = newIntersection;
|
||||
}
|
||||
}
|
||||
|
||||
for (auto sumCase : sumCases)
|
||||
{
|
||||
auto crp = sumCase->caseRealizationParameters();
|
||||
if(crp) crp->calculateParametersHash(paramNames);
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::clearEnsembleParametersHashes()
|
||||
{
|
||||
for (auto sumCase : allSummaryCases())
|
||||
{
|
||||
auto crp = sumCase->caseRealizationParameters();
|
||||
if (crp) crp->clearParametersHash();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -262,6 +337,66 @@ void RimSummaryCaseCollection::loadDataAndUpdate()
|
||||
onLoadDataAndUpdate();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimSummaryCaseCollection::validateEnsembleCases(const std::vector<RimSummaryCase*> cases)
|
||||
{
|
||||
// Validate ensemble parameters
|
||||
try
|
||||
{
|
||||
QString errors;
|
||||
std::hash<std::string> paramsHasher;
|
||||
size_t paramsHash = 0;
|
||||
|
||||
for (RimSummaryCase* rimCase : cases)
|
||||
{
|
||||
if (rimCase->caseRealizationParameters() == nullptr || rimCase->caseRealizationParameters()->parameters().empty())
|
||||
{
|
||||
errors.append(QString("The case %1 has no ensemble parameters\n").arg(QFileInfo(rimCase->summaryHeaderFilename()).fileName()));
|
||||
}
|
||||
else
|
||||
{
|
||||
QString paramNames;
|
||||
for (std::pair<QString, RigCaseRealizationParameters::Value> paramPair : rimCase->caseRealizationParameters()->parameters())
|
||||
{
|
||||
paramNames.append(paramPair.first);
|
||||
}
|
||||
|
||||
size_t currHash = paramsHasher(paramNames.toStdString());
|
||||
if (paramsHash == 0)
|
||||
{
|
||||
paramsHash = currHash;
|
||||
}
|
||||
else if (paramsHash != currHash)
|
||||
{
|
||||
throw QString("Ensemble parameters differ between cases");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!errors.isEmpty())
|
||||
{
|
||||
errors.append("\n");
|
||||
errors.append("No parameters file (parameters.txt or runspecification.xml) was found in \n");
|
||||
errors.append("the searched folders. ResInsight searches the home folder of the summary \n");
|
||||
errors.append("case file and the three folder levels above that.\n");
|
||||
|
||||
throw errors;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
catch (QString errorMessage)
|
||||
{
|
||||
QMessageBox mbox;
|
||||
mbox.setIcon(QMessageBox::Icon::Warning);
|
||||
mbox.setInformativeText(errorMessage);
|
||||
mbox.exec();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -275,7 +410,7 @@ caf::PdmFieldHandle* RimSummaryCaseCollection::userDescriptionField()
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimSummaryCaseCollection::onLoadDataAndUpdate()
|
||||
{
|
||||
// NOP
|
||||
if (m_isEnsemble) calculateEnsembleParametersIntersectionHash();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
|
@ -74,9 +74,13 @@ public:
|
||||
void setAsEnsemble(bool isEnsemble);
|
||||
virtual std::set<RifEclipseSummaryAddress> calculateUnionOfSummaryAddresses() const;
|
||||
EnsembleParameter ensembleParameter(const QString& paramName) const;
|
||||
void calculateEnsembleParametersIntersectionHash();
|
||||
void clearEnsembleParametersHashes();
|
||||
|
||||
void loadDataAndUpdate();
|
||||
|
||||
static bool validateEnsembleCases(const std::vector<RimSummaryCase*> cases);
|
||||
|
||||
private:
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
QString nameAndItemCount() const;
|
||||
|
@ -242,7 +242,6 @@ RimSummaryCaseCollection* RimSummaryCaseMainCollection::addCaseCollection(std::v
|
||||
{
|
||||
RimSummaryCaseCollection* summaryCaseCollection = allocator();
|
||||
if(!collectionName.isEmpty()) summaryCaseCollection->setName(collectionName);
|
||||
summaryCaseCollection->setAsEnsemble(isEnsemble);
|
||||
|
||||
for (RimSummaryCase* summaryCase : summaryCases)
|
||||
{
|
||||
@ -261,6 +260,8 @@ RimSummaryCaseCollection* RimSummaryCaseMainCollection::addCaseCollection(std::v
|
||||
summaryCaseCollection->addCase(summaryCase);
|
||||
}
|
||||
|
||||
summaryCaseCollection->setAsEnsemble(isEnsemble);
|
||||
|
||||
m_caseCollections.push_back(summaryCaseCollection);
|
||||
|
||||
return summaryCaseCollection;
|
||||
|
@ -115,6 +115,16 @@ std::map<QString, RigCaseRealizationParameters::Value> RigCaseRealizationParamet
|
||||
return m_parameters;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::set<QString> RigCaseRealizationParameters::parameterNames() const
|
||||
{
|
||||
std::set<QString> names;
|
||||
for (auto& par : parameters()) names.insert(par.first);
|
||||
return names;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
@ -143,16 +153,41 @@ size_t RigCaseRealizationParameters::parameterHash(const QString& name) const
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RigCaseRealizationParameters::parametersHash()
|
||||
{
|
||||
if (m_parametersHash == 0)
|
||||
if (m_parametersHash == 0) calculateParametersHash();
|
||||
return m_parametersHash;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigCaseRealizationParameters::clearParametersHash()
|
||||
{
|
||||
m_parametersHash = 0;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RigCaseRealizationParameters::calculateParametersHash(const std::set<QString>& paramNames /*= std::set<QString>()*/)
|
||||
{
|
||||
QStringList hashes;
|
||||
|
||||
if (paramNames.empty())
|
||||
{
|
||||
QStringList hashes;
|
||||
for (auto param : m_parameters)
|
||||
{
|
||||
hashes.push_back(QString::number(parameterHash(param.first)));
|
||||
}
|
||||
|
||||
std::hash<std::string> stringHasher;
|
||||
m_parametersHash = stringHasher(hashes.join("").toStdString());
|
||||
}
|
||||
return m_parametersHash;
|
||||
else
|
||||
{
|
||||
for (auto paramName : paramNames)
|
||||
{
|
||||
if (m_parameters.find(paramName) == m_parameters.end()) return;
|
||||
hashes.push_back(QString::number(parameterHash(paramName)));
|
||||
}
|
||||
}
|
||||
|
||||
std::hash<std::string> stringHasher;
|
||||
m_parametersHash = stringHasher(hashes.join("").toStdString());
|
||||
}
|
||||
|
@ -24,6 +24,7 @@
|
||||
#include <QString>
|
||||
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <memory>
|
||||
|
||||
//==================================================================================================
|
||||
@ -66,10 +67,14 @@ public:
|
||||
Value parameterValue(const QString& name);
|
||||
|
||||
std::map<QString, Value> parameters() const;
|
||||
std::set<QString> parameterNames() const;
|
||||
|
||||
size_t parameterHash(const QString& name) const;
|
||||
size_t parametersHash();
|
||||
|
||||
void clearParametersHash();
|
||||
void calculateParametersHash(const std::set<QString>& paramNames = std::set<QString>());
|
||||
|
||||
private:
|
||||
std::map<QString, Value> m_parameters;
|
||||
size_t m_parametersHash;
|
||||
|
Loading…
Reference in New Issue
Block a user