#4580 Import Eclipse RFT data as part of ensemble import

This commit is contained in:
Gaute Lindkvist
2019-07-25 07:38:46 +02:00
parent 222f230687
commit 71da659506
77 changed files with 2960 additions and 848 deletions

View File

@@ -34,6 +34,7 @@ namespace caf
addItem(RifDataSourceForRftPlt::SourceType::RFT, "RFT", "RFT Cases");
addItem(RifDataSourceForRftPlt::SourceType::GRID, "GRID", "Grid Cases");
addItem(RifDataSourceForRftPlt::SourceType::OBSERVED, "OBSERVED", "Observed Data");
addItem(RifDataSourceForRftPlt::SourceType::ENSEMBLE_RFT, "ENSEMBLE", "Ensembles with RFT Data");
setDefault(RifDataSourceForRftPlt::SourceType::NONE);
}
}

View File

@@ -32,6 +32,8 @@
#include "RimEclipseResultCase.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimSummaryCase.h"
#include "RimSummaryCaseCollection.h"
#include "RimWellLogExtractionCurve.h"
#include "RimWellLogFile.h"
#include "RimWellLogFileChannel.h"
@@ -406,6 +408,48 @@ std::vector<RimEclipseResultCase*> RimWellPlotTools::rftCasesForWell(const QStri
return cases;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsemblesForWell(const QString& simWellName)
{
const RimProject* project = RiaApplication::instance()->project();
std::vector<RimSummaryCaseCollection*> allSummaryCaseCollections = project->summaryGroups();
std::vector<RimSummaryCaseCollection*> rftEnsembles;
for (RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections)
{
if (summaryCaseColl && summaryCaseColl->isEnsemble() && !summaryCaseColl->rftTimeStepsForWell(simWellName).empty())
{
rftEnsembles.push_back(summaryCaseColl);
}
}
return rftEnsembles;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
std::vector<RimSummaryCaseCollection*> RimWellPlotTools::rftEnsembles()
{
const RimProject* project = RiaApplication::instance()->project();
std::vector<RimSummaryCaseCollection*> allSummaryCaseCollections = project->summaryGroups();
std::vector<RimSummaryCaseCollection*> rftEnsembles;
for (RimSummaryCaseCollection* summaryCaseColl : allSummaryCaseCollections)
{
if (summaryCaseColl && summaryCaseColl->isEnsemble() && !summaryCaseColl->wellsWithRftData().empty())
{
rftEnsembles.push_back(summaryCaseColl);
}
}
return rftEnsembles;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -495,12 +539,28 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve(const RimWellLogCur
if (rftCurve != nullptr)
{
RimEclipseResultCase* rftCase = dynamic_cast<RimEclipseResultCase*>(rftCurve->eclipseResultCase());
RimEclipseResultCase* rftCase = dynamic_cast<RimEclipseResultCase*>(rftCurve->eclipseResultCase());
RimSummaryCase* rftSummaryCase = rftCurve->summaryCase();
RimSummaryCaseCollection* rftEnsemble = rftCurve->ensemble();
const RifEclipseRftAddress rftAddress = rftCurve->rftAddress();
const QString& wellName = rftAddress.wellName();
const QDateTime& timeStep = rftAddress.timeStep();
if (rftCase != nullptr)
{
const RifEclipseRftAddress rftAddress = rftCurve->rftAddress();
const QDateTime timeStep = rftAddress.timeStep();
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(RifDataSourceForRftPlt::RFT, rftCase), timeStep);
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(RifDataSourceForRftPlt::RFT, rftCase), wellName, timeStep);
}
else if (rftSummaryCase != nullptr)
{
rftSummaryCase->firstAncestorOrThisOfTypeAsserted(rftEnsemble);
return RiaRftPltCurveDefinition(
RifDataSourceForRftPlt(RifDataSourceForRftPlt::SUMMARY_RFT, rftSummaryCase, rftEnsemble), wellName, timeStep);
}
else if (rftEnsemble != nullptr)
{
return RiaRftPltCurveDefinition(
RifDataSourceForRftPlt(RifDataSourceForRftPlt::ENSEMBLE_RFT, rftEnsemble), wellName, timeStep);
}
}
else if (gridCurve != nullptr)
@@ -515,6 +575,7 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve(const RimWellLogCur
if (timeStepIndex < timeStepsMap.size())
{
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(RifDataSourceForRftPlt::GRID, gridCase),
gridCurve->wellName(),
timeStepsVector[timeStepIndex].first);
}
}
@@ -529,11 +590,12 @@ RiaRftPltCurveDefinition RimWellPlotTools::curveDefFromCurve(const RimWellLogCur
if (date.isValid())
{
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(RifDataSourceForRftPlt::OBSERVED, wellLogFile), date);
return RiaRftPltCurveDefinition(
RifDataSourceForRftPlt(RifDataSourceForRftPlt::OBSERVED, wellLogFile), wellLogFile->wellName(), date);
}
}
}
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(), QDateTime());
return RiaRftPltCurveDefinition(RifDataSourceForRftPlt(), QString(), QDateTime());
}
//--------------------------------------------------------------------------------------------------
@@ -591,14 +653,14 @@ std::set<RiaRftPltCurveDefinition>
for (const RifDataSourceForRftPlt& addr : selectedSourcesExpanded)
{
if (addr.rftReader())
if (addr.sourceType() == RifDataSourceForRftPlt::RFT && addr.rftReader())
{
std::set<QDateTime> rftTimes = addr.rftReader()->availableTimeSteps(simWellName, interestingRFTResults);
for (const QDateTime& time : rftTimes)
{
if (selectedTimeStepSet.count(time))
{
curveDefs.insert(RiaRftPltCurveDefinition(addr, time));
curveDefs.insert(RiaRftPltCurveDefinition(addr, simWellName, time));
}
}
}
@@ -611,7 +673,7 @@ std::set<RiaRftPltCurveDefinition>
{
if (selectedTimeStepSet.count(time))
{
curveDefs.insert(RiaRftPltCurveDefinition(addr, time));
curveDefs.insert(RiaRftPltCurveDefinition(addr, simWellName, time));
}
}
}
@@ -621,7 +683,37 @@ std::set<RiaRftPltCurveDefinition>
{
if (selectedTimeStepSet.count(addr.wellLogFile()->date()))
{
curveDefs.insert(RiaRftPltCurveDefinition(addr, addr.wellLogFile()->date()));
curveDefs.insert(RiaRftPltCurveDefinition(addr, simWellName, addr.wellLogFile()->date()));
}
}
}
else if (addr.sourceType() == RifDataSourceForRftPlt::ENSEMBLE_RFT)
{
if (addr.ensemble())
{
for (RimSummaryCase* summaryCase : addr.ensemble()->allSummaryCases())
{
if (summaryCase && summaryCase->rftReader())
{
RifDataSourceForRftPlt summaryAddr(RifDataSourceForRftPlt::SUMMARY_RFT, summaryCase, addr.ensemble());
std::set<QDateTime> timeSteps = summaryCase->rftReader()->availableTimeSteps(simWellName);
for (const QDateTime& time : timeSteps)
{
if (selectedTimeStepSet.count(time))
{
curveDefs.insert(RiaRftPltCurveDefinition(summaryAddr, simWellName, time));
}
}
}
}
std::set<QDateTime> statTimeSteps = addr.ensemble()->rftTimeStepsForWell(simWellName);
for (const QDateTime& time : statTimeSteps)
{
if (selectedTimeStepSet.count(time))
{
curveDefs.insert(RiaRftPltCurveDefinition(addr, simWellName, time));
}
}
}
}
@@ -780,9 +872,11 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
{
bool addFirstTimestep = (interestingRFTResults.count(RifEclipseRftAddress::PRESSURE) == 1);
bool hasObservedData = false;
bool hasRftData = false;
bool hasGridData = false;
bool hasObservedData = false;
bool hasRftData = false;
bool hasGridData = false;
bool hasEnsembleData = false;
bool hasSummaryRftData = false;
for (const auto& source : selSources)
{
@@ -797,12 +891,20 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
case RifDataSourceForRftPlt::OBSERVED:
hasObservedData = true;
break;
case RifDataSourceForRftPlt::SUMMARY_RFT:
hasSummaryRftData = true;
break;
case RifDataSourceForRftPlt::ENSEMBLE_RFT:
hasEnsembleData = true;
break;
}
}
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> observedTimeStepsWithSources;
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> rftTimeStepsWithSources;
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> gridTimestepsWithSources;
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> summaryRftTimeStepsWithSources;
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> ensembleTimeStepsWithSources;
if (hasObservedData)
{
@@ -848,6 +950,39 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
}
}
if (hasSummaryRftData)
{
for (const auto& source : selSources)
{
if (source.sourceType() == RifDataSourceForRftPlt::SUMMARY_RFT && source.summaryCase())
{
std::set<QDateTime> wellTimeSteps =
source.summaryCase()->rftReader()->availableTimeSteps(wellPathNameOrSimWellName);
for (const QDateTime& date : wellTimeSteps)
{
summaryRftTimeStepsWithSources[date].insert(source);
}
}
}
}
if (hasEnsembleData)
{
for (const auto& source : selSources)
{
if (source.sourceType() == RifDataSourceForRftPlt::ENSEMBLE_RFT && source.ensemble())
{
std::set<QDateTime> wellTimeSteps = source.ensemble()->rftTimeStepsForWell(wellPathNameOrSimWellName);
for (const QDateTime& date : wellTimeSteps)
{
ensembleTimeStepsWithSources[date].insert(source);
}
}
}
}
// If we have a time baseline add the equal or adjacent grid timesteps
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> timestepsToShowWithSources;
@@ -861,6 +996,14 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
{
timeBaseline = &rftTimeStepsWithSources;
}
else if (hasSummaryRftData)
{
timeBaseline = &summaryRftTimeStepsWithSources;
}
else if (hasEnsembleData)
{
timeBaseline = &ensembleTimeStepsWithSources;
}
if (timeBaseline)
{
@@ -876,9 +1019,21 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
for (const auto& dateSourceSetPair : gridTimestepsWithSources)
gridTimeSteps.insert(dateSourceSetPair.first);
std::set<QDateTime> summaryRftTimeSteps;
for (const auto& dateSourceSetPair : summaryRftTimeStepsWithSources)
summaryRftTimeSteps.insert(dateSourceSetPair.first);
std::set<QDateTime> ensembleRftTimeSteps;
for (const auto& dateSourceSetPair : ensembleTimeStepsWithSources)
ensembleRftTimeSteps.insert(dateSourceSetPair.first);
std::set<QDateTime> filteredRftTimeSteps = RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, rftTimeSteps);
std::set<QDateTime> filteredGridTimeSteps =
RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, gridTimeSteps);
std::set<QDateTime> filteredSummaryRftTimeSteps =
RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, summaryRftTimeSteps);
std::set<QDateTime> filteredEnsembleRftTimeSteps =
RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, ensembleRftTimeSteps);
if (addFirstTimestep && gridTimeSteps.size())
{
@@ -889,6 +1044,7 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
timestepsToShowWithSources = observedTimeStepsWithSources;
std::set<QDateTime>& allFilteredTimesteps = filteredRftTimeSteps;
allFilteredTimesteps.insert(filteredEnsembleRftTimeSteps.begin(), filteredEnsembleRftTimeSteps.end());
allFilteredTimesteps.insert(filteredGridTimeSteps.begin(), filteredGridTimeSteps.end());
for (const QDateTime& time : allFilteredTimesteps)
@@ -900,11 +1056,25 @@ std::map<QDateTime, std::set<RifDataSourceForRftPlt>> RimWellPlotTools::calculat
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
}
auto gridTimeSourceSetIt = gridTimestepsWithSources.find(time);
auto gridTimeSourceSetIt = gridTimestepsWithSources.find(time);
if (gridTimeSourceSetIt != gridTimestepsWithSources.end())
{
std::set<RifDataSourceForRftPlt>& sourceSet = gridTimeSourceSetIt->second;
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
}
auto summaryRftTimeSourceSetIt = summaryRftTimeStepsWithSources.find(time);
if (summaryRftTimeSourceSetIt != summaryRftTimeStepsWithSources.end())
{
std::set<RifDataSourceForRftPlt>& sourceSet = summaryRftTimeSourceSetIt->second;
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
}
auto ensembleRftTimeSourceSetIt = ensembleTimeStepsWithSources.find(time);
if (ensembleRftTimeSourceSetIt != ensembleTimeStepsWithSources.end())
{
std::set<RifDataSourceForRftPlt>& sourceSet = ensembleRftTimeSourceSetIt->second;
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
}
}
}
@@ -943,9 +1113,10 @@ void RimWellPlotTools::calculateValueOptionsForTimeSteps(
{
QString optionText = RiaQDateTimeTools::toStringUsingApplicationLocale(timeStepPair.first, dateFormatString);
bool hasObs = false;
bool hasRft = false;
bool hasGrid = false;
bool hasObs = false;
bool hasRft = false;
bool hasGrid = false;
bool hasEnsemble = false;
for (const auto& source : timeStepPair.second)
{
@@ -960,15 +1131,19 @@ void RimWellPlotTools::calculateValueOptionsForTimeSteps(
case RifDataSourceForRftPlt::GRID:
hasGrid = true;
break;
case RifDataSourceForRftPlt::ENSEMBLE_RFT:
hasEnsemble = true;
break;
}
}
optionText += " \t[ ";
if (hasObs) optionText += "O ";
if (hasRft) optionText += "R ";
if (hasGrid) optionText += "G";
optionText += " ]";
QStringList optionTags;
if (hasObs) optionTags << "O";
if (hasRft) optionTags << "R";
if (hasGrid) optionTags << "G";
if (hasEnsemble) optionTags << "E";
optionText += QString(" \t[%1]").arg(optionTags.join(", "));
options.push_back(caf::PdmOptionItemInfo(optionText, timeStepPair.first));
}
}

