diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.cpp index 234c5f168c..4fd4374fcd 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewPltPlotFeature.cpp @@ -66,12 +66,12 @@ bool RicNewPltPlotFeature::isCommandEnabled() RimEclipseResultCase* eclCase = caf::firstAncestorOfTypeFromSelectedObject(); if (simWell != nullptr) { - enable &= RimWellPltPlot::hasPressureData(eclCase); + enable &= RimWellPltPlot::hasFlowData(eclCase); } } else if (rimWellPath) { - enable &= RimWellPltPlot::hasPressureData(rimWellPath); + enable &= RimWellPltPlot::hasFlowData(rimWellPath); } return enable; } @@ -110,7 +110,7 @@ void RicNewPltPlotFeature::onActionTriggered(bool isChecked) pltPlotColl->addPlot(pltPlot); pltPlot->setDescription(plotName); - pltPlot->applyInitialSelections(); + //pltPlot->applyInitialSelections(); pltPlot->loadDataAndUpdate(); pltPlotColl->updateConnectedEditors(); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.cpp index 7f77a34b2b..7bae1e78af 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.cpp @@ -42,6 +42,7 @@ #include "RimWellLogTrack.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" +#include "RimWellFlowRateCurve.h" #include "RiuWellPltPlot.h" #include "cafPdmUiTreeSelectionEditor.h" #include @@ -50,10 +51,34 @@ CAF_PDM_SOURCE_INIT(RimWellPltPlot, "WellPltPlot"); +template<> +void caf::AppEnum< RimWellPltPlot::FlowType>::setUp() +{ + addItem(RimWellPltPlot::FLOW_TYPE_TOTAL, "TOTAL", "Total Flow"); + addItem(RimWellPltPlot::FLOW_TYPE_PHASE_SPLIT, "PHASE_SPLIT", "Phase Split"); +} + +template<> +void caf::AppEnum< RimWellPltPlot::FlowPhase>::setUp() +{ + addItem(RimWellPltPlot::PHASE_OIL, "PHASE_OIL", "Oil"); + addItem(RimWellPltPlot::PHASE_GAS, "PHASE_GAS", "Gas"); + addItem(RimWellPltPlot::PHASE_WATER, "PHASE_WATER", "Water"); +} + +const QString RimWellPltPlot::OIL_CHANNEL_NAME = "QOZT"; +const QString RimWellPltPlot::GAS_CHANNEL_NAME = "QGZT"; +const QString RimWellPltPlot::WATER_CHANNEL_NAME = "QWZT"; +const QString RimWellPltPlot::TOTAL_CHANNEL_NAME = "QTZT"; + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -const char RimWellPltPlot::PRESSURE_DATA_NAME[] = "PRESSURE"; +const std::set RimWellPltPlot::FLOW_DATA_NAMES = { + OIL_CHANNEL_NAME, + GAS_CHANNEL_NAME, + WATER_CHANNEL_NAME, + TOTAL_CHANNEL_NAME }; const char RimWellPltPlot::PLOT_NAME_QFORMAT_STRING[] = "RFT: %1"; //-------------------------------------------------------------------------------------------------- @@ -71,25 +96,27 @@ RimWellPltPlot::RimWellPltPlot() CAF_PDM_InitFieldNoDefault(&m_wellLogPlot, "WellLog", "WellLog", "", "", ""); m_wellLogPlot.uiCapability()->setUiHidden(true); m_wellLogPlot = new RimWellLogPlot(); - m_wellLogPlot->setDepthType(RimWellLogPlot::TRUE_VERTICAL_DEPTH); + m_wellLogPlot->setDepthType(RimWellLogPlot::MEASURED_DEPTH); CAF_PDM_InitFieldNoDefault(&m_wellName, "WellName", "WellName", "", "", ""); - CAF_PDM_InitFieldNoDefault(&m_branchIndex, "BranchIndex", "BranchIndex", "", "", ""); + CAF_PDM_InitField(&m_branchIndex, "BranchIndex", 0, "BranchIndex", "", "", ""); CAF_PDM_InitFieldNoDefault(&m_selectedSources, "Sources", "Sources", "", "", ""); m_selectedSources.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName()); - m_selectedSources.xmlCapability()->disableIO(); m_selectedSources.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); m_selectedSources.uiCapability()->setAutoAddingOptionFromValue(false); CAF_PDM_InitFieldNoDefault(&m_selectedTimeSteps, "TimeSteps", "TimeSteps", "", "", ""); m_selectedTimeSteps.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName()); - m_selectedTimeSteps.xmlCapability()->disableIO(); m_selectedTimeSteps.uiCapability()->setUiLabelPosition(caf::PdmUiItemInfo::HIDDEN); m_selectedTimeSteps.uiCapability()->setAutoAddingOptionFromValue(false); + CAF_PDM_InitFieldNoDefault(&m_phaseSelectionMode, "PhaseSelectionMode", "Mode", "", "", ""); + + CAF_PDM_InitFieldNoDefault(&m_phases, "Phases", "Phases", "", "", ""); + m_phases.uiCapability()->setUiEditorTypeName(caf::PdmUiTreeSelectionEditor::uiEditorTypeName()); + this->setAsPlotMdiWindow(); - m_selectedSourcesOrTimeStepsFieldsChanged = false; } //-------------------------------------------------------------------------------------------------- @@ -117,105 +144,105 @@ void RimWellPltPlot::deleteViewWidget() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPltPlot::applyCurveAppearance(RimWellLogCurve* newCurve) -{ - const std::pair& newCurveDef = curveDefFromCurve(newCurve); - - std::vector colorTable; - RiaColorTables::summaryCurveDefaultPaletteColors().color3fArray().toStdVector(&colorTable); - - std::vector 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 assignedColors; - std::set assignedSymbols; - - // Used colors and symbols - for (RimWellLogCurve* const curve : m_wellLogPlot->trackByIndex(0)->curvesVector()) - { - if (curve == newCurve) continue; - - std::pair cDef = curveDefFromCurve(curve); - 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); -} +//void RimWellPltPlot::applyCurveAppearance(RimWellLogCurve* newCurve) +//{ +// const std::pair& newCurveDef = curveDefFromCurve(newCurve); +// +// std::vector colorTable; +// RiaColorTables::summaryCurveDefaultPaletteColors().color3fArray().toStdVector(&colorTable); +// +// std::vector 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 assignedColors; +// std::set assignedSymbols; +// +// // Used colors and symbols +// for (RimWellLogCurve* const curve : m_wellLogPlot->trackByIndex(0)->curvesVector()) +// { +// if (curve == newCurve) continue; +// +// std::pair cDef = curveDefFromCurve(curve); +// 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); +//} //-------------------------------------------------------------------------------------------------- /// @@ -244,85 +271,145 @@ void RimWellPltPlot::updateSelectedTimeStepsFromSelectedSources() } //-------------------------------------------------------------------------------------------------- -/// +/// //-------------------------------------------------------------------------------------------------- -void RimWellPltPlot::applyInitialSelections() +RimWellPltPlot::FlowPhase RimWellPltPlot::flowPhaseFromChannelName(const QString& channelName) { - std::vector> eclCaseTuples = eclipseCasesForWell(m_wellName); + if (QString::compare(channelName, OIL_CHANNEL_NAME, Qt::CaseInsensitive) == 0) return PHASE_OIL; + if (QString::compare(channelName, GAS_CHANNEL_NAME, Qt::CaseInsensitive) == 0) return PHASE_GAS; + if (QString::compare(channelName, WATER_CHANNEL_NAME, Qt::CaseInsensitive) == 0) return PHASE_WATER; + if (QString::compare(channelName, TOTAL_CHANNEL_NAME, Qt::CaseInsensitive) == 0) return PHASE_TOTAL; + return PHASE_NONE; +} - std::vector sourcesToSelect; - std::map> rftTimeStepsMap; - std::map> observedTimeStepsMap; - std::map> gridTimeStepsMap; +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPltPlot::setPlotXAxisTitles(RimWellLogTrack* plotTrack) +{ + std::vector cases = eclipseCases(); - for(RimEclipseResultCase* const rftCase : rftCasesFromEclipseCases(eclCaseTuples)) + RiaEclipseUnitTools::UnitSystem unitSet = !cases.empty() ? + cases.front()->eclipseCaseData()->unitsType() : + RiaEclipseUnitTools::UNITS_UNKNOWN; + + QString unitText; + switch (unitSet) { - sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::RFT, rftCase)); - addTimeStepsToMap(rftTimeStepsMap, timeStepsFromRftCase(rftCase)); + case RiaEclipseUnitTools::UNITS_METRIC: + unitText = "[Liquid Sm3/day], [Gas kSm3/day]"; + break; + case RiaEclipseUnitTools::UNITS_FIELD: + unitText = "[Liquid BBL/day], [Gas BOE/day]"; + break; + case RiaEclipseUnitTools::UNITS_LAB: + unitText = "[cm3/hr]"; + break; + default: + unitText = "(unknown unit)"; + break; + } - - for (RimEclipseResultCase* const gridCase : gridCasesFromEclipseCases(eclCaseTuples)) + plotTrack->setXAxisTitle("Surface Flow Rate " + unitText); +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellPltPlot::eclipseCases() const +{ + std::vector cases; + RimProject* proj = RiaApplication::instance()->project(); + for (const auto& oilField : proj->oilFields) { - sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::GRID, gridCase)); - addTimeStepsToMap(gridTimeStepsMap, timeStepsFromGridCase(gridCase)); - } - - std::vector wellLogFiles = wellLogFilesContainingPressure(m_wellName); - if(wellLogFiles.size() > 0) - { - sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::OBSERVED)); - for (RimWellLogFile* const wellLogFile : wellLogFiles) + for (const auto& eclCase : oilField->analysisModels()->cases) { - addTimeStepsToMap(observedTimeStepsMap, timeStepsFromWellLogFile(wellLogFile)); + cases.push_back(eclCase); } } - - m_selectedSources = sourcesToSelect; - - std::set timeStepsToSelect; - for (const std::pair>& dateTimePair : rftTimeStepsMap) - { - timeStepsToSelect.insert(dateTimePair.first); - } - for (const std::pair>& dateTimePair : observedTimeStepsMap) - { - timeStepsToSelect.insert(dateTimePair.first); - } - if (gridTimeStepsMap.size() > 0) - timeStepsToSelect.insert((*gridTimeStepsMap.begin()).first); - - m_selectedTimeSteps = std::vector(timeStepsToSelect.begin(), timeStepsToSelect.end()); - - syncCurvesFromUiSelection(); + return cases; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +//void RimWellPltPlot::applyInitialSelections() +//{ +// std::vector> eclCaseTuples = eclipseCasesForWell(m_wellName); +// +// std::vector sourcesToSelect; +// std::map> rftTimeStepsMap; +// std::map> observedTimeStepsMap; +// std::map> gridTimeStepsMap; +// +// for(RimEclipseResultCase* const rftCase : rftCasesFromEclipseCases(eclCaseTuples)) +// { +// sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::RFT, rftCase)); +// addTimeStepsToMap(rftTimeStepsMap, timeStepsFromRftCase(rftCase)); +// } +// +// for (RimEclipseResultCase* const gridCase : gridCasesFromEclipseCases(eclCaseTuples)) +// { +// sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::GRID, gridCase)); +// addTimeStepsToMap(gridTimeStepsMap, timeStepsFromGridCase(gridCase)); +// } +// +// std::vector wellLogFiles = wellLogFilesContainingFlow(m_wellName); +// if(wellLogFiles.size() > 0) +// { +// sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::OBSERVED)); +// for (RimWellLogFile* const wellLogFile : wellLogFiles) +// { +// addTimeStepsToMap(observedTimeStepsMap, timeStepsFromWellLogFile(wellLogFile)); +// } +// } +// +// m_selectedSources = sourcesToSelect; +// +// std::set timeStepsToSelect; +// for (const std::pair>& dateTimePair : rftTimeStepsMap) +// { +// timeStepsToSelect.insert(dateTimePair.first); +// } +// for (const std::pair>& dateTimePair : observedTimeStepsMap) +// { +// timeStepsToSelect.insert(dateTimePair.first); +// } +// if (gridTimeStepsMap.size() > 0) +// timeStepsToSelect.insert((*gridTimeStepsMap.begin()).first); +// +// m_selectedTimeSteps = std::vector(timeStepsToSelect.begin(), timeStepsToSelect.end()); +// +// syncCurvesFromUiSelection(); +//} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RimWellPltPlot::updateEditorsFromCurves() { - std::set selectedSources; - std::set selectedTimeSteps; - std::map> selectedTimeStepsMap; - - for (const std::pair& curveDef : curveDefsFromCurves()) - { - if (curveDef.first.sourceType() == RftSourceType::OBSERVED) - selectedSources.insert(RimWellRftAddress(RftSourceType::OBSERVED)); - else - selectedSources.insert(curveDef.first); - - auto newTimeStepMap = std::map> - { - { curveDef.second, std::set { curveDef.first} } - }; - addTimeStepsToMap(selectedTimeStepsMap, newTimeStepMap); - selectedTimeSteps.insert(curveDef.second); - } - - m_selectedSources = std::vector(selectedSources.begin(), selectedSources.end()); - m_selectedTimeSteps = std::vector(selectedTimeSteps.begin(), selectedTimeSteps.end()); - addTimeStepsToMap(m_timeStepsToAddresses, selectedTimeStepsMap); +// std::set selectedSources; +// std::set selectedTimeSteps; +// std::map> selectedTimeStepsMap; +// +// for (const std::pair& curveDef : curveDefsFromCurves()) +// { +// if (curveDef.first.sourceType() == RftSourceType::OBSERVED) +// selectedSources.insert(RimWellRftAddress(RftSourceType::OBSERVED)); +// else +// selectedSources.insert(curveDef.first); +// +// auto newTimeStepMap = std::map> +// { +// { curveDef.second, std::set { curveDef.first} } +// }; +// addTimeStepsToMap(selectedTimeStepsMap, newTimeStepMap); +// selectedTimeSteps.insert(curveDef.second); +// } +// +// m_selectedSources = std::vector(selectedSources.begin(), selectedSources.end()); +// m_selectedTimeSteps = std::vector(selectedTimeSteps.begin(), selectedTimeSteps.end()); +// addTimeStepsToMap(m_timeStepsToAddresses, selectedTimeStepsMap); } //-------------------------------------------------------------------------------------------------- @@ -351,40 +438,14 @@ void RimWellPltPlot::updateWidgetTitleWindowTitle() void RimWellPltPlot::syncCurvesFromUiSelection() { RimWellLogTrack* plotTrack = m_wellLogPlot->trackByIndex(0); - const std::set>& allCurveDefs = selectedCurveDefs(); - const std::set>& curveDefsInPlot = curveDefsFromCurves(); - std::set curvesToDelete; - std::set> newCurveDefs; - - if (allCurveDefs.size() < curveDefsInPlot.size()) - { - // Determine which curves to delete from plot - std::set> deleteCurveDefs; - std::set_difference(curveDefsInPlot.begin(), curveDefsInPlot.end(), - allCurveDefs.begin(), allCurveDefs.end(), - std::inserter(deleteCurveDefs, deleteCurveDefs.end())); - - for (RimWellLogCurve* const curve : plotTrack->curvesVector()) - { - std::pair curveDef = curveDefFromCurve(curve); - if (deleteCurveDefs.count(curveDef) > 0) - curvesToDelete.insert(curve); - } - } - else - { - // Determine which curves are new since last time - std::set_difference(allCurveDefs.begin(), allCurveDefs.end(), - curveDefsInPlot.begin(), curveDefsInPlot.end(), - std::inserter(newCurveDefs, newCurveDefs.end())); - } - updateCurvesInPlot(allCurveDefs, newCurveDefs, curvesToDelete); + const std::set>& curveDefs = selectedCurveDefs(); + updateCurvesInPlot(curveDefs); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimWellPltPlot::wellLogFilesContainingPressure(const QString& wellName) const +std::vector RimWellPltPlot::wellLogFilesContainingFlow(const QString& wellName) const { std::vector wellLogFiles; const RimProject* const project = RiaApplication::instance()->project(); @@ -405,7 +466,7 @@ std::vector RimWellPltPlot::wellLogFilesContainingPressure(cons if (timeStepCount == 0) continue; if (QString::compare(file->wellName(), wellName) != 0) continue; - if (hasPressureData(file)) + if (hasFlowData(file)) { wellLogFiles.push_back(file); } @@ -418,19 +479,20 @@ std::vector RimWellPltPlot::wellLogFilesContainingPressure(cons //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogFileChannel* RimWellPltPlot::getPressureChannelFromWellFile(const RimWellLogFile* wellLogFile) const +std::vector RimWellPltPlot::getFlowChannelsFromWellFile(const RimWellLogFile* wellLogFile) const { + std::vector channels; if(wellLogFile != nullptr) { for (RimWellLogFileChannel* const channel : wellLogFile->wellLogChannels()) { - if (isPressureChannel(channel)) + if (isFlowChannel(channel)) { - return channel; + channels.push_back(channel); } } } - return nullptr; + return channels; } //-------------------------------------------------------------------------------------------------- @@ -461,120 +523,120 @@ RimWellPath* RimWellPltPlot::wellPathFromWellLogFile(const RimWellLogFile* wellL //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector> -RimWellPltPlot::eclipseCasesForWell(const QString& wellName) const -{ - std::vector> cases; - const RimProject* const project = RiaApplication::instance()->project(); - - for (const auto& oilField : project->oilFields) - { - const RimEclipseCaseCollection* const eclCaseColl = oilField->analysisModels(); - for (RimEclipseCase* eCase : eclCaseColl->cases()) - { - auto eclCase = dynamic_cast(eCase); - if (eclCase != nullptr) - { - RigEclipseCaseData* const eclipseCaseData = eclCase->eclipseCaseData(); - for (const cvf::ref& wellResult : eclipseCaseData->wellResults()) - { - if (QString::compare(wellResult->m_wellName, wellName) == 0) - { - bool hasPressure = hasPressureData(eclCase); - bool hasRftData = eclCase->rftReader() != nullptr; - cases.push_back(std::make_tuple(eclCase, hasPressure, hasRftData)); - break; - } - } - } - } - } - return cases; -} +//std::vector> +//RimWellPltPlot::eclipseCasesForWell(const QString& wellName) const +//{ +// std::vector> cases; +// const RimProject* const project = RiaApplication::instance()->project(); +// +// for (const auto& oilField : project->oilFields) +// { +// const RimEclipseCaseCollection* const eclCaseColl = oilField->analysisModels(); +// for (RimEclipseCase* eCase : eclCaseColl->cases()) +// { +// auto eclCase = dynamic_cast(eCase); +// if (eclCase != nullptr) +// { +// RigEclipseCaseData* const eclipseCaseData = eclCase->eclipseCaseData(); +// for (const cvf::ref& wellResult : eclipseCaseData->wellResults()) +// { +// if (QString::compare(wellResult->m_wellName, wellName) == 0) +// { +// bool hasPressure = hasPressureData(eclCase); +// bool hasRftData = eclCase->rftReader() != nullptr; +// cases.push_back(std::make_tuple(eclCase, hasPressure, hasRftData)); +// break; +// } +// } +// } +// } +// } +// return cases; +//} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector -RimWellPltPlot::gridCasesFromEclipseCases(const std::vector>& eclipseCasesTuple) const -{ - std::vector cases; - for (const std::tuple& eclCaseTuple : eclipseCasesTuple) - { - bool hasPressureData = std::get<1>(eclCaseTuple); - size_t timeStepCount = timeStepsFromGridCase(std::get<0>(eclCaseTuple)).size(); - if (hasPressureData && timeStepCount > 0) - { - cases.push_back(std::get<0>(eclCaseTuple)); - } - } - return cases; -} +//std::vector +//RimWellPltPlot::gridCasesFromEclipseCases(const std::vector>& eclipseCasesTuple) const +//{ +// std::vector cases; +// for (const std::tuple& eclCaseTuple : eclipseCasesTuple) +// { +// bool hasPressureData = std::get<1>(eclCaseTuple); +// size_t timeStepCount = timeStepsFromGridCase(std::get<0>(eclCaseTuple)).size(); +// if (hasPressureData && timeStepCount > 0) +// { +// cases.push_back(std::get<0>(eclCaseTuple)); +// } +// } +// return cases; +//} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector -RimWellPltPlot::rftCasesFromEclipseCases(const std::vector>& eclipseCasesTuple) const -{ - std::vector cases; - for (const std::tuple& eclCaseTuple : eclipseCasesTuple) - { - bool hasRftData = std::get<2>(eclCaseTuple); - size_t timeStepCount = timeStepsFromRftCase(std::get<0>(eclCaseTuple)).size(); - if (hasRftData && timeStepCount > 0) - { - cases.push_back(std::get<0>(eclCaseTuple)); - } - } - return cases; -} +//std::vector +//RimWellPltPlot::rftCasesFromEclipseCases(const std::vector>& eclipseCasesTuple) const +//{ +// std::vector cases; +// for (const std::tuple& eclCaseTuple : eclipseCasesTuple) +// { +// bool hasRftData = std::get<2>(eclCaseTuple); +// size_t timeStepCount = timeStepsFromRftCase(std::get<0>(eclCaseTuple)).size(); +// if (hasRftData && timeStepCount > 0) +// { +// cases.push_back(std::get<0>(eclCaseTuple)); +// } +// } +// return cases; +//} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::map> RimWellPltPlot::timeStepsFromRftCase(RimEclipseResultCase* rftCase) const -{ - std::map> timeStepsMap; - RifReaderEclipseRft* const reader = rftCase->rftReader(); - if (reader != nullptr) - { - for (const QDateTime& timeStep : reader->availableTimeSteps(m_wellName, RifEclipseRftAddress::PRESSURE)) - { - if (timeStepsMap.count(timeStep) == 0) - { - timeStepsMap.insert(std::make_pair(timeStep, std::set())); - } - timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::RFT, rftCase)); - } - } - return timeStepsMap; -} +//std::map> RimWellPltPlot::timeStepsFromRftCase(RimEclipseResultCase* rftCase) const +//{ +// std::map> timeStepsMap; +// RifReaderEclipseRft* const reader = rftCase->rftReader(); +// if (reader != nullptr) +// { +// for (const QDateTime& timeStep : reader->availableTimeSteps(m_wellName, RifEclipseRftAddress::PRESSURE)) +// { +// if (timeStepsMap.count(timeStep) == 0) +// { +// timeStepsMap.insert(std::make_pair(timeStep, std::set())); +// } +// timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::RFT, rftCase)); +// } +// } +// return timeStepsMap; +//} //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::map> RimWellPltPlot::timeStepsFromGridCase(RimEclipseCase* gridCase) const -{ - const RigEclipseCaseData* const eclipseCaseData = gridCase->eclipseCaseData(); - size_t resultIndex = eclipseCaseData != nullptr ? - eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, PRESSURE_DATA_NAME) : - cvf::UNDEFINED_SIZE_T; - - std::map> timeStepsMap; - if (resultIndex != cvf::UNDEFINED_SIZE_T) - { - for (const QDateTime& timeStep : eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->timeStepDates(resultIndex)) - { - if (timeStepsMap.count(timeStep) == 0) - { - timeStepsMap.insert(std::make_pair(timeStep, std::set())); - } - timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::GRID, gridCase)); - } - } - return timeStepsMap; -} +//std::map> RimWellPltPlot::timeStepsFromGridCase(RimEclipseCase* gridCase) const +//{ +// const RigEclipseCaseData* const eclipseCaseData = gridCase->eclipseCaseData(); +// size_t resultIndex = eclipseCaseData != nullptr ? +// eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, PRESSURE_DATA_NAME) : +// cvf::UNDEFINED_SIZE_T; +// +// std::map> timeStepsMap; +// if (resultIndex != cvf::UNDEFINED_SIZE_T) +// { +// for (const QDateTime& timeStep : eclipseCaseData->results(RiaDefines::MATRIX_MODEL)->timeStepDates(resultIndex)) +// { +// if (timeStepsMap.count(timeStep) == 0) +// { +// timeStepsMap.insert(std::make_pair(timeStep, std::set())); +// } +// timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::GRID, gridCase)); +// } +// } +// return timeStepsMap; +//} //-------------------------------------------------------------------------------------------------- /// @@ -642,37 +704,38 @@ bool RimWellPltPlot::mapContainsTimeStep(const std::map> RimWellPltPlot::selectedCurveDefs() const { std::set> curveDefs; - const std::vector>& eclipseCases = eclipseCasesForWell(m_wellName); - const std::vector rftCases = rftCasesFromEclipseCases(eclipseCases); - const std::vector gridCases = gridCasesFromEclipseCases(eclipseCases); + //const std::vector>& eclipseCases = eclipseCasesForWell(m_wellName); + //const std::vector rftCases = rftCasesFromEclipseCases(eclipseCases); + //const std::vector gridCases = gridCasesFromEclipseCases(eclipseCases); for (const QDateTime& timeStep : m_selectedTimeSteps()) { for (const RimWellRftAddress& addr : selectedSources()) { - if (addr.sourceType() == RftSourceType::RFT) - { - for (RimEclipseResultCase* const rftCase : rftCases) - { - const std::map>& timeStepsMap = timeStepsFromRftCase(rftCase); - if (mapContainsTimeStep(timeStepsMap , timeStep)) - { - curveDefs.insert(std::make_pair(addr, timeStep)); - } - } - } - else if (addr.sourceType() == RftSourceType::GRID) - { - for (RimEclipseResultCase* const gridCase : gridCases) - { - const std::map>& timeStepsMap = timeStepsFromGridCase(gridCase); - if (mapContainsTimeStep(timeStepsMap, timeStep)) - { - curveDefs.insert(std::make_pair(addr, timeStep)); - } - } - } - else if (addr.sourceType() == RftSourceType::OBSERVED) + //if (addr.sourceType() == RftSourceType::RFT) + //{ + // for (RimEclipseResultCase* const rftCase : rftCases) + // { + // const std::map>& timeStepsMap = timeStepsFromRftCase(rftCase); + // if (mapContainsTimeStep(timeStepsMap , timeStep)) + // { + // curveDefs.insert(std::make_pair(addr, timeStep)); + // } + // } + //} + //else if (addr.sourceType() == RftSourceType::GRID) + //{ + // for (RimEclipseResultCase* const gridCase : gridCases) + // { + // const std::map>& timeStepsMap = timeStepsFromGridCase(gridCase); + // if (mapContainsTimeStep(timeStepsMap, timeStep)) + // { + // curveDefs.insert(std::make_pair(addr, timeStep)); + // } + // } + //} + //else + if (addr.sourceType() == RftSourceType::OBSERVED) { if (addr.wellLogFile() != nullptr) { @@ -712,33 +775,34 @@ std::pair RimWellPltPlot::curveDefFromCurve(const const RimWellLogExtractionCurve* gridCurve = dynamic_cast(curve); const RimWellLogFileCurve* wellLogFileCurve = dynamic_cast(curve); - if (rftCurve != nullptr) - { - RimEclipseResultCase* rftCase = dynamic_cast(rftCurve->eclipseResultCase()); - if (rftCase != nullptr) - { - const RifEclipseRftAddress rftAddress = rftCurve->rftAddress(); - const QDateTime timeStep = rftAddress.timeStep(); - return std::make_pair(RimWellRftAddress(RftSourceType::RFT, rftCase), timeStep); - } - } - else if (gridCurve != nullptr) - { - RimEclipseResultCase* gridCase = dynamic_cast(gridCurve->rimCase()); - if (gridCase != nullptr) - { - size_t timeStepIndex = gridCurve->currentTimeStep(); - const std::map>& timeStepsMap = timeStepsFromGridCase(gridCase); - auto timeStepsVector = std::vector>>( - timeStepsMap.begin(), timeStepsMap.end()); - if (timeStepIndex < timeStepsMap.size()) - { - return std::make_pair(RimWellRftAddress(RftSourceType::GRID, gridCase), - timeStepsVector[timeStepIndex].first); - } - } - } - else if (wellLogFileCurve != nullptr) + //if (rftCurve != nullptr) + //{ + // RimEclipseResultCase* rftCase = dynamic_cast(rftCurve->eclipseResultCase()); + // if (rftCase != nullptr) + // { + // const RifEclipseRftAddress rftAddress = rftCurve->rftAddress(); + // const QDateTime timeStep = rftAddress.timeStep(); + // return std::make_pair(RimWellRftAddress(RftSourceType::RFT, rftCase), timeStep); + // } + //} + //else if (gridCurve != nullptr) + //{ + // RimEclipseResultCase* gridCase = dynamic_cast(gridCurve->rimCase()); + // if (gridCase != nullptr) + // { + // size_t timeStepIndex = gridCurve->currentTimeStep(); + // const std::map>& timeStepsMap = timeStepsFromGridCase(gridCase); + // auto timeStepsVector = std::vector>>( + // timeStepsMap.begin(), timeStepsMap.end()); + // if (timeStepIndex < timeStepsMap.size()) + // { + // return std::make_pair(RimWellRftAddress(RftSourceType::GRID, gridCase), + // timeStepsVector[timeStepIndex].first); + // } + // } + //} + //else + if (wellLogFileCurve != nullptr) { const RimWellPath* const wellPath = wellLogFileCurve->wellPath(); RimWellLogFile* const wellLogFile = wellLogFileCurve->wellLogFile(); @@ -759,90 +823,122 @@ std::pair RimWellPltPlot::curveDefFromCurve(const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPltPlot::updateCurvesInPlot(const std::set>& allCurveDefs, - const std::set>& curveDefsToAdd, - const std::set& curvesToDelete) +void RimWellPltPlot::updateCurvesInPlot(const std::set>& curveDefs) { RimWellLogTrack* const plotTrack = m_wellLogPlot->trackByIndex(0); - // Delete curves - for (RimWellLogCurve* const curve : curvesToDelete) + setPlotXAxisTitles(plotTrack); + + // Delete existing curves + const auto& curves = plotTrack->curvesVector(); + for (const auto& curve : curves) { plotTrack->removeCurve(curve); } - // Add new curves - for (const std::pair& curveDefToAdd : curveDefsToAdd) + // Add curves + for (const std::pair& curveDefToAdd : curveDefs) { - if (curveDefToAdd.first.sourceType() == RftSourceType::RFT) - { - auto curve = new RimWellLogRftCurve(); - plotTrack->addCurve(curve); + //if (curveDefToAdd.first.sourceType() == RftSourceType::RFT) + //{ + // auto curve = new RimWellLogRftCurve(); + // plotTrack->addCurve(curve); - auto rftCase = curveDefToAdd.first.eclCase(); - curve->setEclipseResultCase(dynamic_cast(rftCase)); + // auto rftCase = curveDefToAdd.first.eclCase(); + // curve->setEclipseResultCase(dynamic_cast(rftCase)); - RifEclipseRftAddress address(m_wellName, curveDefToAdd.second, RifEclipseRftAddress::PRESSURE); - curve->setRftAddress(address); - curve->setZOrder(1); + // RifEclipseRftAddress address(m_wellName, curveDefToAdd.second, RifEclipseRftAddress::PRESSURE); + // curve->setRftAddress(address); + // curve->setZOrder(1); - applyCurveAppearance(curve); - curve->loadDataAndUpdate(true); - } - else if (curveDefToAdd.first.sourceType() == RftSourceType::GRID) - { - auto curve = new RimWellLogExtractionCurve(); - plotTrack->addCurve(curve); + // applyCurveAppearance(curve); + // curve->loadDataAndUpdate(true); + //} + //else if (curveDefToAdd.first.sourceType() == RftSourceType::GRID) + //{ + // auto curve = new RimWellLogExtractionCurve(); + // plotTrack->addCurve(curve); - cvf::Color3f curveColor = RiaColorTables::wellLogPlotPaletteColors().cycledColor3f(plotTrack->curveCount()); - curve->setColor(curveColor); - curve->setFromSimulationWellName(m_wellName, m_branchIndex); + // cvf::Color3f curveColor = RiaColorTables::wellLogPlotPaletteColors().cycledColor3f(plotTrack->curveCount()); + // curve->setColor(curveColor); + // curve->setFromSimulationWellName(m_wellName, m_branchIndex); - // Fetch cases and time steps - auto gridCase = curveDefToAdd.first.eclCase(); - if (gridCase != nullptr) - { - // Case - curve->setCase(gridCase); + // // Fetch cases and time steps + // auto gridCase = curveDefToAdd.first.eclCase(); + // if (gridCase != nullptr) + // { + // // Case + // curve->setCase(gridCase); - // Result definition - RimEclipseResultDefinition* resultDef = new RimEclipseResultDefinition(); - resultDef->setResultVariable(PRESSURE_DATA_NAME); - curve->setEclipseResultDefinition(resultDef); + // // Result definition + // RimEclipseResultDefinition* resultDef = new RimEclipseResultDefinition(); + // resultDef->setResultVariable(PRESSURE_DATA_NAME); + // curve->setEclipseResultDefinition(resultDef); - // Time step - const std::map>& timeSteps = timeStepsFromGridCase(gridCase); - auto currentTimeStepItr = std::find_if(timeSteps.begin(), timeSteps.end(), - [curveDefToAdd](std::pair> pair) {return pair.first == curveDefToAdd.second; }); - auto currentTimeStepIndex = std::distance(timeSteps.begin(), currentTimeStepItr); - curve->setCurrentTimeStep(currentTimeStepIndex); - curve->setZOrder(0); + // // Time step + // const std::map>& timeSteps = timeStepsFromGridCase(gridCase); + // auto currentTimeStepItr = std::find_if(timeSteps.begin(), timeSteps.end(), + // [curveDefToAdd](std::pair> pair) {return pair.first == curveDefToAdd.second; }); + // auto currentTimeStepIndex = std::distance(timeSteps.begin(), currentTimeStepItr); + // curve->setCurrentTimeStep(currentTimeStepIndex); + // curve->setZOrder(0); - applyCurveAppearance(curve); - curve->loadDataAndUpdate(false); - } - } - else if (curveDefToAdd.first.sourceType() == RftSourceType::OBSERVED) + // applyCurveAppearance(curve); + // curve->loadDataAndUpdate(false); + // } + //} + //else + if (curveDefToAdd.first.sourceType() == RftSourceType::OBSERVED) { RimWellLogFile* const wellLogFile = curveDefToAdd.first.wellLogFile(); RimWellPath* const wellPath = wellPathFromWellLogFile(wellLogFile); if(wellLogFile!= nullptr) { - RimWellLogFileChannel* pressureChannel = getPressureChannelFromWellFile(wellLogFile); - auto curve = new RimWellLogFileCurve(); - plotTrack->addCurve(curve); - curve->setWellPath(wellPath); - curve->setWellLogFile(wellLogFile); - curve->setWellLogChannelName(pressureChannel->name()); - curve->setZOrder(2); + std::set selectedPhases = m_phaseSelectionMode == FLOW_TYPE_PHASE_SPLIT ? + std::set(m_phases().begin(), m_phases().end()) : + std::set({ PHASE_TOTAL }); - applyCurveAppearance(curve); - curve->loadDataAndUpdate(true); + RigWellLogFile* rigWellLogFile = wellLogFile->wellLogFile(); + + if (rigWellLogFile != nullptr) + { + for (RimWellLogFileChannel* channel : getFlowChannelsFromWellFile(wellLogFile)) + { + const auto& channelName = channel->name(); + if (selectedPhases.count(flowPhaseFromChannelName(channelName)) > 0) + { + + addStackedCurve(channelName, rigWellLogFile->depthValues(), rigWellLogFile->values(channelName), plotTrack); + } + } + } } } } } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPltPlot::addStackedCurve(const QString& channelName, + const std::vector& depthValues, + const std::vector& accFlow, + RimWellLogTrack* plotTrack) +{ + RimWellFlowRateCurve* curve = new RimWellFlowRateCurve; + curve->setFlowValuesPrDepthValue(channelName, depthValues, accFlow); + + auto color = channelName == OIL_CHANNEL_NAME ? cvf::Color3f::DARK_GREEN : + channelName == GAS_CHANNEL_NAME ? cvf::Color3f::DARK_RED : + channelName == WATER_CHANNEL_NAME ? cvf::Color3f::BLUE : + cvf::Color3f::DARK_GRAY; + curve->setColor(color); + + plotTrack->addCurve(curve); + + curve->loadDataAndUpdate(true); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -879,7 +975,7 @@ std::vector RimWellPltPlot::selectedSources() const { if (addr.sourceType() == RftSourceType::OBSERVED) { - for (RimWellLogFile* const wellLogFile : wellLogFilesContainingPressure(m_wellName)) + for (RimWellLogFile* const wellLogFile : wellLogFilesContainingFlow(m_wellName)) { sources.push_back(RimWellRftAddress(RftSourceType::OBSERVED, wellLogFile)); } @@ -933,11 +1029,11 @@ QString RimWellPltPlot::currentWellName() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellPltPlot::hasPressureData(const RimWellLogFile* wellLogFile) +bool RimWellPltPlot::hasFlowData(const RimWellLogFile* wellLogFile) { for (RimWellLogFileChannel* const wellLogChannel : wellLogFile->wellLogChannels()) { - if (isPressureChannel(wellLogChannel)) return true; + if (isFlowChannel(wellLogChannel)) return true; } return false; } @@ -945,11 +1041,11 @@ bool RimWellPltPlot::hasPressureData(const RimWellLogFile* wellLogFile) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellPltPlot::hasPressureData(RimWellPath* wellPath) +bool RimWellPltPlot::hasFlowData(RimWellPath* wellPath) { for (RimWellLogFile* const wellLogFile : wellPath->wellLogFiles()) { - if (hasPressureData(wellLogFile)) + if (hasFlowData(wellLogFile)) { return true; } @@ -960,21 +1056,26 @@ bool RimWellPltPlot::hasPressureData(RimWellPath* wellPath) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellPltPlot::isPressureChannel(RimWellLogFileChannel* channel) +bool RimWellPltPlot::isFlowChannel(RimWellLogFileChannel* channel) { - // Todo: read pressure channel names from config/defines - return QString::compare(channel->name(), PRESSURE_DATA_NAME) == 0; + return FLOW_DATA_NAMES.count(channel->name()) > 0; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellPltPlot::hasPressureData(RimEclipseResultCase* gridCase) +bool RimWellPltPlot::hasFlowData(RimEclipseResultCase* gridCase) { const RigEclipseCaseData* const eclipseCaseData = gridCase->eclipseCaseData(); - size_t resultIndex = eclipseCaseData->results(RiaDefines::MATRIX_MODEL)-> - findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, PRESSURE_DATA_NAME); - return resultIndex != cvf::UNDEFINED_SIZE_T; + + for (const QString& channelName : FLOW_DATA_NAMES) + { + size_t resultIndex = eclipseCaseData->results(RiaDefines::MATRIX_MODEL)-> + findScalarResultIndex(RiaDefines::DYNAMIC_NATIVE, channelName); + + if (resultIndex != cvf::UNDEFINED_SIZE_T) return true; + } + return false; } //-------------------------------------------------------------------------------------------------- @@ -998,35 +1099,35 @@ QList RimWellPltPlot::calculateValueOptions(const caf::P } else if (fieldNeedingOptions == &m_selectedSources) { - const std::vector>& eclipseCases = eclipseCasesForWell(m_wellName); + //const std::vector>& eclipseCases = eclipseCasesForWell(m_wellName); - const std::vector rftCases = rftCasesFromEclipseCases(eclipseCases); - if (rftCases.size() > 0) - { - options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::RFT), true)); - } - for (const auto& rftCase : rftCases) - { - auto addr = RimWellRftAddress(RftSourceType::RFT, rftCase); - auto item = caf::PdmOptionItemInfo(rftCase->caseUserDescription(), QVariant::fromValue(addr)); - item.setLevel(1); - options.push_back(item); - } + //const std::vector rftCases = rftCasesFromEclipseCases(eclipseCases); + //if (rftCases.size() > 0) + //{ + // options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::RFT), true)); + //} + //for (const auto& rftCase : rftCases) + //{ + // auto addr = RimWellRftAddress(RftSourceType::RFT, rftCase); + // auto item = caf::PdmOptionItemInfo(rftCase->caseUserDescription(), QVariant::fromValue(addr)); + // item.setLevel(1); + // options.push_back(item); + //} - const std::vector gridCases = gridCasesFromEclipseCases(eclipseCases); - if (gridCases.size() > 0) - { - options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::GRID), true)); - } - for (const auto& gridCase : gridCases) - { - auto addr = RimWellRftAddress(RftSourceType::GRID, gridCase); - auto item = caf::PdmOptionItemInfo(gridCase->caseUserDescription(), QVariant::fromValue(addr)); - item.setLevel(1); - options.push_back(item); - } + //const std::vector gridCases = gridCasesFromEclipseCases(eclipseCases); + //if (gridCases.size() > 0) + //{ + // options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::GRID), true)); + //} + //for (const auto& gridCase : gridCases) + //{ + // auto addr = RimWellRftAddress(RftSourceType::GRID, gridCase); + // auto item = caf::PdmOptionItemInfo(gridCase->caseUserDescription(), QVariant::fromValue(addr)); + // item.setLevel(1); + // options.push_back(item); + //} - if (wellLogFilesContainingPressure(m_wellName).size() > 0) + if (wellLogFilesContainingFlow(m_wellName).size() > 0) { options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::OBSERVED), true)); @@ -1057,6 +1158,16 @@ QList RimWellPltPlot::calculateValueOptions(const caf::P } } + if (fieldNeedingOptions == &m_phaseSelectionMode) + { + } + else if (fieldNeedingOptions == &m_phases) + { + options.push_back(caf::PdmOptionItemInfo("Oil", PHASE_OIL)); + options.push_back(caf::PdmOptionItemInfo("Gas", PHASE_GAS)); + options.push_back(caf::PdmOptionItemInfo("Water", PHASE_WATER)); + } + return options; } @@ -1092,12 +1203,17 @@ void RimWellPltPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c changedField == &m_selectedTimeSteps) { syncCurvesFromUiSelection(); - m_selectedSourcesOrTimeStepsFieldsChanged = true; } else if (changedField == &m_showPlotTitle) { //m_wellLogPlot->setShowDescription(m_showPlotTitle); } + + if (changedField == &m_phaseSelectionMode || + changedField == &m_phases) + { + syncCurvesFromUiSelection(); + } } //-------------------------------------------------------------------------------------------------- @@ -1121,11 +1237,11 @@ QImage RimWellPltPlot::snapshotWindowContent() //-------------------------------------------------------------------------------------------------- void RimWellPltPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { - if (!m_selectedSourcesOrTimeStepsFieldsChanged) - { - updateEditorsFromCurves(); - } - m_selectedSourcesOrTimeStepsFieldsChanged = false; + //if (!m_selectedSourcesOrTimeStepsFieldsChanged) + //{ + // updateEditorsFromCurves(); + //} + //m_selectedSourcesOrTimeStepsFieldsChanged = false; uiOrdering.add(&m_userName); uiOrdering.add(&m_wellName); @@ -1142,11 +1258,32 @@ void RimWellPltPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& caf::PdmUiGroup* timeStepsGroup = uiOrdering.addNewGroupWithKeyword("Time Steps", "TimeSteps"); timeStepsGroup->add(&m_selectedTimeSteps); + caf::PdmUiGroup* flowGroup = uiOrdering.addNewGroupWithKeyword("Phase Selection", "PhaseSelection"); + flowGroup->add(&m_phaseSelectionMode); + + if (m_phaseSelectionMode == FLOW_TYPE_PHASE_SPLIT) + { + flowGroup->add(&m_phases); + } + //uiOrdering.add(&m_showPlotTitle); uiOrdering.skipRemainingFields(true); } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellPltPlot::defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute) +{ + if (field == &m_phases) + { + caf::PdmUiTreeSelectionEditorAttribute* attrib = dynamic_cast (attribute); + attrib->showTextFilter = false; + attrib->showToggleAllCheckbox = false; + } +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -1213,27 +1350,28 @@ void RimWellPltPlot::calculateValueOptionsForWells(QList void RimWellPltPlot::calculateValueOptionsForTimeSteps(const QString& wellName, QList& options) { std::map> displayTimeStepsMap, obsAndRftTimeStepsMap, gridTimeStepsMap; - const std::vector>& eclipseCases = eclipseCasesForWell(wellName); - const std::vector rftCases = rftCasesFromEclipseCases(eclipseCases); - const std::vector gridCases = gridCasesFromEclipseCases(eclipseCases); + //const std::vector>& eclipseCases = eclipseCasesForWell(wellName); + //const std::vector rftCases = rftCasesFromEclipseCases(eclipseCases); + //const std::vector gridCases = gridCasesFromEclipseCases(eclipseCases); for (const RimWellRftAddress& selection : selectedSources()) { - if (selection.sourceType() == RftSourceType::RFT) - { - for (RimEclipseResultCase* const rftCase : rftCases) - { - addTimeStepsToMap(obsAndRftTimeStepsMap, timeStepsFromRftCase(rftCase)); - } - } - else if (selection.sourceType() == RftSourceType::GRID) - { - for (RimEclipseResultCase* const gridCase : gridCases) - { - addTimeStepsToMap(gridTimeStepsMap, timeStepsFromGridCase(gridCase)); - } - } - else if (selection.sourceType() == RftSourceType::OBSERVED) + //if (selection.sourceType() == RftSourceType::RFT) + //{ + // for (RimEclipseResultCase* const rftCase : rftCases) + // { + // addTimeStepsToMap(obsAndRftTimeStepsMap, timeStepsFromRftCase(rftCase)); + // } + //} + //else if (selection.sourceType() == RftSourceType::GRID) + //{ + // for (RimEclipseResultCase* const gridCase : gridCases) + // { + // addTimeStepsToMap(gridTimeStepsMap, timeStepsFromGridCase(gridCase)); + // } + //} + //else + if (selection.sourceType() == RftSourceType::OBSERVED) { if (selection.wellLogFile() != nullptr) { diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.h index 44f80aec98..ebdfe0f82d 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellPltPlot.h @@ -20,6 +20,7 @@ #include "RimViewWindow.h" +#include "RigFlowDiagResultAddress.h" #include "cafPdmField.h" #include "cafPdmObject.h" @@ -41,6 +42,8 @@ class RimWellLogFileChannel; class RimWellLogPlot; class RimWellPath; class RiuWellPltPlot; +class RimWellLogTrack; + namespace cvf { class Color3f; @@ -59,7 +62,15 @@ class RimWellPltPlot : public RimViewWindow { CAF_PDM_HEADER_INIT; - static const char PRESSURE_DATA_NAME[]; + enum FlowType { FLOW_TYPE_TOTAL, FLOW_TYPE_PHASE_SPLIT }; + enum FlowPhase { PHASE_NONE, PHASE_OIL, PHASE_GAS, PHASE_WATER, PHASE_TOTAL }; + + static const QString OIL_CHANNEL_NAME; + static const QString GAS_CHANNEL_NAME; + static const QString WATER_CHANNEL_NAME; + static const QString TOTAL_CHANNEL_NAME; + + static const std::set FLOW_DATA_NAMES; static const char PLOT_NAME_QFORMAT_STRING[]; public: @@ -79,13 +90,13 @@ public: void setCurrentWellName(const QString& currWellName); QString currentWellName() const; - static bool hasPressureData(const RimWellLogFile* wellLogFile); - static bool isPressureChannel(RimWellLogFileChannel* channel); - static bool hasPressureData(RimEclipseResultCase* gridCase); - static bool hasPressureData(RimWellPath* wellPath); + static bool hasFlowData(const RimWellLogFile* wellLogFile); + static bool isFlowChannel(RimWellLogFileChannel* channel); + static bool hasFlowData(RimEclipseResultCase* gridCase); + static bool hasFlowData(RimWellPath* wellPath); static const char* plotNameFormatString(); - void applyInitialSelections(); + //void applyInitialSelections(); protected: // Overridden PDM methods @@ -98,6 +109,7 @@ protected: virtual void defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) override; + virtual void defineEditorAttribute(const caf::PdmFieldHandle* field, QString uiConfigName, caf::PdmUiEditorAttribute* attribute); private: void addTimeStepToMap(std::map>& destMap, @@ -112,16 +124,16 @@ private: void syncCurvesFromUiSelection(); - std::vector wellLogFilesContainingPressure(const QString& wellName) const; - RimWellLogFileChannel* getPressureChannelFromWellFile(const RimWellLogFile* wellLogFile) const; + std::vector wellLogFilesContainingFlow(const QString& wellName) const; + std::vector getFlowChannelsFromWellFile(const RimWellLogFile* wellLogFile) const; RimWellPath* wellPathFromWellLogFile(const RimWellLogFile* wellLogFile) const; - std::vector> eclipseCasesForWell(const QString& wellName) const; - std::vector gridCasesFromEclipseCases(const std::vector>& eclipseCasesTuple) const; - std::vector rftCasesFromEclipseCases(const std::vector>& eclipseCasesTuple) const; - std::map> timeStepsFromRftCase(RimEclipseResultCase* gridCase) const; - std::map> timeStepsFromGridCase(RimEclipseCase* gridCase) const; + //std::vector> eclipseCasesForWell(const QString& wellName) const; + //std::vector gridCasesFromEclipseCases(const std::vector>& eclipseCasesTuple) const; + //std::vector rftCasesFromEclipseCases(const std::vector>& eclipseCasesTuple) const; + //std::map> timeStepsFromRftCase(RimEclipseResultCase* gridCase) const; + //std::map> timeStepsFromGridCase(RimEclipseCase* gridCase) const; std::map> timeStepsFromWellLogFile(RimWellLogFile* wellLogFile) const; std::map> adjacentTimeSteps(const std::vector>>& allTimeSteps, const std::pair>& searchTimeStepPair); @@ -130,9 +142,12 @@ private: std::set> selectedCurveDefs() const; std::set> curveDefsFromCurves() const; std::pair curveDefFromCurve(const RimWellLogCurve* curve) const; - void updateCurvesInPlot(const std::set>& allCurveDefs, - const std::set>& curveDefsToAdd, - const std::set& curvesToDelete); + void updateCurvesInPlot(const std::set>& curveDefs); + void addStackedCurve(const QString& tracerName, + const std::vector& depthValues, + const std::vector& accFlow, + RimWellLogTrack* plotTrack); + bool isOnlyGridSourcesSelected() const; bool isAnySourceAddressSelected(const std::set& addresses) const; std::vector selectedSources() const; @@ -142,8 +157,11 @@ private: virtual QWidget* createViewWidget(QWidget* mainWindowParent) override; virtual void deleteViewWidget() override; - void applyCurveAppearance(RimWellLogCurve* newCurve); + //void applyCurveAppearance(RimWellLogCurve* newCurve); void updateSelectedTimeStepsFromSelectedSources(); + static FlowPhase flowPhaseFromChannelName(const QString& channelName); + void setPlotXAxisTitles(RimWellLogTrack* plotTrack); + std::vector eclipseCases() const; private: caf::PdmField m_showPlotTitle; @@ -161,5 +179,6 @@ private: std::map> m_timeStepsToAddresses; - bool m_selectedSourcesOrTimeStepsFieldsChanged; + caf::PdmField> m_phaseSelectionMode; + caf::PdmField>> m_phases; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp index 61def64358..0cc5716304 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.cpp @@ -26,6 +26,8 @@ #include "RimWellAllocationPlot.h" #include "RimWellLogCurve.h" #include "RimWellLogTrack.h" +#include "RimWellRftPlot.h" +#include "RimWellPltPlot.h" #include "RiuMainPlotWindow.h" #include "RiuWellLogPlot.h" @@ -34,7 +36,6 @@ #include "cvfAssert.h" #include -#include "RimWellRftPlot.h" #define RI_LOGPLOT_MINDEPTH_DEFAULT 0.0 #define RI_LOGPLOT_MAXDEPTH_DEFAULT 1000.0 @@ -503,6 +504,24 @@ bool RimWellLogPlot::isRftPlotChild() const return rftPlot() != nullptr; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellPltPlot* RimWellLogPlot::pltPlot() const +{ + RimWellPltPlot* pltPlot; + firstAncestorOrThisOfType(pltPlot); + return pltPlot; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellLogPlot::isPltPlotChild() const +{ + return pltPlot() != nullptr; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -815,6 +834,11 @@ void RimWellLogPlot::updateDisabledDepthTypes() m_disabledDepthTypes.insert(PSEUDO_LENGTH); m_disabledDepthTypes.insert(CONNECTION_NUMBER); } + else if (isPltPlotChild()) + { + m_disabledDepthTypes.insert(TRUE_VERTICAL_DEPTH); + m_disabledDepthTypes.insert(CONNECTION_NUMBER); + } else { m_disabledDepthTypes.insert(PSEUDO_LENGTH); diff --git a/ApplicationCode/ProjectDataModel/RimWellLogPlot.h b/ApplicationCode/ProjectDataModel/RimWellLogPlot.h index 04f5da2cce..bfc409f8dc 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogPlot.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogPlot.h @@ -32,6 +32,7 @@ class RiuWellLogPlot; class RimWellLogTrack; class RimWellRftPlot; +class RimWellPltPlot; //================================================================================================== @@ -104,6 +105,8 @@ public: RimWellRftPlot* rftPlot() const; bool isRftPlotChild() const; + RimWellPltPlot* pltPlot() const; + bool isPltPlotChild() const; protected: