diff --git a/ApplicationLibCode/FileInterface/RifEclipseSummaryTools.cpp b/ApplicationLibCode/FileInterface/RifEclipseSummaryTools.cpp index 96ba43bbba..7fbd52a249 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseSummaryTools.cpp +++ b/ApplicationLibCode/FileInterface/RifEclipseSummaryTools.cpp @@ -19,10 +19,12 @@ #include "RifEclipseSummaryTools.h" #include "RiaFilePathTools.h" +#include "RiaPreferencesSummary.h" #include "RiaStdStringTools.h" #include "RiaStringEncodingTools.h" #include "Summary/RiaSummaryAddressAnalyzer.h" +#include "RifOpmSummaryTools.h" #include "RifSummaryReaderInterface.h" #include "cafAppEnum.h" @@ -156,7 +158,9 @@ void RifEclipseSummaryTools::dumpMetaData( RifSummaryReaderInterface* readerEcli //-------------------------------------------------------------------------------------------------- std::vector RifEclipseSummaryTools::getRestartFileNames( const QString& headerFileName, std::vector& warnings ) { - const bool useOpmReader = false; + RiaPreferencesSummary* prefs = RiaPreferencesSummary::current(); + const bool useOpmReader = prefs->summaryDataReader() == RiaPreferencesSummary::SummaryReaderMode::OPM_COMMON; + return getRestartFileNames( headerFileName, useOpmReader, warnings ); } @@ -205,6 +209,16 @@ std::vector if ( useOpmReader ) { relativeFilePathFromFile = getRestartRelativeFilePathOpm( currentFileName ); + + // When ResInsight creates restart files by writing ESMRY files, there is no support for writing the RESTART keyword to the + // ESMRY. As fallback in this situation, read restart file path from SMSPEC. + // + // See ESmry::make_esmry_file() and RifOpmCommonEclipseSummary::writeEsmryFile() + if ( relativeFilePathFromFile.isEmpty() ) + { + auto smspecFileName = RifOpmSummaryTools::smspecSummaryFilename( currentFileName ); + relativeFilePathFromFile = getRestartRelativeFilePathResdata( smspecFileName ); + } } else { @@ -277,14 +291,6 @@ RifRestartFileInfo RifEclipseSummaryTools::getFileInfoAndTimeSteps( const QStrin return fileInfo; } -//-------------------------------------------------------------------------------------------------- -/// -//-------------------------------------------------------------------------------------------------- -std::vector RifEclipseSummaryTools::getRestartFileNamesOpm( const QString& headerFileName, std::vector& warnings ) -{ - return getRestartFileNames( headerFileName, true, warnings ); -} - //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- @@ -357,12 +363,42 @@ QString RifEclipseSummaryTools::getRestartRelativeFilePathOpm( const QString& he Opm::EclIO::EclFile eclFile( headerFileName.toStdString() ); eclFile.loadData( "RESTART" ); - std::string restartCaseNameFromFile; + if ( !eclFile.hasKey( "RESTART" ) ) return ""; - auto restartData = eclFile.get( "RESTART" ); + std::string restartCaseNameFromFile; + auto restartData = eclFile.get( "RESTART" ); for ( const auto& string : restartData ) { - restartCaseNameFromFile += string; + auto candidate = QDir::cleanPath( QString::fromStdString( string ) ); + + // Find "realization-" in both paths + int incomingRealizationPos = headerFileName.indexOf( "realization-" ); + int foundRealizationPos = candidate.indexOf( "realization-" ); + + if ( incomingRealizationPos != -1 && foundRealizationPos != -1 ) + { + // Extract prefix from incoming path (everything up to "realization-") + QString prefix = headerFileName.left( incomingRealizationPos ); + + // Extract suffix from cleaned found path (everything from "realization-" onwards) + QString suffix = candidate.mid( foundRealizationPos ); + + // Combine to get the target path + QString targetPath = QDir::cleanPath( prefix + suffix ); + + // Get the directory of the incoming file + QFileInfo incomingFileInfo( headerFileName ); + QDir incomingDir = incomingFileInfo.absoluteDir(); + + // Create relative path from incoming directory to target + QString relativePath = incomingDir.relativeFilePath( targetPath ); + + restartCaseNameFromFile += relativePath.toStdString(); + } + else + { + restartCaseNameFromFile += string; + } } return QString::fromStdString( restartCaseNameFromFile ); diff --git a/ApplicationLibCode/FileInterface/RifEclipseSummaryTools.h b/ApplicationLibCode/FileInterface/RifEclipseSummaryTools.h index 8c1dfd119f..bbf090b7ed 100644 --- a/ApplicationLibCode/FileInterface/RifEclipseSummaryTools.h +++ b/ApplicationLibCode/FileInterface/RifEclipseSummaryTools.h @@ -69,7 +69,6 @@ public: static void dumpMetaData( RifSummaryReaderInterface* readerEclipseSummary ); static std::vector getRestartFileNames( const QString& headerFileName, std::vector& warnings ); - static std::vector getRestartFileNamesOpm( const QString& headerFileName, std::vector& warnings ); static RifRestartFileInfo getFileInfoAndTimeSteps( const QString& headerFileName ); @@ -81,12 +80,15 @@ public: static std::pair splitVectorNameAndSuffix( const std::string& vectorName ); static std::vector nativeVectorNames( const std::vector& vectorNames ); -private: - static void findSummaryFiles( const QString& inputFile, QString* headerFile, QStringList* dataFiles ); - static QString getRestartRelativeFilePathResdata( const QString& headerFileName ); - static QString getRestartRelativeFilePathOpm( const QString& headerFileName ); + // Do not use this method directly, use the overload that infers the useOpmReader from Preferences + // This method is public to be able to call it from unit tests static std::vector getRestartFileNames( const QString& headerFileName, bool useOpmReader, std::vector& warnings ); - static QString getRestartFilePath( const QString& headerFileName, const QString& restartCaseNameFromFile ); + +private: + static void findSummaryFiles( const QString& inputFile, QString* headerFile, QStringList* dataFiles ); + static QString getRestartRelativeFilePathResdata( const QString& headerFileName ); + static QString getRestartRelativeFilePathOpm( const QString& headerFileName ); + static QString getRestartFilePath( const QString& headerFileName, const QString& restartCaseNameFromFile ); static void findSummaryHeaderFileInfo( const QString& inputFile, QString* headerFile, QString* path, QString* base, bool* isFormatted ); }; diff --git a/ApplicationLibCode/FileInterface/RifEnsembleImportConfig.cpp b/ApplicationLibCode/FileInterface/RifEnsembleImportConfig.cpp index 6eaa6690bb..15a4037fb7 100644 --- a/ApplicationLibCode/FileInterface/RifEnsembleImportConfig.cpp +++ b/ApplicationLibCode/FileInterface/RifEnsembleImportConfig.cpp @@ -58,10 +58,10 @@ void RifEnsembleImportConfig::computePatternsFromSummaryFilePaths( const QString { std::vector warnings; - auto restartFileNames1 = RifEclipseSummaryTools::getRestartFileNamesOpm( filePath1, warnings ); + auto restartFileNames1 = RifEclipseSummaryTools::getRestartFileNames( filePath1, warnings ); auto paramFilePath1 = RifCaseRealizationParametersFileLocator::locate( filePath1 ); - auto restartFileNames2 = RifEclipseSummaryTools::getRestartFileNamesOpm( filePath2, warnings ); + auto restartFileNames2 = RifEclipseSummaryTools::getRestartFileNames( filePath2, warnings ); auto paramFilePath2 = RifCaseRealizationParametersFileLocator::locate( filePath2 ); computeRestartPatternsFromTwoRealizations( restartFileNames1, restartFileNames2 ); diff --git a/ApplicationLibCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp b/ApplicationLibCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp index a55fe7945f..93e71a07d1 100644 --- a/ApplicationLibCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp +++ b/ApplicationLibCode/ProjectDataModel/Summary/RimFileSummaryCase.cpp @@ -175,28 +175,19 @@ std::unique_ptr RimFileSummaryCase::findRelatedFilesA auto findFileCandidates = [&ensembleImportState, &headerFileName, &warnings] -> std::vector { - if ( RiaPreferencesSummary::current()->summaryDataReader() == RiaPreferencesSummary::SummaryReaderMode::OPM_COMMON ) + if ( ( RiaPreferencesSummary::current()->summaryDataReader() == RiaPreferencesSummary::SummaryReaderMode::OPM_COMMON ) && + ensembleImportState.useConfigValues() ) { - if ( ensembleImportState.useConfigValues() ) + auto realizationNumber = RifOpmSummaryTools::extractRealizationNumber( headerFileName ); + if ( !realizationNumber.has_value() ) { - auto realizationNumber = RifOpmSummaryTools::extractRealizationNumber( headerFileName ); - if ( !realizationNumber.has_value() ) - { - RiaLogging::error( realizationNumber.error() ); - return {}; - } - return ensembleImportState.restartFilesForRealization( realizationNumber.value() ); - } - else - { - // If the restart file names are not provided, we search for them - return RifEclipseSummaryTools::getRestartFileNamesOpm( headerFileName, warnings ); + RiaLogging::error( realizationNumber.error() ); + return {}; } + return ensembleImportState.restartFilesForRealization( realizationNumber.value() ); } - else - { - return RifEclipseSummaryTools::getRestartFileNames( headerFileName, warnings ); - } + + return RifEclipseSummaryTools::getRestartFileNames( headerFileName, warnings ); }; std::vector restartFileNames; diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/iter-3/eclipse/model/DROGON-18.SMSPEC b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/iter-3/eclipse/model/DROGON-18.SMSPEC new file mode 100644 index 0000000000..0119fa875d Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/iter-3/eclipse/model/DROGON-18.SMSPEC differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/iter-3/eclipse/model/DROGON-18.UNSMRY b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/iter-3/eclipse/model/DROGON-18.UNSMRY new file mode 100644 index 0000000000..3437b1bd44 Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/iter-3/eclipse/model/DROGON-18.UNSMRY differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY new file mode 100644 index 0000000000..2e064098d4 Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.SMSPEC b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.SMSPEC new file mode 100644 index 0000000000..3c4833f0de Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.SMSPEC differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.UNSMRY b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.UNSMRY new file mode 100644 index 0000000000..1323525a6c Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/no-esmry-restart/realization-18/pred_ref/eclipse/model/DROGON-18.UNSMRY differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-esmry/realization-18/iter-3/eclipse/model/DROGON-18.ESMRY b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-esmry/realization-18/iter-3/eclipse/model/DROGON-18.ESMRY new file mode 100644 index 0000000000..278163995e Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-esmry/realization-18/iter-3/eclipse/model/DROGON-18.ESMRY differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-esmry/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-esmry/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY new file mode 100644 index 0000000000..2e064098d4 Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-esmry/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/iter-3/eclipse/model/DROGON-18.SMSPEC b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/iter-3/eclipse/model/DROGON-18.SMSPEC new file mode 100644 index 0000000000..0119fa875d Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/iter-3/eclipse/model/DROGON-18.SMSPEC differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/iter-3/eclipse/model/DROGON-18.UNSMRY b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/iter-3/eclipse/model/DROGON-18.UNSMRY new file mode 100644 index 0000000000..3437b1bd44 Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/iter-3/eclipse/model/DROGON-18.UNSMRY differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/pred_ref/eclipse/model/DROGON-18.SMSPEC b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/pred_ref/eclipse/model/DROGON-18.SMSPEC new file mode 100644 index 0000000000..3c4833f0de Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/pred_ref/eclipse/model/DROGON-18.SMSPEC differ diff --git a/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/pred_ref/eclipse/model/DROGON-18.UNSMRY b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/pred_ref/eclipse/model/DROGON-18.UNSMRY new file mode 100644 index 0000000000..1323525a6c Binary files /dev/null and b/ApplicationLibCode/UnitTests/TestData/summary-header-search/only-smspec/realization-18/pred_ref/eclipse/model/DROGON-18.UNSMRY differ diff --git a/ApplicationLibCode/UnitTests/opm-summary-Test.cpp b/ApplicationLibCode/UnitTests/opm-summary-Test.cpp index bf31b5b657..c6662eb397 100644 --- a/ApplicationLibCode/UnitTests/opm-summary-Test.cpp +++ b/ApplicationLibCode/UnitTests/opm-summary-Test.cpp @@ -49,7 +49,7 @@ TEST( OpmSummaryTests, DISABLED_PerformanceReadOfRestartFilename ) for ( int i = 0; i < N; i++ ) { std::vector warnings; - auto restartFileInfos = RifEclipseSummaryTools::getRestartFileNamesOpm( filePath, warnings ); + auto restartFileInfos = RifEclipseSummaryTools::getRestartFileNames( filePath, warnings ); } RiaLogging::logElapsedTime( "Completed opm-common", startTime ); @@ -382,3 +382,63 @@ TEST( OpmSummaryTests, DISABLED_ReadOpmRadialGrid ) } } } + +TEST( OpmSummaryHeaderSearch, NoEsmryRestart ) +{ + QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/summary-header-search/no-esmry-restart/" ).arg( TEST_DATA_DIR ); + QString filename = SUMMARY_TEST_DATA_DIRECTORY + "/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY"; + + const bool useOpmReader = true; + std::vector warnings; + auto restartFilenames = RifEclipseSummaryTools::getRestartFileNames( filename, useOpmReader, warnings ); + + EXPECT_TRUE( restartFilenames.size() == 1 ); + auto restartFileName = restartFilenames[0]; + + // search for text iter-3 + EXPECT_TRUE( restartFileName.contains( "iter-3" ) ); + + // check that the file does not exist + QFile file( restartFileName ); + EXPECT_FALSE( file.exists() ); +} + +TEST( OpmSummaryHeaderSearch, OnlyEsmryFiles ) +{ + QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/summary-header-search/only-esmry/" ).arg( TEST_DATA_DIR ); + QString filename = SUMMARY_TEST_DATA_DIRECTORY + "/realization-18/pred_ref/eclipse/model/DROGON-18.ESMRY"; + + const bool useOpmReader = true; + std::vector warnings; + auto restartFilenames = RifEclipseSummaryTools::getRestartFileNames( filename, useOpmReader, warnings ); + + EXPECT_TRUE( restartFilenames.size() == 1 ); + auto restartFileName = restartFilenames[0]; + + // search for text iter-3 + EXPECT_TRUE( restartFileName.contains( "iter-3" ) ); + + // check that the file exists + QFile file( restartFileName ); + EXPECT_TRUE( file.exists() ); +} + +TEST( OpmSummaryHeaderSearch, OnlySmspecFiles ) +{ + QString SUMMARY_TEST_DATA_DIRECTORY = QString( "%1/summary-header-search/only-smspec/" ).arg( TEST_DATA_DIR ); + QString filename = SUMMARY_TEST_DATA_DIRECTORY + "/realization-18/pred_ref/eclipse/model/DROGON-18.SMSPEC"; + + const bool useOpmReader = true; + std::vector warnings; + auto restartFilenames = RifEclipseSummaryTools::getRestartFileNames( filename, useOpmReader, warnings ); + + EXPECT_TRUE( restartFilenames.size() == 1 ); + auto restartFileName = restartFilenames[0]; + + // search for text iter-3 + EXPECT_TRUE( restartFileName.contains( "iter-3" ) ); + + // check that the file exists + QFile file( restartFileName ); + EXPECT_TRUE( file.exists() ); +}