diff --git a/ApplicationCode/Commands/RicWellLogTools.cpp b/ApplicationCode/Commands/RicWellLogTools.cpp index faeabfd294..06f90441b7 100644 --- a/ApplicationCode/Commands/RicWellLogTools.cpp +++ b/ApplicationCode/Commands/RicWellLogTools.cpp @@ -137,7 +137,7 @@ RimWellPath* RicWellLogTools::selectedWellPathWithLogFile() if (selection.size() > 0) { RimWellPath* wellPath = selection[0]; - if (wellPath->wellLogFile()) + if (wellPath->wellLogFiles().size() > 0) { return wellPath; } diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewRftPlotFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewRftPlotFeature.cpp index 2fad3fa953..9f8cf25902 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewRftPlotFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewRftPlotFeature.cpp @@ -57,8 +57,6 @@ bool RicNewRftPlotFeature::isCommandEnabled() { if (RicWellLogPlotCurveFeatureImpl::parentWellAllocationPlot()) return false; - //int branchIndex; - RimSimWellInView* simWell = caf::firstAncestorOfTypeFromSelectedObject(); RimWellPath* rimWellPath = simWell == nullptr ? caf::firstAncestorOfTypeFromSelectedObject() : nullptr; @@ -73,11 +71,7 @@ bool RicNewRftPlotFeature::isCommandEnabled() } else if (rimWellPath) { - auto wellLogFile = rimWellPath->wellLogFile(); - if (wellLogFile != nullptr) - { - enable &= RimWellRftPlot::hasPressureData(wellLogFile); - } + enable &= RimWellRftPlot::hasPressureData(rimWellPath); } return enable; } diff --git a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp index f9e031aca5..dbdbc74538 100644 --- a/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp +++ b/ApplicationCode/Commands/WellLogCommands/RicNewWellLogFileCurveFeature.cpp @@ -97,12 +97,9 @@ bool RicNewWellLogFileCurveFeature::wellLogFilesAvailable() const for (size_t i = 0; i < wellPaths.size(); i++) { - if (wellPaths[i]->wellLogFile()) + if (wellPaths[i]->wellLogFiles().size() > 0) { - if (wellPaths[i]->wellLogFile()->wellLogFile()) - { - return true; - } + return true; } } } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.cpp index 356a2a6f7e..771692b505 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.cpp @@ -17,7 +17,11 @@ ///////////////////////////////////////////////////////////////////////////////// #include "RimWellRftAddress.h" +#include "RimEclipseCase.h" +#include "RimWellLogFile.h" + #include "cafAppEnum.h" +#include "cvfAssert.h" #include #include @@ -34,10 +38,34 @@ namespace caf } } -RimWellRftAddress::RimWellRftAddress(RftSourceType sourceType , int caseId) +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellRftAddress::RimWellRftAddress() : m_sourceType(RftSourceType::NONE) { +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellRftAddress::RimWellRftAddress(RftSourceType sourceType, RimEclipseCase* eclCase) +{ + CVF_ASSERT(sourceType == RftSourceType::RFT || sourceType == RftSourceType::GRID); + CVF_ASSERT(eclCase != nullptr); + m_sourceType = sourceType; - m_caseId = caseId; + m_eclCase = eclCase; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellRftAddress::RimWellRftAddress(RftSourceType sourceType, RimWellLogFile* wellLogFile) +{ + CVF_ASSERT(sourceType == RftSourceType::OBSERVED); + + m_sourceType = sourceType; + m_wellLogFile = wellLogFile; } //-------------------------------------------------------------------------------------------------- @@ -51,19 +79,17 @@ RftSourceType RimWellRftAddress::sourceType() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -int RimWellRftAddress::caseId() const +RimEclipseCase* RimWellRftAddress::eclCase() const { - return m_caseId; + return m_eclCase; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -QString RimWellRftAddress::uiText() const +RimWellLogFile* RimWellRftAddress::wellLogFile() const { - return m_caseId >= 0 ? - QString("%1 %2").arg(sourceTypeUiText(m_sourceType), QString::number(m_caseId)) : - QString("%1").arg(sourceTypeUiText(m_sourceType)); + return m_wellLogFile; } //-------------------------------------------------------------------------------------------------- @@ -85,7 +111,9 @@ QString RimWellRftAddress::sourceTypeUiText(RftSourceType sourceType) //-------------------------------------------------------------------------------------------------- bool operator==(const RimWellRftAddress& addr1, const RimWellRftAddress& addr2) { - return addr1.sourceType() == addr2.sourceType() && addr1.caseId() == addr2.caseId(); + return addr1.sourceType() == addr2.sourceType() + && addr1.eclCase() == addr2.eclCase() + && addr1.wellLogFile() == addr2.wellLogFile(); } //-------------------------------------------------------------------------------------------------- @@ -93,7 +121,8 @@ bool operator==(const RimWellRftAddress& addr1, const RimWellRftAddress& addr2) //-------------------------------------------------------------------------------------------------- QTextStream& operator << (QTextStream& str, const RimWellRftAddress& addr) { - str << RimWellRftAddress::sourceTypeUiText(addr.sourceType()) << " " << addr.caseId(); + // Not implemented + CVF_ASSERT(false); return str; } @@ -102,25 +131,8 @@ QTextStream& operator << (QTextStream& str, const RimWellRftAddress& addr) //-------------------------------------------------------------------------------------------------- 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; + // Not implemented + CVF_ASSERT(false); return str; } @@ -130,6 +142,8 @@ QTextStream& operator >> (QTextStream& str, RimWellRftAddress& source) bool operator<(const RimWellRftAddress& addr1, const RimWellRftAddress& addr2) { return (addr1.m_sourceType < addr2.m_sourceType) || - (addr1.m_sourceType == addr2.m_sourceType && addr1.m_caseId < addr2.m_caseId); - + (addr1.m_sourceType == addr2.m_sourceType && + addr1.eclCase() != nullptr && addr2.eclCase() != nullptr ? addr1.eclCase()->caseId() < addr2.eclCase()->caseId() : + addr1.wellLogFile() != nullptr && addr2.wellLogFile() != nullptr ? addr1.wellLogFile()->fileName() < addr2.wellLogFile()->fileName() : + addr1.wellLogFile() < addr2.wellLogFile()); } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.h b/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.h index d460858e03..6737364ab4 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftAddress.h @@ -24,12 +24,15 @@ #include "cafPdmField.h" #include "cafPdmObject.h" #include "cafPdmPtrField.h" +#include "cafPdmPointer.h" #include #include #include class RimWellLogFile; +class RimEclipseCase; + //================================================================================================== /// @@ -43,28 +46,27 @@ enum class RftSourceType OBSERVED }; - class RimWellRftAddress { + public: - RimWellRftAddress() : m_sourceType(RftSourceType::NONE), m_caseId(-1) - { - } - - RimWellRftAddress(RftSourceType sourceType, int caseId = -1); + RimWellRftAddress(); + RimWellRftAddress(RftSourceType sourceType, RimEclipseCase* eclCase); + RimWellRftAddress(RftSourceType sourceType, RimWellLogFile* wellLogFile = nullptr); RftSourceType sourceType() const; - int caseId() const; + RimEclipseCase* eclCase() const; + RimWellLogFile* wellLogFile() const; - QString uiText() const; static QString sourceTypeUiText(RftSourceType sourceType); friend QTextStream& operator >> (QTextStream& str, RimWellRftAddress& addr); friend bool operator<(const RimWellRftAddress& addr1, const RimWellRftAddress& addr2); private: - RftSourceType m_sourceType; - int m_caseId; + RftSourceType m_sourceType; + caf::PdmPointer m_eclCase; + caf::PdmPointer m_wellLogFile; }; Q_DECLARE_METATYPE(RimWellRftAddress); diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp index 1a0e487776..8877b08f2b 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.cpp @@ -89,6 +89,7 @@ RimWellRftPlot::RimWellRftPlot() m_selectedTimeSteps.uiCapability()->setAutoAddingOptionFromValue(false); this->setAsPlotMdiWindow(); + m_selectedSourcesOrTimeStepsFieldsChanged = false; } //-------------------------------------------------------------------------------------------------- @@ -223,7 +224,7 @@ void RimWellRftPlot::updateSelectedTimeStepsFromSelectedSources() { std::vector selectedTimeSteps = m_selectedTimeSteps; std::vector newTimeStepsSelections; - std::vector selectedSourcesVector = m_selectedSources; + std::vector selectedSourcesVector = selectedSources(); auto selectedSources = std::set(selectedSourcesVector.begin(), selectedSourcesVector.end()); for (const QDateTime& timeStep : m_selectedTimeSteps()) @@ -257,21 +258,24 @@ void RimWellRftPlot::applyInitialSelections() for(RimEclipseResultCase* const rftCase : rftCasesFromEclipseCases(eclCaseTuples)) { - sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::RFT, rftCase->caseId())); + sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::RFT, rftCase)); addTimeStepsToMap(rftTimeStepsMap, timeStepsFromRftCase(rftCase)); } for (RimEclipseResultCase* const gridCase : gridCasesFromEclipseCases(eclCaseTuples)) { - sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::GRID, gridCase->caseId())); + sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::GRID, gridCase)); addTimeStepsToMap(gridTimeStepsMap, timeStepsFromGridCase(gridCase)); } - std::vector wellPaths = wellPathsContainingPressure(m_wellName); - if(wellPaths.size() > 0) + std::vector wellLogFiles = wellLogFilesContainingPressure(m_wellName); + if(wellLogFiles.size() > 0) { sourcesToSelect.push_back(RimWellRftAddress(RftSourceType::OBSERVED)); - addTimeStepsToMap(observedTimeStepsMap, timeStepsFromWellPaths(wellPaths)); + for (RimWellLogFile* const wellLogFile : wellLogFiles) + { + addTimeStepsToMap(observedTimeStepsMap, timeStepsFromWellLogFile(wellLogFile)); + } } m_selectedSources = sourcesToSelect; @@ -304,7 +308,10 @@ void RimWellRftPlot::updateEditorsFromCurves() for (const std::pair& curveDef : curveDefsFromCurves()) { - selectedSources.insert(curveDef.first); + if (curveDef.first.sourceType() == RftSourceType::OBSERVED) + selectedSources.insert(RimWellRftAddress(RftSourceType::OBSERVED)); + else + selectedSources.insert(curveDef.first); auto newTimeStepMap = std::map> { @@ -378,83 +385,77 @@ void RimWellRftPlot::syncCurvesFromUiSelection() //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimWellRftPlot::wellPathsContainingPressure(const QString& wellName) const +std::vector RimWellRftPlot::wellLogFilesContainingPressure(const QString& wellName) const { - std::vector wellPaths; + std::vector wellLogFiles; const RimProject* const project = RiaApplication::instance()->project(); for (const auto& oilField : project->oilFields) { auto wellPathsVector = std::vector(oilField->wellPathCollection()->wellPaths.begin(), oilField->wellPathCollection()->wellPaths.end()); - size_t timeStepCount = timeStepsFromWellPaths(wellPathsVector).size(); - - if (timeStepCount == 0) continue; for (const auto& wellPath : wellPathsVector) { bool hasPressure = false; - RimWellLogFile* const wellLogFile = wellPath->wellLogFile(); + const std::vector files = wellPath->wellLogFiles(); - if (wellLogFile == nullptr || QString::compare(wellLogFile->wellName(), wellName) != 0) continue; + for (RimWellLogFile* const file : files) + { + size_t timeStepCount = timeStepsFromWellLogFile(file).size(); - if (hasPressureData(wellLogFile)) - wellPaths.push_back(wellPath); + if (timeStepCount == 0) continue; + if (QString::compare(file->wellName(), wellName) != 0) continue; + + if (hasPressureData(file)) + { + wellLogFiles.push_back(file); + } + } } } - return wellPaths; + return wellLogFiles; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::vector RimWellRftPlot::getPressureChannelsFromWellPath(const RimWellPath* wellPath) const +RimWellLogFileChannel* RimWellRftPlot::getPressureChannelFromWellFile(const RimWellLogFile* wellLogFile) const { - std::vector channels; - - const RimWellLogFile* const wellLogFile = wellPath->wellLogFile(); - if (wellLogFile != nullptr) + if(wellLogFile != nullptr) { for (RimWellLogFileChannel* const channel : wellLogFile->wellLogChannels()) { - if (hasPressureData(channel)) + if (isPressureChannel(channel)) { - channels.push_back(channel); + return channel; } } } - return channels; + return nullptr; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimEclipseCase* RimWellRftPlot::eclipseCaseFromCaseId(int caseId) +RimWellPath* RimWellRftPlot::wellPathFromWellLogFile(const RimWellLogFile* wellLogFile) const { - const std::vector>& eclipseCases = eclipseCasesForWell(m_wellName); - auto itr = std::find_if(eclipseCases.begin(), eclipseCases.end(), - [caseId](std::tuple eclCase) { return std::get<0>(eclCase)->caseId == caseId; }); - return itr != eclipseCases.end() ? std::get<0>(*itr) : nullptr; -} - -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -RimWellPath* RimWellRftPlot::wellPathForObservedData(const QString& wellName, const QDateTime& date) const -{ - std::vector wellPaths = wellPathsContainingPressure(wellName); - for (const auto& wellPath : wellPaths) + RimProject* const project = RiaApplication::instance()->project(); + for (const auto& oilField : project->oilFields) { - RimWellLogFile* const wellLogFile = wellPath->wellLogFile(); - if (wellLogFile != nullptr) + auto wellPaths = std::vector(oilField->wellPathCollection()->wellPaths.begin(), oilField->wellPathCollection()->wellPaths.end()); + + for (const auto& wellPath : wellPaths) { - const QString& wName = wellLogFile->wellName(); - const QDateTime wDate = RiaDateStringParser::parseDateString(wellLogFile->date()); - if (wName == wellName && wDate == date) + for (RimWellLogFile* const file : wellPath->wellLogFiles()) { - return wellPath; + if (file == wellLogFile) + { + return wellPath; + } } } } + return nullptr; } @@ -545,7 +546,7 @@ std::map> RimWellRftPlot::timeStepsFromRf { timeStepsMap.insert(std::make_pair(timeStep, std::set())); } - timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::RFT, rftCase->caseId)); + timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::RFT, rftCase)); } } return timeStepsMap; @@ -554,7 +555,7 @@ std::map> RimWellRftPlot::timeStepsFromRf //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::map> RimWellRftPlot::timeStepsFromGridCase(const RimEclipseCase* gridCase) const +std::map> RimWellRftPlot::timeStepsFromGridCase(RimEclipseCase* gridCase) const { const RigEclipseCaseData* const eclipseCaseData = gridCase->eclipseCaseData(); size_t resultIndex = eclipseCaseData != nullptr ? @@ -570,7 +571,7 @@ std::map> RimWellRftPlot::timeStepsFromGr { timeStepsMap.insert(std::make_pair(timeStep, std::set())); } - timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::GRID, gridCase->caseId)); + timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::GRID, gridCase)); } } return timeStepsMap; @@ -579,24 +580,18 @@ std::map> RimWellRftPlot::timeStepsFromGr //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -std::map > RimWellRftPlot::timeStepsFromWellPaths(const std::vector wellPaths) const +std::map > RimWellRftPlot::timeStepsFromWellLogFile(RimWellLogFile* wellLogFile) const { std::map > timeStepsMap; - for (const RimWellPath* const wellPath : wellPaths) + + QDateTime timeStep = RiaDateStringParser::parseDateString(wellLogFile->date()); + + if (timeStepsMap.count(timeStep) == 0) { - const RimWellLogFile* wellLogFile = wellPath->wellLogFile(); - - if (wellLogFile != nullptr) - { - QDateTime timeStep = RiaDateStringParser::parseDateString(wellLogFile->date()); - - if ( timeStepsMap.count(timeStep) == 0 ) - { - timeStepsMap.insert(std::make_pair(timeStep, std::set())); - } - timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::OBSERVED)); - } + timeStepsMap.insert(std::make_pair(timeStep, std::set())); } + timeStepsMap[timeStep].insert(RimWellRftAddress(RftSourceType::OBSERVED, wellLogFile)); + return timeStepsMap; } @@ -651,40 +646,43 @@ std::set < std::pair> RimWellRftPlot::selectedCurv const std::vector>& eclipseCases = eclipseCasesForWell(m_wellName); const std::vector rftCases = rftCasesFromEclipseCases(eclipseCases); const std::vector gridCases = gridCasesFromEclipseCases(eclipseCases); - const std::vector wellPaths = wellPathsContainingPressure(m_wellName); + const std::vector wellLogFiles = wellLogFilesContainingPressure(m_wellName); for (const QDateTime& timeStep : m_selectedTimeSteps()) { - for (const RimWellRftAddress& rftAddr : m_selectedSources()) + for (const RimWellRftAddress& addr : selectedSources()) { - if (rftAddr.sourceType() == RftSourceType::RFT) + 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(rftAddr, timeStep)); + curveDefs.insert(std::make_pair(addr, timeStep)); } } } - else if (rftAddr.sourceType() == RftSourceType::GRID) + 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(rftAddr, timeStep)); + curveDefs.insert(std::make_pair(addr, timeStep)); } } } - else if (rftAddr.sourceType() == RftSourceType::OBSERVED) + else if (addr.sourceType() == RftSourceType::OBSERVED) { - const std::map>& timeStepsMap = timeStepsFromWellPaths(wellPaths); - if (mapContainsTimeStep(timeStepsMap, timeStep)) + if (addr.wellLogFile() != nullptr) { - curveDefs.insert(std::make_pair(rftAddr, timeStep)); + const std::map>& timeStepsMap = timeStepsFromWellLogFile(addr.wellLogFile()); + if (mapContainsTimeStep(timeStepsMap, timeStep)) + { + curveDefs.insert(std::make_pair(RimWellRftAddress(RftSourceType::OBSERVED, addr.wellLogFile()), timeStep)); + } } } } @@ -718,17 +716,17 @@ std::pair RimWellRftPlot::curveDefFromCurve(const if (rftCurve != nullptr) { - const RimEclipseResultCase* rftCase = dynamic_cast(rftCurve->eclipseResultCase()); + 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->caseId), timeStep); + return std::make_pair(RimWellRftAddress(RftSourceType::RFT, rftCase), timeStep); } } else if (gridCurve != nullptr) { - const RimEclipseResultCase* gridCase = dynamic_cast(gridCurve->rimCase()); + RimEclipseResultCase* gridCase = dynamic_cast(gridCurve->rimCase()); if (gridCase != nullptr) { size_t timeStepIndex = gridCurve->currentTimeStep(); @@ -737,7 +735,7 @@ std::pair RimWellRftPlot::curveDefFromCurve(const timeStepsMap.begin(), timeStepsMap.end()); if (timeStepIndex < timeStepsMap.size()) { - return std::make_pair(RimWellRftAddress(RftSourceType::GRID, gridCase->caseId), + return std::make_pair(RimWellRftAddress(RftSourceType::GRID, gridCase), timeStepsVector[timeStepIndex].first); } } @@ -745,7 +743,7 @@ std::pair RimWellRftPlot::curveDefFromCurve(const else if (wellLogFileCurve != nullptr) { const RimWellPath* const wellPath = wellLogFileCurve->wellPath(); - const RimWellLogFile* const wellLogFile = wellPath->wellLogFile(); + RimWellLogFile* const wellLogFile = wellLogFileCurve->wellLogFile(); if (wellLogFile != nullptr) { @@ -753,11 +751,11 @@ std::pair RimWellRftPlot::curveDefFromCurve(const if (date.isValid()) { - return std::make_pair(RimWellRftAddress(RftSourceType::OBSERVED), date); + return std::make_pair(RimWellRftAddress(RftSourceType::OBSERVED, wellLogFile), date); } } } - return std::make_pair(RimWellRftAddress(RftSourceType::NONE), QDateTime()); + return std::make_pair(RimWellRftAddress(), QDateTime()); } //-------------------------------------------------------------------------------------------------- @@ -783,7 +781,7 @@ void RimWellRftPlot::updateCurvesInPlot(const std::setaddCurve(curve); - auto rftCase = eclipseCaseFromCaseId(curveDefToAdd.first.caseId()); + auto rftCase = curveDefToAdd.first.eclCase(); curve->setEclipseResultCase(dynamic_cast(rftCase)); RifEclipseRftAddress address(m_wellName, curveDefToAdd.second, RifEclipseRftAddress::PRESSURE); @@ -803,7 +801,7 @@ void RimWellRftPlot::updateCurvesInPlot(const std::setsetFromSimulationWellName(m_wellName, m_branchIndex); // Fetch cases and time steps - auto gridCase = eclipseCaseFromCaseId(curveDefToAdd.first.caseId()); + auto gridCase = curveDefToAdd.first.eclCase(); if (gridCase != nullptr) { // Case @@ -828,14 +826,16 @@ void RimWellRftPlot::updateCurvesInPlot(const std::set pressureChannels = getPressureChannelsFromWellPath(wellPath); + RimWellLogFileChannel* pressureChannel = getPressureChannelFromWellFile(wellLogFile); auto curve = new RimWellLogFileCurve(); plotTrack->addCurve(curve); curve->setWellPath(wellPath); - curve->setWellLogChannelName(pressureChannels.front()->name()); + curve->setWellLogFile(wellLogFile); + curve->setWellLogChannelName(pressureChannel->name()); curve->setZOrder(2); applyCurveAppearance(curve); @@ -871,6 +871,27 @@ bool RimWellRftPlot::isAnySourceAddressSelected(const std::set 0; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +std::vector RimWellRftPlot::selectedSources() const +{ + std::vector sources; + for (const RimWellRftAddress& addr : m_selectedSources()) + { + if (addr.sourceType() == RftSourceType::OBSERVED) + { + for (RimWellLogFile* const wellLogFile : wellLogFilesContainingPressure(m_wellName)) + { + sources.push_back(RimWellRftAddress(RftSourceType::OBSERVED, wellLogFile)); + } + } + else + sources.push_back(addr); + } + return sources; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -914,11 +935,11 @@ QString RimWellRftPlot::currentWellName() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellRftPlot::hasPressureData(RimWellLogFile* wellLogFile) +bool RimWellRftPlot::hasPressureData(const RimWellLogFile* wellLogFile) { for (RimWellLogFileChannel* const wellLogChannel : wellLogFile->wellLogChannels()) { - if (hasPressureData(wellLogChannel)) return true; + if (isPressureChannel(wellLogChannel)) return true; } return false; } @@ -926,7 +947,22 @@ bool RimWellRftPlot::hasPressureData(RimWellLogFile* wellLogFile) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -bool RimWellRftPlot::hasPressureData(RimWellLogFileChannel* channel) +bool RimWellRftPlot::hasPressureData(RimWellPath* wellPath) +{ + for (RimWellLogFile* const wellLogFile : wellPath->wellLogFiles()) + { + if (hasPressureData(wellLogFile)) + { + return true; + } + } + return false; +} + +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +bool RimWellRftPlot::isPressureChannel(RimWellLogFileChannel* channel) { // Todo: read pressure channel names from config/defines return QString::compare(channel->name(), PRESSURE_DATA_NAME) == 0; @@ -973,7 +1009,7 @@ QList RimWellRftPlot::calculateValueOptions(const caf::P } for (const auto& rftCase : rftCases) { - auto addr = RimWellRftAddress(RftSourceType::RFT, rftCase->caseId); + auto addr = RimWellRftAddress(RftSourceType::RFT, rftCase); auto item = caf::PdmOptionItemInfo(rftCase->caseUserDescription(), QVariant::fromValue(addr)); item.setLevel(1); options.push_back(item); @@ -986,18 +1022,18 @@ QList RimWellRftPlot::calculateValueOptions(const caf::P } for (const auto& gridCase : gridCases) { - auto addr = RimWellRftAddress(RftSourceType::GRID, gridCase->caseId); + auto addr = RimWellRftAddress(RftSourceType::GRID, gridCase); auto item = caf::PdmOptionItemInfo(gridCase->caseUserDescription(), QVariant::fromValue(addr)); item.setLevel(1); options.push_back(item); } - if (wellPathsContainingPressure(m_wellName).size() > 0) + if (wellLogFilesContainingPressure(m_wellName).size() > 0) { options.push_back(caf::PdmOptionItemInfo::createHeader(RimWellRftAddress::sourceTypeUiText(RftSourceType::OBSERVED), true)); auto addr = RimWellRftAddress(RftSourceType::OBSERVED); - auto item = caf::PdmOptionItemInfo(addr.uiText(), QVariant::fromValue(addr)); + auto item = caf::PdmOptionItemInfo("Observed Data", QVariant::fromValue(addr)); item.setLevel(1); options.push_back(item); } @@ -1058,6 +1094,7 @@ void RimWellRftPlot::fieldChangedByUi(const caf::PdmFieldHandle* changedField, c changedField == &m_selectedTimeSteps) { syncCurvesFromUiSelection(); + m_selectedSourcesOrTimeStepsFieldsChanged = true; } else if (changedField == &m_showPlotTitle) { @@ -1086,6 +1123,12 @@ QImage RimWellRftPlot::snapshotWindowContent() //-------------------------------------------------------------------------------------------------- void RimWellRftPlot::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiOrdering) { + if (!m_selectedSourcesOrTimeStepsFieldsChanged) + { + updateEditorsFromCurves(); + } + m_selectedSourcesOrTimeStepsFieldsChanged = false; + uiOrdering.add(&m_userName); uiOrdering.add(&m_wellName); @@ -1175,27 +1218,30 @@ void RimWellRftPlot::calculateValueOptionsForTimeSteps(const QString& wellName, const std::vector>& eclipseCases = eclipseCasesForWell(wellName); const std::vector rftCases = rftCasesFromEclipseCases(eclipseCases); const std::vector gridCases = gridCasesFromEclipseCases(eclipseCases); - const std::vector observedWellPaths = wellPathsContainingPressure(m_wellName); + const std::vector wellLogFiles = wellLogFilesContainingPressure(m_wellName); - for (const RimWellRftAddress& selection : m_selectedSources()) + for (const RimWellRftAddress& selection : selectedSources()) { - if (selection.sourceType() == RimWellRftAddress(RftSourceType::RFT)) + if (selection.sourceType() == RftSourceType::RFT) { for (RimEclipseResultCase* const rftCase : rftCases) { addTimeStepsToMap(obsAndRftTimeStepsMap, timeStepsFromRftCase(rftCase)); } } - else if (selection.sourceType() == RimWellRftAddress(RftSourceType::GRID)) + else if (selection.sourceType() == RftSourceType::GRID) { for (RimEclipseResultCase* const gridCase : gridCases) { addTimeStepsToMap(gridTimeStepsMap, timeStepsFromGridCase(gridCase)); } } - else if (selection.sourceType() == RimWellRftAddress(RftSourceType::OBSERVED)) + else if (selection.sourceType() == RftSourceType::OBSERVED) { - addTimeStepsToMap(obsAndRftTimeStepsMap, timeStepsFromWellPaths(observedWellPaths)); + if (selection.wellLogFile() != nullptr) + { + addTimeStepsToMap(obsAndRftTimeStepsMap, timeStepsFromWellLogFile(selection.wellLogFile())); + } } } diff --git a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h index 4559462431..695e88d82a 100644 --- a/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h +++ b/ApplicationCode/ProjectDataModel/Flow/RimWellRftPlot.h @@ -79,9 +79,10 @@ public: void setCurrentWellName(const QString& currWellName); QString currentWellName() const; - static bool hasPressureData(RimWellLogFile* wellLogFile); - static bool hasPressureData(RimWellLogFileChannel* channel); + static bool hasPressureData(const RimWellLogFile* wellLogFile); + static bool isPressureChannel(RimWellLogFileChannel* channel); static bool hasPressureData(RimEclipseResultCase* gridCase); + static bool hasPressureData(RimWellPath* wellPath); static const char* plotNameFormatString(); void applyInitialSelections(); @@ -111,18 +112,17 @@ private: void syncCurvesFromUiSelection(); - std::vector wellPathsContainingPressure(const QString& wellName) const; - std::vector getPressureChannelsFromWellPath(const RimWellPath* wellPath) const; - RimEclipseCase* eclipseCaseFromCaseId(int caseId); - - RimWellPath* wellPathForObservedData(const QString& wellName, const QDateTime& date) const; + std::vector wellLogFilesContainingPressure(const QString& wellName) const; + RimWellLogFileChannel* getPressureChannelFromWellFile(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(const RimEclipseCase* gridCase) const; - std::map> timeStepsFromWellPaths(const std::vector wellPaths) const; + std::map> timeStepsFromGridCase(RimEclipseCase* gridCase) const; + std::map> timeStepsFromWellLogFile(RimWellLogFile* wellLogFile) const; std::map> adjacentTimeSteps(const std::vector>>& allTimeSteps, const std::pair>& searchTimeStepPair); static bool mapContainsTimeStep(const std::map>& map, const QDateTime& timeStep); @@ -135,6 +135,7 @@ private: const std::set& curvesToDelete); bool isOnlyGridSourcesSelected() const; bool isAnySourceAddressSelected(const std::set& addresses) const; + std::vector selectedSources() const; // RimViewWindow overrides @@ -159,4 +160,6 @@ private: caf::PdmChildField m_wellLogPlot; std::map> m_timeStepsToAddresses; + + bool m_selectedSourcesOrTimeStepsFieldsChanged; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp index 4a9791d4d0..2f3a8991a9 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.cpp @@ -30,6 +30,7 @@ #include "RimWellLogTrack.h" #include "RimWellPath.h" #include "RimWellPathCollection.h" +#include "RimWellRftPlot.h" #include "RiuLineSegmentQwtPlotCurve.h" #include "RiuWellLogTrack.h" @@ -40,6 +41,7 @@ #include "cafPdmUiTreeOrdering.h" #include +#include CAF_PDM_SOURCE_INIT(RimWellLogFileCurve, "WellLogFileCurve"); @@ -56,6 +58,8 @@ RimWellLogFileCurve::RimWellLogFileCurve() CAF_PDM_InitFieldNoDefault(&m_wellLogChannnelName, "CurveWellLogChannel", "Well Log Channel", "", "", ""); + CAF_PDM_InitFieldNoDefault(&m_wellLogFile, "WellLogFile", "Well Log File", "", "", ""); + m_wellPath = nullptr; } @@ -81,77 +85,72 @@ void RimWellLogFileCurve::onLoadDataAndUpdate(bool updateParentPlot) firstAncestorOrThisOfType(wellLogPlot); CVF_ASSERT(wellLogPlot); - if (m_wellPath) + if (m_wellPath && m_wellLogFile) { - RimWellLogFile* logFileInfo = m_wellPath->wellLogFile(); - if (logFileInfo) + RigWellLogFile* wellLogFile = m_wellLogFile->wellLogFile(); + if (wellLogFile) { - RigWellLogFile* wellLogFile = logFileInfo->wellLogFile(); - if (wellLogFile) + std::vector values = wellLogFile->values(m_wellLogChannnelName); + std::vector measuredDepthValues = wellLogFile->depthValues(); + + if (wellLogPlot && wellLogPlot->depthType() == RimWellLogPlot::TRUE_VERTICAL_DEPTH) { - std::vector values = wellLogFile->values(m_wellLogChannnelName); - std::vector measuredDepthValues = wellLogFile->depthValues(); - - if (wellLogPlot && wellLogPlot->depthType() == RimWellLogPlot::TRUE_VERTICAL_DEPTH) + bool canUseTvd = false; + if (wellLogFile->hasTvdChannel()) { - bool canUseTvd = false; - if (wellLogFile->hasTvdChannel()) - { - std::vector tvdMslValues = wellLogFile->tvdMslValues(); + std::vector tvdMslValues = wellLogFile->tvdMslValues(); - if (values.size() == measuredDepthValues.size() && values.size() == tvdMslValues.size()) + if (values.size() == measuredDepthValues.size() && values.size() == tvdMslValues.size()) + { + m_curveData->setValuesWithTVD(values, measuredDepthValues, tvdMslValues, wellLogFile->depthUnit(), false); + canUseTvd = true; + } + } + + if (!canUseTvd) + { + RigWellPath* rigWellPath = m_wellPath->wellPathGeometry(); + if (rigWellPath) + { + std::vector trueVerticeldepthValues; + + for (double measuredDepthValue : measuredDepthValues) { - m_curveData->setValuesWithTVD(values, measuredDepthValues, tvdMslValues, wellLogFile->depthUnit(), false); + trueVerticeldepthValues.push_back(-rigWellPath->interpolatedPointAlongWellPath(measuredDepthValue).z()); + } + if (values.size() == trueVerticeldepthValues.size() && values.size() == measuredDepthValues.size()) + { + m_curveData->setValuesWithTVD(values, measuredDepthValues, trueVerticeldepthValues, wellLogFile->depthUnit(), false); canUseTvd = true; } } - - if (!canUseTvd) - { - RigWellPath* rigWellPath = m_wellPath->wellPathGeometry(); - if (rigWellPath) - { - std::vector trueVerticeldepthValues; - - for (double measuredDepthValue : measuredDepthValues) - { - trueVerticeldepthValues.push_back(-rigWellPath->interpolatedPointAlongWellPath(measuredDepthValue).z()); - } - if (values.size() == trueVerticeldepthValues.size() && values.size() == measuredDepthValues.size()) - { - m_curveData->setValuesWithTVD(values, measuredDepthValues, trueVerticeldepthValues, wellLogFile->depthUnit(), false); - canUseTvd = true; - } - } - } - - if (!canUseTvd) - { - if (RiaApplication::instance()->preferences()->showLasCurveWithoutTvdWarning()) - { - QString tmp = QString("Display of True Vertical Depth (TVD) for LAS curves is not possible without a well log path, and the LAS curve will be hidden in this mode.\n\n"); - tmp += "Control display of this warning from \"Preferences->Show LAS curve without TVD warning\""; - - QMessageBox::warning(nullptr, "LAS curve without TVD", tmp); - } - } } - else + + if (!canUseTvd) { - if (values.size() == measuredDepthValues.size()) + if (RiaApplication::instance()->preferences()->showLasCurveWithoutTvdWarning()) { - m_curveData->setValuesAndMD(values, measuredDepthValues, wellLogFile->depthUnit(), false); + QString tmp = QString("Display of True Vertical Depth (TVD) for LAS curves is not possible without a well log path, and the LAS curve will be hidden in this mode.\n\n"); + tmp += "Control display of this warning from \"Preferences->Show LAS curve without TVD warning\""; + + QMessageBox::warning(nullptr, "LAS curve without TVD", tmp); } } } - - if (m_isUsingAutoName) + else { - m_qwtPlotCurve->setTitle(createCurveAutoName()); + if (values.size() == measuredDepthValues.size()) + { + m_curveData->setValuesAndMD(values, measuredDepthValues, wellLogFile->depthUnit(), false); + } } } - } + if (m_isUsingAutoName) + { + m_qwtPlotCurve->setTitle(createCurveAutoName()); + } + } RiaDefines::DepthUnitType displayUnit = RiaDefines::UNIT_METER; if (wellLogPlot) @@ -198,6 +197,14 @@ void RimWellLogFileCurve::setWellLogChannelName(const QString& name) m_wellLogChannnelName = name; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void RimWellLogFileCurve::setWellLogFile(RimWellLogFile* wellLogFile) +{ + m_wellLogFile = wellLogFile; +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -213,7 +220,10 @@ void RimWellLogFileCurve::fieldChangedByUi(const caf::PdmFieldHandle* changedFie { this->loadDataAndUpdate(true); } - + else if (changedField == &m_wellLogFile) + { + this->loadDataAndUpdate(true); + } if (m_parentQwtPlot) m_parentQwtPlot->replot(); } @@ -227,6 +237,7 @@ void RimWellLogFileCurve::defineUiOrdering(QString uiConfigName, caf::PdmUiOrder caf::PdmUiGroup* curveDataGroup = uiOrdering.addNewGroup("Curve Data"); curveDataGroup->add(&m_wellPath); curveDataGroup->add(&m_wellLogChannnelName); + curveDataGroup->add(&m_wellLogFile); caf::PdmUiGroup* appearanceGroup = uiOrdering.addNewGroup("Appearance"); RimPlotCurve::appearanceUiOrdering(*appearanceGroup); @@ -265,7 +276,7 @@ QList RimWellLogFileCurve::calculateValueOptions(const c for (size_t i = 0; i < wellPaths.size(); i++) { // Only include well paths coming from a well log file - if (wellPaths[i]->wellLogFile()) + if (wellPaths[i]->wellLogFiles().size() > 0) { options.push_back(caf::PdmOptionItemInfo(wellPaths[i]->name(), wellPaths[i])); } @@ -282,10 +293,9 @@ QList RimWellLogFileCurve::calculateValueOptions(const c { if (m_wellPath()) { - RimWellLogFile* wellLogFile = m_wellPath->wellLogFile(); - if (wellLogFile) + if (m_wellLogFile) { - std::vector fileLogs = wellLogFile->wellLogChannels(); + std::vector fileLogs = m_wellLogFile->wellLogChannels(); for (size_t i = 0; i < fileLogs.size(); i++) { @@ -301,6 +311,21 @@ QList RimWellLogFileCurve::calculateValueOptions(const c } } + if (fieldNeedingOptions == &m_wellLogFile) + { + if (m_wellPath() && m_wellPath->wellLogFiles().size() > 0) + { + for (RimWellLogFile* const wellLogFile : m_wellPath->wellLogFiles()) + { + if (RimWellRftPlot::hasPressureData(wellLogFile)) + { + QFileInfo fileInfo(wellLogFile->fileName()); + options.push_back(caf::PdmOptionItemInfo(fileInfo.baseName(), wellLogFile)); + } + } + } + } + return options; } @@ -317,8 +342,7 @@ QString RimWellLogFileCurve::createCurveAutoName() txt += " : "; txt += m_wellLogChannnelName; - RimWellLogFile* logFileInfo = m_wellPath->wellLogFile(); - RigWellLogFile* wellLogFile = logFileInfo ? logFileInfo->wellLogFile() : nullptr; + RigWellLogFile* wellLogFile = m_wellLogFile ? m_wellLogFile->wellLogFile() : nullptr; if (wellLogFile) { RimWellLogPlot* wellLogPlot; @@ -346,6 +370,14 @@ QString RimWellLogFileCurve::wellLogChannelName() const return m_wellLogChannnelName; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +RimWellLogFile* RimWellLogFileCurve::wellLogFile() const +{ + return m_wellLogFile(); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h index 3f1227d9d7..342559aa1a 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h +++ b/ApplicationCode/ProjectDataModel/RimWellLogFileCurve.h @@ -28,6 +28,7 @@ class RimWellPath; class RimWellLogFileChannel; +class RimWellLogFile; //================================================================================================== /// @@ -44,10 +45,12 @@ public: void setWellPath(RimWellPath* wellPath); RimWellPath* wellPath() const; void setWellLogChannelName(const QString& name); - + void setWellLogFile(RimWellLogFile* wellLogFile); + // Overrides from RimWellLogPlotCurve virtual QString wellName() const; virtual QString wellLogChannelName() const; + virtual RimWellLogFile* wellLogFile() const; protected: // Overrides from RimWellLogPlotCurve @@ -61,9 +64,10 @@ protected: virtual QList calculateValueOptions(const caf::PdmFieldHandle* fieldNeedingOptions, bool * useOptionsOnly); protected: - caf::PdmPtrField m_wellPath; - caf::PdmField m_wellLogChannnelName; - caf::PdmField m_wellLogChannnelUnit; + caf::PdmPtrField m_wellPath; + caf::PdmPtrField m_wellLogFile; + caf::PdmField m_wellLogChannnelName; + caf::PdmField m_wellLogChannnelUnit; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.cpp b/ApplicationCode/ProjectDataModel/RimWellPath.cpp index 5c47bec97d..8508d6a812 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPath.cpp @@ -124,8 +124,12 @@ RimWellPath::RimWellPath() m_completions = new RimWellPathCompletions; m_completions.uiCapability()->setUiTreeHidden(true); - CAF_PDM_InitFieldNoDefault(&m_wellLogFile, "WellLogFile", "Well Log File", "", "", ""); - m_wellLogFile.uiCapability()->setUiHidden(true); + CAF_PDM_InitFieldNoDefault(&m_wellLogFiles, "WellLogFiles", "Well Log Files", "", "", ""); + m_wellLogFiles.uiCapability()->setUiHidden(true); + + CAF_PDM_InitFieldNoDefault(&m_wellLogFile_OBSOLETE, "WellLogFile", "Well Log File", "", "", ""); + m_wellLogFile_OBSOLETE.uiCapability()->setUiHidden(true); + m_wellLogFile_OBSOLETE.xmlCapability()->setIOWritable(false); m_wellPath = NULL; } @@ -136,9 +140,14 @@ RimWellPath::RimWellPath() //-------------------------------------------------------------------------------------------------- RimWellPath::~RimWellPath() { - if (m_wellLogFile()) + if (m_wellLogFile_OBSOLETE()) { - delete m_wellLogFile; + delete m_wellLogFile_OBSOLETE; + } + + for(const auto& file : m_wellLogFiles()) + { + delete file; } RimProject* project; @@ -354,9 +363,9 @@ void RimWellPath::setName(const QString& name) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RimWellLogFile* RimWellPath::wellLogFile() const +std::vector RimWellPath::wellLogFiles() const { - return m_wellLogFile; + return std::vector(m_wellLogFiles.begin(), m_wellLogFiles.end()); } //-------------------------------------------------------------------------------------------------- @@ -459,7 +468,7 @@ void RimWellPath::defineUiOrdering(QString uiConfigName, caf::PdmUiOrdering& uiO //-------------------------------------------------------------------------------------------------- void RimWellPath::defineUiTreeOrdering(caf::PdmUiTreeOrdering& uiTreeOrdering, QString uiConfigName) { - uiTreeOrdering.add(&m_wellLogFile); + uiTreeOrdering.add(&m_wellLogFiles); if (m_completions->hasCompletions()) { @@ -594,17 +603,24 @@ RiaEclipseUnitTools::UnitSystem RimWellPath::unitSystem() const //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RimWellPath::setLogFileInfo(RimWellLogFile* logFileInfo) +void RimWellPath::addWellLogFile(RimWellLogFile* logFileInfo) { - if (m_wellLogFile()) + auto itr = std::find_if(m_wellLogFiles.begin(), m_wellLogFiles.end(), [&](const RimWellLogFile* file) + { + return QString::compare(file->fileName(), logFileInfo->fileName(), Qt::CaseInsensitive) == 0; + }); + + // Todo: Verify well name to ensure all well log files having the same well name + + if (itr == m_wellLogFiles.end()) { - delete m_wellLogFile; + m_wellLogFiles.push_back(logFileInfo); + + if (m_wellLogFiles.size() == 1) + { + setName(m_wellLogFiles[0]->wellName()); + } } - - m_wellLogFile = logFileInfo; - m_wellLogFile->uiCapability()->setUiHidden(true); - - setName(m_wellLogFile->wellName()); } //-------------------------------------------------------------------------------------------------- @@ -616,7 +632,7 @@ RimWellPath* RimWellPath::fromFilePath(QString filePath) if (logFileInfo) { auto wellPath = new RimWellPath(); - wellPath->setLogFileInfo(logFileInfo); + wellPath->addWellLogFile(logFileInfo); return wellPath; } return nullptr; diff --git a/ApplicationCode/ProjectDataModel/RimWellPath.h b/ApplicationCode/ProjectDataModel/RimWellPath.h index e0bc3b65d7..da3ea5415e 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPath.h +++ b/ApplicationCode/ProjectDataModel/RimWellPath.h @@ -64,7 +64,7 @@ public: RimWellPath(); virtual ~RimWellPath(); - void setLogFileInfo(RimWellLogFile* logFileInfo); + void addWellLogFile(RimWellLogFile* logFileInfo); virtual caf::PdmFieldHandle* userDescriptionField(); virtual caf::PdmFieldHandle* objectToggleField(); @@ -75,7 +75,7 @@ public: QString name() const; void setName(const QString& name); - RimWellLogFile* wellLogFile() const; + std::vector wellLogFiles() const; caf::PdmField filepath; caf::PdmField wellPathIndexInFile; // -1 means none. @@ -152,6 +152,8 @@ private: cvf::ref m_wellPathPartMgr; caf::PdmField m_name; - caf::PdmChildField m_wellLogFile; + caf::PdmChildArrayField m_wellLogFiles; + + caf::PdmChildField m_wellLogFile_OBSOLETE; }; diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp index 66b6a87f7b..9a36d22759 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp @@ -137,26 +137,27 @@ void RimWellPathCollection::readWellPathFiles() } } - RimWellLogFile* wellLogFile = wellPaths[wpIdx]->wellLogFile(); - if (wellLogFile) + for (RimWellLogFile* const wellLogFile : wellPaths[wpIdx]->wellLogFiles()) { - QString errorMessage; - if (!wellLogFile->readFile(&errorMessage)) + if (wellLogFile) { - QString displayMessage = "Could not open the well log file: \n" + wellLogFile->fileName(); - - if (!errorMessage.isEmpty()) + QString errorMessage; + if (!wellLogFile->readFile(&errorMessage)) { - displayMessage += "\n\n"; - displayMessage += errorMessage; - } + QString displayMessage = "Could not open the well log file: \n" + wellLogFile->fileName(); - QMessageBox::warning(RiuMainWindow::instance(), - "File open error", - displayMessage); + if (!errorMessage.isEmpty()) + { + displayMessage += "\n\n"; + displayMessage += errorMessage; + } + + QMessageBox::warning(RiuMainWindow::instance(), + "File open error", + displayMessage); + } } } - progress.setProgressDescription(QString("Reading file %1").arg(wellPaths[wpIdx]->name())); progress.incrementProgress(); } @@ -300,7 +301,7 @@ void RimWellPathCollection::addWellLogs(const QStringList& filePaths) wellPaths.push_back(wellPath); } - wellPath->setLogFileInfo(logFileInfo); + wellPath->addWellLogFile(logFileInfo); } }