diff --git a/ApplicationLibCode/Commands/CMakeLists_files.cmake b/ApplicationLibCode/Commands/CMakeLists_files.cmake index 5efb8ec603a..88aa11abf2f 100644 --- a/ApplicationLibCode/Commands/CMakeLists_files.cmake +++ b/ApplicationLibCode/Commands/CMakeLists_files.cmake @@ -41,8 +41,6 @@ set(SOURCE_GROUP_SOURCE_FILES ${CMAKE_CURRENT_LIST_DIR}/RicReplaceCaseFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicReloadSummaryCaseFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicFlyToObjectFeature.cpp - ${CMAKE_CURRENT_LIST_DIR}/RicGridStatisticsDialog.cpp - ${CMAKE_CURRENT_LIST_DIR}/RicShowGridStatisticsFeature.cpp ${CMAKE_CURRENT_LIST_DIR}/RicRecursiveFileSearchDialog.cpp ${CMAKE_CURRENT_LIST_DIR}/RicSummaryCaseRestartDialog.cpp ${CMAKE_CURRENT_LIST_DIR}/RicImportEnsembleFeature.cpp diff --git a/ApplicationLibCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp b/ApplicationLibCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp index c7f0d28ab40..ee22d4b2d4d 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicSnapshotAllViewsToFileFeature.cpp @@ -24,9 +24,8 @@ #include "RiaQStringFormatter.h" #include "RiaViewRedrawScheduler.h" -#include "Rim3dOverlayInfoConfig.h" +#include "Rim3dView.h" #include "RimCase.h" -#include "RimGridView.h" #include "RimMainPlotCollection.h" #include "RimProject.h" #include "RimViewWindow.h" @@ -140,13 +139,6 @@ void RicSnapshotAllViewsToFileFeature::exportSnapshotOfViewsIntoFolder( const QS QString absoluteFileName = caf::Utils::constructFullFileName( absSnapshotPath, fileName, ".png" ); RicSnapshotViewToFileFeature::saveSnapshotAs( absoluteFileName, riv, width, height ); - - if ( RimGridView* rigv = dynamic_cast( riv ) ) - { - QImage img = rigv->overlayInfoConfig()->statisticsDialogScreenShotImage(); - absoluteFileName = caf::Utils::constructFullFileName( absSnapshotPath, fileName + "_Statistics", ".png" ); - RicSnapshotViewToFileFeature::saveSnapshotAs( absoluteFileName, img ); - } } } diff --git a/ApplicationLibCode/Commands/ExportCommands/RicSnapshotViewToClipboardFeature.cpp b/ApplicationLibCode/Commands/ExportCommands/RicSnapshotViewToClipboardFeature.cpp index 9b72baefc55..c527068df74 100644 --- a/ApplicationLibCode/Commands/ExportCommands/RicSnapshotViewToClipboardFeature.cpp +++ b/ApplicationLibCode/Commands/ExportCommands/RicSnapshotViewToClipboardFeature.cpp @@ -17,7 +17,6 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RicSnapshotViewToClipboardFeature.h" -#include "RicGridStatisticsDialog.h" #include "RiaGuiApplication.h" #include "RiaLogging.h" diff --git a/ApplicationLibCode/Commands/RicGridStatisticsDialog.cpp b/ApplicationLibCode/Commands/RicGridStatisticsDialog.cpp deleted file mode 100644 index 3c29d6ae0ed..00000000000 --- a/ApplicationLibCode/Commands/RicGridStatisticsDialog.cpp +++ /dev/null @@ -1,332 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2017- Statoil ASA -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RicGridStatisticsDialog.h" -#include "ExportCommands/RicSnapshotFilenameGenerator.h" -#include "ExportCommands/RicSnapshotViewToClipboardFeature.h" -#include "ExportCommands/RicSnapshotViewToFileFeature.h" - -#include "RiaPreferences.h" - -#include "Rim3dOverlayInfoConfig.h" -#include "RimEclipseView.h" - -#include "RiuPlotMainWindow.h" -#include "RiuQwtPlotTools.h" -#include "RiuSummaryQwtPlot.h" -#include "RiuTools.h" - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RicGridStatisticsDialog::RicGridStatisticsDialog( QWidget* parent ) - : QDialog( parent, RiuTools::defaultDialogFlags() ) -{ - m_currentRimView = nullptr; - - // Create widgets - m_toolBar = new QToolBar(); - m_mainViewWidget = new QFrame(); - m_label = new QLabel(); - m_textEdit = new QTextEdit(); - m_historgramPlot = new QwtPlot(); - m_aggregatedPlot = new QwtPlot(); - m_buttons = new QDialogButtonBox( QDialogButtonBox::Close ); - - // Connect to close button signal - connect( m_buttons, SIGNAL( rejected() ), this, SLOT( slotDialogFinished() ) ); - - // Set widget properties - m_textEdit->setReadOnly( true ); - - RiuQwtPlotTools::setCommonPlotBehaviour( m_historgramPlot ); - RiuQwtPlotTools::setCommonPlotBehaviour( m_aggregatedPlot ); - - // Define layout - QVBoxLayout* dialogLayout = new QVBoxLayout(); - dialogLayout->addWidget( m_mainViewWidget ); - - QVBoxLayout* mainViewLayout = new QVBoxLayout(); - mainViewLayout->setContentsMargins( 0, 0, 0, 0 ); - m_mainViewWidget->setLayout( mainViewLayout ); - mainViewLayout->addWidget( m_label ); - mainViewLayout->addWidget( m_textEdit ); - - QVBoxLayout* plotLayout = new QVBoxLayout(); - plotLayout->setSpacing( 0 ); - plotLayout->addWidget( m_historgramPlot ); - plotLayout->addWidget( m_aggregatedPlot ); - mainViewLayout->addLayout( plotLayout ); - - dialogLayout->addWidget( m_buttons ); - - setLayout( dialogLayout ); - - // Toolbar - dialogLayout->setMenuBar( m_toolBar ); - createAndConnectToolbarActions(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RicGridStatisticsDialog::~RicGridStatisticsDialog() -{ -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::setLabel( const QString& labelText ) -{ - m_label->setText( labelText ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::updateFromRimView( RimGridView* rimView ) -{ - m_currentRimView = rimView; - setInfoText( m_currentRimView ); - setHistogramData( m_currentRimView ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QImage RicGridStatisticsDialog::screenShotImage() -{ - QPixmap shot = m_mainViewWidget->grab(); - - return shot.toImage(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::setInfoText( RimGridView* view ) -{ - if ( view && view->overlayInfoConfig() ) - { - Rim3dOverlayInfoConfig* overlayInfo = view->overlayInfoConfig(); - - QString text; - text = overlayInfo->timeStepText(); - text += overlayInfo->caseInfoText(); - text += overlayInfo->resultInfoText( overlayInfo->histogramData() ); - m_textEdit->setText( text ); - adjustTextEditHeightToContent(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::setHistogramData( RimGridView* view ) -{ - deletePlotItems( m_historgramPlot ); - deletePlotItems( m_aggregatedPlot ); - - if ( view && view->overlayInfoConfig() ) - { - Rim3dOverlayInfoConfig* overlayInfo = view->overlayInfoConfig(); - - RigHistogramData histogramData = overlayInfo->histogramData(); - - if ( histogramData.isHistogramVectorValid() ) - { - auto hist = new QwtPlotHistogram( "Histogram" ); - auto aggr = new QwtPlotCurve( "Aggregated" ); - - hist->setBrush( QBrush( QColor( Qt::darkCyan ) ) ); - hist->setZ( -1 ); - aggr->setStyle( QwtPlotCurve::Steps ); - aggr->setCurveAttribute( QwtPlotCurve::Inverted ); - - QVector histSamples; - QVector aggrSamples; - double xStep = ( histogramData.max - histogramData.min ) / histogramData.histogram.size(); - double xCurr = histogramData.min; - double aggrValue = 0.0; - for ( size_t value : histogramData.histogram ) - { - double xNext = xCurr + xStep; - histSamples.push_back( QwtIntervalSample( value, xCurr, xNext ) ); - - aggrValue += value; - aggrSamples.push_back( QPointF( xCurr, aggrValue ) ); - - xCurr = xNext; - } - - // Axis - double xAxisSize = histogramData.max - histogramData.min; - double xAxisExtension = xAxisSize * 0.02; - m_historgramPlot->setAxisScale( QwtAxis::XBottom, histogramData.min - xAxisExtension, histogramData.max + xAxisExtension ); - m_aggregatedPlot->setAxisScale( QwtAxis::XBottom, histogramData.min - xAxisExtension, histogramData.max + xAxisExtension ); - - // Set y axis label area width - m_historgramPlot->axisScaleDraw( QwtAxis::YLeft )->setMinimumExtent( 60 ); - m_aggregatedPlot->axisScaleDraw( QwtAxis::YLeft )->setMinimumExtent( 60 ); - - // Samples - hist->setSamples( histSamples ); - aggr->setSamples( aggrSamples ); - hist->attach( m_historgramPlot ); - aggr->attach( m_aggregatedPlot ); - - // Markers - setMarkers( histogramData, m_historgramPlot ); - setMarkers( histogramData, m_aggregatedPlot ); - } - } - - // Refresh plot - m_historgramPlot->replot(); - m_aggregatedPlot->replot(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::createAndConnectToolbarActions() -{ - QAction* scrShotToClipboardAction = - m_toolBar->addAction( RicSnapshotViewToClipboardFeature::icon(), RicSnapshotViewToClipboardFeature::text() ); - connect( scrShotToClipboardAction, SIGNAL( triggered() ), this, SLOT( slotScreenShotToClipboard() ) ); - - QAction* scrShotToFileAction = m_toolBar->addAction( RicSnapshotViewToFileFeature::icon(), RicSnapshotViewToFileFeature::text() ); - connect( scrShotToFileAction, SIGNAL( triggered() ), this, SLOT( slotScreenShotToFile() ) ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::deletePlotItems( QwtPlot* plot ) -{ - QwtPlotItemList itemList = plot->itemList(); - for ( auto item : itemList ) - { - if ( dynamic_cast( item ) || dynamic_cast( item ) || dynamic_cast( item ) ) - { - item->detach(); - delete item; - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::setMarkers( const RigHistogramData& histData, QwtPlot* plot ) -{ - QwtPlotMarker* marker; - - if ( histData.p10 != HUGE_VAL ) - { - marker = createVerticalPlotMarker( Qt::red, histData.p10 ); - marker->attach( plot ); - } - - if ( histData.p90 != HUGE_VAL ) - { - marker = createVerticalPlotMarker( Qt::red, histData.p90 ); - marker->attach( plot ); - } - - if ( histData.mean != HUGE_VAL ) - { - marker = createVerticalPlotMarker( Qt::blue, histData.mean ); - marker->attach( plot ); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QwtPlotMarker* RicGridStatisticsDialog::createVerticalPlotMarker( const QColor& color, double xValue ) -{ - QwtPlotMarker* marker = new QwtPlotMarker(); - marker->setXValue( xValue ); - marker->setLineStyle( QwtPlotMarker::VLine ); - marker->setLinePen( color, 2, Qt::SolidLine ); - return marker; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::adjustTextEditHeightToContent() -{ - int docHeight = m_textEdit->document()->size().height(); - m_textEdit->setFixedHeight( docHeight + 10 ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::slotDialogFinished() -{ - close(); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::slotScreenShotToClipboard() -{ - QImage snapshotImage = screenShotImage(); - RicSnapshotViewToClipboardFeature::copyToClipboard( snapshotImage ); -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicGridStatisticsDialog::slotScreenShotToFile() -{ - QImage snapshotImage = screenShotImage(); - QString defaultFileBaseName; - if ( m_currentRimView ) - { - defaultFileBaseName = RicSnapshotFilenameGenerator::generateSnapshotFileName( m_currentRimView ); - defaultFileBaseName += "_Statistics"; - } - else - { - defaultFileBaseName = "Snapshot_Statistics"; - } - RicSnapshotViewToFileFeature::saveImageToFile( snapshotImage, defaultFileBaseName ); -} diff --git a/ApplicationLibCode/Commands/RicGridStatisticsDialog.h b/ApplicationLibCode/Commands/RicGridStatisticsDialog.h deleted file mode 100644 index 60e560c1064..00000000000 --- a/ApplicationLibCode/Commands/RicGridStatisticsDialog.h +++ /dev/null @@ -1,78 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2017- Statoil ASA -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "cafPdmPointer.h" - -#include - -class QLabel; -class QTextEdit; -class QDialogButtonBox; -class QwtPlot; -class QwtPlotMarker; -class QMainWindow; -class QToolBar; -class RimEclipseView; -class RimGridView; -class RigHistogramData; - -//================================================================================================== -/// -/// -//================================================================================================== -class RicGridStatisticsDialog : public QDialog -{ - Q_OBJECT - -public: - explicit RicGridStatisticsDialog( QWidget* parent ); - ~RicGridStatisticsDialog() override; - - void setLabel( const QString& labelText ); - void updateFromRimView( RimGridView* rimView ); - QImage screenShotImage(); - -private: - void setInfoText( RimGridView* eclipseView ); - void setHistogramData( RimGridView* eclipseView ); - -private: - void createAndConnectToolbarActions(); - void deletePlotItems( QwtPlot* plot ); - static void setMarkers( const RigHistogramData& histData, QwtPlot* plot ); - static QwtPlotMarker* createVerticalPlotMarker( const QColor& color, double xValue ); - void adjustTextEditHeightToContent(); - -private slots: - void slotDialogFinished(); - void slotScreenShotToClipboard(); - void slotScreenShotToFile(); - -private: - QToolBar* m_toolBar; - QWidget* m_mainViewWidget; - QLabel* m_label; - QTextEdit* m_textEdit; - QwtPlot* m_historgramPlot; - QwtPlot* m_aggregatedPlot; - QDialogButtonBox* m_buttons; - - caf::PdmPointer m_currentRimView; -}; diff --git a/ApplicationLibCode/Commands/RicShowGridStatisticsFeature.cpp b/ApplicationLibCode/Commands/RicShowGridStatisticsFeature.cpp deleted file mode 100644 index b188b1e2512..00000000000 --- a/ApplicationLibCode/Commands/RicShowGridStatisticsFeature.cpp +++ /dev/null @@ -1,66 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2017 Statoil ASA -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#include "RicShowGridStatisticsFeature.h" - -#include "RiaApplication.h" -#include "RicGridStatisticsDialog.h" -#include "RicWellLogTools.h" - -#include "Rim3dOverlayInfoConfig.h" -#include "RimEclipseView.h" -#include "RimGeoMechView.h" -#include "RimProject.h" - -#include "cafSelectionManagerTools.h" - -#include - -CAF_CMD_SOURCE_INIT( RicShowGridStatisticsFeature, "RicShowGridStatisticsFeature" ); - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -bool RicShowGridStatisticsFeature::isCommandEnabled() const -{ - if ( RicWellLogTools::isWellPathOrSimWellSelectedInView() ) return false; - - return RiaApplication::instance()->activeGridView() != nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicShowGridStatisticsFeature::onActionTriggered( bool isChecked ) -{ - RimGridView* activeView = RiaApplication::instance()->activeMainOrComparisonGridView(); - - if ( activeView ) - { - activeView->overlayInfoConfig()->showStatisticsInfoDialog(); - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RicShowGridStatisticsFeature::setupActionLook( QAction* actionToSetup ) -{ - actionToSetup->setText( "Grid Statistics (legacy)" ); - actionToSetup->setIcon( QIcon( ":/statistics.png" ) ); // Todo: Change icon -} diff --git a/ApplicationLibCode/Commands/RicShowGridStatisticsFeature.h b/ApplicationLibCode/Commands/RicShowGridStatisticsFeature.h deleted file mode 100644 index c52bb5b0c24..00000000000 --- a/ApplicationLibCode/Commands/RicShowGridStatisticsFeature.h +++ /dev/null @@ -1,36 +0,0 @@ -///////////////////////////////////////////////////////////////////////////////// -// -// Copyright (C) 2017 Statoil ASA -// -// ResInsight is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY -// WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. -// -// See the GNU General Public License at -// for more details. -// -///////////////////////////////////////////////////////////////////////////////// - -#pragma once - -#include "cafCmdFeature.h" - -class RicGridStatisticsDialog; - -//================================================================================================== -/// -//================================================================================================== -class RicShowGridStatisticsFeature : public caf::CmdFeature -{ - CAF_CMD_HEADER_INIT; - -protected: - bool isCommandEnabled() const override; - void onActionTriggered( bool isChecked ) override; - void setupActionLook( QAction* actionToSetup ) override; -}; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleFractureHistogramDataSource.cpp b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleFractureHistogramDataSource.cpp index aff494a5c3c..76f00fdc3a4 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleFractureHistogramDataSource.cpp +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleFractureHistogramDataSource.cpp @@ -111,8 +111,9 @@ std::string RimEnsembleFractureHistogramDataSource::unitNameX() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimHistogramDataSource::HistogramResult RimEnsembleFractureHistogramDataSource::compute( RimHistogramPlot::GraphType graphType, - RimHistogramPlot::FrequencyType frequencyType ) const +RimHistogramDataSource::HistogramResult RimEnsembleFractureHistogramDataSource::compute( RimHistogramPlot::GraphType graphType, + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative ) const { RimHistogramDataSource::HistogramResult result; @@ -126,8 +127,8 @@ RimHistogramDataSource::HistogramResult RimEnsembleFractureHistogramDataSource:: double min = histogramData.min; double max = histogramData.max; - result.valuesX = computeHistogramBins( min, max, m_numBins, graphType ); - result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType ); + result.valuesX = computeHistogramBins( min, max, m_numBins, graphType, cumulative ); + result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType, cumulative ); result.p10 = histogramData.p10; result.mean = histogramData.mean; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleFractureHistogramDataSource.h b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleFractureHistogramDataSource.h index a1a5e52afc5..d0d3e5141a7 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleFractureHistogramDataSource.h +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleFractureHistogramDataSource.h @@ -45,7 +45,9 @@ class RimEnsembleFractureHistogramDataSource : public RimHistogramDataSource std::string unitNameX() const override; std::string unitNameY() const override; - HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override; + HistogramResult compute( RimHistogramPlot::GraphType graphType, + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative = false ) const override; void setDefaults() override; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleParameterHistogramDataSource.cpp b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleParameterHistogramDataSource.cpp index 66cc0726ceb..cd1c7279555 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleParameterHistogramDataSource.cpp +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleParameterHistogramDataSource.cpp @@ -147,8 +147,9 @@ std::string RimEnsembleParameterHistogramDataSource::unitNameX() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource::compute( RimHistogramPlot::GraphType graphType, - RimHistogramPlot::FrequencyType frequencyType ) const +RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource::compute( RimHistogramPlot::GraphType graphType, + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative ) const { RimHistogramDataSource::HistogramResult result; @@ -159,7 +160,7 @@ RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource: double min = parameter.minValue; double max = parameter.maxValue; - result.valuesX = computeHistogramBins( min, max, m_numBins, graphType ); + result.valuesX = computeHistogramBins( min, max, m_numBins, graphType, cumulative ); std::vector values; for ( const QVariant& v : parameter.values ) @@ -171,7 +172,7 @@ RimHistogramDataSource::HistogramResult RimEnsembleParameterHistogramDataSource: RigHistogramCalculator histCalc( min, max, m_numBins, &histogram ); histCalc.addData( values ); - result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType ); + result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType, cumulative ); double p10, p50, p90, mean; RigStatisticsMath::calculateStatisticsCurves( values, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED ); diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleParameterHistogramDataSource.h b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleParameterHistogramDataSource.h index 44807cb83da..464e33af447 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleParameterHistogramDataSource.h +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleParameterHistogramDataSource.h @@ -46,7 +46,9 @@ class RimEnsembleParameterHistogramDataSource : public RimHistogramDataSource std::string unitNameX() const override; std::string unitNameY() const override; - HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override; + HistogramResult compute( RimHistogramPlot::GraphType graphType, + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative = false ) const override; void setDefaults() override; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleSummaryVectorHistogramDataSource.cpp b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleSummaryVectorHistogramDataSource.cpp index 265176d0611..4aeea610779 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleSummaryVectorHistogramDataSource.cpp +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleSummaryVectorHistogramDataSource.cpp @@ -229,8 +229,9 @@ std::vector RimEnsembleSummaryVectorHistogramDataSource::extractValuesFr //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimHistogramDataSource::HistogramResult RimEnsembleSummaryVectorHistogramDataSource::compute( RimHistogramPlot::GraphType graphType, - RimHistogramPlot::FrequencyType frequencyType ) const +RimHistogramDataSource::HistogramResult RimEnsembleSummaryVectorHistogramDataSource::compute( RimHistogramPlot::GraphType graphType, + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative ) const { RimHistogramDataSource::HistogramResult result; @@ -241,13 +242,13 @@ RimHistogramDataSource::HistogramResult RimEnsembleSummaryVectorHistogramDataSou double min = *min_it; double max = *max_it; - result.valuesX = computeHistogramBins( min, max, m_numBins, graphType ); + result.valuesX = computeHistogramBins( min, max, m_numBins, graphType, cumulative ); std::vector histogram; RigHistogramCalculator histCalc( min, max, m_numBins, &histogram ); histCalc.addData( values ); - result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType ); + result.valuesY = computeHistogramFrequencies( histogram, graphType, frequencyType, cumulative ); double p10, p50, p90, mean; RigStatisticsMath::calculateStatisticsCurves( values, &p10, &p50, &p90, &mean, RigStatisticsMath::PercentileStyle::SWITCHED ); diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleSummaryVectorHistogramDataSource.h b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleSummaryVectorHistogramDataSource.h index 27c9cfef178..5e49c406a1a 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleSummaryVectorHistogramDataSource.h +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimEnsembleSummaryVectorHistogramDataSource.h @@ -48,7 +48,9 @@ class RimEnsembleSummaryVectorHistogramDataSource : public RimHistogramDataSourc std::string unitNameX() const override; std::string unitNameY() const override; - HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override; + HistogramResult compute( RimHistogramPlot::GraphType graphType, + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative = false ) const override; void setDefaults() override; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimGridStatisticsHistogramDataSource.cpp b/ApplicationLibCode/ProjectDataModel/Histogram/RimGridStatisticsHistogramDataSource.cpp index e8b7f885a7e..d4487de66c8 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimGridStatisticsHistogramDataSource.cpp +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimGridStatisticsHistogramDataSource.cpp @@ -51,6 +51,15 @@ RimGridStatisticsHistogramDataSource::RimGridStatisticsHistogramDataSource() m_property->setTernaryEnabled( false ); CAF_PDM_InitField( &m_numBins, "NumBins", 15, "Number of Bins" ); + CAF_PDM_InitField( &m_cumulative, "Cumulative", false, "Show Cumulative Curve" ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimGridStatisticsHistogramDataSource::showCumulativeCurve() const +{ + return m_cumulative(); } //-------------------------------------------------------------------------------------------------- @@ -107,6 +116,7 @@ void RimGridStatisticsHistogramDataSource ::defineUiOrdering( QString uiConfigNa { uiOrdering.add( &m_timeStep ); uiOrdering.add( &m_cellFilterView ); + uiOrdering.add( &m_cumulative ); caf::PdmUiGroup* propertyGroup = uiOrdering.addNewGroup( "Property" ); m_property->uiOrdering( uiConfigName, *propertyGroup ); } @@ -132,6 +142,13 @@ void RimGridStatisticsHistogramDataSource::fieldChangedByUi( const caf::PdmField dataSourceChanged.send(); } } + else if ( changedField == &m_cumulative ) + { + // Handled by the owning curve, which creates or deletes the cumulative companion curve. + // Not sent as dataSourceChanged: the companion curve observes that signal, and must not be + // deleted while it is being emitted. + cumulativeChanged.send(); + } else { dataSourceChanged.send(); @@ -158,7 +175,8 @@ std::string RimGridStatisticsHistogramDataSource::unitNameX() const /// //-------------------------------------------------------------------------------------------------- RimHistogramDataSource::HistogramResult RimGridStatisticsHistogramDataSource::compute( RimHistogramPlot::GraphType graphType, - RimHistogramPlot::FrequencyType frequencyType ) const + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative ) const { RimHistogramDataSource::HistogramResult result; @@ -168,8 +186,8 @@ RimHistogramDataSource::HistogramResult RimGridStatisticsHistogramDataSource::co double min = histogramData.min; double max = histogramData.max; - result.valuesX = computeHistogramBins( min, max, m_numBins, graphType ); - result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType ); + result.valuesX = computeHistogramBins( min, max, m_numBins, graphType, cumulative ); + result.valuesY = computeHistogramFrequencies( histogramData.histogram, graphType, frequencyType, cumulative ); result.p10 = histogramData.p10; result.mean = histogramData.mean; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimGridStatisticsHistogramDataSource.h b/ApplicationLibCode/ProjectDataModel/Histogram/RimGridStatisticsHistogramDataSource.h index 4f398b1b63e..3347701f2be 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimGridStatisticsHistogramDataSource.h +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimGridStatisticsHistogramDataSource.h @@ -45,7 +45,11 @@ class RimGridStatisticsHistogramDataSource : public RimHistogramDataSource std::string unitNameX() const override; std::string unitNameY() const override; - HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const override; + HistogramResult compute( RimHistogramPlot::GraphType graphType, + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative = false ) const override; + + bool showCumulativeCurve() const override; std::string name() const override; @@ -70,4 +74,5 @@ class RimGridStatisticsHistogramDataSource : public RimHistogramDataSource caf::PdmPtrField m_cellFilterView; caf::PdmChildField m_property; caf::PdmField m_numBins; + caf::PdmField m_cumulative; }; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurve.cpp b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurve.cpp index a07dd46a1f9..7b5a5134f94 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurve.cpp +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurve.cpp @@ -54,6 +54,12 @@ RimHistogramCurve::RimHistogramCurve() CAF_PDM_InitFieldNoDefault( &m_dataSource, "DataSource", "Data Source" ); m_dataSource.uiCapability()->setUiTreeHidden( true ); + CAF_PDM_InitFieldNoDefault( &m_dataSourceReference, "DataSourceReference", "Data Source Reference" ); + m_dataSourceReference.uiCapability()->setUiHidden( true ); + + CAF_PDM_InitField( &m_isCumulative, "IsCumulative", false, "Cumulative" ); + m_isCumulative.uiCapability()->setUiHidden( true ); + CAF_PDM_InitField( &m_showP10Curve, "ShowP10Curve", true, "P10" ); CAF_PDM_InitField( &m_showP90Curve, "ShowP90Curve", true, "P90" ); CAF_PDM_InitField( &m_showMeanCurve, "ShowMeanCurve", true, "Mean" ); @@ -83,6 +89,9 @@ RimHistogramCurve::~RimHistogramCurve() void RimHistogramCurve::initAfterRead() { setDataSource( m_dataSource ); + + // NB: m_dataSourceReference is not resolved yet. The signal connection for referenced data + // sources is established in onLoadDataAndUpdate(). } //-------------------------------------------------------------------------------------------------- @@ -107,15 +116,64 @@ void RimHistogramCurve::setDataSource( RimHistogramDataSource* dataSource ) { m_dataSource->uiCapability()->setUiTreeHidden( true ); m_dataSource->dataSourceChanged.connect( this, &RimHistogramCurve::onDataSourceChanged ); + m_dataSource->cumulativeChanged.connect( this, &RimHistogramCurve::onCumulativeChanged ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// Use the data source owned by another curve. Used by cumulative curves, which share the data +/// source of their non-cumulative counterpart. +//-------------------------------------------------------------------------------------------------- +void RimHistogramCurve::setDataSourceReference( RimHistogramDataSource* dataSource ) +{ + m_dataSourceReference = dataSource; + connectReferencedDataSourceSignals(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimHistogramCurve::connectReferencedDataSourceSignals() +{ + if ( m_dataSourceReference() ) + { + // Connecting an already connected observer is a no-op + m_dataSourceReference()->dataSourceChanged.connect( this, &RimHistogramCurve::onDataSourceChanged ); + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimHistogramCurve::setCumulative( bool cumulative ) +{ + m_isCumulative = cumulative; + + if ( cumulative ) + { + // The percentile annotations are shown by the non-cumulative counterpart curve + m_showP10Curve = false; + m_showP90Curve = false; + m_showMeanCurve = false; } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimHistogramCurve::isCumulative() const +{ + return m_isCumulative(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimHistogramDataSource* RimHistogramCurve::dataSource() const { - return m_dataSource; + if ( m_dataSource() ) return m_dataSource(); + + return m_dataSourceReference(); } //-------------------------------------------------------------------------------------------------- @@ -134,8 +192,8 @@ RiuPlotAxis RimHistogramCurve::axisX() const //-------------------------------------------------------------------------------------------------- std::string RimHistogramCurve::unitNameY() const { - if ( m_dataSource ) - return m_dataSource()->unitNameY(); + if ( dataSource() ) + return dataSource()->unitNameY(); else return ""; } @@ -145,8 +203,8 @@ std::string RimHistogramCurve::unitNameY() const //-------------------------------------------------------------------------------------------------- std::string RimHistogramCurve::unitNameX() const { - if ( m_dataSource ) - return m_dataSource()->unitNameX(); + if ( dataSource() ) + return dataSource()->unitNameX(); else return ""; } @@ -156,10 +214,10 @@ std::string RimHistogramCurve::unitNameX() const //-------------------------------------------------------------------------------------------------- std::vector RimHistogramCurve::valuesY() const { - if ( m_dataSource ) + if ( dataSource() ) { RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted(); - return m_dataSource()->compute( plot->graphType(), plot->frequencyType() ).valuesY; + return dataSource()->compute( plot->graphType(), plot->frequencyType(), m_isCumulative() ).valuesY; } else return {}; @@ -170,10 +228,10 @@ std::vector RimHistogramCurve::valuesY() const //-------------------------------------------------------------------------------------------------- std::vector RimHistogramCurve::valuesX() const { - if ( m_dataSource ) + if ( dataSource() ) { RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted(); - return m_dataSource()->compute( plot->graphType(), plot->frequencyType() ).valuesX; + return dataSource()->compute( plot->graphType(), plot->frequencyType(), m_isCumulative() ).valuesX; } else return {}; @@ -237,9 +295,10 @@ QList RimHistogramCurve::calculateValueOptions( const ca QString RimHistogramCurve::createCurveAutoName() { QString curveName = ""; - if ( m_dataSource ) + if ( dataSource() ) { - curveName = QString::fromStdString( m_dataSource->name() ); + curveName = QString::fromStdString( dataSource()->name() ); + if ( m_isCumulative() ) curveName += ", Cumulative"; } if ( curveName.isEmpty() ) @@ -271,11 +330,13 @@ void RimHistogramCurve::onLoadDataAndUpdate( bool updateParentPlot ) m_annotationTool->detachAllAnnotations(); - if ( isChecked() && m_dataSource() ) + connectReferencedDataSourceSignals(); + + if ( isChecked() && dataSource() ) { RimHistogramPlot* plot = firstAncestorOrThisOfTypeAsserted(); - auto result = m_dataSource->compute( plot->graphType(), plot->frequencyType() ); + auto result = dataSource()->compute( plot->graphType(), plot->frequencyType(), m_isCumulative() ); bool useLogarithmicScale = plot->isLogarithmicScaleEnabled( axisY() ); @@ -486,11 +547,84 @@ void RimHistogramCurve::onDataSourceChanged( const caf::SignalEmitter* emitter ) loadAndUpdateDataAndPlot(); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimHistogramCurve::onCumulativeChanged( const caf::SignalEmitter* emitter ) +{ + updateCumulativeCurve(); +} + +//-------------------------------------------------------------------------------------------------- +/// Create or delete the cumulative companion curve to match the data source setting. The companion +/// curve shares this curve's data source and is shown on the right axis. +//-------------------------------------------------------------------------------------------------- +void RimHistogramCurve::updateCumulativeCurve() +{ + if ( m_isCumulative() || !m_dataSource() ) return; + + auto plot = firstAncestorOrThisOfType(); + if ( !plot ) return; + + RimHistogramCurve* cumulativeCurve = nullptr; + for ( RimHistogramCurve* curve : plot->histogramCurves() ) + { + if ( curve != this && curve->isCumulative() && curve->dataSource() == m_dataSource() ) + { + cumulativeCurve = curve; + break; + } + } + + bool showCumulativeCurve = m_dataSource->showCumulativeCurve(); + if ( showCumulativeCurve && !cumulativeCurve ) + { + auto newCurve = new RimHistogramCurve(); + newCurve->setCumulative( true ); + newCurve->setDataSourceReference( m_dataSource() ); + newCurve->setColor( color() ); + newCurve->setFillStyle( Qt::NoBrush ); + + plot->addCurveNoUpdate( newCurve, false ); + + if ( !plot->axisPropertiesForPlotAxis( RiuPlotAxis::defaultRight() ) ) + { + plot->addNewAxisProperties( RiuPlotAxis::defaultRight(), "Right" ); + } + if ( plot->plotWidget() ) plot->plotWidget()->ensureAxisIsCreated( RiuPlotAxis::defaultRight() ); + newCurve->setLeftOrRightAxisY( RiuPlotAxis::defaultRight() ); + newCurve->setTopOrBottomAxisX( RiuPlotAxis::defaultBottom() ); + + newCurve->loadDataAndUpdate( true ); + plot->updateAxes(); + plot->updateConnectedEditors(); + } + else if ( !showCumulativeCurve && cumulativeCurve ) + { + auto curveCollection = cumulativeCurve->firstAncestorOrThisOfType(); + if ( curveCollection ) + { + curveCollection->deleteCurve( cumulativeCurve ); + plot->updateAxes(); + plot->updateConnectedEditors(); + plot->scheduleReplotIfVisible(); + } + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimHistogramCurve::setAppearanceFromGraphType( RimHistogramPlot::GraphType graphType ) { + if ( m_isCumulative() ) + { + // Cumulative curves are always drawn as lines, also when the histogram is a bar graph + setFillStyle( Qt::NoBrush ); + setFillColorOpacity( 1.0 ); + return; + } + auto fillType = graphType == RimHistogramPlot::GraphType::BAR_GRAPH ? Qt::SolidPattern : Qt::NoBrush; setFillStyle( fillType ); float opacity = graphType == RimHistogramPlot::GraphType::BAR_GRAPH ? 0.2 : 1.0; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurve.h b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurve.h index 139eb934390..12d5193cf7d 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurve.h +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurve.h @@ -58,8 +58,12 @@ class RimHistogramCurve : public RimStackablePlotCurve void updateLegendEntryVisibilityNoPlotUpdate() override; void setDataSource( RimHistogramDataSource* dataSource ); + void setDataSourceReference( RimHistogramDataSource* dataSource ); void setAppearanceFromGraphType( RimHistogramPlot::GraphType graphType ); + void setCumulative( bool cumulative ); + bool isCumulative() const; + RimHistogramDataSource* dataSource() const; protected: @@ -83,6 +87,10 @@ class RimHistogramCurve : public RimStackablePlotCurve void hideXAxisGroup(); void onDataSourceChanged( const caf::SignalEmitter* emitter ); + void onCumulativeChanged( const caf::SignalEmitter* emitter ); + + void updateCumulativeCurve(); + void connectReferencedDataSourceSignals(); void initAfterRead() override; @@ -91,6 +99,9 @@ class RimHistogramCurve : public RimStackablePlotCurve caf::PdmPtrField m_xPlotAxisProperties; caf::PdmChildField m_dataSource; + caf::PdmPtrField m_dataSourceReference; + + caf::PdmField m_isCumulative; caf::PdmField m_showP10Curve; caf::PdmField m_showP90Curve; diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurveCollection.cpp b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurveCollection.cpp index 34a6841c12f..4cac885719f 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurveCollection.cpp +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurveCollection.cpp @@ -262,6 +262,17 @@ void RimHistogramCurveCollection::onCurvesReordered( const SignalEmitter* emitte void RimHistogramCurveCollection::onChildDeleted( caf::PdmChildArrayFieldHandle* childArray, std::vector& referringObjects ) { + // Delete cumulative curves when the curve owning their referenced data source is deleted + std::vector orphanedCurves; + for ( RimHistogramCurve* curve : curves() ) + { + if ( curve->isCumulative() && !curve->dataSource() ) orphanedCurves.push_back( curve ); + } + for ( RimHistogramCurve* curve : orphanedCurves ) + { + deleteCurve( curve ); + } + curvesChanged.send(); } diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurveCollection.h b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurveCollection.h index 43645d003ae..700b839aad4 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurveCollection.h +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramCurveCollection.h @@ -50,6 +50,8 @@ class RimHistogramCurveCollection : public caf::PdmObject void updateCurveOrder(); + void deleteCurve( RimHistogramCurve* curve ); + private: void setParentPlotAndReplot( RiuPlotWidget* plot ); void setParentPlotNoReplot( RiuPlotWidget* plot ); @@ -58,7 +60,6 @@ class RimHistogramCurveCollection : public caf::PdmObject void addCurve( RimHistogramCurve* curve ); void insertCurve( RimHistogramCurve* curve, size_t index ); - void deleteCurve( RimHistogramCurve* curve ); void removeCurve( RimHistogramCurve* curve ); void deleteAllCurves(); diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramDataSource.cpp b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramDataSource.cpp index fefe5592a33..414c591ca9c 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramDataSource.cpp +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramDataSource.cpp @@ -25,6 +25,7 @@ CAF_PDM_XML_ABSTRACT_SOURCE_INIT( RimHistogramDataSource, "HistogramDataSource" //-------------------------------------------------------------------------------------------------- RimHistogramDataSource::RimHistogramDataSource() : dataSourceChanged( this ) + , cumulativeChanged( this ) { CAF_PDM_InitObject( "Histogram Data Source", ); } @@ -39,7 +40,16 @@ RimHistogramDataSource::~RimHistogramDataSource() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimHistogramDataSource::computeHistogramBins( double min, double max, int numBins, RimHistogramPlot::GraphType graphType ) +bool RimHistogramDataSource::showCumulativeCurve() const +{ + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector + RimHistogramDataSource::computeHistogramBins( double min, double max, int numBins, RimHistogramPlot::GraphType graphType, bool cumulative ) { const double binSize = ( max - min ) / numBins; @@ -57,8 +67,9 @@ std::vector RimHistogramDataSource::computeHistogramBins( double min, do values.push_back( binMin ); values.push_back( binMax ); - // Close last bar on right side - if ( i == numBins - 1 ) values.push_back( binMax ); + // Close last bar on right side. A cumulative curve is not closed: it should end at its + // maximum instead of dropping back to zero. + if ( i == numBins - 1 && !cumulative ) values.push_back( binMax ); } else if ( graphType == RimHistogramPlot::GraphType::LINE_GRAPH ) { @@ -74,10 +85,11 @@ std::vector RimHistogramDataSource::computeHistogramBins( double min, do //-------------------------------------------------------------------------------------------------- std::vector RimHistogramDataSource::computeHistogramFrequencies( const std::vector& values, RimHistogramPlot::GraphType graphType, - RimHistogramPlot::FrequencyType frequencyType ) + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative ) { std::vector valuesAsDouble( values.begin(), values.end() ); - return computeHistogramFrequencies( valuesAsDouble, graphType, frequencyType ); + return computeHistogramFrequencies( valuesAsDouble, graphType, frequencyType, cumulative ); } //-------------------------------------------------------------------------------------------------- @@ -85,12 +97,15 @@ std::vector RimHistogramDataSource::computeHistogramFrequencies( const s //-------------------------------------------------------------------------------------------------- std::vector RimHistogramDataSource::computeHistogramFrequencies( const std::vector& values, RimHistogramPlot::GraphType graphType, - RimHistogramPlot::FrequencyType frequencyType ) + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative ) { double sumElements = 0.0; for ( double value : values ) sumElements += value; + double runningSum = 0.0; + std::vector frequencies; for ( size_t i = 0; i < values.size(); i++ ) { @@ -98,6 +113,12 @@ std::vector RimHistogramDataSource::computeHistogramFrequencies( const s if ( frequencyType == RimHistogramPlot::FrequencyType::RELATIVE_FREQUENCY ) value /= sumElements; if ( frequencyType == RimHistogramPlot::FrequencyType::RELATIVE_FREQUENCY_PERCENT ) value = value / sumElements * 100.0; + if ( cumulative ) + { + runningSum += value; + value = runningSum; + } + if ( graphType == RimHistogramPlot::GraphType::BAR_GRAPH ) { // Close first bar on left side @@ -106,8 +127,9 @@ std::vector RimHistogramDataSource::computeHistogramFrequencies( const s frequencies.push_back( value ); frequencies.push_back( value ); - // Close last bar on right side - if ( i == values.size() - 1 ) frequencies.push_back( 0.0 ); + // Close last bar on right side. A cumulative curve is not closed: it should end at its + // maximum instead of dropping back to zero. + if ( i == values.size() - 1 && !cumulative ) frequencies.push_back( 0.0 ); } else if ( graphType == RimHistogramPlot::GraphType::LINE_GRAPH ) { diff --git a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramDataSource.h b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramDataSource.h index 78cb67b01eb..e44af82ddcd 100644 --- a/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramDataSource.h +++ b/ApplicationLibCode/ProjectDataModel/Histogram/RimHistogramDataSource.h @@ -53,21 +53,28 @@ class RimHistogramDataSource : public caf::PdmObject ~RimHistogramDataSource() override; caf::Signal<> dataSourceChanged; + caf::Signal<> cumulativeChanged; virtual std::string unitNameX() const = 0; virtual std::string unitNameY() const = 0; - virtual HistogramResult compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType ) const = 0; + virtual HistogramResult + compute( RimHistogramPlot::GraphType graphType, RimHistogramPlot::FrequencyType frequencyType, bool cumulative = false ) const = 0; + + virtual bool showCumulativeCurve() const; virtual void setDefaults() = 0; virtual std::string name() const = 0; - static std::vector computeHistogramBins( double min, double max, int numBins, RimHistogramPlot::GraphType graphType ); + static std::vector + computeHistogramBins( double min, double max, int numBins, RimHistogramPlot::GraphType graphType, bool cumulative = false ); static std::vector computeHistogramFrequencies( const std::vector& values, RimHistogramPlot::GraphType graphType, - RimHistogramPlot::FrequencyType frequencyType ); + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative = false ); static std::vector computeHistogramFrequencies( const std::vector& values, RimHistogramPlot::GraphType graphType, - RimHistogramPlot::FrequencyType frequencyType ); + RimHistogramPlot::FrequencyType frequencyType, + bool cumulative = false ); }; diff --git a/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp b/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp index afe8882833d..faeb0c33d20 100644 --- a/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp +++ b/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.cpp @@ -20,14 +20,11 @@ #include "Rim3dOverlayInfoConfig.h" -#include "RiaGuiApplication.h" #include "RiaLogging.h" #include "RiaPreferences.h" #include "RiaQDateTimeTools.h" #include "RiuMessageDialog.h" -#include "RicGridStatisticsDialog.h" - #include "ContourMap/RigContourMapProjection.h" #include "RigActiveCellInfo.h" #include "RigCaseCellResultsData.h" @@ -236,31 +233,6 @@ QString Rim3dOverlayInfoConfig::sampleCountText( const std::vector& hist return QString( "
Sample Count: %1" ).arg( text ); } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RicGridStatisticsDialog* Rim3dOverlayInfoConfig::getOrCreateGridStatisticsDialog() -{ - if ( !m_gridStatisticsDialog ) - { - m_gridStatisticsDialog = new RicGridStatisticsDialog( RiaGuiApplication::widgetToUseAsParent() ); - } - CVF_ASSERT( m_gridStatisticsDialog ); - return m_gridStatisticsDialog; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -QImage Rim3dOverlayInfoConfig::statisticsDialogScreenShotImage() -{ - if ( getOrCreateGridStatisticsDialog()->isVisible() ) - { - return getOrCreateGridStatisticsDialog()->screenShotImage(); - } - return QImage(); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -740,29 +712,6 @@ QString Rim3dOverlayInfoConfig::resultInfoText( const RigHistogramData& histData return infoText; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void Rim3dOverlayInfoConfig::showStatisticsInfoDialog( bool raise ) -{ - auto gridView = dynamic_cast( m_viewDef.p() ); - if ( gridView ) - { - RicGridStatisticsDialog* dialog = getOrCreateGridStatisticsDialog(); - // Show dialog before setting data due to text edit auto height setting - dialog->resize( 600, 800 ); - dialog->show(); - - dialog->setLabel( "Grid statistics" ); - dialog->updateFromRimView( gridView ); - - if ( raise ) - { - dialog->raise(); - } - } -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -806,9 +755,6 @@ void Rim3dOverlayInfoConfig::update3DInfo() m_showVolumeWeightedMean = false; } updateEclipse3DInfo( reservoirView ); - - // Update statistics dialog - getOrCreateGridStatisticsDialog()->updateFromRimView( reservoirView ); } RimGeoMechView* geoMechView = dynamic_cast( m_viewDef.p() ); @@ -817,9 +763,6 @@ void Rim3dOverlayInfoConfig::update3DInfo() m_showVolumeWeightedMean = false; updateGeoMech3DInfo( geoMechView ); - - // Update statistics dialog - getOrCreateGridStatisticsDialog()->updateFromRimView( geoMechView ); } RimSeismicView* seisView = dynamic_cast( m_viewDef.p() ); diff --git a/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.h b/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.h index 03517cfbf41..87d2874fb23 100644 --- a/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.h +++ b/ApplicationLibCode/ProjectDataModel/Rim3dOverlayInfoConfig.h @@ -29,8 +29,6 @@ #include "cvfVector2.h" -#include - #include #include @@ -39,7 +37,6 @@ class RimEclipseContourMapView; class RimEclipseView; class RimGeoMechView; class Rim3dView; -class RicGridStatisticsDialog; class RimSeismicView; //================================================================================================== @@ -65,10 +62,6 @@ class Rim3dOverlayInfoConfig : public caf::PdmObject QString caseInfoText(); QString resultInfoText( const RigHistogramData& histData ); - RicGridStatisticsDialog* getOrCreateGridStatisticsDialog(); - void showStatisticsInfoDialog( bool raise = true ); - QImage statisticsDialogScreenShotImage(); - bool showAnimProgress() const; bool showCaseInfo() const; bool showResultInfo() const; @@ -113,6 +106,4 @@ class Rim3dOverlayInfoConfig : public caf::PdmObject cvf::Vec2ui m_position; std::unique_ptr m_histogramCalculator; - - QPointer m_gridStatisticsDialog; }; diff --git a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp index e13113fe473..a8ae56bc502 100644 --- a/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp +++ b/ApplicationLibCode/ProjectDataModel/RimContextCommandBuilder.cpp @@ -867,7 +867,6 @@ caf::CmdFeatureMenuBuilder RimContextCommandBuilder::commandsFromSelection() else if ( dynamic_cast( firstUiItem ) ) { menuBuilder << "RicCreateGridStatisticsPlotFeature"; - menuBuilder << "RicShowGridStatisticsFeature"; } else if ( dynamic_cast( firstUiItem ) ) { diff --git a/ApplicationLibCode/UnitTests/CMakeLists.txt b/ApplicationLibCode/UnitTests/CMakeLists.txt index adb0d9e531c..5661cee0f85 100644 --- a/ApplicationLibCode/UnitTests/CMakeLists.txt +++ b/ApplicationLibCode/UnitTests/CMakeLists.txt @@ -28,6 +28,7 @@ set(SOURCE_UNITTEST_FILES ${CMAKE_CURRENT_LIST_DIR}/RigStatisticsMath-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RigStimPlanModelTools-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RigWellPathIntersectionTools-Test.cpp + ${CMAKE_CURRENT_LIST_DIR}/RimHistogramDataSource-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RimWellLogExtractionCurveImpl-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RivPipeGeometryGenerator-Test.cpp ${CMAKE_CURRENT_LIST_DIR}/RivTernaryScalarMapper-Test.cpp diff --git a/ApplicationLibCode/UnitTests/RimHistogramDataSource-Test.cpp b/ApplicationLibCode/UnitTests/RimHistogramDataSource-Test.cpp new file mode 100644 index 00000000000..e7069343a14 --- /dev/null +++ b/ApplicationLibCode/UnitTests/RimHistogramDataSource-Test.cpp @@ -0,0 +1,101 @@ +#include "gtest/gtest.h" + +#include "Histogram/RimHistogramDataSource.h" + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RimHistogramDataSourceTest, CumulativeLineGraphRelativePercent ) +{ + std::vector bins = { 1, 2, 3 }; + + std::vector frequencies = + RimHistogramDataSource::computeHistogramFrequencies( bins, + RimHistogramPlot::GraphType::LINE_GRAPH, + RimHistogramPlot::FrequencyType::RELATIVE_FREQUENCY_PERCENT, + true ); + + ASSERT_EQ( 3u, frequencies.size() ); + EXPECT_NEAR( 100.0 / 6.0, frequencies[0], 1e-9 ); + EXPECT_NEAR( 50.0, frequencies[1], 1e-9 ); + EXPECT_NEAR( 100.0, frequencies[2], 1e-9 ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RimHistogramDataSourceTest, CumulativeLineGraphAbsolute ) +{ + std::vector bins = { 1, 2, 3 }; + + std::vector frequencies = RimHistogramDataSource::computeHistogramFrequencies( bins, + RimHistogramPlot::GraphType::LINE_GRAPH, + RimHistogramPlot::FrequencyType::ABSOLUTE_FREQUENCY, + true ); + + ASSERT_EQ( 3u, frequencies.size() ); + EXPECT_NEAR( 1.0, frequencies[0], 1e-9 ); + EXPECT_NEAR( 3.0, frequencies[1], 1e-9 ); + EXPECT_NEAR( 6.0, frequencies[2], 1e-9 ); +} + +//-------------------------------------------------------------------------------------------------- +/// The cumulative sum must be applied per bin before the bar graph expansion: the expanded vector +/// starts with a 0.0 closer and each cumulative bin value is duplicated. Unlike a regular +/// histogram, a cumulative curve has no closing 0.0 at the end: it ends at its maximum. +//-------------------------------------------------------------------------------------------------- +TEST( RimHistogramDataSourceTest, CumulativeBarGraphAbsolute ) +{ + std::vector bins = { 1, 2, 3 }; + + std::vector frequencies = RimHistogramDataSource::computeHistogramFrequencies( bins, + RimHistogramPlot::GraphType::BAR_GRAPH, + RimHistogramPlot::FrequencyType::ABSOLUTE_FREQUENCY, + true ); + + std::vector expected = { 0.0, 1.0, 1.0, 3.0, 3.0, 6.0, 6.0 }; + ASSERT_EQ( expected.size(), frequencies.size() ); + for ( size_t i = 0; i < expected.size(); i++ ) + { + EXPECT_NEAR( expected[i], frequencies[i], 1e-9 ); + } + + std::vector xValues = + RimHistogramDataSource::computeHistogramBins( 0.0, 3.0, static_cast( bins.size() ), RimHistogramPlot::GraphType::BAR_GRAPH, true ); + EXPECT_EQ( frequencies.size(), xValues.size() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RimHistogramDataSourceTest, NonCumulativeBarGraphBinsAndFrequenciesMatch ) +{ + std::vector bins = { 1, 2, 3 }; + + std::vector frequencies = + RimHistogramDataSource::computeHistogramFrequencies( bins, + RimHistogramPlot::GraphType::BAR_GRAPH, + RimHistogramPlot::FrequencyType::ABSOLUTE_FREQUENCY ); + + std::vector xValues = + RimHistogramDataSource::computeHistogramBins( 0.0, 3.0, static_cast( bins.size() ), RimHistogramPlot::GraphType::BAR_GRAPH ); + EXPECT_EQ( frequencies.size(), xValues.size() ); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +TEST( RimHistogramDataSourceTest, NonCumulativeIsUnchanged ) +{ + std::vector bins = { 1, 2, 3 }; + + std::vector frequencies = + RimHistogramDataSource::computeHistogramFrequencies( bins, + RimHistogramPlot::GraphType::LINE_GRAPH, + RimHistogramPlot::FrequencyType::ABSOLUTE_FREQUENCY ); + + ASSERT_EQ( 3u, frequencies.size() ); + EXPECT_NEAR( 1.0, frequencies[0], 1e-9 ); + EXPECT_NEAR( 2.0, frequencies[1], 1e-9 ); + EXPECT_NEAR( 3.0, frequencies[2], 1e-9 ); +} diff --git a/ApplicationLibCode/UserInterface/RiuViewerCommands.cpp b/ApplicationLibCode/UserInterface/RiuViewerCommands.cpp index e0238703a9b..e0c8c9618b0 100644 --- a/ApplicationLibCode/UserInterface/RiuViewerCommands.cpp +++ b/ApplicationLibCode/UserInterface/RiuViewerCommands.cpp @@ -621,7 +621,6 @@ void RiuViewerCommands::displayContextMenu( QMouseEvent* event ) { menuBuilder.addSeparator(); menuBuilder << "RicCreateGridStatisticsPlotFeature"; - menuBuilder << "RicShowGridStatisticsFeature"; // Grid statistics commands operate on the result shown in the overlay info box, so only // offer them when the context menu is invoked inside that box, not on the view geometry. if ( m_viewer->isMousePosWithinInfoBox( event->x(), event->y() ) )