From 7e6943aa96a035d896da46bd896ac3a6237ae13e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Erik=20Jensen?= Date: Tue, 19 Jun 2018 15:39:27 +0200 Subject: [PATCH] #3060 Resampled plot export. Prepare for resampling during summary plot export --- .../Application/Tools/RiaQDateTimeTools.h | 1 + .../Tools/RiaTimeHistoryCurveResampler.cpp | 3 +- .../Summary/RimSummaryPlot.cpp | 254 +++++++++--------- .../ProjectDataModel/Summary/RimSummaryPlot.h | 3 +- 4 files changed, 134 insertions(+), 127 deletions(-) diff --git a/ApplicationCode/Application/Tools/RiaQDateTimeTools.h b/ApplicationCode/Application/Tools/RiaQDateTimeTools.h index dd4ad2c2d7..6d7417b22e 100644 --- a/ApplicationCode/Application/Tools/RiaQDateTimeTools.h +++ b/ApplicationCode/Application/Tools/RiaQDateTimeTools.h @@ -33,6 +33,7 @@ class DateTimeSpan; //================================================================================================== enum class DateTimePeriod { + NONE = -1, DECADE, YEAR, HALFYEAR, diff --git a/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp index ae9fd3337c..677746d8c0 100644 --- a/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp +++ b/ApplicationCode/Application/Tools/RiaTimeHistoryCurveResampler.cpp @@ -34,7 +34,6 @@ // return QString("%1.%2.%3 %4:%5:%6").arg(y).arg(m).arg(d).arg(h).arg(mm).arg(s); //} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -185,7 +184,7 @@ void RiaTimeHistoryCurveResampler::clearData() //-------------------------------------------------------------------------------------------------- void RiaTimeHistoryCurveResampler::computeResampledTimeSteps(DateTimePeriod period) { - CVF_ASSERT(m_originalValues.second.size() > 0); + CVF_ASSERT(period != DateTimePeriod::NONE && m_originalValues.second.size() > 0); auto firstOriginalTimeStep = QDT::fromTime_t(m_originalValues.second.front()); auto lastOriginalTimeStep = QDT::fromTime_t(m_originalValues.second.back()); diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp index 00db4d266f..cd9a3b33f8 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.cpp @@ -20,6 +20,7 @@ #include "RiaApplication.h" #include "RiaSummaryCurveAnalyzer.h" +#include "RiaTimeHistoryCurveResampler.h" #include "SummaryPlotCommands/RicSummaryCurveCreator.h" @@ -61,6 +62,25 @@ CAF_PDM_SOURCE_INIT(RimSummaryPlot, "SummaryPlot"); +//-------------------------------------------------------------------------------------------------- +/// Internal data +//-------------------------------------------------------------------------------------------------- +struct CurveData +{ + QString name; + RifEclipseSummaryAddress address; + std::vector values; +}; + +//-------------------------------------------------------------------------------------------------- +/// Internal functions +//-------------------------------------------------------------------------------------------------- +void prepareCaseCurvesForExport(DateTimePeriod period, + const std::vector &timeSteps, const std::vector& curveData, + std::vector* resampledTimeSteps, std::vector* resampledValues); + +void appendToExportData(QString& out, const std::vector& timeSteps, const std::vector& curveData); + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -243,100 +263,69 @@ QWidget* RimSummaryPlot::viewWidget() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimSummaryPlot::asciiDataForPlotExport() const +QString RimSummaryPlot::asciiDataForPlotExport(DateTimePeriod resamplingPeriod) const { QString out; + RiaTimeHistoryCurveResampler resampler; out += description(); + // Summary curves { std::vector curves; this->descendantsIncludingThisOfType(curves); std::vector caseNames; std::vector > timeSteps; - - std::vector > > allCurveData; - std::vector > allCurveNames; - //Vectors containing cases - curves - data points/curve name + std::vector> allCurveData; + // Vector containing cases - curves for (RimSummaryCurve* curve : curves) { if (!curve->isCurveVisible()) continue; QString curveCaseName = curve->summaryCaseY()->caseName(); - + size_t casePosInList = cvf::UNDEFINED_SIZE_T; for (size_t i = 0; i < caseNames.size(); i++) { if (curveCaseName == caseNames[i]) casePosInList = i; } + CurveData curveData = { curve->curveName(), curve->summaryAddressY(), curve->valuesY() }; + if (casePosInList == cvf::UNDEFINED_SIZE_T) { caseNames.push_back(curveCaseName); - - std::vector curveTimeSteps = curve->timeStepsY(); - timeSteps.push_back(curveTimeSteps); - - std::vector > curveDataForCase; - std::vector curveYData = curve->valuesY(); - curveDataForCase.push_back(curveYData); - allCurveData.push_back(curveDataForCase); - - std::vector curveNamesForCase; - curveNamesForCase.push_back(curve->curveName()); - allCurveNames.push_back(curveNamesForCase); + timeSteps.push_back(curve->timeStepsY()); + allCurveData.push_back(std::vector({ curveData })); } else { - std::vector curveYData = curve->valuesY(); - allCurveData[casePosInList].push_back(curveYData); - - QString curveName = curve->curveName(); - allCurveNames[casePosInList].push_back(curveName); + allCurveData[casePosInList].push_back(curveData); } } for (size_t i = 0; i < timeSteps.size(); i++) //cases { + // Data for export + std::vector expTimeSteps; + std::vector expCurveData; + out += "\n\n"; out += "Case: " + caseNames[i]; out += "\n"; - for (size_t j = 0; j < timeSteps[i].size(); j++) //time steps & data points - { - if (j == 0) - { - out += "Date and time"; - for (size_t k = 0; k < allCurveNames[i].size(); k++) // curves - { - out += "\t" + (allCurveNames[i][k]); - } - } - out += "\n"; - out += QDateTime::fromTime_t(timeSteps[i][j]).toUTC().toString("yyyy-MM-dd hh:mm:ss "); - - for (size_t k = 0; k < allCurveData[i].size(); k++) // curves - { - QString valueText; - if (j < allCurveData[i][k].size()) - { - valueText = QString::number(allCurveData[i][k][j], 'g', 6); - } - out += "\t" + valueText; - } - } + prepareCaseCurvesForExport(resamplingPeriod, timeSteps[i], allCurveData[i], &expTimeSteps, &expCurveData); + appendToExportData(out, expTimeSteps, expCurveData); } } - + // Time history curves (from grid) { std::vector caseNames; std::vector > timeSteps; - - std::vector > > allCurveData; - std::vector > allCurveNames; - //Vectors containing cases - curves - data points/curve name + std::vector> allCurveData; + // Vector containing cases - curves for (RimGridTimeHistoryCurve* curve : m_gridTimeHistoryCurves) { @@ -349,65 +338,40 @@ QString RimSummaryPlot::asciiDataForPlotExport() const if (curveCaseName == caseNames[i]) casePosInList = i; } + CurveData curveData = { curve->curveName(), RifEclipseSummaryAddress(), curve->yValues() }; + if (casePosInList == cvf::UNDEFINED_SIZE_T) { caseNames.push_back(curveCaseName); - - std::vector curveTimeSteps = curve->timeStepValues(); - timeSteps.push_back(curveTimeSteps); - - std::vector > curveDataForCase; - std::vector curveYData = curve->yValues(); - curveDataForCase.push_back(curveYData); - allCurveData.push_back(curveDataForCase); - - std::vector curveNamesForCase; - curveNamesForCase.push_back(curve->curveName()); - allCurveNames.push_back(curveNamesForCase); + timeSteps.push_back(curve->timeStepValues()); + allCurveData.push_back(std::vector({ curveData })); } else { - std::vector curveYData = curve->yValues(); - allCurveData[casePosInList].push_back(curveYData); - - QString curveName = curve->curveName(); - allCurveNames[casePosInList].push_back(curveName); + allCurveData[casePosInList].push_back(curveData); } } for (size_t i = 0; i < timeSteps.size(); i++) //cases { + // Data for export + std::vector expTimeSteps; + std::vector expCurveData; + out += "\n\n"; out += "Case: " + caseNames[i]; out += "\n"; - for (size_t j = 0; j < timeSteps[i].size(); j++) //time steps & data points - { - if (j == 0) - { - out += "Date and time"; - for (size_t k = 0; k < allCurveNames[i].size(); k++) // curves - { - out += "\t" + (allCurveNames[i][k]); - } - } - out += "\n"; - out += QDateTime::fromTime_t(timeSteps[i][j]).toUTC().toString("yyyy-MM-dd hh:mm:ss "); - - for (size_t k = 0; k < allCurveData[i].size(); k++) // curves - { - out += "\t" + QString::number(allCurveData[i][k][j], 'g', 6); - } - } + prepareCaseCurvesForExport(resamplingPeriod, timeSteps[i], allCurveData[i], &expTimeSteps, &expCurveData); + appendToExportData(out, expTimeSteps, expCurveData); } } + // Pasted observed data { std::vector > timeSteps; - - std::vector > > allCurveData; - std::vector > allCurveNames; - //Vectors containing cases - curves - data points/curve name + std::vector> allCurveData; + // Vector containing cases - curves for (RimAsciiDataCurve* curve : m_asciiDataCurves) { @@ -415,52 +379,29 @@ QString RimSummaryPlot::asciiDataForPlotExport() const size_t casePosInList = cvf::UNDEFINED_SIZE_T; + CurveData curveData = { curve->curveName(), RifEclipseSummaryAddress(), curve->yValues() }; + if (casePosInList == cvf::UNDEFINED_SIZE_T) { - std::vector curveTimeSteps = curve->timeSteps(); - timeSteps.push_back(curveTimeSteps); - - std::vector > curveDataForCase; - std::vector curveYData = curve->yValues(); - curveDataForCase.push_back(curveYData); - allCurveData.push_back(curveDataForCase); - - std::vector curveNamesForCase; - curveNamesForCase.push_back(curve->curveName()); - allCurveNames.push_back(curveNamesForCase); + timeSteps.push_back(curve->timeSteps()); + allCurveData.push_back(std::vector({ curveData })); } else { - std::vector curveYData = curve->yValues(); - allCurveData[casePosInList].push_back(curveYData); - - QString curveName = curve->curveName(); - allCurveNames[casePosInList].push_back(curveName); + allCurveData[casePosInList].push_back(curveData); } } for (size_t i = 0; i < timeSteps.size(); i++) //cases { + // Data for export + std::vector expTimeSteps; + std::vector expCurveData; + out += "\n\n"; - for (size_t j = 0; j < timeSteps[i].size(); j++) //time steps & data points - { - if (j == 0) - { - out += "Date and time"; - for (size_t k = 0; k < allCurveNames[i].size(); k++) // curves - { - out += "\t" + (allCurveNames[i][k]); - } - } - out += "\n"; - out += QDateTime::fromTime_t(timeSteps[i][j]).toUTC().toString("yyyy-MM-dd hh:mm:ss "); - - for (size_t k = 0; k < allCurveData[i].size(); k++) // curves - { - out += "\t" + QString::number(allCurveData[i][k][j], 'g', 6); - } - } + prepareCaseCurvesForExport(resamplingPeriod, timeSteps[i], allCurveData[i], &expTimeSteps, &expCurveData); + appendToExportData(out, expTimeSteps, expCurveData); } } @@ -1695,3 +1636,68 @@ void RimSummaryPlot::defineEditorAttribute(const caf::PdmFieldHandle* field, QSt } } } + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void prepareCaseCurvesForExport(DateTimePeriod period, + const std::vector &timeSteps, const std::vector& curveData, + std::vector* resampledTimeSteps, std::vector* resampledCurveData) +{ + RiaTimeHistoryCurveResampler resampler; + + resampledTimeSteps->clear(); + resampledCurveData->clear(); + + if (period != DateTimePeriod::NONE) + { + for (auto& curveDataItem : curveData) + { + resampler.setCurveData(curveDataItem.values, timeSteps); + + if (curveDataItem.address.hasAccumulatedData()) resampler.resampleAndComputePeriodEndValues(period); + else resampler.resampleAndComputeWeightedMeanValues(period); + + auto cd = curveDataItem; + cd.values = resampler.resampledValues(); + resampledCurveData->push_back(cd); + } + + *resampledTimeSteps = resampler.resampledTimeSteps(); + } + else + { + *resampledTimeSteps = timeSteps; + *resampledCurveData = curveData; + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void appendToExportData(QString& out, const std::vector& timeSteps, const std::vector& curveData) +{ + for (size_t j = 0; j < timeSteps.size(); j++) //time steps & data points + { + if (j == 0) + { + out += "Date and time"; + for (size_t k = 0; k < curveData.size(); k++) // curves + { + out += "\t" + (curveData[k].name); + } + } + out += "\n"; + out += QDateTime::fromTime_t(timeSteps[j]).toUTC().toString("yyyy-MM-dd hh:mm:ss "); + + for (size_t k = 0; k < curveData.size(); k++) // curves + { + QString valueText; + if (j < curveData[k].values.size()) + { + valueText = QString::number(curveData[k].values[j], 'g', 6); + } + out += "\t" + valueText; + } + } +} diff --git a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.h b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.h index 1f74fe2024..5f9b62329e 100644 --- a/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.h +++ b/ApplicationCode/ProjectDataModel/Summary/RimSummaryPlot.h @@ -22,6 +22,7 @@ #include "cafPdmChildArrayField.h" #include "RiaDefines.h" +#include "RiaQDateTimeTools.h" #include "RifEclipseSummaryAddress.h" @@ -102,7 +103,7 @@ public: virtual QWidget* viewWidget() override; - QString asciiDataForPlotExport() const; + QString asciiDataForPlotExport(DateTimePeriod resamplingPeriod = DateTimePeriod::NONE) const; std::vector summaryAndEnsembleCurves() const; std::vector summaryCurves() const;