diff --git a/ApplicationCode/Application/RiaApplication.cpp b/ApplicationCode/Application/RiaApplication.cpp index eb17712844..f56cc0c68b 100644 --- a/ApplicationCode/Application/RiaApplication.cpp +++ b/ApplicationCode/Application/RiaApplication.cpp @@ -47,6 +47,9 @@ #include "RimFlowCharacteristicsPlot.h" #include "RimFlowPlotCollection.h" #include "RimFormationNamesCollection.h" +#include "RimRftPlotCollection.h" + +#include "RimEclipseCase.h" #include "RimGeoMechCase.h" #include "RimGeoMechCellColors.h" #include "RimGeoMechModels.h" @@ -71,6 +74,8 @@ #include "RimWellLogPlotCollection.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" +#include "RimRftPlotCollection.h" +#include "RimWellRftPlot.h" #include "RiuMainPlotWindow.h" #include "RiuMainWindow.h" @@ -615,6 +620,7 @@ void RiaApplication::loadAndUpdatePlotData() RimWellLogPlotCollection* wlpColl = nullptr; RimSummaryPlotCollection* spColl = nullptr; RimFlowPlotCollection* flowColl = nullptr; + RimRftPlotCollection* rftColl = nullptr; if (m_project->mainPlotCollection() && m_project->mainPlotCollection()->wellLogPlotCollection()) { @@ -628,11 +634,16 @@ void RiaApplication::loadAndUpdatePlotData() { flowColl = m_project->mainPlotCollection()->flowPlotCollection(); } + if (m_project->mainPlotCollection() && m_project->mainPlotCollection()->rftPlotCollection()) + { + rftColl = m_project->mainPlotCollection()->rftPlotCollection(); + } size_t plotCount = 0; plotCount += wlpColl ? wlpColl->wellLogPlots().size() : 0; plotCount += spColl ? spColl->summaryPlots().size() : 0; plotCount += flowColl ? flowColl->plotCount() : 0; + plotCount += rftColl ? rftColl->rftPlots().size() : 0; caf::ProgressInfo plotProgress(plotCount, "Loading Plot Data"); if (wlpColl) @@ -659,6 +670,15 @@ void RiaApplication::loadAndUpdatePlotData() flowColl->loadDataAndUpdate(); plotProgress.incrementProgress(); } + + if (rftColl) + { + for (const auto& rftPlot : rftColl->rftPlots()) + { + rftPlot->loadDataAndUpdate(); + plotProgress.incrementProgress(); + } + } } //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake b/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake index e451d7b64c..09b9e98d8a 100644 --- a/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake +++ b/ApplicationCode/ProjectDataModel/Flow/CMakeLists_files.cmake @@ -14,6 +14,7 @@ ${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.h ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.h ${CEE_CURRENT_LIST_DIR}RimFlowCharacteristicsPlot.h ${CEE_CURRENT_LIST_DIR}RimWellRftPlot.h +${CEE_CURRENT_LIST_DIR}RimWellRftAddress.h ) set (SOURCE_GROUP_SOURCE_FILES @@ -26,6 +27,7 @@ ${CEE_CURRENT_LIST_DIR}RimWellFlowRateCurve.cpp ${CEE_CURRENT_LIST_DIR}RimWellAllocationPlotLegend.cpp ${CEE_CURRENT_LIST_DIR}RimFlowCharacteristicsPlot.cpp ${CEE_CURRENT_LIST_DIR}RimWellRftPlot.cpp +${CEE_CURRENT_LIST_DIR}RimWellRftAddress.cpp ) list(APPEND CODE_HEADER_FILES diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.cpp new file mode 100644 index 0000000000..48cd6ab9c1 --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.cpp @@ -0,0 +1,125 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#include "RimWellRftAddress.h" +#include "cafAppEnum.h" +#include +#include + +namespace caf +{ + + template<> + void caf::AppEnum::setUp() + { + addItem(RftSourceType::RFT, "RFT", "RFT Cases"); + addItem(RftSourceType::GRID, "GRID", "Grid Cases"); + addItem(RftSourceType::OBSERVED, "OBSERVED", "Observed Data"); + setDefault(RftSourceType::NONE); + } +} + +RimWellRftAddress::RimWellRftAddress(RftSourceType sourceType , int caseId) +{ + m_sourceType = sourceType; + m_caseId = caseId; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RftSourceType RimWellRftAddress::sourceType() const +{ + return m_sourceType; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +int RimWellRftAddress::caseId() const +{ + return m_caseId; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellRftAddress::uiText() const +{ + return m_caseId >= 0 ? + QString("%1 %2").arg(sourceTypeUiText(m_sourceType), QString::number(m_caseId)) : + QString("%1").arg(sourceTypeUiText(m_sourceType)); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QString RimWellRftAddress::sourceTypeUiText(RftSourceType sourceType) +{ + switch (sourceType) + { + case RftSourceType::RFT: return QString("RFT Cases"); + case RftSourceType::GRID: return QString("Grid Cases"); + case RftSourceType::OBSERVED: return QString("Observed Data"); + } + return QString(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool operator==(const RimWellRftAddress& addr1, const RimWellRftAddress& addr2) +{ + return addr1.sourceType() == addr2.sourceType() && addr1.caseId() == addr2.caseId(); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QTextStream& operator << (QTextStream& str, const RimWellRftAddress& addr) +{ + str << RimWellRftAddress::sourceTypeUiText(addr.sourceType()) << " " << addr.caseId(); + return str; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +QTextStream& operator >> (QTextStream& str, RimWellRftAddress& source) +{ + QString sourceTypeString; + int caseId; + + str >> sourceTypeString; + str >> caseId; + + if (QString::compare(sourceTypeString, RimWellRftAddress::sourceTypeUiText(RftSourceType::RFT)) == 0) + { + source.m_sourceType = RftSourceType::RFT; + } + else if (QString::compare(sourceTypeString, RimWellRftAddress::sourceTypeUiText(RftSourceType::GRID)) == 0) + { + source.m_sourceType = RftSourceType::GRID; + } + else if (QString::compare(sourceTypeString, RimWellRftAddress::sourceTypeUiText(RftSourceType::OBSERVED)) == 0) + { + source.m_sourceType = RftSourceType::OBSERVED; + } + source.m_caseId = caseId; + return str; +} diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.h b/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.h new file mode 100644 index 0000000000..376784421b --- /dev/null +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.h @@ -0,0 +1,85 @@ +///////////////////////////////////////////////////////////////////////////////// +// +// 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 +// for more details. +// +///////////////////////////////////////////////////////////////////////////////// + +#pragma once + + +#include "RimViewWindow.h" + +#include "cafPdmField.h" +#include "cafPdmObject.h" +#include "cafPdmPtrField.h" + +#include +#include +#include + +class RimEclipseResultCase; +class RimEclipseWell; +class RimFlowDiagSolution; +class RimTotalWellAllocationPlot; +class RimWellLogPlot; +class RiuWellRftPlot; +class RimWellLogTrack; +class RimTofAccumulatedPhaseFractionsPlot; +class RigSingleWellResultsData; +class RimWellLogFileChannel; +class RimWellLogFile; + + + +//================================================================================================== +/// +/// +//================================================================================================== +enum class RftSourceType +{ + NONE, + RFT, + GRID, + OBSERVED +}; + + +class RimWellRftAddress +{ +public: + RimWellRftAddress() : m_sourceType(RftSourceType::NONE), m_caseId(-1) + { + } + + RimWellRftAddress(RftSourceType sourceType, int caseId = -1); + + RftSourceType sourceType() const; + int caseId() const; + + QString uiText() const; + static QString sourceTypeUiText(RftSourceType sourceType); + + friend QTextStream& operator >> (QTextStream& str, RimWellRftAddress& addr); + +private: + RftSourceType m_sourceType; + int m_caseId; +}; + +Q_DECLARE_METATYPE(RimWellRftAddress); + +bool operator==(const RimWellRftAddress& addr1, const RimWellRftAddress& addr2); +QTextStream& operator <<(QTextStream& str, const RimWellRftAddress& addr); +QTextStream& operator >> (QTextStream& str, RimWellRftAddress& addr); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp index f37dd25712..498dffd088 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp @@ -52,6 +52,7 @@ #include "cafPdmUiTreeSelectionEditor.h" #include "SummaryPlotCommands/RicSummaryCurveCreatorUiKeywords.h" #include "cafPdmChildArrayField.h" +#include "RimWellRftAddress.h" CAF_PDM_SOURCE_INIT(RimWellRftPlot, "WellRftPlot"); @@ -154,6 +155,82 @@ void RimWellRftPlot::updateWidgetTitleWindowTitle() } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellRftPlot::loadDataAndUpdatePlot() +{ + auto wellLogFiles = getWellLogFilesWithPressure(); + + for (const auto& wellLogFile : wellLogFiles) + { + + } +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellRftPlot::isPressureChannel(RimWellLogFileChannel* channel) +{ + // Todo: read pressure channel names from config/defines + return QString::compare(channel->name(), "PRESSURE") == 0; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellRftPlot::getWellLogFilesWithPressure() const +{ + std::vector wellLogFiles; + auto project = RiaApplication::instance()->project(); + + for (RimOilField* oilField : project->oilFields) + { + auto wellPathColl = oilField->wellPathCollection(); + for (const auto& wellPath : wellPathColl->wellPaths) + { + bool hasPressure = false; + const auto& wellLogFile = wellPath->wellLogFile(); + const auto& wellLogChannels = wellLogFile->wellLogChannelNames(); + + for (const auto& wellLogChannel : *wellLogChannels) + { + // Todo: add more criterias + if (isPressureChannel(wellLogChannel)) + { + hasPressure = true; + break; + } + } + if (hasPressure) + wellLogFiles.push_back(wellLogFile); + } + } + return wellLogFiles; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellRftPlot::getPressureChannelsFromWellLogFile(const RimWellLogFile* wellLogFile) const +{ + std::vector channels; + + for (const auto& wellLogFile : getWellLogFilesWithPressure()) + { + for (const auto& channel : *wellLogFile->wellLogChannelNames()) + { + // Todo: add more criterias + if (isPressureChannel(channel)) + { + channels.push_back(channel); + } + } + } + return channels; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -207,16 +284,29 @@ QList RimWellRftPlot::calculateValueOptions(const caf::P } else if (fieldNeedingOptions == &m_selectedSources) { - options.push_back(caf::PdmOptionItemInfo::createHeader("RFT Cases", true)); - options.push_back(caf::PdmOptionItemInfo::createHeader("Grid Cases", true)); + options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::RFT), true)); - options.push_back(caf::PdmOptionItemInfo::createHeader("Observed Data", true)); + options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::GRID), true)); + + options.push_back(caf::PdmOptionItemInfo("Test", "Test")); + + options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::OBSERVED), true)); calculateValueOptionsForObservedData(options, 1); } else if (fieldNeedingOptions == &m_selectedTimeSteps) { - calculateValueOptionsForTimeSteps(options); + for (const auto& selection : m_selectedSources()) + { + if (selection == RimWellRftAddress(RftSourceType::OBSERVED)) + { + for (const auto& wellLogFile : getWellLogFilesWithPressure()) + { + auto item = caf::PdmOptionItemInfo(wellLogFile->date(), wellLogFile->date()); + options.push_back(item); + } + } + } } return options; @@ -229,43 +319,14 @@ void RimWellRftPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c { RimViewWindow::fieldChangedByUi(changedField, oldValue, newValue); - //if (changedField == &m_userName || - // changedField == &m_showPlotTitle) - //{ - // updateWidgetTitleWindowTitle(); - //} - //else if ( changedField == &m_case) - //{ - // if ( m_flowDiagSolution && m_case ) - // { - // m_flowDiagSolution = m_case->defaultFlowDiagSolution(); - // } - // else - // { - // m_flowDiagSolution = nullptr; - // } - - // if (!m_case) m_timeStep = 0; - // else if (m_timeStep >= static_cast(m_case->timeStepDates().size())) - // { - // m_timeStep = std::max(0, ((int)m_case->timeStepDates().size()) - 1); - // } - - // std::set sortedWellNames = findSortedWellNames(); - // if (!sortedWellNames.size()) m_wellName = ""; - // else if ( sortedWellNames.count(m_wellName()) == 0 ){ m_wellName = *sortedWellNames.begin();} - - // loadDataAndUpdate(); - //} - //else if ( changedField == &m_wellName - // || changedField == &m_timeStep - // || changedField == &m_flowDiagSolution - // || changedField == &m_groupSmallContributions - // || changedField == &m_smallContributionsThreshold - // || changedField == &m_flowType ) - //{ - // loadDataAndUpdate(); - //} + if (changedField == &m_selectedSources) + { + loadDataAndUpdatePlot(); + } + else if (changedField == &m_selectedTimeSteps) + { + loadDataAndUpdatePlot(); + } } //-------------------------------------------------------------------------------------------------- @@ -301,6 +362,13 @@ void RimWellRftPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering.add(&m_showPlotTitle); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellRftPlot::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -323,60 +391,15 @@ void RimWellRftPlot::calculateValueOptionsForWells(QList //-------------------------------------------------------------------------------------------------- void RimWellRftPlot::calculateValueOptionsForObservedData(QList& options, int level) { - auto project = RiaApplication::instance()->project(); - - for (RimOilField* oilField : project->oilFields) + if (getWellLogFilesWithPressure().size() > 0) { - auto wellPathColl = oilField->wellPathCollection(); - for (const auto& wellPath : wellPathColl->wellPaths) + auto addr = RimWellRftAddress(RftSourceType::OBSERVED); + auto item = caf::PdmOptionItemInfo(addr.uiText(), QVariant::fromValue(addr)); + if (level > 0) { - const auto& wellLogFile = wellPath->wellLogFile(); - const auto& channels = wellLogFile->wellLogChannelNames(); - - for (const auto& channel : *channels) - { - auto name = channel->name(); - - if (QString::compare(name, "PRESSURE") == 0) // Todo: Move constant to config/defines - { - auto item = caf::PdmOptionItemInfo(name, name); - if (level > 0) - { - item.setLevel(level); - } - options.push_back(item); - } - } - } - } -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -void RimWellRftPlot::calculateValueOptionsForTimeSteps(QList& options) -{ - auto project = RiaApplication::instance()->project(); - - for (RimOilField* oilField : project->oilFields) - { - auto wellPathColl = oilField->wellPathCollection(); - for (const auto& wellPath : wellPathColl->wellPaths) - { - const auto& wellLogFile = wellPath->wellLogFile(); - const auto& channels = wellLogFile->wellLogChannelNames(); - - for (const auto& channel : *channels) - { - auto name = channel->name(); - - if (QString::compare(name, "PRESSURE") == 0) // Todo: Move constant to config/defines - { - auto item = caf::PdmOptionItemInfo(wellLogFile->date(), name); - options.push_back(item); - } - } + item.setLevel(level); } + options.push_back(item); } } @@ -428,4 +451,3 @@ cvf::Color3f RimWellRftPlot::getTracerColor(const QString& tracerName) if (tracerName == RIG_FLOW_WATER_NAME) return cvf::Color3f::BLUE; return cvf::Color3f::DARK_GRAY; } - diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h index e09b882999..0ec01d3233 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h @@ -24,8 +24,11 @@ #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPtrField.h" +#include "RimWellRftAddress.h" #include +#include +#include class RimEclipseResultCase; class RimEclipseWell; @@ -36,6 +39,9 @@ class RiuWellRftPlot; class RimWellLogTrack; class RimTofAccumulatedPhaseFractionsPlot; class RigSingleWellResultsData; +class RimWellLogFileChannel; +class RimWellLogFile; +//class RimWellRftAddress; namespace cvf { class Color3f; @@ -86,15 +92,22 @@ protected: virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, + caf::PdmUiEditorAttribute* attribute) override; private: void calculateValueOptionsForWells(QList& options); void calculateValueOptionsForObservedData(QList& options, int level); - void calculateValueOptionsForTimeSteps(QList& options); void updateFromWell(); void updateWidgetTitleWindowTitle(); + void loadDataAndUpdatePlot(); + + static bool isPressureChannel(RimWellLogFileChannel* channel); + std::vector getWellLogFilesWithPressure() const; + std::vector getPressureChannelsFromWellLogFile(const RimWellLogFile* wellLogFile) const; + // RimViewWindow overrides virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; @@ -107,7 +120,8 @@ private: caf::PdmField m_userName; caf::PdmField m_wellName; - caf::PdmField> m_selectedSources; + caf::PdmField> m_selectedSources; + caf::PdmField> m_selectedTimeSteps; QPointer m_wellLogPlotWidget;