#6243 Support filtering of time steps for Correlation plots

This commit is contained in:
Gaute Lindkvist 2020-07-29 12:19:16 +02:00
parent fde92ad931
commit 4f36332e52
8 changed files with 152 additions and 88 deletions

View File

@ -45,6 +45,8 @@ RimAbstractCorrelationPlot::RimAbstractCorrelationPlot()
m_pushButtonSelectSummaryAddress.uiCapability()->setUiLabelPosition( caf::PdmUiItemInfo::HIDDEN );
m_pushButtonSelectSummaryAddress = false;
CAF_PDM_InitFieldNoDefault( &m_timeStepFilter, "TimeStepFilter", "Time Step Filter", "", "", "" );
CAF_PDM_InitFieldNoDefault( &m_timeStep, "TimeStep", "Time Step", "", "", "" );
m_timeStep.uiCapability()->setUiEditorTypeName( caf::PdmUiComboBoxEditor::uiEditorTypeName() );
@ -150,6 +152,32 @@ void RimAbstractCorrelationPlot::fieldChangedByUi( const caf::PdmFieldHandle* ch
{
this->loadDataAndUpdate();
}
else if ( changedField == &m_timeStepFilter )
{
std::vector<QDateTime> allDateTimes;
for ( time_t timeStep : allAvailableTimeSteps() )
{
QDateTime dateTime = RiaQDateTimeTools::fromTime_t( timeStep );
allDateTimes.push_back( dateTime );
}
std::vector<int> filteredTimeStepIndices =
RimTimeStepFilter::filteredTimeStepIndices( allDateTimes, 0, (int)allDateTimes.size() - 1, m_timeStepFilter(), 1 );
QDateTime closestTimeStep;
for ( int timeStepIndex : filteredTimeStepIndices )
{
qint64 currentDiff = std::abs( allDateTimes[timeStepIndex].secsTo( m_timeStep() ) );
qint64 closestDiff = std::abs( closestTimeStep.secsTo( m_timeStep() ) );
if ( closestTimeStep.isNull() || currentDiff < closestDiff )
{
closestTimeStep = allDateTimes[timeStepIndex];
if ( currentDiff == 0 ) break;
}
}
m_timeStep = closestTimeStep;
this->updateConnectedEditors();
}
}
//--------------------------------------------------------------------------------------------------
@ -185,33 +213,36 @@ QList<caf::PdmOptionItemInfo>
if ( fieldNeedingOptions == &m_timeStep )
{
std::set<time_t> allTimeSteps = allAvailableTimeSteps();
if ( allTimeSteps.empty() )
{
CAF_ASSERT( false && "No time steps found" );
return options;
}
std::map<QDate, std::vector<QTime>> timeStepsDateMap;
std::vector<QDateTime> allDateTimes;
for ( time_t timeStep : allTimeSteps )
{
QDateTime dateTime = QDateTime::fromTime_t( timeStep );
timeStepsDateMap[dateTime.date()].push_back( dateTime.time() );
QDateTime dateTime = RiaQDateTimeTools::fromTime_t( timeStep );
allDateTimes.push_back( dateTime );
}
std::vector<int> filteredTimeStepIndices =
RimTimeStepFilter::filteredTimeStepIndices( allDateTimes, 0, (int)allDateTimes.size() - 1, m_timeStepFilter(), 1 );
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 );
for ( auto dateTimePair : timeStepsDateMap )
for ( auto timeStepIndex : filteredTimeStepIndices )
{
QDate date = dateTimePair.first;
bool multipleTimes = dateTimePair.second.size() > 1u;
for ( auto time : dateTimePair.second )
{
QString timestepString = date.toString( dateFormatString );
if ( multipleTimes )
{
timestepString += QString( " %1" ).arg( time.toString( timeFormatString ) );
}
options.push_back( caf::PdmOptionItemInfo( timestepString, QDateTime( date, time ) ) );
}
QDateTime dateTime = allDateTimes[timeStepIndex];
QString dateTimeFormat = QString( "%1 %2" ).arg( dateFormatString ).arg( timeFormatString );
options.push_back(
caf::PdmOptionItemInfo( RiaQDateTimeTools::toStringUsingApplicationLocale( dateTime, dateTimeFormat ),
dateTime ) );
}
}
else if ( fieldNeedingOptions == &m_labelFontSize || fieldNeedingOptions == &m_axisTitleFontSize ||

View File

@ -22,6 +22,7 @@
#include "RimPlot.h"
#include "RimSummaryCaseCollection.h"
#include "RimTimeStepFilter.h"
#include "cafPdmPtrField.h"
@ -38,6 +39,9 @@ class RimAbstractCorrelationPlot : public RimPlot
{
CAF_PDM_HEADER_INIT;
public:
using TimeStepFilterEnum = caf::AppEnum<RimTimeStepFilter::TimeStepFilterTypeEnum>;
public:
RimAbstractCorrelationPlot();
~RimAbstractCorrelationPlot() override;
@ -120,9 +124,10 @@ protected:
// Fields
caf::PdmChildArrayField<RimAnalysisPlotDataEntry*> m_analysisPlotDataSelection;
caf::PdmField<QString> m_selectedVarsUiField;
caf::PdmField<bool> m_pushButtonSelectSummaryAddress;
caf::PdmField<QDateTime> m_timeStep;
caf::PdmField<QString> m_selectedVarsUiField;
caf::PdmField<bool> m_pushButtonSelectSummaryAddress;
caf::PdmField<TimeStepFilterEnum> m_timeStepFilter;
caf::PdmField<QDateTime> m_timeStep;
caf::PdmField<bool> m_showPlotTitle;
caf::PdmField<bool> m_useAutoPlotTitle;

View File

@ -288,6 +288,7 @@ void RimCorrelationMatrixPlot::defineUiOrdering( QString uiConfigName, caf::PdmU
curveDataGroup->add( &m_selectedVarsUiField );
curveDataGroup->add( &m_pushButtonSelectSummaryAddress, {false, 1, 0} );
curveDataGroup->add( &m_timeStepFilter );
curveDataGroup->add( &m_timeStep );
if ( uiConfigName != "report" )

View File

@ -140,6 +140,7 @@ void RimCorrelationPlot::defineUiOrdering( QString uiConfigName, caf::PdmUiOrder
curveDataGroup->add( &m_selectedVarsUiField );
curveDataGroup->add( &m_pushButtonSelectSummaryAddress, {false, 1, 0} );
curveDataGroup->add( &m_timeStepFilter );
curveDataGroup->add( &m_timeStep );
caf::PdmUiGroup* plotGroup = uiOrdering.addNewGroup( "Plot Settings" );

View File

@ -303,9 +303,9 @@ void RimCorrelationReportPlot::onLoadDataAndUpdate()
updateMdiWindowVisibility();
if ( m_showWindow )
{
// auto curveDefs = m_correlationMatrixPlot->curveDefinitions();
// m_correlationPlot->setCurveDefinitions( curveDefs );
// m_parameterResultCrossPlot->setCurveDefinitions( curveDefs );
auto timeStep = m_correlationMatrixPlot->timeStep().toTime_t();
m_correlationPlot->setTimeStep( timeStep );
m_parameterResultCrossPlot->setTimeStep( timeStep );
m_correlationMatrixPlot->setLabelFontSize( m_labelFontSize() );
m_correlationMatrixPlot->setAxisTitleFontSize( m_axisTitleFontSize() );
@ -327,6 +327,7 @@ void RimCorrelationReportPlot::onLoadDataAndUpdate()
m_correlationMatrixPlot->loadDataAndUpdate();
m_correlationPlot->loadDataAndUpdate();
m_parameterResultCrossPlot->loadDataAndUpdate();
m_viewer->setPlotTitle( m_plotWindowTitle() );
}
updateLayout();
}

View File

@ -116,6 +116,7 @@ void RimParameterResultCrossPlot::defineUiOrdering( QString uiConfigName, caf::P
caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup( "Summary Vector" );
curveDataGroup->add( &m_selectedVarsUiField );
curveDataGroup->add( &m_pushButtonSelectSummaryAddress, {false, 1, 0} );
curveDataGroup->add( &m_timeStepFilter );
curveDataGroup->add( &m_timeStep );
caf::PdmUiGroup* crossPlotGroup = uiOrdering.addNewGroup( "Cross Plot Parameters" );
@ -301,10 +302,8 @@ void RimParameterResultCrossPlot::updatePlotTitle()
{
if ( m_useAutoPlotTitle )
{
m_description = QString( "Cross Plot %1 x %2 at %3" )
.arg( m_ensembleParameter )
.arg( m_selectedVarsUiField )
.arg( timeStepString() );
m_description =
QString( "Cross Plot %1 x %2 at %3" ).arg( m_ensembleParameter ).arg( m_selectedVarsUiField ).arg( timeStepString() );
}
m_plotWidget->setPlotTitle( m_description );
m_plotWidget->setPlotTitleEnabled( m_showPlotTitle && isMdiWindow() );

View File

@ -188,6 +188,79 @@ bool RimTimeStepFilter::updateFilteredTimeStepsFromUi()
return true;
}
QDateTime RimTimeStepFilter::incrementDateTime( const QDateTime& dateTime, TimeStepFilterTypeEnum filterType, int interval )
{
switch ( filterType )
{
case TS_INTERVAL_DAYS:
return dateTime.addDays( interval );
case TS_INTERVAL_WEEKS:
return dateTime.addDays( 7 * interval );
case TS_INTERVAL_MONTHS:
return dateTime.addMonths( interval );
case TS_INTERVAL_QUARTERS:
return dateTime.addMonths( interval * 3 );
case TS_INTERVAL_YEARS:
return dateTime.addYears( interval );
default:
break;
}
return dateTime;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<int> RimTimeStepFilter::filteredTimeStepIndices( const std::vector<QDateTime>& timeSteps,
int firstTimeStep,
int lastTimeStep,
TimeStepFilterTypeEnum filterType,
int interval )
{
std::vector<int> indices;
if ( filterType == TS_ALL )
{
for ( int i = firstTimeStep; i <= lastTimeStep; i++ )
{
indices.push_back( i );
}
}
else
{
QDateTime nextDateTime;
for ( int i = firstTimeStep; i <= lastTimeStep; i++ )
{
if ( !timeSteps[i].isValid() )
{
indices.push_back( i );
}
else
{
if ( nextDateTime.isValid() )
{
if ( timeSteps[i] >= nextDateTime )
{
do
{
nextDateTime = incrementDateTime( nextDateTime, filterType, interval );
} while ( nextDateTime <= timeSteps[i] );
indices.push_back( i );
}
}
else
{
nextDateTime = incrementDateTime( timeSteps[i], filterType, interval );
indices.push_back( i );
}
}
}
}
return indices;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -305,67 +378,13 @@ std::vector<std::pair<QString, QDateTime>> RimTimeStepFilter::allTimeSteps() con
//--------------------------------------------------------------------------------------------------
std::vector<int> RimTimeStepFilter::filteredTimeStepIndicesFromUi() const
{
std::vector<int> indices;
if ( m_filterType == TS_ALL )
std::vector<std::pair<QString, QDateTime>> timeStepStringsAndDate = allTimeSteps();
std::vector<QDateTime> timeSteps;
for ( auto stringDatePair : timeStepStringsAndDate )
{
for ( int i = m_firstTimeStep; i <= m_lastTimeStep; i++ )
{
indices.push_back( i );
}
timeSteps.push_back( stringDatePair.second );
}
else
{
int intervalFactor = 1;
if ( m_filterType == TS_INTERVAL_WEEKS )
{
intervalFactor = 7;
}
else if ( m_filterType == TS_INTERVAL_MONTHS )
{
intervalFactor = 30;
}
else if ( m_filterType == TS_INTERVAL_QUARTERS )
{
intervalFactor = 90;
}
else if ( m_filterType == TS_INTERVAL_YEARS )
{
intervalFactor = 365;
}
int daysToSkip = m_interval * intervalFactor;
std::vector<std::pair<QString, QDateTime>> timeSteps = allTimeSteps();
QDateTime d;
for ( int i = m_firstTimeStep; i <= m_lastTimeStep; i++ )
{
if ( !timeSteps[i].second.isValid() )
{
indices.push_back( i );
}
else
{
if ( d.isValid() )
{
if ( timeSteps[i].second > d )
{
d = d.addDays( daysToSkip );
indices.push_back( i );
}
}
else
{
d = timeSteps[i].second.addDays( daysToSkip );
indices.push_back( i );
}
}
}
}
return indices;
return filteredTimeStepIndices( timeSteps, m_firstTimeStep(), m_lastTimeStep(), m_filterType(), m_interval );
}
//--------------------------------------------------------------------------------------------------

View File

@ -50,12 +50,19 @@ public:
void clearFilteredTimeSteps();
void setTimeStepsFromFile( const std::vector<QDateTime>& timeSteps );
void setTimeStepsFromFile( const std::vector<std::pair<QString, QDateTime>>& timeSteps );
std::vector<size_t> filteredTimeSteps() const;
bool updateFilteredTimeStepsFromUi();
void setTimeStepsFromFile( const std::vector<QDateTime>& timeSteps );
void setTimeStepsFromFile( const std::vector<std::pair<QString, QDateTime>>& timeSteps );
std::vector<size_t> filteredTimeSteps() const;
bool updateFilteredTimeStepsFromUi();
static std::vector<int> filteredTimeStepIndices( const std::vector<QDateTime>& timeSteps,
int firstTimeStep,
int lastTimeStep,
TimeStepFilterTypeEnum filterType,
int interval );
private:
static QDateTime incrementDateTime( const QDateTime& dateTime, TimeStepFilterTypeEnum filterType, int interval );
std::vector<std::pair<QString, QDateTime>> allTimeSteps() const;
std::vector<int> filteredTimeStepIndicesFromUi() const;