Rename ApplicationCode to ApplicationLibCode

This commit is contained in:
Gaute Lindkvist
2021-01-06 14:55:29 +01:00
parent 751df1a421
commit 81699db187
3242 changed files with 0 additions and 0 deletions

View File

@@ -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

View File

@@ -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;
};

View File

@@ -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();
}

View File

@@ -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;
};

View File

@@ -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;
}

View File

@@ -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;
};

View File

@@ -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();
}

View File

@@ -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;
};

View File

@@ -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 );
}

View File

@@ -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;
};