From a6277c0ddc4dd15141343f0b85dd5cc8a0729319 Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Mon, 19 Apr 2021 16:40:29 +0200 Subject: [PATCH] Make opm summary reader work with mixed casing (#7593) * #7592 opm-common : Add case insensitive file search * #7592 opm-common : Find file based on case insensitive search * #7592 opm-common : Improve error messages --- .../FileInterface/RifReaderEclipseSummary.cpp | 9 ++-- .../Summary/RimFileSummaryCase.cpp | 9 +++- .../opm-common/opm/io/eclipse/EclUtil.hpp | 4 ++ .../opm-common/src/opm/io/eclipse/ESmry.cpp | 52 ++++++++++++++++++- .../opm-common/src/opm/io/eclipse/EclUtil.cpp | 22 ++++++++ 5 files changed, 88 insertions(+), 8 deletions(-) diff --git a/ApplicationLibCode/FileInterface/RifReaderEclipseSummary.cpp b/ApplicationLibCode/FileInterface/RifReaderEclipseSummary.cpp index 687bd4f066..d57c538f3d 100644 --- a/ApplicationLibCode/FileInterface/RifReaderEclipseSummary.cpp +++ b/ApplicationLibCode/FileInterface/RifReaderEclipseSummary.cpp @@ -197,17 +197,16 @@ bool RifReaderEclipseSummary::open( const QString& headerFileName, bool useLodsmryFiles = prefSummary->useOptimizedSummaryDataFiles(); if ( useLodsmryFiles && includeRestartFiles ) { - QString txt = "LODSMRY file loading for summary restart files is not supported. Disable one of the options"; - if ( threadSafeLogger ) threadSafeLogger->error( txt ); - - return false; + QString txt = + "LODSMRY file loading for summary restart files is not supported. Restart history might be incomplete."; + if ( threadSafeLogger ) threadSafeLogger->warning( txt ); } m_opmCommonReader = std::make_unique(); m_opmCommonReader->useLodsmaryFiles( prefSummary->useOptimizedSummaryDataFiles() ); m_opmCommonReader->createLodsmaryFiles( prefSummary->createOptimizedSummaryDataFiles() ); - isValid = m_opmCommonReader->open( headerFileName, includeRestartFiles, threadSafeLogger ); + isValid = m_opmCommonReader->open( headerFileName, false, threadSafeLogger ); if ( !isValid ) m_opmCommonReader.reset(); } diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp index e3ec131d1c..953fca708a 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp @@ -100,9 +100,16 @@ void RimFileSummaryCase::createSummaryReaderInterfaceThreadSafe( RiaThreadSafeLo //-------------------------------------------------------------------------------------------------- void RimFileSummaryCase::createSummaryReaderInterface() { + RiaThreadSafeLogger threadSafeLogger; m_summaryFileReader = RimFileSummaryCase::findRelatedFilesAndCreateReader( this->summaryHeaderFilename(), m_includeRestartFiles, - nullptr ); + &threadSafeLogger ); + + auto messages = threadSafeLogger.messages(); + for ( const auto& m : messages ) + { + RiaLogging::info( m ); + } } //-------------------------------------------------------------------------------------------------- diff --git a/ThirdParty/custom-opm-common/opm-common/opm/io/eclipse/EclUtil.hpp b/ThirdParty/custom-opm-common/opm-common/opm/io/eclipse/EclUtil.hpp index c9cab8ef3c..7492225c45 100644 --- a/ThirdParty/custom-opm-common/opm-common/opm/io/eclipse/EclUtil.hpp +++ b/ThirdParty/custom-opm-common/opm-common/opm/io/eclipse/EclUtil.hpp @@ -20,6 +20,7 @@ #define OPM_IO_ECLUTIL_HPP #include +#include #include #include @@ -37,6 +38,9 @@ namespace Opm { namespace EclIO { bool isFormatted(const std::string& filename); bool is_number(const std::string& numstr); + bool isEqualCaseInsensitive(const std::string& string1, const std::string& string2); + Opm::filesystem::path findFileCaseInsensitive(const std::filesystem::path& folder, const std::string& filename); + std::tuple block_size_data_binary(eclArrType arrType); std::tuple block_size_data_formatted(eclArrType arrType); diff --git a/ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/ESmry.cpp b/ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/ESmry.cpp index 61ba6c710b..ae2a72a6ac 100644 --- a/ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/ESmry.cpp +++ b/ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/ESmry.cpp @@ -109,10 +109,19 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData , bool uselodsmry if (inputFileName.extension()=="") inputFileName+=".SMSPEC"; - if ((inputFileName.extension()!=".SMSPEC") && (inputFileName.extension()!=".FSMSPEC")) + if (!isEqualCaseInsensitive(inputFileName.extension().string(), ".SMSPEC") && + !isEqualCaseInsensitive(inputFileName.extension().string(), ".FSMSPEC")) throw std::invalid_argument("Input file should have extension .SMSPEC or .FSMSPEC"); - const bool formatted = inputFileName.extension()==".SMSPEC" ? false : true; + { + auto candidatePath = findFileCaseInsensitive(inputFileName.parent_path(), inputFileName.filename().string()); + if (!Opm::filesystem::exists(candidatePath)) + throw std::invalid_argument("Not able to find summary SMSPEC file"); + + inputFileName = candidatePath; + } + + const bool formatted = isEqualCaseInsensitive(inputFileName.extension().string(), ".SMSPEC") ? false : true; formattedFiles.push_back(formatted); if (formatted) @@ -120,6 +129,12 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData , bool uselodsmry else lodFileName = rootName += ".LODSMRY"; + { + auto candidatePath = findFileCaseInsensitive(lodFileName.parent_path(), lodFileName.filename().string()); + if (Opm::filesystem::exists(candidatePath)) lodFileName = candidatePath; + } + + if ((!loadBaseRunData) && (Opm::filesystem::exists(lodFileName))) lodEnabeled = true; else @@ -132,6 +147,14 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData , bool uselodsmry Opm::filesystem::path smspec_file = path / rootName; smspec_file += inputFileName.extension(); + { + auto candidatePath = findFileCaseInsensitive(smspec_file.parent_path(), smspec_file.filename().string()); + if (!Opm::filesystem::exists(candidatePath)) + throw std::invalid_argument("Not able to find summary SMSPEC file"); + + smspec_file = candidatePath; + } + Opm::filesystem::path rstRootN; Opm::filesystem::path pathRstFile = path; @@ -217,12 +240,29 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData , bool uselodsmry Opm::filesystem::path rstFile = pathRstFile / rstRootN; rstFile += ".SMSPEC"; + { + auto candidatePath = findFileCaseInsensitive(rstFile.parent_path(), rstFile.filename().string()); + if (!Opm::filesystem::exists(candidatePath)) + throw std::invalid_argument("Not able to find summary restart file"); + + rstFile = candidatePath; + } + bool baseRunFmt = false; // if unformatted file not exists, check for formatted file if (!Opm::filesystem::exists(rstFile)){ rstFile = pathRstFile / rstRootN; rstFile += ".FSMSPEC"; + + { + auto candidatePath = findFileCaseInsensitive(rstFile.parent_path(), rstFile.filename().string()); + if (!Opm::filesystem::exists(candidatePath)) + throw std::invalid_argument("Not able to find summary restart file"); + + rstFile = candidatePath; + } + baseRunFmt = true; } @@ -384,6 +424,14 @@ ESmry::ESmry(const std::string &filename, bool loadBaseRunData , bool uselodsmry Opm::filesystem::path unsmryFile = rootName; unsmryFile += formattedFiles[specInd] ? ".FUNSMRY" : ".UNSMRY"; + { + auto candidatePath = findFileCaseInsensitive(unsmryFile.parent_path(), unsmryFile.filename().string()); + if (!Opm::filesystem::exists(candidatePath)) + throw std::invalid_argument("Not able to find summary SMSPEC file"); + + unsmryFile = candidatePath; + } + const bool use_unified = Opm::filesystem::exists(unsmryFile.string()); const std::vector multFileList = checkForMultipleResultFiles(rootName, formattedFiles[specInd]); diff --git a/ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/EclUtil.cpp b/ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/EclUtil.cpp index 8c08294f80..94aa3dc353 100644 --- a/ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/EclUtil.cpp +++ b/ThirdParty/custom-opm-common/opm-common/src/opm/io/eclipse/EclUtil.cpp @@ -83,6 +83,28 @@ bool Opm::EclIO::is_number(const std::string& numstr) } +bool Opm::EclIO::isEqualCaseInsensitive(const std::string& string1, const std::string& string2) +{ + std::string string1LowerCase(string1); + std::string string2LowerCase(string2); + + std::transform(string1.begin(), string1.end(), string1LowerCase.begin(), ::tolower); + std::transform(string2.begin(), string2.end(), string2LowerCase.begin(), ::tolower); + + return string1LowerCase == string2LowerCase; +} + +std::filesystem::path Opm::EclIO::findFileCaseInsensitive(const std::filesystem::path& folder, const std::string& filename) +{ + for (auto& p : std::filesystem::directory_iterator(folder)) { + std::string candidate = p.path().filename().string(); + + if (isEqualCaseInsensitive(filename, candidate)) return p.path(); + } + + return { }; +} + bool Opm::EclIO::isFormatted(const std::string& filename) { const auto p = filename.find_last_of(".");