#2660 Ensemble curves. Curve filtering

This commit is contained in:
Bjørn Erik Jensen 2018-05-31 10:23:51 +02:00
parent 73c49b4ce9
commit 0b4156da02
19 changed files with 801 additions and 69 deletions

View File

@ -28,6 +28,8 @@
#include "RimCellRangeFilterCollection.h"
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseView.h"
#include "RimEnsembleCurveFilterCollection.h"
#include "RimEnsembleCurveSet.h"
#include "RimEnsembleCurveSetCollection.h"
#include "RimFormationNamesCollection.h"
#include "RimGeoMechPropertyFilterCollection.h"
@ -283,6 +285,15 @@ void RicDeleteItemExec::redo()
ensembleCurveSetColl->firstAncestorOrThisOfType(plot);
if (plot) plot->updateConnectedEditors();
}
RimEnsembleCurveFilterCollection* ensembleCurveFilterColl = nullptr;
parentObj->firstAncestorOrThisOfType(ensembleCurveFilterColl);
if (ensembleCurveFilterColl)
{
RimSummaryPlot* plot = nullptr;
ensembleCurveFilterColl->firstAncestorOrThisOfType(plot);
if (plot) plot->loadDataAndUpdate();
}
}
}

View File

@ -25,6 +25,7 @@
#include "RimEclipseInputProperty.h"
#include "RimEclipsePropertyFilter.h"
#include "RimEclipseView.h"
#include "RimEnsembleCurveFilter.h"
#include "RimEnsembleCurveSet.h"
#include "RimFishbonesMultipleSubs.h"
#include "RimFormationNames.h"
@ -119,6 +120,7 @@ bool isDeletable(caf::PdmUiItem* uiItem)
if (dynamic_cast<RimSimWellFractureCollection*>(uiItem)) return true;
if (dynamic_cast<RimSimWellFracture*>(uiItem)) return true;
if (dynamic_cast<RimEnsembleCurveSet*>(uiItem)) return true;
if (dynamic_cast<RimEnsembleCurveFilter*>(uiItem)) return true;
return false;
}

View File

