2017-10-23 06:57:01 -05:00
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
//
|
|
|
|
// 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>
|
|
|
|
// for more details.
|
|
|
|
//
|
|
|
|
/////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
#include "RimWellPltPlot.h"
|
|
|
|
|
|
|
|
#include "RiaApplication.h"
|
|
|
|
#include "RiaColorTables.h"
|
|
|
|
#include "RiaDateStringParser.h"
|
2017-11-08 09:35:58 -06:00
|
|
|
#include "RiaWellNameComparer.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RifReaderEclipseRft.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
|
|
|
|
#include "RigAccWellFlowCalculator.h"
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RigCaseCellResultsData.h"
|
|
|
|
#include "RigEclipseCaseData.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
#include "RigEclipseWellLogExtractor.h"
|
|
|
|
#include "RigMainGrid.h"
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RigSimWellData.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
#include "RigWellLogExtractor.h"
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RigWellPath.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RimEclipseCase.h"
|
|
|
|
#include "RimEclipseCaseCollection.h"
|
|
|
|
#include "RimEclipseResultCase.h"
|
|
|
|
#include "RimEclipseResultDefinition.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
#include "RimMainPlotCollection.h"
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RimOilField.h"
|
|
|
|
#include "RimProject.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
#include "RimSummaryCurveAppearanceCalculator.h"
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RimTools.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
#include "RimWellFlowRateCurve.h"
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RimWellLogExtractionCurve.h"
|
|
|
|
#include "RimWellLogFile.h"
|
|
|
|
#include "RimWellLogFileChannel.h"
|
|
|
|
#include "RimWellLogFileCurve.h"
|
|
|
|
#include "RimWellLogPlot.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
#include "RimWellLogPlotCollection.h"
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RimWellLogRftCurve.h"
|
|
|
|
#include "RimWellLogTrack.h"
|
|
|
|
#include "RimWellPath.h"
|
|
|
|
#include "RimWellPathCollection.h"
|
2017-11-09 03:03:32 -06:00
|
|
|
#include "RimWellPlotTools.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "RiuWellPltPlot.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
|
|
|
|
#include "cafPdmUiTreeOrdering.h"
|
2017-10-23 06:57:01 -05:00
|
|
|
#include "cafPdmUiTreeSelectionEditor.h"
|
2017-11-13 03:21:24 -06:00
|
|
|
#include "cafVecIjk.h"
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
#include <algorithm>
|
|
|
|
#include <iterator>
|
2017-11-13 03:21:24 -06:00
|
|
|
#include <tuple>
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-08 09:35:58 -06:00
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
CAF_PDM_SOURCE_INIT(RimWellPltPlot, "WellPltPlot");
|
|
|
|
|
2017-10-25 12:44:04 -05:00
|
|
|
namespace caf
|
|
|
|
{
|
2017-10-25 07:43:17 -05:00
|
|
|
template<>
|
2017-11-09 03:03:32 -06:00
|
|
|
void caf::AppEnum< FlowType>::setUp()
|
2017-10-25 07:43:17 -05:00
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
addItem(FLOW_TYPE_TOTAL, "TOTAL", "Total Flow");
|
|
|
|
addItem(FLOW_TYPE_PHASE_SPLIT, "PHASE_SPLIT", "Phase Split");
|
2017-10-25 07:43:17 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
template<>
|
2017-11-09 03:03:32 -06:00
|
|
|
void caf::AppEnum< FlowPhase>::setUp()
|
2017-10-25 07:43:17 -05:00
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
addItem(FLOW_PHASE_OIL, "PHASE_OIL", "Oil");
|
|
|
|
addItem(FLOW_PHASE_GAS, "PHASE_GAS", "Gas");
|
|
|
|
addItem(FLOW_PHASE_WATER, "PHASE_WATER", "Water");
|
2017-10-25 07:43:17 -05:00
|
|
|
}
|
2017-10-25 12:44:04 -05:00
|
|
|
}
|
2017-10-25 07:43:17 -05:00
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-10-27 02:17:05 -05:00
|
|
|
const char RimWellPltPlot::PLOT_NAME_QFORMAT_STRING[] = "PLT: %1";
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimWellPltPlot::RimWellPltPlot()
|
|
|
|
{
|
|
|
|
CAF_PDM_InitObject("Well Allocation Plot", ":/WellAllocPlot16x16.png", "", "");
|
|
|
|
|
2017-10-27 02:17:05 -05:00
|
|
|
CAF_PDM_InitField(&m_userName, "PlotDescription", QString("PLT Plot"), "Name", "", "", "");
|
2017-10-23 06:57:01 -05:00
|
|
|
m_userName.uiCapability()->setUiReadOnly(true);
|
|
|
|
|
|
|
|
CAF_PDM_InitField(&m_showPlotTitle, "ShowPlotTitle", true, "Show Plot Title", "", "", "");
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault(&m_wellLogPlot, "WellLog", "WellLog", "", "", "");
|
|
|
|
m_wellLogPlot.uiCapability()->setUiHidden(true);
|
|
|
|
m_wellLogPlot = new RimWellLogPlot();
|
2017-10-25 07:43:17 -05:00
|
|
|
m_wellLogPlot->setDepthType(RimWellLogPlot::MEASURED_DEPTH);
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-08 09:35:58 -06:00
|
|
|
CAF_PDM_InitFieldNoDefault(&m_wellPathName, "WellName", "WellName", "", "", "");
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-10-27 02:38:24 -05:00
|
|
|
CAF_PDM_InitFieldNoDefault(&m_selectedSources, "SourcesInternal", "SourcesInternal", "", "", "");
|
2017-10-23 06:57:01 -05:00
|
|
|
m_selectedSources.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
|
|
|
|
m_selectedSources.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
|
|
|
m_selectedSources.uiCapability()->setAutoAddingOptionFromValue(false);
|
2017-10-27 02:38:24 -05:00
|
|
|
m_selectedSources.xmlCapability()->disableIO();
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault(&m_selectedSourcesForIo, "Sources", "Sources", "", "", "");
|
|
|
|
m_selectedSourcesForIo.uiCapability()->setUiHidden(true);
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault(&m_selectedTimeSteps, "TimeSteps", "TimeSteps", "", "", "");
|
|
|
|
m_selectedTimeSteps.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
|
|
|
|
m_selectedTimeSteps.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN);
|
|
|
|
m_selectedTimeSteps.uiCapability()->setAutoAddingOptionFromValue(false);
|
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
CAF_PDM_InitFieldNoDefault(&m_phaseSelectionMode, "PhaseSelectionMode", "Mode", "", "", "");
|
|
|
|
|
|
|
|
CAF_PDM_InitFieldNoDefault(&m_phases, "Phases", "Phases", "", "", "");
|
|
|
|
m_phases.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName());
|
2017-11-09 03:03:32 -06:00
|
|
|
m_phases = std::vector<caf::AppEnum<FlowPhase>>({ FLOW_PHASE_OIL, FLOW_PHASE_GAS, FLOW_PHASE_WATER });
|
2017-10-25 07:43:17 -05:00
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
this->setAsPlotMdiWindow();
|
2017-10-27 02:38:24 -05:00
|
|
|
m_doInitAfterLoad = false;
|
2017-11-13 01:56:22 -06:00
|
|
|
m_isOnLoad = true;
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimWellPltPlot::~RimWellPltPlot()
|
|
|
|
{
|
|
|
|
removeMdiWindowFromMdiArea();
|
|
|
|
|
|
|
|
deleteViewWidget();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::deleteViewWidget()
|
|
|
|
{
|
|
|
|
if (m_wellLogPlotWidget)
|
|
|
|
{
|
|
|
|
m_wellLogPlotWidget->deleteLater();
|
|
|
|
m_wellLogPlotWidget = nullptr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-10-25 07:43:17 -05:00
|
|
|
//void RimWellPltPlot::applyCurveAppearance(RimWellLogCurve* newCurve)
|
|
|
|
//{
|
2017-10-26 03:35:23 -05:00
|
|
|
// const std::pair<RifWellRftAddress, QDateTime>& newCurveDef = curveDefFromCurve(newCurve);
|
2017-10-25 07:43:17 -05:00
|
|
|
//
|
|
|
|
// std::vector<cvf::Color3f> colorTable;
|
|
|
|
// RiaColorTables::summaryCurveDefaultPaletteColors().color3fArray().toStdVector(&colorTable);
|
|
|
|
//
|
|
|
|
// std::vector<RimPlotCurve::PointSymbolEnum> symbolTable =
|
|
|
|
// {
|
|
|
|
// RimPlotCurve::SYMBOL_ELLIPSE,
|
|
|
|
// RimPlotCurve::SYMBOL_RECT,
|
|
|
|
// RimPlotCurve::SYMBOL_DIAMOND,
|
|
|
|
// RimPlotCurve::SYMBOL_TRIANGLE,
|
|
|
|
// RimPlotCurve::SYMBOL_CROSS,
|
|
|
|
// RimPlotCurve::SYMBOL_XCROSS
|
|
|
|
// };
|
|
|
|
//
|
|
|
|
// // State variables
|
|
|
|
// static size_t defaultColorTableIndex = 0;
|
|
|
|
// static size_t defaultSymbolTableIndex = 0;
|
|
|
|
//
|
|
|
|
// cvf::Color3f currentColor;
|
|
|
|
// RimPlotCurve::PointSymbolEnum currentSymbol = symbolTable.front();
|
|
|
|
// RimPlotCurve::LineStyleEnum currentLineStyle = RimPlotCurve::STYLE_SOLID;
|
|
|
|
// bool isCurrentColorSet = false;
|
|
|
|
// bool isCurrentSymbolSet = false;
|
|
|
|
//
|
|
|
|
// std::set<cvf::Color3f> assignedColors;
|
|
|
|
// std::set<RimPlotCurve::PointSymbolEnum> assignedSymbols;
|
|
|
|
//
|
|
|
|
// // Used colors and symbols
|
|
|
|
// for (RimWellLogCurve* const curve : m_wellLogPlot->trackByIndex(0)->curvesVector())
|
|
|
|
// {
|
|
|
|
// if (curve == newCurve) continue;
|
|
|
|
//
|
2017-10-26 03:35:23 -05:00
|
|
|
// std::pair<RifWellRftAddress, QDateTime> cDef = curveDefFromCurve(curve);
|
2017-10-25 07:43:17 -05:00
|
|
|
// if (cDef.first == newCurveDef.first)
|
|
|
|
// {
|
|
|
|
// currentColor = curve->color();
|
|
|
|
// isCurrentColorSet = true;
|
|
|
|
// }
|
|
|
|
// if (cDef.second == newCurveDef.second)
|
|
|
|
// {
|
|
|
|
// 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;
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// // Observed data
|
|
|
|
// currentLineStyle = newCurveDef.first.sourceType() == RftSourceType::OBSERVED
|
|
|
|
// ? RimPlotCurve::STYLE_NONE : RimPlotCurve::STYLE_SOLID;
|
|
|
|
//
|
|
|
|
// newCurve->setColor(currentColor);
|
|
|
|
// newCurve->setSymbol(currentSymbol);
|
|
|
|
// newCurve->setLineStyle(currentLineStyle);
|
|
|
|
//}
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-12 16:46:12 -06:00
|
|
|
#if 0
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::updateSelectedTimeStepsFromSelectedSources()
|
|
|
|
{
|
|
|
|
std::vector<QDateTime> newTimeStepsSelections;
|
2017-10-27 02:38:24 -05:00
|
|
|
std::vector<RifWellRftAddress> selectedSourcesVector = m_selectedSources();
|
2017-10-26 03:35:23 -05:00
|
|
|
auto selectedSources = std::set<RifWellRftAddress>(selectedSourcesVector.begin(), selectedSourcesVector.end());
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
for (const QDateTime& timeStep : m_selectedTimeSteps())
|
|
|
|
{
|
|
|
|
if(m_timeStepsToAddresses.count(timeStep) > 0)
|
|
|
|
{
|
2017-10-26 03:35:23 -05:00
|
|
|
std::vector<RifWellRftAddress> intersectVector;
|
|
|
|
const std::set<RifWellRftAddress>& addresses = m_timeStepsToAddresses[timeStep];
|
2017-10-23 06:57:01 -05:00
|
|
|
std::set_intersection(selectedSources.begin(), selectedSources.end(),
|
|
|
|
addresses.begin(), addresses.end(), std::inserter(intersectVector, intersectVector.end()));
|
|
|
|
if(intersectVector.size() > 0)
|
|
|
|
{
|
|
|
|
newTimeStepsSelections.push_back(timeStep);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
m_selectedTimeSteps = newTimeStepsSelections;
|
|
|
|
}
|
2017-11-12 16:46:12 -06:00
|
|
|
#endif
|
2017-10-25 07:43:17 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::setPlotXAxisTitles(RimWellLogTrack* plotTrack)
|
|
|
|
{
|
|
|
|
std::vector<RimEclipseCase*> cases = eclipseCases();
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
RiaEclipseUnitTools::UnitSystem unitSet = !cases.empty() ?
|
|
|
|
cases.front()->eclipseCaseData()->unitsType() :
|
|
|
|
RiaEclipseUnitTools::UNITS_UNKNOWN;
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
QString unitText;
|
|
|
|
switch (unitSet)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-25 07:43:17 -05:00
|
|
|
case RiaEclipseUnitTools::UNITS_METRIC:
|
|
|
|
unitText = "[Liquid Sm<sup>3</sup>/day], [Gas kSm<sup>3</sup>/day]";
|
|
|
|
break;
|
|
|
|
case RiaEclipseUnitTools::UNITS_FIELD:
|
|
|
|
unitText = "[Liquid BBL/day], [Gas BOE/day]";
|
|
|
|
break;
|
|
|
|
case RiaEclipseUnitTools::UNITS_LAB:
|
|
|
|
unitText = "[cm<sup>3</sup>/hr]";
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
unitText = "(unknown unit)";
|
|
|
|
break;
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
}
|
|
|
|
plotTrack->setXAxisTitle("Surface Flow Rate " + unitText);
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-10-25 07:43:17 -05:00
|
|
|
std::vector<RimEclipseCase*> RimWellPltPlot::eclipseCases() const
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-25 07:43:17 -05:00
|
|
|
std::vector<RimEclipseCase*> cases;
|
|
|
|
RimProject* proj = RiaApplication::instance()->project();
|
|
|
|
for (const auto& oilField : proj->oilFields)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-25 07:43:17 -05:00
|
|
|
for (const auto& eclCase : oilField->analysisModels()->cases)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-25 07:43:17 -05:00
|
|
|
cases.push_back(eclCase);
|
|
|
|
}
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
2017-10-25 07:43:17 -05:00
|
|
|
return cases;
|
|
|
|
}
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-06 07:40:26 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-11-07 03:38:05 -06:00
|
|
|
void RimWellPltPlot::updateFormationsOnPlot() const
|
2017-11-06 07:40:26 -06:00
|
|
|
{
|
2017-11-12 07:45:06 -06:00
|
|
|
if (m_wellLogPlot->trackCount() > 0)
|
2017-11-06 07:40:26 -06:00
|
|
|
{
|
2017-11-12 07:45:06 -06:00
|
|
|
RimProject* proj = RiaApplication::instance()->project();
|
|
|
|
RimWellPath* wellPath = proj->wellPathByName(m_wellPathName);
|
2017-11-06 07:40:26 -06:00
|
|
|
|
2017-11-12 07:45:06 -06:00
|
|
|
RimCase* formationNamesCase = m_wellLogPlot->trackByIndex(0)->formationNamesCase();
|
2017-11-06 07:40:26 -06:00
|
|
|
|
2017-11-12 07:45:06 -06:00
|
|
|
if ( !formationNamesCase )
|
|
|
|
{
|
|
|
|
/// Set default case. Todo : Use the first of the selected cases in the plot
|
|
|
|
std::vector<RimCase*> cases;
|
|
|
|
proj->allCases(cases);
|
2017-11-06 07:40:26 -06:00
|
|
|
|
2017-11-12 07:45:06 -06:00
|
|
|
if ( !cases.empty() )
|
|
|
|
{
|
|
|
|
formationNamesCase = cases[0];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
m_wellLogPlot->trackByIndex(0)->setAndUpdateWellPathFormationNamesData(formationNamesCase, wellPath);
|
2017-11-06 07:40:26 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
//void RimWellPltPlot::applyInitialSelections()
|
|
|
|
//{
|
|
|
|
// std::vector<std::tuple<RimEclipseResultCase*, bool, bool>> eclCaseTuples = eclipseCasesForWell(m_wellName);
|
|
|
|
//
|
2017-10-26 03:35:23 -05:00
|
|
|
// std::vector<RifWellRftAddress> sourcesToSelect;
|
|
|
|
// std::map<QDateTime, std::set<RifWellRftAddress>> rftTimeStepsMap;
|
|
|
|
// std::map<QDateTime, std::set<RifWellRftAddress>> observedTimeStepsMap;
|
|
|
|
// std::map<QDateTime, std::set<RifWellRftAddress>> gridTimeStepsMap;
|
2017-10-25 07:43:17 -05:00
|
|
|
//
|
|
|
|
// for(RimEclipseResultCase* const rftCase : rftCasesFromEclipseCases(eclCaseTuples))
|
|
|
|
// {
|
2017-10-26 03:35:23 -05:00
|
|
|
// sourcesToSelect.push_back(RifWellRftAddress(RftSourceType::RFT, rftCase));
|
2017-10-25 07:43:17 -05:00
|
|
|
// addTimeStepsToMap(rftTimeStepsMap, timeStepsFromRftCase(rftCase));
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// for (RimEclipseResultCase* const gridCase : gridCasesFromEclipseCases(eclCaseTuples))
|
|
|
|
// {
|
2017-10-26 03:35:23 -05:00
|
|
|
// sourcesToSelect.push_back(RifWellRftAddress(RftSourceType::GRID, gridCase));
|
2017-10-25 07:43:17 -05:00
|
|
|
// addTimeStepsToMap(gridTimeStepsMap, timeStepsFromGridCase(gridCase));
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// std::vector<RimWellLogFile*> wellLogFiles = wellLogFilesContainingFlow(m_wellName);
|
|
|
|
// if(wellLogFiles.size() > 0)
|
|
|
|
// {
|
2017-10-26 03:35:23 -05:00
|
|
|
// sourcesToSelect.push_back(RifWellRftAddress(RftSourceType::OBSERVED));
|
2017-10-25 07:43:17 -05:00
|
|
|
// for (RimWellLogFile* const wellLogFile : wellLogFiles)
|
|
|
|
// {
|
|
|
|
// addTimeStepsToMap(observedTimeStepsMap, timeStepsFromWellLogFile(wellLogFile));
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//
|
|
|
|
// m_selectedSources = sourcesToSelect;
|
|
|
|
//
|
|
|
|
// std::set<QDateTime> timeStepsToSelect;
|
2017-10-26 03:35:23 -05:00
|
|
|
// for (const std::pair<QDateTime, std::set<RifWellRftAddress>>& dateTimePair : rftTimeStepsMap)
|
2017-10-25 07:43:17 -05:00
|
|
|
// {
|
|
|
|
// timeStepsToSelect.insert(dateTimePair.first);
|
|
|
|
// }
|
2017-10-26 03:35:23 -05:00
|
|
|
// for (const std::pair<QDateTime, std::set<RifWellRftAddress>>& dateTimePair : observedTimeStepsMap)
|
2017-10-25 07:43:17 -05:00
|
|
|
// {
|
|
|
|
// timeStepsToSelect.insert(dateTimePair.first);
|
|
|
|
// }
|
|
|
|
// if (gridTimeStepsMap.size() > 0)
|
|
|
|
// timeStepsToSelect.insert((*gridTimeStepsMap.begin()).first);
|
|
|
|
//
|
|
|
|
// m_selectedTimeSteps = std::vector<QDateTime>(timeStepsToSelect.begin(), timeStepsToSelect.end());
|
|
|
|
//
|
|
|
|
// syncCurvesFromUiSelection();
|
|
|
|
//}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::updateWidgetTitleWindowTitle()
|
|
|
|
{
|
|
|
|
updateMdiWindowTitle();
|
|
|
|
|
|
|
|
if (m_wellLogPlotWidget)
|
|
|
|
{
|
|
|
|
if (m_showPlotTitle)
|
|
|
|
{
|
|
|
|
m_wellLogPlotWidget->showTitle(m_userName);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
m_wellLogPlotWidget->hideTitle();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-11-13 04:10:27 -06:00
|
|
|
std::set < std::pair<RifDataSourceForRftPlt, QDateTime>> RimWellPltPlot::selectedCurveDefs() const
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
std::set<std::pair<RifDataSourceForRftPlt, QDateTime>> curveDefs;
|
2017-11-09 03:03:32 -06:00
|
|
|
const std::vector<RimEclipseResultCase*> rftCases = RimWellPlotTools::rftCasesForWell(RimWellPlotTools::simWellName(m_wellPathName));
|
|
|
|
const std::vector<RimEclipseResultCase*> gridCases = RimWellPlotTools::gridCasesForWell(RimWellPlotTools::simWellName(m_wellPathName));
|
|
|
|
const QString simWellName = RimWellPlotTools::simWellName(m_wellPathName);
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
for (const QDateTime& timeStep : m_selectedTimeSteps())
|
|
|
|
{
|
2017-11-15 04:31:35 -06:00
|
|
|
for (const RifDataSourceForRftPlt& addr : expandSelectedSources())
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
if (addr.sourceType() == RifDataSourceForRftPlt::RFT)
|
2017-11-07 07:40:36 -06:00
|
|
|
{
|
|
|
|
for (RimEclipseResultCase* const rftCase : rftCases)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
const std::set<QDateTime>& timeSteps = RimWellPlotTools::timeStepsFromRftCase(rftCase, simWellName);
|
|
|
|
if (timeSteps.count(timeStep) > 0)
|
2017-11-07 07:40:36 -06:00
|
|
|
{
|
|
|
|
curveDefs.insert(std::make_pair(addr, timeStep));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-11-13 04:10:27 -06:00
|
|
|
else if (addr.sourceType() == RifDataSourceForRftPlt::GRID)
|
2017-11-07 07:40:36 -06:00
|
|
|
{
|
|
|
|
for (RimEclipseResultCase* const gridCase : gridCases)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
const std::set<QDateTime>& timeSteps = RimWellPlotTools::timeStepsFromGridCase(gridCase);
|
|
|
|
if (timeSteps.count(timeStep) > 0)
|
2017-11-07 07:40:36 -06:00
|
|
|
{
|
|
|
|
curveDefs.insert(std::make_pair(addr, timeStep));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2017-11-13 04:10:27 -06:00
|
|
|
if (addr.sourceType() == RifDataSourceForRftPlt::OBSERVED)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
|
|
|
if (addr.wellLogFile() != nullptr)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
const QDateTime& wellLogFileTimeStep = RimWellPlotTools::timeStepFromWellLogFile(addr.wellLogFile());
|
|
|
|
if (wellLogFileTimeStep == timeStep)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
curveDefs.insert(std::make_pair(RifDataSourceForRftPlt(RifDataSourceForRftPlt::OBSERVED, addr.wellLogFile()), timeStep));
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return curveDefs;
|
|
|
|
}
|
2017-11-07 07:40:36 -06:00
|
|
|
#if 0
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-10-26 03:35:23 -05:00
|
|
|
std::set<std::pair<RifWellRftAddress, QDateTime>> RimWellPltPlot::curveDefsFromCurves() const
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-26 03:35:23 -05:00
|
|
|
std::set<std::pair<RifWellRftAddress, QDateTime>> curveDefs;
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
RimWellLogTrack* const plotTrack = m_wellLogPlot->trackByIndex(0);
|
|
|
|
for (RimWellLogCurve* const curve : plotTrack->curvesVector())
|
|
|
|
{
|
|
|
|
curveDefs.insert(curveDefFromCurve(curve));
|
|
|
|
}
|
|
|
|
return curveDefs;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-10-26 03:35:23 -05:00
|
|
|
std::pair<RifWellRftAddress, QDateTime> RimWellPltPlot::curveDefFromCurve(const RimWellLogCurve* curve) const
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
|
|
|
const RimWellLogRftCurve* rftCurve = dynamic_cast<const RimWellLogRftCurve*>(curve);
|
|
|
|
const RimWellLogExtractionCurve* gridCurve = dynamic_cast<const RimWellLogExtractionCurve*>(curve);
|
|
|
|
const RimWellLogFileCurve* wellLogFileCurve = dynamic_cast<const RimWellLogFileCurve*>(curve);
|
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
//if (rftCurve != nullptr)
|
|
|
|
//{
|
|
|
|
// RimEclipseResultCase* rftCase = dynamic_cast<RimEclipseResultCase*>(rftCurve->eclipseResultCase());
|
|
|
|
// if (rftCase != nullptr)
|
|
|
|
// {
|
|
|
|
// const RifEclipseRftAddress rftAddress = rftCurve->rftAddress();
|
|
|
|
// const QDateTime timeStep = rftAddress.timeStep();
|
2017-10-26 03:35:23 -05:00
|
|
|
// return std::make_pair(RifWellRftAddress(RftSourceType::RFT, rftCase), timeStep);
|
2017-10-25 07:43:17 -05:00
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//else if (gridCurve != nullptr)
|
|
|
|
//{
|
|
|
|
// RimEclipseResultCase* gridCase = dynamic_cast<RimEclipseResultCase*>(gridCurve->rimCase());
|
|
|
|
// if (gridCase != nullptr)
|
|
|
|
// {
|
|
|
|
// size_t timeStepIndex = gridCurve->currentTimeStep();
|
2017-10-26 03:35:23 -05:00
|
|
|
// const std::map<QDateTime, std::set<RifWellRftAddress>>& timeStepsMap = timeStepsFromGridCase(gridCase);
|
|
|
|
// auto timeStepsVector = std::vector<std::pair<QDateTime, std::set<RifWellRftAddress>>>(
|
2017-10-25 07:43:17 -05:00
|
|
|
// timeStepsMap.begin(), timeStepsMap.end());
|
|
|
|
// if (timeStepIndex < timeStepsMap.size())
|
|
|
|
// {
|
2017-10-26 03:35:23 -05:00
|
|
|
// return std::make_pair(RifWellRftAddress(RftSourceType::GRID, gridCase),
|
2017-10-25 07:43:17 -05:00
|
|
|
// timeStepsVector[timeStepIndex].first);
|
|
|
|
// }
|
|
|
|
// }
|
|
|
|
//}
|
|
|
|
//else
|
|
|
|
if (wellLogFileCurve != nullptr)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
|
|
|
const RimWellPath* const wellPath = wellLogFileCurve->wellPath();
|
|
|
|
RimWellLogFile* const wellLogFile = wellLogFileCurve->wellLogFile();
|
|
|
|
|
|
|
|
if (wellLogFile != nullptr)
|
|
|
|
{
|
2017-11-01 04:29:03 -05:00
|
|
|
const QDateTime date = wellLogFile->date();
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
if (date.isValid())
|
|
|
|
{
|
2017-10-26 03:35:23 -05:00
|
|
|
return std::make_pair(RifWellRftAddress(RifWellRftAddress::OBSERVED, wellLogFile), date);
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-10-26 03:35:23 -05:00
|
|
|
return std::make_pair(RifWellRftAddress(), QDateTime());
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
2017-11-07 07:40:36 -06:00
|
|
|
#endif
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class RigResultPointCalculator
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
RigResultPointCalculator() {}
|
|
|
|
virtual ~RigResultPointCalculator() {}
|
|
|
|
|
|
|
|
const std::vector <cvf::Vec3d>& pipeBranchCLCoords() { return m_pipeBranchCLCoords; }
|
|
|
|
const std::vector <RigWellResultPoint>& pipeBranchWellResultPoints() { return m_pipeBranchWellResultPoints; }
|
|
|
|
const std::vector <double>& pipeBranchMeasuredDepths() { return m_pipeBranchMeasuredDepths; }
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
2017-11-08 09:35:58 -06:00
|
|
|
RigEclipseWellLogExtractor* findWellLogExtractor(const QString& wellPathName,
|
2017-11-07 07:40:36 -06:00
|
|
|
RimEclipseResultCase* eclCase)
|
|
|
|
{
|
|
|
|
RimProject* proj = RiaApplication::instance()->project();
|
2017-11-08 09:35:58 -06:00
|
|
|
RimWellPath* wellPath = proj->wellPathByName(wellPathName);
|
2017-11-07 07:40:36 -06:00
|
|
|
RimWellLogPlotCollection* wellLogCollection = proj->mainPlotCollection()->wellLogPlotCollection();
|
|
|
|
RigEclipseWellLogExtractor* eclExtractor = wellLogCollection->findOrCreateExtractor(wellPath, eclCase);
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-07 07:40:36 -06:00
|
|
|
return eclExtractor;
|
|
|
|
}
|
2017-11-06 15:23:54 -06:00
|
|
|
|
|
|
|
|
2017-11-07 07:40:36 -06:00
|
|
|
std::vector <cvf::Vec3d> m_pipeBranchCLCoords;
|
|
|
|
std::vector <RigWellResultPoint> m_pipeBranchWellResultPoints;
|
|
|
|
std::vector <double> m_pipeBranchMeasuredDepths;
|
|
|
|
};
|
|
|
|
|
2017-11-06 15:23:54 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
|
2017-11-07 07:40:36 -06:00
|
|
|
class RigRftResultPointCalculator : public RigResultPointCalculator
|
2017-11-06 15:23:54 -06:00
|
|
|
{
|
|
|
|
public:
|
2017-11-08 09:35:58 -06:00
|
|
|
RigRftResultPointCalculator(const QString& wellPathName,
|
2017-11-06 15:23:54 -06:00
|
|
|
RimEclipseResultCase* eclCase,
|
|
|
|
QDateTime m_timeStep)
|
|
|
|
{
|
|
|
|
|
2017-11-09 03:03:32 -06:00
|
|
|
RifEclipseRftAddress gasRateAddress(RimWellPlotTools::simWellName(wellPathName), m_timeStep, RifEclipseRftAddress::GRAT);
|
|
|
|
RifEclipseRftAddress oilRateAddress(RimWellPlotTools::simWellName(wellPathName), m_timeStep, RifEclipseRftAddress::ORAT);
|
|
|
|
RifEclipseRftAddress watRateAddress(RimWellPlotTools::simWellName(wellPathName), m_timeStep, RifEclipseRftAddress::WRAT);
|
2017-11-06 15:23:54 -06:00
|
|
|
|
|
|
|
std::vector<caf::VecIjk> rftIndices;
|
|
|
|
eclCase->rftReader()->cellIndices(gasRateAddress, &rftIndices);
|
|
|
|
if (rftIndices.empty()) eclCase->rftReader()->cellIndices(oilRateAddress, &rftIndices);
|
|
|
|
if (rftIndices.empty()) eclCase->rftReader()->cellIndices(watRateAddress, &rftIndices);
|
|
|
|
if (rftIndices.empty()) return;
|
|
|
|
|
|
|
|
std::vector<double> gasRates;
|
|
|
|
std::vector<double> oilRates;
|
|
|
|
std::vector<double> watRates;
|
|
|
|
eclCase->rftReader()->values(gasRateAddress, &gasRates);
|
|
|
|
eclCase->rftReader()->values(oilRateAddress, &oilRates);
|
|
|
|
eclCase->rftReader()->values(watRateAddress, &watRates);
|
|
|
|
|
|
|
|
std::map<size_t, size_t> globCellIdxToIdxInRftFile;
|
|
|
|
|
2017-11-07 07:40:36 -06:00
|
|
|
const RigMainGrid* mainGrid = eclCase->eclipseCaseData()->mainGrid();
|
2017-11-06 15:23:54 -06:00
|
|
|
|
|
|
|
for (size_t rftCellIdx = 0; rftCellIdx < rftIndices.size(); rftCellIdx++)
|
|
|
|
{
|
|
|
|
caf::VecIjk ijkIndex = rftIndices[rftCellIdx];
|
|
|
|
size_t globalCellIndex = mainGrid->cellIndexFromIJK(ijkIndex.i(), ijkIndex.j(), ijkIndex.k());
|
|
|
|
globCellIdxToIdxInRftFile[globalCellIndex] = rftCellIdx;
|
|
|
|
}
|
|
|
|
|
2017-11-08 09:35:58 -06:00
|
|
|
RigEclipseWellLogExtractor* eclExtractor = findWellLogExtractor(wellPathName, eclCase);
|
2017-11-07 07:40:36 -06:00
|
|
|
if (!eclExtractor) return;
|
|
|
|
|
|
|
|
std::vector<CellIntersectionInfo> intersections = eclExtractor->intersectionInfo();
|
|
|
|
|
2017-11-06 15:23:54 -06:00
|
|
|
for (size_t wpExIdx = 0; wpExIdx < intersections.size(); wpExIdx++)
|
|
|
|
{
|
|
|
|
size_t globCellIdx = intersections[wpExIdx].globCellIndex;
|
|
|
|
|
|
|
|
auto it = globCellIdxToIdxInRftFile.find(globCellIdx);
|
2017-11-08 04:58:14 -06:00
|
|
|
if (it == globCellIdxToIdxInRftFile.end())
|
|
|
|
{
|
|
|
|
if (wpExIdx == (intersections.size() - 1))
|
|
|
|
{
|
|
|
|
m_pipeBranchWellResultPoints.pop_back();
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2017-11-06 15:23:54 -06:00
|
|
|
m_pipeBranchCLCoords.push_back(intersections[wpExIdx].startPoint);
|
|
|
|
m_pipeBranchMeasuredDepths.push_back(intersections[wpExIdx].startMD);
|
|
|
|
|
|
|
|
m_pipeBranchCLCoords.push_back(intersections[wpExIdx].endPoint);
|
|
|
|
m_pipeBranchMeasuredDepths.push_back(intersections[wpExIdx].endMD);
|
|
|
|
|
|
|
|
RigWellResultPoint resPoint;
|
2017-11-07 11:35:34 -06:00
|
|
|
resPoint.m_isOpen = true;
|
2017-11-09 06:47:00 -06:00
|
|
|
resPoint.m_gridIndex = 0; // Always main grid
|
2017-11-06 15:23:54 -06:00
|
|
|
resPoint.m_gridCellIndex = globCellIdx; // Shortcut, since we only have main grid results from RFT
|
|
|
|
|
2017-11-09 06:47:00 -06:00
|
|
|
resPoint.m_gasRate = RiaEclipseUnitTools::convertSurfaceGasFlowRateToOilEquivalents(eclCase->eclipseCaseData()->unitsType(),
|
|
|
|
gasRates[it->second]);
|
|
|
|
resPoint.m_oilRate = oilRates[it->second];
|
2017-11-06 15:23:54 -06:00
|
|
|
resPoint.m_waterRate = watRates[it->second];
|
|
|
|
|
|
|
|
m_pipeBranchWellResultPoints.push_back(resPoint);
|
2017-11-07 11:35:34 -06:00
|
|
|
|
|
|
|
if ( wpExIdx < intersections.size() - 1 )
|
|
|
|
{
|
|
|
|
m_pipeBranchWellResultPoints.push_back(RigWellResultPoint()); // Invalid res point describing the "line" between the cells
|
|
|
|
}
|
2017-11-06 15:23:54 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
2017-11-07 07:40:36 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
class RigSimWellResultPointCalculator: public RigResultPointCalculator
|
|
|
|
{
|
|
|
|
public:
|
2017-11-08 09:35:58 -06:00
|
|
|
RigSimWellResultPointCalculator(const QString& wellPathName,
|
2017-11-07 07:40:36 -06:00
|
|
|
RimEclipseResultCase* eclCase,
|
|
|
|
QDateTime m_timeStep)
|
|
|
|
{
|
|
|
|
// Find timestep index from qdatetime
|
|
|
|
|
|
|
|
const std::vector<QDateTime> timeSteps = eclCase->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->timeStepDates();
|
|
|
|
size_t tsIdx = timeSteps.size();
|
|
|
|
for ( tsIdx = 0; tsIdx < timeSteps.size(); ++tsIdx) { if (timeSteps[tsIdx] == m_timeStep) break; }
|
|
|
|
|
|
|
|
if (tsIdx >= timeSteps.size()) return;
|
|
|
|
|
|
|
|
// Build search map into simulation well data
|
|
|
|
|
|
|
|
std::map<size_t, std::pair<size_t, size_t> > globCellIdxToIdxInSimWellBranch;
|
|
|
|
|
2017-11-09 03:03:32 -06:00
|
|
|
const RimWellPath* wellPath = RimWellPlotTools::wellPathByWellPathNameOrSimWellName(wellPathName);
|
2017-11-08 09:35:58 -06:00
|
|
|
const RigSimWellData* simWell = wellPath != nullptr ? eclCase->eclipseCaseData()->findSimWellData(wellPath->associatedSimulationWell()) : nullptr;
|
2017-11-07 07:40:36 -06:00
|
|
|
|
|
|
|
if (!simWell) return;
|
|
|
|
|
|
|
|
if (!simWell->hasWellResult(tsIdx)) return;
|
|
|
|
|
|
|
|
const RigWellResultFrame & resFrame = simWell->wellResultFrame(tsIdx);
|
|
|
|
|
|
|
|
const RigMainGrid* mainGrid = eclCase->eclipseCaseData()->mainGrid();
|
|
|
|
|
|
|
|
for (size_t brIdx = 0; brIdx < resFrame.m_wellResultBranches.size(); ++brIdx)
|
|
|
|
{
|
|
|
|
const std::vector<RigWellResultPoint>& branchResPoints = resFrame.m_wellResultBranches[brIdx].m_branchResultPoints;
|
|
|
|
for ( size_t wrpIdx = 0; wrpIdx < branchResPoints.size(); wrpIdx++ )
|
|
|
|
{
|
|
|
|
const RigGridBase* grid = mainGrid->gridByIndex(branchResPoints[wrpIdx].m_gridIndex);
|
|
|
|
size_t globalCellIndex = grid->reservoirCellIndex(branchResPoints[wrpIdx].m_gridCellIndex);
|
|
|
|
|
|
|
|
globCellIdxToIdxInSimWellBranch[globalCellIndex] = std::make_pair(brIdx, wrpIdx);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-08 09:35:58 -06:00
|
|
|
RigEclipseWellLogExtractor* eclExtractor = findWellLogExtractor(wellPathName, eclCase);
|
2017-11-07 07:40:36 -06:00
|
|
|
|
|
|
|
if (!eclExtractor) return;
|
|
|
|
|
|
|
|
std::vector<CellIntersectionInfo> intersections = eclExtractor->intersectionInfo();
|
|
|
|
|
|
|
|
for (size_t wpExIdx = 0; wpExIdx < intersections.size(); wpExIdx++)
|
|
|
|
{
|
|
|
|
size_t globCellIdx = intersections[wpExIdx].globCellIndex;
|
|
|
|
|
|
|
|
auto it = globCellIdxToIdxInSimWellBranch.find(globCellIdx);
|
2017-11-08 04:58:14 -06:00
|
|
|
if (it == globCellIdxToIdxInSimWellBranch.end())
|
|
|
|
{
|
|
|
|
if (wpExIdx == (intersections.size() - 1))
|
|
|
|
{
|
|
|
|
m_pipeBranchWellResultPoints.pop_back();
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
2017-11-07 07:40:36 -06:00
|
|
|
|
|
|
|
m_pipeBranchCLCoords.push_back(intersections[wpExIdx].startPoint);
|
|
|
|
m_pipeBranchMeasuredDepths.push_back(intersections[wpExIdx].startMD);
|
|
|
|
|
|
|
|
m_pipeBranchCLCoords.push_back(intersections[wpExIdx].endPoint);
|
|
|
|
m_pipeBranchMeasuredDepths.push_back(intersections[wpExIdx].endMD);
|
|
|
|
|
|
|
|
const RigWellResultPoint& resPoint = resFrame.m_wellResultBranches[it->second.first].m_branchResultPoints[it->second.second];
|
|
|
|
|
|
|
|
m_pipeBranchWellResultPoints.push_back(resPoint);
|
2017-11-07 11:35:34 -06:00
|
|
|
if ( wpExIdx < intersections.size() - 1 )
|
|
|
|
{
|
|
|
|
m_pipeBranchWellResultPoints.push_back(RigWellResultPoint()); // Invalid res point describing the "line" between the cells
|
|
|
|
}
|
2017-11-07 07:40:36 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2017-11-06 15:23:54 -06:00
|
|
|
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-10-31 06:49:14 -05:00
|
|
|
void RimWellPltPlot::syncCurvesFromUiSelection()
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-31 06:49:14 -05:00
|
|
|
RimWellLogTrack* plotTrack = m_wellLogPlot->trackByIndex(0);
|
2017-11-13 04:10:27 -06:00
|
|
|
const std::set<std::pair<RifDataSourceForRftPlt, QDateTime>>& curveDefs = selectedCurveDefs();
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
setPlotXAxisTitles(plotTrack);
|
|
|
|
|
|
|
|
// Delete existing curves
|
2017-11-15 04:31:35 -06:00
|
|
|
|
|
|
|
plotTrack->deleteAllCurves();
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-10-27 08:17:24 -05:00
|
|
|
int curveGroupId = 0;
|
|
|
|
|
2017-11-06 15:23:54 -06:00
|
|
|
RimProject* proj = RiaApplication::instance()->project();
|
2017-11-09 03:03:32 -06:00
|
|
|
RimWellPath* wellPath = RimWellPlotTools::wellPathByWellPathNameOrSimWellName(m_wellPathName);
|
2017-11-06 15:23:54 -06:00
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
// Add curves
|
2017-11-13 04:10:27 -06:00
|
|
|
for (const std::pair<RifDataSourceForRftPlt, QDateTime>& curveDefToAdd : curveDefs)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-27 08:17:24 -05:00
|
|
|
std::set<FlowPhase> selectedPhases = m_phaseSelectionMode == FLOW_TYPE_PHASE_SPLIT ?
|
|
|
|
std::set<FlowPhase>(m_phases().begin(), m_phases().end()) :
|
2017-11-09 03:03:32 -06:00
|
|
|
std::set<FlowPhase>({ FLOW_PHASE_TOTAL });
|
2017-11-08 04:22:16 -06:00
|
|
|
|
2017-11-13 04:10:27 -06:00
|
|
|
RifDataSourceForRftPlt sourceDef = curveDefToAdd.first;
|
2017-11-08 04:22:16 -06:00
|
|
|
QDateTime timeStep = curveDefToAdd.second;
|
2017-10-27 08:17:24 -05:00
|
|
|
|
2017-11-07 07:40:36 -06:00
|
|
|
std::unique_ptr<RigResultPointCalculator> resultPointCalc;
|
2017-11-12 16:46:12 -06:00
|
|
|
|
2017-11-08 04:22:16 -06:00
|
|
|
QString curveName;
|
2017-11-12 16:46:12 -06:00
|
|
|
{
|
|
|
|
curveName += sourceDef.eclCase() ? sourceDef.eclCase()->caseUserDescription() : "";
|
|
|
|
curveName += sourceDef.wellLogFile() ? sourceDef.wellLogFile()->name() : "";
|
2017-11-13 04:10:27 -06:00
|
|
|
if ( sourceDef.sourceType() == RifDataSourceForRftPlt::RFT ) curveName += ", RFT";
|
2017-11-12 16:46:12 -06:00
|
|
|
curveName += ", " + timeStep.toString();
|
|
|
|
}
|
2017-11-07 07:40:36 -06:00
|
|
|
|
2017-11-13 04:10:27 -06:00
|
|
|
if ( sourceDef.sourceType() == RifDataSourceForRftPlt::RFT )
|
2017-11-07 07:40:36 -06:00
|
|
|
{
|
2017-11-08 09:35:58 -06:00
|
|
|
resultPointCalc.reset(new RigRftResultPointCalculator(m_wellPathName,
|
2017-11-08 04:22:16 -06:00
|
|
|
dynamic_cast<RimEclipseResultCase*>(sourceDef.eclCase()),
|
|
|
|
timeStep));
|
2017-11-07 07:40:36 -06:00
|
|
|
}
|
2017-11-13 04:10:27 -06:00
|
|
|
else if (sourceDef.sourceType() == RifDataSourceForRftPlt::GRID)
|
2017-11-07 07:40:36 -06:00
|
|
|
{
|
2017-11-08 09:35:58 -06:00
|
|
|
resultPointCalc.reset(new RigSimWellResultPointCalculator(m_wellPathName,
|
2017-11-08 04:22:16 -06:00
|
|
|
dynamic_cast<RimEclipseResultCase*>(sourceDef.eclCase()),
|
|
|
|
timeStep));
|
2017-11-07 07:40:36 -06:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (resultPointCalc != nullptr)
|
2017-11-06 15:23:54 -06:00
|
|
|
{
|
2017-11-07 07:40:36 -06:00
|
|
|
if ( resultPointCalc->pipeBranchCLCoords().size() )
|
2017-11-06 15:23:54 -06:00
|
|
|
{
|
2017-11-09 08:19:42 -06:00
|
|
|
|
2017-11-07 07:40:36 -06:00
|
|
|
RigAccWellFlowCalculator wfAccumulator(resultPointCalc->pipeBranchCLCoords(),
|
|
|
|
resultPointCalc->pipeBranchWellResultPoints(),
|
|
|
|
resultPointCalc->pipeBranchMeasuredDepths(),
|
2017-11-09 08:19:42 -06:00
|
|
|
false); // m_phaseSelectionMode() != FLOW_TYPE_PHASE_SPLIT); The total flow is reservoir conditions must be careful
|
2017-11-06 15:23:54 -06:00
|
|
|
|
|
|
|
const std::vector<double>& depthValues = wfAccumulator.pseudoLengthFromTop(0);
|
|
|
|
std::vector<QString> tracerNames = wfAccumulator.tracerNames();
|
|
|
|
for ( const QString& tracerName: tracerNames )
|
|
|
|
{
|
2017-11-08 04:22:16 -06:00
|
|
|
auto color = tracerName == RIG_FLOW_OIL_NAME ? cvf::Color3f::DARK_GREEN :
|
|
|
|
tracerName == RIG_FLOW_GAS_NAME ? cvf::Color3f::DARK_RED :
|
|
|
|
tracerName == RIG_FLOW_WATER_NAME ? cvf::Color3f::BLUE :
|
|
|
|
cvf::Color3f::DARK_GRAY;
|
|
|
|
|
2017-11-09 03:03:32 -06:00
|
|
|
if ( tracerName == RIG_FLOW_OIL_NAME && selectedPhases.count(FLOW_PHASE_OIL)
|
|
|
|
|| tracerName == RIG_FLOW_GAS_NAME && selectedPhases.count(FLOW_PHASE_GAS)
|
2017-11-09 08:19:42 -06:00
|
|
|
|| tracerName == RIG_FLOW_WATER_NAME && selectedPhases.count(FLOW_PHASE_WATER)
|
|
|
|
|| tracerName == RIG_FLOW_TOTAL_NAME && selectedPhases.count(FLOW_PHASE_TOTAL) )
|
2017-11-08 04:22:16 -06:00
|
|
|
{
|
|
|
|
const std::vector<double> accFlow = wfAccumulator.accumulatedTracerFlowPrPseudoLength(tracerName, 0);
|
|
|
|
addStackedCurve(curveName + ", " + tracerName,
|
|
|
|
depthValues,
|
|
|
|
accFlow,
|
|
|
|
plotTrack,
|
|
|
|
color,
|
|
|
|
curveGroupId,
|
|
|
|
false);
|
|
|
|
}
|
2017-11-06 15:23:54 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-11-13 04:10:27 -06:00
|
|
|
else if ( sourceDef.sourceType() == RifDataSourceForRftPlt::OBSERVED )
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-08 04:22:16 -06:00
|
|
|
RimWellLogFile* const wellLogFile = sourceDef.wellLogFile();
|
2017-11-12 16:46:12 -06:00
|
|
|
if ( wellLogFile )
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-25 07:43:17 -05:00
|
|
|
RigWellLogFile* rigWellLogFile = wellLogFile->wellLogFile();
|
|
|
|
|
2017-11-12 16:46:12 -06:00
|
|
|
if ( rigWellLogFile )
|
2017-10-25 07:43:17 -05:00
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
for (RimWellLogFileChannel* channel : RimWellPlotTools::getFlowChannelsFromWellFile(wellLogFile))
|
2017-10-25 07:43:17 -05:00
|
|
|
{
|
|
|
|
const auto& channelName = channel->name();
|
2017-11-09 03:03:32 -06:00
|
|
|
if (selectedPhases.count(RimWellPlotTools::flowPhaseFromChannelName(channelName)) > 0)
|
2017-10-25 07:43:17 -05:00
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
auto color = RimWellPlotTools::isOilFlowChannel(channelName) ? cvf::Color3f::DARK_GREEN :
|
|
|
|
RimWellPlotTools::isGasFlowChannel(channelName) ? cvf::Color3f::DARK_RED :
|
|
|
|
RimWellPlotTools::isWaterFlowChannel(channelName) ? cvf::Color3f::BLUE :
|
2017-11-08 04:22:16 -06:00
|
|
|
cvf::Color3f::DARK_GRAY;
|
|
|
|
|
|
|
|
addStackedCurve(curveName + ", " + channelName,
|
2017-11-06 15:23:54 -06:00
|
|
|
rigWellLogFile->depthValues(),
|
|
|
|
rigWellLogFile->values(channelName),
|
|
|
|
plotTrack,
|
2017-11-08 04:22:16 -06:00
|
|
|
color,
|
2017-11-06 15:23:54 -06:00
|
|
|
curveGroupId,
|
|
|
|
true);
|
2017-10-25 07:43:17 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
}
|
2017-10-27 08:17:24 -05:00
|
|
|
curveGroupId++;
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
2017-11-09 07:14:09 -06:00
|
|
|
m_wellLogPlot->loadDataAndUpdate();
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-11-08 04:22:16 -06:00
|
|
|
void RimWellPltPlot::addStackedCurve(const QString& curveName,
|
2017-10-25 07:43:17 -05:00
|
|
|
const std::vector<double>& depthValues,
|
|
|
|
const std::vector<double>& accFlow,
|
2017-10-27 08:17:24 -05:00
|
|
|
RimWellLogTrack* plotTrack,
|
2017-11-08 04:22:16 -06:00
|
|
|
cvf::Color3f color,
|
2017-10-27 08:49:00 -05:00
|
|
|
int curveGroupId,
|
|
|
|
bool doFillCurve)
|
2017-10-25 07:43:17 -05:00
|
|
|
{
|
|
|
|
RimWellFlowRateCurve* curve = new RimWellFlowRateCurve;
|
2017-11-08 04:22:16 -06:00
|
|
|
curve->setFlowValuesPrDepthValue(curveName, depthValues, accFlow);
|
2017-10-25 07:43:17 -05:00
|
|
|
|
2017-10-27 08:17:24 -05:00
|
|
|
curve->setColor(color);
|
|
|
|
curve->setGroupId(curveGroupId);
|
2017-10-27 08:49:00 -05:00
|
|
|
curve->setDoFillCurve(doFillCurve);
|
2017-11-08 04:58:14 -06:00
|
|
|
curve->setSymbol(RimSummaryCurveAppearanceCalculator::cycledSymbol(curveGroupId));
|
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
plotTrack->addCurve(curve);
|
|
|
|
|
|
|
|
curve->loadDataAndUpdate(true);
|
|
|
|
}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
bool RimWellPltPlot::isOnlyGridSourcesSelected() const
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
const std::vector<RifDataSourceForRftPlt>& selSources = m_selectedSources();
|
|
|
|
return std::find_if(selSources.begin(), selSources.end(), [](const RifDataSourceForRftPlt& addr)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
return addr.sourceType() == RifDataSourceForRftPlt::RFT || addr.sourceType() == RifDataSourceForRftPlt::OBSERVED;
|
2017-10-23 06:57:01 -05:00
|
|
|
}) == selSources.end();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-11-13 04:10:27 -06:00
|
|
|
bool RimWellPltPlot::isAnySourceAddressSelected(const std::set<RifDataSourceForRftPlt>& addresses) const
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
const std::vector<RifDataSourceForRftPlt>& selectedSourcesVector = m_selectedSources();
|
|
|
|
const auto selectedSources = std::set<RifDataSourceForRftPlt>(selectedSourcesVector.begin(), selectedSourcesVector.end());
|
|
|
|
std::vector<RifDataSourceForRftPlt> intersectVector;
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
std::set_intersection(selectedSources.begin(), selectedSources.end(),
|
|
|
|
addresses.begin(), addresses.end(), std::inserter(intersectVector, intersectVector.end()));
|
|
|
|
return intersectVector.size() > 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-11-15 04:31:35 -06:00
|
|
|
std::vector<RifDataSourceForRftPlt> RimWellPltPlot::expandSelectedSources() const
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
std::vector<RifDataSourceForRftPlt> sources;
|
|
|
|
for (const RifDataSourceForRftPlt& addr : m_selectedSources())
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
if (addr.sourceType() == RifDataSourceForRftPlt::OBSERVED)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
for (RimWellLogFile* const wellLogFile : RimWellPlotTools::wellLogFilesContainingFlow(m_wellPathName))
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
sources.push_back(RifDataSourceForRftPlt(RifDataSourceForRftPlt::OBSERVED, wellLogFile));
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sources.push_back(addr);
|
|
|
|
}
|
|
|
|
return sources;
|
|
|
|
}
|
|
|
|
|
2017-10-27 02:38:24 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-11-13 04:10:27 -06:00
|
|
|
std::vector<RifDataSourceForRftPlt> RimWellPltPlot::selectedSourcesAndTimeSteps() const
|
2017-10-27 02:38:24 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
std::vector<RifDataSourceForRftPlt> sources;
|
|
|
|
for (const RifDataSourceForRftPlt& addr : m_selectedSources())
|
2017-10-27 02:38:24 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
if (addr.sourceType() == RifDataSourceForRftPlt::OBSERVED)
|
2017-10-27 02:38:24 -05:00
|
|
|
{
|
|
|
|
for (const QDateTime& timeStep : m_selectedTimeSteps())
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
for (const RifDataSourceForRftPlt& address : m_timeStepsToAddresses.at(timeStep))
|
2017-10-27 02:38:24 -05:00
|
|
|
{
|
|
|
|
sources.push_back(address);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
sources.push_back(addr);
|
|
|
|
}
|
|
|
|
return sources;
|
|
|
|
}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QWidget* RimWellPltPlot::viewWidget()
|
|
|
|
{
|
|
|
|
return m_wellLogPlotWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::zoomAll()
|
|
|
|
{
|
|
|
|
m_wellLogPlot()->zoomAll();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
RimWellLogPlot* RimWellPltPlot::wellLogPlot() const
|
|
|
|
{
|
|
|
|
return m_wellLogPlot();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::setCurrentWellName(const QString& currWellName)
|
|
|
|
{
|
2017-11-08 09:35:58 -06:00
|
|
|
m_wellPathName = currWellName;
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QString RimWellPltPlot::currentWellName() const
|
|
|
|
{
|
2017-11-08 09:35:58 -06:00
|
|
|
return m_wellPathName;
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
const char* RimWellPltPlot::plotNameFormatString()
|
|
|
|
{
|
|
|
|
return PLOT_NAME_QFORMAT_STRING;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QList<caf::PdmOptionItemInfo> RimWellPltPlot::calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly)
|
|
|
|
{
|
|
|
|
QList<caf::PdmOptionItemInfo> options;
|
2017-11-09 03:03:32 -06:00
|
|
|
const QString simWellName = RimWellPlotTools::simWellName(m_wellPathName);
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-08 09:35:58 -06:00
|
|
|
if (fieldNeedingOptions == &m_wellPathName)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
|
|
|
calculateValueOptionsForWells(options);
|
|
|
|
}
|
|
|
|
else if (fieldNeedingOptions == &m_selectedSources)
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
std::set<RifDataSourceForRftPlt> optionAddresses;
|
2017-10-31 09:41:28 -05:00
|
|
|
|
2017-11-09 03:03:32 -06:00
|
|
|
const std::vector<RimEclipseResultCase*> rftCases = RimWellPlotTools::rftCasesForWell(simWellName);
|
2017-11-07 07:40:36 -06:00
|
|
|
if (rftCases.size() > 0)
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
options.push_back(caf::PdmOptionItemInfo::createHeader(RifDataSourceForRftPlt::sourceTypeUiText(RifDataSourceForRftPlt::RFT), true));
|
2017-11-07 07:40:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto& rftCase : rftCases)
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
auto addr = RifDataSourceForRftPlt(RifDataSourceForRftPlt::RFT, rftCase);
|
2017-11-07 07:40:36 -06:00
|
|
|
auto item = caf::PdmOptionItemInfo(rftCase->caseUserDescription(), QVariant::fromValue(addr));
|
|
|
|
item.setLevel(1);
|
|
|
|
options.push_back(item);
|
|
|
|
}
|
|
|
|
|
2017-11-09 03:03:32 -06:00
|
|
|
const std::vector<RimEclipseResultCase*> gridCases = RimWellPlotTools::gridCasesForWell(simWellName);
|
2017-11-07 07:40:36 -06:00
|
|
|
if (gridCases.size() > 0)
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
options.push_back(caf::PdmOptionItemInfo::createHeader(RifDataSourceForRftPlt::sourceTypeUiText(RifDataSourceForRftPlt::GRID), true));
|
2017-11-07 07:40:36 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto& gridCase : gridCases)
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
auto addr = RifDataSourceForRftPlt(RifDataSourceForRftPlt::GRID, gridCase);
|
2017-11-07 07:40:36 -06:00
|
|
|
auto item = caf::PdmOptionItemInfo(gridCase->caseUserDescription(), QVariant::fromValue(addr));
|
|
|
|
item.setLevel(1);
|
|
|
|
options.push_back(item);
|
|
|
|
}
|
2017-10-25 07:43:17 -05:00
|
|
|
|
2017-11-09 03:03:32 -06:00
|
|
|
if (RimWellPlotTools::wellLogFilesContainingFlow(m_wellPathName).size() > 0)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
options.push_back(caf::PdmOptionItemInfo::createHeader(RifDataSourceForRftPlt::sourceTypeUiText(RifDataSourceForRftPlt::OBSERVED), true));
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-13 04:10:27 -06:00
|
|
|
auto addr = RifDataSourceForRftPlt(RifDataSourceForRftPlt::OBSERVED);
|
2017-10-23 06:57:01 -05:00
|
|
|
auto item = caf::PdmOptionItemInfo("Observed Data", QVariant::fromValue(addr));
|
|
|
|
item.setLevel(1);
|
|
|
|
options.push_back(item);
|
2017-10-31 09:41:28 -05:00
|
|
|
optionAddresses.insert(addr);
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (fieldNeedingOptions == &m_selectedTimeSteps)
|
|
|
|
{
|
2017-11-08 09:35:58 -06:00
|
|
|
calculateValueOptionsForTimeSteps(m_wellPathName, options);
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
if (fieldNeedingOptions == &m_phaseSelectionMode)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
else if (fieldNeedingOptions == &m_phases)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
options.push_back(caf::PdmOptionItemInfo("Oil", FLOW_PHASE_OIL));
|
|
|
|
options.push_back(caf::PdmOptionItemInfo("Gas", FLOW_PHASE_GAS));
|
|
|
|
options.push_back(caf::PdmOptionItemInfo("Water", FLOW_PHASE_WATER));
|
2017-10-25 07:43:17 -05:00
|
|
|
}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
return options;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, const QVariant& oldValue, const QVariant& newValue)
|
|
|
|
{
|
|
|
|
RimViewWindow::fieldChangedByUi(changedField, oldValue, newValue);
|
|
|
|
|
2017-11-08 09:35:58 -06:00
|
|
|
if (changedField == &m_wellPathName)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-08 09:35:58 -06:00
|
|
|
setDescription(QString(plotNameFormatString()).arg(m_wellPathName));
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
2017-11-09 06:36:14 -06:00
|
|
|
if (changedField == &m_wellPathName)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
|
|
|
RimWellLogTrack* const plotTrack = m_wellLogPlot->trackByIndex(0);
|
2017-11-15 04:31:35 -06:00
|
|
|
plotTrack->deleteAllCurves();
|
|
|
|
m_selectedSources.v().clear();
|
|
|
|
m_selectedTimeSteps.v().clear();
|
2017-10-23 06:57:01 -05:00
|
|
|
m_timeStepsToAddresses.clear();
|
2017-11-12 14:22:12 -06:00
|
|
|
updateFormationsOnPlot();
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
else if (changedField == &m_selectedSources)
|
|
|
|
{
|
2017-11-12 16:46:12 -06:00
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
if (changedField == &m_selectedSources ||
|
|
|
|
changedField == &m_selectedTimeSteps)
|
|
|
|
{
|
2017-11-12 14:22:12 -06:00
|
|
|
updateFormationsOnPlot();
|
2017-10-31 09:41:28 -05:00
|
|
|
syncSourcesIoFieldFromGuiField();
|
2017-10-23 06:57:01 -05:00
|
|
|
syncCurvesFromUiSelection();
|
|
|
|
}
|
|
|
|
else if (changedField == &m_showPlotTitle)
|
|
|
|
{
|
|
|
|
//m_wellLogPlot->setShowDescription(m_showPlotTitle);
|
|
|
|
}
|
2017-10-25 07:43:17 -05:00
|
|
|
|
|
|
|
if (changedField == &m_phaseSelectionMode ||
|
|
|
|
changedField == &m_phases)
|
|
|
|
{
|
|
|
|
syncCurvesFromUiSelection();
|
|
|
|
}
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
2017-11-13 03:21:24 -06:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName)
|
|
|
|
{
|
|
|
|
uiTreeOrdering.skipRemainingChildren(true);
|
|
|
|
}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QImage RimWellPltPlot::snapshotWindowContent()
|
|
|
|
{
|
|
|
|
QImage image;
|
|
|
|
|
|
|
|
if (m_wellLogPlotWidget)
|
|
|
|
{
|
|
|
|
QPixmap pix = QPixmap::grabWidget(m_wellLogPlotWidget);
|
|
|
|
image = pix.toImage();
|
|
|
|
}
|
|
|
|
|
|
|
|
return image;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
const QString simWellName = RimWellPlotTools::simWellName(m_wellPathName);
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
uiOrdering.add(&m_userName);
|
2017-11-08 09:35:58 -06:00
|
|
|
uiOrdering.add(&m_wellPathName);
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
caf::PdmUiGroup* sourcesGroup = uiOrdering.addNewGroupWithKeyword("Sources", "Sources");
|
|
|
|
sourcesGroup->add(&m_selectedSources);
|
|
|
|
|
|
|
|
caf::PdmUiGroup* timeStepsGroup = uiOrdering.addNewGroupWithKeyword("Time Steps", "TimeSteps");
|
|
|
|
timeStepsGroup->add(&m_selectedTimeSteps);
|
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
caf::PdmUiGroup* flowGroup = uiOrdering.addNewGroupWithKeyword("Phase Selection", "PhaseSelection");
|
|
|
|
flowGroup->add(&m_phaseSelectionMode);
|
|
|
|
|
|
|
|
if (m_phaseSelectionMode == FLOW_TYPE_PHASE_SPLIT)
|
|
|
|
{
|
|
|
|
flowGroup->add(&m_phases);
|
|
|
|
}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
//uiOrdering.add(&m_showPlotTitle);
|
|
|
|
|
2017-11-06 09:07:29 -06:00
|
|
|
if (m_wellLogPlot && m_wellLogPlot->trackCount() > 0)
|
|
|
|
{
|
|
|
|
RimWellLogTrack* track = m_wellLogPlot->trackByIndex(0);
|
|
|
|
|
|
|
|
track->uiOrderingForShowFormationNamesAndCase(uiOrdering);
|
|
|
|
|
|
|
|
caf::PdmUiGroup* legendAndAxisGroup = uiOrdering.addNewGroup("Legend and Axis");
|
|
|
|
legendAndAxisGroup->setCollapsedByDefault(true);
|
|
|
|
|
|
|
|
m_wellLogPlot->uiOrderingForPlot(*legendAndAxisGroup);
|
|
|
|
|
|
|
|
track->uiOrderingForVisibleXRange(*legendAndAxisGroup);
|
|
|
|
|
|
|
|
m_wellLogPlot->uiOrderingForVisibleDepthRange(*legendAndAxisGroup);
|
|
|
|
}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
uiOrdering.skipRemainingFields(true);
|
|
|
|
}
|
|
|
|
|
2017-10-25 07:43:17 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute)
|
|
|
|
{
|
|
|
|
if (field == &m_phases)
|
|
|
|
{
|
|
|
|
caf::PdmUiTreeSelectionEditorAttribute* attrib = dynamic_cast<caf::PdmUiTreeSelectionEditorAttribute*> (attribute);
|
|
|
|
attrib->showTextFilter = false;
|
|
|
|
attrib->showToggleAllCheckbox = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-27 02:38:24 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::initAfterRead()
|
|
|
|
{
|
|
|
|
RimViewWindow::initAfterRead();
|
|
|
|
|
|
|
|
// Postpone init until data has been loaded
|
|
|
|
m_doInitAfterLoad = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::setupBeforeSave()
|
|
|
|
{
|
2017-10-31 09:41:28 -05:00
|
|
|
syncCurvesFromUiSelection();
|
2017-10-27 02:38:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::initAfterLoad()
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
std::set<RifDataSourceForRftPlt> selectedSources;
|
2017-11-13 04:16:36 -06:00
|
|
|
for (RimDataSourceForRftPlt* addr : m_selectedSourcesForIo)
|
2017-10-27 02:38:24 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
if (addr->address().sourceType() == RifDataSourceForRftPlt::OBSERVED)
|
2017-10-27 02:38:24 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
selectedSources.insert(RifDataSourceForRftPlt(RifDataSourceForRftPlt::OBSERVED));
|
2017-10-27 02:38:24 -05:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
selectedSources.insert(addr->address());
|
|
|
|
}
|
|
|
|
}
|
2017-11-13 04:10:27 -06:00
|
|
|
m_selectedSources = std::vector<RifDataSourceForRftPlt>(selectedSources.begin(), selectedSources.end());
|
2017-10-27 02:38:24 -05:00
|
|
|
}
|
|
|
|
|
2017-10-31 09:41:28 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::syncSourcesIoFieldFromGuiField()
|
|
|
|
{
|
|
|
|
m_selectedSourcesForIo.clear();
|
2017-11-13 04:10:27 -06:00
|
|
|
for (const RifDataSourceForRftPlt& addr : selectedSourcesAndTimeSteps())
|
2017-10-31 09:41:28 -05:00
|
|
|
{
|
2017-11-13 04:16:36 -06:00
|
|
|
m_selectedSourcesForIo.push_back(new RimDataSourceForRftPlt(addr));
|
2017-10-31 09:41:28 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-11-13 04:10:27 -06:00
|
|
|
void RimWellPltPlot::updateTimeStepsToAddresses(const std::vector<RifDataSourceForRftPlt>& addressesToKeep)
|
2017-10-31 09:41:28 -05:00
|
|
|
{
|
|
|
|
for (auto& timeStepPair : m_timeStepsToAddresses)
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
std::vector<RifDataSourceForRftPlt> addressesToDelete;
|
|
|
|
std::set<RifDataSourceForRftPlt> keepAddresses = std::set<RifDataSourceForRftPlt>(addressesToKeep.begin(), addressesToKeep.end());
|
|
|
|
std::set<RifDataSourceForRftPlt>& currentAddresses = timeStepPair.second;
|
2017-10-31 09:41:28 -05:00
|
|
|
|
|
|
|
std::set_difference(currentAddresses.begin(), currentAddresses.end(),
|
|
|
|
keepAddresses.begin(), keepAddresses.end(),
|
|
|
|
std::inserter(addressesToDelete, addressesToDelete.end()));
|
|
|
|
|
|
|
|
for (const auto& addr : addressesToDelete)
|
|
|
|
{
|
|
|
|
currentAddresses.erase(addr);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::calculateValueOptionsForWells(QList<caf::PdmOptionItemInfo>& options)
|
|
|
|
{
|
|
|
|
RimProject * proj = RiaApplication::instance()->project();
|
|
|
|
|
|
|
|
if (proj != nullptr)
|
|
|
|
{
|
2017-11-08 09:35:58 -06:00
|
|
|
std::set<QString> wellNames;
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
// Observed wells
|
2017-11-08 09:35:58 -06:00
|
|
|
for (const RimWellPath* const wellPath : proj->allWellPaths())
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-08 09:35:58 -06:00
|
|
|
wellNames.insert(wellPath->name());
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto& wellName : wellNames)
|
|
|
|
{
|
|
|
|
options.push_back(caf::PdmOptionItemInfo(wellName, wellName));
|
|
|
|
}
|
|
|
|
}
|
2017-11-06 07:20:43 -06:00
|
|
|
|
|
|
|
if (options.size() == 0)
|
|
|
|
{
|
|
|
|
options.push_back(caf::PdmOptionItemInfo("None", "None"));
|
|
|
|
}
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
2017-11-15 04:31:35 -06:00
|
|
|
#if 1
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::calculateValueOptionsForTimeSteps(const QString& wellPathNameOrSimWellName, QList<caf::PdmOptionItemInfo>& options)
|
|
|
|
{
|
|
|
|
std::vector<RifDataSourceForRftPlt> selSources = expandSelectedSources();
|
|
|
|
bool hasObservedData = false;
|
|
|
|
bool hasRftData = false;
|
|
|
|
bool hasGridData = false;
|
|
|
|
|
|
|
|
for (const auto& source : selSources )
|
|
|
|
{
|
|
|
|
switch (source.sourceType())
|
|
|
|
{
|
|
|
|
case RifDataSourceForRftPlt::RFT:
|
|
|
|
hasRftData = true;
|
|
|
|
break;
|
|
|
|
case RifDataSourceForRftPlt::GRID:
|
|
|
|
hasGridData = true;
|
|
|
|
break;
|
|
|
|
case RifDataSourceForRftPlt::OBSERVED:
|
|
|
|
hasObservedData = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
std::map<QDateTime, std::set<RifDataSourceForRftPlt> > observedTimeStepsWithSources;
|
|
|
|
std::map<QDateTime, std::set<RifDataSourceForRftPlt> > rftTimeStepsWithSources;
|
|
|
|
std::map<QDateTime, std::set<RifDataSourceForRftPlt> > gridTimestepsWithSources;
|
|
|
|
|
|
|
|
QString simWellName = RimWellPlotTools::simWellName(wellPathNameOrSimWellName);
|
|
|
|
|
|
|
|
if (hasObservedData)
|
|
|
|
{
|
|
|
|
for (const auto& source : selSources )
|
|
|
|
{
|
|
|
|
if (source.sourceType() == RifDataSourceForRftPlt::OBSERVED && source.wellLogFile())
|
|
|
|
{
|
|
|
|
observedTimeStepsWithSources[source.wellLogFile()->date()].insert(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasRftData)
|
|
|
|
{
|
|
|
|
for (const auto& source : selSources )
|
|
|
|
{
|
|
|
|
if (source.sourceType() == RifDataSourceForRftPlt::RFT && source.rftReader())
|
|
|
|
{
|
|
|
|
std::set<QDateTime> rftTimes = source.rftReader()->availableTimeSteps(simWellName, { RifEclipseRftAddress::ORAT,
|
|
|
|
RifEclipseRftAddress::WRAT,
|
|
|
|
RifEclipseRftAddress::GRAT } );
|
|
|
|
for ( const QDateTime& date: rftTimes)
|
|
|
|
{
|
|
|
|
rftTimeStepsWithSources[date].insert(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( hasGridData )
|
|
|
|
{
|
|
|
|
for ( const auto& source : selSources )
|
|
|
|
{
|
|
|
|
if ( source.sourceType() == RifDataSourceForRftPlt::GRID && source.eclCase() )
|
|
|
|
{
|
|
|
|
std::vector<QDateTime> allTimeSteps = source.eclCase()->eclipseCaseData()->results(RiaDefines::MATRIX_MODEL)->timeStepDates();
|
|
|
|
const RigSimWellData* simWell = source.eclCase()->eclipseCaseData()->findSimWellData(simWellName);
|
|
|
|
|
|
|
|
for ( size_t tsIdx = 0; tsIdx < allTimeSteps.size(); ++tsIdx )
|
|
|
|
{
|
|
|
|
if ( simWell->hasWellResult(tsIdx) )
|
|
|
|
{
|
|
|
|
gridTimestepsWithSources[allTimeSteps[tsIdx]].insert(source);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we have a time baseline add the equal or adjacent grid timesteps
|
|
|
|
|
|
|
|
std::map<QDateTime, std::set<RifDataSourceForRftPlt> > timestepsToShowWithSources;
|
|
|
|
std::map<QDateTime, std::set<RifDataSourceForRftPlt> >* timeBaseline = nullptr;
|
|
|
|
|
|
|
|
if (hasObservedData)
|
|
|
|
{
|
|
|
|
timeBaseline = &observedTimeStepsWithSources;
|
|
|
|
}
|
|
|
|
else if (hasRftData)
|
|
|
|
{
|
|
|
|
timeBaseline = &rftTimeStepsWithSources;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (timeBaseline)
|
|
|
|
{
|
|
|
|
std::set<QDateTime> baseTimeSteps;
|
|
|
|
for (const auto& dateSourceSetPair: *timeBaseline) baseTimeSteps.insert(dateSourceSetPair.first);
|
|
|
|
std::set<QDateTime> rftTimeSteps;
|
|
|
|
for (const auto& dateSourceSetPair: rftTimeStepsWithSources) rftTimeSteps.insert(dateSourceSetPair.first);
|
|
|
|
std::set<QDateTime> gridTimeSteps;
|
|
|
|
for (const auto& dateSourceSetPair: gridTimestepsWithSources) gridTimeSteps.insert(dateSourceSetPair.first);
|
|
|
|
|
|
|
|
std::set<QDateTime> filteredRftTimeSteps = RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, rftTimeSteps);
|
|
|
|
std::set<QDateTime> filteredGridTimeSteps = RimWellPlotTools::findMatchingOrAdjacentTimeSteps(baseTimeSteps, gridTimeSteps);
|
|
|
|
|
|
|
|
// Fill final map
|
|
|
|
timestepsToShowWithSources = observedTimeStepsWithSources;
|
|
|
|
|
|
|
|
for (const QDateTime& time: filteredRftTimeSteps)
|
|
|
|
{
|
|
|
|
std::set<RifDataSourceForRftPlt>& sourceSet = rftTimeStepsWithSources.find(time)->second;
|
|
|
|
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
|
|
|
|
}
|
|
|
|
for (const QDateTime& time: filteredGridTimeSteps)
|
|
|
|
{
|
|
|
|
std::set<RifDataSourceForRftPlt>& sourceSet = gridTimestepsWithSources.find(time)->second;
|
|
|
|
timestepsToShowWithSources[time].insert(sourceSet.begin(), sourceSet.end());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
timestepsToShowWithSources = gridTimestepsWithSources;
|
|
|
|
}
|
|
|
|
|
|
|
|
m_timeStepsToAddresses = timestepsToShowWithSources;
|
|
|
|
|
|
|
|
// Create formatted options of all the timesteps
|
|
|
|
|
|
|
|
std::vector<QDateTime> allTimeSteps;
|
|
|
|
for (const std::pair<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepPair : timestepsToShowWithSources)
|
|
|
|
{
|
|
|
|
allTimeSteps.push_back(timeStepPair.first);
|
|
|
|
}
|
|
|
|
const QString dateFormatString = RimTools::createTimeFormatStringFromDates(allTimeSteps);
|
|
|
|
|
|
|
|
|
|
|
|
for (const std::pair<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepPair : timestepsToShowWithSources)
|
|
|
|
{
|
|
|
|
QString optionText = timeStepPair.first.toString(dateFormatString);
|
|
|
|
optionText += " ";
|
|
|
|
bool hasObs = false;
|
|
|
|
bool hasRft = false;
|
|
|
|
bool hasGrid = false;
|
|
|
|
|
|
|
|
for (const auto& source : timeStepPair.second)
|
|
|
|
{
|
|
|
|
switch (source.sourceType()){
|
|
|
|
case RifDataSourceForRftPlt::OBSERVED: hasObs = true; break;
|
|
|
|
case RifDataSourceForRftPlt::RFT : hasRft = true; break;
|
|
|
|
case RifDataSourceForRftPlt::GRID : hasGrid = true; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hasObs) optionText += "O ";
|
|
|
|
if (hasRft) optionText += "R ";
|
|
|
|
if (hasGrid) optionText += "G";
|
|
|
|
|
|
|
|
options.push_back(caf::PdmOptionItemInfo(optionText, timeStepPair.first));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#else
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-11-08 09:35:58 -06:00
|
|
|
void RimWellPltPlot::calculateValueOptionsForTimeSteps(const QString& wellPathNameOrSimWellName, QList<caf::PdmOptionItemInfo>& options)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
const QString simWellName = RimWellPlotTools::simWellName(m_wellPathName);
|
2017-11-15 04:31:35 -06:00
|
|
|
|
|
|
|
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> displayTimeStepsMap;
|
|
|
|
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> obsAndRftTimeStepsMap;
|
|
|
|
std::map<QDateTime, std::set<RifDataSourceForRftPlt>> gridTimeStepsMap;
|
|
|
|
|
2017-11-09 03:03:32 -06:00
|
|
|
const std::vector<RimEclipseResultCase*> rftCases = RimWellPlotTools::rftCasesForWell(simWellName);
|
|
|
|
const std::vector<RimEclipseResultCase*> gridCases = RimWellPlotTools::gridCasesForWell(simWellName);
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-15 04:31:35 -06:00
|
|
|
std::vector<RifDataSourceForRftPlt> selSources = expandSelectedSources();
|
|
|
|
|
2017-10-31 09:41:28 -05:00
|
|
|
// First update timeSteps to Address 'cache'
|
2017-11-15 04:31:35 -06:00
|
|
|
updateTimeStepsToAddresses(selSources);
|
2017-10-31 09:41:28 -05:00
|
|
|
|
2017-11-13 04:10:27 -06:00
|
|
|
for (const RifDataSourceForRftPlt& selection : selSources)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
if (selection.sourceType() == RifDataSourceForRftPlt::RFT)
|
2017-11-07 07:40:36 -06:00
|
|
|
{
|
|
|
|
for (RimEclipseResultCase* const rftCase : rftCases)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
RimWellPlotTools::addTimeStepsToMap(obsAndRftTimeStepsMap, RimWellPlotTools::timeStepsMapFromRftCase(rftCase, simWellName));
|
2017-11-07 07:40:36 -06:00
|
|
|
}
|
|
|
|
}
|
2017-11-13 04:10:27 -06:00
|
|
|
else if (selection.sourceType() == RifDataSourceForRftPlt::GRID)
|
2017-11-07 07:40:36 -06:00
|
|
|
{
|
|
|
|
for (RimEclipseResultCase* const gridCase : gridCases)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
RimWellPlotTools::addTimeStepsToMap(gridTimeStepsMap, RimWellPlotTools::timeStepsMapFromGridCase(gridCase));
|
2017-11-07 07:40:36 -06:00
|
|
|
}
|
|
|
|
}
|
2017-11-13 04:10:27 -06:00
|
|
|
else if (selection.sourceType() == RifDataSourceForRftPlt::OBSERVED)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
|
|
|
if (selection.wellLogFile() != nullptr)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
RimWellPlotTools::addTimeStepsToMap(obsAndRftTimeStepsMap, RimWellPlotTools::timeStepsMapFromWellLogFile(selection.wellLogFile()));
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (isOnlyGridSourcesSelected())
|
|
|
|
{
|
|
|
|
displayTimeStepsMap = gridTimeStepsMap;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
const auto gridTimeStepsVector = std::vector<std::pair<QDateTime, std::set<RifDataSourceForRftPlt>>>(gridTimeStepsMap.begin(), gridTimeStepsMap.end());
|
2017-10-23 06:57:01 -05:00
|
|
|
|
2017-11-13 04:10:27 -06:00
|
|
|
for (const std::pair<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepPair : obsAndRftTimeStepsMap)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
const std::map<QDateTime, std::set<RifDataSourceForRftPlt>>& adjTimeSteps = RimWellPlotTools::adjacentTimeSteps(gridTimeStepsVector, timeStepPair);
|
2017-11-09 03:03:32 -06:00
|
|
|
RimWellPlotTools::addTimeStepsToMap(displayTimeStepsMap, adjTimeSteps);
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add the first grid time step (from the total grid time steps list)
|
|
|
|
if (gridTimeStepsVector.size() > 0)
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
RimWellPlotTools::addTimeStepToMap(displayTimeStepsMap, gridTimeStepsVector.front());
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// Add already selected time steps
|
|
|
|
for (const QDateTime& timeStep : m_selectedTimeSteps())
|
|
|
|
{
|
|
|
|
if (m_timeStepsToAddresses.count(timeStep) > 0)
|
|
|
|
{
|
2017-11-13 04:10:27 -06:00
|
|
|
const std::set<RifDataSourceForRftPlt> sourceAddresses = m_timeStepsToAddresses[timeStep];
|
2017-10-23 06:57:01 -05:00
|
|
|
if (isAnySourceAddressSelected(sourceAddresses))
|
|
|
|
{
|
2017-11-09 03:03:32 -06:00
|
|
|
RimWellPlotTools::addTimeStepToMap(displayTimeStepsMap, std::make_pair(timeStep, m_timeStepsToAddresses[timeStep]));
|
2017-10-23 06:57:01 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-11-09 03:03:32 -06:00
|
|
|
RimWellPlotTools::addTimeStepsToMap(m_timeStepsToAddresses, displayTimeStepsMap);
|
2017-10-23 06:57:01 -05:00
|
|
|
|
|
|
|
// Create vector of all time steps
|
|
|
|
std::vector<QDateTime> allTimeSteps;
|
2017-11-13 04:10:27 -06:00
|
|
|
for (const std::pair<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepPair : m_timeStepsToAddresses)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
|
|
|
allTimeSteps.push_back(timeStepPair.first);
|
|
|
|
}
|
|
|
|
|
|
|
|
const QString dateFormatString = RimTools::createTimeFormatStringFromDates(allTimeSteps);
|
2017-11-13 04:10:27 -06:00
|
|
|
for (const std::pair<QDateTime, std::set<RifDataSourceForRftPlt>>& timeStepPair : displayTimeStepsMap)
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
|
|
|
options.push_back(caf::PdmOptionItemInfo(timeStepPair.first.toString(dateFormatString), timeStepPair.first));
|
|
|
|
}
|
|
|
|
}
|
2017-11-15 04:31:35 -06:00
|
|
|
#endif
|
2017-10-23 06:57:01 -05:00
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
void RimWellPltPlot::setDescription(const QString& description)
|
|
|
|
{
|
|
|
|
m_userName = description;
|
|
|
|
|
|
|
|
updateWidgetTitleWindowTitle();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QString RimWellPltPlot::description() const
|
|
|
|
{
|
|
|
|
return m_userName();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
2017-10-31 06:49:14 -05:00
|
|
|
void RimWellPltPlot::onLoadDataAndUpdate()
|
2017-10-23 06:57:01 -05:00
|
|
|
{
|
2017-10-27 02:38:24 -05:00
|
|
|
if (m_doInitAfterLoad)
|
|
|
|
{
|
|
|
|
initAfterLoad();
|
|
|
|
m_doInitAfterLoad = false;
|
|
|
|
}
|
|
|
|
|
2017-11-13 01:56:22 -06:00
|
|
|
if (m_isOnLoad)
|
|
|
|
{
|
|
|
|
if (m_wellLogPlot->trackCount() > 0)
|
|
|
|
{
|
|
|
|
m_wellLogPlot->trackByIndex(0)->setShowFormations(true);
|
|
|
|
}
|
|
|
|
m_isOnLoad = false;
|
|
|
|
}
|
|
|
|
|
2017-10-23 06:57:01 -05:00
|
|
|
updateMdiWindowVisibility();
|
2017-11-12 14:22:12 -06:00
|
|
|
updateFormationsOnPlot();
|
2017-10-27 02:38:24 -05:00
|
|
|
syncCurvesFromUiSelection();
|
2017-10-23 06:57:01 -05:00
|
|
|
m_wellLogPlot->loadDataAndUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
///
|
|
|
|
//--------------------------------------------------------------------------------------------------
|
|
|
|
QWidget* RimWellPltPlot::createViewWidget(QWidget* mainWindowParent)
|
|
|
|
{
|
|
|
|
m_wellLogPlotWidget = new RiuWellPltPlot(this, mainWindowParent);
|
|
|
|
return m_wellLogPlotWidget;
|
|
|
|
}
|