///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2017- Statoil ASA // // ResInsight is free software: you can redistribute it and/or modify // it under the terms of the GNU General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. // // ResInsight is distributed in the hope that it will be useful, but WITHOUT ANY // WARRANTY; without even the implied warranty of MERCHANTABILITY or // FITNESS FOR A PARTICULAR PURPOSE. // // See the GNU General Public License at // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "RigWellPathFormations.h" #include "QStringList" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigWellPathFormations::RigWellPathFormations(const std::vector& formations, const QString& filePath, const QString& key) { m_filePath = filePath; m_keyInFile = key; for (const RigWellPathFormation& formation : formations) { if (isFluid(formation.formationName)) { m_fluids.push_back(formation); } else { FormationLevel level = detectLevel(formation.formationName); m_formationsLevelsPresent[level] = true; m_formations.push_back(std::pair(formation, level)); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigWellPathFormations::depthAndFormationNamesWithoutDuplicatesOnDepth(std::vector* names, std::vector* measuredDepths, RimWellLogPlot::DepthTypeEnum depthType) const { std::map tempMakeVectorUniqueOnMeasuredDepth; if (depthType == RimWellLogPlot::MEASURED_DEPTH) { for (const std::pair& formation : m_formations) { if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.mdTop)) { measuredDepths->push_back(formation.first.mdTop); names->push_back(formation.first.formationName + " Top"); tempMakeVectorUniqueOnMeasuredDepth[formation.first.mdTop] = true; } } for (const std::pair& formation : m_formations) { if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.mdBase)) { measuredDepths->push_back(formation.first.mdBase); names->push_back(formation.first.formationName + " Base"); tempMakeVectorUniqueOnMeasuredDepth[formation.first.mdBase] = true; } } } else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH) { for (const std::pair& formation : m_formations) { if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.tvdTop)) { measuredDepths->push_back(formation.first.tvdTop); names->push_back(formation.first.formationName + " Top"); tempMakeVectorUniqueOnMeasuredDepth[formation.first.tvdTop] = true; } } for (const std::pair& formation : m_formations) { if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.tvdBase)) { measuredDepths->push_back(formation.first.tvdBase); names->push_back(formation.first.formationName + " Base"); tempMakeVectorUniqueOnMeasuredDepth[formation.first.tvdBase] = true; } } } /* for (const std::pair& formation : m_formations) { if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.mdTop)) { double depth; if (depthType == RimWellLogPlot::MEASURED_DEPTH) { depth = formation.first.mdTop; } else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH) { depth = formation.first.tvdTop; } else return; measuredDepths->push_back(depth); names->push_back(formation.first.formationName + " Top"); tempMakeVectorUniqueOnMeasuredDepth[depth] = true; } } for (const std::pair& formation : m_formations) { double depth; if (depthType == RimWellLogPlot::MEASURED_DEPTH) { depth = formation.first.mdBase; } else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH) { depth = formation.first.tvdBase; } else return; if (!tempMakeVectorUniqueOnMeasuredDepth.count(formation.first.mdBase)) { measuredDepths->push_back(depth); names->push_back(formation.first.formationName + " Base"); tempMakeVectorUniqueOnMeasuredDepth[depth] = true; } }*/ } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigWellPathFormations::evaluateFormationsForOnePosition( const std::vector>& formations, const FormationLevel& maxLevel, const PickPosition& position, std::map* uniqueListMaker, RimWellLogPlot::DepthTypeEnum depthType) const { QString postFix; if (position == TOP) { postFix = " Top"; } else { postFix = " Base"; } for (const std::pair& formation : formations) { double depth; if (depthType == RimWellLogPlot::MEASURED_DEPTH) { if (position == TOP) { depth = formation.first.mdTop; } else { depth = formation.first.mdBase; } } else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH) { if (position == TOP) { depth = formation.first.tvdTop; } else { depth = formation.first.tvdBase; } } else return; if (formation.second > maxLevel) continue; if (!uniqueListMaker->count(depth) || uniqueListMaker->at(depth).level < formation.second) { (*uniqueListMaker)[depth] = LevelAndName(formation.second, formation.first.formationName + postFix); } } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigWellPathFormations::evaluateFormations(const std::vector>& formations, const FormationLevel& maxLevel, std::vector* names, std::vector* depths, RimWellLogPlot::DepthTypeEnum depthType) const { std::map tempMakeVectorUniqueOnDepth; evaluateFormationsForOnePosition(formations, maxLevel, PickPosition::TOP, &tempMakeVectorUniqueOnDepth, depthType); evaluateFormationsForOnePosition(formations, maxLevel, PickPosition::BASE, &tempMakeVectorUniqueOnDepth, depthType); for (const std::pair& uniqueDepth : tempMakeVectorUniqueOnDepth) { depths->push_back(uniqueDepth.first); names->push_back(uniqueDepth.second.name); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigWellPathFormations::evaluateFluids(const std::vector& fluidFormations, std::vector* names, std::vector* depths, RimWellLogPlot::DepthTypeEnum depthType) const { std::map uniqueListMaker; for (const RigWellPathFormation& formation : fluidFormations) { double depthBase; if (depthType == RimWellLogPlot::MEASURED_DEPTH) { depthBase = formation.mdBase; } else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH) { depthBase = formation.tvdBase; } else return; uniqueListMaker[depthBase] = formation.formationName + " Base"; } for (const RigWellPathFormation& formation : fluidFormations) { double depthTop; if (depthType == RimWellLogPlot::MEASURED_DEPTH) { depthTop = formation.mdTop; } else if (depthType == RimWellLogPlot::TRUE_VERTICAL_DEPTH) { depthTop = formation.tvdTop; } else return; uniqueListMaker[depthTop] = formation.formationName + " Top"; } for (const std::pair& depthAndFormation : uniqueListMaker) { depths->push_back(depthAndFormation.first); names->push_back(depthAndFormation.second); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RigWellPathFormations::depthAndFormationNamesUpToLevel(FormationLevel level, std::vector* names, std::vector* depths, bool includeFluids, RimWellLogPlot::DepthTypeEnum depthType) const { names->clear(); depths->clear(); if (includeFluids) { evaluateFluids(m_fluids, names, depths, depthType); } if (level == RigWellPathFormations::NONE) { return; } else if (level == RigWellPathFormations::ALL) { depthAndFormationNamesWithoutDuplicatesOnDepth(names, depths, depthType); } else { evaluateFormations(m_formations, level, names, depths, depthType); } } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- std::vector RigWellPathFormations::formationsLevelsPresent() const { std::vector formationLevels; for (const std::pair& formationLevel : m_formationsLevelsPresent) { formationLevels.push_back(formationLevel.first); } return formationLevels; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RigWellPathFormations::filePath() const { return m_filePath; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- QString RigWellPathFormations::keyInFile() const { return m_keyInFile; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- size_t RigWellPathFormations::formationNamesCount() const { return m_formations.size() + m_fluids.size(); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- bool RigWellPathFormations::isFluid(QString formationName) { formationName = formationName.trimmed(); if (formationName == "OIL" || formationName == "GAS" || formationName == "WATER") { return true; } return false; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RigWellPathFormations::FormationLevel RigWellPathFormations::detectLevel(QString formationName) { formationName = formationName.trimmed(); bool isGroupName = true; for (QChar c : formationName) { if (c.isLower()) { isGroupName = false; break; } } if (isGroupName) { return RigWellPathFormations::GROUP; } QStringList formationNameSplitted = formationName.split(" "); std::vector levelDesctiptorCandidates; for (QString word : formationNameSplitted) { for (const QChar& c : word) { if (c.isDigit()) { levelDesctiptorCandidates.push_back(word); break; } } } if (levelDesctiptorCandidates.empty()) { return RigWellPathFormations::LEVEL0; } if (levelDesctiptorCandidates.size() > 1) { for (auto it = levelDesctiptorCandidates.begin(); it != levelDesctiptorCandidates.end(); it++) { for (const QChar& c : *it) { if (c.isLetter()) { levelDesctiptorCandidates.erase(it); } } } } if (levelDesctiptorCandidates.size() != 1) return RigWellPathFormations::UNKNOWN; QString levelDescriptor = levelDesctiptorCandidates[0]; QStringList joinedLevel = levelDescriptor.split('+'); if (joinedLevel.size() > 1) { levelDescriptor = joinedLevel[0]; } int dotCount = levelDescriptor.count('.'); switch (dotCount) { case 0: return RigWellPathFormations::LEVEL1; case 1: return RigWellPathFormations::LEVEL2; case 2: return RigWellPathFormations::LEVEL3; case 3: return RigWellPathFormations::LEVEL4; case 4: return RigWellPathFormations::LEVEL5; case 5: return RigWellPathFormations::LEVEL6; case 6: return RigWellPathFormations::LEVEL7; case 7: return RigWellPathFormations::LEVEL8; case 8: return RigWellPathFormations::LEVEL9; case 9: return RigWellPathFormations::LEVEL10; default: break; } return RigWellPathFormations::UNKNOWN; }