2020-02-12 09:48:25 -06:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// 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 "RimAnalysisPlot.h"
|
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
#include "RiaPreferences.h"
|
|
|
|
|
2020-02-12 09:48:25 -06:00
|
|
|
#include "RiuGroupedBarChartBuilder.h"
|
2020-02-28 07:51:21 -06:00
|
|
|
#include "RiuPlotMainWindowTools.h"
|
2020-02-12 09:48:25 -06:00
|
|
|
#include "RiuSummaryQwtPlot.h"
|
2020-02-18 04:48:04 -06:00
|
|
|
#include "RiuSummaryVectorSelectionDialog.h"
|
2020-02-12 09:48:25 -06:00
|
|
|
|
2020-02-27 02:01:38 -06:00
|
|
|
#include "RifSummaryReaderInterface.h"
|
|
|
|
|
|
|
|
#include "RimAnalysisPlotDataEntry.h"
|
|
|
|
#include "RimDerivedSummaryCase.h"
|
2020-02-28 07:51:21 -06:00
|
|
|
#include "RimPlotAxisProperties.h"
|
2020-02-28 04:07:53 -06:00
|
|
|
#include "RimPlotAxisPropertiesInterface.h"
|
2020-03-19 10:34:30 -05:00
|
|
|
#include "RimPlotDataFilterCollection.h"
|
2020-02-27 02:01:38 -06:00
|
|
|
#include "RimProject.h"
|
|
|
|
#include "RimSummaryCase.h"
|
|
|
|
#include "RimSummaryCaseCollection.h"
|
2020-02-28 07:51:21 -06:00
|
|
|
#include "RimSummaryPlotAxisFormatter.h"
|
2020-02-27 02:01:38 -06:00
|
|
|
|
2020-02-12 09:48:25 -06:00
|
|
|
#include "qwt_column_symbol.h"
|
|
|
|
#include "qwt_legend.h"
|
|
|
|
#include "qwt_painter.h"
|
|
|
|
#include "qwt_plot_barchart.h"
|
|
|
|
#include "qwt_scale_draw.h"
|
|
|
|
|
2020-02-18 04:48:04 -06:00
|
|
|
#include "cafPdmUiActionPushButtonEditor.h"
|
2020-02-26 04:21:44 -06:00
|
|
|
#include "cafPdmUiCheckBoxEditor.h"
|
2020-02-25 02:25:57 -06:00
|
|
|
#include "cafPdmUiComboBoxEditor.h"
|
2020-02-27 02:01:38 -06:00
|
|
|
#include "cafPdmUiGroup.h"
|
2020-02-25 02:25:57 -06:00
|
|
|
#include "cafPdmUiListEditor.h"
|
2020-07-31 02:50:13 -05:00
|
|
|
#include "cafPdmUiTreeSelectionEditor.h"
|
2020-02-25 02:25:57 -06:00
|
|
|
|
2020-02-12 09:48:25 -06:00
|
|
|
#include <limits>
|
|
|
|
#include <map>
|
|
|
|
|
|
|
|
namespace caf
|
|
|
|
{
|
|
|
|
template <>
|
|
|
|
void caf::AppEnum<RimAnalysisPlot::SortGroupType>::setUp()
|
|
|
|
{
|
2020-02-25 02:25:57 -06:00
|
|
|
addItem( RimAnalysisPlot::NONE, "NONE", "None" );
|
2020-02-12 09:48:25 -06:00
|
|
|
addItem( RimAnalysisPlot::SUMMARY_ITEM, "SUMMARY_ITEM", "Summary Item" );
|
2020-02-25 09:11:44 -06:00
|
|
|
addItem( RimAnalysisPlot::QUANTITY, "QUANTITY", "Quantity" );
|
2020-02-12 09:48:25 -06:00
|
|
|
addItem( RimAnalysisPlot::CASE, "CASE", "Case" );
|
|
|
|
addItem( RimAnalysisPlot::ENSEMBLE, "ENSEMBLE", "Ensemble" );
|
|
|
|
addItem( RimAnalysisPlot::VALUE, "VALUE", "Value" );
|
|
|
|
addItem( RimAnalysisPlot::ABS_VALUE, "ABS_VALUE", "abs(Value)" );
|
|
|
|
addItem( RimAnalysisPlot::OTHER_VALUE, "OTHER_VALUE", "Other Value" );
|
|
|
|
addItem( RimAnalysisPlot::ABS_OTHER_VALUE, "ABS_OTHER_VALUE", "abs(Other Value)" );
|
|
|
|
addItem( RimAnalysisPlot::TIME_STEP, "TIME_STEP", "Time Step" );
|
2020-02-25 02:25:57 -06:00
|
|
|
setDefault( RimAnalysisPlot::NONE );
|
2020-02-12 09:48:25 -06:00
|
|
|
}
|
2020-02-19 05:03:41 -06:00
|
|
|
|
|
|
|
template <>
|
|
|
|
void caf::AppEnum<RimAnalysisPlot::BarOrientation>::setUp()
|
|
|
|
{
|
2020-02-24 03:18:43 -06:00
|
|
|
addItem( RimAnalysisPlot::BARS_HORIZONTAL, "BARS_HORIZONTAL", "Horizontal" );
|
2020-02-19 05:03:41 -06:00
|
|
|
addItem( RimAnalysisPlot::BARS_VERTICAL, "BARS_VERTICAL", "Vertical" );
|
2020-02-24 03:18:43 -06:00
|
|
|
setDefault( RimAnalysisPlot::BARS_VERTICAL );
|
2020-02-19 05:03:41 -06:00
|
|
|
}
|
2020-02-12 09:48:25 -06:00
|
|
|
} // namespace caf
|
|
|
|
|
|
|
|
CAF_PDM_SOURCE_INIT( RimAnalysisPlot, "AnalysisPlot" );
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimAnalysisPlot::RimAnalysisPlot()
|
|
|
|
: RimPlot()
|
|
|
|
{
|
2020-03-13 05:40:10 -05:00
|
|
|
CAF_PDM_InitObject( "Analysis Plot", ":/AnalysisPlot16x16.png", "", "" );
|
2020-02-12 09:48:25 -06:00
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
// Variable selection
|
2020-02-19 05:03:41 -06:00
|
|
|
|
2020-02-18 04:48:04 -06:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_selectedVarsUiField, "selectedVarsUiField", "Selected Variables", "", "", "" );
|
|
|
|
m_selectedVarsUiField.xmlCapability()->disableIO();
|
|
|
|
m_selectedVarsUiField.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
m_selectedVarsUiField.uiCapability()->setUiReadOnly( true );
|
|
|
|
|
|
|
|
CAF_PDM_InitField( &m_selectVariablesButtonField, "BrowseButton", false, "...", "", "", "" );
|
|
|
|
caf::PdmUiActionPushButtonEditor::configureEditorForField( &m_selectVariablesButtonField );
|
2020-02-12 09:48:25 -06:00
|
|
|
|
2020-03-19 10:34:30 -05:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_analysisPlotDataSelection, "AnalysisPlotData", "", "", "", "" );
|
|
|
|
m_analysisPlotDataSelection.uiCapability()->setUiTreeChildrenHidden( true );
|
|
|
|
m_analysisPlotDataSelection.uiCapability()->setUiTreeHidden( true );
|
2020-02-12 09:48:25 -06:00
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
// Time Step Selection
|
2020-07-31 02:50:13 -05:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_timeStepFilter, "TimeStepFilter", "Time Step Filter", "", "", "" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_selectedTimeSteps, "TimeSteps", "Select Time Steps", "", "", "" );
|
|
|
|
m_selectedTimeSteps.uiCapability()->setUiEditorTypeName( caf::PdmUiTreeSelectionEditor::uiEditorTypeName() );
|
|
|
|
m_selectedTimeSteps.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::TOP );
|
2020-02-25 02:25:57 -06:00
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
// Options
|
|
|
|
|
2020-02-27 02:01:38 -06:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_referenceCase, "ReferenceCase", "Reference Case", "", "", "" );
|
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
CAF_PDM_InitField( &m_showPlotTitle, "ShowPlotTitle", true, "Title", "", "", "" );
|
|
|
|
m_showPlotTitle.xmlCapability()->setIOWritable( false );
|
|
|
|
m_showPlotTitle.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
2020-02-26 04:21:44 -06:00
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
CAF_PDM_InitField( &m_useAutoPlotTitle, "IsUsingAutoName", true, "Auto", "", "", "" );
|
|
|
|
m_useAutoPlotTitle.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
|
|
|
CAF_PDM_InitField( &m_description, "PlotDescription", QString( "Analysis Plot" ), "Title", "", "", "" );
|
|
|
|
m_description.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_barOrientation, "BarOrientation", "Bar Orientation", "", "", "" );
|
|
|
|
|
|
|
|
// Grouping
|
2020-02-26 04:21:44 -06:00
|
|
|
|
2020-02-25 02:25:57 -06:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_majorGroupType, "MajorGroupType", "Major Grouping", "", "", "" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_mediumGroupType, "MediumGroupType", "Medium Grouping", "", "", "" );
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_minorGroupType, "MinorGroupType", "Minor Grouping", "", "", "" );
|
2020-02-12 09:48:25 -06:00
|
|
|
|
2020-02-25 02:25:57 -06:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_valueSortOperation, "ValueSortOperation", "Sort by Value", "", "", "" );
|
2020-02-12 09:48:25 -06:00
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_sortGroupForColors, "groupForColors", "Coloring Using", "", "", "" );
|
|
|
|
m_sortGroupForColors = RimAnalysisPlot::CASE;
|
|
|
|
m_showPlotLegends = false;
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
CAF_PDM_InitField( &m_useTopBarsFilter, "UseTopBarsFilter", false, "Show Only Top", "", "", "" );
|
|
|
|
m_useTopBarsFilter.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
|
|
|
CAF_PDM_InitField( &m_maxBarCount, "MaxBarCount", 20, "Bar Count", "", "", "" );
|
|
|
|
m_maxBarCount.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
|
|
|
// Bar text
|
|
|
|
|
2020-02-26 04:21:44 -06:00
|
|
|
CAF_PDM_InitField( &m_useBarText, "UseBarText", true, "Activate Bar Labels", "", "", "" );
|
|
|
|
m_useBarText.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
|
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
CAF_PDM_InitField( &m_useCaseInBarText, "UseCaseInBarText", true, "Case Name", "", "", "" );
|
2020-02-26 05:56:35 -06:00
|
|
|
CAF_PDM_InitField( &m_useEnsembleInBarText, "UseEnsembleInBarText", false, "Ensemble", "", "", "" );
|
|
|
|
CAF_PDM_InitField( &m_useSummaryItemInBarText, "UseSummaryItemInBarText", false, "Summary Item", "", "", "" );
|
|
|
|
CAF_PDM_InitField( &m_useTimeStepInBarText, "UseTimeStepInBarText", false, "Time Step", "", "", "" );
|
|
|
|
CAF_PDM_InitField( &m_useQuantityInBarText, "UseQuantityInBarText", false, "Quantity", "", "", "" );
|
2020-02-28 07:51:21 -06:00
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_barTextFontSize, "BarTextFontSize", "Font Size", "", "", "" );
|
|
|
|
|
2020-02-28 07:51:21 -06:00
|
|
|
CAF_PDM_InitFieldNoDefault( &m_valueAxisProperties, "ValueAxisProperties", "ValueAxisProperties", "", "", "" );
|
|
|
|
m_valueAxisProperties.uiCapability()->setUiTreeHidden( true );
|
|
|
|
m_valueAxisProperties = new RimPlotAxisProperties;
|
|
|
|
m_valueAxisProperties->setNameAndAxis( "Value-Axis", QwtPlot::yLeft );
|
|
|
|
m_valueAxisProperties->enableRangeSettings( false );
|
2020-03-19 10:34:30 -05:00
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault( &m_plotDataFilterCollection, "PlotDataFilterCollection", "PlotDataFilterCollection", "", "", "" );
|
|
|
|
m_plotDataFilterCollection.uiCapability()->setUiTreeHidden( true );
|
|
|
|
m_plotDataFilterCollection = new RimPlotDataFilterCollection;
|
2020-05-18 09:02:27 -05:00
|
|
|
|
|
|
|
setDeletable( true );
|
2020-02-12 09:48:25 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimAnalysisPlot::~RimAnalysisPlot()
|
|
|
|
{
|
|
|
|
removeMdiWindowFromMdiArea();
|
|
|
|
|
|
|
|
cleanupBeforeClose();
|
|
|
|
}
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::updateCaseNameHasChanged()
|
|
|
|
{
|
2020-02-28 04:07:53 -06:00
|
|
|
this->onLoadDataAndUpdate();
|
2020-02-12 09:48:25 -06:00
|
|
|
}
|
2020-03-19 10:34:30 -05:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimPlotDataFilterCollection* RimAnalysisPlot::plotDataFilterCollection() const
|
|
|
|
{
|
|
|
|
return m_plotDataFilterCollection;
|
|
|
|
}
|
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::setCurveDefinitions( const std::vector<RiaSummaryCurveDefinition>& curveDefinitions )
|
|
|
|
{
|
|
|
|
m_analysisPlotDataSelection.deleteAllChildObjects();
|
|
|
|
for ( auto curveDef : curveDefinitions )
|
|
|
|
{
|
|
|
|
auto dataEntry = new RimAnalysisPlotDataEntry();
|
|
|
|
dataEntry->setFromCurveDefinition( curveDef );
|
|
|
|
m_analysisPlotDataSelection.push_back( dataEntry );
|
|
|
|
}
|
|
|
|
auto timeSteps = allAvailableTimeSteps();
|
|
|
|
if ( m_selectedTimeSteps().empty() && !timeSteps.empty() )
|
|
|
|
{
|
|
|
|
m_selectedTimeSteps.v().push_back( RiaQDateTimeTools::fromTime_t( *timeSteps.rbegin() ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-19 10:34:30 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::set<RifEclipseSummaryAddress> RimAnalysisPlot::unfilteredAddresses()
|
|
|
|
{
|
|
|
|
std::set<RifEclipseSummaryAddress> addresses;
|
|
|
|
|
2020-04-21 01:56:27 -05:00
|
|
|
RiaSummaryCurveDefinitionAnalyser* analyserOfSelectedCurveDefs = getOrCreateSelectedCurveDefAnalyser();
|
2020-03-19 10:34:30 -05:00
|
|
|
|
|
|
|
for ( RimSummaryCase* sumCase : analyserOfSelectedCurveDefs->m_singleSummaryCases )
|
|
|
|
{
|
|
|
|
const std::set<RifEclipseSummaryAddress>& caseAddrs = sumCase->summaryReader()->allResultAddresses();
|
|
|
|
addresses.insert( caseAddrs.begin(), caseAddrs.end() );
|
|
|
|
}
|
|
|
|
|
|
|
|
return addresses;
|
|
|
|
}
|
|
|
|
|
2020-03-20 05:22:14 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::set<EnsembleParameter> RimAnalysisPlot::ensembleParameters()
|
|
|
|
{
|
|
|
|
std::set<EnsembleParameter> ensembleParms;
|
|
|
|
|
2020-04-21 01:56:27 -05:00
|
|
|
RiaSummaryCurveDefinitionAnalyser* analyserOfSelectedCurveDefs = getOrCreateSelectedCurveDefAnalyser();
|
2020-03-20 05:22:14 -05:00
|
|
|
|
2020-03-23 05:59:44 -05:00
|
|
|
std::set<RimSummaryCaseCollection*> ensembles;
|
|
|
|
|
|
|
|
for ( RimSummaryCase* sumCase : analyserOfSelectedCurveDefs->m_singleSummaryCases )
|
|
|
|
{
|
|
|
|
if ( sumCase->ensemble() )
|
|
|
|
{
|
|
|
|
ensembles.insert( sumCase->ensemble() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( RimSummaryCaseCollection* ensemble : ensembles )
|
2020-03-20 05:22:14 -05:00
|
|
|
{
|
|
|
|
std::vector<EnsembleParameter> parameters = ensemble->variationSortedEnsembleParameters();
|
|
|
|
ensembleParms.insert( parameters.begin(), parameters.end() );
|
|
|
|
}
|
|
|
|
|
|
|
|
return ensembleParms;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-03-23 05:59:44 -05:00
|
|
|
EnsembleParameter RimAnalysisPlot::ensembleParameter( const QString& ensembleParameterName )
|
|
|
|
{
|
|
|
|
std::set<EnsembleParameter> ensembleParms = ensembleParameters();
|
|
|
|
for ( const EnsembleParameter& eParam : ensembleParms )
|
|
|
|
{
|
|
|
|
if ( eParam.name == ensembleParameterName ) return eParam;
|
|
|
|
}
|
|
|
|
|
|
|
|
return EnsembleParameter();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::maxMinValueFromAddress( const RifEclipseSummaryAddress& address,
|
|
|
|
RimPlotDataFilterItem::TimeStepSourceType timeStepSourceType,
|
|
|
|
const std::vector<QDateTime>& timeRangeOrSelection,
|
|
|
|
bool useAbsValue,
|
|
|
|
double* minVal,
|
|
|
|
double* maxVal )
|
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
double min = std::numeric_limits<double>::infinity();
|
|
|
|
double max = useAbsValue ? 0.0 : -std::numeric_limits<double>::infinity();
|
2020-03-23 05:59:44 -05:00
|
|
|
|
|
|
|
std::function<double( double, double )> minOrAbsMin;
|
|
|
|
std::function<double( double, double )> maxOrAbsMax;
|
|
|
|
|
|
|
|
if ( useAbsValue )
|
|
|
|
{
|
|
|
|
minOrAbsMin = []( double v1, double v2 ) { return std::min( fabs( v1 ), fabs( v2 ) ); };
|
|
|
|
maxOrAbsMax = []( double v1, double v2 ) { return std::max( fabs( v1 ), fabs( v2 ) ); };
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
minOrAbsMin = []( double v1, double v2 ) { return std::min( v1, v2 ); };
|
|
|
|
maxOrAbsMax = []( double v1, double v2 ) { return std::max( v1, v2 ); };
|
|
|
|
}
|
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
std::vector<time_t> selectedTimesteps;
|
2020-03-23 05:59:44 -05:00
|
|
|
if ( timeStepSourceType == RimPlotDataFilterItem::SELECT_TIMESTEPS )
|
|
|
|
{
|
|
|
|
for ( const QDateTime& dateTime : timeRangeOrSelection )
|
|
|
|
{
|
|
|
|
selectedTimesteps.push_back( dateTime.toTime_t() );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( timeStepSourceType == RimPlotDataFilterItem::PLOT_SOURCE_TIMESTEPS )
|
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
selectedTimesteps = selectedTimeSteps();
|
2020-03-23 05:59:44 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
std::set<RimSummaryCase*> allSumCases = allSourceCases();
|
|
|
|
|
|
|
|
for ( RimSummaryCase* sumCase : allSumCases )
|
|
|
|
{
|
|
|
|
RifSummaryReaderInterface* reader = sumCase->summaryReader();
|
|
|
|
if ( !reader ) continue;
|
|
|
|
|
|
|
|
if ( reader->hasAddress( address ) )
|
|
|
|
{
|
|
|
|
std::vector<double> values;
|
|
|
|
reader->values( address, &values );
|
|
|
|
|
|
|
|
const std::vector<time_t>& timesteps = reader->timeSteps( address );
|
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( timesteps.size() && values.size() )
|
2020-03-23 05:59:44 -05:00
|
|
|
{
|
|
|
|
if ( timeStepSourceType == RimPlotDataFilterItem::LAST_TIMESTEP )
|
|
|
|
{
|
|
|
|
min = minOrAbsMin( min, values[timesteps.size() - 1] );
|
|
|
|
max = maxOrAbsMax( max, values[timesteps.size() - 1] );
|
|
|
|
}
|
|
|
|
else if ( timeStepSourceType == RimPlotDataFilterItem::FIRST_TIMESTEP )
|
|
|
|
{
|
|
|
|
min = minOrAbsMin( min, values[0] );
|
|
|
|
max = maxOrAbsMax( max, values[0] );
|
|
|
|
}
|
|
|
|
else if ( timeStepSourceType == RimPlotDataFilterItem::ALL_TIMESTEPS )
|
|
|
|
{
|
|
|
|
for ( size_t tIdx = 0; tIdx < timesteps.size(); ++tIdx )
|
|
|
|
{
|
|
|
|
min = minOrAbsMin( min, values[tIdx] );
|
|
|
|
max = maxOrAbsMax( max, values[tIdx] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( timeStepSourceType == RimPlotDataFilterItem::SELECT_TIMESTEP_RANGE )
|
|
|
|
{
|
|
|
|
if ( timeRangeOrSelection.size() >= 2 )
|
|
|
|
{
|
|
|
|
time_t minTime = timeRangeOrSelection.front().toTime_t();
|
|
|
|
time_t maxTime = timeRangeOrSelection.back().toTime_t();
|
|
|
|
|
|
|
|
for ( size_t tIdx = 0; tIdx < timesteps.size(); ++tIdx )
|
|
|
|
{
|
|
|
|
time_t dateTime = timesteps[tIdx];
|
|
|
|
|
|
|
|
if ( minTime <= dateTime && dateTime <= maxTime )
|
|
|
|
{
|
|
|
|
min = minOrAbsMin( min, values[tIdx] );
|
|
|
|
max = maxOrAbsMax( max, values[tIdx] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( timeStepSourceType == RimPlotDataFilterItem::LAST_TIMESTEP_WITH_HISTORY )
|
|
|
|
{
|
|
|
|
RifEclipseSummaryAddress historyAddr = address;
|
|
|
|
|
|
|
|
if ( !historyAddr.isHistoryQuantity() ) historyAddr.setQuantityName( address.quantityName() + "H" );
|
|
|
|
|
|
|
|
const std::vector<time_t>& historyTimesteps = reader->timeSteps( historyAddr );
|
|
|
|
if ( historyTimesteps.size() )
|
|
|
|
{
|
|
|
|
min = minOrAbsMin( min, values[historyTimesteps.size() - 1] );
|
|
|
|
max = maxOrAbsMax( max, values[historyTimesteps.size() - 1] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( selectedTimesteps.size() )
|
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
std::vector<size_t> selectedTimestepIndices =
|
|
|
|
RimAnalysisPlot::findTimestepIndices( selectedTimesteps, timesteps );
|
2020-03-23 05:59:44 -05:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( size_t tsIdx : selectedTimestepIndices )
|
2020-03-23 05:59:44 -05:00
|
|
|
{
|
|
|
|
min = minOrAbsMin( min, values[tsIdx] );
|
|
|
|
max = maxOrAbsMax( max, values[tsIdx] );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
( *minVal ) = min;
|
|
|
|
( *maxVal ) = max;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::onFiltersChanged()
|
2020-03-20 05:22:14 -05:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
this->loadDataAndUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::vector<time_t> RimAnalysisPlot::selectedTimeSteps()
|
|
|
|
{
|
|
|
|
std::vector<time_t> selectedTimeTTimeSteps;
|
|
|
|
for ( const QDateTime& dateTime : m_selectedTimeSteps.v() )
|
|
|
|
{
|
|
|
|
selectedTimeTTimeSteps.push_back( dateTime.toTime_t() );
|
|
|
|
}
|
|
|
|
|
|
|
|
return selectedTimeTTimeSteps;
|
2020-03-20 05:22:14 -05:00
|
|
|
}
|
|
|
|
|
2020-02-12 09:48:25 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::fieldChangedByUi( const caf::PdmFieldHandle* changedField,
|
|
|
|
const QVariant& oldValue,
|
|
|
|
const QVariant& newValue )
|
|
|
|
{
|
2020-02-25 09:11:44 -06:00
|
|
|
RimPlot::fieldChangedByUi( changedField, oldValue, newValue );
|
|
|
|
|
2020-02-18 04:48:04 -06:00
|
|
|
if ( changedField == &m_selectVariablesButtonField )
|
|
|
|
{
|
|
|
|
// Do select variables
|
|
|
|
RiuSummaryVectorSelectionDialog dlg( nullptr );
|
2020-02-24 03:44:51 -06:00
|
|
|
|
2020-02-18 04:48:04 -06:00
|
|
|
dlg.enableMultiSelect( true );
|
2020-03-03 02:49:54 -06:00
|
|
|
dlg.enableIndividualEnsembleCaseSelection( true );
|
2020-03-25 10:23:41 -05:00
|
|
|
dlg.setCurveSelection( this->curveDefinitionsWithoutEnsembleReference() );
|
2020-02-18 04:48:04 -06:00
|
|
|
|
|
|
|
if ( dlg.exec() == QDialog::Accepted )
|
|
|
|
{
|
|
|
|
std::vector<RiaSummaryCurveDefinition> summaryVectorDefinitions = dlg.curveSelection();
|
2020-03-19 10:34:30 -05:00
|
|
|
m_analysisPlotDataSelection.deleteAllChildObjects();
|
2020-02-18 04:48:04 -06:00
|
|
|
for ( const RiaSummaryCurveDefinition& vectorDef : summaryVectorDefinitions )
|
|
|
|
{
|
|
|
|
auto plotEntry = new RimAnalysisPlotDataEntry();
|
|
|
|
plotEntry->setFromCurveDefinition( vectorDef );
|
2020-03-19 10:34:30 -05:00
|
|
|
m_analysisPlotDataSelection.push_back( plotEntry );
|
2020-02-18 04:48:04 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_selectVariablesButtonField = false;
|
|
|
|
}
|
2020-07-31 02:50:13 -05:00
|
|
|
else if ( changedField == &m_timeStepFilter )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
2020-07-31 02:50:13 -05:00
|
|
|
this->updateConnectedEditors();
|
2020-02-25 02:25:57 -06:00
|
|
|
}
|
|
|
|
|
2020-02-12 09:48:25 -06:00
|
|
|
this->loadDataAndUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-02-18 04:48:04 -06:00
|
|
|
void RimAnalysisPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrdering& uiOrdering )
|
|
|
|
{
|
|
|
|
caf::PdmUiGroup* selVectorsGrp = uiOrdering.addNewGroup( "Selected Vectors" );
|
|
|
|
selVectorsGrp->add( &m_selectedVarsUiField );
|
2020-06-08 04:09:11 -05:00
|
|
|
selVectorsGrp->add( &m_selectVariablesButtonField, {false} );
|
2020-02-18 04:48:04 -06:00
|
|
|
|
2020-02-25 09:11:44 -06:00
|
|
|
QString vectorNames;
|
2020-07-30 06:20:00 -05:00
|
|
|
if ( getOrCreateSelectedCurveDefAnalyser() )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
2020-07-30 06:20:00 -05:00
|
|
|
for ( const std::string& quantityName : getOrCreateSelectedCurveDefAnalyser()->m_quantityNames )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
|
|
|
vectorNames += QString::fromStdString( quantityName ) + ", ";
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( !vectorNames.isEmpty() )
|
|
|
|
{
|
|
|
|
vectorNames.chop( 2 );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-30 07:03:50 -05:00
|
|
|
if ( !vectorNames.isEmpty() )
|
|
|
|
{
|
|
|
|
m_selectedVarsUiField = vectorNames;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_selectedVarsUiField = "Select Data Sources -->";
|
|
|
|
}
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-02-18 04:48:04 -06:00
|
|
|
caf::PdmUiGroup* timeStepGrp = uiOrdering.addNewGroup( "Time Steps" );
|
2020-07-31 02:50:13 -05:00
|
|
|
timeStepGrp->add( &m_timeStepFilter );
|
2020-02-18 04:48:04 -06:00
|
|
|
timeStepGrp->add( &m_selectedTimeSteps );
|
|
|
|
|
2020-06-08 04:09:11 -05:00
|
|
|
uiOrdering.add( &m_referenceCase, {true, 3, 2} );
|
2020-02-27 02:01:38 -06:00
|
|
|
|
2020-02-25 09:11:44 -06:00
|
|
|
uiOrdering.add( &m_showPlotTitle );
|
2020-06-08 04:09:11 -05:00
|
|
|
uiOrdering.add( &m_useAutoPlotTitle, {false} );
|
|
|
|
uiOrdering.add( &m_description, {false} );
|
2020-02-25 09:11:44 -06:00
|
|
|
m_description.uiCapability()->setUiReadOnly( m_useAutoPlotTitle() );
|
|
|
|
|
2020-06-08 04:09:11 -05:00
|
|
|
uiOrdering.add( &m_barOrientation, {true, 3, 2} );
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
caf::PdmUiGroup* sortGrp = uiOrdering.addNewGroup( "Sorting, Grouping and Coloring" );
|
2020-02-25 02:25:57 -06:00
|
|
|
sortGrp->add( &m_majorGroupType );
|
|
|
|
sortGrp->add( &m_mediumGroupType );
|
|
|
|
sortGrp->add( &m_minorGroupType );
|
|
|
|
sortGrp->add( &m_valueSortOperation );
|
2020-02-26 04:21:44 -06:00
|
|
|
sortGrp->add( &m_useTopBarsFilter );
|
2020-06-08 04:09:11 -05:00
|
|
|
sortGrp->add( &m_maxBarCount, {false} );
|
2020-02-26 04:21:44 -06:00
|
|
|
m_maxBarCount.uiCapability()->setUiReadOnly( !m_useTopBarsFilter() );
|
2020-07-30 06:20:00 -05:00
|
|
|
sortGrp->add( &m_sortGroupForColors );
|
2020-02-18 04:48:04 -06:00
|
|
|
|
2020-02-25 09:11:44 -06:00
|
|
|
caf::PdmUiGroup* legendGrp = uiOrdering.addNewGroup( "Legend" );
|
2020-02-18 04:48:04 -06:00
|
|
|
legendGrp->add( &m_showPlotLegends );
|
|
|
|
legendGrp->add( &m_legendFontSize );
|
2020-02-25 09:11:44 -06:00
|
|
|
m_legendFontSize.uiCapability()->setUiReadOnly( !m_showPlotLegends() );
|
|
|
|
|
|
|
|
caf::PdmUiGroup* barLabelGrp = uiOrdering.addNewGroup( "Bar Labels" );
|
2020-02-26 04:21:44 -06:00
|
|
|
barLabelGrp->add( &m_useBarText );
|
2020-07-30 06:20:00 -05:00
|
|
|
barLabelGrp->add( &m_barTextFontSize );
|
2020-02-25 09:11:44 -06:00
|
|
|
barLabelGrp->add( &m_useQuantityInBarText );
|
2020-07-30 06:20:00 -05:00
|
|
|
barLabelGrp->add( &m_useSummaryItemInBarText );
|
2020-02-25 09:11:44 -06:00
|
|
|
barLabelGrp->add( &m_useCaseInBarText );
|
2020-07-30 06:20:00 -05:00
|
|
|
barLabelGrp->add( &m_useEnsembleInBarText );
|
|
|
|
barLabelGrp->add( &m_useTimeStepInBarText );
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
m_barTextFontSize.uiCapability()->setUiReadOnly( !m_useBarText );
|
2020-02-25 09:11:44 -06:00
|
|
|
m_useQuantityInBarText.uiCapability()->setUiReadOnly( !m_useBarText );
|
|
|
|
m_useSummaryItemInBarText.uiCapability()->setUiReadOnly( !m_useBarText );
|
|
|
|
m_useCaseInBarText.uiCapability()->setUiReadOnly( !m_useBarText );
|
|
|
|
m_useEnsembleInBarText.uiCapability()->setUiReadOnly( !m_useBarText );
|
|
|
|
m_useTimeStepInBarText.uiCapability()->setUiReadOnly( !m_useBarText );
|
2020-02-18 04:48:04 -06:00
|
|
|
|
|
|
|
uiOrdering.skipRemainingFields( true );
|
|
|
|
}
|
2020-02-12 09:48:25 -06:00
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::defineEditorAttribute( const caf::PdmFieldHandle* field,
|
|
|
|
QString uiConfigName,
|
|
|
|
caf::PdmUiEditorAttribute* attribute )
|
|
|
|
{
|
|
|
|
if ( field == &m_useTopBarsFilter || field == &m_useBarText || field == &m_showPlotTitle || field == &m_useAutoPlotTitle )
|
|
|
|
{
|
|
|
|
auto attrib = dynamic_cast<caf::PdmUiCheckBoxEditorAttribute*>( attribute );
|
|
|
|
if ( attrib )
|
|
|
|
{
|
|
|
|
attrib->m_useNativeCheckBoxLabel = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
caf::PdmFieldHandle* RimAnalysisPlot::userDescriptionField()
|
|
|
|
{
|
|
|
|
return &m_description;
|
|
|
|
}
|
|
|
|
|
2020-02-25 02:25:57 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QList<caf::PdmOptionItemInfo> RimAnalysisPlot::calculateValueOptions( const caf::PdmFieldHandle* fieldNeedingOptions,
|
|
|
|
bool* useOptionsOnly )
|
|
|
|
{
|
|
|
|
QList<caf::PdmOptionItemInfo> options = RimPlot::calculateValueOptions( fieldNeedingOptions, useOptionsOnly );
|
|
|
|
|
|
|
|
if ( !options.isEmpty() ) return options;
|
|
|
|
|
2020-07-31 02:50:13 -05:00
|
|
|
if ( fieldNeedingOptions == &m_selectedTimeSteps )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
2020-07-31 02:50:13 -05:00
|
|
|
std::set<time_t> allTimeSteps = allAvailableTimeSteps();
|
|
|
|
std::set<QDateTime> currentlySelectedTimeSteps( m_selectedTimeSteps().begin(), m_selectedTimeSteps().end() );
|
|
|
|
|
|
|
|
if ( allTimeSteps.empty() )
|
|
|
|
{
|
|
|
|
CAF_ASSERT( false && "No time steps found" );
|
|
|
|
return options;
|
|
|
|
}
|
2020-02-25 02:25:57 -06:00
|
|
|
|
2020-07-31 02:50:13 -05:00
|
|
|
std::set<int> currentlySelectedTimeStepIndices;
|
|
|
|
std::vector<QDateTime> allDateTimes;
|
|
|
|
for ( time_t timeStep : allTimeSteps )
|
|
|
|
{
|
|
|
|
QDateTime dateTime = RiaQDateTimeTools::fromTime_t( timeStep );
|
|
|
|
if ( currentlySelectedTimeSteps.count( dateTime ) )
|
|
|
|
{
|
|
|
|
currentlySelectedTimeStepIndices.insert( (int)allDateTimes.size() );
|
|
|
|
}
|
|
|
|
allDateTimes.push_back( dateTime );
|
|
|
|
}
|
2020-02-25 02:25:57 -06:00
|
|
|
|
2020-07-31 02:50:13 -05:00
|
|
|
std::vector<int> filteredTimeStepIndices =
|
|
|
|
RimTimeStepFilter::filteredTimeStepIndices( allDateTimes, 0, (int)allDateTimes.size() - 1, m_timeStepFilter(), 1 );
|
|
|
|
|
|
|
|
// Add existing time steps to list of options to avoid removing them when changing filter.
|
|
|
|
filteredTimeStepIndices.insert( filteredTimeStepIndices.end(),
|
|
|
|
currentlySelectedTimeStepIndices.begin(),
|
|
|
|
currentlySelectedTimeStepIndices.end() );
|
|
|
|
std::sort( filteredTimeStepIndices.begin(), filteredTimeStepIndices.end() );
|
|
|
|
filteredTimeStepIndices.erase( std::unique( filteredTimeStepIndices.begin(), filteredTimeStepIndices.end() ),
|
|
|
|
filteredTimeStepIndices.end() );
|
|
|
|
|
|
|
|
QString dateFormatString = RiaQDateTimeTools::dateFormatString( RiaPreferences::current()->dateFormat(),
|
|
|
|
RiaQDateTimeTools::DATE_FORMAT_YEAR_MONTH_DAY );
|
|
|
|
QString timeFormatString =
|
|
|
|
RiaQDateTimeTools::timeFormatString( RiaPreferences::current()->timeFormat(),
|
|
|
|
RiaQDateTimeTools::TimeFormatComponents::TIME_FORMAT_HOUR_MINUTE );
|
|
|
|
QString dateTimeFormat = QString( "%1 %2" ).arg( dateFormatString ).arg( timeFormatString );
|
|
|
|
|
|
|
|
for ( auto timeStepIndex : filteredTimeStepIndices )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
2020-07-31 02:50:13 -05:00
|
|
|
QDateTime dateTime = allDateTimes[timeStepIndex];
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-07-31 02:50:13 -05:00
|
|
|
options.push_back(
|
|
|
|
caf::PdmOptionItemInfo( RiaQDateTimeTools::toStringUsingApplicationLocale( dateTime, dateTimeFormat ),
|
|
|
|
dateTime ) );
|
2020-02-25 02:25:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( fieldNeedingOptions == &m_valueSortOperation )
|
|
|
|
{
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( NONE ), NONE ) );
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( VALUE ), VALUE ) );
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( ABS_VALUE ), ABS_VALUE ) );
|
|
|
|
}
|
|
|
|
else if ( fieldNeedingOptions == &m_majorGroupType || fieldNeedingOptions == &m_mediumGroupType ||
|
2020-07-30 06:20:00 -05:00
|
|
|
fieldNeedingOptions == &m_minorGroupType || fieldNeedingOptions == &m_sortGroupForColors )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( NONE ), NONE ) );
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( SUMMARY_ITEM ), SUMMARY_ITEM ) );
|
2020-02-25 09:11:44 -06:00
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( QUANTITY ), QUANTITY ) );
|
2020-02-25 02:25:57 -06:00
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( CASE ), CASE ) );
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( ENSEMBLE ), ENSEMBLE ) );
|
|
|
|
options.push_back( caf::PdmOptionItemInfo( SortGroupAppEnum::uiText( TIME_STEP ), TIME_STEP ) );
|
|
|
|
}
|
2020-02-27 02:01:38 -06:00
|
|
|
else if ( fieldNeedingOptions == &m_referenceCase )
|
|
|
|
{
|
2020-05-12 02:50:38 -05:00
|
|
|
std::vector<RimSummaryCase*> allSummaryCases = RimProject::current()->allSummaryCases();
|
2020-02-27 02:01:38 -06:00
|
|
|
|
2020-06-08 04:09:11 -05:00
|
|
|
options.push_back( {"None", nullptr} );
|
2020-02-27 02:01:38 -06:00
|
|
|
|
|
|
|
for ( auto sumCase : allSummaryCases )
|
|
|
|
{
|
|
|
|
QString displayName = sumCase->displayCaseName();
|
|
|
|
auto caseColl = dynamic_cast<RimSummaryCaseCollection*>( sumCase->parentField()->ownerObject() );
|
|
|
|
if ( caseColl )
|
|
|
|
{
|
|
|
|
displayName = caseColl->name() + "/" + displayName;
|
|
|
|
}
|
|
|
|
|
2020-06-08 04:09:11 -05:00
|
|
|
options.push_back( {displayName, sumCase} );
|
2020-02-27 02:01:38 -06:00
|
|
|
}
|
|
|
|
}
|
2020-07-30 06:20:00 -05:00
|
|
|
else if ( fieldNeedingOptions == &m_barTextFontSize )
|
|
|
|
{
|
|
|
|
options = caf::FontTools::relativeSizeValueOptions( RiaPreferences::current()->defaultPlotFontSize() );
|
|
|
|
}
|
2020-02-25 02:25:57 -06:00
|
|
|
|
|
|
|
return options;
|
|
|
|
}
|
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
2020-03-23 05:59:44 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::set<time_t> RimAnalysisPlot::allAvailableTimeSteps()
|
|
|
|
{
|
|
|
|
std::set<time_t> timeStepUnion;
|
|
|
|
|
|
|
|
for ( RimSummaryCase* sumCase : timestepDefiningSourceCases() )
|
|
|
|
{
|
|
|
|
const std::vector<time_t>& timeSteps = sumCase->summaryReader()->timeSteps( RifEclipseSummaryAddress() );
|
|
|
|
|
|
|
|
for ( time_t t : timeSteps )
|
|
|
|
{
|
|
|
|
timeStepUnion.insert( t );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return timeStepUnion;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::set<RimSummaryCase*> RimAnalysisPlot::timestepDefiningSourceCases()
|
|
|
|
{
|
2020-07-30 06:20:00 -05:00
|
|
|
RiaSummaryCurveDefinitionAnalyser* analyserOfSelectedCurveDefs = getOrCreateSelectedCurveDefAnalyser();
|
|
|
|
std::set<RimSummaryCase*> timeStepDefiningSumCases = analyserOfSelectedCurveDefs->m_singleSummaryCases;
|
|
|
|
for ( auto ensemble : analyserOfSelectedCurveDefs->m_ensembles )
|
|
|
|
{
|
|
|
|
auto allSumCases = ensemble->allSummaryCases();
|
|
|
|
timeStepDefiningSumCases.insert( allSumCases.begin(), allSumCases.end() );
|
|
|
|
}
|
2020-03-23 05:59:44 -05:00
|
|
|
|
|
|
|
return timeStepDefiningSumCases;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::set<RimSummaryCase*> RimAnalysisPlot::allSourceCases()
|
|
|
|
{
|
2020-07-30 06:20:00 -05:00
|
|
|
RiaSummaryCurveDefinitionAnalyser* analyserOfSelectedCurveDefs = getOrCreateSelectedCurveDefAnalyser();
|
|
|
|
std::set<RimSummaryCase*> allSumCases = analyserOfSelectedCurveDefs->m_singleSummaryCases;
|
2020-03-23 05:59:44 -05:00
|
|
|
|
|
|
|
return allSumCases;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
2020-02-28 04:07:53 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QWidget* RimAnalysisPlot::viewWidget()
|
|
|
|
{
|
|
|
|
return m_plotWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::deleteViewWidget()
|
|
|
|
{
|
|
|
|
cleanupBeforeClose();
|
|
|
|
}
|
|
|
|
|
2020-02-12 09:48:25 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::onLoadDataAndUpdate()
|
|
|
|
{
|
|
|
|
updateMdiWindowVisibility();
|
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
getOrCreateSelectedCurveDefAnalyser();
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-02-12 09:48:25 -06:00
|
|
|
if ( m_plotWidget )
|
|
|
|
{
|
2020-02-18 04:48:04 -06:00
|
|
|
m_plotWidget->detachItems( QwtPlotItem::Rtti_PlotBarChart );
|
|
|
|
m_plotWidget->detachItems( QwtPlotItem::Rtti_PlotScale );
|
|
|
|
|
2020-02-17 04:11:27 -06:00
|
|
|
RiuGroupedBarChartBuilder chartBuilder;
|
2020-07-30 06:20:00 -05:00
|
|
|
chartBuilder.setLabelFontSize( barTextFontSize() );
|
2020-02-18 04:48:04 -06:00
|
|
|
// buildTestPlot( chartBuilder );
|
2020-02-24 03:18:43 -06:00
|
|
|
addDataToChartBuilder( chartBuilder );
|
2020-02-17 04:11:27 -06:00
|
|
|
|
2020-02-26 04:21:44 -06:00
|
|
|
chartBuilder.addBarChartToPlot( m_plotWidget,
|
|
|
|
m_barOrientation == BARS_HORIZONTAL ? Qt::Horizontal : Qt::Vertical,
|
|
|
|
m_useTopBarsFilter() ? m_maxBarCount : -1 );
|
2020-02-12 09:48:25 -06:00
|
|
|
|
|
|
|
if ( m_showPlotLegends && m_plotWidget->legend() == nullptr )
|
|
|
|
{
|
|
|
|
QwtLegend* legend = new QwtLegend( m_plotWidget );
|
|
|
|
m_plotWidget->insertLegend( legend, QwtPlot::RightLegend );
|
|
|
|
}
|
2020-02-18 04:48:04 -06:00
|
|
|
else if ( !m_showPlotLegends )
|
2020-02-12 09:48:25 -06:00
|
|
|
{
|
|
|
|
m_plotWidget->insertLegend( nullptr );
|
|
|
|
}
|
|
|
|
|
2020-05-09 04:23:58 -05:00
|
|
|
m_plotWidget->setLegendFontSize( legendFontSize() );
|
2020-02-12 09:48:25 -06:00
|
|
|
m_plotWidget->updateLegend();
|
|
|
|
}
|
|
|
|
|
|
|
|
this->updateAxes();
|
2020-02-18 04:48:04 -06:00
|
|
|
this->updatePlotTitle();
|
|
|
|
}
|
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QImage RimAnalysisPlot::snapshotWindowContent()
|
|
|
|
{
|
|
|
|
QImage image;
|
|
|
|
|
|
|
|
if ( m_plotWidget )
|
|
|
|
{
|
|
|
|
QPixmap pix = m_plotWidget->grab();
|
|
|
|
image = pix.toImage();
|
|
|
|
}
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QString RimAnalysisPlot::description() const
|
|
|
|
{
|
|
|
|
return m_description();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RiuQwtPlotWidget* RimAnalysisPlot::doCreatePlotViewWidget( QWidget* mainWindowParent /*= nullptr */ )
|
|
|
|
{
|
|
|
|
if ( !m_plotWidget )
|
|
|
|
{
|
|
|
|
m_plotWidget = new RiuQwtPlotWidget( this, mainWindowParent );
|
|
|
|
|
|
|
|
this->connect( m_plotWidget, SIGNAL( plotZoomed() ), SLOT( onPlotZoomed() ) );
|
|
|
|
|
|
|
|
// updatePlotTitle();
|
|
|
|
}
|
|
|
|
|
|
|
|
return m_plotWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RiuQwtPlotWidget* RimAnalysisPlot::viewer()
|
|
|
|
{
|
|
|
|
return m_plotWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::detachAllCurves()
|
|
|
|
{
|
|
|
|
if ( m_plotWidget ) m_plotWidget->detachItems();
|
|
|
|
}
|
|
|
|
|
2020-02-28 07:51:21 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::updateAxes()
|
|
|
|
{
|
|
|
|
if ( !m_plotWidget ) return;
|
|
|
|
|
|
|
|
QwtPlot::Axis qwtAxis = QwtPlot::yLeft;
|
|
|
|
if ( m_barOrientation == BARS_HORIZONTAL )
|
|
|
|
{
|
|
|
|
qwtAxis = QwtPlot::xBottom;
|
|
|
|
m_plotWidget->setAxisTitleEnabled( QwtPlot::yLeft, false );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_plotWidget->setAxisTitleEnabled( QwtPlot::xBottom, false );
|
|
|
|
}
|
|
|
|
|
|
|
|
RimPlotAxisProperties* valAxisProperties = m_valueAxisProperties();
|
|
|
|
if ( valAxisProperties->isActive() )
|
|
|
|
{
|
|
|
|
m_plotWidget->enableAxis( qwtAxis, true );
|
|
|
|
m_valueAxisProperties->setNameAndAxis( "Value-Axis", qwtAxis );
|
|
|
|
|
|
|
|
std::set<QString> timeHistoryQuantities;
|
|
|
|
|
2020-03-25 10:23:41 -05:00
|
|
|
RimSummaryPlotAxisFormatter calc( valAxisProperties, {}, curveDefinitionsWithoutEnsembleReference(), {}, {} );
|
2020-02-28 07:51:21 -06:00
|
|
|
calc.applyAxisPropertiesToPlot( m_plotWidget );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_plotWidget->enableAxis( qwtAxis, false );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::onAxisSelected( int axis, bool toggle )
|
|
|
|
{
|
|
|
|
RiuPlotMainWindowTools::showPlotMainWindow();
|
|
|
|
|
|
|
|
caf::PdmObject* itemToSelect = nullptr;
|
|
|
|
if ( axis == QwtPlot::yLeft )
|
|
|
|
{
|
|
|
|
if ( m_barOrientation == BARS_VERTICAL )
|
|
|
|
{
|
|
|
|
itemToSelect = m_valueAxisProperties;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
itemToSelect = this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( axis == QwtPlot::xBottom )
|
|
|
|
{
|
|
|
|
if ( m_barOrientation == BARS_HORIZONTAL )
|
|
|
|
{
|
|
|
|
itemToSelect = m_valueAxisProperties;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
itemToSelect = this;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( toggle )
|
|
|
|
{
|
|
|
|
RiuPlotMainWindowTools::toggleItemInSelection( itemToSelect );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
RiuPlotMainWindowTools::selectAsCurrentItem( itemToSelect );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::cleanupBeforeClose()
|
|
|
|
{
|
|
|
|
detachAllCurves();
|
|
|
|
|
|
|
|
if ( m_plotWidget )
|
|
|
|
{
|
|
|
|
m_plotWidget->setParent( nullptr );
|
|
|
|
delete m_plotWidget;
|
|
|
|
m_plotWidget = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-02-25 02:25:57 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QString assignGroupingText( RimAnalysisPlot::SortGroupType sortGroup,
|
2020-02-26 06:51:57 -06:00
|
|
|
const RiaSummaryCurveDefinition dataEntry,
|
2020-02-25 02:25:57 -06:00
|
|
|
const QString& timestepString )
|
|
|
|
{
|
|
|
|
QString groupingText;
|
|
|
|
|
|
|
|
switch ( sortGroup )
|
|
|
|
{
|
|
|
|
case RimAnalysisPlot::SUMMARY_ITEM:
|
|
|
|
{
|
2020-02-26 06:51:57 -06:00
|
|
|
RifEclipseSummaryAddress addr = dataEntry.summaryAddress();
|
2020-02-25 09:11:44 -06:00
|
|
|
groupingText = QString::fromStdString( addr.itemUiText() );
|
2020-02-25 02:25:57 -06:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RimAnalysisPlot::CASE:
|
|
|
|
{
|
2020-02-26 06:51:57 -06:00
|
|
|
if ( dataEntry.summaryCase() )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
2020-02-26 06:51:57 -06:00
|
|
|
groupingText = dataEntry.summaryCase()->displayCaseName();
|
2020-02-25 02:25:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case RimAnalysisPlot::ENSEMBLE:
|
|
|
|
{
|
2020-02-26 06:51:57 -06:00
|
|
|
if ( dataEntry.ensemble() )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
2020-02-26 06:51:57 -06:00
|
|
|
groupingText = dataEntry.ensemble()->name();
|
2020-02-25 02:25:57 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2020-02-25 09:11:44 -06:00
|
|
|
case RimAnalysisPlot::QUANTITY:
|
|
|
|
{
|
2020-02-26 06:51:57 -06:00
|
|
|
RifEclipseSummaryAddress addr = dataEntry.summaryAddress();
|
2020-02-25 09:11:44 -06:00
|
|
|
|
|
|
|
groupingText = QString::fromStdString( addr.quantityName() );
|
|
|
|
}
|
|
|
|
break;
|
2020-02-25 02:25:57 -06:00
|
|
|
case RimAnalysisPlot::TIME_STEP:
|
|
|
|
{
|
|
|
|
groupingText = timestepString;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
{
|
|
|
|
// Return empty string
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return groupingText;
|
|
|
|
}
|
|
|
|
|
2020-02-18 04:48:04 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-03-24 10:29:38 -05:00
|
|
|
std::vector<size_t> RimAnalysisPlot::findTimestepIndices( std::vector<time_t> selectedTimesteps,
|
|
|
|
const std::vector<time_t>& timesteps )
|
2020-02-18 04:48:04 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
std::vector<size_t> selectedTimestepIndices;
|
|
|
|
|
|
|
|
for ( time_t tt : selectedTimesteps )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( size_t timestepIdx = 0; timestepIdx < timesteps.size(); ++timestepIdx )
|
|
|
|
{
|
|
|
|
if ( timesteps[timestepIdx] == tt )
|
|
|
|
{
|
|
|
|
selectedTimestepIndices.push_back( timestepIdx );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2020-02-25 02:25:57 -06:00
|
|
|
}
|
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
return selectedTimestepIndices;
|
|
|
|
}
|
2020-02-27 02:01:38 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
std::vector<RiaSummaryCurveDefinition> RimAnalysisPlot::filteredCurveDefs()
|
|
|
|
{
|
2020-03-25 10:23:41 -05:00
|
|
|
std::vector<RiaSummaryCurveDefinition> dataDefinitions = curveDefinitionsWithEmbeddedEnsembleReference();
|
2020-02-27 02:01:38 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
// Split out the filter targets
|
|
|
|
|
|
|
|
std::set<RimSummaryCase*> filteredSumCases;
|
|
|
|
std::set<RifEclipseSummaryAddress> filteredSummaryItems; // Stores only the unique summary items
|
|
|
|
|
|
|
|
for ( const auto& curveDef : dataDefinitions )
|
2020-02-18 04:48:04 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
filteredSumCases.insert( curveDef.summaryCase() );
|
2020-02-25 02:25:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
RifEclipseSummaryAddress address = curveDef.summaryAddress();
|
2020-03-03 02:49:54 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
address.setQuantityName( "" ); // Quantity name set to "" in order to store only unique summary items
|
|
|
|
filteredSummaryItems.insert( address );
|
|
|
|
}
|
2020-02-18 04:48:04 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
std::vector<RimPlotDataFilterItem*> filters = m_plotDataFilterCollection->filters();
|
|
|
|
|
|
|
|
for ( RimPlotDataFilterItem* filter : filters )
|
|
|
|
{
|
|
|
|
applyFilter( filter, &filteredSumCases, &filteredSummaryItems );
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remove all
|
|
|
|
|
|
|
|
std::vector<RiaSummaryCurveDefinition> filteredDataDefinitions;
|
|
|
|
|
|
|
|
for ( const RiaSummaryCurveDefinition& curveDefCandidate : dataDefinitions )
|
|
|
|
{
|
|
|
|
RimSummaryCase* sumCase = curveDefCandidate.summaryCase();
|
|
|
|
RifEclipseSummaryAddress addr = curveDefCandidate.summaryAddress();
|
|
|
|
addr.setQuantityName( "" );
|
|
|
|
|
|
|
|
if ( filteredSumCases.count( sumCase ) && filteredSummaryItems.count( addr ) )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
filteredDataDefinitions.push_back( curveDefCandidate );
|
2020-02-25 02:25:57 -06:00
|
|
|
}
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
return filteredDataDefinitions;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
void RimAnalysisPlot::applyFilter( const RimPlotDataFilterItem* filter,
|
|
|
|
std::set<RimSummaryCase*>* filteredSumCases,
|
|
|
|
std::set<RifEclipseSummaryAddress>* filteredSummaryItems )
|
|
|
|
{
|
|
|
|
const std::vector<RiaSummaryCurveDefinition> curveDefsToFilter;
|
|
|
|
|
|
|
|
if ( !filter->isActive() ) return;
|
|
|
|
|
|
|
|
std::vector<RiaSummaryCurveDefinition> filteredCurveDefs;
|
|
|
|
|
|
|
|
std::set<RimSummaryCase*> casesToKeep;
|
|
|
|
std::set<RifEclipseSummaryAddress> sumItemsToKeep;
|
|
|
|
|
|
|
|
std::map<RimSummaryCase*, double> casesToKeepWithValue;
|
|
|
|
std::map<RifEclipseSummaryAddress, double> sumItemsToKeepWithValue;
|
|
|
|
|
|
|
|
if ( filter->filterTarget() == RimPlotDataFilterItem::ENSEMBLE_CASE )
|
|
|
|
{
|
|
|
|
sumItemsToKeep = ( *filteredSummaryItems ); // Not filtering items
|
|
|
|
|
|
|
|
EnsembleParameter eParam = this->ensembleParameter( filter->ensembleParameterName() );
|
|
|
|
|
|
|
|
std::set<RimSummaryCase*> casesToRemove;
|
|
|
|
for ( auto sumCase : ( *filteredSumCases ) )
|
2020-02-25 02:25:57 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( !eParam.isValid() ) continue;
|
|
|
|
if ( !sumCase->caseRealizationParameters() ) continue;
|
|
|
|
|
|
|
|
RigCaseRealizationParameters::Value crpValue =
|
|
|
|
sumCase->caseRealizationParameters()->parameterValue( filter->ensembleParameterName() );
|
|
|
|
|
|
|
|
if ( eParam.isNumeric() && crpValue.isNumeric() )
|
2020-03-03 02:49:54 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
double value = crpValue.numericValue();
|
|
|
|
|
|
|
|
if ( filter->filterOperation() == RimPlotDataFilterItem::RANGE )
|
|
|
|
{
|
|
|
|
std::pair<double, double> minMax = filter->filterRangeMinMax();
|
|
|
|
|
|
|
|
if ( filter->useAbsoluteValues() ) value = fabs( value );
|
|
|
|
|
|
|
|
if ( minMax.first < value && value < minMax.second )
|
|
|
|
{
|
|
|
|
casesToKeep.insert( sumCase );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( filter->filterOperation() == RimPlotDataFilterItem::TOP_N ||
|
|
|
|
filter->filterOperation() == RimPlotDataFilterItem::BOTTOM_N )
|
|
|
|
{
|
|
|
|
if ( filter->useAbsoluteValues() ) value = fabs( value );
|
|
|
|
bool useLargest = filter->filterOperation() == RimPlotDataFilterItem::TOP_N;
|
|
|
|
|
2020-06-08 04:09:11 -05:00
|
|
|
auto itIsInsertedPair = casesToKeepWithValue.insert( {sumCase, value} );
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( !itIsInsertedPair.second ) // Already exists in map
|
|
|
|
{
|
|
|
|
double& insertedValue = itIsInsertedPair.first->second;
|
|
|
|
if ( ( useLargest && ( insertedValue < value ) ) || ( !useLargest && ( value < insertedValue ) ) )
|
|
|
|
{
|
|
|
|
insertedValue = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-03 02:49:54 -06:00
|
|
|
}
|
2020-03-24 10:29:38 -05:00
|
|
|
else if ( eParam.isText() && crpValue.isText() )
|
2020-03-03 02:49:54 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
const auto& filterCategories = filter->selectedEnsembleParameterCategories();
|
|
|
|
|
|
|
|
if ( crpValue.isText() &&
|
|
|
|
std::count( filterCategories.begin(), filterCategories.end(), crpValue.textValue() ) == 0 )
|
|
|
|
{
|
|
|
|
casesToKeep.insert( sumCase );
|
|
|
|
}
|
2020-03-03 02:49:54 -06:00
|
|
|
}
|
2020-02-26 06:51:57 -06:00
|
|
|
}
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::vector<time_t> selectedTimesteps;
|
|
|
|
|
|
|
|
if ( filter->consideredTimeStepsType() == RimPlotDataFilterItem::SELECT_TIMESTEPS )
|
|
|
|
{
|
|
|
|
selectedTimesteps = filter->explicitlySelectedTimeSteps();
|
|
|
|
}
|
|
|
|
else if ( filter->consideredTimeStepsType() == RimPlotDataFilterItem::PLOT_SOURCE_TIMESTEPS )
|
|
|
|
{
|
|
|
|
selectedTimesteps = this->selectedTimeSteps();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::function<void( double )> storeResultCoreLambda;
|
|
|
|
|
|
|
|
RimSummaryCase* sumCaseInEvaluation = nullptr;
|
2020-02-18 04:48:04 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
// clang-format off
|
|
|
|
std::function<void( RifEclipseSummaryAddress )> evaluateFilterForAllCases =
|
|
|
|
[&]( RifEclipseSummaryAddress addrToFilterValue ) // clang-format on
|
2020-02-26 06:51:57 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( auto sumCase : *filteredSumCases )
|
|
|
|
{
|
|
|
|
sumCaseInEvaluation = sumCase;
|
2020-02-27 02:01:38 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
RifSummaryReaderInterface* reader = sumCase->summaryReader();
|
|
|
|
if ( !reader ) continue;
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( reader->hasAddress( addrToFilterValue ) )
|
|
|
|
{
|
|
|
|
std::vector<double> values;
|
|
|
|
reader->values( addrToFilterValue, &values );
|
|
|
|
const std::vector<time_t>& timesteps = reader->timeSteps( addrToFilterValue );
|
2020-02-18 04:48:04 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( filter->consideredTimeStepsType() == RimPlotDataFilterItem::ALL_TIMESTEPS )
|
|
|
|
{
|
2020-04-24 12:55:54 -05:00
|
|
|
for ( size_t tIdx = 0; tIdx < timesteps.size(); ++tIdx )
|
2020-03-24 10:29:38 -05:00
|
|
|
{
|
|
|
|
double value = values[tIdx];
|
2020-02-27 02:01:38 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
storeResultCoreLambda( value );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( timesteps.size() )
|
|
|
|
{
|
|
|
|
std::vector<size_t> selectedTimestepIndices;
|
|
|
|
|
|
|
|
if ( filter->consideredTimeStepsType() == RimPlotDataFilterItem::FIRST_TIMESTEP )
|
|
|
|
{
|
|
|
|
selectedTimestepIndices.push_back( 0 );
|
|
|
|
}
|
|
|
|
else if ( filter->consideredTimeStepsType() == RimPlotDataFilterItem::LAST_TIMESTEP )
|
|
|
|
{
|
|
|
|
size_t timeStepIdx = timesteps.size() - 1;
|
|
|
|
selectedTimestepIndices.push_back( timeStepIdx );
|
|
|
|
}
|
|
|
|
else if ( selectedTimesteps.size() )
|
|
|
|
{
|
|
|
|
selectedTimestepIndices = RimAnalysisPlot::findTimestepIndices( selectedTimesteps, timesteps );
|
|
|
|
}
|
|
|
|
else if ( filter->consideredTimeStepsType() == RimPlotDataFilterItem::LAST_TIMESTEP_WITH_HISTORY )
|
|
|
|
{
|
|
|
|
RifEclipseSummaryAddress historyAddr = addrToFilterValue;
|
|
|
|
|
|
|
|
if ( !historyAddr.isHistoryQuantity() )
|
|
|
|
historyAddr.setQuantityName( addrToFilterValue.quantityName() + "H" );
|
|
|
|
|
|
|
|
const std::vector<time_t>& historyTimesteps = reader->timeSteps( historyAddr );
|
|
|
|
if ( historyTimesteps.size() )
|
|
|
|
{
|
|
|
|
selectedTimestepIndices =
|
2020-06-08 04:09:11 -05:00
|
|
|
RimAnalysisPlot::findTimestepIndices( {historyTimesteps.back()}, timesteps );
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( filter->consideredTimeStepsType() == RimPlotDataFilterItem::SELECT_TIMESTEP_RANGE )
|
|
|
|
{
|
|
|
|
std::pair<time_t, time_t> timeMinMax = filter->timeRangeMinMax();
|
|
|
|
|
|
|
|
for ( size_t tIdx = 0; tIdx < timesteps.size(); ++tIdx )
|
|
|
|
{
|
|
|
|
time_t dateTime = timesteps[tIdx];
|
|
|
|
|
|
|
|
if ( timeMinMax.first <= dateTime && dateTime <= timeMinMax.second )
|
|
|
|
{
|
|
|
|
selectedTimestepIndices.push_back( tIdx );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for ( size_t timeStepIdx : selectedTimestepIndices )
|
|
|
|
{
|
|
|
|
double value = values[timeStepIdx];
|
|
|
|
storeResultCoreLambda( value );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
if ( filter->filterTarget() == RimPlotDataFilterItem::SUMMARY_CASE )
|
|
|
|
{
|
|
|
|
sumItemsToKeep = ( *filteredSummaryItems ); // Not filtering items
|
|
|
|
|
|
|
|
RifEclipseSummaryAddress addrToFilterValue = filter->summaryAddress();
|
|
|
|
|
|
|
|
if ( filter->filterOperation() == RimPlotDataFilterItem::RANGE )
|
2020-02-27 02:01:38 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
std::pair<double, double> minMax = filter->filterRangeMinMax();
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
storeResultCoreLambda = [&]( double value ) // clang-format on
|
|
|
|
{
|
|
|
|
if ( filter->useAbsoluteValues() ) value = fabs( value );
|
|
|
|
|
|
|
|
if ( minMax.first <= value && value <= minMax.second )
|
|
|
|
{
|
|
|
|
casesToKeep.insert( sumCaseInEvaluation );
|
|
|
|
}
|
|
|
|
};
|
2020-02-27 02:01:38 -06:00
|
|
|
}
|
2020-03-24 10:29:38 -05:00
|
|
|
else if ( filter->filterOperation() == RimPlotDataFilterItem::TOP_N ||
|
|
|
|
filter->filterOperation() == RimPlotDataFilterItem::BOTTOM_N )
|
2020-02-27 02:01:38 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
// clang-format off
|
|
|
|
storeResultCoreLambda = [&]( double value ) // clang-format on
|
|
|
|
{
|
|
|
|
if ( filter->useAbsoluteValues() ) value = fabs( value );
|
|
|
|
bool useLargest = filter->filterOperation() == RimPlotDataFilterItem::TOP_N;
|
2020-02-27 02:01:38 -06:00
|
|
|
|
2020-06-08 04:09:11 -05:00
|
|
|
auto itIsInsertedPair = casesToKeepWithValue.insert( {sumCaseInEvaluation, value} );
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( !itIsInsertedPair.second ) // Already exists in map
|
|
|
|
{
|
|
|
|
double& insertedValue = itIsInsertedPair.first->second;
|
|
|
|
if ( ( useLargest && ( insertedValue < value ) ) || ( !useLargest && ( value < insertedValue ) ) )
|
|
|
|
{
|
|
|
|
insertedValue = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2020-02-27 02:01:38 -06:00
|
|
|
}
|
2020-02-25 02:25:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
evaluateFilterForAllCases( addrToFilterValue );
|
|
|
|
}
|
|
|
|
else if ( filter->filterTarget() == RimPlotDataFilterItem::SUMMARY_ITEM )
|
|
|
|
{
|
|
|
|
casesToKeep = ( *filteredSumCases ); // Not filtering cases
|
2020-02-25 02:25:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
std::string quantityName;
|
|
|
|
{
|
|
|
|
RifEclipseSummaryAddress addrToFilterValue = filter->summaryAddress();
|
2020-02-25 02:25:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
quantityName = addrToFilterValue.quantityName();
|
|
|
|
}
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( auto sumItem : *filteredSummaryItems )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
RifEclipseSummaryAddress addrToFilterValue = sumItem;
|
|
|
|
addrToFilterValue.setQuantityName( quantityName );
|
|
|
|
|
|
|
|
if ( filter->filterOperation() == RimPlotDataFilterItem::RANGE )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
std::pair<double, double> minMax = filter->filterRangeMinMax();
|
|
|
|
|
|
|
|
// clang-format off
|
|
|
|
storeResultCoreLambda = [&]( double value ) // clang-format on
|
2020-02-26 06:51:57 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( filter->useAbsoluteValues() ) value = fabs( value );
|
|
|
|
|
|
|
|
if ( minMax.first <= value && value <= minMax.second )
|
|
|
|
{
|
|
|
|
sumItemsToKeep.insert( sumItem );
|
|
|
|
}
|
|
|
|
};
|
|
|
|
}
|
|
|
|
else if ( filter->filterOperation() == RimPlotDataFilterItem::TOP_N ||
|
|
|
|
filter->filterOperation() == RimPlotDataFilterItem::BOTTOM_N )
|
|
|
|
{
|
|
|
|
// clang-format off
|
|
|
|
storeResultCoreLambda = [&]( double value ) // clang-format on
|
|
|
|
{
|
|
|
|
if ( filter->useAbsoluteValues() ) value = fabs( value );
|
|
|
|
bool useLargest = filter->filterOperation() == RimPlotDataFilterItem::TOP_N;
|
|
|
|
|
2020-06-08 04:09:11 -05:00
|
|
|
auto itIsInsertedPair = sumItemsToKeepWithValue.insert( {sumItem, value} );
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( !itIsInsertedPair.second ) // Already exists in map
|
|
|
|
{
|
|
|
|
double& insertedValue = itIsInsertedPair.first->second;
|
|
|
|
if ( ( useLargest && ( insertedValue < value ) ) ||
|
|
|
|
( !useLargest && ( value < insertedValue ) ) )
|
|
|
|
{
|
|
|
|
insertedValue = value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2020-02-25 09:11:44 -06:00
|
|
|
}
|
2020-03-24 10:29:38 -05:00
|
|
|
|
|
|
|
evaluateFilterForAllCases( addrToFilterValue );
|
2020-02-26 06:51:57 -06:00
|
|
|
}
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Handle top/bottom n filter
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( filter->filterOperation() == RimPlotDataFilterItem::TOP_N ||
|
|
|
|
filter->filterOperation() == RimPlotDataFilterItem::BOTTOM_N )
|
|
|
|
{
|
|
|
|
if ( filter->filterTarget() == RimPlotDataFilterItem::SUMMARY_ITEM )
|
|
|
|
{
|
|
|
|
std::multimap<double, RifEclipseSummaryAddress> valueSortedSumItems;
|
|
|
|
for ( const auto& itemValPair : sumItemsToKeepWithValue )
|
2020-02-26 06:51:57 -06:00
|
|
|
{
|
2020-06-08 04:09:11 -05:00
|
|
|
valueSortedSumItems.insert( {itemValPair.second, itemValPair.first} );
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( filter->filterOperation() == RimPlotDataFilterItem::TOP_N )
|
|
|
|
{
|
2020-04-24 12:55:54 -05:00
|
|
|
int count = 0;
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( auto it = valueSortedSumItems.rbegin();
|
|
|
|
count < filter->topBottomN() && it != valueSortedSumItems.rend();
|
|
|
|
++it )
|
|
|
|
{
|
|
|
|
sumItemsToKeep.insert( it->second );
|
|
|
|
++count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( filter->filterOperation() == RimPlotDataFilterItem::BOTTOM_N )
|
|
|
|
{
|
2020-04-24 12:55:54 -05:00
|
|
|
int count = 0;
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( auto it = valueSortedSumItems.begin();
|
|
|
|
count < filter->topBottomN() && it != valueSortedSumItems.end();
|
|
|
|
++it )
|
|
|
|
{
|
|
|
|
sumItemsToKeep.insert( it->second );
|
|
|
|
++count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
std::multimap<double, RimSummaryCase*> valueSortedSumCases;
|
|
|
|
for ( const auto& caseValPair : casesToKeepWithValue )
|
|
|
|
{
|
2020-06-08 04:09:11 -05:00
|
|
|
valueSortedSumCases.insert( {caseValPair.second, caseValPair.first} );
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( filter->filterOperation() == RimPlotDataFilterItem::TOP_N )
|
|
|
|
{
|
2020-04-24 12:55:54 -05:00
|
|
|
int count = 0;
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( auto it = valueSortedSumCases.rbegin();
|
|
|
|
count < filter->topBottomN() && it != valueSortedSumCases.rend();
|
|
|
|
++it )
|
|
|
|
{
|
|
|
|
casesToKeep.insert( it->second );
|
|
|
|
++count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ( filter->filterOperation() == RimPlotDataFilterItem::BOTTOM_N )
|
|
|
|
{
|
2020-04-24 12:55:54 -05:00
|
|
|
int count = 0;
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( auto it = valueSortedSumCases.begin();
|
|
|
|
count < filter->topBottomN() && it != valueSortedSumCases.end();
|
|
|
|
++it )
|
|
|
|
{
|
|
|
|
casesToKeep.insert( it->second );
|
|
|
|
++count;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-02-26 06:51:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
( *filteredSumCases ) = casesToKeep;
|
|
|
|
( *filteredSummaryItems ) = sumItemsToKeep;
|
|
|
|
}
|
2020-02-26 06:51:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::addDataToChartBuilder( RiuGroupedBarChartBuilder& chartBuilder )
|
|
|
|
{
|
|
|
|
std::vector<time_t> selectedTimesteps;
|
|
|
|
for ( const QDateTime& dateTime : m_selectedTimeSteps.v() )
|
|
|
|
{
|
|
|
|
selectedTimesteps.push_back( dateTime.toTime_t() );
|
|
|
|
}
|
|
|
|
|
|
|
|
RifSummaryReaderInterface* referenceCaseReader = nullptr;
|
|
|
|
|
|
|
|
if ( m_referenceCase ) referenceCaseReader = m_referenceCase->summaryReader();
|
|
|
|
|
|
|
|
// Unpack ensemble curves and make one curve definition for each individual curve.
|
|
|
|
// Store both ensemble and summary case in the definition
|
|
|
|
|
|
|
|
std::vector<RiaSummaryCurveDefinition> barDataDefinitions = filteredCurveDefs();
|
|
|
|
|
|
|
|
for ( const RiaSummaryCurveDefinition& curveDef : barDataDefinitions )
|
|
|
|
{
|
2020-04-15 05:09:40 -05:00
|
|
|
if ( !curveDef.summaryCase() ) continue;
|
2020-03-24 10:29:38 -05:00
|
|
|
RifSummaryReaderInterface* reader = curveDef.summaryCase()->summaryReader();
|
|
|
|
|
|
|
|
if ( !reader ) continue;
|
|
|
|
|
|
|
|
// Todo:
|
|
|
|
// If curveDef.summaryCase() is a RimGridSummaryCase and we are using summary item as legend and the summary
|
|
|
|
// items are wells, then:
|
|
|
|
/// use color from eclCase->defaultWellColor( wellName );
|
|
|
|
|
|
|
|
std::vector<time_t> timeStepStorage;
|
|
|
|
const std::vector<time_t>* timeStepsPtr = &timeStepStorage;
|
|
|
|
std::vector<double> values;
|
|
|
|
|
|
|
|
if ( referenceCaseReader )
|
|
|
|
{
|
|
|
|
std::pair<std::vector<time_t>, std::vector<double>> timeAndValues =
|
|
|
|
RimDerivedSummaryCase::calculateDerivedValues( reader,
|
2020-03-31 06:13:47 -05:00
|
|
|
-1,
|
2020-03-24 10:29:38 -05:00
|
|
|
referenceCaseReader,
|
2020-03-31 06:13:47 -05:00
|
|
|
-1,
|
2020-03-24 10:29:38 -05:00
|
|
|
DerivedSummaryOperator::DERIVED_OPERATOR_SUB,
|
|
|
|
curveDef.summaryAddress() );
|
|
|
|
timeStepStorage.swap( timeAndValues.first );
|
|
|
|
values.swap( timeAndValues.second );
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
timeStepsPtr = &( reader->timeSteps( curveDef.summaryAddress() ) );
|
2020-02-26 06:51:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
reader->values( curveDef.summaryAddress(), &values );
|
|
|
|
}
|
|
|
|
|
|
|
|
const std::vector<time_t>& timesteps = *timeStepsPtr;
|
|
|
|
|
|
|
|
if ( !( timesteps.size() && values.size() ) ) continue;
|
|
|
|
|
|
|
|
// Find selected timestep indices
|
|
|
|
|
|
|
|
std::vector<int> selectedTimestepIndices;
|
|
|
|
|
|
|
|
for ( time_t tt : selectedTimesteps )
|
|
|
|
{
|
|
|
|
for ( int timestepIdx = 0; static_cast<unsigned>( timestepIdx ) < timesteps.size(); ++timestepIdx )
|
|
|
|
{
|
|
|
|
if ( timesteps[timestepIdx] == tt )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
2020-03-24 10:29:38 -05:00
|
|
|
selectedTimestepIndices.push_back( timestepIdx );
|
|
|
|
break;
|
2020-02-25 09:11:44 -06:00
|
|
|
}
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
|
|
|
}
|
2020-02-25 09:11:44 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
for ( int timestepIdx : selectedTimestepIndices )
|
|
|
|
{
|
|
|
|
double sortValue = std::numeric_limits<double>::infinity();
|
2020-02-26 06:51:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
QDateTime dateTime = RiaQDateTimeTools::fromTime_t( timesteps[timestepIdx] );
|
2020-06-08 04:09:11 -05:00
|
|
|
QString formatString = RiaQDateTimeTools::createTimeFormatStringFromDates( {dateTime} );
|
2020-02-26 06:51:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
QString timestepString = dateTime.toString( formatString );
|
2020-02-26 06:51:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
QString majorText = assignGroupingText( m_majorGroupType(), curveDef, timestepString );
|
|
|
|
QString medText = assignGroupingText( m_mediumGroupType(), curveDef, timestepString );
|
|
|
|
QString minText = assignGroupingText( m_minorGroupType(), curveDef, timestepString );
|
2020-07-30 06:20:00 -05:00
|
|
|
QString legendText = assignGroupingText( m_sortGroupForColors(), curveDef, timestepString );
|
2020-02-26 06:51:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
double value = values[timestepIdx];
|
2020-02-26 06:51:57 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
switch ( m_valueSortOperation() )
|
|
|
|
{
|
|
|
|
case VALUE:
|
|
|
|
sortValue = value;
|
|
|
|
break;
|
|
|
|
case ABS_VALUE:
|
|
|
|
sortValue = fabs( value );
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
QString barText;
|
|
|
|
QString separator = " ";
|
|
|
|
|
|
|
|
if ( m_useBarText() )
|
|
|
|
{
|
|
|
|
if ( m_useQuantityInBarText )
|
|
|
|
{
|
|
|
|
barText += QString::fromStdString( curveDef.summaryAddress().quantityName() ) + separator;
|
2020-02-25 09:11:44 -06:00
|
|
|
}
|
2020-02-18 04:48:04 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
if ( m_useSummaryItemInBarText )
|
|
|
|
{
|
|
|
|
barText += QString::fromStdString( curveDef.summaryAddress().itemUiText() ) + separator;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_useCaseInBarText && curveDef.summaryCase() )
|
|
|
|
{
|
|
|
|
barText += curveDef.summaryCase()->displayCaseName() + separator;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_useEnsembleInBarText && curveDef.ensemble() )
|
|
|
|
{
|
|
|
|
barText += curveDef.ensemble()->name() + separator;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_useTimeStepInBarText )
|
|
|
|
{
|
|
|
|
barText += timestepString + separator;
|
|
|
|
}
|
2020-02-26 06:51:57 -06:00
|
|
|
}
|
2020-03-24 10:29:38 -05:00
|
|
|
|
|
|
|
chartBuilder.addBarEntry( majorText, medText, minText, sortValue, legendText, barText, value );
|
2020-02-25 02:25:57 -06:00
|
|
|
}
|
2020-02-18 04:48:04 -06:00
|
|
|
}
|
2020-02-12 09:48:25 -06:00
|
|
|
}
|
2020-02-17 04:11:27 -06:00
|
|
|
|
2020-02-18 04:48:04 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::updatePlotTitle()
|
|
|
|
{
|
2020-07-30 06:20:00 -05:00
|
|
|
if ( m_useAutoPlotTitle )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
|
|
|
QString autoTitle;
|
|
|
|
QString separator = ", ";
|
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
if ( getOrCreateSelectedCurveDefAnalyser()->m_ensembles.size() == 1 )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
2020-07-30 06:20:00 -05:00
|
|
|
autoTitle += ( *getOrCreateSelectedCurveDefAnalyser()->m_ensembles.begin() )->name();
|
2020-02-25 09:11:44 -06:00
|
|
|
}
|
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
if ( getOrCreateSelectedCurveDefAnalyser()->m_singleSummaryCases.size() == 1 )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
|
|
|
if ( !autoTitle.isEmpty() ) autoTitle += separator;
|
2020-07-30 06:20:00 -05:00
|
|
|
autoTitle += ( *getOrCreateSelectedCurveDefAnalyser()->m_singleSummaryCases.begin() )->displayCaseName();
|
2020-02-25 09:11:44 -06:00
|
|
|
}
|
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
if ( getOrCreateSelectedCurveDefAnalyser()->m_summaryItems.size() == 1 )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
|
|
|
if ( !autoTitle.isEmpty() ) autoTitle += separator;
|
2020-07-30 06:20:00 -05:00
|
|
|
autoTitle +=
|
|
|
|
QString::fromStdString( getOrCreateSelectedCurveDefAnalyser()->m_summaryItems.begin()->itemUiText() );
|
2020-02-25 09:11:44 -06:00
|
|
|
}
|
|
|
|
|
2020-07-30 06:20:00 -05:00
|
|
|
for ( std::string quantName : getOrCreateSelectedCurveDefAnalyser()->m_quantityNames )
|
2020-02-25 09:11:44 -06:00
|
|
|
{
|
|
|
|
if ( !autoTitle.isEmpty() ) autoTitle += separator;
|
|
|
|
autoTitle += QString::fromStdString( quantName );
|
|
|
|
}
|
|
|
|
|
2020-02-27 02:01:38 -06:00
|
|
|
if ( m_referenceCase() )
|
|
|
|
{
|
|
|
|
if ( !autoTitle.isEmpty() ) autoTitle += separator;
|
|
|
|
autoTitle += "Compared to " + m_referenceCase->displayCaseName();
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_useTopBarsFilter )
|
|
|
|
{
|
|
|
|
if ( !autoTitle.isEmpty() ) autoTitle += " - ";
|
|
|
|
autoTitle += "Top " + QString::number( m_maxBarCount() );
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( m_selectedTimeSteps().size() == 1 )
|
|
|
|
{
|
|
|
|
if ( !autoTitle.isEmpty() ) autoTitle += " @ ";
|
|
|
|
|
2020-06-08 04:09:11 -05:00
|
|
|
QString formatString = RiaQDateTimeTools::createTimeFormatStringFromDates( {m_selectedTimeSteps()[0]} );
|
2020-02-27 02:01:38 -06:00
|
|
|
autoTitle += m_selectedTimeSteps()[0].toString( formatString );
|
|
|
|
}
|
|
|
|
|
2020-02-25 09:11:44 -06:00
|
|
|
m_description = autoTitle;
|
|
|
|
}
|
|
|
|
|
2020-02-18 04:48:04 -06:00
|
|
|
if ( m_plotWidget )
|
|
|
|
{
|
|
|
|
QString plotTitle = description();
|
|
|
|
m_plotWidget->setPlotTitle( plotTitle );
|
|
|
|
m_plotWidget->setPlotTitleEnabled( m_showPlotTitle && isMdiWindow() );
|
|
|
|
m_plotWidget->scheduleReplot();
|
|
|
|
}
|
|
|
|
}
|
2020-02-24 03:44:51 -06:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-04-21 01:56:27 -05:00
|
|
|
RiaSummaryCurveDefinitionAnalyser* RimAnalysisPlot::getOrCreateSelectedCurveDefAnalyser()
|
2020-03-19 10:34:30 -05:00
|
|
|
{
|
|
|
|
if ( !m_analyserOfSelectedCurveDefs )
|
|
|
|
{
|
2020-07-30 07:03:50 -05:00
|
|
|
m_analyserOfSelectedCurveDefs =
|
|
|
|
std::unique_ptr<RiaSummaryCurveDefinitionAnalyser>( new RiaSummaryCurveDefinitionAnalyser );
|
2020-03-19 10:34:30 -05:00
|
|
|
}
|
2020-07-30 07:03:50 -05:00
|
|
|
m_analyserOfSelectedCurveDefs->setCurveDefinitions( this->curveDefinitionsWithoutEnsembleReference() );
|
2020-03-19 10:34:30 -05:00
|
|
|
return m_analyserOfSelectedCurveDefs.get();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-03-25 10:23:41 -05:00
|
|
|
std::vector<RiaSummaryCurveDefinition> RimAnalysisPlot::curveDefinitionsWithoutEnsembleReference() const
|
2020-02-24 03:44:51 -06:00
|
|
|
{
|
|
|
|
std::vector<RiaSummaryCurveDefinition> curveDefs;
|
2020-03-19 10:34:30 -05:00
|
|
|
for ( auto dataEntry : m_analysisPlotDataSelection )
|
2020-02-24 03:44:51 -06:00
|
|
|
{
|
|
|
|
curveDefs.push_back( dataEntry->curveDefinition() );
|
|
|
|
}
|
|
|
|
|
|
|
|
return curveDefs;
|
|
|
|
}
|
2020-02-26 04:21:44 -06:00
|
|
|
|
2020-03-24 10:29:38 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
/// The curve definitions returned contain both the case AND the ensemble from which it has been spawned
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-03-25 10:23:41 -05:00
|
|
|
std::vector<RiaSummaryCurveDefinition> RimAnalysisPlot::curveDefinitionsWithEmbeddedEnsembleReference()
|
2020-03-24 10:29:38 -05:00
|
|
|
{
|
|
|
|
std::vector<RiaSummaryCurveDefinition> barDataDefinitions;
|
|
|
|
|
|
|
|
for ( const RimAnalysisPlotDataEntry* dataEntry : m_analysisPlotDataSelection )
|
|
|
|
{
|
|
|
|
RiaSummaryCurveDefinition orgBarDataEntry = dataEntry->curveDefinition();
|
|
|
|
|
2020-03-25 10:23:41 -05:00
|
|
|
if ( orgBarDataEntry.summaryCase() && orgBarDataEntry.summaryCase()->ensemble() )
|
2020-03-24 10:29:38 -05:00
|
|
|
{
|
2020-03-25 10:23:41 -05:00
|
|
|
barDataDefinitions.push_back( RiaSummaryCurveDefinition( orgBarDataEntry.summaryCase(),
|
|
|
|
orgBarDataEntry.summaryAddress(),
|
|
|
|
orgBarDataEntry.summaryCase()->ensemble() ) );
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-03-25 10:23:41 -05:00
|
|
|
barDataDefinitions.push_back( orgBarDataEntry );
|
2020-03-24 10:29:38 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return barDataDefinitions;
|
|
|
|
}
|
|
|
|
|
2020-02-26 04:21:44 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2020-02-28 04:07:53 -06:00
|
|
|
std::set<RimPlotAxisPropertiesInterface*> RimAnalysisPlot::allPlotAxes() const
|
2020-02-26 04:21:44 -06:00
|
|
|
{
|
2020-06-08 04:09:11 -05:00
|
|
|
return {m_valueAxisProperties};
|
2020-02-28 04:07:53 -06:00
|
|
|
}
|
|
|
|
|
2020-07-02 06:06:31 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::connectAxisSignals( RimPlotAxisProperties* axis )
|
|
|
|
{
|
|
|
|
axis->settingsChanged.connect( this, &RimAnalysisPlot::axisSettingsChanged );
|
|
|
|
axis->logarithmicChanged.connect( this, &RimAnalysisPlot::axisLogarithmicChanged );
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::axisSettingsChanged( const caf::SignalEmitter* emitter )
|
|
|
|
{
|
|
|
|
updateAxes();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::axisLogarithmicChanged( const caf::SignalEmitter* emitter, bool isLogarithmic )
|
|
|
|
{
|
|
|
|
loadDataAndUpdate();
|
|
|
|
}
|
|
|
|
|
2020-02-28 04:07:53 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimAnalysisPlot::buildTestPlot( RiuGroupedBarChartBuilder& chartBuilder )
|
|
|
|
{
|
|
|
|
chartBuilder.addBarEntry( "T1_The_red_Fox", "", "", std::numeric_limits<double>::infinity(), "R1", "", 0.4 );
|
|
|
|
chartBuilder.addBarEntry( "T1_The_red_Fox", "", "", std::numeric_limits<double>::infinity(), "R2", "", 0.45 );
|
|
|
|
chartBuilder.addBarEntry( "T1_The_red_Fox", "W1", "", std::numeric_limits<double>::infinity(), "R1", "", 0.5 );
|
|
|
|
chartBuilder.addBarEntry( "T1_The_red_Fox", "W1", "", std::numeric_limits<double>::infinity(), "R2", "", 0.55 );
|
|
|
|
chartBuilder.addBarEntry( "T1_The_red_Fox", "W3", "", std::numeric_limits<double>::infinity(), "R1", "", 0.7 );
|
|
|
|
chartBuilder.addBarEntry( "T1_The_red_Fox", "W3", "", std::numeric_limits<double>::infinity(), "R2", "", 0.75 );
|
|
|
|
chartBuilder.addBarEntry( "T1_The_red_Fox", "W2", "", std::numeric_limits<double>::infinity(), "R1", "", 1.05 );
|
|
|
|
chartBuilder.addBarEntry( "T1_The_red_Fox", "W2", "", std::numeric_limits<double>::infinity(), "R2", "", 1.0 );
|
|
|
|
|
|
|
|
chartBuilder.addBarEntry( "T2", "W1", "", std::numeric_limits<double>::infinity(), "R1", "", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "T2", "W1", "", std::numeric_limits<double>::infinity(), "R2", "", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "T2", "W2", "", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
|
|
|
|
chartBuilder.addBarEntry( "T2", "W2", "", std::numeric_limits<double>::infinity(), "R2", "", 2.0 );
|
|
|
|
|
|
|
|
chartBuilder.addBarEntry( "T3", "W1", "1", std::numeric_limits<double>::infinity(), "R1", "", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "T3", "W1", "2", std::numeric_limits<double>::infinity(), "R2", "", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "T3", "W2", "3", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
|
|
|
|
chartBuilder.addBarEntry( "T3", "W2", "4", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
|
|
|
|
chartBuilder.addBarEntry( "T3", "W2", "5", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
|
|
|
|
|
|
|
|
chartBuilder.addBarEntry( "T4", "W1", "1", std::numeric_limits<double>::infinity(), "R1", "", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "T4", "W1", "2", std::numeric_limits<double>::infinity(), "R2", "", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "T4", "W2", "3", std::numeric_limits<double>::infinity(), "R1", "", 2.0 );
|
|
|
|
chartBuilder.addBarEntry( "T4", "W2", "4", std::numeric_limits<double>::infinity(), "R2", "", 2.0 );
|
|
|
|
chartBuilder.addBarEntry( "T4", "W1", "1", std::numeric_limits<double>::infinity(), "R1", "", 1.6 );
|
|
|
|
chartBuilder.addBarEntry( "T4", "W1", "2", std::numeric_limits<double>::infinity(), "R2", "", 1.6 );
|
|
|
|
chartBuilder.addBarEntry( "T4", "W2", "3", std::numeric_limits<double>::infinity(), "R1", "", 2.6 );
|
|
|
|
chartBuilder.addBarEntry( "T4", "W2", "4", std::numeric_limits<double>::infinity(), "R2", "", -0.3 );
|
|
|
|
|
|
|
|
chartBuilder.addBarEntry( "T5", "", "", 1.5, "R3", "G1", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "T5", "", "", 1.5, "R3", "G2", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "T5", "", "", 2.0, "R3", "G3", 2.0 );
|
|
|
|
chartBuilder.addBarEntry( "T5", "", "", 2.0, "R3", "G4", 2.0 );
|
|
|
|
chartBuilder.addBarEntry( "T5", "", "", 1.6, "R3", "G5", 1.6 );
|
|
|
|
chartBuilder.addBarEntry( "T5", "", "", 1.6, "R3", "G6", 1.6 );
|
|
|
|
chartBuilder.addBarEntry( "T5", "", "", 2.6, "R3", "G7", 2.6 );
|
|
|
|
chartBuilder.addBarEntry( "T5", "", "", -0.1, "R3", "G8", -0.1 );
|
|
|
|
|
|
|
|
chartBuilder.addBarEntry( "", "", "", 1.2, "", "A", 1.2 );
|
|
|
|
chartBuilder.addBarEntry( "", "", "", 1.5, "", "B", 1.5 );
|
|
|
|
chartBuilder.addBarEntry( "", "", "", 2.3, "", "C", 2.3 );
|
|
|
|
chartBuilder.addBarEntry( "", "", "", 2.0, "", "D", 2.0 );
|
|
|
|
chartBuilder.addBarEntry( "", "", "", 1.6, "", "E", 1.6 );
|
|
|
|
chartBuilder.addBarEntry( "", "", "", 2.4, "", "F", -2.4 );
|
2020-02-26 04:21:44 -06:00
|
|
|
}
|
2020-07-30 06:20:00 -05:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
int RimAnalysisPlot::barTextFontSize() const
|
|
|
|
{
|
|
|
|
return caf::FontTools::absolutePointSize( RiaPreferences::current()->defaultPlotFontSize(), m_barTextFontSize() );
|
|
|
|
}
|