mirror of
https://github.com/OPM/ResInsight.git
synced 2025-02-25 18:55:39 -06:00
Rename ApplicationCode to ApplicationLibCode
This commit is contained in:
@@ -0,0 +1,29 @@
|
||||
|
||||
set (SOURCE_GROUP_HEADER_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlot.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlotDataEntry.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlotCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPlotDataFilterCollection.h
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPlotDataFilterItem.h
|
||||
)
|
||||
|
||||
set (SOURCE_GROUP_SOURCE_FILES
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlot.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlotDataEntry.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimAnalysisPlotCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPlotDataFilterCollection.cpp
|
||||
${CMAKE_CURRENT_LIST_DIR}/RimPlotDataFilterItem.cpp
|
||||
)
|
||||
|
||||
list(APPEND CODE_HEADER_FILES
|
||||
${SOURCE_GROUP_HEADER_FILES}
|
||||
)
|
||||
|
||||
list(APPEND CODE_SOURCE_FILES
|
||||
${SOURCE_GROUP_SOURCE_FILES}
|
||||
)
|
||||
|
||||
list(APPEND QT_MOC_HEADERS
|
||||
)
|
||||
|
||||
source_group( "ProjectDataModel\\AnalysisPlots" FILES ${SOURCE_GROUP_HEADER_FILES} ${SOURCE_GROUP_SOURCE_FILES} ${CMAKE_CURRENT_LIST_DIR}/CMakeLists_files.cmake )
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,226 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 Equinor 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 "RiaSummaryCurveDefinition.h"
|
||||
|
||||
#include "RimPlot.h"
|
||||
#include "RimPlotDataFilterItem.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
#include "RimTimeStepFilter.h"
|
||||
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
class RiuSummaryQwtPlot;
|
||||
class RiuGroupedBarChartBuilder;
|
||||
|
||||
class RimAnalysisPlotDataEntry;
|
||||
class RiaSummaryCurveDefinitionAnalyser;
|
||||
class RimPlotAxisPropertiesInterface;
|
||||
class RimPlotAxisProperties;
|
||||
class RimPlotDataFilterCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimAnalysisPlot : public RimPlot
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
enum BarOrientation
|
||||
{
|
||||
BARS_HORIZONTAL,
|
||||
BARS_VERTICAL
|
||||
};
|
||||
|
||||
enum SortGroupType
|
||||
{
|
||||
NONE,
|
||||
SUMMARY_ITEM,
|
||||
QUANTITY,
|
||||
CASE,
|
||||
ENSEMBLE,
|
||||
VALUE,
|
||||
ABS_VALUE,
|
||||
OTHER_VALUE,
|
||||
ABS_OTHER_VALUE,
|
||||
TIME_STEP,
|
||||
};
|
||||
typedef caf::AppEnum<SortGroupType> SortGroupAppEnum;
|
||||
|
||||
using TimeStepFilterEnum = caf::AppEnum<RimTimeStepFilter::TimeStepFilterTypeEnum>;
|
||||
|
||||
public:
|
||||
RimAnalysisPlot();
|
||||
~RimAnalysisPlot() override;
|
||||
|
||||
void updateCaseNameHasChanged();
|
||||
|
||||
RimPlotDataFilterCollection* plotDataFilterCollection() const;
|
||||
|
||||
void setCurveDefinitions( const std::vector<RiaSummaryCurveDefinition>& curveDefinitions );
|
||||
void setTimeSteps( const std::vector<time_t>& timeSteps );
|
||||
|
||||
std::set<RifEclipseSummaryAddress> unfilteredAddresses();
|
||||
std::set<EnsembleParameter> ensembleParameters();
|
||||
EnsembleParameter ensembleParameter( const QString& ensembleParameterName );
|
||||
|
||||
void maxMinValueFromAddress( const RifEclipseSummaryAddress& address,
|
||||
RimPlotDataFilterItem::TimeStepSourceType timeStepSourceType,
|
||||
const std::vector<QDateTime>& timeRangeOrSelection,
|
||||
bool useAbsValue,
|
||||
double* min,
|
||||
double* max );
|
||||
|
||||
std::vector<time_t> selectedTimeSteps();
|
||||
|
||||
private:
|
||||
// Overridden PDM methods
|
||||
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
caf::PdmFieldHandle* userDescriptionField() override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly ) override;
|
||||
|
||||
std::set<time_t> allAvailableTimeSteps();
|
||||
|
||||
std::set<RimSummaryCase*> timestepDefiningSourceCases();
|
||||
std::set<RimSummaryCase*> allSourceCases();
|
||||
|
||||
void onFiltersChanged( const caf::SignalEmitter* emitter );
|
||||
|
||||
// RimViewWindow overrides
|
||||
|
||||
QWidget* viewWidget() override;
|
||||
void deleteViewWidget() override;
|
||||
void onLoadDataAndUpdate() override;
|
||||
void zoomAll() override {}
|
||||
QImage snapshotWindowContent() override;
|
||||
|
||||
// RimPlotWindow overrides
|
||||
|
||||
QString description() const override;
|
||||
void doUpdateLayout() override {}
|
||||
|
||||
// RimPlot Overrides
|
||||
|
||||
RiuQwtPlotWidget* doCreatePlotViewWidget( QWidget* mainWindowParent = nullptr ) override;
|
||||
RiuQwtPlotWidget* viewer() override;
|
||||
|
||||
void detachAllCurves() override;
|
||||
|
||||
void reattachAllCurves() override {}
|
||||
void updateAxes() override;
|
||||
void onAxisSelected( int axis, bool toggle ) override;
|
||||
void updateZoomInQwt() override {}
|
||||
void updateZoomFromQwt() override {}
|
||||
void setAutoScaleXEnabled( bool enabled ) override {}
|
||||
void setAutoScaleYEnabled( bool enabled ) override {}
|
||||
void updateLegend() override{};
|
||||
|
||||
QString asciiDataForPlotExport() const override { return ""; }
|
||||
caf::PdmObject* findPdmObjectFromQwtCurve( const QwtPlotCurve* curve ) const override { return nullptr; }
|
||||
|
||||
// Private methods
|
||||
|
||||
void cleanupBeforeClose();
|
||||
void addDataToChartBuilder( RiuGroupedBarChartBuilder& chartBuilder );
|
||||
void updatePlotTitle();
|
||||
|
||||
QString assignGroupingText( RimAnalysisPlot::SortGroupType sortGroup,
|
||||
const RiaSummaryCurveDefinition dataEntry,
|
||||
const QString& timestepString ) const;
|
||||
|
||||
RiaSummaryCurveDefinitionAnalyser* getOrCreateSelectedCurveDefAnalyser();
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefinitions() const;
|
||||
std::vector<RiaSummaryCurveDefinition> filteredCurveDefs();
|
||||
void applyFilter( const RimPlotDataFilterItem* filter,
|
||||
std::set<RimSummaryCase*>* filteredSumCases,
|
||||
std::set<RifEclipseSummaryAddress>* filteredSummaryItems );
|
||||
|
||||
static std::vector<size_t> findTimestepIndices( std::vector<time_t> selectedTimesteps,
|
||||
const std::vector<time_t>& timesteps );
|
||||
|
||||
std::set<RimPlotAxisPropertiesInterface*> allPlotAxes() const;
|
||||
|
||||
void connectAxisSignals( RimPlotAxisProperties* axis );
|
||||
void axisSettingsChanged( const caf::SignalEmitter* emitter );
|
||||
void axisLogarithmicChanged( const caf::SignalEmitter* emitter, bool isLogarithmic );
|
||||
|
||||
void buildTestPlot( RiuGroupedBarChartBuilder& chartBuilder );
|
||||
|
||||
int barTextFontSize() const;
|
||||
void initAfterRead() override;
|
||||
|
||||
private:
|
||||
void onCaseRemoved( const SignalEmitter* emitter, RimSummaryCase* summaryCase );
|
||||
void connectAllCaseSignals();
|
||||
|
||||
private:
|
||||
std::unique_ptr<RiaSummaryCurveDefinitionAnalyser> m_analyserOfSelectedCurveDefs;
|
||||
|
||||
QPointer<RiuQwtPlotWidget> m_plotWidget;
|
||||
|
||||
// Fields
|
||||
|
||||
caf::PdmField<QString> m_selectedVarsUiField;
|
||||
caf::PdmField<bool> m_selectVariablesButtonField;
|
||||
|
||||
caf::PdmChildArrayField<RimAnalysisPlotDataEntry*> m_analysisPlotDataSelection;
|
||||
|
||||
caf::PdmField<TimeStepFilterEnum> m_timeStepFilter;
|
||||
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
|
||||
|
||||
caf::PdmPtrField<RimSummaryCase*> m_referenceCase;
|
||||
|
||||
caf::PdmField<bool> m_useAutoPlotTitle;
|
||||
caf::PdmField<QString> m_description;
|
||||
|
||||
caf::PdmField<caf::AppEnum<BarOrientation>> m_barOrientation;
|
||||
|
||||
caf::PdmField<SortGroupAppEnum> m_majorGroupType;
|
||||
caf::PdmField<SortGroupAppEnum> m_mediumGroupType;
|
||||
caf::PdmField<SortGroupAppEnum> m_minorGroupType;
|
||||
caf::PdmField<SortGroupAppEnum> m_valueSortOperation;
|
||||
|
||||
caf::PdmField<bool> m_useTopBarsFilter;
|
||||
caf::PdmField<int> m_maxBarCount;
|
||||
|
||||
caf::PdmField<SortGroupAppEnum> m_sortGroupForColors;
|
||||
|
||||
caf::PdmField<bool> m_useBarText;
|
||||
caf::PdmField<bool> m_useCaseInBarText;
|
||||
caf::PdmField<bool> m_useEnsembleInBarText;
|
||||
caf::PdmField<bool> m_useSummaryItemInBarText;
|
||||
caf::PdmField<bool> m_useTimeStepInBarText;
|
||||
caf::PdmField<bool> m_useQuantityInBarText;
|
||||
caf::PdmField<caf::FontTools::RelativeSizeEnum> m_barTextFontSize;
|
||||
|
||||
caf::PdmChildField<RimPlotAxisProperties*> m_valueAxisProperties;
|
||||
caf::PdmChildField<RimPlotDataFilterCollection*> m_plotDataFilterCollection;
|
||||
};
|
||||
@@ -0,0 +1,266 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor 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 "RimAnalysisPlotCollection.h"
|
||||
|
||||
#include "RimAnalysisPlot.h"
|
||||
#include "RimPlotDataFilterCollection.h"
|
||||
#include "RimProject.h"
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimAnalysisPlotCollection, "AnalysisPlotCollection" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotCollection::RimAnalysisPlotCollection()
|
||||
{
|
||||
CAF_PDM_InitObject( "Analysis Plots", ":/AnalysisPlots16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_analysisPlots, "AnalysisPlots", "Analysis Plots", "", "", "" );
|
||||
m_analysisPlots.uiCapability()->setUiHidden( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotCollection::~RimAnalysisPlotCollection()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlot* RimAnalysisPlotCollection::createAnalysisPlot()
|
||||
{
|
||||
RimAnalysisPlot* plot = new RimAnalysisPlot();
|
||||
plot->setAsPlotMdiWindow();
|
||||
|
||||
if ( firstEnsemble() )
|
||||
{
|
||||
applyFirstEnsembleFieldAddressesToPlot( plot, "FOPT" );
|
||||
}
|
||||
else if ( firstSummaryCaseCollection() )
|
||||
{
|
||||
applyFirstSummaryCaseCollectionAndFieldAddressesToPlot( plot, "FOPT" );
|
||||
}
|
||||
else
|
||||
{
|
||||
applyAllSummaryCasesAndFieldAddressesToPlot( plot, "FOPT" );
|
||||
}
|
||||
|
||||
// plot->enableAutoPlotTitle( true );
|
||||
addPlot( plot );
|
||||
|
||||
plot->loadDataAndUpdate();
|
||||
|
||||
auto filter = plot->plotDataFilterCollection()->addFilter();
|
||||
filter->updateMaxMinAndDefaultValues( true );
|
||||
|
||||
plot->loadDataAndUpdate();
|
||||
plot->updateConnectedEditors();
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlot* RimAnalysisPlotCollection::createAnalysisPlot( RimSummaryCaseCollection* ensemble,
|
||||
const QString& quantityName,
|
||||
std::time_t timeStep )
|
||||
{
|
||||
RimAnalysisPlot* plot = new RimAnalysisPlot();
|
||||
plot->setAsPlotMdiWindow();
|
||||
|
||||
applySummaryCaseCollectionAndFieldAddressToPlot( plot, ensemble, quantityName.toStdString() );
|
||||
plot->setTimeSteps( { timeStep } );
|
||||
|
||||
// plot->enableAutoPlotTitle( true );
|
||||
addPlot( plot );
|
||||
|
||||
plot->loadDataAndUpdate();
|
||||
|
||||
auto filter = plot->plotDataFilterCollection()->addFilter();
|
||||
filter->updateMaxMinAndDefaultValues( true );
|
||||
|
||||
plot->loadDataAndUpdate();
|
||||
plot->updateConnectedEditors();
|
||||
|
||||
return plot;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::updateSummaryNameHasChanged()
|
||||
{
|
||||
for ( RimAnalysisPlot* plot : m_analysisPlots )
|
||||
{
|
||||
plot->updateCaseNameHasChanged();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimAnalysisPlot*> RimAnalysisPlotCollection::plots() const
|
||||
{
|
||||
return m_analysisPlots.childObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
size_t RimAnalysisPlotCollection::plotCount() const
|
||||
{
|
||||
return m_analysisPlots.size();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::applyFirstEnsembleFieldAddressesToPlot( RimAnalysisPlot* plot,
|
||||
const std::string& quantityName )
|
||||
{
|
||||
auto ensemble = firstSummaryCaseCollection();
|
||||
if ( ensemble )
|
||||
{
|
||||
applySummaryCaseCollectionAndFieldAddressToPlot( plot, ensemble, quantityName );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::applyFirstSummaryCaseCollectionAndFieldAddressesToPlot( RimAnalysisPlot* plot,
|
||||
const std::string& quantityName /*= "" */ )
|
||||
{
|
||||
auto summaryCaseCollection = firstSummaryCaseCollection();
|
||||
if ( summaryCaseCollection )
|
||||
{
|
||||
applySummaryCaseCollectionAndFieldAddressToPlot( plot, summaryCaseCollection, quantityName );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::applyAllSummaryCasesAndFieldAddressesToPlot( RimAnalysisPlot* plot,
|
||||
const std::string& quantityName /*= "" */ )
|
||||
{
|
||||
std::vector<RimSummaryCase*> allSummaryCases;
|
||||
RimProject::current()->descendantsOfType( allSummaryCases );
|
||||
|
||||
if ( !allSummaryCases.empty() )
|
||||
{
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefs;
|
||||
|
||||
for ( auto summaryCase : allSummaryCases )
|
||||
{
|
||||
curveDefs.push_back(
|
||||
RiaSummaryCurveDefinition( summaryCase, RifEclipseSummaryAddress::fieldAddress( quantityName ), false ) );
|
||||
}
|
||||
|
||||
plot->setCurveDefinitions( curveDefs );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::applySummaryCaseCollectionAndFieldAddressToPlot( RimAnalysisPlot* plot,
|
||||
RimSummaryCaseCollection* summaryCaseCollection,
|
||||
const std::string& quantityName )
|
||||
{
|
||||
if ( summaryCaseCollection )
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> allAddresses = summaryCaseCollection->ensembleSummaryAddresses();
|
||||
std::vector<RiaSummaryCurveDefinition> curveDefs;
|
||||
if ( allAddresses.empty() )
|
||||
{
|
||||
for ( auto summaryCase : summaryCaseCollection->allSummaryCases() )
|
||||
{
|
||||
curveDefs.push_back( RiaSummaryCurveDefinition( summaryCase,
|
||||
RifEclipseSummaryAddress::fieldAddress( quantityName ),
|
||||
false ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( auto address : allAddresses )
|
||||
{
|
||||
if ( address.category() == RifEclipseSummaryAddress::SUMMARY_FIELD )
|
||||
{
|
||||
if ( quantityName.empty() || quantityName == address.quantityName() )
|
||||
{
|
||||
for ( auto summaryCase : summaryCaseCollection->allSummaryCases() )
|
||||
{
|
||||
curveDefs.push_back( RiaSummaryCurveDefinition( summaryCase, address, false ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
plot->setCurveDefinitions( curveDefs );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCaseCollection* RimAnalysisPlotCollection::firstEnsemble() const
|
||||
{
|
||||
std::vector<RimSummaryCaseCollection*> allSummaryCaseCollections;
|
||||
RimProject::current()->descendantsOfType( allSummaryCaseCollections );
|
||||
for ( auto summaryCaseCollection : allSummaryCaseCollections )
|
||||
{
|
||||
if ( summaryCaseCollection->isEnsemble() ) return summaryCaseCollection;
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCaseCollection* RimAnalysisPlotCollection::firstSummaryCaseCollection() const
|
||||
{
|
||||
std::vector<RimSummaryCaseCollection*> allSummaryCaseCollections;
|
||||
RimProject::current()->descendantsOfType( allSummaryCaseCollections );
|
||||
|
||||
if ( !allSummaryCaseCollections.empty() ) return allSummaryCaseCollections.front();
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::insertPlot( RimAnalysisPlot* analysisPlot, size_t index )
|
||||
{
|
||||
m_analysisPlots.insert( index, analysisPlot );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotCollection::removePlot( RimAnalysisPlot* analysisPlot )
|
||||
{
|
||||
m_analysisPlots.removeChildObject( analysisPlot );
|
||||
updateAllRequiredEditors();
|
||||
}
|
||||
@@ -0,0 +1,68 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020- Equinor 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 "RimAbstractPlotCollection.h"
|
||||
#include "RimAnalysisPlot.h"
|
||||
|
||||
#include "cafPdmChildArrayField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include <ctime>
|
||||
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimAnalysisPlotCollection : public caf::PdmObject, public RimTypedPlotCollection<RimAnalysisPlot>
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimAnalysisPlotCollection();
|
||||
~RimAnalysisPlotCollection() override;
|
||||
|
||||
RimAnalysisPlot* createAnalysisPlot();
|
||||
RimAnalysisPlot*
|
||||
createAnalysisPlot( RimSummaryCaseCollection* ensemble, const QString& quantityName, std::time_t timeStep );
|
||||
|
||||
void updateSummaryNameHasChanged();
|
||||
|
||||
std::vector<RimAnalysisPlot*> plots() const final;
|
||||
size_t plotCount() const final;
|
||||
void insertPlot( RimAnalysisPlot* analysisPlot, size_t index ) final;
|
||||
void removePlot( RimAnalysisPlot* analysisPlot ) final;
|
||||
|
||||
private:
|
||||
void applyFirstEnsembleFieldAddressesToPlot( RimAnalysisPlot* plot, const std::string& quantityName = "" );
|
||||
void applyFirstSummaryCaseCollectionAndFieldAddressesToPlot( RimAnalysisPlot* plot,
|
||||
const std::string& quantityName = "" );
|
||||
void applyAllSummaryCasesAndFieldAddressesToPlot( RimAnalysisPlot* plot, const std::string& quantityName = "" );
|
||||
void applySummaryCaseCollectionAndFieldAddressToPlot( RimAnalysisPlot* plot,
|
||||
RimSummaryCaseCollection* summaryCaseCollection,
|
||||
const std::string& quantityName );
|
||||
|
||||
RimSummaryCaseCollection* firstEnsemble() const;
|
||||
RimSummaryCaseCollection* firstSummaryCaseCollection() const;
|
||||
|
||||
private:
|
||||
caf::PdmChildArrayField<RimAnalysisPlot*> m_analysisPlots;
|
||||
};
|
||||
@@ -0,0 +1,121 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 Equinor 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 "RimAnalysisPlotDataEntry.h"
|
||||
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "RimSummaryAddress.h"
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimAnalysisPlotDataEntry, "AnalysisPlotDataEntry" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotDataEntry::RimAnalysisPlotDataEntry()
|
||||
{
|
||||
CAF_PDM_InitObject( "Data Entry", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_summaryCase, "SummaryCase", "Case", "", "", "" );
|
||||
m_summaryCase.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_summaryCase.uiCapability()->setAutoAddingOptionFromValue( false );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_ensemble, "Ensemble", "Ensemble", "", "", "" );
|
||||
m_ensemble.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_ensemble.uiCapability()->setAutoAddingOptionFromValue( false );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_summaryAddress, "SummaryAddress", "Summary Address", "", "", "" );
|
||||
m_summaryAddress.uiCapability()->setUiHidden( true );
|
||||
m_summaryAddress.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_summaryAddress = new RimSummaryAddress;
|
||||
|
||||
CAF_PDM_InitField( &m_isEnsembleCurve, "IsEnsembleCurve", false, "Is Ensemble Curve", "", "", "" );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimAnalysisPlotDataEntry::~RimAnalysisPlotDataEntry()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimAnalysisPlotDataEntry::setFromCurveDefinition( const RiaSummaryCurveDefinition& curveDef )
|
||||
{
|
||||
m_summaryAddress->setAddress( curveDef.summaryAddress() );
|
||||
if ( curveDef.ensemble() )
|
||||
{
|
||||
m_ensemble = curveDef.ensemble();
|
||||
}
|
||||
m_summaryCase = curveDef.summaryCase();
|
||||
m_isEnsembleCurve = curveDef.isEnsembleCurve();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RiaSummaryCurveDefinition RimAnalysisPlotDataEntry::curveDefinition() const
|
||||
{
|
||||
if ( m_summaryCase() )
|
||||
{
|
||||
return RiaSummaryCurveDefinition( m_summaryCase(), m_summaryAddress->address(), m_isEnsembleCurve );
|
||||
}
|
||||
else
|
||||
{
|
||||
CAF_ASSERT( m_ensemble() );
|
||||
return RiaSummaryCurveDefinition( m_ensemble(), m_summaryAddress->address() );
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCase* RimAnalysisPlotDataEntry::summaryCase() const
|
||||
{
|
||||
return m_summaryCase;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimSummaryCaseCollection* RimAnalysisPlotDataEntry::ensemble() const
|
||||
{
|
||||
return m_ensemble;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseSummaryAddress RimAnalysisPlotDataEntry::summaryAddress() const
|
||||
{
|
||||
return m_summaryAddress->address();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimAnalysisPlotDataEntry::isEnsembleCurve() const
|
||||
{
|
||||
return m_isEnsembleCurve;
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 Equinor 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 "RiaSummaryCurveDefinition.h"
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
#include "cafPdmPtrField.h"
|
||||
|
||||
class RimSummaryCase;
|
||||
class RimSummaryAddress;
|
||||
class RimSummaryCaseCollection;
|
||||
|
||||
class RimAnalysisPlotDataEntry : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
RimAnalysisPlotDataEntry();
|
||||
~RimAnalysisPlotDataEntry() override;
|
||||
|
||||
void setFromCurveDefinition( const RiaSummaryCurveDefinition& curveDef );
|
||||
RiaSummaryCurveDefinition curveDefinition() const;
|
||||
|
||||
RimSummaryCase* summaryCase() const;
|
||||
RimSummaryCaseCollection* ensemble() const;
|
||||
RifEclipseSummaryAddress summaryAddress() const;
|
||||
bool isEnsembleCurve() const;
|
||||
|
||||
private:
|
||||
caf::PdmPtrField<RimSummaryCase*> m_summaryCase;
|
||||
caf::PdmPtrField<RimSummaryCaseCollection*> m_ensemble;
|
||||
caf::PdmChildField<RimSummaryAddress*> m_summaryAddress;
|
||||
caf::PdmField<bool> m_isEnsembleCurve;
|
||||
};
|
||||
@@ -0,0 +1,92 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 Equinor 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 "RimPlotDataFilterCollection.h"
|
||||
#include "RimPlotDataFilterItem.h"
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimPlotDataFilterCollection, "PlotDataFilterCollection" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimPlotDataFilterCollection::RimPlotDataFilterCollection()
|
||||
: filtersChanged( this )
|
||||
{
|
||||
CAF_PDM_InitObject( "Plot Data Filters", ":/AnalysisPlotFilter16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_isActive, "IsActive", true, "IsActive", "", "", "" );
|
||||
m_isActive.uiCapability()->setUiHidden( true );
|
||||
CAF_PDM_InitFieldNoDefault( &m_filters, "PlotDataFiltersField", "", "", "", "" );
|
||||
m_filters.uiCapability()->setUiTreeHidden( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimPlotDataFilterItem* RimPlotDataFilterCollection::addFilter()
|
||||
{
|
||||
auto newFilter = new RimPlotDataFilterItem();
|
||||
m_filters.push_back( newFilter );
|
||||
|
||||
newFilter->updateMaxMinAndDefaultValues( false );
|
||||
newFilter->filterChanged.connect( this, &RimPlotDataFilterCollection::onFilterChanged );
|
||||
|
||||
filtersChanged.send();
|
||||
|
||||
return newFilter;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotDataFilterCollection::removeFilter( RimPlotDataFilterItem* filter )
|
||||
{
|
||||
m_filters.removeChildObject( filter );
|
||||
delete filter;
|
||||
|
||||
filtersChanged.send();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<RimPlotDataFilterItem*> RimPlotDataFilterCollection::filters() const
|
||||
{
|
||||
return m_filters.childObjects();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimPlotDataFilterCollection::isActive() const
|
||||
{
|
||||
return m_isActive();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimPlotDataFilterCollection::objectToggleField()
|
||||
{
|
||||
return &m_isActive;
|
||||
}
|
||||
|
||||
void RimPlotDataFilterCollection::onFilterChanged( const caf::SignalEmitter* emitter )
|
||||
{
|
||||
filtersChanged.send();
|
||||
}
|
||||
@@ -0,0 +1,52 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 Equinor 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 RimPlotDataFilterItem;
|
||||
|
||||
//==================================================================================================
|
||||
///
|
||||
//==================================================================================================
|
||||
class RimPlotDataFilterCollection : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::Signal<> filtersChanged;
|
||||
|
||||
public:
|
||||
RimPlotDataFilterCollection();
|
||||
|
||||
RimPlotDataFilterItem* addFilter();
|
||||
void removeFilter( RimPlotDataFilterItem* filter );
|
||||
std::vector<RimPlotDataFilterItem*> filters() const;
|
||||
bool isActive() const;
|
||||
|
||||
private:
|
||||
caf::PdmFieldHandle* objectToggleField() override;
|
||||
|
||||
void onFilterChanged( const caf::SignalEmitter* emitter );
|
||||
|
||||
private:
|
||||
caf::PdmField<bool> m_isActive;
|
||||
caf::PdmChildArrayField<RimPlotDataFilterItem*> m_filters;
|
||||
};
|
||||
@@ -0,0 +1,481 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 Equinor 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 "RimPlotDataFilterItem.h"
|
||||
|
||||
#include "RimAnalysisPlot.h"
|
||||
#include "RimSummaryAddress.h"
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "RifSummaryReaderInterface.h"
|
||||
#include "RimSummaryCase.h"
|
||||
|
||||
#include "QFontMetrics"
|
||||
#include "cafPdmUiActionPushButtonEditor.h"
|
||||
#include "cafPdmUiDoubleSliderEditor.h"
|
||||
#include "cafPdmUiLineEditor.h"
|
||||
#include "cafPdmUiListEditor.h"
|
||||
#include "cafPdmUiPushButtonEditor.h"
|
||||
|
||||
#include <limits>
|
||||
|
||||
namespace caf
|
||||
{
|
||||
template <>
|
||||
void caf::AppEnum<RimPlotDataFilterItem::FilterTarget>::setUp()
|
||||
{
|
||||
addItem( RimPlotDataFilterItem::SUMMARY_ITEM, "SUMMARY_ITEM", "summary items" );
|
||||
addItem( RimPlotDataFilterItem::SUMMARY_CASE, "SUMMARY_CASE", "summary cases" );
|
||||
addItem( RimPlotDataFilterItem::ENSEMBLE_CASE, "ENSEMBLE_CASE", "ensemble cases" );
|
||||
|
||||
setDefault( RimPlotDataFilterItem::ENSEMBLE_CASE );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimPlotDataFilterItem::FilterOperation>::setUp()
|
||||
{
|
||||
addItem( RimPlotDataFilterItem::RANGE, "RANGE", "within range" );
|
||||
addItem( RimPlotDataFilterItem::TOP_N, "TOP_N", "top" );
|
||||
addItem( RimPlotDataFilterItem::BOTTOM_N, "BOTTOM_N", "bottom" );
|
||||
|
||||
setDefault( RimPlotDataFilterItem::RANGE );
|
||||
}
|
||||
|
||||
template <>
|
||||
void caf::AppEnum<RimPlotDataFilterItem::TimeStepSourceType>::setUp()
|
||||
{
|
||||
addItem( RimPlotDataFilterItem::PLOT_SOURCE_TIMESTEPS, "PLOT_SOURCE_TIMESTEPS", "plot source timesteps" );
|
||||
addItem( RimPlotDataFilterItem::LAST_TIMESTEP, "LAST_TIMESTEP", "last timestep" );
|
||||
addItem( RimPlotDataFilterItem::LAST_TIMESTEP_WITH_HISTORY, "LAST_TIMESTEP_WITH_HISTORY", "last timestep with history" );
|
||||
addItem( RimPlotDataFilterItem::FIRST_TIMESTEP, "FIRST_TIMESTEP", "first timestep" );
|
||||
addItem( RimPlotDataFilterItem::ALL_TIMESTEPS, "ALL_TIMESTEPS", "all timesteps" );
|
||||
addItem( RimPlotDataFilterItem::SELECT_TIMESTEPS, "SELECT_TIMESTEPS", "selected timesteps" );
|
||||
addItem( RimPlotDataFilterItem::SELECT_TIMESTEP_RANGE, "SELECT_TIMESTEP_RANGE", "timestep range" );
|
||||
|
||||
setDefault( RimPlotDataFilterItem::PLOT_SOURCE_TIMESTEPS );
|
||||
}
|
||||
|
||||
} // namespace caf
|
||||
|
||||
CAF_PDM_SOURCE_INIT( RimPlotDataFilterItem, "PlotDataFilterItem" );
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimPlotDataFilterItem::RimPlotDataFilterItem()
|
||||
: m_lowerLimit( -std::numeric_limits<double>::infinity() )
|
||||
, m_upperLimit( std::numeric_limits<double>::infinity() )
|
||||
, filterChanged( this )
|
||||
{
|
||||
CAF_PDM_InitObject( "Plot Data Filter", ":/AnalysisPlotFilter16x16.png", "", "" );
|
||||
|
||||
CAF_PDM_InitField( &m_isActive, "IsActive", true, "Active", "", "", "" );
|
||||
m_isActive.uiCapability()->setUiHidden( true );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_filterTarget, "FilterTarget", "Use only the", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_filterAddress, "FilterAddressField", "Filter Address", "", "", "" );
|
||||
m_filterAddress.uiCapability()->setUiTreeHidden( true );
|
||||
m_filterAddress.uiCapability()->setUiTreeChildrenHidden( true );
|
||||
m_filterAddress = new RimSummaryAddress();
|
||||
|
||||
CAF_PDM_InitField( &m_filterEnsembleParameter, "QuantityText", QString( "" ), "where", "", "", "" );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_filterQuantityUiField, "SelectedVariableDisplayVar", "where", "", "", "" );
|
||||
m_filterQuantityUiField.xmlCapability()->disableIO();
|
||||
m_filterQuantityUiField.uiCapability()->setUiEditorTypeName( caf::PdmUiLineEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitField( &m_filterQuantitySelectButton, "SelectAddress", false, "...", "", "", "" );
|
||||
caf::PdmUiActionPushButtonEditor::configureEditorForField( &m_filterQuantitySelectButton );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_filterOperation, "FilterOperation", "is", "", "", "" );
|
||||
CAF_PDM_InitField( &m_topBottomN, "MinTopN", 20, "N", "", "", "" );
|
||||
m_topBottomN.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
|
||||
CAF_PDM_InitField( &m_max, "Max", m_upperLimit, "Max", "", "", "" );
|
||||
m_max.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
|
||||
CAF_PDM_InitField( &m_min, "Min", m_lowerLimit, "Min", "", "", "" );
|
||||
m_min.uiCapability()->setUiEditorTypeName( caf::PdmUiDoubleSliderEditor::uiEditorTypeName() );
|
||||
|
||||
CAF_PDM_InitFieldNoDefault( &m_ensembleParameterValueCategories, "EnsembleParameterValueCategories", "one of", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_consideredTimestepsType, "ConsideredTimestepsType", "at the", "", "", "" );
|
||||
CAF_PDM_InitFieldNoDefault( &m_explicitlySelectedTimeSteps, "ExplicitlySelectedTimeSteps", "TimeSteps", "", "", "" );
|
||||
m_explicitlySelectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiListEditor::uiEditorTypeName() );
|
||||
m_explicitlySelectedTimeSteps.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
||||
|
||||
setDeletable( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimPlotDataFilterItem::~RimPlotDataFilterItem()
|
||||
{
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
bool RimPlotDataFilterItem::isValid() const
|
||||
{
|
||||
if ( m_filterTarget() == ENSEMBLE_CASE && ensembleParameterName().isEmpty() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else if ( ( m_filterTarget() == SUMMARY_CASE || m_filterTarget() == SUMMARY_ITEM ) && !summaryAddress().isValid() )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RifEclipseSummaryAddress RimPlotDataFilterItem::summaryAddress() const
|
||||
{
|
||||
CVF_ASSERT( m_filterTarget() == SUMMARY_CASE || m_filterTarget() == SUMMARY_ITEM );
|
||||
return m_filterAddress->address();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QString RimPlotDataFilterItem::ensembleParameterName() const
|
||||
{
|
||||
CVF_ASSERT( m_filterTarget() == ENSEMBLE_CASE );
|
||||
return m_filterEnsembleParameter();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<double, double> RimPlotDataFilterItem::filterRangeMinMax() const
|
||||
{
|
||||
CVF_ASSERT( m_filterOperation() == RANGE );
|
||||
return std::make_pair( m_min(), m_max() );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
int RimPlotDataFilterItem::topBottomN() const
|
||||
{
|
||||
CVF_ASSERT( m_filterOperation() != RANGE );
|
||||
return m_topBottomN;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<QString> RimPlotDataFilterItem::selectedEnsembleParameterCategories() const
|
||||
{
|
||||
CVF_ASSERT( m_filterTarget() == ENSEMBLE_CASE );
|
||||
return m_ensembleParameterValueCategories;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
RimPlotDataFilterItem::TimeStepSourceType RimPlotDataFilterItem::consideredTimeStepsType() const
|
||||
{
|
||||
CVF_ASSERT( m_filterTarget() != ENSEMBLE_CASE );
|
||||
return m_consideredTimestepsType();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::pair<time_t, time_t> RimPlotDataFilterItem::timeRangeMinMax() const
|
||||
{
|
||||
CVF_ASSERT( m_consideredTimestepsType() == SELECT_TIMESTEP_RANGE );
|
||||
|
||||
if ( m_explicitlySelectedTimeSteps().size() >= 2 )
|
||||
{
|
||||
time_t minTime = m_explicitlySelectedTimeSteps().front().toTime_t();
|
||||
time_t maxTime = m_explicitlySelectedTimeSteps().back().toTime_t();
|
||||
|
||||
return std::make_pair( minTime, maxTime );
|
||||
}
|
||||
return std::make_pair( time_t( 0 ), time_t( 0 ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
std::vector<time_t> RimPlotDataFilterItem::explicitlySelectedTimeSteps() const
|
||||
{
|
||||
CVF_ASSERT( m_consideredTimestepsType == RimPlotDataFilterItem::SELECT_TIMESTEPS );
|
||||
|
||||
std::vector<time_t> selectedTimesteps;
|
||||
{
|
||||
for ( const QDateTime& dateTime : m_explicitlySelectedTimeSteps() )
|
||||
{
|
||||
selectedTimesteps.push_back( dateTime.toTime_t() );
|
||||
}
|
||||
}
|
||||
|
||||
return selectedTimesteps;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotDataFilterItem::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
||||
const QVariant& oldValue,
|
||||
const QVariant& newValue )
|
||||
{
|
||||
if ( changedField == &m_filterTarget )
|
||||
{
|
||||
this->updateMaxMinAndDefaultValues( true );
|
||||
}
|
||||
else if ( changedField == &m_filterQuantityUiField )
|
||||
{
|
||||
m_filterAddress->setAddress( m_filterQuantityUiField );
|
||||
this->updateMaxMinAndDefaultValues( true );
|
||||
}
|
||||
else if ( changedField == &m_filterEnsembleParameter )
|
||||
{
|
||||
this->updateMaxMinAndDefaultValues( true );
|
||||
}
|
||||
else if ( changedField == &m_filterOperation )
|
||||
{
|
||||
this->updateMaxMinAndDefaultValues( false );
|
||||
}
|
||||
else if ( changedField == &m_consideredTimestepsType || changedField == &m_explicitlySelectedTimeSteps )
|
||||
{
|
||||
this->updateMaxMinAndDefaultValues( false );
|
||||
}
|
||||
filterChanged.send();
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
QList<caf::PdmOptionItemInfo>
|
||||
RimPlotDataFilterItem::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions, bool* useOptionsOnly )
|
||||
{
|
||||
QList<caf::PdmOptionItemInfo> options;
|
||||
RimAnalysisPlot* parentPlot;
|
||||
this->firstAncestorOrThisOfTypeAsserted( parentPlot );
|
||||
|
||||
if ( fieldNeedingOptions == &m_filterQuantityUiField )
|
||||
{
|
||||
if ( m_filterTarget != ENSEMBLE_CASE )
|
||||
{
|
||||
std::set<RifEclipseSummaryAddress> allAddresses = parentPlot->unfilteredAddresses();
|
||||
|
||||
for ( auto& address : allAddresses )
|
||||
{
|
||||
if ( address.isErrorResult() ) continue;
|
||||
|
||||
options.push_back( caf::PdmOptionItemInfo( QString::fromStdString( address.uiText() ),
|
||||
QVariant::fromValue( address ) ) );
|
||||
}
|
||||
|
||||
options.push_front( caf::PdmOptionItemInfo( RiaDefines::undefinedResultName(),
|
||||
QVariant::fromValue( RifEclipseSummaryAddress() ) ) );
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_filterEnsembleParameter )
|
||||
{
|
||||
if ( m_filterTarget() == ENSEMBLE_CASE )
|
||||
{
|
||||
std::set<EnsembleParameter> ensembleParams = parentPlot->ensembleParameters();
|
||||
for ( const EnsembleParameter& ensParam : ensembleParams )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( ensParam.uiName(), ensParam.name ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ( fieldNeedingOptions == &m_ensembleParameterValueCategories )
|
||||
{
|
||||
EnsembleParameter eParm = selectedEnsembleParameter();
|
||||
if ( eParm.isText() )
|
||||
{
|
||||
for ( const auto& val : eParm.values )
|
||||
{
|
||||
options.push_back( caf::PdmOptionItemInfo( val.toString(), val.toString() ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return options;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
caf::PdmFieldHandle* RimPlotDataFilterItem::objectToggleField()
|
||||
{
|
||||
return &m_isActive;
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotDataFilterItem::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
||||
{
|
||||
if ( m_filterAddress )
|
||||
{
|
||||
m_filterQuantityUiField = m_filterAddress->address();
|
||||
}
|
||||
|
||||
updateMaxMinAndDefaultValues( false );
|
||||
|
||||
uiOrdering.add( &m_filterTarget, { true, -1, 1 } );
|
||||
if ( m_filterTarget() == ENSEMBLE_CASE )
|
||||
{
|
||||
uiOrdering.add( &m_filterEnsembleParameter, { true, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN, 1 } );
|
||||
}
|
||||
else
|
||||
{
|
||||
uiOrdering.add( &m_filterQuantityUiField, { true, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN, 1 } );
|
||||
// uiOrdering.add( &m_filterQuantitySelectButton, {false, 1, 0} );
|
||||
}
|
||||
if ( m_filterTarget() != ENSEMBLE_CASE )
|
||||
{
|
||||
uiOrdering.add( &m_consideredTimestepsType, { true, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN, 1 } );
|
||||
if ( m_consideredTimestepsType == SELECT_TIMESTEPS || m_consideredTimestepsType == SELECT_TIMESTEP_RANGE )
|
||||
{
|
||||
uiOrdering.add( &m_explicitlySelectedTimeSteps );
|
||||
}
|
||||
}
|
||||
|
||||
EnsembleParameter eParm;
|
||||
if ( m_filterTarget() == ENSEMBLE_CASE )
|
||||
{
|
||||
eParm = selectedEnsembleParameter();
|
||||
}
|
||||
|
||||
if ( m_filterTarget() == ENSEMBLE_CASE && eParm.isText() ) // Ensemble Quantity is a category value
|
||||
{
|
||||
uiOrdering.add( &m_ensembleParameterValueCategories );
|
||||
}
|
||||
else
|
||||
{
|
||||
uiOrdering.add( &m_filterOperation, { true, 2, 1 } );
|
||||
|
||||
if ( m_filterOperation() == RANGE )
|
||||
{
|
||||
uiOrdering.add( &m_max, { true, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN, 1 } );
|
||||
uiOrdering.add( &m_min, { true, caf::PdmUiOrdering::LayoutOptions::MAX_COLUMN_SPAN, 1 } );
|
||||
}
|
||||
else if ( m_filterOperation == TOP_N || m_filterOperation == BOTTOM_N )
|
||||
{
|
||||
uiOrdering.add( &m_topBottomN, { false } );
|
||||
}
|
||||
}
|
||||
|
||||
uiOrdering.skipRemainingFields( true );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotDataFilterItem::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute )
|
||||
{
|
||||
if ( field == &m_min || field == &m_max )
|
||||
{
|
||||
caf::PdmUiDoubleSliderEditorAttribute* myAttr = dynamic_cast<caf::PdmUiDoubleSliderEditorAttribute*>( attribute );
|
||||
if ( !myAttr )
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
myAttr->m_minimum = m_lowerLimit;
|
||||
myAttr->m_maximum = m_upperLimit;
|
||||
myAttr->m_delaySliderUpdateUntilRelease = true;
|
||||
}
|
||||
else if ( field == &m_topBottomN )
|
||||
{
|
||||
caf::PdmUiLineEditorAttribute* myAttr = dynamic_cast<caf::PdmUiLineEditorAttribute*>( attribute );
|
||||
|
||||
if ( !myAttr ) return;
|
||||
|
||||
QFontMetrics fm = QFontMetrics( QFont() );
|
||||
|
||||
myAttr->maximumWidth = fm.boundingRect( "XXXX" ).width();
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
void RimPlotDataFilterItem::updateMaxMinAndDefaultValues( bool forceDefault )
|
||||
{
|
||||
RimAnalysisPlot* parentPlot;
|
||||
this->firstAncestorOrThisOfTypeAsserted( parentPlot );
|
||||
|
||||
if ( m_filterTarget == ENSEMBLE_CASE )
|
||||
{
|
||||
if ( !selectedEnsembleParameter().isValid() )
|
||||
{
|
||||
std::set<EnsembleParameter> ensembleParams = parentPlot->ensembleParameters();
|
||||
if ( !ensembleParams.empty() )
|
||||
{
|
||||
m_filterEnsembleParameter = ensembleParams.begin()->name;
|
||||
}
|
||||
}
|
||||
|
||||
EnsembleParameter eParam = selectedEnsembleParameter();
|
||||
if ( eParam.isValid() && eParam.isNumeric() )
|
||||
{
|
||||
if ( RiaCurveDataTools::isValidValue( eParam.minValue, false ) )
|
||||
{
|
||||
m_lowerLimit = eParam.minValue;
|
||||
}
|
||||
if ( RiaCurveDataTools::isValidValue( eParam.maxValue, false ) )
|
||||
{
|
||||
m_upperLimit = eParam.maxValue;
|
||||
}
|
||||
|
||||
if ( m_upperLimit < m_lowerLimit )
|
||||
{
|
||||
std::swap( m_upperLimit, m_lowerLimit );
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
parentPlot->maxMinValueFromAddress( m_filterQuantityUiField,
|
||||
m_consideredTimestepsType(),
|
||||
m_explicitlySelectedTimeSteps(),
|
||||
false,
|
||||
&m_lowerLimit,
|
||||
&m_upperLimit );
|
||||
}
|
||||
|
||||
if ( forceDefault || !( m_min >= m_lowerLimit && m_min <= m_upperLimit ) ) m_min = m_lowerLimit;
|
||||
if ( forceDefault || !( m_max >= m_lowerLimit && m_max <= m_upperLimit ) ) m_max = m_upperLimit;
|
||||
|
||||
m_min.uiCapability()->setUiName( QString( "Min (%1)" ).arg( m_lowerLimit ) );
|
||||
m_max.uiCapability()->setUiName( QString( "Max (%1)" ).arg( m_upperLimit ) );
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
///
|
||||
//--------------------------------------------------------------------------------------------------
|
||||
EnsembleParameter RimPlotDataFilterItem::selectedEnsembleParameter() const
|
||||
{
|
||||
RimAnalysisPlot* parentPlot;
|
||||
this->firstAncestorOrThisOfTypeAsserted( parentPlot );
|
||||
return parentPlot->ensembleParameter( m_filterEnsembleParameter );
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/////////////////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Copyright (C) 2020 Equinor 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 "cafAppEnum.h"
|
||||
#include "cafPdmChildField.h"
|
||||
#include "cafPdmField.h"
|
||||
#include "cafPdmObject.h"
|
||||
|
||||
#include "RifEclipseSummaryAddress.h"
|
||||
#include "RifEclipseSummaryAddressQMetaType.h"
|
||||
|
||||
#include "RimSummaryCaseCollection.h"
|
||||
|
||||
#include "RiaSummaryCurveDefinition.h"
|
||||
|
||||
#include <QDateTime>
|
||||
|
||||
class RiuSummaryQwtPlot;
|
||||
class RiuGroupedBarChartBuilder;
|
||||
|
||||
class RimAnalysisPlotDataEntry;
|
||||
class RiaSummaryCurveDefinitionAnalyser;
|
||||
class RimPlotAxisPropertiesInterface;
|
||||
class RimPlotAxisProperties;
|
||||
|
||||
class RimSummaryAddress;
|
||||
|
||||
// Filter of type :
|
||||
// Only [Cases/SummaryItem/Case by ensemble param] where the [Quantity]
|
||||
// is [within range/top N/min N]
|
||||
// considering the [Plot Source/Last/First/Last with History/all] timestep(s) [range/1,2..]
|
||||
|
||||
// Use only the "Summary Cases" where "FOPT" at the "plot source" time step(s) is "within range"
|
||||
// Use only the "Summary Items" where "WOPT" at the "Last" time step(s) is "Top " "5"
|
||||
// Use only the "Ensemble Cases" where "LGOR_FOR_EDKNRE" is "within range" "5"
|
||||
|
||||
class RimPlotDataFilterItem : public caf::PdmObject
|
||||
{
|
||||
CAF_PDM_HEADER_INIT;
|
||||
|
||||
public:
|
||||
caf::Signal<> filterChanged;
|
||||
|
||||
public:
|
||||
RimPlotDataFilterItem();
|
||||
~RimPlotDataFilterItem() override;
|
||||
|
||||
enum TimeStepSourceType
|
||||
{
|
||||
PLOT_SOURCE_TIMESTEPS,
|
||||
LAST_TIMESTEP,
|
||||
FIRST_TIMESTEP,
|
||||
LAST_TIMESTEP_WITH_HISTORY,
|
||||
ALL_TIMESTEPS,
|
||||
SELECT_TIMESTEPS,
|
||||
SELECT_TIMESTEP_RANGE
|
||||
};
|
||||
|
||||
// Filter target
|
||||
enum FilterTarget
|
||||
{
|
||||
SUMMARY_ITEM,
|
||||
SUMMARY_CASE,
|
||||
ENSEMBLE_CASE
|
||||
};
|
||||
|
||||
enum FilterOperation
|
||||
{
|
||||
TOP_N,
|
||||
BOTTOM_N,
|
||||
RANGE
|
||||
};
|
||||
|
||||
bool isActive() const { return m_isActive(); }
|
||||
FilterTarget filterTarget() const { return m_filterTarget(); }
|
||||
bool isValid() const;
|
||||
|
||||
RifEclipseSummaryAddress summaryAddress() const;
|
||||
|
||||
QString ensembleParameterName() const;
|
||||
|
||||
FilterOperation filterOperation() const { return m_filterOperation(); }
|
||||
std::pair<double, double> filterRangeMinMax() const;
|
||||
int topBottomN() const;
|
||||
|
||||
std::vector<QString> selectedEnsembleParameterCategories() const;
|
||||
|
||||
TimeStepSourceType consideredTimeStepsType() const;
|
||||
std::pair<time_t, time_t> timeRangeMinMax() const;
|
||||
std::vector<time_t> explicitlySelectedTimeSteps() const;
|
||||
void updateMaxMinAndDefaultValues( bool forceDefault );
|
||||
|
||||
private:
|
||||
void fieldChangedByUi( const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue ) override;
|
||||
void defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering ) override;
|
||||
void defineEditorAttribute( const caf::PdmFieldHandle* field,
|
||||
QString uiConfigName,
|
||||
caf::PdmUiEditorAttribute* attribute ) override;
|
||||
|
||||
caf::PdmFieldHandle* objectToggleField() override;
|
||||
QList<caf::PdmOptionItemInfo> calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
||||
bool* useOptionsOnly ) override;
|
||||
|
||||
EnsembleParameter selectedEnsembleParameter() const;
|
||||
|
||||
caf::PdmField<bool> m_isActive;
|
||||
|
||||
caf::PdmField<caf::AppEnum<FilterTarget>> m_filterTarget;
|
||||
|
||||
// Quantity
|
||||
|
||||
// Complete address or quantity name only
|
||||
caf::PdmChildField<RimSummaryAddress*> m_filterAddress;
|
||||
caf::PdmField<QString> m_filterEnsembleParameter;
|
||||
caf::PdmField<RifEclipseSummaryAddress> m_filterQuantityUiField;
|
||||
caf::PdmField<bool> m_filterQuantitySelectButton;
|
||||
|
||||
// Operation and parameters
|
||||
|
||||
caf::PdmField<caf::AppEnum<FilterOperation>> m_filterOperation;
|
||||
caf::PdmField<int> m_topBottomN;
|
||||
caf::PdmField<double> m_max;
|
||||
caf::PdmField<double> m_min;
|
||||
|
||||
caf::PdmField<std::vector<QString>> m_ensembleParameterValueCategories;
|
||||
|
||||
// Considered Timesteps
|
||||
|
||||
caf::PdmField<caf::AppEnum<TimeStepSourceType>> m_consideredTimestepsType;
|
||||
caf::PdmField<std::vector<QDateTime>> m_explicitlySelectedTimeSteps;
|
||||
|
||||
double m_lowerLimit;
|
||||
double m_upperLimit;
|
||||
};
|
||||
Reference in New Issue
Block a user