View File

@@ -33,6 +33,7 @@
class RimEclipseCase;
class RimEclipseResultCase;
class RimSummaryCaseCollection;
class RimWellLogCurve;
class RimWellLogFileChannel;
class RimWellLogPlot;
@@ -82,6 +83,8 @@ public:
// Both
static std::vector<RimEclipseResultCase*> gridCasesForWell(const QString& simWellName);
static std::vector<RimEclipseResultCase*> rftCasesForWell(const QString& simWellName);
static std::vector<RimSummaryCaseCollection*> rftEnsemblesForWell(const QString& simWellName);
static std::vector<RimSummaryCaseCollection*> rftEnsembles();
static QString simWellName(const QString& wellPathNameOrSimWellName);
static std::map<QDateTime, std::set<RifDataSourceForRftPlt>>

View File

@@ -19,6 +19,7 @@
#include "RimWellRftPlot.h"
#include "RiaApplication.h"
#include "RiaColorTools.h"
#include "RiaColorTables.h"
#include "RiaDateStringParser.h"
#include "RiaSimWellBranchTools.h"
@@ -36,6 +37,7 @@
#include "RimEclipseResultDefinition.h"
#include "RimOilField.h"
#include "RimProject.h"
#include "RimSummaryCaseCollection.h"
#include "RimTools.h"
#include "RimWellLogExtractionCurve.h"
#include "RimWellLogFile.h"
@@ -49,6 +51,7 @@
#include "RimWellPlotTools.h"
#include "RimWellPltPlot.h"
#include "RiuWellLogTrack.h"
#include "RiuWellRftPlot.h"
#include "cafPdmUiTreeOrdering.h"
@@ -76,6 +79,8 @@ RimWellRftPlot::RimWellRftPlot()
m_userName.uiCapability()->setUiReadOnly(true);
CAF_PDM_InitField(&m_showPlotTitle, "ShowPlotTitle", true, "Show Plot Title", "", "", "");
CAF_PDM_InitField(&m_showStatisticsCurves, "ShowStatisticsCurves", true, "Show Statistics Curves", "", "", "");
CAF_PDM_InitField(&m_showEnsembleCurves, "ShowEnsembleCurves", true, "Show Ensemble Curves", "", "", "");
CAF_PDM_InitFieldNoDefault(&m_wellLogPlot, "WellLog", "Well Log", "", "", "");
m_wellLogPlot.uiCapability()->setUiHidden(true);
@@ -135,94 +140,39 @@ void RimWellRftPlot::deleteViewWidget()
//--------------------------------------------------------------------------------------------------
void RimWellRftPlot::applyCurveAppearance(RimWellLogCurve* newCurve)
{
const RiaRftPltCurveDefinition& newCurveDef = RimWellPlotTools::curveDefFromCurve(newCurve);
RiaRftPltCurveDefinition newCurveDef = RimWellPlotTools::curveDefFromCurve(newCurve);
std::vector<cvf::Color3f> colorTable;
RiaColorTables::summaryCurveDefaultPaletteColors().color3fArray().toStdVector(&colorTable);
RiuQwtPlotCurve::LineStyleEnum currentLineStyle = RiuQwtPlotCurve::STYLE_SOLID;
std::vector<RiuQwtSymbol::PointSymbolEnum> symbolTable = {RiuQwtSymbol::SYMBOL_ELLIPSE,
RiuQwtSymbol::SYMBOL_RECT,
RiuQwtSymbol::SYMBOL_DIAMOND,
RiuQwtSymbol::SYMBOL_TRIANGLE,
RiuQwtSymbol::SYMBOL_CROSS,
RiuQwtSymbol::SYMBOL_XCROSS};
// State variables
static size_t defaultColorTableIndex = 0;
static size_t defaultSymbolTableIndex = 0;
cvf::Color3f currentColor;
RiuQwtSymbol::PointSymbolEnum currentSymbol = symbolTable.front();
RiuQwtPlotCurve::LineStyleEnum currentLineStyle = RiuQwtPlotCurve::STYLE_SOLID;
bool isCurrentColorSet = false;
bool isCurrentSymbolSet = false;
std::set<cvf::Color3f> assignedColors;
std::set<RiuQwtSymbol::PointSymbolEnum> assignedSymbols;
// Used colors and symbols
for (RimWellLogCurve* const curve : m_wellLogPlot->trackByIndex(0)->curvesVector())
{
if (curve == newCurve) continue;
RiaRftPltCurveDefinition cDef = RimWellPlotTools::curveDefFromCurve(curve);
if (cDef.address() == newCurveDef.address())
{
currentColor = curve->color();
isCurrentColorSet = true;
}
if (cDef.timeStep() == newCurveDef.timeStep())
{
currentSymbol = curve->symbol();
isCurrentSymbolSet = true;
}
assignedColors.insert(curve->color());
assignedSymbols.insert(curve->symbol());
}
// Assign color
if (!isCurrentColorSet)
{
for (const auto& color : colorTable)
{
if (assignedColors.count(color) == 0)
{
currentColor = color;
isCurrentColorSet = true;
break;
}
}
if (!isCurrentColorSet)
{
currentColor = colorTable[defaultColorTableIndex];
if (++defaultColorTableIndex == colorTable.size()) defaultColorTableIndex = 0;
}
}
// Assign symbol
if (!isCurrentSymbolSet)
{
for (const auto& symbol : symbolTable)
{
if (assignedSymbols.count(symbol) == 0)
{
currentSymbol = symbol;
isCurrentSymbolSet = true;
break;
}
}
if (!isCurrentSymbolSet)
{
currentSymbol = symbolTable[defaultSymbolTableIndex];
if (++defaultSymbolTableIndex == symbolTable.size()) defaultSymbolTableIndex = 0;
}
}
cvf::Color3f currentColor;
if (newCurveDef.address().sourceType() == RifDataSourceForRftPlt::SUMMARY_RFT)
{
RifDataSourceForRftPlt sourceAddress(RifDataSourceForRftPlt::ENSEMBLE_RFT, newCurveDef.address().ensemble());
currentColor = m_dataSourceColors[sourceAddress];
if (m_showStatisticsCurves)
{
cvf::Color3f backgroundColor =
RiaColorTools::fromQColorTo3f(m_wellLogPlot->trackByIndex(0)->viewer()->canvasBackground().color());
currentColor = RiaColorTools::blendCvfColors(backgroundColor, currentColor, 2, 1);
}
}
else
{
currentColor = m_dataSourceColors[newCurveDef.address()];
}
RiuQwtSymbol::PointSymbolEnum currentSymbol = RiuQwtSymbol::SYMBOL_NONE;
if (newCurveDef.address().sourceType() != RifDataSourceForRftPlt::ENSEMBLE_RFT)
{
currentSymbol = m_timeStepSymbols[newCurveDef.timeStep()];
}
// Observed data
currentLineStyle = newCurveDef.address().sourceType() == RifDataSourceForRftPlt::OBSERVED ? RiuQwtPlotCurve::STYLE_NONE
: RiuQwtPlotCurve::STYLE_SOLID;
newCurve->setColor(currentColor);
newCurve->setSymbolEdgeColor(currentColor);
newCurve->setSymbol(currentSymbol);
newCurve->setLineStyle(currentLineStyle);
}
@@ -289,6 +239,11 @@ void RimWellRftPlot::applyInitialSelections()
sourcesToSelect.push_back(RifDataSourceForRftPlt(RifDataSourceForRftPlt::GRID, gridCase));
}
for (RimSummaryCaseCollection* const ensemble : RimWellPlotTools::rftEnsemblesForWell(simWellName))
{
sourcesToSelect.push_back(RifDataSourceForRftPlt(RifDataSourceForRftPlt::ENSEMBLE_RFT, ensemble));
}
std::vector<RimWellLogFile*> wellLogFiles = RimWellPlotTools::wellLogFilesContainingPressure(m_wellPathNameOrSimWellName);
if (!wellLogFiles.empty())
{
@@ -447,6 +402,8 @@ void RimWellRftPlot::updateCurvesInPlot(const std::set<RiaRftPltCurveDefinition>
// Delete curves
plotTrack->deleteAllCurves();
defineCurveColorsAndSymbols(allCurveDefs);
// Add new curves
for (const RiaRftPltCurveDefinition& curveDefToAdd : allCurveDefs)
{
@@ -465,6 +422,47 @@ void RimWellRftPlot::updateCurvesInPlot(const std::set<RiaRftPltCurveDefinition>
applyCurveAppearance(curve);
}
else if (m_showEnsembleCurves && curveDefToAdd.address().sourceType() == RifDataSourceForRftPlt::SUMMARY_RFT)
{
auto curve = new RimWellLogRftCurve();
plotTrack->addCurve(curve);
auto rftCase = curveDefToAdd.address().summaryCase();
curve->setSummaryCase(rftCase);
RifEclipseRftAddress address(simWellName, curveDefToAdd.timeStep(), RifEclipseRftAddress::PRESSURE);
curve->setRftAddress(address);
curve->setZOrder(1);
applyCurveAppearance(curve);
}
else if (m_showStatisticsCurves && curveDefToAdd.address().sourceType() == RifDataSourceForRftPlt::ENSEMBLE_RFT)
{
RimSummaryCaseCollection* ensemble = curveDefToAdd.address().ensemble();
std::set<RifEclipseRftAddress> rftAddresses =
ensemble->rftStatisticsReader()->eclipseRftAddresses(simWellName, curveDefToAdd.timeStep());
for (auto rftAddress : rftAddresses)
{
if (rftAddress.wellLogChannel() != RifEclipseRftAddress::TVD)
{
auto curve = new RimWellLogRftCurve();
plotTrack->addCurve(curve);
curve->setEnsemble(ensemble);
curve->setRftAddress(rftAddress);
curve->setZOrder(RiuQwtPlotCurve::Z_ENSEMBLE_STAT_CURVE);
applyCurveAppearance(curve);
auto symbol = statisticsCurveSymbolFromAddress(rftAddress);
RiuQwtSymbol::LabelPosition labelPos = statisticsLabelPosFromAddress(rftAddress);
curve->setSymbol(symbol);
curve->setSymbolLabelPosition(labelPos);
curve->setSymbolSize(curve->symbolSize() + 3);
curve->setSymbolSkipDistance(150);
curve->setLineStyle(RiuQwtPlotCurve::STYLE_SOLID);
QString uiText =
caf::AppEnum<RifEclipseRftAddress::RftWellLogChannelType>::uiText(rftAddress.wellLogChannel());
QString label = uiText.replace("Pressure", "");
curve->setSymbolLabel(label);
}
}
}
else if (curveDefToAdd.address().sourceType() == RifDataSourceForRftPlt::GRID)
{
auto curve = new RimWellLogExtractionCurve();
@@ -580,6 +578,14 @@ RimWellLogPlot* RimWellRftPlot::wellLogPlot() const
return m_wellLogPlot();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const QString& RimWellRftPlot::simWellOrWellPathName() const
{
return m_wellPathNameOrSimWellName.v();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@@ -639,6 +645,21 @@ QList<caf::PdmOptionItemInfo> RimWellRftPlot::calculateValueOptions(const caf::P
}
}
const std::vector<RimSummaryCaseCollection*> rftEnsembles = RimWellPlotTools::rftEnsemblesForWell(simWellName);
if (!rftEnsembles.empty())
{
options.push_back(caf::PdmOptionItemInfo::createHeader(
RifDataSourceForRftPlt::sourceTypeUiText(RifDataSourceForRftPlt::ENSEMBLE_RFT), true));
for (RimSummaryCaseCollection* rftEnsemble : rftEnsembles)
{
auto addr = RifDataSourceForRftPlt(RifDataSourceForRftPlt::ENSEMBLE_RFT, rftEnsemble);
auto item = caf::PdmOptionItemInfo(rftEnsemble->name(), QVariant::fromValue(addr));
item.setLevel(1);
options.push_back(item);
}
}
const std::vector<RimEclipseResultCase*> gridCases = RimWellPlotTools::gridCasesForWell(simWellName);
if (!gridCases.empty())
{
@@ -716,7 +737,14 @@ void RimWellRftPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c
{
updateFormationsOnPlot();
syncCurvesFromUiSelection();
this->updateConnectedEditors();
}
else if (changedField == &m_showStatisticsCurves || changedField == &m_showEnsembleCurves)
{
updateFormationsOnPlot();
syncCurvesFromUiSelection();
}
else if (changedField == &m_showPlotTitle)
{
// m_wellLogPlot->setShowDescription(m_showPlotTitle);
@@ -754,6 +782,20 @@ void RimWellRftPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering&
{
uiOrdering.add(&m_userName);
uiOrdering.add(&m_wellPathNameOrSimWellName);
uiOrdering.add(&m_showStatisticsCurves);
uiOrdering.add(&m_showEnsembleCurves);
bool showingEnsembleData = false;
for (const RifDataSourceForRftPlt& dataSource : m_selectedSources())
{
if (dataSource.sourceType() == RifDataSourceForRftPlt::ENSEMBLE_RFT)
{
showingEnsembleData = true;
break;
}
}
m_showStatisticsCurves.uiCapability()->setUiReadOnly(!showingEnsembleData);
m_showEnsembleCurves.uiCapability()->setUiReadOnly(!showingEnsembleData);
RiaSimWellBranchTools::appendSimWellBranchFieldsIfRequiredFromWellName(
&uiOrdering, m_wellPathNameOrSimWellName, m_branchDetection, m_branchIndex);
@@ -818,6 +860,20 @@ void RimWellRftPlot::calculateValueOptionsForWells(QList<caf::PdmOptionItemInfo>
}
}
// Ensemble RFT wells
const std::vector<RimSummaryCaseCollection*> rftEnsembles = RimWellPlotTools::rftEnsembles();
if (!rftEnsembles.empty())
{
for (RimSummaryCaseCollection* summaryCaseColl : rftEnsembles)
{
std::set<QString> wellsWithRftData = summaryCaseColl->wellsWithRftData();
for (QString wellName : wellsWithRftData)
{
wellNames.insert(std::make_pair(wellName, wellName));
}
}
}
for (const auto& wellName : wellNames)
{
options.push_back(caf::PdmOptionItemInfo(wellName.first, wellName.second));
@@ -870,6 +926,8 @@ void RimWellRftPlot::onLoadDataAndUpdate()
updateEditorsFromCurves();
updateWidgetTitleWindowTitle();
// applyInitialSelections();
}
//--------------------------------------------------------------------------------------------------
@@ -903,3 +961,88 @@ QWidget* RimWellRftPlot::createViewWidget(QWidget* mainWindowParent)
return m_wellLogPlotWidget;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtSymbol::PointSymbolEnum RimWellRftPlot::statisticsCurveSymbolFromAddress(const RifEclipseRftAddress& address)
{
switch (address.wellLogChannel())
{
case RifEclipseRftAddress::PRESSURE_P10:
return RiuQwtSymbol::SYMBOL_TRIANGLE;
case RifEclipseRftAddress::PRESSURE_P50:
return RiuQwtSymbol::SYMBOL_DOWN_TRIANGLE;
case RifEclipseRftAddress::PRESSURE_P90:
return RiuQwtSymbol::SYMBOL_LEFT_TRIANGLE;
case RifEclipseRftAddress::PRESSURE_MEAN:
return RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE;
}
return RiuQwtSymbol::SYMBOL_RIGHT_TRIANGLE;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RiuQwtSymbol::LabelPosition RimWellRftPlot::statisticsLabelPosFromAddress(const RifEclipseRftAddress& address)
{
switch (address.wellLogChannel())
{
case RifEclipseRftAddress::PRESSURE_P10:
return RiuQwtSymbol::LabelLeftOfSymbol;
case RifEclipseRftAddress::PRESSURE_P50:
return RiuQwtSymbol::LabelAboveSymbol;
case RifEclipseRftAddress::PRESSURE_P90:
return RiuQwtSymbol::LabelRightOfSymbol;
case RifEclipseRftAddress::PRESSURE_MEAN:
return RiuQwtSymbol::LabelBelowSymbol;
}
return RiuQwtSymbol::LabelAboveSymbol;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RimWellRftPlot::defineCurveColorsAndSymbols(const std::set<RiaRftPltCurveDefinition>& allCurveDefs)
{
m_dataSourceColors.clear();
m_timeStepSymbols.clear();
std::vector<cvf::Color3f> colorTable;
RiaColorTables::summaryCurveDefaultPaletteColors().color3fArray().toStdVector(&colorTable);
std::vector<RiuQwtSymbol::PointSymbolEnum> symbolTable = {RiuQwtSymbol::SYMBOL_ELLIPSE,
RiuQwtSymbol::SYMBOL_RECT,
RiuQwtSymbol::SYMBOL_DIAMOND,
RiuQwtSymbol::SYMBOL_CROSS,
RiuQwtSymbol::SYMBOL_XCROSS,
RiuQwtSymbol::SYMBOL_STAR1};
// Add new curves
for (const RiaRftPltCurveDefinition& curveDefToAdd : allCurveDefs)
{
auto colorTableIndex = m_dataSourceColors.size();
auto symbolTableIndex = m_timeStepSymbols.size();
RifDataSourceForRftPlt address = curveDefToAdd.address();
if (address.sourceType() != RifDataSourceForRftPlt::SUMMARY_RFT)
{
if (!m_dataSourceColors.count(curveDefToAdd.address()))
{
colorTableIndex = colorTableIndex % colorTable.size();
m_dataSourceColors[curveDefToAdd.address()] = colorTable[colorTableIndex];
}
}
if (address.sourceType() != RifDataSourceForRftPlt::ENSEMBLE_RFT)
{
if (!m_timeStepSymbols.count(curveDefToAdd.timeStep()))
{
symbolTableIndex = symbolTableIndex % symbolTable.size();
m_timeStepSymbols[curveDefToAdd.timeStep()] = symbolTable[symbolTableIndex];
}
}
}
}

View File

@@ -1,27 +1,27 @@
/////////////////////////////////////////////////////////////////////////////////
//
// 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 <http://www.gnu.org/licenses/gpl.html>
//
// See the GNU General Public License at <http://www.gnu.org/licenses/gpl.html>
// for more details.
//
/////////////////////////////////////////////////////////////////////////////////
#pragma once
#include "RimViewWindow.h"
#include "RifDataSourceForRftPltQMetaType.h"
#include "RiuQwtSymbol.h"
#include "cafPdmField.h"
#include "cafPdmObject.h"
@@ -46,102 +46,118 @@ class RiuWellRftPlot;
class RigEclipseCaseData;
class RiaRftPltCurveDefinition;
class RifDataSourceForRftPlt;
class RifEclipseRftAddress;
namespace cvf {
class Color3f;
namespace cvf
{
class Color3f;
}
namespace caf {
class PdmOptionItemInfo;
namespace caf
{
class PdmOptionItemInfo;
}
//==================================================================================================
///
///
///
///
//==================================================================================================
class RimWellRftPlot : public RimViewWindow
{
CAF_PDM_HEADER_INIT;
static const std::set<QString> PRESSURE_DATA_NAMES;
static const char PLOT_NAME_QFORMAT_STRING[];
static const char PLOT_NAME_QFORMAT_STRING[];
public:
RimWellRftPlot();
~RimWellRftPlot() override;
void setDescription(const QString& description);
QString description() const;
void setDescription(const QString& description);
QString description() const;
QWidget* viewWidget() override;
void zoomAll() override;
QWidget* viewWidget() override;
void zoomAll() override;
RimWellLogPlot* wellLogPlot() const;
RimWellLogPlot* wellLogPlot() const;
void setSimWellOrWellPathName(const QString& currWellName);
const QString& simWellOrWellPathName() const;
void setSimWellOrWellPathName(const QString& currWellName);
int branchIndex() const;
int branchIndex() const;
void applyInitialSelections();
void applyInitialSelections();
static const char* plotNameFormatString();
protected:
// Overridden PDM methods
caf::PdmFieldHandle* userDescriptionField() override { return &m_userName; }
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override;
caf::PdmFieldHandle* userDescriptionField() override
{
return &m_userName;
}
void fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue) override;
void defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly) override;
QList<caf::PdmOptionItemInfo> calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions,
bool* useOptionsOnly) override;
QImage snapshotWindowContent() override;
QImage snapshotWindowContent() override;
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
void onLoadDataAndUpdate() override;
void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override;
void onLoadDataAndUpdate() override;
private:
void calculateValueOptionsForWells(QList<caf::PdmOptionItemInfo>& options);
void updateEditorsFromCurves();
void updateWidgetTitleWindowTitle();
void syncCurvesFromUiSelection();
void assignWellPathToExtractionCurves();
void calculateValueOptionsForWells(QList<caf::PdmOptionItemInfo>& options);
void updateEditorsFromCurves();
void updateWidgetTitleWindowTitle();
void syncCurvesFromUiSelection();
void assignWellPathToExtractionCurves();
std::set<RiaRftPltCurveDefinition> selectedCurveDefs() const;
std::set<RiaRftPltCurveDefinition> curveDefsFromCurves() const;
std::set<RiaRftPltCurveDefinition> selectedCurveDefs() const;
std::set<RiaRftPltCurveDefinition> curveDefsFromCurves() const;
void updateCurvesInPlot(const std::set<RiaRftPltCurveDefinition>& allCurveDefs,
const std::set<RiaRftPltCurveDefinition>& curveDefsToAdd,
const std::set<RimWellLogCurve*>& curvesToDelete);
void updateCurvesInPlot(const std::set<RiaRftPltCurveDefinition>& allCurveDefs,
const std::set<RiaRftPltCurveDefinition>& curveDefsToAdd,
const std::set<RimWellLogCurve*>& curvesToDelete);
std::vector<RifDataSourceForRftPlt> selectedSourcesExpanded() const;
// RimViewWindow overrides
QWidget* createViewWidget(QWidget* mainWindowParent) override;
void deleteViewWidget() override;
QWidget* createViewWidget(QWidget* mainWindowParent) override;
void deleteViewWidget() override;
void applyCurveAppearance(RimWellLogCurve* newCurve);
void applyCurveAppearance(RimWellLogCurve* newCurve);
void updateFormationsOnPlot() const;
QString associatedSimWellName() const;
void updateFormationsOnPlot() const;
QString associatedSimWellName() const;
static RiuQwtSymbol::PointSymbolEnum statisticsCurveSymbolFromAddress(const RifEclipseRftAddress& address);
static RiuQwtSymbol::LabelPosition statisticsLabelPosFromAddress(const RifEclipseRftAddress& address);
void defineCurveColorsAndSymbols(const std::set<RiaRftPltCurveDefinition>& allCurveDefs);
private:
caf::PdmField<bool> m_showPlotTitle;
caf::PdmField<QString> m_userName;
caf::PdmField<bool> m_showPlotTitle;
caf::PdmField<QString> m_userName;
caf::PdmField<QString> m_wellPathNameOrSimWellName;
caf::PdmField<int> m_branchIndex;
caf::PdmField<bool> m_branchDetection;
caf::PdmField<QString> m_wellPathNameOrSimWellName;
caf::PdmField<int> m_branchIndex;
caf::PdmField<bool> m_branchDetection;
caf::PdmField<bool> m_showStatisticsCurves;
caf::PdmField<bool> m_showEnsembleCurves;
caf::PdmField<std::vector<RifDataSourceForRftPlt>> m_selectedSources;
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
caf::PdmField<std::vector<RifDataSourceForRftPlt>> m_selectedSources;
caf::PdmChildField<RimWellLogPlot*> m_wellLogPlot;
caf::PdmField<std::vector<QDateTime>> m_selectedTimeSteps;
QPointer<RiuWellRftPlot> m_wellLogPlotWidget;
caf::PdmChildField<RimWellLogPlot*> m_wellLogPlot;
QPointer<RiuWellRftPlot> m_wellLogPlotWidget;
std::map<RifDataSourceForRftPlt, cvf::Color3f> m_dataSourceColors;
std::map<QDateTime, RiuQwtSymbol::PointSymbolEnum> m_timeStepSymbols;
bool m_isOnLoad;
};