@ -34,6 +34,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculator.h
${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryCrossPlotCurveFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryEnsembleCurveSetFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicPasteEnsembleCurveSetFeature.h
${CMAKE_CURRENT_LIST_DIR}/RicNewEnsembleCurveFilterFeature.h
)
set (SOURCE_GROUP_SOURCE_FILES
@ -71,6 +72,7 @@ ${CMAKE_CURRENT_LIST_DIR}/RicSummaryCurveCalculator.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryCrossPlotCurveFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewSummaryEnsembleCurveSetFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicPasteEnsembleCurveSetFeature.cpp
${CMAKE_CURRENT_LIST_DIR}/RicNewEnsembleCurveFilterFeature.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,68 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RicNewEnsembleCurveFilterFeature.h"
#include "RiaApplication.h"
#include "RimEnsembleCurveFilter.h"
#include "RimEnsembleCurveFilterCollection.h"
#include "RimEnsembleCurveSet.h"
#include "RiuPlotMainWindowTools.h"
#include "cafSelectionManagerTools.h"
#include <QAction>
CAF_CMD_SOURCE_INIT(RicNewEnsembleCurveFilterFeature, "RicNewEnsembleCurveFilterFeature");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RicNewEnsembleCurveFilterFeature::isCommandEnabled()
{
std::vector<RimEnsembleCurveFilterCollection*> filterColls = caf::selectedObjectsByType<RimEnsembleCurveFilterCollection*>();
return filterColls.size() == 1;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewEnsembleCurveFilterFeature::onActionTriggered(bool isChecked)
{
std::vector<RimEnsembleCurveFilterCollection*> filterColls = caf::selectedObjectsByType<RimEnsembleCurveFilterCollection*>();
if (filterColls.size() == 1)
{
auto newFilter = filterColls[0]->addFilter();
filterColls[0]->updateConnectedEditors();
RiuPlotMainWindowTools::selectAsCurrentItem(newFilter);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RicNewEnsembleCurveFilterFeature::setupActionLook(QAction* actionToSetup)
{
actionToSetup->setText("New Ensemble Curve Filter");
actionToSetup->setIcon(QIcon(":/SummaryCurveFilter16x16.png"));
}

View File

@ -0,0 +1,39 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "cafCmdFeature.h"
class RimSummaryPlotCollection;
class RimSummaryCase;
class RimSummaryPlot;
//==================================================================================================
///
//==================================================================================================
class RicNewEnsembleCurveFilterFeature : public caf::CmdFeature
{
CAF_CMD_HEADER_INIT;
protected:
// Overrides
virtual bool isCommandEnabled();
virtual void onActionTriggered( bool isChecked );
virtual void setupActionLook(QAction* actionToSetup);
};

View File

@ -26,6 +26,9 @@
#include "RicSummaryCurveCreator.h"
#include "RicSummaryCurveCreatorDialog.h"
#include "RimEnsembleCurveFilter.h"
#include "RimEnsembleCurveFilterCollection.h"
#include "RimRegularLegendConfig.h"
#include "RimSummaryCurveFilter.h"
#include "RimSummaryPlot.h"
#include "RimSummaryPlotCollection.h"
@ -36,7 +39,6 @@
#include "cvfAssert.h"
#include "cafSelectionManagerTools.h"
//#include "cafPdmUiItem.h"
#include <QAction>
@ -56,6 +58,11 @@ bool RicNewSummaryPlotFeature::isCommandEnabled()
sumPlotColl = RiaSummaryTools::parentSummaryPlotCollection(selObj);
}
auto ensembleFilter = dynamic_cast<RimEnsembleCurveFilter*>(selObj);
auto ensembleFilterColl = dynamic_cast<RimEnsembleCurveFilterCollection*>(selObj);
auto legendConfig = dynamic_cast<RimRegularLegendConfig*>(selObj);
if (ensembleFilter || ensembleFilterColl || legendConfig) return false;
if (sumPlotColl) return true;
// Multiple case selections

View File

@ -39,6 +39,7 @@
#include "RimEclipsePropertyFilterCollection.h"
#include "RimEclipseStatisticsCase.h"
#include "RimEclipseView.h"
#include "RimEnsembleCurveFilterCollection.h"
#include "RimEnsembleCurveSetCollection.h"
#include "RimEnsembleCurveSet.h"
#include "RimFaultInView.h"
@ -476,6 +477,10 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection()
{
menuBuilder << "RicNewSummaryEnsembleCurveSetFeature";
}
else if (dynamic_cast<RimEnsembleCurveFilterCollection*>(uiItem))
{
menuBuilder << "RicNewEnsembleCurveFilterFeature";
}
else if (dynamic_cast<RimSummaryCaseMainCollection*>(uiItem))
{
menuBuilder << "RicImportSummaryCaseFeature";

View File

@ -852,7 +852,7 @@ QList<caf::PdmOptionItemInfo> RimRegularLegendConfig::calculateValueOptions(cons
if ( ( eclCellColors && eclCellColors->hasCategoryResult())
|| ( gmCellColors && gmCellColors->hasCategoryResult())
|| ( eclCellEdgColors && eclCellEdgColors->hasCategoryResult())
|| ( ensembleCurveSet && ensembleCurveSet->currentEnsembleParameterType() == RimEnsembleCurveSet::TYPE_TEXT) )
|| ( ensembleCurveSet && ensembleCurveSet->currentEnsembleParameterType() == EnsembleParameter::TYPE_TEXT) )
{
isCategoryResult = true;
}

View File

@ -32,6 +32,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RimSummaryPlotNameHelper.h
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSetCollection.h
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSet.h
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSetColorManager.h
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilter.h
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilterCollection.h
)
set (SOURCE_GROUP_SOURCE_FILES
@ -67,6 +69,8 @@ ${CMAKE_CURRENT_LIST_DIR}/RimSummaryPlotNameHelper.cpp
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSetCollection.cpp
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSet.cpp
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveSetColorManager.cpp
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilter.cpp
${CMAKE_CURRENT_LIST_DIR}/RimEnsembleCurveFilterCollection.cpp
)
list(APPEND CODE_HEADER_FILES

View File

@ -0,0 +1,204 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimEnsembleCurveFilter.h"
#include "RimEnsembleCurveFilterCollection.h"
#include "RimEnsembleCurveSet.h"
#include "cafPdmUiDoubleSliderEditor.h"
CAF_PDM_SOURCE_INIT(RimEnsembleCurveFilter, "RimEnsembleCurveFilter");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEnsembleCurveFilter::RimEnsembleCurveFilter()
{
CAF_PDM_InitObject("Ensemble Curve Filter", ":/EnsembleCurveSet16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_active, "Active", "Active", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_ensembleParameter, "EnsembleParameter", "Ensemble Parameter", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_minValue, "MinValue", "Min", "", "", "");
m_minValue.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&m_maxValue, "MaxValue", "Max", "", "", "");
m_maxValue.uiCapability()->setUiEditorTypeName(caf::PdmUiDoubleSliderEditor::uiEditorTypeName());
CAF_PDM_InitFieldNoDefault(&m_categories, "Categories", "Categories", "", "", "");
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCurveFilter::isActive() const
{
RimEnsembleCurveFilterCollection* coll;
firstAncestorOrThisOfType(coll);
return (!coll || coll->isActive()) && m_active;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimEnsembleCurveFilter::ensembleParameter() const
{
return m_ensembleParameter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimEnsembleCurveFilter::minValue() const
{
return m_minValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double RimEnsembleCurveFilter::maxValue() const
{
return m_maxValue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::set<QString> RimEnsembleCurveFilter::categories() const
{
const auto cs = m_categories();
return std::set<QString>(cs.begin(), cs.end());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QList<caf::PdmOptionItemInfo> RimEnsembleCurveFilter::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly)
{
QList<caf::PdmOptionItemInfo> options;
if (fieldNeedingOptions == &m_ensembleParameter)
{
auto curveSet = parentCurveSet();
if (curveSet)
{
auto names = curveSet->ensembleParameterNames();
for (auto& name : names)
{
options.push_back(caf::PdmOptionItemInfo(name, name));
}
}
}
else if (fieldNeedingOptions == &m_categories)
{
auto curveSet = parentCurveSet();
auto ensemble = curveSet ? curveSet->summaryCaseCollection() : nullptr;
auto eParam = ensemble ? ensemble->ensembleParameter(m_ensembleParameter) : EnsembleParameter();
if (eParam.isText())
{
for (const auto& val : eParam.values)
{
options.push_back(caf::PdmOptionItemInfo(val.toString(), val.toString()));
}
}
}
return options;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveFilter::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
auto curveSet = parentCurveSet();
if (changedField == &m_ensembleParameter)
{
auto ensemble = curveSet ? curveSet->summaryCaseCollection() : nullptr;
auto eParam = ensemble ? ensemble->ensembleParameter(m_ensembleParameter) : EnsembleParameter();
if (eParam.isNumeric())
{
m_minValue = eParam.minValue;
m_maxValue = eParam.maxValue;
}
else if (eParam.isText())
{
m_categories.v().clear();
for (const auto val : eParam.values)
{
m_categories.v().push_back(val.toString());
}
}
curveSet->updateAllCurves();
}
else if (changedField == &m_active ||
changedField == &m_minValue ||
changedField == &m_maxValue ||
changedField == &m_categories)
{
if (curveSet) curveSet->updateAllCurves();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveFilter::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
{
auto curveSet = parentCurveSet();
auto ensemble = curveSet ? curveSet->summaryCaseCollection() : nullptr;
auto eParam = ensemble ? ensemble->ensembleParameter(m_ensembleParameter) : EnsembleParameter();
uiOrdering.add(&m_ensembleParameter);
if (eParam.isNumeric())
{
uiOrdering.add(&m_minValue);
uiOrdering.add(&m_maxValue);
}
else if (eParam.isText())
{
uiOrdering.add(&m_categories);
}
uiOrdering.skipRemainingFields(true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimEnsembleCurveFilter::objectToggleField()
{
return &m_active;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEnsembleCurveSet * RimEnsembleCurveFilter::parentCurveSet() const
{
RimEnsembleCurveSet* curveSet;
firstAncestorOrThisOfType(curveSet);
return curveSet;
}

View File

@ -0,0 +1,60 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmField.h"
#include "cafPdmObject.h"
class RimEnsembleCurveSet;
//==================================================================================================
///
//==================================================================================================
class RimEnsembleCurveFilter : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimEnsembleCurveFilter();
bool isActive() const;
QString ensembleParameter() const;
double minValue() const;
double maxValue() const;
std::set<QString> categories() const;
virtual QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly) override;
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
protected:
virtual caf::PdmFieldHandle* objectToggleField();
private:
RimEnsembleCurveSet * parentCurveSet() const;
private:
caf::PdmField<bool> m_active;
caf::PdmField<QString> m_ensembleParameter;
caf::PdmField<double> m_minValue;
caf::PdmField<double> m_maxValue;
caf::PdmField<std::vector<QString>> m_categories;
};

View File

@ -0,0 +1,98 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 "RimEnsembleCurveFilterCollection.h"
#include "RiaApplication.h"
#include "RimEnsembleCurveFilter.h"
#include "RimEnsembleCurveSet.h"
#include <algorithm>
CAF_PDM_SOURCE_INIT(RimEnsembleCurveFilterCollection, "RimEnsembleCurveFilterCollection");
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEnsembleCurveFilterCollection::RimEnsembleCurveFilterCollection()
{
CAF_PDM_InitObject("Curve Filters", ":/SummaryCurveFilter16x16.png", "", "");
CAF_PDM_InitFieldNoDefault(&m_active, "Active", "Active", "", "", "");
m_active.uiCapability()->setUiHidden(true);
CAF_PDM_InitFieldNoDefault(&m_filters, "CurveFilters", "", "", "", "");
m_filters.uiCapability()->setUiHidden(true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEnsembleCurveFilter* RimEnsembleCurveFilterCollection::addFilter()
{
auto newFilter = new RimEnsembleCurveFilter();
m_filters.push_back(newFilter);
return newFilter;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveFilterCollection::removeFilter(RimEnsembleCurveFilter* filter)
{
std::remove_if(m_filters.begin(), m_filters.end(), [&](RimEnsembleCurveFilter* f) { return f == filter; });
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimEnsembleCurveFilter*> RimEnsembleCurveFilterCollection::filters() const
{
return m_filters.childObjects();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RimEnsembleCurveFilterCollection::isActive() const
{
return m_active;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimEnsembleCurveFilterCollection::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
{
if (changedField == &m_active)
{
RimEnsembleCurveSet* curveSet;
firstAncestorOrThisOfType(curveSet);
if (curveSet) curveSet->updateAllCurves();
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
caf::PdmFieldHandle* RimEnsembleCurveFilterCollection::objectToggleField()
{
return &m_active;
}

View File

@ -0,0 +1,53 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "cafPdmChildArrayField.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
class RimEnsembleCurveFilter;
//==================================================================================================
///
//==================================================================================================
class RimEnsembleCurveFilterCollection : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
public:
RimEnsembleCurveFilterCollection();
RimEnsembleCurveFilter* addFilter();
void removeFilter(RimEnsembleCurveFilter* filter);
std::vector<RimEnsembleCurveFilter*> filters() const;
bool isActive() const;
virtual void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue);
protected:
virtual caf::PdmFieldHandle* objectToggleField();
private:
caf::PdmField<bool> m_active;
caf::PdmChildArrayField<RimEnsembleCurveFilter*> m_filters;
};

View File

@ -21,8 +21,12 @@
#include "RiaApplication.h"
#include "RiaColorTables.h"
#include "SummaryPlotCommands/RicSummaryCurveCreator.h"
#include "RifReaderEclipseSummary.h"
#include "RimEnsembleCurveFilter.h"
#include "RimEnsembleCurveFilterCollection.h"
#include "RimEnsembleCurveSetCollection.h"
#include "RimEnsembleCurveSetColorManager.h"
#include "RimProject.h"
@ -49,6 +53,7 @@
#include "qwt_plot_curve.h"
#include "qwt_symbol.h"
#include <algorithm>
//--------------------------------------------------------------------------------------------------
/// Internal constants
@ -129,6 +134,9 @@ RimEnsembleCurveSet::RimEnsembleCurveSet()
m_legendConfig = new RimRegularLegendConfig();
m_legendConfig->setColorRange( RimEnsembleCurveSetColorManager::DEFAULT_ENSEMBLE_COLOR_RANGE );
CAF_PDM_InitFieldNoDefault(&m_curveFilters, "CurveFilters", "Curve Filters", "", "", "");
m_curveFilters = new RimEnsembleCurveFilterCollection();
CAF_PDM_InitField(&m_userDefinedName, "UserDefinedName", QString("Ensemble Curve Set"), "Curve Set Name", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_autoGeneratedName, "AutoGeneratedName", "Curve Set Name", "", "", "");
@ -323,22 +331,20 @@ RimEnsembleCurveSet::ColorMode RimEnsembleCurveSet::colorMode() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RimEnsembleCurveSet::EnsembleParameterType RimEnsembleCurveSet::currentEnsembleParameterType() const
EnsembleParameter::Type RimEnsembleCurveSet::currentEnsembleParameterType() const
{
if (m_colorMode() == BY_ENSEMBLE_PARAM)
{
RimSummaryCaseCollection* group = m_yValuesSummaryGroup();
QString parameterName = m_ensembleParameter();
if (group && !parameterName.isEmpty() && !group->allSummaryCases().empty())
if (group && !parameterName.isEmpty())
{
bool isTextParameter = group->allSummaryCases().front()->caseRealizationParameters() != nullptr ?
group->allSummaryCases().front()->caseRealizationParameters()->parameterValue(parameterName).isText() : false;
return isTextParameter ? TYPE_TEXT : TYPE_NUMERIC;
auto eParam = group->ensembleParameter(parameterName);
return eParam.type;
}
}
return TYPE_NONE;
return EnsembleParameter::TYPE_NONE;
}
//--------------------------------------------------------------------------------------------------
@ -395,7 +401,7 @@ void RimEnsembleCurveSet::fieldChangedByUi(const caf::PdmFieldHandle* changedFie
{
if (m_ensembleParameter().isEmpty())
{
auto params = ensembleParameters();
auto params = ensembleParameterNames();
m_ensembleParameter = !params.empty() ? params.front() : "";
}
updateCurveColors();
@ -525,6 +531,11 @@ void RimEnsembleCurveSet::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrd
{
uiTreeOrdering.add(m_legendConfig());
}
if (uiConfigName != RicSummaryCurveCreator::CONFIGURATION_NAME)
{
uiTreeOrdering.add(m_curveFilters);
}
uiTreeOrdering.skipRemainingChildren(true);
}
@ -588,14 +599,14 @@ QList<caf::PdmOptionItemInfo> RimEnsembleCurveSet::calculateValueOptions(const c
auto byEnsParamOption = caf::AppEnum<RimEnsembleCurveSet::ColorMode>(RimEnsembleCurveSet::BY_ENSEMBLE_PARAM);
options.push_back(caf::PdmOptionItemInfo(singleColorOption.uiText(), RimEnsembleCurveSet::SINGLE_COLOR));
if (!ensembleParameters().empty())
if (!ensembleParameterNames().empty())
{
options.push_back(caf::PdmOptionItemInfo(byEnsParamOption.uiText(), RimEnsembleCurveSet::BY_ENSEMBLE_PARAM));
}
}
else if (fieldNeedingOptions == &m_ensembleParameter)
{
for (const auto& param : ensembleParameters())
for (const auto& param : ensembleParameterNames())
{
options.push_back(caf::PdmOptionItemInfo(param, param));
}
@ -693,23 +704,15 @@ void RimEnsembleCurveSet::updateCurveColors()
if (group && !parameterName.isEmpty() && !group->allSummaryCases().empty())
{
bool isTextParameter = group->allSummaryCases().front()->caseRealizationParameters() != nullptr ?
group->allSummaryCases().front()->caseRealizationParameters()->parameterValue(parameterName).isText() : false;
auto ensembleParam = group->ensembleParameter(parameterName);
if (isTextParameter)
if (ensembleParam.isText())
{
std::set<QString> categories;
for (RimSummaryCase* rimCase : group->allSummaryCases())
for (auto value : ensembleParam.values)
{
if (rimCase->caseRealizationParameters() != nullptr)
{
RigCaseRealizationParameters::Value value = rimCase->caseRealizationParameters()->parameterValue(parameterName);
if (value.isText())
{
categories.insert(value.textValue());
}
}
categories.insert(value.toString());
}
std::vector<QString> categoryNames = std::vector<QString>(categories.begin(), categories.end());
@ -735,25 +738,18 @@ void RimEnsembleCurveSet::updateCurveColors()
curve->updateCurveAppearance();
}
}
else
else if(ensembleParam.isNumeric())
{
double minValue = DOUBLE_INF;
double maxValue = -DOUBLE_INF;
for (RimSummaryCase* rimCase : group->allSummaryCases())
for (auto value : ensembleParam.values)
{
if (rimCase->caseRealizationParameters() != nullptr)
double nValue = value.toDouble();
if (nValue != DOUBLE_INF)
{
RigCaseRealizationParameters::Value value = rimCase->caseRealizationParameters()->parameterValue(parameterName);
if (value.isNumeric())
{
double nValue = value.numericValue();
if (nValue != DOUBLE_INF)
{
if (nValue < minValue) minValue = nValue;
if (nValue > maxValue) maxValue = nValue;
}
}
if (nValue < minValue) minValue = nValue;
if (nValue > maxValue) maxValue = nValue;
}
}
@ -825,7 +821,8 @@ void RimEnsembleCurveSet::updateAllCurves()
{
if(m_showCurves)
{
for (auto& sumCase : group->allSummaryCases())
const auto filteredCases = filterEnsembleCases(group);
for (auto& sumCase : filteredCases)
{
RimSummaryCurve* curve = new RimSummaryCurve();
curve->setSummaryCaseY(sumCase);
@ -895,6 +892,82 @@ void RimEnsembleCurveSet::updateAllTextInPlot()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RimEnsembleCurveSet::ensembleParameterNames() const
{
RimSummaryCaseCollection* group = m_yValuesSummaryGroup;
std::set<QString> paramSet;
if (group)
{
for (RimSummaryCase* rimCase : group->allSummaryCases())
{
if (rimCase->caseRealizationParameters() != nullptr)
{
auto ps = rimCase->caseRealizationParameters()->parameters();
for (auto p : ps) paramSet.insert(p.first);
}
}
}
return std::vector<QString>(paramSet.begin(), paramSet.end());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCase*> RimEnsembleCurveSet::filterEnsembleCases(const RimSummaryCaseCollection* ensemble)
{
if (!ensemble) return std::vector<RimSummaryCase*>();
std::set<RimSummaryCase*> notIncludeCases;
if (!m_curveFilters->filters().empty())
{
for (const auto& sumCase : ensemble->allSummaryCases())
{
for (const auto& filter : m_curveFilters()->filters())
{
if (!filter->isActive()) continue;
auto eParam = ensemble->ensembleParameter(filter->ensembleParameter());
if (!eParam.isValid()) continue;
if (!sumCase->caseRealizationParameters()) continue;
auto crpValue = sumCase->caseRealizationParameters()->parameterValue(filter->ensembleParameter());
if (eParam.isNumeric())
{
if (!crpValue.isNumeric() ||
crpValue.numericValue() < filter->minValue() ||
crpValue.numericValue() > filter->maxValue())
{
notIncludeCases.insert(sumCase);
break;
}
}
else if (eParam.isText())
{
const auto& filterCategories = filter->categories();
if (!crpValue.isText() ||
std::count(filterCategories.begin(), filterCategories.end(), crpValue.textValue()) == 0)
{
notIncludeCases.insert(sumCase);
break;
}
}
}
}
}
std::vector<RimSummaryCase*> filteredCases;
const auto& allSumCaseVector = ensemble->allSummaryCases();
std::set<RimSummaryCase*> allCasesSet(allSumCaseVector.begin(), allSumCaseVector.end());
std::set_difference(allCasesSet.begin(), allCasesSet.end(),
notIncludeCases.begin(), notIncludeCases.end(),
std::inserter(filteredCases, filteredCases.end()));
return filteredCases;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -932,28 +1005,6 @@ void RimEnsembleCurveSet::updateEnsembleLegendItem()
m_qwtPlotCurveForLegendText->setItemAttribute(QwtPlotItem::Legend, showLegendItem);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<QString> RimEnsembleCurveSet::ensembleParameters() const
{
RimSummaryCaseCollection* group = m_yValuesSummaryGroup;
std::set<QString> paramSet;
if (group)
{
for (RimSummaryCase* rimCase : group->allSummaryCases())
{
if (rimCase->caseRealizationParameters() != nullptr)
{
auto ps = rimCase->caseRealizationParameters()->parameters();
for (auto p : ps) paramSet.insert(p.first);
}
}
}
return std::vector<QString>(paramSet.begin(), paramSet.end());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -1001,12 +1052,12 @@ void RimEnsembleCurveSet::updateLegendMappingMode()
{
switch (currentEnsembleParameterType())
{
case TYPE_TEXT:
case EnsembleParameter::TYPE_TEXT:
if (m_legendConfig->mappingMode() != RimRegularLegendConfig::MappingType::CATEGORY_INTEGER)
m_legendConfig->setMappingMode(RimRegularLegendConfig::MappingType::CATEGORY_INTEGER);
break;
case TYPE_NUMERIC:
case EnsembleParameter::TYPE_NUMERIC:
if (m_legendConfig->mappingMode() == RimRegularLegendConfig::MappingType::CATEGORY_INTEGER)
m_legendConfig->setMappingMode(RimRegularLegendConfig::MappingType::LINEAR_CONTINUOUS);
break;

View File

@ -24,6 +24,7 @@
#include "RiaDefines.h"
#include "RimRegularLegendConfig.h"
#include "RimSummaryCaseCollection.h"
#include "cafPdmFieldCvfColor.h"
#include "cafPdmChildArrayField.h"
@ -46,8 +47,10 @@ class RimSummaryAddress;
class RimSummaryFilter;
class RimSummaryPlotSourceStepping;
class RimSummaryCurveAutoName;
class RimEnsembleCurveFilterCollection;
class QKeyEvent;
//==================================================================================================
///
//==================================================================================================
@ -57,7 +60,6 @@ class RimEnsembleCurveSet : public caf::PdmObject
public:
enum ColorMode {SINGLE_COLOR, BY_ENSEMBLE_PARAM};
enum EnsembleParameterType {TYPE_NONE, TYPE_NUMERIC, TYPE_TEXT};
RimEnsembleCurveSet();
virtual ~RimEnsembleCurveSet();
@ -86,13 +88,16 @@ public:
ColorMode colorMode() const;
void updateEnsembleLegendItem();
EnsembleParameterType currentEnsembleParameterType() const;
EnsembleParameter::Type currentEnsembleParameterType() const;
void updateAllCurves();
RimEnsembleCurveSet* clone() const;
void showCurves(bool show);
void updateAllTextInPlot();
std::vector<QString> ensembleParameterNames() const;
std::vector<RimSummaryCase*> filterEnsembleCases(const RimSummaryCaseCollection* ensemble);
private:
caf::PdmFieldHandle* userDescriptionField() override;
@ -116,7 +121,6 @@ private:
void updateCurveColors();
void updateQwtPlotAxis();
std::vector<QString> ensembleParameters() const;
QString name() const;
QString createAutoName() const;
@ -143,6 +147,7 @@ private:
caf::PdmField<caf::AppEnum< RiaDefines::PlotAxis>> m_plotAxis;
caf::PdmChildField<RimRegularLegendConfig*> m_legendConfig;
caf::PdmChildField<RimEnsembleCurveFilterCollection*> m_curveFilters;
caf::PdmField<bool> m_isUsingAutoName;
caf::PdmField<QString> m_userDefinedName;

View File

@ -25,6 +25,8 @@
#include "RifSummaryReaderInterface.h"
#include <cmath>
CAF_PDM_SOURCE_INIT(RimSummaryCaseCollection, "SummaryCaseSubCollection");
//--------------------------------------------------------------------------------------------------
@ -78,7 +80,7 @@ void RimSummaryCaseCollection::addCase(RimSummaryCase* summaryCase)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCase*> RimSummaryCaseCollection::allSummaryCases()
std::vector<RimSummaryCase*> RimSummaryCaseCollection::allSummaryCases() const
{
return m_cases.childObjects();
}
@ -139,6 +141,99 @@ std::set<RifEclipseSummaryAddress> RimSummaryCaseCollection::calculateUnionOfSum
return addressUnion;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
EnsembleParameter RimSummaryCaseCollection::ensembleParameter(const QString& paramName) const
{
if (!isEnsemble() || paramName.isEmpty()) return EnsembleParameter();
EnsembleParameter eParam;
eParam.name = paramName;
bool numericValuesCount = 0;
bool textValuesCount = 0;
// Prepare case realization params, and check types
for (const auto& rimCase : allSummaryCases())
{
auto crp = rimCase->caseRealizationParameters();
if (!crp) continue;
auto value = crp->parameterValue(paramName);
if (!value.isValid()) continue;
if (value.isNumeric())
{
double numVal = value.numericValue();
eParam.values.push_back(QVariant(numVal));
if (numVal < eParam.minValue) eParam.minValue = numVal;
if (numVal > eParam.maxValue) eParam.maxValue = numVal;
numericValuesCount++;
}
else if (value.isText())
{
eParam.values.push_back(QVariant(value.textValue()));
textValuesCount++;
}
}
if (numericValuesCount && !textValuesCount)
{
eParam.type = EnsembleParameter::TYPE_NUMERIC;
}
else if (textValuesCount && !numericValuesCount)
{
eParam.type = EnsembleParameter::TYPE_TEXT;
}
if (numericValuesCount && textValuesCount)
{
// A mix of types have been added to parameter values
if (numericValuesCount > textValuesCount)
{
// Use numeric type
for (auto& val : eParam.values)
{
if (val.type() == QVariant::String)
{
val.setValue(std::numeric_limits<double>::infinity());
}
}
eParam.type = EnsembleParameter::TYPE_NUMERIC;
}
else
{
// Use text type
for (auto& val : eParam.values)
{
if (val.type() == QVariant::Double)
{
val.setValue(QString::number(val.value<double>()));
}
}
eParam.type = EnsembleParameter::TYPE_TEXT;
eParam.minValue = std::numeric_limits<double>::infinity();
eParam.maxValue = -std::numeric_limits<double>::infinity();
}
}
if (eParam.isText())
{
// Remove duplicate texts
std::set<QString> valueSet;
for (const auto& val : eParam.values)
{
valueSet.insert(val.toString());
}
eParam.values.clear();
for (const auto& val : valueSet)
{
eParam.values.push_back(QVariant(val));
}
}
return eParam;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -29,6 +29,33 @@
class RimSummaryCase;
//==================================================================================================
///
//==================================================================================================
class EnsembleParameter
{
public:
enum Type { TYPE_NONE, TYPE_NUMERIC, TYPE_TEXT };
QString name;
Type type;
std::vector<QVariant> values;
double minValue;
double maxValue;
EnsembleParameter() :
type(TYPE_NONE),
minValue(std::numeric_limits<double>::infinity()),
maxValue(-std::numeric_limits<double>::infinity()) { }
bool isValid() const { return !name.isEmpty() && type != TYPE_NONE; }
bool isNumeric() const { return type == TYPE_NUMERIC; }
bool isText() const { return type == TYPE_TEXT; }
};
//==================================================================================================
///
//==================================================================================================
class RimSummaryCaseCollection : public caf::PdmObject
{
CAF_PDM_HEADER_INIT;
@ -39,12 +66,14 @@ public:
void removeCase(RimSummaryCase* summaryCase);
void addCase(RimSummaryCase* summaryCase);
std::vector<RimSummaryCase*> allSummaryCases();
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;
EnsembleParameter ensembleParameter(const QString& paramName) const;
private:
caf::PdmFieldHandle* userDescriptionField() override;
void updateReferringCurveSets() const;

View File

@ -17,7 +17,7 @@
/////////////////////////////////////////////////////////////////////////////////
#include "RigCaseRealizationParameters.h"
#include <cmath>
#include <limits>
//--------------------------------------------------------------------------------------------------
///

View File

@ -26,7 +26,6 @@
#include <map>
#include <memory>
//==================================================================================================
//
//