///////////////////////////////////////////////////////////////////////////////// // // 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RimCorrelationPlotCollection.h" #include "RiaSummaryCurveDefinition.h" #include "RimCorrelationMatrixPlot.h" #include "RimCorrelationPlot.h" #include "RimCorrelationReportPlot.h" #include "RimParameterResultCrossPlot.h" #include "RimProject.h" #include "RimSummaryCaseCollection.h" CAF_PDM_SOURCE_INIT( RimCorrelationPlotCollection, "CorrelationPlotCollection" ); //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCorrelationPlotCollection::RimCorrelationPlotCollection() { CAF_PDM_InitObject( "Ensemble Correlation Plots", ":/CorrelationPlots16x16.png" ); CAF_PDM_InitFieldNoDefault( &m_correlationPlots, "CorrelationPlots", "Correlation Plots" ); CAF_PDM_InitFieldNoDefault( &m_correlationReports, "CorrelationReports", "Correlation Reports" ); m_correlationPlots.uiCapability()->setUiTreeHidden( true ); m_correlationReports.uiCapability()->setUiTreeHidden( true ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCorrelationPlotCollection::~RimCorrelationPlotCollection() { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCorrelationPlot* RimCorrelationPlotCollection::createCorrelationPlot( bool defaultToFirstEnsembleFopt ) { RimCorrelationPlot* plot = new RimCorrelationPlot(); plot->setAsPlotMdiWindow(); if ( defaultToFirstEnsembleFopt ) applyFirstEnsembleFieldAddressesToPlot( plot, { "FOPT" } ); plot->selectAllParameters(); addPlot( plot ); return plot; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCorrelationPlot* RimCorrelationPlotCollection::createCorrelationPlot( RimSummaryCaseCollection* ensemble, const QString& quantityName, std::time_t timeStep ) { RimCorrelationPlot* plot = new RimCorrelationPlot(); plot->setAsPlotMdiWindow(); applyEnsembleFieldAndTimeStepToPlot( plot, ensemble, { quantityName }, timeStep ); plot->selectAllParameters(); addPlot( plot ); return plot; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCorrelationMatrixPlot* RimCorrelationPlotCollection::createCorrelationMatrixPlot( bool defaultToFirstEnsembleField ) { RimCorrelationMatrixPlot* plot = new RimCorrelationMatrixPlot(); plot->setAsPlotMdiWindow(); if ( defaultToFirstEnsembleField ) applyFirstEnsembleFieldAddressesToPlot( plot, { "FOPT", "FWPT", "FGPT" } ); plot->selectAllParameters(); addPlot( plot ); return plot; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCorrelationMatrixPlot* RimCorrelationPlotCollection::createCorrelationMatrixPlot( RimSummaryCaseCollection* ensemble, const std::vector& quantityNames, std::time_t timeStep ) { RimCorrelationMatrixPlot* plot = new RimCorrelationMatrixPlot(); plot->setAsPlotMdiWindow(); applyEnsembleFieldAndTimeStepToPlot( plot, ensemble, quantityNames, timeStep ); plot->selectAllParameters(); addPlot( plot ); return plot; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimParameterResultCrossPlot* RimCorrelationPlotCollection::createParameterResultCrossPlot( bool defaultToFirstEnsembleFopt ) { RimParameterResultCrossPlot* plot = new RimParameterResultCrossPlot; plot->setAsPlotMdiWindow(); if ( defaultToFirstEnsembleFopt ) applyFirstEnsembleFieldAddressesToPlot( plot, { "FOPT" } ); addPlot( plot ); return plot; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimParameterResultCrossPlot* RimCorrelationPlotCollection::createParameterResultCrossPlot( RimSummaryCaseCollection* ensemble, const QString& paramName, const QString& quantityName, std::time_t timeStep ) { RimParameterResultCrossPlot* plot = new RimParameterResultCrossPlot; plot->setAsPlotMdiWindow(); applyEnsembleFieldAndTimeStepToPlot( plot, ensemble, { quantityName }, timeStep ); plot->setEnsembleParameter( paramName ); addPlot( plot ); return plot; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCorrelationReportPlot* RimCorrelationPlotCollection::createCorrelationReportPlot( bool defaultToFirstEnsembleField /*= true */ ) { RimCorrelationReportPlot* report = new RimCorrelationReportPlot; report->setAsPlotMdiWindow(); if ( defaultToFirstEnsembleField ) applyFirstEnsembleFieldAddressesToReport( report, { "FOPT", "FWPT", "FGPT" }, "FOPT" ); report->matrixPlot()->selectAllParameters(); report->correlationPlot()->selectAllParameters(); m_correlationReports.push_back( report ); return report; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RimCorrelationReportPlot* RimCorrelationPlotCollection::createCorrelationReportPlot( RimSummaryCaseCollection* ensemble, const std::vector& matrixQuantityNames, const QString& tornadoAndCrossPlotQuantityName, std::time_t timeStep ) { RimCorrelationReportPlot* report = new RimCorrelationReportPlot; report->setAsPlotMdiWindow(); applyEnsembleFieldAndTimeStepToReport( report, ensemble, matrixQuantityNames, tornadoAndCrossPlotQuantityName, timeStep ); report->matrixPlot()->selectAllParameters(); report->correlationPlot()->selectAllParameters(); m_correlationReports.push_back( report ); return report; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCorrelationPlotCollection::insertPlot( RimAbstractCorrelationPlot* plot, size_t index ) { m_correlationPlots.insert( index, plot ); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCorrelationPlotCollection::removePlot( RimAbstractCorrelationPlot* plot ) { m_correlationPlots.removeChild( plot ); updateAllRequiredEditors(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimCorrelationPlotCollection::plots() const { return m_correlationPlots.children(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RimCorrelationPlotCollection::plotCount() const { return m_correlationPlots.size(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RimCorrelationPlotCollection::reports() const { return m_correlationReports.children(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCorrelationPlotCollection::deleteAllPlots() { RimTypedPlotCollection::deleteAllPlots(); m_correlationReports.deleteChildren(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToPlot( RimAbstractCorrelationPlot* plot, const std::vector& quantityNames /*= {} */ ) { std::vector ensembles; RimProject::current()->descendantsIncludingThisOfType( ensembles ); if ( !ensembles.empty() ) { std::set allAddresses = ensembles.front()->ensembleSummaryAddresses(); std::vector curveDefs; for ( auto address : allAddresses ) { auto it = std::find( quantityNames.begin(), quantityNames.end(), QString::fromStdString( address.uiText() ) ); if ( it != quantityNames.end() || quantityNames.empty() ) { curveDefs.push_back( RiaSummaryCurveDefinition( ensembles.front(), address ) ); } } plot->setCurveDefinitions( curveDefs ); auto crossPlot = dynamic_cast( plot ); if ( crossPlot ) { crossPlot->setEnsembleParameter( ensembles.front()->alphabeticEnsembleParameters().front().name ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCorrelationPlotCollection::applyEnsembleFieldAndTimeStepToPlot( RimAbstractCorrelationPlot* plot, RimSummaryCaseCollection* ensemble, const std::vector& quantityNames, std::time_t timeStep ) { if ( ensemble ) { std::set allAddresses = ensemble->ensembleSummaryAddresses(); std::vector curveDefs; std::vector highestCorrelationParameters; for ( auto address : allAddresses ) { auto it = std::find( quantityNames.begin(), quantityNames.end(), QString::fromStdString( address.uiText() ) ); if ( it != quantityNames.end() || quantityNames.empty() ) { curveDefs.push_back( RiaSummaryCurveDefinition( ensemble, address ) ); auto correlationSortedEnsembleParameters = ensemble->correlationSortedEnsembleParameters( address, timeStep ); highestCorrelationParameters.push_back( correlationSortedEnsembleParameters.front().first.name ); } } plot->setCurveDefinitions( curveDefs ); plot->setTimeStep( timeStep ); auto crossPlot = dynamic_cast( plot ); if ( crossPlot && !highestCorrelationParameters.empty() ) { crossPlot->setEnsembleParameter( highestCorrelationParameters.front() ); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCorrelationPlotCollection::applyFirstEnsembleFieldAddressesToReport( RimCorrelationReportPlot* plot, const std::vector& matrixQuantityNames, const QString& tornadoAndCrossPlotQuantityName ) { std::vector ensembles; RimProject::current()->descendantsIncludingThisOfType( ensembles ); if ( !ensembles.empty() ) { std::set allAddresses = ensembles.front()->ensembleSummaryAddresses(); std::vector curveDefsMatrix; std::vector curveDefsTornadoAndCrossPlot; for ( auto address : allAddresses ) { auto it = std::find( matrixQuantityNames.begin(), matrixQuantityNames.end(), QString::fromStdString( address.uiText() ) ); if ( it != matrixQuantityNames.end() || matrixQuantityNames.empty() ) { curveDefsMatrix.push_back( RiaSummaryCurveDefinition( ensembles.front(), address ) ); } if ( tornadoAndCrossPlotQuantityName.isEmpty() || tornadoAndCrossPlotQuantityName == QString::fromStdString( address.uiText() ) ) { curveDefsTornadoAndCrossPlot.push_back( RiaSummaryCurveDefinition( ensembles.front(), address ) ); } } plot->matrixPlot()->setCurveDefinitions( curveDefsMatrix ); plot->correlationPlot()->setCurveDefinitions( curveDefsTornadoAndCrossPlot ); plot->crossPlot()->setCurveDefinitions( curveDefsTornadoAndCrossPlot ); time_t timeStep = *( plot->matrixPlot()->allAvailableTimeSteps().rbegin() ); auto correlationSortedEnsembleParameters = ensembles.front()->correlationSortedEnsembleParameters( curveDefsTornadoAndCrossPlot.front().summaryAddress(), timeStep ); if ( !correlationSortedEnsembleParameters.empty() ) { QString crossPlotEnsembleParameterName = correlationSortedEnsembleParameters.front().first.name; plot->crossPlot()->setEnsembleParameter( crossPlotEnsembleParameterName ); } plot->matrixPlot()->setTimeStep( timeStep ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCorrelationPlotCollection::applyEnsembleFieldAndTimeStepToReport( RimCorrelationReportPlot* plot, RimSummaryCaseCollection* ensemble, const std::vector& matrixQuantityNames, const QString& tornadoAndCrossPlotQuantityName, std::time_t timeStep ) { if ( ensemble ) { std::set allAddresses = ensemble->ensembleSummaryAddresses(); std::vector curveDefsMatrix; std::vector curveDefsTornadoAndCrossPlot; for ( auto address : allAddresses ) { auto it = std::find( matrixQuantityNames.begin(), matrixQuantityNames.end(), QString::fromStdString( address.uiText() ) ); if ( it != matrixQuantityNames.end() || matrixQuantityNames.empty() ) { curveDefsMatrix.push_back( RiaSummaryCurveDefinition( ensemble, address ) ); } if ( tornadoAndCrossPlotQuantityName.isEmpty() || tornadoAndCrossPlotQuantityName == QString::fromStdString( address.uiText() ) ) { curveDefsTornadoAndCrossPlot.push_back( RiaSummaryCurveDefinition( ensemble, address ) ); } } plot->matrixPlot()->setCurveDefinitions( curveDefsMatrix ); plot->matrixPlot()->setTimeStep( timeStep ); plot->correlationPlot()->setCurveDefinitions( curveDefsTornadoAndCrossPlot ); plot->correlationPlot()->setTimeStep( timeStep ); plot->crossPlot()->setCurveDefinitions( curveDefsTornadoAndCrossPlot ); plot->crossPlot()->setTimeStep( timeStep ); auto correlationSortedEnsembleParameters = ensemble->correlationSortedEnsembleParameters( curveDefsTornadoAndCrossPlot.front().summaryAddress(), timeStep ); QString crossPlotEnsembleParameterName = correlationSortedEnsembleParameters.front().first.name; plot->crossPlot()->setEnsembleParameter( crossPlotEnsembleParameterName ); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimCorrelationPlotCollection::loadDataAndUpdateAllPlots() { for ( const auto& corrPlot : m_correlationPlots ) corrPlot->loadDataAndUpdate(); for ( const auto& reports : m_correlationReports ) reports->loadDataAndUpdate(); }