From a2d2879babe04501faa23c3c110f2447e4ca5e8e Mon Sep 17 00:00:00 2001 From: Rebecca Cox Date: Fri, 8 Dec 2017 09:27:30 +0100 Subject: [PATCH] #2227 Well formations: New Rig data stucture with top+base MD and level --- .../RifWellPathFormationReader.cpp | 81 +++++++++++++------ .../RifWellPathFormationReader.h | 7 +- .../ProjectDataModel/RimWellLogTrack.cpp | 2 +- .../RimWellPathCollection.cpp | 12 ++- .../RigWellPathFormations.cpp | 50 +++++++++--- .../RigWellPathFormations.h | 19 ++++- 6 files changed, 123 insertions(+), 48 deletions(-) diff --git a/ApplicationCode/FileInterface/RifWellPathFormationReader.cpp b/ApplicationCode/FileInterface/RifWellPathFormationReader.cpp index fdad0c55a6..efed4f6f66 100644 --- a/ApplicationCode/FileInterface/RifWellPathFormationReader.cpp +++ b/ApplicationCode/FileInterface/RifWellPathFormationReader.cpp @@ -37,22 +37,46 @@ std::map> { std::map> result; - std::map>> formations; + std::vector wellNames; + std::vector formationNames; + std::vector mdTop; + std::vector mdBase; - readFileIntoMap(filePath, &formations); - if (formations.empty()) + readFile(filePath, &wellNames, &formationNames, &mdTop, &mdBase); + if (wellNames.empty() || formationNames.empty() || mdTop.empty() || mdBase.empty()) { QMessageBox::warning(RiuMainWindow::instance(), "Import failure", - QString("Failed to parse %1 as well picks file").arg(filePath)); - RiaLogging::error(QString("Failed to parse %1 as well picks file").arg(filePath)); + QString("Failed to parse %1 as a well pick file").arg(filePath)); + RiaLogging::error(QString("Failed to parse %1 as a well pick file").arg(filePath)); + + return result; } - std::map>>::iterator it; + CVF_ASSERT(wellNames.size() == formationNames.size()); + CVF_ASSERT(mdTop.size() == formationNames.size()); + CVF_ASSERT(mdBase.size() == formationNames.size()); - for (it = formations.begin(); it != formations.end(); it++) + std::map> formations; + + for (size_t i = 0; i < wellNames.size(); i++) + { + RigWellPathFormation formation; + formation.formationName = formationNames[i]; + formation.mdTop = mdTop[i]; + formation.mdBase = mdBase[i]; + + if (!formations.count(wellNames[i])) + { + formations[wellNames[i]] = std::vector(); + } + + formations[wellNames[i]].push_back(formation); + } + + for (auto it = formations.begin(); it != formations.end(); it++) { cvf::ref wellPathFormations = new RigWellPathFormations(it->second, filePath, it->first); - result[it->first] = wellPathFormations; + result[it->first] = wellPathFormations; } return result; @@ -69,8 +93,9 @@ void removeWhiteSpaces(QString* word) //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RifWellPathFormationReader::readFileIntoMap(const QString& filePath, - std::map>>* formations) +void RifWellPathFormationReader::readFile(const QString& filePath, std::vector* wellNames, + std::vector* formationNames, std::vector* mdTop, + std::vector* mdBase) { QFile data(filePath); @@ -90,12 +115,12 @@ void RifWellPathFormationReader::readFileIntoMap(const QString& header = line.split(';', QString::KeepEmptyParts); } - static const QString wellNameText = "wellname"; - static const QString surfaceNameText = "surfacename"; + static const QString wellNameText = "wellname"; + static const QString surfaceNameText = "surfacename"; static const QString measuredDepthText = "md"; - int wellNameIndex = header.indexOf(wellNameText); - int surfaceNameIndex = header.indexOf(surfaceNameText); + int wellNameIndex = header.indexOf(wellNameText); + int surfaceNameIndex = header.indexOf(surfaceNameText); int measuredDepthIndex = header.indexOf(measuredDepthText); if (wellNameIndex != -1 && surfaceNameIndex != -1 && measuredDepthIndex != -1) @@ -111,22 +136,24 @@ void RifWellPathFormationReader::readFileIntoMap(const QString& double measuredDepth = dataLine[measuredDepthIndex].toDouble(&conversionOk); if (!conversionOk) continue; - QString wellName = dataLine[wellNameIndex]; + QString wellName = dataLine[wellNameIndex]; QString surfaceName = dataLine[surfaceNameIndex]; - (*formations)[wellName].push_back(std::make_pair(measuredDepth, surfaceName)); + wellNames->push_back(wellName); + formationNames->push_back(surfaceName); + mdTop->push_back(measuredDepth); } while (!data.atEnd()); return; } - static const QString unitNameText = "unitname"; - static const QString measuredDepthToptext = "topmd"; + static const QString unitNameText = "unitname"; + static const QString measuredDepthToptext = "topmd"; static const QString measuredDepthBasetext = "basemd"; - int unitNameIndex = header.indexOf(unitNameText); - int measuredDepthTopIndex = header.indexOf(measuredDepthToptext); + int unitNameIndex = header.indexOf(unitNameText); + int measuredDepthTopIndex = header.indexOf(measuredDepthToptext); int measuredDepthBaseIndex = header.indexOf(measuredDepthBasetext); if (unitNameIndex != -1 && measuredDepthTopIndex != -1 && measuredDepthBaseIndex != -1) @@ -138,14 +165,16 @@ void RifWellPathFormationReader::readFileIntoMap(const QString& QStringList dataLine = line.split(';', QString::KeepEmptyParts); if (dataLine.size() != header.size()) continue; - QString wellName = dataLine[wellNameIndex]; - QString unitName = dataLine[unitNameIndex]; - unitName = unitName.trimmed(); - double measuredDepthTop = dataLine[measuredDepthTopIndex].toDouble(); + QString wellName = dataLine[wellNameIndex]; + QString unitName = dataLine[unitNameIndex]; + unitName = unitName.trimmed(); + double measuredDepthTop = dataLine[measuredDepthTopIndex].toDouble(); double measuredDepthBase = dataLine[measuredDepthBaseIndex].toDouble(); - (*formations)[wellName].push_back(std::make_pair(measuredDepthTop, unitName)); - (*formations)[wellName].push_back(std::make_pair(measuredDepthBase, unitName)); + wellNames->push_back(wellName); + formationNames->push_back(unitName); + mdTop->push_back(measuredDepthTop); + mdBase->push_back(measuredDepthBase); } while (!data.atEnd()); } diff --git a/ApplicationCode/FileInterface/RifWellPathFormationReader.h b/ApplicationCode/FileInterface/RifWellPathFormationReader.h index 091f596c6c..fa61d6f4be 100644 --- a/ApplicationCode/FileInterface/RifWellPathFormationReader.h +++ b/ApplicationCode/FileInterface/RifWellPathFormationReader.h @@ -21,8 +21,8 @@ #include "RigWellPathFormations.h" #include -#include #include +#include #include "cvfBase.h" #include "cvfObject.h" @@ -35,8 +35,9 @@ class RifWellPathFormationReader { public: - static std::map > readWellFormationsToGeometry(const QString& filePath); + static std::map> readWellFormationsToGeometry(const QString& filePath); private: - static void readFileIntoMap(const QString& filePath, std::map> >* formations); + static void readFile(const QString& filePath, std::vector* wellNames, std::vector* formationNames, + std::vector* mdTop, std::vector* mdBase); }; diff --git a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp index aafa067e14..ab449af1ad 100644 --- a/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellLogTrack.cpp @@ -1247,7 +1247,7 @@ void RimWellLogTrack::updateFormationNamesOnPlot() const RigWellPathFormations* formations = m_formationWellPath->formationsGeometry(); if (!formations) return; - formations->measuredDepthAndFormationNamesWithoutDuplicates(formationNamesToPlot, yValues); + formations->measuredDepthAndFormationNamesWithoutDuplicatesOnDepth(&formationNamesToPlot, &yValues); m_annotationTool->attachWellPicks(this->viewer(), formationNamesToPlot, yValues); } diff --git a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp index 964b425707..8805387ec3 100644 --- a/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp +++ b/ApplicationCode/ProjectDataModel/RimWellPathCollection.cpp @@ -337,6 +337,8 @@ void RimWellPathCollection::addWellPathFormations(const QStringList& filePaths) outputMessage += "-----------------------------------------------\n"; outputMessage += "Well Name \tDetected Well Path \tCount\n"; + bool fileReadSuccess = false; + for (QString filePath : filePaths) { std::map> newFormations = @@ -344,6 +346,8 @@ void RimWellPathCollection::addWellPathFormations(const QStringList& filePaths) for (auto it = newFormations.begin(); it != newFormations.end(); it++) { + fileReadSuccess = true; + RimWellPath* wellPath = tryFindMatchingWellPath(it->first); if (!wellPath) { @@ -364,8 +368,12 @@ void RimWellPathCollection::addWellPathFormations(const QStringList& filePaths) } } outputMessage += "-----------------------------------------------"; - QMessageBox::information(RiuMainWindow::instance(), "Well Picks Import", outputMessage); - RiaLogging::info(outputMessage); + + if (fileReadSuccess) + { + QMessageBox::information(RiuMainWindow::instance(), "Well Picks Import", outputMessage); + RiaLogging::info(outputMessage); + } this->sortWellsByName(); } diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathFormations.cpp b/ApplicationCode/ReservoirDataModel/RigWellPathFormations.cpp index 7121c8ba9c..b91336d2b2 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathFormations.cpp +++ b/ApplicationCode/ReservoirDataModel/RigWellPathFormations.cpp @@ -18,33 +18,59 @@ #include "RigWellPathFormations.h" +#include "QStringList" + +#include "cvfMath.h" + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -RigWellPathFormations::RigWellPathFormations(std::vector> measuredDepthAndFormationNames, const QString& filePath, const QString& key) +RigWellPathFormations::RigWellPathFormations(std::vector formations, const QString& filePath, const QString& key) { - m_measuredDepthAndFormationNames = measuredDepthAndFormationNames; m_filePath = filePath; m_keyInFile = key; + m_formations = formations; } +struct MeasuredDepthComp +{ + bool operator()(const double& md1, const double& md2) const + { + if (cvf::Math::abs(md1 - md2) < 1.0) + { + return false; + } + return md1 < md2; + } +}; + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- -void RigWellPathFormations::measuredDepthAndFormationNamesWithoutDuplicates(std::vector& names, std::vector& measuredDepths) const +void RigWellPathFormations::measuredDepthAndFormationNamesWithoutDuplicatesOnDepth(std::vector* names, std::vector* measuredDepths) const { - names.clear(); - measuredDepths.clear(); + names->clear(); + measuredDepths->clear(); - std::map tempMakeVectorUniqueOnMeasuredDepth; + std::map tempMakeVectorUniqueOnMeasuredDepth; - for (const std::pair& mdAndFormName : m_measuredDepthAndFormationNames) + for (RigWellPathFormation formation : m_formations) { - if (tempMakeVectorUniqueOnMeasuredDepth.find(mdAndFormName.first) == tempMakeVectorUniqueOnMeasuredDepth.end()) + if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.mdTop)) { - measuredDepths.push_back(mdAndFormName.first); - names.push_back(mdAndFormName.second); - tempMakeVectorUniqueOnMeasuredDepth[mdAndFormName.first] = mdAndFormName.second; + measuredDepths->push_back(formation.mdTop); + names->push_back(formation.formationName + " Top"); + tempMakeVectorUniqueOnMeasuredDepth[formation.mdTop] = true; + } + } + + for (RigWellPathFormation formation : m_formations) + { + if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.mdBase)) + { + measuredDepths->push_back(formation.mdBase); + names->push_back(formation.formationName + " Base"); + tempMakeVectorUniqueOnMeasuredDepth[formation.mdBase] = true; } } } @@ -70,5 +96,5 @@ QString RigWellPathFormations::keyInFile() const //-------------------------------------------------------------------------------------------------- size_t RigWellPathFormations::formationNamesCount() const { - return m_measuredDepthAndFormationNames.size(); + return m_formations.size(); } diff --git a/ApplicationCode/ReservoirDataModel/RigWellPathFormations.h b/ApplicationCode/ReservoirDataModel/RigWellPathFormations.h index 5d8f912cfc..443db152bb 100644 --- a/ApplicationCode/ReservoirDataModel/RigWellPathFormations.h +++ b/ApplicationCode/ReservoirDataModel/RigWellPathFormations.h @@ -22,17 +22,28 @@ #include "cvfObject.h" #include +#include #include #include -#include + +struct RigWellPathFormation +{ + double mdTop; + double mdBase; + QString formationName; + size_t level = 0; +}; + class RigWellPathFormations : public cvf::Object { public: - RigWellPathFormations(std::vector> measuredDepthAndFormationNames, const QString& filePath, const QString& key); + RigWellPathFormations(std::vector formations, const QString& filePath, const QString& key); - void measuredDepthAndFormationNamesWithoutDuplicates(std::vector& names, std::vector& measuredDepths) const; + void measuredDepthAndFormationNamesWithoutDuplicatesOnDepth(std::vector* names, std::vector* measuredDepths) const; + + void measuredDepthAndFormationNamesForLevel(size_t level, std::vector* names, std::vector* measuredDepths) const; QString filePath() const; QString keyInFile() const; @@ -43,5 +54,5 @@ private: QString m_filePath; QString m_keyInFile; - std::vector> m_measuredDepthAndFormationNames; + std::vector m_formations; };