#4136 Export of Flow Characteristics : Create text for export and add context menu

This commit is contained in:
Magne Sjaastad
2019-06-23 15:18:17 +02:00
parent 79df075fe4
commit 7879fe186d
5 changed files with 200 additions and 26 deletions

View File

@@ -18,6 +18,7 @@
#include "RicShowPlotDataFeature.h"
#include "RiaFeatureCommandContext.h"
#include "RiaGuiApplication.h"
#include "RimGridCrossPlot.h"
@@ -36,7 +37,6 @@
#include <QAction>
CAF_CMD_SOURCE_INIT(RicShowPlotDataFeature, "RicShowPlotDataFeature");
//--------------------------------------------------------------------------------------------------
@@ -171,6 +171,12 @@ private:
//--------------------------------------------------------------------------------------------------
bool RicShowPlotDataFeature::isCommandEnabled()
{
QString content = RiaFeatureCommandContext::instance()->contentString();
if (!content.isEmpty())
{
return true;
}
auto selectedSummaryPlots = caf::selectedObjectsByType<RimSummaryPlot*>();
if (selectedSummaryPlots.size() > 0)
{
@@ -199,11 +205,25 @@ bool RicShowPlotDataFeature::isCommandEnabled()
//--------------------------------------------------------------------------------------------------
void RicShowPlotDataFeature::onActionTriggered(bool isChecked)
{
QString content = RiaFeatureCommandContext::instance()->contentString();
if (!content.isEmpty())
{
QString title = "Data Content";
{
QString titleCandidate = RiaFeatureCommandContext::instance()->titleString();
if (!titleCandidate.isEmpty()) titleCandidate = titleCandidate;
}
RicShowPlotDataFeature::showTextWindow(title, content);
return;
}
this->disableModelChangeContribution();
std::vector<RimSummaryPlot*> selectedSummaryPlots = caf::selectedObjectsByType<RimSummaryPlot*>();
std::vector<RimWellLogPlot*> wellLogPlots = caf::selectedObjectsByType<RimWellLogPlot*>();
std::vector<RimGridCrossPlot*> crossPlots = caf::selectedObjectsByType<RimGridCrossPlot*>();
std::vector<RimWellLogPlot*> wellLogPlots = caf::selectedObjectsByType<RimWellLogPlot*>();
std::vector<RimGridCrossPlot*> crossPlots = caf::selectedObjectsByType<RimGridCrossPlot*>();
if (selectedSummaryPlots.size() == 0 && wellLogPlots.size() == 0 && crossPlots.size() == 0)
{
CVF_ASSERT(false);
@@ -223,7 +243,7 @@ void RicShowPlotDataFeature::onActionTriggered(bool isChecked)
for (RimWellLogPlot* wellLogPlot : wellLogPlots)
{
QString title = wellLogPlot->description();
QString text = wellLogPlot->asciiDataForPlotExport();
QString text = wellLogPlot->asciiDataForPlotExport();
RicShowPlotDataFeature::showTextWindow(title, text);
}

View File

@@ -18,6 +18,8 @@
#include "RimFlowCharacteristicsPlot.h"
#include "RifEclipseDataTableFormatter.h"
#include "RigActiveCellInfo.h"
#include "RigEclipseCaseData.h"
#include "RigFlowDiagResults.h"
@@ -555,19 +557,22 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
if (m_flowDiagSolution && m_flowCharPlotWidget)
{
RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults();
std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
RigFlowDiagResults* flowResult = m_flowDiagSolution->flowDiagResults();
if (m_timeStepSelectionType == SELECTED)
{
for (int tsIdx : m_selectedTimeSteps())
{
m_flowDiagSolution()->flowDiagResults()->maxAbsPairFlux(tsIdx);
}
calculatedTimesteps = m_selectedTimeSteps();
}
std::vector<int> calculatedTimesteps = flowResult->calculatedTimeSteps(RigFlowDiagResultAddress::PHASE_ALL);
m_currentlyPlottedTimeSteps = calculatedTimesteps;
if (m_timeStepSelectionType == SELECTED)
{
for (int tsIdx : m_selectedTimeSteps())
{
m_flowDiagSolution()->flowDiagResults()->maxAbsPairFlux(tsIdx);
}
calculatedTimesteps = m_selectedTimeSteps();
}
m_currentlyPlottedTimeSteps = calculatedTimesteps;
}
std::vector<QDateTime> timeStepDates = m_case->timeStepDates();
QStringList timeStepStrings = m_case->timeStepStrings();
@@ -586,7 +591,7 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
std::map<int, RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame> timeStepToFlowResultMap;
for (int timeStepIdx : calculatedTimesteps)
for (int timeStepIdx : m_currentlyPlottedTimeSteps)
{
if (m_cellFilter() == RigFlowDiagResults::CELLS_VISIBLE)
{
@@ -622,9 +627,11 @@ void RimFlowCharacteristicsPlot::onLoadDataAndUpdate()
lorenzVals[timeStepIdx] = timeStepToFlowResultMap[timeStepIdx].m_lorenzCoefficient;
}
m_timeStepToFlowResultMap = timeStepToFlowResultMap;
m_flowCharPlotWidget->setLorenzCurve(timeStepStrings, timeStepDates, lorenzVals);
for (int timeStepIdx : calculatedTimesteps)
for (int timeStepIdx : m_currentlyPlottedTimeSteps)
{
const auto& flowCharResults = timeStepToFlowResultMap[timeStepIdx];
@@ -652,6 +659,120 @@ void RimFlowCharacteristicsPlot::viewGeometryUpdated()
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double interpolate(std::vector<double>& xData, std::vector<double>& yData, double x, bool extrapolate)
{
size_t itemCount = xData.size();
size_t index = 0;
if (x >= xData[itemCount - 2])
{
index = itemCount - 2;
}
else
{
while (x > xData[index + 1])
index++;
}
double xLeft = xData[index];
double yLeft = yData[index];
double xRight = xData[index + 1];
double yRight = yData[index + 1];
if (!extrapolate)
{
if (x < xLeft) yRight = yLeft;
if (x > xRight) yLeft = yRight;
}
double dydx = (yRight - yLeft) / (xRight - xLeft);
return yLeft + dydx * (x - xLeft);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
QString RimFlowCharacteristicsPlot::curveDataAsText() const
{
QString tableText;
QTextStream stream(&tableText);
RifEclipseDataTableFormatter formatter(stream);
std::vector<RifEclipseOutputTableColumn> header = {
RifEclipseOutputTableColumn("Date"),
RifEclipseOutputTableColumn("Storage Capacity"),
RifEclipseOutputTableColumn("Flow Capacity"),
RifEclipseOutputTableColumn("Sweep Efficiency"),
RifEclipseOutputTableColumn("Dimensionless Time"),
RifEclipseOutputTableColumn("Lorentz Coefficient"),
};
formatter.header(header);
std::vector<QDateTime> timeStepDates = m_case->timeStepDates();
std::vector<double> storageCapacitySamplingValues = {0.08, 0.1, 0.2, 0.3, 0.4};
size_t sampleCount = storageCapacitySamplingValues.size();
for (const auto& timeIndex : m_currentlyPlottedTimeSteps)
{
QString dateString = timeStepDates[timeIndex].toString("yyyy-MM-DD");
auto a = m_timeStepToFlowResultMap.find(timeIndex);
if (a != m_timeStepToFlowResultMap.end())
{
auto storageCapacityValues = a->second.m_storageCapFlowCapCurve.first;
auto flowCapacityValues = a->second.m_storageCapFlowCapCurve.second;
bool extrapolate = false;
std::vector<double> flowCapacitySamplingValues;
for (const auto storageCapacity : storageCapacitySamplingValues)
{
{
double flowCapacity = interpolate(storageCapacityValues, flowCapacityValues, storageCapacity, extrapolate);
flowCapacitySamplingValues.push_back(flowCapacity);
}
}
auto dimensionLessTimeValues = a->second.m_dimensionlessTimeSweepEfficiencyCurve.first;
auto sweepEffValues = a->second.m_dimensionlessTimeSweepEfficiencyCurve.second;
std::vector<double> dimensionLessTimeSamplingValues;
std::vector<double> sweepEffSamplingValues;
double range = dimensionLessTimeValues.back() - dimensionLessTimeValues[0];
double step = range / sampleCount;
for (size_t i = 0; i < sampleCount; i++)
{
double dimensionLessTimeValue = i * step;
dimensionLessTimeSamplingValues.push_back(dimensionLessTimeValue);
double sweepEffValue = interpolate(dimensionLessTimeValues, sweepEffValues, dimensionLessTimeValue, extrapolate);
sweepEffSamplingValues.push_back(sweepEffValue);
}
auto lorentz = a->second.m_lorenzCoefficient;
for (size_t i = 0; i < sampleCount; i++)
{
formatter.add(dateString);
formatter.add(storageCapacitySamplingValues[i]);
formatter.add(flowCapacitySamplingValues[i]);
formatter.add(sweepEffSamplingValues[i]);
formatter.add(dimensionLessTimeSamplingValues[i]);
formatter.add(lorentz);
formatter.rowCompleted();
}
}
}
formatter.tableCompleted();
return tableText;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -67,6 +67,8 @@ public:
void deleteViewWidget() override;
void viewGeometryUpdated();
QString curveDataAsText() const;
enum TimeSelectionType
{
ALL_AVAILABLE,
@@ -107,6 +109,7 @@ private:
caf::PdmField<int> m_maxTof;
std::vector<int> m_currentlyPlottedTimeSteps;
std::map<int, RigFlowDiagSolverInterface::FlowCharacteristicsResultFrame> m_timeStepToFlowResultMap;
QPointer<RiuFlowCharacteristicsPlot> m_flowCharPlotWidget;
};

View File

@@ -20,6 +20,7 @@
#include "RiaApplication.h"
#include "RiaColorTables.h"
#include "RiaFeatureCommandContext.h"
#include "RiaFontCache.h"
#include "RiaPreferences.h"
@@ -34,6 +35,8 @@
#include "cvfBase.h"
#include "cvfColor3.h"
#include "cafCmdFeatureMenuBuilder.h"
#include "qwt_date.h"
#include "qwt_legend.h"
#include "qwt_plot.h"
@@ -315,6 +318,32 @@ QSize RiuFlowCharacteristicsPlot::minimumSizeHint() const
return QSize(0, 100);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RiuFlowCharacteristicsPlot::contextMenuEvent(QContextMenuEvent* event)
{
if (m_plotDefinition)
{
QString curveDataAsText = m_plotDefinition->curveDataAsText();
QString dialogTitle = "Flow Characteristics";
RiaFeatureCommandContextTextHelper helper(dialogTitle, curveDataAsText);
caf::CmdFeatureMenuBuilder menuBuilder;
menuBuilder << "RicShowPlotDataFeature";
QMenu menu;
menuBuilder.appendToMenu(&menu);
if (menu.actions().size() > 0)
{
menu.exec(event->globalPos());
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@@ -68,6 +68,7 @@ public:
protected:
QSize sizeHint() const override;
QSize minimumSizeHint() const override;
void contextMenuEvent(QContextMenuEvent* event) override;
private:
void setDefaults();