ResInsight/ApplicationCode/ProjectDataModel/RimEclipseStatisticsCase.cpp
2019-07-30 12:32:10 +02:00

781 lines
33 KiB
C++

/////////////////////////////////////////////////////////////////////////////////
//
// Copyright (C) 2011- Statoil ASA
// Copyright (C) 2013- Ceetron Solutions AS
// Copyright (C) 2011-2012 Ceetron AS
//
// 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 "RimEclipseStatisticsCase.h"
#include "RicfCommandObject.h"
#include "RicNewViewFeature.h"
#include "RigCaseCellResultsData.h"
#include "RigEclipseCaseData.h"
#include "RigSimWellData.h"
#include "RimCaseCollection.h"
#include "RimEclipseCellColors.h"
#include "RimEclipseStatisticsCaseEvaluator.h"
#include "RimEclipseView.h"
#include "RimIdenticalGridCaseGroup.h"
#include "RimIntersectionCollection.h"
#include "RimReservoirCellResultsStorage.h"
#include "RimSimWellInViewCollection.h"
#include "RiuMainWindow.h"
#include "cafPdmUiPushButtonEditor.h"
#include "cafPdmUiTextEditor.h"
#include "cafProgressInfo.h"
namespace caf {
template<>
void caf::AppEnum<RimEclipseStatisticsCase::PercentileCalcType>::setUp()
{
addItem(RimEclipseStatisticsCase::NEAREST_OBSERVATION, "NearestObservationPercentile", "Nearest Observation");
addItem(RimEclipseStatisticsCase::HISTOGRAM_ESTIMATED, "HistogramEstimatedPercentile", "Histogram based estimate");
addItem(RimEclipseStatisticsCase::INTERPOLATED_OBSERVATION, "InterpolatedObservationPercentile", "Interpolated Observation");
setDefault(RimEclipseStatisticsCase::INTERPOLATED_OBSERVATION);
}
}
CAF_PDM_SOURCE_INIT(RimEclipseStatisticsCase, "RimStatisticalCalculation");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseStatisticsCase::RimEclipseStatisticsCase()
: RimEclipseCase()
{
CAF_PDM_InitObject("Case Group Statistics", ":/Histogram16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_calculateEditCommand, "m_editingAllowed", "", "", "", "");
caf::PdmUiPushButtonEditor::configureEditorForField(&m_calculateEditCommand);
m_calculateEditCommand = false;
CAF_PDM_InitField(&m_selectionSummary, "SelectionSummary", QString(""), "Summary of Calculation Setup", "", "", "");
m_selectionSummary.xmlCapability()->disableIO();
m_selectionSummary.uiCapability()->setUiReadOnly(true);
m_selectionSummary.uiCapability()->setUiEditorTypeName(caf::PdmUiTextEditor::uiEditorTypeName());
m_selectionSummary.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
RICF_InitFieldNoDefault(&m_resultType, "ResultType", "Result Type", "", "", "");
m_resultType.xmlCapability()->setIOWritable(false);
RICF_InitFieldNoDefault(&m_porosityModel, "PorosityModel", "Porosity Model", "", "", "");
m_porosityModel.xmlCapability()->setIOWritable(false);
RICF_InitFieldNoDefault(&m_selectedDynamicProperties, "DynamicPropertiesToCalculate", "Dyn Prop", "", "", "");
RICF_InitFieldNoDefault(&m_selectedStaticProperties, "StaticPropertiesToCalculate", "Stat Prop", "", "", "");
RICF_InitFieldNoDefault(&m_selectedGeneratedProperties, "GeneratedPropertiesToCalculate", "", "", "", "");
RICF_InitFieldNoDefault(&m_selectedInputProperties, "InputPropertiesToCalculate", "", "", "", "");
RICF_InitFieldNoDefault(&m_selectedFractureDynamicProperties, "FractureDynamicPropertiesToCalculate", "", "", "", "");
RICF_InitFieldNoDefault(&m_selectedFractureStaticProperties, "FractureStaticPropertiesToCalculate", "", "", "", "");
RICF_InitFieldNoDefault(&m_selectedFractureGeneratedProperties, "FractureGeneratedPropertiesToCalculate", "", "", "", "");
RICF_InitFieldNoDefault(&m_selectedFractureInputProperties, "FractureInputPropertiesToCalculate", "", "", "", "");
m_selectedDynamicProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedStaticProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedGeneratedProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedInputProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedFractureDynamicProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedFractureStaticProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedFractureGeneratedProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
m_selectedFractureInputProperties.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
RICF_InitField(&m_calculatePercentiles, "CalculatePercentiles", true, "Calculate Percentiles", "", "", "");
RICF_InitFieldNoDefault(&m_percentileCalculationType, "PercentileCalculationType", "Method", "", "", "");
RICF_InitField(&m_lowPercentile, "LowPercentile", 10.0, "Low", "", "", "");
RICF_InitField(&m_midPercentile, "MidPercentile", 50.0, "Mid", "", "", "");
RICF_InitField(&m_highPercentile, "HighPercentile", 90.0, "High", "", "", "");
RICF_InitField(&m_wellDataSourceCase, "WellDataSourceCase", RiaDefines::undefinedResultName(), "Well Data Source Case", "", "", "" );
RICF_InitField(&m_useZeroAsInactiveCellValue, "UseZeroAsInactiveCellValue", false, "Use Zero as Inactive Cell Value", "", "", "");
m_populateSelectionAfterLoadingGrid = false;
// These does not work properly for statistics case, so hide for now
m_flipXAxis.uiCapability()->setUiHidden(true);
m_flipYAxis.uiCapability()->setUiHidden(true);
activeFormationNames.uiCapability()->setUiHidden(true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEclipseStatisticsCase::~RimEclipseStatisticsCase()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::setMainGrid(RigMainGrid* mainGrid)
{
CVF_ASSERT(mainGrid);
CVF_ASSERT(this->eclipseCaseData());
eclipseCaseData()->setMainGrid(mainGrid);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseStatisticsCase::openEclipseGridFile()
{
if (this->eclipseCaseData()) return true;
cvf::ref<RigEclipseCaseData> eclipseCase = new RigEclipseCaseData(this);
CVF_ASSERT(parentStatisticsCaseCollection());
RimIdenticalGridCaseGroup* gridCaseGroup = parentStatisticsCaseCollection()->parentCaseGroup();
CVF_ASSERT(gridCaseGroup);
RigMainGrid* mainGrid = gridCaseGroup->mainGrid();
eclipseCase->setMainGrid(mainGrid);
eclipseCase->setActiveCellInfo(RiaDefines::MATRIX_MODEL, gridCaseGroup->unionOfActiveCells(RiaDefines::MATRIX_MODEL));
eclipseCase->setActiveCellInfo(RiaDefines::FRACTURE_MODEL, gridCaseGroup->unionOfActiveCells(RiaDefines::FRACTURE_MODEL));
this->setReservoirData( eclipseCase.p() );
if (m_populateSelectionAfterLoadingGrid)
{
this->populateResultSelection();
m_populateSelectionAfterLoadingGrid = false;
}
return true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::reloadEclipseGridFile()
{
setReservoirData(nullptr);
openReserviorCase();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimCaseCollection* RimEclipseStatisticsCase::parentStatisticsCaseCollection() const
{
return dynamic_cast<RimCaseCollection*>(this->parentField()->ownerObject());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::populateResultSelectionAfterLoadingGrid()
{
m_populateSelectionAfterLoadingGrid = true;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::computeStatistics()
{
if (this->eclipseCaseData() == nullptr)
{
openEclipseGridFile();
}
RimIdenticalGridCaseGroup* gridCaseGroup = caseGroup();
CVF_ASSERT(gridCaseGroup);
gridCaseGroup->computeUnionOfActiveCells();
std::vector<RimEclipseCase*> sourceCases = getSourceCases();
if (sourceCases.size() == 0
|| !sourceCases.at(0)->results(RiaDefines::MATRIX_MODEL))
{
return;
}
// The first source has been read completely from disk, and contains grid and meta data
// Use this information for all cases in the case group
size_t timeStepCount = sourceCases.at(0)->results(RiaDefines::MATRIX_MODEL)->maxTimeStepCount();
RimStatisticsConfig statisticsConfig;
statisticsConfig.m_calculatePercentiles = m_calculatePercentiles();
statisticsConfig.m_pMaxPos = m_highPercentile();
statisticsConfig.m_pMidPos = m_midPercentile();
statisticsConfig.m_pMinPos = m_lowPercentile();
statisticsConfig.m_pValMethod = m_percentileCalculationType();
std::vector<size_t> timeStepIndices;
for (size_t i = 0; i < timeStepCount; i++)
{
timeStepIndices.push_back(i);
}
RigEclipseCaseData* resultCase = eclipseCaseData();
QList<RimEclipseStatisticsCaseEvaluator::ResSpec > resultSpecification;
for(size_t pIdx = 0; pIdx < m_selectedDynamicProperties().size(); ++pIdx)
{
resultSpecification.append(RimEclipseStatisticsCaseEvaluator::ResSpec(RiaDefines::MATRIX_MODEL, RiaDefines::DYNAMIC_NATIVE, m_selectedDynamicProperties()[pIdx]));
}
for(size_t pIdx = 0; pIdx < m_selectedStaticProperties().size(); ++pIdx)
{
resultSpecification.append(RimEclipseStatisticsCaseEvaluator::ResSpec(RiaDefines::MATRIX_MODEL, RiaDefines::STATIC_NATIVE, m_selectedStaticProperties()[pIdx]));
}
for(size_t pIdx = 0; pIdx < m_selectedGeneratedProperties().size(); ++pIdx)
{
resultSpecification.append(RimEclipseStatisticsCaseEvaluator::ResSpec(RiaDefines::MATRIX_MODEL, RiaDefines::GENERATED, m_selectedGeneratedProperties()[pIdx]));
}
for(size_t pIdx = 0; pIdx < m_selectedInputProperties().size(); ++pIdx)
{
resultSpecification.append(RimEclipseStatisticsCaseEvaluator::ResSpec(RiaDefines::MATRIX_MODEL, RiaDefines::INPUT_PROPERTY, m_selectedInputProperties()[pIdx]));
}
for(size_t pIdx = 0; pIdx < m_selectedFractureDynamicProperties().size(); ++pIdx)
{
resultSpecification.append(RimEclipseStatisticsCaseEvaluator::ResSpec(RiaDefines::FRACTURE_MODEL, RiaDefines::DYNAMIC_NATIVE, m_selectedFractureDynamicProperties()[pIdx]));
}
for(size_t pIdx = 0; pIdx < m_selectedFractureStaticProperties().size(); ++pIdx)
{
resultSpecification.append(RimEclipseStatisticsCaseEvaluator::ResSpec(RiaDefines::FRACTURE_MODEL, RiaDefines::STATIC_NATIVE, m_selectedFractureStaticProperties()[pIdx]));
}
for(size_t pIdx = 0; pIdx < m_selectedFractureGeneratedProperties().size(); ++pIdx)
{
resultSpecification.append(RimEclipseStatisticsCaseEvaluator::ResSpec(RiaDefines::FRACTURE_MODEL, RiaDefines::GENERATED, m_selectedFractureGeneratedProperties()[pIdx]));
}
for(size_t pIdx = 0; pIdx < m_selectedFractureInputProperties().size(); ++pIdx)
{
resultSpecification.append(RimEclipseStatisticsCaseEvaluator::ResSpec(RiaDefines::FRACTURE_MODEL, RiaDefines::INPUT_PROPERTY, m_selectedFractureInputProperties()[pIdx]));
}
RimEclipseStatisticsCaseEvaluator stat(sourceCases, timeStepIndices, statisticsConfig, resultCase, gridCaseGroup);
if (m_useZeroAsInactiveCellValue)
{
stat.useZeroAsValueForInActiveCellsBasedOnUnionOfActiveCells();
}
stat.evaluateForResults(resultSpecification);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::scheduleACTIVEGeometryRegenOnReservoirViews()
{
for (size_t i = 0; i < reservoirViews().size(); i++)
{
RimEclipseView* reservoirView = reservoirViews()[i];
CVF_ASSERT(reservoirView);
reservoirView->scheduleGeometryRegen(ACTIVE);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimEclipseCase*> RimEclipseStatisticsCase::getSourceCases() const
{
std::vector<RimEclipseCase*> sourceCases;
RimIdenticalGridCaseGroup* gridCaseGroup = caseGroup();
if (gridCaseGroup)
{
size_t caseCount = gridCaseGroup->caseCollection->reservoirs.size();
for (size_t i = 0; i < caseCount; i++)
{
CVF_ASSERT(gridCaseGroup->caseCollection);
CVF_ASSERT(gridCaseGroup->caseCollection->reservoirs[i]);
RimEclipseCase* sourceCase = gridCaseGroup->caseCollection->reservoirs[i];
sourceCases.push_back(sourceCase);
}
}
return sourceCases;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimIdenticalGridCaseGroup* RimEclipseStatisticsCase::caseGroup() const
{
RimCaseCollection* parentCollection = parentStatisticsCaseCollection();
if (parentCollection)
{
return parentCollection->parentCaseGroup();
}
return nullptr;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
updateSelectionSummaryLabel();
updateSelectionListVisibilities();
updatePercentileUiVisibility();
uiOrdering.add(&caseUserDescription);
uiOrdering.add(&caseId);
uiOrdering.add(&m_calculateEditCommand);
caf::PdmUiGroup * group = uiOrdering.addNewGroup("Summary of Calculation Setup");
group->add(&m_useZeroAsInactiveCellValue);
m_useZeroAsInactiveCellValue.uiCapability()->setUiHidden(hasComputedStatistics());
group->add(&m_selectionSummary);
group = uiOrdering.addNewGroup("Properties to consider");
group->setUiHidden(hasComputedStatistics());
group->add(&m_resultType);
group->add(&m_porosityModel);
group->add(&m_selectedDynamicProperties);
group->add(&m_selectedStaticProperties);
group->add(&m_selectedGeneratedProperties);
group->add(&m_selectedInputProperties);
group->add(&m_selectedFractureDynamicProperties);
group->add(&m_selectedFractureStaticProperties);
group->add(&m_selectedFractureGeneratedProperties);
group->add(&m_selectedFractureInputProperties);
group = uiOrdering.addNewGroup("Percentile setup");
group->setUiHidden(hasComputedStatistics());
group->add(&m_calculatePercentiles);
group->add(&m_percentileCalculationType);
group->add(&m_lowPercentile);
group->add(&m_midPercentile);
group->add(&m_highPercentile);
group = uiOrdering.addNewGroup("Case Options");
group->add(&m_wellDataSourceCase);
group->add(&activeFormationNames);
group->add(&m_flipXAxis);
group->add(&m_flipYAxis);
}
QList<caf::PdmOptionItemInfo> toOptionList(const QStringList& varList)
{
QList<caf::PdmOptionItemInfo> optionList;
int i;
for (i = 0; i < varList.size(); ++i)
{
optionList.push_back(caf::PdmOptionItemInfo( varList[i], varList[i]));
}
return optionList;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimEclipseStatisticsCase::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
{
QList<caf::PdmOptionItemInfo> options;
if (useOptionsOnly) *useOptionsOnly = true;
RimIdenticalGridCaseGroup* idgcg = caseGroup();
if (!(caseGroup() && caseGroup()->mainCase() && caseGroup()->mainCase()->eclipseCaseData()))
{
return options;
}
RigEclipseCaseData* caseData = idgcg->mainCase()->eclipseCaseData();
if (&m_selectedDynamicProperties == fieldNeedingOptions)
{
QStringList varList = caseData->results(RiaDefines::MATRIX_MODEL)->resultNames(RiaDefines::DYNAMIC_NATIVE);
return toOptionList(varList);
}
else if (&m_selectedStaticProperties == fieldNeedingOptions)
{
QStringList varList = caseData->results(RiaDefines::MATRIX_MODEL)->resultNames(RiaDefines::STATIC_NATIVE);
return toOptionList(varList);
}
else if (&m_selectedGeneratedProperties == fieldNeedingOptions)
{
QStringList varList = caseData->results(RiaDefines::MATRIX_MODEL)->resultNames(RiaDefines::GENERATED);
return toOptionList(varList);
}
else if (&m_selectedInputProperties == fieldNeedingOptions)
{
QStringList varList = caseData->results(RiaDefines::MATRIX_MODEL)->resultNames(RiaDefines::INPUT_PROPERTY);
return toOptionList(varList);
}
else if (&m_selectedFractureDynamicProperties == fieldNeedingOptions)
{
QStringList varList = caseData->results(RiaDefines::FRACTURE_MODEL)->resultNames(RiaDefines::DYNAMIC_NATIVE);
return toOptionList(varList);
}
else if (&m_selectedFractureStaticProperties == fieldNeedingOptions)
{
QStringList varList = caseData->results(RiaDefines::FRACTURE_MODEL)->resultNames(RiaDefines::STATIC_NATIVE);
return toOptionList(varList);
}
else if (&m_selectedFractureGeneratedProperties == fieldNeedingOptions)
{
QStringList varList = caseData->results(RiaDefines::FRACTURE_MODEL)->resultNames(RiaDefines::GENERATED);
return toOptionList(varList);
}
else if (&m_selectedFractureInputProperties == fieldNeedingOptions)
{
QStringList varList = caseData->results(RiaDefines::FRACTURE_MODEL)->resultNames(RiaDefines::INPUT_PROPERTY);
return toOptionList(varList);
}
else if (&m_wellDataSourceCase == fieldNeedingOptions)
{
QStringList sourceCaseNames;
sourceCaseNames += RiaDefines::undefinedResultName();
for (size_t i = 0; i < caseGroup()->caseCollection()->reservoirs().size(); i++)
{
sourceCaseNames += caseGroup()->caseCollection()->reservoirs()[i]->caseUserDescription();
}
return toOptionList(sourceCaseNames);
}
if (!options.size()) options = RimEclipseCase::calculateValueOptions(fieldNeedingOptions, useOptionsOnly);
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
RimEclipseCase::fieldChangedByUi(changedField, oldValue, newValue);
if (&m_resultType == changedField || &m_porosityModel == changedField)
{
}
if (&m_calculateEditCommand == changedField)
{
if (hasComputedStatistics())
{
clearComputedStatistics();
}
else
{
computeStatisticsAndUpdateViews();
}
m_calculateEditCommand = false;
}
if (&m_wellDataSourceCase == changedField)
{
// Find or load well data for given case
RimEclipseCase* sourceResultCase = caseGroup()->caseCollection()->findByDescription(m_wellDataSourceCase);
if (sourceResultCase)
{
sourceResultCase->openEclipseGridFile();
// Propagate well info to statistics case
if (sourceResultCase->eclipseCaseData())
{
const cvf::Collection<RigSimWellData>& sourceCaseSimWellData = sourceResultCase->eclipseCaseData()->wellResults();
setWellResultsAndUpdateViews(sourceCaseSimWellData);
}
}
else
{
cvf::Collection<RigSimWellData> sourceCaseWellResults;
setWellResultsAndUpdateViews(sourceCaseWellResults);
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::setWellResultsAndUpdateViews(const cvf::Collection<RigSimWellData>& sourceCaseSimWellData)
{
this->eclipseCaseData()->setSimWellData(sourceCaseSimWellData);
caf::ProgressInfo progInfo(reservoirViews().size() + 1, "Updating Well Data for Views");
// Update views
for (size_t i = 0; i < reservoirViews().size(); i++)
{
RimEclipseView* reservoirView = reservoirViews()[i];
CVF_ASSERT(reservoirView);
reservoirView->wellCollection()->wells.deleteAllChildObjects();
reservoirView->updateDisplayModelForWellResults();
reservoirView->wellCollection()->updateConnectedEditors();
progInfo.incrementProgress();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void addPropertySetToHtmlText(QString& html, const QString& heading, const std::vector<QString>& varNames)
{
if (varNames.size())
{
html += "<p><b>" + heading + "</b></p>";
html += "<p class=indent>";
for (size_t pIdx = 0; pIdx < varNames.size(); ++pIdx)
{
html += varNames[pIdx];
if ( (pIdx+1)%6 == 0 ) html += "<br>";
else if (pIdx != varNames.size() -1) html += ", ";
}
html += "</p>";
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::updateSelectionSummaryLabel()
{
QString html;
html += "<style> "
"p{ margin-top:0px; margin-bottom:0px;} "
"p.indent{margin-left:20px; margin-top:0px;} "
"p.indent2{margin-left:40px; margin-top:0px;} "
"</style>";
html += "<p><b>Statistical variables to compute:</b></p>";
html += "<p class=indent>";
html += "Min, Max, Sum, Range, Mean, Std.dev"; ;
if (m_calculatePercentiles())
{
html += "<br>";
html += "Percentiles for : "
+ QString::number(m_lowPercentile()) + ", "
+ QString::number(m_midPercentile()) + ", "
+ QString::number(m_highPercentile());
}
html += "</p>";
addPropertySetToHtmlText(html, "Dynamic properties", m_selectedDynamicProperties());
addPropertySetToHtmlText(html, "Static properties", m_selectedStaticProperties());
addPropertySetToHtmlText(html, "Generated properties", m_selectedGeneratedProperties());
addPropertySetToHtmlText(html, "Input properties", m_selectedInputProperties());
addPropertySetToHtmlText(html, "Dynamic properties, fracture model" , m_selectedFractureDynamicProperties());
addPropertySetToHtmlText(html, "Static properties, fracture model" , m_selectedFractureStaticProperties());
addPropertySetToHtmlText(html, "Generated properties, fracture model", m_selectedFractureGeneratedProperties());
addPropertySetToHtmlText(html, "Input properties, fracture model" , m_selectedFractureInputProperties());
m_selectionSummary = html;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute * attribute)
{
if (&m_selectionSummary == field)
{
caf::PdmUiTextEditorAttribute* textEditAttrib = dynamic_cast<caf::PdmUiTextEditorAttribute*> (attribute);
if (textEditAttrib)
{
textEditAttrib->textMode = caf::PdmUiTextEditorAttribute::HTML;
}
}
if (&m_calculateEditCommand == field)
{
caf::PdmUiPushButtonEditorAttribute* attrib = dynamic_cast<caf::PdmUiPushButtonEditorAttribute*> (attribute);
if (attrib)
{
attrib->m_buttonText = hasComputedStatistics() ? "Edit (Will DELETE current results)": "Compute";
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::updateSelectionListVisibilities()
{
bool isLocked = hasComputedStatistics();
m_resultType.uiCapability()->setUiHidden(isLocked);
m_porosityModel.uiCapability()->setUiHidden(isLocked ); // || !caseGroup()->mainCase()->reservoirData()->results(RiaDefines::FRACTURE_MODEL)->resultCount()
m_selectedDynamicProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RiaDefines::MATRIX_MODEL && m_resultType() == RiaDefines::DYNAMIC_NATIVE));
m_selectedStaticProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RiaDefines::MATRIX_MODEL && m_resultType() == RiaDefines::STATIC_NATIVE));
m_selectedGeneratedProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RiaDefines::MATRIX_MODEL && m_resultType() == RiaDefines::GENERATED));
m_selectedInputProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RiaDefines::MATRIX_MODEL && m_resultType() == RiaDefines::INPUT_PROPERTY));
m_selectedFractureDynamicProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RiaDefines::FRACTURE_MODEL && m_resultType() == RiaDefines::DYNAMIC_NATIVE));
m_selectedFractureStaticProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RiaDefines::FRACTURE_MODEL && m_resultType() == RiaDefines::STATIC_NATIVE));
m_selectedFractureGeneratedProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RiaDefines::FRACTURE_MODEL && m_resultType() == RiaDefines::GENERATED));
m_selectedFractureInputProperties.uiCapability()->setUiHidden( isLocked || !(m_porosityModel() == RiaDefines::FRACTURE_MODEL && m_resultType() == RiaDefines::INPUT_PROPERTY));
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::updatePercentileUiVisibility()
{
bool isLocked = hasComputedStatistics();
m_calculatePercentiles.uiCapability()->setUiHidden(isLocked);
m_percentileCalculationType.uiCapability()->setUiHidden( isLocked || !m_calculatePercentiles());
m_lowPercentile .uiCapability()->setUiHidden(isLocked || !m_calculatePercentiles());
m_midPercentile .uiCapability()->setUiHidden(isLocked || !m_calculatePercentiles());
m_highPercentile.uiCapability()->setUiHidden(isLocked || !m_calculatePercentiles());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEclipseStatisticsCase::hasComputedStatistics() const
{
if ( eclipseCaseData()
&& ( eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->existingResults().size()
|| eclipseCaseData()->results(RiaDefines::FRACTURE_MODEL)->existingResults().size()))
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::updateConnectedEditorsAndReservoirViews()
{
for (size_t i = 0; i < reservoirViews.size(); ++i)
{
if (reservoirViews[i])
{
// As new result might have been introduced, update all editors connected
reservoirViews[i]->cellResult()->updateConnectedEditors();
// It is usually not needed to create new display model, but if any derived geometry based on generated data (from Octave)
// a full display model rebuild is required
reservoirViews[i]->hasUserRequestedAnimation = true;
reservoirViews[i]->scheduleCreateDisplayModelAndRedraw();
reservoirViews[i]->crossSectionCollection()->scheduleCreateDisplayModelAndRedraw2dIntersectionViews();
}
}
this->updateConnectedEditors();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::clearComputedStatistics()
{
if (eclipseCaseData() && eclipseCaseData()->results(RiaDefines::MATRIX_MODEL))
{
eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->clearAllResults();
}
if (eclipseCaseData() && eclipseCaseData()->results(RiaDefines::FRACTURE_MODEL))
{
eclipseCaseData()->results(RiaDefines::FRACTURE_MODEL)->clearAllResults();
}
updateConnectedEditorsAndReservoirViews();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::computeStatisticsAndUpdateViews()
{
if (getSourceCases().empty()) return;
computeStatistics();
scheduleACTIVEGeometryRegenOnReservoirViews();
updateConnectedEditorsAndReservoirViews();
if (reservoirViews.size() == 0)
{
RicNewViewFeature::addReservoirView(this, nullptr);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEclipseStatisticsCase::populateResultSelection()
{
RimIdenticalGridCaseGroup* idgcg = caseGroup();
if (!(caseGroup() && caseGroup()->mainCase() && caseGroup()->mainCase()->eclipseCaseData()))
{
return;
}
RigEclipseCaseData* caseData = idgcg->mainCase()->eclipseCaseData();
if (m_selectedDynamicProperties().size() == 0)
{
QStringList varList = caseData->results(RiaDefines::MATRIX_MODEL)->resultNames(RiaDefines::DYNAMIC_NATIVE);
if (varList.contains("SOIL")) m_selectedDynamicProperties.v().push_back("SOIL");
if (varList.contains("PRESSURE")) m_selectedDynamicProperties.v().push_back("PRESSURE");
}
if (m_selectedStaticProperties().size() == 0)
{
QStringList varList = caseData->results(RiaDefines::MATRIX_MODEL)->resultNames(RiaDefines::STATIC_NATIVE);
if (varList.contains("PERMX")) m_selectedStaticProperties.v().push_back("PERMX");
if (varList.contains("PORO")) m_selectedStaticProperties.v().push_back("PORO");
}
if (m_selectedFractureDynamicProperties().size() == 0)
{
QStringList varList = caseData->results(RiaDefines::FRACTURE_MODEL)->resultNames(RiaDefines::DYNAMIC_NATIVE);
if (varList.contains("SOIL")) m_selectedFractureDynamicProperties.v().push_back("SOIL");
if (varList.contains("PRESSURE")) m_selectedFractureDynamicProperties.v().push_back("PRESSURE");
}
if (m_selectedFractureStaticProperties().size() == 0)
{
QStringList varList = caseData->results(RiaDefines::FRACTURE_MODEL)->resultNames(RiaDefines::STATIC_NATIVE);
if (varList.contains("PERMX")) m_selectedFractureStaticProperties.v().push_back("PERMX");
if (varList.contains("PORO")) m_selectedFractureStaticProperties.v().push_back("PORO");
}
}